计算图(Computation Graph)是一个由ROS进程组成的点对点网络,它们能够共同处理数据。ROS的基本计算图概念有节点(Nodes)、主节点(Master)、参数服务器(Parameter Server)、消息(Messages)、服务(Services)、话题(Topics)和袋(Bags),它们都以不同的方式向图(Graph)提供数据。
为了更加形象地理解节点的概念,这里举一个通俗的例子:
例如,咱们有一个机器人,和一个遥控器,那么这个机器人和遥控器开始工作后,就是两个节点。遥控器起到了下达指 令的作用;机器人负责监听遥控器下达的指令,完成相应动作。从这里我们可以看出,节点是一个能执行特定工作任 务的工作单元,并且能够相互通信,从而实现一个机器人系统整体的功能。在这里我们把遥控器和机器人简单定义为两个节点,实际上在机器人中根据控制器、传感器、执行机构等不同组成模块,还可以将其进一步细分为更多的节点,这个是根据用户编写的程序来定义的。)
rosnode显示当前正在运行的ROS节点信息。
rosnode list命令会列出这些活动的节点:
rosnode list
rosnode info命令返回的是某个指定节点的信息:
rosnode info /node_name
rosnode ping命令来测试节点是否正常:
rosnode ping /node_name
rosrun可以让你用包名直接运行软件包内的节点(而不需要知道包的路径)。
rosrun [package_name] [executable_file_name]
roslaunch 是一个用于同时启动多个ros节点的命令行工具:
roslaunch package_name launch_file_name
launch 文件是实现多个节点配置和启动的 XML 文件。根据规范,这些文件的后缀都是.launch 。通常会在packages 的 src 文件中创建一个 launch 文件夹,用于存放.launch文件。roslaunch 启动节点时,如果没有 ros Master 节点,则 roslaunch 会自动创建一个。
一个launch文件可以像下面这样:
<launch>
<node pkg="package_name" type="executable_file_name" name="node_name" output="screen"/>
<include file="$(find demo)/launch/demo.launch" ns="demo_namespace"/>
<remap from="demo_name_1" to="demo_name_2"/>
<param name="demo_param" type="int" value="6"/>
<rosparam command="load" file="$(find pkg-name)/path/name.yaml"/>
<arg name="arg_demo" default="6"/>
launch>
<launch>
...
launch>
XML文件必须要包含一个根元素,launch文件中的根元素采用标签定义,文件中的其他内容都必须包含在这个标签之中。
<node pkg="package_name" type="executable_file_name" name="node_name" output="screen"/>
<include file="$(find demo)/launch/demo.launch" ns="demo_namespace"/>
举一个例子,比如turtlebot的键盘控制节点,发布的速度控制指令话题可能是/turtlebot/cmd_vel,但是我们自己的机器人订阅的速度控制话题是/cmd_vel,这个时候在键盘控制节点下使用
<remap from="/turtlebot/cmd_vel"to="/cmd_vel"/>
如果这个 remap 标签写在与 node 元素的同一级,而且在 launch 元素内的最顶层。 那么这个重映射将会作用于 launch 文件中所有的节点。
<param name="demo_param" type="int" value="6"/>
<rosparam command="load" file="$(find pkg-name)/path/name.yaml"/>
arg 标签只能在launch文件中使用。而param则是储存在参数服务器中,可以被节点使用。
<arg name="arg_demo_1" default="6"/>
<arg name="arg_demo_2" value="6"/>
以上是两种简单的赋值方法,两者的区别是使用 default 赋值的参数可以在命令行中像下面这样被修改,value 则不行。
roslaunch demo demo.launch arg_demo_1:=777
demo.launch 文件
<include file="include.launch">
<arg name="hoge" value="fuga" />
include>
include.launch文件
<launch>
<arg name="hoge" />
<param name="param" value="$(arg hoge)"/>
launch>
group标签可以将若干个节点同时划分进某个工作空间,还可以做到对node的批量管理。
<group if="1-or-0">
<node name="demo_1" pkg="demo_1" type="demo_pub_1" output="screen"/>……
……
group>
<group unless="1-or-0">
<node name="demo_2" pkg="demo_2" type="demo_pub_2" output="screen"/>
……
……
group>
第一种情况,当 if 属性的值为 0 的时候将会忽略掉
之间的标签。
第二种恰好相反,当 if 属性的值为 1 的时候将会忽略掉
之间的标签。
但是我们通常不会直接用 1 或 0 来定义 if 标签。因为这样不够灵活。
通常会搭配 $(arg arg_name)
来使用,例如:
demo.launch 文件
<launch>
<include file="include.launch">
<arg name="demo_arg" value="1"/>
include>
launch>
include.launch文件
<launch>
<arg name="demo_arg"/>
<group if="$(demo_arg)">
<node name="demo" pkg="demo" type="demo_pub" output="screen"/>
<node name="demo" pkg="demo" type="demo_sub" output="screen"/>
group>
launch>