Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bolt + BQdeck persistent parameters #931

Merged
merged 10 commits into from
Feb 7, 2022
Merged

Conversation

knmcguire
Copy link
Member

@knmcguire knmcguire commented Feb 2, 2022

a PR to start making parameters persistent that are necessary when making a bigger drone with the BQ deck or Bolt.

@knmcguire knmcguire marked this pull request as draft February 3, 2022 09:41
@knmcguire
Copy link
Member Author

knmcguire commented Feb 3, 2022

actually we should have mass outside of the Mellinger controller as a more global assessable parameters.

@knmcguire
Copy link
Member Author

So currently tuning values in both PID and Mellinger, as noise values in the EKF are persistent in this PR. Anything else missing?

@knmcguire
Copy link
Member Author

Perhaps the nonstandard IMU orientation values? But then these need to be converted to a parameters as well. @matejkarasek what do you think?

@knmcguire
Copy link
Member Author

knmcguire commented Feb 3, 2022

Just going to start a list here of what I think could be persistent based on the parameter list.

EDIT:
Values that can to be converted to parameters and then persistent.

@matejkarasek
Copy link
Contributor

matejkarasek commented Feb 3, 2022

Perhaps the nonstandard IMU orientation values? But then these need to be converted to a parameters as well. @matejkarasek what do you think?

Yes, good idea to do that.

If we consider some motors can be servos, two more ideas (that will require code changes):

  • for supervisor.c, param that says which motors are "thrusters" and which servos
    // We say we are flying if the sum of the ratio of all motors are above
    // a certain threshold.
    //
    static bool isFlyingCheck()
    {
    int sumRatio = 0;
    for (int i = 0; i < NBR_OF_MOTORS; ++i) {
    sumRatio += motorsGetRatio(i);
    }
    return sumRatio > SUPERVISOR_FLIGHT_THRESHOLD;
    }
  • for motors.c, param that specifies the neutrel position at which the (servo) motor initializes
  • // Output zero power
    motorsSetRatio(MOTOR_M1, 0);
    motorsSetRatio(MOTOR_M2, 0);
    motorsSetRatio(MOTOR_M3, 0);
    motorsSetRatio(MOTOR_M4, 0);
    }

These would certainly deserve a new PR, though... can help...

@matejkarasek
Copy link
Contributor

And two more ideas (with code changes needed):

  • 1S voltage is now hardcoded, but with Bolt you can have 2S-4S
  • thrust mapping?
    // We have data that maps PWM to thrust at different supply voltage levels.
    // However, it is not the PWM that drives the motors but the voltage and
    // amps (= power). With the PWM it is possible to simulate different
    // voltage levels. The assumption is that the voltage used will be an
    // procentage of the supply voltage, we assume that 50% PWM will result in
    // 50% voltage.
    //
    // Thrust (g) Supply Voltage PWM (%) Voltage needed
    // 0.0 4.01 0 0
    // 1.6 3.98 6.25 0.24875
    // 4.8 3.95 12.25 0.49375
    // 7.9 3.82 18.75 0.735
    // 10.9 3.88 25 0.97
    // 13.9 3.84 31.25 1.2
    // 17.3 3.80 37.5 1.425
    // 21.0 3.76 43.25 1.6262
    // 24.4 3.71 50 1.855
    // 28.6 3.67 56.25 2.06438
    // 32.8 3.65 62.5 2.28125
    // 37.3 3.62 68.75 2.48875
    // 41.7 3.56 75 2.67
    // 46.0 3.48 81.25 2.8275
    // 51.9 3.40 87.5 2.975
    // 57.9 3.30 93.75 3.09375
    //
    // To get Voltage needed from wanted thrust we can get the quadratic
    // polyfit coefficients using GNU octave:
    //
    // thrust = [0.0 1.6 4.8 7.9 10.9 13.9 17.3 21.0 ...
    // 24.4 28.6 32.8 37.3 41.7 46.0 51.9 57.9]
    //
    // volts = [0.0 0.24875 0.49375 0.735 0.97 1.2 1.425 1.6262 1.855 ...
    // 2.064375 2.28125 2.48875 2.67 2.8275 2.975 3.09375]
    //
    // p = polyfit(thrust, volts, 2)
    //
    // => p = -0.00062390 0.08835522 0.06865956
    //
    // We will not use the contant term, since we want zero thrust to equal
    // zero PWM.
    //
    // And to get the PWM as a percentage we would need to divide the
    // Voltage needed with the Supply voltage.
    static uint16_t motorsCompensateBatteryVoltage(uint16_t ithrust)
    {
    float supply_voltage = pmGetBatteryVoltage();
    /*
    * A LiPo battery is supposed to be 4.2V charged, 3.7V mid-charge and 3V
    * discharged.
    *
    * A suiteble sanity check for disabiling the voltage compensation would be
    * under 2V. That would suggest a damaged battery. This protects against
    * rushing the motors on bugs and invalid voltage levels.
    */
    if (supply_voltage < 2.0f)
    {
    return ithrust;
    }
    float thrust = ((float) ithrust / 65536.0f) * 60;
    float volts = -0.0006239f * thrust * thrust + 0.088f * thrust;
    float percentage = volts / supply_voltage;
    percentage = percentage > 1.0f ? 1.0f : percentage;
    return percentage * UINT16_MAX;
    }

@matejkarasek
Copy link
Contributor

For lighthouse, it could certainly be the position of the markers on the airframe...

@knmcguire
Copy link
Member Author

Very good input @matejkarasek, thanks!

For the controller gains, currently I made the attitude rate parameters persistent and planning now to do attitude paramters. Theoretically, or rather in an ideal world, the position and velocity gains should not have to be changed... but ofcourse reality is different.
Do you need to hardcode those pos and vel pid values for your platform ?

@knmcguire
Copy link
Member Author

About your comments about motors.c and the initialized thrust, Isn't the param group powerdist about that?

@matejkarasek
Copy link
Contributor

Could be a suitable param group indeed. Now it contains only idle power for brushless motors.
I suggest adding the startup power, which is the "power"/pwm signal/position of the motor at startup. This should be 0 for motors giving thrust (as hardcoded now) but for servos this should be a non-zero value, configurable for each servo separately...

@matejkarasek
Copy link
Contributor

matejkarasek commented Feb 3, 2022

Do you need to hardcode those pos and vel pid values for your platform ?

Yes, we do... #reality :)

@knmcguire
Copy link
Member Author

For lighthouse, it could certainly be the position of the markers on the airframe...

This will be a bit difficult for the yaw estimation due to a strong assumption that the deck needs to be flat and on top of the platform. But it's a good one thought! I have put it in the list so it least it is written down.

@knmcguire
Copy link
Member Author

@matejkarasek with the thrust mapping and 1s voltage you mean the values that are hardcoded in these lines?

if (supply_voltage < 2.0f)

float thrust = ((float) ithrust / 65536.0f) * 60;
float volts = -0.0006239f * thrust * thrust + 0.088f * thrust;

@matejkarasek
Copy link
Contributor

Yes indeed, for the thrust mapping those two lines.

For the battery voltage, there might be a few more places in the code... Like detection of low voltage and indication with the LEDs...

@matejkarasek
Copy link
Contributor

For lighthouse, it could certainly be the position of the markers on the airframe...

This will be a bit difficult for the yaw estimation due to a strong assumption that the deck needs to be flat and on top of the platform. But it's a good one thought! I have put it in the list so it least it is written down.

Yeah, true... Well it could be xyz position of the deck on the airframe at least (now in the code you do that per receiver I think). Just an idea anyway for possible future updates :)

@knmcguire
Copy link
Member Author

For now there are 90 parameters set as persistent.

@knmcguire
Copy link
Member Author

So I've just flashed this on a crazyflie, set every persistent parameter in eeprom that is possible, restarted the crazyflie and...... no crash! So it seems to be doing pretty good :)

@knmcguire knmcguire marked this pull request as ready for review February 7, 2022 14:20
@tobbeanton
Copy link
Member

I think the list is a really good start. For those properties that do not have a parameter yet I think we should add them in separate pull requests such as board alignment, battery levels etc. As we have also decided to shrink the platform concept a bit, due to different default values, and introduce kbuild to make selection easy. Thus the CF2.1, Bolt and possibly Flapper would be its's own platform with own binary (own compile time flags).

One parameter I'm thinking about the the forceArm which is tagged now. The whole idea of that parameter is for something external to have to set it to be able to arm the motors. If this could be set permanently the purpose might be gone. On the other side, it would be easy to set it to different default value for different platform. E.g CF2.1 will not require forceArm but Bolt could. I think I changed my mind, let's keep it as persistent.

We should keep in mind also that the 8Kbyte EEPROM can store somewhere between 200-300 parameters in total.

@krichardsson krichardsson merged commit 6066c64 into master Feb 7, 2022
@krichardsson krichardsson deleted the persistent-parameters branch February 7, 2022 14:31
@matejkarasek
Copy link
Contributor

Nice start indeed! Already helps to minimize the amount of changes needed in our fork compared to master..

I agree it might be even better to split the current CF2 platform into more specific ones (CF2.1, Bolt, Flapper, ...) as it would simplify the very first setup, no need to change to the platform-specific default values after the first flashing...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants