Posted by Doug Weibel on October 8, 2009 at 5:00pm
Hello All,I am going through the ArduIMU v1.1 software and getting ready to start modifying it for my own purposes. I am pretty excited about this IMU and think there are some really cool, creative things that can be done with it.I keep generating questions that people are helping me find the answers. I've decided to update this top post as questions get answered so that it will be a bit of a FAQ,I know there are others than me digging in to the code, so post your questions and answers as comments and I'll keep the FAQ at the top updated :)DougCURRENT QUESTIONS:Q The V1.1 download code has#define Kp_YAW 0 //.5Yaw Porportional Gain#define Ki_YAW 0 //0.0005Yaw Integrator Gainso the values in use as downloaded are zero and there is no yaw drift correction. Has anyone tried out the values in the comments? What testing did you do and what were the results?Q I have been looking at the accelerometer data to see if I could use it to integrate velocity, but it looks much too coarse, and despite claims that accelerometers don't drift mine have some poor behavior that I would either call drift or hysteresis. For example, using groundtest.vi and looking at the accelerometer data - With the IMU sitting on my desk the raw accelerometer data should be (and initially is) 0, 101, 0. However, after moving the IMU around and then bringing it back to rest I might see data of 1, 101, 2, or 0, 101, -3, and those readings might persist for quite some time (>20 seconds). If you work the math on 0, 101, 3 it works out to indicating a velocity of 13 miles per hour in the z direction after 20 seconds. So, the question is: Is this hardware any good for inertial navigation applications???ANSWERED QUESTIONS:Q Where is the yaw drift correction??? Am I correct in thinking that it is not included in this release of the software?A - No - the yaw drift correction is handled in the roll_pitch_drift() routine. However, note that the P and I coefficients are set to zero in the v1.1 download. You will need to change them. I haven't tested values out yet.Q Why is Gyro_Scaled(x) defined as x*((Gyro_Gain*PI)/360) instead of x*((Gyro_Gain*2*PI)/360) or x*((Gyro_Gain*PI)/180)?A Well, because the factor of 2 is incorporated in the Gyro_Gain (we think)Q Why the procedure in setup() of reading the adc's 75 times? From the filtering it looks like 3 or 4 times should be sufficient as the value after any read is 90% the most recent measurement and only 10% previous averaged measurements.A I looked at the raw data and for some reason the data is pretty goofy the first 5+ times through the loop, almost like you need to warm up the AD converters. Can't explain it, but that is probably why 75 samples are taken even though 5 would be sufficient with the filtering used.Q Why is AN_OFFSET[4]=AN[4]+GRAVITY instead of AN_OFFSET[4]=AN[4]-GRAVITY?A Because gravity works to lessen the value of the raw data in the y axis, so GRAVITY is added back to get the "zero gravity" offset. It is just a matter of the direction and sign.
@Lorentz - Thank you for the simulation work. I may try some real world sim in my car today, but it is snowing (Colorado) so I will have to see if I can get GPS lock in my car with the windows up. If that goes well and the weather improves somewhat I may go for a flight in my Citabria tomorrow. I'll use Kp = 0.5 and Ki = 0.005. I will be interested to see what the performance is like in a real aircraft. I suppose my testing will be to some extent much more qualitative, although I could drop some data out and look at the yaw error in the feedback loop. That won't happen by tomorrow, though. Right now I'm mostly curious if I can go fly for a half hour with lots of maneuvering and have consistently correct yaw readings within say 2 degrees.
On the inertial measurements the data I have seen with this hardware so far has me wondering if I wouldn't get better data just relying on the GPS alone.... Maybe it would actually work better in a dynamic situation with movement causing more white noise type error. What I have been doing is seeing how much static error I could create.
@Doug - sorry for misspelling yor name - it was unintentional. Simulation update: tried with Kp = 0.5 and Ki = 0.005. Yaw lock is good. Still wondering if the yaw-to-roll effect may be related to Kp being too high. I uploaded a short imu.swfvideo (requires shockwave flash player): at first the board is moved around its axes. Then gpsfeed "turns" toward north and the "board" on Vpython turns in a short while. It's not so clear on the video, but the "board" has a short movement every time a new GPS sentence is received, meaning that yaw gyro actually drifts and yaw compensation works.
Hi Dough and all.
Regarding question #1 on yaw Ki and Kp: I did some simulations with Kp = 0.01 and Ki = 0.00001. I'm simulating GPS with gpsfeed+ and looking at the results with demo.py (thanks goes to Brian Wolfe). gpsfeed simulates a square shaped path with 500 m side, speed = 4 kts. No visible yaw correction. I then tried with Kp = 0.1 and Ki = 0.0001 and yaw correction started manifesting. Compensation shows some overshoot (Kp too high ? 90 deg turns ?) and has slow settling to target yaw (Ki too low ?). I found interesting that turning the board around yaw axis only has an effect on roll axis too. I suspect that the firmware is trying to compensate for a centrifugal acceleration that doesn't exist because the board is not moving.
Regarding question #2 on accelerometers. Some time ago I've tried to do some dead reckoning with accelerometer data only. It works for very short distances and with very accurate accelerometers. The problem is in the double integration of acceleration to obtain position: the slightest error in acceleration and position data has no meaning after few seconds. Velocity is only slightly better. What's needed is an accurate speed reference to periodically cancel out velocity errors due to integration. What about comparing speed over ground from GPS to speed over ground computed from accelerometers and DCM ?
@Doug: The Pyramidally mounted IMU will allow all 3 accelerometers an opportunity to receive their initial calibration at rest since they see some portion of the gravity vector equally. As Bill Premerlani recently replied in another post, two vectors are ultimately required to handle "yaw" as far as the gyros are concerned, and that is where DCMs gps velocity vector comes in. Initial gryo drift can be calibrated on the ground as well, but only two axis that are perpendicular to a reference vector can be adjusted during normal flight. This is why gravity and GPS velocity vector must be used together for total sensor drift adjustment. Obviously, the magnetometer can be another reference vector if GPS is not available. In either event, I've talked myself out of the possibility that a unique IMU orientation alone could handle yaw drift with gravity alone!! The only advantage to the pyramid mount is initial 3-axis accelerometer calibration.
If you are just checking back in on this blog, I have updated the original post to be a FAQ of the questions and answers that have come up so far. I will continue to update the top post as questions come up and get answered.
//*****YAW***************
COGX = cos(ToRad(ground_course));
COGY = -sin(ToRad(ground_course));
errorCourse=(DCM_Matrix[0][0]*COGX) - (DCM_Matrix[1][0]*COGY); //Calculating YAW error
Vector_Scale(errorYaw,&DCM_Matrix[2][0],errorCourse); //Applys the yaw correction to the XYZ rotation of the aircraft, depeding the position.
Vector_Scale(&Scaled_Omega_P[0],&errorYaw[0],Kp_YAW);//.01proportional of YAW.
Vector_Add(Omega_P,Omega_P,Scaled_Omega_P);//Adding Proportional.
Vector_Scale(&Scaled_Omega_I[0],&errorYaw[0],Ki_YAW);//.00001Integrator
Vector_Add(Omega_I,Omega_I,Scaled_Omega_I);//adding integrator to the Omega_I
I'm in the process of modifying it to work with a 3-axis manometer instead of GPS. It is coming along quite well, I'll post soon.
@Doug - It may be possible to use a 3-axis magnetometer, for use only at initial startup of IMU, to calulate the taildraggers angles and heading. No electrical interference would be present at that point. The data would be used by the Pyramidally mounted IMU to determine the relative amount of the gravity each of the 3 accelerometers should be seeing and thus calibrate. The gryos could then be given the appropriate initial angle, the gryos angle rotated from level flight seen at rest. After that, ignore the magnetometer and take off!
@Doug - sorry, my fault: I was mislead by line 95 in file ArduIMU_DCM_V11.pde:
float speed_3d=0; //Speed (3-D) (not used)
Instead speed_3d is updated inside the GPS.pde file (which I didn't consider because I use different GPS parsing code). OTOH Premerlani's code has this estYawDrift() function that returns course over ground coming from GPS only if GPS has valid data, otherwise it returns a filtered version of the direction coming from DCM matrix itself.
@Dan and Lorentz - Thanks, I have found the code now. Stupid of me to assume that roll_pitch_drift could not mean roll_pitch_yaw_drift.... Lorentz, not sure I understand your comment about "speed3d", but it seems that the yaw correction code should have some logic in it that only attempts to apply the correction if the ground speed > 0. If the ground speed is zero the ground course will be an unreliable/noise measurement that would induce a yaw error rather than correct it.
@Michael - Thank you for your idea of mounting the IMU "pyramid style". I had had that idea but hadn't really worked through it in my mind. In addition to playing with the IMU for autopilot use I am interested in it for an experimental full scale aircraft avionics project. Maybe you have an idea for another issue I have there which is handling the offsets at startup if the IMU is not in a "stabilized" attitude at start-up. For example think of the IMU mounted in the panel of a taildragger airplane. At rest on the ground it is in a pitch up attitude. You know the angle, so you could account for the angled gravity vector and calculate the offsets. But then what if you park your airplane on a 5% slope?? I am looking for an idea on how to handle the offsets when the initial attitude is not precisely known. The particular application I am thinking of could see pitch and roll off by up to maybe 15 degrees at startup.
Pyramid style ArduiIMU mounting as a possible solution for static Yaw drift. The Yaw's drift correction is dependent on the active GPS vector. It is a consequence of the lack of observability of the gravity vector for the yaw gyro and accelerometer during stationary, level at rest conditions. Typically, we mount the 6dof ArduIMU flat, in its strapdown orientation so that all the sensors fit our concept of alignment with the usual x,y,z axis. If the 6dof cube was mounted on one of its "points", there would be the sqr(x^2+y^2+z^2) vector from all three accelerometers sensing gravity at rest. Each accelerometer would see it's percentage of the total gravity vector and so the usual routines for Gyro drift compensation could be used on all three gryos. All 3 Gyro axis would be stabilized at rest or in the QuadCopter hover application. The matrices that define x,y,z would need to account for their new "static" initial rotation to describe it's orientation with the body axis as each body vector would use a contribution of the sensors. Nothing major really changes with the routines and the GPS corrections regarding DCM would still be all the same. A nice method to hold the cube in the new orientation would be needed, possibly made of 2 FR-4 pcbs.
Comments
On the inertial measurements the data I have seen with this hardware so far has me wondering if I wouldn't get better data just relying on the GPS alone.... Maybe it would actually work better in a dynamic situation with movement causing more white noise type error. What I have been doing is seeing how much static error I could create.
Doug
Regarding question #1 on yaw Ki and Kp: I did some simulations with Kp = 0.01 and Ki = 0.00001. I'm simulating GPS with gpsfeed+ and looking at the results with demo.py (thanks goes to Brian Wolfe). gpsfeed simulates a square shaped path with 500 m side, speed = 4 kts. No visible yaw correction. I then tried with Kp = 0.1 and Ki = 0.0001 and yaw correction started manifesting. Compensation shows some overshoot (Kp too high ? 90 deg turns ?) and has slow settling to target yaw (Ki too low ?). I found interesting that turning the board around yaw axis only has an effect on roll axis too. I suspect that the firmware is trying to compensate for a centrifugal acceleration that doesn't exist because the board is not moving.
Regarding question #2 on accelerometers. Some time ago I've tried to do some dead reckoning with accelerometer data only. It works for very short distances and with very accurate accelerometers. The problem is in the double integration of acceleration to obtain position: the slightest error in acceleration and position data has no meaning after few seconds. Velocity is only slightly better. What's needed is an accurate speed reference to periodically cancel out velocity errors due to integration. What about comparing speed over ground from GPS to speed over ground computed from accelerometers and DCM ?
//*****YAW***************
COGX = cos(ToRad(ground_course));
COGY = -sin(ToRad(ground_course));
errorCourse=(DCM_Matrix[0][0]*COGX) - (DCM_Matrix[1][0]*COGY); //Calculating YAW error
Vector_Scale(errorYaw,&DCM_Matrix[2][0],errorCourse); //Applys the yaw correction to the XYZ rotation of the aircraft, depeding the position.
Vector_Scale(&Scaled_Omega_P[0],&errorYaw[0],Kp_YAW);//.01proportional of YAW.
Vector_Add(Omega_P,Omega_P,Scaled_Omega_P);//Adding Proportional.
Vector_Scale(&Scaled_Omega_I[0],&errorYaw[0],Ki_YAW);//.00001Integrator
Vector_Add(Omega_I,Omega_I,Scaled_Omega_I);//adding integrator to the Omega_I
I'm in the process of modifying it to work with a 3-axis manometer instead of GPS. It is coming along quite well, I'll post soon.
float speed_3d=0; //Speed (3-D) (not used)
Instead speed_3d is updated inside the GPS.pde file (which I didn't consider because I use different GPS parsing code). OTOH Premerlani's code has this estYawDrift() function that returns course over ground coming from GPS only if GPS has valid data, otherwise it returns a filtered version of the direction coming from DCM matrix itself.
@Michael - Thank you for your idea of mounting the IMU "pyramid style". I had had that idea but hadn't really worked through it in my mind. In addition to playing with the IMU for autopilot use I am interested in it for an experimental full scale aircraft avionics project. Maybe you have an idea for another issue I have there which is handling the offsets at startup if the IMU is not in a "stabilized" attitude at start-up. For example think of the IMU mounted in the panel of a taildragger airplane. At rest on the ground it is in a pitch up attitude. You know the angle, so you could account for the angled gravity vector and calculate the offsets. But then what if you park your airplane on a 5% slope?? I am looking for an idea on how to handle the offsets when the initial attitude is not precisely known. The particular application I am thinking of could see pitch and roll off by up to maybe 15 degrees at startup.