DO_CHANGE_SPEED not working in AUTO?

I’m sending DO_CHANGE_SPEED commands from a custom tweak to MAVProxy, but while they are reporting as “accepted”, they’re not actually changing speed in AUTO.

Changing speed via the mission planner button DOES work as expected.

Here’s my command:

self.master.mav.command_long_send(self.target_system, # target_system self.target_component, mavutil.mavlink.MAV_CMD_DO_CHANGE_SPEED, # command 1, # ground speed 2.8, # speed (m/s) 10, # throttle 0, 0, 0, 0, 0) # Empty

What it should be doing is setting a ground speed of 2.8m/s at 10% throttle.

Hi @mroberts,

Rover only consumes the “param2” field (desired speed in m/s) in case that helps.

Some ideas about what the problem might be:

  1. a different version of the AP software is being used
  2. the target_system is incorrect. Normally it should be 1
  3. the target_component is incorrect. Normally it should be 0
  4. the command is not reaching the vehicle code for some reason

PEBKAC - was missing the “confirmation” parameter so everything was off by one, which was giving me screwy results.

Handy to know that AS / GS and throttle setting are ignored.

However, Rover doesn’t like a DO_CHANGE_SPEED of 0 - I had to send it 0.1 to make it stop. That may be worth looking into.

Don’t use DO_CHANGE_SPEED to stop. Switch to hold mode. As long as you don’t disarm, the mission will resume where you left off when auto is reselected (with default mission behavior params).

I use an onboard Lua script to do very similar when the GPS fix type degrades.

We could also add support for MAV_CMD_DO_PAUSE_CONTINUE like we have in Copter to allow pausing an resuming.

I agree that simply setting the speed to 0 is an intuitive way to stop the vehicle and we should probably support that. It was quite a few years ago but I think we added the lower limit of 0.1 to avoid support calls asking, “why is the vehicle stuck?”. It’s possible that we could automatically answer that question in another way (like a send-text to the operator every x seconds while the vehicle is stopped).


It seems, though, that DO_CHANGE_SPEED should be just that. A change in speed. If a pause is desired, either support for mission pause should be added, or hold mode should be commanded. Or am I off base?


I think it would make intuitive sense if do-change-speed to zero made the vehicle stop. Heck if the user put in -4 maybe it should go backwards at 4m/s (e.g. run the mission in reverse).

1 Like

It might be nice, also, if Rover responded mid-mission to changes in WP_SPEED, much like Copter does.


Rover does actually respond to do-change-speed commands in the middle of missions. I just tested it in SITL and it seems to be working ok. I think it worked in 4.1.x as well although I haven’t gone back to check.

Yes, I’m using DO_CHANGE_SPEED in a script to detect rough terrain and slow accordingly, and it does work fine.

But I’d rather just set the WP_SPEED parameter in real time rather than inserting a waypoint command (since MAVLink commands are not directly accessible in Lua). The simple parameter change method does not work without exiting AUTO mode.

1 Like


Ah, ok, I see. We should add a binding for do-change-speed to Lua then I think.

1 Like

That was fast! Perfect solution for my use case, and probably many others.

The important thing about setting speed to zero is that the vehicle continues to navigate - if you go to HOLD, it centres the steering, which does not necessarily keep you on path. Not sure how “pause” behaves.

1 Like

Support for negative speeds with “braking” vehicles (ones without reverse) would give you a way to command how hard you wanted the vehicle to decelerate - you’ll get a nice big “P” kick on the brake output if you set it to -20 when you REALLY want to stop in a hurry.

How are you doing the speed change? Any chance you’d be willing to share your script?

Do you record the previous speed? If so, how? I would be keen to implement functionality that will slow the vehicle if it starts to go off track, but I don’t know how to get it to go back to the previous planned speed.

As a workaround for now, I’m storing the previous waypoint in a variable, then overwriting it with a DO_CHANGE_SPEED mission command and setting the nav index backward to that waypoint.

I read WP_SPEED to store the previous speed along with a SCR_USER parameter for the slower speed.

When I want to resume, I do the same thing and then restore the mission to its previous state.

It’s a little clunky since the mission nav is interrupted, so there’s always a little “wiggle” when the nav controller resumes its path.

Randy’s suggestion to add a binding for direct DO_CHANGE_SPEED access should help a lot!

I intend to make a pull request and add this script to the examples library when I’m happy that I have no logic errors. I think that will happen this week.

EDIT: It’s already available in my fork of ArduPilot. I just don’t want to make the PR until I’m a little more confident in it.

1 Like