Ask Your Question

Expected behaviour when cmd_vel == 0

asked 2019-09-09 08:16:27 -0600

georgeknowlden gravatar image

I've just finished writing a hardware interface for my custom robot. It finally performs as hoped, but I'm not sure what cmd_vel == 0 m/s should actually cause. Does it mean:

  1. Stop powering the robot's wheels, allowing it to coast downhill (i.e. robot is not powered)
  2. Hold the robot still, as if it were being actively braked (i.e. robot velocity = 0 m/s)

Maybe it's just personal preference, but I am very interested in hearing what the ROS official convention is.

edit retag flag offensive close merge delete


Hi, I have the same question. I used the diff drive controller in my robot using velocity joint interface. When I place the robot on a ramp and apply 0 cmd_vel , it coasts down the ramp. But I want to achieve the other behavior which it brakes it self so it won't coasts down. Any help on how to achieve that?

pasindu_sandima gravatar image pasindu_sandima  ( 2020-11-30 20:14:09 -0600 )edit

Please do not post follow-up questions as answer to already answered questions.

Your question will have very low visibility.

I'd suggest to post a new question, clearly describing your desired behaviour and referring to this one.

Edit: seems you already did: #q366698.

gvdhoorn gravatar image gvdhoorn  ( 2020-12-01 02:49:33 -0600 )edit

1 Answer

Sort by ยป oldest newest most voted

answered 2019-09-09 08:57:17 -0600

gvdhoorn gravatar image

updated 2019-09-09 09:22:44 -0600

For all robots I've worked with, wrote my own hw interfaces for or have used hw interfaces of others with, cmd_vel was always used to dictate the state in which the system should be (ie: messages encode the desired state or set point). For those robots a command of 0 m/s meant: motors powered, but not rotating.

This has made sense to me, as by convention cmd_vel carries setpoints in the form of geometry_msgs/Twist, which contains the following comment:

This expresses velocity in free space broken into its linear and angular parts.

So, Twists sent to a mobile base platform encode a body relative set of linear and angular velocities. These are then typically mapped onto joint space velocities for wheels in case of a wheeled mobile base such that 'the robot' (or mobile base) attains the desired attitude.

Following this, a Twist carrying only zeroes would encode for a 0 m/s linear and 0 rad/s angular state in the body local reference frame, or in other words: a non-moving robot.

Your other option (unpowered or backdrivable actuators) would lead to a non-zero state in case of "coast[ing] downhill" (as the encoders, which will probably be present to support velocity control, will register a non-zero displacement). That would lead to a velocity error, which a controller would probably try to rectify (by breaking or applying a corrective velocity).

Edit: I don't believe there is a REP that documents or standardises this particular aspect (as in: in a robot-agnostic manner), but there is REP 119: Specification for TurtleBot Compatible Platforms, which in the section called TurtleBot Node Core API writes:

Subscribed Topics

  • cmd_vel (geometry_msgs/Twist)

    The desired velocity of the robot. The type of this message is determined by the drive_mode parameter. Default is geometry_msgs/Twist.

which seems to confirm my experience and intuition.

As almost all use of cmd_vel seems to follow this convention (as authors of early nodes looked to existing implementations to match their own against, and TurtleBot and PR2 were the most prominent ones), I believe only your second alternative would be the correct one.

Edit 2: there is also REP 147: A Standard interface for Aerial Vehicles, which doesn't directly deal with cmd_vel or its semantics, but discusses something similar in the Rate Interface section:

The command is a body relative set of accelerations in linear and angular space.

Note that this talks about 'accelerations', but the idea and use is similar to cmd_vel and velocities for wheeled robots.

edit flag offensive delete link more


Thank you for such a detailed response. This is exactly the information I was looking for, and it makes perfect sense.

georgeknowlden gravatar image georgeknowlden  ( 2019-09-09 09:39:45 -0600 )edit

I believe that if you'd actually want to achieve something like backdrivability, stopping any active controller could be used achieve that (in combination with some support in your hardware_interface).

You can stop and start controllers with ros_control by calling the appropriate service on your instance of the ControllerManager.

A combination of prepareSwitch(..) and doSwitch(..) in your hardware_interface could probably be used to determine whether there is any active controller, and when there isn't, you could enable some special mode in your hardware that allows for coasting or backdrivability.

gvdhoorn gravatar image gvdhoorn  ( 2019-09-09 09:47:16 -0600 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools



Asked: 2019-09-09 08:16:27 -0600

Seen: 177 times

Last updated: Sep 09 '19