机器人操作系统ROS—初探

一直听到ROS这个名字,很好奇它为什么在机器人领域这么出名,所以从今天起我将从零开始学习一下,看看它到底有哪些神奇之处。本文作为初探篇会先带大家了解ROS的基本概念,通过安装和创建/运行程序包了解Nodes节点、Topics/Msg、Service服务/参数服务器、几个常见的工具。

ROS (Robot Operating System, 机器人操作系统) 提供一系列程序库和工具以帮助软件开发者创建机器人应用软件。它提供了硬件抽象、设备驱动、库函数、可视化、消息传递和软件包管理等诸多功能。ROS遵守BSD开源许可协议。

ROS的官网:https://ros.org/

ROS 图(graph)概念:

  • Nodes:节点,一个节点即为一个可执行文件,它可以通过ROS与其它节点进行通信。

  • Messages:消息,消息是一种ROS数据类型,用于订阅或发布到一个话题。

  • Topics:话题,节点可以发布消息到话题,也可以订阅话题以接收消息。

  • Master:节点管理器,ROS名称服务 (比如帮助节点找到彼此)。

  • rosout: ROS中相当于stdout/stderr。

  • roscore: 主机+ rosout + 参数服务器 (参数服务器会在后面介绍)。

一、安装

今天刚攒了一台Ubuntu18.04机器,就用这台机器来安装ROS吧。

目前支持Ubuntu18.04的最新ROS发行版是Melodic Morenia,参考Ubuntu install of ROS Melodic安装即可。

# 配置 Ubuntu软件更新 允许 "restricted"、"universe" 和 "multiverse"这三种安装模式

# LANG
sudo locale-gen en_US en_US.UTF-8
sudo update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8
export LANG=en_US.UTF-8

# 添加 sources.list
#sudo sh -c 'echo "deb [arch=$(dpkg --print-architecture)] http://packages.ros.org/ros/ubuntu $(lsb_release -cs) main" > /etc/apt/sources.list.d/ros-latest.list'
sudo sh -c '. /etc/lsb-release && echo "deb [arch=$(dpkg --print-architecture)] http://mirrors.ustc.edu.cn/ros/ubuntu/ $DISTRIB_CODENAME main" > /etc/apt/sources.list.d/ros-latest.list'

# 添加公钥
sudo apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654
# or  curl -s https://raw.githubusercontent.com/ros/rosdistro/master/ros.asc | sudo apt-key add -
# 安装
sudo apt update
sudo apt install ros-melodic-desktop-full   #桌面完整版ros-melodic-desktop-full;桌面版ros-melodic-desktop;基础版ros-melodic-ros-base

# 设置环境
echo "source /opt/ros/melodic/setup.bash" >> ~/.bashrc
source ~/.bashrc

# 安装工具
sudo apt install python-rosdep python-rosinstall python-rosinstall-generator python-wstool build-essential
# 或 pip install --user catkin_pkg rosdep rosinstall-generator wstool six vcstools pydot
sudo apt install python-rosdep
# 初始化 rosdep
sudo vim /etc/hosts
    185.199.109.133  raw.githubusercontent.com
sudo rosdep init
rosdep update    # timeout问题解决方法:https://www.guyuehome.com/33258

printenv | grep ROS

 

二、创建/编译程序包

参考:Installing and Configuring Your ROS EnvironmentNavigating the ROS FilesystemCreating a ROS Package

# 创建工作空间
mkdir -p ~/catkin_ws/src
cd ~/catkin_ws/
catkin_make -DPYTHON_EXECUTABLE=/usr/bin/python3


echo "source /home/work/catkin_ws/devel/setup.bash" >> ~/.bashrc
source ~/.bashrc
echo $ROS_PACKAGE_PATH


# 文件系统工具
sudo apt-get install ros-melodic-ros-tutorials  libfwup1 python3-rosdistro-modules python3-rospkg-modules
  rospack find roscpp
  roscd roscpp
  echo $ROS_PACKAGE_PATH

  roscd roscpp/cmake
  roscd log
  rosls roscpp_tutorials
  roscd roscpp_tutorials/

# 创建ROS程序包
cd ~/catkin_ws/src
# catkin_create_pkg <package_name> [depend1] [depend2] [depend3]
catkin_create_pkg beginner_tutorials std_msgs rospy roscpp
cd ~/catkin_ws
catkin_make

  # 查看程序包的一级依赖
  rospack depends1 beginner_tutorials 
  roscd beginner_tutorials
  cat package.xml

  # 查看间接依赖
  rospack depends1 rospy
  rospack depends beginner_tutorials


# 自定义ROS程序包
vim ~/catkin_ws/src/beginner_tutorials/package.xml
  <description>Mars test package: beginner_tutorials</description>
  <maintainer email="yanjingang@mail.com">yanjingang</maintainer>
  <license>BSD</license>
cd ~/catkin_ws
catkin_make

三、理解ROS Nodes节点

参考:Understanding ROS Nodes

一个节点其实只不过是ROS程序包中的一个可执行文件。ROS节点可以使用ROS客户库与其他节点通信。节点可以发布或接收一个话题,也可以提供或使用某种服务。

ROS客户端库允许使用不同编程语言编写的节点之间互相通信:

  • rospy = python 客户端库
  • roscpp = c++ 客户端库
# 启动roscore server
roscore     # ros+core : master (provides name service for ROS) + rosout (stdout/stderr) + parameter server (parameter server will be introduced later)


# 显示当前运行的ROS节点信息
rosnode list   #ros+node : ROS tool to get information about a node.
    /rosout    #看到这个表示当前只有一个节点在运行: rosout。因为这个roscore内置节点用于收集和记录节点调试输出信息,所以它总是在运行的

# 查看指定节点信息
rosnode info /rosout


# 运行指定节点
# rosrun [package_name] [node_name]    #ros+run : runs a node from a given package.
rosrun turtlesim turtlesim_node     #这里打开一个内置的小龟模拟器

# 此时可以看到多了一个turtlesim节点
rosnode list
     /rosout
     /turtlesim

# 使用__name自定义节点名
rosrun turtlesim turtlesim_node  __name:=mars_turtlesim

# ping节点测试
rosnode ping /mars_turtlesim
    rosnode: node is [/mars_turtlesim]
    pinging /mars_turtlesim with a timeout of 3.0s
    xmlrpc reply from http://mars:36119/	time=0.364065ms
    xmlrpc reply from http://mars:36119/	time=1.200914ms

三、理解ROS Topics话题

参考:Understanding ROS Topics

# 分别启动roscore、turtlesim
roscore
rosrun turtlesim turtlesim_node

# 启动turtlesim键盘远程控制节点 
rosrun turtlesim turtle_teleop_key       #注:必须在当前命令窗口按键才会被程序监听到

turtlesim_node节点和turtle_teleop_key节点之间是通过一个ROS话题来互相通信的。turtle_teleop_key在一个话题上发布按键输入消息,而turtlesim则订阅该话题以接收该消息。下面让我们使用rqt_graph来显示当前运行的节点和话题。

# 安装rqt_graph(rqt能够创建一个显示当前系统运行情况的动态关系图)
sudo apt install ros-melodic-rqt  ros-melodic-rqt-common-plugins
# 启动rqt_graph节点
rosrun rqt_graph rqt_graph   #这里可以看到当前turtle_teleop_key控制turtlesim的topic名称叫/turtle1/cmd_vel

# 监听topic传输的数据
rostopic echo /turtle1/cmd_vel     #刷新rqt_graph界面可以看到新的topic监听链路

从上图可以看到,turtle_teleop_key向名叫/turtle1/cmd_vel的topic发送消息,左侧的turtlesim模拟器和右侧的rostopic echo指令监听了这个topic并执行对应的动画或数据打印操作。

# 查看当前运行中的topic情况
rostopic list -v
    Published topics:
     * /turtle1/color_sensor [turtlesim/Color] 1 publisher
     * /turtle1/cmd_vel [geometry_msgs/Twist] 1 publisher
     * /rosout [rosgraph_msgs/Log] 4 publishers
     * /rosout_agg [rosgraph_msgs/Log] 1 publisher
     * /turtle1/pose [turtlesim/Pose] 1 publisher

    Subscribed topics:
     * /turtle1/cmd_vel [geometry_msgs/Twist] 2 subscribers
     * /rosout [rosgraph_msgs/Log] 1 subscriber
     * /statistics [rosgraph_msgs/TopicStatistics] 1 subscriber


# 查看topic的MessageType
rostopic type /turtle1/cmd_vel
    geometry_msgs/Twist

# 查看MessageType结构定义
rosmsg show geometry_msgs/Twist
    geometry_msgs/Vector3 linear
       float64 x
       float64 y
       float64 z
    geometry_msgs/Vector3 angular
       float64 x
       float64 y
       float64 z

# 模拟向topic发送message
# rostopic pub [topic] [msg_type] [args]
rostopic pub -1 /turtle1/cmd_vel geometry_msgs/Twist -- '[2.0, 0.0, 0.0]' '[0.0, 0.0, 1.8]'   #以2.0大小的线速度和1.8大小的角速度开始移动(-1表示发布一条消息后马上退出;--表示后边的都是数据)

rostopic pub /turtle1/cmd_vel geometry_msgs/Twist -r 1 -- '[2.0, 0.0, 0.0]' '[0.0, 0.0, 1.8]'   #-r 1参数:以1Hz的频率发布命令到topic

rostopic hz /turtle1/cmd_vel  #查看topic消息pub频率

可以看到左侧的小龟一直转圈,中间rqt_graph上多了一个pub节点向turtlesim和rostopic echo监听pub数据。

四、理解ROS Service服务/参数服务器

参考:Understanding ROS Services and Parameters

服务(services)是节点之间通讯的另一种方式。服务允许节点发送请求(request) 并获得一个响应(response)。

# 常用命令
rosservice list 输出可用服务的信息
rosservice call 调用带参数的服务
rosservice type 输出服务类型
rosservice find 依据类型寻找服务find services by service type 
rosservice uri 输出服务的ROSRPC uri

# 查看可用服务
rosservice list
    /clear       #清除
    /kill           #终止
    /reset      #重置
    /spawn    #再生
    /rosout/get_loggers
    /rosout/set_logger_level
    /rostopic_15460_1592213188678/get_loggers
    /rostopic_15460_1592213188678/set_logger_level
    /rqt_gui_py_node_15282/get_loggers
    /rqt_gui_py_node_15282/set_logger_level
    /teleop_turtle/get_loggers
    /teleop_turtle/set_logger_level
    /turtle1/set_pen
    /turtle1/teleport_absolute
    /turtle1/teleport_relative
    /turtlesim/get_loggers
    /turtlesim/set_logger_level

# 查看clear服务类型(参数/返回值)
rosservice type clear
      std_srvs/Empty       #Empty:请求不需要发送数据,响应也没有数据

# 使用clear清空模拟器画面
rosservice call clear    #此时turtlesim上的轨迹会清除,只剩下小龟


# 查看spawn服务类型(参数/返回值)
rosservice type spawn| rossrv show
    float32 x
    float32 y
    float32 theta
    string name
    ---
    string name

# 使用spawn在给定的位置和角度生成一只新的乌龟
rosservice call spawn 2 2 0.2 ""
    name: "turtle2"
rosservice call spawn 2 8 0.1 ""
    name: "turtle3"
rosservice call spawn 7 6 0.3 ""
    name: "turtle4"

 

ROS 参数服务器(Parameter Server)上的数据可以通过rosparam操作存储。参数服务器能够存储整型、浮点、布尔、字符串、字典和列表等数据类型。rosparam使用YAML标记语言的语法。一般而言,YAML的表述很自然:1 是整型, 1.0 是浮点型, one是字符串, true是布尔, [1, 2, 3]是整型列表, {a: b, c: d}是字典. rosparam有很多指令可以用来操作参数,如下所示:

# 常用命令
rosparam set 设置参数 
rosparam get 获取参数 
rosparam load 从文件读取参数 
rosparam dump 向文件中写入参数 
rosparam delete 删除参数 
rosparam list 列出参数名

# 查看当前参数服务器上有哪些参数
rosparam list
    /mars_turtlesim/background_b
    /mars_turtlesim/background_g
    /mars_turtlesim/background_r
    /rosdistro
    /roslaunch/uris/host_localhost__36533
    /rosversion
    /run_id
    /turtlesim/background_b
    /turtlesim/background_g
    /turtlesim/background_r

# 获取参数
rosparam get /turtlesim/background_r      #获取指定参数
    70
rosparam get /     #获取所有参数
    background_r: 150
    roslaunch:
        uris: {host_localhost__36533: 'http://localhost:36533/'}
    rosversion: '1.14.6
    ......

# 修改参数
rosparam set /turtlesim/background_r 150
rosservice call clear

# 导出所有参数到文件
rosparam dump params.yaml

# 加载导出的参数配置
rosparam load params.yaml

五、工具

参考:Using rqt_console and roslaunchUsing rosed to edit files in ROSGetting started with roswtf

# launch启动器   (可以用来启动定义在launch文件中的多个节点)
roscd beginner_tutorials
mkdir launch
cd launch
vim turtlemimic.launch         (group:节点分组;ns:命名空间namespace;mimic:模仿节点,让turtlesim2模仿turtlesim1)
    <launch>
          <group ns="turtlesim1">
                <node pkg="turtlesim" name="sim" type="turtlesim_node"/>
          </group>
          <group ns="turtlesim2">
                <node pkg="turtlesim" name="sim" type="turtlesim_node"/>
          </group>
          <node pkg="turtlesim" name="mimic" type="mimic">
                <remap from="input" to="turtlesim1/turtle1"/>
                <remap from="output" to="turtlesim2/turtle1"/>
          </node>
    </launch>

# 启动
roslaunch beginner_tutorials turtlemimic.launch    #可以看到同时起了两个小龟模拟器

# 查看小龟模拟器的topic
rostopic list |grep turtlesim1
    /turtlesim1/turtle1/cmd_vel
    /turtlesim1/turtle1/color_sensor
    /turtlesim1/turtle1/pose

# 向topic发送指令   (可以看到turtlesim2在模仿turtlesim1一起转圈)
rostopic pub /turtlesim1/turtle1/cmd_vel geometry_msgs/Twist -r 1 -- '[2.0, 0.0, 0.0]' '[0.0, 0.0, 1.8]'   #-r 1参数:以1Hz的频率发布命令到topic

# 是使用rqt可以看到他们之间的数据流关系
rosrun rqt_graph rqt_graph

# log查看器
rosrun rqt_logger_level rqt_logger_level     #如果日志等级都改成DEBUG后卡死了,可以重启ros节点日志等级会自动重置
rosrun rqt_console rqt_console

# rosed快捷编辑
# rosed [package_name] [filename]     #直接通过package名vim编辑文件而无需指定文件路径
rosed beginner_tutorials package.xml    

# roswtf错误排查
ps -ef | grep -i rosmaster   #确认roscore运行
roscd rosmaster
roswtf    #检查系统错误
    Loaded plugin tf.tfwtf
    Package: rosmaster
    ================================================================================
    Static checks summary:
    No errors or warnings
    ================================================================================
    Beginning tests of your ROS graph. These may take a while...
    analyzing graph...
    ... done analyzing graph
    running graph rules...
    ... done running graph rules
    Online checks summary:
    Found 1 warning(s).
    Warnings are things that may be just fine, but are sometimes at fault
    WARNING The following node subscriptions are unconnected:
     * /turtlesim:
       * /turtle1/cmd_vel

 

今天我们学习了ROS的基本概念,安装并通过创建和运行程序包了解了Nodes节点、Topics/Msg、Service服务/参数服务器以及几个常见的工具,下一篇将讲解如何自己创建Message消息、ROS服务及Client、仿真回放,以及在机器人项目中的应用。

 

yan 20.6.14 23:50

 

参考:

en – ROS Wiki

cn – ROS Wiki(有坑,不如英文的准确)

Ubuntu install GIMP and plugns

清华大学开源软件镜像站-ubuntu x86/64

 

欢迎关注下方“非著名资深码农“公众号进行交流~

发表评论

邮箱地址不会被公开。