How to use Nav2, slam_toolbox with odom data, gps and imu sensors?

asked 2022-08-05 14:32:08 -0500

dvy gravatar image

Setup details: ROS2 foxy on amd64 architecture CPU with nav2 and slam_toolbox installed

Robot is Clearpath husky with Velodyne VLP-16 lidar, IMU and GPS sensor in gazebo. Can see data on every topic

Long term Objective: Provide gps co-ordinates as goal / way points and autonomously navigate robot to the destination with the help of Nav2 stack by using slam_toolbox

Short term objective: Obtain a stable map (drift free)/ no shaking behavior (if that's possible) using slam_toolbox which updates when obstacles are removed from environment.

Below are the topics. Sometimes /odometry/local is present, sometimes not even though the node is running through launch file. Also, ros2 node list does not show anything which seems weird to me.

/clock
/cmd_vel
/diagnostics
/downsampled_costmap
/downsampled_costmap_updates
/e_stop
/global_costmap/costmap
/global_costmap/costmap_updates
/goal_pose
/gps/data
/gps/filtered
/husky_velocity_controller/cmd_vel_unstamped
/imu/data
/initialpose
/joint_states
/joy_teleop/cmd_vel
/map
/map_updates
/odom
/odometry/global
/odometry/gps
/parameter_events
/plan
/robot_description
/rosout
/scan
/tf
/tf_static
/twist_marker_server/cmd_vel
/velodyne_points
/waypoints

My workflow is as below.

1) Spawn the robot in gazebo, all the sensors are outputting data.

2) Run ros2 launch pointcloud_to_laserscan sample_pointcloud_to_laserscan_launch.py to convert 3D point cloud to 2D laserscan on /scan topic which can be used later on by slam_toolbox

3) Since the odometry information (from topic /odom from wheel encoders) is know to have drift, its good to use EKF to fuse odometry data from other sensors (IMU and GPS). There are 4 scenarios/ combinations described down in the post and this is how I am calling the nodes in the launch file. I just comment ld.add_action(node_ekf_local) if I don't want to run the ekf_filter_node_odom as an example and so on.

    #Used for map to base_link TF
    node_ekf_global = Node(
        package='robot_localization',
        executable='ekf_node',
        name='ekf_filter_node_map',
        output='screen',
        remappings=[('odometry/filtered', 'odometry/global'),
                ('/set_pose', '/initialpose')],
        parameters=[config_husky_ekf, {'use_sim_time':True}],
        )
    ld.add_action(node_ekf_global)


    #Used for odom to base_link TF
    node_ekf_local = Node(
        package='robot_localization',
        executable='ekf_node',
        name='ekf_filter_node_odom',
        output='screen',
        remappings=[('odometry/filtered', 'odometry/local'),
                ('/set_pose', '/initialpose')],
        parameters=[config_husky_ekf, {'use_sim_time':True}],
        )
    ld.add_action(node_ekf_local)

    start_navsat_transform_cmd = Node(
        package='robot_localization',
        executable='navsat_transform_node',
        name='navsat_transform_node',
        output='screen',
        parameters=[config_husky_ekf, {'use_sim_time':True}],
        remappings=[('imu', 'imu/data'),
                    ('gps/fix', 'gps/data'), 
                    ('gps/filtered', 'gps/filtered'),
                    ('odometry/gps', 'odometry/gps'),
                    ('odometry/filtered', 'odometry/global')])
    ld.add_action(start_navsat_transform_cmd)

Below is the content of the yaml configuration file provided by config_husky_ekf which contains configuration for three nodes: ekf_filter_node_map (or global), ekf_filter_node_odom (or local), and navsat_transform_node (to convert gps co-ordinates to odometry data)

### ekf config file ### for odom to base_link transform
ekf_filter_node_odom:
    ros__parameters:

        use_sim_time: true


# The frequency, in Hz, at which the filter will output a position estimate. Note that the filter will not begin
# computation until it receives at least one message from one of the inputs. It will then run continuously at the
# frequency specified here, regardless of whether it receives more measurements. Defaults to 30 if unspecified.
        frequency: 50.0

# The period, in seconds, after which we consider a sensor to have timed out. In this event, we carry out a predict
# cycle ...
(more)
edit retag flag offensive close merge delete

Comments

Hi! I have a similar problem, so if you found any solutions in the end I would love to hear about it. Thanks!

Cferreira gravatar image Cferreira  ( 2023-03-24 04:43:50 -0500 )edit