uNav INS

brtaylor is right. If your platform has any significant motion, you can't rely on the accelerometer to give you a second attitude reference (the first I assume is your magnetometer). Even with GPS aiding, and if you have a great dynamics model of your system, it's unlikely that you'll be able to retrieve an estimated gravity vector with enough accuracy or precision to use as a second reference using COTS MEMs sensors (that most of us can afford at least) - at least not good enough for a control system to use. I've tried this on many platforms with various levels of success. When I've gotten it to work, it was through artificially increasing terms in the covariance matrix to ignore the error buildup - but then I end up with a lot of drift in the attitude estimate. This is why it wasn't suitable for a control system without additional attitude measurements. It also depends on the system you are trying to control, its required bandwith and dynamics - smaller systems will need more sensitivity and bandwidth to control. I've ended up at this wall for hobbyist type hardware a few times. Make sure your control system, state estimator and overall system are matched to each other.

Attitude measurements, which are needed to correct the gyro stabilized dynamics model, are a tough topic - especially in the MEMS hobby world (read: us cheap bastards!). A properly calibrated magnetometer is usually the first attitude reference we all use since it's cheap and works on earth and in near-earth as long as you have a good magnetic model to use (see WMM). But additional attitude measurements to use if you are not motionless are a real challenge. Note, if you didn't know already, you'll need at least two (2) attitude references to estimate a 3-D attitude - but the more the better! RTK GPS can be used to provide an attitude reference (with 2+ receivers), and that equipment is getting more available and cheaper by the bay. But I'm not sure if it'll have the bandwidth for a pedestal balance type problem. Other options include camera object tracking (lot of CPU horsepower needed), time-of-flight type sensors, etc. Lots of ideas out there, but as usual implementation and bandwidth are a challenge.

This problem has certainly been solved in the past, but it'll use very expensive sensors, precision calibration of those sensors, and a system built to be controllable by the available hardware.

Good luck!

I've had plenty of luck estimating attitude, inertial velocity, and inertial position of manned and unmanned aircraft with MEMS sensors and GNSS aiding. To be clear, the EKF is only using the GNSS data as the measurement source, the gyro and accel are used in the time update. I typically don't use mags except to initialize the EKF and you get good heading accuracy if the inertial speed is above approximately 5 to 10 m/s. Where GNSS yaw comes in handy is if you spend lots of time slower than that, such as hover. Last year I did a comparison of our 15 state EKF, the VectorNav VN-300 (a high-end GNSS aided MEMS INS with GNSS yaw), and three GNSS receivers, which were used to measure attitude directly for their differential positions at a rate of 10 Hz. The results are attached, a little bias is present, but in general all 3 solutions match very well.

gnss attitude.PNG

I'm currently developing an INS around what is probably the most expensive MEMS IMU on the market, the Honeywell HG4930CA51 (https://www.digikey.com/en/products...B2BTAngdxQG2wAgAkBxAFgE4BmABgGEBBAVgEYQBdAXyA), should be interesting to compare with our EKF!
 

Attachments

  • gnss_attitude.pdf
    94.3 KB · Views: 143
Youhoo! I have solved the compiler problem, using a combination of Arduino, VS Code, PlatformIO + reconfiguring some compiling flags. Also one should add the ElapsedMillis.h to a few libs.
If You guys have any interest on ESP32 , I can share.
Now I can compile and upload it. I can read the mpu outputs but its keep telling me : "Unable to establish communication and configure GNSS RX"

I struggled with it, probably there is some compatibility issues with hardwareSerial. or maybe this lib does not support NEO-m8n, does it?

So, broadly speaking, if this is going on a vehicle, you'll want to use GPS data as your measurement update. If it's stationary on the ground, you're going to have better results using just the IMU data, since you won't have enough excitation of the GPS to get useful data out of it.
Your comment was so inspiring thank you, I used to work complementary filter years ago, very first works of Mahony, now I was wondering how the INS/GPS fusion world has changed.
I did a comparison of our 15 state EKF, the VectorNav VN-300 (a high-end GNSS aided MEMS INS with GNSS yaw), and three GNSS receivers, which were used to measure attitude directly for their differential positions at a rate of 10 Hz. The results are attached, a little bias is present, but in general all 3 solutions match very well.
These information are priceless, thank you again.

I typically don't use mags except to initialize the EKF and you get good heading accuracy if the inertial speed is above approximately 5 to 10 m/s.
I guess I will put Mags in use as a second absolute ref, later. right now I just want to run a basis.

if you have a great dynamics model of your system, it's unlikely that you'll be able to retrieve an estimated gravity vector with enough accuracy or precision to use as a second reference using COTS MEMs sensors
Hi @metalwave, thanks for your concerns. my platform is a pedestal , installed on a regular car, so I dont expect a high dynamic environment, but still I know gyro has better behavior while rotating rather than staying still, which is opposite of Accelerator behavior when is used as an absolute ref.
 
Now I can compile and upload it. I can read the mpu outputs but its keep telling me : "Unable to establish communication and configure GNSS RX"

I struggled with it, probably there is some compatibility issues with hardwareSerial. or maybe this lib does not support NEO-m8n, does it?

That is a possibility, I recall that there is a cutoff where older GPS receivers don't work with the newer library (the biggest offender IIRC is that uBlox changed the size of the UBX-NAV-PVT packet), but I don't recall where the cutoff is in the uBlox lineup or if there is an old enough version of my library on GitHub that will support it. You might try SparkFun, they have a uBlox library as well:
https://github.com/sparkfun/SparkFun_u-blox_GNSS_Arduino_Library

I'm sure there are also other uBlox UBX libraries now available. Or you could check the packet definitions in my library against the M8N documentation to see if modifications are needed. I typically only use SAM-M8Q receivers when I want to use something low cost or ZED-F9P if I want high accuracy or to use a differential measurement.
 
I've had plenty of luck estimating attitude, inertial velocity, and inertial position of manned and unmanned aircraft with MEMS sensors and GNSS aiding. To be clear, the EKF is only using the GNSS data as the measurement source, the gyro and accel are used in the time update.

Same here. I used a 15 state EKF in sounding rockets for state estimation and attitude control with great success. But I think for a pedestal control problem for a small system as RouthUAV was mentioning, using hobby grade sensors, it may be a stretch. However, I don't know the details of what he's doing... Note that I've successfully used my filter to provide control data to a pedestal type problem (thrust vectored takeoff), but I had to add a lot of inertia to the vehicle to reduce the control bandwith required. Small rockets went unstable, but add 30# of weight in the right spots and it worked! But that's what I alluded to earlier in matching the filter, control system and system hardware to each other to get it all to work.

I typically don't use mags except to initialize the EKF and you get good heading accuracy if the inertial speed is above approximately 5 to 10 m/s. Where GNSS yaw comes in handy is if you spend lots of time slower than that, such as hover.

Yes, the filter behaves better with motion, but I still use the mag to stabilize attitude especially at higher roll rates where gyro bias dominates the error terms. This is application specific now I think and brings up another point of "what are you using this for"?


I'm currently developing an INS around what is probably the most expensive MEMS IMU on the market, the Honeywell HG4930CA51 (https://www.digikey.com/en/products...B2BTAngdxQG2wAgAkBxAFgE4BmABgGEBBAVgEYQBdAXyA), should be interesting to compare with our EKF!

It'd be great for you to show us how it compares. I've use a few non-MEMs type sensors in filters in the past and its amazing how much easier it is to work with very high quality sensors.
 
Same here. I used a 15 state EKF in sounding rockets for state estimation and attitude control with great success. But I think for a pedestal control problem for a small system as RouthUAV was mentioning, using hobby grade sensors, it may be a stretch. However, I don't know the details of what he's doing... Note that I've successfully used my filter to provide control data to a pedestal type problem (thrust vectored takeoff), but I had to add a lot of inertia to the vehicle to reduce the control bandwith required. Small rockets went unstable, but add 30# of weight in the right spots and it worked! But that's what I alluded to earlier in matching the filter, control system and system hardware to each other to get it all to work.



Yes, the filter behaves better with motion, but I still use the mag to stabilize attitude especially at higher roll rates where gyro bias dominates the error terms. This is application specific now I think and brings up another point of "what are you using this for"?




It'd be great for you to show us how it compares. I've use a few non-MEMs type sensors in filters in the past and its amazing how much easier it is to work with very high quality sensors.

Agree completely with everything you mention. It is very application dependent and you need to pick the sensors and the time update / measurement update scheme to match dynamics. I'll try to remember to post some data from the Honeywell sensor here when I get it!
 
I recall that there is a cutoff where older GPS receivers don't work with the newer library
I know @Don Kelly used an neo-m8n and someone had problem with 6 series. I wish I wont have to change the libs.

I'll try to remember to post some data from the Honeywell sensor here when I get it!
we love you
 
Dear Friends,
Thank you for the knowledge you share here.
I've worked for quite a while on this library, checked different versions. now I have connected my Neo-m8n module(UART) and Mpu9255 module (SPI) to an Arduino board.
I can collect data from the sensors, they look fine. but every time I test the EKF, it only iterates twice, one for initialization and only one more time in the main EKF, and then the micro is RESET!
I have checked many things, I pass every data from sensors and gps to console before running the EKF, they look fine. also I checked the sensors axis, in the MPU library it has rotate the gyro+accel axis so they match the mag sensor which looks fine for the EKF. here is how I call the EKF function:
Code:
Filter.update(gps.gps_tow_s(),gps.north_vel_mps(),gps.east_vel_mps(),gps.down_vel_mps(),gps.lat_rad(),gps.lon_rad(),gps.alt_msl_m(),Imu.gyro_x_radps(),Imu.gyro_y_radps(),Imu.gyro_z_radps(),Imu.accel_x_mps2(),Imu.accel_y_mps2(),Imu.accel_z_mps2(),Imu.mag_x_ut(),Imu.mag_y_ut(),Imu.mag_z_ut());

The GPS library is a ubx base lib.

here is the rotation of the axis:
Code:
  /* Convert to float values and rotate the accel / gyro axis */
  accel_[0] = static_cast<float>(accel_cnts_[1]) * accel_scale_ * G_MPS2_;
  accel_[1] = static_cast<float>(accel_cnts_[0]) * accel_scale_ * G_MPS2_;
  accel_[2] = static_cast<float>(accel_cnts_[2]) * accel_scale_ * -1.0f *
              G_MPS2_;
  temp_ = (static_cast<float>(temp_cnts_) - 21.0f) / TEMP_SCALE_ + 21.0f;
  gyro_[0] = static_cast<float>(gyro_cnts_[1]) * gyro_scale_ * DEG2RAD_;
  gyro_[1] = static_cast<float>(gyro_cnts_[0]) * gyro_scale_ * DEG2RAD_;
  gyro_[2] = static_cast<float>(gyro_cnts_[2]) * gyro_scale_ * -1.0f * DEG2RAD_;

in the meantime, I have faced a variable inside the uNAVINS.cpp library,
Code:
_dt
this variable is supposed to carry the loop time duration, but I cannot find any clue on how it is supposed to have the value, seems like its forgotten, so I fill it with a constant,
Code:
_dt = 0.2010;//(float)_t/1e6;
. I hoped this could solve the problem, but still nothing has changed!!
I really can not find any thing else to check , could any one plzzzzz help me with this?
Here is the whole code:
View attachment attach.zip
 
Back
Top