From 84c63181217a7eca4f163cfc1b00e2b49db03454 Mon Sep 17 00:00:00 2001 From: jingyang-huang <1178065793@qq.com> Date: Thu, 2 Apr 2026 16:11:40 +0800 Subject: [PATCH] test ver --- CMakeLists.txt | 20 ++ config/control_command.yaml | 25 ++- config/odin_ros2.rviz | 16 +- include/cloud_reprojection_ros_node.hpp | 16 +- include/cloud_reprojector.hpp | 7 + include/host_sdk_sample.h | 86 +++++++- include/image_overlay_node.hpp | 91 +++++++++ include/lidar_api.h | 35 ++++ include/yaml_parser.h | 2 +- launch_ROS1/odin1_ros1.launch | 5 + launch_ROS2/odin1_ros2.launch.py | 15 +- lib/liblydHostApi_amd.a | Bin 422616 -> 455106 bytes lib/liblydHostApi_arm.a | Bin 455912 -> 488626 bytes package.xml | 35 ++-- src/cloud_reprojection_ros.cpp | 80 +++++++- src/cloud_reprojector.cpp | 29 ++- src/host_sdk_sample.cpp | 212 +++++++++++++++++++- src/image_overlay_node.cpp | 254 ++++++++++++++++++++++++ 18 files changed, 879 insertions(+), 49 deletions(-) create mode 100644 include/image_overlay_node.hpp create mode 100644 src/image_overlay_node.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 1135cf7..4bf049f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -209,6 +209,12 @@ if(ROS_VERSION STREQUAL "ROS1") ${PCL_LIBRARIES} ) + add_executable(image_overlay_node src/image_overlay_node.cpp) + target_link_libraries(image_overlay_node + ${catkin_LIBRARIES} + ${OpenCV_LIBS} + ) + # Installation rules install(TARGETS host_sdk_sample RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} @@ -340,12 +346,26 @@ elseif(ROS_VERSION STREQUAL "ROS2") message_filters ) + add_executable(image_overlay_node src/image_overlay_node.cpp) + target_compile_definitions(image_overlay_node PRIVATE ROS2) + target_link_libraries(image_overlay_node + ${OpenCV_LIBS} + ) + ament_target_dependencies(image_overlay_node + rclcpp + sensor_msgs + cv_bridge + image_transport + message_filters + ) + # Installation rules - ensure all install targets are defined before ament_package() # Install executable install(TARGETS host_sdk_sample pcd2depth_ros2_node cloud_reprojection_ros2_node + image_overlay_node EXPORT export_${PROJECT_NAME} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib diff --git a/config/control_command.yaml b/config/control_command.yaml index a2ec35c..cc6a95f 100644 --- a/config/control_command.yaml +++ b/config/control_command.yaml @@ -6,7 +6,7 @@ register_keys: # 0: use odin internal system time as data time stamp, typical and recommended; # 1: use host ros time (upon receive) as data time stamp, only use if you specifically require this setup, not recommended for most users # 2: align odin1 time to host time, timestamp is the sensor data reception time on host time axis - use_host_ros_time: 2 + use_host_ros_time: 0 # Changed to 0 to use device timestamp without PTP offset correction streamctrl: 1 # 0: off; 1: on @@ -25,6 +25,14 @@ register_keys: # IMU data sendimu: 1 # 0: off; 1: on + # SDK IMU smooth sending feature + # When enabled, SDK will send IMU data at precise intervals (default 400Hz) + # using a dedicated high-priority thread to reduce jitter and timing variance + enable_imu_smooth: 0 # 0: disable SDK IMU smooth sending; 1: enable (default) + + # SDK IMU smooth sending frequency in Hz (only effective when enable_imu_smooth = 1) + imu_smooth_frequency: 400 # 1-1000 Hz, recommended 400 Hz + # Odometry data sendodom: 1 # 0: off; 1: on @@ -57,6 +65,14 @@ register_keys: # Processed on host device sendreprojection: 0 # 0: off; 1: on + # image overlay settings - overlays reprojected points on camera image + # Processed on host device + sendoverlay: 0 # 0: off; 1: on + overlay_reprojected_topic: "/odin1/reprojected_image" # reprojected image topic + overlay_camera_topic: "/odin1/image" # camera image topic (undistorted) + overlay_output_topic: "/odin1/overlay_image" # output overlay image topic + overlay_alpha: 0.6 # blend alpha (0.0-1.0, higher = more reproj color) + # record rgb, odometry, and slam cloud data as proprietary olx format for further processing in MindCloud(TM) software. # save path: ws/src/odin_ros_driver/recorddata/{record_start_time}/ # ATTENTION: please copy the full folder for post-processing. @@ -80,3 +96,10 @@ register_keys: # To get the mapping result file, please use the set_param.sh script provided: "./set_param.sh save_map 1" mapping_result_dest_dir: "" # "": if not specified, save to default location of {ws}/src/odin_ros_driver/map/{driver_start_time}/ mapping_result_file_name: "" # "": if not specified, save to location above with default file name of map_{map_save_time}.bin + + # Image mask transfer settings + sendimagemask: 0 # 0: off; 1: on - transfer image mask to device on startup + image_mask_abs_path: "" # absolute path to the image mask file (e.g., /path/to/mask.png(1600x1296)) + + # Algorithm reset settings + resetalgo: 0 # 0: off; 1: on - send algo_reset command to device on startup diff --git a/config/odin_ros2.rviz b/config/odin_ros2.rviz index 2a8eb7a..48d42c3 100644 --- a/config/odin_ros2.rviz +++ b/config/odin_ros2.rviz @@ -385,7 +385,7 @@ Visualization Manager: Use Fixed Frame: true Use rainbow: true Value: false - Enabled: true + Enabled: false Name: dense_depth_demo - Class: rviz_default_plugins/TF Enabled: true @@ -460,9 +460,9 @@ Visualization Manager: Swap Stereo Eyes: false Value: false Focal Point: - X: 0.28456413745880127 - Y: 1.8771981000900269 - Z: 0.38664406538009644 + X: 0.2568470537662506 + Y: 2.1451337337493896 + Z: 0.3774382472038269 Focal Shape Fixed Size: false Focal Shape Size: 0.05000000074505806 Invert Z Axis: false @@ -483,16 +483,16 @@ Window Geometry: collapsed: false Image_undistort: collapsed: false - QMainWindow State: 000000ff00000000fd0000000400000000000001d40000039efc020000000cfb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003d0000028e000000c900fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261fb0000000a0049006d00610067006501000002d10000010a0000002800fffffffb0000002200640065006e00730065005f00640065007000740068005f0069006d0061006700650300000293000000dd000002d400000205fb0000001e0049006d006100670065005f0075006e0064006900730074006f00720074000000028f0000014c0000002800fffffffb0000002a0063006c006f007500640073006c0061006d005f0072006500700072006f006a006500630074006500640000000310000000cb0000002800ffffff000000010000010f0000039efc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a00560069006500770073010000003d0000039e000000a400fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e10000019700000003000004420000003efc0100000002fb0000000800540069006d00650100000000000004420000000000000000fb0000000800540069006d006501000000000000045000000000000000000000044b0000039e00000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 + QMainWindow State: 000000ff00000000fd0000000400000000000001d40000039efc020000000cfb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003d0000028e000000c900fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261fb0000000a0049006d00610067006501000002d10000010a0000002800fffffffb0000002200640065006e00730065005f00640065007000740068005f0069006d006100670065000000023e0000007a0000002800fffffffb0000001e0049006d006100670065005f0075006e0064006900730074006f00720074000000028f0000014c0000002800fffffffb0000002a0063006c006f007500640073006c0061006d005f0072006500700072006f006a006500630074006500640000000310000000cb0000002800ffffff000000010000010f0000039efc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a00560069006500770073010000003d0000039e000000a400fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e10000019700000003000004420000003efc0100000002fb0000000800540069006d00650100000000000004420000000000000000fb0000000800540069006d00650100000000000004500000000000000000000004910000039e00000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 Selection: collapsed: false Tool Properties: collapsed: false Views: collapsed: false - Width: 1850 - X: 70 - Y: 27 + Width: 1920 + X: 540 + Y: 124 cloudslam_reprojected: collapsed: false dense_depth_image: diff --git a/include/cloud_reprojection_ros_node.hpp b/include/cloud_reprojection_ros_node.hpp index 4408255..ef3c96b 100644 --- a/include/cloud_reprojection_ros_node.hpp +++ b/include/cloud_reprojection_ros_node.hpp @@ -23,6 +23,7 @@ limitations under the License. #include #include #include + #include #else #include #include @@ -32,6 +33,7 @@ limitations under the License. #include #include #include + #include #endif #include @@ -56,12 +58,14 @@ private: std::string cloud_slam_topic_; std::string odometry_topic_; + std::string wiwc_topic_; std::string reprojected_image_topic_; message_filters::Subscriber cloud_sub_; message_filters::Subscriber odom_sub_; + message_filters::Subscriber wiwc_sub_; - typedef message_filters::sync_policies::ExactTime MySyncPolicy; + typedef message_filters::sync_policies::ApproximateTime MySyncPolicy; typedef message_filters::Synchronizer Sync; std::shared_ptr sync_; @@ -71,7 +75,8 @@ private: void loadParameters(); void syncCallback(const PointCloud2::ConstSharedPtr& cloud_msg, - const Odometry::ConstSharedPtr& odom_msg); + const Odometry::ConstSharedPtr& odom_msg, + const Odometry::ConstSharedPtr& wiwc_msg); }; #else class CloudReprojectionRosNode @@ -84,12 +89,14 @@ private: std::string cloud_slam_topic_; std::string odometry_topic_; + std::string wiwc_topic_; std::string reprojected_image_topic_; message_filters::Subscriber cloud_sub_; message_filters::Subscriber odom_sub_; + message_filters::Subscriber wiwc_sub_; - typedef message_filters::sync_policies::ExactTime MySyncPolicy; + typedef message_filters::sync_policies::ApproximateTime MySyncPolicy; typedef message_filters::Synchronizer Sync; std::shared_ptr sync_; @@ -99,6 +106,7 @@ private: void loadParameters(); void syncCallback(const sensor_msgs::PointCloud2ConstPtr& cloud_msg, - const nav_msgs::OdometryConstPtr& odom_msg); + const nav_msgs::OdometryConstPtr& odom_msg, + const nav_msgs::OdometryConstPtr& wiwc_msg); }; #endif diff --git a/include/cloud_reprojector.hpp b/include/cloud_reprojector.hpp index e7ff884..77939fc 100644 --- a/include/cloud_reprojector.hpp +++ b/include/cloud_reprojector.hpp @@ -63,6 +63,13 @@ public: const CameraParams& getCameraParams() const { return camera_params_; } const ExtrinsicParams& getExtrinsicParams() const { return extrinsic_params_; } + // Update extrinsic parameters at runtime with real-time values from module + void updateExtrinsics(const Eigen::Matrix4d& Tcl, const Eigen::Matrix4d& Til) { + extrinsic_params_.Tcl = Tcl; + extrinsic_params_.Til = Til; + extrinsic_params_.Tic = calculateTic(Tcl, Til); + } + static Eigen::Matrix4d calculateTic(const Eigen::Matrix4d& Tcl, const Eigen::Matrix4d& Til); private: diff --git a/include/host_sdk_sample.h b/include/host_sdk_sample.h index 5909823..0fd079e 100644 --- a/include/host_sdk_sample.h +++ b/include/host_sdk_sample.h @@ -1019,12 +1019,25 @@ void publishRgb(capture_Image_List_t *stream) { for (int idx = 0; idx < 16; ++idx) { T_CL(idx / 4, idx % 4) = static_cast(odom_data->pose_cov[idx]); } + // Force last row to be [0, 0, 0, 1] for valid transformation matrix + T_CL(3, 0) = 0.0; T_CL(3, 1) = 0.0; T_CL(3, 2) = 0.0; T_CL(3, 3) = 1.0; // Build TIL matrix (4x4) from twist_cov Eigen::Matrix4d T_IL = Eigen::Matrix4d::Identity(); for (int idx = 0; idx < 16; ++idx) { T_IL(idx / 4, idx % 4) = static_cast(odom_data->twist_cov[idx]); } + // Force last row to be [0, 0, 0, 1] for valid transformation matrix + T_IL(3, 0) = 0.0; T_IL(3, 1) = 0.0; T_IL(3, 2) = 0.0; T_IL(3, 3) = 1.0; + + // Debug print to compare with cloud_reprojection values + // static int host_print_count = 0; + // if (host_print_count++) { + // std::cout << "=== host_sdk_sample T_CL from odom_data->pose_cov ===" << std::endl; + // std::cout << T_CL << std::endl; + // std::cout << "=== host_sdk_sample T_IL from odom_data->twist_cov ===" << std::endl; + // std::cout << T_IL << std::endl; + // } // Extract rotation and translation from T_CL Eigen::Matrix3d RCL = T_CL.block<3, 3>(0, 0); @@ -1033,7 +1046,20 @@ void publishRgb(capture_Image_List_t *stream) { // Extract rotation and translation from T_IL Eigen::Matrix3d RIL = T_IL.block<3, 3>(0, 0); Eigen::Vector3d TIL = T_IL.block<3, 1>(0, 3); - + + // Debug print extracted RCL and TCL + // static int rcl_print_count = 0; + // if (rcl_print_count++ ) { + // std::cout << "=== host_sdk_sample RCL (3x3 rotation from T_CL) ===" << std::endl; + // std::cout << RCL << std::endl; + // std::cout << "=== host_sdk_sample TCL (3x1 translation from T_CL) ===" << std::endl; + // std::cout << TCL.transpose() << std::endl; + // std::cout << "=== host_sdk_sample RIL (3x3 rotation from T_IL) ===" << std::endl; + // std::cout << RIL << std::endl; + // std::cout << "=== host_sdk_sample TIL (3x1 translation from T_IL) ===" << std::endl; + // std::cout << TIL.transpose() << std::endl; + // } + // Save RIL, TIL, RCL, TCL to YAML file static int save_count = 0; static int index_count = 0; @@ -1096,6 +1122,59 @@ void publishRgb(capture_Image_List_t *stream) { } + // Publish WIWC data (T_CL and T_IL extrinsics) as a separate topic + void publishWiwc(capture_Image_List_t* stream) { + uint32_t data_len = stream->imageList[0].length; + if (data_len != sizeof(ros_odom_convert_complete_t)) { + return; + } + + ros_odom_convert_complete_t* odom_data = (ros_odom_convert_complete_t*)stream->imageList[0].pAddr; + +#ifdef ROS2 + auto msg = nav_msgs::msg::Odometry(); + msg.header.stamp = make_aligned_stamp(odom_data->timestamp_ns, node_); + msg.header.frame_id = "odom"; +#else + nav_msgs::Odometry msg; + msg.header.stamp = make_aligned_stamp(odom_data->timestamp_ns); + msg.header.frame_id = "odom"; +#endif + + // Store T_CL in pose.covariance (first 16 elements) + // Force last row to be [0, 0, 0, 1] for valid transformation matrix + for (int i = 0; i < 16; ++i) { + msg.pose.covariance[i] = odom_data->pose_cov[i]; + } + msg.pose.covariance[12] = 0.0; + msg.pose.covariance[13] = 0.0; + msg.pose.covariance[14] = 0.0; + msg.pose.covariance[15] = 1.0; + // Fill remaining with zeros + for (int i = 16; i < 36; ++i) { + msg.pose.covariance[i] = 0.0; + } + + // Store T_IL in twist.covariance (first 16 elements) + // Force last row to be [0, 0, 0, 1] for valid transformation matrix + for (int i = 0; i < 16; ++i) { + msg.twist.covariance[i] = odom_data->twist_cov[i]; + } + msg.twist.covariance[12] = 0.0; + msg.twist.covariance[13] = 0.0; + msg.twist.covariance[14] = 0.0; + msg.twist.covariance[15] = 1.0; + // Fill remaining with zeros + for (int i = 16; i < 36; ++i) { + msg.twist.covariance[i] = 0.0; + } + +#ifdef ROS2 + wiwc_publisher_->publish(msg); +#else + wiwc_publisher_.publish(msg); +#endif + } void publishOdometry(capture_Image_List_t* stream, OdometryType odom_type, bool show_path, bool show_camerapose) { @@ -1161,6 +1240,7 @@ void publishRgb(capture_Image_List_t *stream) { msg.twist.twist.angular.y = static_cast(odom_data->angular_velocity[1]) / 1e6; msg.twist.twist.angular.z = static_cast(odom_data->angular_velocity[2]) / 1e6; + // Copy original covariance data for (int i = 0; i < 36; ++i) { msg.pose.covariance[i] = odom_data->pose_cov[i]; } @@ -1606,6 +1686,7 @@ private: compressed_rgb_pub_ = node_->create_publisher("odin1/image/compressed", qos_small); undistort_rgb_pub_ = node_->create_publisher("odin1/image/undistorted", qos_sensor); intensity_gray_pub_ = node_->create_publisher("odin1/image/intensity_gray", qos_sensor); + wiwc_publisher_ = node_->create_publisher("odin1/wiwc", qos_small); tf_broadcaster = std::make_unique(node_); #endif } @@ -1623,6 +1704,7 @@ private: compressed_rgb_pub_ = nh.advertise("odin1/image/compressed", 100); undistort_rgb_pub_ = nh.advertise("odin1/image/undistorted", 100); intensity_gray_pub_ = nh.advertise("odin1/image/intensity_gray", 100); + wiwc_publisher_ = nh.advertise("odin1/wiwc", 100); tf_broadcaster = std::make_unique(); } #endif @@ -1643,6 +1725,7 @@ private: rclcpp::Publisher::SharedPtr undistort_rgb_pub_; rclcpp::Publisher::SharedPtr intensity_gray_pub_; rclcpp::Publisher::SharedPtr pub_camera_pose_visual_; + rclcpp::Publisher::SharedPtr wiwc_publisher_; camera_pose_visualization cameraposevisual_; std::unique_ptr tf_broadcaster; #else @@ -1661,6 +1744,7 @@ private: ros::Publisher compressed_rgb_pub_; // New compressed image publisher ros::Publisher undistort_rgb_pub_; ros::Publisher intensity_gray_pub_; + ros::Publisher wiwc_publisher_; std::unique_ptr tf_broadcaster; #endif }; diff --git a/include/image_overlay_node.hpp b/include/image_overlay_node.hpp new file mode 100644 index 0000000..4501b57 --- /dev/null +++ b/include/image_overlay_node.hpp @@ -0,0 +1,91 @@ +/* +Copyright 2025 Manifold Tech Ltd.(www.manifoldtech.com.co) +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#pragma once + +#ifdef ROS2 + #include + #include + #include + #include +#else + #include + #include + #include + #include + #include + #include +#endif + +#include +#include +#include + +#ifdef ROS2 +class ImageOverlayNode : public rclcpp::Node +{ +public: + ImageOverlayNode(const rclcpp::NodeOptions& options = rclcpp::NodeOptions()); + +private: + using Image = sensor_msgs::msg::Image; + + std::string reprojected_topic_; + std::string camera_topic_; + std::string overlay_topic_; + double alpha_; // blend alpha for overlay + + rclcpp::Subscription::SharedPtr reproj_sub_; + rclcpp::Subscription::SharedPtr camera_sub_; + rclcpp::Publisher::SharedPtr overlay_pub_; + + // Cache latest images + cv::Mat latest_reproj_img_; + cv::Mat latest_camera_img_; + std_msgs::msg::Header latest_header_; + std::mutex mutex_; + + void reprojCallback(const Image::ConstSharedPtr& msg); + void cameraCallback(const Image::ConstSharedPtr& msg); + void publishOverlay(); +}; +#else +#include +class ImageOverlayNode +{ +public: + ImageOverlayNode(ros::NodeHandle& nh, ros::NodeHandle& pnh); + +private: + ros::NodeHandle nh_, pnh_; + + std::string reprojected_topic_; + std::string camera_topic_; + std::string overlay_topic_; + double alpha_; // blend alpha for overlay + + ros::Subscriber reproj_sub_; + ros::Subscriber camera_sub_; + ros::Publisher overlay_pub_; + + // Cache latest images + cv::Mat latest_reproj_img_; + cv::Mat latest_camera_img_; + std_msgs::Header latest_header_; + std::mutex mutex_; + + void reprojCallback(const sensor_msgs::ImageConstPtr& msg); + void cameraCallback(const sensor_msgs::ImageConstPtr& msg); + void publishOverlay(); +}; +#endif diff --git a/include/lidar_api.h b/include/lidar_api.h index 21268a0..ff9d985 100644 --- a/include/lidar_api.h +++ b/include/lidar_api.h @@ -244,6 +244,18 @@ int lidar_get_custom_parameter(device_handle device, const char* param_name, int */ int lidar_get_mapping_result(device_handle device, const char* dest_dir, const char* file_name); +/** + * @brief Set the image mask file for the device + * + * Read & send specified image mask file to device + * + * @param device Handle to the target device + * @param abs_path Absolute path to the image mask file (e.g., mask.png) + * @return int 0 on success, -1 on failure, -2 if file transfer in progress + */ + int lidar_set_image_mask(device_handle device, const char* abs_path); + + /** * @brief enable device log * @@ -266,6 +278,29 @@ int lidar_get_custom_parameter(device_handle device, const char* param_name, int */ int lidar_set_depth_parameter(device_handle device, const lidar_depth_para_t *params); +/** + * @brief Enable or disable IMU smooth sending feature + * + * When enabled, IMU data will be sent at precise intervals (default 400Hz) + * using a dedicated high-priority thread to reduce jitter and timing variance. + * When disabled, IMU data will be sent immediately upon reception. + * + * @param enable 1 to enable smooth sending, 0 to disable + * @return int 0 on success, -1 on failure + */ +int lidar_enable_imu_smooth_sending(int enable); + +/** + * @brief Set IMU smooth sending frequency + * + * Set the target frequency for IMU smooth sending. Only effective when + * smooth sending is enabled via lidar_enable_imu_smooth_sending(). + * + * @param frequency_hz Target frequency in Hz (1-1000 Hz, recommended 400 Hz) + * @return int 0 on success, -1 on failure + */ +int lidar_set_imu_smooth_frequency(uint32_t frequency_hz); + #ifdef __cplusplus } #endif diff --git a/include/yaml_parser.h b/include/yaml_parser.h index b5231eb..81a2b65 100644 --- a/include/yaml_parser.h +++ b/include/yaml_parser.h @@ -87,7 +87,7 @@ private: std::map register_keys_str_val_; std::map custom_parameters_; - std::unordered_set allowed_key_w_str_val = {"relocalization_map_abs_path", "mapping_result_dest_dir", "mapping_result_file_name"}; + std::unordered_set allowed_key_w_str_val = {"relocalization_map_abs_path", "mapping_result_dest_dir", "mapping_result_file_name", "image_mask_abs_path"}; }; } diff --git a/launch_ROS1/odin1_ros1.launch b/launch_ROS1/odin1_ros1.launch index e9790f2..8a0fd18 100644 --- a/launch_ROS1/odin1_ros1.launch +++ b/launch_ROS1/odin1_ros1.launch @@ -26,6 +26,11 @@ + + + + + diff --git a/launch_ROS2/odin1_ros2.launch.py b/launch_ROS2/odin1_ros2.launch.py index 060859c..6f51d6b 100644 --- a/launch_ROS2/odin1_ros2.launch.py +++ b/launch_ROS2/odin1_ros2.launch.py @@ -65,6 +65,18 @@ def generate_launch_description(): parameters=[reprojection_params] ) + # Image overlay node - overlays reprojected points on camera image + overlay_config_path = os.path.join(package_dir, 'config', 'control_command.yaml') + with open(overlay_config_path, 'r') as f: + overlay_params = yaml.safe_load(f) + image_overlay_node = Node( + package='odin_ros_driver', + executable='image_overlay_node', + name='image_overlay_node', + output='screen', + parameters=[overlay_params] + ) + # Create RViz2 node - loads specified configuration file rviz_node = Node( package='rviz2', @@ -81,6 +93,7 @@ def generate_launch_description(): ld.add_action(host_sdk_node) ld.add_action(pcd2depth_node) ld.add_action(cloud_reprojection_node) - # ld.add_action(rviz_node) # Add RViz node + ld.add_action(image_overlay_node) + ld.add_action(rviz_node) # Add RViz node return ld diff --git a/lib/liblydHostApi_amd.a b/lib/liblydHostApi_amd.a index 9a258881915ecf032afbec854957708da2204568..ff5ce2cedb09bb056c15bee0f72fe0c571ae6a6b 100644 GIT binary patch delta 75801 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 z⩔$aWc0%`>nae^PV*cPJiI6wsNZ^igq}gtktg0Qq=h$8;7ashtBNq^_Si07v@VW z-S?rBZq?Z8f)`pWzYLef68Si}~N?Q^cO ztaGKm?039goSNucbg+HfT2S{BjFHC=*`GMM;keDiNc@74Akz?b(0R)a_e0r1XE|Q{ z`+SOliGeMjI=lRb(0ckZNV2VHcIE@Ta@1PrBlzw9}K?zu=A|l!O!Y` zJM7$LclAT+N^f(>KH}VI-NUNBJK{{n1R40Xvl7SD)n4x#XQXv4zh6i1n?OW`(+F-n z>SS7d8Q*l&8DQN?_#*3e7b@LW;motGDbW46Gs6z}A?u@Iyge zUouSk&Y5bzsXU4J9zA)5RWAGmi?@krg9RL|Aoe%gYtizc92@(_+akePHxowxE!Z1#o_mO=C`x!tQY|H z8RwF<0PM5QLhA-td=~Sy9+aPTme?_fxOYD9 zw5mz^=Kq7*o`c!voo;n#2b8hU+QtThziXn3_f>dW`~lB}^% zz99=1jM z*29`Ot7Yj^^?a?H23~FMdCKvvY3?a=d>5K|_B(BtH23`K^A$I@o(bEJdxj$sUs>NZ z^K7QW-_Pp!kosBVwFqpl`=+n5ndkBN6*jiEU47ERR#^itkrKW5{z$|3aT8m5-4P;?I%k0I zc!E_>nmO6`xzBpLw0*AcS@()kYQ zAys(nPgNw8P?f}0Q?A-@mCw~Sw~DX8Zw%D+)bg}k!TLt1bJg0AHUl*@=IVCHq1Ij8 z%79{Q#XpB%3>Ikc-H5dx1 zH5|5JD?UqovUM|x9T%cgppwWBDl*-I3>M@kA&HcfvVn3oaD)wsgNWm(;<4h!BA;Zn^)tVYuxa*(gaM;J7AVsT?of*#qe zWAoq}2!DRdy>yeO#t@vDF;x?S`+Vld*A@Vv!rXC&@ zo^6I=BwM?<`WniK`S%daQDC)1=7vy7RVzrLsx2g?V09;CVk^GyY*dcL%z(kL3d#2H z*{;uHVGD@{S>N-l?+w!kAK=umg++Za@*JDv!xbLLBbvKt2!f-5|2ah58v&( z^W8oTf;4Q^%2Ujg_jO?|LNKR|KO+7yfm6Pxkv+|%tV^RY7?C?R+Efa`8=*h0*s6|*@6tD%yZpH`M$ zW=roXOMBVU!4Q_dVoS%^5`K-pE&3h~#qF@F4;9q98Oo{E0#B5%N&~AsR=psNS_2@3 zTK7T@w&F(>R7L;4_*TzyJOd%-b*v9}rqtTX`VO+buUOwP)_2m?XPt&j)E*yG$ZBbv zM`tPf9Fh~|OHj#$+Ii>lg?)CsE?NJH)RHS=J32OROnkVD4W!z$wG3dPjA z2ewe_UMQ#5BvzBlYG$*Vd8}s1JjlNd)vSR`l32^y{>R$(u(q#R+qbOkPu6zc)t2C$ z&p|VCEn6p*zL zg@4jZXBt@DDgW4alwh_NR=FU*s&bXUGX?)`kb~;t2P!hTMyJ=>_B1Fa@?%1}u8`gd zcR>_Z@%u!eyKnz`FlW>BdEllx`PNQt3W6{i&gHt2`*fw>k#b zK?RZ9DKZU(EoSV!5Y+>FHF-HZQUGbxT!?=;OFLbF9BjrvBXqwlbUzQpM1Dn(Wfr^v zOhil9>CHUaadGcw@!i5TbgcwP|aR2a6V4uE+sML$bBBbVzUijdiR7 zC>-XWfk!iEhxt3#v{$U5PrhO5cz>!j0!qgFJL5fDB~~ys%O3{qvi$9=sgRR}coCFj z`2+aDM#==NaIZK4!M;#QRTD^==nsT@-eDhpgDv@XA{?6NuWx%cL;hU+XuSUY{tRT# qxgUk`_LZswkduv75mZuj6mlkERll@yl7Eq7H*-Hzf(;M&oBTi1=Pwxm delta 54961 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 A!~g&Q diff --git a/lib/liblydHostApi_arm.a b/lib/liblydHostApi_arm.a index 981b1d48d4623409ccbebf4ceeb7b863a060cd89..67f027cc60af9d6602095ad269ea7e574e50b396 100644 GIT binary patch delta 110191 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 a1k8#D7(e`~{^>e;A8aPN4|b&Y!TtrFmj62d delta 91753 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

<_ZWO3wB(rm zZ57uG-v(}+=ZOrRIXhOZf5|hWIj`Riw?k{^#Hh<&@x(^woVD>5Yx|XjJM!Gq9#!z3 zoj&mmdbRmw*kFykXJ4a((EIxH$Fk z-{8}et*?0IsaFT>CCYves;|pcFZ|73r1PAwz7^-WsQK~t?Jg&>@a7x07w!0V;ht+l ze|RTGo&SMnVdSpT9ou)5TwD52C2IJ;p&Esm;b-Y4MXAe=+Gm?rA7_U9)Uglkuc^3U z`wW#eY#*3+(YWB2wHaT}g}Ay%y*~^)!RuLaA-WH6{(pY3#Wr8ey_9Lf(7YQK4g0|c2yxdkA<_BCF=_}edyfZ zGcVoeVms7U6`N3s$$IhT$w5d~v8(p6+_$pa6)YR))pjWQ{#d8UR!P5u-D?ZWzMExl zWgNbxHGZ@s*9z%*gf{XW$aO8bpHAeuo49?K;o*6{Z6%EC;@>^Y|$(0s6mKj9ibf@rVqKH`nuRDthwV<(maxQ~Qf zH;Qw(N9Z2f>)vsna9QsB_=(uSLE#OiC-txkH&6l!7T0sL^8p-6}cQP9mwVI8t~{T#~Ff- zdB+=jSu{>lTIh1-HW9gWyBWC*gnVXyySlN|6L(S^1ifw?oJIRJ83$FEUB*GRn)bQ9 zFckhobl@PGP}U)=ZJprMSq-d4cd(W>5ithzkV zyOC3|q^b*_t3LRXos00&P|jpA$mNU`k6d>L z-w>pStKyHmu{$$Pk?v>Z@Qpzcv*)}Vx$NGWa5JnLFrD8u~Qt|;%#0cOwn3FLBA zdGVf&ZouvATGdL%1gU$*6r+1Crjt@eH@IX$PAw;%$NX{K^QUOtw+U~gmtSzws}Q-= zy$Cs#PJZ?XPJW6FpV&L}fe!j86&Z*JkxSj-YXR<|3+B4lPBD9jhADc#5PjnAU6uLjX@74$dNP{;f|zLCor9qB7H5qZAvXC?wzVS!<_~0_A44~C@-lKBX|*J zjz=z4P84O4pCrM_PqN_?J&5^}{3Hs7Hs(wFn%xN{%P*cP`$Me?twnwghd6)n5F&> z6CLHqWtdbTH(^57@Oc#De6;s7|NQ>Pu;J>iBi>m{z4$?k45bLN`kP%27=vH;A z;IuxZA(x?&j+_c7KN*6PpG@S}QY#v9AUTav94b$W1J>^(8*qgq@t|Qlibeo`LDq?G&V$$f@PTeas)9=yIa9 z?wf@-(mhXb(kmai)V%;Xl}>)P2~K|ehEM2D3rUg4K)e{a)V+k+bKUnLm%8sqK1ufm zOpv;_qVAoTE_LrhPAw2hUBN3I*f=jzN^dO=FqjLC9k**44l;C~+` z>rVQSshIn`-z3+vsCCAH>gNu%IvX!@WIA}OMgOX*^eOX=c;9~#ezf)}H5Nrnf;@AgrK zWKjTRNMnw;bm`2V^Bm-INE9MBQsYIGR-g>Nou{u$_p^eyj_`wW?m;a#@8F9i%pupe z+ST`<@J9O9A(#3#h*HSDQTQRbngpj0&sz+itZ%C*fHHJ2M_k8FX3u#qayffV65w_>`~y$w0F z9LtA4+%&JWKdyU+t9zI5MtXG%PT!{MK`wRgMNXxYpFY9KPruBcG&u8YW2HeREB`=V7|kJs&x>oOCZ>{0UOU&_uO&2Ly4Ig>Wm@LCHwxM? zS+|ELcOaMhwG+?_KZQ%hGnP8jmhqihTI@u4^DSCNtl6S%j&-+aOY@l>-=gh7?#79F ze@A%S`UBL3a1LU!373h4TIP;#q#9#Qw6tNmjFxuf)L-PWgZbmp0^jJU2q5#U^XO6hOh0LDw zV&qcyQsk3#uf_x!?{%nq3#LomTaioM+n7JDd%LT9r|?EPb_q_)cQz+4H$9sYBMtW@%oWjwMT}OIoRW6mo6Pb&pRl+pkni*ZSW=n!q_N!QFnPW3p}! zPxc{~+b@5DzFoGe43l*y@l99-<9riVonSU$4GHE0nkHt)H(_naWwdl4H_L|Ll|;(OMLNeA3ut_PjshkxO|qkQ;f~Ew0=|qi+E#2qWKZ=QdUl=YHmp>sy$p z^(_|ONS6}iQpZwJ3fY$lKQzY$1&_w?-DmjZJywM%fHG7uM_k8hX3zOSPa3(m&`Gb=Z*{*o^qm$I^W zB$u(QT;kx@Ad=OLKY1epq$BCFAF~iAT`G`EeXB&#6rN|E=z?Pw8eJ6d7m< zZ(td?j*ZNo^Hw$UPu@7E{cC!q-qeLwT5Z16btBi!;k*~QT*0jc`U`$L7U-IO$p=Zu zP2U+C{hZD?FQo*z969?Im>H`I)2S24V>NOLX5ux>AMfYd1$xG65Z)?qMrlMYyR=D^ zLiR1f4|Qp);Em|N&G5-HR=X&GGITLVyi2>8J?H(*{!Gv!4fPmc_Gjv!K%#^ZOwhXX z4OsL-lT&lP0gGSgZot$JZwfbG#N3(AEcq5JAGsXW+mOr1C}VyC)Qxc7ztBWL4W`Qo zs6{R#;2`tIBcN`fj(|qtje4|6aO%+(0XBka>i>x z-8(Q{>fVW*T5jRdgJyyev>&O?PJRXjCqF}mPv}mI*oeqL zoPH5S>h4`+xrZ*8>mGw#>Yj*vlI}iCkhi4De z{Yv;{TlbKCT#lU7rxNxvKYIznxni;I;~L?O{*JO1x$NVEq7<@+AHsDHsulHdgW!#{ zTQPj{ZUTP$*FC5il%b6|;(gi9>^bjd_Gf}e+BCoq0FV1WX*U5s?&}^}Z@!!GE}7tb zHxaeO+|Ef_;@-~LnZoQUO&0e#7rBgwJmfMSikTn2rUjRnF%CZ)>>i{v6;*|tgd+|= zRO}vdZmn6O`~RTuHr}6tkM}2X85fPnsdVzwBslqjpG?-r#N0}I2Kd=!_aH~aJCN&U z^L~b(ZyvYj9Ddx{J*4dY$c^l5FA;&S<=h&dtaXpO2$QAksmQ6mrc{VG=8g}$^kgl2 zrtn5``2?peKn`*#doFS+o&0PToc!b&&SdwR3KxhBw3YB9m$DZ!doFtkaw&Tm@=3DS zV1ksr!Id5U^Z?VP?rq4a<)l0OzPNkHaPM$+?-JffFZcm*_n=ZJOyQ@--9zf$i=0X) zKYfCeANculeN5<1TZTcAf%q_Tsrv}C=ekEMbqkpErO0UHlXOqV1gU$@QZvouV>&5f z+{0hFA*YrT-^Tp$c=s>W@xDiRBfW}|OMOd3DP&(N{E)t7g450*X!zu<#6D2~WvF0| zxV}})p7Xk;W-HOORBt7mmZkcmflcjbtw#Z0(>svM9YrT{Ed#e7S*jWrgvIVWafPA^3+JH3qgca zWiV7Br_#w!wczBZ#_);3Mw8h=k%4#vayi%qKs3XE*%@F~QYcZ3)s| zF8VanH&X8yzypTkxnUs)1XO3F7-}BPNkC{`k`au-nwKMpiQCP0SGw z@D^9_HcX}NBca*_C!so!OTjylld$BcOK|ejZTRF5PJ2ZLT21-k4(kTA_v6@ojq-qRa@wGTO!PJa3Y zCqDy*Ps|M&Sn!a@Kzszb4Am3No`-7Ga#LfedkpePb3+Cu$hjeRxzW7<)1~g)kWOLaf;Ij&R3Qm6N44=FtHi`_iB(@-z zy0F+^Lrx0Xe8rk1i9Oj z@F&i&_x;UPPK^6AP7(Uf92}H~etj%TaO&k~Eb$8FVlP2B zSDgt1Q|-PQzco+V)C%{c%|YZ+<2q3+`DqZG{4@&xeN*sT^DQC+B)CT#%fPj4XZDqTne3pTne3xT>Ifdr>xLIAF2p9f1W@Br3?2Y zPzG`-bfzel{P+YXKRLobtSn}bZWbA6$$@_o?;bLk3z$6@x(K-xx)`|>x?%->|JW7U zl;u9xt}shZBdfqkS6i$CoVOsCg12hH1MR{a>D3`P>D7r`>fVK%x|{rT3r>D|44+tX zsxgrJL(lJ>sIRz`t*HL*Omi1G z_3H!SQQzjPTN-|(Bf~NSxeUvE#<^To$Yr!1Of%8igz0j6XhBZ#LUnIt{`L}tb6c8@ z)-Fty(bp|X$%`;qdj#*8YIrYlDxK{61Sk7`!_AV%qim36;CvW4HM+~do~5NN5*bL6Vx9rK z5HCS4yP{P1p#fheIQ>v%(D2EhW$wca)JK$|f;r-nS226e>yS%n8<87n;hRx(w4anf z)Ux`KOUZ|g29Mo&2N- zPJU7ipV-}%W9X)f48${$>t=J^eaxQoeB`n}wjrMs>ZO<m%7&=rL`M~BEjybHP1y_?x{-TRPB z-3O3Q(mmpAqnOk^{%oy#+(noyWlu#;4JX;tm^&_e`q?_%Gle&j%O^P9qRBxnWzR)U zrIVk{f|H*-!fVN& zT28vRGk;w74p;Xs;f?g_7M#Mg2f5U}7de$qe)Ugi10=#oe-Q|Rm6Sb^-qBfSb#=Ox5opfok1}{z4nEP+Z%&wB<&t&`n z<9_6({SyiMk;{p;irMopZ8d!IXGooEOq}*&Mj5Al$SG2&3jN4+gZC1I^S~NCD+~#5 z^z+-pf>V5rAeV7^0y&jVeyp{oNaEzjYxqQ*R!17cD3O79400K#@ywpbX)1E5dpdI6 zfRp}7L>?x{`N6-|=w6KJQuh+%)IyTDl=lS?iI+Xbn;Ur zIQgkId_s4+eyJ51h}R*Px;HR;u6rADse1=z^q-W0tl_`jWti8ppJFmh zKP6+j?57muq!f8fW&U_SrDf=T$`Ia2-%P?c37=lxWST=r8b@=4>P8WW`Mb*Os_rc2#hkyFb__crE_>)!6_-YLA1UR{FI zhPfNL)V&8el}>(o1t&j!hBMu9<2@iU(8hZRxzv4_*>m0F&-wE3O<|lifEmc7q?yR6 zQ6#C4`QVb~oTEc|v+zbz^NN+&;F!O2gA;Y@zq5k`v)v?EMJF6B>R_FVqVb$WxhDHoHq`nQlI zaNdkuZv66)>-KT`;&pmMxN{#SllVUTpr>5$JmmY4lPqLkAvoDruT#-0;A@x%FIm}lzgrp%c;T}{WFa;!6^vR zk;`DpKu)ETpG?8YkI(Rl>2Ugk%9OS za;f_;v*)@;;GJfvdo=P%x~E}+)IBHD#CtxbOWg~QQ_D&BZOk9n-JhxBy-0W?z4i!B zaaxRA>Ry7JN+&<1f|H*z! zPZAl3ry!TQr!sr4d+vGWt3TT?UF*+RA^&;qSAPmIS+|EL??EmXwW{;n#j6*SbtfGn zrQzI%oaChc%hQjXltq=KCtV*~OzVghgRfYC4nyQhTXqs?zaJ{Z> zLMJPRe;26BO?GkCfGlZOKPke;A-AfS8C)VpBZJlord27QSjzCV{h({rx z6k5U$g;0#(8F)`B-tftPK9YzTs9?&F#2oPuN@4b#=bo=c-IR~XvM&md%f2W^E(dn- ze4~B^rjuSIXccm*Ht}lakE>sEzE;0Zcq5e?kV};tMJZ(8B>a&2ErOS$`mKgf{#><9 z6hIj|m?N%o7qjQQAGwr$0J)K!ePr$R8O5aTF+QVvGNw!2Q;i-)#6~-Sb2SDqtIO-E6L}pV@O>#OxC+nCfsi7c=_= z{Us(!D8U4+djn*kBj_`)WCxZbm*b}P6!vvrX8$$t-GK?R!+Ws92QXcB_#kqU7F@Z< zkk6d8Ki=WPZik=1RPsh0Vr7|J#Hqu*$YsYyAg9vFPn6)~C))7IJC}Hofp#uQ$YqBo zGkf0QImo4q`Ha(zj6&vH2L~NR%s1zIn2)_=4Cmr3J%&n!HFa8$Piqq0M%c$UwXXxsg!-vfNFH)19T4cc(WiH1tI5szJ2Y1A;I1L&$Zr zI3LM!KX8f2Hp0m*N@BLVJf&l@?!I3#i8nL;BgXxV^UqC+vd!lvW!dI)lYPvNe{NEZ zT-LT7xg74D%>H&(j{)W%W|Q$_#Bld}%bOxL7*2zWtfG)pj}wnZE{AZ;1|4sS!dnln zWl4h5&`U-x<1Ga_l}>(A1t&jghEM!sMEa+686pF5A95LQIn18NTRw7Edv)Wz&dHyc zmSD0R;rlk2m9dHy$4759D~|IT=5H@a59eA}<%7Z-sZ%F7snZ}hEnJPrrTQ(%rTVRg zPhJ_@L`N(Cr6!5~JzT{_{;N-_| zI9u1erjsOF%G`yV0+Kv- zGk<)T^tihB32&rVzu+`X29QhL2a!|hOlU`-WrS3uG zR669B`zGT>7wBrQDq;S3ayfF{jz6<(9T%vf=e@CNxpJaHyH(Wms0&T1HhfFH z|5A9|MNcvNOqSftcn)$o2sR^k2Z37nviKLqWfz)|-;ZV_CwZ(Kc|*? z(S(*6II@!J?LS6e#ZkGwv8-W%n#U!<>-rgw99D)5jKXTPP!eoIy*o7}6ZeVg0~ zsn$IOS~i&~$UbjHF1vXExvm-?$R`-*4UM|^%bOTu_;v1t#51IxB11ZIseCTuJg7Hw zu4euO_VhftfG4w#EV|eo3!6$=dLv8Uk6i1*yR3@Y^XAlC>|VRJVDcoHnLECy^j_=^ zxxR~aU#ZA{3y)gQODo=Ns-(pzXSFLqE^8Outo!v=srF;`!gS=ErhAfJJ)*oO&P_cmnu)WkR+ z0KHq>{@rBd8DpKVmF0_KoKIhgjQ^V1r{$TYF`cFJX(Tt#EiWODr8lzt1$lb-2lkvI zIfz_FcLlTOvq=MTIgK;PhX4t*ypDj4_`oT+_fq$t^qqC7DN`5oGAllxabA4!rMkM)_p#(x z)Qx`*kNY;aYGuis_aK)mOD}TWD|}@+!Tj(!J1XCev89PxNjPMTB_VfvQ{CGuZu_L< z>ySznnW@XuB=?v?(gjbOVR!~|8B#vvGNf`0pO~WQf63&E3{*fqav4$u%wE5w8MhF* zRJjPbQ8~)gUO$)RtEAs~W1aoxyt9HiD4Q^|s*&r8@WrbJxo#=vwX8tyr!8Mq9ES2b z@^vr;deKbBU^^>rm~kFOF_#%5IW*Fc%XX(Dm(i7Dc<8&2%(gEx3KW_1&OOW(uXzb_ zsX!@msX!TWT{QPobD66^LJOwrro76U-g#N5;-T18-Iy#})Wh8J@iKUsY8>{)VQVh4 zE;lZ9c3ye}a@mR~hfA`QgL7 z>~b^A_hY)QuigaFQGwhYVJgt#oczCCsxQ~WyhdcEVO}eE5qdo+xHZ!x)FIa*@Euwc za<>v-O8#36pBUy;K&!|=1#}?St<;fE!?}~$bDn#JshC#(H|C}LJji%C|MR8jf{?#9 zZeGDew%1s;qyl#^reU&f<}EC_5V`ErJX(@8*v!q$ZSrGZST*#{p54cy89jxGk zm_Y_vBXV6)UT`~dS<#MD*!MI40WQ~Yf!WA-ziDbiEup$aAg7iPk3z01yq6%Hqra)c zF-CZ!aETY3q9sxA7St;VxeUh?mPkm zhhB7|)DMq%qXN~4WyjYbCyA-1wah*5_=Cu0SJg59T*(H*CqAE`K5S$e5};Iykrw1s zA+m21ob20$AAhuILgz{LP$f#}VF|pZeaPh)97e7?h6`<7rvy?Z~ANJ;+T2 zu)Su#34x`9!XYU#!ZPkvHx7lH|HC+h4f1X?hE#8APlVuPAB9|wy=Z37+ZoR|wsWCd zVh$$Akj~!*v$|8T%>;H4T2VhxtM&-D#EY3%-v1@YWwlF%e`fIsjfoegqYL60H{WEOb`c^P2qq)k zzeY}VC!Wq+a78n&(TZjYZ=`6B@=LHlBP6f0gm%6thpQL*) zCP>`}w;SD0V7k=Z@*Ab4?q1|l_Xxk%JqlCF8&x}6aFQiP@HW&p9=YtNWaLyU@}FY( zWZhFm1}Y!}xvnVhk4$FIc>!{%`!?j0bT7pOse8HK=w6NKq?Cn64RUHB@ml0k_k&t@ zwfj^2`BD<30nN!h3Es#!Z(kE~DR?__st)<@5FGq(vGmc!5_kdK$f-gW?p%ABy}ME& zAM%^er-D1cDIB`p<>saP+_)p;yC3eA?tqV>;_RLJzF;Wvg$VaknBD4;*F16d?gLxk z`Fizx^CqB?dV8uTF0|>sr~|+DMA=1ZrVVf3x*t9(bv)(+Q}t<;$Nh$nGh~^MRHJP7 zBh|NTv~ae$z}atj!fVDpp&P2G5B+}>ZZa?3=MmfWqkb5Uj#C_6clFkHsK^AbCu&A9 z%TjELR+}I}f7{6EMeuzBsp#|&0`*_NF{bJ*>8!!jGct^ddus~4+5~OV{#9fI7PQTB zZ~3Zq0L%x-Lzdh8-2mpX3Ej%Y=IYQ$R`*7Lyw9okt2}XP`R}|@>UUs2gZEgjZ9IRf z6P{;{4VwBbp9($ld}u5?&VF8Pfo__Y!i*vu^G27Jq5?YkIhGua$vRA4P)|(tEU{xk zFIL4(ryA?HdtLqhJD#|UI$6Fne67dzzcHSHuXS;+GoFdB^*H%Abv{Io{qJgQiYIQy z@0nGp5z(nOXS-cjMI8dM16|Cl7hmg2|AFy-d@TzfM6N4)GqaC|_xjM4;yebq4#f_~M@#+ESj>`|5RQEX#bLm>W!FU1V-HiJg=YERZZVml9E6RRDy$|7W z7SC1Aay`ksRWW{(nh8TU^yw2(p#_am>c^jZ;_W}Fu}Bd8k17xaryjL(8k~-pcQ>f* z@J{{sjIbDW$;z;3cS5kiA!a&Ly{N5wTr=?WKD?WECKOHrQo!jvJ!&D8Fz-(~8S6(u zp_9*4TUZ5hbOpBCIqGe5I)A!nyL+WjFx%t}q6?i>Pjf}cX@C$fMP4E7gUG7|FGpT0 zc*ShI3s@%-YB58j;El*z1aCo(*wPifEA;;0+0BP$c)WHXo)X~vAf)Ld49?#*FWu(` z#`QSWajK7}8ULC=?(+!a+P)5V$Ei5TwSV_zINnAp6$y1F%&m683#OV{`L;u6?{WU^0@Uy1C|kzV~FF%v?qZYp5aYUl^_V9G z?-Ejls`E_3S&VD@Ytg=Xx_P1PS6Yck;q()hpfgn2s^aW0pBjwuyrq5<>xorkb3Iek zZ{~VtsJC}cS)}q}J$E#}AL}{p(ZO?Pm};x@ELe>F4Q2@ z_xok=IEDQzygxMlQPaB6jW5PIpB zTfYBG?0@|g_B2cL+O~d${Xz84wf*B)*f*d(_kZLo>}gWx_PbAQKezo${C`(HvU|$e zPQ)&im*t5Kt$#Ub*3e7FE(JFi>(nFXhOKmZc7bqn%$H!vR6`O5EZ&$gJ~+<8t68!Ba+|d6nu=ni*)3}@%(I^bAhwo4prpFMyA|qaGR}8BzYDjTy~0r z2fnWoXLy%6d05y;rDYJ_-fpuH&5m1 zpN-kR@lJ5M(NTQJI2uh=nsGe|M1P>Ykw5{0aF$MYpR_MlCvA{=QIsUQ&i*YrMVZuD%(FMjuV|nx^ z1`rsp#W}}4Znu^1HMMw?RdfUj_UWF!)1=j!H1*5#!lv4gmhFi<9rvnT7*;wcPy3QK zO!KO?L!MYC;;vBA>&u*QugbH%anVXQ!Lq2O>q1X-#6`xz6r{Q1sJ5K2So_?Gp4sJ9 zK8Q>w?=BUc9k$H5#%m(A4;_v7l-j-_EY4{{^P;;{6pRn&31hxIrP`G1*M-BOYrO&< zQu(kj)d&Jit+-2D!O)wii4~@bA!$}Qy6Q0&dbIs6&WXc}J(#g$BI9h#=)d38fi`*& z?~rk2m}y|`-J#l7mO0DAO#2FOTR9=rjjzW!SAi=SiB8?!p`^}b9@r>_esa-Vr~B^l zxyQLR%FD*t!D3E)`+`1~0s}|R9CTJS)L_^JktH=h$hXw?9mCQf&3m#;`@rznkgJzU0d)d4_uO&tXfNZ@R|2I@hjK zKl`b7<-9tqScwS~_iLHDQ)<=wKlR3qcT^cB>w1~wg+GHYt)1Px_GezGUY+_uop)s< zIm>bGYl4tEQs<3U>zlk0v+}Xo`bNi@;QeehR;RP8xO(sVkbBA@R+VmMtjj7=TMn_R z^fC!easZOSmpbHqf4n{UD5Ne?TcxQ-e(qW||C|+7#N;+sW3E+mT!Rdh3O;`q&Gr3sPx(|jJv=7k`-Pn+(oOEPq22@32)JA zJ0yd%?>(WN6)DvS&WcQxEFX?Es#}kGyOBA|Wdl(+v`5YSmFw)ZUm0f?KIy#>eBS${ zH%?vC?v1efRY1S~&6D2f@hBK#UfgbMe*a0+u$fKXl_1yoO;BbYc2IS=soO-S-^i0| zFWOEdY8B0|J>%W(nb-IK>bf4dsH*J$-ecYj2?nXbpswJ*qSjqm zvzpRkOk3G>gNiLa$p)pa?CL5iB_#zZuC%&=X&y>;p|V7?m0wYVW=e&{u53_IQc+H= zCA-V6RHm2|zjNQcXXbFp`F!O0zTb1tIrn?degEdod&=8fwkZ%j2tw*U*X#s3Ti&SA zu~5AaQ_6tWedsJBaC{%uDg5;%EXFQ%q)AfMLi&D8yHW+}Q8bNWEffoy2Dz8fvXu7- zx>mK094b2=Zn z>~nRaE5{5%Kbqho{#7g3Y^$_U9ndxCuGZ ztlczE2+(ZW8uV`Sdu<9Lc7&L1Zm}i;$|EI zAM9zyEPe1Mu7!-7bmKtG-&_}431upkmN*%dq=;)AD3x|d#Z~yjVHB5|98*mw zekAPSO}e34H2LDN%b$>|HW``mG72@xh13?OYL>N#s)6;mmXNQEqt&q)8RtW5i|fcp zdKX)dqABBEH#GhOH|oUqYR!@F`G@Q0q3u#e!oXaDkp31HIQ6bk(d0f4Qd@Csh;G(e z=fN^TC#efo?HZi~)q*BDgN&8~-`a}X#11tWUUA5VAL=wU~S=UpfL@^`TjrC&cv_JcZE2?sgdq-gS42`2A2QmND91~5z@Y=_AG$nd$a}rwsRy5f7f5B$EpVPy86Y(@^DUv=7n+O~Mo@n#KkX zEO_fujm8b|$5_unIEq%dIQ=nBs1iv11lLO7wolkjHg~Mdi#%sQHPUeHC$30%{}Vh8 zC<`3_1do40sg#V94Z-Hsp1|^SF+ZUJ{rWM{ABzU3OcEk zk&Wc>19MJ>eom(-nlj9V$)90slG>-W&V?ML#li7st}9K9wdbEa)`WrG^}le4Lc zrtT&~%rVw_x<-2;6=~eW-F6I5IB0a6wHUYy{~VnV-KIIgUAUm>U5Xv7wbbk&r-Q7u zq)&W~wc&%rFEA5d;L0yt#byFsC^$KBV0UYw^|(09JC5b>zvFlmMTU_V4IG17nB0Yi zKkdR}KCj}$0LYLz$b~eU#Aq?Ox}Y3s+~Du%LQyC{r)E_Pd;W!aqyGOwUu4xYD2Y(@p`l3wy$|{`69zoZs0mxuZWF|)iO_}5}T4WLlF+E5}Dy{N0 z8uxcdo5_LOdR$=QLG+0)(K=6d+Ne@rW>G55koXm&w=0_Z(*fy%rr*QYFh*qc8KB^Ee0rgu)47VKjJz-zf9)6QeLkaQ$efdSfRO=--=Gzp zL}g7H7z2;NkTz>z(KoL0kQIMrxll3#VosqGy1$pdh+NRkkb24q)sI$Y3dEnr>Pk^( zdfg%!{7~8%kaHS+`4ru&(LN{_G>xfCT(ecJWv>njnz}=8!6wPd-~`gRlk)Vs7Ma-j zWoK|T57wU%`#5#ZJ9={1r$|2!TG1*YPn|#}52E`8O&QUfi$#BAMw7pFI)CC@;Y7MN zsx&7!3}+d=UD1@cAJPR)G3vF}ekev-915SsqbKUe1ob@%Il;|UA37m=lA=j?JVFz6 zo>E~tYc2cH%IR6GwWRy|uw*k}@^|Qj?hMFhRzk`o$obB-1FbyYGr{R~z~MyGzeguM zDwAWHlRPNqG=JBx%w!MJD8`%LJE4~K<5~)=?`K7q{j-5Xj2CavDxo=6!t^p;lBOB@ z1x@nPyLUrF{ODvGXVRl5?C?QHhl)UbYJ)`67W$-{%&J?<1GmqDra*m+R$UV`RX2Y} ztxz`>jv{Tw22PvyQ8S_W0@)jSks+mmhshD>rDM3H)q4xsPA}1gG_}s3D$Pg>+%gNA zTJx6`$`p%THl7%&>mIdQYrI(KLK(aeV`HXXxY)MwlwY0d^H=eS{`g>-ZLbP-cdoj$ zO_^i_`fVGpPvR{~9(2|LS9czFHv*4?W%#2)Ij18Y)zxq!DuN-`Vjj_NKm@< zgPhkwY7{0E3%5m~79=~pO@=y)rx$3I5UU0)_iCAfa3W*03MZGr@hE$?xF0MU*E(Q! zG$~SZwNNA;Alkmz#A6M?X9bQ#qky59^v;ZMW-;eG;-sF>#BogzhZdvM0m}s4p{i{J zqh)5*f+lh3bs7{S7FvXo^TL zk`S#`g$g=fweHed=Lh!0imJk$?*(W^B~fecA94v1h)TsX+MRT}p@#)0???PXR%nwrJ*xMmt*tlW6?Sp$K1 z^hs8(>jvgm3;k%7K=AnMl}j4sT8Q}(x}@nvk2xi}15yP|5!KU6ouet4&@w^iDv6@6 zAE(aF*i6H8(zeYtPX|pGA+eKpIPN{h3=&6)nj9v=W#wCf-GRQ$e zQ)_x^UwBMU@YeM3K0(XYiOJYcyh5FfsRUtBG7c@)yI4zuH<1hN)nn(%yvQ@2OI(6S zQ$A?D1dV-g{1P;#0*(FUKx1EE@}+jp1!h{He46bst(PuzZbX8YrrTaK4qB(%sb&wv zT!V{bNEeHIC>M(cXcdcQh`AOQUPu>}%0Q%yo#SK)P5YLAh8I zLaSKRK+H^Bpl-N;^Jk)`tut+()xJ1%KL?zeiG9OwRc8sGNsuuMeU?Evu8Qo$A{Jt< zx93@xU9ma%^-rzf*g)0w_VSr086>{j!6 zsM=_+HeU#M|71s*=1VZ)VY}FT5w<^!!o3K|<+!Ma-R1TMG%ZhQHV`FtWzpWWMI80&moy{j1=A0)=`Vf=^&yo1v{0o2`7(E;XB= z_emV}LxGB?>|)D2EIgK*|A3lj(Ersq@4n)de+_y>wjX#2Y$ZWzR5H{a4O>Y=j?U(V+`Rl zaN}R?Dwnk|A<+H2J(_@l7PgApTkJ!q8N zjN8R6{=1CJznN$4#C=nRzy;QeZJx0FXOay6-o!{_`R)sh%)|&N#P*X$~cplcZKiN+M%01#T%m!)!RQA^5NaaRL4;g z^wrycHOIlTFWRGqmJBsAU&J^ymVa+9y!)cPXXXQ zF(T)E;r{)eesK|F#JBS!Hl2DZ0^N_qbY(Zbmf?1x9ekN=PK3Mm+N0sE3(Ux2_KK35 z@yq0j`G&D6Xr#W6JxL1Kanb&a-YdSDciqmLEdzh^60pY%kK6UBQsC4o|CwO5|IAHL z9I$8nC~jBp4r6ci5aW`{A-H_a=>2y6kexy*(Z!DgxIrj^*$sAT)TdYY_kMQaEL3fQAMdlL*+(to%jaP6K06`GJ78C~mNE`z{xeUn2Je15TdjS5KNRh^=iw6@JNDa!7~-Z^>;!Awy|CmJdyO^mZv5q* zz0_KGALJgeFTJVJH0mo8jCvYxV`A?WVo*gdsqSzvhXofKdxO*bX9RxuyZ(4F3P#Bt zy}6dLfh+T0IC=mlZwX`^v@bGG!K#DySeQD@90u2>M~oO-ii3@Z_M6bnriu5J-25BE ze};;n5sTnaIC{{|!`#yv?Mt(RV|uSRJ%8rT5)6nf@c!kJVV`0m2DZX~dyR3DKeKq& z&a*48-+9kD?1JC-UnwTjDXdVej9uSgmBNipcGg7;mzUhUh~*#(Q52tuN?zxF2mU7e zH@7Urf+gFJ`}^Zht#xf`G)rz49)&Eg-YEJd>t5DdoTxX4tHJ3cG8T2QWR#If1APCh z_Bc<1k=gjq{wv}8SM1!ME?hfU6$7LFVE_LDQ(v?1veqqg_9<3dpHr4ozKHPd;!2CG zuYYi0mA))WTIuPpg6Xf@cUTiwie27Cu8n>D@o>d!cCIxsUm#;fEJox96+Hh?epr>W z--G{~>9#ljFZF^*@tZq4A{pVtrVhj4Gd z7JP5u#=aEl-@qJ8HYvp}T)1j*o278eo4EJd6nOVdd!E}`_uD|qTlV>;b!ZXzTkVIf z>lcV!#y!@dgASGeTH!|vdQd1Jj#WS zLX2`D*%<9bpyK?K5q%dKTZWfdxK?{%hly*w@h)6B>2=}%+ec!H?osUmZySUEZ%cIG zByo5D$#LBl;wLY%MT0GY`@gk6y}%p|InnO;3o94HlAk~R+sA%)UDcv(d1+gJ|L9U{ z4Qz;ZUp74|Vy5-p`yYJxQRnQABQs!0<>JSF_xNwO z_urcl#;jZ6>uC4n@uJNP!QUZi?!&>YqQKmtZrnZA1^$`f-eH@g0~-?E)uwfE+#~nL zS+_cWOP#-4#osB<;2l2Wj6|$^`RP>4p*R)BId|4eU=sFQeAdJZKRcYiEzaMMoxjJO zzh63kul5R?V)1w6pYax*Va8A+xKXx0hFXfx-yNIJoWI|Cp=UeZlI=+lEk-1WJNnhv zaA^5+$KEjRNPyfe_>{|9VP(B7{%&5nCNgmQc=rWy=lNDFymP_IWxrn-$iK?{Mug=x zpbal-!{OUJQGq+IaZj=mE?17SEcqXC{vSCB*Jd5+eL43r|IiGLq{H79*tfrQ{cf@}p1qT|ZyUtVo6q?Iu>-+RIDXVZcWSuro$Q7+>3{wro_{{p z{=oKU^W3+E+o!O5o@D#Qi+Ou~%ar6Je$RQjVJV#7wx#YP?oj`yj@9FDxZ92QrjS0n z2k~Fu<6ac5hDqbJ_HxyjI}Y-9xZ(nj6uMKw-fDI0z(@DGW2{hZm5%>mZx!QZB^0?! zY^;Q*9(3mnp$ub_ok%cljk^K4kJh+zM6s-OAHl`&Qn40TS?WF>j*@-p4@W7wROP&$ z=iIGZ!$)QAoRC0iKh~VVEf2YOgy%iHK ze6-TUg(duiyanbz%&Q@&^KiD@(dpd^N2kj+x$(08<$+rs;Wh4OU!|%V+rqte4dS;w zidlt5m4CzOw3kU5bt$rsL9+F_hy7DtZ@7BPjJ3=5dZR%JbvdDy8jKm+ZD#M?3pAHMVWttXBt{OGdAmbUFeAhkaE(}k;x$IjUIgIcA6(?Uv z82$x}aeO=TMUZbkARJ@3BQ!sH`fbhgZMUPN;-=>kq)W(KgBLf&gvVqRKJ*^qGiK`i+WmY|Z(-Nvd6Cs$55X~ZT;R!r?%Z%RdgW6{Ss3-Iv)x$z zs+0S(ucFSO*z{7MkaghY*WGvz%H{BS6WbCMrO6?^?vT4p$nb`v%DgxDkmj?C;Znq? zX3o2A(7XBa-!K()_rhTos&I}R;VCWdWKml4TAj2vw4$V;dDn5H=1Z;`(djbJ6>q!! zp+5T4HRHhHw{b&-zAt-M_=frKx_4lOMz!-0X*X%DRETW6rinLp1-^dIT^`oa5SL)^ z6V`Ft5sVSap=uC6>H}wk1k*lrwoltW@M9nFzP6;{<2?b&H`tH?nGB8So3WfuY&d5<^&7e{5jvqWn^jAfo)&#O=g?UD{tLd z(%ZN$w^xkKw0}9{zW85UMta(BSmyuyn@_dE+x6ftbn`7-^gNxP^FOZZcAZzrwak;r zSv|a~$=QRveaW+>=T?TZJ^U4qmiue1y^2=wYiPvRtOeGbbf>sNB}5M~W8QkXunTg3 z*jrhy8m4b~?#FcNz_zoz0xRy+yancb$M?sPcj^2K-(yjQiYBP@(%dlSJK4PWyoVh; zWzW~0oi#n|P&RUb&VLl)VP`p82JtIx58KLREY#bt^?2A8x^ECa=R8k!cniH?k={Nc znzwi5>HOiLp3^R@;@5|H!pC#xO%pO>;yb>O#+|@bI?hYd&CGf+x|6UJf-s zw&Sb`%Qv@ejl03OTw00e5-_aA+=uuahG#STH4HCX?mSt{s#%VY4#V?Mwc03G zo7HO2SsmKLoj_|4pD+6F?a|ig6_9@fPhzL85UE+SR%}jsF5X1&Lj;$|<;eUMGOC`~ zmKDzP!0xJ2yy#FaOR(k~?e;VKGG^a&4!i^Nz@v4mX9cAEpDS((JsV1VDIdeyyH?5- zF}pY(xe{VuaN$G!6n`c1YJcK1@G6}Ab*ZzS(Fzy+=JrWi9I~IF`JoqoBuiXAy;mfb zq)uWdX^yCYPsf%0bQXXgMfjOL$1@c!2IiH}BS$cSB`c+(MJuJE8<}ISTm^H?@hwWx zO2zAnR%!l7p&AV@lmljL*YHO5^PO6S>myJvaru};kr)MNPz|UAD8POVrvS|g7emjL zYhm^rKc;Y@=-tNV?CnFWUepq2%aq6h*%_)L)ionp;gk~LvkK(&%`R}J?*g@2Bv-e{ zMNPrx;PyDHu0T%HrUGZ0winQ)x?9fsS#mig zQ`w33O_Vk+bI;Mf5Zj4)T5`8jRaV8_a^7uG_Ij06Dx4IfL9Ehnnie%0UNb}{wO!$Q zmDEaH&O1JeyHx`k5(-?W;S{)D!zpkB!@2)Xg$v>48c?*uHN-lmL^-KM=~XtmD18do zMWMHK5Kg(d?vWx8-ljx}RJblmw8RIC5~~{MqKwdR3hdQz3Ot(OTok{;xhQG($V$n& zM^;LzAwr6^O{6-S+>8Q8&m@s08^C1RK2brHKYf0Xk{4X583^(tH!%e87?#nE6yN<6$# zrU22Z0f|TfMrb%W^0EM2tR!a7ai7Auh#9Noo-LR8;$kgezBrz@N><_$#p@#GYyK$b z0u86W7ixH~+OriYTo<=g;$aafK$&VlB2s{j8cqSK6fUZVi?yBEbG%XEVG*NDrD2e{ z;#wVJt~lPMH0)Nqu3?YnkGgnL!)fQ;tKoTS6W6D3T|<{_I9S6-<&iX`0MQyw0lW&= zH5|?CxrWIK7aBfe+(Hu;?}KN=!7yyhQn=^=KjhD3_WTGr8zL_8jKB6F=Aw+5zQXW| zbGY7J=PtMMifJT+noG56 z9Mf>0`u?Cx;rdASD4bFt|0gwEtf=BN?f15n#Yb-YXAfeD})DNE&O; zOMNbD&+&|V}!vNfD$d9H@1s41{O;ks~3BtCcw` zDV^&5D}VHADdHr>=^~~moN^+a zrmmJE`V_BkKBjB_NJPJeQy*t(c-cr9iJriyi*aKXUi_MY4(J7FniQtym7heawluR1?p4%jlLgh@P{iuyI||G?&!1sTy7~N;>r^T$gT^!YKukE=|Lg|2f87 zji3No3fF5Wo7r=TO7E8?vE_bQ65Cn(0YlH)b9}edsJKq?`s8cS{87jDYd8tlsBm4N zCWY$)HA_4^`N&a=7Jwf4*seJuyp!2;fr8AQBZt2|d0JC7g5wrvX5N4`@FLwW`^ob)-S;pD$Z;o8g? zX3*30#Yj4*Z!qm@{2pjRv6NwIv6Nv}vFsp?D|I(b;WU1P&n=cm1sRIhWysY0QNOY@ zoR0akH9V*el5-WV>y{_+@XVk9OH>0&m;%sqj0vXzMJzBcpc3YX<5dc0GsD`gM66@J z2GkPs#qlO3Vzbtc`qH9sUEDU!p8D9%aGrCg!gUdY5+5w$G1Y*?q5xeC=K)SCoT`VO zuiwk;MaKy@N@N|0gy!%sgS;iOEGLvWWjS(^GNeRgGrWjVBFZnmSkbybeuYy$HR>Q| zmcq#$37w|lWItEox^Ni^zg?SdMkaH_1Hi&k)d!QTm!>16)rl=@dXMOabJf$evjk+h7tz9$=sAOyqV$K8O|@fH9iQzm+`?Q z4?6ccS))alSLOh?%uO>kQ9$t7?t7ZzR50 zF``dPnS(ag;vWp}V)$DOKgsYGhR3dzD?&?t*&#*YKhlY*iVz9Sfn~i`{8BM@{G+9x zxr(M5B0QTnWATd=PQ~7+{FG>Z2(Mf#)Ggk94tI^3JO7VltR~GJ;T;MW`Bpj*SqzLy2y6815Bj{8)l3u)LWNU&@>3-7@F5~OD$xS; zsEJXgIU>A**>kbBFnf;IDV&Sgs6=dIzGB#9ZD+nX-l0V7RJ<@>>^VMF;atR7f0UJ&$$W9KvY0Q9 zXa7-FVy@zK5%V;EB;pbcClT`%u8UZpaOykxDU|qN5sS0{B}&9n%@N@nnLQV)g4uJt zR^eR4CM9A!^ToyLWWG3lOo`Z~cwNLE%^!9Cq=u7-y$aVw>{GZdqOrj#tid9>B;h8SqnpW%LZBPZHm_iszdWf1J$YFG*Cf>>jQO6;iND5 z>5};1f$G)*RI1~JlbR#K`7h%&*3NOhy2*+XwpV;5hfvx@oKZ_M9YSkZ}yBAmkDktJ%>r{Iq?1Gz`Hlf z1EJoHkT0I}{U_Ni(ZeU?f1STm|K!}RTfCp~JhKjl|BbclQ8*m~R3=HXSK(9(gc}b_ zUc~1I*Vz&;9(4Xw$Qtm#6$+=owJLC>!YMG}HOvnW+{f^T_$jEjJe(;HoT6|F+@J#c z6i$H&_cK2{a23NJlA-XGy!fB(<!vT^rBgui_m3wkTY8SI6*>RM_Q) zO`BsMbKWN(`1V#$>=1l(RMedwe5_kw+MOOa&uZF4uaZlOYCJ79s!1^6v1#_@)|N*? zk1P|fzqBeJao*Plx8qZ3a7Db^4!&CK@!~VjqLz44Bbp!4-gvoU36i<60ZDuy+F`M% zg{a@-!V7c6q7ydY!m4?3b5fIdtXkAkT odin_ros_driver 0.0.1 - ROS2 driver for Odin sensor + ROS driver for Odin sensor rlk Apache 2.0 - - ament_cmake - - rclcpp - + + + catkin + + + roscpp std_msgs sensor_msgs nav_msgs - geometry_msgs cv_bridge image_transport - pcl_conversions - message_filters - tf2 - tf2_ros - tf2_geometry_msgs - - - ament_cmake - - \ No newline at end of file + + + eigen + opencv + yaml-cpp + + + + catkin + + diff --git a/src/cloud_reprojection_ros.cpp b/src/cloud_reprojection_ros.cpp index 9207c53..f928467 100644 --- a/src/cloud_reprojection_ros.cpp +++ b/src/cloud_reprojection_ros.cpp @@ -63,14 +63,16 @@ CloudReprojectionRosNode::CloudReprojectionRosNode(const rclcpp::NodeOptions& op RCLCPP_INFO_STREAM(this->get_logger(), "\n cloud_slam_topic: " << cloud_slam_topic_ << "\n odometry_topic: " << odometry_topic_ + << "\n wiwc_topic: " << wiwc_topic_ << "\n reprojected_image_topic: " << reprojected_image_topic_); cloud_sub_.subscribe(this, cloud_slam_topic_); odom_sub_.subscribe(this, odometry_topic_); + wiwc_sub_.subscribe(this, wiwc_topic_); - sync_ = std::make_shared(MySyncPolicy(10), cloud_sub_, odom_sub_); + sync_ = std::make_shared(MySyncPolicy(10), cloud_sub_, odom_sub_, wiwc_sub_); sync_->registerCallback(std::bind(&CloudReprojectionRosNode::syncCallback, this, - std::placeholders::_1, std::placeholders::_2)); + std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); reprojected_image_pub_ = image_transport::create_publisher(this, reprojected_image_topic_); @@ -82,10 +84,12 @@ void CloudReprojectionRosNode::loadParameters() // Declare and get parameters this->declare_parameter("cloud_slam_topic", "/odin1/cloud_slam"); this->declare_parameter("odometry_topic", "/odin1/odometry"); + this->declare_parameter("wiwc_topic", "/odin1/wiwc"); this->declare_parameter("reprojected_image_topic", "/odin1/reprojected_image"); cloud_slam_topic_ = this->get_parameter("cloud_slam_topic").as_string(); odometry_topic_ = this->get_parameter("odometry_topic").as_string(); + wiwc_topic_ = this->get_parameter("wiwc_topic").as_string(); reprojected_image_topic_ = this->get_parameter("reprojected_image_topic").as_string(); // Load camera parameters from calib.yaml file directly @@ -167,8 +171,13 @@ void CloudReprojectionRosNode::loadParameters() void CloudReprojectionRosNode::syncCallback( const PointCloud2::ConstSharedPtr& cloud_msg, - const Odometry::ConstSharedPtr& odom_msg) + const Odometry::ConstSharedPtr& odom_msg, + const Odometry::ConstSharedPtr& wiwc_msg) { + // Debug: print that syncCallback is called + static int sync_count = 0; + // RCLCPP_INFO(this->get_logger(), "=== syncCallback called, count: %d ===", ++sync_count); + pcl::PointCloud cloud_odom; pcl::fromROSMsg(*cloud_msg, cloud_odom); @@ -178,6 +187,45 @@ void CloudReprojectionRosNode::syncCallback( return; } + // Extract real-time extrinsics from WIWC message covariance fields + // pose.covariance contains T_CL (first 16 values), twist.covariance contains T_IL (first 16 values) + Eigen::Matrix4d T_CL = Eigen::Matrix4d::Identity(); + Eigen::Matrix4d T_IL = Eigen::Matrix4d::Identity(); + for (int i = 0; i < 16; ++i) { + T_CL(i / 4, i % 4) = wiwc_msg->pose.covariance[i]; + T_IL(i / 4, i % 4) = wiwc_msg->twist.covariance[i]; + } + + // Update extrinsics if valid (not identity matrix) + bool T_CL_valid = (T_CL - Eigen::Matrix4d::Identity()).norm() > 1e-6; + bool T_IL_valid = (T_IL - Eigen::Matrix4d::Identity()).norm() > 1e-6; + + // // Debug print to compare with host_sdk_sample values + // static int print_count = 0; + // if (print_count++) { + // // Extract rotation (3x3) and translation (3x1) from T_CL + // Eigen::Matrix3d RCL = T_CL.block<3,3>(0,0); + // Eigen::Vector3d TCL = T_CL.block<3,1>(0,3); + // RCLCPP_INFO_STREAM(this->get_logger(), "=== cloud_reprojection RCL (3x3 rotation from T_CL) ===\n" << RCL); + // RCLCPP_INFO_STREAM(this->get_logger(), "=== cloud_reprojection TCL (3x1 translation from T_CL) ===\n" << TCL.transpose()); + + // // Extract rotation (3x3) and translation (3x1) from T_IL + // Eigen::Matrix3d RIL = T_IL.block<3,3>(0,0); + // Eigen::Vector3d TIL = T_IL.block<3,1>(0,3); + // RCLCPP_INFO_STREAM(this->get_logger(), "=== cloud_reprojection RIL (3x3 rotation from T_IL) ===\n" << RIL); + // RCLCPP_INFO_STREAM(this->get_logger(), "=== cloud_reprojection TIL (3x1 translation from T_IL) ===\n" << TIL.transpose()); + + // RCLCPP_INFO(this->get_logger(), "T_CL_valid: %d, T_IL_valid: %d", T_CL_valid, T_IL_valid); + // if (T_CL_valid && T_IL_valid) { + // Eigen::Matrix4d Tic = CloudReprojector::calculateTic(T_CL, T_IL); + // RCLCPP_INFO_STREAM(this->get_logger(), "=== cloud_reprojection calculated Tic ===\n" << Tic); + // } + // } + + if (T_CL_valid && T_IL_valid) { + reprojector_->updateExtrinsics(T_CL, T_IL); + } + CloudReprojector::OdomPose odom_pose; odom_pose.orientation = Eigen::Quaterniond( odom_msg->pose.pose.orientation.w, @@ -276,13 +324,15 @@ CloudReprojectionRosNode::CloudReprojectionRosNode(ros::NodeHandle& nh, ros::Nod ROS_INFO_STREAM("\n cloud_slam_topic: " << cloud_slam_topic_ << "\n odometry_topic: " << odometry_topic_ + << "\n wiwc_topic: " << wiwc_topic_ << "\n reprojected_image_topic: " << reprojected_image_topic_); cloud_sub_.subscribe(nh_, cloud_slam_topic_, 1); odom_sub_.subscribe(nh_, odometry_topic_, 1); + wiwc_sub_.subscribe(nh_, wiwc_topic_, 1); - sync_ = std::make_shared(MySyncPolicy(10), cloud_sub_, odom_sub_); - sync_->registerCallback(boost::bind(&CloudReprojectionRosNode::syncCallback, this, _1, _2)); + sync_ = std::make_shared(MySyncPolicy(10), cloud_sub_, odom_sub_, wiwc_sub_); + sync_->registerCallback(boost::bind(&CloudReprojectionRosNode::syncCallback, this, _1, _2, _3)); reprojected_image_pub_ = nh_.advertise(reprojected_image_topic_, 1); @@ -293,6 +343,7 @@ void CloudReprojectionRosNode::loadParameters() { pnh_.param("cloud_slam_topic", cloud_slam_topic_, std::string("/odin1/cloud_slam")); pnh_.param("odometry_topic", odometry_topic_, std::string("/odin1/odometry")); + pnh_.param("wiwc_topic", wiwc_topic_, std::string("/odin1/wiwc")); pnh_.param("reprojected_image_topic", reprojected_image_topic_, std::string("/odin1/reprojected_image")); // Load camera parameters @@ -349,7 +400,8 @@ void CloudReprojectionRosNode::loadParameters() void CloudReprojectionRosNode::syncCallback( const sensor_msgs::PointCloud2ConstPtr& cloud_msg, - const nav_msgs::OdometryConstPtr& odom_msg) + const nav_msgs::OdometryConstPtr& odom_msg, + const nav_msgs::OdometryConstPtr& wiwc_msg) { pcl::PointCloud cloud_odom; pcl::fromROSMsg(*cloud_msg, cloud_odom); @@ -360,6 +412,22 @@ void CloudReprojectionRosNode::syncCallback( return; } + // Extract real-time extrinsics from WIWC message covariance fields + // pose.covariance contains T_CL (first 16 values), twist.covariance contains T_IL (first 16 values) + Eigen::Matrix4d T_CL = Eigen::Matrix4d::Identity(); + Eigen::Matrix4d T_IL = Eigen::Matrix4d::Identity(); + for (int i = 0; i < 16; ++i) { + T_CL(i / 4, i % 4) = wiwc_msg->pose.covariance[i]; + T_IL(i / 4, i % 4) = wiwc_msg->twist.covariance[i]; + } + + // Update extrinsics if valid (not identity matrix) + bool T_CL_valid = (T_CL - Eigen::Matrix4d::Identity()).norm() > 1e-6; + bool T_IL_valid = (T_IL - Eigen::Matrix4d::Identity()).norm() > 1e-6; + if (T_CL_valid && T_IL_valid) { + reprojector_->updateExtrinsics(T_CL, T_IL); + } + CloudReprojector::OdomPose odom_pose; odom_pose.orientation = Eigen::Quaterniond( odom_msg->pose.pose.orientation.w, diff --git a/src/cloud_reprojector.cpp b/src/cloud_reprojector.cpp index 7ede028..f45d0d3 100644 --- a/src/cloud_reprojector.cpp +++ b/src/cloud_reprojector.cpp @@ -3,7 +3,7 @@ Copyright 2025 Manifold Tech Ltd.(www.manifoldtech.com.co) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 +http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -90,16 +90,31 @@ cv::Mat CloudReprojector::projectCloudToImage(const pcl::PointCloudfx(); + const double fy = camera_model_->fy(); + const double cx = camera_model_->cx(); + const double cy = camera_model_->cy(); + for (const auto& pt : cloud_in_cam) { if (pt.z <= 0.01) continue; - Eigen::Vector3d pt_cam(pt.x, pt.y, pt.z); - Eigen::Vector2d uv = camera_model_->world2cam(pt_cam); - - int u_int = static_cast(std::round(uv[0])); - int v_int = static_cast(std::round(uv[1])); + int u_int, v_int; + if (0) + { + // Pinhole projection (undistorted image) + u_int = static_cast(std::round(fx * pt.x / pt.z + cx)); + v_int = static_cast(std::round(fy * pt.y / pt.z + cy)); + } + else + { + // Distorted projection (original image) + Eigen::Vector3d pt_cam(pt.x, pt.y, pt.z); + Eigen::Vector2d uv = camera_model_->world2cam(pt_cam); + u_int = static_cast(std::round(uv[0])); + v_int = static_cast(std::round(uv[1])); + } if (u_int >= 0 && u_int < camera_params_.image_width && v_int >= 0 && v_int < camera_params_.image_height) @@ -110,4 +125,4 @@ cv::Mat CloudReprojector::projectCloudToImage(const pcl::PointCloud #include #include +#include #include #include +#include +#include #include #include #include @@ -46,7 +49,7 @@ limitations under the License. #include #include #endif -#define ros_driver_version "0.9.0" +#define ros_driver_version "0.10.0" #define required_firmware_version_major 0 #define required_firmware_version_minor 10 #define required_firmware_version_patch 0 @@ -85,13 +88,21 @@ static std::shared_ptr g_renderer = nullptr; std::string calib_file_ = ""; static std::shared_ptr g_parser = nullptr; -static constexpr size_t PTP_SMOOTH_WINDOW_SIZE = 30; +static constexpr size_t PTP_SMOOTH_WINDOW_SIZE = 300; static std::mutex g_ptp_mutex; static std::deque g_ptp_delay_buf; static std::deque g_ptp_offset_buf; static std::atomic g_ptp_delay_smooth{0.0}; static std::atomic g_ptp_offset_smooth{0.0}; +// IMU dedicated processing thread +static std::atomic g_imu_thread_running(false); +static std::thread g_imu_thread; +static std::queue g_imu_queue; +static std::mutex g_imu_queue_mutex; +static std::condition_variable g_imu_queue_cv; +static const size_t IMU_QUEUE_MAX_SIZE = 200; + double get_ptp_smoothed_delay() { return g_ptp_delay_smooth.load(std::memory_order_relaxed); } @@ -109,6 +120,10 @@ int g_sendimu = 1; int g_senddtof = 1; int g_sendodom = 1; int g_send_odom_baselink_tf = 0; + +// SDK IMU smooth sending configuration +int g_enable_imu_smooth = 0; +int g_imu_smooth_frequency = 400; int g_sendcloudslam = 0; int g_sendcloudrender = 0; int g_sendrgb_compressed = 0; @@ -132,6 +147,11 @@ std::string g_relocalization_map_abs_path = ""; std::string g_mapping_result_dest_dir = ""; std::string g_mapping_result_file_name = ""; +int g_send_image_mask = 0; +std::string g_image_mask_abs_path = ""; + +int g_reset_algo = 0; + const char* DEV_STATUS_CSV_FILE = "dev_status.csv"; FILE* dev_status_csv_file = nullptr; @@ -764,6 +784,105 @@ void clear_all_queues() { g_latest_bgr.reset(); g_latest_rgb_timestamp = 0; g_has_rgb = false; + + // Clear IMU queue + { + std::lock_guard lock(g_imu_queue_mutex); + while (!g_imu_queue.empty()) { + g_imu_queue.pop(); + } + } +} + +// IMU dedicated processing thread routine +static void imu_thread_routine() +{ + // Try to set higher thread priority for IMU processing + pthread_t this_thread = pthread_self(); + struct sched_param param; + param.sched_priority = 70; + + int ret = pthread_setschedparam(this_thread, SCHED_FIFO, ¶m); + if (ret != 0) { + ret = pthread_setschedparam(this_thread, SCHED_RR, ¶m); + } + + #ifdef ROS2 + RCLCPP_INFO(rclcpp::get_logger("imu_thread"), "IMU dedicated thread started (priority: %d)", param.sched_priority); + #else + ROS_INFO("IMU dedicated thread started (priority: %d)", param.sched_priority); + #endif + + while (g_imu_thread_running) { + std::unique_lock lock(g_imu_queue_mutex); + + // Wait for IMU data + g_imu_queue_cv.wait(lock, []() { + return !g_imu_queue.empty() || !g_imu_thread_running; + }); + + if (!g_imu_thread_running) { + break; + } + + // Process all pending IMU data + while (!g_imu_queue.empty() && g_imu_thread_running) { + imu_convert_data_t imu_data = g_imu_queue.front(); + g_imu_queue.pop(); + lock.unlock(); + + // Publish IMU data + if (g_ros_object && g_sendimu) { + g_ros_object->publishImu(&imu_data); + } + + lock.lock(); + } + } + + #ifdef ROS2 + RCLCPP_INFO(rclcpp::get_logger("imu_thread"), "IMU dedicated thread exiting"); + #else + ROS_INFO("IMU dedicated thread exiting"); + #endif +} + +// Start IMU dedicated thread +static void start_imu_thread() +{ + if (!g_imu_thread_running) { + g_imu_thread_running = true; + g_imu_thread = std::thread(imu_thread_routine); + #ifdef ROS2 + RCLCPP_INFO(rclcpp::get_logger("imu_thread"), "IMU dedicated thread created"); + #else + ROS_INFO("IMU dedicated thread created"); + #endif + } +} + +// Stop IMU dedicated thread +static void stop_imu_thread() +{ + if (g_imu_thread_running) { + g_imu_thread_running = false; + g_imu_queue_cv.notify_all(); + if (g_imu_thread.joinable()) { + g_imu_thread.join(); + } + + // Clear queue + std::lock_guard lock(g_imu_queue_mutex); + while (!g_imu_queue.empty()) { + g_imu_queue.pop(); + } + + #ifdef ROS2 + RCLCPP_INFO(rclcpp::get_logger("imu_thread"), "IMU dedicated thread stopped"); + #else + ROS_INFO("IMU dedicated thread stopped"); + #endif + } } // Lidar data callback @@ -800,7 +919,15 @@ static void lidar_data_callback(const lidar_data_t *data, void *user_data) case LIDAR_DT_RAW_IMU: if (g_sendimu) { imudata = (imu_convert_data_t *)data->stream.imageList[0].pAddr; - g_ros_object->publishImu(imudata); + // Enqueue IMU data for dedicated thread processing + { + std::lock_guard lock(g_imu_queue_mutex); + if (g_imu_queue.size() >= IMU_QUEUE_MAX_SIZE) { + g_imu_queue.pop(); // Drop oldest if full + } + g_imu_queue.push(*imudata); + } + g_imu_queue_cv.notify_one(); } update_count(&imu_rx_fps); break; @@ -999,6 +1126,9 @@ static void lidar_data_callback(const lidar_data_t *data, void *user_data) break; case LIDAR_DT_SLAM_WIWC: { + // Always publish WIWC data for real-time extrinsics + g_ros_object->publishWiwc((capture_Image_List_t *)&data->stream); + if(g_record_data ) { g_ros_object->recordrotate((capture_Image_List_t *)&data->stream); } @@ -1451,6 +1581,51 @@ static void lidar_device_callback(const lidar_device_info_t* device, bool attach return; } } + + // Transfer image mask if enabled + if (g_send_image_mask == 1) { + if (g_image_mask_abs_path != "" && std::filesystem::exists(g_image_mask_abs_path)) { + int ret = lidar_set_image_mask(odinDevice, g_image_mask_abs_path.c_str()); + if (ret == 0) { + #ifdef ROS2 + RCLCPP_INFO(rclcpp::get_logger("device_cb"), "Image mask set successfully: %s", g_image_mask_abs_path.c_str()); + #else + ROS_INFO("Image mask set successfully: %s", g_image_mask_abs_path.c_str()); + #endif + } else { + #ifdef ROS2 + RCLCPP_ERROR(rclcpp::get_logger("device_cb"), "Failed to set image mask: %s, error: %d", g_image_mask_abs_path.c_str(), ret); + #else + ROS_ERROR("Failed to set image mask: %s, error: %d", g_image_mask_abs_path.c_str(), ret); + #endif + } + } else { + #ifdef ROS2 + RCLCPP_WARN(rclcpp::get_logger("device_cb"), "Image mask path not set or file not found: %s", g_image_mask_abs_path.c_str()); + #else + ROS_WARN("Image mask path not set or file not found: %s", g_image_mask_abs_path.c_str()); + #endif + } + } + + // Send algo_reset command if enabled + if (g_reset_algo == 1) { + int reset_value = 1; + int ret = lidar_set_custom_parameter(odinDevice, "algo_reset", &reset_value, sizeof(int)); + if (ret == 0) { + #ifdef ROS2 + RCLCPP_INFO(rclcpp::get_logger("device_cb"), "Algo reset command sent successfully"); + #else + ROS_INFO("Algo reset command sent successfully"); + #endif + } else { + #ifdef ROS2 + RCLCPP_ERROR(rclcpp::get_logger("device_cb"), "Failed to send algo reset command, error: %d", ret); + #else + ROS_ERROR("Failed to send algo reset command, error: %d", ret); + #endif + } + } lidar_data_callback_info_t data_callback_info; data_callback_info.data_callback = lidar_data_callback; @@ -1532,6 +1707,9 @@ static void lidar_device_callback(const lidar_device_info_t* device, bool attach deviceConnected = true; deviceDisconnected = false; + // Start IMU dedicated thread + start_imu_thread(); + // Start custom parameter monitoring thread g_param_monitor_running = true; g_param_monitor_thread = std::thread(custom_parameter_monitor); @@ -1567,6 +1745,9 @@ static void lidar_device_callback(const lidar_device_info_t* device, bool attach deviceConnected = false; deviceDisconnected = true; + // Stop IMU dedicated thread + stop_imu_thread(); + // Stop custom parameter monitoring thread g_param_monitor_running = false; if (g_param_monitor_thread.joinable()) { @@ -1647,6 +1828,10 @@ int main(int argc, char *argv[]) g_sendrgb = get_key_value("sendrgb", 1); g_sendimu = get_key_value("sendimu", 1); g_senddtof = get_key_value("senddtof", 1); + + // SDK IMU smooth sending configuration + g_enable_imu_smooth = get_key_value("enable_imu_smooth", 0); + g_imu_smooth_frequency = get_key_value("imu_smooth_frequency", 400); g_cloud_raw_confidence_threshold = get_key_value("cloud_raw_confidence_threshold", 35); g_rosNodeControlImpl.setCloudRawConfidenceThreshold(g_cloud_raw_confidence_threshold); g_dtof_fps = get_key_value("dtof_fps", 145); // Read DTOF frame rate from config (100=10fps, 145=14.5fps) @@ -1679,7 +1864,10 @@ int main(int argc, char *argv[]) g_relocalization_map_abs_path = get_key_str_value("relocalization_map_abs_path", ""); g_mapping_result_dest_dir = get_key_str_value("mapping_result_dest_dir", ""); g_mapping_result_file_name = get_key_str_value("mapping_result_file_name", ""); + g_image_mask_abs_path = get_key_str_value("image_mask_abs_path", ""); + g_send_image_mask = get_key_value("sendimagemask", 0); + g_reset_algo = get_key_value("resetalgo", 0); g_custom_map_mode = g_parser->getCustomMapMode(2); lidar_log_set_level(LIDAR_LOG_INFO); @@ -1747,6 +1935,24 @@ int main(int argc, char *argv[]) return -1; } + // Configure SDK IMU smooth sending AFTER lidar_system_init + // SDK now defaults to disabled, only enable if configured + if (g_enable_imu_smooth) { + lidar_enable_imu_smooth_sending(1); + lidar_set_imu_smooth_frequency(g_imu_smooth_frequency); + #ifdef ROS2 + RCLCPP_INFO(node->get_logger(), "Enabling SDK IMU smooth sending at %d Hz", g_imu_smooth_frequency); + #else + ROS_INFO("Enabling SDK IMU smooth sending at %d Hz", g_imu_smooth_frequency); + #endif + } else { + #ifdef ROS2 + RCLCPP_INFO(node->get_logger(), "SDK IMU smooth sending disabled"); + #else + ROS_INFO("SDK IMU smooth sending disabled"); + #endif + } + bool usbPresent = false; bool usbVersionChecked = false; diff --git a/src/image_overlay_node.cpp b/src/image_overlay_node.cpp new file mode 100644 index 0000000..2e1f4c0 --- /dev/null +++ b/src/image_overlay_node.cpp @@ -0,0 +1,254 @@ +/* +Copyright 2025 Manifold Tech Ltd.(www.manifoldtech.com.co) +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "image_overlay_node.hpp" + +#ifdef ROS2 +// ==================== ROS2 Implementation ==================== + +ImageOverlayNode::ImageOverlayNode(const rclcpp::NodeOptions& options) + : Node("image_overlay_node", options) +{ + // Read from register_keys (same structure as control_command.yaml) + this->declare_parameter("register_keys.overlay_reprojected_topic", "/odin1/reprojected_image"); + this->declare_parameter("register_keys.overlay_camera_topic", "/odin1/image/undistorted"); + this->declare_parameter("register_keys.overlay_output_topic", "/odin1/overlay_image"); + this->declare_parameter("register_keys.overlay_alpha", 0.6); + + reprojected_topic_ = this->get_parameter("register_keys.overlay_reprojected_topic").as_string(); + camera_topic_ = this->get_parameter("register_keys.overlay_camera_topic").as_string(); + overlay_topic_ = this->get_parameter("register_keys.overlay_output_topic").as_string(); + alpha_ = this->get_parameter("register_keys.overlay_alpha").as_double(); + + RCLCPP_INFO(this->get_logger(), "Subscribing to: %s and %s", + reprojected_topic_.c_str(), camera_topic_.c_str()); + RCLCPP_INFO(this->get_logger(), "Publishing to: %s (alpha=%.2f)", overlay_topic_.c_str(), alpha_); + + // Independent subscriptions - no synchronization needed + reproj_sub_ = this->create_subscription( + reprojected_topic_, 10, + std::bind(&ImageOverlayNode::reprojCallback, this, std::placeholders::_1)); + + camera_sub_ = this->create_subscription( + camera_topic_, 10, + std::bind(&ImageOverlayNode::cameraCallback, this, std::placeholders::_1)); + + overlay_pub_ = this->create_publisher(overlay_topic_, 10); + + RCLCPP_INFO(this->get_logger(), "ImageOverlayNode initialized (no-sync mode)"); +} + +void ImageOverlayNode::reprojCallback(const Image::ConstSharedPtr& msg) +{ + try { + cv_bridge::CvImagePtr cv_ptr = cv_bridge::toCvCopy(msg, "bgr8"); + { + std::lock_guard lock(mutex_); + latest_reproj_img_ = cv_ptr->image.clone(); + latest_header_ = msg->header; + } + } catch (cv_bridge::Exception& e) { + RCLCPP_ERROR(this->get_logger(), "cv_bridge exception (reproj): %s", e.what()); + return; + } + publishOverlay(); +} + +void ImageOverlayNode::cameraCallback(const Image::ConstSharedPtr& msg) +{ + try { + cv_bridge::CvImagePtr cv_ptr = cv_bridge::toCvCopy(msg, "bgr8"); + { + std::lock_guard lock(mutex_); + latest_camera_img_ = cv_ptr->image.clone(); + } + } catch (cv_bridge::Exception& e) { + RCLCPP_ERROR(this->get_logger(), "cv_bridge exception (camera): %s", e.what()); + return; + } + publishOverlay(); +} + +void ImageOverlayNode::publishOverlay() +{ + cv::Mat reproj_copy, camera_copy; + std_msgs::msg::Header header_copy; + + { + std::lock_guard lock(mutex_); + if (latest_reproj_img_.empty() || latest_camera_img_.empty()) { + return; + } + reproj_copy = latest_reproj_img_.clone(); + camera_copy = latest_camera_img_.clone(); + header_copy = latest_header_; + } + + if (reproj_copy.size() != camera_copy.size()) { + RCLCPP_WARN(this->get_logger(), + "Image sizes don't match: reproj(%dx%d) vs camera(%dx%d)", + reproj_copy.cols, reproj_copy.rows, + camera_copy.cols, camera_copy.rows); + return; + } + + // Create overlay using alpha blending + // Replace white background in reproj with camera image, keep colored points + cv::Mat overlay = camera_copy.clone(); + + // Blend: where reproj has color (non-white), show reproj color semi-transparently + // where reproj is white (background), show camera image + + for (int y = 0; y < reproj_copy.rows; ++y) { + for (int x = 0; x < reproj_copy.cols; ++x) { + cv::Vec3b reproj_pixel = reproj_copy.at(y, x); + // Check if pixel is not white (has point cloud color) + if (reproj_pixel[0] < 250 || reproj_pixel[1] < 250 || reproj_pixel[2] < 250) { + // Blend reproj color with camera color + cv::Vec3b cam_pixel = camera_copy.at(y, x); + overlay.at(y, x) = cv::Vec3b( + static_cast(alpha_ * reproj_pixel[0] + (1 - alpha_) * cam_pixel[0]), + static_cast(alpha_ * reproj_pixel[1] + (1 - alpha_) * cam_pixel[1]), + static_cast(alpha_ * reproj_pixel[2] + (1 - alpha_) * cam_pixel[2]) + ); + } + // else: keep camera image (already in overlay) + } + } + + auto overlay_msg = cv_bridge::CvImage(header_copy, "bgr8", overlay).toImageMsg(); + overlay_pub_->publish(*overlay_msg); +} + +// ==================== ROS2 Main ==================== +int main(int argc, char **argv) +{ + rclcpp::init(argc, argv); + + auto node = std::make_shared(); + + rclcpp::spin(node); + rclcpp::shutdown(); + return 0; +} + +#else +// ==================== ROS1 Implementation ==================== + +ImageOverlayNode::ImageOverlayNode(ros::NodeHandle& nh, ros::NodeHandle& pnh) + : nh_(nh), pnh_(pnh) +{ + // Read from register_keys (same structure as control_command.yaml) + pnh_.param("register_keys/overlay_reprojected_topic", reprojected_topic_, "/odin1/reprojected_image"); + pnh_.param("register_keys/overlay_camera_topic", camera_topic_, "/odin1/image/undistorted"); + pnh_.param("register_keys/overlay_output_topic", overlay_topic_, "/odin1/overlay_image"); + pnh_.param("register_keys/overlay_alpha", alpha_, 0.6); + + ROS_INFO("Subscribing to: %s and %s", reprojected_topic_.c_str(), camera_topic_.c_str()); + ROS_INFO("Publishing to: %s (alpha=%.2f)", overlay_topic_.c_str(), alpha_); + + // Independent subscriptions - no synchronization needed + reproj_sub_ = nh_.subscribe(reprojected_topic_, 10, &ImageOverlayNode::reprojCallback, this); + camera_sub_ = nh_.subscribe(camera_topic_, 10, &ImageOverlayNode::cameraCallback, this); + + overlay_pub_ = nh_.advertise(overlay_topic_, 10); + + ROS_INFO("ImageOverlayNode initialized (no-sync mode)"); +} + +void ImageOverlayNode::reprojCallback(const sensor_msgs::ImageConstPtr& msg) +{ + try { + cv_bridge::CvImagePtr cv_ptr = cv_bridge::toCvCopy(msg, "bgr8"); + { + std::lock_guard lock(mutex_); + latest_reproj_img_ = cv_ptr->image.clone(); + latest_header_ = msg->header; + } + } catch (cv_bridge::Exception& e) { + ROS_ERROR("cv_bridge exception (reproj): %s", e.what()); + return; + } + publishOverlay(); +} + +void ImageOverlayNode::cameraCallback(const sensor_msgs::ImageConstPtr& msg) +{ + try { + cv_bridge::CvImagePtr cv_ptr = cv_bridge::toCvCopy(msg, "bgr8"); + { + std::lock_guard lock(mutex_); + latest_camera_img_ = cv_ptr->image.clone(); + } + } catch (cv_bridge::Exception& e) { + ROS_ERROR("cv_bridge exception (camera): %s", e.what()); + return; + } + publishOverlay(); +} + +void ImageOverlayNode::publishOverlay() +{ + cv::Mat reproj_copy, camera_copy; + std_msgs::Header header_copy; + + { + std::lock_guard lock(mutex_); + if (latest_reproj_img_.empty() || latest_camera_img_.empty()) { + return; + } + reproj_copy = latest_reproj_img_.clone(); + camera_copy = latest_camera_img_.clone(); + header_copy = latest_header_; + } + + if (reproj_copy.size() != camera_copy.size()) { + ROS_WARN_THROTTLE(2, "Image sizes don't match: reproj(%dx%d) vs camera(%dx%d)", + reproj_copy.cols, reproj_copy.rows, camera_copy.cols, camera_copy.rows); + return; + } + + // Create overlay using alpha blending + cv::Mat overlay = camera_copy.clone(); + + for (int y = 0; y < reproj_copy.rows; ++y) { + for (int x = 0; x < reproj_copy.cols; ++x) { + cv::Vec3b reproj_pixel = reproj_copy.at(y, x); + if (reproj_pixel[0] < 250 || reproj_pixel[1] < 250 || reproj_pixel[2] < 250) { + cv::Vec3b cam_pixel = camera_copy.at(y, x); + overlay.at(y, x) = cv::Vec3b( + static_cast(alpha_ * reproj_pixel[0] + (1 - alpha_) * cam_pixel[0]), + static_cast(alpha_ * reproj_pixel[1] + (1 - alpha_) * cam_pixel[1]), + static_cast(alpha_ * reproj_pixel[2] + (1 - alpha_) * cam_pixel[2]) + ); + } + } + } + + sensor_msgs::ImagePtr overlay_msg = cv_bridge::CvImage(header_copy, "bgr8", overlay).toImageMsg(); + overlay_pub_.publish(overlay_msg); +} + +// ==================== ROS1 Main ==================== +int main(int argc, char **argv) +{ + ros::init(argc, argv, "image_overlay_node"); + ros::NodeHandle nh; + ros::NodeHandle pnh("~"); + + ImageOverlayNode node(nh, pnh); + + ros::spin(); + return 0; +} +#endif