ROS Resources: Documentation | Support | Discussion Forum | Service Status | Q&A answers.ros.org

Why not include a velocity profile in the controller input path?

n nav2_core::Controller the input path is a nav_msgs/Path which does not allow for the caller to specify a velocity profile. Consider the following motivating examples.

  • We want a different speed while turning and we had that information while building the path.
  • We want the robot to slow down as it enters a main passageway.

Now we could achieve these with the max velocity topic by monitoring the robot’s progress and updating the topic as necessary but this seems like an awkward coupling and it wouldn’t be as accurate as providing the profile upfront.

So my question is should the controller also take in as input a velocity profile perhaps via a new Path message?

PS. This topic is duplicated on ROSAnswers.

Hi, I’m using for this purpose Pose.position.z which is “unused”, but of course this is not clean solution.

Maybe it would be good to “template” on message type where relevant. I’m also missing the possiblity to use AckermannDrive instead of Twist (similar ad hoc solution to fill Twist fields and convert to Ackermann at the end)

The profile doesn’t need to follow the same discretization as the path i.m.o.

So it could be some kind of array containing the position on the path and the velocity at that point?
And while trying to achieve that velocity, do acceleration limits still apply? If so, should one decelerate already if a future point has a low velocity?

1 Like

As a general answer, the idea of a velocity profile is a little bit outside the core navigation calculations. I would instead consider switching between differently configured controllers rather than trying to make the interface fit this use case.

There are other ways to embed that information, including a controller algorithm that will slow in those situations (like sharp turns). Luckily for you, a new algorithm was added to Nav2 which does that, Regulated Pure Pursuit.

I look at this 3 ways:

  • A: You have areas you want to slow down in → Use the Speed Restricted Costmap Filter
  • B: You’d like to slow when making sharp turns independent of area → Use the RPP Controller or an algorithm which slows in turns
  • C: You’d like to do full-fledged kinodynamic global planning → No support currently, not practically required for most all mobile robot applications & not going to be very fast to compute. We may down the line support this for folks that really need it, but I think we’re still a bit off from that eventuality. It sounds like A and B meet your needs though.

My use case is that I have some path sections where I want to slow down. Attaching this to global path is very handy because then I can use soft constraints (teb’s via_points) in mpc_local_planner.

We considered this but for this to work the controller would need a lot of contextual information, which seems like a messy design and one that wouldn’t be compatible with the existing controllers.

Those were just motivating examples, and we could use specific controllers or monitors to control the max speed but those don’t quite achieve what we’re looking for. Regardless, this is a forum for discussion and I appreciate the responses.

If you like I could provide another example. Suppose our robot has a left and right compartment for carrying a load, where a sharp left turn would dump the load in the right compartment on the floor. Furthermore suppose we use a Dubins planner and are easily able to know when we are making a left turn. Thus if we had a path with max speed embedded, we could design a path to slow down for left turns only when we have a load in the right compartment.

Other applications might require a tight coupling of speed and position that is best done at the planning stage instead of leaving it up to a monitor or creating custom controllers for each behaviour.

This is kind of fundamentally flawed in my mind. If you have some path planner using dubin motion models, what’s the difference between identifying a left/right turn at the sampling time versus on executing the path? Either way, you’re just assigning a L or R value to some information which it itself self contains the L or R information. So doing this in the planner or the controller (either) is a pretty arbitrary decision because both have access to identical information to make an identical decision.

I definitely understand semantically it makes more sense to stick in the planner because its “at” planning time, but logically the controller is the one that needs to make the decision about whether to slow or not depending if left or right. So if there’s some logic in the controller already to take that L or R and slow based on the right one, why not also determine L or R at that time as well? Particularly because a robot never perfectly follows a path so to make a robust system, you’d need to verify in the controller again in case of dynamic effects or obstacle information different in the local costmap settings that could soften or deepen the turn to track the path.

If L or R is part of the planning sequence, that’s different, but it sounds like you’re just classifying the turn and not using the load information as an additional planning heuristic (and even if you were, both are still valid options).

Given the common separation of a path vs local trajectory planner, the local trajectory planner seems like the right place since “slowing” is varying speed, which is more of a “trajectory” than a “path”. I’m not arguing that you couldn’t also do it in the path planner, but unless you’re doing full kinodynamic planning, it seems overkill to change the interfaces for certain areas which can be easily taken care of via other existing tools / methods.

Thanks for everyone’s participation. Clearly some see value in this design while others do not. Personally, I see value in it as I don’t understand why I would have to treat the velocity information separately from pose information if I have it at planning, and then I would need to either monitor the robot’s progress to update it’s max speed or choose a custom controller to mimic the information that I already have.

I wonder which direction ROS will take. Adding this as a feature seems like a pretty low bar as the controllers already respect a max speed topic, thus respecting one more limit seems pretty easy.

Anyways, thanks again.