Posted on  Updated on 

基于古月居的ros入门

前言

由于前段时间的学习总结的习惯不好,决定新开一栏用于ros基础学习。有一说一,通过和学长的进度比较,总感觉自己是个废物。

虚拟机的安装

不要装机械盘,运行慢。使用VMware
ubantu系统18

linux基本命令行

1
2
3
4
5
6
7
8
9
10
11
12
cd
ls
mv
rm -r
cp
pwd
mkdir
touch

shutdown -h now
reboot
sudo

基本命令行

1
2
sudo apt-get update   //更新源
source ~/catkin_ws/devel/setup.bash //刷新环境变量

前置安装

1
2
3
4
5
6
7
8
9
//安装C加加编译器
sudo apt-get install g++
//安装python解释器
sudo apt-get install python
//安装vim文本编译器
sudo apt install vim
//ros安装
wget http://fishros.com/install -O fishros && . fishros

ros的核心概念

节点(node)与节点管理器(ros master)
节点名称唯一

话题(topic)与服务(serve)

话题:单向

  • 发布者
  • 订阅者
  • 消息(massage):话题的数据由.msg文件定义

服务:双向

  • 客户端
  • 服务端
  • .srv文件定义命名请求应答数据

参数(parameter)—全局共享字典
适合静态,非二进制的配置参数

文件系统

  • 功能包(package) :含节点源码,配置文件,数据定义
  • 功能包清单: 作者信息,许可信息,依赖选项
  • 元功能包:组织多个同一目的的功能包

ros命令行工具

1
2
3
4
5
6
rostopic
rosservice
rosnode
rosparam
rosmsg
rossrv

小海龟

1
2
3
4
5
6
//启动ros mastre
roscore
//启动小海龟仿真器
rosrun turtlesim turtlesim_node
//启动海龟控制节点
rosrun turtlesim turtle_teleop_key

工具

1
2
3
4
5
6
7
8
9
rqt_graph   //节点可视化
rosnode //显示节点
rostopic //话题 pub
rosmsg

rosservice //服务 call

rosbag record -a -O cmd_record //话题记录 cmd_record位保存文件名,默认hom目录下
rosbag play cmd_record.bag //话题复现

ros的文件结构

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
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: 编译的基本配置

创建工作空间

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//创建工作空间
mkdir -p ~/catkin_ws/src
cd ~/catkin_ws/src
catkin_init_workspace

//编译工作空间
cd catkin_ws/
catkin_make

catkin_make install //可要可不要
//设置环境变量
source devel/setup.bash

//检查环境变量
echo $ROS_PACKAGE_PATH

功能包创建与编译

1
2
3
4
5
6
7
8
9
10
//创建功能包
cd ~/catkin_ws/src
catkin_create_pkg my_package_name rospy roscpp std_msgs

//编译
cd catkin_ws/
catkin_make

//刷新环境变量
source ~/catkin_ws/devel/setup.bash

问题:我需要在原有的ROS工程基础之上,新建一个ROS功能包。我直接复制了其他目录下原有的一个包,进行修改。然后问题来了:catkin_make后竟然没有反应。甚至没有检测到我新改写的cmake

解决:ros允许多个工作空间使用相同功能包,但多个工作空间source不要放在脚本里,手动敲,否则会被覆盖,在catkin_make之前source一下,之后再source一下。而且要多次执行,如下。注意要先开下roscore,py文件要给其可执行权限.

1
2
3
4
5
6
//将文件复制过来后,在工作空间目录下打开终端
source ~/ws_space/devel/setup.bash
catkin_make
source ~/ws_space/devel/setup.bash
catkin_make
source ~/ws_space/devel/setup.bash

脚本文件的source只在新的终端开启时才运行

发布者与订阅者

以海龟为例

python文件要记得给可执行权限

发布者

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
#!/usr/bin/env python
# -*- coding: utf-8 -*-

########################################################################
#### Copyright 2020 GuYueHome (www.guyuehome.com). ###
########################################################################

# 该例程将发布turtle1/cmd_vel话题,消息类型geometry_msgs::Twist

import rospy
from geometry_msgs.msg import Twist

def velocity_publisher():
# ROS节点初始化
rospy.init_node('velocity_publisher', anonymous=True)

# 创建一个Publisher,发布名为/turtle1/cmd_vel的topic,消息类型为geometry_msgs::Twist,队列长度10
turtle_vel_pub = rospy.Publisher('/turtle1/cmd_vel', Twist, queue_size=10)

#设置循环的频率
rate = rospy.Rate(10)

while not rospy.is_shutdown():
# 初始化geometry_msgs::Twist类型的消息
vel_msg = Twist()
vel_msg.linear.x = 0.5
vel_msg.angular.z = 0.2

# 发布消息
turtle_vel_pub.publish(vel_msg)
rospy.loginfo("Publsh turtle velocity command[%0.2f m/s, %0.2f rad/s]",
vel_msg.linear.x, vel_msg.angular.z)

# 按照循环频率延时
rate.sleep()

if __name__ == '__main__':
try:
velocity_publisher()
except rospy.ROSInterruptException:
pass

订阅者

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
#!/usr/bin/env python
# -*- coding: utf-8 -*-

########################################################################
#### Copyright 2020 GuYueHome (www.guyuehome.com). ###
########################################################################

# 该例程将订阅/turtle1/pose话题,消息类型turtlesim::Pose

import rospy
from turtlesim.msg import Pose

def poseCallback(msg):
rospy.loginfo("Turtle pose: x:%0.6f, y:%0.6f", msg.x, msg.y)

def pose_subscriber():
# ROS节点初始化
rospy.init_node('pose_subscriber', anonymous=True)

# 创建一个Subscriber,订阅名为/turtle1/pose的topic,注册回调函数poseCallback
rospy.Subscriber("/turtle1/pose", Pose, poseCallback)

# 循环等待回调函数
rospy.spin()

if __name__ == '__main__':
pose_subscriber()



消息的自定义

定义msg文件

在功能包的src同级目录下创建msg文件夹
1
2
3
4
5
6
7
8
9
10
// 举例,该文件名为Person.msg
string name
uint8 age
uint8 sex

uint8 unknown = 0
uint8 male = 1
uint8 female = 2


launch文件

使用 launch 文件,可以一次性启动多个 ROS 节点
launch文件自动启动ROS Master

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!-- 包名 节点名称 自定义节点名 -->
<!-- 注释 -->

<launch>
<node pkg="helloworld" type="demo_hello" name="hello" output="screen" />
<node pkg="turtlesim" type="turtlesim_node" name="t1"/>
<node pkg="turtlesim" type="turtle_teleop_key" name="key1" />

<!-- 参数设置 -->
<param name="output_feame" value="odom"/>
<!-- name:参数名称,value 参数值 -->
<rosparam= file="params.yaml" command="load" ns="params"/>

<!-- 重映射remap -->
<remap from="/turtlebot/cmd_vel"to="/cmd_vel"/>
<!-- from:原名 to:映射后的名字 -->

<!-- 嵌套include -->
<include file="$(dirname)/other.launch"/>
</launch>

客户端与服务端

客户端

rosservice call /clear “{}”

参数的使用

parameter Server 全局变量存储空间

1
2
3
4
5
6
7
8
9
10
11
12
// 列出当前有多个参数
rosparam list
// 显示某个参数值
rosparam get param_key
// 设置某个参数值
rosparam set param_key param_value
//保存参数到文件
rosparam dump file_name
// 从文件读取参数
rosparam load file_anme
// 删除参数
rosparam delete param_key

yaml 参数文件
在程序里实现

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
51
52
#!/usr/bin/env python
# -*- coding: utf-8 -*-

########################################################################
#### Copyright 2020 GuYueHome (www.guyuehome.com). ###
########################################################################

# 该例程设置/读取海龟例程中的参数

import sys
import rospy
from std_srvs.srv import Empty

def parameter_config():
# ROS节点初始化
rospy.init_node('parameter_config', anonymous=True)

# 读取背景颜色参数
red = rospy.get_param('/background_r')
green = rospy.get_param('/background_g')
blue = rospy.get_param('/background_b')

rospy.loginfo("Get Backgroud Color[%d, %d, %d]", red, green, blue)

# 设置背景颜色参数
rospy.set_param("/background_r", 255);
rospy.set_param("/background_g", 255);
rospy.set_param("/background_b", 255);

rospy.loginfo("Set Backgroud Color[255, 255, 255]");

# 读取背景颜色参数
red = rospy.get_param('/background_r')
green = rospy.get_param('/background_g')
blue = rospy.get_param('/background_b')

rospy.loginfo("Get Backgroud Color[%d, %d, %d]", red, green, blue)

# 发现/spawn服务后,创建一个服务客户端,连接名为/spawn的service
rospy.wait_for_service('/clear')
try:
clear_background = rospy.ServiceProxy('/clear', Empty)

# 请求服务调用,输入请求数据
response = clear_background()
return response
except rospy.ServiceException, e:
print "Service call failed: %s"%e

if __name__ == "__main__":
parameter_config()

TF坐标管理系统

tf功能包,默认10秒

实现机制

  • 广播TF变换
  • 监听TF变换
    1
    2
    3
    4
    5
    6
    7
    8
    //安装功能包
    sudo apt-get install ros-melodic-turtle-tf
    //启动节点
    roslaunch turtle tfturtle tf demo.launch
    //turtles键盘控制节点
    rosrun turtlesim turtle teleop_key
    //保存tf tree为 pdf 至当前目录
    rosrun tf view frames

tf工具

  • 命令行工具
    rosrun tf tf_echo turtle1 turtle2
  • 可视化工具
    rosrun rviz rviz -d rospack find turtle tf /rviz/turtle rviz.rviz

tf坐标的广播与监听

单词释义

quaternion 四元数
radian 弧度
degree 角度

常用可视化工具

QT工具箱

  • 日志输出rqt_console
  • 计算图ret_graph
  • 数据绘图rqt_plot
  • 图像渲染rqt_image_view

rviz

gazebo

进阶

  • 控制与仿真 gazebo + ros +ros_control