How are actuator controls read in the px4io mixer?

Dear all,

I need to understand precisely how are the attitude control signals (roll, pitch, yaw and thrust controls) retrieved in the px4io mixer.
Normally it all happens inside the function [Mixer::get_control] but I couldn’t go any further. This function uses a control callback variable that somehow returns the value of the attitude control signals, which should be written in the PX4IO_PAGE_CONTROLS register if I am not mistaken. But how is it done? I was expecting some io_reg_get function at that level…
Actually, the problem I have is a mismatch between the values that the attitude controller sends and those that the mixer gets. The control values received px4io look like being periodically reset to some value (zero).

PS. The control signals I am sending are not between -1 and 1, but rather physical values of torques and thrust (with physical limits). And I deactivated all the saturations between -1 and 1 that I could found…
Hope I was clear enough, thanks in advance for your help

So usually if you suddenly see attitude control signals of 0 the reason is usually that some other module is publishing at the same time. Can you check with top what else is running to rule out it’s some other module? Or you can also disable whatever publishes the right output (non-zero) and see if you still see published messages with zero.

I am running into a very similar issue - the thrust control index [3] of the control signal was getting periodically constrained (running at about 2hz). I noticed this because I was using a custom mixer that allow values ranging from -1 to 1 for the index and value would get temporarily get squashed to 0 every half second.

A very frustrating bug and I never found out where the constraining was occurring, I just moved over to index [4] and [5].

I think I understood the origin of the problem, the register page where the control signals are written does not support any range of floats because it encodes signed integers 16bits (check the function REG_TO_FLOAT to see how the float values are then deduced, a division by 10000 basically) so the maximum float than it can handle should be about 3.2, once reached it gets squashed to zero…
I think it’s possble to encode registers directly using floats, I didn’t try it yet though I will let you know if something works

1 Like

I have a plot here of what I was running into. Essentially I’m sending negative values for actuator_controls_0[3] (following a z-down convention in my 6dof mixer so upward thrust is negative for my geometry). I think I’m remembering this correctly, its been a few months since I found the workaround to avoid these indices being constrained.

You can see the oscillations occurring were the thrust is getting reset by something periodically at about 2hz.

to be honest I am not sure if it’s the same problem I am having. If it could help, I solved mine by changing the way control signals are wrtitten in the registers: I used two pages for each control signal (so I ended up using 8 pages of PX4IO_PAGE_CONTROLS instead of only 4), in the first page I write the integral part of the control signal (so it can be put in uint16 with no approximations) and in the second page I put the fractional part, using the same logic of FLOAT_TO_REG (so it is cast and converted into an uint16), and then on the px4io side I sum both values to reconstruct my control signal which could be as a consequence any float number (as long as its integral part does not exceed the maximal int16 value, which should be always the case)

2 Likes

@Joheart thanks for following up. So given your changes, do you suggest that we should change something in the architecture to have more resolution? As far as I know it’s a trade-off between resolution and latency (due to higher or more messages that have to be sent).

@dlwalter: your problem looks more like some sort of aliasing or something fluctuating in the sensor/estimation/controls pipeline. Is it reproducible with the upstream code, or does that only happen with custom changes? If it’s upstream, it would be good if you could provide instructions how to reproduce so we could look into it.

My changes might give a bit more resolution because I only pass the fractional part through the FLOT_TO_REG function and not the whole float, but I use 8 sections of the register(instead of 4), which are already available so there aren’t really big changes in the architecture. I don’t know if this adds alot latency though, I didn’t notice anything bad sofar… Again what I did only make sense if we want to use control signals that are not normalized.

Aha, right now I understand.

@JulianOes , I can make an example branch where I set z-thrust between 0 and -1 and then correct for the down z-axis in the mixer, this should show the same oscillation during hover. I’ll post it as a separate issue to not clog up this thread.

1 Like