Mixer customization and override

Hello,

I would like to check if there is any interest in using the passthrough mixer to override the regular mixer behaviour and implement custom mixers.
This is motivated by:

  • research purposes: test new mixer concepts different from the multirotor mixer already implemented;
  • educational purposes, i.e., how does the mixer work under the hood?

As an example, in our research lab we have developed a tilt-arm quadrotor, which in addition to the four motors has four servos to let the arms tilt independently from each other (thus we have 4+4 control variables):


The control architecture we developed includes a nonlinear mixer which computes the eight control variables (four motors PWM and four servo angles) based on the required forces and moments.
Since the PX4 mixing architecture only allows for a linear mixer (with offsets) to be implemented, we employed a passthrough mixer so as to be able to directly pilot the actuators, thus bypassing the multirotor mixing mechanism.
The actual nonlinear mixer, together with the controller, was implemented in a module upstream the passthrough mixer.

This solution works, however it breaks the interface established at the level of control group:
the idea of control group is to publish normalized forces and moments (to the actuator_controls_X topic where X is usually 0) which are then fed to the mixer.
But when using a passthrough mixer, one has to publish actuator demands on the same topic. The result is that the mixing system might misinterpret the request coming from the higher level (e.g., in control group #0 the fourth input is interpreted as the throttle, but if using a passthrough mixer this is actually the demand to motor#4).
To see what I mean, have a look at this piece of code in the px4iofirmware module:

Possible solutions:

  • introduce some structure in the architecture: define a new custom mixer class at the same level of the multirotor mixer. this has the advantage of not disrupting the interface at the mixer input, and it avoids using the passthrough mixer; however it requires handling separately controller and mixer.
  • if one wants to keep the architecture as unstructured as possible (i.e. keep controller and custom mixer in the same module, and use a passthrough mixer - this makes sense in a research framework), one idea could be to add a new control group (say, associated with topic actuator_controls_X) explicitly dedicated to the usage of the passthrough mixer (i.e. the actuator demands are published on actuator_controls_X) while still publishing the required forces/moments on actuator_controls_0, though this information would not be used for control, rather for monitoring and logging purposes. This would preserve the role of actuator_controls_0 as the channel where the information on forces/moments runs.

I had some discussion about this with @MaEtUgR at the dev summit, and I think @tumbili and @bresch might be interested as well.

Related work:

In this PR, direct motor control is implemented by sending the individual actuator control actions through mavros, bypassing the mixer. Direct motor control is sought as a desirable feature. However, the bottleneck is the serial communication bandwidth. This can be avoided if the actuator commands come e.g. from a controller running on a module onboard the FCU.

Again, some comments on direct access to actuators from companion:

In these works, a common problem is which mixer to use for non-conventional UAV configurations.


In this work, a “physical” mixer which takes forces and moments is developed. the usage of passthrough mixer is envisaged.

Apologies for the long post, hope that some interesting discussion can take place.

Bye
Simone

1 Like

Yes, I am facing a similar issue right now with the NaNs being expected to passthrough the mixer to indicate motors should be disarmed.

I feel it would make the system significantly more flexible to remove that forced assignment of controls index 3 to NAN. If the PX4IO firmware has access to the armed/disarmed state can we move that to the pwm_limit functionally. Currently it reduces the orthogonality of the system - we can’t change the actuator_controls indices because it also require PX4IO firmware changes.

I see the reasoning is to force the motors to a safe state (which should propagate from the throttle = NAN) while leaving servo channels free to move.

Maybe a PWM_MAIN_MOTOR_MASK parameter, set as 11110000 to have the first 4 MAIN channels treated as motors?

What do you think is a better way to to let PX4IO know the difference between motor and servo channels?

The current system also causes problems if PX4 moves to a 6DOF mixer and control strategy. The vertical thrust command is negative (positive down with the aircraft axes), but should be able to ask for a positive or negative thrust in Z.

There are hidden dependencies occurring where that controls[3] index is being forced positive, or set to NAN on the PX4IO. In addition land_detector checks the raw value of that index for landing without taking the absolute value.

@simopanzer Thanks for your post. Interesting work you guys have done. I am currently trying to understand the mixing architecture used in the px4. I also want to implement a custom mixer for a similar drone as yours. But i’m a bit stuck at the moment.

I think it’s on topic to mention recent changes taking a step towards making the mixer more modular: https://github.com/PX4/Firmware/pull/12790
We need support for dynamic mixers but to get there certain historic patterns have to be refactored.