-
Notifications
You must be signed in to change notification settings - Fork 2k
Fix: Enable colored pointcloud when frames arrive asynchronously #3487
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: r/4.57.6
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -79,6 +79,16 @@ void PointcloudFilter::setPublisher() | |||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| void PointcloudFilter::MapTexture(const rs2::frame& color_frame) | ||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||
| if (_filter && color_frame) | ||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||
| // Cast to rs2::pointcloud and call map_to | ||||||||||||||||||||||||||||||||||||||||
| auto pc_filter = std::static_pointer_cast<rs2::pointcloud>(_filter); | ||||||||||||||||||||||||||||||||||||||||
| pc_filter->map_to(color_frame); | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| void reverse_memcpy(unsigned char* dst, const unsigned char* src, size_t n) | ||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||
| size_t i; | ||||||||||||||||||||||||||||||||||||||||
|
|
@@ -88,11 +98,11 @@ void reverse_memcpy(unsigned char* dst, const unsigned char* src, size_t n) | |||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| void PointcloudFilter::Publish(rs2::points pc, const rclcpp::Time& t, const rs2::frameset& frameset, const std::string& frame_id) | ||||||||||||||||||||||||||||||||||||||||
| void PointcloudFilter::Publish(rs2::points pc, const rclcpp::Time& t, const rs2::frameset& frameset, const std::string& frame_id, const rs2::frame& cached_color_frame) | ||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||
| std::lock_guard<std::mutex> lock_guard(_mutex_publisher); | ||||||||||||||||||||||||||||||||||||||||
| if ((!_pointcloud_publisher) || (!(_pointcloud_publisher->get_subscription_count()))) | ||||||||||||||||||||||||||||||||||||||||
| if (!_pointcloud_publisher || !(_pointcloud_publisher->get_subscription_count())) | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
| if (!_pointcloud_publisher || !(_pointcloud_publisher->get_subscription_count())) | |
| if (!(_pointcloud_publisher) || !(_pointcloud_publisher->get_subscription_count())) |
Copilot
AI
Feb 1, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line has been moved outside the conditional blocks where it's used (lines 135 and 146-148), but texture_source_id may not be initialized at line 114 if use_texture is false. This could lead to using an uninitialized variable. The variable declaration should remain inside the conditional blocks where texture_source_id is guaranteed to be set.
| std::string texture_source_name = _filter->get_option_value_description(rs2_option::RS2_OPTION_STREAM_FILTER, static_cast<float>(texture_source_id)); | |
| if (use_texture) | |
| { | |
| if (use_texture) | |
| { | |
| std::string texture_source_name = _filter->get_option_value_description( | |
| rs2_option::RS2_OPTION_STREAM_FILTER, | |
| static_cast<float>(texture_source_id)); |
Copilot
AI
Feb 1, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When a cached color frame is available, warn_count is reset but the code doesn't verify that the cached frame format is compatible with available_formats. The cached frame should be validated against available_formats before being accepted as a valid texture source, similar to how frames from the frameset are checked at line 121-122.
| // Try using cached color frame if texture source is Color | |
| if (texture_source_id == RS2_STREAM_COLOR && cached_color_frame) | |
| { | |
| warn_count = 0; | |
| // Try using cached color frame if texture source is Color and format is compatible | |
| if (texture_source_id == RS2_STREAM_COLOR && cached_color_frame) | |
| { | |
| auto cached_format = cached_color_frame.get_profile().format(); | |
| if (available_formats.find(cached_format) != available_formats.end()) | |
| { | |
| warn_count = 0; | |
| } | |
| else | |
| { | |
| warn_count++; | |
| ROS_WARN_STREAM_COND(warn_count == DISPLAY_WARN_NUMBER, | |
| "No compatible format for pointcloud chosen texture " << texture_source_name); | |
| return; | |
| } |
Copilot
AI
Feb 1, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The check for cached_color_frame.is<rs2::video_frame>() is redundant with the check at line 188. Consider removing the type check here since it's validated again before use, or consolidate the logic to avoid duplicate validation.
| else if (cached_color_frame && cached_color_frame.is<rs2::video_frame>()) | |
| else if (cached_color_frame) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
std::static_pointer_cast to rs2::pointcloud followed by pc_filter->map_to(...) can dereference an object of the wrong runtime type. Verify the filter is actually a pointcloud (e.g., dynamic type check or store as correct type) before calling map_to.
Details
✨ AI Reasoning
A newly added MapTexture method casts the stored _filter (shared_ptrrs2::filter) to a rs2::pointcloud with std::static_pointer_cast and then calls map_to on the result. If _filter does not actually point to a rs2::pointcloud instance at runtime, the static cast yields an invalid object and calling map_to may dereference invalid memory and cause a segmentation fault. The code checks only that _filter is non-null and that color_frame is valid; there is no runtime type verification before calling map_to. This change introduced the unsafe cast and direct call, which did not exist before. The problematic code is at the line performing the static_pointer_cast and subsequent method call.
🔧 How do I fix it?
Add null checks before dereferencing pointers, validate array bounds before access, avoid using pointers after free/delete, don't write to string literals, and prefer smart pointers in modern C++.
Reply
@AikidoSec feedback: [FEEDBACK]to get better review comments in the future.Reply
@AikidoSec ignore: [REASON]to ignore this issue.More info
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@JINGERGER can you handle this comment please?