jcg1541

  • **
  • 98
    • Phones, Networks, And The Red Pill
Convert racing controller PIDs to CC3D
« on: January 09, 2022, 10:15:34 pm »

More than 3 different racing flight software in the market have "define" PID_SERVO_MIXER_SCALING 0.7,  PTERM_SCALE 0.032029, etc, vintage scaling in their pid.h .
In the video, the left side is controlled by such a racing controller with those vintage scaling numbers set by a racing champion robot or an anonymous human.
The right side is controlled by a CC3D Atom.
Both sides have identical main blades, RPM, swash mix, servos, tail motor, tail prop, weight, and weight distribution.
With racing controller on the left side, scaled PIDs are 45/118/0 , tail 34/10/28 , seen in configuration dump.
With CC3D on the right side, the true PIDs are 0.002/0.04/0, tail 0.0013/0.003/2.1e-5, seen in Stabilization/Advanced tab.

For gyro-only-control, straight-line flying (the b and c terms in pid2 of Matlab are canceled by zero steering), the conversion is to undo the vintage scaling as so,
Pracing * 0.032029 * 0.7 / 1000 * 2 = Pcc3d   , e.g.   45*0.032029*0.7/1000*2 =  0.002
Iracing   * 0.244381 * 0.7 / 1000 * 2 = Icc3d    , e.g. 118*0.244381*0.7/1000*2 = 0.04
Dracing * 0.000529 * 0.7 / 1000  * 2 = Dcc3d   , e.g.   28*0.000529*0.7/1000*2 = 2.1e-5
. The 1/1000 factor is an emulation of PWM 2000-1000 in racing controllers. The factor 2 converts unsigned range to CC3D's signed range, -1 to +1.

 The temperature on the left side is -1 degree Celsius. Temperature is -9 degrees Celsius on the right side of the video.
« Last Edit: May 21, 2023, 04:36:38 am by jcg1541 »

Re: Convert racing controller PIDs to CC3D
« Reply #1 on: January 10, 2022, 08:50:20 am »
Just some general musings:

OP/LP tries to create settings that are based on measurement units (e.g. degrees per second, seconds, meters, meters per second per second) and use floating point to allow some of it (e.g. very small numbers).  Even within OP/LP there are simplifications to make e.g. tunings into "unitless" numbers 00-99 (Stabilization -> Use Basic Configuration View).

Even within OP/LP there are multiple forms (maths) of PIDs.  For instance, one of these cannot have a P term of zero, but the other can.  One has a Beta (wind-up decay) term and the other an ILimit (wind-up hard limit) term.  I think that only the ILimit form can "perfectly" compensate for constant drift.

There are other reasonable measurement units like feet and radians.  I don't know that all/many firmwares even try to make their settings based on units.  I would guess that some just use 00-99 or 000-999, at least initially.  Some, like the Fahrenheit temperature scale or qwerty keyboards may be based on their version 1.0, and scale later versions to match that.

Changing "loop times" for those firmwares that use a big loop will change require different PIDs if not internally scaled by loop time.  I would make a guess though that all modern loop-based firmwares scale PIDs by loop time.

Unrelated to your testing and generally invisible, there is a factor of 1000 in internal OP/LP PID calculations that is a relic of integer math beginnings.  Multiply by 1000 at the beginning and divide by 1000 at the end.  Still in the latest next.  Now (unless it is optimized out, which I doubt) it is just a lot (at least 500 times a second times RPY=3 times 4 per call plus a lot of others at lower rates) of useless extra floating point multiplies/divides.  Back of envelope calculation says this is not a noticeable percentage of CPU though...  It is one of the things on my list of things to change, or at least to remember needs changing.  :)
« Last Edit: January 10, 2022, 11:40:40 am by TheOtherCliff »

jcg1541

  • **
  • 98
    • Phones, Networks, And The Red Pill
Re: Convert racing controller PIDs to CC3D
« Reply #2 on: July 17, 2022, 09:09:16 am »
Just some general musings:

OP/LP tries to create settings that are based on measurement units (e.g. degrees per second, seconds, meters, meters per second per second) and use floating point to allow some of it (e.g. very small numbers).  Even within OP/LP there are simplifications to make e.g. tunings into "unitless" numbers 00-99 (Stabilization -> Use Basic Configuration View).

Good point. I looked at both CC3D code and racing clean flight code, and I couldn't easily tell whether degree or radian was the unit from the gyro sensor. I could tell for sure though that both CC3D and clean flight treat the gyro sensor input as-is in the core PIDs code. Neither CC3D nor clean flight try to do unit conversion leading to the core PIDs loops.

Re: Convert racing controller PIDs to CC3D
« Reply #3 on: July 17, 2022, 01:41:40 pm »
Hmm...

By the time the sensor data gets into a UAV where you can see it, it is already converted into standard units and floating point.  For instance GyroSensor is in degrees per second.  The PID comes later than that.

The raw gyro sensor data is scaled to be float degrees per second in flight/modules/Sensors/sensors.c and put in GyroSensor with GyroSensorSet().  It goes into GyroState from there and every time that changes, innerloop.c gets the values and puts them into gyro_filtered and that is what the PID acts on.

There seems to be a hold over from the days of integers though.  The PID code multiplies the inputs by 1000 at the beginning and divides by 1000 at the end.  This kind of looks like scaling to avoid integer overflow / underflow and tastes like the old days of direct hardware access, but it might be some reasonable required scaling.  Maybe just to match the values used in the integer days.  I cringe when I think about it, but it is only 500 x 2 x ?6? = 6000 FLOPS so it isn't really worth a special version to take it out.