Hi folks - this is by first blog post here, so let me know if I'm commiting a faux pas in any manner :)
I've decided that the compass support on ArduPilotMega needs beefing up. I'm working on this in a few ways:
1. Added MicroMag3 support - this is accomplished, though I still need to refactor to make things part of a better OO-design.
2. Added a LUT for both magnetic declination and inclination so that these values are populated by the GPS.
3. Looking to improve the drift correction algorithm. I like in an area where the inclination of the magnetic field is about 70 degrees from horizontal. Many people assume that the magnetic runs tagent to the earth's surface - this is significantly untrue. Becuase the magnetic field vector is so close to vertical here, it actually provides a much better estimator for pitch and roll than yaw if the plane is horizontal. Thus, I intend to modify the drift correction in the DCM to use the magnetic vector as a truly 3D vector. This means that depending on the orientation of the plane, it will correct for pitch, roll, and/or yaw with varying levels of accracy. Has anyone already looked into this?
4. Make a calibration wizard in "setup" and have it store the values in the EEPROM.
Cheers,
John
Comments
Adam-
Check out my other post: http://diydrones.com/profiles/blogs/magnetic-declination-and?xg_sou.... It has the source code. Some folks asked some good follow-up questions, so check the comments, too :)
I'm on vacation, so I won't be able to dig into the code for a week or so.
Thanks!
john
John,
I just stumbled upon your post by searching for my own automatic declination blog post. I didn't realize that someone had already implemented this. Out of curiosity what was the size of your lookup table?
Thanks,
Adam
Randy, thanks for the guidance. Fortunately, I had guessed correctly and was already adding support to that area once Chris pointed me to the APM 2.0 trunk. The tricky part is that DataFlash and AP_Compass_MicroMag3 are going to have to share the same SPI line. This leaves me with a few options:
1. (current) DataFlash remains unchanged. AP_Compass_MicroMag3 saves "SPI state" before using it and then restores it after - think KeSaveFloatingPointState. We can get away with this because DataFlash uses SPI in a synchronous (no interrupts) manner and we can force MicroMag3 to also work in a synchronous manner. However, the latter would require the addition of void Compass::do_work() that would run in the fast (50hz) loop so that we can check for the DRDY pin and pull in new data when it is ready and then request the next axis. I'm estimating this call will take ~tens of microseconds once I tighten the timings.
2. Create an SPI arbiter that would allow multiple devices to use the SPI bus in an async manner. This would involve disabling interrupts for a short periods of time. I'll have to research if I have to disable them outright or if I can away with disable solely the SPI interrupt.
On a somewhat related note, I'm using PK0-4 for the sideband signals. Is there a GPIO arbiter that would make sure two devices aren't trying to use the same pin? Ideally at compile time? :)
e.g.
config.h:
#define COMPASS_TYPE COMPASS_MICROMAG3
micromag3.h:
#if COMPASS_ENABLED && COMPASS_TYPE == COMPASS_MICROMAG3
#define PK0_IN_USE
#endif
someotherwidget.h:
#define PK0_IN_USE // compiler error already defined
John,
to make it fit in with the existing compasses we support, it would be great if you could make an addition to the AP_Compass library. If you chose to do this you would need to create two new files AP_Compass_MicroMag3.cpp and AP_Compass_MicroMag3.h. And you'd also need to make a minor change in the AP_Compass.h file to include your new h file.
I know it's often more difficult to try and fit yourself into someone else's framework but that's probably the easiest way to get support for the MicroMag3 without widespread changes to other people's code.
-Randy
Hi John,
A couple points:
We do not do automatic detection of declination (Sorry Chris). What we do is automatic detection of the magnetometer offsets. A LUT might be nice, but we are getting a little tight on code space. How big is it? And what kind of geographic resolution? I live in an area with significant changes in declination over relatively short distances, so I have not been a fan of a LUT.
You have a bit of a point on the magnetic field angle w.r.t horizontal. However, using the mag vector as a 3d vector doesn't really help us with drift correction. To correct 3 gyro axis you need two independent vector references. The closer to orthogonal they are the better. The first we use is acceleration due to gravity - this corrects for pitch and roll drift. The second if the magnetometer vector which we use only to correct for drift in yaw. I have previously tried to use the magnetic vector as a 3d vector for drift correction and found two things. First it provides no improvement in yaw drift correction, and second, using two vectors to simultaneously try to correct the same set of axis is difficult as the two drift correction processes tend to fight each other and oscillate.
Thanks for the pointer, Chris! I'm sync'd into the SVN repository now. (Still have to figure out the build process, but I'm getting closer! :)
Bill's paper was very interesting. I had originally assumed that I would have to dynamically compensate for the servos and the motor, but emperically, that doesn't look to be necessary.
I'll have to read Bill's paper a couple more times, but it looks like he's able to dynamically compute the offsets for calibration, but not the declination or inclination of the magnetic field. His work would take care of #4 - in terms of offsets. MicroMag3 doesn't have the same built-in scaling calibration that his algorithm needs.
-
1
-
2
of 2 Next