ROS中C++编写发布、python编写订阅

本文介绍了一种在ROS中使用C++编写消息发布者和Python编写消息订阅者的实践案例,展示了如何通过简单配置实现不同语言间的消息传递。文章提供了源代码示例,包括C++的mytalker.cpp和Python的mylisten2.py,以及运行结果和相关配置说明。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


因为在做项目的过程中需要用到C++和Python程序,所以想要尝试一下在ROS中能不能用C++编写消息的发布者,Python编写消息的订阅者。

源程序

mytalker.cpp

#include"ros/ros.h"
#include"std_msgs/String.h"
#include<sstream>
#include<string.h>

using namespace std;

int main(int argc, char** argv)
{
	ros::init(argc, argv, "mytalker");  // 节点名称
	ros::NodeHandle n;

	ros::Publisher chatter_pub  = n.advertise<std_msgs::String>("chatter",1000);
	ros::Rate loop_rate(10);
	int count = 0;

	while( ros::ok() )
	{
		std_msgs::String msg;
		std::stringstream ss;
		ss<<"hello "<<count;
		msg.data = ss.str();
	
		ROS_INFO("Publish %s\n", msg.data.c_str() );

		chatter_pub.publish(msg);

		ros::spinOnce();

		loop_rate.sleep();
		++count;
	}

	return 0;	
}

mylisten2.py

#!/usr/bin/env python
import rospy
from std_msgs.msg import String

def callback(data):
    print("Received \n")

def listener():
    rospy.init_node('listener', anonymous= True)
    rospy.Subscriber("chatter", String, callback)
    rospy.spin()


if __name__ == '__main__':
    listener()

程序比较简单,就不解读了

运行结果

发布者

在这里插入图片描述

订阅者

在这里插入图片描述
可以看到,即使我们用C++编写消息的发布者,用python编写消息的订阅者,消息还是能正常传输,并且能够执行相应的回调函数。

相关配置

mylisten2.py文件的位置。应当先在包(比如mytest)下面创建一个scripts文件夹,然后将mylisten2.py文件放在scripts文件夹下就行,在CMakeList中,只需要在add_executable和target_link_libraries中加入mylistener.cpp相应的内容就行,不需要加入python文件的相关编译内容。

include_directories(include ${catkin_INCLUDE_DIRS})

add_executable(mytalker src/mytalker.cpp)
target_link_libraries(mytalker ${catkin_LIBRARIES})
add_dependencies(mytalker ${PROJECT_NAME}_generate_messages_cpp)
 
#add_executable(mylistener src/mylistener.cpp)
#target_link_libraries(mylistener ${catkin_LIBRARIES})
#add_dependencies(mytalker ${PROJECT_NAME}_generate_messages_cpp)

ROS真的好方便,这样C++和Python就能随便用了

参考博客

1:C++、python编写消息程序
2:检验自己编写的消息程序

<think>好的,我现在需要帮助用户了解ROS环境中C++Python之间的通信方法。首先,我得回忆一下ROS的基本通信机制。ROS主要使用基于发布-订阅模型的通信方式,也就是话题(Topic),还有服务(Service)和动作(Action)等其他方式。用户可能对这些基本概念有所了解,但需要具体的实现方法。 根据用户提供的引用内容,特别是引用[1]和引用[2],里面提到了使用C++Python实现话题通信的例子。比如talker.py是用Python发布的,而C++可能有对应的订阅者。需要解释这两种语言如何通过ROS的中间件进行通信,可能涉及到消息类型的统一和ROS Master的作用。 另外,引用[3]提到了服务通信的配置,需要说明服务通信与话题的不同,即服务是双向的,有请求和响应。这里可能需要分别给出C++Python实现服务的代码示例,并说明如何确保两者兼容,比如使用相同的srv文件。 用户的问题是关于C++Python之间的通信方法,所以需要覆盖主要的通信方式:话题、服务,可能还有动作。每种方式都需要简要说明原理,然后给出实现步骤,比如创建包、定义消息/服务、编写节点等。 需要注意用户提供的引用中提到的CMakeLists.txt和package.xml的配置,特别是在添加依赖和生成消息的部分。这部分对于C++节点来说很重要,而Python可能不需要编译,但需要确保srv和msg文件正确安装。 还要考虑用户可能遇到的常见问题,比如不同进程通信的机制,如引用[2]中提到的,需要解释ROS的通信层如何抽象底层进程间通信,使得不同语言节点可以无缝交互。 最后,生成相关问题时要围绕ROS通信的扩展,比如参数服务器、动作库,或者调试工具如rostopic和rosservice的使用,以及可能遇到的兼容性问题。</think>### ROSC++Python通信的实现方法 在ROS中,C++Python节点可以通过以下三种主要方式实现跨语言通信: --- #### 一、话题通信(发布/订阅模式)[^2] **实现原理**:通过ROS Master进行节点注册和匹配,建立直接连接后实现异步通信。消息类型必须完全一致,但发布者和订阅者可以用不同语言编写。 **Python发布者示例**(与引用[1]代码一致): ```python #!/usr/bin/env python import rospy from std_msgs.msg import String def talker(): pub = rospy.Publisher('chatter', String, queue_size=10) rospy.init_node('talker', anonymous=True) rate = rospy.Rate(10) while not rospy.is_shutdown(): msg = "hello world %s" % rospy.get_time() pub.publish(msg) rate.sleep() if __name__ == '__main__': try: talker() except rospy.ROSInterruptException: pass ``` **C++订阅者实现**: ```cpp #include "ros/ros.h" #include "std_msgs/String.h" void chatterCallback(const std_msgs::String::ConstPtr& msg) { ROS_INFO("Received: [%s]", msg->data.c_str()); } int main(int argc, char **argv) { ros::init(argc, argv, "listener"); ros::NodeHandle n; ros::Subscriber sub = n.subscribe("chatter", 10, chatterCallback); ros::spin(); return 0; } ``` --- #### 二、服务通信(请求/响应模式)[^3] **实现特点**:需要严格定义服务接口(.srv文件),服务端与客户端可使用不同语言。 **服务定义示例**(AddInts.srv): ``` int32 a int32 b --- int32 sum ``` **Python服务端实现**: ```python from beginner_tutorials.srv import AddInts, AddIntsResponse import rospy def handle_add(req): return AddIntsResponse(req.a + req.b) rospy.init_node('add_server') s = rospy.Service('add_ints', AddInts, handle_add) rospy.spin() ``` **C++客户端实现**: ```cpp #include "ros/ros.h" #include "beginner_tutorials/AddInts.h" int main(int argc, char **argv) { ros::init(argc, argv, "add_client"); ros::NodeHandle n; ros::ServiceClient client = n.serviceClient<beginner_tutorials::AddInts>("add_ints"); beginner_tutorials::AddInts srv; srv.request.a = 3; srv.request.b = 5; if(client.call(srv)) { ROS_INFO("Sum: %ld", (long int)srv.response.sum); } return 0; } ``` --- #### 三、配置注意事项 1. **包配置**(package.xml): ```xml <build_depend>message_generation</build_depend> <exec_depend>message_runtime</exec_depend> ``` 2. **CMake配置**: ```cmake find_package(catkin REQUIRED COMPONENTS roscpp rospy std_msgs message_generation ) add_service_files(FILES AddInts.srv) generate_messages(DEPENDENCIES std_msgs) ``` --- #### 四、通信保障机制 1. **数据类型匹配**:通过`.msg`/`.srv`文件生成对应语言的消息类 2. **序列化协议**:使用统一的序列化/反序列化机制 3. **中间件抽象**:ROS层屏蔽了底层的TCP/UDP通信细节
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值