ros msg head 中的seq被重写为从0开始。

来源:互联网 发布:js小写转化为大写 编辑:程序博客网 时间:2024/06/06 02:44

ros msg head 中的seq被重写为从0开始。

Why does ROS overwrite my sequence number?

asked Feb 13 '13

Max Pfingsthorn gravatar image

updated Jan 29 '14

ngrennan gravatar image

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/Imagemessage 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 ...
(more)
add a comment

1 Answer

Sort by »oldestnewestmost voted
6

answered Feb 13 '13

dornhege gravatar image

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.

link

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.

Stephen Vidas gravatar imageStephen Vidas ( Jul 19 '13 )

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.

dornhege gravatar imagedornhege ( Jul 19 '13 )
2

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.

Max Pfingsthorn gravatar imageMax Pfingsthorn ( Jul 24 '13 )
1

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

tfoote gravatar imagetfoote ( Nov 11 '13 )

The link https://code.ros.org/trac/ros/ticket/... doesn't seem to be working (I'll keep searching migrated link if any).

130s gravatar image130s ( Oct 21 '14 )
add a comment
原创粉丝点击