ROS2 launch文件demo与parameter设置
项目架构
project_name
│ README.md
│
└───package_1
│ │ CMakeLists.txt
│ │ package.xml
│ │
│ └───include
│ │
│ └───src
│ │
│ └───msg
│ │
│ └───config
│ │
│ └───launch
│ │
│ └───srv
│
└───package_2
│ │
│ └───...
│
└───...
launch文件的整体编排
基于ROS Eloquent环境实现以下功能,在Dashing及之前版本可能存在一定差异,敬请注意。
ROS2 launch文件由XML格式转换为.py,实例代码如下
#file name: example.launch.py
import os
import launch
from ament_index_python.packages import get_package_share_directory
from launch.substitutions import EnvironmentVariable
from launch.substitutions import LaunchConfiguration
from launch import LaunchDescription
from launch_ros.actions import Node
from launch.actions import DeclareLaunchArgument
def generate_launch_description():
para_dir = os.path.join(get_package_share_directory('your_package_name'), 'config', 'your_parameter_file.yaml')
rviz_config_dir = os.path.join(get_package_share_directory('your_package_name'), 'config', 'default.rviz')
return LaunchDescription([
Node(
package='your_package_name',
node_namespace='your_node_namespace',
node_executable='your_exec_name',
node_name='the_name_you_assign_to_the_node',
parameters=[para_dir],
remappings=None,
arguments=None,
output='screen',
),
Node(
package='rviz2',
node_namespace='rviz2',
node_executable='rviz2',
node_name=[LaunchConfiguration("node_prefix"), 'rviz2'],
parameters=None,
remappings=None,
arguments=['-d',rviz_config_dir],
output='screen',
)
])
注意
node_namespace是ROS Eloquent 新引入的特性,其会影响原本node发布的publisher的topic名称,例如your_exec_name
内有publisher topic为your_publisher
,在单独运行时其名称为/your_publisher
,在ros2 launch中启用时其topic名称会变更为/your_node_namespace/your_publisher
,在后续Subscriber定义时需要注意!!!
在Node中Parameter
的输入为yaml的路径,通常可以存放于config
文件夹以便于统一管理。
yaml编写
在ROS2中parameter通常是提供yaml路径以供.py调用,包含了namespace的yaml demo如下:
#file name: your_parameter_file.yaml
your_node_namespace:
your_node_name_1:
ros__parameters:
ip: "192.168.0.10"
port: 12002
output: false
your_node_name_2:
ros__parameters:
subscribe_topic: "/node_namespace_1/topic"
第一层为你的namespace
,第二层为你的node_name
,第三层为ros__parameters
,该层名称为固定不可修改的,第四层为具体的参数,接收包括int, double, bool, string
等类型。同一namespace
的node
应放置于同一层相邻。
不包含namespace的demo如下:
#file name: your_parameter_file.yaml
your_node_name_1:
ros__parameters:
ip: "192.168.0.10"
port: 12002
output: false
your_node_name_2:
ros__parameters:
subscribe_topic: "/node_namespace_1/topic"
C++程序获取parameter
#include <rclcpp/rclcpp.hpp>
#include <std_msgs/msg/string.hpp>
#include <iostream>
#include <cstdlib>
#include <math.h>
void Callback()
{
//Do something
}
int main(int argc, char** argv)
{
rclcpp::init(argc, argv);
node=rclcpp::Node::make_shared("your_ros_node_name");
std::string topic;
node->declare_parameter("subscribe_topic","default value, whatever you want");
node->get_parameter<std::string>("subscribe_topic",topic);
auto obj_sub=node->create_subscription<your topic type>(topic,100,Callback);
rclcpp::spin(node);
exit(0);
}
具体解释:
rclcpp::init(argc, argv);
node=rclcpp::Node::make_shared("your_ros_node_name");
创建ROS node;
std::string topic;
创建用于储存parameter的变量,类型应与yaml内类型一致;
node->declare_parameter("subscribe_topic","default value, whatever you want");
声明需要获取的parameter名称和默认值;
node->get_parameter<std::string>("subscribe_topic",topic);
将指定名称的paramter储存至指定变量。例如本例中将yaml中subscribe_topic
对应的值"/node_namespace_1/topic"
赋予topic
。
之后即可使用获取的变量值进行后续操作,例如本例中:
auto obj_sub=node->create_subscription<your topic type>(topic,100,Callback);
创建了订阅topic
,即/node_namespace_1/topic
的Subscriberobj_sub
。
CMakeLists修改
在CMakeLists.txt中添加如下代码块:
install(DIRECTORY launch
DESTINATION share/${PROJECT_NAME}/
)
install(DIRECTORY config
DESTINATION share/${PROJECT_NAME}/
)