rtabmap icon indicating copy to clipboard operation
rtabmap copied to clipboard

enhancing mapping kinect v1 ros 1 noetic and move base navigation

Open Bouchrikator opened this issue 4 months ago • 1 comments

hello hope you're doing well so am using a kinect v1 only based slam and am kinda having not quite the results that i want when i map how can i improve it make it smoother and more accurate and also i want it to map the floor quickly so what params that can help in that way , also how should be my move_base files and what move base methods should i use for the navigation i want to be guided because am only using kinect so i kinda got stuck and thank you here some exemple that i got and also here is my launch file :

Image Image
<launch>
  <!-- ================== ARGS ================== -->
  <arg name="model"                default="dd_robot6.urdf"/>
  <arg name="use_rtabmapviz"       default="true"/>
  <arg name="use_vo"               default="true"/>   <!-- visual odom node -->
  <arg name="use_ekf"              default="true"/>
  <arg name="virtual_scan"         default="true"/>
  <arg name="rviz_config"          default="$(find robot_diff)/urdf.rviz"/>
  <arg name="db_path"              default="$(env HOME)/.ros/rtabmap.db"/>

  <!-- ================== ROBOT DESCRIPTION ================== -->
  <param name="robot_description" textfile="$(find robot_diff)/urdf/$(arg model)"/>

  <node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher"/>
  <node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher"/>

  <!-- ===== STATIC TF: base_link -> camera_link (EDIT the 6 numbers!) ===== -->
  <node pkg="tf2_ros" type="static_transform_publisher" name="cam_tf"
        args="0.2 0 0.1 0 0 0 base_link camera_link"/>

  <node pkg="topic_tools" type="relay" name="grid_map_relay" output="screen" args="/rtabmap/grid_map /map" />
  <!-- ===== diff_tf disabled (don't publish odom->base_link) -->
  <node pkg="robot_diff" type="diff_tf.py" name="diff_tf" output="screen">
    <param name="publish_tf" value="false"/>
  </node>

  <!-- ===== Trajectory viz ===== -->
  <node name="robot_trajectory_visualization"
        pkg="robot_diff"
        type="trajectory_visualization.py"
        output="screen"/>

  <!-- ===== Rosbridge ===== -->
  <include file="$(find rosbridge_server)/launch/rosbridge_websocket.launch">
    <arg name="port" value="9090"/>
  </include>

  <!-- ===== RViz ===== -->
  <node name="rviz" pkg="rviz" type="rviz"
        args="-d $(arg rviz_config)"
        required="true" />

  <param name="use_sim_time" value="false"/>

  <!-- ================== VISUAL ODOMETRY (rgbd_odometry) ================== -->
  <group if="$(arg use_vo)">
    <node pkg="rtabmap_odom" type="rgbd_odometry" name="rgbd_odometry" output="screen">
      <!-- Frames -->
      <param name="frame_id" value="base_link"/>
      <param name="odom_frame_id" value="odom_vo"/>
      <param name="publish_tf" value="false"/>

      <!-- Help VO stick using motion guess -->
      <param name="Odom/GuessMotion" value="true"/>

      <!-- Advanced VO tuning (from Advanced Parameter Tuning) -->
      <param name="Odom/Strategy" value="0"/>          <!-- F2F odometry -->
      <param name="Vis/CorType" value="0"/>            <!-- Optical flow -->
      <param name="OdomF2M/MaxSize" value="1000"/>     <!-- F2M feature buffer -->
      <param name="Vis/MaxFeatures" value="1000"/>      <!-- per-image features -->
      <param name="GFTT/MinDistance" value="40"/>      <!-- for ≥720p images -->
      <param name="Reg/Force3DoF" value="true"/>       <!-- planar odom -->
      <!-- Your thresholds/features kept -->
      <param name="Odom/MinInliers"  value="12"/>
      <param name="Vis/MinInliers"   value="12"/>
      <param name="Kp/MaxFeatures"   value="1500"/>
      <param name="Odom/FilteringStrategy"   value="1"/>
      <!-- Sync tuning -->
      <param name="approx_sync" value="true"/>
      <param name="approx_sync_max_interval" value="0.05"/>

      <!-- Auto reset after 1 bad frame -->
      <param name="Odom/ResetCountdown" value="20"/>

      <!-- Feed EKF odom as guess -->
      <remap from="odom" to="/odom"/>

      <!-- Camera topics -->
      <remap from="rgb/image"       to="/camera/rgb/image_color"/>
      <remap from="depth/image"     to="/camera/depth/image"/>
      <remap from="rgb/camera_info" to="/camera/rgb/camera_info"/>
    </node>
  </group>

  <!-- ================== EKF (robot_localization) ================== -->
  <group if="$(arg use_ekf)">
    <node pkg="robot_localization"
          type="ekf_localization_node"
          name="ekf_odom"
          output="screen">
      <remap from="odometry/filtered" to="/odom"/>
      <rosparam file="$(find robot_diff)/params/ekf.yaml" command="load"/>
    </node>
  </group>

  <!-- ================== RTAB-Map SLAM ================== -->
  <include file="$(find rtabmap_ros)/launch/rtabmap.launch">
    <!-- Camera topics -->
    <arg name="rgb_topic"         value="/camera/rgb/image_rect_color"/>
    <arg name="depth_topic"       value="/camera/depth_registered/image_raw"/>
    <arg name="camera_info_topic" value="/camera/rgb/camera_info"/>

    <!-- External odom -->
    <arg name="icp_odometry" value="false"/>
    <arg name="odom_topic"   value="/odom"/>

    <!-- Frames -->
    <arg name="frame_id"      value="base_link"/>
    <arg name="odom_frame_id" value="odom"/>

    <!-- Sync -->
    <arg name="approx_sync" value="true"/>
    <arg name="queue_size"  value="20"/>
    <param name="approx_sync_max_interval" value="0.05"/>

    <!-- ===== RTAB-Map (SLAM) params from Advanced Tuning ===== -->
    <!-- Planar SLAM (3-DoF) -->
    <param name="Reg/Force3DoF" value="true"/>
    <param name="Optimizer/Slam2D" value="true"/>

    <!-- Initial costmap (min map extent) -->
    <param name="grid_size" type="double" value="90"/>

    <!-- Reduce 3D point cloud noise (radius outlier removal) -->
    <param name="cloud_noise_filtering_radius" value="0.08"/>
    <param name="cloud_noise_filtering_min_neighbors" value="100"/>

    <!-- Projected occupancy grid characteristics -->
    <param name="proj_max_ground_angle" value="60"/>
    <param name="proj_max_ground_height" value="0.001"/>
    <param name="proj_max_height" value="2.0"/>
    <param name="proj_min_cluster_size" value="1000"/>

    <!-- Mapping behavior when odom resets -->
    <param name="Rtabmap/StartNewMapOnLoopClosure" value="true"/>

    <!-- ===== Extra RTAB-Map params for a cleaner, high-fidelity map ===== -->
    <!-- Process all frames -->
    <param name="Rtabmap/DetectionRate" value="0"/>

    <!-- Stronger feature set + stricter matching -->
    <param name="Kp/MaxFeatures" value="2500"/>
    <param name="Kp/MaxDepth"    value="4.5"/>
    <param name="Vis/MinDepth"   value="0.3"/>
    <param name="Vis/MinInliers" value="30"/>
    <param name="Vis/CorNNDR"    value="0.75"/>

    <!-- Refine neighbor constraints + ICP polishing -->
    <param name="RGBD/NeighborLinkRefining" value="true"/>
    <param name="Icp/PointToPlane"          value="true"/>
    <param name="Icp/Iterations"            value="50"/>
    <param name="Icp/MaxCorrespondenceDistance" value="0.05"/>

    <!-- Occupancy grid: finer cells + stronger denoising + freespace ray tracing -->
    <param name="Grid/CellSize"                   value="0.02"/>
    <param name="Grid/PreVoxelFiltering"          value="true"/>
    <param name="Grid/NoiseFilteringRadius"       value="0.06"/>
    <param name="Grid/NoiseFilteringMinNeighbors" value="10"/>
    <param name="Grid/NormalsSegmentation"        value="true"/>
    <param name="Grid/RayTracing"                 value="true"/>

    <!-- Robust loop closures & optimization -->
    <param name="Rtabmap/LoopThr"          value="0.12"/>
    <param name="Optimizer/Robust"         value="true"/>
    <param name="Optimizer/Iterations"     value="200"/>
    <param name="RGBD/OptimizeMaxError"    value="2.0"/>

    <!-- Spatial proximity loop closures -->
    <param name="RGBD/ProximityBySpace"           value="true"/>
    <param name="RGBD/ProximityMaxGraphDepth"     value="50"/>
    <param name="RGBD/ProximityPathFilteringRadius" value="1.0"/>
    <param name="RGBD/ProximityMaxPaths"          value="3"/>

    <!-- DB + remaining args you already used -->
    <arg name="database_path" value="$(arg db_path)"/>
    <arg name="rtabmapviz"    value="$(arg use_rtabmapviz)"/>
    <arg name="rtabmap_args"  value="--delete_db_on_start \
                                     --Reg/Strategy 0 \
                                     --Vis/FeatureType 1 \
                                     --Kp/DetectorStrategy 4 \
                                     --Kp/MaxFeatures 1000"/>
  </include>

  <!-- ================== Virtual Laser (PointCloud2 -> LaserScan) ================== -->
  <group if="$(arg virtual_scan)">
    <node pkg="pointcloud_to_laserscan" type="pointcloud_to_laserscan_node" name="pc2scan" output="screen">
      <param name="target_frame" value="base_link"/>
      <param name="min_height" value="0.01"/>
      <param name="max_height" value="0.20"/>
      <param name="range_min" value="0.01"/>
      <param name="range_max" value="8.0"/>
      <remap from="cloud_in" to="/camera/depth_registered/points"/>
      <remap from="scan"     to="/scan"/>
    </node>
  </group>
</launch>

Bouchrikator avatar Aug 20 '25 00:08 Bouchrikator

Which version of rtabmap/ros are you using? rtabmap.launch from rtabmap_ros package (not rtabmap_launch) is kinda old.

Note also that if you launch yourself rgbd_odometry and rtabmap.launch like this, rtabmap.launch also starts its own rgbd_odometry node. You should explicitly set visual_odometry:=false for rtabmap.launch to not use it.

Instead of:

<node pkg="topic_tools" type="relay" name="grid_map_relay" output="screen" args="/rtabmap/grid_map /map" />

you could do:

<remap from="/rtabmap/grid_map" to="/map"/>

before rtabmap.launch include.

To include EKF as guess grame for rgbd_odometry, you cannot do:

<!-- Feed EKF odom as guess -->
<remap from="odom" to="/odom"/>

you should do this instead:

<!-- Feed EKF odom as guess -->
<param name="guess_frame_id" value="odom"/> <!-- the TF frame published by EKF node -->
<remap from="odom" to="/odom_vo"/> <!-- remap to a topic name different than the output /odom from EKF node -->

I don't recommend using:

<param name="Rtabmap/DetectionRate" value="0"/>

the max I set myself is 2 Hz, but generally use always 1 Hz.

For a move_base integration example, you may check this turtlebot3 example on ros1, or this on ros2. Note that in both cases, we don't use visual odometry because indoor with a single camera the visual odometry can get lost often or be not super accurate. If you can get a good wheel / EKF odometry already, I would use only rtabmap node at 1 or 2 Hz update rate. If the occupancy grid looks already good, then to make it smoother and faster it would be more a tuning problem for move_base afterwards. I used rqt_reconfigure a lot with move_base to tune it live, if that can help you.

matlabbe avatar Aug 21 '25 22:08 matlabbe