Skip to content

Commit 77eb752

Browse files
committed
bricks/primehub/modules: Add calibration routine.
This works on Prime Hub, Technic Hub, and Essential Hub, but the instructions are still specific to Prime Hub.
1 parent 53b3c20 commit 77eb752

File tree

1 file changed

+149
-1
lines changed

1 file changed

+149
-1
lines changed
Lines changed: 149 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,149 @@
1-
print("Calibrating!")
1+
from pybricks.hubs import ThisHub
2+
from pybricks.parameters import Side, Axis
3+
from pybricks.tools import wait, vector
4+
5+
6+
hub = ThisHub()
7+
8+
9+
def beep(freq):
10+
try:
11+
hub.speaker.beep(freq, 100)
12+
except AttributeError:
13+
# Technic hub does not have a speaker.
14+
pass
15+
wait(10)
16+
17+
18+
def wait_for_stationary(side):
19+
while not hub.imu.stationary() or hub.imu.up() != side:
20+
wait(10)
21+
22+
23+
up_sides = {
24+
Side.FRONT: (0, 0),
25+
Side.BACK: (1, 0),
26+
Side.LEFT: (2, 1),
27+
Side.RIGHT: (3, 1),
28+
Side.TOP: (4, 2),
29+
Side.BOTTOM: (5, 2),
30+
}
31+
32+
gravity = [0] * 6
33+
bias = vector(0, 0, 0)
34+
35+
STATIONARY_COUNT = 1000
36+
37+
38+
def roll_over_axis(axis, new_side):
39+
40+
global bias, bias_count
41+
42+
print("Roll it towards you, without lifting the hub up!")
43+
44+
angle_start = hub.imu.rotation(axis, calibrated=False)
45+
while hub.imu.up() != new_side or not hub.imu.stationary():
46+
47+
_, _, z = hub.imu.orientation() * axis
48+
if abs(z) > 0.07:
49+
print(hub.imu.orientation() * axis)
50+
raise RuntimeError("Lifted it!")
51+
wait(100)
52+
53+
uncalibrated_90_deg_rotation = abs(hub.imu.rotation(axis, calibrated=False) - angle_start)
54+
if abs(uncalibrated_90_deg_rotation - 90) > 10:
55+
raise RuntimeError("Not 90 deg!")
56+
57+
print("Calibrating...")
58+
beep(1000)
59+
60+
rotation_start = vector(
61+
hub.imu.rotation(Axis.X, calibrated=False),
62+
hub.imu.rotation(Axis.Y, calibrated=False),
63+
hub.imu.rotation(Axis.Z, calibrated=False),
64+
)
65+
66+
acceleration = vector(0, 0, 0)
67+
68+
for i in range(STATIONARY_COUNT):
69+
acceleration += hub.imu.acceleration(calibrated=False)
70+
bias += hub.imu.angular_velocity(calibrated=False)
71+
wait(1)
72+
73+
acceleration /= STATIONARY_COUNT
74+
75+
rotation_end = vector(
76+
hub.imu.rotation(Axis.X, calibrated=False),
77+
hub.imu.rotation(Axis.Y, calibrated=False),
78+
hub.imu.rotation(Axis.Z, calibrated=False),
79+
)
80+
if abs(rotation_end - rotation_start) > 1:
81+
raise RuntimeError("Moved it!")
82+
83+
side_index, axis_index = up_sides[new_side]
84+
85+
# Store the gravity value for the current side being up.
86+
# We will visit each side several times. We'll divide by the number
87+
# of visits later.
88+
gravity[side_index] += acceleration[axis_index]
89+
90+
beep(500)
91+
92+
return uncalibrated_90_deg_rotation
93+
94+
95+
calibrate_x = """
96+
Going to calibrate X now!
97+
- Put the hub on the table in front of you.
98+
- top side (display) facing up
99+
- right side (ports BDF) towards you.
100+
"""
101+
102+
calibrate_y = """
103+
Going to calibrate Y now
104+
- Put the hub on the table in front of you.
105+
- top side (display) facing up
106+
- back side (speaker) towards you.
107+
"""
108+
109+
calibrate_z = """
110+
Going to calibrate Z now!
111+
- Put the hub on the table in front of you.
112+
- front side (USB port) facing up
113+
- left side (ports ACE) towards you
114+
"""
115+
116+
REPEAT = 2
117+
118+
# For each 3-axis run, we will visit each side twice.
119+
SIDE_COUNT = REPEAT * 2
120+
121+
122+
def roll_hub(axis, message, start_side, sides):
123+
print(message)
124+
wait_for_stationary(start_side)
125+
beep()
126+
rotation = 0
127+
for _ in range(REPEAT):
128+
for side in sides:
129+
rotation += roll_over_axis(axis, side)
130+
return rotation / REPEAT
131+
132+
133+
rotation_x = roll_hub(
134+
Axis.X, calibrate_x, Side.TOP, [Side.LEFT, Side.BOTTOM, Side.RIGHT, Side.TOP]
135+
)
136+
rotation_y = roll_hub(
137+
Axis.Y, calibrate_y, Side.TOP, [Side.FRONT, Side.BOTTOM, Side.BACK, Side.TOP]
138+
)
139+
rotation_z = roll_hub(
140+
Axis.Z, calibrate_z, Side.FRONT, [Side.RIGHT, Side.BACK, Side.LEFT, Side.FRONT]
141+
)
142+
143+
hub.imu.settings(
144+
angular_velocity_bias=tuple(bias / SIDE_COUNT / STATIONARY_COUNT / 6),
145+
angular_velocity_scale=(rotation_x, rotation_y, rotation_z),
146+
acceleration_correction=[g / SIDE_COUNT for g in gravity],
147+
)
148+
149+
print("Result: ", hub.imu.settings())

0 commit comments

Comments
 (0)