ros2 节点参数可以通过启动节点添加,也可以通过launch文件添加,还可以通过配置文件.yaml文件添加,或者是几种方式套用添加,给初学者带来很大的困惑具体是哪个生效了呢,我们拿slam_toolbox 包的online_sync_launch.py来剖析。
(SLAM) 建图时导航 — Navigation 2 1.0.0 文档
我们这里采用源码编译安装,方便随时修改代码编译运行看效果
源码下载地址:https://github.com/SteveMacenski/slam_toolbox/tree/foxy-develhttps://github.com/SteveMacenski/slam_toolbox/tree/foxy-devel
import os
from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument, LogInfo
from launch.conditions import UnlessCondition
from launch.substitutions import LaunchConfiguration, PythonExpression
from launch_ros.actions import Node
from ament_index_python.packages import get_package_share_directory
from nav2_common.launch import HasNodeParams
def generate_launch_description():
use_sim_time = LaunchConfiguration('use_sim_time')
params_file = LaunchConfiguration('params_file')
default_params_file = os.path.join(get_package_share_directory("slam_toolbox"),
'config', 'mapper_params_online_sync.yaml')
declare_use_sim_time_argument = DeclareLaunchArgument(
'use_sim_time',
default_value='true',
description='Use simulation/Gazebo clock')
declare_params_file_cmd = DeclareLaunchArgument(
'params_file',
default_value=default_params_file,
description='Full path to the ROS2 parameters file to use for the slam_toolbox node')
# If the provided param file doesn't have slam_toolbox params, we must pass the
# default_params_file instead. This could happen due to automatic propagation of
# LaunchArguments. See:
# https://github.com/ros-planning/navigation2/pull/2243#issuecomment-800479866
has_node_params = HasNodeParams(source_file=params_file,
node_name='slam_toolbox')
actual_params_file = PythonExpression(['"', params_file, '" if ', has_node_params,
' else "', default_params_file, '"'])
log_param_change = LogInfo(msg=['provided params_file ', params_file,
' does not contain slam_toolbox parameters. Using default: ',
default_params_file],
condition=UnlessCondition(has_node_params))
start_sync_slam_toolbox_node = Node(
parameters=[
actual_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_params_file_cmd)
ld.add_action(log_param_change)
ld.add_action(start_sync_slam_toolbox_node)
return ld
这里我们只看节点配置部分
start_sync_slam_toolbox_node = Node(
parameters=[
actual_params_file,
{'use_sim_time': use_sim_time}
],
package='slam_toolbox',
executable='sync_slam_toolbox_node',
name='slam_toolbox',
output='screen')
parameters=[
actual_params_file,
{'use_sim_time': use_sim_time}
],
这里我们只拿最常用的一个参数use_sim_time举例,看看是哪一步的设置生效了,其他参数逻辑是一样的。
启动这个节点
ros2 launch slam_toolbox online_sync_launch.py
[INFO] [launch]: All log files can be found below /home/m/.ros/log/2023-09-06-01-39-24-649989-ubun-44795
[INFO] [launch]: Default logging verbosity is set to INFO
[INFO] [sync_slam_toolbox_node-1]: process started with pid [44797]
[sync_slam_toolbox_node-1] [INFO] [1693935564.841328831] [slam_toolbox]: Node using stack size 40000000
[sync_slam_toolbox_node-1] [INFO] [1693935564.869237603] [slam_toolbox]: Using solver plugin solver_plugins::CeresSolver
[sync_slam_toolbox_node-1] [INFO] [1693935564.869558263] [slam_toolbox]: CeresSolver: Using SCHUR_JACOBI preconditioner.
m@ubun:~/ros2_ws$ ros2 node list
/slam_toolbox
/transform_listener_impl_563889db4b50
m@ubun:~/ros2_ws$ ros2 param dump slam_toolbox
Saving to: ./slam_toolbox.yaml
下载的slam_toolbox节点参数详情
/slam_toolbox:
ros__parameters:
angle_variance_penalty: 1.0
base_frame: base_footprint
ceres_dogleg_type: TRADITIONAL_DOGLEG
ceres_linear_solver: SPARSE_NORMAL_CHOLESKY
ceres_loss_function: None
ceres_preconditioner: SCHUR_JACOBI
ceres_trust_strategy: LEVENBERG_MARQUARDT
coarse_angle_resolution: 0.0349
coarse_search_angle_offset: 0.349
correlation_search_space_dimension: 0.5
correlation_search_space_resolution: 0.01
correlation_search_space_smear_deviation: 0.1
debug_logging: false
distance_variance_penalty: 0.5
do_loop_closing: true
enable_interactive_mode: true
fine_search_angle_offset: 0.00349
interactive_mode: false
link_match_minimum_response_fine: 0.1
link_scan_maximum_distance: 1.5
loop_match_maximum_variance_coarse: 3.0
loop_match_minimum_chain_size: 10
loop_match_minimum_response_coarse: 0.35
loop_match_minimum_response_fine: 0.45
loop_search_maximum_distance: 3.0
loop_search_space_dimension: 8.0
loop_search_space_resolution: 0.05
loop_search_space_smear_deviation: 0.03
map_file_name: ''
map_frame: map
map_name: /map
map_start_at_dock: null
map_start_pose: null
map_update_interval: 5.0
minimum_angle_penalty: 0.9
minimum_distance_penalty: 0.5
minimum_time_interval: 0.5
minimum_travel_distance: 0.5
minimum_travel_heading: 0.5
mode: mapping
odom_frame: odom
paused_new_measurements: false
paused_processing: false
resolution: 0.05
scan_buffer_maximum_scan_distance: 10.0
scan_buffer_size: 10
scan_topic: /scan
solver_plugin: solver_plugins::CeresSolver
tf_buffer_duration: 30.0
throttle_scans: 1
transform_publish_period: 0.02
transform_timeout: 0.2
use_response_expansion: true
use_scan_barycenter: true
use_scan_matching: true
use_sim_time: true
看最后一项:
use_sim_time: true
declare_use_sim_time_argument = DeclareLaunchArgument(
'use_sim_time',
default_value='true',
description='Use simulation/Gazebo clock')
如果我们启动这个launch文件加上参数
m@ubun:~/ros2_ws$ ros2 launch slam_toolbox online_sync_launch.py use_sim_time:=false
[INFO] [launch]: All log files can be found below /home/m/.ros/log/2023-09-06-01-48-36-038660-ubun-45408
[INFO] [launch]: Default logging verbosity is set to INFO
[INFO] [sync_slam_toolbox_node-1]: process started with pid [45410]
[sync_slam_toolbox_node-1] [INFO] [1693936116.286793795] [slam_toolbox]: Node using stack size 40000000
[sync_slam_toolbox_node-1] [INFO] [1693936116.307085638] [slam_toolbox]: Using solver plugin solver_plugins::CeresSolver
[sync_slam_toolbox_node-1] [INFO] [1693936116.307325365] [slam_toolbox]: CeresSolver: Using SCHUR_JACOBI preconditioner.
m@ubun:~/ros2_ws$ ros2 param dump slam_toolbox
Saving to: ./slam_toolbox.yaml
/slam_toolbox:
ros__parameters:
angle_variance_penalty: 1.0
base_frame: base_footprint
ceres_dogleg_type: TRADITIONAL_DOGLEG
ceres_linear_solver: SPARSE_NORMAL_CHOLESKY
ceres_loss_function: None
ceres_preconditioner: SCHUR_JACOBI
ceres_trust_strategy: LEVENBERG_MARQUARDT
coarse_angle_resolution: 0.0349
coarse_search_angle_offset: 0.349
correlation_search_space_dimension: 0.5
correlation_search_space_resolution: 0.01
correlation_search_space_smear_deviation: 0.1
debug_logging: false
distance_variance_penalty: 0.5
do_loop_closing: true
enable_interactive_mode: true
fine_search_angle_offset: 0.00349
interactive_mode: false
link_match_minimum_response_fine: 0.1
link_scan_maximum_distance: 1.5
loop_match_maximum_variance_coarse: 3.0
loop_match_minimum_chain_size: 10
loop_match_minimum_response_coarse: 0.35
loop_match_minimum_response_fine: 0.45
loop_search_maximum_distance: 3.0
loop_search_space_dimension: 8.0
loop_search_space_resolution: 0.05
loop_search_space_smear_deviation: 0.03
map_file_name: ''
map_frame: map
map_name: /map
map_start_at_dock: null
map_start_pose: null
map_update_interval: 5.0
minimum_angle_penalty: 0.9
minimum_distance_penalty: 0.5
minimum_time_interval: 0.5
minimum_travel_distance: 0.5
minimum_travel_heading: 0.5
mode: mapping
odom_frame: odom
paused_new_measurements: false
paused_processing: false
resolution: 0.05
scan_buffer_maximum_scan_distance: 10.0
scan_buffer_size: 10
scan_topic: /scan
solver_plugin: solver_plugins::CeresSolver
tf_buffer_duration: 30.0
throttle_scans: 1
transform_publish_period: 0.02
transform_timeout: 0.2
use_response_expansion: true
use_scan_barycenter: true
use_scan_matching: true
use_sim_time: false
use_sim_time: false
m@ubun:~/ros2_ws$ ros2 launch slam_toolbox online_sync_launch.py use_sim_time:=true
再次下载配置文件
use_sim_time: true
这里可以看出use_sim_time 的值生效顺序ros2 launch slam_toolbox online_sync_launch.py use_sim_time:=true 或者use_sim_time:=false 是大于launch内的默认配置的。所以我们可以不管launch内的默认配置,直接在启动launch文件时在后面加上参数配置。
这里还有另外一种情况,launch内导入了配置文件的.yaml文件,我们还拿use_sim_time举例。
start_sync_slam_toolbox_node = Node(
parameters=[
actual_params_file,
{'use_sim_time': use_sim_time}
],
actual_params_file其实就是导入的下面的文件
default_params_file = os.path.join(get_package_share_directory("slam_toolbox"),
'config', 'mapper_params_online_sync.yaml')
mapper_params_online_sync.yaml
slam_toolbox:
ros__parameters:
# Plugin params
solver_plugin: solver_plugins::CeresSolver
ceres_linear_solver: SPARSE_NORMAL_CHOLESKY
ceres_preconditioner: SCHUR_JACOBI
ceres_trust_strategy: LEVENBERG_MARQUARDT
ceres_dogleg_type: TRADITIONAL_DOGLEG
ceres_loss_function: None
# ROS Parameters
odom_frame: odom
map_frame: map
base_frame: base_footprint
scan_topic: /scan
mode: mapping #localization
# if you'd like to immediately start continuing a map at a given pose
# or at the dock, but they are mutually exclusive, if pose is given
# will use pose
#map_file_name: test_steve
#map_start_pose: [0.0, 0.0, 0.0]
#map_start_at_dock: true
debug_logging: false
throttle_scans: 1
transform_publish_period: 0.02 #if 0 never publishes odometry
map_update_interval: 5.0
resolution: 0.05
max_laser_range: 20.0 #for rastering images
minimum_time_interval: 0.5
transform_timeout: 0.2
tf_buffer_duration: 30.
stack_size_to_use: 40000000 #// program needs a larger stack size to serialize large maps
enable_interactive_mode: true
# General Parameters
use_scan_matching: true
use_scan_barycenter: true
minimum_travel_distance: 0.5
minimum_travel_heading: 0.5
scan_buffer_size: 10
scan_buffer_maximum_scan_distance: 10.0
link_match_minimum_response_fine: 0.1
link_scan_maximum_distance: 1.5
loop_search_maximum_distance: 3.0
do_loop_closing: true
loop_match_minimum_chain_size: 10
loop_match_maximum_variance_coarse: 3.0
loop_match_minimum_response_coarse: 0.35
loop_match_minimum_response_fine: 0.45
# Correlation Parameters - Correlation Parameters
correlation_search_space_dimension: 0.5
correlation_search_space_resolution: 0.01
correlation_search_space_smear_deviation: 0.1
# Correlation Parameters - Loop Closure Parameters
loop_search_space_dimension: 8.0
loop_search_space_resolution: 0.05
loop_search_space_smear_deviation: 0.03
# Scan Matcher Parameters
distance_variance_penalty: 0.5
angle_variance_penalty: 1.0
fine_search_angle_offset: 0.00349
coarse_search_angle_offset: 0.349
coarse_angle_resolution: 0.0349
minimum_angle_penalty: 0.9
minimum_distance_penalty: 0.5
use_response_expansion: true
#临时在下面添加的参数
use_sim_time: true
我们在.yaml后面添加了use_sim_time: true
再次启动节点
ros2 launch slam_toolbox online_sync_launch.py use_sim_time:=true 或者use_sim_time:=false
下载参数
ros2 param dump slam_toolbox
Saving to: ./slam_toolbox.yaml
/slam_toolbox:
ros__parameters:
angle_variance_penalty: 1.0
base_frame: base_footprint
ceres_dogleg_type: TRADITIONAL_DOGLEG
ceres_linear_solver: SPARSE_NORMAL_CHOLESKY
ceres_loss_function: None
ceres_preconditioner: SCHUR_JACOBI
ceres_trust_strategy: LEVENBERG_MARQUARDT
coarse_angle_resolution: 0.0349
coarse_search_angle_offset: 0.349
correlation_search_space_dimension: 0.5
correlation_search_space_resolution: 0.01
correlation_search_space_smear_deviation: 0.1
debug_logging: false
distance_variance_penalty: 0.5
do_loop_closing: true
enable_interactive_mode: true
fine_search_angle_offset: 0.00349
interactive_mode: false
link_match_minimum_response_fine: 0.1
link_scan_maximum_distance: 1.5
loop_match_maximum_variance_coarse: 3.0
loop_match_minimum_chain_size: 10
loop_match_minimum_response_coarse: 0.35
loop_match_minimum_response_fine: 0.45
loop_search_maximum_distance: 3.0
loop_search_space_dimension: 8.0
loop_search_space_resolution: 0.05
loop_search_space_smear_deviation: 0.03
map_file_name: ''
map_frame: map
map_name: /map
map_start_at_dock: null
map_start_pose: null
map_update_interval: 5.0
minimum_angle_penalty: 0.9
minimum_distance_penalty: 0.5
minimum_time_interval: 0.5
minimum_travel_distance: 0.5
minimum_travel_heading: 0.5
mode: mapping
odom_frame: odom
paused_new_measurements: false
paused_processing: false
resolution: 0.05
scan_buffer_maximum_scan_distance: 10.0
scan_buffer_size: 10
scan_topic: /scan
solver_plugin: solver_plugins::CeresSolver
tf_buffer_duration: 30.0
throttle_scans: 1
transform_publish_period: 0.02
transform_timeout: 0.2
use_response_expansion: true
use_scan_barycenter: true
use_scan_matching: true
use_sim_time: true
不管怎么修改launch的启动参数,use_sim_time: true不变,说明launch文件内加载的.yaml 的权重是大于launch文件后面的启动参数的。
注意我们每次修改完程序都需要重新编译,要不然修改是不生效的。
我们这么反复测试只是为了验证参数在传递过程中哪里生效了,因为launch文件经过层层套娃,一个参数传递了好多次。
参数生效顺序 launch内的.yaml文件大于 ros2 launch slam_toolbox online_sync_launch.py use_sim_time:=true 大于launch文件内的默认参数配置
declare_use_sim_time_argument = DeclareLaunchArgument(
'use_sim_time',
default_value='true',
description='Use simulation/Gazebo clock')
虽然yaml文件的权重最大,但是yaml文件可以在launch文件内进行替换,
# Create our own temporary YAML files that include substitutions
# 创建我们自己的临时YAML文件,其中包括替换
param_substitutions = {
'use_sim_time': use_sim_time,
'yaml_filename': map_yaml_file}
configured_params = RewrittenYaml(
source_file=params_file,
root_key=namespace,
param_rewrites=param_substitutions,
convert_types=True)
经过这样替换yaml文件的某些参数,使yaml文件的某些参数权重不再是最大。而变成
ros2 launch slam_toolbox online_sync_launch.py use_sim_time:=true 这样的后缀参数权重最大。