Olaphsen

Untitled

Apr 21st, 2023 (edited)
321
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.18 KB | Source Code | 0 0
  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3. from scipy.spatial.transform import Rotation
  4.  
  5. from datetime import datetime
  6. start_time = datetime.now()
  7.  
  8. beta = 0 * np.sqrt(3. / 4.) * np.radians(3 / 3600)
  9.  
  10. # errors
  11. nu_1 = np.radians(0 * 1 / 3600)
  12. nu_2 = np.radians(0 * 1 / 3600)
  13. nu_3 = np.radians(0 * 1 / 3600)
  14. df1 = 0 * 1e-2
  15. df2 = 0 * 1e-2
  16. df3 = 0 * 1e-2
  17. nu = np.array([nu_1, nu_2, nu_3])
  18. df = np.array([df1, df2, df3])
  19.  
  20. # ang Earth velocity
  21. phi = np.radians(55.8)
  22. u_0 = 7.292115e-5
  23. uE, uN, uU = 0, np.cos(phi) * u_0, np.sin(phi) * u_0
  24.  
  25. deltat = 0.004
  26. directory = '/home/andrei/CLionProjects/imitators/cmake-build-release/tt3axis.imu'
  27.  
  28. # quaternion product
  29. def quat_mult(a, b):
  30.     q0 = a[0]*b[0] - a[1]*b[1] - a[2]*b[2] - a[3]*b[3]
  31.     q1 = a[0]*b[1] + b[0]*a[1] + a[2]*b[3] - a[3]*b[2]
  32.     q2 = a[0]*b[2] + b[0]*a[2] + a[3]*b[1] - a[1]*b[3]
  33.     q3 = a[0]*b[3] + b[0]*a[3] + a[1]*b[2] - a[2]*b[1]
  34.     return np.array([q0, q1, q2, q3])
  35.  
  36.  
  37. # inverse quaternion
  38. def inverse_quat(q):
  39.     q_inv = np.array(q, dtype=np.float64)
  40.     q_inv[1:] *= -1
  41.     return q_inv
  42.  
  43.  
  44. def deltaq(q1, q0):
  45.     q0_inv = inverse_quat(q0)
  46.     return quat_mult(q1, q0_inv)
  47.  
  48.  
  49. # data from file
  50. def get_all_data(path):
  51.     data_1 = np.loadtxt(path, skiprows=1)
  52.     w, f, q = np.transpose(data_1[:, :3]), np.transpose(data_1[:, 3:6]), data_1[:, 6:]
  53.     return w[0], w[1], w[2], f[0], f[1], f[2], q[:, 0], q[:, 1], q[:, 2], q[:, 3]
  54.  
  55.  
  56. data_file = get_all_data(directory)
  57. w_init = np.radians(data_file[:3]).T
  58. f_init = (data_file[3:6] + df[:, None]).T
  59. w = np.radians(data_file[:3]) + nu[:, None]
  60. f = data_file[3:6] + df[:, None]
  61.  
  62. w1, w2, w3 = w[0], w[1], w[2]
  63. f1, f2, f3 = f[0], f[1], f[2]
  64. q0_data, q1_data, q2_data, q3_data = data_file[6:]
  65.  
  66.  
  67. # initial alignment to find q(0)
  68. def initial_alignment(f_init, w_init, n_samples=30*250):
  69.     f_z = np.mean(f_init[:n_samples], axis=0)
  70.     w_z = np.mean(w_init[:n_samples], axis=0)
  71.     L_xz = np.array([np.cross(w_z, f_z) / np.linalg.norm(np.cross(w_z, f_z)),
  72.                      np.cross(f_z, np.cross(w_z, f_z)) / np.linalg.norm(np.cross(f_z, np.cross(w_z, f_z))),
  73.                      f_z / np.linalg.norm(f_z)])
  74.  
  75.     r = Rotation.from_matrix(L_xz)
  76.     r_ = r.as_quat()[[3, 0, 1, 2]]
  77.     return L_xz, r_
  78.  
  79.  
  80. L_xz, r_ = initial_alignment(f_init, w_init)
  81.  
  82. # initial conditions
  83. qmy_0, qmy_1, qmy_2, qmy_3 = r_
  84. vmy_0, vmy_1, vmy_2 = 0, 0, 0
  85. xmy_0, xmy_1, xmy_2 = 0, 0, 0
  86.  
  87.  
  88. def g0_find():
  89.     g0_ = np.sqrt(np.mean(f_init[:30*250], axis=0)[0] ** 2 +
  90.                   np.mean(f_init[:30*250], axis=0)[1] ** 2 +
  91.                   np.mean(f_init[:30*250], axis=0)[2] ** 2)
  92.     return g0_
  93.  
  94.  
  95. g0 = g0_find()
  96.  
  97.  
  98. def rotation_imu():
  99.     new = [v_my(w1[m], w2[m], w3[m], f1[m], f2[m], f3[m])[2] for m in range(len(data_file[0]))]
  100.     q = [[float(new[m][i]) for i in range(4)] for m in range(len(data_file[0]))]
  101.     q0, q1, q2, q3 = zip(*q)
  102.     return q0, q1, q2, q3
  103.  
  104.  
  105. def x_imu():
  106.     new = [v_my(w1[m], w2[m], w3[m], f1[m], f2[m], f3[m])[0] for m in range(len(data_file[0]))]
  107.     x = [[float(new[m][i]) for i in range(3)] for m in range(len(data_file[0]))]
  108.     x0, x1, x2 = zip(*x)
  109.     return x0, x1, x2
  110.  
  111.  
  112. def v_imu():
  113.     new = [v_my(w1[m], w2[m], w3[m], f1[m], f2[m], f3[m])[1] for m in range(len(data_file[0]))]
  114.     v = [[float(new[m][i]) for i in range(3)] for m in range(len(data_file[0]))]
  115.     v0, v1, v2 = zip(*v)
  116.     return v0, v1, v2
  117.  
  118.  
  119. def v_my(w_x, w_y, w_z, a_x, a_y, a_z):
  120.     global xmy_0, xmy_1, xmy_2
  121.     global vmy_0, vmy_1, vmy_2
  122.     global qmy_0, qmy_1, qmy_2, qmy_3
  123.  
  124.     a = np.array([a_x, a_y, a_z])
  125.     norm = np.linalg.norm(a)
  126.     a /= norm
  127.  
  128.     dp0, dp1, dp2, dp3 = quat_mult([qmy_0 / 2, qmy_1 / 2, qmy_2 / 2, qmy_3 / 2], [0, w_x, w_y, w_z])
  129.     p = qmy_0 + dp0 * deltat / 2, qmy_1 + dp1 * deltat / 2, qmy_2 + dp2 * deltat / 2, qmy_3 + dp3 * deltat / 2,
  130.  
  131.     u = np.cross([a_x, a_y, a_z], quat_mult(quat_mult(inverse_quat(p), [0, 0, 0, g0]), p)[1:])
  132.     norm_u = np.linalg.norm(u)
  133.     if norm_u > 0:
  134.         u_1, u_2, u_3 = (-2 * beta * u[:3]) / norm_u
  135.     else:
  136.         u_0, u_1, u_2, u_3 = 0, 0, 0, 0
  137.     qq_omega_0, qq_omega_1, qq_omega_2, qq_omega_3 = quat_mult([0.5 * qmy_0, 0.5 * qmy_1, 0.5 * qmy_2, 0.5 * qmy_3],
  138.                                                                [0, w_x - u_1, w_y - u_2, w_z - u_3])
  139.  
  140.     qmy_0 += qq_omega_0 * deltat
  141.     qmy_1 += qq_omega_1 * deltat
  142.     qmy_2 += qq_omega_2 * deltat
  143.     qmy_3 += qq_omega_3 * deltat
  144.  
  145.     norm = np.linalg.norm([qmy_0, qmy_1, qmy_2, qmy_3])
  146.     qmy_0 /= norm
  147.     qmy_1 /= norm
  148.     qmy_2 /= norm
  149.     qmy_3 /= norm
  150.     g_quat = [0, 0, 0, g0]
  151.     a_quat = [0, a_x, a_y, a_z]
  152.  
  153.     v_new = (quat_mult(quat_mult([qmy_0, qmy_1, qmy_2, qmy_3], a_quat), inverse_quat([qmy_0, qmy_1, qmy_2, qmy_3])) + g_quat)[1:]
  154.  
  155.     vmy_0 += v_new[0] * deltat
  156.     vmy_1 += v_new[1] * deltat
  157.     vmy_2 += v_new[2] * deltat
  158.  
  159.     xmy_0 += vmy_0 * deltat
  160.     xmy_1 += vmy_1 * deltat
  161.     xmy_2 += vmy_2 * deltat
  162.  
  163.     return [xmy_0, xmy_1, xmy_2], [vmy_0, vmy_1, vmy_2], [qmy_0, qmy_1, qmy_2, qmy_3]
  164.  
  165.  
  166. if __name__ == '__main__':
  167.     q0_my, q1_my, q2_my, q3_my = rotation_imu()
  168.     v0, v1, v2 = v_imu()
  169.     x0, x1, x2 = x_imu()
  170.  
  171.     T = np.arange(0, len(q0_data), 1) * deltat
  172.  
  173.     dq = np.array(deltaq([q0_my, q1_my, q2_my, q3_my], [q0_data, q1_data, q2_data, q3_data]))
  174.     dq[:, dq[0] < 0] *= -1
  175.     fig, (ax1, ax2, ax3) = plt.subplots(1, 3, layout='constrained')
  176.     fig.suptitle(fr'$\beta={round(beta * 3600 * (180 / np.pi), 1)},\ \Delta f_1={df1},\ \Delta f_2={df2},\ \Delta f_3={df3},\ \nu_1={nu_1 * 3600 * (180 / np.pi)},\ \nu_2={nu_2 * 3600 * (180 / np.pi)},\ \nu_3={nu_3 * 3600 * (180 / np.pi)}$', fontsize=14)
  177.  
  178.     ax3.plot(T, dq[1] * (180 / np.pi) * 2, "-", label=r'$\alpha_1$')
  179.     ax3.plot(T, dq[2] * (180 / np.pi) * 2, "-", label=r'$\alpha_2$')
  180.     ax3.plot(T, dq[3] * (180 / np.pi) * 2, "-", label=r'$\alpha_3$')
  181.  
  182.     ax2.plot(T, v0, "-", label=r'$v_1$')
  183.     ax2.plot(T, v1, "-", label=r'$v_2$')
  184.     ax2.plot(T, v2, "-", label=r'$v_3$')
  185.  
  186.     ax1.plot(T, x0, "-", label=r'$x_1$')
  187.     ax1.plot(T, x1, "-", label=r'$x_2$')
  188.     ax1.plot(T, x2, "-", label=r'$x_3$')
  189.  
  190.     plt.show()
  191.  
  192.  
  193. end_time = datetime.now()
  194. print('Duration: {}'.format(end_time - start_time))
  195.  
Advertisement
Add Comment
Please, Sign In to add comment