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

add gyro functionality #115

Open
mstrens opened this issue Oct 23, 2023 · 229 comments
Open

add gyro functionality #115

mstrens opened this issue Oct 23, 2023 · 229 comments

Comments

@mstrens
Copy link
Owner

mstrens commented Oct 23, 2023

In this issue, I propose to discuss the best way to implement gyro functionality

@Mike-HRC
Copy link

mstrens

here is an explanation of the latching - it would affect PID calculations

  1. Stick priority controls how fast the Cortex "lets" go of the plane and stops stabilizing it. So the further one moves the sticks away from center the more the Cortex stops stabilizing the plane. In a 3D plane this setting is better if higher since a higher setting will cause the Cortex to let go of the plane earlier. Higher setting equals the stick taking priority.

  2. Latching controls how fast the Cortex starts to stabilize the plane again as the sticks are returned to center. In a 3D plane this setting should be lower as a lower setting means it take longer or the sticks to be closer to the center before the Cortex starts to stabilize the plane again.

Mike

@mstrens
Copy link
Owner Author

mstrens commented Oct 23, 2023

About stick priority :

  • I understand that when the correction on one axis is calculated on the PID, it is not always applied at 100% but with a ratio that depends on the original stick position;
  • when stick is centered, we apply 100% of correction (but taking also care of the ratio provided by the global gain and of the per axis gain).
  • When the "Stick priority" is set on 50% of max (= 10 on 20 in bavarian setup), does it means that if the stick is e.g at 75 % offset from the center, then the correction is not applied at all. When stick has less than 50% offset (e.g. 30%), the correction is apply proportionally to the offset (so with 40% if offset is 30%).
    Is this right?

About the latching control. It is not yet clear how this applies:

  • does it means that when the stick was in a position (enough far away from center e.g. more than 50% in my previous example) where no correction was applied and then it moves again to the center, it has to be close enough to center (e.g. offset less than 25%) before a correction is immediately applied again. So this would be a kind of hysteresis.
  • you said also that "it can take longer". Does it means that when the stick stays at e.g. 40% offset, then the correction foreseen for 40% offset will progressively be applied and reaches his "normal" value after some delay (e.g. 2 sec)

@aeropic
Copy link

aeropic commented Oct 24, 2023

I reset my pswd on Github :-)

stick priority :
what I did on my prototype is working quite well in RATE mode. Define the Stick priority setpoint (eg 50%) this means that between neutral position and 50% the correction applied proportionally to the stick position. Above 50% the correction is 0.
Yes a linear decrease of the correction is OK.
If the user does not want any stick priority just set the setpoint at 1000% or so...

latching:
It is not clear for me neither how it should behave. I understand this is mainly usefull for the HOLD mode to define the initial attitude. A kind of delay to learn in real time the new attitude setpoint. The delay should start when the stick is over the "stick prio" setpoint and returns to the neutral position.
If we assimilate the stick order to an angular rate order, when the angular rate order is 0 (again) this means that the pilot has finished his manoeuver on the given axis.... Obviously this approach is very empiric: when hovering a 3D plan, I'm not sure the ELE sticks comes very often in neutral position !

@Mike-HRC
Copy link

Some of these vary from manufacturer to manufacturer - I have read of some that immediately over-ride all "corrections" if there is a stick input for that axis (I often have my gyros set up a low-ish gain so that it will pick up a big change, but I still correct small extraneous inputs myself - it helps the plane fly more naturally.

My understanding (perhaps wrongly) that it was how quickly / aggressively it corrects for wind. Some FBL systems had different modes for different types of flight - 3D flight might select "Mechanical" as it wants fast / aggressive corrections whereas for a war-bird the user might select "Fluid" which would give gentler, longer return to position to reflect scale flight. This would be reflected in different PIS settings for different styles.

Th 2 paragraph that I pasted earlier were copied from a Bavarian Demon thread on RCG explaining the Latching and stick priority. My assumption (based upon other gyros) is that these are used to change the "feel" of how the plane flies...

@mstrens
Copy link
Owner Author

mstrens commented Oct 24, 2023

@aeropic
About stick priority:
Flightstab code does not have this concept and applies the correction proportionally to the stick position (100% when stick is centered, 0 % when stick is at the end).
I could add this parameter in a second phase.

Latching: I will not take care of this now.

I still have a conceptual issue. I will try to explain.
This issue occurs when size of Pwm changes depends on the direction of the stick movement.
Imagine a glider with 2 ailerons where we apply aileron differential in the handset mixer.
Imagine that when Ail stick goes 100%

  • to the left, left servo moves up and PWM changes from 1500 to 1900us. (so max travel = 400)
  • to the right, left servo moves down and PWM changes from 1500 to 1600us. (so max travel = 100)
    Those values are registered during the learning process.
    The correction takes care of the original stick position (linear stick priority) and then is applied to each servo based on the rate discovered during the learning process.

So, imagine that the original stick position is currently 1550. So oXs get a PWM value for left Ail of about 1540 (I did not calculate the exact value)
For each axis, oXs calculates gyro corrections (in us) without taking care of the mixer. So it just like there is a 1 to 1 relation between the stick and the servo (with 100% mixing).
Imagine that oXs calculated that a correction of 300 us should be applied to the right (as reaction of a wind effect).
Please note that I take a quite big correction for the example but it could happens because the stick is nearly centered.

The easy way to apply the correction would be just to add (subtract). So the servo would get a value of 1540-300 = 1240us.
It should be possible to limit it to the min value (=1600) but this would not be logic.

A more clever way (the one I expect to implement) is more complex and is the following.
The original stick position (OP) = 1550.
The expected position (EP) that the stick should have to apply the correction would be 1550-300 = 1250.
As OP and EP are on opposite sides compared to the neutral position (1500), the correction will be split in 2 parts
Upper (left) correction = 1500 - 1550 = -50
Lower (right) correction = 1250 - 1500 = -250.
On the upper part, we take care of the max travel for moving left : -50 * 400 / 500 = -40
On the lower part, we take care of the max travel for moving right : -250 * 100 / 500 = -25
Then we sum the 2 parts -40 -25 = -65
And we apply it to the uncompensated PWM channel of ail left: 1540 - 65 = 1475us

@aeropic
Copy link

aeropic commented Oct 24, 2023

I understand the conceptual issue...
My feeling is keep it simple.
Apply the stick damping with only one coefficient : the max side one.
Apply the same correction both sides of the given axis. If we get some ail differencial, I assume that compensations will be most of the case at small angles... Effect of differencial or not at compensation level should be neglectible...

@aeropic
Copy link

aeropic commented Oct 25, 2023

I looked at the code (not deeply enough for sure) and I have few questions/comments:

  • param.h : I do not understand what is the enum STICK_GAIN_THROW for? What does throw mean ? Why setting discrete values 1,2,3,4 ?

  • gyro.cpp : Are ...
    #define IDX_AIL 0
    #define IDX_ELV 1
    #define IDX_RUD 2
    ... the index of AIL, ELV and RUD ?

  • gyro.cpp
    correction and correctionpos/negside are expressed in microsec (+/-500 µsec ?), If yes I would add it in a comment:
    int16_t correction[3] = {0, 0, 0}; // gyro compensation applied to the 3 axis (micro seconds range -500/+500)
    int16_t correctionPosSide[3] = {0, 0, 0}; //gyro compensation after having taken into account possible differential on servos
    int16_t correctionNegSide[3] = {0, 0, 0}; // as above

  • apply gyro correction
    rcPwmChannelsComp[i] = rcPwmChannels[i] = fmap( rcSbusOutChannels[i]) ;
    I'm not familiar with this double "=" syntax. Is it equivalent to those 2 lines ? :
    rcPwmChannels[i] = fmap( rcSbusOutChannels[i]) ;
    rcPwmChannelsComp[i] = rcPwmChannels[i]

  • I need to understand what is calibration_wag : same for me !
    from the code I understand it is shaking the axis (+/- 150 micro sec) and this every 200msec but what for ? To see if the gyro is compensating ?

So far no other comment... Good start :-)

@Zebble
Copy link

Zebble commented Oct 25, 2023

In case it helps, there's this code:

https://github.com/John-RB/FlightStab

It's a replacement firmware for some really simple gyro's (8-bit Atmel MCU's w/MPU6050). It works really well. Even includes firmware for programming boxes that work nicely in the field.

Nothing fancy. No stick priorities. Just master gain, individual gains and configuration of wing type (delta, v-tail, std).

-zeb

@mstrens
Copy link
Owner Author

mstrens commented Oct 25, 2023

Thanks for the feedback.

  • parameter STICK_GAIN_THROW is used to manage the gain per stick depending on the position of the stick.
    // see enum STICK_GAIN_THROW. shift=0 => FULL, shift=1 => HALF, shift=2 => QUARTER
    //int8_t shift = cfg.stick_gain_throw - 1;
    int8_t shift = config.stick_gain_throw - 1;

    // stick_gain[] [1100, <ail*|ele|rud>_in2_mid, 1900] => [0%, 100%, 0%] = [0, STICK_GAIN_MAX, 0]
    stick_gain[0] = stick_gain_max - min(abs(ail_in2_offset) << shift, stick_gain_max);
    stick_gain[1] = stick_gain_max - min(abs(ele_in2_offset) << shift, stick_gain_max);
    stick_gain[2] = stick_gain_max - min(abs(rud_in2_offset) << shift, stick_gain_max);

stick_gain will give a % of correction on each axis depending on the position of the stick.
stick_gain_max = 400 (number of us between mid and min). 400 means that correction has to be applied at 100%
when stick is centered, stick gain will always be 400 (parameter has no impact)
when stick is at 100%, stick gain will always be 0 (parameter has no impact)
when stick is at 25% offset, stick offset = 100 us (nearly) and stick_gain = 300 (when param =1), or 200 (when param =2), or 100 (when param = 3).
So this parameter allows to apply gyro correction on a smaller part of the stick offset.

@mstrens
Copy link
Owner Author

mstrens commented Oct 25, 2023

gyro.cpp : Are ...
#define IDX_AIL 0
#define IDX_ELV 1
#define IDX_RUD 2
... the index of AIL, ELV and RUD ?
It just a way to remember in which order the axis are define in some array (it is easier to read code)

@mstrens
Copy link
Owner Author

mstrens commented Oct 25, 2023

gyro.cpp
correction and correctionpos/negside are expressed in microsec (+/-500 µsec ?), If yes I would add it in a comment:
int16_t correction[3] = {0, 0, 0}; // gyro compensation applied to the 3 axis (micro seconds range -500/+500)
int16_t correctionPosSide[3] = {0, 0, 0}; //gyro compensation after having taken into account possible differential on servos
int16_t correctionNegSide[3] = {0, 0, 0}; // as above

This part has to be reviewed.
I made an xls sheet to check the formula about splitting correction in pos and neg part.
Code will be adapted.

@mstrens
Copy link
Owner Author

mstrens commented Oct 25, 2023

apply gyro correction
rcPwmChannelsComp[i] = rcPwmChannels[i] = fmap( rcSbusOutChannels[i]) ;
I'm not familiar with this double "=" syntax. Is it equivalent to those 2 lines ? :
rcPwmChannels[i] = fmap( rcSbusOutChannels[i]) ;
rcPwmChannelsComp[i] = rcPwmChannels[i]

YES

@mstrens
Copy link
Owner Author

mstrens commented Oct 25, 2023

I need to understand what is calibration_wag : same for me !
from the code I understand it is shaking the axis (+/- 150 micro sec) and this every 200msec but what for ? To see if the gyro is compensating ?

I am not sure buy I expect it is used during some manual set up. It probably move the servo to confirm that a command/setup has been applied.

@mstrens
Copy link
Owner Author

mstrens commented Oct 25, 2023

In case it helps, there's this code:

https://github.com/John-RB/FlightStab

It's a replacement firmware for some really simple gyro's (8-bit Atmel MCU's w/MPU6050). It works really well. Even includes firmware for programming boxes that work nicely in the field.

Nothing fancy. No stick priorities. Just master gain, individual gains and configuration of wing type (delta, v-tail, std).

-zeb

Thanks for the link.
It is the one I used to define the main parameters and calculate corrections.
On top of it, I try to avoid having to define the type and wing and let the gyro uses the mixers as defined on Tx side.
For this I apply principles found in Bavarian gyro

@Zebble
Copy link

Zebble commented Oct 25, 2023

Thanks @mstrens.

Sounds great! If you need guinea pigs, I have a simple tester plane with elevons...

-zeb

@aeropic
Copy link

aeropic commented Oct 25, 2023

Thanks for the feedback.

  • parameter STICK_GAIN_THROW is used to manage the gain per stick depending on the position of the stick.
    // see enum STICK_GAIN_THROW. shift=0 => FULL, shift=1 => HALF, shift=2 => QUARTER
    //int8_t shift = cfg.stick_gain_throw - 1;
    int8_t shift = config.stick_gain_throw - 1;
    // stick_gain[] [1100, <ail*|ele|rud>_in2_mid, 1900] => [0%, 100%, 0%] = [0, STICK_GAIN_MAX, 0]
    stick_gain[0] = stick_gain_max - min(abs(ail_in2_offset) << shift, stick_gain_max);
    stick_gain[1] = stick_gain_max - min(abs(ele_in2_offset) << shift, stick_gain_max);
    stick_gain[2] = stick_gain_max - min(abs(rud_in2_offset) << shift, stick_gain_max);

stick_gain will give a % of correction on each axis depending on the position of the stick. stick_gain_max = 400 (number of us between mid and min). 400 means that correction has to be applied at 100% when stick is centered, stick gain will always be 400 (parameter has no impact) when stick is at 100%, stick gain will always be 0 (parameter has no impact) when stick is at 25% offset, stick offset = 100 us (nearly) and stick_gain = 300 (when param =1), or 200 (when param =2), or 100 (when param = 3). So this parameter allows to apply gyro correction on a smaller part of the stick offset.

Thanks for your answers.
Not sure I've all understood, I have to draw some curves... !
Anyway my concern was just to avoid steps on the values of gains. A continuous variation of gains function of the sticks inputs is needed to avoid jerky servos. But maybe this Algo gives a continuous gain...

@aeropic
Copy link

aeropic commented Oct 25, 2023

I need to understand what is calibration_wag : same for me ! from the code I understand it is shaking the axis (+/- 150 micro sec) and this every 200msec but what for ? To see if the gyro is compensating ?

I am not sure buy I expect it is used during some manual set up. It probably move the servo to confirm that a command/setup has been applied.

Yes, for sure it is to get a visual feedback when teaching different axis...

@mstrens
Copy link
Owner Author

mstrens commented Oct 25, 2023

Thanks for the feedback.

  • parameter STICK_GAIN_THROW is used to manage the gain per stick depending on the position of the stick.
    // see enum STICK_GAIN_THROW. shift=0 => FULL, shift=1 => HALF, shift=2 => QUARTER
    //int8_t shift = cfg.stick_gain_throw - 1;
    int8_t shift = config.stick_gain_throw - 1;
    // stick_gain[] [1100, <ail*|ele|rud>_in2_mid, 1900] => [0%, 100%, 0%] = [0, STICK_GAIN_MAX, 0]
    stick_gain[0] = stick_gain_max - min(abs(ail_in2_offset) << shift, stick_gain_max);
    stick_gain[1] = stick_gain_max - min(abs(ele_in2_offset) << shift, stick_gain_max);
    stick_gain[2] = stick_gain_max - min(abs(rud_in2_offset) << shift, stick_gain_max);

stick_gain will give a % of correction on each axis depending on the position of the stick. stick_gain_max = 400 (number of us between mid and min). 400 means that correction has to be applied at 100% when stick is centered, stick gain will always be 400 (parameter has no impact) when stick is at 100%, stick gain will always be 0 (parameter has no impact) when stick is at 25% offset, stick offset = 100 us (nearly) and stick_gain = 300 (when param =1), or 200 (when param =2), or 100 (when param = 3). So this parameter allows to apply gyro correction on a smaller part of the stick offset.

Thanks for your answers. Not sure I've all understood, I have to draw some curves... ! Anyway my concern was just to avoid steps on the values of gains. A continuous variation of gains function of the sticks inputs is needed to avoid jerky servos. But maybe this Algo gives a continuous gain...

This give a continuous gain on a range selected by the user (on whole range of the stick, on first 50 % only, on first 25% only)

@mstrens
Copy link
Owner Author

mstrens commented Oct 25, 2023

I put on Rc groups a proposal on the way to execute the learning process.
It seems me reasonably simple.
Comments are welcome.

@mstrens
Copy link
Owner Author

mstrens commented Oct 26, 2023

So the bug is probably when I reused the PIO/SM from GPS.
I will try to check it but I am not available this PM and I also try to concentrate on gyro up to some clean point.

So I also presume that there is no issue with the sdk being used.
It is only oXs related (and depend on options activated in config)

@Satcomix
Copy link

Thanks for the info,
I can't test this evening either because work calls. I would have time again from tomorrow morning.

@aeropic
Copy link

aeropic commented Oct 27, 2023

gyro HOLD conceptual question
If I understand well, the gyro compensation in HOLD mode is based upon gyro angular rates (gyroX/Y/Z) and some gyro gains config.vr_gain[i] all this inserted in a PID loop.
There is no absolute attitude but only integrated angular rates...

Don't you fear some drift after few seconds of integration?

At the opposite the estimated attitude (the one used in camera stab) is computed in the OXS Mahony filter taking into account the 3 gyro rates and the 3 accelero data. The Mahony filter thus recalibrates the initial attitude of the gyro trying to avoid drifts.
Of course, in yaw, the accelero is blind if the plane flies level and this is the reason why you observe some drifts in yaw in OXS.

But with the PID algo based only on gyro rates, I'm afraid all axis will drift?

Do I miss something ?

@mstrens
Copy link
Owner Author

mstrens commented Oct 27, 2023

You are right.
Still I think (not 100% sure) that there are 2 different concepts HOLD and STABILIZE that differs when sticks are moved and then release to center.
In HOLD, when sticks are centered after having been moved, the gyros tries to keep the current position (the one when sticks have been released).
Indeed in HOLD mode with stick centered, there could be slow change of attitude but this has to be corrected from time to time by the pilot.
In STABILIZE, when sticks are centered after having been moved, the gyro tries to set the plane hozizontal (so corrections are based on the plane attitude and not on gyro rates).

I am not sure that it makes sense to ask the gyro to maintain the attitude of the plane as it was when HOLD has been engaged if the sticks have been off center in the meantime.

Perhaps I am wrong. I have no experience with gyro.

@aeropic
Copy link

aeropic commented Oct 27, 2023

From what I understand with the definition you give of HOLD and STABILIZE, both modes share the same equations , the only difference is the setpoint attitude.
In Hold, it is the last attitude when stick was centered. The gyro tries to keep the last attitude.
In STABILIZE, whatever the intital attitude, the gyro tries to keep the plane horizontal.
Except from the setpoint (last attitude/horizontal) both shall be based on an absolute attitude estimation. Any drift of gyro due for instance to a bad estimate of the scalefactor or to integrated numerical errors, will be translated into a drift of attitude.
This will be the case unless an absolute attitude sensor (for us an accelero able to sense and estimate the gravity vector) will reinitialize the gyro from time to time (job of the inertial measurement Unit filter for us the Mahony filter).

This is the reason why the RATE mode is much simpler to code and make it work. The gyro only removes the wind and compensates angular rates. When a plane is stabilized, whatever its attitude, the angular rates are equal to zero. For this mode using only gyroX/Y/Z is fine.

RQ: I worked in Space business, in satellites we get the same issues. gyros are drifting, we compensate all this inside a big kalman filter which is mixing gyro values and absolute attitude given by star trackers. Star trackers may be unlocked, unable to find the attitude, when the satellite is rotating too fast, during those periods of time, the kalman relies on gyro angular rates to estimate the attitude. When the satellite attitude is quiet, star trackers give again an attitude measure which is used by the Kalman filter to reinitialize the gyros... gyros are good for high frequencies while absolute sensors (acceleros, star trackers) are noisy but good in low frequencies...

@Satcomix
Copy link

Hello Aeropic,
"RQ: I worked in Space business, in satellites.....", welcome to the club :-))
Look at my nickname and cross out the last two letters (ix)
Greetings,
Torsten

@aeropic
Copy link

aeropic commented Oct 27, 2023

Hi Torsen,
For me it was Earth Observation sats ...
We will open a club indeed ;-)

@Mike-HRC
Copy link

You are using the terminology differently to how most people use it for gyros (plane or FBL), generally

Stabilised - means correction of changes of attitudes due to "outside forces" (wind, turbulence etc.) in this case the gyro will generate "corrections" to counter the "outside force", it does not know or care then attitude of the plane or if it is level. This is what AS3X does and how most people fly with gyros - much less set-up needed. This is only using the 3-axis gyro.

Auto-level - in this case the gyro will try to return the plane to the attitude that it learned at set-up time (i.e. flat and level) - this uses 6-axis gyros to learn flat and level in the initialisation. This is used mainly by beginners or as a "rescue" if people get badly out of shape. I have heard of many gyros struggling in this mode.

Hold - not many gyros have this - it is similar to "Heading Hold" where the gyro will try to keep the plane at the attitude commanded when the last stick input was received (i.e. not necessarily flat and level).

These are certainly the way that the different modes are know in HobbyEagle, FrSky, Spektrum and most heli FBL units that I know

@Zebble
Copy link

Zebble commented Oct 27, 2023

The terminology seems to be used inconsistently, which makes it even more confusing. @Mike-HRC 's description is what sits in my brain too. Some differences I've seen:

Stabilised = Normal, Auto-Level, Rate
Auto-Level = Stabilised, Trainer, or often combined with Angle/Horizon or other modes
Hold = Lock, POS, 3D

I know the code @mstrens is using has both Rate and Hold modes and I'd be happy with just the Rate mode.

@mstrens
Copy link
Owner Author

mstrens commented Oct 27, 2023

Thanks for the clarification.
I expect that most gyro in HOLD mode uses only the rates (angles/sec) provided by the sensor.
And that they accept a low drift.
This is for sure the way flightstab gyro program works.

This would for sure not be the case in AUTO_LEVEL mode.

@mstrens
Copy link
Owner Author

mstrens commented Oct 27, 2023

FYI, I put on github test a version 2.9.5 with some more code in order to support a gyro.
You can test it if you want but take care:

  • there are for sure many bugs (I did not yet tested)
  • there are no USB commands to edit the parameters that should be stored in the config. Currently you have to edit 4 define in gyro.cpp in function initGyroConfig();
    Currently I put:
    #define GYRO_CHANNEL_CONTROL 9 // 0 means channel 1
    #define GYRO_CHAN_AIL 10 // 0 means channel 1
    #define GYRO_CHAN_ELV 11 // 0 means channel 1
    #define GYRO_CHAN_RUD 12 // 0 means channel 1
  • there are dummy parameters for gyro mixers (only one Ail is compensated). You can edit the function initGyroMixer() to add more corrections or you can try the learning process. This process is coded but the result is not yet saved in flash. You can still see the new (current) parameters with the ENTER usb command.

To test it you have to connect oXs to a receiver with a wire that provides Rc channels (sbus,, fbus,...) and to a MPU6050 (scl/sda)

Note: the learning process has been modified. Please read the file "gyro concepts.md" in the folder "doc"
The led changes in the learning process are not yet implemented.

@mstrens
Copy link
Owner Author

mstrens commented Nov 20, 2023

I just tested with the 3D plane. I get the expected servo amplitude which is proportional to the angular error wrt to horizontal flight.

I found a funny behavior I got the same with my first gyro code. If you set the plane fully upside down, when crossing 180° in roll, the aillerons change in direction from +45° to - 45°. This is due to the fact estimated attitude (cameraRoll) switches from +180° to -180°... I did not find any solution for this.

I expect it is "normal". If cameraRoll is e.g. +150, the correction must be in one direction and when -150 it must be in the opposite direction.

Note: on pitch, I expect some more issue because the pitch value varies only in a range +90/-90°.
Note: the value of roll becomes quickly abnormal when pitch is close to +90° or -90°. I did not found a solution for this.
Also when roll is + or -90° there could be some strange servo behavior (not sure) in stabilize mode.

@aeropic
Copy link

aeropic commented Nov 20, 2023

Note: on pitch, I expect some more issue because the pitch value varies only in a range +90/-90°. Note: the value of roll becomes quickly abnormal when pitch is close to +90° or -90°. I did not found a solution for this. Also when roll is + or -90° there could be some strange servo behavior (not sure) in stabilize mode.

All this will be fun to test in flight... I hope I will not crash my dirty plane before as it is the only one I can sacrifice !

@mstrens
Copy link
Owner Author

mstrens commented Nov 21, 2023

I made a few (minor) changes in 2.10.9 version:

  • I avoid to recalibrate automatically the gyro after a watchdog (should never happen)
  • I discard the results of the automatic gyro calibration after a reset if the gyro is moving (to big difference between min and max during the calibration). In this case, the offsets stored in the flash during horizontal calibration are used.
  • I check that the plane is still during horizontal calibration (MPUCAL+H). Results are discarded if plane move
  • In stabilize mode, I set the gyro corrections to 0 when roll or pitch is more than 60° (in absolute value). I hope it help to secure the plane.

@aeropic
Copy link

aeropic commented Nov 21, 2023

Humm, not sure the last bullet will help to secure the plane.... In case of panic, the pilot may leave the plane in an extreme attitude, then if he relies on stabilize to recover the situation what would happen ?

I fly a parrot disco (autopilot drone flying wing). This bird can be set to full manual using a switch on the TX, I remember some situations with the plane diving towards ground, just switch to autopilot and it does the job whatever initial attitude!

@mstrens
Copy link
Owner Author

mstrens commented Nov 21, 2023

The issue I see is that roll does not seems reliable when pitch is close to 90°.
I tried about 5 different algorithm to calculate roll and none provided good result.
So I do not know what must be done.
Furthermore, normally ail servo is controlled by roll but when pitch is 90°, roll does not help anymore to stabilize the plane.
In the same way, elv servo is controlled by pitch but when roll is 90° , pitch does not help to stabilize the plane (it should be yaw that should avoid diving).

I do not know how "good" flight controllers (like ardupilot, betaflight,...) works. They are so complex that I do not understand the code. Simple flight controllers seems to have the same issue as oXs about the stabilization.

@aeropic
Copy link

aeropic commented Nov 21, 2023

I understand... Let's see the inflight results :-)

@Satcomix
Copy link

Hello Mstrens,
Protocol: FBUS
Version: 2.10.28
I just built a new board and wanted to calibrate the MP6050 (GY-86).
Sensor is horizontal.
If MPUCAL=H the following error message appears:
Error in IMU calibration: too many variations in the acceleration values
I've tried it several times now.
MPUCAL=V with nose up works without error message.
Greetings,
Torsten

@mstrens
Copy link
Owner Author

mstrens commented Nov 26, 2023

When you use the command MPUCAL, the MP6050 may not move.
oXs reads the 1000 X Acc x,y,z and register for each axis, the min and max values.
Then it checks that the difference between min and max does not exceed 100.
Perhaps that I have to increase the tolerance.
It is defined in mpu.cpp:
#define MAX_ACC_DIFF 100

@Satcomix
Copy link

When you use the command MPUCAL, the MP6050 may not move. oXs reads the 1000 X Acc x,y,z and register for each axis, the min and max values. Then it checks that the difference between min and max does not exceed 100. Perhaps that I have to increase the tolerance. It is defined in mpu.cpp: #define MAX_ACC_DIFF 100

Hello Mstrens,
The GY-86 lies horizontally on the table, so nothing moves.
Still I can't do MPUCAL=H.

@mstrens
Copy link
Owner Author

mstrens commented Nov 26, 2023

Your mp6050 is perhaps more noisy.
Can you try to change
#define MAX_ACC_DIFF 100
to e.g.
#define MAX_ACC_DIFF 200

@Satcomix
Copy link

I set it to:
#define MAX_ACC_DIFF 200
no improvement.
Cmd to execute: MPUCAL=H
Before calibration:
Offset Values in config:
Acc. X = 0, Y = 0, Z = 0
Gyro. X = 0, Y = 0, Z = 0
Error in IMU calibration: to much variations in the acceleration values
I will try 500, maybe it helps.
It would be the first GY-86 from Sertronics to be this noisy.

@Satcomix
Copy link

I set it to:
#define MAX_ACC_DIFF 500
Offset Values in config:
Acc. X = -814, Y = -124, Z = 317
Gyro. X = -22, Y = -30, Z = -83
Horizontal calibration done: use SAVE command to save the config!!

@Satcomix
Copy link

Hello Mstrens,
Version 2.11.1-test with FBUS Protocol
I just did several builds with Camera Stabilizer enabled.
The pitch and roll value can be changed from -200% to 200% =500-2500us.
Roll servo also works from 500 to 2500us, but pitch servo only works like +/-100% from 988us to 2012us.
Best regards,
Torsten

@Satcomix
Copy link

Satcomix commented Dec 11, 2023

Hello Mstrens,
New test with version 2.11.3-test and FBUS protocol.
I tried 3 different GY-86, all from Sertronics / Germany
but all show the same in MPUCAL=H
Cmd to execute: MPUCAL=H
Before calibration:
Offset Values in config:
Acc. X = 0, Y = 0, Z = 0
Gyro. X = 0, Y = 0, Z = 0
Error in IMU calibration: to much variations in the acceleration values

can you please set
#define MAX_ACC_DIFF 500
as a default value in the next version.
With 300 and 400 it make the same output. With 600 it is direct ok, and with 500 you must try a little bit.
Thank you.
regards,
Torsten

@mstrens
Copy link
Owner Author

mstrens commented Dec 11, 2023

It is done in 2.11.4 (500 for ACC, for gyro, I put 200 instead of 100)

@Satcomix
Copy link

Ok, thank you.
I will test in one hour.
First you put 100 and than in the last version you go to 300.
With Ver 2.11.4 we go to 500.
Can you explain me why?
regards,
Torsten

@mstrens
Copy link
Owner Author

mstrens commented Dec 11, 2023

The goal is to detect if the imu is moving during calibration (and so to reject calibration).
As the imu is noisy there must be some margins.
I expected that a margin of 100 would be enough but you said it was not enough.
Then I expected that your imu (that required 500) was exceptionally noisy and so I set the value on 300.
Now, if it is not unusual to have a noise of 500, I increased the value to 500.
It is just a try and error process.

@Satcomix
Copy link

Hello Martens,
For hundreds of tests up to version 2.8.0 there were no problems with the setting:
#define MAX_ACC_DIFF 100
Only since the gyro was added to the new versions have there been problems, first with 100 which I increased to 300 and now in the last version I have to set 500. This has nothing to do with my Noisy IMU, doesn't it?
All my MP6050/GY-86 worked at 100 for 1 year. Weird.
But I have another question that was asked to me:
The V1 to V4 voltage or current values ​​sometimes change very quickly. I know, you could lower the prioritization a little so that hopping that is too fast doesn't become visible, but could you also install an average for the V1-V4 values ​​like with the ADC1115?
Or can I set the 0 in NBR_VOLTAGES to e.g. 10 to get a higher average?
Now we have 50 conversations per loop, = 100 measurements.
sumVoltage[MAX_NBR_VOLTAGES] = { 0,0,0}; // used to calculate average voltage
regards,
Torsten

@mstrens
Copy link
Owner Author

mstrens commented Dec 11, 2023

I do not totally understand your question about averaging voltage conversions.
Currently SUM_COUNT_MAX_VOLTAGE is set to 50.
It means that the voltages (or current/temp) transmitted to the handset are the averages of 50 loops.
In fact in each loop, oXs performs 3 ADC conversions but only summarizes 2 of them.
So the values transmitted to the handset are the averages of 100 ADC conversions.
It is strange that there are lots of fluctuation with 100 conversions.
If you change SUM_COUNT_MAX_VOLTAGE to e.g. 500, then the transmitted values will be the averages of 1000 conversions.
The drawback is that this average will be calculated only once every 2 sec (instead of once every 0.2 sec currently).

@Satcomix
Copy link

Hello Mstrens,
I had already read the hundred measurements from the voltage.h.
But if I now set the 50 to 100 or 500 I have 200 or 1000 conversations for all 4 values ​​(V1 to V4/Temp1-2)
I was hoping for a way to average the individual values ​​differently.
The Temp1+2 values ​​are always very stable, which is normal, and the V1 doesn't fluctuate that much, but when an ESC is used, V2 jumps back and forth quite a bit.
Then I prefer to prioritize Value V2 from 80 to 200, so that it appears a little quieter on the display.
regards,
Torsten

@Mike-HRC
Copy link

Mike-HRC commented Dec 11, 2023 via email

@mstrens
Copy link
Owner Author

mstrens commented Dec 11, 2023

In the meantime, in order to get a better Idea of the raw fluctuations (and so to avoid a potential bug in the calculations) I made a version 2.11.5 that should print a line (on the PC) with the index (0=VOLT1, 1,=Volt2,...) the minimum , maximum and average raw adc values.

Now that I read your last messages, I expect that there is no bug in oXs but it is just the issue that oXs sending frequency is to high.
In order to get only one value per second (which is enough from my point of view), I could easily change the value 50 to 250 to increase the number of loops part of an averaging.

@Satcomix
Copy link

I never said it was a bug.
I just wanted to delay/smooth the display a little with a higher average, which you can also do with the change in the transmission/polling time of the individual sensors, from 80 to 160.

@Satcomix
Copy link

Satcomix commented Dec 11, 2023

In the meantime, in order to get a better Idea of the raw fluctuations (and so to avoid a potential bug in the calculations) I made a version 2.11.5 that should print a line (on the PC) with the index (0=VOLT1, 1,=Volt2,...) the minimum , maximum and average raw adc values.

Now that I read your last messages, I expect that there is no bug in oXs but it is just the issue that oXs sending frequency is to high. In order to get only one value per second (which is enough from my point of view), I could easily change the value 50 to 250 to increase the number of loops part of an averaging.

That's exactly what I wanted to avoid.
If the current value is only calculated every second, the current peaks are also excluded from the capacity calculation and this then becomes more inaccurate.
I could be wrong, it's just my opinion

@mstrens
Copy link
Owner Author

mstrens commented Dec 11, 2023

@Satcomix
At some time I suspected a bug because several users had remarks about the fluctuations.

Changing the transmission/polling time is probably not the best solution because:

  • it is valid only for some protocols
  • even for some protocols where it could be used, it would not have an impact if there is only one (or not many) fields to transmit because the priority is "relative".

If there is a consensus, I can change the parameter to 250 and remove the debug messages I just added.

@mstrens
Copy link
Owner Author

mstrens commented Dec 11, 2023

I forgot to say that increasing or not the number of loops for averaging does not have an impact on the value for the consumed capacity.

@Satcomix
Copy link

Satcomix commented Dec 11, 2023

I forgot to say that increasing or not the number of loops for averaging does not have an impact on the value for the consumed capacity.

I was under the assumption that if I encrease the loops, e.g. set V2 Current higher, the calculation of the capacity would be inaccurate because it is calculated from the current. When increasing this value, it is about the time it takes to transmit/display a value and not the time it takes to calculate a value. Otherwise the capacity calculated from the current value would be inaccurate.
EDIT:
Next Test with Version: 2.11.5-test FBUS protocol
The values ​​V1 to V4 no longer fluctuate as much as you said.
Thank you.

@Satcomix
Copy link

Satcomix commented Apr 2, 2024

Hello Mstrens,
I'll get back after a while and hope you're doing well.
A question about the Angle of Attack DIY sensor, could you set it to DIY 5149 or 5150 (RESERVE9 , RESERVR10)?
Today I looked for the cause of my new SENSOR CONFLICT which come with version 2.13.1 and found it at address 5147.
But since we have been using the DIY addresses 5143 to 5148 as 6x sequencer feedback for some time, there was of course a problem. I couldn't find anything about AoA in the documentation or on the GitHub page either, so the search for the 5147 cause took a long time.
What task or display does this AoA fulfill? Gyro Pitch and Roll at 0° and AoA changes from 0° to 51°.
Best regards,
Torsten

@mstrens
Copy link
Owner Author

mstrens commented Apr 3, 2024

AOA (angle of attack) was a request of a member.
I did not publish it (yet) because I do not think it is really useful and I was waiting his feedback. Still after several weeks, I did not got a feedback. This field calculates the difference between roll angle and and second angle (based on Vspeed and Gps Speed).

I do not understand why you got an issue with this sensor ID.
For the sequencer feedback, oXs uses only 2 ID's (RESERVE3 and RESERVE4).
AOA is transmitted as RESERVE5.
RESERVE5 is not used by sequencer functionality.
If you want to change the ID's for some telemetry fields you can edit some lines in sport.h
E.g. at the end of this file, you currently have
#define DIY_RESERVE3 0X5143
#define DIY_RESERVE4 0X5144
#define DIY_RESERVE5 0X5145
#define DIY_RESERVE6 0X5146
#define DIY_RESERVE7 0X5147

@Satcomix
Copy link

Satcomix commented Apr 3, 2024

AOA (angle of attack) was a request of a member. I did not publish it (yet) because I do not think it is really useful and I was waiting his feedback. Still after several weeks, I did not got a feedback. This field calculates the difference between roll angle and and second angle (based on Vspeed and Gps Speed).

I do not understand why you got an issue with this sensor ID. For the sequencer feedback, oXs uses only 2 ID's (RESERVE3 and RESERVE4). AOA is transmitted as RESERVE5. RESERVE5 is not used by sequencer functionality. If you want to change the ID's for some telemetry fields you can edit some lines in sport.h E.g. at the end of this file, you currently have #define DIY_RESERVE3 0X5143 #define DIY_RESERVE4 0X5144 #define DIY_RESERVE5 0X5145 #define DIY_RESERVE6 0X5146 #define DIY_RESERVE7 0X5147

Hello Mstrens,
Thank you for the feedback.
I put the AoA sensor to Reserve 9, so its ok for me.
The Sequencer is grown up to 6 Senor IDs, from DIY5143 to DIY5148. I make some new builds on Version 2.13.1, and expand the sensors from Reserve3 to Reserve10, because we need Reserve 3 to Reserve 8 for the Sequencer with 48 GPio Outputs.
best regards,
Torsten

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

No branches or pull requests

6 participants