|
11 | 11 | from spatialmath import SO3, SE3
|
12 | 12 | import numpy as np
|
13 | 13 |
|
14 |
| - |
15 |
| -# TODO |
16 |
| -# rotate the rings according to the rotation axis, so that the axles |
17 |
| -# point the right way |
18 |
| - |
19 |
| -# Launch the simulator Swift |
20 |
| -env = swift.Swift() |
21 |
| -env.launch() |
22 |
| - |
23 | 14 | path = rtb.rtb_path_to_datafile("data")
|
24 | 15 |
|
| 16 | +# rotation angle sequence |
| 17 | +sequence = "ZYX" |
| 18 | + |
| 19 | +# compute the three rotation matrices |
| 20 | +BASE = SE3(0, 0, 0.5) |
| 21 | +R1 = SO3() |
| 22 | +R2 = SO3() |
| 23 | +R3 = SO3() |
25 | 24 |
|
26 | 25 | g1 = Mesh(
|
27 |
| - filename=str(path / "gimbal-ring1.stl"), color=[34, 143, 201], scale=(1.0 / 3,) * 3 |
| 26 | + filename=str(path / "gimbal-ring1.stl"), |
| 27 | + color=[34, 143, 201], |
| 28 | + scale=(1.0 / 3,) * 3, |
28 | 29 | )
|
29 | 30 |
|
30 | 31 | g2 = Mesh(
|
31 |
| - filename=str(path / "gimbal-ring2.stl"), color=[31, 184, 72], scale=(1.1 / 3,) * 3 |
| 32 | + filename=str(path / "gimbal-ring2.stl"), |
| 33 | + color=[31, 184, 72], |
| 34 | + scale=(1.1 / 3,) * 3, |
32 | 35 | )
|
33 | 36 |
|
34 | 37 | g3 = Mesh(
|
35 | 38 | filename=str(path / "gimbal-ring3.stl"),
|
36 | 39 | color=[240, 103, 103],
|
37 |
| - scale=(1.1**2 / 3,) * 3, |
| 40 | + scale=(1.1 ** 2 / 3,) * 3, |
38 | 41 | )
|
39 | 42 |
|
40 | 43 | plane = Mesh(
|
41 | 44 | filename=str(path / "spitfire_assy-gear_up.stl"),
|
42 | 45 | scale=(1.0 / (180 * 3),) * 3,
|
43 | 46 | color=[240, 103, 103],
|
44 | 47 | )
|
45 |
| -print(path / "spitfire_assy-gear_up.stl") |
46 |
| -env.add(g1) |
47 |
| -env.add(g2) |
48 |
| -env.add(g3) |
49 |
| -env.add(plane) |
50 |
| - |
51 |
| -print("Supermarine Spitfire Mk VIII by Ed Morley @GRABCAD") |
52 |
| -print("Gimbal models by Peter Corke using OpenSCAD") |
53 |
| - |
54 |
| -# compute the three rotation matrices |
55 |
| -BASE = SE3(0, 0, 0.5) |
56 |
| -R1 = SO3() |
57 |
| -R2 = SO3() |
58 |
| -R3 = SO3() |
59 |
| - |
60 |
| -# rotation angle sequence |
61 |
| -sequence = "ZYX" |
62 | 48 |
|
63 | 49 |
|
64 | 50 | def update_gimbals(theta, ring):
|
@@ -92,140 +78,159 @@ def convert(R):
|
92 | 78 | plane.T = convert(R1 * R2 * R3 * SO3.Ry(pi / 2) * SO3.Rz(pi / 2))
|
93 | 79 |
|
94 | 80 |
|
95 |
| -# slider call backs, invoke the central handler |
96 |
| -def set_one(x): |
97 |
| - update_gimbals(float(x), 1) |
98 |
| - |
99 |
| - |
100 |
| -def set_two(x): |
101 |
| - update_gimbals(float(x), 2) |
102 |
| - |
103 |
| - |
104 |
| -def set_three(x): |
105 |
| - update_gimbals(float(x), 3) |
| 81 | +def demo(): |
| 82 | + # TODO |
| 83 | + # rotate the rings according to the rotation axis, so that the axles |
| 84 | + # point the right way |
106 | 85 |
|
| 86 | + # Launch the simulator Swift |
| 87 | + env = swift.Swift() |
| 88 | + env.launch() |
107 | 89 |
|
108 |
| -r_one = swift.Slider( |
109 |
| - set_one, min=-180, max=180, step=1, value=0, desc="Outer gimbal", unit="°" |
110 |
| -) |
| 90 | + print(path / "spitfire_assy-gear_up.stl") |
| 91 | + env.add(g1) |
| 92 | + env.add(g2) |
| 93 | + env.add(g3) |
| 94 | + env.add(plane) |
111 | 95 |
|
| 96 | + print("Supermarine Spitfire Mk VIII by Ed Morley @GRABCAD") |
| 97 | + print("Gimbal models by Peter Corke using OpenSCAD") |
112 | 98 |
|
113 |
| -r_two = swift.Slider( |
114 |
| - set_two, min=-180, max=180, step=1, value=0, desc="Middle gimbal", unit="°" |
115 |
| -) |
| 99 | + # slider call backs, invoke the central handler |
| 100 | + def set_one(x): |
| 101 | + update_gimbals(float(x), 1) |
116 | 102 |
|
| 103 | + def set_two(x): |
| 104 | + update_gimbals(float(x), 2) |
117 | 105 |
|
118 |
| -r_three = swift.Slider( |
119 |
| - set_three, min=-180, max=180, step=1, value=0, desc="Inner gimbal", unit="°" |
120 |
| -) |
| 106 | + def set_three(x): |
| 107 | + update_gimbals(float(x), 3) |
121 | 108 |
|
| 109 | + r_one = swift.Slider( |
| 110 | + set_one, min=-180, max=180, step=1, value=0, desc="Outer gimbal", unit="°" |
| 111 | + ) |
122 | 112 |
|
123 |
| -# buttons to set a 3-angle sequence |
124 |
| -ZYX_button = swift.Button( |
125 |
| - lambda x: change_sequence("ZYX"), desc="ZYX (roll-pitch-yaw angles)" |
126 |
| -) |
| 113 | + r_two = swift.Slider( |
| 114 | + set_two, min=-180, max=180, step=1, value=0, desc="Middle gimbal", unit="°" |
| 115 | + ) |
127 | 116 |
|
128 |
| -XYZ_button = swift.Button( |
129 |
| - lambda x: change_sequence("XYZ"), desc="XYZ (roll-pitch-yaw angles)" |
130 |
| -) |
| 117 | + r_three = swift.Slider( |
| 118 | + set_three, |
| 119 | + min=-180, |
| 120 | + max=180, |
| 121 | + step=1, |
| 122 | + value=0, |
| 123 | + desc="Inner gimbal", |
| 124 | + unit="°", |
| 125 | + ) |
131 | 126 |
|
132 |
| -ZYZ_button = swift.Button(lambda x: change_sequence("ZYZ"), desc="ZYZ (Euler angles)") |
| 127 | + # buttons to set a 3-angle sequence |
| 128 | + ZYX_button = swift.Button( |
| 129 | + lambda x: change_sequence("ZYX"), desc="ZYX (roll-pitch-yaw angles)" |
| 130 | + ) |
133 | 131 |
|
134 |
| -button = swift.Button(lambda x: set("ZYX"), desc="Set to Zero") |
| 132 | + XYZ_button = swift.Button( |
| 133 | + lambda x: change_sequence("XYZ"), desc="XYZ (roll-pitch-yaw angles)" |
| 134 | + ) |
135 | 135 |
|
| 136 | + ZYZ_button = swift.Button( |
| 137 | + lambda x: change_sequence("ZYZ"), desc="ZYZ (Euler angles)" |
| 138 | + ) |
136 | 139 |
|
137 |
| -# button to reset joint angles |
138 |
| -def reset(e): |
139 |
| - r_one.value = 0 |
140 |
| - r_two.value = 0 |
141 |
| - r_three.value = 0 |
142 |
| - # env.step(0) |
| 140 | + button = swift.Button(lambda x: set("ZYX"), desc="Set to Zero") |
143 | 141 |
|
| 142 | + # button to reset joint angles |
| 143 | + def reset(e): |
| 144 | + r_one.value = 0 |
| 145 | + r_two.value = 0 |
| 146 | + r_three.value = 0 |
| 147 | + # env.step(0) |
144 | 148 |
|
145 |
| -zero_button = swift.Button(reset, desc="Set to Zero") |
146 |
| - |
147 |
| - |
148 |
| -def update_all_sliders(): |
149 |
| - update_gimbals(float(r_one.value), 1) |
150 |
| - update_gimbals(float(r_two.value), 2) |
151 |
| - update_gimbals(float(r_three.value), 3) |
152 |
| - |
| 149 | + zero_button = swift.Button(reset, desc="Set to Zero") |
153 | 150 |
|
154 |
| -def change_sequence(new): |
155 |
| - global sequence |
| 151 | + def update_all_sliders(): |
| 152 | + update_gimbals(float(r_one.value), 1) |
| 153 | + update_gimbals(float(r_two.value), 2) |
| 154 | + update_gimbals(float(r_three.value), 3) |
156 | 155 |
|
157 |
| - xyz = "XYZ" |
| 156 | + def change_sequence(new): |
| 157 | + global sequence |
158 | 158 |
|
159 |
| - # update the state of the ring_axis dropdowns |
160 |
| - ring1_axis.checked = xyz.find(new[0]) |
161 |
| - ring2_axis.checked = xyz.find(new[1]) |
162 |
| - ring3_axis.checked = xyz.find(new[2]) |
| 159 | + xyz = "XYZ" |
163 | 160 |
|
164 |
| - sequence = new |
165 |
| - update_all_sliders() |
| 161 | + # update the state of the ring_axis dropdowns |
| 162 | + ring1_axis.checked = xyz.find(new[0]) |
| 163 | + ring2_axis.checked = xyz.find(new[1]) |
| 164 | + ring3_axis.checked = xyz.find(new[2]) |
166 | 165 |
|
| 166 | + sequence = new |
| 167 | + update_all_sliders() |
167 | 168 |
|
168 |
| -# handle radio button on angle slider |
169 |
| -def angle(index, ring): |
170 |
| - global sequence |
| 169 | + # handle radio button on angle slider |
| 170 | + def angle(index, ring): |
| 171 | + global sequence |
171 | 172 |
|
172 |
| - # print('angle', index, ring) |
173 |
| - xyz = "XYZ" |
174 |
| - s = list(sequence) |
175 |
| - s[ring] = xyz[int(index)] |
176 |
| - sequence = "".join(s) |
177 |
| - update_all_sliders() |
| 173 | + # print('angle', index, ring) |
| 174 | + xyz = "XYZ" |
| 175 | + s = list(sequence) |
| 176 | + s[ring] = xyz[int(index)] |
| 177 | + sequence = "".join(s) |
| 178 | + update_all_sliders() |
178 | 179 |
|
| 180 | + ring1_axis = swift.Radio(lambda x: angle(x, 0), options=["X", "Y", "Z"], checked=2) |
179 | 181 |
|
180 |
| -ring1_axis = swift.Radio(lambda x: angle(x, 0), options=["X", "Y", "Z"], checked=2) |
| 182 | + ring2_axis = swift.Radio(lambda x: angle(x, 1), options=["X", "Y", "Z"], checked=1) |
181 | 183 |
|
182 |
| -ring2_axis = swift.Radio(lambda x: angle(x, 1), options=["X", "Y", "Z"], checked=1) |
| 184 | + ring3_axis = swift.Radio(lambda x: angle(x, 2), options=["X", "Y", "Z"], checked=0) |
183 | 185 |
|
184 |
| -ring3_axis = swift.Radio(lambda x: angle(x, 2), options=["X", "Y", "Z"], checked=0) |
| 186 | + label = swift.Label(desc="Triple angle") |
185 | 187 |
|
| 188 | + def chekked(e, el): |
| 189 | + nlabel = "s: " |
186 | 190 |
|
187 |
| -label = swift.Label(desc="Triple angle") |
| 191 | + if e[0]: |
| 192 | + nlabel += "a" |
| 193 | + r_one.value = 0 |
188 | 194 |
|
| 195 | + if e[1]: |
| 196 | + nlabel += "b" |
| 197 | + r_two.value = 0 |
189 | 198 |
|
190 |
| -def chekked(e, el): |
191 |
| - nlabel = "s: " |
| 199 | + if e[2]: |
| 200 | + nlabel += "c" |
| 201 | + r_three.value = 0 |
192 | 202 |
|
193 |
| - if e[0]: |
194 |
| - nlabel += "a" |
195 |
| - r_one.value = 0 |
| 203 | + if e[3]: |
| 204 | + el.value = 1 |
196 | 205 |
|
197 |
| - if e[1]: |
198 |
| - nlabel += "b" |
199 |
| - r_two.value = 0 |
| 206 | + label.desc = nlabel |
200 | 207 |
|
201 |
| - if e[2]: |
202 |
| - nlabel += "c" |
203 |
| - r_three.value = 0 |
| 208 | + env.add(label) |
| 209 | + env.add(r_one) |
| 210 | + env.add(ring1_axis) |
204 | 211 |
|
205 |
| - if e[3]: |
206 |
| - el.value = 1 |
| 212 | + env.add(r_two) |
| 213 | + env.add(ring2_axis) |
207 | 214 |
|
208 |
| - label.desc = nlabel |
| 215 | + env.add(r_three) |
| 216 | + env.add(ring3_axis) |
209 | 217 |
|
| 218 | + env.add(ZYX_button) |
| 219 | + env.add(XYZ_button) |
| 220 | + env.add(ZYZ_button) |
| 221 | + env.add(zero_button) |
210 | 222 |
|
211 |
| -env.add(label) |
212 |
| -env.add(r_one) |
213 |
| -env.add(ring1_axis) |
| 223 | + update_gimbals(0, 1) |
| 224 | + update_gimbals(0, 2) |
| 225 | + update_gimbals(0, 3) |
214 | 226 |
|
215 |
| -env.add(r_two) |
216 |
| -env.add(ring2_axis) |
| 227 | + while True: |
| 228 | + env.step(0) |
217 | 229 |
|
218 |
| -env.add(r_three) |
219 |
| -env.add(ring3_axis) |
220 | 230 |
|
221 |
| -env.add(ZYX_button) |
222 |
| -env.add(XYZ_button) |
223 |
| -env.add(ZYZ_button) |
224 |
| -env.add(zero_button) |
| 231 | +def main(): |
| 232 | + demo() |
225 | 233 |
|
226 |
| -update_gimbals(0, 1) |
227 |
| -update_gimbals(0, 2) |
228 |
| -update_gimbals(0, 3) |
229 | 234 |
|
230 |
| -while True: |
231 |
| - env.step(0) |
| 235 | +if __name__ == "__main__": |
| 236 | + main() |
0 commit comments