✅博客主页:爆打维c-CSDN博客 🐾
🔹分享自己学习AI/编程知识的过程 🐾
🔹我的GitHub代码仓库 https://github.com/lyy-0118

目录
3) geometry_msgs/Quaternion.msg
3.3 话题通信编程
3.3.1理论模型
1. 话题基本概念
话题通信是ROS中使用频率最高的一种通信模式,话题通信是基于发布订阅模式的,也即:一个节点发布消息,另一个节点订阅该消息。
话题通信实现模型是比较复杂的,该模型如下图所示,该模型中涉及到三个角色:
- ROS Master (管理者)
- Talker (发布者)
- Listener (订阅者)
ROS Master负责保管Talker和Listener注册的信息,并匹配话题相同的Talker与Listener,帮助Talker与Listener建立连接,连接建立后,Talker可以发布消息,且发布的消息会被Listener 订阅。

整个流程由以下步骤实现:
0.Talker注册
Talker启动后,会通过RPC在ROS Master中注册自身信息,其中包含所发布消息的话题名称。ROS Master会将节点的注册信息加入到注册表中。
1.Listener注册
Listener启动后,也会通过RPC在ROS Master中注册自身信息,包含需要订阅消息的话题名。ROS Master会将节点的注册信息加入到注册表中。
2.ROS Master实现信息匹配
ROS Master会根据注册表中的信息匹配Talker和Listener,并通过RPC向Listener发送 Talker的RPC地址信息。
3.Listener向Talker发送请求
Listener根据接收到的RPC地址,通过RPC向Talker发送连接请求,传输订阅的话题名称、消息类型以及通信协议(TCP/UDP)。
4.Talker确认请求
Talker 接收到Listener的请求后,也是通过RPC向Listener确认连接信息,并发送自身的TCP 地址信息。
5.Listener与Talker件里连接
Listener根据步骤4返回的消息使用TCP与Talker建立网络连接。
6.Talker向Listener发送消息
连接建立后,Talker开始向Listener发布消息。
编写发布订阅实现,要求发布方以10HZ(每秒10次)的频率发布文本消息,订阅方订阅消息并将消息内容打印输出。
2. 私有、全局、相对命名空间
ROS中的命名空间分为三种:全局、相对、私有。其实命名空间就是名称的前缀,前缀代表着所在路径,存放的位置可以相对于根目录、节点、节点句柄的命名空间这三者来进行划分:

话题命名空间的设置
- cpp源文件设置:
话题首先要在master中注册,所以注册话题信息的函数是节点句柄调用的,因此相对/私有命名空间的设置是靠节点句柄完成的。相对和私有命名空间的设置如下所示:
// 全局命名空间:topic=/chatter
ros::Publisher pub = nh.advertise<std_msgs::String>("/chatter",10);
// 相对命名空间:topic=/default_namespace/chatter
ros::NodeHandle nh("dr");
ros::Publisher pub = nh.advertise<std_msgs::String>("chatter",10);
// 相对命名空间:topic= /node_name/namespace/ chatter
ros::NodeHandle nh("~dr");
ros::Publisher pub = nh.advertise<std_msgs::String>("chatter",10);
// 私有命名空间:topic=/node_name/chatter
ros::NodeHandle nh("~");
ros::Publisher pub = nh.advertise<std_msgs::String>("chatter",10);
当我们的topic设置为“/chatter”(带有斜杠)且全局优先级最高,因此topic不会受到namspace和node_name的影响。
- rosrun命令行设置:
除此之外,还可以使用rosrun给该.cpp文件中所有的属性添加相对命名空间,具体形式为:rosrun package_name cpp_name __ns:="hello",运行结果如下所示:

在该节点所在文件中所有的话题、所有的上报参数、所有的节点名称都将加上/hello/的前缀。
注意:__ns:=”global_namespace”是双下划线。
3.3.2 C++实现
1 发布者C++代码
// 1.包含头文件
#include "ros/ros.h"
#include "std_msgs/String.h" //普通文本类型的消息
#include <sstream>
int main(int argc, char *argv[])
{
//设置编码
setlocale(LC_ALL,"");
//2.初始化ROS节点:命名(唯一)
// 参数1和参数2 后期为节点传值会使用
// 参数3 是节点名称,是一个标识符,需要保证运行后,在 ROS 网络拓扑中唯一
ros::init(argc,argv,"talker");
//3.实例化ROS句柄
ros::NodeHandle nh;//该类封装了 ROS 中的一些常用功能
//4.实例化发布者对象
//泛型: 发布的消息类型
//参数1: 要发布到的话题
//参数2: 队列中最大保存的消息数,超出此阀值时,先进的先销毁(时间早的先销毁)
ros::Publisher pub = nh.advertise<std_msgs::String>("chatter",1000);
//5.组织被发布的数据,并编写逻辑发布数据
//数据(动态组织)
std_msgs::String msg;
// msg.data = "你好啊!!!";
std::string msg_front = "Hello 你好!"; //消息前缀
int count = 0; //消息计数器
//逻辑(一秒10次)
ros::Rate r(10);
//节点不死
while (ros::ok())
{
//使用 stringstream 拼接字符串与编号
std::stringstream ss;
ss << msg_front << count;
msg.data = ss.str();
//发布消息
pub.publish(msg);
//加入调试,打印发送的消息
ROS_INFO("发送的消息:%s",msg.data.c_str());
//根据前面制定的发送贫频率自动休眠 休眠时间 = 1/频率;
r.sleep();
count++;//循环结束前,让 count 自增
//暂无应用
ros::spinOnce();
}
return 0;
}
2 订阅者C++代码
// 1.包含头文件
#include "ros/ros.h"
#include "std_msgs/String.h"
void doMsg(const std_msgs::String::ConstPtr& msg_p){
ROS_INFO("我听见:%s",msg_p->data.c_str());
// ROS_INFO("我听见:%s",(*msg_p).data.c_str());
}
int main(int argc, char *argv[])
{
setlocale(LC_ALL,"");
//2.初始化 ROS 节点:命名(唯一)
ros::init(argc,argv,"listener");
//3.实例化 ROS 句柄
ros::NodeHandle nh;
//4.实例化 订阅者 对象
ros::Subscriber sub = nh.subscribe<std_msgs::String>("chatter",10,doMsg);
//5.处理订阅的消息(回调函数)
//6.设置循环调用回调函数
ros::spin();//循环读取接收的数据,并调用回调函数处理
return 0;
}
3 配置CMakeLists.txt
add_executable(Hello_pub
src/Hello_pub.cpp
)
add_executable(Hello_sub
src/Hello_sub.cpp
)
target_link_libraries(Hello_pub
${catkin_LIBRARIES}
)
target_link_libraries(Hello_sub
${catkin_LIBRARIES}
)
执行:在VScode中添加两个终端:
- roscore
- source ./devel/setup.bash
- rosrun 包名 节点名
3.3.3 python实现
1 发布者python代码
#! /usr/bin/env python
#coding=utf-8
#1.导包
import rospy
from std_msgs.msg import String
if __name__ == "__main__":
#2.初始化 ROS 节点:命名(唯一)
rospy.init_node("talker_p")
#3.实例化 发布者 对象
pub = rospy.Publisher("chatter",String,queue_size=10)
#4.组织被发布的数据,并编写逻辑发布数据
msg = String() #创建 msg 对象
msg_front = "hello 你好"
count = 0 #计数器
# 设置循环频率
rate = rospy.Rate(1)
while not rospy.is_shutdown():
#拼接字符串
msg.data = msg_front + str(count)
pub.publish(msg)
rate.sleep()
rospy.loginfo("写出的数据:%s",msg.data)
count += 1
2 订阅者python代码
#! /usr/bin/env python
#coding=utf-8
#1.导包
import rospy
from std_msgs.msg import String
def doMsg(msg):
rospy.loginfo("I heard:%s",msg.data)
if __name__ == "__main__":
#2.初始化 ROS 节点:命名(唯一)
rospy.init_node("listener_p")
#3.实例化 订阅者 对象
sub = rospy.Subscriber("chatter",String,doMsg,queue_size=10)
#4.处理订阅的消息(回调函数)
#5.设置循环调用回调函数
rospy.spin()
3 添加可执行权限
终端下进入scripts 执行: chmod +x *.py
4 配置CMakeLists.txt
catkin_install_python(PROGRAMS
scripts/talker_p.py
scripts/listener_p.py
DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)
执行:在VScode中添加两个终端:
- roscore
- source ./devel/setup.bash
- rosrun 包名 节点名.py
3.3.4 自定义msg文件
1 消息(msg)
在 ROS 通信协议中,数据载体是一个较为重要组成部分,ROS 中通过 std_msgs 封装了一些原生的数据类型,比如:String、Int32、Int64、Char、Bool、Empty.... 但是,这些数据一般只包含一个 data 字段,结构的单一意味着功能上的局限性。
msgs只是简单的文本文件,每行具有字段类型和字段名称,可以使用的字段类型有:
- int8, int16, int32, int64 (或者无符号类型: uint*)
- float32, float64
- string
- time, duration
- other msg files
- variable-length array[] and fixed-length array[C]
ROS中还有一种特殊类型:Header,标头包含时间戳和ROS中常用的坐标帧信息。会经常看到msg文件的第一行具有Header标头。
| Primitive Type | Serialization | C++ | Python2 | Python3 |
| bool (1) | unsigned 8-bit int | uint8_t (2) | bool | |
| int8 | signed 8-bit int | int8_t | int | |
| uint8 | unsigned 8-bit int | uint8_t | int (3) | |
| int16 | signed 16-bit int | int16_t | int | |
| uint16 | unsigned 16-bit int | uint16_t | int | |
| int32 | signed 32-bit int | int32_t | int | |
| uint32 | unsigned 32-bit int | uint32_t | int | |
| int64 | signed 64-bit int | int64_t | long | int |
| uint64 | unsigned 64-bit int | uint64_t | long | int |
| float32 | 32-bit IEEE float | float | float | |
| float64 | 64-bit IEEE float | double | float | |
| string | ascii string (4) | std::string | str | bytes |
| time | secs/nsecs unsigned 32-bit ints | |||
| duration | secs/nsecs signed 32-bit ints | |||
2 编写msg文件
流程:
- 按照固定格式创建 msg 文件
- 编辑配置文件
- 编译生成可以被 Python 或 C++ 调用的中间文件
功能包下新建msg目录,添加文件 Person.msg
string name
uint16 age
float64 height

3 编辑package.xml文件
我们要确保msg文件被转换成为C++,Python和其他语言的源代码: 查看package.xml, 确保它包含以下两条语句:
<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>
注意,在构建的时候,我们只需要"message_generation"。然而,在运行的时候,我们只需要"message_runtime"。
4 编辑CMakeLists.txt文件
CMakeLists.txt编辑 msg 相关配置
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
std_msgs
message_generation
)
# 需要加入 message_generation,必须有 std_msgs
## 配置 msg 源文件
add_message_files(
FILES
Person.msg
)
# 生成消息时依赖于 std_msgs
generate_messages(
DEPENDENCIES
std_msgs
)
#执行时依赖
catkin_package(
# INCLUDE_DIRS include
# LIBRARIES demo02_talker_listener
CATKIN_DEPENDS roscpp rospy std_msgs message_runtime
# DEPENDS system_lib
)
5 编译后的头文件或库文件
编译后的中间文件查看:
C++ 需要调用的中间文件(.../工作空间/devel/include/包名/xxx.h)

Python 需要调用的中间文件(.../工作空间/devel/lib/python3/dist-packages/包名/msg)

3.3.5 C++中使用自定义msg
1 vscode 配置
为了方便代码提示以及避免误抛异常,需要先配置vscode,将前面生成的head文件路径配置进 c_cpp_properties.json 的 includepath属性:
{
"configurations": [
{
"browse": {
"databaseFilename": "",
"limitSymbolsToIncludedHeaders": true
},
"includePath": [
"/opt/ros/noetic/include/**",
"/usr/include/**",
"/xxx/yyy工作空间/devel/include/**" //配置 head 文件的路径
],
"name": "ROS",
"intelliSenseMode": "gcc-x64",
"compilerPath": "/usr/bin/gcc",
"cStandard": "c11",
"cppStandard": "c++17"
}
],
"version": 4
}
2 发布者
#include "ros/ros.h"
#include "demo02_talker_listener/Person.h"
int main(int argc, char *argv[])
{
setlocale(LC_ALL,"");
//1.初始化 ROS 节点
ros::init(argc,argv,"talker_person");
//2.创建 ROS 句柄
ros::NodeHandle nh;
//3.创建发布者对象
ros::Publisher pub = nh.advertise<demo02_talker_listener::Person>("chatter_person",1000);
//4.组织被发布的消息,编写发布逻辑并发布消息
demo02_talker_listener::Person p;
p.name = "sunwukong";
p.age = 2000;
p.height = 1.45;
ros::Rate r(1);
while (ros::ok())
{
pub.publish(p);
p.age += 1;
ROS_INFO("我叫:%s,今年%d岁,高%.2f米", p.name.c_str(), p.age, p.height);
r.sleep();
ros::spinOnce();
}
return 0;
}
3 订阅者
#include "ros/ros.h"
#include "demo02_talker_listener/Person.h"
void doPerson(const demo02_talker_listener::Person::ConstPtr& person_p)
{
ROS_INFO("订阅的人信息:%s, %d, %.2f", person_p->name.c_str(), person_p->age, person_p->height);
}
int main(int argc, char *argv[])
{
setlocale(LC_ALL,"");
//1.初始化 ROS 节点
ros::init(argc,argv,"listener_person");
//2.创建 ROS 句柄
ros::NodeHandle nh;
//3.创建订阅对象
ros::Subscriber sub = nh.subscribe<demo02_talker_listener::Person>("chatter_person",10,doPerson);
//4.回调函数中处理 person
//5.ros::spin();
ros::spin();
return 0;
}
4.配置 CMakeLists.txt
需要添加 add_dependencies 用以设置所依赖的消息相关的中间文件。
add_executable(person_talker(节点名) src/person_talker.cpp)
add_executable(person_listener(节点名) src/person_listener.cpp)
add_dependencies(person_talker ${PROJECT_NAME}_generate_messages_cpp)
add_dependencies(person_listener ${PROJECT_NAME}_generate_messages_cpp)
target_link_libraries(person_talker
${catkin_LIBRARIES}
)
target_link_libraries(person_listener
${catkin_LIBRARIES}
)
5.执行
1.启动 roscore;
2.启动发布节点;
source ./devel/setup.bash
rosrun 包名 节点名
3.启动订阅节点。
source ./devel/setup.bash
rosrun 包名 节点名
4.使用rostopic命令或rqt_graph
3.3.5 python中使用自定义msg
1 vscode配置
为了方便代码提示以及误抛异常,需要先配置vscode,将前面生成的 python 文件路径配置进 settings.json
{
"python.autoComplete.extraPaths": [
"/opt/ros/noetic/lib/python3/dist-packages",
"/xxx/yyy工作空间/devel/lib/python3/dist-packages"
]
}
2 发布者
#! /usr/bin/env python
#coding=utf-8
import rospy
from demo02_talker_listener.msg import Person
if __name__ == "__main__":
#1.初始化 ROS 节点
rospy.init_node("talker_person_p")
#2.创建发布者对象
pub = rospy.Publisher("chatter_person",Person,queue_size=10)
#3.组织消息
p = Person()
p.name = "葫芦瓦"
p.age = 18
p.height = 0.75
#4.编写消息发布逻辑
rate = rospy.Rate(1)
while not rospy.is_shutdown():
pub.publish(p) #发布消息
rate.sleep() #休眠
rospy.loginfo("姓名:%s, 年龄:%d, 身高:%.2f",p.name, p.age, p.height)
3 订阅者
#! /usr/bin/env python
#coding=utf-8
import rospy
from demo02_talker_listener.msg import Person
def doPerson(p):
rospy.loginfo("接收到的人的信息:%s, %d, %.2f",p.name, p.age, p.height)
if __name__ == "__main__":
#1.初始化节点
rospy.init_node("listener_person_p")
#2.创建订阅者对象
sub = rospy.Subscriber("chatter_person",Person,doPerson,queue_size=10)
rospy.spin() #4.循环
4.权限设置
终端下进入 scripts 执行:chmod +x *.py
5.配置 CMakeLists.txt
catkin_install_python(PROGRAMS
scripts/person_talker.py
scripts/person_listener.py
DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)
6.执行
1.启动 roscore;
2.启动发布节点;
source ./devel/setup.bash
rosrun 包名 节点名.py
3.启动订阅节点。
source ./devel/setup.bash
rosrun 包名 节点名.py
3.3.6 相关命令行命令或图形工具
1 rosmsg命令
rosmsg是用于显示有关ROS消息类型的信息的命令行工具。
rosmsg list 列出所有消息
rosmsg package 显示某个功能包下的所有消息ros
rosmsg show 显示消息描述
rosmsg info 显示消息信息
rosmsg md5 显示 md5 加密后的消息
rosmsg packages 列出包含消息的功能包
2 rostopic命令
rostopic命令工具能让你获取有关ROS话题的信息。
rostopic list list active topics
rostopic info print information about active topic
rostopic type print topic or field type
rostopic pub publish data to topic
rostopic echo print messages to screen
rostopic bw display bandwidth used by topic
rostopic hz display publishing rate of topic
3 rqt_graph工具
在ROS系统中,rqt_graph以图形的方式查看节点之间的连接关系,显示节点之间的发布-订阅关系。执行命令:
- rqt_graph
- rosrun rqt_graph rqt_graph

4 rqt_msg工具
在ROS系统中,rqt_msg以图形的方式查看系统中的所有消息数据类型。执行命令:
- rosrun rqt_msg rqt_msg

5 rqt_topic工具
在ROS系统中,rqt_topic以图形的方式查看系统中的所有话题,并进行实时的监测。执行命令:
- rosrun rqt_topic rqt_topic

6 rqt_publisher工具
在ROS系统中,rqt_publisher以图形的方式发布具有固定或计算字段值的任意消息。执行命令:
- rosrun rqt_publisher rqt_publisher

3.3.7 话题通信相关API
1. geometry_msgs
geometry_msgs 是 ROS(Robot Operating System)中一个常用的消息包,用于表示机器人系统中几何形状和变换。它包括了一系列消息类型,如 Point, Vector3, Quaternion, Pose, Twist 等。这些消息类型在机器人定位、导航、控制等任务中非常有用。
1) geometry_msgs/Point.msg
Point 用于表示三维空间中的一个点。它有三个浮点类型的成员变量:x, y, z。
#include <geometry_msgs/Point.h>
geometry_msgs::Point point;
point.x = 1.0;
point.y = 2.0;
point.z = 3.0;
2) geometry_msgs/Vector3.msg
Vector3 用于表示三维空间中的一个向量。它同样有三个浮点类型的成员变量:x, y, z。
#include <geometry_msgs/Vector3.h>
geometry_msgs::Vector3 vector;
vector.x = 1.0;
vector.y = 2.0;
vector.z = 3.0;
3) geometry_msgs/Quaternion.msg
Quaternion 用于表示四元数,用于描述三维空间中的旋转。它有四个浮点类型的成员变量:x, y, z, w。
#include <geometry_msgs/Quaternion.h>
geometry_msgs::Quaternion quaternion;
quaternion.x = 0.0;
quaternion.y = 0.0;
quaternion.z = 0.0;
quaternion.w = 1.0;
4) geometry_msgs/Pose.msg
Pose 用于表示机器人在三维空间中的位置和方向。它包括一个 Point 类型的成员变量 position 和一个 Quaternion 类型的成员变量 orientation。
#include <geometry_msgs/Pose.h>
geometry_msgs::Pose pose;
pose.position.x = 1.0;
pose.position.y = 2.0;
pose.position.z = 3.0;
pose.orientation.x = 0.0;
pose.orientation.y = 0.0;
pose.orientation.z = 0.0;
pose.orientation.w = 1.0;
5) geometry_msgs/Twist.msg
Twist 用于表示机器人的线速度和角速度。它包括两个 Vector3 类型的成员变量:linear 和 angular。
#include <geometry_msgs/Twist.h>
geometry_msgs::Twist twist;
twist.linear.x = 1.0;
twist.linear.y = 0.0;
twist.linear.z = 0.0;
twist.angular.x = 0.0;
twist.angular.y = 0.0;
twist.angular.z = 1.0;
2. C++API
1) NodeHandle类中话题相关功能
- 获得Publisher对象
| template<class M > | |
| advertise (const std::string &topic, uint32_t queue_size, bool latch=false) | |
| Advertise a topic, simple version. More... | |
| template<class M > | |
| advertise (const std::string &topic, uint32_t queue_size, const SubscriberStatusCallback &connect_cb, const SubscriberStatusCallback &disconnect_cb=SubscriberStatusCallback(), const VoidConstPtr &tracked_object=VoidConstPtr(), bool latch=false) | |
- 获得Subscriber对象
| emplate<class M , class C > | |
| subscribe (const std::string &topic, uint32_t queue_size, const boost::function< void(C)> &callback, const VoidConstPtr &tracked_object=VoidConstPtr(), const TransportHints &transport_hints=TransportHints()) | |
| template<class M > | |
| subscribe (const std::string &topic, uint32_t queue_size, const boost::function< void(const boost::shared_ptr< M const > &)> &callback, const VoidConstPtr &tracked_object=VoidConstPtr(), const TransportHints &transport_hints=TransportHints()) | |
| template<class M > | |
| subscribe (const std::string &topic, uint32_t queue_size, void(*fp)(const boost::shared_ptr< M const > &), const TransportHints &transport_hints=TransportHints()) | |
| template<class M > | |
| subscribe (const std::string &topic, uint32_t queue_size, void(*fp)(M), const TransportHints &transport_hints=TransportHints()) | |
| template<class M , class T > | |
| subscribe (const std::string &topic, uint32_t queue_size, void(T::*fp)(const boost::shared_ptr< M const > &) const, const boost::shared_ptr< T > &obj, const TransportHints &transport_hints=TransportHints()) | |
| template<class M , class T > | |
| subscribe (const std::string &topic, uint32_t queue_size, void(T::*fp)(const boost::shared_ptr< M const > &) const, T *obj, const TransportHints &transport_hints=TransportHints()) | |
| template<class M , class T > | |
| subscribe (const std::string &topic, uint32_t queue_size, void(T::*fp)(const boost::shared_ptr< M const > &), const boost::shared_ptr< T > &obj, const TransportHints &transport_hints=TransportHints()) | |
| template<class M , class T > | |
| subscribe (const std::string &topic, uint32_t queue_size, void(T::*fp)(const boost::shared_ptr< M const > &), T *obj, const TransportHints &transport_hints=TransportHints()) | |
| template<class M , class T > | |
| subscribe (const std::string &topic, uint32_t queue_size, void(T::*fp)(M) const, const boost::shared_ptr< T > &obj, const TransportHints &transport_hints=TransportHints()) | |
| template<class M , class T > | |
| subscribe (const std::string &topic, uint32_t queue_size, void(T::*fp)(M) const, T *obj, const TransportHints &transport_hints=TransportHints()) | |
| and the const version More... | |
| template<class M , class T > | |
| subscribe (const std::string &topic, uint32_t queue_size, void(T::*fp)(M), const boost::shared_ptr< T > &obj, const TransportHints &transport_hints=TransportHints()) | |
| template<class M , class T > | |
| subscribe (const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints()) | |
2) Publisher类
Manages an advertisement on a specific topic.
A Publisher should always be created through a call to NodeHandle::advertise(), or copied from one that was. Once all copies of a specific Publisher go out of scope, any subscriber status callbacks associated with that handle will stop being called. Once all Publishers for a given topic go out of scope the topic will be unadvertised.
- 发布对象获取
publisher advertise(const std::string& topic, uint32_t queue_size, bool latch = false)
* 在 ROS master 注册并返回一个发布者对象,该对象可以发布消息
* 使用示例如下:
* ros::Publisher pub = handle.advertise<std_msgs::Empty>("my_topic", 1);
* param topic 发布消息使用的话题
* param queue_size 等待发送给订阅者的最大消息数量
* param latch (optional) 如果为 true,该话题发布的最后一条消息将被保存,并且后期当有订阅者连接时会将该消息发送给订阅者
* return 调用成功时,会返回一个发布对象
- 消息发布函数
void publish(const M& message) const
| boost::function< void( const SubscriberLinkPtr &)> | |
| uint32_t | getNumSubscribers () const |
| Returns the number of subscribers that are currently connected to this Publisher. More... | |
| std::string | getTopic () const |
| Returns the topic that this Publisher will publish on. More... | |
| bool | isLatched () const |
| Returns whether or not this topic is latched. More... | |
| operator void * () const | |
| bool | operator!= (const Publisher &rhs) const |
| bool | |
| bool | operator== (const Publisher &rhs) const |
| template<typename M > | |
| void | publish (const boost::shared_ptr< M > &message) const |
| Publish a message on the topic associated with this Publisher. More... | |
| template<typename M > | |
| void | publish (const M &message) const |
| Publish a message on the topic associated with this Publisher. More... | |
| Publisher () | |
| void | shutdown () |
| Shutdown the advertisement associated with this Publisher. This method usually does not need to be explicitly called, as automatic shutdown happens when all copies of this Publisher go out of scope This method overrides the automatic reference counted unadvertise, and does so immediately. | |
| ~Publisher () | |
3) Subscriber类
Manages an subscription callback on a specific topic.
A Subscriber should always be created through a call to NodeHandle::subscribe(), or copied from one that was. Once all copies of a specific Subscriber go out of scope, the subscription callback associated with that handle will stop being called. Once all Subscriber for a given topic go out of scope the topic will be unsubscribed.
- 订阅对象获取
Subscriber subscribe(const std::string& topic, uint32_t queue_size, void(*fp)(const boost::shared_ptr<M const>&), const TransportHints& transport_hints = TransportHints())
该函数将根据给定的话题在ROS master注册,并自动连接相同主题的发布方,每接收到一条消息,都会调用回调函数,并且传入该消息的共享指针,该消息不能被修改,因为可能其他订阅对象也会使用该消息。
void callback(const std_msgs::Empty::ConstPtr& message)
{
}
ros::Subscriber sub = handle.subscribe("my_topic", 1, callback);
* param M [template] M 是指消息类型
* param topic 订阅的话题
* param queue_size 消息队列长度,超出长度时,头部的消息将被弃用
* param fp 当订阅到一条消息时,需要执行的回调函数
* return 调用成功时,返回一个订阅者对象,失败时,返回空对象
| uint32_t | getNumPublishers () const |
| Returns the number of publishers this subscriber is connected to. More... | |
| std::string | getTopic () const |
| operator void * () const | |
| bool | operator!= (const Subscriber &rhs) const |
| bool | operator< (const Subscriber &rhs) const |
| operator= (const Subscriber &other)=default | |
| bool | operator== (const Subscriber &rhs) const |
| void | shutdown () |
| Unsubscribe the callback associated with this Subscriber. This method usually does not need to be explicitly called, as automatic shutdown happens when all copies of this Subscriber go out of scope This method overrides the automatic reference counted unsubscribe, and immediately unsubscribes the callback associated with this Subscriber | |
| Subscriber () | |
| Subscriber (const Subscriber &rhs) | |
| ~Subscriber () |
4) shared_ptr指针
typedef boost::shared_ptr< ::test01::Person_<ContainerAllocator> > Ptr;
typedef boost::shared_ptr< ::test01::Person_<ContainerAllocator> const> ConstPtr;
当然shared_ptr作为一种智能指针,也拥有和auto_ptr一些相似的性质。它们本质上都是类,但是使用起来像指针。它们都是为了解决防止内存泄漏的解决方案。
Shared_ptr和auto_ptr最大的区别就是,shared_ptr解决了指针间共享对象所有权的问题。所以满足了容器的要求,可以用于容器中。
boost::detail::sp_dereference< T >::type operator* () const
{
return *px;
}
boost::detail::sp_member_access< T >::type operator-> () const
{
return px;
}
3. Python API
1) Publisher类
- 发布对象获取
class Publisher(Topic):
def __init__(self, name, data_class, subscriber_listener=None, tcp_nodelay=False, latch=False, headers=None, queue_size=None):
"""
Constructor
@param name: 话题名称
@type name: str
@param data_class: 消息类型
@param latch: 如果为 true,该话题发布的最后一条消息将被保存,并且后期当有订阅者连接时会将该消息发送给订阅者
@type latch: bool
@param queue_size: 等待发送给订阅者的最大消息数量
@type queue_size: int
- 消息发布函数
def publish(self, *args, **kwds)
2) Subscriber类
- 订阅对象获取
class Subscriber(Topic):
def __init__(self, name, data_class, callback=None, callback_args=None,
queue_size=None, buff_size=DEFAULT_BUFF_SIZE, tcp_nodelay=False):
"""
Constructor.
@param name: 话题名称
@type name: str
@param data_class: 消息类型
@type data_class: L{Message} class
@param callback: 处理订阅到的消息的回调函数
@type callback: fn(msg, cb_args)
大家一定要边看边动手,知识很简单但是得实践起来,不然真的很容易忘记!!
如果这篇文章对你有帮助的话,请给博主一个免费的赞鼓励一下吧~ 💓

2774

被折叠的 条评论
为什么被折叠?



