Motor speed control by Identify mixer and actuator_control

Hi, dear colleges.

Now I am trying to control the motor speed by sending messages to the actuator_control topic with PX4 1.7.3.

I found the control flow in PX4 is like this:

actuator_control------------>mixer------------>normalised PWM------------>PWM----------->ESC(motor)

  1. I identify the relation between the PWM sent to ESC and the motor speed: omega = g(PWM)

  2. the relation PWM = f(normalised PWM) can be found

effective_pwm[i] = control_value * (max_pwm[i] - min_pwm[i]) / 2 + (max_pwm[i] + min_pwm[i]) / 2;

from https://github.com/PX4/Firmware/blob/v1.7.3/src/modules/systemlib/pwm_limit/pwm_limit.c.

  1. An identity mixer is defined such that normalised PWM = actuator_control. The mixer is defined as
    I followed the steps Modifying mixer file without reflashing
M: 1
O:      10000  10000      0 -10000  10000
S: 0 0  10000  10000      0 -10000  10000

M: 1
O:      10000  10000      0 -10000  10000
S: 0 1  10000  10000      0 -10000  10000

M: 1
O:      10000  10000      0 -10000  10000
S: 0 2  10000  10000      0 -10000  10000

M: 1
O:      10000  10000      0 -10000  10000
S: 0 3  10000  10000      0 -10000  10000

Finally, the control messages publish to actuator_control can be computed from motor speed as
actuator_control = f^-1(g^-1(omega)).

However, I have meet some problems:

  1. with the mixer in (auto.land mode), the /rc/out shozs that PWM sent to the motors are the same. However, the motor speeds are quite different. In fact, when PWM = 1500, the motor 4 are around 9000 rpm while motor 1,2,3 are like 14000. So, is there some other setting that I need to change, or my mixer is not defined correctly?

  2. when switch to the OFFBOARD mode, /target_actuator_control is defined to copy the messages from /actuator_control and sent to PX4 in mavros. Howevcer, /target_actuator_control change to [0,0,0,0,0,0,0,-1] periodically. As a consequence, when I publish [-0.7,-0.7,-0.7,-0.7,0,0,0,0] to /actuator_control, /rc/out vibrates between [1512, 1512, 1512, 1512] and [1590,1590,1590,1590]. Is this a bug or I misunderstood something?

Thanks for your question.
But I’m a new develop of px4, I dont know how to get the motor speed(motor rpm). The way you choose to get motor speed is by using PWM?
Thanks! I’ll appreciate it.

Yes, I did tests to control motor speed by sending normalised PWM. It seems like controlling a single motor was fine, but when I tried integrating motor speed control in a flight control system, it failed.

please have a look at my answer at RE: Motor speed control by Identify mixer and actuator_control

Appreciate your answer!
But the page you show which I can’t visit.

Now my method is to get the motor speed in gazebo, which can be get indirectly. And then pub it to mavlink.

Hi, this is the answer in my link.

If I remember correctly, we cannot get rpm directly from mavros. In PX4, there is a reference motor speed signal, target_actuator_control, and a motor speed state actuator_control. Both them have the same unit ranging from 0-1.

Their units are not rpm, but I would like to call them normalised rpm.

What I did is to find a (linear) relation between a normalised rpm and the real rpm for a given motor.

It is kind of identification: I measured the real rpm with an external sensor and recorded the normalised rpm. With the data, I tried linear approximation.

In simulation, that can be a solution. But if we want to implement motor speed control in real world experiment, I think it could be difficult.

Yes you’re right, there just one way to get the motor speed in the real world where we need to use the "dshot " ESC , which is expensive to buy.

Thanks your replies, But I found that just a linear formulation relation between motor speed and PWM is not a accuracy way . If we wanna get more accurate motor rpm in SITL, I find the only way is to get motor speed in gazebo-simulator (the number of motor rpm is in “gazebo-motor-plugin”).

This can be a good idea.