ROS:自定义消息类型话题的发布及订阅
手把手教你编写自定义消息类型话题的发布及订阅
本次的上机实验以解析GPGGA报文发布为例,题设为:
在ROS工作空间里新建功能包text,并创建自定义msg:GPGGA.msg;
创建节点publish,该节点发布一个话题,话题名称为“/simurobot/yourname/”,话题的消息类型为:msg:GPGGA.msg
在节点C++源代码中解析GPGGA报文,并将对应信息赋值给GPGGA.msg,发布话题内容,将发布内容打印到终端;
发送频率10hz。
说明:
1、ROS为我存放各个上机实验的文件目录
2、代码有什么问题可以在评论区提出或者不要问我
3、文章编写完成后又结果演示、代码没问题
4、通俗易懂、粘贴可用
第一步 创建功能包:
mkdir -p ROS/shangji41/src
cd ROS/shangji41/src
catkin_init_workspace
catkin_create_pkg text roscpp std_msgs
cd text
mkdir msg
cd msg
vi GPGGA.msg
其中GPGGA.msg文件内容为
string time
float64 latitude
string lat_direction
float64 longitude
string lon_direction
int8 fix_quality
uint8 num_satellites
float64 hdop
float64 altitude
char altitude_units
float64 geoid_height
char geoid_height_units
第二步CMakeLists.txt编辑 msg 相关配置
find_package(catkin REQUIRED COMPONENTS
geometry_msgs
roscpp
std_msgs
message_generation
)
add_message_files(
FILES
GPGGA.msg
)
generate_messages(
DEPENDENCIES
std_msgs
)
package.xml中添加编译依赖与执行依赖
<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>
第三步 修改完成后进入工作空间编译
cd ~/ROS/shangji41
catkin_make
编译完成后可以在/ROS/shangji41/devel/include/text/目录下看到GPGGA.h文件
第四步 编写发布者程序
在text
功能包的src
文件夹下创建publish.cpp
文件,并添加以下内容:
cd ~/ROS/shangji41/src/text/src
vi publish.cpp
publish.cpp
#include <ros/ros.h>
#include <text/GPGGA.h>
#include <sstream>
#include <iomanip>
// 回调函数来解析GPGGA报文并发布消息
void parseGPGGA(const std::string& gpgga_str, text::GPGGA& gpgga_msg) {
std::istringstream iss(gpgga_str);
std::string token;
// 跳过GPGGA头部
getline(iss, token, ',');
// 解析时间
getline(iss, gpgga_msg.time, ',');
// 解析纬度
getline(iss, token, ',');
gpgga_msg.latitude = std::stod(token);
// 解析纬度方向
getline(iss, gpgga_msg.lat_direction, ',');
// 解析经度
getline(iss, token, ',');
gpgga_msg.longitude = std::stod(token);
// 解析经度方向
getline(iss, gpgga_msg.lon_direction, ',');
// 解析其他字段
for (int i = 0; i < 9; ++i) {
getline(iss, token, ',');
// 这里需要按照GPGGA报文格式添加解析代码
// 这里只是一个示例,具体实现需要根据GPGGA报文的实际格式
// 例如,fix_quality是int8,num_satellites是uint8
if (i == 2) {
gpgga_msg.fix_quality = static_cast<int8_t>(std::stoi(token));
} else if (i == 3) {
gpgga_msg.num_satellites = static_cast<uint8_t>(std::stoi(token));
}
// 添加其他字段的解析
}
}
int main(int argc, char **argv) {
// 初始化ROS节点
ros::init(argc, argv, "send_gpgga");
// 创建节点句柄
ros::NodeHandle nh;
// 创建发布者,发布GPGGA消息
ros::Publisher gpgga_pub = nh.advertise<text::GPGGA>("/simurobot/yourname/gpgga", 10);
// 设置发布频率
ros::Rate rate(10);
// GPGGA报文
std::string gpgga_str = "$GPGGA,121252.000,3937.3032,N,11611.6046,E,1,05,2.0,45.9,M,-5.7,M,,0000*77";
// 循环发布GPGGA消息
while (ros::ok()) {
// 创建GPGGA消息实例
text::GPGGA gpgga_msg;
// 解析GPGGA报文并赋值给消息
parseGPGGA(gpgga_str, gpgga_msg);
// 发布GPGGA消息
gpgga_pub.publish(gpgga_msg);
// 打印发布内容到终端
ROS_INFO_STREAM("Publishing GPGGA message: "
<< "Time: " << gpgga_msg.time
<< ", Latitude: " << gpgga_msg.latitude
<< ", Longitude: " << gpgga_msg.longitude
<< ", Fix Quality: " << static_cast<int>(gpgga_msg.fix_quality)
<< ", Num Satellites: " << static_cast<int>(gpgga_msg.num_satellites));
// 按照设定的频率休眠
rate.sleep();
}
return 0;
}
第五步 CMakeLists.txt配置.cpp文件:
在CMakeLists.txt中添加以下内容
add_executable(publish
src/publish.cpp
)
target_link_libraries(publish
${catkin_LIBRARIES}
)
第六步 编译节点
cd ~/ROS/shangji41
catkin_make
第七步 运行节点:
编译完成后,你可以通过以下命令来运行你的节点
source ~/catkin_ws/devel/setup.bash # 假设你的工作空间是~/catkin_ws
rosrun text publish
在新终端中运行
roscore
在工作终端空间中运行
source devel/setup.bash
rosrun text publish
可以看到将发布内容打印到终端;