Skip to content

Commit 336bf7b

Browse files
authored
feat(robot): use robot leds if pixel not connected (#40)
* remove image
1 parent b673a73 commit 336bf7b

File tree

3 files changed

+155
-56
lines changed

3 files changed

+155
-56
lines changed

Makefile

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,18 @@ controller-upload:
2020

2121
.PHONY: robot-install
2222
robot-install:
23-
mpremote mip install github:arduino/arduino-modulino-mpy
23+
mpremote mip install github:arduino/arduino-modulino-mpy github:arduino/ucPack-mpy
2424

2525
.PHONY: robot-get-mac
2626
robot-get-mac:
2727
mpremote exec "import network; print(':'.join('{:02x}'.format(x) for x in network.WLAN().config('mac')))"
2828

29+
30+
.PHONY: robot-get-charge
31+
robot-get-charge:
32+
mpremote exec "from arduino_alvik import ArduinoAlvik; a = ArduinoAlvik(); a.begin(); print(a.get_battery_charge())"
33+
34+
2935
.PHONY: robot-upload
3036
robot-upload:
3137
mpremote fs cp ./sketches/robot/main.py :main.py
@@ -43,10 +49,11 @@ robot-patch-firmware:
4349
robot-patch-mpy:
4450
rm -rf arduino-alvik-mpy
4551
git clone [email protected]:arduino/arduino-alvik-mpy.git
46-
# Use the commit with `1.0.4 - default servo 90` that move the servo to 90 degrees by default and not 0.
52+
# See issue: https://github.com/bcmi-labs/alvik-fight-club/issues/38
4753
# See https://github.com/arduino/arduino-alvik-mpy/commit/177c43620b08ee6f66fac4d11839564eebddbd88
4854
cd arduino-alvik-mpy && git checkout 177c43620b08ee6f66fac4d11839564eebddbd88
4955

56+
mpremote fs mkdir lib/arduino_alvik || true
5057
mpremote fs cp ./arduino-alvik-mpy/arduino_alvik/__init__.py :lib/arduino_alvik/__init__.py
5158
mpremote fs cp ./arduino-alvik-mpy/arduino_alvik/arduino_alvik.py :lib/arduino_alvik/arduino_alvik.py
5259
mpremote fs cp ./arduino-alvik-mpy/arduino_alvik/constants.py :lib/arduino_alvik/constants.py

README.md

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,26 @@ The project is composed by two components:
1616
- `make init` to install tools on local pc
1717

1818
### Configure the Alvik robot
19-
1. Connect the Alvik
20-
2. `make robot-patch-firmware`: to patch the firmware running on the STM32 (needed to resolve [Issue 10](https://github.com/bcmi-labs/alvik-fight-club/issues/10))
21-
3. `make robot-patch-mpy`: to install the `dev` branch with of the Arduino-Alvik-mpy (Needed to resolve [Issue 10](https://github.com/bcmi-labs/alvik-fight-club/issues/10))
19+
1. Connect the usb-c to the Alvik and turn on it
20+
2. `make robot-patch-firmware`: to upload the patched firmware running on the STM32 (needed to resolve [Issue 10](https://github.com/bcmi-labs/alvik-fight-club/issues/10))
21+
3. `make robot-patch-mpy`: to install the `dev` branch of the arduino-alvik-mpy code in the robot (needed to resolve [Issue 10](https://github.com/bcmi-labs/alvik-fight-club/issues/10)) and [Issue 38](https://github.com/bcmi-labs/alvik-fight-club/issues/38).
2222
4. `make robot-install` to upload the `Modulino` lib
23-
5. `make robot-get-mac` to get the `MAC` address and print it into the consle.
24-
6. Copy the printed MAC address
25-
7. `make robot-upload` to upload the code into the alvik
23+
5. `make robot-upload` to upload the code into the alvik
24+
6. check if the robot is: shows red leds animation on black surface, and steady green leds on white surface.
25+
7. `make robot-get-mac` to get the `MAC` address and print it into the console
26+
8. Copy the printed MAC address
2627

27-
NOTE: the PATCH steps `2` and `3` are no more necessary when the [Arduino_AlvikCarrier](https://github.com/arduino-libraries/Arduino_AlvikCarrier) and the [Arduino-Alvik-mpy](https://github.com/arduino/arduino-alvik-mpy) are merged to master and released.
28+
Wiring
29+
- right motor connected to upper pin
30+
- left motor connected to lower pin
31+
32+
MAC of Robots (Maker Fair Rome 2024):
33+
- Livia robot: `74:4d:bd:a2:08:74` previous mac was `74:4d:bd:7e:28:70`
34+
- Stefano robot `74:4d:bd:a2:1b:bc`
35+
- Davide robot: `74:4d:bd:a2:27:08`
36+
- Alessia robot:`dc:da:0c:22:eb:94`
37+
38+
NOTE: the PATCH steps `2` and `3` are no more necessary when the [Arduino_AlvikCarrier](https://github.com/arduino-libraries/Arduino_AlvikCarrier) and the [Arduino-Alvik-mpy](https://github.com/arduino/arduino-alvik-mpy) are merged to master
2839

2940
#### Color calibration mode
3041
The robot exposes a `color calibration mode` that can be activated by pressing the `ok` button.
@@ -47,7 +58,7 @@ Steps to calibrate the robot
4758
- Download the [Micropython Installer](https://labs.arduino.cc/en/labs/micropython-installer)
4859
- Open the installer and clik `Install Micropython` button
4960
4. `make controller-install` to install libraries into the controller
50-
5. `make controller-upload robot-mac=<PUT_THE_ALVIK_MAC_HERE>` to upload the code and setting the MAC sddress obtained with the `make robot-get-mac` (robot Step 5).
61+
5. `make controller-upload robot-mac=<PUT_THE_ALVIK_MAC_HERE>` to upload the code and setting the MAC address obtained with the `make robot-get-mac` (robot Step 5).
5162
Example: `make controller-upload robot-mac=74:4d:bd:a0:49:e8`
5263

5364
## Techninal info

sketches/robot/main.py

Lines changed: 127 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
print("ImportError: ModulinoPixels not installed")
1515
sys.exit(-1)
1616

17-
LINEAR_VELOCITY = 10 # (max 13cm/s)
17+
LINEAR_VELOCITY = 10 # (max 13cm/s)
1818
ANGULAR_VELOCITY = 75 # (max 320.8988764044944)
1919
FREEZE_FOR_SECONDS = 5
2020
REVERT_CONTROLLER_FOR_SECONDS = 10
@@ -40,11 +40,12 @@
4040
LIFT = 5
4141

4242

43-
isPlayingReverted = False # if true the controller action are reverted
44-
lifState = 0 # 0 = down, 1 = up
43+
isPlayingReverted = False # if true the controller action are reverted
44+
lifState = 0 # 0 = down, 1 = up
4545

4646
lin = 0
4747
ang = 0
48+
4849
def receiveAndExecuteFromEspNow():
4950
global lifState
5051
global lin
@@ -61,16 +62,21 @@ def receiveAndExecuteFromEspNow():
6162

6263
if int(msg_type) == STOP:
6364
lin, ang = 0, 0
65+
a.drive(lin, ang)
6466
elif int(msg_type) == GO_FORWARD:
6567
lin = LINEAR_VELOCITY if isPlayingReverted else -LINEAR_VELOCITY
6668
ang = 0
69+
a.drive(lin, ang)
6770
elif int(msg_type) == GO_BACKWARD:
6871
lin = -LINEAR_VELOCITY if isPlayingReverted else LINEAR_VELOCITY
6972
ang = 0
73+
a.drive(lin, ang)
7074
elif int(msg_type) == TURN_LEFT:
7175
ang = -ANGULAR_VELOCITY if isPlayingReverted else ANGULAR_VELOCITY
76+
a.drive(lin, ang)
7277
elif int(msg_type) == TURN_RIGHT:
7378
ang = ANGULAR_VELOCITY if isPlayingReverted else -ANGULAR_VELOCITY
79+
a.drive(lin, ang)
7480
elif int(msg_type) == LIFT:
7581
if lifState == 0:
7682
liftUp()
@@ -81,37 +87,49 @@ def receiveAndExecuteFromEspNow():
8187
else:
8288
print("unknown command type ", msg_type)
8389

84-
a.drive(lin, ang)
8590

8691
def liftUp():
87-
a.set_servo_positions(180, 0)
92+
a.set_servo_positions(0, 180)
8893
sleep_ms(25)
89-
a.set_servo_positions(175, 5)
94+
a.set_servo_positions(5, 175)
9095
sleep_ms(25)
91-
a.set_servo_positions(170, 10)
96+
a.set_servo_positions(10, 170)
9297
sleep_ms(25)
93-
a.set_servo_positions(165, 15)
98+
a.set_servo_positions(15, 165)
9499
sleep_ms(25)
95-
a.set_servo_positions(160, 20)
100+
a.set_servo_positions(20, 160)
96101
sleep_ms(25)
97102

98103

99104
def liftDown():
100-
a.set_servo_positions(165, 15)
105+
a.set_servo_positions(15, 165)
101106
sleep_ms(25)
102-
a.set_servo_positions(170, 10)
107+
a.set_servo_positions(10, 170)
103108
sleep_ms(25)
104-
a.set_servo_positions(175, 5)
109+
a.set_servo_positions(15, 175)
105110
sleep_ms(25)
106-
a.set_servo_positions(180, 0)
111+
a.set_servo_positions(0, 180)
107112

108113

109114
def showReadyToPlayLeds():
115+
if not pixels.connected:
116+
a.left_led.set_color(red=False, green=True, blue=False)
117+
a.right_led.set_color(red=False, green=True, blue=False)
118+
return
110119
pixels.set_all_color(ModulinoColor.GREEN, 15)
111120
pixels.show()
112121

113122

114123
def showEndAnimation():
124+
if not pixels.connected:
125+
a.left_led.set_color(red=True, green=False, blue=False)
126+
a.right_led.set_color(red=True, green=False, blue=False)
127+
sleep_ms(100)
128+
a.left_led.set_color(red=False, green=False, blue=False)
129+
a.right_led.set_color(red=False, green=False, blue=False)
130+
sleep_ms(100)
131+
return
132+
115133
for i in range(0, 8):
116134
pixels.clear_all()
117135
pixels.set_rgb(i, 255, 0, 0, 15)
@@ -125,6 +143,39 @@ def showEndAnimation():
125143
sleep_ms(50)
126144

127145

146+
def showRevertedAnimation(mapped):
147+
if not pixels.connected:
148+
a.left_led.set_color(red=True, green=False, blue=True)
149+
a.right_led.set_color(red=True, green=False, blue=True)
150+
sleep_ms(100)
151+
a.left_led.set_color(red=False, green=False, blue=False)
152+
a.right_led.set_color(red=False, green=False, blue=False)
153+
sleep_ms(100)
154+
return
155+
pixels.clear_all()
156+
pixels.set_range_color(0, mapped, ModulinoColor.VIOLET)
157+
pixels.show()
158+
159+
160+
def showFreezeAnimation():
161+
for x in range(0, FREEZE_FOR_SECONDS):
162+
sleep_ms(500)
163+
if not pixels.connected:
164+
a.left_led.set_color(red=False, green=False, blue=True)
165+
a.right_led.set_color(red=False, green=False, blue=True)
166+
else:
167+
pixels.set_all_color(ModulinoColor.BLUE, 15)
168+
pixels.show()
169+
sleep_ms(500)
170+
171+
def showSlipAnimation():
172+
if not pixels.connected:
173+
print("pixels not connect, slip not")
174+
return
175+
pixels.set_all_color(ModulinoColor.YELLOW, 15)
176+
pixels.show()
177+
178+
128179
def map_value(value, from_low, from_high, to_low, to_high):
129180
return int(
130181
(value - from_low) * (to_high - to_low) / (from_high - from_low) + to_low
@@ -133,35 +184,68 @@ def map_value(value, from_low, from_high, to_low, to_high):
133184

134185
def countdown_color(color, ledoff_every_tick=2):
135186
for i in range(7, 0, -ledoff_every_tick):
136-
pixels.set_range_color(0, i, color)
137-
pixels.show()
187+
if not pixels.connected:
188+
a.left_led.set_color(red=True, green=True, blue=True)
189+
a.right_led.set_color(red=True, green=True, blue=True)
190+
else:
191+
pixels.set_range_color(0, i, color)
192+
pixels.show()
138193
sleep_ms(500)
139-
pixels.clear_all()
140-
pixels.show()
194+
if not pixels.connected:
195+
a.left_led.set_color(red=False, green=False, blue=False)
196+
a.right_led.set_color(red=False, green=False, blue=False)
197+
else:
198+
pixels.clear_all()
199+
pixels.show()
141200
sleep_ms(500)
142-
pixels.clear_all()
143-
pixels.show()
201+
144202

145203
def calibrate_color():
146204
print("Reading white color")
147-
countdown_color(ModulinoColor.WHITE)
148-
a.color_calibration("white")
205+
for i in range(7, 0, -2):
206+
if not pixels.connected:
207+
a.left_led.set_color(red=True, green=True, blue=True)
208+
a.right_led.set_color(red=True, green=True, blue=True)
209+
else:
210+
pixels.set_range_color(0, i, ModulinoColor.WHITE)
211+
pixels.show()
212+
sleep_ms(500)
213+
if not pixels.connected:
214+
a.left_led.set_color(red=False, green=False, blue=False)
215+
a.right_led.set_color(red=False, green=False, blue=False)
216+
else:
217+
pixels.clear_all()
218+
pixels.show()
219+
sleep_ms(500)
149220

150-
pixels.set_all_color(ModulinoColor.GREEN, 15)
151-
pixels.show()
152-
sleep_ms(2000)
221+
a.color_calibration("white")
153222

154223
print("Reading black color")
155-
countdown_color(ModulinoColor.BLUE)
224+
for i in range(7, 0, -2):
225+
if not pixels.connected:
226+
a.left_led.set_color(red=False, green=False, blue=True)
227+
a.right_led.set_color(red=False, green=False, blue=True)
228+
else:
229+
pixels.set_range_color(0, i, ModulinoColor.BLUE)
230+
pixels.show()
231+
sleep_ms(500)
232+
if not pixels.connected:
233+
a.left_led.set_color(red=False, green=False, blue=False)
234+
a.right_led.set_color(red=False, green=False, blue=False)
235+
else:
236+
pixels.clear_all()
237+
pixels.show()
238+
sleep_ms(500)
156239
a.color_calibration("black")
157240

158-
pixels.set_all_color(ModulinoColor.GREEN, 15)
159-
pixels.show()
241+
if pixels.connected:
242+
pixels.set_all_color(ModulinoColor.GREEN, 15)
243+
pixels.show()
244+
else:
245+
a.left_led.set_color(red=False, green=True, blue=False)
246+
a.right_led.set_color(red=False, green=True, blue=False)
160247
sleep_ms(2000)
161248

162-
pixels.clear_all()
163-
pixels.show()
164-
165249
# hard-reset the board to refresh the calibration (read again the color from the file)
166250
machine.reset()
167251

@@ -197,32 +281,29 @@ def calibrate_color():
197281
if color == "BLACK":
198282
state = STATE_INIT
199283
elif color == "YELLOW":
200-
pixels.set_all_color(ModulinoColor.YELLOW, 15)
201-
pixels.show()
202-
deg = random.choice([30.0, 45.0, 90.0, 130.0, 150.0, 180.0, 275.0, 360.0])
284+
showSlipAnimation()
285+
deg = random.choice(
286+
[30.0, 45.0, 90.0, 130.0, 150.0, 180.0, 275.0, 360.0]
287+
)
203288
a.rotate(deg, "deg")
204289
showReadyToPlayLeds()
205-
elif color == "BLUE":
290+
elif color == "BLUE" or color == "LIGHT BLUE":
206291
a.drive(0, 0)
207-
for x in range(0, FREEZE_FOR_SECONDS):
208-
sleep_ms(500)
209-
pixels.set_all_color(ModulinoColor.BLUE, 15)
210-
pixels.show()
211-
sleep_ms(500)
212-
pixels.clear_all()
213-
pixels.show()
292+
showFreezeAnimation()
214293
showReadyToPlayLeds()
215294
elif color == "GREEN" or color == "LIGHT GREEN":
216295
if not isPlayingReverted:
217-
deadline = ticks_add(ticks_ms(), REVERT_CONTROLLER_FOR_SECONDS * 1000)
296+
deadline = ticks_add(
297+
ticks_ms(), REVERT_CONTROLLER_FOR_SECONDS * 1000
298+
)
218299
isPlayingReverted = True
219300

220301
if isPlayingReverted:
221302
elapsed = ticks_diff(deadline, ticks_ms())
222-
mapped = map_value(elapsed, 0, REVERT_CONTROLLER_FOR_SECONDS * 1000, 0, 7)
223-
pixels.clear_all()
224-
pixels.set_range_color(0, mapped, ModulinoColor.VIOLET)
225-
pixels.show()
303+
mapped = map_value(
304+
elapsed, 0, REVERT_CONTROLLER_FOR_SECONDS * 1000, 0, 7
305+
)
306+
showRevertedAnimation(mapped)
226307
if elapsed < 0:
227308
showReadyToPlayLeds()
228309
isPlayingReverted = False

0 commit comments

Comments
 (0)