Altitude Hold improvement solution

This forum is dedicated to software development related to MultiWii.
It is not the right place to submit a setup problem.
Software download
Post Reply
User avatar
dramida
Posts: 473
Joined: Mon Feb 28, 2011 12:58 pm
Location: Bucharest
Contact:

Re: Altitude Hold improvement solution

Post by dramida »

Crashpilot1000 wrote:I sum it up:
2 people (dramida & nhadrian) hold the holy grail of alt hold in their hands but haven't been able to disclose any concise details on the last 4 pages. Just some general ideas, you could get from anyone in the street.
......
So long
Kraut ROB


As i mentioned in first post, i am not a Arduino C programmer, i played with leds, switches, serial com and servos and that's all. The algorithm behind altitude hold that i suggested is constructed around some obvious facts as:

-DJI uses accelerometer for Altitude Hold (try to push it in flying and will react instantaneously to your push);
-Every FC has about same sensor accuracy (even use the same baro, gps and Acc/giro) but has significant better results due to program;
-GPS has an instantaneous 2 m error accuracy in X-Y plane and at least same for altitude Z so is far worst than baro;
- More time we collect data from a sensor, more accurate the reading is;
- Accelerometer offers an instant respunse to movement but over time it can't ceep the altitude fixed because does not sense slow movements below the level of its noise
- Barometer MS6511 has an noisy output but when averaging the output for a few seconds, the altitude is clearly revealed. This could compensate the long term drift of altitude keept by accelerometer.

I hope this remarks could inspire a nice programmer to improve the Alt Hold algorithm.
And BTW, with 3.5, 0.15, 10 i have a quite good alt hold with slow variations around 50 cm.

vpb
Posts: 231
Joined: Mon Jul 23, 2012 4:09 pm

Re: Altitude Hold improvement solution

Post by vpb »

Hi dramida, about your idea - the ALT hold solution and the ALT PID 3.5 0.15 10, what is your tuning procedure? I want to test your idea. Tks!

User avatar
dramida
Posts: 473
Joined: Mon Feb 28, 2011 12:58 pm
Location: Bucharest
Contact:

Re: Altitude Hold improvement solution

Post by dramida »

vpb wrote:Hi dramida, about your idea - the ALT hold solution and the ALT PID 3, 0.15, 7 what is your tuning procedure? I want to test your idea. Tks!


I just checked and the actual values Alt PID are 3, 0.15, 7, i played a lot and i forgot the changes since it works satisfactory even in forward flight. Please see video and hear the engines when alt hold and gps pos hold are activated

http://www.youtube.com/watch?v=B4D2CRxx7zk



My easy Alt Hold setup procedure based on actual 2.1 average algorithm:

1-Put zero on Alt P and Alt I. Then play with D (in reality D term represents the proportional accelerometer influence over thrust) and trying to find a sweet spot where copter maintains altitude on short term. You know you got a good "D" value when pushed down or up, the copter reacts instantly to your change and keeps its altitude. Unfortunately, there is one single proportional term to this loop, so it is less perfect than it could be (PID).

2- After finding the sweet spot accelerometer response D, any other influence on thrust like baro (P, I) would make the copter overshoot. So we need to lower a fraction of D and complete the response with Baro PI loop. My sweet spot of D is 15 and i lowered it to 7. You could try some 50 to 80% from the initial D find, my opinion is that D should be more than half.

3-Now leave alone the shrinked D (I=0 during this time) and start increase P term until you got altitude BIG oscillation with an continous increasing amplitude . When you got altitude self increasing oscillation, half the P. Now the copter should hold its altitude in a range of about 1 meter because the P only term loop can't fix the altitude error exactly.

4- Leave alone P and D found as described above and increase I term until the copter stays in a range of 20 cm up or down. 20 cm is the noise of inflight baro MS6511. That's it.


Note:
The 20cm result is valable using MS6511 baro.
The baro shoud be protected by direct sunlight and direct wind.
All test below must be made at an altitude higher than 1.5 meters to avoid ground effect.
All tests should be made on a calm weather.
Blutooth data connection with GUI is invaluable for graph visualisation of Baro pressure or even inflight parameter settings as i did. I let the copter on GPS Pos Hold howering above a field and i played with the parameters from my laptop.

vpb
Posts: 231
Joined: Mon Jul 23, 2012 4:09 pm

Re: Altitude Hold improvement solution

Post by vpb »

Hi dramida, thanks for your instructions.

I've just tested tuning ALT recently for the method I read somewhere (maybe yours), yes luckily it's like your way, I put P&I at 0, and play with D. I increase big step to 30, it yoyo-ed :D, I decrease some steps downto 22, it looks fine. But I couldnot continue due to late evening and the black cloud was going to cover my head. I'll continue to tune tomorrow with your instructions.

As I see, it seems that D play the main part in ALT HOLD. And yes, my board is AIO, so the baro sensor is ms6511.

copterrichie
Posts: 2261
Joined: Sat Feb 19, 2011 8:30 pm

Re: Altitude Hold improvement solution

Post by copterrichie »

Than the Fixed cycle time that hamburger introduced should be the magic patch.

rbirdie001
Posts: 178
Joined: Fri Apr 01, 2011 10:32 pm
Location: Czech Republic, Prague

Re: Altitude Hold improvement solution

Post by rbirdie001 »

Hi!
I did comparation inflight test between GPS and BARO altitude measurement and it again confirmed that GPS really can't be used (for anything including altitude hold).
My goal was to see on OSD during FPV how high I'm in reality because I still have problems to guess it from the video and GPS meauserement turned to be unusable for that.
Anyone interested can see test here: http://www.youtube.com/watch?v=Ux266uz0WQ0
@ Dramida: Can you please share, where you found description for what is the D term in 2.1 alt hold really used?
While I was playing with with AH PIDs in 2.1, I got more feeling that lovering D "limits" influence of BARO to throttle.
From my observation high D causes "dramatic" responses on the throttle and low D makes AH more smooth but maybe too weak to compensate when battery is getting low.
I ended up with AH D=3 and my Tri is quite stable.
Just observations to discuss, I can be wrong...
Anyway I'll surely try your method of PID tunning!
Roman

vpb
Posts: 231
Joined: Mon Jul 23, 2012 4:09 pm

Re: Altitude Hold improvement solution

Post by vpb »

Hi rbirdie! What OSD are you using? Very nice video but why you didn't try flying much higher, about 100-200m, I think the GPS alt is just for reference.

vpb
Posts: 231
Joined: Mon Jul 23, 2012 4:09 pm

Re: Altitude Hold improvement solution

Post by vpb »

dramida wrote:I just checked and the actual values Alt PID are 3, 0.15, 7, i played a lot and i forgot the changes since it works satisfactory even in forward flight. Please see video and hear the engines when alt hold and gps pos hold are activated

http://www.youtube.com/watch?v=B4D2CRxx7zk


Very very "beautiful" test-flight dramida! Were you the pilot? :D Look like it flied very high, and the pilot controlled visually not FPV, how could the pilot see the kit :D?
For the BARO hold, can you explain me some more?
- With Baro on, at which throttle level, the FC will try to maintain the height or the ALT PID will play the role? With higher throttle as we want to reach higher height or lower throttle as we want to landing, will it try to fight this?
- Do you have any experience on ALT_HOLD_THROTTLE_NEUTRAL_ZONE? It reads "neutral zone of throttle stick during altitude hold", the stock setting is +/- 20, and it will be added directly to throttle, like 1500+/- 20? I read some little info that it's the sensitive zone, for exp 1480-1520, what is sensitivity meaning here? the throttle stick will be very sensitive or in-sensitve in the throttle zone?

I always fly with BARO on, increasing height is easy but decreasing is a bit not smooth, maybe the ALT is not tuned, or I land too fast.
Thank you!

mahowik
Posts: 332
Joined: Sun Apr 10, 2011 6:26 pm

Re: Altitude Hold improvement solution

Post by mahowik »

Hi guys!

This weekend I became restless again that we are worse than others! :)

I have already tried and spent too much time 6-8 month ago without real success, but today I have collected all my knowledge again and made second attempt. :)
In two words! Now I can say "I got real results with baro+acc Alt Hold!" ;)

http://www.youtube.com/watch?v=nePjkz_leR8

It's:
- take into acount inclinations
- doesn't see horizontal accelerations
- keeps altitude on the wind (tried with 15-20km/h)
- has very good reaction for pushing
- has accuracy +/-20..40cm in calm weather according to baro accuracy
- has accuracy about +/-1m during the flights... flying 4 packs with initial PIDs without any tuning because I was too satisfied with results ;)


Code: Select all

#define ACC_LPF_FOR_VELOCITY 10
static float accLPFVel[3];

static t_fp_vector EstG;

void getEstimatedAttitude(){

.....................................
.....................................

    #if defined(ACC_LPF_FACTOR)
      accLPF[axis] = accLPF[axis] * (1.0f - (1.0f/ACC_LPF_FACTOR)) + accADC[axis] * (1.0f/ACC_LPF_FACTOR);
    
     accLPFVel[axis] = accLPFVel[axis] * (1.0f - (1.0f/ACC_LPF_FOR_VELOCITY)) + accADC[axis] * (1.0f/ACC_LPF_FOR_VELOCITY);


Code: Select all

#define UPDATE_INTERVAL 25000    // 40hz update rate (20hz LPF on acc)
#define INIT_DELAY      4000000  // 4 sec initialization delay
#define BARO_TAB_SIZE   40

#define ACC_Z_DEADBAND (acc_1G/50)

void getEstimatedAltitude(){
  uint8_t index;
  static uint32_t deadLine = INIT_DELAY;

  static int16_t BaroHistTab[BARO_TAB_SIZE];
  static int8_t BaroHistIdx;
  static int32_t BaroHigh;
 
 
  if (abs(currentTime - deadLine) < UPDATE_INTERVAL) return;
  uint16_t dTime = currentTime - deadLine;
  deadLine = currentTime;
 

  //**** Alt. Set Point stabilization PID ****
  BaroHistTab[BaroHistIdx] = BaroAlt/10;
  BaroHigh += BaroHistTab[BaroHistIdx];
  index = (BaroHistIdx + (BARO_TAB_SIZE/2))%BARO_TAB_SIZE;
  BaroHigh -= BaroHistTab[index];
 
  BaroHistIdx++;
  if (BaroHistIdx == BARO_TAB_SIZE) BaroHistIdx = 0;


  //EstAlt = BaroHigh*10/(BARO_TAB_SIZE/2);
  EstAlt = EstAlt*0.6f + (BaroHigh*10.0f/(BARO_TAB_SIZE/2))*0.4f; // additional LPF to reduce baro noise
 
  //P
  int16_t error = applyDeadband16(AltHold - EstAlt, 10); //remove small P parametr to reduce noise near zero position
  BaroPID = constrain((conf.P8[PIDALT] * error / 100), -100, +100);
 
  //I
  errorAltitudeI += error * conf.I8[PIDALT]/50;
  errorAltitudeI = constrain(errorAltitudeI,-30000,30000);
  BaroPID += (errorAltitudeI / 500); //I in range +/-60
 
 
  // projection of ACC vector to global Z, with 1G subtructed
  // Math: accZ = A * G / |G| - 1G
  float invG = InvSqrt(isq(EstG.V.X) + isq(EstG.V.Y) + isq(EstG.V.Z));
  //int16_t accZ = (accADC[ROLL] * EstG.V.X + accADC[PITCH] * EstG.V.Y + accADC[YAW] * EstG.V.Z) * invG - acc_1G;
  //int16_t accZ = (accADC[ROLL] * EstG.V.X + accADC[PITCH] * EstG.V.Y + accADC[YAW] * EstG.V.Z) * invG - 1/invG;
  int16_t accZ = (accLPFVel[ROLL] * EstG.V.X + accLPFVel[PITCH] * EstG.V.Y + accLPFVel[YAW] * EstG.V.Z) * invG - acc_1G;
  accZ = applyDeadband16(accZ, ACC_Z_DEADBAND);
  debug[0] = accZ;
 
  static float vel = 0.0f;
  static float accVelScale = 9.80665f / acc_1G / 10000.0f;
 
  // Integrator - velocity, cm/sec
  vel+= accZ * accVelScale * dTime;
 
  static int32_t lastBaroAlt = EstAlt;
  float baroVel = (EstAlt - lastBaroAlt) / (dTime/1000000.0f);
  baroVel = constrain(baroVel, -300, 300); // constrain baro velocity +/- 300cm/s
  baroVel = applyDeadbandFloat(baroVel, 10); // to reduce noise near zero 
  lastBaroAlt = EstAlt;
  debug[1] = baroVel;
 
  // apply Complimentary Filter to keep near zero caluculated velocity based on baro velocity
  vel = vel * 0.985f + baroVel * 0.015f;
  //vel = constrain(vel, -300, 300); // constrain velocity +/- 300cm/s
  debug[2] = vel;
  //debug[3] = applyDeadbandFloat(vel, 5);
 
  //D
  BaroPID -= constrain(conf.D8[PIDALT] * applyDeadbandFloat(vel, 5) / 20, -150, 150);
  debug[3] = BaroPID;
}

int16_t applyDeadband16(int16_t value, int16_t deadband) {
  if(abs(value) < deadband) {
    value = 0;
  } else if(value > 0){
    value -= deadband;
  } else if(value < 0){
    value += deadband;
  }
  return value;
}

float applyDeadbandFloat(float value, int16_t deadband) {
  if(abs(value) < deadband) {
    value = 0;
  } else if(value > 0){
    value -= deadband;
  } else if(value < 0){
    value += deadband;
  }
  return value;
}

float InvSqrt (float x){
  union{ 
    int32_t i; 
    float   f;
  } conv;
  conv.f = x;
  conv.i = 0x5f3759df - (conv.i >> 1);
  return 0.5f * conv.f * (3.0f - x * conv.f * conv.f);
}

int32_t isq(int32_t x){return x * x;}



How it works:
1. new array for acc values (accLPFvel) was created to prepare specialy filtered ACC data for alt hold, where fast acceleration still visible but not noise/vibrations. Because accADC is too noisy raw data even with MPU6050_LPF_42HZ filter, but accLPF has too big delay and shift of phase...
2. was used BaroHistTab and additional LPF to reduce baro noise (LPF too soft to doesn't lost the phase, i.e. to avoid increase of the delay )
3. then "P" calculated based on baro with applied deadband (=10) to reduce noise near zero position
4. then "I" calculated as before... nothing special here
5. accZ calculted as projection of ACC vector to global Z, with 1G subtructed (accZ = A * G / |G| - 1G) where (EstG vector taken from IMU). And again apply deababnd for 2% of acc_1G (acc_1G/50).
6. then vertical velocity calculated from accZ in integrator (cm/sec)
- and here we got MAIN issue: HOW TO KEEP VELOCITY NEAR ZERO BY USING INTEGRATOR?!
...answers in points below ;)
7. baro velocity calculated from filtered baro values, BUT it still very noisy... so applying of deadband (=10) little bit solve the problem
8. !!! then we apply Complimentary Filter (CF) to keep the calculated velocity based on baro velocity (i.e. near real velocity). By using CF it's possible to correct the drift of integrated accZ (velocity) without loosing the phase, i.e without delay
9. So then calculated velocity from CF (with applyed deadband = 5) used for D

Code is still required some performance optimizations (e.g. replace float calculations to integer where it's possible) but in general it's good I think...
In debug you can see:
- debug[0] - accZ
- debug[1] - baro velocity
- debug[2] - velocity after CF (velocity from acc corrected by baro velocity through the CF)
- debug[3] - sum of the P+I+D

I tried PIDs 5.0-0.030-30 from first attempt and was satisfied with 4 packs of flying... so I hadn't tried to tune that, but it make sense ;)

Note: I'm used mpu6050+ms5611 (AIO from rctimer) with PCB just screwed on the board, BUT i'm not sure about other accelerometers like ADXL345 (too sensitive to the noise) or bma020 with low 1G resolution (64 only) for 8G range... bma180 should be good I suppose.

thx-
Alex
Last edited by mahowik on Wed Dec 12, 2012 9:38 pm, edited 1 time in total.

timecop
Posts: 1880
Joined: Fri Sep 02, 2011 4:48 pm

Re: Altitude Hold improvement solution

Post by timecop »

I moved this code to baseflight and tried it out. Turning on baro just makes quad instantly shoot up in the air.
I see some attempts at keeping altitude, but its very erratic and 'strong', I guess due to P=5.0.
Changes are here:
http://code.google.com/p/afrodevices/so ... tail?r=214
I'm pretty sure I carried everything over same way - and I tried this with looptime=3000 which means it should be close to timing of arduino stuff.

Maybe another set of eyes can spot something I missed.

User avatar
shikra
Posts: 783
Joined: Wed Mar 30, 2011 7:58 pm

Re: Altitude Hold improvement solution

Post by shikra »

Alex - awesome effort. It looks pretty good on the vid. Look forward to testing this soon.

vpb
Posts: 231
Joined: Mon Jul 23, 2012 4:09 pm

Re: Altitude Hold improvement solution

Post by vpb »

@dramida: I've done the ALT tuning, and decided to stop at 3.0 15 10. It's similar to your PID, my tri now hold atitude very good, low 50cm, 3m or 20m. For the I term, it seems that at zero it's good, higher value like 20 30 I saw no noticeable difference except sometimes it loosed height slowly, I went out of all my battery packs so can not do further test on I term, maybe I'll do it again tomorrow.

One small problem, when it held alt, it started to dift (back & right)... so I'll do ACC tuning again.

mahowik
Posts: 332
Joined: Sun Apr 10, 2011 6:26 pm

Re: Altitude Hold improvement solution

Post by mahowik »

timecop wrote:I moved this code to baseflight and tried it out. Turning on baro just makes quad instantly shoot up in the air.
I see some attempts at keeping altitude, but its very erratic and 'strong', I guess due to P=5.0.
Changes are here:
http://code.google.com/p/afrodevices/so ... tail?r=214
I'm pretty sure I carried everything over same way - and I tried this with looptime=3000 which means it should be close to timing of arduino stuff.

Maybe another set of eyes can spot something I missed.


Hi timecop,

Actually I can give some guaranties in case of using ms5611 and mpu6050 (also bma180 probably as it has good precision and right internal tunable LPF).

What acc and baro you are using? In case of bmp085 it has precision at least 5 time less :((

I have bma020+bmp085 and I will try to tune algorithm for that sensors and let you know soon...

thx-
Alex

timecop
Posts: 1880
Joined: Fri Sep 02, 2011 4:48 pm

Re: Altitude Hold improvement solution

Post by timecop »

Thanks for reply.

I forget what was in my test quad. I think rev3 naze32 so MMA8452 acc + MPU3050 + BMP085.
Buut, with default alt pids and BMP085 things more or less worked (yes it bounced a bit but nothing like after these changes).
I believe nicog is going to be testing on hardware with mma8452+mpu6050+MS5611 soon.

copterrichie
Posts: 2261
Joined: Sat Feb 19, 2011 8:30 pm

Re: Altitude Hold improvement solution

Post by copterrichie »

Just curious here being what controls Altitude on a Rotor copter is the throttle, have anyone made any adjustments to the MWC's Throttle Curve? Personally, I get good altitude holding without the usage of a baro.

User avatar
Crashpilot1000
Posts: 631
Joined: Tue Apr 03, 2012 7:38 pm

Re: Altitude Hold improvement solution

Post by Crashpilot1000 »

@mahowik:
Thank you very much for making your code public. I will try to integrate it as well.

Thanks!

Rob

mahowik
Posts: 332
Joined: Sun Apr 10, 2011 6:26 pm

Re: Altitude Hold improvement solution

Post by mahowik »

copterrichie wrote:Just curious here being what controls Altitude on a Rotor copter is the throttle, have anyone made any adjustments to the MWC's Throttle Curve? Personally, I get good altitude holding without the usage of a baro.

Yes, expo throttle can help to keep altitude BUT not for long term and in calm...

copterrichie
Posts: 2261
Joined: Sat Feb 19, 2011 8:30 pm

Re: Altitude Hold improvement solution

Post by copterrichie »

mahowik wrote:Yes, expo throttle can help to keep altitude BUT not for long term and in calm...


Define long term?

mahowik
Posts: 332
Joined: Sun Apr 10, 2011 6:26 pm

Re: Altitude Hold improvement solution

Post by mahowik »

copterrichie wrote:Define long term?

not sure that i understood the question...

copterrichie
Posts: 2261
Joined: Sat Feb 19, 2011 8:30 pm

Re: Altitude Hold improvement solution

Post by copterrichie »

mahowik wrote:
copterrichie wrote:Define long term?

not sure that i understood the question...


Here is your statement:"Yes, expo throttle can help to keep altitude BUT not for long term and in calm..."

How do you defineLONG TERM? In other words, what does Long Term means to you?
Last edited by copterrichie on Mon Sep 10, 2012 4:23 pm, edited 1 time in total.

vpb
Posts: 231
Joined: Mon Jul 23, 2012 4:09 pm

Re: Altitude Hold improvement solution

Post by vpb »

@copterrichie: do you mean RC expo? I always fly with 40-45% expo, with BARO always ON, I feel smooth throttle, just that, no idea about ALT Hold :D. I think mahowik meant the ALT Hold for long time.

fiendie
Posts: 151
Joined: Fri Apr 20, 2012 4:22 pm

Re: Altitude Hold improvement solution

Post by fiendie »

copterrichie wrote:Here is your statement:"Yes, expo throttle can help to keep altitude BUT not for long term and in calm..."
How do you define LONG TERM? In other words, what does Long Term means to you?


You can't be serious...
Are you really insinuating that you can hold your copter at a certain altitude indefinitely with just Throttle Expo?
And please, try yawing around with your method and tell me what happens.

If you don't need baro-based altitude hold, that's fine.
But please don't derail the conversation.

copterrichie
Posts: 2261
Joined: Sat Feb 19, 2011 8:30 pm

Re: Altitude Hold improvement solution

Post by copterrichie »

vpb wrote:@copterrichie: do you mean RC expo? I always fly with 40-45% expo, with BARO always ON, I feel smooth throttle, just that, no idea about ALT Hold :D. I think mahowik meant the ALT Hold for long time.


Here is the deal in MY OPINION, because each copter build and AUW are unique, the point where they will hover on throttle will vary. Ideally, we want that hover zone at about 50-60% throttle (for me anyways), so we want to flatten the curve at that point. So I do not get the up and down motion as much, yes in high winds, there is added lift as the wind crosses the props but nothing major.
Last edited by copterrichie on Mon Sep 10, 2012 4:36 pm, edited 1 time in total.

copterrichie
Posts: 2261
Joined: Sat Feb 19, 2011 8:30 pm

Re: Altitude Hold improvement solution

Post by copterrichie »

fiendie wrote:
copterrichie wrote:Here is your statement:"Yes, expo throttle can help to keep altitude BUT not for long term and in calm..."
How do you define LONG TERM? In other words, what does Long Term means to you?


You can't be serious...
Are you really insinuating that you can hold your copter at a certain altitude indefinitely with just Throttle Expo?
And please, try yawing around with your method and tell me what happens.

If you don't need baro-based altitude hold, that's fine.
But please don't derail the conversation.


Believe what you wish, I am very happy with the performance of my copters and the Work that has gone into the MWC.

Thanks to everyone and the Throttle Expo does work!

mahowik
Posts: 332
Joined: Sun Apr 10, 2011 6:26 pm

Re: Altitude Hold improvement solution

Post by mahowik »

copterrichie wrote:Here is your statement:"Yes, expo throttle can help to keep altitude BUT not for long term and in calm..."

How do you defineLONG TERM? In other words, what does Long Term means to you?

I mean when you tune expo throttle in mwii from GUI (or on your TX) it's very simple to find the throttle stick position manually when copter starts to hover. But after some time (e.g. in calm weather) about 10-20sec on my current config it's start to move up or down... So i mean that even you have correct setup of expo throttle it will keep altitude only for some time (10..20sec), i.e. not in long term and we need alt hold function in any case...

vpb
Posts: 231
Joined: Mon Jul 23, 2012 4:09 pm

Re: Altitude Hold improvement solution

Post by vpb »

copterrichie wrote:Here is the deal in MY OPINION, because each copter build and AUW are unique, the point where they will hover on throttle will vary. Ideally, we want that hover zone want that hover zone at about 50-60% throttle (for me anyways), so we want to flatten the curve at that point. So I do not that that up and down motion, yes in high winds, there is added lift as the wind crosses the props but nothing major.

I think different, at hover zone, (as you say it's 50-60% throttle), you dont want to go up or down much, you want to stay, so the curve should step in for the in-sensitive throttle signal. It should be curve, not flat :D. But, it depends on kit and pilot's behavior.

fiendie
Posts: 151
Joined: Fri Apr 20, 2012 4:22 pm

Re: Altitude Hold improvement solution

Post by fiendie »

copterrichie wrote:Believe what you wish, I am very happy with the performance of my copters and the Work that has gone into the MWC.

I totally believe you. But remind me: What's that got to do with the improvements to baro-based alt hold which mahowik propesd?

Thanks to everyone and the Throttle Expo does work!

Seriously, how can you use that as an opportunity for brownnosing?

Either you are trolling or you're completely missing the point.

copterrichie
Posts: 2261
Joined: Sat Feb 19, 2011 8:30 pm

Re: Altitude Hold improvement solution

Post by copterrichie »

"I think different, at hover zone, (as you say it's 50-60% throttle), you dont want to go up or down much, you want to stay, so the curve should step in for the in-sensitive throttle signal. It should be curve, not flat :D. But, it depends on kit and pilot's behavior."

Semantics.

copterrichie
Posts: 2261
Joined: Sat Feb 19, 2011 8:30 pm

Re: Altitude Hold improvement solution

Post by copterrichie »

fiendie wrote:
copterrichie wrote:Believe what you wish, I am very happy with the performance of my copters and the Work that has gone into the MWC.

I totally believe you. But remind me: What's that got to do with the improvements to baro-based alt hold which mahowik propesd?

Thanks to everyone and the Throttle Expo does work!

Seriously, how can you use that as an opportunity for brownnosing?

Either you are trolling or you're completely missing the point.


IMO and (I don't use a Baro), if you start with a good throttle curve/control, it should make the Baro routine and tuning much easier.

vpb
Posts: 231
Joined: Mon Jul 23, 2012 4:09 pm

Re: Altitude Hold improvement solution

Post by vpb »

copterrichie wrote:Semantics.

Sorry I dont know what you mean (English is not my primary language).

Btw, I dont think many people fly multicopter to just hold at a level for a long time, just stand a couple of seconds then fly away, a stable copter w/ or w/o baro can help. With my tricopter, I see the big different in throttle smoothness with expo.

copterrichie
Posts: 2261
Joined: Sat Feb 19, 2011 8:30 pm

Re: Altitude Hold improvement solution

Post by copterrichie »

vpb wrote:
copterrichie wrote:Semantics.

Sorry I dont know what you mean (English is not my primary language).

Btw, I dont think many people fly multicopter to just hold at a level for a long time, just stand a couple of seconds then fly away, a stable copter w/ or w/o baro can help. With my tricopter, I see the big different in throttle smoothness with expo.


My copters and flying skills are tailored around aerial video, so I have trained myself and built my copters around that theme. Yes, I do remain stationary in one altitude and locations for minutes at a time.

mahowik
Posts: 332
Joined: Sun Apr 10, 2011 6:26 pm

Re: Altitude Hold improvement solution

Post by mahowik »

Guys! Pls. stop this SPAM!!! This topic about alt-hold improvement solutions!!!

copterrichie
Posts: 2261
Joined: Sat Feb 19, 2011 8:30 pm

Re: Altitude Hold improvement solution

Post by copterrichie »

mahowik wrote:Guys! Pls. stop this SPAM!!! This topic about alt-hold improvement solutions!!!


LOL, I just give you the most important factor to improve Alt-holding. LOL LOL LOL

nicog
Posts: 88
Joined: Tue Aug 21, 2012 2:21 pm

Re: Altitude Hold improvement solution

Post by nicog »

mahowik I will try to do a test of your code tomorrow.

With old algo I can get a very good althold while hover. But It would be a plus if I can do dynamic movements at same altitude.

vpb
Posts: 231
Joined: Mon Jul 23, 2012 4:09 pm

Re: Altitude Hold improvement solution

Post by vpb »

Glad to hear that, I'll search some of your videos. I'm new to multiwii & multicopter, I want to fly FPV slow, can stop to watch, that's why I build multicopter... but I'm far from the topic's point :D.

mahowik
Posts: 332
Joined: Sun Apr 10, 2011 6:26 pm

Re: Altitude Hold improvement solution

Post by mahowik »

nicog wrote:mahowik I will try to do a test of your code tomorrow.

With old algo I can get a very good althold while hover. But It would be a plus if I can do dynamic movements at same altitude.


one more advantage with using acc+baro algorithm: when you go up/down with velocity of 1-2m/s and activate alt hold, it must stop immediately and start to hover ;)

p.s. I have already got one feedback from russian forum. It keeps +/-30cm outside during the wind ;)
http://forum.rcdesign.ru/f123/thread283 ... ost3613804

nhadrian
Posts: 421
Joined: Tue Oct 25, 2011 9:25 am

Re: Altitude Hold improvement solution

Post by nhadrian »

timecop wrote:I moved this code to baseflight and tried it out. Turning on baro just makes quad instantly shoot up in the air.
I see some attempts at keeping altitude, but its very erratic and 'strong', I guess due to P=5.0.
Changes are here:
http://code.google.com/p/afrodevices/so ... tail?r=214
I'm pretty sure I carried everything over same way - and I tried this with looptime=3000 which means it should be close to timing of arduino stuff.

Maybe another set of eyes can spot something I missed.



Hi,

unfortunatelly the same here. Doesn't matter what PID I set up... :(

BR
Adrian

mahowik
Posts: 332
Joined: Sun Apr 10, 2011 6:26 pm

Re: Altitude Hold improvement solution

Post by mahowik »

probably bmp085 no so precise and has big noise for this solution/approach... i will check in a few day...

timecop
Posts: 1880
Joined: Fri Sep 02, 2011 4:48 pm

Re: Altitude Hold improvement solution

Post by timecop »

bmp isn't that bad. I'm talking this thing going up 20+ meters.
I have reasonable althold on it at default settings.
might try with other hw tomorrow.

User avatar
dramida
Posts: 473
Joined: Mon Feb 28, 2011 12:58 pm
Location: Bucharest
Contact:

Re: Altitude Hold improvement solution

Post by dramida »

Today I flew with alt hold and I can say it is satisfying stable. It could be better but right now, I got the sweet spot. 20 cm of error. Video soon.

mahowik
Posts: 332
Joined: Sun Apr 10, 2011 6:26 pm

Re: Altitude Hold improvement solution

Post by mahowik »

dramida wrote:Today I flew with alt hold and I can say it is satisfying stable. It could be better but right now, I got the sweet spot. 20 cm of error. Video soon.

Do you want to test baro+acc solution? ;)
viewtopic.php?f=8&t=2371&p=22485#p22485

As I remember default 2.1 alt hold could not keep altitude in wind... only calm and only static because during the flights baro hasn't necessary reaction to produce compensations...

nhadrian
Posts: 421
Joined: Tue Oct 25, 2011 9:25 am

Re: Altitude Hold improvement solution

Post by nhadrian »

Update:

I tried again with Ales's code, now I succeed, with the 5;0,030;30 PIDs it works great, even in windy conditions with GPS hold!!!

mahowik
Posts: 332
Joined: Sun Apr 10, 2011 6:26 pm

Re: Altitude Hold improvement solution

Post by mahowik »

nhadrian wrote:Update:

I tried again with Ales's code, now I succeed, with the 5;0,030;30 PIDs it works great, even in windy conditions with GPS hold!!!


Many thanks for the tests! Which acc and baro you are using?

my current PIDs 5.2 - 0.020 - 30

@timecop: I also tried to test bma020+bmp085 yesterday (in GUI only). Seems it works but required some tuning of coefficients/factors accordingly... pls try this one

Code: Select all

..................
#define ACC_LPF_FOR_VELOCITY 15
..................

#define UPDATE_INTERVAL 25000    // 40hz update rate (20hz LPF on acc)
#define INIT_DELAY      4000000  // 4 sec initialization delay
#define BARO_TAB_SIZE   26

#define ACC_Z_DEADBAND (acc_1G/40)

void getEstimatedAltitude(){
  static uint32_t deadLine = INIT_DELAY;

  static int16_t baroHistTab[BARO_TAB_SIZE];
  static int8_t baroHistIdx;
  static int32_t baroHigh;
 
 
  if (abs(currentTime - deadLine) < UPDATE_INTERVAL) return;
  uint16_t dTime = currentTime - deadLine;
  deadLine = currentTime;
 

  //**** Alt. Set Point stabilization PID ****
  baroHistTab[baroHistIdx] = BaroAlt/10;
  baroHigh += baroHistTab[baroHistIdx];
  baroHigh -= baroHistTab[(baroHistIdx + 1)%BARO_TAB_SIZE];
 
  baroHistIdx++;
  if (baroHistIdx == BARO_TAB_SIZE) baroHistIdx = 0;


  //EstAlt = baroHigh*10/(BARO_TAB_SIZE-1);
  EstAlt = EstAlt*0.65f + (baroHigh*10.0f/(BARO_TAB_SIZE-1))*0.35f; // additional LPF to reduce baro noise
 
  //P
  int16_t error = constrain(AltHold - EstAlt, -300, 300);
  error = applyDeadband16(error, 10); //remove small P parametr to reduce noise near zero position
  BaroPID = constrain((conf.P8[PIDALT] * error / 100), -150, +150);
 
  //I
  errorAltitudeI += error * conf.I8[PIDALT]/50;
  errorAltitudeI = constrain(errorAltitudeI,-30000,30000);
  BaroPID += (errorAltitudeI / 500); //I in range +/-60
 
 
  // projection of ACC vector to global Z, with 1G subtructed
  // Math: accZ = A * G / |G| - 1G
  float invG = InvSqrt(isq(EstG.V.X) + isq(EstG.V.Y) + isq(EstG.V.Z));
  int16_t accZ = (accLPFVel[ROLL] * EstG.V.X + accLPFVel[PITCH] * EstG.V.Y + accLPFVel[YAW] * EstG.V.Z) * invG - acc_1G;
  //int16_t accZ = (accLPFVel[ROLL] * EstG.V.X + accLPFVel[PITCH] * EstG.V.Y + accLPFVel[YAW] * EstG.V.Z) * invG - 1/invG;
  accZ = applyDeadband16(accZ, ACC_Z_DEADBAND);
  debug[0] = accZ;
 
  static float vel = 0.0f;
  static float accVelScale = 9.80665f / acc_1G / 10000.0f;
 
  // Integrator - velocity, cm/sec
  vel+= accZ * accVelScale * dTime;
 
  static int32_t lastBaroAlt = EstAlt;
  float baroVel = (EstAlt - lastBaroAlt) / (dTime/1000000.0f);
  baroVel = constrain(baroVel, -300, 300); // constrain baro velocity +/- 300cm/s
  baroVel = applyDeadbandFloat(baroVel, 10); // to reduce noise near zero 
  lastBaroAlt = EstAlt;
  debug[1] = baroVel;
 
  // apply Complimentary Filter to keep the calculated velocity based on baro velocity (i.e. near real velocity).
  // By using CF it's possible to correct the drift of integrated accZ (velocity) without loosing the phase, i.e without delay
  vel = vel * 0.987f + baroVel * 0.013f;
  //vel = constrain(vel, -300, 300); // constrain velocity +/- 300cm/s
  debug[2] = vel;
 
  //D
  BaroPID -= constrain(conf.D8[PIDALT] * applyDeadbandFloat(vel, 5) / 20, -150, 150);
  debug[3] = BaroPID;
}

int16_t applyDeadband16(int16_t value, int16_t deadband) {
  if(abs(value) < deadband) {
    value = 0;
  } else if(value > 0){
    value -= deadband;
  } else if(value < 0){
    value += deadband;
  }
  return value;
}

float applyDeadbandFloat(float value, int16_t deadband) {
  if(abs(value) < deadband) {
    value = 0;
  } else if(value > 0){
    value -= deadband;
  } else if(value < 0){
    value += deadband;
  }
  return value;
}

float InvSqrt (float x){
  union{ 
    int32_t i; 
    float   f;
  } conv;
  conv.f = x;
  conv.i = 0x5f3759df - (conv.i >> 1);
  return 0.5f * conv.f * (3.0f - x * conv.f * conv.f);
}

int32_t isq(int32_t x){return x * x;}


mahowik
Posts: 332
Joined: Sun Apr 10, 2011 6:26 pm

Re: Altitude Hold improvement solution

Post by mahowik »

Also here is little bit refactored version for ms5611

Code: Select all

#define UPDATE_INTERVAL 25000    // 40hz update rate (20hz LPF on acc)
#define INIT_DELAY      4000000  // 4 sec initialization delay
#define BARO_TAB_SIZE   21

#define ACC_Z_DEADBAND (acc_1G/50)

void getEstimatedAltitude(){
  static uint32_t deadLine = INIT_DELAY;

  static int16_t baroHistTab[BARO_TAB_SIZE];
  static int8_t baroHistIdx;
  static int32_t baroHigh;
 
 
  if (abs(currentTime - deadLine) < UPDATE_INTERVAL) return;
  uint16_t dTime = currentTime - deadLine;
  deadLine = currentTime;
 

  //**** Alt. Set Point stabilization PID ****
  baroHistTab[baroHistIdx] = BaroAlt/10;
  baroHigh += baroHistTab[baroHistIdx];
  baroHigh -= baroHistTab[(baroHistIdx + 1)%BARO_TAB_SIZE];
 
  baroHistIdx++;
  if (baroHistIdx == BARO_TAB_SIZE) baroHistIdx = 0;


  //EstAlt = baroHigh*10/(BARO_TAB_SIZE-1);
  EstAlt = EstAlt*0.6f + (baroHigh*10.0f/(BARO_TAB_SIZE - 1))*0.4f; // additional LPF to reduce baro noise
 
  //P
  int16_t error = constrain(AltHold - EstAlt, -300, 300);
  error = applyDeadband16(error, 10); //remove small P parametr to reduce noise near zero position
  BaroPID = constrain((conf.P8[PIDALT] * error / 100), -150, +150);
 
  //I
  errorAltitudeI += error * conf.I8[PIDALT]/50;
  errorAltitudeI = constrain(errorAltitudeI,-30000,30000);
  BaroPID += (errorAltitudeI / 500); //I in range +/-60
 
 
  // projection of ACC vector to global Z, with 1G subtructed
  // Math: accZ = A * G / |G| - 1G
  float invG = InvSqrt(isq(EstG.V.X) + isq(EstG.V.Y) + isq(EstG.V.Z));
  int16_t accZ = (accLPFVel[ROLL] * EstG.V.X + accLPFVel[PITCH] * EstG.V.Y + accLPFVel[YAW] * EstG.V.Z) * invG - acc_1G;
  //int16_t accZ = (accLPFVel[ROLL] * EstG.V.X + accLPFVel[PITCH] * EstG.V.Y + accLPFVel[YAW] * EstG.V.Z) * invG - 1/invG;
  accZ = applyDeadband16(accZ, ACC_Z_DEADBAND);
  debug[0] = accZ;
 
  static float vel = 0.0f;
  static float accVelScale = 9.80665f / acc_1G / 10000.0f;
 
  // Integrator - velocity, cm/sec
  vel+= accZ * accVelScale * dTime;
 
  static int32_t lastBaroAlt = EstAlt;
  float baroVel = (EstAlt - lastBaroAlt) / (dTime/1000000.0f);
  baroVel = constrain(baroVel, -300, 300); // constrain baro velocity +/- 300cm/s
  baroVel = applyDeadbandFloat(baroVel, 10); // to reduce noise near zero 
  lastBaroAlt = EstAlt;
  debug[1] = baroVel;
 
  // apply Complimentary Filter to keep the calculated velocity based on baro velocity (i.e. near real velocity).
  // By using CF it's possible to correct the drift of integrated accZ (velocity) without loosing the phase, i.e without delay
  vel = vel * 0.985f + baroVel * 0.015f;
  //vel = constrain(vel, -300, 300); // constrain velocity +/- 300cm/s
  debug[2] = vel;
 
  //D
  BaroPID -= constrain(conf.D8[PIDALT] * applyDeadbandFloat(vel, 5) / 20, -150, 150);
  debug[3] = BaroPID;
}

int16_t applyDeadband16(int16_t value, int16_t deadband) {
  if(abs(value) < deadband) {
    value = 0;
  } else if(value > 0){
    value -= deadband;
  } else if(value < 0){
    value += deadband;
  }
  return value;
}

float applyDeadbandFloat(float value, int16_t deadband) {
  if(abs(value) < deadband) {
    value = 0;
  } else if(value > 0){
    value -= deadband;
  } else if(value < 0){
    value += deadband;
  }
  return value;
}

float InvSqrt (float x){
  union{ 
    int32_t i; 
    float   f;
  } conv;
  conv.f = x;
  conv.i = 0x5f3759df - (conv.i >> 1);
  return 0.5f * conv.f * (3.0f - x * conv.f * conv.f);
}

int32_t isq(int32_t x){return x * x;}


wilco1967
Posts: 156
Joined: Thu Aug 18, 2011 6:04 pm
Location: Winterswijk, Netherlands

Re: Altitude Hold improvement solution

Post by wilco1967 »

Hi Mahowik,

I tried your version 2.1 code (download) and it worked pretty good (Tricopter with Flyduino mega, MPU6050 and BMP-085).

Then I tried to incorporatie the modified code into the current shared version, and there I must have missed something....
(There are so many other improvements in the shared since the official 2.1, that I do not want to go back)

As Timecop also mentioned a few pages back after he implemented your code, when activating alt-hold, mine also shoots into the air.... In the downloaded version, it did not do this..... It does seem to respond though after climbing a couple of meters.
It seems to me like an initalisation step or so is missing upon activation of alt-holt.... could be something completely different though :roll: .

Is there somewhere in the code some other modification, that you did not show in your posts ? (but was obviously included in your 2.1 downloadable file).

There are soo many differences between the original 2.1 code, and the current shared, that I loose track.

Thanks a lot....
I really think you're on the right path with alt-hold

nhadrian
Posts: 421
Joined: Tue Oct 25, 2011 9:25 am

Re: Altitude Hold improvement solution

Post by nhadrian »

mahowik wrote:
nhadrian wrote:Update:

I tried again with Ales's code, now I succeed, with the 5;0,030;30 PIDs it works great, even in windy conditions with GPS hold!!!


Many thanks for the tests! Which acc and baro you are using?

my current PIDs 5.2 - 0.020 - 30

@timecop: I also tried to test bma020+bmp085 yesterday (in GUI only). Seems it works but required some tuning of coefficients/factors accordingly... pls try this one

Code: Select all

..................
#define ACC_LPF_FOR_VELOCITY 15
..................

#define UPDATE_INTERVAL 25000    // 40hz update rate (20hz LPF on acc)
#define INIT_DELAY      4000000  // 4 sec initialization delay
#define BARO_TAB_SIZE   26

#define ACC_Z_DEADBAND (acc_1G/40)

void getEstimatedAltitude(){
  static uint32_t deadLine = INIT_DELAY;

  static int16_t baroHistTab[BARO_TAB_SIZE];
  static int8_t baroHistIdx;
  static int32_t baroHigh;
 
 
  if (abs(currentTime - deadLine) < UPDATE_INTERVAL) return;
  uint16_t dTime = currentTime - deadLine;
  deadLine = currentTime;
 

  //**** Alt. Set Point stabilization PID ****
  baroHistTab[baroHistIdx] = BaroAlt/10;
  baroHigh += baroHistTab[baroHistIdx];
  baroHigh -= baroHistTab[(baroHistIdx + 1)%BARO_TAB_SIZE];
 
  baroHistIdx++;
  if (baroHistIdx == BARO_TAB_SIZE) baroHistIdx = 0;


  //EstAlt = baroHigh*10/(BARO_TAB_SIZE-1);
  EstAlt = EstAlt*0.65f + (baroHigh*10.0f/(BARO_TAB_SIZE-1))*0.35f; // additional LPF to reduce baro noise
 
  //P
  int16_t error = constrain(AltHold - EstAlt, -300, 300);
  error = applyDeadband16(error, 10); //remove small P parametr to reduce noise near zero position
  BaroPID = constrain((conf.P8[PIDALT] * error / 100), -150, +150);
 
  //I
  errorAltitudeI += error * conf.I8[PIDALT]/50;
  errorAltitudeI = constrain(errorAltitudeI,-30000,30000);
  BaroPID += (errorAltitudeI / 500); //I in range +/-60
 
 
  // projection of ACC vector to global Z, with 1G subtructed
  // Math: accZ = A * G / |G| - 1G
  float invG = InvSqrt(isq(EstG.V.X) + isq(EstG.V.Y) + isq(EstG.V.Z));
  int16_t accZ = (accLPFVel[ROLL] * EstG.V.X + accLPFVel[PITCH] * EstG.V.Y + accLPFVel[YAW] * EstG.V.Z) * invG - acc_1G;
  //int16_t accZ = (accLPFVel[ROLL] * EstG.V.X + accLPFVel[PITCH] * EstG.V.Y + accLPFVel[YAW] * EstG.V.Z) * invG - 1/invG;
  accZ = applyDeadband16(accZ, ACC_Z_DEADBAND);
  debug[0] = accZ;
 
  static float vel = 0.0f;
  static float accVelScale = 9.80665f / acc_1G / 10000.0f;
 
  // Integrator - velocity, cm/sec
  vel+= accZ * accVelScale * dTime;
 
  static int32_t lastBaroAlt = EstAlt;
  float baroVel = (EstAlt - lastBaroAlt) / (dTime/1000000.0f);
  baroVel = constrain(baroVel, -300, 300); // constrain baro velocity +/- 300cm/s
  baroVel = applyDeadbandFloat(baroVel, 10); // to reduce noise near zero 
  lastBaroAlt = EstAlt;
  debug[1] = baroVel;
 
  // apply Complimentary Filter to keep the calculated velocity based on baro velocity (i.e. near real velocity).
  // By using CF it's possible to correct the drift of integrated accZ (velocity) without loosing the phase, i.e without delay
  vel = vel * 0.987f + baroVel * 0.013f;
  //vel = constrain(vel, -300, 300); // constrain velocity +/- 300cm/s
  debug[2] = vel;
 
  //D
  BaroPID -= constrain(conf.D8[PIDALT] * applyDeadbandFloat(vel, 5) / 20, -150, 150);
  debug[3] = BaroPID;
}

int16_t applyDeadband16(int16_t value, int16_t deadband) {
  if(abs(value) < deadband) {
    value = 0;
  } else if(value > 0){
    value -= deadband;
  } else if(value < 0){
    value += deadband;
  }
  return value;
}

float applyDeadbandFloat(float value, int16_t deadband) {
  if(abs(value) < deadband) {
    value = 0;
  } else if(value > 0){
    value -= deadband;
  } else if(value < 0){
    value += deadband;
  }
  return value;
}

float InvSqrt (float x){
  union{ 
    int32_t i; 
    float   f;
  } conv;
  conv.f = x;
  conv.i = 0x5f3759df - (conv.i >> 1);
  return 0.5f * conv.f * (3.0f - x * conv.f * conv.f);
}

int32_t isq(int32_t x){return x * x;}



Hi, I'm running on Crius AIO PRO board which means MS5611 and MPU6050 acc.

Here is a test video of my mini Y-6 copter in quite windy conditions:
http://youtu.be/POSwO33wFUU

PIDs are: P5.0 I0.030 D30

Works quite well, as you can see in the video!!! (please note that the copter is really small, 500g AUW so the movements in the video is not as much as it seems...)

BR Adrian

fiendie
Posts: 151
Joined: Fri Apr 20, 2012 4:22 pm

Re: Altitude Hold improvement solution

Post by fiendie »

mahowik wrote:Also here is little bit refactored version for ms5611

Code: Select all

#define UPDATE_INTERVAL 25000    // 40hz update rate (20hz LPF on acc)
#define INIT_DELAY      4000000  // 4 sec initialization delay
#define BARO_TAB_SIZE   21

#define ACC_Z_DEADBAND (acc_1G/50)

void getEstimatedAltitude(){
  static uint32_t deadLine = INIT_DELAY;

  static int16_t baroHistTab[BARO_TAB_SIZE];
  static int8_t baroHistIdx;
  static int32_t baroHigh;
 
 
  if (abs(currentTime - deadLine) < UPDATE_INTERVAL) return;
  uint16_t dTime = currentTime - deadLine;
  deadLine = currentTime;
 

  //**** Alt. Set Point stabilization PID ****
  baroHistTab[baroHistIdx] = BaroAlt/10;
  baroHigh += baroHistTab[baroHistIdx];
  baroHigh -= baroHistTab[(baroHistIdx + 1)%BARO_TAB_SIZE];
 
  baroHistIdx++;
  if (baroHistIdx == BARO_TAB_SIZE) baroHistIdx = 0;


  //EstAlt = baroHigh*10/(BARO_TAB_SIZE-1);
  EstAlt = EstAlt*0.6f + (baroHigh*10.0f/(BARO_TAB_SIZE - 1))*0.4f; // additional LPF to reduce baro noise
 
  //P
  int16_t error = constrain(AltHold - EstAlt, -300, 300);
  error = applyDeadband16(error, 10); //remove small P parametr to reduce noise near zero position
  BaroPID = constrain((conf.P8[PIDALT] * error / 100), -150, +150);
 
  //I
  errorAltitudeI += error * conf.I8[PIDALT]/50;
  errorAltitudeI = constrain(errorAltitudeI,-30000,30000);
  BaroPID += (errorAltitudeI / 500); //I in range +/-60
 
 
  // projection of ACC vector to global Z, with 1G subtructed
  // Math: accZ = A * G / |G| - 1G
  float invG = InvSqrt(isq(EstG.V.X) + isq(EstG.V.Y) + isq(EstG.V.Z));
  int16_t accZ = (accLPFVel[ROLL] * EstG.V.X + accLPFVel[PITCH] * EstG.V.Y + accLPFVel[YAW] * EstG.V.Z) * invG - acc_1G;
  //int16_t accZ = (accLPFVel[ROLL] * EstG.V.X + accLPFVel[PITCH] * EstG.V.Y + accLPFVel[YAW] * EstG.V.Z) * invG - 1/invG;
  accZ = applyDeadband16(accZ, ACC_Z_DEADBAND);
  debug[0] = accZ;
 
  static float vel = 0.0f;
  static float accVelScale = 9.80665f / acc_1G / 10000.0f;
 
  // Integrator - velocity, cm/sec
  vel+= accZ * accVelScale * dTime;
 
  static int32_t lastBaroAlt = EstAlt;
  float baroVel = (EstAlt - lastBaroAlt) / (dTime/1000000.0f);
  baroVel = constrain(baroVel, -300, 300); // constrain baro velocity +/- 300cm/s
  baroVel = applyDeadbandFloat(baroVel, 10); // to reduce noise near zero 
  lastBaroAlt = EstAlt;
  debug[1] = baroVel;
 
  // apply Complimentary Filter to keep the calculated velocity based on baro velocity (i.e. near real velocity).
  // By using CF it's possible to correct the drift of integrated accZ (velocity) without loosing the phase, i.e without delay
  vel = vel * 0.985f + baroVel * 0.015f;
  //vel = constrain(vel, -300, 300); // constrain velocity +/- 300cm/s
  debug[2] = vel;
 
  //D
  BaroPID -= constrain(conf.D8[PIDALT] * applyDeadbandFloat(vel, 5) / 20, -150, 150);
  debug[3] = BaroPID;
}

int16_t applyDeadband16(int16_t value, int16_t deadband) {
  if(abs(value) < deadband) {
    value = 0;
  } else if(value > 0){
    value -= deadband;
  } else if(value < 0){
    value += deadband;
  }
  return value;
}

float applyDeadbandFloat(float value, int16_t deadband) {
  if(abs(value) < deadband) {
    value = 0;
  } else if(value > 0){
    value -= deadband;
  } else if(value < 0){
    value += deadband;
  }
  return value;
}

float InvSqrt (float x){
  union{ 
    int32_t i; 
    float   f;
  } conv;
  conv.f = x;
  conv.i = 0x5f3759df - (conv.i >> 1);
  return 0.5f * conv.f * (3.0f - x * conv.f * conv.f);
}

int32_t isq(int32_t x){return x * x;}



@mahowik: Would it be possible to provide the code as a patch against the current _shared repo? I would love to put a feature branch up on my GitHub and test it.
Thanks for the effort you put in so far!

Cheers
Andy

timecop
Posts: 1880
Joined: Fri Sep 02, 2011 4:48 pm

Re: Altitude Hold improvement solution

Post by timecop »

What would be really nice is all the constants broken out with explanations of what they do.
The last 2-3 code copies you pasted all look identical - probably just changing some fixed value somewhere, but its really hard to read them as they're not patches,, so, which numbers are you changing?

mahowik
Posts: 332
Joined: Sun Apr 10, 2011 6:26 pm

Re: Altitude Hold improvement solution

Post by mahowik »

Hi guys!

All necessary changes for new baro+acc alt hold only in one file IMU.ino

You can just compare this with official IMU.ino from 2.1 version with any merge tool and apply necessary diff where you want: dev or your own...

1) for ms5611 - pls. use IMU_ms5611.ino
2) for bmp085 - at first also try to use IMU_ms5611.ino... and if it's not stable try IMU_bmp085.ino

Some notes:
- for mpu6050 pls turn on 42hz LPF (#define MPU6050_LPF_42HZ)... for other ACCs it's already done in Sensors.ino
- wait 10-15 sec after power on OR after ACC calibration... all LPFs, velocity integrator and CF need to be syncronized (i'm going to reduce init time... i.e. it's in my todo list ;))
- after init you can check debug0 (z axis acceleration) and debug2 (calculated velocity) in GUI (with max zoom = 10)... it should swim near zero point: +/-2..5 for acceleration (debug0) and +/-5..15 for velocity (debug2)
- then turn on motors (with 40..50% power about throttle hover), keep it in hands, don't switch to alt hold and check the same (debug0, debug2) in GUI... without vertical movements z axis acceleration and calculated velocity should be in calm...
- then try to move up/down... you should see acceleration and velocity on each debug graphics
- try to turn on alt hold and move up/down... you should get immediate resistance when trying to push down and visible throttle reduce when going up...

Guys from our forum prepared the video ;) http://www.youtube.com/watch?v=qUlphS7D ... r_embedded

thx-
Alex
Last edited by mahowik on Sat Dec 15, 2012 11:18 pm, edited 1 time in total.

timecop
Posts: 1880
Joined: Fri Sep 02, 2011 4:48 pm

Re: Altitude Hold improvement solution

Post by timecop »

Hmm. More changes. I diff'd the posted with original 2.1 and made same changes to baseflight code.
it doesn't shoot up in the air anymore, but it also doesn't really hold, either. I've had better althold w/bmp085 and regular non-accZ code w/default PIDs. Used 5.0/0.03/30 for the test video:
http://www.youtube.com/watch?v=rQuw0RCMhbo
The video was done with acc_hardware=1 (MMA845x), but I then flew again with acc_hardware=2 (MPU6050 accel) and it was pretty much same.
Changes here:
http://code.google.com/p/afrodevices/so ... tail?r=217

Post Reply