Formula Student Electronics & Software
The code for the embedded software
Loading...
Searching...
No Matches
calibv2.py
Go to the documentation of this file.
1import numpy as np
2import matplotlib.pyplot as plt
3from scipy import interpolate
4
5
6def import_new_raw_data(in_file, out_file):
7 with open(in_file) as data_file:
8 data = [line.strip().split(";") for line in data_file.readlines()]
9 data = [[int(line[0]), int(line[1]), float(line[2])] for line in data]
10 data.sort(key=lambda x: x[-1], reverse=True)
11 with open(out_file, "w") as output_file:
12 for index in range(len(data)):
13 if index >= 1 and ((data[index][0] > data[index - 1][0]) or (data[index][1] > data[index - 1][1])):
14 continue
15 output_file.write("\t".join(str(x) for x in data[index]) + "\n")
16 apps1_values = [line[0] for line in data]
17 apps2_values = [line[1] for line in data]
18 compression_values = [line[2] for line in data]
19 # adjust for measuing offset
20 compression_values = [val - min(compression_values) for val in compression_values]
21 return apps1_values, apps2_values, compression_values
22
23
24# define a 2d plot function that saves the plot to a png file and does not block the program
25def plot_2d_data_nonblocking(x_data, y_data, x_label, y_label, title):
26 plt.plot(x_data, y_data, "ro")
27 plt.xlabel(x_label)
28 plt.ylabel(y_label)
29 plt.title(title)
30 plt.savefig("data_files/" + title + ".png")
31 plt.clf()
32
33
34# create a function that takes in the raw sensor data and returns the interpolated data for each sensor
35def interpolate_data(apps1_vals, apps2_vals, compr_vals):
36 # create an interpolation function for each sensor
37 apps1_interp = interpolate.interp1d(compr_vals, apps1_vals, kind="linear", fill_value="extrapolate")
38 apps2_interp = interpolate.interp1d(compr_vals, apps2_vals, kind="linear", fill_value="extrapolate")
39 # create a new array of compression values to interpolate the data to
40 interpolation_step = 0.01
41 new_compr_vals = np.arange(0, max(compr_vals), interpolation_step)
42 # create a new array of interpolated data for each sensor
43 new_apps1_vals = apps1_interp(new_compr_vals)
44 new_apps2_vals = apps2_interp(new_compr_vals)
45 # correct interpolation results according to physical constraints
46 for index in range(len(new_apps1_vals)):
47 if new_apps1_vals[index] < 0:
48 new_apps1_vals[index] = 0
49 if new_apps1_vals[index] > 1023:
50 new_apps1_vals[index] = 1023
51
52 for index in range(len(new_apps2_vals)):
53 if new_apps2_vals[index] < 0:
54 new_apps2_vals[index] = 0
55 if new_apps2_vals[index] > 1023:
56 new_apps2_vals[index] = 1023
57 # return the interpolated data
58 return new_apps1_vals, new_apps2_vals, new_compr_vals
59
60
61def read_data_from_file(file_name):
62 with open("data_files/interpolation_data.txt", "r") as input_file:
63 apps1_vals = []
64 apps2_vals = []
65 compr_vals = []
66 for line in input_file:
67 line = line.strip().split("\t")
68 apps1_vals.append(float(line[0]))
69 apps2_vals.append(float(line[1]))
70 compr_vals.append(float(line[2]))
71 return apps1_vals, apps2_vals, compr_vals
72
73
74def process_interpolation_results(apps1_vals, apps2_vals):
75 # compress input arrays into a single array and round the values to the unit
76 sensor_data = [[round(apps1_vals[index]), round(apps2_vals[index])] for index in range(len(apps1_vals))]
77 sensor_data = sorted(list(set(tuple(x) for x in sensor_data)))
78 apps_1_deadzone_vals = [vals for vals in sensor_data if vals[0] >= 1022]
79 apps_2_deadzone_vals = [vals for vals in sensor_data if vals[1] <= 1]
80 apps_1_deadozone_interval = (
81 min([vals[1] for vals in apps_1_deadzone_vals]),
82 max([vals[1] for vals in apps_1_deadzone_vals]),
83 )
84 apps_2_deadozone_interval = (
85 min([vals[0] for vals in apps_2_deadzone_vals]),
86 max([vals[0] for vals in apps_2_deadzone_vals]),
87 )
88 # print(apps_linear_zone)
89 apps_linear_zone = [vals for vals in sensor_data if vals not in apps_1_deadzone_vals + apps_2_deadzone_vals]
90 apps_linear_offset = round(sum([vals[0] - vals[1] for vals in apps_linear_zone]) / len(apps_linear_zone))
91 max_error = round(max([vals[0] - (vals[1] + apps_linear_offset) for vals in apps_linear_zone]), ndigits=4)
92 max_error_percent = round(max_error / 1023 * 100, ndigits=4)
93 return apps_1_deadozone_interval, apps_2_deadozone_interval, apps_linear_offset, max_error, max_error_percent
94
95
96def import_and_process_new_data(in_filename, out_filename):
97 apps1_vals, apps2_vals, compr_vals = import_new_raw_data(in_filename, out_filename)
98 plot_2d_data_nonblocking(compr_vals, apps1_vals, "Sensor Compression (mm)", "APPS 1", "APPS 1 vs. Compression")
99 plot_2d_data_nonblocking(compr_vals, apps2_vals, "Sensor Compression (mm)", "APPS 2", "APPS 2 vs. Compression")
100 new_apps1_vals, new_apps2_vals, new_compr_vals = interpolate_data(apps1_vals, apps2_vals, compr_vals)
102 new_compr_vals, new_apps1_vals, "Sensor Compression (mm)", "APPS 1", "APPS 1 vs. Compression (Interpolated)"
103 )
105 new_compr_vals, new_apps2_vals, "Sensor Compression (mm)", "APPS 2", "APPS 2 vs. Compression (Interpolated)"
106 )
107 with open("data_files/interpolation_data.txt", "w") as output_file:
108 for index in range(len(new_compr_vals)):
109 output_file.write(
110 "\t".join(str(x) for x in [new_apps1_vals[index], new_apps2_vals[index], new_compr_vals[index]]) + "\n"
111 )
112
113
115 import_and_process_new_data("data_files/raw_data.txt", "data_files/new_data.txt")
116
117 apps1_vals, apps2_vals, compr_vals = read_data_from_file("data_files/interpolation_data.txt")
118 (
119 apps_1_deadozone_interval,
120 apps_2_deadozone_interval,
121 apps_linear_offset,
122 max_error,
123 max_error_percent,
124 ) = process_interpolation_results(apps1_vals, apps2_vals)
125
126 print("APPS 1 Deadzone Interval: " + str(apps_1_deadozone_interval))
127 print("APPS 2 Deadzone Interval: " + str(apps_2_deadozone_interval))
128 print("APPS Linear Offset: " + str(apps_linear_offset))
129 print("Max Error: " + str(max_error))
130 print("Max Error Percent: " + str(max_error_percent))
131
132
133if __name__ == "__main__":
134 __main__()
read_data_from_file(file_name)
Definition calibv2.py:61
interpolate_data(apps1_vals, apps2_vals, compr_vals)
Definition calibv2.py:35
process_interpolation_results(apps1_vals, apps2_vals)
Definition calibv2.py:74
import_new_raw_data(in_file, out_file)
Definition calibv2.py:6
plot_2d_data_nonblocking(x_data, y_data, x_label, y_label, title)
Definition calibv2.py:25
__main__()
Definition calibv2.py:114
import_and_process_new_data(in_filename, out_filename)
Definition calibv2.py:96