ros msg head 中的seq被重写为从0开始。
来源:互联网 发布:js小写转化为大写 编辑:程序博客网 时间:2024/06/06 02:44
ros msg head 中的seq被重写为从0开始。
Why does ROS overwrite my sequence number?
Why does ROS overwrite my sequence number?
I have noticed that the ROS Publishers seem to overwrite the sequence number set by me in the message header (std_msgs/Header
). This only happens if the message is one known by ROS (such as sensor_msgs/Image
) but not if it is one I defined myself.
What happens is that I set the header.seq field in e.g. the sensor_msgs/Image
message to something, but during publishing, ROS overwrites this number with a counter which is apparently kept in the ros::Publisher
class itself. So, when I subscribe to the message, sequence numbers of sensor_msgs/Image
always start with 0 and count up by one from here, no matter what I set in the header before my call to ros::Publisher::publish()
.
I dug a little deeper and found that I can prevent this by using ros::AdvertiseOptions
.
ros::NodeHandle n;ros::AdvertizeOptions op = ros::AdvertiseOptions::create<sensor_msgs::Image>("/foo", 1, &connected, &disconnected, ros::VoidPtr(), NULL);op.has_header = false;ros::Publisher pub = n.advertise(op);
The callbacks unfortunately have to be defined, I was unable to just give NULL
...
void connected(const ros::SingleSubscriberPublisher&) {}void disconnected(const ros::SingleSubscriberPublisher&) {}
This way, my sequence numbers persist and are not overwritten by the ros::Publisher::publish()
call later.
My question is, why does ROS not trust me to set the sequence number as I want it?
My test publisher:
#include <stdio.h>#include <stdlib.h>#include <time.h>#include <ros ros.h="">#include <sensor_msgs image.h="">// dummy callbacksvoid connected(const ros::SingleSubscriberPublisher&) {}void disconnected(const ros::SingleSubscriberPublisher&) {}int main(int argc, char** argv) { srand ( time(NULL) ); ros::init(argc, argv, "test_pub"); ros::NodeHandle n; ros::Publisher pub_messed_up = n.advertise<sensor_msgs::image>("/foo", 1); ros::AdvertiseOptions op = ros::AdvertiseOptions::create<sensor_msgs::image>("/bar", 1, &connected, &disconnected, ros::VoidPtr(), NULL); op.has_header = false; ros::Publisher pub_ok = n.advertise(op); ros::Rate r(1); while(ros::ok()) { sensor_msgs::Image msg; msg.header.seq = rand(); msg.header.stamp = ros::Time::now(); msg.header.frame_id = "foo"; msg.height = msg.header.seq; pub_messed_up.publish(msg); pub_ok.publish(msg); r.sleep(); }}
My test subscriber:
#include <ros ros.h="">#include <sensor_msgs image.h="">void callback( const sensor_msgs::ImageConstPtr& msg ) { ROS_INFO("BAD: image seq is: %10u, should be %10u", msg->header.seq, msg->height);}void callback2( const sensor_msgs::ImageConstPtr& msg ) { ROS_INFO("OK : image seq is: %10u, should be %10u", msg->header.seq, msg->height);}int main(int argc, char** argv) { ros::init(argc, argv, "test_sub"); ros::NodeHandle n; ros::Subscriber sub = n.subscribe("/foo", 1, &callback); ros::Subscriber sub2 = n.subscribe("/bar", 1, &callback2); ros::spin();}
Output:
[ INFO] [1360774481.858622442]: OK : image seq is: 180403487, should be 180403487[ INFO] [1360774481.858737733]: BAD: image seq is: 3, should be 180403487[ INFO] [1360774481.958441959]: OK : image seq is: 1993875195, should be 1993875195[ INFO] [1360774481.958503343]: BAD: image seq is: 4, should be 1993875195[ INFO] [1360774482.058392020]: OK : image seq is: 458683548, should be 458683548[ INFO] [1360774482.058461137]: BAD: image seq is: 5, should be 458683548[ INFO] [1360774482.158405818]: OK : image seq ...
1 Answer
The sequence number is the sequence number of published messages. You are not supposed to change that or set that yourself as then you could only do it exactly as is or wrong (according to what it is supposed to be). This is why you can't change it nicely.
Your fix just tells ROS that there is no place (header) to store the sequence number and thus it can't supply one. If you need some unique number in your custom message, you should just define another message field.
I can't really see a use case, where you'd need to set a user-defined sequence number in an sensor_msgs/Image message that is used by a standard ROS program.
Comments
I'm working on a sensor fusion application where node A subscribes to an image stream, and outputs a pose estimate for each image. Node B also subscribes to the image stream, along with the pose estimates from node A, so it's useful if it can simply match the seq # to determine image-pose pairs.
If you have a sequence number, you have a header. Use the time stamp in the header to synchronize messages from the same origin. There is even a message filter that does this for you.
If ROS is so clever, why doesn't it know if a message has a header or not? Only core messages show this behavior by default, which makes it hard to track down and inconsistent. Also, this is the only thing ROS changes when I publish a message, so it's very unintuitive.
Sequence numbers were deprecated from the specification 4 years ago. But existing behavior was left for backwards compatibility. https://code.ros.org/trac/ros/ticket/1965
The link https://code.ros.org/trac/ros/ticket/... doesn't seem to be working (I'll keep searching migrated link if any).
- ros msg head 中的seq被重写为从0开始。
- ROS msg
- ros定义msg消息
- ROS Kinetic: msg & srv
- 机器人操作系统ROS笔记--从仿真开始
- ROS——从turtle开始
- 创建ROS msg 和 srv
- ROS的msg和srv
- ROS中几种常用的msg
- (四)创建ROS msg 和 srv
- 创建ROS的msg和srv
- (四)创建ROS msg 和 srv
- ROS:定制自己的消息类型msg
- ROS:定制自己的消息类型msg
- 7、创建ROS msg和srv
- ROS:定制自己的消息类型msg
- ROS定制并使用自己的msg
- ROS自定义msg类型及使用
- Tarjan算法--求无向图的割点和桥
- 小感
- 线段树--数据结构(建树,查询区间和&&最大值&&最小值)
- Spring mvc中把表单数据当做一个对象提交给controller的实现
- Java动态代理机制详解
- ros msg head 中的seq被重写为从0开始。
- 自已动手编译Linux系统-基于ALFS的LFS8.0实践(三)
- Apache Commons Pool2 源码分析
- win7字符界面的目录切换
- java 字节输入流、字节输出流、字节缓冲流
- 2482二叉排序树
- 深度学习论文和开源代码
- 机械臂(4)--正向求解
- 公共CBB实现方案思考