ROS机器人操作系统Catkin的编译与常用命令的使用介绍

ROS中命令有很多,对一些频繁使用的常见命令,做一个整理,这些命令在平时操作机器人当中都是常用到的,也是在ROS中如何让机器人正常运作的必备知识。

尤其是对包进行编译时,熟悉CMake的朋友来说会很简单,在ROS中目前基本都用Catkin了,它将CMake和Make做了一个封装,变得更加高效和简洁了,而且移植性更好,支持交叉编译和更加合理的功能包分配。当然在ROS系统里面也兼容以前的旧版本rosbuild的编译。不过推荐使用Catkin了,基本上ROS的核心软件包都已全部转换为Catkin。

一、常用命令

命令 作用
roslaunch 运行启动文件
catkin_create_pkg 创建功能包
rospack 获取功能包
catkin_make 编译工作空间中的功能包
rosdep  自动安装功能包依赖的其他包
roscd 功能包目录跳转
roscp 拷贝功能包中的文件
rosed 编辑功能包中的文件
rosrun 运行功能包中的可执行文件

对于上述一些常见命令,下面给出它们的详细解释,来自官方的帮助文档,我对其做了中文注释,方便后期的查找与应用。

1.1、roslaunch

roslaunch:运行启动文件,是非常重要的命令,对于ROS拥有非常多节点的复杂系统来说,一次性全部启动很多节点,就需要用到这个命令。

roslaunch -h

Usage: roslaunch [options] [package] <filename> [arg_name:=value...]
       roslaunch [options] <filename> [<filename>...] [arg_name:=value...]

If <filename> is a single dash ('-'), launch XML is read from standard input.

Options:
  -h, --help         show this help message and exit    显示此帮助消息并退出
  --files               Print list files loaded by launch file, including launch file itself  打印由启动文件加载的列表文件,包括启动文件本身  
  --args=NODE_NAME      Print command-line arguments for node   为节点打印命令行参数
  --nodes               Print list of node names in launch file    打印启动文件中的节点名称列表
  --find-node=NODE_NAME  Find launch file that node is defined in      查找在其中定义节点的启动文件
  -c NAME, --child=NAME     Run as child service 'NAME'. Required with -u    作为子服务'NAME'运行。需要带-u
  --local               Do not launch remote nodes    不启动远程节点
  --screen              Force output of all local nodes to screen     强制所有本地节点输出到屏幕
  --required            Force all nodes to be required    强制所有节点为必需节点
  --log                 Force output of all local nodes to log   强制所有本地节点输出日志
  -u URI, --server_uri=URI     URI of server. Required with -c       服务器的URI。与-c一起使用
  --run_id=RUN_ID       run_id of session. Required with -c          会话的Run_id。与-c一起使用
  --wait                wait for master to start before launching   等主程序启动后再启动
  -p PORT, --port=PORT  master port. Only valid if master is launched   主端口。仅在主服务器启动时有效
  --core                Launch core services only    只推出核心服务
  --pid=PID_FN          write the roslaunch pid to filename  将roslaunch的pid写入到文件
  -v                    verbose printing  详细打印
  --no-summary          hide summary printing   不打印摘要
  --dump-params         Dump parameters of all roslaunch files to stdout   将所有roslaunch文件的参数转储到标准输出
  --skip-log-check      skip check size of log folder  跳过检查日志文件夹的大小
  --ros-args            Display command-line arguments for this launch file   显示此启动文件的命令行参数
  --disable-title       Disable setting of terminal title    禁用终端标题设置
  -w NUM_WORKERS, --numworkers=NUM_WORKERS
                        override number of worker threads. Only valid for core services.     覆盖工作线程数。仅对核心有效服务。
  -t TIMEOUT, --timeout=TIMEOUT
                        override the socket connection timeout (in seconds). Only valid for core services.
                        覆盖套接字连接超时(以秒为单位)。仅对核心服务有效。
  --master-logger-level=MASTER_LOGGER_LEVEL
                        set rosmaster.master logger level ('debug', 'info', 'warn', 'error', 'fatal')  设置日志级别

参数比较多,一般常跟的参数就是screen

--screen: 强制所有本地节点输出到屏幕,这样便于观察和调试,当然想要保存到日志文件,便于后期随时查看的情况,就指定为--log即可。一般在调试完成之后,还是将screen这个参数给去掉,保持终端输出干净。
roslaunch命令运行时首先会检测系统的rosmaster是否运行,如果已经启动,就用现有的rosmaster;如果没有启动,会先启动rosmaster,然后再执行launch文件中的设置,一次性把多个节点按照我们预先的配置启动起来。需要注意的是, launch文件不需要编译,设置好之后可以直接用上述方式运行。
arg:=value: 如果launch文件中有待赋值的变量,可以通过这种方式赋值。

1.2、catkin_create_pkg

创建功能包的信息

catkin_create_pkg -h

usage: catkin_create_pkg [-h] [--meta] [-s [SYS_DEPS [SYS_DEPS ...]]]
                         [-b [BOOST_COMPS [BOOST_COMPS ...]]] [-V PKG_VERSION]
                         [-D DESCRIPTION] [-l LICENSE] [-a AUTHOR]
                         [-m MAINTAINER] [--rosdistro ROSDISTRO]
                         name [dependencies [dependencies ...]]

Creates a new catkin package

positional arguments:
  name                  The name for the package
  dependencies          Catkin package Dependencies

optional arguments:
  -h, --help            show this help message and exit
  --meta                Creates meta-package files  创建元包文件
  -s [SYS_DEPS [SYS_DEPS ...]], --sys-deps [SYS_DEPS [SYS_DEPS ...]]
                        System Dependencies 系统依赖项
  -b [BOOST_COMPS [BOOST_COMPS ...]], --boost-comps [BOOST_COMPS [BOOST_COMPS ...]]
                        Boost Components Boost组件
  -V PKG_VERSION, --pkg_version PKG_VERSION  Initial Package version  初始软件包版本
  -D DESCRIPTION, --description DESCRIPTION  Description  说明
  -l LICENSE, --license LICENSE  Name for License, (e.g. BSD, MIT, GPLv3...)    许可协议
  -a AUTHOR, --author AUTHOR  A single author, may be used multiple times   作者
  -m MAINTAINER, --maintainer MAINTAINER  A single maintainer, may be used multiple times  维护者
  --rosdistro ROSDISTRO  The ROS distro (default: environment variable ROS_DISTRO if defined)  ROS发行版

1.3、rospack

获取功能包的信息

rospack -h

USAGE: rospack <command> [options] [package]
  Allowed commands:
    help
    cflags-only-I     [--deps-only] [package]
    cflags-only-other [--deps-only] [package]
    depends           [package] (alias: deps)
    depends-indent    [package] (alias: deps-indent)
    depends-manifests [package] (alias: deps-manifests)
    depends-msgsrv    [package] (alias: deps-msgsrv)
    depends-on        [package]
    depends-on1       [package]
    depends-why --target=<target> [package] (alias: deps-why)
    depends1          [package] (alias: deps1)
    export [--deps-only] --lang=<lang> --attrib=<attrib> [package]
    find [package]
    langs
    libs-only-L     [--deps-only] [package]
    libs-only-l     [--deps-only] [package]
    libs-only-other [--deps-only] [package]
    list
    list-duplicates
    list-names
    plugins --attrib=<attrib> [--top=<toppkg>] [package]
    profile [--length=<length>] [--zombie-only]
    rosdep  [package] (alias: rosdeps)
    rosdep0 [package] (alias: rosdeps0)
    vcs  [package]
    vcs0 [package]
  Extra options:
    -q     Quiets error reports.

 If [package] is omitted, the current working directory
 is used (if it contains a package.xml or manifest.xml).

如果不指明包名,就表示当前工作目录。

1.4、catkin_make

编译工作空间中的功能包,这个在本文最前面就已介绍,专门针对ROS里面包的编译,是对CMake和Make的封装。

catkin_make -h

usage: catkin_make [-h] [-C DIRECTORY] [--source SOURCE] [--build BUILD]
                   [--use-ninja] [--use-nmake] [--use-gmake] [--force-cmake]
                   [--no-color] [--pkg PKG [PKG ...]]
                   [--only-pkg-with-deps ONLY_PKG_WITH_DEPS [ONLY_PKG_WITH_DEPS ...]]
                   [--cmake-args [CMAKE_ARGS [CMAKE_ARGS ...]]]
                   [--make-args [MAKE_ARGS [MAKE_ARGS ...]]]
                   [--override-build-tool-check]

optional arguments:
  -h, --help            show this help message and exit
  -C DIRECTORY, --directory DIRECTORY   The base path of the workspace (default '.')  工作空间的基本路径(默认'.')
  --source SOURCE       The path to the source space (default 'workspace_base/src')  源代码空间路径(默认为'workspace_base/src')
  --build BUILD         The path to the build space (default 'workspace_base/build')  构建空间的路径(默认为'workspace_base/build')
  --use-ninja           Use 'ninja' instead of 'make'   用ninja代替make
  --use-nmake           Use 'nmake' instead of 'make'  用nmake代替make
  --use-gmake           Use 'gmake' instead of 'make'  用gmake代替make
  --force-cmake         Invoke 'cmake' even if it has been executed before   强制使用cmake
  --no-color            Disables colored output (only for catkin_make and CMake)  禁用彩色输出(仅适用于catkin_make和CMake)
  --pkg PKG [PKG ...]   Invoke 'make' on specific packages only  只对特定的包调用make
  --only-pkg-with-deps ONLY_PKG_WITH_DEPS [ONLY_PKG_WITH_DEPS ...]
                        Whitelist only the specified packages and their
                        dependencies by setting the CATKIN_WHITELIST_PACKAGES
                        variable. This variable is stored in CMakeCache.txt
                        and will persist between CMake calls unless explicitly
                        cleared; e.g. catkin_make
                        -DCATKIN_WHITELIST_PACKAGES="".
    通过设置CATKIN_WHITELIST_PACKAGES变量,将指定的包和它的依赖包列入白名单,该变量存储在CMakeCache.txt中,并且将在CMake调用之间持续存在,除非显式地清除。
  --cmake-args [CMAKE_ARGS [CMAKE_ARGS ...]]
                        Arbitrary arguments which are passed to CMake. It must be passed after other arguments since it collects all following options.
传递给CMake的任意参数。它必须在其他参数之后传递,因为它收集以下所有选项
  --make-args [MAKE_ARGS [MAKE_ARGS ...]]
                        Arbitrary arguments which are passes to make. It must be passed after other arguments since it collects all following options. This is only necessary in combination with --cmake-args since else all unknown arguments are passed to make anyway. 
只有在与 --cmake-args 结合使用时才需要这样做,否则所有未知参数都会传递给make
  --override-build-tool-check
                        use to override failure due to using different build tools on the same workspace.  用于覆盖由于在同一工作空间上使用不同构建工具而导致的故障。

1.5、rosdep

自动安装功能包的依赖包

rosdep -h

Usage: rosdep [options] <command> <args>

Commands:

rosdep check <stacks-and-packages>...
  check if the dependencies of package(s) have been met.    检查包的依赖项是否满足。

rosdep install <stacks-and-packages>...
  download and install the dependencies of a given package or packages.  下载并安装一个或多个给定包的依赖项。

rosdep db
  generate the dependency database and print it to the console.  生成依赖关系数据库并将其打印到控制台

rosdep init
  initialize rosdep sources in /etc/ros/rosdep.  May require sudo.   在/etc/ ross /rosdep中初始化依赖项源。可能需要sudo权限

rosdep keys <stacks-and-packages>...
  list the rosdep keys that the packages depend on.   列出包所依赖的rosdep键。

rosdep resolve <rosdeps>
  resolve <rosdeps> to system dependencies    将<rosdeps>解析为系统依赖项

rosdep update
  update the local rosdep database based on the rosdep sources.    根据rosdep源更新本地rosdep数据库

rosdep what-needs <rosdeps>...
  print a list of packages that declare a rosdep on (at least one of) <rosdeps>  打印<rosdeps>上(至少一个)定义rosdep的程序包的列表

rosdep where-defined <rosdeps>...
  print a list of yaml files that declare a rosdep on (at least one of) <rosdeps>  打印在<rosdeps>上(至少一个)定义的rosdep的yaml文件列表

 1.5.1、权限命令

rosdep fix-permissions
  Recursively change the permissions of the user's ros home directory. 递归地更改用户ros主目录的权限。
  May require sudo.  Can be useful to fix permissions after calling "rosdep update" with sudo accidentally.

权限被拒绝的时候,可以使用如下命令:
sudo rosdep fix-permissions
rosdep update (有时可能需要sudo

1.5.2、Options

Options:
  -h, --help            show this help message and exit
  --os=OS_NAME:OS_VERSION
                        Override OS name and version (colon-separated), e.g. ubuntu:lucid  覆盖操作系统名称和版本(冒号分隔)
  -c SOURCES_CACHE_DIR, --sources-cache-dir=SOURCES_CACHE_DIR
                        Override /home/jetson/.ros/rosdep/sources.cache
  -v, --verbose         verbose display   详细显示
  --version             print just the rosdep version, then exit  只打印rosdep版本,然后退出
  --all-versions        print rosdep version and version of installers, then exit  打印rosdep版本和安装程序版本,然后退出
  --reinstall           (re)install all dependencies, even if already installed   安装所有依赖项,即使已经安装
  -y, --default-yes     Tell the package manager to default to y or fail when installing  安装时告诉包管理器默认为y
  -s, --simulate        Simulate install  模拟安装
  -r                    Continue installing despite errors.    尽管出现错误,仍继续安装。
  -q                    Quiet. Suppress output except for errors.   静默安装。除错误外,禁止输出。
  -a, --all             select all packages    选择所有包
  -n                    Do not consider implicit/recursive dependencies.  Only valid with 'keys', 'check', and 'install' commands.
    不要考虑隐式/递归依赖。仅对'keys', 'check'和'install'命令有效。
  -i, --ignore-packages-from-source, --ignore-src
                        Affects the 'check', 'install', and 'keys' verbs. If specified then rosdep will ignore keys that are found to be catkin or ament packages anywhere in the ROS_PACKAGE_PATH, AMENT_PREFIX_PATH or in any of the directories given by the --from-paths option.   如果指定这个参数rosdeep将忽略在catkin或其他路径找到的包
  --skip-keys=SKIP_KEYS
                        Affects the 'check' and 'install' verbs. The specified rosdep keys will be ignored, i.e. not resolved and not installed. The option can be supplied multiple times.
                        A space separated list of rosdep keys can also be passed as a string. A more permanent solution to locally ignore a rosdep key is creating a local rosdep rule with an empty list of packages (include it in /etc/ros/rosdep/sources.list.d/ before the defaults).  本地忽略rosdep键的更永久的解决方案是创建一个带有空包列表的本地rosdep规则(包含在/etc/ ross /rosdep/sources.list.d),在默认值之前
  --filter-for-installers=FILTER_FOR_INSTALLERS
                        Affects the 'db' verb. If supplied, the output of the 'db' command is filtered to only list packages whose installer is in the provided list. The option can be supplied multiple times. A space separated list of installers can also be passed as a string. Example:
                        `--filter-for-installers "apt pip"`               仅安装过滤的包
  --from-paths          Affects the 'check', 'keys', and 'install' verbs. If specified the arguments to those verbs will be considered paths to be searched, acting on all catkin packages found there in.
  --rosdistro=ROS_DISTRO
                        Explicitly sets the ROS distro to use, overriding the normal method of detecting the ROS distro using the ROS_DISTRO environment variable. When used with the 'update' verb, only the specified distro will be updated.  显示指定ros的发行版本
  --as-root=INSTALLER_KEY:<bool>
                        Override whether sudo is used for a specific installer, e.g. '--as-root pip:false' or '--as-root "pip:no homebrew:yes"'. Can be specified multiple times.
  --include-eol-distros
                        Affects the 'update' verb. If specified end-of-life distros are being fetched too.  指定过时的发行版本也会被获取
  -t DEPENDENCY_TYPES, --dependency-types=DEPENDENCY_TYPES
                        Dependency types to install, can be given multiple times. Choose from set(['exec', 'doc', 'build_export','buildtool', 'test', 'build', 'buildtool_export']).Default: all except doc. 

1.6、rosrun

运行功能包中的可执行文件
rosrun -h

Usage: rosrun [--prefix cmd] [--debug] PACKAGE EXECUTABLE [ARGS]
  rosrun will locate PACKAGE and try to find an executable named EXECUTABLE in the PACKAGE tree. If it finds it, it will run it with ARGS.

rosrun将定位包然后试着在包树中查找可执行文件,如果找到将根据参数运行。

必须先启动节点管理器(master),master 是用来管理系统中的很多进程的,每个node启动时都要向master注册管理node之间的通信。master启动后再去通过master注册每一个node节点。在Ubuntu终端中输入命令:roscore,这个roscore是每个ROS所必须的,是用来给节点之间提供连接信息的,就是说一个结点启动时,都会连接到roscore并注册该节点发布和订阅的消息,当出现新的节点时,roscore会向它提供其他发布并订阅相同消息主题的节点建立点对点连接的必要信息。如果没有roscore,那节点之间无法互相找到,也就不能互相通信了。
rosrun方法每次只能运行一个节点。接下来就是对命令的一些实战。

二、示例演示

2.1、单只海龟模拟器

首先启动节点管理器,输入命令:roscore
下面是启动的相关信息,检查日志文件大小、显示服务地址与端口、版本号、摘要等,按Ctrl+C将结束ROS所有节点:

... logging to /home/jetson/.ros/log/fd65134c-d010-11ec-95c6-0013eff86fe1/roslaunch-jetson-desktop-10638.log
Checking log directory for disk usage. This may take a while.
Press Ctrl-C to interrupt
Done checking log file disk usage. Usage is <1GB.

started roslaunch server http://jetson-desktop:33239/
ros_comm version 1.14.11


SUMMARY
========

PARAMETERS
 * /rosdistro: melodic
 * /rosversion: 1.14.11

NODES

auto-starting new master
process[master]: started with pid [10695]
ROS_MASTER_URI=http://jetson-desktop:11311/

setting /run_id to fd65134c-d010-11ec-95c6-0013eff86fe1
process[rosout-1]: started with pid [10727]
started core service [/rosout]

再打开一个终端,启动海龟模拟器节点

rosrun turtlesim turtlesim_node

[ INFO] [1652153768.669399182]: Starting turtlesim with node name /turtlesim
[ INFO] [1652153768.694629755]: Spawning turtle [turtle1] at x=[5.544445], y=[5.544445], theta=[0.000000]
QXcbConnection: XCB error: 148 (Unknown), sequence: 173, resource id: 0, major code: 140 (Unknown), minor code: 20

最后再次打开一个终端,启动海龟键盘控制器节点
rosrun turtlesim turtle_teleop_key
在这个键盘控制器节点的命令下面,就可以通过上下左右方向键来控制海龟的移动了。如下图所示: 

也就是说在这个操作海龟移动中,我们开了三个终端,首先启动节点管理,然后分别启动各自需要的节点即可。我们可以查看下启动了哪些话题,输入命令:rostopic list

/rosout
/rosout_agg
/turtle1/cmd_vel
/turtle1/color_sensor
/turtle1/pose

也可以输入 rqt_graph 命令来查看ROS图: 

2.2、两只海龟 

下面来看下,一只海龟跟着键盘操作的海龟移动的例子
安装功能包:sudo apt install ros-melodic-turtle-tf

可能出现下面的错误:

Could not resolve 'packages.ros.org'
E: Failed to fetch http://packages.ros.org/ros/ubuntu/pool/main/r/ros-melodic-turtle-tf/ros-melodic-turtle-tf_0.2.2-0bionic.20210922.040438_arm64.deb  Could not resolve 'packages.ros.org'
E: Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?

我们直接查看下列表页面:http://packages.ros.org/ros/ubuntu/pool/main/r/ros-melodic-turtle-tf/
可以发现没有上述的deb文件,我们可以选择其他的手动下载都可以。当然如果说这个版本是有的情况,那就是网络超时等关系,可以科学上网或手动下载等方式来处理了。
也可以更换为国内的镜像源:

cd /etc/apt
vim sources.list

比如阿里云的开源镜像站:

deb http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse

我这里使用的是清华镜像:

deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic main multiverse restricted universe
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic-security main multiverse restricted universe
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic-updates main multiverse restricted universe
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic-backports main multiverse restricted universe
deb-src http://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic main multiverse restricted universe
deb-src http://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic-security main multiverse restricted universe
deb-src http://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic-updates main multiverse restricted universe
deb-src http://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic-backports main multiverse restricted universe

最后执行下:

刷新本地的软件列表:sudo apt-get update
软件更新:sudo apt-get upgrade

通过roslaunch命令运行.launch文件来启动海龟,同样的将显示一些相关信息

roslaunch turtle_tf turtle_tf_demo.launch

比如其中的摘要:

SUMMARY
========

PARAMETERS
 * /rosdistro: melodic
 * /rosversion: 1.14.11
 * /scale_angular: 2.0
 * /scale_linear: 2.0
 * /turtle1_tf_broadcaster/turtle: turtle1
 * /turtle2_tf_broadcaster/turtle: turtle2

NODES
  /
    sim (turtlesim/turtlesim_node)
    teleop (turtlesim/turtle_teleop_key)
    turtle1_tf_broadcaster (turtle_tf/turtle_tf_broadcaster.py)
    turtle2_tf_broadcaster (turtle_tf/turtle_tf_broadcaster.py)
    turtle_pointer (turtle_tf/turtle_tf_listener.py)

ROS_MASTER_URI=http://localhost:11311

process[sim-1]: started with pid [30907]
process[teleop-2]: started with pid [30908]
process[turtle1_tf_broadcaster-3]: started with pid [30909]
process[turtle2_tf_broadcaster-4]: started with pid [30917]
process[turtle_pointer-5]: started with pid [30920]

可以看到显示出了启动的多个节点,以及每个程序启动的线程ID。

使用rosrun来启动节点,操作键盘控制海龟
rosrun turtlesim turtle_teleop_key

如下图所示,有一只被键盘控制的海龟,另一只海龟则跟随被操控的海龟:

三、launch文件 

我们来具体了解下launch文件,就用上面启动海龟的这个launch文件,我们先找到它:
sudo find / -name turtle_tf_demo.launch
找到之后,我们查看下里面是一些什么内容
cat /opt/ros/melodic/share/turtle_tf/launch/turtle_tf_demo.launch

<launch>

  <!-- Turtlesim Node-->
  <node pkg="turtlesim" type="turtlesim_node" name="sim"/>

  <node pkg="turtlesim" type="turtle_teleop_key" name="teleop" output="screen"/>
  <!-- Axes -->
  <param name="scale_linear" value="2" type="double"/>
  <param name="scale_angular" value="2" type="double"/>

  <node name="turtle1_tf_broadcaster" pkg="turtle_tf" type="turtle_tf_broadcaster.py" respawn="false" output="screen" >
    <param name="turtle" type="string" value="turtle1" />
  </node>
  <node name="turtle2_tf_broadcaster" pkg="turtle_tf" type="turtle_tf_broadcaster.py" respawn="false" output="screen" >
    <param name="turtle" type="string" value="turtle2" />
  </node>
  <node name="turtle_pointer" pkg="turtle_tf" type="turtle_tf_listener.py" respawn="false" output="screen" >
  </node>

</launch>

可以看到这个launch文件是XML格式的文件,根据海龟1和海龟2的示例,我们可以知道,启动的包名和可执行程序的名称对应到node节点。
第一个海龟示例:pkg="turtlesim" type="turtlesim_node",所以启动代码为:rosrun turtlesim turtlesim_node
第二个海龟示例:pkg="turtle_tf" type="turtle_tf_broadcaster.py",所以启动代码为:roslaunch turtle_tf turtle_tf_demo.launch
键盘操作启动都一样:rosrun turtlesim turtle_teleop_key
那为什么需要弄一个launch文件呢?因为一个完整的机器人,一般是包含特别多的节点程序,需要同时运行协作,那如果一个一个去启动节点就显得比较麻烦了,所以通过这个配置文件,我们可以一次搞定,让它们全部启动,是不是轻松多了。
接下来具体看下这个文件的一些参数说明:

<launch>                  <!--根标签开始-->
<node>                    <!--需要启动的node及其参数-->
<remap>                  <!--设定topic映射-->
<include>                <!--包含其他launch-->

<arg>                       <!--定义变量-->
<param>                 <!--定义全局变量-->
<rosparam>            <!--加载yaml文件中的参数到参数服务器-->

<group>                 <!--设定分组-->
<machine>              <!--指定运行的机器-->
<env-loader>          <!--设置环境变量-->
</launch>               <!--根标签结束-->

3.1、<node>

 node标签是launch文件的核心部分,定义如下:

<launch>
    <node pkg="包名1" type="可执行文件1" name="节点名1"/>
    <node pkg="包名2" type="可执行文件2" name="节点名2"></node>
    ...
</launch>

其中type如果是Python写的就是 .py文件,如果是C++写的,就是编译之后的可执行文件的名称。需要注意的是这个launch文件,对于里面的节点启动,不是按照顺序来启动的。除了这三个必要参数之外,还有一些可选参数:

<launch>
    <node pkg="" type="" name="" respawn="true" required="true" launch-prefix="xterm -e" output="screen" ns="namespace" />
</launch>

respawn:若该节点关闭,是否自动重新启动
required:若该节点关闭,是否关闭其他所有节点
launch-prefix: 是否新开一个窗口执行
output:默认是存入log文件中,可以设置显示到屏幕
ns:node 归入不同的 namespace,即在 node name 前边加 ns 指定的前缀。为了实现这类操作,在 node 源文件中定义 node nametopic name 时要采用相对名称, 即不加符号 /。

3.1.1、计算图源

在ROS中,计算图源是指话题、节点、服务和参数等的统称。每一个计算图源由一个叫做计算图源名称的短字符串标识。计算图源名称如下:
基础名称:比如,topic
全局名称:以"/"开头的计算图源名称。比如,/A/topic
相对名称:名称开头没有"/"的计算图源名称。比如,A/topic
私有名称:波浪符号"~"开始的计算图源名称。比如,~topic
匿名名称:没有名称的计算图源。
发布和订阅时有下面这样的代码:

ros::init(argc, argv, "publish_node");
ros::NodeHandle nh;
ros::Publisher pub = nh.advertise<std_msgs::string>("topic",1000);

3.2、<remap>

将名称重新映射参数传递给ROS节点,不需要去设置节点的参数属性。
话题分为发布和订阅
发布话题:

<node pkg="pub_node" type="pub_node" name="pub_node">
    <remap from="/pub_topic" to="/new_topic" />
</node>

这里是将pub_node节点发布的话题/pub_topic映射到/new_topic

订阅话题:

<node pkg="sub_node" type="sub_node" name="sub_node">
    <remap from="/sub_topic" to="/turtle" />
</node>

这里是订阅他人的话题/turtle映射为sub_node节点的sub_topic名称,也就是将别人发布的话题映射到自己订阅的话题上。

3.3、<include>

将另外的launch文件包含进来,相当于launch文件的嵌套,file参数指定为全路径即可

<include file="path-to-launch-file" />

当然这里为了更好的移植性,可以使用find命令来代替:

<include file="$(find package-name)/launch-file-name" />

这样的好处是,即便更换了主控,只要安装的是同样的包,就能找到对应路径。有时,另一个launch引入的节点可能需要统一命名,或者具有类似特征的节点名字,比如 /my/gps, /my/lidar, /my/imu 这样具有统一的前缀,方便查找,可以通过设置命名空间ns属性来实现,命令如下:

<include file="$(find package-name)/launch-file-name " ns="my" /> 

3.4、<arg>

参数可以重复使用,三种常见写法

<arg name="foo">                          <!--只定义,不赋值-->
<arg name="foo" default="1">              <!--默认值-->
<arg name="foo" value="1">                <!--固定值-->

赋值的其余常见方法:
命令行赋值
roslaunch package_name xxx.launch arg1:=v1 arg2:=v2

变量替换

1、$(find pkg): 例如$(find rospy)/manifest.xml 如果可能,强烈推荐这种基于包的路径设置
2、$(arg arg_name): 先设置默认值,如果没有额外的赋值,就用这个默认值了
比如

<arg name="gui" default="true" />
<!-- 如果没有额外的赋值,就用这个默认值 -->
<param name="use_gui" value="$(arg gui)"/>

还可以使用命令行赋值

<node pkg="包名" type="可执行文件" name="节点名" args="$(arg a) $(arg b)" />

这样在启动launch文件的时候就可以对args赋值:
roslaunch 包名 file_name.launch a:=1 b:=2

3.5、<param>

arg不一样,这里的param是共享的,其定义差不多

<param name="publish_frequency" type="double" value="10.0" />

这里的取值,除了上述之外,还可以来自文件。

<param name="参数名" textfile="$(find pkg)/path/file"/>
<param name="参数名" command="$(find pkg)/exe '$(find pkg)/arg.txt'"/>
<param name="参数名" type="yaml" command="cat '$(find pkg)/*.yaml'"/>

除了在全局范围定义之外,还可以在node节点里面定义:

<node name="node1" pkg="pkg1" type="exe1">
    <param name="param1" value="False"/>
 </node>

可以通过命令查看所有的param:rosparam list
那么上述将出现如下情况:

/publish_frequency
/node1/param1   # 这里会自动加上命名空间前缀,需要注意的是虽然名字前加了命名空间,但依然是全局范围。

3.6、<rosparam>

前面的param是通过value、textfile、command取值,返回的是单个的param的内容,rosparam可以批量操作,还包括一些对参数设置的命令,如 dump、delete
来看下其用法
load : 从 YAML 文件中加载一批param:

<rosparam command="load" file="$(find rosparam)/example.yaml" />

delete: 删除某个param

<rosparam command="delete" param="my_param" />

赋值操作

<rosparam param="my_param">[1,2,3,4]</rosparam>

还可以这样

<rosparam>
a: 1
b: 2
</rosparam>

同样的,这个rosparam也是可以放在节点里面。

3.7、<group>

如果要对多个节点进行同样的设置,比如都在同一个特定的命名空间,remap相同的话题等,就可以用到这个group分组。

<group ns="rosbot">
    <remap from="chatter" to="talker"/>       # 对该组中后面的节点都有效
    <node ... />
    <node ... >
        <remap from="chatter" to="talker1"/>  # 还可以对单个节点重新设置
    </node>
</group>

从这些启动节点来看,ROS的设计是非常的松耦合,这对于共同协作来说是非常好的设计,而且单个节点的崩溃都不会影响到其他节点,这对于调试和维护来说都是优势。

猜你喜欢

转载自blog.csdn.net/weixin_41896770/article/details/132207097
今日推荐