ROS

ROS: 机器人操作系统(Robot Operating System, ROS)机器人软件框架。

开源社区内的ROS功能包呈指 数级增长, 涉及的应用领域包括轮式机器人、 人形机器人、 工业机器 人、 农业机器人等。

ROS中的功能模块都封装于独立的功能包(Package) 或元功能包(Meta Package)

实验室或者研究机构共同协作来开发机器人软件 。 例如一个拥有室内地图建模领域专家的实验室可能会开发并发布一个先进的地图建模系统; 一个拥有导航方面专家的组织可以使用建模完成的地图进行机器人导航; 另一个专注于机器人视觉的组织可能开发出了一种物体识别的有效方法。

1
2
3
sudo sh -c '. /etc/lsb-release && echo \
"deb http://mirrors.ustc.edu.cn/ros/ubuntu/ $DISTRIB_CODENAME main" \
/etc/apt/sources.list.d/ros-latest.list'

2-架构

架构分层:

  • OS层:基于Linux系统的OS层;

  • 中间层:实现ROS核心通信机制以及众多机器人开发库;

  • 应用层:在ROS Master的管理下保证功能节点的正常运行。

ROS的三种通信机制:

  • 基于发布/订阅的话题通信、

  • 基于客户端/服务器的服务通信

  • 基于RPC的参数服务器

系统实现角度,ROS划分三个层次:计算图、 文件系统和 开源社区。其中涵盖了ROS中的关键概念, 如节点、 消息、 话题、 服务、 功能包、 元功能包等。

通信层:

除了TCPROS/UDPROS的通信机制外, ROS还提供一种进程内的通信方法——Nodelet, 可以为多进程通信提供一种更优化的数据传输方式, 适合对数据传输实时性方面有较高要求的应用。

在通信机制之上, ROS提供了大量机器人开发相关的库, 如数据类型定义、 坐标变换、 运动控制等, 可以提供给应用层使用。

计算图

  • 节点:执行运算任务的进程

  • 消息:支持标准数据类型(整型、 浮点型、 布尔型等) , 也支持嵌套结构和数组(类似于C语言的结构体struct) , 还可以根据需求由开发者自主定义。

  • 话题:消息以一种发布/订阅(Publish/Subscribe) 的方式传递。

    • 一个节点可以针对一个给定的话题(Topic) 发布消息(称为发布者/Talker) ,

    • 也可以关注某个话题并订阅特定类型的数据(称为订阅者/Listener) 。

    • 多对多模式:可以多个Talker,多个Listener

    • 不适合双向的同步传输模式

  • 服务:基于客户端/服务器(Client/Server) 模型, 包含两个部分的通信数据类型: 一个用于请求, 另一个用于应答, 类似于Web服务器。

    • 与话题不同的是, ROS中只允许有一个节点提供指定命名的服务。
  • ROS Master :节点管理器

文件系统

  • Package: 功能包,包含节点,库,配置文件

  • Package Manifest: package.xml 记录功能包基本信息,作者,许可,依赖,编译标志

  • Meta Package:组织多个用于同一目地的功能包,例如ROS导航功能包,包含建模,定位,导航等多个功能包

功能包:

1) config: 放置功能包中的配置文件, 由用户创建, 文件名可以不同。
2) include: 放置功能包中需要用到的头文件。
3) scripts: 放置可以直接运行的Python脚本。
4) src: 放置需要编译的C++代码。
5) launch: 放置功能包中的所有启动文件。
6) msg: 放置功能包自定义的消息类型。
7) srv: 放置功能包自定义的服务类型。
8) action: 放置功能包自定义的动作指令。
9) CMakeLists.txt: 编译器编译功能包的规则。
10) package.xml: 功能包清单, 图2-7是一个典型的功能包清单示例。

命令

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

Meta Package

package.xml

1
2
3
4
5
6
7
8
9
10
11
<package>
<name />

<buildtool_depend>catkin</buildtool_depend>
<run_depend>amcl</run_depend>
<run_depend>carrot_planner</run_depend>
<run_depend>dwa_local_planner</run_depend>
<export>
<metapackage/>
</export>
</package>
1
2
roscd navigation
vim package.xml

社区

通信机制

  • 话题通信机制

    • 节点建立连接后, 可以关掉ROS Master, 节点之间的数据传输并不
      会受到影响, 但是其他节点也无法加入这两个节点之间的网络。
  • 服务通信机制

  • 参数管理机制RPC

    • 不涉及TCP/UDP的通信

话题服务

3-基础

1) src: 代码空间(Source Space) , 开发过程中最常用的文件夹,用来存储所有ROS功能包的源码文件。
2) build: 编译空间(Build Space) , 用来存储工作空间编译过程 中产生的缓存信息和中间文件。
3) devel: 开发空间(Development Space) , 用来放置编译生成的可执行文件。
4) install: 安装空间(Install Space) , 编译成功后, 可以使用make install命令将可执行文件安装到该空间中, 运行该空间中的环境变量脚本, 即可在终端中运行这些可执行文件。 安装空间并不是必需的,很多工作空间中可能并没有该文件夹

1
2
3
4
5
6
7
8
9
$ mkdir -p ~/catkin_ws/src
$ cd ~/catkin_ws/src
$ catkin_init_workspace

$ cd ~/catkin_ws/
$ catkin_make


source devel/setup.bash

创建新包

1
2
3
4
5
6
7
8
9
10
catkin_create_pkg <package_name> [depend1] [depend2] [depend3]

$ cd ~/catkin_ws/src
$ catkin_create_pkg learning_communication std_msgs rospy roscpp

# 创建完成后, 代码空间src中会生成一个learning_communication功能
# 包, 其中已经包含package.xml和CMakeLists.txt文件。
$ cd ~/catkin_ws
$ catkin_make
$ source ~/catkin_ws/devel/setup.bash

小乌龟仿真

键盘控制一只小乌龟在界面中移动,而且会接触到第一个ROS功能包——turtlesim。

该功能包的核心是turtlesim_node节点, 提供一个可视化的乌龟仿真器, 可以实现很多ROS基础功能的测试。

1
2
3
4
5
6
7
8
9
10
11
# 安装依赖
# sudo apt-get install ros-kinetic-turtlesim
sudo apt-get install ros-noetic-turtlesim

# master
$roscore

# rosrun (可视化仿真器界面)
$rosrun turtlesim turtlesim_node
# rosrun 新终端, 运行键盘控制的节点
$rosrun turtlesim turtle_teleop_key

Publisher/Subscriber

Server/Client

多机器通信

master_URI=ip:11311

4-组件

  • launch文件

  • TF坐标转换

  • Qt工具箱

  • rviz三维可视化平台

  • gazebo仿真环境

  • rosbag数据记录与回放

launch启动文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<launch>
<node pkg="package-name" type="executable-name" name="node-name" />


<param name="output_frame" value="odom"/>
<rosparam file="$(find 2dnav_pr2)/config/costmap_common_params.yaml"
command="load" ns="local_cos" />


<arg name="arg-name" default= "arg-value"/>
<param name="foo" value="$(arg arg-name)" />
<node name="node" pkg="package" type="type " args="$(arg arg-name)" />

<!--# 重映射机制-->
<remap from="turtlebot/cmd_wel" to="/cmd_wel" />

</launch>

嵌套使用

1
<include file="$(dirname)/other.launch" />

TF工具

tf_monitor

1
2
$tf_monitor
$tf_monitor <source_target> <target_target>

tf_echo: 查看指定坐标系之间的变换关系

1
$tf_echo  <source_frame>   <target_frame>

static_transform_publisher

  • 发布两个坐标系之间的静态左边变换

view_frames

  • 可视化调试工具,生成pdf

  • 1
    2
    3
    4
    $rosrun tf view_frames

    # 查看TF树信息
    $evince frames.pdf

QT工具

Rviz可视化

Gazebo仿真环境

1
2
3
4
5
6
7
8
9
10
11
# Install
sudo apt-get install ros-kinetic-gazebo-ros-pkgs \
ros-kinetic-gazebo-ros-control

# start ros gazebo
roscore
rosrun gazebo_ros gazebo

rostopic list # 查看gazebo的topic

rosservice list # 查看gazebo的服务

模型的加载需要连接国外网站, 为了保证模型顺利加载, 可以提前将模型文件下载并放置到本地路径~/.gazebo/models下, 模型文件的下载地址:

GitHub - osrf/gazebo_models: Gazebo database of SDF models. This is a predecessor to https://app.gazebosim.org

rosbag数据记录和回放

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 首先启动键盘控制乌龟例程所需的所有节点:
$ roscore
$ rosrun turtlesim turtlesim_node
$ rosrun turtlesim turtle_teleop_key
# 移动操作一会

$ rostopic list -v

# 抓取日志
$ mkdir ~/bagfiles
$ cd ~/bagfiles
$ rosbag record -a

回放数据
$ rosbag info <your bagfile>
$ rosbag play <your bagfile>

5-ROBOT平台搭建

什么是机器人? 一个完整的机器人系统包含哪些部分?

如何构建一个真实的机器人系统? 学习完本章内容后, 你就会有答案了

控制系统

嵌入式系统的选择有很多, 比如常用的Raspberry Pi、 TK1、RK3288、 Odroid、 Arduino等

Raspberry PI控制系统

GitHub - dajianli/mrobot: mrobot ros package

1
2
# QT 图像显示工具--订阅图像topic
rqt_image_view

mrobot_teleop

6-ROBOT建模,仿真

大纲:

  • URDF

  • xacro优化模型

  • <gazebo> 标签,传感器,转动结构等仿真

  • rviz + ArbotiX 仿真环境,机器人控制等仿真

  • ros_control 在Gazebo物理仿真创建世界,仿真

6.1 URDF语法

(Unified Robot Description Format, 统一机器人描述格式)

link(刚体)

<link>标签用于描述机器人某个刚体部分的外观和物理属性,
包括尺寸(size) 、 颜色(color) 、 形状(shape) 、 惯性矩阵(inertial matrix) 、 碰撞参数(collision properties)

1
2
3
4
5
<link>
<inertial>惯性</inertail>
<visual></visual>
<collision>碰撞属性</collision>
</link>

joint(关节)

描述机器人关节的运动学和动力学属性, 包括关节运动的位置和速度限制。

关节类型 描述
continuous 旋转关节,可以围绕单轴无限旋转
revolute 旋转关节,类似于continuous,但是有旋转的角度极限
prismatic 滑动关节,沿某一轴线移动的关节,带有位置极限
planar 平面关节,允许在平面正交方向上平移或者旋转
floating 浮动关节,允许进行平移、旋转运动
fixed 固定关节,不允许运动的特殊关节

与人的关节一样, 机器人关节的主要作用是连接两个刚体link, 这两个link分别称为parent link和child link,

1
2
3
4
5
6
7
8
<joint name="<name of the joint>">
<parent link="parent_link"/>
<child link="child_link"/>
<calibration .... /> 位置
<dynamics damping ..../> 物理属性
<limit effort .... /> 极限值
....
</joint>

其中必须指定joint的parent link和child link, 还可以设置关节的其他属性。
·: 关节的参考位置, 用来校准关节的绝对位置。
·: 用于描述关节的物理属性, 例如阻尼值、 物理静摩擦力等, 经常在动力学仿真中用到。
·: 用于描述运动的一些极限值, 包括关节运动的上下限位置、 速度限制、 力矩限制等。
·: 用于描述该关节与已有关节的关系。
·: 用于描述安全控制器参数。

robot

最顶层标签, 标签都必须包含在标签内。

gazebo

1
2
3
<gazebo reference="link_1">
<material>Gazebo/Black</material>
</gazebo>

6.2 创建URDF模型

1
$catkin_create_pkg  mrobot_description urdf xacro

mrobot_description功能包含urdf,meshes,launch和config文件夹

  • urdf: 存放URDF或 xacro文件

  • meshes: 模型渲染文件

  • launch: 启动文件

  • config: rviz配置文件

MRobot底盘模型有7个link和6个joint。7个link包含1个底盘,2个电机,2个驱动轮,2个万向轮‘;6个joint负责连接各个组件到底盘上;

模型文件mrobot_description/urdf/mrobot_chassis.urdf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?xml version="1.0" ?>
<robot name="mrobot_chassis">
<link name="base_link" >
<visual>
</visual>
</link>
<joint>
<origin />
<parent link="" >
<child link="" >
</joint>
<!-- Left motor -->
<link name="left_motor" >
<visual>
<origin xyz="" rpy="">

</visual>
</link>
<joint>
</joint>
<!-- Left wheel -->
<!-- right motor -->

</robot>

检查URDF模型整体结构(生成pdf文件)

1
2
3
$apt install liburdfdom-tools

$check_urdf mrobot_chassis.urdf
1
$urdf_to_graphiz mrobot_chassis.urdf

模型解析

1
2
3
4
5
6
7
<!-- motor wheel joint  (type=?)-->
<joint name="left_wheel_joint" type="continuous">
<origin xyz="0 0.0485 0" rpy="0 0 0" /> <!--起点-->
<parent link="left_motor" />
<child link="left_wheel_link" />
<axis xyz="0 1 0" /> <!--只围绕y轴旋转-->
</joint>

viza显示模型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<launch>
<param name="robot_description"
textfile="$(find mrobot_description)/urdf/mrobot_chassis.urdf" />
<!-- 设置GUI参数,显示关节控制插件 -->
<param name="use_gui" value="true" />
<!-- 运行joint_state_publisher node, 发布robot的关节状态 -->
<param name="joint_state_publisher" pkg="joint_state_publisher"
type="joint_state_publisher" />
<!-- 运行joint_state_publisher node, 发布TF -->
<param name="robot_state_publisher" pkg="robot_state_publisher"
type= "robot_state_publisher" />
<!-- 运行rviz可视化界面-->
<node name="rviz" pkg="rviz" type="rviz" args="-d $(find
mrobot_description/config/morobot_urdf.rviz"
required="true" />
<param/>
</launch>

#

6.3 模型xacro优化

xacro

1
2
3
4
5
# 将xacro文件转换成URDF文件
### $rosrun xacro xacro.py mrobot.urdf.xacro > mrobot.urdf (Fail)
$rosrun xacro xacro mrobot.urdf.xacro > mrobot.urdf

$

直接调用xacro文件解析器

1
2
3
<arg name="model" default="$(find xacro)/xacro --inorder 
'$(find mrobot_description)/urdf/mrobot.' >'
<param name="robot_description" command="$(arg model)" />
  • 注意:xacro定义的组件,使用时需要加xacro命名空间(ROS2)

6.4 传感器添加

  • 注意:name=“ ”不要有空格

6.5 Arbox+rviz

ArbotiX是一款控制电机、 舵机的控制板, 并提供相应的ROS功能包, 但是这个功能包的功能不仅可以驱动真实的ArbotiX控制板, 它还提供一个差速控制器, 通过接收速度控制指令更新机器人的joint状态,从而帮助我们实现机器人在rviz中的运动。

1
2
apt install ros-noetic-arbotix
apt install ros-noetic-arbotix-*

配置arbotix

  • 创建launch文件

  • 创建配置文件(控制器)

  • 运行仿真

    • roslaunch mrobot_description arbotix_mrobot_with_kinect.launch
  • 话题cmd_vel (tostopic list)

  • 控制运行(键盘)

    • roslaunch mrobot_teleop mrobot_teleop.launch

此时rviz中设置的“Fixed Frame”是odom, 也就是机器人的里程计坐 标系。 这是一个全局坐标系, 通过里程计记录机器人当前的运动位姿,从而更新rviz中的模型状态。

rviz+ArbotiX可以构建一个较为简单的运动仿真器, 在本书后续内 容中还会多次使用这个仿真器实现导航等功能。 除此之外, ROS还集成 了更为强大的物理仿真平台——Gazebo, 可以做到类似真实机器人的高度仿真状态, 包括物理属性、 传感器数据、 环境模型等

mrobot_teleop.launch

  • 控制模块

6.6 ros_control

针对不同类型的机器人(移动机器人、 机械臂等),ros_control可以提供多种类型的控制器(controller) , 但是这些控制器的接口各不相同。 为了提高代码的复用率, ros_control还提供一个硬件抽象层, 负责机器人硬件资源的管理, 而controller从抽象层请求资源即可, 并不直接接触硬件。

1 框架

(1) 控制器管理器(Controller Manager)

提供一种通用的接口来管理不同的控制器。 控制器管理器的输入就是ROS上层应用功能包的输出。

(2) 控制器(Controller)

控制器可以完成每个joint的控制, 读取硬件资源接口中的状态, 再发布控制命令, 并且提供PID控制器。

(3) 硬件资源(Hardware Resource)
为上下两层提供硬件资源的接口。

(4) 机器人硬件抽象(RobotHW)

机器人硬件抽象和硬件资源直接打交道, 通过write和read方法完成硬件操作, 这一层也包含关节约束、 力矩转换、 状态转换等功能。

(5) 真实机器人(Real Robot)

真实机器人上也需要有自己的嵌入式控制器, 将接收到的命令反映到执行器上, 比如接收到旋转90度的命令后, 就需要让执行器快速、 稳定地旋转90度。

2 控制器

目前ROS中的ros_controllers功能包提供了以下控制器(见图6-19) 。

  • effort_controllers

  • joint_effort_controller

  • joint_position_controller

  • joint_velocity_controller

  • joint_state_controller

  • joint_state_controller

  • position_controllers

  • joint_position_controller

  • velocity_controllers

  • joint_velocity_controller

当然, 我们也可以根据自己的需求创建需要的控制器, 然后通过控 制器管理器来管理自己创建的控制器。 创建控制器的具体方法可以参考 wiki:controller_interface

3 硬件接口

硬件接口是控制器和RobotHW沟通的接口, 基本与控制器的种类相互对应(见图6-20) , 同样可以自己创建需要的接口, 具体实现方法可以参考wiki: wiki-hardware_interface

4 传动系统

传动系统(Transmission) 可以将机器人的关节指令转换成执行器的控制信号。 机器人每个需要运动的关节都需要配置相应的传动系统。可以在机器人的URDF模型文件中按照以下方法配置:

1
2
3
4
5
6
7
8
9
10
<transmission name="simple_trans">
<type>transmission_interface/SimpleTransmission</type>
        <joint name="foo_joint">
            <hardwareInterface>EffortJointInterface</hardwareInterface>
        </joint>
    <actuator name="foo_motor">
        <mechanicalReduction>50</mechanicalReduction>
        <hardwareInterface>EffortJointInterface</hardwareInterface>
    </actuator>
</transmission>

5 关节约束

关节约束(Joint Limits) 是硬件抽象层中的一部分, 维护一个关节约束的数据结构,

  • 这些约束数据可以从机器人的URDF文件中加载,

  • 也可以在ROS的参数服务器上加载(需要先用YAML配置文件导入ROS参数服务器) ,

  • 不仅包含关节速度、 位置、 加速度、 加加速度、 力矩等方面的约束,

  • 还包含起安全作用的位置软限位、 速度边界(k_v) 和位置边界(k_p) 等

URDF

1
2
3
4
5
6
7
8
<joint name="$foo_joint" type="revolute">
<!-- other joint description elements -->
<!-- Joint limits -->
<limit lower="0.0" upper="1.0" effort="10.0" xxx="5.0" />
<!-- Soft limits -->
<safety_controller k_position="100" k_velocity="10"
soft_lower_limit="0.1" soft_upper_limit="0.9" />
</joint>

YAML参数服务器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
joint_limits:
foo_joint:
has_position_limits: true
min_position: 0.0
max_position: 1.0
has_velocity_limits: true
max_velocity: 2.0
has_acceleration_limits: true
max_acceleration: 5.0
has_jerk_limits: true
max_jerk: 100.0
has_effort_limits: truemax_effort: 5.0
bar_joint:
has_position_limits: false # Continuous joint
has_velocity_limits: true
max_velocity: 4.0

6 控制器管理器

controller_manager提供了一种多控制器控制的机制, 可以实现控制器的加载、 开始运行、 停止运行、 卸载等多种操作。

6.1 命令行工具

管理

1
2
3
4
5
6
7
$rosrun controller_manager controller_manager <command> <controller_name>
支持的<command>如下:
·load: 加载一个控制器。·unload: 卸载一个控制器。
·start: 启动控制器。
·stop: 停止控制器。
·spawn: 加载并启动一个控制器。
·kill: 停止并卸载一个控制器

查看命令

1
2
3
4
5
6
$rosrun controller_manager controller_manager <command>
支持的<command>如下:
·list: 根据执行顺序列出所有控制器, 并显示每个控制器的状态。
·list-types: 显示所有控制器的类型。
·reload-libraries: 以插件的形式重载所有控制器的库, 不需要重新启动, 方便对控制器的开发和测试。
·reload-libraries--restore: 以插件的形式重载所有控制器的库, 并恢复到初始状态。

spawner命令一次控制多个控制器:

1
2
3
4
5
6
7
$rosrun controller_manager spawner [--stopped] name1 name2 name3

上面的命令可以自动加载、 启动控制器, 如果加上--stopped参数,那么控制器则只会被加载,
但是并不会开始运行。

如果想要停止一系列控制器, 但是不需要卸载, 可以使用如下命令:
$rosrun controller_manager unspawner name1 name2 name3

6.2 launch工具

在launch文件中, 同样可以通过运行controller_manager命令, 加载 和启动一系列控制器:

1
2
3
4
<launch>  
<node pkg="controller_manager" type="spawner"
            args="controller_name1 controller_name2" />
</launch>

以上launch文件会加载并启动controller, 如果只需加载不必启动,可以使用以下配置:

1
2
3
4
<launch>  
<node pkg="controller_manager" type="spawner"
args="--stopped controller_name1 controller_name" />
</launch>

6.3.可视化工具rqt_controller_manager

controller_manager还提供了可视化工具rqt_controller_manager, 安装成功后, 直接使用以下命令即可打开界面:

1
$rosrun rqt_controller_manager rqt_controller_manager

6.7 Gazebo仿真

使用xacro设计的机器人URDF模型已经描述了机器人的外观特征和物理特性, 虽然已经具备在Gazebo中仿真的基本条件, 但是, 由于没有 在模型中加入Gazebo的相关属性, 还是无法让模型在Gazebo仿真环境中动起来。 那么如何开始仿真呢?

首先我们需要确保每个link的元素已经进行了合理的设置, 然后要为每个必要的设置标签。 标签是URDF模型中描述gazebo仿真时所需要的扩展属性。

1
2
3
4
5
6
7
8
9
cd src
$catkin_create_pkg robot_package roscpp rospy std_msgs sensor_msgs
gazebo_ros gazebo_plugins gazebo_ros_control

cd ../
$catkin_make


$roslaunch mrobot_gazebo view_mrobot_gazebo.launch

control

1
2
3
4
$catkin_create_pkg mrobot_teleop geometry_msgs  roscpp  rospy
cd ../
$catkin_make
$roslaunch mrobot_teleop mrobot_teleop.launch
1
2
3
4
5
6
ERR: /usr/bin/env: ‘python’: No such file or directory

1. 安装依赖
apt install python3-rosinstall
apt install python-setuptools
2. ln软连接

7-机器视觉

8-机器语音

9 SLAM与自主导航

10-Movelt机械臂

11-ROS与机器学习

12-ROS进阶

13-ROS机器人实例

14-ROS2