Simon Shi的小站

人工智能,机器学习, 强化学习,大模型,自动驾驶

0%

ROS Robot实战(gazebo)

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

  • $rosrun tf view_frames
    
    # 查看TF树信息
    $evince frames.pdf
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19

    #### QT工具

    #### Rviz可视化

    #### Gazebo仿真环境

    ```shell
    # 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平台搭建

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

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

  • 如何驱动USB摄像头和RGB-D摄像头,

  • 通过ROS提供的工具将这些图像数据显示出来。

控制系统

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

Raspberry PI控制系统

Ubuntu 20.04.5 LTS (Focal Fossa)

GitHub - dajianli/mrobot: mrobot ros package

1

安装ROS

1
2
3
4
5
6
7
sudo apt-get install ros-kinetic-ros-base

# 安装rosdep工具。
$ sudo rosdep init
$rosdep update

echo "source /opt/ros/noetic/setup.bash" >> ~/.bashrc
1
2
# QT 图像显示工具--订阅图像topic
rqt_image_view

mrobot_teleop

1
2
3
$roscore (PC)
$roslaunch mrobot_bringup mrobot.launch (Raspberry Pi)
$rosrun mrobot_teleop mrobot_teleop.py (PC)

5.6 摄像头

1
2
3
$ sudo apt-get install ros-kinetic-usb-cam
# 驱动摄像头
$roslaunch usb_cam usb_cam-test.launch

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>

img

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仿真

6.7.1 添加Gazebo属性

link ADD

1
2
3
<gazebo reference="wheel_${lr}_link">
<material>Gazebo/Black</material>
</gazebo>

传动装置添加

为了使用ROS控制器驱动机器人, 需要在模型中加入 元素, 将传动装置与joint绑定:

1
2
3
4
5
6
7
8
9
<transmission name="wheel_${lr}_joint_trans">
<type>transmission_interface/SimpleTransmission</type> <!--传动装置类型-->
<joint name="base_to_wheel_${lr}_joint" /> <!--要绑定驱动器的joint-->
<actuator name="wheel_${lr}_joint_motor">
<!-- 硬件接口的类型, 这里使用的是速度控制接口 -->
<hardwareInterface>VelocityJointInterface</hardwareInterface>
<mechanicalReduction>1</mechanicalReduction>
</actuator>
</transmission>

控制器插件-(使静态模型,动起来)

1
2
3
4
5
6
7
8
<!-- ( 1) 为<robot>元素添加插件 -->
<gazebo>
<plugin name="unique_name" filename="plugin_name.so">
... plugin parameters ...
</plugin>
</gazebo>
<!--至于Gazebo目前支持的插件种类, 可以查看ROS默认安装路径下的
/opt/ros/kinetic/lib文件夹, 所有插件都是以libgazeboXXX.so的形式命名的。-->

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

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

6.7.2 在Gazebo中显示机器人模型
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<launch>
<!-- 设置launch文件的参数 -->
<arg name="world_name" value="$(find mrobot_gazebo)/worlds/playground.world"/>
<arg name="paused" default="false"/>
<arg name="use_sim_time" default="true"/>
<arg name="gui" default="true"/>
<arg name="headless" default="false"/>
<arg name="debug" default="false"/>

<!-- 运行Gazebo仿真环境 -->
<include file="$(find gazebo_ros)/launch/empty_world.launch">
<arg name="world_name" value="$(arg world_name)" />
<arg name="debug" value="$(arg debug)" />
<arg name="gui" value="$(arg gui)" />
<arg name="paused" value="$(arg paused)"/>
<arg name="use_sim_time" value="$(arg use_sim_time)"/>
<arg name="headless" value="$(arg headless)"/>
</include>

<!-- 加载机器人模型描述参数 -->
<param name="robot_description" command="$(find xacro)/xacro --inorder
'$(find mrobot_gazebo) "/>

<!-- 运行joint_state_publisher节点, 发布机器人的关节状态 -->
<node name="joint_state_publisher" pkg="joint_state_publisher"
type="joint_state_publisher" >

<!-- 运行robot_state_publisher节点, 发布TF -->
<node name="robot_state_publisher" pkg="robot_state_publisher"
type="robot_state_publisher" />"
<param name="publish_frequency" type="double" value="50.0" />
</node>

<!-- 在gazebo中加载机器人模型-->
<node name="urdf_spawner" pkg="gazebo_ros" type="spawn_model"
respawn= "false" output="screen"
args="-urdf -model mrobot -param robot_description" />
</launch>

launch文件的2个作用:

1) 启动机器人的状态发布节点, 同时加载带有Gazebo属性的机器人URDF模型。
2) 启动Gazebo, 并且将机器人模型加载到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

6.7.3 control Gazebo
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软连接

6.7.4 摄像头仿真
1
2
3
4
5
6
7
$roslaunch mrobot_gazebo view_mrobot_with_camera_gazebo.launch

sudo apt-get install ros-noetic-rqt-image-view

$rqt_image_view

# 仿真摄像头发布的图像话题/camera/image_raw

6.7.5 Kinect 方法
1
2
3
$roslaunch mrobot_gazebo view_mrobot_with_kinect_gazebo.launch

$rosrun rviz rviz

6.7.6 激光雷达仿真
1
2
3
4
5
6
7
$roslaunch mrobot_gazebo view_mrobot_with_laser_gazebo.launch


$rosrun rviz rviz
# 在rviz中设置“Fixed Frame”为“base_footprint”, 然后添加一个
# LaserScan类型的插件, 修改插件订阅的话题为“/scan”, 就可以看到界面
# 中的激光数据了(见图6-33)

6.8 小结

  • URDF文件创建机器人模型

  • xacro优化模型

  • riviz+arbotiX或Gazebo仿真环境

7-机器视觉

ROS中的功能包实现以下常用的机器视觉应用。

  • 摄像机标定:camera_calibrationg功能包实现单目和双目摄像头标定。

  • 基于opencv的人脸识别和物体跟踪:ROS的cv_bridge功能包为两者提供了接口,赋予ROS应用强大的图形处理能力

  • 二维码识别:ar_track_alvar功能包允许我们创建许多二维码标签,可以使用摄像头或kinect实现二维码的识别与定位。

  • 物体识别 ORK是ROS的物体识别框架,提供了多种物体识别的方法, 需要将已知的物体模型进行训练,通过模式匹配的方式识别三维物体的位置

7.1 图像数据

  • 二维图像数据

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    $roslaunch usb_cam usb_camera-test.launch

    $rostopic info /usb_cam/image_raw

    $rosmsg shwo sensor_msgs/Image
    - header
    - height
    - width
    - encoding
    - is_bigendian
    - step 一行图像数据的字节数量, 作为数据的步长参数, 这里使
        用的摄像头为width×3=1280×3=3840字节。
    - data 存储图像数据的数组, 大小为step×height字节,
    根据该公式可以算出这里使用的摄像头产生一帧图像的数据大小是:
    3840×720=2764800字节, 即2.7648MB

    一帧720×1280分辨率的图像数据量就是2.76MB, 如果按照30帧/秒的帧率计算,
    那么一秒钟摄像头产生的数据量就高达82.944MB

    压缩后的数据:

    1
    2
    3
    4
    ROS也设计了压缩图像的消息类型——sensor_msgs/CompressedImage
    - header
    - data
    - format
  • 三维点云数据

    • kinect数据显示中,rviz订阅camera/depth_registered/points话题后,显示的三维点云数据,查看命令:

    • $rostopic info /camera/depth_registered/points
      
      $rosmsg show sensor_msgs/PointClound2
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
        
      - <img src="ROS_dev/2024-07-15-19-24-48-image.png" title="" alt="" width="209">

      ### 7.2 摄像机标定

      ROS官方提供了用于双目和 单目摄像头标定的功能包——camera_calibration。

      ```shell
      apt install ros-xxx-camera-calibration

      # 标定靶 robot_vision/doc/checkerboard.pdf

2.2 启动标定程序

1
2
3
4
5
6
# usb摄像头启动
$roslaunch robot_vision usb_cam.launch

# 启动标定程序
$rosrun camera_calibration cameracalibrator.py --size 8x6 --square 0.024
iamge:/usb_camera

2.3 标定Camera

不断在视野中移动标定靶, 直到“CALIBRATE”按钮变色, 表示标定程序的参数采集完成。 点击“CALIBRATE”按钮, 标定程序开始自动计算摄像头的标定参数,

这个过程需要等待一段时间, 界面可能会变成灰色无响应状态, 注意千万不要关闭。

  • 点击界面中的“SAVE”按钮, 标定参数将被保存到默认的文件夹下, 并在终端中看到该路径,

  • commit 按钮:提交数据并退出程序。 然后打开/tmp文件 夹, 就可以看到标定结果的压缩文件calibrationdata.tar.gz; 解压该文件 后的内容如图7-10所示, 从中可以找到ost.yaml命名的标定结果文件, 将该文件复制出来, 重新命名就可以使用了

2.4 标定Kinect

1
2
3
4
5
$roslaunch robot_vision freenect.launch
$rosrun camera_calibration cameracalibrator.py image:/camera/rgb/image_raw
camera:=/camera/rgb
$rosrun camera_calibration cameracalibrator.py image:=/camera/ir/image_raw
camera:=/camera/ir

2.5 加载标定参数配置文件

标定摄像头生成的配置文件是YAML格式的, 可以在启动摄像头的 launch文件中进行加载, 例如加载摄像头标定文件的robot_vision/launch/usb_cam_with_calibration.launch:

1
2
3
4
5
6
7
8
9
10
11
12
<launch>
<node name="usb_cam" pkg="usb_cam" type="usb_cam_node" output="screen" >
<param name="video_device" value="/dev/video0" />
<param name="iamge_width" value="1280" />
<param name="iamge_height" value="720" />
<param name="pixel_format" value="yuyv" />
<param name="camera_frame_id" value="usb_cam" />
<param name="io_method" value="mmap" />
<param name="camera_info_url" type="string" value=
"file://$(find robot_vision)/camera_calibration.yaml" />
</node>
</launch>

Kinect标定文件的加载方法相同, 分别设置RGB摄像头和红外深度 摄像头的标定文件即可, 详见
robot_vision/launch/freenect_with_calibration.launch:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<launch>
<!-- Launch the freenect driver -->
<include file="$(find freenect_launch)/launch/freenect.launch">
<arg name="publish_tf" value="false" />

<!-- use device registration -->
<arg name="depth_registration" value="true" />

<arg name="rgb_processing" value="true" />
<arg name="ir_processing" value="false" />
<arg name="depth_processing" value="false" />
<arg name="depth_registered_processing" value="true" />
<arg name="disparity_processing" value="false" />
<arg name="disparity_registered_processing" value="false" />
<arg name="sw_registered_processing" value="false" />
<arg name="hw_registered_processing" value="true" />

<arg name="rgb_camera_info_url"
        value="file://$(find robot_vision)/kinect_rgb_calibration.yaml" />
    <arg name="depth_camera_info_url"
        value="file://$(find robot_vision)/kinect_depth_calibration.yaml" />
</include>
</launch>lse" />

比如运行的警告,分别将两个标定文件中的camera_name参数修改 为“rgb_A70774707163327A”、 “depth_A70774707163327A”即可。

7.3 opencv库

1
2
3
4
5
sudo apt-get install ros-kinetic-vision-opencv libopencv-dev python-opencv

$roslaunch robot_vision usb_cam.launch
$rosrun robot_vision cv_bridge_test.py
$rqt_image_view

7.4 人脸识别

1
2
$roslaunch robot_vision usb_cam.launch
$roslaunch robot_vision face_detector.launch

7.5 物体跟踪

1
2
$roslaunch robot_vision usb_cam.launch
$roslaunch robot_vision motion_detector.launch

7.6 二维码识别

在ROS Noetic中安装ar_track_alvar包并不是像其他一些ROS版本那样直接通过包管理器简单安装,因为Noetic版本中并没有预编译好的ar_track_alvar包。但是,你仍然可以通过从源代码编译的方式来安装它。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ sudo apt-get install ros-kinetic-ar-track-alvar

cd ~/catkin_ws/src
git clone https://github.com/machinekoder/ar_track_alvar.git -b noetic-devel
cd ../
$catkin_make

# create
$rosrun ar_track_alvar createMarker AR_ID


$rosrun ar_track_alvar createMarker 0


$ roscd robot_vision/config
$ rosrun ar_track_alvar createMarker -s 5 0
$ rosrun ar_track_alvar createMarker -s 5 1
$ rosrun ar_track_alvar createMarker -s 5 2

识别

1
2
$roslaunch robot_vision usb_cam_with_calibration.launch
$roslaunch robot_vision ar_track_camera.launch

7.7 物体识别 ORK

ROS中集成了一个强大的物体识别框架——Object Recognition Kitchen(ORK) , 其中包含了多种三维物体识别的方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$sudo apt-get install ros-indigo-object-recognition-kitchen-*

$ sudo apt-get install meshlab
$ sudo apt-get install libosmesa6-dev
$ sudo apt-get install python-pyside.qtcore
$ sudo apt-get install python-pyside.qtgui

$ mkdir ork_ws && cd ork_ws
$ wstool init src https://raw.github.com/wg-perception/object_recognition_core/master/doc/source/
然后下载所有需要的功能包源码:
$ cd src && wstool update -j8
$ cd .. && rosdep install --from-paths src -i –y

$ echo "export ~/ork_ws/devel/setup.bash" >> ~/.bashrc
$ source ~/.bashrc

7.8 小节

8-机器语音

  • 英文语音识别: 基于创建的语音库, ROS中的pocketsphinx功能包可以实现机器人的语音识别功能。

  • 英文语音播放: ROS中的元功能包audio-common提供了文本转语音的功能包sound_play, 可以实现机器人的英文语音播放功能。

  • 智能语音应答: 结合人工智能标记语言AIML, 机器人可以从语料库中智能匹配交流的输出语句, 从而实现智能化交流应用。

  • 中文语音的识别与合成: 在ROS中集成科大讯飞的语音处理SDK, 让机器人更懂中文

8.1.1 pocketsphinx 功能包

9 SLAM与自主导航

使用ROS实现机器人的SLAM和自主导航等功能是非常方便的, 因为有较多现成的功能包可供开发者使用, 如gmapping、 hector_slam、 cartographer、 rgbdslam、 ORB_SLAM、 move_base、 amcl等。

9.2 准备工作

1) 导航功能包对差分、 轮式机器人的效果好, 并且假设机器人可直接使用速度指令进行控制, 速度指令的定义如图9-5所示。

  • linear: 机器人在xyz三轴方向上的线速度, 单位是m/s。

  • angular: 机器人在xyz三轴方向上的角速度, 单位是rad/s。

2) 导航功能包要求机器人必须安装激光雷达等测距设备, 可以获取环境深度信息。
3) 导航功能包以正方形和圆形的机器人为模板进行开发, 对于其他外形的机器人, 虽然可以正常使用, 但是效果可能不佳。

9.2.1 传感器信息,

1 深度信息

ROS在sensor_msgs包中定义了专用数据结构——

LaserScan, 用于存储激光消息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
root@cdce9f3334ed:/data/mrobot_ws# rosmsg show sensor_msgs/LaserScan
std_msgs/Header header
uint32 seq
time stamp
string frame_id
float32 angle_min
float32 angle_max
float32 angle_increment
float32 time_increment
float32 scan_time
float32 range_min
float32 range_max
float32[] ranges
float32[] intensities

Kinect等RGB-D摄像头,(三维点云数据)

那么将三维数据降维到二维数据 的方法也很简单, 即把大量数据拦腰斩断, 只抽取其中的一行数据, 重新封装为LaserScan消息, 就可以获取到需要的二维激光雷达信息。 这么做虽然损失了大量有效数据, 但是刚好可以满足2D SLAM的需求。

ROS中也提供了相应的功能包——
depthimage_to_laserscan, 可以在launch文件中使用如下方法调用:

1
2
3
4
5
6
7
8
<!-- 运行depthimage_to_laserscan节点, 将点云深度数据转换成激光数据 -->
<node pkg="depthimage_to_laserscan" type="depthimage_to_laserscan"
name="depthimage_to_laserscan" >
<remap from="image" to="/camera/depth/image_raw" />
<remap from="camera_info" to="/camera/depth/camera_info" />
<remap from="scan" to="/scan" />
<param name="output_frame_id" value="/camera_link" />
</node>
  1. 里程计信息

导航功能包要求机器人能够发布里程计nav_msgs/Odometry消息。包含机器人在自由空间中的位置和速度估算值。

  • pose: 机器人当前位置坐标, 包括机器人的x、 y、 z三轴位置与方向参数, 以及用于校正误差的协方差矩阵。

  • twist: 机器人当前的运动状态, 包括x、 y、 z三轴的线速度与角速度, 以及用于校正误差的协方差矩阵

上述数据结构中, 除速度与位置的关键信息外, 还包含用于滤波算法的协方差矩阵。 在精度要求不高的机器人系统中, 可以使用默认的协 方差矩阵; 而在精度要求较高的系统中, 需要先对机器人精确建模后, 再通过仿真、 实验等方法确定该矩阵的具体数值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
root@cdce9f3334ed:/data/mrobot_ws# rosmsg show nav_msgs/Odometry
std_msgs/Header header
uint32 seq
time stamp
string frame_id
string child_frame_id
geometry_msgs/PoseWithCovariance pose
geometry_msgs/Pose pose
geometry_msgs/Point position
float64 x
float64 y
float64 z
geometry_msgs/Quaternion orientation
float64 x
float64 y
float64 z
float64 w
float64[36] covariance
geometry_msgs/TwistWithCovariance twist
geometry_msgs/Twist twist
geometry_msgs/Vector3 linear
float64 x
float64 y
float64 z
geometry_msgs/Vector3 angular
float64 x
float64 y
float64 z
float64[36] covariance
9.2.2 仿真平台

1、创建仿真环境

  • 自定义环境,Fail,todo

  • 教材资料worlds OK

2、加载机器人

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 rostopic list
/clock
/cmd_vel
/gazebo/link_states
/gazebo/model_states
/gazebo/parameter_descriptions
/gazebo/parameter_updates
/gazebo/performance_metrics
/gazebo/set_link_state
/gazebo/set_model_state
/joint_states
/odom
/rosout
/rosout_agg
/scan
/tf
/tf_static
/usb_cam/camera_info
/usb_cam/image_raw
9.2.3 真实Robot

todo

9.3 gamapping

gmapping功能包集成了Rao-Blackwellized粒子滤波算法, 为开发者隐去了复杂的内部实现。 图9-14所示的是gmapping功能包的总体框架。

1
2
# $ sudo apt-get install ros-kinetic-gmapping
$ sudo apt-get install ros-noetic-gmapping
发布的话题
  1. /map
    这个话题发布的是地图消息,类型为nav_msgs/OccupancyGrid。它包含了环境的地图信息,包括栅格的大小、分辨率、位置、方向以及每个栅格的占用概率。

  2. /map_metadata(在早期版本中):
    有时gmapping会单独发布地图元数据,如地图的原点和分辨率,但这些信息现在通常包含在/map消息中。

  3. /map_update
    当地图发生更新时,gmapping会发布nav_msgs/OccupancyGrid类型的消息到/map_update话题,只包含地图改变的部分,而不是整个地图。

  4. /pose
    发布机器人在地图中的估计位置,类型为geometry_msgs/PoseWithCovarianceStamped

  5. /initialpose
    这个话题虽然不是由gmapping发布,但通常与gmapping配合使用。它允许用户手动设置机器人在地图中的初始位置和姿态,类型为geometry_msgs/PoseWithCovarianceStamped

订阅的话题
  1. /scangmapping订阅激光雷达传感器的扫描数据,类型为sensor_msgs/LaserScan,用于构建和更新地图。

  2. /odom
    订阅来自里程计或者其他定位系统的位姿数据,类型为nav_msgs/Odometry,用于辅助定位和地图构建。

  3. /tf
    订阅TF(Transform)树,类型为tf/tfMessage,用于处理坐标系变换,尤其是在多机器人或多传感器系统中。

提供的服务
  1. /global_mapgmapping提供了一个名为/global_map的服务,类型为nav_msgs/GetMap,用于请求当前的地图信息。客户端可以通过调用此服务获取完整的地图数据。

  2. /set_initial_pose
    有时候gmapping也提供一个服务来设置初始位姿,尽管这通常通过发布到/initialpose话题来完成。

1
2
3
4
5
6
7
8
9
10
# 模拟环境
$roslaunch mrobot_gazebo mrobot_laser_nav_gazebo.launch
# 建图可视化
$roslaunch mrobot_navigation gmapping_demo.launch
# 动起来
$roslaunch mrobot_teleop mrobot_teleop.launch
# 保存地图
$rosrun map_server map_saver
- map.pgm
- map.ymal

1
2
3
$roslaunch mrobot_gazebo mrobot_kinect_nav_gazebo.launch

$roslaunch mrobot_navigation gmapping_demo.launch

9.4 hector-slam

hector_slam功能包使用高斯牛顿方法, 不需要里程计数据, 只根据 激光信息便可构建地图。 因此, 该功能包可以很好地在空中机器人、 手持构图设备及特种机器人中运行。

1
apt install ros-noetic-hector-slam

hector_slam的核心节点是hector_mapping, 它订阅“/scan”话题以获取SLAM所需的激光数据。 与gmapping相同的是, hector_mapping节点也会发布map话题, 提供构建完成的地图信息; 不同的是,hector_mapping节点还会发布slam_out_pose和poseupdate这两个话题, 提供当前估计的机器人位姿。

name Type 描述
订阅 scan sensor_msgs/LaserScan 雷达数据
syscommand std_msgs/String
发布 map_metadata nav_msgs/MapMetaData
map nav_msgs/OccupancyGrid 发布地图栅格数据
slam_out_pose geometry_msgs/PoseStamped
poseupdate geometry_msgs/PoseWithCovarianceStamped
服务 dynamic_map nav_msgs/GetMap

9.4.2 配置

1
2
3
4
5
mrobot_navigation/launch/hector.launch

演示hector_slam的mrobot_navigation/launch/hector_demo.launch文件,

启动hector_mapping节点和rviz可视化界面

9.4.3 Gazebo仿真SLAM

1
2
3
4
5
$roslaunch mrobot_gazebo mrobot_laser_nav_gazebo.launch
$roslaunch mrobot_navigation hector_demo.launch
$roslaunch mrobot_teleop mrobot_teleop.launch
# 保存地图
$rosrun map_server map_saver -f hector_map

hector_slam建图的效果也非常不错, 但由于要基于深度数据估算里程计信息, 因此对深度传感器的数据精度有较高要求, 建图的稳定性不如gmapping。 如果使用Kinect在该仿真环境中进行 hector_slam建图, 特征点过少, 估算的里程计信息不佳, 建图的效果会大打折扣

9.4.4 真实SLAM

9.5 cartographer[todo]

谷歌宣布开放一个名为cartographer的即时定位与地图建模库, 开发人员可以使用该库实现机器人在二维或三维条件下的定位及建图功能。

cartograhper的设计目的是在计算资源有限的情况下, 实时获取相对较高精度的2D地图。 考虑到基于模拟策略的粒子滤波方法在较大环境下对内存和计算资源的需求较高, cartographer采用基于图网络的优化方法。

目前cartographer主要基于激光雷达来实现SLAM,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
apt-get install -y python3-wstool python3-rosdep ninja-build


# 创建工作空间
mkdir catkin_ws_carto
cd catkin_ws_carto
wstool init src

wstool merge -t src https://raw.githubusercontent.com/googlecartographer/cartographer_ros/master/cartographer_ros.rosinstall

# 拉取代码
wstool update -t src

--------------------
root@cdce9f3334ed:/data/carto_ws# cat src/.rosinstall
# THIS IS AN AUTOGENERATED FILE, LAST GENERATED USING wstool ON 2024-07-18
- git:
local-name: cartographer
uri: https://github.com/cartographer-project/cartographer.git
version: master
- git:
local-name: cartographer_ros
uri: https://github.com/cartographer-project/cartographer_ros.git
version: master

- git:
local-name: ceres-solver
uri: https://github.com/ceres-solver/ceres-solver.git
version: master
--------------------

更新ROSdep 镜像
https://gitee.com/ncnynl/rosdep/blob/master/README.md

# 安装依赖
src/cartographer/scripts/install_proto3.sh
sudo rosdep init
rosdep update
rosdep install --from-paths src --ignore-src --rosdistro=${ROS_DISTRO} -y


# - 注释掉cartographer/package.xml的libabsl-dev
# 安装absl
./src/cartographer/scripts/install_abseil.sh
修改CmakeFile.txt
find_package(absl REQUIRED /usr/local/stow/absl)

# 编译
$ catkin_make_isolated --install --use-ninja
$ source install_isolated/setup.bash
1
2
git 
# git git-man less liberror-perl
测试
1
2
3
4
wget -P ~/Downloads https://storage.googleapis.com/cartographer-public-data/bags/backpack_2d/cartographer_paper_deutsches_museum.bag
https://pan.baidu.com/s/1UmkuHawGL2R3C2OURnqa7g 提取码rwp7
# RUN
roslaunch cartographer_ros demo_backpack_2d.launch bag_filename:=${HOME}/Downloads/cartographer_paper_deutsches_museum.bag

9.6 rgbslam

https://github.com/felixendres/rgbdslam_v2

1
2
3
4
5
6
7
8
# 依赖安装
sudo apt-get install libsuitesparse-dev
# 安装脚本(配置较为复杂,脚本比较方便)
https://raw.githubusercontent.com/felixendres/rgbdslam_v2/kinetic/install.sh
bash install.sh

# 配置环境变量
source ~/Code/rgbdslam_catkin_ws/devel/setup.bash

数据包实现(测试)SLAM

1
2
3
4
5
6
7
8
9
10
11
12
13
14
数据包:
http://vision.in.tum.de/rgbd/dataset/freiburg1/rgbd_dataset_freiburg1_desk.bag

rgbdslam.launch
<!-- Input data settings -->
<param name="config/topic_image_mono" value="/camera/rgb/image_color" />
<param name="config/topic_image_depth" value="/camera/depth/image" />

$roslaunch rgbdslam rgbdslam.launch
$rosbag play rgbd_dataset_freiburg1_desk.bag
# 建图完成后, 直接在菜单栏中选择保存为点云数据即可。

# 查看已保存的点云地图
$rosrun pcl_ros pcd_to_pointcloud quicksave.pcd

9.6.3 使用Kinect实现SLAM

运行之前修改rgbdslam.launch中的图像话题名, 必须与Kinect发布的话题一致。

1
2
$ roslaunch robot_vision freenect.launch
$ roslaunch rgbdslam rgbdslam.launch

9.7 ORB-SLAM

1
2
$ git clone https://github.com/raulmur/ORB_SLAM2.git
$ sudo apt-get install libboost-all-dev libblas-dev liblapack-dev

eigen 3.2 安装

https://eigen.tuxfamily.org/index.php?title=Main_Page

1
2
3
4
5
$ mkdir build
$ cd build
$ cmake ..
$ make
$ sudo make install

编译ORB-SLAM2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ mkdir build
$ cd build
$ cmake -DCPP11_NO_BOOST=1 ..
$ make
$ sudo make install

-----
CMake Error at CMakeLists.txt:35 (message):
OpenCV > 2.4.3 not found.

git clone https://github.com/stevenlovegrove/Pangolin.git
cd Pangolin
mkdir build
cd build
cmake ..
make -j
sudo make install

编译依赖

1
$ ./build.sh

ORB-SLAM2环境配置及运行_orbslam2环境配置-CSDN博客

【SLAM】Jetson Xvier运行ORB_SLAM2 配置、跑数据集、usb_cam实时轨迹_orb-slam2怎么获得真实轨迹-CSDN博客

编译ORB-SLAM2 的ROS功能包

1
2
3
4
5
$ export ROS_PACKAGE_PATH=${ROS_PACKAGE_PATH}:ORB_SLAM_PATH/ORB_SLAM2/Examples/ROS
$ chmod +x build_ros.sh
$ ./build_ros.sh

$ source ORB_SLAM2/Examples/ROS/ORB_SLAM2/build/devel/setup.bash
9.7.2 数据包实现单目SLAM

http://vision.in.tum.de/rgbd/dataset/freiburg1/rgbd_dataset_freiburg1_desk.bag

1
2
3
4
5
6
$rosrun ORB_SLAM2 Mono Vocabulary/ORBvoc.txt Examples/ROS/ORB_SLAM2/Asus.yaml
启动Mono节点时, 还应输入两个必需的参数。
1) PATH_TO_VOCABULARY: 算法参数文件。 在ORB_SLAM2/Vocabulary中,
将其中的压缩包解压即可。
2) PATH_TO_SETTINGS_FILE: 相机参数设置文件, 需要对camera进行标定,
或者使用ORB_SLAM2/Examples/ROS/ORB_SLAM2中已有的设置文件Asus.yaml。

启动成功后就可以看到如图9-48所示的界面, 暂时还没有数据产生, 所以界面中没有任何显示。

现在播放数据包:

1
2
$rosbag play rgbd_dataset_freiburg1_desk.bag \
/camera/rgb/image_color:=/camera/image_raw

一会就可以在界面中看到如图9-49所示的SLAM过程

ORB_SLAM2构建的地图是一种三维稀疏点云的形式, 与其他方法构建的地图格式有所不同。

ORB_SLAM2包中还提供了AR功能,

1
2
3
$ roscore
$ rosrun ORB_SLAM2 MonoAR Vocabulary/ORBvoc.txt Examples/ROS/ORB_SLAM2/Asus.yaml
$ rosbag play rgbd_dataset_freiburg1_desk.bag /camera/rgb/image_color:=/camera/image_raw

9.7.3 摄像头实现单目SLAM

1
2
$roslaunch robot_vision usb_cam_remap.launch
$rosrun ORB_SLAM2 Mono Vocabulary/ORBvoc.txt Examples/ROS/ORB_SLAM2/Asus.yaml

AR

1
2
$roslaunch robot_vision usb_cam_remap.launch
$rosrun ORB_SLAM2 MonoAR Vocabulary/ORBvoc.txt Examples/ROS/ORB_SLAM2/Asus.yaml

9.8 导航功能包

定位+导航

ROS提供两个功能包:

1) move_base: 实现机器人导航中的最优路径规划。
2) amcl: 实现二维地图中的机器人定位。

在此基础上,提供一套完整的导航功能框架

  • 采集传感器信息

  • robot发布nav_msgs/Odometry里程计信息,TF变换

  • 输出geometry_msgs/Twist控制指令

1
apt install ros-noetic-navigation
9.8.2 move_base功能包

move_base是ROS中完成路径规划的功能包, 主要由以下两大规划器组成。

  • 全局路径规划(global_planner) 。 全局路径规划是根据给定的目标位置和全局地图进行总体路径的规划。 在导航中, 使用Dijkstra或A* 算法进行全局路径的规划, 计算出机器人到目标位置的最优路线, 作为机器人的全局路线。

  • 本地实时规划(local_planner) 。 在实际情况中, 机器人往往无法严格按照全局路线行驶, 所以需要针对地图信息和机器人附近随时可能出现的障碍物规划机器人每个周期内应该行驶的路线, 使之尽量符合全局最优路径。 本地实时规划由local_planner模块实现, 使用Dynamic Window Approaches算法搜索躲避和行进的多条路经, 综合各评价标准 (是否会撞击障碍物, 所需要的时间等) 选取最优路径, 并且计算行驶周期内的线速度和角速度, 避免与动态出现的障碍物发生碰撞。

话题&服务

Name Type Info
Act Sub move_base/goal
move_base/cancel
Act Pub move_base/feedback
move_base/status
move_base/result
Topic Reg move_base_simple/goal
Topic Send cmd_vel
Server ~make_plan
~clear_unknown_space
~clear_costmaps

参数

todo

9.8.3 amcl功能包

自适应(或kld采样) 的蒙特卡罗定位方法(amcl)

Topic Reg Scan 激光雷达数据
Tf 坐标变换信息
initialpose
map
Topic Send amcl_pose 机器人在地图中的位姿估计,带协方差信息
particlecloud 粒子滤波器维护的位姿估计集合
Tf
Servers global_localization 初始化全局定位
request_nomotion_update 手动执行更新发布更新粒子
Server call static_map amcl调用该服务获取地图数据

坐标变换

  • 里程计 VS amcl 实现机器人定位的区别?

  • 里程计: 只通过里程计的数据处理/base和odom之间的TF变换

  • amcl定位:可以估算robot在地图坐标系的位姿,提供base odom ,map之间的TF变换

9.8.4 代价地图配置
  1. 通用配置文件(Common Configuration,local_costmap&global_costmap)
    costmap_common_params.yaml的配置文件, 具体代
    码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    obstacle_range: 2.5  # 检测障碍物的最大范围 2.5m
    raytrace_range: 3.0 # 检测自由空间的最大范围
    # 机器人在二维地图上的占用面积,
    # footprint: [[0.165, 0.165], [0.165, -0.165], [-0.165, -0.165], [-0.165, 0.165]]
    robot_radius: 0.165
    inflation_radius: 0.1 # 障碍物保持的最小安全距离
    # 障碍物的最大高度和最小高度
    max_obstacle_height: 0.6
    min_obstacle_height: 0.0
    observation_sources: scan
    scan: { data_type: LaserScan,
    topic: /scan,
    marking: true,
    clearing: true,
    expected_update_rate: 0}
    # marking和clearing参数用来表示是否需要使用传感器的实时信息来
    # 添加或清除代价地图中的障碍物信息。
  2. 全局规划配置文件(Global Configuration, global_costmap)

global_costmap_params.yaml, 代码如下:

1
2
3
4
5
6
7
8
9
10
global_costmap:
global_frame: /map
robot_base_frame: /base_footprint
update_frequency: 1.0
publish_frequency: 0
static_map: true
rolling_window: false
resolution: 0.01
transform_tolerance: 1.0
map_type: costmap
  1. 本地规划配置文件(Local Configuration, local_costmap)

local_costmap_params.yaml, 代码如下:

1
2
3
4
5
6
7
8
9
10
local_costmap:
global_frame: map
robot_base_frame: base_footprint
update_frequency: 3.0publish_frequency: 1.0
static_map: true
rolling_window: false
width: 6.0
height: 6.0
resolution: 0.01
transform_tolerance: 1.0
9.8.5 本地规划器配置

base_local_planner_params.yaml

本地规划采用Trajectory Rollout算法, 并且设置算法中需要用到的机器人速度、 加速度阈值等参数。

9.9 rviz仿真导航

1
2
3
4
mrobot_navigation/launch/fake_move_base.launch
mrobot_navigation/launch/fake_nav_demo.launch

mrobot_bringup/launch/fake_morobot_with_laser.launch
1. 开始导航
1
2
$roslaunch mrobot_bringup fake_mrobot_with_laser.launch
$roslaunch mrobot_navigation fake_nav_demo.launch

checkfile:

    - mrobot_navigation\rviz\nav.rviz

运行结果:

用鼠标点击菜单栏中的“2D Nav Goal”按钮, 这个按钮的功能是帮 助我们设置导航的目标点。 将鼠标移动到地图上导航的目标位置, 点击 鼠标左键(注意不要放开) 。 这时, 可以在目标位置看到一个绿色的箭 头, 因为导航目标点不仅包含机器人的位置信息, 还包含机器人的姿态 信息, 通过拖动鼠标可以设置导航目标的姿态

2. 自动导航(todo)
1
2
3
4
5
6
7
$roslaunch mrobot_bringup fake_mrobot_with_laser.launch
$roslaunch mrobot_navigation fake_nav_demo.launch
# 自主导航
$rosrun mrobot_navigation random_navigation.py

# view机器人发布的距离信息、 状态信息、 目标点编号、 成功率和速度等日志
rqt_console

9.10 gazebo仿真导航

首先启动Gazebo仿真环境, 然后启动move_base导航功能节点。

1
2
3
4
5
6
7
8
9
10
#1 
mrobot_gazebo/launch/mrobot_laser_nav_gazebo.launch
#2
mrobot_navigation/launch/fake_nav_cloister_demo.launch


# Gazebo界面
$roslaunch mrobot_gazebo mrobot_laser_nav_gazebo.launch
# Rviz界面
$roslaunch mrobot_navigation fake_nav_cloister_demo.launch
1.运行效果

2.实时避障

9.11 真实导航

9.12 自主探索slam

为什么机器人在SLAM过程中需要远程遥控机器人运动?

能不能让机器人自主移动并且实现SLAM呢?

将前面学到的SLAM和导航功能结合到一起, 在导航避障过程中建立环境地图。

下面以gmapping为例(其他SLAM功能包类似) , 实现机器人自主探索式的SLAM, 不再需要人工 控制。

1 launch

gmapping_demo.launch文件基础上,添加move_base节点加入到SLAM系统中。

mrobot_navigation/launch/exploring_slam_demo.launch

1
2
3
4
5
6
7
8
9
10
<launch>
<include file="$(find mrobot_navigation)/launch/gmapping.launch"/>

<!-- 运行move_base节点 -->
<include file="$(find mrobot_navigation)/launch/move_base.launch" />

<!-- 运行rviz -->
<node pkg="rviz" type="rviz" name="rviz"
args="-d $(find mrobot_navigation)rviz/nav.rviz"/>
</launch>
2 rviz设置探索目标
1
2
3
4
# gazebo环境模拟
$roslaunch mrobot_gazebo mrobot_laser_nav_gazebo.launch
# SLAM 自动探索(rviz指定目标位置)
$roslaunch mrobot_navigation exploring_slam_demo.launch
3 实现自主探索

修改target PT: mrobot_navigation/scripts/exploring_slam.py

1
2
3
4
5
6
locations['1'] = Pose(Point(4.589, -0.376, 0.000), Quaternion(0.000, 0.000, -0.447, 0.89
locations['2'] = Pose(Point(4.231, -6.050, 0.000), Quaternion(0.000, 0.000, -0.847, 0.53
locations['3'] = Pose(Point(-0.674, -5.244, 0.000), Quaternion(0.000, 0.000, 0.000, 1.000
locations['4'] = Pose(Point(-5.543, -4.779, 0.000), Quaternion(0.000, 0.000, 0.645, 0.764
locations['5'] = Pose(Point(-4.701, -0.590, 0.000), Quaternion(0.000, 0.000, 0.340, 0.940
locations['6'] = Pose(Point(2.924, 0.018, 0.000), Quaternion(0.000, 0.000, 0.000, 1.000
1
2
# 自主探索
$rosrun mrobot_navigation exploring_slam.py
总结
  • SLAM建图

  • 自主导航(框架使用)

  • 自主探索SLAM (SLAM+自主导航)

10-Movelt机械臂

MoveIt

创建配置机械臂

启动moveIt

配置文件

ArbotiX 关节配置

pick and place

Gazebo仿真

控制Gazebo机器臂

11-ROS与机器学习

Alpha GO

TF基础

线性回归

手写数字识别

物体识别

12-ROS进阶

action

plugin

rviz plugin

动态参数配置

SMACH

ROS-MATLAB

Web GUI

13-ROS机器人实例

PR2

TurtleBot

Universal Robots

catvehicle

HRMRP

Kungfu Arm

14-ROS2