【ROS学习笔记】7.订阅者Subscriber的编程实现(C++和Python)

基于B站ROS公开课:【古月居】古月·ROS入门21讲
基于Ubuntu 20.04.1、Noetic版本
修正错误,并详述Python版本部署

本节通过创建一个订阅者Subscriber来控制海龟。
我们先看要实现的这个小程序的图。
(部分图摘自:b站【古月居】古月·ROS入门21讲)

1 模型图

ROS Master管理两个主要节点:
Publisher,海龟仿真器/turtlesim
Subscriber,名为Pose Listener
这次海龟仿真器turtlesim为Publisher,发布Message(传输的是动作信息,以数据结构 turtlesim::Pose发布),通过Topic(/turtle1/pose)的管道,将数据传输给Subscriber。Subscriber订阅得到的数据,获得Pose信息。

“/turtle1/pose”这个topic是海归仿真器节点/turtlesim下自带的topic,直接拿来用。

在这里插入图片描述

2 创建功能包

我们之前已经创建了工作空间和功能包learning topic了。
直接上代码。

3 创建Subscriber代码(C++)

如何实现一个Subscriber:

  • 初始化ROS节点
  • 订阅需要的话题
  • 循环等待话题消息,接收到消息后进入回调函数
  • 在回调函数中完成消息处理

(源码:https://github.com/guyuehome/ros_21_tutorials/blob/master/learning_topic/src/pose_subscriber.cpp)
我用红字标上了代码讲解。
在这里插入图片描述

4 编译代码(C++)

有了代码,接下来编译。

配置代码编译规则

配置CMakeLists.txt中的编译规则:

  • 设置需要编译的代码和生成的可执行文件
  • 设置链接库

将下列代码拷贝至CMakeLists.txt中:
直接加到之前那两行下面即可

add_executable(pose_subscriber src/pose_subscriber.cpp)
target_link_libraries(pose_subscriber ${catkin_LIBRARIES})

在这里插入图片描述

执行编译

回到工作空间目录,执行编译.

cd ~/catkin_ws
catkin_make

在这里插入图片描述

source 一下 setup.bash

source devel/setup.bash放入环境变量.bashrc中,之前已完成。

运行

打开终端,分别运行:

roscore
rosrun turtlesim turtlesim_node
rosrun learning_topic pose_subscriber

在这里插入图片描述这时海龟的位置就会一直被pose_subscriber监听,现在因为海龟没动,所以x、y的坐标值是不会变的。
我们让海龟动起来,再建立一个之前用过的键盘控制节点:

rosrun turtlesim turtle_teleop_key

控制它移动,坐标就发生实时变化啦!
在这里插入图片描述

5 Python实现

(源码:https://github.com/guyuehome/ros_21_tutorials/blob/master/learning_topic/scripts/pose_subscriber.py)

创建Python代码

源码拷贝到scripts下。
我用红字标上了代码讲解。
在这里插入图片描述

右击文件→属性,打开执行权限。

配置代码编译规则

配置一下CMakeLists.txt中的编译规则:
之前已将文件中的catkin_install_python这段取消注释,并将默认的my_python_script改成了velocity_publisher.py
这次再加上一个关于pose_subscriber.py的catkin_install_python方法:
在这里插入图片描述

编译代码

回到工作空间目录,执行编译.

cd ~/catkin_ws
catkin_make

source 一下 setup.bash

略过。

运行

打开终端,分别运行:

roscore
rosrun turtlesim turtlesim_node
rosrun learning_topic pose_subscriber.py
rosrun turtlesim turtle_teleop_key

控制它移动,成功!
在这里插入图片描述

试着查看一下系统当前的计算图

再打开一个终端,输入:

rqt_graph

调到所有活动active节点/话题视图,可看到3个节点:
键盘控制器节点/teleop_turtle 通过 /turtle/cmd_vel 传速度msg给海归仿真器节点/turtlesim,
/turtlesim 通过 /turtle/pose 传位置msg给subscriber节点。
/turtle/cmd_vel 和 /turtle/pose 两个topic都在turtle1海龟下面,因为海龟自身会发布速度和位置的msg给这两个topic
在这里插入图片描述

  • 12
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
需要使用ROS中的C++ API来实现话题订阅和UDP数据转发。以下是一个简单的示例程序: ```cpp #include <ros/ros.h> #include <std_msgs/String.h> #include <arpa/inet.h> #include <sys/socket.h> #define BUFLEN 512 #define PORT 8888 int main(int argc, char **argv) { ros::init(argc, argv, "udp_forwarder"); ros::NodeHandle nh; // Create a UDP socket int udp_socket; if ((udp_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) { ROS_ERROR("Failed to create UDP socket"); return 1; } // Configure the UDP socket struct sockaddr_in udp_addr; memset((char *)&udp_addr, 0, sizeof(udp_addr)); udp_addr.sin_family = AF_INET; udp_addr.sin_port = htons(PORT); udp_addr.sin_addr.s_addr = htonl(INADDR_ANY); if (bind(udp_socket, (struct sockaddr *)&udp_addr, sizeof(udp_addr)) == -1) { ROS_ERROR("Failed to bind UDP socket"); return 1; } // Subscribe to the ROS topic ros::Subscriber sub = nh.subscribe("my_topic", 1000, [](const std_msgs::String::ConstPtr& msg) { // Send the message over UDP struct sockaddr_in dest_addr; memset((char *)&dest_addr, 0, sizeof(dest_addr)); dest_addr.sin_family = AF_INET; dest_addr.sin_port = htons(PORT); dest_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); if (sendto(udp_socket, msg->data.c_str(), msg->data.length(), 0, (struct sockaddr *)&dest_addr, sizeof(dest_addr)) == -1) { ROS_ERROR("Failed to send UDP packet"); } }); ros::spin(); return 0; } ``` 在这个示例中,我们使用了一个名为“my_topic”的ROS话题来接收数据。当有新的数据到达时,我们将其转发到UDP端口8888上的127.0.0.1。注意,我们在发送数据之前需要先创建一个UDP套接字并进行绑定。在程序退出时,我们使用ros::spin()来保持节点的活动状态,以确保我们能够接收到所有的ROS消息。 为了编译这个程序,您需要在CMakeLists.txt文件中添加以下内容: ``` add_executable(udp_forwarder src/udp_forwarder.cpp) target_link_libraries(udp_forwarder ${catkin_LIBRARIES}) ``` 然后,您可以使用catkin_make命令来编译程序。当您运行这个程序时,它将开始订阅“my_topic”话题,并将所有接收到的消息转发到UDP端口8888上的127.0.0.1。您可以在需要接收这些数据的其他节点上运行一个UDP监听器来接收这些数据。
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值