Home        Store        Learn        Blog

Motor PWM Resolution question


Quick question. Looking at the Servo outputs from the pixhawk, zero thrust is set at 1500 and full thrust is 1900 in a given direction. Does this mean there is only 400 points of resolution in that direction or is there another float value used within the pixhawk which would use the full resolution of +1000 as sent Via MANUAL_CONTROL(69)?

Thanks. john

Hi @john6,

In short, yes, there are only 400 points of resolution for each direction that are actually used as input (by default).

As a bit of context, motion commands in ArduSub are handled as/via RC input, because previously the Manual Control Protocol didn’t support enough axes. We recently added additional axes (and buttons) to the MANUAL_CONTROL MAVLink definition, but those updates aren’t yet included in ArduSub (so at this stage MANUAL_CONTROL can only control forward/lateral/vertical/yaw OR roll/pitch/vertical/yaw with any single command, and only 16 buttons can be assigned functionality and used).

By default ArduSub uses 1100-1900 as the RC input range, to match the 1100-1900us pulse-durations that we use for the servo-style output channels. For thruster outputs, our BasicESC considers 1100us → full reverse, 1500 → stopped, and 1900 → full forwards. The MANUAL_CONTROL message has inputs from -1000 to +1000 for each control axis, which ArduSub maps to 1100 to 1900, after which it’s treated as standard RC input.

For more direct motion control input you may wish to use RC_CHANNELS_OVERRIDE, which by default follows our RC Inputs mapping, in which case you specify the 1100-1900 values directly. If you’re using Pymavlink you might be interested in our Send RC (Joystick) example, although if you’re keeping the default channel mapping you may want to use a wrapper function to make the purpose of each channel more obvious (like this one, that I wrote recently).

Note that while RC Channel inputs are more direct for how motion is actually controlled, only Manual Control can be used for the button functionalities.

Out of interest, do you want extra resolution, or are you just asking how much resolution there actually is?

It might be possible to adjust the resolutions indirectly by increasing the ranges using parameters (although currently that could only work with RC_CHANNELS_OVERRIDE messages for control, since the MANUAL_CONTROL handling is seemingly hardcoded to the 1100-1900 range), but for that to be meaningful you’d need to adjust both the input and the output ranges, and if you’re adjusting the outputs then you’d need to also reprogram the ESCs to match.

In case it’s relevant/of interest, there’s an open issue to refactor ArduSub’s input handling to a more abstract interface internally, although we don’t have an expected timeline on when that will be completed. Presumably the integer microseconds output resolution is something of a determining factor for the usable/meaningful input resolution because of quantisation, but technically the input and output resolutions are and should be independent (it’s already possible to reduce the output range without changing the input range), so if you’re interested in having extra input resolution in future you’re welcome to make a comment in that issue about why you think internally handling the input as a float would be helpful.

Thanks for the reply and extra info Eliot…

I’m programming my own joysticks and was just using the standard 0-1024 resolution on the MCU per axis, I had read that the MANUAL_CONTROL used -1000 to 1000 per axis which meant I could have upped the resolution to 0-2048, but if ultimately the PWM resolution 1100 -1900 per axis (800) 1024 is plenty.

1 Like