I have differential drive robot with Roboteq controller. After successfully created the map with slam_toolbox and localise the robot I tried to use the Nav2 to navigate the robot. Im using ROS2 humble. The controller try to navigate the robot to the goal pose but is stuck.
Here the launch file for mapping and localisation
from launch import LaunchDescription
from launch_ros.actions import Node
from launch.actions import IncludeLaunchDescription
from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch.substitutions import ThisLaunchFileDir, LaunchConfiguration, Command
from ament_index_python.packages import get_package_share_directory
import launch_ros
import os
def generate_launch_description():
pkg_share = launch_ros.substitutions.FindPackageShare(package='amr_bot').find('amr_bot')
#slam_params_file_path = os.path.join(get_package_share_directory('your_package_name'), 'config', 'mapper_params_online_async.yaml')
# Static Transform Publishers
static_tf_base_to_laser = Node(
package='tf2_ros',
executable='static_transform_publisher',
arguments=['-0.02', '0.02', '-0.02', '0', '0', '0', 'base_link', 'laser_link'],
)
static_tf_base_to_odom = Node(
package='tf2_ros',
executable='static_transform_publisher',
arguments=['-0.002', '0', '-0.002', '0', '0', '0', 'base_link', 'odom'],
)
static_tf_base_to_footprint = Node(
package='tf2_ros',
executable='static_transform_publisher',
arguments=['0', '0', '0', '0', '0', '0', 'base_link', 'base_footprint'],
)
camera2base_node = Node(
package = 'tf2_ros',
executable = 'static_transform_publisher',
arguments = ['-0.04','0', '0', '0', '0', '0', 'base_link', 'camera_link'],
)
#ros2 run realsense2_camera realsense2_camera_node
#rs_camera_node = Node(
#package = 'realsense2_camera',
#executable = 'realsense2_camera_node',
#using unite_imu_method is important, or the imu messages will be separated
#arguments = {'align_depth': True, 'linear_accel_cov': '1.0', 'unite_imu_method':'2' ,
#'initial_reset':'true', 'enable_gyro':'true', 'enable_accel':'true'},
#)
#include_realsense2_camera = IncludeLaunchDescription(
#PythonLaunchDescriptionSource(os.path.join(
#get_package_share_directory('realsense2_camera'),
#'launch',
#'rs_launch.py' )),
#launch_arguments={
#'align_depth.enable': 'true',
#'linear_accel_cov': '1.0',
#'unite_imu_method': '2', 'initial_reset':'true', 'enable_gyro':'true', 'enable_accel':'true'
# 'filters': 'pointcloud',
#}.items()
#)
include_realsense2_camera = IncludeLaunchDescription(
PythonLaunchDescriptionSource(os.path.join(
get_package_share_directory('realsense2_camera'),
'launch',
'rs_launch.py'
)),
launch_arguments={
'align_depth.enable': 'true',
'linear_accel_cov': '1.0',
'unite_imu_method': '2',
'initial_reset':'true',
'enable_gyro':'true',
'enable_accel':'true',
'enable_infra1':'true',
'enable_infra2':'true',
'gyro_fps':'200',
'accel_fps': '250',
'enable_sync': 'true'
# 'filters': 'pointcloud',
}.items()
)
# Lidar Driver Launch
lslidar_launch = IncludeLaunchDescription(
PythonLaunchDescriptionSource(
os.path.join(get_package_share_directory('lslidar_driver'), 'launch', 'lslidar_launch.py')),
)
# Corrected Roboteq Driver Launch
roboteq_driver_launch = IncludeLaunchDescription(
PythonLaunchDescriptionSource(
os.path.join(get_package_share_directory('roboteq_ros2_driver'), 'launch', 'roboteq_ros2_driver.launch.py') ),
#launch_arguments={'config': os.path.join(get_package_share_directory('roboteq_ros2_driver'), 'config', 'roboteq.yaml')}.items(),
)
# filter that fuses imu msg into odom msg
#download from here ->https://github.com/CCNYRoboticsLab/imu_tools/tree/humble
imu_to_odom_node = Node(
package='imu_filter_madgwick',
executable='imu_filter_madgwick_node',
name='imu_filter',
parameters=[{
'use_mag': False,
'mag_bias_x': 0.0,
'mag_bias_y': 0.0,
'mag_bias_z': 0.0,
'orientation_stddev': 0.02,
'gain': 0.02,
'zeta': 0.002,
'publish_tf': False
}],
remappings=[
#change to your camera imu topic
('/imu/data_raw', '/camera/camera/imu'), ],
)
#launch frame matcher
points_xyzrgb_node = Node(
package='rtabmap_util',
executable='point_cloud_xyzrgb',
#namespace='/rtabmap',
output='screen',
parameters=[{'decimation': 4, 'voxel_size': 0.05, 'approx_sync': False}],
remappings=[('cloud', '/camera/camera/depth/image_rect_raw')],
)
#rgbd_odometry_node = Node(
#package='rtabmap_odom',
#executable='rgbd_odometry',
#output='screen',
#parameters=[{
#'frame_id': 'camera_link',
#'subscribe_rgbd':False,
#'publish_tf': False,
#'publish_null_when_lost': False,
#'guess_from_tf': True,
#'Odom/FillInfoData': True,
#'Odom/ResetCountdown': 1,
#'Vis/FeatureType': 6,
#'OdomF2M/MaxSize': 1000,}],
#remappings=[
#('rgb/image', '/camera/camera/color/image_raw'),
#('depth/image', '/camera/camera/aligned_depth_to_color/image_raw'),
#('rgb/camera_info', '/camera/camera/color/camera_info'),
#('odom', 'odom/rgbd1'),],
#)
rgbd_odom_node = Node(
package='rtabmap_odom', executable='stereo_odometry', output='screen',
parameters=[{
'frame_id':'camera_link',
'subscribe_depth':True,
#'subscribe_stereo':True,
'subscribe_odom_info':True,
'approx_sync':False,
'wait_imu_to_init':True}],
remappings=[
('imu', '/imu/data'),
#('rgb/image', '/camera/camera/infra1/image_rect_raw'),
('left/image_rect', '/camera/camera/infra1/image_rect_raw'),
#('rgb/camera_info', '/camera/camera/infra1/camera_info'),
('left/camera_info', '/camera/camera/infra1/camera_info'),
#('depth/image', '/camera/camera/depth/image_rect_raw'),
('right/image_rect', '/camera/camera/infra2/image_rect_raw'),
('right/camera_info', '/camera/camera/infra2/camera_info'),
('odom', 'odom/rgbd')],
)
rgbd_odometry_node = Node(
package='rtabmap_odom',
executable='rgbd_odometry',
output='screen',
parameters=[{
'frame_id': 'camera_link',
'publish_tf': False,
'approx_sync':True,
'publish_null_when_lost': True,
'Odom/FillInfoData': True,
'Odom/ResetCountdown': 5,}],
#change to your camera topics
remappings=[
('rgb/image', '/camera/camera/color/image_raw'),
('depth/image', '/camera/camera/aligned_depth_to_color/image_raw'),
('rgb/camera_info', '/camera/camera/color/camera_info'),
('odom', 'odom/rgbd'),],
)
icp_odometry_node = Node(
package='rtabmap_odom',
executable='icp_odometry',
output='screen',
parameters=[{
'frame_id': 'laser_link',
'subscribe_depth':True,
'subscribe_scan_cloud': False,
'scan_cloud_max_points': 1000,
'scan_range_max': 20.0,
'scan_range_min': 0.02,
'subscribe_scan':True,
'subscribe_rgbd':False,
'subscribe_rgb':False,
'use_sim_time': False,
'odom_frame_id':'odom',
#'queue_size': 10,
'queue_size': 10,
'map_always_update': True,
'map_empty_ray_tracing': True,
'approx_sync': True,
'publish_tf': False,}],
remappings=[
('rgb/camera_info', '/camera/camera/color/camera_info'),
('depth/image', '/camera/camera/depth/image_raw' ),
('odom', 'odom/icp'),],
)
robot_localization_node = Node(
package='robot_localization',
executable='ekf_node',
name='ekf_filter_node',
output='screen',
#parameters=[os.path.join(ThisLaunchFileDir(), 'config/ekf.yaml')],
parameters=[os.path.join(pkg_share, 'config/ekf.yaml')],
)
# gmapping Launch
gmapping_node = Node(
package ='slam_gmapping',
executable ='slam_gmapping',
output='screen',
parameters=[{'use_sim_time':False,'base_frame':'base_link','map_frame':'map','odom_frame':'odom',}],
)
slam_toolbox_launch_file = os.path.join(get_package_share_directory('slam_toolbox'), 'launch', 'online_async_launch.py')
slam_params_file_path = os.path.join(get_package_share_directory('amr_bot'), 'config', 'mapper_params_online_async.yaml')
slam_toolbox_node = Node(
package='slam_toolbox',
executable='async_slam_toolbox_node',
name='slam_toolbox',
output='screen',
parameters=[{'slam_toolbox_config_file': slam_params_file_path}],
remappings=[
('/scan', '/scan'), # Remap from /scan to your custom scan topic
# Add more remappings as needed
],
)
slam_toolbox_launch = IncludeLaunchDescription(
PythonLaunchDescriptionSource(slam_toolbox_launch_file),
launch_arguments={
'autostart': 'true',
#'use_lifecycle_manager': ,
'use_sim_time': 'false',
'slam_params_file': slam_params_file_path}.items(),
)
return LaunchDescription([
static_tf_base_to_laser,
static_tf_base_to_odom,
static_tf_base_to_footprint,
lslidar_launch,
roboteq_driver_launch,
imu_to_odom_node,
#rgbd_odometry_node,
#rgbd_odom_node,
robot_localization_node,
#gmapping_node,
icp_odometry_node,
points_xyzrgb_node,
camera2base_node,
#rs_camera_node,
include_realsense2_camera,
slam_toolbox_launch,
slam_toolbox_node,
])
Then I run the nav2 with
ros2 launch nav2_bringup bringup_launch.py use_sim_time:=False autostart:=False map:=/map_15_3_1.yaml params_file:=nav2_params.yaml
here the nav2 launch file
# Copyright (c) 2018 Intel Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch.actions import (DeclareLaunchArgument, GroupAction,
IncludeLaunchDescription, SetEnvironmentVariable)
from launch.conditions import IfCondition
from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch.substitutions import LaunchConfiguration, PythonExpression
from launch_ros.actions import Node
from launch_ros.actions import PushRosNamespace
from launch_ros.descriptions import ParameterFile
from nav2_common.launch import RewrittenYaml, ReplaceString
def generate_launch_description():
# Get the launch directory
bringup_dir = get_package_share_directory('nav2_bringup')
launch_dir = os.path.join(bringup_dir, 'launch')
# Create the launch configuration variables
namespace = LaunchConfiguration('namespace')
use_namespace = LaunchConfiguration('use_namespace')
slam = LaunchConfiguration('slam')
map_yaml_file = LaunchConfiguration('map')
use_sim_time = LaunchConfiguration('use_sim_time')
params_file = LaunchConfiguration('params_file')
autostart = LaunchConfiguration('autostart')
use_composition = LaunchConfiguration('use_composition')
use_respawn = LaunchConfiguration('use_respawn')
log_level = LaunchConfiguration('log_level')
# Map fully qualified names to relative ones so the node's namespace can be prepended.
# In case of the transforms (tf), currently, there doesn't seem to be a better alternative
# https://github.com/ros/geometry2/issues/32
# https://github.com/ros/robot_state_publisher/pull/30
# TODO(orduno) Substitute with `PushNodeRemapping`
# https://github.com/ros2/launch_ros/issues/56
remappings = [('/tf', 'tf'),
('/tf_static', 'tf_static')]
# Create our own temporary YAML files that include substitutions
param_substitutions = {
'use_sim_time': use_sim_time,
'yaml_filename': map_yaml_file}
# Only it applys when `use_namespace` is True.
# '<robot_namespace>' keyword shall be replaced by 'namespace' launch argument
# in config file 'nav2_multirobot_params.yaml' as a default & example.
# User defined config file should contain '<robot_namespace>' keyword for the replacements.
params_file = ReplaceString(
source_file=params_file,
replacements={'<robot_namespace>': ('/', namespace)},
condition=IfCondition(use_namespace))
configured_params = ParameterFile(
RewrittenYaml(
source_file=params_file,
root_key=namespace,
param_rewrites=param_substitutions,
convert_types=True),
allow_substs=True)
stdout_linebuf_envvar = SetEnvironmentVariable(
'RCUTILS_LOGGING_BUFFERED_STREAM', '1')
declare_namespace_cmd = DeclareLaunchArgument(
'namespace',
default_value='',
description='Top-level namespace')
declare_use_namespace_cmd = DeclareLaunchArgument(
'use_namespace',
default_value='false',
description='Whether to apply a namespace to the navigation stack')
declare_slam_cmd = DeclareLaunchArgument(
'slam',
default_value='False',
description='Whether run a SLAM')
declare_map_yaml_cmd = DeclareLaunchArgument(
'map',
description='Full path to map yaml file to load')
declare_use_sim_time_cmd = DeclareLaunchArgument(
'use_sim_time',
default_value='false',
description='Use simulation (Gazebo) clock if true')
declare_params_file_cmd = DeclareLaunchArgument(
'params_file',
default_value=os.path.join(bringup_dir, 'params', 'nav2_params.yaml'),
description='Full path to the ROS2 parameters file to use for all launched nodes')
declare_autostart_cmd = DeclareLaunchArgument(
'autostart', default_value='true',
description='Automatically startup the nav2 stack')
declare_use_composition_cmd = DeclareLaunchArgument(
'use_composition', default_value='True',
description='Whether to use composed bringup')
declare_use_respawn_cmd = DeclareLaunchArgument(
'use_respawn', default_value='False',
description='Whether to respawn if a node crashes. Applied when composition is disabled.')
declare_log_level_cmd = DeclareLaunchArgument(
'log_level', default_value='info',
description='log level')
# Specify the actions
bringup_cmd_group = GroupAction([
PushRosNamespace(
condition=IfCondition(use_namespace),
namespace=namespace),
Node(
condition=IfCondition(use_composition),
name='nav2_container',
package='rclcpp_components',
executable='component_container_isolated',
parameters=[configured_params, {'autostart': autostart}],
arguments=['--ros-args', '--log-level', log_level],
remappings=remappings,
output='screen'),
IncludeLaunchDescription(
PythonLaunchDescriptionSource(os.path.join(launch_dir, 'slam_launch.py')),
condition=IfCondition(slam),
launch_arguments={'namespace': namespace,
'use_sim_time': use_sim_time,
'autostart': autostart,
'use_respawn': use_respawn,
'params_file': params_file}.items()),
IncludeLaunchDescription(
PythonLaunchDescriptionSource(os.path.join(launch_dir,
'localization_launch.py')),
condition=IfCondition(PythonExpression(['not ', slam])),
launch_arguments={'namespace': namespace,
'map': map_yaml_file,
'use_sim_time': use_sim_time,
'autostart': autostart,
'params_file': params_file,
'use_composition': use_composition,
'use_respawn': use_respawn,
'container_name': 'nav2_container'}.items()),
IncludeLaunchDescription(
PythonLaunchDescriptionSource(os.path.join(launch_dir, 'navigation_launch.py')),
launch_arguments={'namespace': namespace,
'use_sim_time': use_sim_time,
'autostart': autostart,
'params_file': params_file,
'use_composition': use_composition,
'use_respawn': use_respawn,
'container_name': 'nav2_container'}.items()),
])
# Create the launch description and populate
ld = LaunchDescription()
# Set environment variables
ld.add_action(stdout_linebuf_envvar)
# Declare the launch options
ld.add_action(declare_namespace_cmd)
ld.add_action(declare_use_namespace_cmd)
ld.add_action(declare_slam_cmd)
ld.add_action(declare_map_yaml_cmd)
ld.add_action(declare_use_sim_time_cmd)
ld.add_action(declare_params_file_cmd)
ld.add_action(declare_autostart_cmd)
ld.add_action(declare_use_composition_cmd)
ld.add_action(declare_use_respawn_cmd)
ld.add_action(declare_log_level_cmd)
# Add the actions to launch all of the navigation nodes
ld.add_action(bringup_cmd_group)
return ld
and start the rviz2
Here the RVIZ
and the output of the nav2 in the terminal
service clients [INFO] [launch_ros.actions.load_composable_nodes]: Loaded node '/lifecycle_manager_navigation' in container '/nav2_container' ^C[WARNING] [launch]: user interrupted with ctrl-c (SIGINT) [component_container_isolated-1] [INFO] [1710484832.888408006] [rclcpp]: signal_handler(signum=2) [component_container_isolated-1] [INFO] [1710484832.888679601] [waypoint_follower]: Running Nav2 LifecycleNode rcl preshutdown (waypoint_follower) [component_container_isolated-1] [INFO] [1710484832.888755495] [waypoint_follower]: Destroying bond (waypoint_follower) to lifecycle manager. [component_container_isolated-1] [INFO] [1710484832.888763064] [bt_navigator]: Running Nav2 LifecycleNode rcl preshutdown (bt_navigator) [component_container_isolated-1] [INFO] [1710484832.888771364] [bt_navigator]: Destroying bond (bt_navigator) to lifecycle manager. [component_container_isolated-1] [INFO] [1710484832.888777373] [velocity_smoother]: Running Nav2 LifecycleNode rcl preshutdown (velocity_smoother) [component_container_isolated-1] [INFO] [1710484832.888785376] [velocity_smoother]: Destroying bond (velocity_smoother) to lifecycle manager. [component_container_isolated-1] [INFO] [1710484832.888789816] [behavior_server]: Running Nav2 LifecycleNode rcl preshutdown (behavior_server) [component_container_isolated-1] [INFO] [1710484832.888798101] [behavior_server]: Destroying bond (behavior_server) to lifecycle manager. [component_container_isolated-1] [INFO] [1710484832.888803016] [global_costmap.global_costmap]: Running Nav2 LifecycleNode rcl preshutdown (global_costmap) [component_container_isolated-1] [INFO] [1710484832.888811157] [global_costmap.global_costmap]: Destroying bond (global_costmap) to lifecycle manager. [component_container_isolated-1] [INFO] [1710484832.888817116] [lifecycle_manager_localization]: Running Nav2 LifecycleManager rcl preshutdown (lifecycle_manager_localization) [component_container_isolated-1] [INFO] [1710484832.893635551] [planner_server]: Running Nav2 LifecycleNode rcl preshutdown (planner_server) [component_container_isolated-1] [INFO] [1710484832.893669297] [planner_server]: Destroying bond (planner_server) to lifecycle manager. [component_container_isolated-1] [INFO] [1710484832.893673567] [amcl]: Running Nav2 LifecycleNode rcl preshutdown (amcl) [component_container_isolated-1] [INFO] [1710484832.893680723] [amcl]: Destroying bond (amcl) to lifecycle manager. [component_container_isolated-1] [INFO] [1710484832.893684446] [smoother_server]: Running Nav2 LifecycleNode rcl preshutdown (smoother_server) [component_container_isolated-1] [INFO] [1710484832.893693013] [smoother_server]: Destroying bond (smoother_server) to lifecycle manager. [component_container_isolated-1] [INFO] [1710484832.893696299] [map_server]: Running Nav2 LifecycleNode rcl preshutdown (map_server) [component_container_isolated-1] [INFO] [1710484832.893700887] [map_server]: Destroying bond (map_server) to lifecycle manager. [component_container_isolated-1] [INFO] [1710484832.893704871] [lifecycle_manager_navigation]: Running Nav2 LifecycleManager rcl preshutdown (lifecycle_manager_navigation) [component_container_isolated-1] [INFO] [1710484832.904373069] [local_costmap.local_costmap]: Running Nav2 LifecycleNode rcl preshutdown (local_costmap) [component_container_isolated-1] [INFO] [1710484832.904429558] [local_costmap.local_costmap]: Destroying bond (local_costmap) to lifecycle manager. [component_container_isolated-1] [INFO] [1710484832.904434455] [controller_server]: Running Nav2 LifecycleNode rcl preshutdown (controller_server) [component_container_isolated-1] [INFO] [1710484832.904440043] [controller_server]: Destroying bond (controller_server) to lifecycle manager.
Here is the controler log
[INFO] [1710825585.014564751] [controller_server]:
controller_server lifecycle node launched.
Waiting on external lifecycle transitions to activate
See https://design.ros2.org/articles/node_lifecycle.html for more information.
[INFO] [1710825585.023839210] [controller_server]: Creating controller server
[INFO] [1710825585.031004619] [local_costmap.local_costmap]:
local_costmap lifecycle node launched.
Waiting on external lifecycle transitions to activate
See https://design.ros2.org/articles/node_lifecycle.html for more information.
[INFO] [1710825585.032567899] [local_costmap.local_costmap]: Creating Costmap
[INFO] [1710825652.745676708] [controller_server]: Configuring controller interface
[INFO] [1710825652.745910925] [controller_server]: getting goal checker plugins..
[INFO] [1710825652.746057955] [controller_server]: Controller frequency set to 20.0000Hz
[INFO] [1710825652.746099470] [local_costmap.local_costmap]: Configuring
[INFO] [1710825652.751358090] [local_costmap.local_costmap]: Using plugin "static_layer"
[INFO] [1710825652.760378301] [local_costmap.local_costmap]: Subscribing to the map topic (/map) with transient local durability
[INFO] [1710825652.763639891] [local_costmap.local_costmap]: Initialized plugin "static_layer"
[INFO] [1710825652.763703329] [local_costmap.local_costmap]: Using plugin "obstacle_layer"
[INFO] [1710825652.764864160] [local_costmap.local_costmap]: Subscribed to Topics:
[INFO] [1710825652.764957138] [local_costmap.local_costmap]: Initialized plugin "obstacle_layer"
[INFO] [1710825652.764971485] [local_costmap.local_costmap]: Using plugin "inflation_layer"
[INFO] [1710825652.765273358] [local_costmap.local_costmap]: Initialized plugin "inflation_layer"
[INFO] [1710825652.778955286] [controller_server]: Created progress_checker : progress_checker of type nav2_controller::SimpleProgressChecker
[INFO] [1710825652.779281606] [local_costmap.local_costmap]: StaticLayer: Resizing costmap to 241 X 267 at 0.050000 m/pix
[INFO] [1710825652.782659669] [controller_server]: Created goal checker : goal_checker of type nav2_controller::SimpleGoalChecker
[INFO] [1710825652.783075356] [controller_server]: Controller Server has goal_checker goal checkers available.
[INFO] [1710825652.787465730] [controller_server]: Created controller : FollowPath of type dwb_core::DWBLocalPlanner
[INFO] [1710825652.790595747] [controller_server]: Setting transform_tolerance to 0.100000
[ERROR] [1710825652.809613691] [controller_server]: Couldn't load critics! Caught exception: No critics defined for FollowPath
[ERROR] [1710825652.819932433] [controller_server]: Caught exception in callback for transition 10
[ERROR] [1710825652.820056641] [controller_server]: Original error: No critics defined for FollowPath
[WARN] [1710825652.820110026] [controller_server]: Error occurred while doing error handling.
[FATAL] [1710825652.820140596] [controller_server]: Lifecycle node controller_server does not have error state implemented
[INFO] [1710825681.850150027] [rclcpp]: signal_handler(signum=2)
[INFO] [1710825681.850433018] [local_costmap.local_costmap]: Running Nav2 LifecycleNode rcl preshutdown (local_costmap)
[INFO] [1710825681.850571977] [local_costmap.local_costmap]: Cleaning up
[INFO] [1710825681.853669747] [local_costmap.local_costmap]: Destroying bond (local_costmap) to lifecycle manager.
[INFO] [1710825681.853724837] [controller_server]: Running Nav2 LifecycleNode rcl preshutdown (controller_server)
[INFO] [1710825681.853744622] [controller_server]: Destroying bond (controller_server) to lifecycle manager.
Any help why the robot is not navigating?