ROS是机器人操作系统的简称,本文介绍ROS应用开发入门,订阅者Subscriber的编程。程序很简单,代码就几行,但是时刻获取仿真小乌龟运动坐标信息并显示出来。先是c++代码,然后是python 代码,你也可选择只看一种你熟悉的。
本文是 ROS 应用开发 发布者Publisher的编程 一文的继续。所以假定工程包已经建立好了。当然我们这2个也是互相独立的。订阅的信息来自仿真小乌龟。如果没有建立工程包,就用下面建立的命令,但是建立了的话就不要重复建立。
cd ~/catkin_ws/src
catkin_create_pkg learning_topic std_msgs roscpp rospy geometry_msgs turtlesim
下面直接介绍c++和 python 的编程。
c++ 源代码
在工程包learning_topic的src 目录下,也是~/catkin_ws/src/learning_topic/src 目录, 建立一个文件 pose_subscriber.cpp,
cd ~/catkin_ws/src/learning_topic/src
nano pose_subscriber.cpp
内容为:
/**
* 该例程将订阅/turtle1/pose话题,消息类型turtlesim::Pose
*/
#include <ros/ros.h>
#include "turtlesim/Pose.h"
// 接收到订阅的消息后,会进入消息回调函数
void poseCallback(const turtlesim::Pose::ConstPtr& msg)
{
// 将接收到的消息打印出来
ROS_INFO("Turtle pose: x:%0.6f, y:%0.6f", msg->x, msg->y);
}
int main(int argc, char **argv)
{
// 初始化ROS节点
ros::init(argc, argv, "pose_subscriber");
// 创建节点句柄
ros::NodeHandle n;
// 创建一个Subscriber,订阅名为/turtle1/pose的topic,注册回调函数poseCallback
ros::Subscriber pose_sub = n.subscribe("/turtle1/pose", 10, poseCallback);
// 循环等待回调函数
ros::spin();
return 0;
}
这个代码有清晰的注释,这是一个实现订阅者的基本流程:
初始化ROS节点
创建节点句柄
创建一个Subscriber,订阅名为/turtle1/pose的topic,注册回调函数poseCallback
循环等待话题消息,接收到消息后进入回调函数
回调函数poseCallback(const turtlesim::Pose::ConstPtr& msg)
只是简单显示小乌龟的位置
配置cmake文件
在 ~/catkin_ws/src/learning_topic/ 目录下,有个CMakeLists.txt 文件,我们需要修改这个文件
cd ~/catkin_ws/src/learning_topic/
nano CMakeLists.txt
在这个文件中添加下面2行,
add_executable(pose_subscriber src/pose_subscriber.cpp)
target_link_libraries(pose_subscriber ${catkin_LIBRARIES})
添加的位置是参考下面位置,就是 ## install ## 前面,然后上一个发布者添加2行的后面:
# target_link_libraries(${PROJECT_NAME}_node
# ${catkin_LIBRARIES}
# )
add_executable(velocity_publisher src/velocity_publisher.cpp)
target_link_libraries(velocity_publisher ${catkin_LIBRARIES})
add_executable(pose_subscriber src/pose_subscriber.cpp)
target_link_libraries(pose_subscriber ${catkin_LIBRARIES})
#############
## Install ##
#############
保存,退出
这样编译配置就完成了。
编译和运行测试
编译必须回到 ~/catkin_ws 目录下
cd ~/catkin_ws
catkin_make
编译后应该source 一次:
source devel/setup.bash
如果编译有错,就要排除错误,然后就运行测试。
打开一个终端,启动ros,执行
roscore
再打开一个终端,运行小乌龟
rosrun turtlesim turtlesim_node
上面是启动测试环境,如果有问题,可以 参看: ROS 下的仿真小乌龟,只是现在不启动键盘控制。
最后在我们的终端执行:
rosrun learning_topic pose_subscriber
这个时候终端不断显示,很多行
[ INFO] [1615853945.863184221]: Turtle pose: x:7.222570, y:9.893890
[ INFO] [1615853945.879153450]: Turtle pose: x:7.222570, y:9.893890
但是 Turtle pose: x:7.222570, y:9.893890 没有变化,因为小乌龟没有动。
现在我们再打开一个终端,执行:
rosrun turtlesim turtle_teleop_key
然后键盘方向键控制小乌龟运动,我们可以看到坐标的变化。
当然,如果做了发布者的编程,也可以启动发布者,让乌龟运动。
下面图就是用启动发布者的,一边控制按键,一边截图,不好操作
c++ 的编程就介绍到此。
python 代码
为了不和c++代码混淆,我们建立了scripts 目录,现在进入这个目录,并建立一个pose_subscriber.py 文件
cd ~/catkin_ws/src/learning_topic/scripts
nano pose_subscriber.py
文件内容是:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 该例程将订阅/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()
这里定义了2个函数:
poseCallback 是回调函数,显示x,y 坐标
pose_subscriber() 是被主函数直接调用的,就是主函数
# ROS节点初始化
# 创建一个Subscriber,订阅名为/turtle1/pose的topic,注册回调函数poseCallback
# 循环等待回调函数
最后面的部分就是主函数调用pose_subscriber()
if __name__ == '__main__':
pose_subscriber()
运行测试
更改 pose_subscriber.py 有执行属性
chmod +x *.py
这个可以用 ls -l 查核:
leon@ubuntu:~/catkin_ws/src/learning_topic/scripts$ ls -l
total 8
-rwxrwxrwx 1 leon leon 824 May 8 2020 pose_subscriber.py
-rwxrwxrwx 1 leon leon 1275 May 8 2020 velocity_publisher.py
leon@ubuntu:~/catkin_ws/src/learning_topic/scripts$
python 不用编译,直接执行就可以
rosrun learning_topic pose_subscriber.py
但执行之前,先要一个终端启动 roscore, 再一个启动rosrun turtlesim turtlesim_node,然后才是启动上面的命令。
要看到乌龟坐标变化,还要控制乌龟运动,这个是
再打开一个终端,执行:
rosrun turtlesim turtle_teleop_key
然后键盘方向键控制小乌龟运动,我们就可以看到坐标的变化。
当然,如果做了发布者的编程,也可以启动发布者,让乌龟运动。
运行效果图参看c++ 的运行结果图,其实那个图就是运行python 程序的结果图。
显示信息流关系
再打开一个新的终端,并输入命令:
rqt_graph
可以看到如下信息关系图:
信息后部分是话题/turtle/pose 就是订阅者和仿真乌龟间的信息流。
这2个源代码也可以在 https://github.com/huchunxu/ros_21_tutorials 下载
全文介绍到此。