ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
1

What is the ros::spin rate?

asked 2019-02-13 01:03:45 -0600

Pujie gravatar image

Hi, I need to run a moving robot in simulation and I need to know the translation and rotation of this robot. I was thinking to use the translation = linear.velocity *dt, and rotation = linear.velocity.z * dt. But I don't know what dt is. I have a subscriber with ros::spin() to subscriber the /cmd_vel topic.

  1. How can I get the dt?

  2. Does the dt strictly equal to the (1/publisher node's rate) ?

Thank you!

edit retag flag offensive close merge delete

Comments

I can also use the data in /odom. But I still want to know the dt. Thank you!

Pujie gravatar image Pujie  ( 2019-02-13 01:05:21 -0600 )edit

2 Answers

Sort by ยป oldest newest most voted
3

answered 2019-02-13 03:40:12 -0600

gvdhoorn gravatar image

I need to know the translation and rotation of this robot. I was thinking to use the translation = linear.velocity *dt, and rotation = linear.velocity.z * dt. But I don't know what dt is. I have a subscriber with ros::spin() to subscriber the /cmd_vel topic.

The cmd_vel topic is typically used to command new velocity setpoints to a mobile base. It doesn't carry any state information in those cases -- only desired state. It would seem strange to me to use that to derive actual state of your robot, unless you don't care about discrepancies between commanded and actual state of course.

I can also use the data in /odom.

The odom topic (nav_msgs/Odometry) does carry information about the actual state of your system. Both position and velocity, so the integration step has already been done for you (and possibly in a more advanced and robust way than simply integration velocity over a time interval, but that depends on the driver used and how that is written).

But I still want to know the dt.

For message types that include a header (such as Odom and TwistStamped), I would advise you to make use of the stamp field in the header. If the publisher has correctly populated the fields, the stamp field should correspond to when the measurement (or calculation) that was used to populate the fields in the message associated with the timestamp took place (or was performed).

In that case, dt would simply be msg1.header.stamp - msg0.header.stamp. As long as you keep a single-message history in your receiving node, you can calculate the dt between two successive messages that way.

For messages that don't have headers (such as a regular Twist), you have two options:

  1. use ros::Time::now() to approximate the time your code received the message as shown by @HankYuan in his answer
  2. use a callback for a ros::MessageEvent<M> instead of the message type itself and use the receipt time as an approximation of when the message was received by the middleware

Refer to wiki/roscpp/Overview/Publishers and Subscribers: Subscribing to a Topic - MessageEvent for information on MessageEvent.

edit flag offensive delete link more

Comments

Thank you very much! This helps a lot!

Pujie gravatar image Pujie  ( 2019-02-13 09:50:14 -0600 )edit

One thing to keep in mind: in message "processing pipelines" it's customary to keep the header.stamp of the source or origin message that was fed into the pipeline. All subsequent processing steps copy the timestamp of the incoming msgs into the outgoing msgs.

An example would be image ..

gvdhoorn gravatar image gvdhoorn  ( 2019-02-13 09:54:25 -0600 )edit

.. processing pipelines: the original image message gets a timestamp and every subsequent operation on that image results in a new msg which gets the same timestamp. Results of object recognition -- in a new msg -- also get the same timestamp.

This may complicate dt(..)calculation, but ..

gvdhoorn gravatar image gvdhoorn  ( 2019-02-13 09:56:21 -0600 )edit

.. but is often done to allow the use of packages like message_filters to keep related (sensor) data temporally linked without having to create large messages that carry all results of the processing pipeline.

gvdhoorn gravatar image gvdhoorn  ( 2019-02-13 09:57:39 -0600 )edit

@gvdhoorn. Thank you. You mean there is some kind of time delay if the message has too much data? Do you think the message from 2d Lidar will be influenced?

Pujie gravatar image Pujie  ( 2019-02-13 11:22:21 -0600 )edit

No, I meant to say that the stamp field does not always represent the time at which a msg was published by the preceding publisher (ie: the one that published that msg "last", in a manner of speaking).

It could be an older timestamp -- preserved -- such that temporal correlations can be saved.

gvdhoorn gravatar image gvdhoorn  ( 2019-02-13 13:12:04 -0600 )edit

Got it ! Thank you!

Pujie gravatar image Pujie  ( 2019-02-13 21:42:59 -0600 )edit
1

answered 2019-02-13 02:14:35 -0600

HankYuan gravatar image

updated 2019-02-13 02:20:24 -0600

Hi,

  1. You can add a member variable in your class to save the last time when you get to msg.

    class moving_robot{
    public:
        moving_robot() : last_time_(ros::Time::now())
        {
            sub = nh.subscribe("/cmd_vel", 10, &moving_robot::callback, this);
        }
    private:
        void callback(const geometry_msgs::Twist::ConstPtr &msg)
        {
            ros::Time curr_time = ros::Time::now();
            double dt = (curr_time - last_time_).toSec();
            ROS_INFO_STREAM("dt: " << dt);
            last_time_ = curr_time;
            // other works
        }
        ros::NodeHandle nh;
        ros::Subscriber sub;
        ros::Time last_time_;  };
    
  2. Yes, it depends on the topic frequency which you subscribe to and the callback function running time

Hope this will help!

edit flag offensive delete link more

Comments

Thank you for help!

Pujie gravatar image Pujie  ( 2019-02-13 09:49:32 -0600 )edit

Question Tools

2 followers

Stats

Asked: 2019-02-13 01:03:45 -0600

Seen: 2,007 times

Last updated: Feb 13 '19