2026.7.30-初入ros+slam+opencv第六天-学习rosbag+发布者cpp代码
一.Rosbag1.概念rosbag ROS自带工具可以把运行过程中的所有话题数据保存到bag文件后续可以离线回放bag文件复现当时全部传感器数据流。2.适用场景保存相机图像、小车坐标、激光雷达、IMU 传感器数据离线复现 bug算法反复测试3.实操基础命令rosbag record录制话题数据rosbag info查看数据包信息rosbag play离线回放数据1.启动roscoreroscore2.启动小乌龟仿真rosrun turtlesim turtlesim_node3.启动键盘rosrun turtlesim turtle_teleop_key4.录制所有话题数据创建bag数据包文件夹mkdir-p~/bag_datacd~/bag_data录制话题rosbag record-a-a record all录制所有话题5.切换到键盘终端 按方向键控制乌龟移动 10~20 秒然后按CtrlC停止录制。6.查看bag文件信息rosbag info 文件名.bag按tab键补齐7.数据回放测试关闭键盘终端 其他节点不变 在bag目录下执行回放指令rosbag play xxx.bay按Tab键补齐乌龟会自动重复之前手动控制的运动轨迹8.录制指定话题rosbag record-Oturtle_bag.bag /turtle1/cmd_vel /turtle1/pose理论上可以指定无数个话题录制只录制速度指令、乌龟坐标两个话题减小文件体积。二.发布者代码#includeros/ros.h#includestd_msgs/String.h// 引入 ROS 标准字符串消息类型。// 我们要发布文本消息 hi!必须包含这个头文件// 对应消息std_msgs/String。intmain(intargc,char**argv){ros::init(argc,argv,test_node);// 初始化节点ros::init(argc,argv,节点名称)printf(Hello robot!\n);ros::NodeHandle nh;// 创建发布者话题名 test_topic队列10ros::Publisher pubnh.advertisestd_msgs::String(test_topic,10);// ros::Publisher pub nh.advertise模板参数(话题名称,消息队列长度);// 设置发送频率 1Hz1秒发一次ros::Raterate(1);// 创建频率控制器对象 rate// 括号内 1 1Hz代表希望循环每 1 秒执行一轮。while(ros::ok()){std_msgs::String msg;// 定义消息对象 msg// std_msgs::String 是 ROS 内置结构体内部只有一个成员 data用来存放字符串。// 此时 msg 是空消息。msg.datahi!;pub.publish(msg);// 发布消息// 把填充好数据的 msg发送到话题 /test_topic// 任何订阅该话题的终端 / 节点立刻收到这条数据。// 休眠控制频率防止全速死循环rate.sleep();}return0;}#includeros/ros.h引入 ROS 核心头文件。所有 ROS 程序必备提供ros::init、ros::NodeHandle、ros::Publisher、ros::Rate 等基础类与函数。#includestd_msgs/String.h引入 ROS 标准字符串消息类型。我们要发布文本消息 hi!必须包含这个头文件对应消息std_msgs/String。int main(int argc, char **argvC 程序入口函数。argc命令行参数个数argv命令行参数数组ros::init 需要读取这两个参数完成节点初始化。ros::init(argc,argv,“test_node”);初始化 ROS 节点参数说明argc、argv传入命令行参数“test_node”节点名称作用向 ROS Master 注册当前程序名字为 test_node同一个网络不能同时启动两个同名节点。printf(“Hello robot!\n”);控制台打印字符串程序启动时输出一句话方便观察节点是否成功运行。ros::NodeHandle nh;创建节点句柄 nh相当于当前程序和 ROS 系统通信的 “通行证 / 接口”。后续创建发布者、订阅者、读写参数全部依靠 NodeHandle。ros::Publisher pub nh.advertisestd_msgs::String(“test_topic”,10);创建发布者对象 pub逐段拆分nh.advertise()通过句柄向 Master 注册发布话题std_msgs::String模板参数指定这条话题传输的消息类型字符串“test_topic”话题名称订阅节点需要使用同名话题才能接收数据10消息队列长度如果消息发送太快订阅方来不及接收最多缓存 10 条超出直接丢弃。ros::Rate rate(1);创建频率控制器对象 rate括号内 1 1Hz代表希望循环每 1 秒执行一轮。while(ros::ok())ROS 标准主循环ros::ok() 判断条件返回 true节点正常运行返回 false按下 CtrlC 关闭节点 / 程序异常退出一旦按下终端 CtrlC循环立刻终止。std_msgs::String msg;定义消息对象 msgstd_msgs::String 是 ROS 内置结构体内部只有一个成员 data用来存放字符串。此时 msg 是空消息。msg.data“hi!”;给消息内部成员赋值。把字符串 “hi!” 存入消息的 data 字段准备发送。pub.publish(msg);发布消息把填充好数据的 msg发送到话题 /test_topic任何订阅该话题的终端 / 节点立刻收到这条数据。rate.sleep();按照预先设置的 1Hz 进行休眠。自动计算本轮循环剩余等待时间保证整体循环稳定 1s 一次。缺少这一行循环全速疯狂执行CPU 占满。#includeros/ros.h引入 ROS 核心头文件。所有 ROS 程序必备提供ros::init、ros::NodeHandle、ros::Publisher、ros::Rate 等基础类与函数。#includestd_msgs/String.h引入 ROS 标准字符串消息类型。我们要发布文本消息 hi!必须包含这个头文件对应消息std_msgs/String。int main(int argc, char **argv)C 程序入口函数。argc命令行参数个数argv命令行参数数组ros::init 需要读取这两个参数完成节点初始化。ros::init(argc,argv,“test_node”);初始化 ROS 节点参数说明argc、argv传入命令行参数“test_node”节点名称作用向 ROS Master 注册当前程序名字为 test_node同一个网络不能同时启动两个同名节点。printf(“Hello robot!\n”);控制台打印字符串程序启动时输出一句话方便观察节点是否成功运行。ros::NodeHandle nh;创建节点句柄 nh相当于当前程序和 ROS 系统通信的 “通行证 / 接口”。后续创建发布者、订阅者、读写参数全部依靠 NodeHandle。ros::Publisher pub nh.advertisestd_msgs::String(“test_topic”,10);创建发布者对象 pub逐段拆分nh.advertise()通过句柄向 Master 注册发布话题std_msgs::String模板参数指定这条话题传输的消息类型字符串“test_topic”话题名称订阅节点需要使用同名话题才能接收数据10消息队列长度如果消息发送太快订阅方来不及接收最多缓存 10 条超出直接丢弃。ros::Rate rate(1);创建频率控制器对象 rate括号内 1 1Hz代表希望循环每 1 秒执行一轮。while(ros::ok())ROS 标准主循环ros::ok() 判断条件返回 true节点正常运行返回 false按下 CtrlC 关闭节点 / 程序异常退出一旦按下终端 CtrlC循环立刻终止。std_msgs::String msg;定义消息对象 msgstd_msgs::String 是 ROS 内置结构体内部只有一个成员 data用来存放字符串。此时 msg 是空消息。msg.data“hi!”;给消息内部成员赋值。把字符串 “hi!” 存入消息的 data 字段准备发送。pub.publish(msg);发布消息把填充好数据的 msg发送到话题 /test_topic任何订阅该话题的终端 / 节点立刻收到这条数据。rate.sleep();按照预先设置的 1Hz 进行休眠。自动计算本轮循环剩余等待时间保证整体循环稳定 1s 一次。缺少这一行循环全速疯狂执行CPU 占满。1. #includeros/ros.h引入 ROS 核心头文件。所有 ROS 程序必备提供ros::init、ros::NodeHandle、ros::Publisher、ros::Rate 等基础类与函数。#includestd_msgs/String.h引入 ROS 标准字符串消息类型。我们要发布文本消息 hi!必须包含这个头文件对应消息std_msgs/String。int main(int argc, char **argv[])C 程序入口函数。argc命令行参数个数argv命令行参数数组ros::init 需要读取这两个参数完成节点初始化。⚠️小笔误标准写法 char **argv不要多加[]编译不会报错但是不规范。ros::init(argc,argv,“test_node”);初始化 ROS 节点参数说明argc、argv传入命令行参数“test_node”节点名称作用向 ROS Master 注册当前程序名字为 test_node❗同一个网络不能同时启动两个同名节点。printf(“Hello robot!\n”);控制台打印字符串程序启动时输出一句话方便观察节点是否成功运行。ros::NodeHandle nh;创建节点句柄 nh相当于当前程序和 ROS 系统通信的 “通行证 / 接口”。后续创建发布者、订阅者、读写参数全部依靠 NodeHandle。ros::Publisher pub nh.advertisestd_msgs::String(“test_topic”,10);创建发布者对象 pub逐段拆分nh.advertise()通过句柄向 Master 注册发布话题std_msgs::String模板参数指定这条话题传输的消息类型字符串“test_topic”话题名称订阅节点需要使用同名话题才能接收数据10消息队列长度如果消息发送太快订阅方来不及接收最多缓存 10 条超出直接丢弃。ros::Rate rate(1);创建频率控制器对象 rate括号内 1 1Hz代表希望循环每 1 秒执行一轮。while(ros::ok())ROS 标准主循环ros::ok() 判断条件返回 true节点正常运行返回 false按下 CtrlC 关闭节点 / 程序异常退出一旦按下终端 CtrlC循环立刻终止。std_msgs::String msg;定义消息对象 msgstd_msgs::String 是 ROS 内置结构体内部只有一个成员 data用来存放字符串。此时 msg 是空消息。msg.data“hi!”;给消息内部成员赋值。把字符串 “hi!” 存入消息的 data 字段准备发送。pub.publish(msg);发布消息把填充好数据的 msg发送到话题 /test_topic任何订阅该话题的终端 / 节点立刻收到这条数据。rate.sleep();按照预先设置的 1Hz 进行休眠。自动计算本轮循环剩余等待时间保证整体循环稳定 1s 一次。缺少这一行循环全速疯狂执行CPU 占满。