开始小车测试之前,先补充下背景知识
nav2
Navigation2具有下列工具:
加载、提供和存储地图的工具(地图服务器Map Server)
在地图上定位机器人的工具 (AMCL)
避开障碍物从A点移动到B点的路径规划工具(Nav2 Planner)
跟随路径过程中控制机器人的工具(Nav2 Controller)
将传感器数据转换为机器人世界中的成本地图表达的工具(Nav2 Costmap 2D)
使用行为树构建复杂机器人行为的工具(Nav2 行为树和BT Navigator)
发生故障时计算恢复行为的工具(Nav2 Recoveries)
跟随顺序航点的工具(Nav2 Waypoint Follower)
管理服务器生命周期的工具和看门狗(Nav2 Lifecycle Manager)
启用用户自定义算法和行为的插件(Nav2 Core)
Navigation 2(Nav 2)是ROS 2中自带的导航框架,其目的是能够通过一种安全的方式使移动机器人从A点移动到B点。所以,Nav 2可以完成动态路径规划、计算电机速度、避开障碍物和恢复结构等行为。
Nav 2使用行为树(BT,Behavior Trees)调用模块化服务器来完成一个动作。动作可以是计算路径、控制工作(control efforts)、恢复或其他与导航相关的动作。这些动作都是通过动作服务器与行为树(BT)进行通信的独立节点。
资料参考网址:
Navigation2 文档:https://navigation.ros.org/index.html
Navigation2 github:https://github.com/ros-planning/navigation2
之前小鱼老师讲的:ros2笔记-7.3机器人导航框架navigation2_ros2 安装nav2-CSDN博客
亚博接下来就是启动launch了。我看了下,觉得还是要补充下对应的bringup跟dwb_nav_params.yaml。
nav2 bringup
了解下里面有什么脚本,启动了什么节点。
bringup_launch.py
# 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()),
])
创建了一个动作群组,里面包含
命名空间指定:如果use_namespace,指定命名空间为namespace
节点启动:启动rclcpp_components功能包中的component_container_isolated可执行,并命名为nav2_container节点
启动参数为configured_params,该参数是从父启动文件传递过来的params_file参数中读取到的
并将节点中的话题进行重映射
launch文件启动,启动了3个子launch文件:
slam_launch.py文件,启动条件为slam参数,默认为false不启动;
localization_launch.py文件,启动条件为slam参数为false时,即PythonExpression(['not ', slam])默认为true 所以默认启动 localization_launch.py
navigation_launch.py文件
slam_launch.py
slam_launch_file = os.path.join(slam_toolbox_dir, 'launch', 'online_sync_launch.py')
start_map_saver_server_cmd = Node(
package='nav2_map_server',
executable='map_saver_server',
output='screen',
respawn=use_respawn,
respawn_delay=2.0,
arguments=['--ros-args', '--log-level', log_level],
parameters=[configured_params])
start_lifecycle_manager_cmd = Node(
package='nav2_lifecycle_manager',
executable='lifecycle_manager',
name='lifecycle_manager_slam',
output='screen',
arguments=['--ros-args', '--log-level', log_level],
parameters=[{'use_sim_time': use_sim_time},
{'autostart': autostart},
{'node_names': lifecycle_nodes}])
调用了slam_toolbox工程下online_sync_launch.py
map_saver_server, #启动了地图储存服务节点
import os
from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument
from launch.substitutions import LaunchConfiguration
from launch_ros.actions import Node
from ament_index_python.packages import get_package_share_directory
def generate_launch_description():
use_sim_time = LaunchConfiguration('use_sim_time')
slam_params_file = LaunchConfiguration('slam_params_file')
declare_use_sim_time_argument = DeclareLaunchArgument(
'use_sim_time',
default_value='true',
description='Use simulation/Gazebo clock')
declare_slam_params_file_cmd = DeclareLaunchArgument(
'slam_params_file',
default_value=os.path.join(get_package_share_directory("slam_toolbox"),
'config', 'mapper_params_online_sync.yaml'),
description='Full path to the ROS2 parameters file to use for the slam_toolbox node')
start_sync_slam_toolbox_node = Node(
parameters=[
slam_params_file,
{'use_sim_time': use_sim_time}
],
package='slam_toolbox',
executable='sync_slam_toolbox_node',
name='slam_toolbox',
output='screen')
ld = LaunchDescription()
ld.add_action(declare_use_sim_time_argument)
ld.add_action(declare_slam_params_file_cmd)
ld.add_action(start_sync_slam_toolbox_node)
return ld
'sync_slam_toolbox_node', #启动了slam工具箱同步定位建图
作用:slam同步定位建图,储存地图。
localization_launch.py
load_nodes = GroupAction(
condition=IfCondition(PythonExpression(['not ', use_composition])),
actions=[
Node(
package='nav2_map_server',
executable='map_server',
name='map_server',
output='screen',
respawn=use_respawn,
respawn_delay=2.0,
parameters=[configured_params],
arguments=['--ros-args', '--log-level', log_level],
remappings=remappings),
Node(
package='nav2_amcl',
executable='amcl',
name='amcl',
output='screen',
respawn=use_respawn,
respawn_delay=2.0,
parameters=[configured_params],
arguments=['--ros-args', '--log-level', log_level],
remappings=remappings),
Node(
package='nav2_lifecycle_manager',
executable='lifecycle_manager',
name='lifecycle_manager_localization',
output='screen',
arguments=['--ros-args', '--log-level', log_level],
parameters=[{'use_sim_time': use_sim_time},
{'autostart': autostart},
{'node_names': lifecycle_nodes}])
]
)
启动了节点
- nav2_map_server功能包下的map_server节点
- nav2_amcl功能包下的amcl节点
- nav2_lifecycle_manager功能包下的lifecycle_manager_localization节点
作用:启动地图服务,在地图上给机器人定位。
navigation_launch.py
load_nodes = GroupAction(
condition=IfCondition(PythonExpression(['not ', use_composition])),
actions=[
Node(
package='nav2_controller',
executable='controller_server',
output='screen',
respawn=use_respawn,
respawn_delay=2.0,
parameters=[configured_params],
arguments=['--ros-args', '--log-level', log_level],
remappings=remappings + [('cmd_vel', 'cmd_vel_nav')]),
Node(
package='nav2_smoother',
executable='smoother_server',
name='smoother_server',
output='screen',
respawn=use_respawn,
respawn_delay=2.0,
parameters=[configured_params],
arguments=['--ros-args', '--log-level', log_level],
remappings=remappings),
Node(
package='nav2_planner',
executable='planner_server',
name='planner_server',
output='screen',
respawn=use_respawn,
respawn_delay=2.0,
parameters=[configured_params],
arguments=['--ros-args', '--log-level', log_level],
remappings=remappings),
Node(
package='nav2_behaviors',
executable='behavior_server',
name='behavior_server',
output='screen',
respawn=use_respawn,
respawn_delay=2.0,
parameters=[configured_params],
arguments=['--ros-args', '--log-level', log_level],
remappings=remappings),
Node(
package='nav2_bt_navigator',
executable='bt_navigator',
name='bt_navigator',
output='screen',
respawn=use_respawn,
respawn_delay=2.0,
parameters=[configured_params],
arguments=['--ros-args', '--log-level', log_level],
remappings=remappings),
Node(
package='nav2_waypoint_follower',
executable='waypoint_follower',
name='waypoint_follower',
output='screen',
respawn=use_respawn,
respawn_delay=2.0,
parameters=[configured_params],
arguments=['--ros-args', '--log-level', log_level],
remappings=remappings),
Node(
package='nav2_velocity_smoother',
executable='velocity_smoother',
name='velocity_smoother',
output='screen',
respawn=use_respawn,
respawn_delay=2.0,
parameters=[configured_params],
arguments=['--ros-args', '--log-level', log_level],
remappings=remappings +
[('cmd_vel', 'cmd_vel_nav'), ('cmd_vel_smoothed', 'cmd_vel')]),
Node(
package='nav2_lifecycle_manager',
executable='lifecycle_manager',
name='lifecycle_manager_navigation',
output='screen',
arguments=['--ros-args', '--log-level', log_level],
parameters=[{'use_sim_time': use_sim_time},
{'autostart': autostart},
{'node_names': lifecycle_nodes}]),
]
配置指南 — Navigation 2 1.0.0 文档 推荐看看小鱼老师的nav2文档,下面就是摘自文档的部分内容。参数没贴。
'controller_server', #启动机器人控制器,Controller Server实现了用于处理堆栈的控制器请求的服务器,并承载了插件实现的映射表。它将接收控制器、进度检查器和目标检查器的路径和插件名称,并调用相应的插件。
‘smoother_server’,由于Planner规划器
搜索的路径最优性标准通常与现实情况相比有所降低,因此额外的路径细化通常是有益的。为此目的,引入了平滑器,通常负责减少路径粗糙度和平滑突然旋转,但也负责增加与障碍物和高成本区域的距离,因为平滑器可以访问全局环境表示。
'planner_server', 规划服务器实现了用于处理堆栈的规划请求的服务器,并托管插件实现的地图。它将接收一个目标和要使用的规划插件名称,并调用适当的插件来计算到目标的路径。
‘behavior_server’,Behavior Server实现了处理恢复行为请求和托管实现各种C++行为的插件向量的服务器。也可以为每个自定义行为实现独立的行为服务器,但此服务器允许多个行为共享资源,如costmaps和TF缓冲区,以降低新行为的增量成本。
'bt_navigator', BT导航器(行为树导航器)模块实现了NavigateToPose任务接口。它是一种基于行为树的导航实现,旨在允许导航任务的灵活性,并提供一种简便的方式来指定复杂的机器人行为,包括恢复操作。
'waypoint_follower', #启动路点跟随,模块通过使用 NavigateToPose 动作服务器实现了一种按照路径点进行跟随的方法。它会接收一组有序的路径点,并尝试按顺序导航到它们。该模块还提供了一个路径点任务执行插件,可用于在路径点上执行自定义行为,如等待用户指令、拍照或拾取物品。如果某个路径点无法到达,stop_on_failure
参数将决定是继续到下一个点还是停止。
‘velocity_smoother’ 是一个包含生命周期组件节点的软件包,用于平滑Nav2发送给机器人控制器的速度。该软件包的目的是通过平滑加速度/突变运动,从Nav2实现速度、加速度和死区的平滑,以减少机器人电机和硬件控制器的磨损。
‘lifecycle_manager’ 生命周期管理器模块以确定性方式实现了处理堆栈生命周期转换状态的方法。它将接收一组有序节点,逐个将它们转换为配置和激活状态以运行堆栈。然后,它将按相反的顺序将堆栈降低到最终状态。它还将与服务器建立连接,以确保它们仍然运行,并在任何非响应或崩溃的节点时降低所有节点。
作用:启动导航核心节点,行为树 规划器 控制器 恢复器 路点跟随
dwb_nav_params.yaml
amcl:
ros__parameters:
use_sim_time: False
alpha1: 0.2
alpha2: 0.2
alpha3: 0.2
alpha4: 0.2
alpha5: 0.2
base_frame_id: "base_footprint"
beam_skip_distance: 0.5
beam_skip_error_threshold: 0.9
beam_skip_threshold: 0.3
do_beamskip: false
global_frame_id: "map"
lambda_short: 0.1
laser_likelihood_max_dist: 2.0
laser_max_range: 100.0
laser_min_range: -1.0
laser_model_type: "likelihood_field"
max_beams: 60
max_particles: 2000
min_particles: 500
odom_frame_id: "odom"
pf_err: 0.05
pf_z: 0.99
recovery_alpha_fast: 0.0
recovery_alpha_slow: 0.0
resample_interval: 1
robot_model_type: "nav2_amcl::DifferentialMotionModel"
save_pose_rate: 0.5
sigma_hit: 0.2
tf_broadcast: true
transform_tolerance: 1.0
update_min_a: 0.2
update_min_d: 0.25
z_hit: 0.5
z_max: 0.05
z_rand: 0.5
z_short: 0.05
scan_topic: scan
bt_navigator:
ros__parameters:
use_sim_time: False
global_frame: map
robot_base_frame: base_link
odom_topic: /odom
bt_loop_duration: 10
default_server_timeout: 20
default_bt_xml_filename: "navigate_to_pose_w_replanning_and_recovery.xml"
# 'default_nav_through_poses_bt_xml' and 'default_nav_to_pose_bt_xml' are use defaults:
# nav2_bt_navigator/navigate_to_pose_w_replanning_and_recovery.xml
# nav2_bt_navigator/navigate_through_poses_w_replanning_and_recovery.xml
# They can be set here or via a RewrittenYaml remap from a parent launch file to Nav2.
plugin_lib_names:
- nav2_compute_path_to_pose_action_bt_node
- nav2_compute_path_through_poses_action_bt_node
- nav2_smooth_path_action_bt_node
- nav2_follow_path_action_bt_node
- nav2_spin_action_bt_node
- nav2_wait_action_bt_node
- nav2_assisted_teleop_action_bt_node
- nav2_back_up_action_bt_node
- nav2_drive_on_heading_bt_node
- nav2_clear_costmap_service_bt_node
- nav2_is_stuck_condition_bt_node
- nav2_goal_reached_condition_bt_node
- nav2_goal_updated_condition_bt_node
- nav2_globally_updated_goal_condition_bt_node
- nav2_is_path_valid_condition_bt_node
- nav2_initial_pose_received_condition_bt_node
- nav2_reinitialize_global_localization_service_bt_node
- nav2_rate_controller_bt_node
- nav2_distance_controller_bt_node
- nav2_speed_controller_bt_node
- nav2_truncate_path_action_bt_node
- nav2_truncate_path_local_action_bt_node
- nav2_goal_updater_node_bt_node
- nav2_recovery_node_bt_node
- nav2_pipeline_sequence_bt_node
- nav2_round_robin_node_bt_node
- nav2_transform_available_condition_bt_node
- nav2_time_expired_condition_bt_node
- nav2_path_expiring_timer_condition
- nav2_distance_traveled_condition_bt_node
- nav2_single_trigger_bt_node
- nav2_goal_updated_controller_bt_node
- nav2_is_battery_low_condition_bt_node
- nav2_navigate_through_poses_action_bt_node
- nav2_navigate_to_pose_action_bt_node
- nav2_remove_passed_goals_action_bt_node
- nav2_planner_selector_bt_node
- nav2_controller_selector_bt_node
- nav2_goal_checker_selector_bt_node
- nav2_controller_cancel_bt_node
- nav2_path_longer_on_approach_bt_node
- nav2_wait_cancel_bt_node
- nav2_spin_cancel_bt_node
- nav2_back_up_cancel_bt_node
- nav2_assisted_teleop_cancel_bt_node
- nav2_drive_on_heading_cancel_bt_node
- nav2_is_battery_charging_condition_bt_node
bt_navigator_navigate_through_poses_rclcpp_node:
ros__parameters:
use_sim_time: False
bt_navigator_navigate_to_pose_rclcpp_node:
ros__parameters:
use_sim_time: False
controller_server:
ros__parameters:
use_sim_time: False
controller_frequency: 20.0
min_x_velocity_threshold: 0.001
min_y_velocity_threshold: 0.5
min_theta_velocity_threshold: 0.001
failure_tolerance: 0.3
progress_checker_plugin: "progress_checker"
goal_checker_plugins: ["general_goal_checker"]
controller_plugins: ["FollowPath"]
# Progress checker parameters
progress_checker:
plugin: "nav2_controller::SimpleProgressChecker"
required_movement_radius: 0.5
movement_time_allowance: 10.0
# Goal checker parameters
#precise_goal_checker:
# plugin: "nav2_controller::SimpleGoalChecker"
# xy_goal_tolerance: 0.25
# yaw_goal_tolerance: 0.25
# stateful: True
general_goal_checker:
stateful: True
plugin: "nav2_controller::SimpleGoalChecker"
xy_goal_tolerance: 0.25
yaw_goal_tolerance: 0.25
# DWB parameters
FollowPath:
plugin: "dwb_core::DWBLocalPlanner"
debug_trajectory_details: True
min_vel_x: -0.20
min_vel_y: 0.0
max_vel_x: 0.30
max_vel_y: 0.0
max_vel_theta: 1.0
min_speed_xy: -0.20
max_speed_xy: 0.30
min_speed_theta: -0.5
# Add high threshold velocity for turtlebot 3 issue.
# https://github.com/ROBOTIS-GIT/turtlebot3_simulations/issues/75
acc_lim_x: 2.5
acc_lim_y: 0.0
acc_lim_theta: 3.2
decel_lim_x: -2.5
decel_lim_y: 0.0
decel_lim_theta: -3.2
vx_samples: 20
vy_samples: 5
vtheta_samples: 20
sim_time: 1.7
linear_granularity: 0.05
angular_granularity: 0.025
transform_tolerance: 0.2
xy_goal_tolerance: 0.25
trans_stopped_velocity: 0.25
short_circuit_trajectory_evaluation: True
stateful: True
critics: ["RotateToGoal", "Oscillation", "BaseObstacle", "GoalAlign", "PathAlign", "PathDist", "GoalDist"]
BaseObstacle.scale: 0.02
PathAlign.scale: 32.0
PathAlign.forward_point_distance: 0.1
GoalAlign.scale: 24.0
GoalAlign.forward_point_distance: 0.1
PathDist.scale: 32.0
GoalDist.scale: 24.0
RotateToGoal.scale: 32.0
RotateToGoal.slowing_factor: 5.0
RotateToGoal.lookahead_time: -1.0
local_costmap:
local_costmap:
ros__parameters:
update_frequency: 5.0
publish_frequency: 2.0
global_frame: odom
robot_base_frame: base_link
use_sim_time: False
rolling_window: true
width: 3
height: 3
resolution: 0.05
robot_radius: 0.22
plugins: ["voxel_layer", "inflation_layer"]
inflation_layer:
plugin: "nav2_costmap_2d::InflationLayer"
cost_scaling_factor: 3.0
inflation_radius: 0.55
voxel_layer:
plugin: "nav2_costmap_2d::VoxelLayer"
enabled: True
publish_voxel_map: True
origin_z: 0.0
z_resolution: 0.05
z_voxels: 16
max_obstacle_height: 2.0
mark_threshold: 0
observation_sources: scan
scan:
topic: /scan
max_obstacle_height: 2.0
clearing: True
marking: True
data_type: "LaserScan"
raytrace_max_range: 3.0
raytrace_min_range: 0.0
obstacle_max_range: 2.5
obstacle_min_range: 0.0
static_layer:
plugin: "nav2_costmap_2d::StaticLayer"
map_subscribe_transient_local: True
always_send_full_costmap: True
global_costmap:
global_costmap:
ros__parameters:
update_frequency: 1.0
publish_frequency: 1.0
global_frame: map
robot_base_frame: base_link
use_sim_time: False
robot_radius: 0.22
resolution: 0.05
track_unknown_space: true
plugins: ["static_layer", "obstacle_layer", "inflation_layer"]
obstacle_layer:
plugin: "nav2_costmap_2d::ObstacleLayer"
enabled: True
observation_sources: scan
scan:
topic: /scan
max_obstacle_height: 2.0
clearing: True
marking: True
data_type: "LaserScan"
raytrace_max_range: 3.0
raytrace_min_range: 0.0
obstacle_max_range: 2.5
obstacle_min_range: 0.0
static_layer:
plugin: "nav2_costmap_2d::StaticLayer"
map_subscribe_transient_local: True
inflation_layer:
plugin: "nav2_costmap_2d::InflationLayer"
cost_scaling_factor: 3.0
inflation_radius: 0.55
always_send_full_costmap: True
map_server:
ros__parameters:
use_sim_time: False
# Overridden in launch by the "map" launch configuration or provided default value.
# To use in yaml, remove the default "map" value in the tb3_simulation_launch.py file & provide full path to map below.
yaml_filename: ""
map_saver:
ros__parameters:
use_sim_time: False
save_map_timeout: 5.0
free_thresh_default: 0.25
occupied_thresh_default: 0.65
map_subscribe_transient_local: True
planner_server:
ros__parameters:
expected_planner_frequency: 20.0
use_sim_time: False
planner_plugins: ["GridBased"]
GridBased:
plugin: "nav2_navfn_planner/NavfnPlanner"
tolerance: 0.5
use_astar: false
allow_unknown: true
smoother_server:
ros__parameters:
use_sim_time: False
smoother_plugins: ["simple_smoother"]
simple_smoother:
plugin: "nav2_smoother::SimpleSmoother"
tolerance: 1.0e-10
max_its: 1000
do_refinement: False
behavior_server:
ros__parameters:
costmap_topic: local_costmap/costmap_raw
footprint_topic: local_costmap/published_footprint
cycle_frequency: 10.0
behavior_plugins: ["spin", "backup", "drive_on_heading", "assisted_teleop", "wait"]
spin:
plugin: "nav2_behaviors/Spin"
backup:
plugin: "nav2_behaviors/BackUp"
drive_on_heading:
plugin: "nav2_behaviors/DriveOnHeading"
wait:
plugin: "nav2_behaviors/Wait"
assisted_teleop:
plugin: "nav2_behaviors/AssistedTeleop"
global_frame: odom
robot_base_frame: base_link
transform_tolerance: 0.1
use_sim_time: False
simulate_ahead_time: 2.0
max_rotational_vel: 1.0
min_rotational_vel: 0.4
rotational_acc_lim: 3.2
robot_state_publisher:
ros__parameters:
use_sim_time: False
waypoint_follower:
ros__parameters:
use_sim_time: False
loop_rate: 20
stop_on_failure: false
waypoint_task_executor_plugin: "wait_at_waypoint"
wait_at_waypoint:
plugin: "nav2_waypoint_follower::WaitAtWaypoint"
enabled: True
waypoint_pause_duration: 200
velocity_smoother:
ros__parameters:
use_sim_time: False
smoothing_frequency: 20.0
scale_velocities: False
feedback: "OPEN_LOOP"
max_velocity: [0.26, 0.0, 1.0]
min_velocity: [-0.26, 0.0, -1.0]
max_accel: [2.5, 0.0, 3.2]
max_decel: [-2.5, 0.0, -3.2]
odom_topic: "odom"
odom_duration: 0.1
deadband_velocity: [0.0, 0.0, 0.0]
velocity_timeout: 1.0
这参数配置文件300多行,的确很多,我也没逐行看。大概有几个主要的:
planner_server节点的参数,用于设置路径规划器(global planner)的参数,如地图、规划器类型、规划时间等。
controller_server节点的参数,用于设置控制器(local planner)的参数,如速度、加速度、PID参数等。
recoveries_server节点的参数,用于设置恢复行为(recovery behaviors)的参数,如障碍物避让、路径重新规划等。
bt_navigator节点的参数,用于设置行为树(behavior tree)导航器的参数,如行为树的文件路径、调试模式等。
通过修改nav2_params.yaml文件中的这些参数,可以调整导航栈的行为,以适应不同的场景和需求
小鱼老师nav2 文档上有:生命周期管理器 — Navigation 2 1.0.0 文档
也有大佬的文章汇总了参数,并做了进一步说明,限于篇幅,推荐看原文,不贴了:
【10天速通Navigation2】(六):Navigation2 导航bringup基础配置和参数详解_十天速通-CSDN博客
测试
启动小车代理
sudo docker run -it --rm -v /dev:/dev -v /dev/shm:/dev/shm --privileged --net=host microros/micro-ros-agent:humble udp4 --port 8090 -v4
首先启动小车处理底层数据程序
ros2 launch yahboomcar_bringup yahboomcar_bringup_launch.py
bohu@bohu-TM1701:~/yahboomcar/yahboomcar_ws$ ros2 launch yahboomcar_bringup yahboomcar_bringup_launch.py
[INFO] [launch]: All log files can be found below /home/bohu/.ros/log/2025-02-02-14-52-51-635219-bohu-TM1701-485615
[INFO] [launch]: Default logging verbosity is set to INFO
---------------------robot_type = x3---------------------
[INFO] [complementary_filter_node-1]: process started with pid [485617]
[INFO] [ekf_node-2]: process started with pid [485619]
[INFO] [static_transform_publisher-3]: process started with pid [485621]
[INFO] [joint_state_publisher-4]: process started with pid [485623]
[INFO] [robot_state_publisher-5]: process started with pid [485625]
[INFO] [static_transform_publisher-6]: process started with pid [485627]
[static_transform_publisher-3] [WARN] [1738479171.990437080] []: Old-style arguments are deprecated; see --help for new-style arguments
[static_transform_publisher-6] [WARN] [1738479171.991202044] []: Old-style arguments are deprecated; see --help for new-style arguments
[static_transform_publisher-3] [INFO] [1738479172.104536837] [base_link_to_base_imu]: Spinning until stopped - publishing transform
[static_transform_publisher-3] translation: ('-0.002999', '-0.003000', '0.031701')
[static_transform_publisher-3] rotation: ('0.000000', '0.000000', '0.000000', '1.000000')
[static_transform_publisher-3] from 'base_link' to 'imu_frame'
[complementary_filter_node-1] [INFO] [1738479172.137987218] [complementary_filter_gain_node]: Starting ComplementaryFilterROS
[static_transform_publisher-6] [INFO] [1738479172.155545031] [static_transform_publisher_HOLxXJ1FIA5414tp]: Spinning until stopped - publishing transform
[static_transform_publisher-6] translation: ('0.000000', '0.000000', '0.050000')
[static_transform_publisher-6] rotation: ('0.000000', '0.000000', '0.000000', '1.000000')
[static_transform_publisher-6] from 'base_footprint' to 'base_link'
[robot_state_publisher-5] [WARN] [1738479172.216038947] [kdl_parser]: The root link base_link has an inertia specified in the URDF, but KDL does not support a root link with an inertia. As a workaround, you can add an extra dummy link to your URDF.
[robot_state_publisher-5] [INFO] [1738479172.216185449] [robot_state_publisher]: got segment base_link
[robot_state_publisher-5] [INFO] [1738479172.216257807] [robot_state_publisher]: got segment imu_Link
[robot_state_publisher-5] [INFO] [1738479172.216278937] [robot_state_publisher]: got segment jq1_Link
[robot_state_publisher-5] [INFO] [1738479172.216289860] [robot_state_publisher]: got segment jq2_Link
[robot_state_publisher-5] [INFO] [1738479172.216301021] [robot_state_publisher]: got segment radar_Link
[robot_state_publisher-5] [INFO] [1738479172.216315380] [robot_state_publisher]: got segment yh_Link
[robot_state_publisher-5] [INFO] [1738479172.216328033] [robot_state_publisher]: got segment yq_Link
[robot_state_publisher-5] [INFO] [1738479172.216339831] [robot_state_publisher]: got segment zh_Link
[robot_state_publisher-5] [INFO] [1738479172.216355571] [robot_state_publisher]: got segment zq_Link
[joint_state_publisher-4] [INFO] [1738479173.196961127] [joint_state_publisher]: Waiting for robot_description to be published on the robot_description topic...
启动rviz,可视化导航,终端输入
ros2 launch yahboomcar_nav display_launch.py #rviz可视化
此时还没有显示地图加载,因为还没有启动导航的程序,所以没有地图加载。接下来运行导航节点,
ros2 launch yahboomcar_nav navigation_dwb_launch.py maps:=/home/bohu/maps-data/gmapping/yahboom_map.yaml
此时可以看到地图加载进去了,然后我们点击【2D Pose Estimate】,给小车设置初始位姿,根据小车在实际环境中的位置,在rviz中用鼠标点击拖动,小车模型移动我们设置的位置。
单点导航,点击【2D Goal Pose】工具,然后在rviz中选择一个目标点,小车结合周围的情况,规划出一条路径并且沿着路径移动到目标点。
多点导航,没有截图。用了nav2插件
节点通信图
原图太大,截图了小部分太复杂了。
tf TREE
navigation_dwb_launch.py
import os
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument
from launch.actions import IncludeLaunchDescription
from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch.substitutions import LaunchConfiguration
from launch_ros.actions import Node
def generate_launch_description():
package_path = get_package_share_directory('yahboomcar_nav')
nav2_bringup_dir = get_package_share_directory('nav2_bringup')
use_sim_time = LaunchConfiguration('use_sim_time', default='false')
namespece = LaunchConfiguration('namespece', default='')
map_yaml_path = LaunchConfiguration(
'maps', default=os.path.join('/home/yahboom/yahboomcar_ws/src/yahboomcar_nav', 'maps', 'yahboom_map.yaml'))
nav2_param_path = LaunchConfiguration('params_file', default=os.path.join(
package_path, 'params', 'dwb_nav_params.yaml'))
return LaunchDescription([
DeclareLaunchArgument('use_sim_time', default_value=use_sim_time,
description='Use simulation (Gazebo) clock if true'),
DeclareLaunchArgument('namespece', default_value=namespece,
description='Use simulation (Gazebo) clock if true'),
DeclareLaunchArgument('maps', default_value=map_yaml_path,
description='Full path to map file to load'),
DeclareLaunchArgument('params_file', default_value=nav2_param_path,
description='Full path to param file to load'),
IncludeLaunchDescription(
PythonLaunchDescriptionSource(
[nav2_bringup_dir, '/launch', '/bringup_launch.py']),
launch_arguments={
'map': map_yaml_path,
'use_sim_time': use_sim_time,
'namespece': namespece,
'params_file': nav2_param_path}.items(),
),
Node(
package='yahboomcar_nav',
executable='stop_car'
) ,
Node(
package='tf2_ros',
executable='static_transform_publisher',
name='base_link_to_base_laser',
arguments=['-0.0046412', '0' , '0.094079','0','0','0','base_link','laser_frame']
)
])
这里启动了以下几个节点:
base_link_to_base_laser:发布静态的TF变换;
stop_car:停车节点,ctrl c退出程序后,会发布停车速度给到小车;
bringup_launch.py:启动导航的launch文件,文件位于,
/opt/ros/humble/share/nav2_bringup/launch
另外还加载了一个导航参数配置文件dwb_nav_params.yaml和加载地图文件yahboom_map.yaml,
参见上面的第一部分代码。
测试发现的问题:
小车运行前面没啥问题,能规划路线去指定点。跑了几圈之后,误差有积累,此时位置、姿态不太准确。会显示自己在障碍物边上停止运动,实际上没有。此类问题不知道怎么解决。