History
So I did some digging and found some interesting points.
The DO_SET_SERVO / ACTUATOR not working properly has been thoroughly discussed in the past:
PX4:master ← kpetrykin:make_do_set_servo_working
opened 03:26PM - 24 Aug 18 UTC
Hello!
My goal was to make the mission command DO_SET_SERVO working with the po… ssibility of triggering the servo with RC switch.
First, I have found that "vmount" module (when enabled) publishes its values to actuator_controls_2 topic all the time. This overwrites all other publications to this topic. That is why DO_SET_SERVO is not working.
I modified "vmount" module so that it would publish only if one of the actuator values were changed by RC. In other cases it stays silent.
Second, I have found that the formula, which translates PWM value from DO_SET_SERVO command parameters to -1..1 range for uORB, does not match the one which translates it back.
[Original formula:](https://github.com/PX4/Firmware/blob/c997159e32f3870c7fd3202877324b76a62ea610/src/modules/navigator/mission_block.cpp#L433) `actuators.control[(int)item.params[0]] = 1.0f / 2000 * -item.params[1];`
[Formula, which translates value back](https://github.com/4ert/Firmware/blob/397522d3813924380c209984b47b05bf743c3037/src/lib/pwm_limit/pwm_limit.cpp#L211): `effective_pwm[i] = control_value * (max_pwm[i] - min_pwm[i]) / 2 + (max_pwm[i] + min_pwm[i]) / 2;`
[New formula](https://github.com/4ert/Firmware/blob/397522d3813924380c209984b47b05bf743c3037/src/modules/navigator/mission_block.cpp#L440): `actuators.control[(int)item.params[0]] = (float)(((float)item.params[1] - (PWM_DEFAULT_MAX + PWM_DEFAULT_MIN) / 2)/((PWM_DEFAULT_MAX - PWM_DEFAULT_MIN) / 2));`
I need to discuss two questions about the formula:
- to make it work properly we need to get actual "max_pwm[i]" and "min_pwm[i]" into navigator module. I have found a [way to get them](https://github.com/PX4/Firmware/blob/c997159e32f3870c7fd3202877324b76a62ea610/src/drivers/px4fmu/fmu.cpp#L1678), but I don't understand how to use it correctly
- when I tested mission with DO_SET_SERVO command, servo works nice only with 1, 3 and 4 aux outputs. The second one for some reason outputs into first. I think there is something wrong with casting here: `(int)item.params[0]`
I have tested everything with 1.7.3 Firmvare (px4fmu-v2_default), but did not save the flight log.
I will test the last master in a few days.
There are definitely a lot of users asking about this / being confused, e.g.:
opened 09:53AM - 07 Nov 22 UTC
bug-report
## set_servo
Waypoint with this command has ignored by drone. It doesnt work. I… found the same issues in questions on forums, but there are no answers.
In the source code I found the only place where this command is handle in mission_block.cpp:
```
if (item.nav_cmd == NAV_CMD_DO_SET_SERVO) {
PX4_INFO("DO_SET_SERVO command");
// XXX: we should issue a vehicle command and handle this somewhere else
actuator_controls_s actuators = {};
actuators.timestamp = hrt_absolute_time();
// params[0] actuator number to be set 0..5 (corresponds to AUX outputs 1..6)
// params[1] new value for selected actuator in ms 900...2000
actuators.control[(int)item.params[0]] = 1.0f / 2000 * -item.params[1];
_actuator_pub.publish(actuators);
}
```
But as I see, its wrong implementation and #10320 wrote about this 4 years ago. So I dont know, how it can be working.
## set_actuator
When I try to upload mission with this command in QGC, I receive the message "Ignoring mission item, invalid Item" and "Mission transfer failed. Error: Command is not supported. Item 1 Command: Set actuator"
The same issue I get when uploading mission in my own app with MAVSDK. It was expected because command MAV_CMD_DO_SET_ACTUATOR should use COMMAND_LONG frame instead of COMMAND_INT (I think the problem is this).
## conclusion
DO_SET_SERVO doesnt work at all, drone has no reaction to this command. DO_SET_ACTUATOR cant be used in Mission.
So, how can I use servo (AUX1, for example) in Mission mode?
Thanks.
Drone firmware: 1.13.1, Quadrotor X
QGC: Daily master:9c77d15b2 2022-10-25
P.S. Servo work via RC and with setActuator command in MAVSDK. So the problem only in mission
The switch to control allocation introduced the support for DO_SET_ACTUATOR command specifically (affecting v1.13 and onwards):
PX4:master ← PX4:ctrl_alloc_function_params
> This is borderline bike-shedding, but should we try to settle this one now?
…
We might as well.
> I'm in favor of these outputs being named as close as possible to what's user facing.
Agreed. I don't think it will matter much though in this case, as the config UI will not even show the param name, just the label.
> I think this is going to seem pretty odd for all but the most technical users that understand the full picture and history
Odd yes, but is it really a problem? They can ask and there's a good reason. It is a historical problem that we have to carry.
Most people will probably not know about any downsides and just stick to the default.
Overall I tend towards `PWM_FMU_`, but really only slightly.
> I actually don't think we should even be carrying opinionated default airframes that we pretend will work everywhere. There are a handful of cases where exact configurations should be carried. For the rest it should be a generic start. A "generic quadcopter" should default to using 4 MAIN outputs, but otherwise carry no actuator specifics. Then on the GUI side it should be easy for a user to switch those over to DSHOT, UAVCAN, etc on arbitrary outputs and set any specifics.
I see that the same way.
----
> Is "Actuator Set X" for Mavlink MAV_CMD_DO_SET_SERVO?
No, it's for `DO_SET_ACTUATOR`. I did not plan to add support for `MAV_CMD_DO_SET_SERVO`, but if needed I'd rather map it to the (future) actuator test interface.
And then, the DO_SET_ACTUATOR support in mavlink receiver was removed from this commi (affecting v1.14 and onwards)t:
committed 01:14PM - 09 Sep 22 UTC
Conclusions
Therefore, it seems that:
In v1.13, the DO_SET_ACTUATOR *should work, however you will have to map the mixer correctly to the AUX ports to accept control from control group 3 (manual passthrough), index 5 through 7
} else if (cmd_mavlink.command == MAV_CMD_DO_SET_ACTUATOR) {
// since we're only paying attention to 3 AUX outputs, the
// index should be 0, otherwise ignore the message
if (((int) vehicle_command.param7) == 0) {
actuator_controls_s actuator_controls{};
// update with existing values to avoid changing unspecified controls
_actuator_controls_3_sub.update(&actuator_controls);
actuator_controls.timestamp = hrt_absolute_time();
bool updated = false;
if (PX4_ISFINITE(vehicle_command.param1)) {
actuator_controls.control[5] = vehicle_command.param1;
updated = true;
}
if (PX4_ISFINITE(vehicle_command.param2)) {
actuator_controls.control[6] = vehicle_command.param2;
updated = true;
This file has been truncated. show original
MAV_CMD_DO_SET_ACTUATOR in MAVLink definition seems to only conceptually note “Actuator 1 ~ 6”. And it seems like we at the time (v1.13) just decided to use convention of having the Index (param7) set to 0, and using only the Actuator 1 ~ 3 in the message to map to control group 3, index 5 ~ 7 (RC aux 1 ~ 3).
Speaking of that, @ChanJoon you will probably have to definitely setup the mixer part as noted in point 1 above. Hope this helps!
Note on v1.14
Starting from v1.14, the concept of control groups, etc were removed and we have unified control allocation. Here, the support for DO_SET_ACTUATOR and DO_SET_SERVO should be easier to use, but as of now there is no implementation for this in PX4.
Addition of these features would definitely be welcome! I will create an issue to have this tracked:
opened 01:16PM - 15 Aug 23 UTC
feature-request
### Describe problem solved by the proposed feature
I have noted that a lot of … users (e.g. https://discuss.px4.io/t/using-do-set-actuator-to-releasing-the-payload/28686) were asking for ways to control the servo, or an actuator via the DO_SET_ACTUATOR/SERVO messages coming from an external entity (e.g. onboard computer).
This definitely sounds like a basic feature that we should support, as it can be used for all kinds of applications that controls *any sort of actuator onboard the drone,
As we now have the `Actuators` and `Servos` concept in place with control allocation, it should be pretty straightforward to implement, I think.
### Describe your preferred solution
Add the logic in `mavlink_receiver.cpp` like was done in v1.13:
https://github.com/PX4/PX4-Autopilot/blob/1c8ab2a0d7db2d14a6f320ebd8766b5ffaea28fa/src/modules/mavlink/mavlink_receiver.cpp#L554-L586
### Describe possible alternatives
None
### Additional context
I have posted a bit of history behind the support for these commands here: https://discuss.px4.io/t/using-do-set-actuator-to-releasing-the-payload/28686/3, however, to summarize:
1. This feature was supported in v1.13 ([related comment](https://github.com/PX4/PX4-Autopilot/pull/18265#issuecomment-923681920)), and was utilizing control groups convention (which was removed after complete switch to control allocation in v1.14)
2. It was then removed when purging old mixer system (using control groups, etc): https://github.com/PX4/PX4-Autopilot/commit/13f9eabd70de2038330e89ab46d5cb3f1cde38ec
Therefore, I would say this was an accidental deletion and the feature should be put back in place.