ROS系统(二)
理解ROS服务和参数
turtlesim提供了什么服务?
服务是节点之间通讯的另一种方式。服务允许节点发送请求,并获得一个响应。
使用rosservice
rosservice可以使用ROS客户端、服务器框架提供的服务。
rosservice list
输出可服务的信息,包括:重置(reset),清除(clear),再生(spawn),终止(kill)等9个服务。rosservice type [service]
输出服务类型
例:
rosservice type clear
输出:std_srvs/Empty
服务类型为空,表明调用这个服务不需要参数
rosservice call [service] [args]
调用带参数的服务
rosservice call clear 因为服务类型为空,所以进行无参数调用,可以消除turtlesim_node背景上的轨迹
通过再生(spawn)服务的信息,来了解带参数服务
rosservice type spawn|rossrv show
也可以在指定位置和角度处生成一个新的turtlesim,名字参数可选
rosservice call spawn 2 2 0.2 “name”
使用rosparam
存储并操作ROS参数服务器上的数据。
可存储整型(1)、浮点(1.0)、布尔(true)、字符串(one)、字典({a:b,c:d})、列表([1,2,3])等数据类型
rosparams使用YAML标记语言的语法。
rosparam list
列出参数名rosparam set [param_name] 值
设置参数
例 rosparam set background_r 150
上述命令修改了参数的值,应调用清除服务rosparam call clear
使修改后参数生效。rosparam get 参数名
可查看参数服务器上的参数值rosparam get /
可显示参数服务器上所有内容rosparam dump params.yaml
可将所有参数写入params.yml文件中rosparam load params.yaml copy
可将params.yaml文件重新载入新的命名空间,例copy空间。rosparam get copy/background_b
获取参数值.
使用rqt_console和roslaunch
rqt_console 是ROS日志框架的一部分,采用显示节点的输出信息
rqt_logger_level允许修改节点运行时输出信息的日志等级(例DEBUG,WARN,INFO和ERROR)
rqt_console
在启动turtlesim之前,在另外两个终端中运行
rosrun rqt_console rqt_console
rosrun rqt_logger_level rqt_logger_level
弹出两个窗口,然后在新终端中启动turtlesim
rosrun turtlesim turtlesim_node
因为默认等级为info,可在rqt_console中看到turtlesim启动后所有输出信息。在logger_level将日志等级修改为warn。然后让两个小乌龟动起来,观察rqt_console输出。
rostopic pub /turtlel/cmd_vel geometry_msgs/iwist -r / -- '[2.0,0.0.0.0]' '[0.0,0.0,1.8]'
日志等级优先排序:
- Fatal 最高优先级
- Error
- Warn
- Info
- Debug 最低优先级
若设气质等级为warn,则只能得到fatal、warn、Error三个等级的所有信息。
roslaunch
可以启动多个turtlesim节点和一个模仿节点。让一个turtlesim节点来模仿另一个turtlesim节点。
用法: roslaunch [package] [filename.launch]
- 先切换到beginner_tutorials程序包目录下
roscd beginner_tutorials
若roscd执行失败,设置了当前终端下的ROS_PACKAGE_PATH环境变量
export ROS_PACKAGE_PATH =~/本地ros版本号_workspace/sandbox:$ROS_PACKAGE_PATH
- 创建Launch文件夹
mkdir launch
cd launch
创建名为turtlemimic.launch文件,并复制到内存文件中
touch turtlemimic.launch
创建文件
vim turtlemimic.launch
进入窗口,按i
开始编译,esc退出编译,打印冒号:
,输入wq
,回车。
cat turtlemimic.launch 查看turtlemimic.launch文件内容
3. 通过roslaunch命令启动launch文件
roslaunch beginner_tutorials turtleminic.launch
在新终端使用rostopic命令
rostopic pub /turtlesiml/turtlel/cmd_vel geometry_msgs/iwist -r / -- '[2.0,0.0.0.0]' '[0.0,0.0,1.8]'
可看两个turtlesim同时运动
4. 可用rqt_graph查看launch文件的作用
使用rosed编辑ROS文件
rosed是rosbash的一部分,可直接用package名来获取待编辑的文件,而不需要指定该文件的存储路径
rosed [package_name] [filename]
例:rosed roscpp Logger.msg
编译器: ros默认编译器VIm。若想将其他的编译器设为默认值,需修改~/.bashrc文件,增加
终端输入命令ll
vim .bashrc
增加export EDITOR='emacs -nw'
将emacs设置成为默认编辑器。
bashrc文件的改变,只会在新的终端才有效。已经打开的终端不受环境变量的影响。
打开一个新的终端,echo $EDITOR
看看那是否定义了EDITOR。
创建ROS消息和服务
消息(msg):msg文件是一个描述ROS中所使用消息类型的简单文本,被用来执行生成不同语言的源代码
服务:一个src文件描述一项服务,包括:请求和响应
msg文件存放在package的msg目录下,srv文件则存放在srv目录下。
msg文件就是每行声明一个数据类型和变量名。ROS中有一个特殊的数据类型:Header,它含有时间戳和坐标系信息。
srv文件分为请求和响应两部分,由’—'分隔。
使用msg
- 创建msg
cd ~/catkin_ws/src/beginner_tutorials
mkdir msg
echo "int64 num" > msg/Num.msg
- 添加配置信息
查看package.xml, 确保它包含一下两条语句:
<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>
在 CMakeLists.txt文件中,利用find_packag函数,增加对message_generation的依赖。
find_package(catkin REQUIRED COMPONENTS roscpp rospy std_msgs message_generation)
catkin_package(
...
CATKIN_DEPENDS message_runtime ...
...)
add_message_files(
FILES
Num.msg
)
generate_messages()
最终确保终端工作空间与程序包工作空间相同,用source devel/setup.bash
3. 使用rosmsg show beginner_tutorials/Num
检查ROS是否能够识消息
beginner_tutorials – 消息所在的package
Num – 消息名Num.
如果忘记消息所在的package,也可输入rosmsg show Num
使用srv
- 创建srv
roscd beginner_tutorials
mkdir srv
下次创建服务时,可以用roscp将文件从一个package复制到另一个package中
使用方法: roscp [package_name] [file_to_copy_path] [copy_path]
例:
roscp rospy_tutorials AddTwoInts.srv srv/AddTwoInts.srv
要确保srv文件被转换成C++,Python和其他语言的源代码。
在CMakeLists.txt文件中增加了对message_generation的依赖:
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
std_msgs
message_generation)
add_service_files(
FILES
AddTwoInts.srv #自己的srv文件名
)
- 使用
rossrv show <service type>
检查ROS是否能够识该服务。
例:
rossrv show beginner_tutorials/AddTwoInts
或
rossrv show AddTwoInts
msg和srv都需要的操作
在CMakeLists.txt中
generate_messages(
DEPENDENCIES
std_msgs
)
由于增加了新的消息,需要重新编译package:
cd ../..
catkin_make
cd -
rosmsg -h 可看到一系列rosmsg子命令
rosmsg show -h 可获得rosmsg show所需参数
编写简单的消息发布器和订阅器
编写发布器节点
『节点』(Node) 是指 ROS 网络中可执行文件。将会创建一个发布器节点(“talker”),它将不断的在 ROS 网络中广播消息。
cd ~/catkin_ws/src/beginner_tutorials
- 在 beginner_tutorials package 路径下创建一个src文件夹,
mkdir -p ~/catkin_ws/src/beginner_tutorials/src
src将用来放置beginner_tutorials package的所有源码。
在 beginner_tutorials package 里创建 src/talker.cpp 文件,并将如下代码粘贴到文件内:
#include "ros/ros.h"
//ros/ros.h 是一个实用的头文件,它引用了 ROS 系统中大部分常用的头文件
#include "std_msgs/String.h"
//引用了 std_msgs/String 消息, 它存放在 std_msgs package 里,是由 String.msg 文件自动生成的头文件
#include <sstream>
int main(int argc, char **argv)
{
ros::init(argc, argv, "talker");
//初始化 ROS 。它允许 ROS 通过命令行进行名称重映射,也可以指定节点的名称——运行过程中,节点的名称必须唯一
ros::NodeHandle n;
//为这个进程的节点创建一个句柄。第一个创建的 NodeHandle 会为节点进行初始化,最后一个销毁的 NodeHandle 则会释放该节点所占用的所有资源。
ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000);
/* 告诉master 将要在 chatter(话题名) 上发布 std_msgs/String 消息类型的消息。master 就会告诉所有订阅了 chatter 话题的节点,将要有数据发布。第二个参数是发布序列的大小。如果我们发布的消息的频率太高,缓冲区中的消息在大于 1000 个的时候就会开始丢弃先前发布的消息。
NodeHandle::advertise() 返回一个 ros::Publisher 对象,有两个作用: 1) 它有一个 publish() 成员函数可以让你在topic上发布消息; 2) 如果消息类型不对,会拒绝发布。 */
ros::Rate loop_rate(10);
//ros::Rate 对象可以允许你指定自循环的频率。它会追踪记录自上一次调用 Rate::sleep() 后时间的流逝,并休眠直到一个频率周期的时间。
int count = 0;
/*roscpp 会默认生成一个 SIGINT 句柄,它负责处理 Ctrl-C 键盘操作——使得 ros::ok() 返回 false。
如果下列条件之一发生,ros::ok() 返回false:
SIGINT 被触发 (Ctrl-C)
被另一同名节点踢出 ROS 网络
ros::shutdown() 被程序的另一部分调用节点中的所有 ros::NodeHandles 都已经被销毁 一旦 ros::ok() 返回 false, 所有的 ROS 调用都会失效*/
while (ros::ok())
{
std_msgs::String msg;
std::stringstream ss;
ss << "hello world " << count;
msg.data = ss.str();
//使用一个由 msg file 文件产生的『消息自适应』类在 ROS 网络中广播消息。现使用标准的String消息,它只有一个数据成员 "data"。
ROS_INFO("%s", msg.data.c_str());
//ROS_INFO 和其他类似的函数可以用来代替 printf/cout 等函数
chatter_pub.publish(msg);
//向所有订阅 chatter 话题的节点发送消息。
ros::spinOnce();
//如果你的程序里包含其他回调函数,最好在这里加上 ros::spinOnce()这一语句,否则你的回调函数就永远也不会被调用了。
loop_rate.sleep();
//调用 ros::Rate 对象来休眠一段时间以使得发布频率为 10Hz。
++count;
}
return 0;
}
- 初始化 ROS 系统
- 在 ROS 网络内广播我们将要在 chatter 话题上发布 std_msgs/String 类型的消息
- 以每秒 10 次的频率在 chatter 上发布消息