forked from s2mLab/ControlOdrive
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathresisting_current_calibration_load.py
126 lines (101 loc) · 3.82 KB
/
resisting_current_calibration_load.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
"""
This script is used to sample the current corresponding to the resisting torque of the motor at different velocities.
60 psi
"""
import json
import matplotlib.pyplot as plt
import numpy as np
import time
from scipy.optimize import curve_fit
from ergocycleS2M.motor_control.enums import DirectionMode
from ergocycleS2M.motor_control.motor_controller import MotorController
# Initialisation
motor = MotorController()
motor.set_direction(DirectionMode.REVERSE)
def calibration(instruction, nb_turns=5):
"""
This function is used to sample the current corresponding to the resisting torque of the motor at different
cadences.
Parameters
----------
instruction
The cadence instruction in rpm.
nb_turns
The number of turns to sample the data at the desired cadence.
"""
if instruction > 0:
motor.set_direction(DirectionMode.FORWARD)
else:
motor.set_direction(DirectionMode.REVERSE)
motor.cadence_control(instruction)
print(f"Waiting to stabilize at {instruction} rpm...")
# Wait for to reach the instruction
while not (instruction - 1 < motor.get_cadence() < instruction + 1):
pass
t0 = time.time()
t1 = time.time()
# Wait for 1 second to stabilize at the instructed velocity (can't be done with a time.sleep() because of the
# watchdog thread)
while t1 - t0 < 3.0:
t1 = time.time()
print(f"Stabilized at {instruction} rpm.")
t0 = time.time()
t1 = time.time()
# Save the data as frequently as possible during nb_turns
iq_measured = []
vel_estimate = []
while t1 - t0 < nb_turns / (abs(instruction) / 60):
t1 = time.time()
iq_measured.append(motor.axis.motor.current_control.Iq_measured)
vel_estimate.append(motor.axis.encoder.vel_estimate)
print(np.mean(iq_measured), "*/-", np.std(iq_measured), "A")
print(np.mean(vel_estimate), "*/-", np.std(vel_estimate), "tr/s")
return np.mean(iq_measured), np.std(iq_measured), np.mean(vel_estimate), np.std(vel_estimate)
if __name__ == "__main__":
intensities = []
velocities = []
intensities_std = []
velocities_std = []
for ins in range(5, 61, 5):
average_iq_measured, i_std, average_vel_estimate, v_std = calibration(ins)
intensities.append(average_iq_measured)
velocities.append(average_vel_estimate)
intensities_std.append(i_std)
velocities_std.append(v_std)
def lost_current(vel_estimate, resisting_current_proportional, resisting_current_constant):
"""
The current corresponding to the resisting torque of the motor is modeled as a linear function of the velocity.
Parameters
----------
vel_estimate:
The velocity of the motor.
resisting_current_proportional:
The proportional coefficient.
resisting_current_constant:
The constant coefficient.
Returns
-------
"""
return np.sign(vel_estimate) * (
resisting_current_proportional * np.abs(vel_estimate) + resisting_current_constant
)
popt = curve_fit(lost_current, np.asarray(velocities), np.asarray(intensities), p0=[0.01, 0.5])
motor.stop()
plt.plot(velocities, intensities)
plt.plot(velocities, lost_current(velocities, *popt[0]))
plt.xlabel("Motor velocity (tr/s)")
plt.ylabel("Resisting current (A)")
plt.show()
data = {
"velocities": velocities,
"intensities": intensities,
"velocities_std": velocities_std,
"intensities": intensities_std,
"a" : -popt[0][0],
"b" : -popt[0][1]
}
print(data["a"], data["b"])
# Writing to .json
json_object = json.dumps(data, indent=4)
with open("./calibration_files/resisting_current_load_h3_b10.json", "w") as outfile:
outfile.write(json_object)