-
Notifications
You must be signed in to change notification settings - Fork 13.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Multicopter mixer saturation handling strategy -- continue #9062
Conversation
8940046
to
c5406a7
Compare
src/lib/mixer/mixer_multirotor.cpp
Outdated
roll_pitch_scale = (thrust + boost) / (thrust - min_out); | ||
if (!_airmode) { | ||
// disable positive boosting if not in air-mode | ||
// boosting is positive when min_out < 0.0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest a minor wording update to: boosting can only be positive when min_out < 0.0
, because boosting can also be negative when min_out < 0
(in case of delta_out_max > 1.0f
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for starting a new pr which is clear again.
I hope my questions are useful.
I have to add that if you need to change 6 drivers to introduce one bool available to the mixer that's according to my understanding an architecture fault. Maybe we can improve this in the future.
src/lib/mixer/mixer.h
Outdated
/** | ||
* @brief Set airmode. Airmode allows the mixer to increase the total thrust in order to unsaturate the motors. | ||
* | ||
* @param[in] airmode Dis/-activate airmode by setting it to false/true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd suggest De/-activate
or Diasable/activate
. I've never seen disactivate before.
src/lib/mixer/mixer_multirotor.cpp
Outdated
boost = math::constrain(-(max_out - 1.0f - min_out) / 2.0f, -max_thrust_diff, 0.0f); | ||
roll_pitch_scale = (1 - (thrust + boost)) / (max_out - thrust); | ||
} else { | ||
roll_pitch_scale = 1 / (delta_out_max); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please make it a float literal 1.f
for consistency.
src/lib/mixer/mixer_multirotor.cpp
Outdated
roll_pitch_scale = (1 - (thrust + boost)) / (max_out - thrust); | ||
} else { | ||
roll_pitch_scale = 1 / (delta_out_max); | ||
boost = 1.0f - ((max_out - thrust) * roll_pitch_scale + thrust); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure what this formula is for...
When min and max are symetric with respect to the middle (thrust) then it's correct but can be simplified to boost = 0.5f - thrust;
In an asymetric case, which I suppose the math is for, the result is incorrect according to my analysis. When I find any mistake I might have made or a better solution I'll suggest it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found that the calculation here: https://github.com/PX4/Firmware/pull/9062/files#diff-40032af52ac957eae697d7d0a1856ef2R252 only scales roll and pitch (like the name suggests). This makes things unnecessary complicated when the mixer is not symetric.
If it's symetric boosting the thrust to be 0.5 is the right solution because all the authority gets used.
If it's not symetric it would be a lot easier to directly generate the correct output instead of rerunning and rescaling the whole mixer... Similar to what I did here: https://github.com/PX4/Firmware/pull/8485/files#diff-40032af52ac957eae697d7d0a1856ef2R215
Hopefully I'll get around to do a suggestion in a pr.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This formula is for the asymmetric case and is from the constraint
(max_out - thrust*thrust_scale)*roll_pitch_scale + (thrust + boost)*thrust_scale = 1.0
.
Assuming the thrust_scale is 1.0, the constraint is
(max_out - thrust)*roll_pitch_scale + thrust + boost = 1.0
then
boost = 1 - (max_out - thrust)*roll_pitch_scale - thrust
.
It could also be simplified by using the min output:
(min_out - thrust)*roll_pitch_scale + thrust + boost = 0
which gives
boost = -(min_out - thrust)*roll_pitch_scale - thrust
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bresch Yeah I found all these variants also with the min:
boost1 = 1-thrust-roll_pitch_scale*(max_out - thrust);
boost2 = -thrust -roll_pitch_scale*(min_out - thrust);
but my script still gave the wrong output and just now when I wrote with you on slack I realized my script had a mistake in it. Sorry for the churn, it's correct.
@@ -355,6 +373,10 @@ void task_main(int argc, char *argv[]) | |||
// Main loop | |||
while (!_task_should_exit) { | |||
|
|||
if (_mixer) { | |||
_mixer->set_airmode(airmode); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does it need to be set at every loop iteration and not only on parameter change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is currently needed, because a mixer can dynamically be loaded with an ioctl
. In that case the parameter would not be applied to the new mixer. I agree it's not nice, but it's ok for now.
/** | ||
* Multicopter air-mode | ||
* | ||
* The air-mode enables the mixer to increase or decrease the total thrust of the multirotor |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe the comment should mention that it's only disabling "upwards boost".
I think it's the right way to do it but the comment right now says increase or decrease
.
Test flights:
It works as expected. |
… saturation handling
- fmu: in case of _mot_t_max==0 _airmode was not set in the mixer - px4io: param_val is a float
this avoids calling param_get() on every loop iteration.
If not in air-mode the mixer is not able to apply positive boosting and roll_pitch_scale is recomputed to apply symmetric - reduced - thrust. This has the consequence to cut completely the outputs when the thrust is set to zero.
Can we get some docs for this soon? :) Not super clear for an end user yet. |
With the updated mixer (#9062) it's safe to set maximum thrust to 1 (in both cases, if MC_AIRMODE is set, or not set). So I see no reason to limit the maximum thrust.
With the updated mixer (#9062) it's safe to set maximum thrust to 1 (in both cases, if MC_AIRMODE is set, or not set). So I see no reason to limit the maximum thrust.
Follows #7920
Rebased onto master
Works on:
When MC_AIRMODE is disabled, it is possible to tune the attitude/rate controllers really safely since no positive boosting will be applied by the mixer. This has the consequence to be able to cut completely the throttle of all the motors (idle) if the RC throttle is at zero.