From ad28a413cc6a6d74381d0976b9619855b2506f44 Mon Sep 17 00:00:00 2001 From: duongtd Date: Thu, 6 Aug 2026 19:50:46 +0700 Subject: [PATCH] add new file nav_c_api2 and function --- CMAKE_BUILD_README.md | 3 +- CMakeLists.txt | 79 +- config/config/voxel_layer_params.yaml | 6 +- config/costmap_common_params.yaml | 52 +- config/hybrid_local_planner_params.yaml | 51 +- config/mission_adapters_params.yaml | 42 + config/move_base_common_params.yaml | 51 +- config/mppi_local_planner_params.yaml | 192 ++-- config/mprim/mqtt_general.yaml | 16 +- config/priest_local_planner_params.yaml | 56 ++ config/recovery_behaviors_params.yaml | 170 ++++ config/sbpl_global_params.yaml | 6 +- config/stanley_local_planner_params.yaml | 113 ++- src/APIs/c_api/NAV_C_API_2_GUIDE.md | 859 ++++++++++++++++++ src/APIs/c_api/include/convertor_2.h | 51 ++ src/APIs/c_api/include/nav_c_api_2.h | 301 ++++++ .../c_api/include/nav_c_api_io_structure.md | 0 .../include/sensor_msgs/DepthCameraData.h | 36 + src/APIs/c_api/src/convertor_2.cpp | 78 ++ src/APIs/c_api/src/nav_c_api.cpp | 7 +- src/APIs/c_api/src/nav_c_api_2.cpp | 422 +++++++++ src/Libraries/common_msgs | 2 +- src/Libraries/costmap_2d | 2 +- src/Libraries/costmap_2d_dev_1_cam.zip | Bin 0 -> 125010 bytes .../costmap_2d_dev_multi_cam_test.zip | Bin 0 -> 117280 bytes src/Libraries/data_convert | 2 +- src/Libraries/data_convert.zip | Bin 0 -> 7416 bytes .../include/move_base_core/navigation.h | 22 + .../include/robot_nav_core2/global_planner.h | 1 + .../include/robot_nav_core2/local_planner.h | 1 + .../Packages/move_base/CMakeLists.txt | 4 +- .../move_base/include/move_base/move_base.h | 11 +- .../Packages/move_base/package.xml | 3 + .../Packages/move_base/src/move_base.cpp | 16 +- 34 files changed, 2439 insertions(+), 216 deletions(-) create mode 100644 config/mission_adapters_params.yaml create mode 100644 config/priest_local_planner_params.yaml create mode 100644 config/recovery_behaviors_params.yaml create mode 100644 src/APIs/c_api/NAV_C_API_2_GUIDE.md create mode 100644 src/APIs/c_api/include/convertor_2.h create mode 100644 src/APIs/c_api/include/nav_c_api_2.h delete mode 100644 src/APIs/c_api/include/nav_c_api_io_structure.md create mode 100644 src/APIs/c_api/include/sensor_msgs/DepthCameraData.h create mode 100644 src/APIs/c_api/src/convertor_2.cpp create mode 100644 src/APIs/c_api/src/nav_c_api_2.cpp create mode 100644 src/Libraries/costmap_2d_dev_1_cam.zip create mode 100644 src/Libraries/costmap_2d_dev_multi_cam_test.zip create mode 100644 src/Libraries/data_convert.zip diff --git a/CMAKE_BUILD_README.md b/CMAKE_BUILD_README.md index a6f434c..4361fd5 100644 --- a/CMAKE_BUILD_README.md +++ b/CMAKE_BUILD_README.md @@ -356,7 +356,8 @@ export PNKX_NAV_CORE_CONFIG_DIR=/path/to/config # Chỉ định workspace directory export PNKX_NAV_CORE_DIR=/path/to/pnkx_nav_core - ] không install) + +# LD_LIBRARY_PATH (nếu không install) export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path/to/pnkx_nav_core/build/lib ``` diff --git a/CMakeLists.txt b/CMakeLists.txt index f949b57..e5c34ec 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -150,6 +150,83 @@ if (NOT TARGET robot_clear_costmap_recovery) add_subdirectory(${CMAKE_SOURCE_DIR}/src/Navigations/Libraries/robot_clear_costmap_recovery) endif() +# 3. Packages being migrated from AMR_T800/Test +# +# Prefer the future in-tree location. Until the migration is physically done, +# keep the current sibling Test directory buildable from this root CMake file. +option(PNKX_NAV_CORE_BUILD_TEST_PACKAGES + "Build navigation packages currently kept in AMR_T800/Test" + ON) + +option(PNKX_NAV_CORE_BUILD_CATKIN_TEST_PACKAGES + "Build Test packages that require a catkin workspace instead of standalone CMake" + OFF) + +set(PNKX_NAV_CORE_TEST_PACKAGES_DIR "" + CACHE PATH "Directory containing the migrated navigation Test packages") + +if(NOT PNKX_NAV_CORE_TEST_PACKAGES_DIR) + if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/Test") + set(PNKX_NAV_CORE_TEST_PACKAGES_DIR "${CMAKE_CURRENT_SOURCE_DIR}/Test") + elseif(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../Test") + set(PNKX_NAV_CORE_TEST_PACKAGES_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../Test") + endif() +endif() + +function(pnkx_add_test_package package_name) + set(package_dir "${PNKX_NAV_CORE_TEST_PACKAGES_DIR}/${package_name}") + if(EXISTS "${package_dir}/CMakeLists.txt") + message(STATUS "[pnkx_nav_core] Adding migrated Test package: ${package_name}") + add_subdirectory("${package_dir}" "${CMAKE_BINARY_DIR}/Test/${package_name}") + else() + message(WARNING + "[pnkx_nav_core] Test package '${package_name}' was not found in " + "'${PNKX_NAV_CORE_TEST_PACKAGES_DIR}'.") + endif() +endfunction() + +if(PNKX_NAV_CORE_BUILD_TEST_PACKAGES) + if(NOT PNKX_NAV_CORE_TEST_PACKAGES_DIR) + message(FATAL_ERROR + "PNKX_NAV_CORE_BUILD_TEST_PACKAGES is ON, but no Test package directory was found. " + "Set PNKX_NAV_CORE_TEST_PACKAGES_DIR explicitly.") + endif() + + # Foundation and message packages. + pnkx_add_test_package(angles) + pnkx_add_test_package(image_geometry) + pnkx_add_test_package(grid_map_core) + pnkx_add_test_package(vda5050_msgs) + + # Planner libraries and plugins. SBPL must precede its lattice plugin. + pnkx_add_test_package(sbpl) + pnkx_add_test_package(sbpl_lattice_planner) + pnkx_add_test_package(base_local_planner) + pnkx_add_test_package(hybrid_local_planner) + pnkx_add_test_package(mppi_local_planner) + pnkx_add_test_package(priest_local_planner) + pnkx_add_test_package(stanley_local_planner) + + # Supporting runtime packages and test utilities. + pnkx_add_test_package(depth_image_proc) + pnkx_add_test_package(action_core) + pnkx_add_test_package(recovery_core) + pnkx_add_test_package(mission_adapters) + pnkx_add_test_package(nav_test_harness) + + # Must be last: it consumes planners, actions, recovery and mission APIs. + pnkx_add_test_package(move_base2) +endif() + +# These packages call find_package(catkin REQUIRED ...) for T800 packages. +# Keep them outside the standalone graph until their dependencies export +# *Config.cmake files, or build them through a catkin workspace. +if(PNKX_NAV_CORE_BUILD_CATKIN_TEST_PACKAGES) + pnkx_add_test_package(deep_mpc_local_planner) + pnkx_add_test_package(nav_ros_bridge) + pnkx_add_test_package(depth_local_costmap_noetic_test) +endif() + # 2. Main packages (phụ thuộc vào cores) # message(STATUS "[move_base] Shared library configured") if (NOT TARGET move_base) @@ -164,5 +241,3 @@ endif() message(STATUS "========================================") message(STATUS "All packages configured successfully") message(STATUS "========================================") - - diff --git a/config/config/voxel_layer_params.yaml b/config/config/voxel_layer_params.yaml index 3dc96dd..b168fdd 100644 --- a/config/config/voxel_layer_params.yaml +++ b/config/config/voxel_layer_params.yaml @@ -8,4 +8,8 @@ voxel_layer: unknown_threshold: 15.0 mark_threshold: 0 combination_method: 1 - + frustum_clearing_enabled: true + frustum_clearing_pixel_step: 8 + frustum_min_range: 0.20 + frustum_max_range: 3.0 + frustum_depth_camera_topic: /camera/depth/data diff --git a/config/costmap_common_params.yaml b/config/costmap_common_params.yaml index efb6335..be43c2a 100755 --- a/config/costmap_common_params.yaml +++ b/config/costmap_common_params.yaml @@ -1,5 +1,7 @@ robot_base_frame: base_link transform_tolerance: 1.0 +performance_metrics_enabled: true +performance_metrics_period: 5.0 obstacle_range: 3.0 #mark_threshold: 1 publish_voxel_map: true @@ -19,7 +21,7 @@ virtual_walls_map: lethal_cost_threshold: 100 obstacles: - observation_sources: b_scan_marking b_scan_clearing pc_marking pc_clearing + observation_sources: b_scan pc_marking pc_clearing pc_r_marking pc_r_clearing # f_scan_marking: f_scan_marking f_scan_clearing # topic: /f_scan # data_type: LaserScan @@ -36,20 +38,13 @@ obstacles: # inf_is_valid: true # min_obstacle_height: 0.0 # max_obstacle_height: 0.25 - b_scan_marking: - topic: /b_scan - data_type: LaserScan - clearing: false - marking: true - inf_is_valid: true - min_obstacle_height: 0.0 - max_obstacle_height: 0.25 - b_scan_clearing: + b_scan: topic: /b_scan data_type: LaserScan clearing: true - marking: false + marking: true inf_is_valid: true + frustum_clearing_enabled: false min_obstacle_height: 0.0 max_obstacle_height: 0.25 @@ -59,6 +54,7 @@ obstacles: clearing: false marking: true inf_is_valid: false + frustum_clearing_enabled: false observation_persistence: 0.0 expected_update_rate: 0.5 obstacle_range: 2.5 @@ -67,14 +63,38 @@ obstacles: max_obstacle_height: 1.0 pc_clearing: - topic: /camera/depth/points_clear + topic: /camera/depth/data + data_type: DepthCameraData + clearing: false + marking: true + frustum_clearing_enabled: true + frustum_clearing_pixel_step: 8 + frustum_min_range: 0.20 + frustum_max_range: 3.5 + + pc_r_marking: + topic: /camera_right/depth/points_proc data_type: PointCloud2 - clearing: true - marking: false + clearing: false + marking: true inf_is_valid: false + frustum_clearing_enabled: false observation_persistence: 0.0 expected_update_rate: 0.5 obstacle_range: 2.5 raytrace_range: 3.0 - min_obstacle_height: -0.5 - max_obstacle_height: 5.0 + min_obstacle_height: 0.1 + max_obstacle_height: 1.0 + + pc_r_clearing: + topic: /camera_right/depth/data + data_type: DepthCameraData + clearing: false + marking: true + frustum_clearing_enabled: true + frustum_clearing_pixel_step: 8 + frustum_min_range: 0.20 + frustum_max_range: 3.5 + + # Depth camera clearing is handled by VoxelLayer frustum clearing from + # /camera/depth/image_raw + /camera/depth/camera_info. /camera_right/depth/data diff --git a/config/hybrid_local_planner_params.yaml b/config/hybrid_local_planner_params.yaml index 213875a..321000b 100644 --- a/config/hybrid_local_planner_params.yaml +++ b/config/hybrid_local_planner_params.yaml @@ -1,32 +1,17 @@ -LocalPlannerAdapter: - library_path: liblocal_planner_adapter - yaw_goal_tolerance: 0.017 - xy_goal_tolerance: 0.03 - min_approach_linear_velocity: 0.06 - HybridLocalPlanner: # base_local_planner: "hybrid_local_planner/HybridLocalPlanner" # HybridLocalPlanner: library_path: libhybrid_local_planner # Robot - robot_max_v_ac: 0.4 - robot_max_w_ac: 0.6 - robot_max_v_pt: 1.0 - robot_max_w_pt: 0.6 - robot_min_v: -0.5 - robot_min_w: 0.05 - robot_max_v_backwards_pt: -0.25 - acc_lim_x: 1.0 + max_forward_velocity: 1.0 + max_reverse_velocity: 0.25 # [m/s], positive magnitude + avoidance_max_velocity: 0.4 + max_angular_velocity: 0.6 + min_in_place_angular_velocity: 0.3 + acc_lim_x: 0.1 + decel_lim_x: 0.5 acc_lim_theta: 2.0 min_turn_radius: 0.0 - turn_around_priority: true - stop_dist: 0.5 - dec_dist: 1.0 - max_acceleration: 0.1 - max_deceleration: 0.5 - max_d_yawrate: 3.2 - max_in_place_yawrate: 0.6 - min_in_place_yawrate: 0.3 robot_radius: 0.1 footprint_padding: 0.08 use_footprint: true @@ -39,26 +24,32 @@ HybridLocalPlanner: max_global_plan_lookahead_dist: 3.0 global_plan_viapoint_sep: 0.5 global_plan_goal_sep: 0.05 - global_plan_prune_distance: 0.0 predict_time: 3.0 sim_period: 0.1 sim_time_samples: 10 - sim_direction: M_PI / 2.0 # Optimization - w_vel: 0.8 w_omega: 2.5 obs_cost_gain: 1.3 - path_cost_gain: 2.0 + path_cost_gain: 0.5 to_goal_cost_gain: 0.8 - speed_cost_gain: 0.8 + speed_cost_gain: 0.5 # Obstacles obs_range: 2.5 #GeneralSetting - segment_transition_threshold: 0.01 - calibration_factor: 1.5 + segment_transition_threshold: 0.03 # [m], also used as DWA stop distance for intermediate segments + rotation_segment_yaw_threshold: 0.05 # [rad], ignore tiny yaw noise at duplicate positions + direction_change_hysteresis: 0.15 # normalized dot product use_obstacle_avoidance: true slow_velocity_th: 0.1 - turn_direction_th: 0.1 \ No newline at end of file + turn_direction_th: 0.1 + avoidance_clear_hold_time: 0.5 # [s] + rejoin_blend_time: 0.8 # [s] + rejoin_max_velocity: 0.25 # [m/s] + rejoin_heading_tolerance: 0.35 # [rad] + rejoin_path_tolerance: 0.20 # [m] + pp_max_omega_correction: 0.15 # [rad/s] + rejoin_acc_lim_theta: 1.0 # [rad/s^2] + rejoin_lookahead_distance: 0.8 # [m] diff --git a/config/mission_adapters_params.yaml b/config/mission_adapters_params.yaml new file mode 100644 index 0000000..902a7db --- /dev/null +++ b/config/mission_adapters_params.yaml @@ -0,0 +1,42 @@ +# Tham số RUNTIME của mission layer (gói `mission_adapters`). +# +# Đây là bản đang có hiệu lực. Bản trong `Test/mission_adapters/test/config/` chỉ phục vụ test và +# chỉ được đọc khi chạy kèm PNKX_NAV_CORE_CONFIG_DIR trỏ vào đúng thư mục đó. + +mission_adapters: + # Nguồn mission. Thêm một loại nguồn mới = thêm một entry ở đây + một plugin .so, không phải sửa + # code của gói. + # name: tên instance, cũng là namespace param riêng của nó + # type: tên symbol export bằng BOOST_DLL_ALIAS, phải có khoá library_path tương ứng bên dưới + mission_sources: + - {name: goal_src, type: GoalSourceAdapter} + - {name: vda5050_src, type: VDA5050SourceAdapter} + + # Trần thời gian cho MỘT chặng (navigation + action), tính từ lúc chặng được giao. [s] + # 0 = tắt. Quá hạn thì chặng bị đánh dấu thất bại VÀ navigation được bảo dừng — lưới cuối cho + # trường hợp navigation không bao giờ báo kết quả về. + mission_timeout: 0.0 + + # Một chặng thất bại thì xử lý phần còn lại của hàng đợi thế nào. + # true = xoá sạch hàng đợi (mặc định, an toàn cho tuyến đường tuần tự kiểu VDA5050: không tới + # được node n thì chạy tiếp chặng n+1 là cắt ngang đoạn chưa được cho phép đi) + # false = chỉ bỏ chặng lỗi rồi chạy tiếp. Chỉ đặt false khi các mission trong hàng đợi ĐỘC LẬP + # với nhau, không phải các chặng của cùng một tuyến. + clear_queue_on_failure: true + +# Param riêng của từng instance nguồn mission, đặt theo `name` ở trên. +vda5050_src: + # Frame gán cho goal/start sinh ra từ nodePosition của VDA5050. + # Lưu ý: `mapId` trong VDA5050 là danh tính bản đồ, KHÔNG phải frame TF, nên không dùng làm frame. + global_frame: map + +# Bảng symbol -> thư viện cho Boost.DLL. +# +# Thiếu khoá library_path là nguyên nhân phổ biến nhất của lỗi "plugin build xong nhưng runtime báo +# không tìm thấy". Tên không có đuôi .so được resolve qua PNKX_NAV_CORE_LIBRARY_PATH / devel/lib / +# LD_LIBRARY_PATH — tức phải `source devel/setup.bash` trước khi chạy. +GoalSourceAdapter: + library_path: libmission_adapters_goal_source + +VDA5050SourceAdapter: + library_path: libmission_adapters_vda5050_source diff --git a/config/move_base_common_params.yaml b/config/move_base_common_params.yaml index b1c056b..3b83e09 100755 --- a/config/move_base_common_params.yaml +++ b/config/move_base_common_params.yaml @@ -1,43 +1,18 @@ -# position_planner_name: PNKXLocalPlanner -# docking_planner_name: PNKXDockingLocalPlanner -# position_planner_name: StanleyLocalPlanner -# docking_planner_name: StanleyDockingLocalPlanner -position_planner_name: MPPILocalPlanner #HybridLocalPlanner MPPILocalPlanner -docking_planner_name: PNKXDockingLocalPlanner +position_planner_name: PriestLocalPlanner #HybridLocalPlanner MPPILocalPlanner PriestLocalPlanner PNKXLocalPlanner +docking_planner_name: PNKXDockingLocalPlanner #StanleyDockingLocalPlanner PNKXDockingLocalPlanner go_straight_planner_name: PNKXGoStraightLocalPlanner rotate_planner_name: PNKXRotateLocalPlanner base_local_planner: LocalPlannerAdapter base_global_planner: CustomPlanner -# PNKXLocalPlanner: -# base_local_planner: LocalPlannerAdapter -# base_global_planner: SBPLLatticePlanner - -# PNKXDockingLocalPlanner: -# base_local_planner: LocalPlannerAdapter -# base_global_planner: CustomPlanner - -# StanleyLocalPlanner: -# base_local_planner: LocalPlannerAdapter -# base_global_planner: CustomPlanner - -# StanleyDockingLocalPlanner: -# base_local_planner: LocalPlannerAdapter -# base_global_planner: CustomPlanner - -# HybridLocalPlanner: -# base_local_planner: LocalPlannerAdapter -# base_global_planner: CustomPlanner - -MPPILocalPlanner: +PriestLocalPlanner: base_local_planner: LocalPlannerAdapter - base_global_planner: SBPLLatticePlanner + base_global_planner: CustomPlanner #CustomPlanner SBPLLatticePlanner PNKXDockingLocalPlanner: base_local_planner: LocalPlannerAdapter base_global_planner: TwoPointsPlanner - PNKXGoStraightLocalPlanner: base_local_planner: LocalPlannerAdapter base_global_planner: TwoPointsPlanner @@ -47,18 +22,28 @@ PNKXRotateLocalPlanner: base_global_planner: TwoPointsPlanner ### replanning -controller_frequency: 30.0 # run controller at 15.0 Hz +controller_frequency: 30.0 # run controller at 30.0 Hz controller_patience: 0.0 # if the controller failed, clear obstacles and retry; after 15.0 s, abort and replan planner_frequency: 0.0 # don't continually replan (only when controller failed) planner_patience: 2.0 # if the first planning attempt failed, abort planning retries after 5.0 s... max_planning_retries: 0 # ... or after 10 attempts (whichever happens first) oscillation_timeout: -1 # abort controller and trigger recovery behaviors after 30.0 s oscillation_distance: 0.5 -### recovery behaviors -recovery_behavior_enabled: true +## recovery behaviors +# +# Recovery của move_base cũ đã dừng: bộ behavior gen-2 (tick-based) khai ở +# `recovery_behaviors_params.yaml` và do `recovery_core::RecoveryRegistry` nạp, không phải khoá +# `recovery_behaviors` ở đây. +# +# Danh sách gen-1 đã được gỡ hẳn thay vì để lại: các entry cũ trỏ tên alias `RotateRecovery` / +# `ClearCostmapRecovery` vào file .so gen-2, trong khi loader ở đây import theo chữ ký gen-1 +# (`robot_nav_core::RecoveryBehavior`). Boost.DLL không kiểm kiểu qua ranh giới .so, nên hai bên +# không bao giờ gặp nhau ở compile time và lỗi chỉ hiện ra lúc chạy. Giữ lại khoá cũng làm hai file +# config tranh nhau cùng một tên alias. +recovery_behavior_enabled: false recovery_behaviors: [ {name: aggressive_reset, type: ClearCostmapRecovery}, - {name: conservative_reset, type: ClearCostmapRecovery} + {name: conservative_reset, type: ClearCostmapRecovery}, ] conservative_reset: diff --git a/config/mppi_local_planner_params.yaml b/config/mppi_local_planner_params.yaml index 28f8e15..bc90f9d 100644 --- a/config/mppi_local_planner_params.yaml +++ b/config/mppi_local_planner_params.yaml @@ -7,120 +7,92 @@ LocalPlannerAdapter: MPPILocalPlanner: library_path: libmppi_local_planner - # Robot limits [m/s, rad/s, m/s^2, rad/s^2] - max_velocity: 0.5 + # Robot limits [m/s, rad/s] min_velocity: 0.0 - max_y_velocity: 0.0 - min_command_velocity: 0.05 - max_angular_velocity: 1.9 - min_angular_velocity: 0.05 - max_acceleration: 0.5 - max_angular_acceleration: 1.0 - max_vel_trans: 0.5 + # Cao hon reference_velocity mot khoang dem (headroom). Neu de sat ref thi + # nua tren cua nhieu sampling bi clamp o max, keo van toc trung binh xuong + # (do duoc: ref0.45/max0.50 -> chi dat 0.33; max0.65 -> dat 0.41). Robot chay + # duoc >0.6 m/s nen dat 0.65. + max_velocity: 0.65 + max_angular_velocity: 1.0 + robot_radius: 0.30 + obstacle_point_radius: 0.08 + footprint_padding: 0.05 + + # MPPI core + # Horizon = model_dt * time_steps = 3.6 s ~ 1.8 m @0.5 m/s. + # Truoc day 1.4 s (0.7 m) qua ngan: robot chi "thay" vat can khi da sat, khong con + # cho de vong qua -> hoac ket hoac lang nhang. Do thuc te: 0.7m/1.2m khong toi dich; + # 1.8m toi dich voi quang duong chi dai hon 6% so voi duong thang. + # Khong tang dt qua 0.15: dt=0.20 lam dao dong tang gap 4 lan. + model_dt: 0.2 + time_steps: 20 + batch_size: 220 + # So thread OpenMP. De mac dinh (= 16 core) thi tranh chap voi gazebo/rviz/perception + # lam 1 chu ky solveMPPI cham tu 0.9 ms len ~25 ms. + num_threads: 4 + param_lambda: 100.0 + param_alpha: 0.98 + param_exploration: 0.05 vx_std: 0.2 - vy_std: 0.2 - wz_std: 0.4 - motion_model: 0 - min_turning_radius: 0.2 + wz_std: 0.25 + reference_velocity: 0.48 - # Goal tolerance [m, rad] - xy_goal_tolerance: 0.1 - yaw_goal_tolerance: 0.1 - stopped_xy_velocity: 0.03 - stopped_theta_velocity: 0.03 - - # MPPI horizon and global-plan handling - model_dt: 0.05 - time_steps: 56 - batch_size: 1000 - iteration_count: 1 - temperature: 0.3 - gamma: 0.1 - retry_attempt_limit: 10 - regenerate_noises: false - open_loop: false - controller_frequency: 30.0 - prune_distance: 1.5 - max_robot_pose_search_dist: 0.0 + # Path and goal + # Phai lon hon horizon (1.8 m), neu khong terminal goal_weight se keo robot ve + # diem cat cua reference path va lam no giam toc moi chu ky. max_global_plan_lookahead_dist: 3.0 - global_plan_prune_distance: 0.2 - sim_period: 0.1 + xy_goal_tolerance: 0.10 + yaw_goal_tolerance: 0.10 - # Costmap safety - use_costmap_collision_check: true - allow_unknown: true - lethal_cost: 253 - inflation_score_distance: 0.3 - consider_footprint: true + # Costmap and cost weights + obstacle_range: 2.5 + obstacle_cost_threshold: 150 + obstacle_cell_step: 2 + max_obstacle_points: 180 + obstacle_influence_radius: 1.0 + # Cost vat can gio CONG DON tren tung cell (truoc day lay max), nen thang nay phai + # nho hon nhieu. Giu 85 voi che do sum lam cost vot len ~180x85, ap dao moi thanh + # phan khac -> dao dong manh va di vong xa 45%. Do thuc te tai T=24/dt=0.15: + # weight=10 cho dao dong thap nhat va khoang ho 0.48 m (du 13 cm). + obstacle_cost_use_sum: true + obstacle_weight: 10.0 + collision_cost: 1000000.0 + progress_weight: 8.0 + terminal_progress_weight: 20.0 + goal_weight: 30.0 + # Phat v^2: gan 0 vi no truc tiep keo van toc xuong (phan truc giac voi robot + # muon chay nhanh). Giu nho de van co chut smoothing. + linear_control_weight: 0.2 + angular_control_weight: 0.2 + control_change_weight: 1.0 + # Giam toc khi lech huong: ha tu 0.8 xuong 0.3. Truoc day khi ne vat can + # (yaw error lon) robot bo <0.1 m/s. 0.3 van giam toc vao cua nhung khong bo. + yaw_error_slowdown: 0.1 + min_tracking_velocity: 0.08 - # Critic defaults ported from the legacy MPPI dynamic_reconfigure files. - constraint_enabled: true - constraint_power: 1.0 - constraint_weight: 4.0 + # Phat hien ket: MPPI co the tra lenh hop le nhung ~0 mai o cuc tieu dia phuong. + # Qua nguong nay controller bao that bai -> move_base PLANNING roi CLEARING. + stuck_velocity_threshold: 0.03 + stuck_omega_threshold: 0.05 + stuck_patience_cycles: 40 - cost_enabled: true - cost_power: 1.0 - cost_weight: 3.81 - cost_critical_cost: 300.0 - cost_near_collision_cost: 253 - cost_collision_cost: 1000000.0 - cost_near_goal_distance: 1.0 - cost_trajectory_point_step: 2 - - goal_enabled: true - goal_power: 1.0 - goal_weight: 5.0 - goal_threshold_to_consider: 1.4 - - goal_angle_enabled: true - goal_angle_power: 1.0 - goal_angle_weight: 3.0 - goal_angle_threshold_to_consider: 0.5 - - obstacles_enabled: false - obstacles_power: 1.0 - obstacles_weight: 0.0 - obstacles_repulsion_weight: 1.5 - obstacles_collision_cost: 10000.0 - obstacles_collision_margin_distance: 0.1 - obstacles_near_goal_distance: 0.5 - - path_align_enabled: true - path_align_power: 1.0 - path_align_weight: 8.0 - path_align_max_path_occupancy_ratio: 0.07 - path_align_threshold_to_consider: 0.5 - path_align_offset_from_furthest: 20 - path_align_trajectory_point_step: 4 - path_align_use_path_orientations: false - - path_angle_enabled: true - path_angle_power: 1.0 - path_angle_weight: 2.0 - path_angle_max_angle_to_furthest: 1.2 - path_angle_threshold_to_consider: 0.5 - path_angle_offset_from_furthest: 4 - path_angle_mode: 0 - - path_follow_enabled: true - path_follow_power: 1.0 - path_follow_weight: 5.0 - path_follow_threshold_to_consider: 1.4 - path_follow_offset_from_furthest: 6 - - prefer_forward_enabled: true - prefer_forward_power: 1.0 - prefer_forward_weight: 1.0 - prefer_forward_threshold_to_consider: 0.5 - - twirling_enabled: false - twirling_power: 1.0 - twirling_weight: 0.0 - twirling_threshold_to_consider: 0.5 - - velocity_deadband_enabled: false - velocity_deadband_power: 1.0 - velocity_deadband_weight: 0.0 - velocity_deadband_deadband_velocities: [0.0, 0.0, 0.0] - - publish_debug: false + # --- Covariance thich nghi (giai doan 2) --- + # Moi chu ky fit lai do rong nhieu cho TUNG buoc thoi gian tu chinh batch. + # vx_std/wz_std o tren chi con la gia tri khoi tao va gia tri sau reset. + adaptive_covariance: true + gaussian_fitting_lambda: 5.0 # phai < param_lambda de trong so du nhon + # San chon bang thuc nghiem: thap hon -> muot hon nhung cham va sat vat can hon. + min_vx_std: 0.08 + max_vx_std: 0.35 + min_wz_std: 0.10 + max_wz_std: 0.60 + # Khi bi ket, no rong sigma dan qua tung chu ky de thoat cuc tieu dia phuong. + stuck_sigma_inflation: 1.6 + hard_obstacle_cost_threshold: 254 + stage_xy_weight: 60.0 + stage_yaw_weight: 1.0 + stage_speed_weight: 12.0 + terminal_xy_weight: 90.0 + terminal_yaw_weight: 1.0 + terminal_speed_weight: 12.0 \ No newline at end of file diff --git a/config/mprim/mqtt_general.yaml b/config/mprim/mqtt_general.yaml index 1230673..bc22191 100644 --- a/config/mprim/mqtt_general.yaml +++ b/config/mprim/mqtt_general.yaml @@ -1,8 +1,8 @@ -MQTT: - Name: T800 - Host: 172.20.235.170 - Port: 1885 - Client_ID: T800 - Username: robotics - Password: robotics - Keep_Alive: 60 \ No newline at end of file +# MQTT: +# Name: T800 +# Host: 172.20.235.170 +# Port: 1885 +# Client_ID: T800 +# Username: robotics +# Password: robotics +# Keep_Alive: 60 \ No newline at end of file diff --git a/config/priest_local_planner_params.yaml b/config/priest_local_planner_params.yaml new file mode 100644 index 0000000..d2c579c --- /dev/null +++ b/config/priest_local_planner_params.yaml @@ -0,0 +1,56 @@ +PriestLocalPlanner: + library_path: libpriest_local_planner + + # ================= Horizon / optimizer ================= + t_fin: 7.0 # [s] planning horizon + num_steps: 30 # trajectory samples over the horizon + num_batch: 60 # trajectories per CEM iteration + initial_up_sampling: 5 # candidate oversampling factor + ellite_num: 40 # elites ranked by projection residual + num_warm: 20 # warm-started trajectories between cycles + max_proj_iter: 8 # alternating projection iterations + max_cem_iter: 4 # CEM iterations per control cycle + optimizer_threads: 4 # bounded workers; avoid severe overhead from using all CPU cores + solve_time_warn_ms: 30.0 # [ms] leaves margin inside the 30 Hz controller period + lateral_std: 0.8 # [m] std of lateral waypoint perturbations + + # ================= Robot limits (differential drive) ================= + max_velocity: 0.5 # [m/s] forward velocity limit + max_angular_velocity: 0.4 # [rad/s] also enforced inside the optimizer as a + # lateral-acceleration clamp |a_n| <= omega_max * v + max_acceleration: 0.5 # [m/s^2] used in the trajectory projection + reference_velocity: 0.4 # [m/s] desired cruise speed along the path + v_eps: 0.05 # [m/s] below this speed the curvature clamp/cost is skipped + v_min_seed: 0.05 # [m/s] initial-velocity seed along yaw when the robot is stopped + + # Trajectory -> differential (v, omega) conversion with curvature feedforward: + # omega = clamp(omega_traj, +-max_angular_velocity) - heading_gain * heading_error + heading_gain: 1.5 # [1/s] feedback gain on the heading error + heading_error_stop: 1.2 # [rad] above this, rotate in place (v = 0) + min_in_place_yawrate: 0.2 # [rad/s] + + # ================= Goal / plan ================= + xy_goal_tolerance: 0.10 # [m] + yaw_goal_tolerance: 0.10 # [rad] + max_global_plan_lookahead_dist: 3.0 # [m] + + # ================= Obstacles (from local costmap) ================= + num_obs: 40 # obstacles in the CEM cost + num_obs_proj: 30 # closest obstacles inside the projection + obstacle_range: 2.5 # [m] costmap scan radius around the robot + robot_radius: 0.50 # [m] + obstacle_point_radius: 0.08 # [m] + footprint_padding: 0.05 # [m] + obstacle_cost_threshold: 150 + obstacle_cell_step: 2 + max_obstacle_points: 150 + + # ================= Cost weights ================= + weight_smoothness: 0.1 + weight_track: 0.2 + weight_obs: 1.2 + weight_clearance: 3.0 # bounded proximity term in (0,1]: 1 at an obstacle + # centre, 0.5 on the collision boundary, 0 out of range + weight_angular: 0.5 # hinge penalty on |omega| > max_angular_velocity + cem_lamda: 0.9 # CEM temperature + cem_alpha: 0.7 # CEM mean/cov blending factor diff --git a/config/recovery_behaviors_params.yaml b/config/recovery_behaviors_params.yaml new file mode 100644 index 0000000..102dd36 --- /dev/null +++ b/config/recovery_behaviors_params.yaml @@ -0,0 +1,170 @@ +# Bộ recovery behavior (gen-2, tick-based) và tham số vận hành của chúng. +# +# Đây là cây config RUNTIME. Bản dùng cho test của gói nằm ở +# `Test/recovery_core/test/config/recovery_behaviors_params.yaml` — sửa tham số vận hành thì sửa ở +# đây, đừng sửa bản test. +# +# Danh sách này được `recovery_core::RecoveryRegistry` đọc; caller (RecoveryRunner của move_base2) +# truyền namespace `recovery` vào. Khoá `recovery_behaviors:` trong `move_base_common_params.yaml` +# thuộc về move_base cũ và KHÔNG liên quan tới file này. + +recovery: + # `behaviors` là registry mọi plugin/instance CÓ THỂ dùng. Thứ tự ở đây chỉ là thứ tự nạp, + # không còn quyết định luồng chạy. `routes` bên dưới chọn riêng chuỗi theo trigger. + # + # wait : không di chuyển. Vật cản động (người, xe khác) tự đi qua là xong. + # clear : xoá vật cản đã tích trong costmap, gần trước rồi xa sau. + # rotate : quay tại chỗ cho costmap nhìn lại xung quanh. + # back_up: LÙI — hướng robot không có sensor, nên xếp cuối cùng. + behaviors: + - {name: wait, type: WaitRecovery} + - {name: clear, type: ClearCostmapRecovery} + # Đặt schema trước plugin: chưa có `DetourPathRecovery`/library_path thì RecoveryRunner bỏ + # entry này cùng warning, và bỏ nó khỏi từng route. Khi plugin SBPL được thêm sau này, không + # cần sửa move_base2 hay route. + - {name: detour_path, type: DetourPathRecovery} + - {name: rotate, type: RotateRecovery} + - {name: back_up, type: BackUpRecovery} + + # trigger -> tên behavior thử tuần tự; lần lỗi kế tiếp cùng trigger mới tiến tới phần tử tiếp + # theo của route đó. Đường quay về sau khi một behavior kết thúc (contract 2026-08-04b): + # - planning_failed -> quay về PLANNING lập plan lại (không có plan nào để bám); + # - controlling/oscillation-> quay về CONTROLLING bám tiếp GLOBAL PATH CŨ, KHÔNG lập plan lại + # (thay plan trong lúc chạy là việc riêng của planner_frequency); + # riêng khi leo thang từ PLANNING vì mất pose thì về PLANNING; + # - behavior họ detour (output kPath, vd DetourPathRecovery) nộp path mới -> path đó được áp + # và robot bám tiếp — cách duy nhất một recovery được thay plan. + # Robot đi được quá `oscillation_distance` thì mọi cursor route được reset — ngân sách recovery + # đầy lại theo tiến độ thật (2026-08-04). + # + # `controlling_failed` từ 2026-08-04 nghĩa là MẤT DỮ LIỆU/LỆNH: controller không ra lệnh (kể cả + # mất pose) quá controller_patience, hoặc mất pose ngay trong PLANNING. Route chỉ có [wait] là + # chủ đích: đứng yên chờ một nhịp cho dữ liệu quay lại; hết wait mà dữ liệu vẫn chưa về thì + # cursor cạn -> ABORTED, robot dừng hẳn và báo fail; dữ liệu về thì lập plan chạy tiếp. + # `planning_failed` giữ đúng nghĩa "planner CÓ dữ liệu nhưng không tìm được đường". + # `path_blocked` / `off_path` là TUỲ CHỌN: xoá hai dòng đó = tắt giám sát tuyến, runtime chạy y + # như trước 2026-08-04d. Chúng dùng chung `detour_path` nhưng giữ cursor riêng — mỗi nguyên nhân + # một ngân sách, và log phân biệt được vì sao robot dừng. + routes: + planning_failed: [wait, clear] + controlling_failed: [detour_path] + oscillation: [wait] + # Cursor reset (2026-08-05): recovery THÀNH CÔNG + NỘP PATH MỚI (detour) thì cursor của trigger + # đó reset NGAY — lần chắn kế tiếp là sự cố mới, detour được chạy lại. Từ chối/thất bại mới ăn + # vào ngân sách route. Route được phép LẶP behavior nếu muốn cấp thêm lượt thử giữa các nhịp + # wait/nhích-lại-gần. + # + # Cạn route KHÔNG còn nghĩa là ABORT (contract 2026-08-05e): `path_blocked`/`off_path` là DỰ + # BÁO, plan vẫn hợp lệ và controller vẫn ra lệnh được, nên robot bám tiếp plan cũ và trigger bị + # KHOÁ tới khi đi được quá `oscillation_distance`. Đường ABORT hợp lệ duy nhất đi qua + # `controlling_failed` (controller thật sự hết ra lệnh quá controller_patience) hoặc + # `planning_failed`. + path_blocked: [detour_path] + off_path: [detour_path] + + wait: + wait_duration: 3.0 # [s] đợi vật cản động đi qua + + # Xoá vật cản trong vùng vuông cạnh reset_distance quanh robot. + clear: + reset_distance: 3.0 # [m] cạnh vùng xoá + invert_area_to_clear: false # false = xoá BÊN TRONG vùng + affected_maps: both # local | global | both + layer_names: [obstacles] # phải khớp `plugins:` của costmap; sai tên -> log kèm tên layer thật + + rotate: + full_rotation: true # quay đủ 2*pi để costmap thấy toàn bộ xung quanh + angular_speed: 0.4 # [rad/s] độ lớn; dấu do goal.angle quyết định + acc_lim_theta: 0.8 # [rad/s^2] ramp, tránh giật khi có tải + sim_granularity: 0.1 # [rad] bước quét footprint dọc cung lúc start + timeout: 20.0 # [s] lưới cuối nếu robot bị giữ cơ học + + back_up: + backup_distance: 0.1 # [m] quãng lùi mặc định + backup_distance_max: 1.0 # [m] trần cứng, chặn cả goal.distance lẫn param + linear_speed: 0.1 # [m/s] ĐỘ LỚN; dấu âm (lùi) do plugin đặt + acc_lim_x: 0.3 # [m/s^2] + timeout: 15.0 # [s] + + # Lập đường vòng quanh vật cản (gói sbpl_recovery, họ kPath) rồi NỐI LẠI plan hiện hành — đường + # vòng được bám ngay, không replan (contract 2026-08-04b). Chưa nằm trong route nào ở trên: thêm + # `detour_path` vào route cần nó (vd `controlling_failed: [wait, detour_path]`) để kích hoạt. + detour_path: + # Instance planner RIÊNG, không dùng chung SBPLLatticePlanner của backup: detour gọi makePlan + # ĐỒNG BỘ trên control thread, nên `allocated_time` của instance này là trần treo control loop + # mỗi tick. Xem khối SBPLDetourPlanner ở cuối file. + planner_name: SBPLDetourPlanner # namespace param riêng (khối bên dưới) + planner_symbol: SBPLLatticePlanner # alias Boost.DLL CÓ THẬT trong .so — libsbpl_lattice_planner + # chỉ export đúng một symbol này. Khác bộ local planner, nơi + # mỗi biến thể là một class riêng nên tên instance trùng alias. + # "combined" (2026-08-05, vòng 3 — LƯỚI GỘP, xem DETOUR_MERGED_GRID_PLAN.md): snapshot global + # làm nền (tường/kệ tĩnh toàn bản đồ) + đè cửa sổ local lên (vật cản sensor tươi), SBPL lập + # đường TRÊN BẢN CHỤP GỘP — không giữ mutex costmap nào trong lúc search, map update không bị + # bỏ đói dù attempt thua. Một bên báo chắn là chắn; local FREE không xoá tường global. + # Cần planner export capability "ExternalGrid" (sbpl_lattice_planner có sẵn). + # "local" / "global" đơn lẻ vẫn dùng được cho hệ thiếu một trong hai nguồn. + costmap_source: combined + planning_distance: 1.0 # [m] điểm nối cách robot tối thiểu chừng này dọc plan. + # [m] TRẦN quét dọc plan, thuần tuỳ chọn. 0 = quét tới CUỐI PLAN (lưới gộp phủ toàn bản đồ nên + # không còn ràng buộc cửa sổ local). Quét luôn tự dừng ở rìa lưới; hai lần sim 2026-08-05 cap + # hữu hạn (3.8 rồi 8.0) đều cắt quét ngay sau pose bẩn cuối và báo "không có chỗ sạch" oan. + max_rejoin_distance: 0.0 + sample_step: 0.5 # [m] khoảng cách dọc plan giữa hai ứng viên điểm nối + # [m] Điểm nối phải cách pose bẩn gần nhất CẢ HAI PHÍA dọc plan chừng này, và nằm SAU CỤM CHẮN + # ĐẦU TIÊN (không phải pose bẩn cuối toàn tầm — vết bẩn xa trên đuôi plan cũ không được giết + # ứng viên hợp lệ giữa hai vật cản; sim 11:00: `last blocked at 7.96 m` -> refuse oan -> ABORT). + rejoin_clearance: 0.5 + attempts_per_run: 3 # số ứng viên thử tối đa; mỗi control cycle thử MỘT ứng viên + # Tuyến để NỐI LẠI (2026-08-05e). "reference" = tuyến GỐC của chặng, tức plan do planner sinh và + # recovery không thay được: đường vòng luôn quay về tuyến order, và `max_deviation` đo đúng hành + # lang fleet đã duyệt. "current" = plan đang bám (hành vi cũ) — sim đo được tuyến bị ăn mòn dần + # qua từng lượt detour (rejoin 106/305 -> 130/289 -> 132/273) và robot không bao giờ về tuyến. + rejoin_on: reference + # [m] Hành lang lệch tuyến cho phép quanh tuyến gốc của order. 0 = KHÔNG giới hạn — giữ 0 cho + # tới khi biết dung sai thật của fleet master; đặt số mò còn tệ hơn tắt. + max_deviation: 0.0 + timeout: 10.0 # [s] trần lượt + +# Bảng symbol -> thư viện cho Boost.DLL. Thiếu khoá library_path là nguyên nhân phổ biến nhất của +# lỗi "plugin build xong nhưng runtime báo không tìm thấy". +WaitRecovery: + library_path: librecovery_core_wait_recovery + +ClearCostmapRecovery: + library_path: librecovery_core_clear_costmap_recovery + +RotateRecovery: + library_path: librecovery_core_rotate_recovery + +BackUpRecovery: + library_path: librecovery_core_back_up_recovery + +DetourPathRecovery: + library_path: libsbpl_recovery + +# Instance SBPL RIÊNG cho detour — cùng .so với SBPLLatticePlanner, khác tuning. +# +# Vì sao không dùng chung: `DetourPathRecovery::onUpdate` gọi makePlan ĐỒNG BỘ trên control thread, +# nên `allocated_time` ở đây là trần thời gian control loop bị treo mỗi tick — `cancel`/`pause` từ +# host không được xử lý trong khoảng đó. Bản backup để 10.0 s là hợp lý cho vai trò của nó, nhưng +# treo loop 10 s thì không. +# +# `initial_epsilon` lớn = ARA* trả nghiệm đầu rất nhanh, đường dài hơn tối ưu nhưng đây là đường +# vòng tạm — nhanh quan trọng hơn ngắn. +SBPLDetourPlanner: + # KHÔNG có `library_path` ở đây: `SBPLDetourPlanner` không phải symbol, nó chỉ là namespace param. + # Việc nạp .so đi theo `planner_symbol: SBPLLatticePlanner` ở trên. + environment_type: XYThetaLattice + planner_type: ARAPlanner + allocated_time: 0.4 # [s] TRẦN CỨNG cho một tick recovery + initial_epsilon: 2.0 + force_scratch_limit: 10000 + forward_search: true + # false cho DETOUR, khác bản backup: free heading làm mỗi lượt hỏng chạy HAI lần search (log sim: + # "no solution with free start heading, retrying..." = 0.77 s giữ mutex costmap, map update miss + # nhịp). Detour chạy khi robot ĐANG BÁM plan nên heading thật đã xuôi theo tuyến — không cần nới. + free_start_heading: true + nominalvel_mpersecs: 0.3 + timetoturn45degsinplace_secs: 1.31 + # Cùng file .mprim với SBPLLatticePlanner: resolution 0.05 m khớp resolution costmap local. + primitive_filename: /home/duongtd/rl_ws/mir_robot/mir_navigation/mprim/unicycle_highcost_5cm.mprim diff --git a/config/sbpl_global_params.yaml b/config/sbpl_global_params.yaml index c619680..dc4d1c0 100644 --- a/config/sbpl_global_params.yaml +++ b/config/sbpl_global_params.yaml @@ -6,6 +6,10 @@ SBPLLatticePlanner: initial_epsilon: 1.0 force_scratch_limit: 10000 forward_search: true + # Bỏ ràng buộc heading xuất phát: local planner đã có bước quay tại chỗ đầu path + # (turn_around_priority) nên không cần SBPL vẽ cung quay đầu khi goal ở phía sau. + # Nếu không ra nghiệm, planner tự retry một lần với heading thật của robot. + free_start_heading: true nominalvel_mpersecs: 0.3 timetoturn45degsinplace_secs: 1.31 # = 0.6 rad/s - primitive_filename: /home/duongtd/T800_ws/src/AMR_T800/Test/sbpl_lattice_planner/matlab/mprim/unicycle_highcost_5cm.mprim \ No newline at end of file + primitive_filename: /home/duongtd/rl_ws/mir_robot/mir_navigation/mprim/unicycle_highcost_5cm.mprim \ No newline at end of file diff --git a/config/stanley_local_planner_params.yaml b/config/stanley_local_planner_params.yaml index 494379c..5cc1a76 100644 --- a/config/stanley_local_planner_params.yaml +++ b/config/stanley_local_planner_params.yaml @@ -1,14 +1,115 @@ LocalPlannerAdapter: library_path: liblocal_planner_adapter - yaw_goal_tolerance: 0.017 - xy_goal_tolerance: 0.03 + yaw_goal_tolerance: 0.017 + xy_goal_tolerance: 0.03 min_approach_linear_velocity: 0.06 StanleyLocalPlanner: - # Algorithm library_path: libstanley_local_planner -StanleyDockingLocalPlanner: - # Algorithm + # ================= Robot limits ================= + max_vel_x: 0.40 # [m/s] forward, > 0 + min_vel_x: -0.25 # [m/s] reverse, < 0 + wheel_base: 0.0 # [m] 0 = derive from TF front_axle_frame -> rear_axle_frame + front_axle_frame: "steer_link" + rear_axle_frame: "base_link" + + # Two SEPARATE steering limits. + # Path tracking must not use a large angle: forward_vel_ scales with cos(delta) so it + # collapses to speed_base, and vel_steer = v/cos(steer) is guarded to 0 as cos -> 0. + # Pivoting in place uses the full 90 deg the hardware has. + steer_limit_standstill: 1.5708 # [rad] TO BE MEASURED - ceiling at |v| ~ 0 + steer_limit_at_max_vel: 0.5000 # [rad] TO BE MEASURED - ceiling at |v| = max_vel_x + align_steer_angle: 1.5708 # [rad] steering while pivoting. Literal number, NOT M_PI/2 + min_steer_angle: 0.20 # [rad] threshold for "steering is engaged" + max_steer_rate: 0.90 # [rad/s] TO BE MEASURED - steering servo slew + + # ================= Goal tolerance ================= + xy_goal_tolerance: 0.030 # [m] should match LocalPlannerAdapter + yaw_goal_tolerance: 0.020 # [rad] + goal_sq_dist_tol: 0.05 # [m^2] early exit of the closest-point scan + + # ================= Control law (Stanley) ================= + path_yaw_mode: "tangent" # tangent | bearing - "bearing" is the old behaviour, kept for rollback + control_gain_e: 2.0 # heading gain (path tangent - robot yaw) + control_gain_d: 1.0 # base cross-track gain + gain_cte_weight: 0.8 # added to k per |cross-track error| [1/m] + gain_heading_weight: 0.5 # added to k per |heading error| [1/rad] + gain_min: 0.5 # lower clamp of k + gain_max: 1.8 # upper clamp of k + soft_min_vel: 0.20 # [m/s] FLOOR of the atan2(k*e, v) denominator. NO ceiling + alpha_gain: 0.0 # steering low-pass [0..1]; 0 = off, max_steer_rate is used instead + curve_gain_e_bonus: 2.0 # added to control_gain_e in curve mode + tangent_window_pts: 3 # points averaged for the tangent when the plan carries no yaw + + # ================= Steering bias (kills the steady-state offset) ================= + # Enable when the robot tracks parallel to the global path because of a mechanical + # zero offset or an IMU bias. Start at 0 and raise by 0.005 per trial. + steer_bias_gain: 0.0 # [rad/(m*s)] 0 = OFF. Suggested when enabled: 0.02 + steer_bias_clamp: 0.05 # [rad] anti-windup ceiling + steer_bias_decay: 0.995 # per-cycle bleed when the integrate conditions do not hold + steer_bias_min_vel: 0.30 # [m/s] below this, do not integrate + steer_bias_max_heading_err: 0.10 # [rad] above this, do not integrate + + # ================= Plan window / lookahead ================= + max_global_plan_lookahead_dist: 3.0 # [m] window ceiling + min_lookahead: 0.50 # [m] window floor + min_lookahead_near_goal: 0.40 # [m] separate floor near the goal + dyn_lookahead_gain: 2.50 # [m/(m/s)] lookahead = min + gain*|v| + near_goal_freeze_dist: 0.50 # [m] below this: freeze yaw_path, run theta_d only + + # Index continuity thresholds, given in METRES and converted to indices with the + # point spacing measured at runtime - the plan resolution is the global planner's + # choice, not a constant. + # The old code used fixed indices (back=3, fwd=15 ~ 0.75 m on a 0.05 m/point plan) and + # therefore never fired: at 1.2 m/s the robot covers 0.04 m = 0.8 index per 33 ms cycle. + # Applied to BOTH closest (window anchor) and target_idx_ (inside the core). + max_advance_dist: 0.20 # [m] forward travel allowed along the plan per cycle + max_back_dist: 0.10 # [m] backward travel allowed along the plan per cycle + + # ================= Curvature ================= + high_curvature: 0.30 # [1/m] above: shrink lookahead + mid_curvature: 0.20 # [1/m] above: cut the transform window + low_curvature: 0.10 # [1/m] above: enter curve mode + straight_confirm_steps: 110 # consecutive straight cycles before leaving curve mode + + # ================= Speed profile ================= + speed_base: 0.30 # [m/s] base of the cosine steering profile + curve_max_speed: 0.25 # [m/s] ceiling while curving + min_drive_speed: 0.07 # [m/s] floor while driving + accel_distance: 2.00 # [m] ramp length after leaving a curve + decel_min: 0.05 # [m/s per cycle] deceleration on predicted collision + decel_max: 0.10 # [m/s per cycle] + collision_horizon_factor: 2.0 # multiplies max_vel_x to get the collision check distance + + # ================= Align / phase ================= + heading_eps: 0.020 # [rad] heading error accepted as aligned + steer_eps: 0.020 # [rad] steering error accepted as "servo arrived" + heading_align_tol: 0.050 # [rad] gate for the final straight-line approach (was 0.01 = too tight) + near_goal_dist: 1.00 # [m] below this: enable the final straight mode + steer_realign_off: 0.503 # [rad] above this: CUT drive (0.16*pi) + steer_realign_on: 0.150 # [rad] below this: RESUME drive - must be smaller than _off + steering_active: 0.094 # [rad] above this the steering counts as active (0.03*pi) + segment_transition_threshold: 0.010 # [m] + segment_end_ratio: 0.05 # fraction of the segment left before advancing + xy_reached_gate_factor: 3.0 # multiplies xy_goal_tolerance; a 1-point window may only latch inside this + + # ================= TF guard ================= + # Measured on the robot: 225 map->odom jumps, max 12.381 m, coinciding with the + # localisation FinishTrajectory(1) 10:41:18 / AddTrajectory(2) 10:41:21. The source is + # outside this package; this is containment, not a cure. + tf_lookup_at_pose_stamp: true # true = look up at pose.header.stamp instead of "latest". + # "latest" returns a different entry each call when the + # buffer holds two map->odom transforms + transform_tolerance: 0.20 # [s] accepted age when looking up by timestamp + max_plan_tf_jump_rate: 0.60 # [m/s] threshold as a RATE, multiplied by the real elapsed time + max_plan_tf_yaw_jump: 0.20 # [rad] rotation threshold - the old code checked translation only + tf_reject_window_cycles: 30 # sliding window; exceeding it means a real relocalisation + tf_reject_ratio: 0.5 # reject fraction inside the window that triggers the reset + + # ================= Debug ================= + debug_level: 1 # 0=off 1=on state change 2=throttled 1 Hz 3=every cycle + # 3 produces >2000 lines/min at 30 Hz - field debugging only + +StanleyDockingLocalPlanner: library_path: libstanley_local_planner - \ No newline at end of file diff --git a/src/APIs/c_api/NAV_C_API_2_GUIDE.md b/src/APIs/c_api/NAV_C_API_2_GUIDE.md new file mode 100644 index 0000000..71fbf3d --- /dev/null +++ b/src/APIs/c_api/NAV_C_API_2_GUIDE.md @@ -0,0 +1,859 @@ +# `nav_c_api_2` — hướng dẫn cho khung C# + +Tài liệu cho phía host .NET/C# khi chuyển nền navigation từ `libmove_base.so` sang +`libmove_base2.so`. + +Bám sát mã nguồn tại thời điểm viết: +`pnkx_nav_core/src/APIs/c_api`, `Test/move_base2`, `pnkx_nav_core/src/Navigations/Packages/move_base` +(bản cũ, dùng để đối chiếu). + +--- + +## 0. Đọc nhanh — 8 việc phải làm ở phía C# + +| # | Việc | Vì sao | +|---|---|---| +| 1 | Gọi `navigation_add_static_map` **trước** `navigation_initialize` | Planner lattice chặn tới khi costmap có kích thước khác 0, và tự `exit(1)` khi chờ quá lâu — giết cả tiến trình | +| 2 | Gọi `navigation_set_robot_footprint` **trước** `navigation_initialize` | Bản cũ gọi trước là rơi mất; bản mới cache lại và áp đúng lúc dựng costmap | +| 3 | Thay `navigation_initialize` bằng `navigation_initialize_checked` | Hàm cũ luôn trả `true`, kể cả khi lõi dựng hỏng | +| 4 | Thêm `navigation_shutdown` vào đường tắt, **trước** `navigation_destroy` | Bản mới có control thread + thread costmap + thread mission đang chạy | +| 5 | Bỏ mọi suy đoán từ giá trị trả về của `navigation_set_twist_linear/_angular` | Giờ luôn trả `true` nếu số hợp lệ; tín hiệu "đang cancel" của bản cũ không còn | +| 6 | Bỏ mọi so sánh chuỗi `feed_back_str`, chuyển sang so enum | Nội dung chuỗi do lõi mới đặt, khác hoàn toàn bản cũ | +| 7 | Không coi `navigation_pause` trả về là robot đã dừng | Lệnh chỉ được ghi nhận, có hiệu lực ở cycle sau (≤ 33 ms @ 30 Hz) | +| 8 | Gọi các hàm `navigation_free_*` mới sau mỗi getter cấp bộ nhớ | Trước đây không có hàm giải phóng nào cho grid/scan/cloud/plan — mỗi lời gọi rò một lần | + +Ba việc **nên** làm thêm: dùng `navigation_get_state` thay cho `navigation_get_feedback` ở vòng poll +(không cấp phát chuỗi); dùng `navigation_add_depth_camera_data` để bật clear theo frustum; dùng +`navigation_move_to_order_v2` nếu fleet master có gửi order update. + +--- + +## 1. Bố cục — và các hàm cũ nằm ở đâu + +**Một thư viện `.so` duy nhất.** `nav_c_api_2` không phải một thư viện khác, không phải một handle +khác, không phải một tầng bọc. Nó là thêm file nguồn vào **cùng** thư viện đó. + +``` +libnav_c_api.so +├── nav_c_api.cpp → 50 hàm cũ (không sửa, không dịch lại, không bọc) +├── convertor.cpp → order_free +├── nav_c_api_2.cpp → 13 hàm mới +└── convertor_2.cpp → converter cho depth camera +``` + +64 symbol, cùng một `.so`, không hàm nào trùng tên hàm nào. + +**Vậy các hàm không đổi thì C# gọi thế nào? Y hệt hôm nay, không sửa một dòng.** Cùng +`DllImport("nav_c_api")`, cùng tên symbol, cùng chữ ký, cùng struct. C# không dùng file header — +P/Invoke nối theo **tên symbol** trong `.so`, mà tên đó không đổi. Lớp binding hiện có tiếp tục chạy +nguyên trạng. + +Cái C# phải thêm chỉ là **13 `DllImport` mới + 4 struct mới** (phụ lục B). Cái C# phải *sửa* là hành +vi, không phải khai báo — đúng 8 việc ở mục 0. + +Hai header chỉ dành cho bên gọi C/C++: + +| File | Nội dung | +|---|---| +| `include/nav_c_api.h` | Bề mặt cũ. Không đổi chữ ký hàm nào. | +| `include/nav_c_api_2.h` | Phần thêm. `#include` luôn `nav_c_api.h`, nên bên gọi C/C++ chỉ cần include file này. | + +Tên thư viện sinh ra là `libnav_c_api.so` (target `nav_c_api`), nên phía C# là +`[DllImport("nav_c_api")]`. Tài liệu cũ có chỗ ghi `libnavigation_c_api.so` — kiểm tra lại chuỗi +khung hiện tại đang dùng. + +Mọi hàm dùng `CallingConvention.Cdecl`. `bool` của C++ là 1 byte, phải khai +`[return: MarshalAs(UnmanagedType.I1)]`. `size_t` trên Linux x64 là 8 byte — dùng `UIntPtr`. + +--- + +## 2. Điều kiện vận hành trước khi chạy + +| Việc | Giá trị | +|---|---| +| `PNKX_NAV_CORE_CONFIG_DIR` | Trỏ vào `Test/move_base2/config/runtime` — **không** phải `pnkx_nav_core/config` | +| YAML chọn plugin | `MoveBase: library_path: libmove_base2` (đã có sẵn trong `move_base_common_params.yaml`) | +| Đường tìm `.so` | `libmove_base2.so` và toàn bộ plugin planner/recovery/costmap phải nằm trong `PNKX_NAV_CORE_LIBRARY_PATH`, `devel/lib` hoặc `LD_LIBRARY_PATH` | +| Nhịp control loop | `controller_frequency: 30.0` — mọi độ trễ "một cycle" nói trong tài liệu này là ~33 ms | + +`navigation_create()` tra symbol `"MoveBase"`. `move_base2` export cả `MoveBase` lẫn `MoveBase2`, nên +đổi runtime chỉ tốn một dòng YAML, không phải sửa C#. + +--- + +## 3. Trình tự khởi tạo + +Thứ tự này **bắt buộc**, không phải khuyến nghị. Sai thứ tự ở bước 3 làm chết cả tiến trình. + +``` +1. tf3_buffer_create() → có buffer TF +2. navigation_create() → nạp libmove_base2.so, chưa chạy gì +3. bơm TF liên tục vào buffer → bắt đầu NGAY, chạy suốt vòng đời +4. navigation_set_robot_footprint() → trước initialize +5. navigation_add_static_map("/map", ...) → BẮT BUỘC trước initialize +6. navigation_initialize_checked() → nặng, chặn, tự start control thread +7. kiểm tra kết quả trả về → false thì đọc navigation_get_status_text() +8. bắt đầu vòng bơm sensor định kỳ +9. từ đây mới gửi goal +``` + +```csharp +// ---- 1..2 ------------------------------------------------------------------------------- +tfHandle = tf3_buffer_create(); +navHandle = navigation_create(); +if (navHandle == IntPtr.Zero) + throw new InvalidOperationException("navigation_create failed — kiểm tra library_path của MoveBase"); + +// ---- 3 ---------------------------------------------------------------------------------- +// TF phải chảy TRƯỚC initialize: costmap lấy pose robot ngay trong chu kỳ cập nhật đầu tiên. +StartTfPump(); + +// ---- 4 ---------------------------------------------------------------------------------- +// Footprint theo chiều ngược kim đồng hồ, toạ độ trong frame base_link, đơn vị mét. +var footprint = new[] +{ + new Point { x = 0.3, y = -0.2, z = 0.0 }, + new Point { x = 0.3, y = 0.2, z = 0.0 }, + new Point { x = -0.3, y = 0.2, z = 0.0 }, + new Point { x = -0.3, y = -0.2, z = 0.0 }, +}; +navigation_set_robot_footprint(navHandle, footprint, (UIntPtr)footprint.Length); + +// ---- 5 ---------------------------------------------------------------------------------- +// Tên "/map" phải khớp map_topic trong costmap_common_params.yaml. +navigation_add_static_map(navHandle, "/map", occupancyGrid); + +// ---- 6..7 ------------------------------------------------------------------------------- +// Chặn hàng giây: dựng 2 costmap, nạp planner/controller/recovery, dựng mission layer, +// start control thread. Không gọi từ UI thread. +if (!navigation_initialize_checked(navHandle, tfHandle)) +{ + IntPtr reason = navigation_get_status_text(navHandle); + string text = Marshal.PtrToStringAnsi(reason) ?? "unknown"; + nav_c_api_free_string(reason); + throw new InvalidOperationException($"navigation core not ready: {text}"); +} + +// ---- 8..9 ------------------------------------------------------------------------------- +StartSensorPumps(); +``` + +**Vì sao static map phải đi trước.** `initialize()` nạp planner ở pha hai. +`SBPLLatticePlanner::initialize` chặn tới khi costmap báo kích thước khác 0, mà kích thước đó chỉ có +khi một static map đã tới `StaticLayer`. Nạp planner trước khi map vào được là khoá chết: planner chờ +map, map chờ planner xong. SBPL `exit(1)` sau 2 giây. `move_base2` xử lý bằng cách cất static map đã +nhận rồi **phát lại** ngay trước khi nạp planner — nhưng nó chỉ phát lại được cái host đã gửi. + +**Về `map_save_` / `map_name_save_`.** Hai biến public đó là cách bản cũ bù cho đúng vấn đề trên. Với +`move_base2` host **không cần** đụng tới chúng. + +--- + +## 4. Bơm dữ liệu: cái gì, tên gì, tần số nào + +Tên truyền vào các hàm `navigation_add_*` phải khớp **giá trị `topic`** khai trong +`Test/move_base2/config/runtime/costmap_common_params.yaml`, không phải khoá của observation source. +Sai tên thì dữ liệu được nhận rồi bị bỏ ở tầng layer, im lặng. + +| Dữ liệu | Hàm | Tên (`topic` trong YAML) | Tần số | Bắt buộc | +|---|---|---|---|---| +| Bản đồ tĩnh | `navigation_add_static_map` | `/map` | Khi bản đồ đổi | **Có** — và trước `initialize` | +| Laser sau | `navigation_add_laser_scan` | `/b_scan` | Theo nguồn (~10–40 Hz) | Có, nếu dùng laser | +| Point cloud depth | `navigation_add_point_cloud2` | `/camera/depth/points_proc` | Theo camera | Tuỳ cấu hình | +| Point cloud depth phải | `navigation_add_point_cloud2` | `/camera_right/depth/points_proc` | Theo camera | Tuỳ cấu hình | +| Depth camera (clear frustum) | `navigation_add_depth_camera_data` | `/camera/depth/data` | Theo camera (~10–15 Hz) | Cần nếu muốn clear ghost | +| Depth camera phải | `navigation_add_depth_camera_data` | `/camera_right/depth/data` | Theo camera | Cần nếu muốn clear ghost | +| Odometry | `navigation_add_odometry` | tên tự do | Theo nguồn odometry | **Có** | +| TF | qua `tf3` buffer, không qua API này | — | Liên tục | **Có** | + +Ghi chú quan trọng: + +- **Odometry giờ là dữ liệu điều khiển, không phải dữ liệu hiển thị.** `move_base2` lấy vận tốc đo + được từ đó và đẩy xuống controller mỗi cycle. Bơm thưa hoặc bỏ qua là controller mất feedback vận + tốc. +- **Nguồn `/camera/depth/data` khai `data_type: DepthCameraData` và `frustum_clearing_enabled: true`.** + Chỉ `navigation_add_depth_camera_data` đẩy vào được nguồn này. Point cloud không thay thế được — + không có intrinsics thì không dựng được frustum, không clear được. +- **Không bơm nhanh hơn nguồn thật.** Đường depth tốn CPU nhất trong các đường sensor. +- **Toàn bộ đường sensor không thread-safe.** Xem mục 8. + +--- + +## 5. Trình tự tắt + +```csharp +public void Dispose() +{ + // 1. Dừng MỌI thread C# đang gọi navigation_add_* và đợi chúng thoát hẳn. + sensorCts.Cancel(); + Task.WaitAll(sensorTasks, TimeSpan.FromSeconds(2)); + + // 2. Quiesce lõi khi tiến trình còn sống đầy đủ. Trả về trong khoảng 1 giây. + // Sau bước này lõi không phát lệnh vận tốc nữa, nhưng getter vẫn gọi được. + navigation_shutdown(navHandle); + + // 3. Thả instance. + navigation_destroy(navHandle); + navHandle = IntPtr.Zero; + + // 4. Buffer TF sau cùng — lõi còn tham chiếu nó cho tới hết bước 3. + tf3_buffer_destroy(tfHandle); + tfHandle = IntPtr.Zero; +} +``` + +Không được đảo bước 1 và 2, và không được để `navigation_destroy` chạy trong finalizer/GC: thời điểm +đó do runtime .NET quyết định, có thể rơi vào lúc nó đã tháo dỡ một phần trong khi control thread vẫn +đang chạy. + +--- + +## 6. Tham chiếu từng hàm + +Ký hiệu cột "Đổi so với bản cũ": **=** giữ nguyên · **~** cùng chữ ký, khác hành vi · **+** hàm mới. + +### 6.1. Vòng đời + +| | Hàm | Đổi | +|---|---|---| +| | `NavigationHandle navigation_create(void)` | = | + +Nạp `libmove_base2.so` qua symbol `MoveBase` và tạo một instance. Trả `NULL` khi không tìm được +library (sai `library_path`, sai `PNKX_NAV_CORE_CONFIG_DIR`, hoặc `.so` không nằm trong đường tìm). +Chưa chạy thread nào. + +| | Hàm | Đổi | +|---|---|---| +| | `bool navigation_initialize(NavigationHandle, TFListenerHandle)` | ~ | + +Dựng costmap, nạp planner/controller/recovery, dựng mission layer, start control thread. **Chặn**, +tốn hàng giây. **Luôn trả `true`** — contract bên dưới trả `void` nên không có gì để trả về. Dùng +`navigation_initialize_checked` thay thế. + +| | Hàm | Đổi | +|---|---|---| +| | `bool navigation_initialize_checked(NavigationHandle, TFListenerHandle)` | + | + +Như trên, nhưng đọc lại cờ sẵn sàng của lõi và trả về đúng kết quả thật. Trả `false` khi bất kỳ pha +nào hỏng: dựng costmap, cấu hình sensor, nạp plugin, cấu hình control loop, start control thread. +Lý do cụ thể lấy bằng `navigation_get_status_text`. + +| | Hàm | Đổi | +|---|---|---| +| | `bool navigation_is_ready(NavigationHandle)` | + | + +Lõi đã sẵn sàng nhận goal chưa. Rẻ, poll được. Không cấp phát gì. + +| | Hàm | Đổi | +|---|---|---| +| | `void navigation_shutdown(NavigationHandle)` | + | + +Dừng control thread, thread cập nhật costmap và thread mission — **không huỷ instance**. Sau lời gọi +này mọi getter vẫn an toàn. Idempotent. Không ném exception ra ngoài biên C. + +| | Hàm | Đổi | +|---|---|---| +| | `void navigation_destroy(NavigationHandle)` | ~ | + +Thả instance. Bản cũ gọi thẳng là chấp nhận được vì nó không override `shutdown()`. Bản mới **phải** +gọi `navigation_shutdown` trước. + +### 6.2. Trạng thái và phản hồi + +| | Hàm | Đổi | +|---|---|---| +| | `bool navigation_get_feedback(NavigationHandle, NavFeedback &out)` | ~ | + +Trả trạng thái, chuỗi mô tả, pose 2D hiện tại, cờ `goal_checked`, cờ `is_ready`. + +- `feed_back_str` được `strdup`, **phải** giải phóng bằng `nav_c_api_free_string`. +- **Nội dung `feed_back_str` khác bản cũ** — là chuỗi lý do của control loop mới. Chỉ dùng để log. +- `navigation_state` là nguồn duy nhất nên rẽ nhánh. +- Giữa hai chặng của một order nhiều node, lõi ở `SUCCEEDED`/`PENDING` nhưng API **cố ý báo `ACTIVE`**. + Nhờ vậy suy "order xong" từ `SUCCEEDED` vẫn đúng — đừng tìm cách đi vòng qua lớp che này. + +| | Hàm | Đổi | +|---|---|---| +| | `bool navigation_get_state(NavigationHandle, NavigationState *out)` | + | + +Chỉ lấy enum trạng thái, không cấp phát chuỗi. Dùng cho vòng poll. `navigation_get_feedback` gọi ở +10 Hz nghĩa là 10 lần `strdup` + 10 lần `free` mỗi giây, và một lần quên `free` là một lần rò. + +| | Hàm | Đổi | +|---|---|---| +| | `char *navigation_get_status_text(NavigationHandle)` | + | + +Chuỗi mô tả của lõi, hoặc `NULL`. Giải phóng bằng `nav_c_api_free_string`. Chỉ để log — nội dung +không phải hợp đồng. + +| | Hàm | Đổi | +|---|---|---| +| | `char *navigation_state_to_string(NavigationState)` | = | + +Tên trạng thái dạng chuỗi. Giải phóng bằng `nav_c_api_free_string`. (Hàm này có export nhưng chưa +được khai báo trong `nav_c_api.h` — khai báo thủ công phía C# nếu cần.) + +### 6.3. Footprint + +| | Hàm | Đổi | +|---|---|---| +| | `bool navigation_set_robot_footprint(NavigationHandle, const Point *pts, size_t n)` | ~ | + +Đặt hình robot, toạ độ trong frame `base_link`, đơn vị mét, thứ tự ngược kim đồng hồ. + +- **Bản cũ:** áp ngay vào hai costmap; gọi trước `initialize` thì **rơi mất im lặng**. +- **Bản mới:** ghi nhận rồi áp trong `initialize` và ở cycle sau nếu đổi. **Nên gọi trước + `initialize`** để planner đầu tiên thấy đúng hình robot. + +| | Hàm | Đổi | +|---|---|---| +| | `bool navigation_get_robot_footprint(NavigationHandle, Point *out, size_t &out_count)` | ~ | + +- **Bản cũ:** trả footprint của costmap — có giá trị (từ YAML) kể cả khi host chưa từng set. +- **Bản mới:** trả đúng cái host đã set. **Rỗng nếu host chưa gọi `set_robot_footprint`.** + +Cảnh báo về chữ ký: mảng do bên gọi cấp mà **không có tham số dung lượng** — hàm không biết mảng có +đủ chỗ không. Cấp dư (ví dụ 64 điểm) khi gọi. + +### 6.4. Lệnh di chuyển + +Tất cả trả `true` khi lệnh được nhận, không phải khi robot tới nơi. Theo dõi kết quả bằng +`navigation_get_state`. + +| | Hàm | Đổi | +|---|---|---| +| | `bool navigation_move_to(NavigationHandle, PoseStamped goal)` | ~ | + +Đi tới một pose. Quaternion không hợp lệ bị từ chối ngay tại API. Trong `move_base2` goal này đi qua +mission layer như một mission một chặng, để dùng chung đường huỷ và vòng đời với order VDA5050; mission +layer tắt thì rơi xuống đường trực tiếp. + +Dung sai `xy`/`yaw` đến từ profile trong YAML, không đặt được theo từng goal (bản cũ có tham số dung +sai trong contract nhưng `c_api` chưa bao giờ truyền). + +| | Hàm | Đổi | +|---|---|---| +| | `bool navigation_move_to_order(NavigationHandle, Order order, PoseStamped goal)` | ~ | + +Gửi order VDA5050 đầy đủ. Trong `move_base2` order được **cắt thành từng chặng** tại các node có +action, lọc theo cờ `released`, và nối tiếp được khi fleet master release thêm horizon. `orderId` và +`orderUpdateId` là định danh order ở tầng mission — điền đúng. + +Nếu `Order` lấy từ `convert2COrder()` thì gọi `order_free()` khi xong. + +| | Hàm | Đổi | +|---|---|---| +| | `bool navigation_move_to_nodes_edges(NavigationHandle, const Node*, size_t, const Edge*, size_t, PoseStamped)` | ~ | + +Tiện ích: gửi order chỉ từ mảng node/edge. **Không đặt được `orderId`/`orderUpdateId`** — cả hai để +rỗng/0, nên mission layer không phân biệt được order update với order mới. Dùng +`navigation_move_to_order_v2` nếu cần order update. + +> Bản trước của hàm này dựng `Order` **không khởi tạo**, khiến bộ chuyển đổi đọc con trỏ rác trên +> stack. Đã sửa. Nếu khung C# đang chạy với `.so` cũ và thấy crash ngẫu nhiên hoặc chuỗi vô nghĩa ở +> đường order, đây là nguyên nhân. + +| | Hàm | Đổi | +|---|---|---| +| | `bool navigation_move_to_order_v2(NavigationHandle, const char *order_id, uint32_t order_update_id, const Node*, size_t, const Edge*, size_t, PoseStamped)` | + | + +Như trên nhưng có định danh thật. Quy ước: cùng `order_id` + `order_update_id` tăng dần = cập nhật +tuyến đang chạy; đổi `order_id` = order mới thay thế hoàn toàn. `order_id` rỗng bị từ chối. + +| | Hàm | Đổi | +|---|---|---| +| | `bool navigation_dock_to(NavigationHandle, const char *marker, PoseStamped goal)` | = | +| | `bool navigation_dock_to_order(NavigationHandle, Order, const char *marker, PoseStamped)` | = | +| | `bool navigation_dock_to_nodes_edges(...)` | ~ (cùng vấn đề `Order`, đã sửa) | +| | `bool navigation_dock_to_order_v2(NavigationHandle, const char *marker, const char *order_id, uint32_t, const Node*, size_t, const Edge*, size_t, PoseStamped)` | + | + +Docking dùng profile riêng (`docking_planner_name`) và tên marker. Docking **không** đi qua mission +layer — nó xuống thẳng lõi. + +| | Hàm | Đổi | +|---|---|---| +| | `bool navigation_move_straight_to(NavigationHandle, double distance)` | = | + +Đi thẳng theo hướng hiện tại. Tham số là **khoảng cách [m]**, không phải pose: hàm tự đọc pose robot +rồi tính goal. Âm là lùi. Vì nó đọc pose ngay lúc gọi nên TF phải sẵn sàng. + +| | Hàm | Đổi | +|---|---|---| +| | `bool navigation_rotate_to(NavigationHandle, PoseStamped goal)` | = | + +Quay tại chỗ tới hướng của `goal` (chỉ dùng phần orientation). + +### 6.5. Vòng đời nhiệm vụ + +| | Hàm | Đổi | +|---|---|---| +| | `void navigation_pause(NavigationHandle)` | ~ | +| | `void navigation_resume(NavigationHandle)` | ~ | +| | `void navigation_cancel(NavigationHandle)` | ~ | + +- **Bản cũ:** đồng bộ, có hiệu lực ngay trong lời gọi; ném `std::runtime_error` nếu lõi chưa dựng + xong (C API nuốt, C# thấy im lặng). +- **Bản mới:** chỉ ghi nhận yêu cầu; control thread áp ở cycle kế tiếp (≤ 33 ms @ 30 Hz). Không bao + giờ ném. + +Hệ quả: **trả về ≠ robot đã dừng.** Muốn biết đã dừng, chờ `navigation_get_state` báo `PAUSED`, hoặc +theo dõi `navigation_get_twist`. Nếu C# có tầng an toàn giả định dừng tức thì thì phải sửa ở phía C#. + +`cancel` từ host huỷ **cả order** (gồm hàng đợi mission), khác với huỷ nội bộ do chính mission layer +phát ra chỉ dừng chặng đang chạy. + +### 6.6. Trần vận tốc + +| | Hàm | Đổi | +|---|---|---| +| | `bool navigation_set_twist_linear(NavigationHandle, double x, double y, double z)` | ~ | +| | `bool navigation_set_twist_angular(NavigationHandle, double x, double y, double z)` | ~ | + +**Đây là trần vận tốc, không phải lệnh jog.** Đường này để tầng an toàn hạ tốc độ robot. + +- **Dấu của `x` tuyến tính chọn chiều**: `x < 0` đặt trần lùi, còn lại đặt trần tiến. Hai trần được + giữ riêng. +- Đơn vị: tuyến tính `[m/s]`, góc `[rad/s]`. +- `NaN`/`Inf` bị từ chối, trả `false`. +- Có hiệu lực ở cycle kế tiếp. +- **Bản cũ** đẩy thẳng xuống controller và trả `false` khi đang có cancel (kèm `unlock()` nội bộ). + **Bản mới** chỉ kiểm tra số: giá trị hợp lệ luôn trả `true`. Tín hiệu "đang cancel" **không còn tồn + tại** — C# nào dựa vào nó phải chuyển sang đọc trạng thái. + +### 6.7. Truy vấn pose và vận tốc + +| | Hàm | Đổi | +|---|---|---| +| | `bool navigation_get_robot_pose_stamped(NavigationHandle, PoseStamped &out)` | = | +| | `bool navigation_get_robot_pose_2d(NavigationHandle, Pose2D &out)` | = | + +Pose robot trong global frame. Trả `false` khi TF chưa đủ. Bản `PoseStamped` cấp `frame_id` bằng +`strdup` — giải phóng bằng `nav_c_api_free_string`. + +| | Hàm | Đổi | +|---|---|---| +| | `bool navigation_get_twist(NavigationHandle, Twist2DStamped &out)` | ~ | + +**Lệnh vận tốc đang phát**, không phải vận tốc đo được. Đây là thứ host publish ra `cmd_vel`. + +Bản mới có cửa ân hạn: khi không có yêu cầu nào chạy, **stamp đứng yên**; stamp bằng 0 nghĩa là lõi +chưa từng điều khiển. C# nên kiểm tra stamp trước khi publish, tránh đè lên teleop. + +`out.header.frame_id` được `strdup` — giải phóng bằng `nav_c_api_free_string`. + +### 6.8. Bơm dữ liệu sensor vào + +| | Hàm | Đổi | +|---|---|---| +| | `bool navigation_add_static_map(NavigationHandle, const char *name, OccupancyGrid)` | ~ | +| | `bool navigation_add_laser_scan(NavigationHandle, const char *name, LaserScan)` | = | +| | `bool navigation_add_point_cloud(NavigationHandle, const char *name, PointCloud)` | = | +| | `bool navigation_add_point_cloud2(NavigationHandle, const char *name, PointCloud2)` | = | +| | `bool navigation_add_odometry(NavigationHandle, const char *name, Odometry)` | ~ | +| | `bool navigation_add_depth_camera_data(NavigationHandle, const char *topic, DepthCameraData)` | + | + +Chung cho cả nhóm: dữ liệu được **copy** ngay trong lời gọi, buffer C# giải phóng được ngay sau khi +hàm trả về. `name` phải khớp `topic` trong YAML costmap. + +- `navigation_add_static_map`: gọi được **trước** `initialize`, và bắt buộc phải thế (mục 3). +- `navigation_add_odometry`: giờ là nguồn vận tốc đo được của controller, không còn chỉ để hiển thị. +- `navigation_add_depth_camera_data` (mới): đường duy nhất tới `VoxelLayer` để **clear theo frustum** + — xoá vật cản ma nằm trong tầm nhìn camera. Yêu cầu: + - `header.frame_id` là **optical frame** của camera, và TF từ frame đó tới base frame phải có trong + buffer tf3 tại đúng `header.stamp`; + - `depth.encoding` đúng thật (`"16UC1"` hoặc `"32FC1"`), `step` là số byte mỗi hàng; + - `camera_info` là intrinsics của **đúng độ phân giải đang gửi**, không phải của stream màu; + - ảnh depth và camera info **cùng một thời điểm** — ghép lệch hai luồng là clear sai vùng. + +### 6.9. Đọc lại và xoá dữ liệu sensor + +| | Hàm | Đổi | +|---|---|---| +| | `bool navigation_get_static_map(NavigationHandle, const char *name, OccupancyGrid &out)` | = | +| | `bool navigation_get_laser_scan(NavigationHandle, const char *name, LaserScan &out)` | = | +| | `bool navigation_get_point_cloud(NavigationHandle, const char *name, PointCloud &out)` | = | +| | `bool navigation_get_point_cloud2(NavigationHandle, const char *name, PointCloud2 &out)` | = | +| | `bool navigation_get_all_static_maps(NavigationHandle, NamedOccupancyGrid *out, size_t &n)` | = | +| | `bool navigation_get_all_laser_scans(...)`, `..._point_clouds(...)`, `..._point_cloud2s(...)` | = | +| | `bool navigation_remove_static_map / _laser_scan / _point_cloud / _point_cloud2` | = | +| | `bool navigation_remove_all_static_maps / _laser_scans / _point_clouds / _point_cloud2s` | = | +| | `bool navigation_remove_all_data(NavigationHandle)` | = | + +Các getter **cấp bộ nhớ** — dùng `navigation_free_*` (mục 6.11) sau khi xong. + +Bản mới cất **bản đã lọc** của laser scan, đúng bản mà costmap nhìn thấy, nên getter và costmap không +còn lệch nguồn. + +Cảnh báo về chữ ký `get_all_*`: mảng do bên gọi cấp, **không có tham số dung lượng**. Cấp dư. + +### 6.10. Dữ liệu hiển thị + +| | Hàm | Đổi | +|---|---|---| +| | `bool navigation_get_global_data(NavigationHandle, PlannerDataOutput *out)` | ~ | +| | `bool navigation_get_local_data(NavigationHandle, PlannerDataOutput *out)` | ~ | + +Trả plan, lưới costmap (hoặc bản update), cờ `is_costmap_updated`, và footprint. Hàm **tự giải phóng +nội dung cũ** của struct được truyền vào, nên tái sử dụng một struct qua nhiều lần poll là đúng cách +và không rò. Lần điền cuối cùng thì giải phóng bằng `navigation_free_planner_data`. + +Ba khác biệt so với bản cũ: + +1. **`plan` của `get_local_data` giờ có dữ liệu.** Bản cũ không bao giờ điền trường này cho local. +2. **`costmap` vẫn được điền đầy đủ** qua bộ xuất costmap — không rỗng. +3. **`footprint` đổi ý nghĩa.** Bản cũ: polygon **đã pad và đã transform tới pose robot**, `frame_id` + là global frame — vẽ thẳng lên bản đồ là đúng chỗ. Bản mới: polygon **thô** host đã set, chưa + transform, `frame_id` là `base_link`, và **rỗng nếu host chưa set footprint**. + +> Điểm 3 làm vỡ hiển thị footprint. Chỗ sửa đúng nằm ở `move_base2` (lấy footprint từ costmap thay vì +> từ bản thô) chứ không phải bắt C# tự transform. Xem `C_API_MOVE_BASE2_PLAN.md` mục 8.4. Cho tới khi +> sửa, C# muốn vẽ đúng thì phải tự xoay/tịnh tiến footprint theo pose lấy từ +> `navigation_get_robot_pose_2d` — chấp nhận lệch thời gian giữa hai lời gọi. + +### 6.11. Bộ nhớ + +| | Hàm | Đổi | +|---|---|---| +| | `void nav_c_api_free_string(char *)` | = | +| | `void order_free(Order *)` | = | +| | `void navigation_free_occupancy_grid(OccupancyGrid *)` | + | +| | `void navigation_free_laser_scan(LaserScan *)` | + | +| | `void navigation_free_point_cloud(PointCloud *)` | + | +| | `void navigation_free_point_cloud2(PointCloud2 *)` | + | +| | `void navigation_free_planner_data(PlannerDataOutput *)` | + | + +Trước đây chỉ có hai hàm đầu, nên grid/scan/cloud/plan **không có hàm giải phóng nào** — mỗi lời gọi +getter rò một lần. Năm hàm mới đóng lỗ đó. Tất cả đều an toàn với `NULL`, xoá luôn con trỏ và bộ đếm, +gọi hai lần không sao. + +Nguyên tắc: cấp phát ở trong thư viện thì **phải** giải phóng bằng hàm của thư viện. Đừng gọi `free()` +của libc từ C#. + +### 6.12. Tiện ích hình học + +| | Hàm | Đổi | +|---|---|---| +| | `bool navigation_offset_goal_2d(const Pose2D&, const char *frame_id, double d, PoseStamped &out)` | = | +| | `bool navigation_offset_goal_stamped(const PoseStamped&, double d, PoseStamped &out)` | = | + +Dịch một pose đi `d` mét dọc theo hướng của chính nó (âm là lùi). Thuần tính toán, không đụng lõi. +(Hai hàm này có export nhưng chưa được khai báo trong `nav_c_api.h`.) + +--- + +## 7. Quy tắc bộ nhớ — ai giải phóng cái gì + +| Nguồn | Giải phóng bằng | +|---|---| +| `NavFeedback.feed_back_str` | `nav_c_api_free_string` | +| `navigation_get_status_text` | `nav_c_api_free_string` | +| `navigation_state_to_string` | `nav_c_api_free_string` | +| `PoseStamped.header.frame_id`, `Twist2DStamped.header.frame_id` từ getter | `nav_c_api_free_string` | +| `OccupancyGrid` từ `navigation_get_static_map` | `navigation_free_occupancy_grid` | +| `LaserScan` từ `navigation_get_laser_scan` | `navigation_free_laser_scan` | +| `PointCloud` / `PointCloud2` từ getter | `navigation_free_point_cloud` / `_point_cloud2` | +| `PlannerDataOutput` từ `get_global_data` / `get_local_data` | `navigation_free_planner_data` | +| `Order` từ `convert2COrder` | `order_free` | +| Mảng truyền **vào** các hàm `add_*` / `move_to_*` | C# tự giữ; thư viện đã copy xong khi hàm trả về | + +--- + +## 8. Thread safety + +| Nhóm | Gọi được từ thread nào | +|---|---| +| `navigation_add_*` (mọi đường sensor) | **Một thread duy nhất.** Đường sensor không thread-safe. Nếu C# có nhiều nguồn chạy song song, dồn qua một hàng đợi rồi bơm từ một thread. | +| `navigation_set_robot_footprint` | Thread bất kỳ (ghi dưới mutex, áp ở cycle sau) | +| `pause` / `resume` / `cancel` / `set_twist_*` | Thread bất kỳ (ghi dưới mutex, áp ở cycle sau) | +| `move_to*` / `dock_to*` / `rotate_to` / `move_straight_to` | Thread bất kỳ | +| `get_feedback` / `get_state` / `get_twist` / `get_robot_pose_*` | Thread bất kỳ | +| `get_global_data` / `get_local_data` | Thread bất kỳ; mỗi consumer nên có **struct riêng**, không dùng chung một `PlannerDataOutput` giữa nhiều timer | +| `navigation_initialize*` / `navigation_shutdown` / `navigation_destroy` | Thread khởi tạo/thread tắt, **không** song song với nhóm sensor | + +--- + +## 9. Chẩn đoán nhanh + +| Hiện tượng | Nguyên nhân thường gặp | +|---|---| +| `navigation_create` trả `NULL` | Sai `PNKX_NAV_CORE_CONFIG_DIR`, thiếu khoá `MoveBase: library_path`, hoặc `libmove_base2.so` không nằm trong đường tìm | +| Tiến trình chết ngay trong `initialize` | Chưa bơm static map trước `initialize` — SBPL chờ costmap rồi `exit(1)` | +| `initialize_checked` trả `false` | Đọc `navigation_get_status_text` — chuỗi nói rõ pha nào hỏng | +| Gửi goal xong không có gì xảy ra, không log | Control thread chưa chạy: `initialize` đã hỏng nhưng code cũ không kiểm tra kết quả | +| Robot không tránh vật cản từ camera | Sai tên `topic` khi bơm, hoặc thiếu TF của optical frame, hoặc chưa dùng `navigation_add_depth_camera_data` | +| Vật cản ma không bao giờ biến mất | Chưa bơm `DepthCameraData` — point cloud không clear được theo frustum | +| Footprint vẽ sai chỗ trên bản đồ | Mục 6.10 điểm 3 | +| Bộ nhớ tăng dần | Thiếu `navigation_free_*` ở đường getter, hoặc thiếu `nav_c_api_free_string` cho `feed_back_str` | +| Tắt chương trình bị treo hoặc crash | Thiếu `navigation_shutdown`, hoặc còn thread bơm sensor chạy khi tắt | +| Đổi tham số planner mãi không có tác dụng | Sửa nhầm cây config — `move_base2` đọc `Test/move_base2/config/runtime`, không đọc `pnkx_nav_core/config` | + +--- + +## 10. Chưa xác nhận + +- Chưa đọc được mã C# hiện tại, nên chưa biết chỗ nào đang thật sự dựa vào các hành vi cũ ở mục 6.5, + 6.6 và 6.10. +- Trường `footprint` trong dữ liệu hiển thị: đã đối chiếu cả hai bản và khác biệt là chắc chắn, nhưng + chưa xác nhận phía C# có đang vẽ nó lên bản đồ hay không. +- Các hàm mới trong `nav_c_api_2` mới chỉ được kiểm tra biên dịch, **chưa chạy trên robot hay + Gazebo**. Đường depth camera cần kiểm tra thực tế bằng bộ đếm chẩn đoán của cổng sensor. +- `navigation_move_straight_to` với khoảng cách âm (lùi) trong `move_base2` chưa được kiểm tra. + +--- + +## Phụ lục A — bảng symbol đầy đủ trong `libnav_c_api.so` + +Lấy bằng `nm --defined-only` trên các object file. Cột "Nguồn" cho biết symbol nằm trong file nguồn +nào — chỉ để tra cứu, C# không cần biết: mọi symbol đều nằm chung một `.so`. + +### 50 symbol cũ — `nav_c_api.cpp`, C# **không đổi gì** + +``` +nav_c_api_free_string navigation_get_point_cloud2 +navigation_add_laser_scan navigation_get_robot_footprint +navigation_add_odometry navigation_get_robot_pose_2d +navigation_add_point_cloud navigation_get_robot_pose_stamped +navigation_add_point_cloud2 navigation_get_static_map +navigation_add_static_map navigation_get_twist +navigation_cancel navigation_initialize +navigation_create navigation_move_straight_to +navigation_destroy navigation_move_to +navigation_dock_to navigation_move_to_nodes_edges +navigation_dock_to_nodes_edges navigation_move_to_order +navigation_dock_to_order navigation_offset_goal_2d +navigation_get_all_laser_scans navigation_offset_goal_stamped +navigation_get_all_point_cloud2s navigation_pause +navigation_get_all_point_clouds navigation_remove_all_data +navigation_get_all_static_maps navigation_remove_all_laser_scans +navigation_get_feedback navigation_remove_all_point_cloud2s +navigation_get_global_data navigation_remove_all_point_clouds +navigation_get_laser_scan navigation_remove_all_static_maps +navigation_get_local_data navigation_remove_laser_scan +navigation_get_point_cloud navigation_remove_point_cloud +navigation_resume navigation_remove_point_cloud2 +navigation_rotate_to navigation_remove_static_map +navigation_set_robot_footprint navigation_state_to_string +navigation_set_twist_angular navigation_set_twist_linear +``` + +Cộng `order_free` từ `convertor.cpp`. + +### 13 symbol mới — `nav_c_api_2.cpp` + +``` +navigation_initialize_checked navigation_add_depth_camera_data +navigation_is_ready navigation_move_to_order_v2 +navigation_shutdown navigation_dock_to_order_v2 +navigation_get_state navigation_free_occupancy_grid +navigation_get_status_text navigation_free_laser_scan +navigation_free_point_cloud navigation_free_point_cloud2 +navigation_free_planner_data +``` + +--- + +## Phụ lục B — phần C# phải thêm + +Đây là **toàn bộ** phần khai báo mới. Mọi thứ khác trong lớp binding hiện tại giữ nguyên. + +### B.1. Bốn struct mới + +Ba struct đầu chưa từng xuất hiện trong bề mặt cũ vì đường depth camera chưa bao giờ được phơi ra. + +```csharp +[StructLayout(LayoutKind.Sequential)] +public struct RegionOfInterest +{ + public uint x_offset; + public uint y_offset; + public uint height; + public uint width; + [MarshalAs(UnmanagedType.I1)] public bool do_rectify; +} + +[StructLayout(LayoutKind.Sequential)] +public struct Image +{ + public Header header; + public uint height; + public uint width; + public IntPtr encoding; // char* — "16UC1" hoặc "32FC1" + public byte is_bigendian; + public uint step; // số byte mỗi hàng + public IntPtr data; // uint8_t* + public UIntPtr data_count; +} + +[StructLayout(LayoutKind.Sequential)] +public struct CameraInfo +{ + public Header header; + public uint height; + public uint width; + public IntPtr distortion_model; // char* + public IntPtr D; // double* + public UIntPtr D_count; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 9)] public double[] K; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 9)] public double[] R; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)] public double[] P; + public uint binning_x; + public uint binning_y; + public RegionOfInterest roi; +} + +[StructLayout(LayoutKind.Sequential)] +public struct DepthCameraData +{ + public Header header; // stamp + optical frame của mẫu + public Image depth; + public CameraInfo camera_info; // intrinsics của ĐÚNG ảnh trên +} +``` + +### B.2. Mười ba `DllImport` mới + +```csharp +private const string Lib = "nav_c_api"; +private const CallingConvention Cdecl = CallingConvention.Cdecl; + +// ---- vòng đời --------------------------------------------------------------------------- +[DllImport(Lib, CallingConvention = Cdecl)] [return: MarshalAs(UnmanagedType.I1)] +public static extern bool navigation_initialize_checked(IntPtr handle, IntPtr tf3Buffer); + +[DllImport(Lib, CallingConvention = Cdecl)] [return: MarshalAs(UnmanagedType.I1)] +public static extern bool navigation_is_ready(IntPtr handle); + +[DllImport(Lib, CallingConvention = Cdecl)] +public static extern void navigation_shutdown(IntPtr handle); + +// ---- trạng thái ------------------------------------------------------------------------- +[DllImport(Lib, CallingConvention = Cdecl)] [return: MarshalAs(UnmanagedType.I1)] +public static extern bool navigation_get_state(IntPtr handle, out NavigationState state); + +[DllImport(Lib, CallingConvention = Cdecl)] +public static extern IntPtr navigation_get_status_text(IntPtr handle); // free: nav_c_api_free_string + +// ---- sensor ----------------------------------------------------------------------------- +[DllImport(Lib, CallingConvention = Cdecl)] [return: MarshalAs(UnmanagedType.I1)] +public static extern bool navigation_add_depth_camera_data( + IntPtr handle, [MarshalAs(UnmanagedType.LPStr)] string topic, DepthCameraData data); + +// ---- order ------------------------------------------------------------------------------ +[DllImport(Lib, CallingConvention = Cdecl)] [return: MarshalAs(UnmanagedType.I1)] +public static extern bool navigation_move_to_order_v2( + IntPtr handle, + [MarshalAs(UnmanagedType.LPStr)] string orderId, uint orderUpdateId, + [In] Node[] nodes, UIntPtr nodeCount, + [In] Edge[] edges, UIntPtr edgeCount, + PoseStamped goal); + +[DllImport(Lib, CallingConvention = Cdecl)] [return: MarshalAs(UnmanagedType.I1)] +public static extern bool navigation_dock_to_order_v2( + IntPtr handle, [MarshalAs(UnmanagedType.LPStr)] string marker, + [MarshalAs(UnmanagedType.LPStr)] string orderId, uint orderUpdateId, + [In] Node[] nodes, UIntPtr nodeCount, + [In] Edge[] edges, UIntPtr edgeCount, + PoseStamped goal); + +// ---- giải phóng bộ nhớ ------------------------------------------------------------------ +[DllImport(Lib, CallingConvention = Cdecl)] +public static extern void navigation_free_occupancy_grid(ref OccupancyGrid grid); + +[DllImport(Lib, CallingConvention = Cdecl)] +public static extern void navigation_free_laser_scan(ref LaserScan scan); + +[DllImport(Lib, CallingConvention = Cdecl)] +public static extern void navigation_free_point_cloud(ref PointCloud cloud); + +[DllImport(Lib, CallingConvention = Cdecl)] +public static extern void navigation_free_point_cloud2(ref PointCloud2 cloud); + +[DllImport(Lib, CallingConvention = Cdecl)] +public static extern void navigation_free_planner_data(ref PlannerDataOutput data); +``` + +### B.3. Ví dụ bơm một mẫu depth camera + +Ảnh depth thường vài MB. Ghim mảng lại thay vì để bộ marshaller sao chép thêm một lần — thư viện đã +copy sang phía C++ ngay trong lời gọi, nên gỡ ghim ngay sau khi trả về là an toàn. + +```csharp +public bool PushDepthSample(string topic, string opticalFrame, + uint sec, uint nsec, + byte[] depthBytes, uint height, uint width, uint step, + double[] k, double[] p) +{ + var frameId = Marshal.StringToHGlobalAnsi(opticalFrame); + var encoding = Marshal.StringToHGlobalAnsi("16UC1"); + var distModel = Marshal.StringToHGlobalAnsi("plumb_bob"); + var pinned = GCHandle.Alloc(depthBytes, GCHandleType.Pinned); + try + { + var header = new Header { seq = 0, sec = sec, nsec = nsec, frame_id = frameId }; + + var data = new DepthCameraData + { + header = header, + depth = new Image + { + header = header, + height = height, + width = width, + encoding = encoding, + is_bigendian = 0, + step = step, + data = pinned.AddrOfPinnedObject(), + data_count = (UIntPtr)depthBytes.Length, + }, + camera_info = new CameraInfo + { + header = header, + height = height, + width = width, + distortion_model = distModel, + D = IntPtr.Zero, + D_count = UIntPtr.Zero, + K = k, // 9 phần tử + R = new double[9], + P = p, // 12 phần tử + binning_x = 0, + binning_y = 0, + roi = default, + }, + }; + + return navigation_add_depth_camera_data(navHandle, topic, data); + } + finally + { + pinned.Free(); + Marshal.FreeHGlobal(distModel); + Marshal.FreeHGlobal(encoding); + Marshal.FreeHGlobal(frameId); + } +} +``` + +### B.4. Ví dụ đọc dữ liệu hiển thị mà không rò bộ nhớ + +```csharp +// MỘT struct cho MỖI consumer, giữ lại giữa các lần poll: hàm tự giải phóng nội dung cũ. +// Đừng dùng chung một struct giữa nhiều timer. +private PlannerDataOutput globalData; + +private void OnGlobalTimer() +{ + if (!navigation_get_global_data(navHandle, ref globalData)) + return; + + DrawPlan(globalData.plan); + DrawCostmap(globalData.costmap, globalData.is_costmap_updated, globalData.costmap_update); +} + +// Khi dừng consumer — nếu không, lần điền cuối cùng sẽ rò. +private void StopGlobalTimer() +{ + timer.Stop(); + navigation_free_planner_data(ref globalData); +} +``` diff --git a/src/APIs/c_api/include/convertor_2.h b/src/APIs/c_api/include/convertor_2.h new file mode 100644 index 0000000..47ad8fe --- /dev/null +++ b/src/APIs/c_api/include/convertor_2.h @@ -0,0 +1,51 @@ +#ifndef C_API_CONVERTOR_2_H +#define C_API_CONVERTOR_2_H + +/** + * @file convertor_2.h + * @brief Converters that only the move_base2 entry points need. + * + * Kept apart from convertor.h so the move_base2 surface can be added, reviewed and reverted without + * touching the converters the existing binding already depends on. + */ + +// C +#include "std_msgs/Header.h" +#include "sensor_msgs/Image.h" +#include "sensor_msgs/CameraInfo.h" +#include "sensor_msgs/DepthCameraData.h" + +// C++ +#include +#include +#include +#include + +/** + * @brief Convert C Header to C++ Header. + * @param header C header; `frame_id` may be NULL (becomes an empty string). + */ +robot_std_msgs::Header convert2CppHeader(const Header& header); + +/** + * @brief Convert C Image to C++ Image. + * + * The pixel buffer is copied, so the caller keeps ownership of `image.data` and may free it as + * soon as this call returns. + * + * @param image C image; `data` and `encoding` may be NULL. + */ +robot_sensor_msgs::Image convert2CppImage(const Image& image); + +/** + * @brief Convert C CameraInfo to C++ CameraInfo. + * @param info C camera info; `D` and `distortion_model` may be NULL. K/R/P are fixed size (9/9/12). + */ +robot_sensor_msgs::CameraInfo convert2CppCameraInfo(const CameraInfo& info); + +/** + * @brief Convert C DepthCameraData to C++ DepthCameraData. Everything is deep-copied. + */ +robot_sensor_msgs::DepthCameraData convert2CppDepthCameraData(const DepthCameraData& data); + +#endif // C_API_CONVERTOR_2_H diff --git a/src/APIs/c_api/include/nav_c_api_2.h b/src/APIs/c_api/include/nav_c_api_2.h new file mode 100644 index 0000000..c1f6715 --- /dev/null +++ b/src/APIs/c_api/include/nav_c_api_2.h @@ -0,0 +1,301 @@ +#ifndef NAVIGATION_C_API_2_H +#define NAVIGATION_C_API_2_H + +/** + * @file nav_c_api_2.h + * @brief Additional C entry points required by the move_base2 navigation runtime. + * + * ## What this file is + * + * `nav_c_api.h` covers the navigation contract as the previous runtime exposed it. Every one of + * those functions keeps working against move_base2 — move_base2 implements + * `robot::move_base_core::BaseNavigation` with the signatures unchanged, so no existing binding + * breaks. This file adds what that contract gained but the C surface never exposed, plus the two + * entry points move_base2 makes newly necessary: + * + * - navigation_shutdown() — quiesce the core before destroying it. + * - navigation_is_ready() — did initialize() actually succeed? + * - navigation_initialize_checked() — initialize + verify, in one call. + * - navigation_get_state() — poll the state without allocating a string. + * - navigation_get_status_text() — the core's own explanation, for logging. + * - navigation_add_depth_camera_data() — the depth-camera input path, never exposed before. + * - navigation_move_to_order_v2() — an order carrying a real orderId / orderUpdateId. + * - navigation_dock_to_order_v2() — same, for docking. + * + * Include this header **in addition to** nav_c_api.h. It adds symbols; it replaces none. + * + * ## What changed underneath the functions you already call + * + * These keep their signatures and their meaning, but behave differently enough to matter: + * + * 1. navigation_initialize() is now heavy and blocking — it builds both costmaps, loads the + * planners, the controller, the recovery behaviours and the mission layer, then starts the + * control thread. It still returns `true` unconditionally because the underlying contract + * returns void. Use navigation_initialize_checked(), or call navigation_is_ready() after it. + * + * 2. A static map must be pushed **before** initialize(). The lattice planner blocks until the + * costmap has a non-zero size, and that size only exists once a static map has reached the + * static layer. It aborts the whole process if it waits too long. + * + * 3. navigation_set_robot_footprint() may now be called before initialize() — the footprint is + * cached and applied while the costmaps are built. Under the old runtime the same call was + * dropped silently because the costmaps did not exist yet. + * + * 4. navigation_pause() / _resume() / _cancel() no longer take effect inside the call. They record + * the request; the control thread applies it on its next cycle. Returning from the call does + * not mean the robot stopped — watch the state, or watch the twist. + * + * 5. navigation_set_twist_linear() / _angular() set a velocity **ceiling**, and the sign of the + * linear x component selects which direction the ceiling applies to. They now only reject + * NaN/Inf; the old runtime also returned false while a cancel was in flight, and that signal no + * longer exists. The new ceiling takes effect on the next control cycle. + * + * 6. navigation_get_twist() returns the command being issued, not a measurement. While no request + * is running its stamp stops advancing; a zero stamp means the core has never commanded + * anything. Check the stamp before republishing it as a velocity command. + * + * 7. NavFeedback.feed_back_str now carries the core's own reason strings — different text from the + * old runtime. Branch on NavigationState, never on the string. + * + * 8. NavFeedback.navigation_state deliberately reports ACTIVE between the legs of a multi-leg + * order, where the core itself is momentarily SUCCEEDED or PENDING. Treating SUCCEEDED as "the + * order finished" stays correct only because of that; do not bypass it. + * + * 9. navigation_add_odometry() feeds the controller's measured velocity every cycle, not just a + * stored value. Push it at the rate the odometry source produces it. + * + * 10. The `footprint` field of navigation_get_global_data() / _local_data() is the raw footprint the + * host set, in the robot base frame, and it is empty if the host never set one. The old runtime + * returned the padded footprint already transformed to the robot pose in the global frame. + * + * 11. navigation_destroy() alone is no longer enough — call navigation_shutdown() first, from a + * point in your own shutdown sequence where the process is still fully alive. + * + * See NAV_C_API_2_GUIDE.md in this directory for the per-function walkthrough and the startup and + * shutdown sequences. + */ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include +#include + +#include "nav_c_api.h" +#include "sensor_msgs/DepthCameraData.h" +#include "sensor_msgs/LaserScan.h" +#include "sensor_msgs/PointCloud.h" +#include "sensor_msgs/PointCloud2.h" +#include "nav_msgs/OccupancyGrid.h" +#include "protocol_msgs/Node.h" +#include "protocol_msgs/Edge.h" + + // ============================================================================================ + // Lifecycle + // ============================================================================================ + + /** + * @brief Initialize the navigation core and report whether it actually came up. + * + * Wraps navigation_initialize(). The underlying contract method returns void, so every failure + * path inside the runtime — costmap construction, sensor configuration, plugin loading, control + * loop configuration, control thread startup — returns normally and only records the reason in + * the feedback. This function reads that back and turns it into a return value. + * + * Blocking and expensive: it builds two costmaps, loads every plugin named in the YAML, starts + * the map-update threads, the mission threads and the control thread. Do not call it from a UI + * thread. + * + * @param handle Navigation handle from navigation_create(). + * @param tf3_buffer tf3 BufferCore the host owns; must outlive the navigation instance. + * @return true only when the core is ready to accept goals. + * + * @pre At least one static map has been pushed with navigation_add_static_map(). + * @pre The robot footprint has been set with navigation_set_robot_footprint(), if the host wants + * its own footprint rather than the one in the YAML. + * @see navigation_get_status_text() for the reason behind a false return. + */ + bool navigation_initialize_checked(NavigationHandle handle, TFListenerHandle tf3_buffer); + + /** + * @brief Is the core initialized and accepting goals? + * + * Cheap enough to poll. Reads the same flag navigation_initialize_checked() checks, without + * allocating the feedback string. + * + * @return false if the handle is null, the core never initialized, or initialization failed. + */ + bool navigation_is_ready(NavigationHandle handle); + + /** + * @brief Stop the core's threads without destroying the instance. + * + * Gives the host a point inside its own shutdown sequence — while the process is still fully + * alive — to stop the control thread, the costmap update threads and the mission threads. + * Destroying the instance from a finalizer, after the runtime has already begun tearing down, is + * the race this exists to avoid. + * + * After this call the core issues no further velocity commands, and every getter + * (navigation_get_feedback, navigation_get_twist, navigation_get_robot_pose_*) remains safe to + * call. Safe to call more than once. + * + * @warning No thread may be calling navigation_add_* while this runs, and none may call them + * afterwards. The sensor path is not thread-safe and there is no longer a control thread + * consuming what it produces. + */ + void navigation_shutdown(NavigationHandle handle); + + // ============================================================================================ + // Status + // ============================================================================================ + + /** + * @brief Current navigation state, without allocating anything. + * + * navigation_get_feedback() strdup()s its message on every call, so polling it at control rate + * means one allocation and one free per poll — and one leak per missed free. Use this when only + * the state matters, which is the common case. + * + * @param handle Navigation handle. + * @param out_state Receives the current state; untouched on failure. + * @return false if the handle is null or the core has no feedback yet. + */ + bool navigation_get_state(NavigationHandle handle, NavigationState *out_state); + + /** + * @brief The core's own description of what it is doing, or why it refused. + * + * For logging and diagnostics only. The wording comes from the runtime and changes between + * versions — never branch on it. Branch on navigation_get_state(). + * + * @return Newly allocated string, or NULL. Free with nav_c_api_free_string(). + */ + char *navigation_get_status_text(NavigationHandle handle); + + // ============================================================================================ + // Sensor input + // ============================================================================================ + + /** + * @brief Push one coherent depth-camera sample into the navigation core. + * + * This is the only way to reach the depth-camera path from C. The voxel layer projects the depth + * image through the intrinsics to build the camera frustum, which is what lets it *clear* stale + * obstacles inside the field of view. A point cloud cannot substitute: it carries no intrinsics, + * so no frustum can be reconstructed and nothing gets cleared. + * + * @param handle Navigation handle. + * @param topic Logical name of the stream. Must match an `observation_source` declared for the + * voxel layer in the costmap YAML — a name no layer subscribes to is accepted here + * and then dropped, silently, further down. + * @param data Depth image and its matching intrinsics. Deep-copied; the caller may release its + * buffers as soon as this returns. + * @return true if the sample was accepted. + * + * @pre `data.header.frame_id` is the camera's optical frame, and a transform from it to the robot + * base frame exists in the tf3 buffer at `data.header.stamp`. + * @pre `data.depth.encoding` matches the real encoding ("16UC1" or "32FC1") and `step` is the + * real row stride in bytes. + * @pre `data.camera_info` describes the resolution actually being sent, not the colour stream's. + * @pre The depth image and the camera info come from the same instant. + * + * @note Push at the camera's real rate. This is the most expensive sensor path in the core; + * pushing faster than the source only burns CPU. + */ + bool navigation_add_depth_camera_data(NavigationHandle handle, const char *topic, + const DepthCameraData data); + + // ============================================================================================ + // Orders + // ============================================================================================ + + /** + * @brief Send a multi-node order with a real identity. + * + * Under move_base2 an order goes through the mission layer, which splits it into legs at the + * nodes that carry actions, filters by `released`, and can extend the route when the fleet master + * releases more of the horizon. `orderId` plus `orderUpdateId` is what identifies an order there: + * the same `orderId` with a higher `orderUpdateId` is an update of the route in progress, while a + * different `orderId` is a new order that replaces it. + * + * navigation_move_to_nodes_edges() cannot express that — it has nowhere to put either field — so + * every call looks like a different order and no update can ever be sent. Use this instead + * whenever the fleet master sends order updates or releases the horizon progressively. + * + * @param handle Navigation handle. + * @param order_id VDA5050 orderId. Must not be NULL or empty. + * @param order_update_id VDA5050 orderUpdateId. Must increase within one orderId. + * @param nodes Node array; the host keeps ownership. + * @param node_count Number of nodes. + * @param edges Edge array; the host keeps ownership. + * @param edge_count Number of edges. + * @param goal Final pose, in the global frame. + * @return true if the order was accepted. + */ + bool navigation_move_to_order_v2(NavigationHandle handle, + const char *order_id, uint32_t order_update_id, + const Node *nodes, size_t node_count, + const Edge *edges, size_t edge_count, + const PoseStamped goal); + + /** + * @brief Docking counterpart of navigation_move_to_order_v2(). + * + * @param handle Navigation handle. + * @param marker Docking marker name or id. Must not be NULL. + * @param order_id VDA5050 orderId. Must not be NULL or empty. + * @param order_update_id VDA5050 orderUpdateId. + * @param nodes Node array; the host keeps ownership. + * @param node_count Number of nodes. + * @param edges Edge array; the host keeps ownership. + * @param edge_count Number of edges. + * @param goal Docking pose. + * @return true if the docking order was accepted. + */ + bool navigation_dock_to_order_v2(NavigationHandle handle, const char *marker, + const char *order_id, uint32_t order_update_id, + const Node *nodes, size_t node_count, + const Edge *edges, size_t edge_count, + const PoseStamped goal); + + // ============================================================================================ + // Releasing what the getters allocate + // ============================================================================================ + // + // Every navigation_get_* function that returns a grid, a scan, a cloud or a plan fills it with + // buffers allocated inside the library. Only two release helpers ever shipped — + // nav_c_api_free_string() and order_free() — so the rest had no counterpart and leaked one + // allocation per call. At four display timers polling at 10 Hz that is a steady leak, not a + // rounding error. These close it. + // + // All are null-safe, clear the pointers and counts they release, and are safe to call twice. + + /** @brief Release the buffers inside an OccupancyGrid filled by navigation_get_static_map(). */ + void navigation_free_occupancy_grid(OccupancyGrid *grid); + + /** @brief Release the buffers inside a LaserScan filled by navigation_get_laser_scan(). */ + void navigation_free_laser_scan(LaserScan *scan); + + /** @brief Release the buffers inside a PointCloud filled by navigation_get_point_cloud(). */ + void navigation_free_point_cloud(PointCloud *cloud); + + /** @brief Release the buffers inside a PointCloud2 filled by navigation_get_point_cloud2(). */ + void navigation_free_point_cloud2(PointCloud2 *cloud); + + /** + * @brief Release the buffers inside a PlannerDataOutput. + * + * navigation_get_global_data() / _local_data() already release the previous contents of the + * struct they are handed, so reusing one struct across polls does not leak. What does leak is the + * last fill, once the host stops polling — free it here. + */ + void navigation_free_planner_data(PlannerDataOutput *data); + +#ifdef __cplusplus +} +#endif + +#endif // NAVIGATION_C_API_2_H diff --git a/src/APIs/c_api/include/nav_c_api_io_structure.md b/src/APIs/c_api/include/nav_c_api_io_structure.md deleted file mode 100644 index e69de29..0000000 diff --git a/src/APIs/c_api/include/sensor_msgs/DepthCameraData.h b/src/APIs/c_api/include/sensor_msgs/DepthCameraData.h new file mode 100644 index 0000000..dcd8be6 --- /dev/null +++ b/src/APIs/c_api/include/sensor_msgs/DepthCameraData.h @@ -0,0 +1,36 @@ +#ifndef C_API_SENSOR_MSGS_DEPTHCAMERADATA_H +#define C_API_SENSOR_MSGS_DEPTHCAMERADATA_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include "std_msgs/Header.h" +#include "sensor_msgs/Image.h" +#include "sensor_msgs/CameraInfo.h" + +/** + * @brief One coherent depth-camera sample: a depth image plus the intrinsics that describe it. + * + * Mirrors robot_sensor_msgs::DepthCameraData. "Coherent" is the whole point of the struct: the + * voxel layer projects every depth pixel through the intrinsics to build a frustum, so a depth + * image paired with intrinsics from a different resolution or a different instant clears the wrong + * volume of space. Pair them at the source, not here. + */ +typedef struct +{ + /** Canonical timestamp and optical frame of this sample. */ + Header header; + /** Depth image. `encoding` must be the true encoding ("16UC1" or "32FC1"). */ + Image depth; + /** Intrinsics of the exact image above — same resolution, same instant. */ + CameraInfo camera_info; +} DepthCameraData; + +#ifdef __cplusplus +} +#endif + +#endif // C_API_SENSOR_MSGS_DEPTHCAMERADATA_H diff --git a/src/APIs/c_api/src/convertor_2.cpp b/src/APIs/c_api/src/convertor_2.cpp new file mode 100644 index 0000000..85a6637 --- /dev/null +++ b/src/APIs/c_api/src/convertor_2.cpp @@ -0,0 +1,78 @@ +#include "convertor_2.h" + +#include +#include +#include + +namespace +{ + +/// Empty string for a NULL C string — every char* coming from the host is optional. +inline std::string safe_string(const char* s) +{ + return s != nullptr ? std::string(s) : std::string(); +} + +} // namespace + +robot_std_msgs::Header convert2CppHeader(const Header& header) +{ + robot_std_msgs::Header cpp; + cpp.seq = header.seq; + cpp.stamp.sec = header.sec; + cpp.stamp.nsec = header.nsec; + cpp.frame_id = safe_string(header.frame_id); + return cpp; +} + +robot_sensor_msgs::Image convert2CppImage(const Image& image) +{ + robot_sensor_msgs::Image cpp; + cpp.header = convert2CppHeader(image.header); + cpp.height = image.height; + cpp.width = image.width; + cpp.encoding = safe_string(image.encoding); + cpp.is_bigendian = image.is_bigendian; + cpp.step = image.step; + + // Copy, never alias: the host buffer may be a pinned .NET array released right after this call, + // while the voxel layer reads the sample later on the map-update thread. + const size_t count = image.data != nullptr ? image.data_count : 0; + cpp.data.assign(image.data, image.data + count); + return cpp; +} + +robot_sensor_msgs::CameraInfo convert2CppCameraInfo(const CameraInfo& info) +{ + robot_sensor_msgs::CameraInfo cpp; + cpp.header = convert2CppHeader(info.header); + cpp.height = info.height; + cpp.width = info.width; + cpp.distortion_model = safe_string(info.distortion_model); + + const size_t d_count = info.D != nullptr ? info.D_count : 0; + cpp.D.assign(info.D, info.D + d_count); + + std::copy(info.K, info.K + 9, cpp.K.begin()); + std::copy(info.R, info.R + 9, cpp.R.begin()); + std::copy(info.P, info.P + 12, cpp.P.begin()); + + cpp.binning_x = info.binning_x; + cpp.binning_y = info.binning_y; + + cpp.roi.x_offset = info.roi.x_offset; + cpp.roi.y_offset = info.roi.y_offset; + cpp.roi.height = info.roi.height; + cpp.roi.width = info.roi.width; + cpp.roi.do_rectify = info.roi.do_rectify; + return cpp; +} + +robot_sensor_msgs::DepthCameraData convert2CppDepthCameraData(const DepthCameraData& data) +{ + robot_sensor_msgs::DepthCameraData cpp; + cpp.header = convert2CppHeader(data.header); + cpp.depth = convert2CppImage(data.depth); + cpp.camera_info = convert2CppCameraInfo(data.camera_info); + return cpp; +} diff --git a/src/APIs/c_api/src/nav_c_api.cpp b/src/APIs/c_api/src/nav_c_api.cpp index 0292a09..a269992 100644 --- a/src/APIs/c_api/src/nav_c_api.cpp +++ b/src/APIs/c_api/src/nav_c_api.cpp @@ -317,7 +317,9 @@ extern "C" bool navigation_move_to_nodes_edges(NavigationHandle handle, const No if (!nav_ptr) return false; robot::log_error("navigation_move_to_nodes_edges goal %f %f", goal.pose.position.x, goal.pose.position.y); - Order order; + // Zero-init: the fields left unset below are all char*, and convert2CppOrder treats any + // non-null pointer as a valid string — an uninitialized struct hands it stack garbage. + Order order{}; order.nodes = const_cast(nodes); order.nodes_count = node_count; order.edges = const_cast(edges); @@ -416,7 +418,8 @@ extern "C" bool navigation_dock_to_nodes_edges(NavigationHandle handle, const ch reinterpret_cast(handle), [](::robot::move_base_core::BaseNavigation *) {}); if (!nav_ptr) return false; - Order order; + // Zero-init: see navigation_move_to_nodes_edges. + Order order{}; order.nodes = const_cast(nodes); order.nodes_count = node_count; order.edges = const_cast(edges); diff --git a/src/APIs/c_api/src/nav_c_api_2.cpp b/src/APIs/c_api/src/nav_c_api_2.cpp new file mode 100644 index 0000000..1d38efc --- /dev/null +++ b/src/APIs/c_api/src/nav_c_api_2.cpp @@ -0,0 +1,422 @@ +/** + * @file nav_c_api_2.cpp + * @brief Implementation of the move_base2 additions to the C navigation API. + * + * Deliberately separate from nav_c_api.cpp: the surface the existing binding depends on stays byte + * for byte where it is, and everything move_base2 needs on top of it lands here, where it can be + * reviewed — or dropped — on its own. + * + * The handle is the same opaque `robot::move_base_core::BaseNavigation*` navigation_create() + * returns; ownership still lives in nav_c_api.cpp, so nothing here creates or frees an instance. + */ + +#include "nav_c_api_2.h" + +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include "convertor.h" +#include "convertor_2.h" + +namespace +{ + +/// Non-owning view of the handle. The instance is owned by the table in nav_c_api.cpp. +inline robot::move_base_core::BaseNavigation *as_navigation(NavigationHandle handle) +{ + return static_cast(handle); +} + +/** + * @brief Build a C Order from an id plus the node/edge arrays the host owns. + * + * Zero-initialized on purpose. Every optional field of Order is a char*, and the converter treats a + * non-null pointer as a valid string — an uninitialized struct therefore hands it stack garbage to + * build std::string from. The pointers below stay non-owning: the converter copies before this + * returns, and the arrays are never freed here. + */ +Order make_order(const char *order_id, uint32_t order_update_id, + const Node *nodes, size_t node_count, + const Edge *edges, size_t edge_count) +{ + Order order{}; + order.orderId = const_cast(order_id); + order.orderUpdateId = order_update_id; + order.nodes = const_cast(nodes); + order.nodes_count = nodes != nullptr ? node_count : 0; + order.edges = const_cast(edges); + order.edges_count = edges != nullptr ? edge_count : 0; + return order; +} + +} // namespace + +// ================================================================================================ +// Lifecycle +// ================================================================================================ + +extern "C" bool navigation_initialize_checked(NavigationHandle handle, TFListenerHandle tf3_buffer) +{ + if (!handle || !tf3_buffer) + { + robot::log_error("navigation_initialize_checked: null handle or tf3 buffer"); + return false; + } + + try + { + auto *nav = as_navigation(handle); + + // The host owns the buffer and must outlive the core; hand over a non-owning alias. + robot::TFListenerPtr tf(static_cast(tf3_buffer), + [](tf3::BufferCore *) {}); + + nav->initialize(tf); + + // initialize() returns void, so the runtime reports failure the only way it can: it leaves + // is_ready false and writes the reason into the feedback. Not reading it back is how a host + // ends up pushing goals into a core that has no control thread. + robot::move_base_core::NavFeedback *feedback = nav->getFeedback(); + if (feedback == nullptr) + { + robot::log_error("navigation_initialize_checked: core exposes no feedback"); + return false; + } + if (!feedback->is_ready) + { + robot::log_error("navigation_initialize_checked: core not ready: %s", + feedback->feed_back_str.c_str()); + return false; + } + return true; + } + catch (const std::exception &e) + { + robot::log_error("navigation_initialize_checked failed: %s", e.what()); + return false; + } + catch (...) + { + robot::log_error("navigation_initialize_checked failed: unknown exception"); + return false; + } +} + +extern "C" bool navigation_is_ready(NavigationHandle handle) +{ + if (!handle) + { + return false; + } + + try + { + robot::move_base_core::NavFeedback *feedback = as_navigation(handle)->getFeedback(); + return feedback != nullptr && feedback->is_ready; + } + catch (...) + { + return false; + } +} + +extern "C" void navigation_shutdown(NavigationHandle handle) +{ + if (!handle) + { + return; + } + + try + { + as_navigation(handle)->shutdown(); + } + catch (const std::exception &e) + { + // Swallowed on purpose: this runs inside the host's shutdown sequence, where throwing across + // the C boundary would abort a process that is already on its way down. + robot::log_error("navigation_shutdown failed: %s", e.what()); + } + catch (...) + { + robot::log_error("navigation_shutdown failed: unknown exception"); + } +} + +// ================================================================================================ +// Status +// ================================================================================================ + +extern "C" bool navigation_get_state(NavigationHandle handle, NavigationState *out_state) +{ + if (!handle || !out_state) + { + return false; + } + + try + { + robot::move_base_core::NavFeedback *feedback = as_navigation(handle)->getFeedback(); + if (feedback == nullptr) + { + return false; + } + *out_state = static_cast(static_cast(feedback->navigation_state)); + return true; + } + catch (...) + { + return false; + } +} + +extern "C" char *navigation_get_status_text(NavigationHandle handle) +{ + if (!handle) + { + return nullptr; + } + + try + { + robot::move_base_core::NavFeedback *feedback = as_navigation(handle)->getFeedback(); + if (feedback == nullptr || feedback->feed_back_str.empty()) + { + return nullptr; + } + return strdup(feedback->feed_back_str.c_str()); + } + catch (...) + { + return nullptr; + } +} + +// ================================================================================================ +// Sensor input +// ================================================================================================ + +extern "C" bool navigation_add_depth_camera_data(NavigationHandle handle, const char *topic, + const DepthCameraData data) +{ + if (!handle || !topic) + { + return false; + } + + try + { + // ConstPtr is a boost::shared_ptr and the core keeps the sample for as long as it needs it, so + // hand it a copy rather than a view of host memory. + auto sample = boost::make_shared( + convert2CppDepthCameraData(data)); + + as_navigation(handle)->addDepthCameraData(std::string(topic), sample); + return true; + } + catch (const std::exception &e) + { + robot::log_error("navigation_add_depth_camera_data failed: %s", e.what()); + return false; + } + catch (...) + { + return false; + } +} + +// ================================================================================================ +// Orders +// ================================================================================================ + +extern "C" bool navigation_move_to_order_v2(NavigationHandle handle, + const char *order_id, uint32_t order_update_id, + const Node *nodes, size_t node_count, + const Edge *edges, size_t edge_count, + const PoseStamped goal) +{ + if (!handle || order_id == nullptr || order_id[0] == '\0') + { + robot::log_error("navigation_move_to_order_v2: null handle or empty orderId"); + return false; + } + if (!isQuaternionValid(goal.pose.orientation)) + { + robot::log_error("navigation_move_to_order_v2: goal quaternion is invalid"); + return false; + } + + try + { + const Order order = make_order(order_id, order_update_id, nodes, node_count, edges, edge_count); + return as_navigation(handle)->moveTo(convert2CppOrder(order), convert2CppPoseStamped(goal)); + } + catch (const std::exception &e) + { + robot::log_error("navigation_move_to_order_v2 failed: %s", e.what()); + return false; + } + catch (...) + { + return false; + } +} + +extern "C" bool navigation_dock_to_order_v2(NavigationHandle handle, const char *marker, + const char *order_id, uint32_t order_update_id, + const Node *nodes, size_t node_count, + const Edge *edges, size_t edge_count, + const PoseStamped goal) +{ + if (!handle || !marker || order_id == nullptr || order_id[0] == '\0') + { + robot::log_error("navigation_dock_to_order_v2: null handle, marker or empty orderId"); + return false; + } + if (!isQuaternionValid(goal.pose.orientation)) + { + robot::log_error("navigation_dock_to_order_v2: goal quaternion is invalid"); + return false; + } + + try + { + const Order order = make_order(order_id, order_update_id, nodes, node_count, edges, edge_count); + return as_navigation(handle)->dockTo(convert2CppOrder(order), std::string(marker), + convert2CppPoseStamped(goal)); + } + catch (const std::exception &e) + { + robot::log_error("navigation_dock_to_order_v2 failed: %s", e.what()); + return false; + } + catch (...) + { + return false; + } +} + +// ================================================================================================ +// Releasing what the getters allocate +// ================================================================================================ +// +// The converters allocate with malloc()/strdup(), so these release with free(). Mixing in delete[] +// here would be undefined behaviour, and the host cannot free these itself on Windows-style +// runtimes anyway — allocation and release must happen inside the same C runtime. + +namespace +{ + +/// free() a buffer and clear both the pointer and its element count in one step. +template +inline void free_array(T *&ptr, size_t &count) +{ + free(ptr); + ptr = nullptr; + count = 0; +} + +inline void free_string_field(char *&str) +{ + free(str); + str = nullptr; +} + +} // namespace + +extern "C" void navigation_free_occupancy_grid(OccupancyGrid *grid) +{ + if (!grid) + { + return; + } + free_string_field(grid->header.frame_id); + free_array(grid->data, grid->data_count); +} + +extern "C" void navigation_free_laser_scan(LaserScan *scan) +{ + if (!scan) + { + return; + } + free_string_field(scan->header.frame_id); + free_array(scan->ranges, scan->ranges_count); + free_array(scan->intensities, scan->intensities_count); +} + +extern "C" void navigation_free_point_cloud(PointCloud *cloud) +{ + if (!cloud) + { + return; + } + free_string_field(cloud->header.frame_id); + free_array(cloud->points, cloud->points_count); + + // Each channel owns a name and a value buffer of its own; freeing the array alone leaks both. + if (cloud->channels != nullptr) + { + for (size_t i = 0; i < cloud->channels_count; ++i) + { + free_string_field(cloud->channels[i].name); + free_array(cloud->channels[i].values, cloud->channels[i].values_count); + } + } + free_array(cloud->channels, cloud->channels_count); +} + +extern "C" void navigation_free_point_cloud2(PointCloud2 *cloud) +{ + if (!cloud) + { + return; + } + free_string_field(cloud->header.frame_id); + + if (cloud->fields != nullptr) + { + for (size_t i = 0; i < cloud->fields_count; ++i) + { + free_string_field(cloud->fields[i].name); + } + } + free_array(cloud->fields, cloud->fields_count); + free_array(cloud->data, cloud->data_count); +} + +extern "C" void navigation_free_planner_data(PlannerDataOutput *data) +{ + if (!data) + { + return; + } + + if (data->plan.poses != nullptr) + { + for (size_t i = 0; i < data->plan.poses_count; ++i) + { + free_string_field(data->plan.poses[i].header.frame_id); + } + } + free_array(data->plan.poses, data->plan.poses_count); + free_string_field(data->plan.header.frame_id); + + navigation_free_occupancy_grid(&data->costmap); + + free_string_field(data->costmap_update.header.frame_id); + free_array(data->costmap_update.data, data->costmap_update.data_count); + + free_string_field(data->footprint.header.frame_id); + free_array(data->footprint.polygon.points, data->footprint.polygon.points_count); + + data->is_costmap_updated = false; +} diff --git a/src/Libraries/common_msgs b/src/Libraries/common_msgs index b6c387d..0313fe6 160000 --- a/src/Libraries/common_msgs +++ b/src/Libraries/common_msgs @@ -1 +1 @@ -Subproject commit b6c387dd0fcd4350edf2841767356ad6ee5f2c9e +Subproject commit 0313fe6aa2c2fb87b5e792d9d804f0b0f4b60cb8 diff --git a/src/Libraries/costmap_2d b/src/Libraries/costmap_2d index 2fcd211..9f7e2f8 160000 --- a/src/Libraries/costmap_2d +++ b/src/Libraries/costmap_2d @@ -1 +1 @@ -Subproject commit 2fcd211ccf121e28845f365550e7c21c68b26fc9 +Subproject commit 9f7e2f82f11ac1401cc94ff831d9d3e18921a8a7 diff --git a/src/Libraries/costmap_2d_dev_1_cam.zip b/src/Libraries/costmap_2d_dev_1_cam.zip new file mode 100644 index 0000000000000000000000000000000000000000..d287e80b4561832ea222c4a7f4ab631f72fa98a8 GIT binary patch literal 125010 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

lO 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 z

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 literal 0 HcmV?d00001 diff --git a/src/Libraries/data_convert b/src/Libraries/data_convert index 1cf62c0..5570c30 160000 --- a/src/Libraries/data_convert +++ b/src/Libraries/data_convert @@ -1 +1 @@ -Subproject commit 1cf62c085687dc167e28cded970371b329a83479 +Subproject commit 5570c30deb061fd5b94e405017692ba5c50af4bc diff --git a/src/Libraries/data_convert.zip b/src/Libraries/data_convert.zip new file mode 100644 index 0000000000000000000000000000000000000000..df05a405c1cd4d8b2ac671e27a88af110dcea280 GIT binary patch literal 7416 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

Azo*V(TZIK z(j(Be@hMr@)NCR1v?QW%@8H>0I@^w;TSAdfCdWesWB<18)Hy|1WI5xt0NE{pmB%h>mI zSLRbIc)C(NvF?3m>JKvt+0_zO+EN+IYWfO$vtob@2_8gNcfRduy2YJ7UmArQc^Cn_Ebz-iJdqrK#}cfK zCF&bzkE8jd6`l8iAy8YHl0u+xcJumrA--Zupd#|$z_)x63H`YU&$w=6!iC= z;71Q6NOtfO7O1))=y5b$*RP7qwexky33lRx#F%7v6szeTmO4Z^N!aj2zkQF0n*o*~ zN#_XkAiTfiNUA*~RLhmqvkA9OUp}g$Gl+MhFQ?>3Co&=sOB^_&mHd);lWJDHF3DwG z;oCK98x|-*!^3>2laRI8mV>x9i`6L0im|n>o8CkaE0;%MsoS@_j~wBZvT0XHQyIeK zAY5xrCQ^uci!LIjV9g3w$tGL}#uiLwawmw#C%JSzx>E>Kdu&_FeN$0i8Zy52>NWG!ZNDl$;~;UASmY9n znTE&cN~9c>sAj=YvO<$aw5ph?tzVX|7#2XCVNjcVd=(Mxa)@$i#-uEUO<l z>-NnV=lc)FLU<2g67%c_(N}mM-|)SpoBa@srOhOFk@@r#;E<@rGq+1a#Kr$gHTjY) z_%mx~I=T~sZ-8$B6Mbtcb^mz`2g9p8!Dbw~UA>p$cO$Rhth4XQFvK=9kYF#W8qtl} z7a@+y6rthf$GBKEmOg~LlijG~)eM~mZtfi)5^tP&&GG$;hmH@G7#Xg=&Q&-Wn;a*S z1rSlS@r2ovgP_~KZkZQo5^kEhc<_~D z+n#O#&v+-5HD1YGfTP1cmSJB{78|s?TrhTK__nK zctdUmrSL6l^57r|C9?z?fBl0n1JQ|$N;|_GDCGAApHWDjqCu8Yc)A4S0 zM`NbE73)c>Pa?C>(lj&i-nlCKJ)J({gmrp8!Ls|jSfE9A58HCa?3i@~j}+fA_5ZZE8brS`?ozPxyr5Ud(o3AuxM=#~bU7*RF{mg;S* z&`y8uJ``|9k=&Ws$Ez6{q!PDYNy8B!CaofQh+h!P8Ai;N?35m|Dm2&Da4c$0Y^dL9 z=B+W2Vh0x@{90a{VvDQyayD z*NmDe$fOn7ao9YLx9Kp)mr3Zy8ukdHM7^c&>c-o7ZKL+U9O0C3yE|LpDQlz#U17vDR7(%*Y~M= z#ZTY{)DPg%nvsnd>0w^0i8R=mchGazu#L@M+1CK;pO7(qat}vXDyDOj;ZeQ~*xJVc zp|c9n6F;Y+sF#x2TH&TK$wsePBvuzTee5IeEtK=pl(Ip36}28elp|+L%Va&825bIq zPJy4*B;yQGa9#sQ>x^z&Kwz|(nb7HiO~)&US}FkQy|3S?B$F6ufe<-rVLAxRaXLlw z%^-Vm&jiCGq7n>!i8!&N7IVK=%r z=9fBGxh2!Sm(;fpjiKkn;4l&ZaQkQ|D_4=fC?q{C_uS`Qhjm@UK+CAC9gd z>1e-Q(cjkye`evYRKlMw_WqNLe^1T-sTuxE&8=$qt3+_C8vd|4e<=EYIMToP`*rjG zYluHC^fq(1GQ_VWb}K{tusVOw@6`4yHrI~}{g*%gD^cQC=eIoh>&tM #include #include +#include #include #include #include @@ -184,6 +185,19 @@ namespace robot */ virtual void initialize(TFListenerPtr tf) = 0; + /** + * @brief Stop internal activity (control loop, planner...) before destruction. + * + * The host MUST be able to quiesce the navigation core at a chosen point in its + * own shutdown sequence, while the process is still fully alive — destroying the + * object from a static-destruction context after main() has returned is exactly + * the race that produced boost::lock_error crashes. Default is a no-op so legacy + * implementations remain source-compatible; after this call the object must stop + * producing velocity commands, and queries (getFeedback, getTwist...) must remain + * safe to call. Safe to call multiple times. + */ + virtual void shutdown() {} + /** * @brief Set the robot's footprint (outline shape) in the global frame. * This can be used for planning or collision checking. @@ -245,6 +259,14 @@ namespace robot */ virtual void addPointCloud2(const std::string &point_cloud2_name, robot_sensor_msgs::PointCloud2 point_cloud2) = 0; + /** + * @brief Add one coherent depth-camera sample to the navigation system. + * @param topic The logical topic of the combined depth-camera stream. + * @param data Depth image and matching camera intrinsics. + */ + virtual void addDepthCameraData(const std::string &topic, + robot_sensor_msgs::DepthCameraData::ConstPtr data) = 0; + /** * @brief Get a static map from the navigation system. * @param map_name The name of the map. diff --git a/src/Navigations/Cores/robot_nav_core2/include/robot_nav_core2/global_planner.h b/src/Navigations/Cores/robot_nav_core2/include/robot_nav_core2/global_planner.h index b437c3e..90465f6 100755 --- a/src/Navigations/Cores/robot_nav_core2/include/robot_nav_core2/global_planner.h +++ b/src/Navigations/Cores/robot_nav_core2/include/robot_nav_core2/global_planner.h @@ -36,6 +36,7 @@ #include #include +#include #include #include #include diff --git a/src/Navigations/Cores/robot_nav_core2/include/robot_nav_core2/local_planner.h b/src/Navigations/Cores/robot_nav_core2/include/robot_nav_core2/local_planner.h index 55802a8..24f8120 100755 --- a/src/Navigations/Cores/robot_nav_core2/include/robot_nav_core2/local_planner.h +++ b/src/Navigations/Cores/robot_nav_core2/include/robot_nav_core2/local_planner.h @@ -36,6 +36,7 @@ #include #include +#include #include #include #include diff --git a/src/Navigations/Packages/move_base/CMakeLists.txt b/src/Navigations/Packages/move_base/CMakeLists.txt index f1af110..2f761e0 100644 --- a/src/Navigations/Packages/move_base/CMakeLists.txt +++ b/src/Navigations/Packages/move_base/CMakeLists.txt @@ -46,6 +46,7 @@ if (NOT BUILDING_WITH_CATKIN) robot_cpp robot_move_base_msgs laser_filter + mission_adapters ) find_library(TF3_LIBRARY NAMES tf3 PATHS /usr/lib /usr/local/lib /usr/lib/x86_64-linux-gnu) else() @@ -65,12 +66,13 @@ else() robot_nav_2d_utils robot_cpp robot_move_base_msgs + mission_adapters ) find_library(TF3_LIBRARY NAMES tf3 PATHS /usr/lib /usr/local/lib /usr/lib/x86_64-linux-gnu) catkin_package( INCLUDE_DIRS include LIBRARIES ${PROJECT_NAME} - CATKIN_DEPENDS geometry_msgs robot_std_msgs move_base_core robot_nav_core robot_costmap_2d robot_tf3_sensor_msgs robot_tf3_geometry_msgs data_convert robot_nav_2d_utils robot_cpp robot_move_base_msgs + CATKIN_DEPENDS mission_adapters geometry_msgs robot_std_msgs move_base_core robot_nav_core robot_costmap_2d robot_tf3_sensor_msgs robot_tf3_geometry_msgs data_convert robot_nav_2d_utils robot_cpp robot_move_base_msgs DEPENDS Boost yaml-cpp ) diff --git a/src/Navigations/Packages/move_base/include/move_base/move_base.h b/src/Navigations/Packages/move_base/include/move_base/move_base.h index 5628a8d..bb8b4fc 100644 --- a/src/Navigations/Packages/move_base/include/move_base/move_base.h +++ b/src/Navigations/Packages/move_base/include/move_base/move_base.h @@ -18,6 +18,7 @@ #include #include #include +#include // boost headers #include @@ -140,6 +141,14 @@ namespace move_base * @param point_cloud2 The point cloud2 to add. */ virtual void addPointCloud2(const std::string &point_cloud2_name, robot_sensor_msgs::PointCloud2 point_cloud2) override; + + /** + * @brief Add one coherent depth-camera sample to the navigation system. + * @param topic The logical topic of the combined depth-camera stream. + * @param data Depth image and matching camera intrinsics. + */ + virtual void addDepthCameraData(const std::string &topic, + robot_sensor_msgs::DepthCameraData::ConstPtr data) override; /** * @brief Get a static map from the navigation system. @@ -705,4 +714,4 @@ namespace move_base } // namespace move_base -#endif // NAV_MOVE_BASE_ACTION_H_ \ No newline at end of file +#endif // NAV_MOVE_BASE_ACTION_H_ diff --git a/src/Navigations/Packages/move_base/package.xml b/src/Navigations/Packages/move_base/package.xml index 3a8f0bc..9746e12 100644 --- a/src/Navigations/Packages/move_base/package.xml +++ b/src/Navigations/Packages/move_base/package.xml @@ -49,6 +49,9 @@ robot_cpp robot_cpp + mission_adapters + mission_adapters + robot_move_base_msgs robot_move_base_msgs diff --git a/src/Navigations/Packages/move_base/src/move_base.cpp b/src/Navigations/Packages/move_base/src/move_base.cpp index 08d49ab..c63bb2d 100644 --- a/src/Navigations/Packages/move_base/src/move_base.cpp +++ b/src/Navigations/Packages/move_base/src/move_base.cpp @@ -613,6 +613,20 @@ void move_base::MoveBase::addPointCloud2(const std::string &point_cloud2_name, r updateGlobalCostmap(point_cloud2, robot_costmap_2d::LayerType::VOXEL_LAYER, point_cloud2_name); } +void move_base::MoveBase::addDepthCameraData(const std::string &topic, + robot_sensor_msgs::DepthCameraData::ConstPtr data) +{ + if (!data) + return; + + // robot::log_error("DEBUG"); + + updateLocalCostmap( + data, robot_costmap_2d::LayerType::VOXEL_LAYER, topic); + updateGlobalCostmap( + data, robot_costmap_2d::LayerType::VOXEL_LAYER, topic); +} + robot_sensor_msgs::PointCloud2 move_base::MoveBase::getPointCloud2(const std::string &point_cloud2_name) { auto it = point_cloud2s_.find(point_cloud2_name); @@ -3249,4 +3263,4 @@ robot::move_base_core::BaseNavigation::Ptr move_base::MoveBase::create() return std::make_shared(); } -BOOST_DLL_ALIAS(move_base::MoveBase::create, MoveBase) \ No newline at end of file +BOOST_DLL_ALIAS(move_base::MoveBase::create, MoveBase)