add Python scripts to plot the result

This commit is contained in:
liqiang 2024-04-25 15:05:06 +08:00
parent bb15456bdb
commit 7685d69ea2

318
scripts/plot_navresult.py Normal file
View File

@ -0,0 +1,318 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import numpy as np
import math as m
import matplotlib.pyplot as plt
# WGS84参数
WGS84_RA = 6378137.0
WGS84_E1 = 0.00669437999013
WGS84_WIE = 7.2921151467e-5
D2R = np.pi / 180.0
R2D = 180.0 / np.pi
# 计算子午圈半径和卯酉圈半径
# 输入参数: lat(纬度)[rad]
def radiusmn(lat):
tmp = np.square(m.sin(lat))
tmp = 1 - WGS84_E1 * tmp
sqrttmp = np.sqrt(tmp)
radm = WGS84_RA * (1 - WGS84_E1) / (sqrttmp * tmp)
radn = WGS84_RA / sqrttmp
return radm, radn
# 地理坐标系增量转成n系下坐标增量
# 参数: rm, rn 子午圈半径和卯酉圈半径; pos当前位置地理位置[rad, rad, m], drad(地理坐标系相对增量)[rad, rad, m]
# @param: return: dm, n系下增量
def drad2dm(rm, rn, pos, drad):
dm = np.zeros([3, 1])
dm[0] = drad[0] * (rm + pos[2])
dm[1] = drad[1] * (rn + pos[2]) * m.cos(pos[0])
dm[2] = -drad[2]
return dm
def plotNavresult(navresult_filepath):
navresult = np.loadtxt(navresult_filepath)
# 小范围内将位置转到第一个位置确定的n系
pos = np.zeros([len(navresult), 4])
navresult[:, 2:4] = navresult[:, 2:4] * D2R
pos[:, 0] = navresult[:, 1]
blh_station = navresult[0, 2:5]
rm, rn = radiusmn(blh_station[0])
for i in range(len(pos)):
delta_blh = navresult[i, 2:5] - navresult[0, 2:5]
pos[i, 1:4] = drad2dm(rm, rn, blh_station, delta_blh).reshape(1, 3)
print('plotting estimated navigation result!')
# 绘图
plt.figure('horizontal position')
plt.plot(pos[:, 2], pos[:, 1])
plt.axis('equal')
plt.xlabel('East [m]')
plt.ylabel('North [m]')
plt.title('Horizontal Position')
plt.grid()
plt.tight_layout()
plt.figure('height')
plt.plot(navresult[:, 1], navresult[:, 4])
plt.xlabel('Time [s]')
plt.ylabel('Height [m]')
plt.title('Height')
plt.grid()
plt.tight_layout()
plt.figure()
plt.plot(navresult[:, 1], navresult[:, 5:8])
plt.legend(['North', 'East', 'Down'])
plt.xlabel('Time [s]')
plt.ylabel('Velocity [m/s]')
plt.title('Velocity')
plt.grid()
plt.tight_layout()
plt.figure()
plt.plot(navresult[:, 1], navresult[:, 8:11])
plt.legend(['Roll', 'Pitch', 'Yaw'])
plt.xlabel('Time [s]')
plt.ylabel('Angle [deg]')
plt.title('Attitude')
plt.grid()
plt.tight_layout()
plt.show()
def plotIMUerror(imuerr_filepath):
imuerr = np.loadtxt(imuerr_filepath)
print('plotting estimated IMU error!')
plt.figure('gyro bias')
plt.plot(imuerr[:, 0], imuerr[:, 1:4])
plt.legend(['X', 'Y', 'Z'])
plt.xlabel('Time [s]')
plt.ylabel('Bias [deg/h]')
plt.title('Gyroscope Bias')
plt.grid()
plt.tight_layout()
plt.figure('accel bias')
plt.plot(imuerr[:, 0], imuerr[:, 4:7])
plt.legend(['X', 'Y', 'Z'])
plt.xlabel('Time [s]')
plt.ylabel('Bias [mGal]')
plt.title('Accelerometer Bias')
plt.grid()
plt.tight_layout()
plt.figure('gyro scale')
plt.plot(imuerr[:, 0], imuerr[:, 7:10])
plt.legend(['X', 'Y', 'Z'])
plt.xlabel('Time [s]')
plt.ylabel('Scale [ppm]')
plt.title('Gyroscope Scale')
plt.grid()
plt.tight_layout()
plt.figure('accel scale')
plt.plot(imuerr[:, 0], imuerr[:, 10:13])
plt.legend(['X', 'Y', 'Z'])
plt.xlabel('Time [s]')
plt.ylabel('Scale [ppm]')
plt.title('Accelerometer Scale')
plt.grid()
plt.tight_layout()
plt.show()
def plotNavError(navresult_filepath, refresult_filepath):
naverror = calcNavresultError(navresult_filepath, refresult_filepath)
print('calculate mavigtion result error finished!')
print('plotting navigation error!')
# 绘制误差曲线
plt.figure('position error')
plt.plot(naverror[:, 1], naverror[:, 2:5])
plt.legend(['North', 'East', 'Down'])
plt.xlabel('Time [s]')
plt.ylabel('Error [m]')
plt.title('Position Error')
plt.grid()
plt.tight_layout()
plt.figure('velocity error')
plt.plot(naverror[:, 1], naverror[:, 5:8])
plt.legend(['North', 'East', 'Down'])
plt.xlabel('Time [s]')
plt.ylabel('Error [m/s]')
plt.title('Velocity Error')
plt.grid()
plt.tight_layout()
plt.figure('attitude error')
plt.plot(naverror[:, 1], naverror[:, 8:11])
plt.legend(['Roll', 'Pitch', 'Yaw'])
plt.xlabel('Time [s]')
plt.ylabel('Error [deg]')
plt.title('Attitude Error')
plt.grid()
plt.tight_layout()
plt.show()
def plotSTD(std_filepath):
std = np.loadtxt(std_filepath)
print('plotting estimated STD!')
plt.figure('position std')
plt.plot(std[:, 0], std[:, 1:4])
plt.legend(['North', 'East', 'Down'])
plt.xlabel('Time [s]')
plt.ylabel('STD [m]')
plt.title('Position STD')
plt.grid()
plt.tight_layout()
plt.figure('velocity std')
plt.plot(std[:, 0], std[:, 4:7])
plt.legend(['North', 'East', 'Down'])
plt.xlabel('Time [s]')
plt.ylabel('STD [m/s]')
plt.title('Velocity STD')
plt.grid()
plt.tight_layout()
plt.figure('attitude std')
plt.plot(std[:, 0], std[:, 7:10])
plt.legend(['Roll', 'Pitch', 'Yaw'])
plt.xlabel('Time [s]')
plt.ylabel('STD [deg]')
plt.title('Attitude STD')
plt.grid()
plt.tight_layout()
plt.figure('gyrobias std')
plt.plot(std[:, 0], std[:, 10:13])
plt.legend(['X', 'Y', 'Z'])
plt.xlabel('Time [s]')
plt.ylabel('STD [deg/h]')
plt.title('Gyroscope Bias STD')
plt.grid()
plt.tight_layout()
plt.figure('accelbias std')
plt.plot(std[:, 0], std[:, 13:16])
plt.legend(['X', 'Y', 'Z'])
plt.xlabel('Time [s]')
plt.ylabel('STD [mGal]')
plt.title('Accelerometer Bias STD')
plt.grid()
plt.tight_layout()
plt.figure('gyroscale std')
plt.plot(std[:, 0], std[:, 16:19])
plt.legend(['X', 'Y', 'Z'])
plt.xlabel('Time [s]')
plt.ylabel('STD [ppm]')
plt.title('Gyroscope Scale STD')
plt.grid()
plt.tight_layout()
plt.figure('accelscale std')
plt.plot(std[:, 0], std[:, 19:22])
plt.legend(['X', 'Y', 'Z'])
plt.xlabel('Time [s]')
plt.ylabel('STD [ppm]')
plt.title('Accelerometer Scale STD')
plt.grid()
plt.tight_layout()
plt.show()
def calcNavresultError(navresult_filepath, refresult_filepath):
navresult = np.loadtxt(navresult_filepath)
refresult = np.loadtxt(refresult_filepath)
# 航向角平滑
for i in range(1, len(navresult)):
if navresult[i, 10] - navresult[i - 1, 10] < -180:
navresult[i:, 10] = navresult[i:, 10] + 360
if navresult[i, 10] - navresult[i - 1, 10] > 180:
navresult[i:, 10] = navresult[i:, 10] - 360
for i in range(1, len(refresult)):
if refresult[i, 10] - refresult[i - 1, 10] < -180:
refresult[i:, 10] = refresult[i:, 10] + 360
if refresult[i, 10] - refresult[i - 1, 10] > 180:
refresult[i:, 10] = refresult[i:, 10] - 360
# 找到数据重合部分,参考结果内插到测试结果
start_time = refresult[0, 1] if refresult[0, 1] >= navresult [0, 1] else navresult [0, 1]
end_time = refresult[-1, 1] if refresult[-1, 1] <= navresult [-1, 1] else navresult [-1, 1]
start_index = np.argwhere(navresult[:, 1] >= start_time)[0, 0]
end_index = np.argwhere(navresult[:, 1] <= end_time)[-1, 0]
navresult = navresult[start_index:end_index, :]
navresult[:, 2:4] = navresult[:, 2:4] * D2R
refresult[:, 2:4] = refresult[:, 2:4] * D2R
refinter = np.zeros_like(navresult)
refinter[:, 1] = navresult[:, 1]
for col in range(2, 11):
refinter[:, col] = np.interp(navresult[:, 1], refresult[:, 1], refresult[:, col])
# 计算误差
naverror = np.zeros_like(navresult)
naverror[:, 1] = navresult[:, 1]
naverror[:, 2:11] = navresult[:, 2:11] - refinter[:, 2:11]
# 航向角误差处理
for i in range(len(naverror)):
if naverror[i, 10] > 180:
naverror[i, 10] -= 360
if naverror[i, 10] < -180:
naverror[i, 10] += 360
# 位置误差转到第一个位置确定的n系
blh_station = navresult[0, 2:5]
rm, rn = radiusmn(blh_station[0])
for i in range(len(naverror)):
naverror[i, 2:5] = drad2dm(rm, rn, blh_station, naverror[i, 2:5]).reshape(1, 3)
return naverror
if __name__ == '__main__':
# 导航结果和导航误差
navresult_filepath = '../dataset/KF_GINS_Navresult.nav'
refresult_filepath = '../dataset/truth.nav'
# 导航结果
plotNavresult(navresult_filepath)
# 计算并绘制导航误差
# plotNavError(navresult_filepath, refresult_filepath)
# 估计的IMU误差
imuerr_filepath = '../dataset/KF_GINS_IMU_ERR.txt'
# plotIMUerror(imuerr_filepath)
# 估计的导航状态标准差和IMU误差标准差
std_filepath = '../dataset/KF_GINS_STD.txt'
# plotSTD(std_filepath)