How the throttle output of each motor from the Mixer is converted in PWMs in Arducopter

Hello,

The short question is that I want to convert the throttle values (0-1) of each motors that is outputted from the Mixer to PWMs values in a MATLAB/Simulink simulation to validate it to real flight data.

Context:
For a research project, I need to make a simulator with realistic dynamics to evaluate a experimental octoquad X8 drone response in the wind. Using MATLAB, I made a script that calculate the 6dof dynamics of the drone and the changing thrust and pitching moments of the propellers function of the airspeed.

The coaxial propellers thrust/moments function is done with a neural net using multiple dataset from wind tunnel tests. The coaxial propellers influence each other so it was simpler to use experimental data instead of a complex analytical model. For each arm, this neural net function takes in the PWM values from the upper and lower motors and the incoming airspeed and then output the total thrust and moments in all axis for that arm.

For the controller I made multiple nested PID loops similar to the real Arducopter architecture. For the mixer, I used the AP_MotorsMatrix.cpp that I translated into MATLAB to calculate the throttle value from each motors function of the required RATE. I then converted this throttle value into PWM using the relation: PWM = ThrottleX*PWMrange + PWMmin. I checked on the Pixhawk flight controller and my PWMmin = 1066 and my PWMmax = 1933 so my PWMrange = 867.

For validation, I used the RATE from real flight log and input them directly into my mixer to compare the simulated PWMs to the real PWMs. The curves were generally close in shape, but there was always a significant offset between the real and experimental PWMs. Adjusting the PWM/throttle relation was only shifting the problem around.

Someone mentioned me that there’s is already a MATLAB/Simulink version of the Stabilize/Alt Hold version of Arducopter (ardupilot/Tools/simulink/arducopter at master · ArduPilot/ardupilot · GitHub) that closely follow the real architecture and included a more detailed motor Mixer. This Mixer follows closely the real architecture of Arducopter with the comGain and thrAvgMax parameters that I didn’t included in mine However, the Simulink model doesn’t include conversion from throttle to PWM. Nonetheless, using a flight log, I used this Simulink model to generate the throttle for each motors and use the previous relation (PWM = ThrottleX*PWMrange + PWMmin) to calculate the PWM. The simulated PWM was then now much closer to the experimental one in term of shape, but there’s still a significant offset for most of the flight (see figure ‘‘Graph_compare_PWM_SimVsExp’’).

I looked around in the docs to see where the throttle is converted in PWM in Arducopter and found in this page (Copter Attitude Control — Dev documentation) that the function SRV_Channels.cpp does a scaling on the Output before the function AP_HAL:RCOutput.cpp sends it to the ESCs. I checked the code in SRV_Channels.cpp and a scaling and slew rate seems to be done in the function ‘‘SRV_Channels::calc_pwm’’ at line 436 and but I am not coding in C++ often and I’m not sure what kind of operation is done there and if its this function that does the scaling.

I would greatly appreciate if someone could explain me the manipulation done to convert the throttles outputted from the mixer to PWM values.

Thanks
Marc-Antoine

1 Like

hey, i working on simulate the electro-mechanical components (esc,bldc motor, battery).
i’m using the AP_recevier which pass the pwms from the sitl simulation and send the state back to the sitl through the AP_send.
do you have simulink model for this system : AP_recevier → battery → esc → bldc motor?

1 Like