-
Notifications
You must be signed in to change notification settings - Fork 637
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
feat(autoware_pointcloud_preprocessor): redesign concatenate and time sync node #8300
base: main
Are you sure you want to change the base?
feat(autoware_pointcloud_preprocessor): redesign concatenate and time sync node #8300
Conversation
Thank you for contributing to the Autoware project! 🚧 If your pull request is in progress, switch it to draft mode. Please ensure:
|
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #8300 +/- ##
==========================================
+ Coverage 26.19% 28.10% +1.90%
==========================================
Files 1302 1339 +37
Lines 96935 100091 +3156
Branches 39172 40494 +1322
==========================================
+ Hits 25395 28128 +2733
- Misses 68959 71800 +2841
+ Partials 2581 163 -2418
*This pull request uses carry forward flags. Click here to find out more. ☔ View full report in Codecov by Sentry. |
@kminoda |
@vividf Thanks. Let me do that later |
sensing/autoware_pointcloud_preprocessor/schema/cocatenate_and_time_sync_node.schema.json
Outdated
Show resolved
Hide resolved
"maximum_queue_size": { | ||
"type": "integer", | ||
"default": 5, | ||
"description": "Maximum size of the queue." |
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.
Please describe in more detail:
- which queue does this refer to - the number of waiting input pointclouds, the number of cloud collector groups, etc.?
- Effects on maximum latency of the produced concatenated cloud. If this refers to the number of groups possible, wouldn't the maximum latency be 500 ms?
"properties": { | ||
"maximum_queue_size": { | ||
"type": "integer", | ||
"default": 5, |
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.
Check what effects this has on latency (see comment one line below). If this parameter refers to the number of groups, the latency would be up to 500 ms, which is not good for A/D. Setting this default to 2 would be safer imho.
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.
@mojomex
The maximum_queue_size
is defined for most of the nodes in pointcloud preprocessor (and the value is 5).
I think if we modify the number from 5 to 2, perhaps we also need to consider whether we should modify the value in other nodes.
btw, maximum_queue_size
parameter is for the qos setting instead of the group (collector?)
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.
As I just discussed with @drwnz in person, setting it to 1
is best. This reduces latency to a minimum. Just starting with this node for now is okay.
sensing/autoware_pointcloud_preprocessor/docs/concatenate-data.md
Outdated
Show resolved
Hide resolved
...include/autoware/pointcloud_preprocessor/concatenate_data/concatenate_and_time_sync_node.hpp
Outdated
Show resolved
Hide resolved
...include/autoware/pointcloud_preprocessor/concatenate_data/concatenate_and_time_sync_node.hpp
Outdated
Show resolved
Hide resolved
...include/autoware/pointcloud_preprocessor/concatenate_data/concatenate_and_time_sync_node.hpp
Outdated
Show resolved
Hide resolved
...include/autoware/pointcloud_preprocessor/concatenate_data/concatenate_and_time_sync_node.hpp
Outdated
Show resolved
Hide resolved
sensing/autoware_pointcloud_preprocessor/src/concatenate_data/combine_cloud_handler.cpp
Outdated
Show resolved
Hide resolved
...ing/autoware_pointcloud_preprocessor/src/concatenate_data/concatenate_and_time_sync_node.cpp
Outdated
Show resolved
Hide resolved
sensing/autoware_pointcloud_preprocessor/src/concatenate_data/cloud_collector.cpp
Outdated
Show resolved
Hide resolved
sensing/autoware_pointcloud_preprocessor/src/concatenate_data/cloud_collector.cpp
Outdated
Show resolved
Hide resolved
sensing/autoware_pointcloud_preprocessor/src/concatenate_data/cloud_collector.cpp
Outdated
Show resolved
Hide resolved
sensing/autoware_pointcloud_preprocessor/src/concatenate_data/cloud_collector.cpp
Outdated
Show resolved
Hide resolved
sensing/autoware_pointcloud_preprocessor/src/concatenate_data/cloud_collector.cpp
Show resolved
Hide resolved
sensing/autoware_pointcloud_preprocessor/src/concatenate_data/cloud_collector.cpp
Outdated
Show resolved
Hide resolved
concatenate_cloud_ptr = | ||
std::make_shared<sensor_msgs::msg::PointCloud2>(*transformed_delay_compensated_cloud_ptr); |
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.
Reserving the total number of bytes needed in the point cloud's data
field could spare us a couple of resize/re-allocation operations.
Something like this perhaps:
auto n_total_points = // sum of the number of points of all pointclouds
concatenate_cloud_ptr->data.reserve(concatenate_cloud_ptr->point_step * n_total_points)
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.
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.
Sorry, this is not quite what I meant: with your new implementation, the size of the additional single pointlcoud is reserved but not the size of all poinclouds combined.
What I wanted to see is
- initialize
concatenate_cloud_ptr
with an empty pointcloud (*1) before the for loop starts - reserve
data
such that it's (pseudocode)point_step * sum([cloud.data.size() for cloud in cloud_map.values()]
(so if you have clouds with sizes 1, 2 and 3 bytes, it would reserve 6 bytes at once before the for loop starts - then concatenate the clouds to
concatenate_cloud_ptr
in the loop
The manual initialization of all fields should not be necessary (please revert to how it was before, just make_shared).
*1: when calling pcl::concatenatePointCloud
it will sadly throw away the empty initial pointcloud... Unless we want to do something sketchy (or implement concatenation ourselves) we can't proceed with this comment.
Feel free to
- revert and resolve this conversation
- and add a comment above the for loop saying that this could be made faster by reserving space first.
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.
sensing/autoware_pointcloud_preprocessor/src/concatenate_data/combine_cloud_handler.cpp
Outdated
Show resolved
Hide resolved
// convert to original sensor frame if necessary | ||
bool need_transform_to_sensor_frame = (cloud->header.frame_id != output_frame_); | ||
if (keep_input_frame_in_synchronized_pointcloud_ && need_transform_to_sensor_frame) { | ||
sensor_msgs::msg::PointCloud2::SharedPtr transformed_cloud_ptr_in_sensor_frame( | ||
new sensor_msgs::msg::PointCloud2()); | ||
pcl_ros::transformPointCloud( | ||
(std::string)cloud->header.frame_id, *transformed_delay_compensated_cloud_ptr, | ||
*transformed_cloud_ptr_in_sensor_frame, tf_buffer_); | ||
transformed_cloud_ptr_in_sensor_frame->header.stamp = oldest_stamp; | ||
transformed_cloud_ptr_in_sensor_frame->header.frame_id = cloud->header.frame_id; | ||
topic_to_transformed_cloud_map[topic] = transformed_cloud_ptr_in_sensor_frame; | ||
} else { | ||
transformed_delay_compensated_cloud_ptr->header.stamp = oldest_stamp; | ||
transformed_delay_compensated_cloud_ptr->header.frame_id = output_frame_; | ||
topic_to_transformed_cloud_map[topic] = transformed_delay_compensated_cloud_ptr; | ||
} |
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.
As far as I understand, these will only be published if the publish_synchronized_pointcloud
parameter is true. However, this part of the code here is always running (at the least, the original pointclouds are kept as-is and inserted into the map, thus causing increased memory usage).
Only creating this map if the feature is enabled (e.g. std::optional<std::unordered_map<...>>
) and not keeping the original pointclouds in it if disabled, would be preferable.
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.
Thanks!!! I didn't notice that in the old design!
Fix the logic in 52ed5ed
sensing/autoware_pointcloud_preprocessor/src/concatenate_data/combine_cloud_handler.cpp
Outdated
Show resolved
Hide resolved
sensing/autoware_pointcloud_preprocessor/src/concatenate_data/combine_cloud_handler.cpp
Outdated
Show resolved
Hide resolved
"default": [], | ||
"description": "List of input point cloud topics." | ||
}, | ||
"output_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.
When it comes to frames empty ones are usually not allowed in ROS. Can you add a restriction here?
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.
Thanks! Addressed the schema-related suggestions in b6700a9
@vividf
Can you provide / right the previous items? |
Signed-off-by: vividf <[email protected]>
Signed-off-by: vividf <[email protected]>
Signed-off-by: vividf <[email protected]>
Signed-off-by: vividf <[email protected]>
Signed-off-by: vividf <[email protected]>
Signed-off-by: vividf <[email protected]>
@vividf I built and ran with ThreadSanitizer (TSan). Setupcd ~/autoware
# Autoware is already built, just build the preprocessor with tsan
colcon build --symlink-install --cmake-args -DCMAKE_BUILD_TYPE=RelWithDebInfo --packages-select autoware_pointcloud_preprocessor --mixin tsan
source install/setup.bash
ros2 launch autoware_pointcloud_preprocessor concatenate_and_time_sync_node.launch.xml In a previous run, I recorded all necessary inputs into a rosbag which I replayed. ResultsThere is one memory safety issue ( In Suggested solutionBecause |
Signed-off-by: vividf <[email protected]>
Signed-off-by: vividf <[email protected]>
Signed-off-by: vividf <[email protected]>
Signed-off-by: vividf <[email protected]>
Signed-off-by: vividf <[email protected]>
Signed-off-by: vividf <[email protected]>
Signed-off-by: vividf <[email protected]>
Signed-off-by: vividf <[email protected]>
Signed-off-by: vividf <[email protected]>
Signed-off-by: vividf <[email protected]>
Signed-off-by: vividf <[email protected]>
Signed-off-by: vividf <[email protected]>
@mojomex |
Signed-off-by: vividf <[email protected]>
Signed-off-by: vividf <[email protected]>
Description
This PR solved the issue #6832.
Previous designs have some issues concatenating the pointcloud correctly, therefore, this PR redesigns the logic of the concatenate node in order to handle the edge cases like pointcloud delay or pointcloud drop.
Changes
A more detailed description of the algorithm is on the Readme page.https://github.com/vividf/autoware.universe/blob/feature/redesign_concatenate_and_time_sync_node/sensing/autoware_pointcloud_preprocessor/docs/concatenate-data.md
Related links
Parent Issue:
How was this PR tested?
Unit test and Component test for concatenate node
launch
Tested with xx1
data: TIER4_INTERNAL_LINK
Note
This bag can test the scenario when the pointclouds are dropped.
Tested with xx2 gen2
data: TIER4_INTERNAL_LINK
modify the config file
concatenate_and_time_sync_node.param.yaml
Result
TIER4_INTERNAL_LINK
Time comparison (xx1 bag)
From last arrived pointcloud to publish concatenate pointcloud (include publishing)
Before (move the toc to the beginning of the cloudcallback function)
Note that the huge latency is because a pointcloud is dropped.
After
By setting is_motion_compensated to false
Notes for reviewers
locking logic (mutex) might be an important part of double-checking :)
Interface changes
None.
Effects on system behavior
None.