ROS = 机器人专用的操作系统工具包

第一节 环境配置

1.下载需要用到的资料

首先下载虚拟机软件 VMware,再下载的Ubuntu镜像(我自己的是Ubuntu20.04)。

通过网盘分享的文件:linux镜像
链接: https://pan.baidu.com/s/1cf23CHcw62Eg8S8zbQZV5w?pwd=1234 提取码: 1234 

2.安装虚拟机软件VMware

部分电脑因为权限存在问题,所以在安装时尽量右击安装包文件,使用管理员权限运行。运行后会弹出页面,选择“下一步”:

选择后,会弹出自定义安装,我们可以选择安装的位置:

完成这一步后,后面直接全部默认“下一步”即可,所以这里跳过几步,直到安装,安装好以后出现下图画面,不要点击完成,而是点击“许可证”,这里不小心点了完成也没事,后续在软件内输入密钥 也可以:

点击“许可证”后,出现下图画面:

密钥大家在网上找一下即可,直接浏览器搜索。

3.创建虚拟机

打开VMware workstation软件,来到主页,选择创建新的虚拟机

选择后出现下图界面:

按照图中选择,出现下图界面,保证第一步为你的VMware所支持的最高版本即可,所以操作时可能会与下图内容有出入:

选择“下一步”后会出现下图界面:

选择“下一步”后会出现下图界面:

选择“下一步”后会出现下图界面,第一步是让自己命名虚拟机的名称,第二步是让选择虚拟机安装的位置,这里需要自己挑选一个位置来存放安装的虚拟机:

选择“下一步”后会出现下图界面,直接默认即可:

选择“下一步”后会出现下图界面,直接默认即可:

选择“下一步”后会出现下图界面:

选择“下一步”后会出现下图界面:

选择“下一步”后会出现下图界面:

选择“下一步”后会出现下图界面,第一步,根据自己电脑空间大小进行选择

选择“下一步”后会出现下图界面,直接默认即可:

选择“下一步”后会出现下图界面:

选择“自定义硬件”后,会出现下图界面:

除了已经配置过的部分,还需要对“镜像”与“USB控制器”进行配置,首先选择“新CD/DVD(SATA)”,然后进行第二步操作,找到上述过程中下载的镜像(我以22.04为例,大家安装其他的过程也是一样的):

选择后,选中“USB控制器”,将USB改为3.1,然后关闭此页面:

接着在下图界面中选择“完成”

会显示下图页面,选择开启此虚拟机:

会显示下图页面,鼠标选中后,回车:(18.04和20.04不会出现哦)

下方会出现一个引导,直接关掉即可:

经过等待后,会出现下图界面

这时我们选中左侧,滑动滚轮,选中简体中文,然后选择“安装Ubuntu”,选择后会来到下图的界面。

选择继续后,出现下图界面,其中第一步与第二步应该都是默认的

选择继续后,出现下图界面,此时屏幕开始放大,第一步中的清除整个磁盘,不必害怕,这个是前面操作中分给它的20G,不会动自己电脑里的东西

选择“现在安装”后,会出现下图的界面,弹出一个小框,选择继续

选择“继续”后,会出现下图的界面,直接选择“继续”

选择“继续”后,会出现下图的界面,输入自己的姓名与计算机名,以及密码后,选择继续即可,计算机名与密码不推荐太长

然后等待安装进程,大概10分钟左右,根据自己的网速快慢会有变化,网速慢多等会

安装好以后,重启虚拟机即可。(重启后,注意看桌面,需要按一下"回车"按键哦),至此,我们算是创建好虚拟机了。

4.在虚拟机中安装ROS

安装ROS,我们选择小鱼大佬的一键安装

打开ubuntu终端,输入:

wget http://fishros.com/install -O fishros && . fishros

运行项目并下载源码
回车后会出现下图界面:

输入密码后会出现下图的界面:

输入“1”后回车,会出现下图界面:

输入“1”后回车,会出现下图界面:

输入“2”后回车,会出现下图界面:

输入“1”后回车,可能会选择镜像源,我这里选择的中科大的:

输入“1”后回车,会出现类似这种布局的选项,选择ros1+noetic:

输入“1”后回车,会出现类似的下图界面

输入“1”后下载桌面版回车,等待进程跑完并且出现下图页面,就安装好了ros。
 

5.ROS的测试方法如下:

# 启动ros核心
roscore
# 新开终端启动小乌龟
rosrun turtlesim turtlesim_node
# 新开终端控制乌龟
rosrun turtlesim turtle_teleop_key

会出现一只小乌龟,就代表你安装成功了。

6.Linux基础操作

Ctrl + Alt + t :快速打开终端

ls:查看当前文件夹内容

pwd:查看当前的绝对路径

mkdir:创建文件夹

touch 文件名:创建文件(touch 已存在路径/文件名)

gedit 文件名:弹出文本框,也能创建新文件

rm 文件名:删除文件

rm -rf 文件夹名:删除文件夹

sudo chmod 777 文件名:赋予文件可执行权限

./文件名(没有空格):执行文件

Ctrl + h:显示隐藏文件

第二节 文件系统架构

ROS文件系统级指的是在硬盘上ROS源代码的组织形式,其结构大致可以如下图所示:

WorkSpace --- 自定义的工作空间

    |--- build:编译空间,用于存放CMake和catkin的缓存信息、配置信息和其他中间文件。

    |--- devel:开发空间,用于存放编译后生成的目标文件,包括头文件、动态&静态链接库、可执行文件等。

    |--- src: 源码

        |-- package:功能包(ROS基本单元)包含多个节点、库与配置文件,包名所有字母小写,只能由字母、数字与下划线组成

            |-- CMakeLists.txt 配置编译规则,比如源文件、依赖项、目标文件

            |-- package.xml 包信息,比如:包名、版本、作者、依赖项...(以前版本是 manifest.xml)

            |-- scripts 存储python文件

            |-- src 存储C++源文件

            |-- include 头文件

            |-- msg 消息通信格式文件

            |-- srv 服务通信格式文件

            |-- action 动作格式文件

            |-- launch 可一次性运行多个节点 

            |-- config 配置信息

        |-- CMakeLists.txt: 编译的基本配置

Helloworld(Python)

1.先创建一个工作空间(第一层);

mkdir 自定义空间名称/src
cd 自定义空间名称

上述命令,首先会创建一个工作空间以及一个 src 子目录,然后再进入工作空间调用 catkin_make命令编译。

2.进入 src (第二层)创建 ros 包并添加依赖(第三层)

cd src
catkin_create_pkg 自定义ROS包名 roscpp rospy std_msgs

上述命令,会在工作空间下生成一个功能包,该功能包依赖于 roscpp、rospy 与 std_msgs,其中roscpp是使用C++实现的库,而rospy则是使用python实现的库,std_msgs是标准消息库,创建ROS功能包时,一般都会依赖这三个库实现。

3.进入 ros 包添加 scripts 目录(第四层)并编辑 python 文件(第五层);

cd ros包
mkdir scripts

scripts 文件夹 专门放 Python 文件
没有这个文件夹,Python 文件不能运行

新建 python 文件: (文件名自定义)(第五层)

cd scripts
touch 自定义文件名.py

打开文件:

gedit hello.py
#! /usr/bin/env python

"""
    Python 版 HelloWorld

"""
import rospy

if __name__ == "__main__":
    rospy.init_node("Hello")
    rospy.loginfo("Hello World!!!!")

4.为 Python 文件添加可执行权限

chmod +x 自定义文件名.py

5.编辑 ROS 包下的 CamkeList.txt 文件(在160行左右)

#打开 CMakeLists.txt
gedit CMakeLists.txt
catkin_install_python(PROGRAMS scripts/自定义文件名.py
  DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)

6.进入工作空间目录并编译

cd 自定义空间名称
catkin_make

7.进入工作空间目录并执行

先启动命令行1:

roscore

再启动命令行2:

cd 工作空间
source ./devel/setup.bash
rosrun 包名 自定义文件名.py

输出结果:Hello World!!!!

第三节 通信机制

roscore与节点

roscore 相当于 ROS 通信的环境,只有运行了 roscore,ROS 机器人各模块之间的通信才能建立,这是 ROS 的硬性要求。

手机、电脑、平板,必须连 WiFi才能互相发消息、传文件
路由器一关,所有设备直接断联,啥都干不了
roscore = WiFi 路由器

硬性规矩:你想让 ROS 里的小程序互相说话、传数据,必须先开 roscore!不开,啥都别想干!

节点是 ROS 功能的最小单元,节点由可执行文件生成,节点存在于 roscore 生成的通信环境中。所有执行 ROS 功能的可执行文件,都会定义并产生(也就是注册)一个节点,直到这个功能结束或关闭,或者 roscore 被关闭,节点才会消失。如果可执行文件没有注册节点,就无法参与 ROS 多机通信,就无法算作含有 ROS 功能。

手机 = 1 个节点
电脑 = 1 个节点
平板 = 1 个节点
节点 = 连 WiFi 的设备微信(一个个小程序)
节点的规矩,就 3 条:
        想连 WiFi(roscore),必须先登记(注册节点)
        设备关机 / WiFi 关了,这个设备就下线(节点消失)
        不连 WiFi、不登记,就不能和别的设备聊天,就不算 ROS 程序

节点常用命令

rosnode:

        rosnode ping :测试到节点的连接状态

        rosnode list :列出活动节点

        rosnode info :打印节点信息

        rosnode machine :列出指定设备上节点

        rosnode kill :杀死某个节点

        rosnode cleanup : 清除不可链接的节点

rqt_graph:

        椭圆代表节点,横线代表两个节点是通过什么话题进行沟通的

rosrun 与 roslaunch

rosrun 是 ROS 提供的调用 ROS 功能包的可执行文件的命令,

        使用方法为:rosrun 功能包名称 可执行文件名称

        该命令会自动在工作空间里面寻找对应功能包下面对应的可执行文件。位置已讲过。

roslaunch是 ROS 提供的调用 ROS 功能包下 launch 文件的命令,

        使用方法为:roslaunch 功能包名称 launch文件名称

roslaunch
        作用:一次性开好多个小程序,还能自动帮你启动 roscore
        例子:一个 launch 文件可以同时打开小乌龟 + 键盘控制
        特点:不用手动输roscore,直接一键启动一堆节点

话题通信

话题通信:主要涉及三个角色ROS master (管理者)、Talker (发布者)、Listener (订阅者)

ROS Master 负责保管 Talker 和 Listener 注册的信息,并匹配话题相同的 Talker 与 Listener,帮助 Talker 与 Listener 建立连接,连接建立后,Talker 可以发布消息,且发布的消息会被 Listener 订阅。

话题通信一共分为7步(默认主节点开了):

1.发布者注册

Talker 启动后,会通过 RPC(远程过程调用协议)在 ROS Master 中注册自身信息,其中包含所发布消息的话题名称。ROS Master 会将节点的注册信息加入到注册表中。

农户(Talker)开张,打电话给村委会(RPC):我是卖玉米的,我卖的商品叫「玉米」,我家地址在哪。村委会(Master)把农户信息记在本子上。

2.订阅者注册

Listener 启动后,也会通过 RPC 在 ROS Master 中注册自身信息,包含需要订阅消息的话题名。ROS Master 会将节点的注册信息加入到注册表中。

你(Listener)想买玉米,打电话给村委会(RPC):我要买「玉米」,帮我找卖玉米的。村委会把你的需求也记下来。

3.ROS Master 实现匹配注册

ROS Master 会根据注册表中的信息匹配 Talker 和 Listener,并通过 RPC 向 Listener 发送 Talker 的 RPC 地址信息。

村委会翻本子:哦,有人卖玉米、有人买玉米!打电话告诉你(RPC):卖玉米的农户家地址发给你了。

4. 订阅者向发布者发送请求

Listener 根据接收到的 RPC 地址,通过 RPC 向 Talker 发送连接请求,传输订阅的话题名称、消息类型以及通信协议 (TCP/UDP)。

你拿到农户地址,直接打电话给农户(RPC):我要买玉米,我要跟你交易,咱们直接当面交易(TCP)。

5. 发布者确认请求

Talker 接收到 Listener 的请求后,也是通过 RPC 向 Listener 确认连接信息,并发送自身的 TCP 地址信息。

农户接电话:行,我愿意卖给你,我在我家等你

6. 订阅者与发布者建立连接

Listener 根据步骤 4 返回的消息使用 TCP 与 Talker 建立网络连接。

你直接走到农户家门口,和农户面对面(TCP 通道建立)

到这一步,村委会彻底没用了,全程不参与后面交易

7. 发布者向订阅者发送消息

连接建立后,Talker 开始向 Listener 发布消息。

农户源源不断把玉米递给你,你一直收玉米。农户一直卖、你一直买,单向不停交易

注意 1:上述实现流程中,前五步使用的 RPC 协议,最后两步使用的是 TCP 协议(传输控制协议)

注意 2:Talker 与 Listener 的启动无先后顺序要求

注意 3:Talker 与 Listener 都可以有多个

注意 4:Talker 与 Listener 连接建立后,不再需要 ROS Master。也即,即便关闭 ROS Master,Talker 与 Listener 照常通信。

话题通信常用命令

rostopic:

        rostopic bw 显示主题使用的带宽

        rostopic delay 显示带有 header 的主题延迟

        rostopic echo 打印消息到屏幕

        rostopic find 根据类型查找主题

        rostopic hz 显示主题的发布频率

        rostopic info 显示主题相关信息

        rostopic list 显示所有活动状态下的主题

        rostopic pub 将数据发布到主题

        rostopic type 打印主题类型 

话题通信基本操作B(Python)  

1.发布方   

#! /usr/bin/env python3

#1.导包 
import rospy
from 自定义ROS包名.msg import String

if __name__ == "__main__":
    #2.初始化 ROS 节点:命名(唯一)
    rospy.init_node("talker_p")
    #3.实例化 发布者 对象
    pub = rospy.Publisher("chatter",String,queue_size=10)
    #4.组织被发布的数据,并编写逻辑发布数据
    msg = String()  #创建 msg 对象
    msg_front = "hello 你好"
    count = 0  #计数器 
    # 设置循环频率
    rate = rospy.Rate(1)
    while not rospy.is_shutdown():

        #拼接字符串
        msg.data = msg_front + str(count)

        pub.publish(msg)
        rate.sleep()
        rospy.loginfo("写出的数据:%s",msg.data)
        count += 1
2.订阅方
#! /usr/bin/env python3

#1.导包 
import rospy
from 自定义ROS包名.msg import String

def doMsg(msg):
    rospy.loginfo("I heard:%s",msg.data)

if __name__ == "__main__":
    #2.初始化 ROS 节点:命名(唯一)
    rospy.init_node("listener_p")
    #3.实例化 订阅者 对象
    sub = rospy.Subscriber("chatter",String,doMsg,queue_size=10)
    #4.处理订阅的消息(回调函数)
    #5.设置循环调用回调函数
    rospy.spin()

3.配置CMakeLists.txt

catkin_install_python(PROGRAMS
  scripts/talker_p.py
  scripts/listener_p.py
  DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)

4.执行

1.启动 roscore;

2.启动发布节点;

3.启动订阅节点。

话题通信自定义msg

流程:
  1. 按照固定格式创建 msg 文件
  2. 编辑配置文件
  3. 编译生成可以被 Python 或 C++ 调用的中间文件

1.定义msg文件

功能包下新建 msg 目录,添加文件 自定义文件名.msg

string name
uint16 age
float64 height

2.编辑配置文件

package.xml中添加编译依赖与执行依赖

  <build_depend>message_generation</build_depend>
  <exec_depend>message_runtime</exec_depend>
  <!-- 
  exce_depend 以前对应的是 run_depend 现在非法
  -->

CMakeLists.txt编辑 msg 相关配置

find_package(catkin REQUIRED COMPONENTS
  roscpp
  rospy
  std_msgs
  message_generation
)
# 需要加入 message_generation,必须有 std_msgs
## 配置 msg 源文件
add_message_files(
  FILES
  自定义文件名.msg
)
# 生成消息时依赖于 std_msgs
generate_messages(
  DEPENDENCIES
  std_msgs
)
#执行时依赖
catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES demo02_talker_listener
  CATKIN_DEPENDS roscpp rospy std_msgs message_runtime
#  DEPENDS system_lib
)

话题通信自定义msg

流程:
  1. 编写发布方实现;
  2. 编写订阅方实现;
  3. 为python文件添加可执行权限;
  4. 编辑配置文件;
  5. 编译并执行。
1.发布方
#! /usr/bin/env python3

import rospy
from ceshi1.msg import Work


if __name__ == "__main__":
    #1.初始化 ROS 节点
    rospy.init_node("talker_Work_p")
    #2.创建发布者对象
    pub = rospy.Publisher("chatter_Work",Work,queue_size=10)
    #3.组织消息
    p = Work()
    p.name = "葫芦瓦"
    p.age = 18
    p.height = 0.75

    #4.编写消息发布逻辑
    rate = rospy.Rate(1)
    while not rospy.is_shutdown():
        pub.publish(p)  #发布消息
        rate.sleep()  #休眠
        rospy.loginfo("姓名:%s, 年龄:%d, 身高:%.2f",p.name, p.age, p.height)
2.订阅方
#! /usr/bin/env python3

import rospy
from ceshi1.msg import Work

def doWork(p):
    rospy.loginfo("接收到的人的信息:%s, %d, %.2f",p.name, p.age, p.height)


if __name__ == "__main__":
    #1.初始化节点
    rospy.init_node("listener_Work_p")
    #2.创建订阅者对象
    sub = rospy.Subscriber("chatter_Work",Work,doWork,queue_size=10)
    rospy.spin() #4.循环
3.权限设置

终端下进入 scripts 执行:chmod +x *.py

4.配置 CMakeLists.txt
catkin_install_python(PROGRAMS
  scripts/sub.py
  scripts/pub.py
  scripts/sub2.py
  scripts/pub2.py
  DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)
5.执行

1.启动 roscore;

2.启动发布节点;

3.启动订阅节点。

服务通信

服务通信:主要涉及三个角色ROS master (管理者)、Server (服务端)、Client (客户端)、
ROS Master 负责保管 Server 和 Client 注册的信息,并匹配话题相同的 Server 与 Client ,帮助 Server 与 Client 建立连接,连接建立后,Client 发送请求信息,Server 返回响应信息。

一共分为5步:

1.服务端注册

2.客户端注册

3.ROS Master实现匹配注册

4.客户端发送请求

5.服务端响应

第四节 ROS常用工具

Rviz

Rviz是一款三维可视化工具,可以很好的兼容基于 ROS 软件框架的机器人平台。

        在 rviz 中,可以使用可扩展标记语言 XML 对机器人、周围物体等任何实物进行尺寸、质量、位置、材质、关节等属性的描述,并且在界面中呈现出来。
        同时,rviz 还可以通过图形化的方式,实时显示机器人传感器的信息、机器人的运动状态、周围环境的变化等信息。
        总而言之,rviz 通过机器人模型参数、机器人发布的传感信息等数据,为用户进行所有可监测信息的图形化显示。用户和开发者也可以在 rviz 的控制界面下,通过按钮、滑动条、数值等方式,控制机器人的行为。

Rviz看数据,看真实 / 虚拟机器人发出来的状态、传感器画面、运动轨迹,不能模拟物理环境

 Gazebo

Gazebo 是一个三维动态物理仿真器,能准确高效地仿真在复杂的室内外环境下机器人群体。与游戏引擎类似,Gazebo 能对一整套传感器进行高度逼真的物理仿真、为程序和用户提供交互接口,其典型应用场景包括:

  • 测试机器人算法
  • 机器人的设计
  • 现实情景下的回溯测试

就像玩游戏一样,在电脑里造一个虚拟房间、地形、障碍物,把虚拟机器人放进去跑,完全模拟真实物理环境(重力、碰撞、摩擦力、传感器数据)。

rosbag的使用

使用流程:以小乌龟为例

1.创建用于保存录制文件的目录,进入文件系统,右击新建文件夹即可

2.打开主节点        roscore

3.打开小乌龟节点

        rosrun turtlesim turtlesim_node

        rosrun turtlesim turtle_teleop_key

4.录制文件        rosbag record -a -O 1

5.回放文件        rosbag play 1.bag

1.对指定话题进行录制

        指令格式:rosbag record topic_name1  topic_name2...

2.对所有话题进行录制

        指令格式:rosbag record -a

TF

传感器测到的坐标 → 换算成机器人本体坐标

        机器人系统上,有多个传感器,如激光雷达、摄像头等,有的传感器是可以感知机器人周边的物体方位 (或者称之为:坐标,横向、纵向、高度的距离信息) 的,以协助机器人定位障碍物,可以直接将物体相对该传感器的方位信息,等价于物体相对于机器人系统或机器人其它组件的方位信息吗?显示是不行的,这中间需要一个转换过程。   

cv_bridge     

cv_bridge = ROS 和 OpenCV 之间的翻译官

  • ROS 里的图片是ROS 专用格式,OpenCV 看不懂
  • OpenCV 处理后的图片,ROS 也看不懂
  • cv_bridge 专门负责互相翻译格式

        机器人的传感器除了 IMU、里程计和雷达外,还有摄像头,摄像头提供的图像信息是这些传感器信息中信息量最大,也是最难处理的,同时机器人的很多功能都需要使用到摄像头。

        图像处理是一个非常庞大且复杂的领域,当前最流行的图像处理库为 OpenCV, 而 ROS 就提供了与 OpenCV 库连接的接口。ROS 中与 OpenCV 连接的接口是 cv_bridge, 通过 cv_bridge 可以把 ROS 中的图像话题转换为 OpenCV 的图像格式,然后使用 OpenCV 库进行图像处理;通过 cv_bridge 也可以把 OpenCV 的图像格式转换为 ROS 中的图像话题进行发布。

第五节 机器人仿真建模

URDF集成Rviz流程

创建新的功能包

新建urdf文件夹

编写 URDF 文件

<robot name="mycar">
    <link name="base_link">
        <visual>
            <geometry>
                <box size="0.5 0.2 0.1" />
            </geometry>
        </visual>
    </link>
</robot>

新建launch文件夹

新建launch文件

<launch>

    <!-- 设置参数 -->
    <param name="robot_description" textfile="$(find ceshi3)/urdf/box.urdf" />

    <!-- 启动 rviz -->
    <node pkg="rviz" type="rviz" name="rviz" />

</launch>

直接运行

点击左下角ADD,选择RobotModel,点击ok。

将Fixed Frame改为vase_link.

第六节 建图导航实操

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐