Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #14 +/- ##
==========================================
- Coverage 16.34% 11.48% -4.87%
==========================================
Files 20 28 +8
Lines 893 1271 +378
Branches 241 297 +56
==========================================
Hits 146 146
- Misses 661 1039 +378
Partials 86 86
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
jorgenfj
left a comment
There was a problem hiding this comment.
Try splitting the code into lib/ and ros/ folders. Try to make the ros2 node file as minimalistic as possible.
RayMeasurement should be independent from ros.
Use spdlog instead of rclcpp log
| target_frame: orca/odom # TF frame to transform measurements into | ||
| window_size: 30 # Max number of measurements kept in buffer | ||
| max_measurement_age_sec: 5.0 # Remove measurements older than this (s) | ||
| min_measurements: 5 # Min measurements needed to triangulate | ||
| min_baseline_m: 0.5 # Min distance between first and last measurement (m) | ||
| min_ray_angle_deg: 5.0 # Min angle between rays to accept solution (deg) | ||
| outlier_residual_threshold_m: 1.0 # Residual above this marks a measurement as outlier (m) | ||
| max_outlier_iterations: 2 # Max rounds of outlier rejection | ||
| publish_markers: true # Publish Foxglove markers for debugging | ||
| landmark_type: 3 # Landmark type ID sent in output message | ||
| landmark_subtype: 2 # Landmark subtype ID sent in output message | ||
|
|
||
| aruco: | ||
| target_frame: orca/odom | ||
| window_size: 15 | ||
| max_measurement_age_sec: 2 | ||
| min_measurements: 4 | ||
| min_baseline_m: 0.1 | ||
| min_ray_angle_deg: 1.0 | ||
| outlier_residual_threshold_m: 0.1 | ||
| max_outlier_iterations: 2 | ||
| publish_markers: true |
There was a problem hiding this comment.
Could have separate non-ros yaml files for the different configs, similar to how waypoint utils solves it. So that if we ever want to run this as a pure cpp executable we are not dependent on ros for the config values
| @@ -0,0 +1,75 @@ | |||
| #pragma once | |||
There was a problem hiding this comment.
Use the conventional vortex #ifndef pattern
| void BearingLocalizationNode::declare_parameters() { | ||
| declare_parameter("profile", "default"); | ||
| declare_parameter("target_frame", "orca/odom"); | ||
| declare_parameter("window_size", 30); | ||
| declare_parameter("max_measurement_age_sec", 5.0); | ||
| declare_parameter("min_measurements", 5); | ||
| declare_parameter("min_baseline_m", 0.5); | ||
| declare_parameter("min_ray_angle_deg", 5.0); | ||
| declare_parameter("outlier_residual_threshold_m", 1.0); | ||
| declare_parameter("max_outlier_iterations", 2); | ||
| declare_parameter("publish_markers", true); | ||
| declare_parameter("landmark_type", 0); | ||
| declare_parameter("landmark_subtype", 0); | ||
| declare_parameter("landmark_id", 0); | ||
|
|
||
| declare_parameter("topics.bearing_measurement", "bearing_measurement"); | ||
| declare_parameter("topics.bearing_array", | ||
| "/aruco_detector/marker_directions"); | ||
| declare_parameter("topics.landmarks", "landmarks"); | ||
| declare_parameter("topics.bearing_localization_markers", | ||
| "bearing_localization/markers"); | ||
| } |
There was a problem hiding this comment.
Should avoid default values for ros parameters. Default values here can create hidden bugs where the config value is not applied if there is a type somewhere.
| void BearingLocalizationNode::publish_result(const Eigen::Vector3d& position, | ||
| double residual) { | ||
| auto stamp = now(); | ||
|
|
||
| vortex_msgs::msg::Landmark landmark; | ||
| landmark.header.stamp = stamp; | ||
| landmark.header.frame_id = target_frame_; | ||
| landmark.id = 0; | ||
| landmark.type.value = static_cast<uint16_t>(landmark_type_); | ||
| landmark.subtype.value = static_cast<uint16_t>(landmark_subtype_); | ||
| landmark.pose.pose.position.x = position.x(); | ||
| landmark.pose.pose.position.y = position.y(); | ||
| landmark.pose.pose.position.z = position.z(); | ||
| landmark.pose.pose.orientation.w = 1.0; | ||
| const double var = residual * residual; | ||
| landmark.pose.covariance[0] = var; | ||
| landmark.pose.covariance[7] = var; | ||
| landmark.pose.covariance[14] = var; | ||
|
|
||
| vortex_msgs::msg::LandmarkArray landmark_array; | ||
| landmark_array.header.stamp = stamp; | ||
| landmark_array.header.frame_id = target_frame_; | ||
| landmark_array.landmarks.push_back(landmark); | ||
| landmark_pub_->publish(landmark_array); | ||
| } |
There was a problem hiding this comment.
This could be moved into a separate utils file to avoid cluttering the main node file
| min_ray_angle_deg: 5.0 # Min angle between rays to accept solution (deg) | ||
| outlier_residual_threshold_m: 1.0 # Residual above this marks a measurement as outlier (m) | ||
| max_outlier_iterations: 2 # Max rounds of outlier rejection | ||
| publish_markers: true # Publish Foxglove markers for debugging |
There was a problem hiding this comment.
maybe rename to publish_debug_markers to be more explicit that this is a debug topic
|
|
||
| void BearingLocalizationNode::setup_pubsub() { | ||
| bearing_sub_ = create_subscription<geometry_msgs::msg::Vector3Stamped>( | ||
| get_parameter("topics.bearing_measurement").as_string(), 10, |
There was a problem hiding this comment.
qos here. Use the helper qos function from vortex utils
ROS 2 node that estimates the 3D position of a target using bearing-only triangulation. It collects directional measurements from different viewpoints and solves for the point in space that best fits all rays.