
Usually there are two specs related to the covariance matrix in a Kalman filter. Let's only take gyro for example because accel is similar. The two specs are ARW and Bias Instability. ARW reperesents the noise level of the gyro output: ARW = std*sqrt(dt), where std is the standard deviation of gyro noise and dt is the sampling interval. Depending on your system equation in the EKF, you might also need to estimate the gyro bias in real time, and then you need bias instability to model the varying gyro bias. Bias instability is hard to model and is a much difficult topic. Generally we can model it as a random walk or a firstorder GaussMarkov process. We provide an online document for your reference: https://openimu.readthedocs.io/en/latest/algorithms.html

If you want to esimate gyro bias by averaging its output, you need to put it static for some time. Static time can be determined by running an Allan Variance analysis on its output. Or you can just use 100sec.
Posts made by Dong xiaoguang
We will add units in the headerline of the csv file.
Thanks for your feedback.
IMU自身是无法产生这三个数据的。但是通过不同传感器的融合，可以实现对零偏的估计。
以加速度和陀螺仪融合进行动态倾角测量为例，可以估计出陀螺仪x和y轴（非竖直方向的轴）的零偏。
当有GPS测量时，陀螺和加速度的三轴零偏都可以估计出来。
但并不建议将xRate减去xRateBias作为陀螺的实际角速度。因为估计本身是有误差的，尤其是在高动态的场合，估计误差往往会增加。因此，是否这样应用，需要取决于具体的应用。以动态倾角测量为例，若设备长期保持接近静止，则零偏的估计精度可以较高，但是存在频繁的加减速时，零偏估计误差会增加。
Hi JayantD,
That depends on the dynamic profile and measurement range of your application. However, 0.1deg is a pretty high accuracy. If you further consider the temperatur range, it is quite chanllenging. In our spec, the static angle accuracy of the full temperature range (40C to 85C) is 0.15deg.
Generally, this is difficult. However, you can use a firstorder approximation.
euler_angles = f(quaternion) ≈ f(quaternion_0) + (df/dquaternion)*(delta_quaterninon)
H = df/dquaternion
= [droll/dq0 droll/dq1 droll/dq2 droll/dq2
dpitch/dq0 dpitch/dq1 dpitch/dq2 dpitch/dq3
dyaw/dq0 dyaw/dq1 dyaw/dq2 dyaw/dq3]
cov(euler_angles) = H*cov(quaternion)*H'
The choice of the function f depends on the rotation sequence of Euler angles you want. We use ZYX in our code.
@robotsrobots
In my test, I adds ublox nav_pvt support. Since it is opensource, it is very easy to add support of GPS receivers.
To set the heading from GNSS always valid, you need set a variable in UpdateFunctions.c called "useMagHeading" FALSE.
Indeed, you need to a bit more to make this work reliably. For single antenna GNSS receiver, heading is derived from velocity, and heading accuracy is determined by velocity. We estimate heading variance used in the Kalman fitler according to GNSS velocity.
But since you decide to use a dualantenan GNSS receiver, the heading accuracy is decided by the separation between the antenna and the positioning engine (RTK, PPP).
Yes, you can. But you need to modify some of the source code:
 You need prepare GPS receiver driver to handle the UBLOX messages. Navpvt is supported now.
 Currently, we use ground speed to determine if the heading from GNSS is valid. You need to change the code to set the heading from GNSS always valid.
@zhendaozhao
There are a few things to notice.
 The algorithm output rate is 25Hz, which is defined in ekfSim_ins.cfg, The max rate can be 100Hz because this algorithm indeed run in an embeded system and there is only limited computational resources. If you want to manually compare the algo output with reference, reference need be downsampled to match the algo output. In the simulation, to deal with cases like this, interp is performaed to align the two sets of data. Please refer to the source code for details.
 Algo output is in the form of Lat/Lon/Alt. If you want to convert it to [m, m, m], there are two routines in the simulation. But you need to do this manually. The first is to use lla2ecef_batch or lla2ecef in geoparams.py to convert LLA to ECEF positions. However, we usually want position error in NED frame instead of the ECEF frame. So, the second is to further convert the above ECEF position to NED position. You can refer to function array_error in ins_data_manager.py for details.
def array_error(self, x, r, angle=False, lla=0):
'''
Calculate the error of an array w.r.t its reference.
Args:
x: input data, numpy array.
r: reference data, same size as x.
angle: True if x contains angles, False if not.
pos: 0 if x is not in LLA form;
1 if x is in LLA form, and NED error is required;
>=2 if x is in LLA form, and ECEF error is required.
Returns:
err: error
'''
if lla == 0:
err = x  r
if angle:
for j in range(len(err.flat)):
err.flat[j] = attitude.angle_range_pi(err.flat[j])
else:
# convert x and r to ECEF first
x_ecef = geoparams.lla2ecef_batch(x)
r_ecef = geoparams.lla2ecef_batch(r)
err = x_ecef  r_ecef
# convert ecef err to NED err
if lla == 1:
n = err.shape[0]
for i in range(0, n):
c_ne = attitude.ecef_to_ned(r[i, 0], r[i, 1])
err[i, :] = c_ne.dot(err[i, :])
return err