多传感器融合定位(3-惯性导航原理及误差分析)7-实现 分立级标定 accel加速度计内参公式验证

多传感器融合定位(3-惯性导航原理及误差分析)7-实现 分立级标定 accel加速度计内参公式验证多传感器融合定位(3-惯性导航原理及误差分析)7-实现分立级标定accel加速度计内参公式验证参考博客:组合导航系列文章(五):IMU误差标定之基于转台的标定基于Python的开源GNSS/INS仿真github代码h

多传感器融合定位(3-惯性导航原理及误差分析)7-实现 分立级标定 accel加速度计内参公式验证

参考博客:
组合导航系列文章(五):IMU误差标定之基于转台的标定
基于Python的开源GNSS/INS仿真
github代码 hkwww/gnss-ins-sim

本次主要使用 解析法进行 accel 加速度计的内参公式验证

最终结果

在这里插入图片描述

搭建仿真场景

参考 gnss-ins-sim 中的 demo_allan.py 构建 imu 仿真模型,并保存数据

sim_imu.py 部分代码(全部代码在文末)

指定 场景设计motion的文件、fs 采样频率为100HZ (1秒读取100次)
# globals
D2R = math.pi/180

motion_def_path = os.path.abspath('.//demo_motion_def_files//')
fs = 100.0          # IMU sample frequency
    imu_err = { 
   'gyro_b': np.array([0.0, 0.0, 0.0]),
               'gyro_arw': np.array([0.25, 0.25, 0.25]) * 1.0,
               'gyro_b_stability': np.array([3.5, 3.5, 3.5]) * 1.0,
               'gyro_b_corr': np.array([100.0, 100.0, 100.0]),
               'accel_b': np.array([0.0, 0.0, 0.0]),
               'accel_vrw': np.array([0.03119, 0.03009, 0.04779]) * 1.0,
               'accel_b_stability': np.array([4.29e-5, 5.72e-5, 8.02e-5]) * 1.0,
               'accel_b_corr': np.array([200.0, 200.0, 200.0]),
               'mag_std': np.array([0.2, 0.2, 0.2]) * 1.0
              }
    # do not generate GPS and magnetometer data
    imu = imu_model.IMU(accuracy=imu_err, axis=6, gps=False)
根据自定义的运动场景,进行数据仿真
    #### start simulation
    sim = ins_sim.Sim([fs, 0.0, 0.0],
                      motion_def_path+"//internal_calibration_imu.csv",
                      ref_frame=1,
                      imu=imu,
                      mode=None,
                      env=None,
                      algorithm=None)
    sim.run(1)
    # generate simulation results, summary, and save data to files
    sim.results('')  # save data files
自定义的运动场景 internal_calibration_imu.csv
根据解析法的公式,需要设置6个imu场景,分别是

在这里插入图片描述

IMU Z轴朝上,Z轴朝下,Y轴朝上,Y轴朝下,X轴朝上,X轴朝下

在这里插入图片描述

internal_calibration_imu.csv

每个场景持续时间 20s,采样频率100hz,一个场景生成 2000个个数据
在这里插入图片描述

生成的仿真数据 accel-0.csv

在这里插入图片描述

进行内参标定验证

internal_calibration.py 部分代码(全部代码在文末)

指定accel的仿真生成数据
imu_sim_path = 'demo_saved_data/2020-11-05-11-37-15/accel-0.csv'
数据处理,这里以Z轴朝向数据为例,在accel-0.csv表中,区间 1-2000代表Z朝上,区间 2000-4000代表 Z朝下,经多次试验得知,imu在仿真运动后的数据需要一段时间才能稳定,所以选择取每个场景中 2000个数据中的500个,再把500个数据取均值表征 IMU在这个状态下的每个轴加速度
    truth_z_up = get_imu_mean_data(raw_data,1000,1500)   # IMU Z轴朝上 ,取中间500个数据的均值
    truth_z_down = get_imu_mean_data(raw_data, 3000, 3500)  # IMU Z轴朝下
6个场景 IMU数据处理后结果

留意 g 重力加速度所在的位置

——————————————————Z轴——————————————————————
[[ 8.90824804e-05 -6.20375208e-05 -9.79496514e+00]]
[[ 1.48275457e-04 -1.10436760e-01  9.79419008e+00]]
——————————————————Y轴——————————————————————
[[ 3.06869928e-04 -9.79499159e+00 -4.09315067e-02]]
[[-1.73602602e-04  9.79438219e+00  6.92753399e-02]]
——————————————————x轴——————————————————————
[[ 9.79475112e+00  2.27139296e-04 -1.53404379e-02]]
[[-9.79437605e+00  2.96217751e-04  2.76735700e-02]]
自定义内参矩阵
    #init internal_calibration
    truth_bias = np.array([0.1,0.2,0.3]).reshape(3,-1)
    calib_bias = np.zeros((3,1))

    truth_sacle_factor = np.asarray([[0.0024,0   ,   0],
                                    [0     ,0.25,   0],
                                    [0     ,0   ,0.26]])
    cailb_sacle_factor = np.zeros((3, 3))

    truth_installation_error = np.asarray([[0     ,-0.0333,0.064222],
                                          [0.0343,0      ,0.00890 ],
                                          [0.0080,0.00231,0       ]])
    cailb_installation_error = np.zeros((3, 3))


    internal_martix = truth_sacle_factor + truth_installation_error    # internal_martix 内参误差矩阵,包含(标度因素,安装误差)
求解误差模型

在这里插入图片描述

    #分别求解 对应的误差模型 error_matix_ (Ax Ay Az)
    ##z 朝上;朝下
    error_matix_z_up   = np.dot(internal_martix,truth_z_up.T) + truth_bias
    error_matix_z_down = np.dot(internal_martix,truth_z_down.T) + truth_bias
    ##y 朝上;朝下
    error_matix_y_up   = np.dot(internal_martix,truth_y_up.T) + truth_bias
    error_matix_y_down = np.dot(internal_martix,truth_y_down.T) + truth_bias
    ##x 朝上;朝下
    error_matix_x_up   = np.dot(internal_martix,truth_x_up.T) + truth_bias
    error_matix_x_down = np.dot(internal_martix,truth_x_down.T) + truth_bias
反验证,求内参误差
    #解析法求解 零偏误差
    calib_bias = (error_matix_z_up + error_matix_z_down)  /  2
    #解析法求解 标度因子 安装误差矩阵
    internal_martix_z = (error_matix_z_up - calib_bias) / -g
    internal_martix_y = (error_matix_y_up - calib_bias) / -g
    internal_martix_x = (error_matix_x_up - calib_bias) / g
最后结果
零偏误差
truth bias
[[0.1]
 [0.2]
 [0.3]]
 
calib_bias
[[0.1018152 ]
 [0.18618827]
 [0.29977257]]
标度因素
truth_sacle_factor
[[0.0024 0.     0.    ]
 [0.     0.25   0.    ]
 [0.     0.     0.26  ]]

cailb_sacle_factor
[[0.00211219 0.         0.        ]
 [0.         0.24849897 0.        ]
 [0.         0.         0.25984316]]
安装误差
truth_installation_error
[[ 0.       -0.0333    0.064222]
 [ 0.0343    0.        0.0089  ]
 [ 0.008     0.00231   0.      ]]
 
cailb_installation_error
[[ 0.         -0.0328296   0.064374  ]
 [ 0.03568285  0.          0.00748734]
 [ 0.00761199  0.0033713   0.        ]]

全部代码

sim_imu.py

import numpy as np
import os
import math
from gnss_ins_sim.sim import imu_model
from gnss_ins_sim.sim import ins_sim

# globals
D2R = math.pi/180

motion_def_path = os.path.abspath('.//demo_motion_def_files//')
fs = 100.0          # IMU sample frequency

def create_sim_imu():     #生成 imu 方针imu数据
    ### Customized IMU model parameters, typical for IMU381
    imu_err = { 
   'gyro_b': np.array([0.0, 0.0, 0.0]),
               'gyro_arw': np.array([0.25, 0.25, 0.25]) * 1.0,
               'gyro_b_stability': np.array([3.5, 3.5, 3.5]) * 1.0,
               'gyro_b_corr': np.array([100.0, 100.0, 100.0]),
               'accel_b': np.array([0.0, 0.0, 0.0]),
               'accel_vrw': np.array([0.03119, 0.03009, 0.04779]) * 1.0,
               'accel_b_stability': np.array([4.29e-5, 5.72e-5, 8.02e-5]) * 1.0,
               'accel_b_corr': np.array([200.0, 200.0, 200.0]),
               'mag_std': np.array([0.2, 0.2, 0.2]) * 1.0
              }
    # do not generate GPS and magnetometer data
    imu = imu_model.IMU(accuracy=imu_err, axis=6, gps=False)

    #### start simulation
    sim = ins_sim.Sim([fs, 0.0, 0.0],
                      motion_def_path+"//internal_calibration_imu.csv",
                      ref_frame=1,
                      imu=imu,
                      mode=None,
                      env=None,
                      algorithm=None)
    sim.run(1)
    # generate simulation results, summary, and save data to files
    sim.results('')  # save data files

internal_calibration_imu.py

# -*- coding: utf-8 -*-
# Filename: demo_allan.py

""" Test Sim with Allan analysis. Created on 2018-01-23 @author: dongxiaoguang """

import os
import math
import numpy as np
from read_csv import  getRawData
from sim_imu  import  create_sim_imu
from gnss_ins_sim.sim import imu_model
from gnss_ins_sim.sim import ins_sim

# globals
D2R = math.pi/180

imu_sim_path = 'demo_saved_data/2020-11-05-11-37-15/accel-0.csv'
fs = 100.0          # IMU sample frequency
g = 9.8             # gravity

def print_info(truth_bias,calib_bias,
               truth_sacle_factor,cailb_sacle_factor,
               truth_installation_error,cailb_installation_error):
    print("truth bias")
    print(truth_bias)
    print("calib_bias")
    print(calib_bias)
    print("truth_sacle_factor")
    print(truth_sacle_factor)
    print("cailb_sacle_factor")
    print(cailb_sacle_factor)
    print("truth_installation_error")
    print(truth_installation_error)
    print("cailb_installation_error")
    print(cailb_installation_error)


def get_imu_mean_data(raw_data,x1,x2):     # 获取IMU data ,做均值处理,取中间的500次数据做平均; x1 x2 为输入的区间
    truth_array = np.asarray(raw_data[x1:x2])
    truth_array = truth_array.astype(np.float)  # 将numpy 中的字符型数据 转换 为 浮点型
    data_mean  = np.mean(truth_array, axis=0)  # IMU Z轴朝上 ,取中间500个数据的均值
    data_mean = np.asarray([data_mean])
    return  data_mean

def accel_calibration():
    #get imu sim data
    raw_data = np.asarray([])
    raw_data = getRawData(imu_sim_path)   # 获取imu仿真的原始数据
    #process imu data
    ##Z轴##
    truth_z_up = get_imu_mean_data(raw_data,1000,1500)   # IMU Z轴朝上 ,取中间500个数据的均值
    truth_z_down = get_imu_mean_data(raw_data, 3000, 3500)  # IMU Z轴朝下
    # print("——————————————————Z轴——————————————————————")
    # print(truth_z_up)
    # print(truth_z_down)
    ##Y轴##
    truth_y_up = get_imu_mean_data(raw_data,7000,7500)   # IMU y轴朝上 ,取中间500个数据的均值
    truth_y_down = get_imu_mean_data(raw_data, 9000, 9500)  # IMU y轴朝下
    # print("——————————————————Y轴——————————————————————")
    # print(truth_y_up)
    # print(truth_y_down)
    ##X轴##
    truth_x_up = get_imu_mean_data(raw_data,13000,13500)   # IMU x轴朝上 ,取中间500个数据的均值
    truth_x_down = get_imu_mean_data(raw_data, 15000, 15500)  # IMU x轴朝下
    # print("——————————————————x轴——————————————————————")
    # print(truth_x_up)
    # print(truth_x_down)

    #init internal_calibration
    truth_bias = np.array([0.1,0.2,0.3]).reshape(3,-1)
    calib_bias = np.zeros((3,1))

    truth_sacle_factor = np.asarray([[0.0024,0   ,   0],
                                    [0     ,0.25,   0],
                                    [0     ,0   ,0.26]])
    cailb_sacle_factor = np.zeros((3, 3))

    truth_installation_error = np.asarray([[0     ,-0.0333,0.064222],
                                          [0.0343,0      ,0.00890 ],
                                          [0.0080,0.00231,0       ]])
    cailb_installation_error = np.zeros((3, 3))


    internal_martix = truth_sacle_factor + truth_installation_error    # internal_martix 内参误差矩阵,包含(标度因素,安装误差)

    #分别求解 对应的误差模型 error_matix_ (Ax Ay Az)
    ##z 朝上;朝下
    error_matix_z_up   = np.dot(internal_martix,truth_z_up.T) + truth_bias
    error_matix_z_down = np.dot(internal_martix,truth_z_down.T) + truth_bias
    ##y 朝上;朝下
    error_matix_y_up   = np.dot(internal_martix,truth_y_up.T) + truth_bias
    error_matix_y_down = np.dot(internal_martix,truth_y_down.T) + truth_bias
    ##x 朝上;朝下
    error_matix_x_up   = np.dot(internal_martix,truth_x_up.T) + truth_bias
    error_matix_x_down = np.dot(internal_martix,truth_x_down.T) + truth_bias

    #解析法求解 零偏误差
    calib_bias = (error_matix_z_up + error_matix_z_down)  /  2
    #解析法求解 标度因子 安装误差矩阵
    internal_martix_z = (error_matix_z_up - calib_bias) / -g
    internal_martix_y = (error_matix_y_up - calib_bias) / -g
    internal_martix_x = (error_matix_x_up - calib_bias) / g

    #给 cailb_sacle_factor 对角线赋值
    cailb_sacle_factor[0,0] = internal_martix_x[0]
    cailb_sacle_factor[1,1] = internal_martix_y[1]
    cailb_sacle_factor[2,2] = internal_martix_z[2]
    # 给 cailb_installation_error 非对角线元素赋值
    cailb_installation_error[1,0] = internal_martix_x[1]
    cailb_installation_error[2,0] = internal_martix_x[2]
    cailb_installation_error[0,1] = internal_martix_y[0]
    cailb_installation_error[2,1] = internal_martix_y[2]
    cailb_installation_error[0,2] = internal_martix_z[0]
    cailb_installation_error[1,2] = internal_martix_z[1]

    print_info(truth_bias, calib_bias,truth_sacle_factor, cailb_sacle_factor,truth_installation_error, cailb_installation_error)

if __name__ == '__main__':
    #create_sim_imu() #生成自定义的方针 imu 数据
    accel_calibration()    #进行imu 加速度计内参标定

read_csv.py

import csv
import  numpy as np


def getRawData(path):
    raw_data = []
    csv_reader  = csv.reader(open(path,'r'))
    header = next(csv_reader)   # read the head
    for row in csv_reader:
        raw_data.append(row)
    raw_data = np.asarray(raw_data)    # 转换为numpy格式
    return  raw_data


if __name__ == '__main__':
    raw_data = []
    csv_reader  = csv.reader(open('demo_saved_data/2020-11-03-23-07-52/accel-0.csv','r'))
    header = next(csv_reader)   # read the head
    for row in csv_reader:
        raw_data.append(row)
    raw_data = np.asarray(raw_data)    # 转换为numpy格式
    print(raw_data.shape)


今天的文章多传感器融合定位(3-惯性导航原理及误差分析)7-实现 分立级标定 accel加速度计内参公式验证分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/66453.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注