2 Command line tool to for IMU delay Test
5 import matplotlib.pyplot
as plt
6 from scipy.interpolate
import interp1d
7 from statsmodels.graphics.tsaplots
import plot_acf
10 from argparse
import RawTextHelpFormatter
15 binning of azimuth angles in 1, 2 or 3 lidar segments with decay time ca. 10 milliseconds
17 timestamp_azimuth_pairs = np.zeros([0,2])
19 for src_row
in range(len(timestamp_way_offset)):
20 timestamp = timestamp_way_offset[src_row, 0]
21 azimuth = timestamp_way_offset[src_row, 1]
22 if timestamp - last_timestamp > decay_microsec:
23 timestamp_azimuth_pairs = np.vstack((timestamp_azimuth_pairs,np.array(([timestamp, azimuth]))))
24 last_timestamp = timestamp
26 dst_row = len(timestamp_azimuth_pairs) - 1
27 timestamp_azimuth_pairs[dst_row, 1] = timestamp_azimuth_pairs[dst_row, 1] + azimuth
28 return timestamp_azimuth_pairs
32 remove azimuth angles less than e.g. 16 degree (other segments or outliers)
34 timestamp_azimuth_pairs = np.zeros([0,2])
35 for row
in range(len(timestamp_way_offset)):
36 timestamp = timestamp_way_offset[row, 0]
37 azimuth = timestamp_way_offset[row, 1]
38 if azimuth > min_azimuth:
39 timestamp_azimuth_pairs = np.vstack((timestamp_azimuth_pairs,np.array(([timestamp, azimuth]))))
40 return timestamp_azimuth_pairs
44 calculates the gradients of azimuth angles
46 timestamp_azi_gradient = np.zeros([0,2])
47 for row
in range(1, len(timestamp_way_offset)):
48 time1 = timestamp_way_offset[row - 1, 0]
49 azi1 = timestamp_way_offset[row - 1, 1]
50 time2 = timestamp_way_offset[row, 0]
51 azi2 = timestamp_way_offset[row, 1]
52 timestamp = 0.5 * (time1 + time2)
53 gradient = (azi2 - azi1) / (time2 - time1)
54 timestamp_azi_gradient = np.vstack((timestamp_azi_gradient,np.array(([timestamp, gradient]))))
55 return timestamp_azi_gradient
59 returns the array of (timestamp, value) of all local minima
61 timestamp_minima = np.zeros([0,2])
62 for row
in range(1, len(timestamp_way_offset) - 1):
63 timestamp = timestamp_way_offset[row, 0]
64 value = timestamp_way_offset[row, 1]
65 if value < timestamp_way_offset[row - 1, 1]
and value < timestamp_way_offset[row + 1, 1]:
66 timestamp_minima = np.vstack((timestamp_minima,np.array(([timestamp, value]))))
67 return timestamp_minima
71 returns the array of (timestamp, value) of all local maxim
73 timestamp_minima = np.zeros([0,2])
74 for row
in range(1, len(timestamp_way_offset) - 1):
75 timestamp = timestamp_way_offset[row, 0]
76 value = timestamp_way_offset[row, 1]
77 if value > timestamp_way_offset[row - 1, 1]
and value > timestamp_way_offset[row + 1, 1]:
78 timestamp_minima = np.vstack((timestamp_minima,np.array(([timestamp, value]))))
79 return timestamp_minima
82 best_lidar_timestamp = timestamp_velocity[0, 0]
83 best_dt = abs(timestamp_velocity[0, 0] - imu_timestamp)
84 for row
in range(1, len(timestamp_velocity)):
85 lidar_timestamp = timestamp_velocity[row, 0]
86 if abs(lidar_timestamp - imu_timestamp) < best_dt:
87 best_lidar_timestamp = lidar_timestamp
88 best_dt = abs(lidar_timestamp - imu_timestamp)
89 return best_lidar_timestamp, best_dt
93 Idea taken from https://mathformeremortals.wordpress.com/2013/01/12/a-numerical-second-derivative-from-three-points/
95 num_pairs = len(xaxis)
96 y_2nd_derivate = np.zeros(num_pairs)
98 for idx
in range(1,num_pairs-1):
99 y_part = yaxis[idx-1:idx+2]
100 x_part = xaxis[idx-1:idx+2]
106 x_diff = np.array([2.0/((x2-x1)*(x3-x1)), -2.0/((x3 - x2)*(x2 - x1)), 2.0/((x3 - x2)*(x3 - x1))])
107 y_2nd_derivate[idx] = np.dot(x_diff, y_part)
109 return y_2nd_derivate
116 parser = argparse.ArgumentParser(
117 prog=
'IMU Delay Tester',
118 formatter_class=RawTextHelpFormatter,
119 description=
"Calculates delay between LIDAR and IMU\n"
122 csv_filename =
'../test/20231024_multiscan_timestamp_azimuth_imuacceleration.csv'
123 parser.add_argument(
'--csv_filename', help=
'CSV data file with timestamp', default=csv_filename, type=str)
124 args = parser.parse_args()
126 csv_filename = args.csv_filename
128 with open(csv_filename)
as file:
129 lines = [line.rstrip()
for line
in file]
131 timestamp_way_offset = np.zeros([0,2])
132 timestamp_imu_z = np.zeros([0,2])
133 timestamp_start = -1.0
135 line = line.replace(
',',
'.')
136 token_list = line.split(
";")
137 if len(token_list) == 3:
138 for idx, token
in enumerate(token_list):
142 timestamp = float(token)
144 if timestamp_start < 0:
145 timestamp_start = timestamp
146 timestamp = 0.001 * (timestamp - timestamp_start)
148 way_offset = float(token)
149 timestamp_way_offset = np.vstack((timestamp_way_offset,np.array(([timestamp, way_offset]))))
151 imu_value = float(token)
152 timestamp_imu_z = np.vstack((timestamp_imu_z,np.array(([timestamp, imu_value]))))
161 xaxis_azi_org = np.array(timestamp_way_offset[:, 0])
163 yaxis_azi_org = np.array(timestamp_way_offset[:, 1])
165 xaxis_imu_org = np.array(timestamp_imu_z[:,0])
166 yaxis_imu_org = np.array(timestamp_imu_z[:,1])
169 xaxis_azi_grad = np.array(timestamp_azi_gradient[:,0])
170 yaxis_azi_grad = -np.array(timestamp_azi_gradient[:,1])
172 compute_derivates =
False
173 if compute_derivates:
180 timestamp_min_imu_accel_sorted = timestamp_min_imu_accel[timestamp_min_imu_accel[:, 1].argsort()]
181 timestamp_min_imu_accel = timestamp_min_imu_accel_sorted[0:8,:]
182 timestamp_min_imu_accel = timestamp_min_imu_accel[timestamp_min_imu_accel[:, 0].argsort()]
183 xaxis_min_imu_accel = np.array(timestamp_min_imu_accel[:,0])
184 yaxis_min_imu_accel = np.array(timestamp_min_imu_accel[:,1])
185 xaxis_max_velocity = np.array(timestamp_max_velocity[:,0])
186 yaxis_max_velocity = np.array(timestamp_max_velocity[:,1])
189 min_imu_latency_sec = 1.0e6
190 for row
in range(len(timestamp_min_imu_accel)):
191 imu_timestamp = timestamp_min_imu_accel[row, 0]
193 imu_latency_sec = dt * 1.0e-6
194 min_imu_latency_sec = min(min_imu_latency_sec, imu_latency_sec)
195 print(f
"imu latency: {imu_latency_sec:.6} sec")
197 print(f
"\nimu_delay_tester ({csv_filename}): min imu latency = {min_imu_latency_sec:.6} sec")
205 fig, (ax1, ax2, ax3) = plt.subplots(3)
208 ax1.set_title(
'azimuth over time')
209 ax1.scatter(xaxis_azi_org, yaxis_azi_org)
210 ax1.plot(xaxis_azi_org, yaxis_azi_org)
212 ax2.set_title(
'imu acceleration over time')
213 ax2.scatter(xaxis_imu_org, yaxis_imu_org)
214 ax2.plot(xaxis_imu_org, yaxis_imu_org)
216 ax3.set_title(
'azimuth gradient over time')
217 ax3.scatter(xaxis_azi_grad, yaxis_azi_grad)
218 ax3.plot(xaxis_azi_grad, yaxis_azi_grad)
220 fig.set_figheight(10)
223 plt.savefig(fname=csv_filename[:-4]+
'.png')