安装
配置软件源
打开软件与更新,配置 ubuntu 的软件和更新,并且允许安装未经认证的软件
官方默认安装源
1 | sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list' |
清华的安装源
1 | sudo sh -c '. /etc/lsb-release && echo "deb http://mirrors.tuna.tsinghua.edu.cn/ros/ubuntu/ `lsb_release -cs` main" > /etc/apt/sources.list.d/ros-latest.list' |
中科大安装源
1 | sudo sh -c '. /etc/lsb-release && echo "deb http://mirrors.ustc.edu.cn/ros/ubuntu/ `lsb_release -cs` main" > /etc/apt/sources.list.d/ros-latest.list' |
设置key
在终端中输入
1 | sudo apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654 |
安装ros
首先需要更新源和 apt,终端中输入
1 | sudo apt update |
然后开始安装 ros,终端输入
1 | sudo apt install ros-noetic-desktop-full |
配置环境变量
在终端中输入指令
1 | echo "source /opt/ros/noetic/setup.bash" >> ~/.bashrc |
卸载指令
1 | sudo apt remove ros-noetic-* |
初始化 rosdep
在命令行中输入指令
1 | sudo rosdep init |
有些版本老的ros会报错,因为是缺少依赖,那就需要安装构建依赖
首先安装构建依赖的相关工具
1 | sudo apt install python3-rosdep python3-rosinstall python3-rosinstall-generator python3-wstool build-essential |
如果不是依赖的问题,就可以看看 ros安装
ros介绍
ros的文件系统
ros的指令
rosnode获取节点信息的指令
rosnode ping
测试到节点的连接状态rosnode list
列出活动节点rosnode info
打印节点信息rosnode machine
列出指定设备上节点rosnode kill
杀死某个节点rosnode cleanup
清除不可连接的节点
rostopic获取话题信息的指令
rostopic bw
显示主题使用的带宽rostopic delay
显示带有 header 的主题延迟rostopic echo
打印消息到屏幕rostopic find
根据类型查找主题rostopic hz
显示主题的发布频率rostopic info
显示主题相关信息rostopic list
显示所有活动状态下的主题rostopic pub
将数据发布到主题rostopic type
打印主题类型
rosmsg获取有关消息类型信息的指令
rosmsg show
显示消息描述rosmsg info
显示消息信息rosmsg list
列出所有消息rosmsg md5
显示 md5 加密后的消息rosmsg package
显示某个功能包下的所有消息rosmsg packages
列出包含消息的功能包
rosservice获取服务信息的指令
rosservice args
打印服务参数rosservice call
使用提供的参数调用服务rosservice find
按照服务类型查找服务rosservice info
打印有关服务的信息rosservice list
列出所有活动的服务rosservice type
打印服务类型rosservice uri
打印服务的 ROSRPC uri
rossrv显示有关服务类型信息的指令
rossrv show
显示服务消息详情rossrv info
显示服务消息相关信息rossrv list
列出所有服务信息rossrv md5
显示 md5 加密后的服务消息rossrv package
显示某个包下所有服务消息rossrv packages
显示包含服务消息的所有包
rosparam获取和设置参数信息的指令
rosparam set
设置参数rosparam get
获取参数rosparam load
从外部文件加载参数rosparam dump
将参数写出到外部文件rosparam delete
删除参数rosparam list
列出所有参数
设置命名空间和重映射
在 rosrun
时的节点名称之后添加 __ns:=namespace
设置命名空间
1 | rosrun turtlesim turtlesim_node __ns:=/xxx |
在 rosrun
时的节点名称之后添加 __name:=newname
1 | rosrun turtlesim turtlesim_node __name:=t1 |
设置话题重映射
rosrun名称重映射语法: rorun 包名 节点名 话题名:=新话题名称
设置参数
rosrun 包名 节点名称 _参数名:=参数值
一些需要注意的
在每一种通信都需要依赖于 ros 的句柄,所以就是在实例化各种通信端之前都需要初始化一个句柄
1 | ros::NodeHandle nh; |
话题通信
话题操作基本思想就是创建两个节点,然后这两个节点需要有一致的话题,然后作为发布方会发送该话题的消息,而接收放就接收该话题的消息,以此实现通信
发布方
1 | // 初始化发布方,话题名称,保存的最大消息数 |
订阅方
1 | // 订阅回调函数 |
自定义msg
msgs是一个文本文件,每一行分别是字段类型和字段名称
首先在功能包下新建 msg 目录,添加文件 xxx.msg
xxx是自定义的名称,内容可以自定义,这里暂定为
1 | string name |
在 package.xml
中添加编译依赖与执行依赖
1 | <build_depend>message_generation</build_depend> |
在 CMakeLists.txt
编辑相关配置
- 在
find_package
中添加message_generation
与std_msgs
- 在
add_message_files
中添加 msg 文件xxx.msg
- 在
generate_messages
中添加std_msgs
编译之后会生成一个头文件,位于 \devel\include\包名\xxx.h
,并且1需要配置该头文件的路径,然后就可以像 std_msgs
一样使用了
服务通信
ros 系统负责存储服务端和客户端的注册信息,并且匹配话题相同的服务端和客户端,并且建立连接,之后客户端请求,服务端响应
自定义服务器
功能包下新建 srv 目录,添加 xxx.srv
文件,内容为(根据自己需求来定义)
1 | # 客户端请求时发送的两个数据 |
中间记得加 ---
来做划分
编辑配置文件,在 package.xml
中添加编译依赖与执行依赖
1 | <build_depend>message_generation</build_depend> |
在 CMakeLists.txt
中编辑相关配置
- 在
find_package
中添加message_generation
与std_msgs
- 在
add_service_files
中添加 msg 文件xxx.srv
- 在
generate_messages
中添加std_msgs
编译之后会生成一个头文件,位于 \devel\include\包名\xxx.h
,并且1需要配置该头文件的路径,然后就可以作为头文件被引入使用了
服务端
1 | // 服务器响应回调函数 |
客户端
1 | // 创建客户端对象 |
参数服务器
有两种增删改查的参数操作
设置参数
1 | // 1 |
获取参数
第一种方式
1 | ros::NodeHandle::param(key, default_value); |
第二种方式
1 | ros::param::get(key, &value); |
删除参数
1 | ros::NodeHandle::deleteParam(key); |
动作action
类似于服务通信,并且在运行过程中服务端不断地向客户端反馈数据与状态
自定义action消息
需要在导入工程包的时候还要额外导入 actionlib actionlib_msgs
等文件,在功能包下新建 action
目录,新增 xxx.action
文件。
action
文件内容由三部分组成
- 请求目标值
- 最终响应结果
- 连续反馈
1 | #目标值 |
在 CMakeLists.txt
文件的 add_action_files
中添加 xxx.action
编译之后会在工作空间内生成对应的头文件
服务器
1 | // 创建服务器 |
客户端
1 | actionlib::SimpleActionClient<demo01_action::AddIntsAction> client(nh,"addInts",true); |
launch文件
launch 文件是一个 XML 格式的文件,可以启动本地和远程的多个节点,还可以在参数服务器上设置参数
可以使用一个 launch
文件就打开多个节点,提高 ROS 程序的启动效果
使用步骤
- 在功能包下添加
launch
目录,在目录下面新建xxx.launch
文件,并且编辑文件 - 在命令行中输入指令
roslaunch 包名 xxx.launch
来调用launch
文件,使用roslaunch
指令时会自动打开roscore
注意
由于 ros 是多进程的,所以不能保证 launch
文件中的节点的启动顺序
介绍
launch
标签
是所有 launch
文件的根标签,充当其它标签的容器
node
标签属性
pkg="pkgname"
节点所属的包名type="nodetype"
节点的类型name="nodename"
节点名称args="xxx"
参数可选,是传递给节点的参数machine="machinename"
机器名称,在指定的机器上启动节点respawn="true or false"
如果节点退出是否重新启动respawn_delay="N"
如果上述respawn
为true
则延迟N
秒后重启节点required="true or false"
该节点是否必要,如果为true
退出将杀死整个roslaunch
ns="xxx"
在指定命名空间中启动节点clear_params="true or false"
再启动前,删除节点的私有空间的所有参数output="log or screen"
日志发送的目标,发送到屏幕或者是文件
node
子级标签
env
环境变量设置remap
重映射节点名称rosparam
参数设置param
参数设置
include
标签属性
file="$(find pkgname)/xxx/xxx.launch"
要包含的文件路径ns="xxx"
在指定的命名空间导入文件,可不填
include
子级标签
env
环境变量设置arg
将参数传递给被包含的文件
remap
标签
用于话题重命名
from="xxx"
原始话题名称to="xxx"
重命名目标名称
param
标签
name="namespace/paramname"
参数名称,可以包含命名空间value="xxx"
可选参数,定义参数值,如果省略,必须指定外部文件作为参数来源type="str or ..."
指定参数类型,如未指定,roslaunch
会尝试确定参数类型
rosparam
标签
command="load or dump or delete"
可选,默认为load
,加载,导出或者删除参数file="$(find xxx)/xxx/xxx..."
加载或导出到的yaml
文件param="paramname"
参数名称ns="namespace"
命名空间
group
标签
ns="namespace"
可选,命名空间clear_params="true or false"
可选,启动前是否删除组名称空间内部的所有参数- 除了
launch
标签以外的标签都是它的子标签
arg
标签
name="paramname"
参数名称default="defaultvalue"
默认数值,可选value="value"
数值,可选,不可与default
并存doc="description"
参数描述说明
其它的功能
回旋函数
spin()
不断回旋,相当于while(1)
spinOnce()
只回旋一次,没有循环,相当于顺序语句
时间
获取时刻
1 | ros::Time right_now = ros::Time::now(); |
持续时间
1 | ros::Duration du(10); // 设置一个持续时间 s,相当于 sleep 函数 |
设置运行频率
1 | ros::Rate rate(1); // 指定频率 |
定时器
1 | /** |
重映射和命名空间
别名设置
1 | ros::init(argc,argv,"zhangsan",ros::init_options::AnonymousName); |
命名空间
1 | std::map<std::string, std::string> map; |
话题重映射
rosrun名称重映射语法: rorun 包名 节点名 话题名:=新话题名称
话题的名称与节点的命名空间,节点的名称是有一定关系的,话题名称分为三种类型
全局,与节点命名空间平级,以 /
开头的节点名称
1 | ros::Publisher pub = nh.advertise<std_msgs::String>("/chatter",1000); |
相对,与节点名称平级,以非 /
开头的节点名称来确定话题名称
1 | ros::Publisher pub = nh.advertise<std_msgs::String>("chatter",1000); |
私有,是节点名称的子级,以 ~
开头的名称
1 | ros::NodeHandle nh("~"); |
后记
这些记录是我在学习 ros 时所记录下来的,可以看看赵老师所做的文档,写的很详细,很不错 ros学习文档