Skip to content

Commit 254355c

Browse files
committed
EV3RSTORM demo
1 parent 32f5796 commit 254355c

File tree

2 files changed

+171
-0
lines changed

2 files changed

+171
-0
lines changed

demo/EV3RSTORM/README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
EV3RSTORM
2+
=========
3+
4+
EV3RSTORM is the most advanced of the LEGO(r) MINDSTORMS(r) Robots.
5+
Equipped with a blasting bazooka and a spinning tri-blade, EV3RSTORM is
6+
superior in both intelligence as well as in fighting power.
7+
8+
Our version, being built with ev3dev, is also vastly more intelligent (one
9+
could say, it has a [brain size of a planet](https://en.wikipedia.org/wiki/Marvin_(character)))
10+
so ut may be afflicted with severe depression and boredom at times.
11+
12+
The build instructions may be found at the official LEGO MINDSTROMS site
13+
[here](http://www.lego.com/en-us/mindstorms/build-a-robot/ev3rstorm).
14+

demo/EV3RSTORM/ev3rstorm.py

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
#!/usr/bin/env python3
2+
3+
import time, random
4+
import ev3dev.ev3 as ev3
5+
6+
random.seed( time.time() )
7+
8+
def quote(topic):
9+
"""
10+
Recite a random Marvin the Paranoid Android quote on the specified topic.
11+
See https://en.wikipedia.org/wiki/Marvin_(character)
12+
"""
13+
14+
marvin_quotes = {
15+
'initiating' : (
16+
"Life? Don't talk to me about life!",
17+
"Now I've got a headache.",
18+
"This will all end in tears.",
19+
),
20+
'depressed' : (
21+
"I think you ought to know I'm feeling very depressed.",
22+
"Incredible... it's even worse than I thought it would be.",
23+
"I'd make a suggestion, but you wouldn't listen.",
24+
),
25+
}
26+
27+
ev3.Sound.speak(random.choice(marvin_quotes[topic])).wait()
28+
29+
def check(condition, message):
30+
"""
31+
Check that condition is true,
32+
loudly complain and throw an exception otherwise.
33+
"""
34+
if not condition:
35+
ev3.Sound.speak(message).wait()
36+
quote('depressed')
37+
raise Exception(message)
38+
39+
class ev3rstorm:
40+
def __init__(self):
41+
# Connect the required equipement
42+
self.lm = ev3.LargeMotor('outB')
43+
self.rm = ev3.LargeMotor('outC')
44+
self.mm = ev3.MediumMotor()
45+
46+
self.ir = ev3.InfraredSensor()
47+
self.ts = ev3.TouchSensor()
48+
self.cs = ev3.ColorSensor()
49+
50+
self.screen = ev3.Screen()
51+
52+
# Check if everything is attached
53+
check(self.lm.connected, 'My left leg is missing!')
54+
check(self.rm.connected, 'Right leg is not found!')
55+
check(self.mm.connected, 'My left arm is not connected!')
56+
57+
check(self.ir.connected, 'My eyes, I can not see!')
58+
check(self.ts.connected, 'Touch sensor is not attached!')
59+
check(self.cs.connected, 'Color sensor is not responding!')
60+
61+
# Reset the motors
62+
for m in (self.lm, self.rm, self.mm):
63+
m.reset()
64+
m.position = 0
65+
m.stop_action = 'brake'
66+
67+
self.draw_face()
68+
69+
quote('initiating')
70+
71+
def draw_face(self):
72+
w,h = self.screen.shape
73+
y = h // 2
74+
75+
eye_xrad = 20
76+
eye_yrad = 30
77+
78+
pup_xrad = 10
79+
pup_yrad = 10
80+
81+
def draw_eye(x):
82+
self.screen.draw.ellipse((x-eye_xrad, y-eye_yrad, x+eye_xrad, y+eye_yrad))
83+
self.screen.draw.ellipse((x-pup_xrad, y-pup_yrad, x+pup_xrad, y+pup_yrad), fill='black')
84+
85+
draw_eye(w//3)
86+
draw_eye(2*w//3)
87+
88+
self.screen.update()
89+
90+
def shoot(self, direction='up'):
91+
"""
92+
Shot a ball in the specified direction (valid choices are 'up' and 'down')
93+
"""
94+
self.mm.run_to_rel_pos(speed_sp=900, position_sp=(-1080 if direction == 'up' else 1080))
95+
while 'running' in self.mm.state:
96+
time.sleep(0.1)
97+
98+
def rc_loop(self):
99+
"""
100+
Enter the remote control loop. RC buttons on channel 1 control the
101+
robot movement, channel 2 is for shooting things.
102+
The loop ends when the touch sensor is pressed.
103+
"""
104+
105+
def roll(motor, led_group, speed):
106+
"""
107+
Generate remote control event handler. It rolls given motor into
108+
given direction (1 for forward, -1 for backward). When motor rolls
109+
forward, the given led group flashes green, when backward -- red.
110+
When motor stops, the leds are turned off.
111+
112+
The on_press function has signature required by RemoteControl
113+
class. It takes boolean state parameter; True when button is
114+
pressed, False otherwise.
115+
"""
116+
def on_press(state):
117+
if state:
118+
# Roll when button is pressed
119+
motor.run_forever(speed_sp=speed)
120+
ev3.Leds.set_color(led_group,
121+
ev3.Leds.GREEN if speed > 0 else ev3.Leds.RED)
122+
else:
123+
# Stop otherwise
124+
motor.stop()
125+
ev3.Leds.set_color(led_group, ev3.Leds.BLACK)
126+
127+
return on_press
128+
129+
rc1 = ev3.RemoteControl(self.ir, 1)
130+
rc1.on_red_up = roll(self.lm, ev3.Leds.LEFT, 900)
131+
rc1.on_red_down = roll(self.lm, ev3.Leds.LEFT, -900)
132+
rc1.on_blue_up = roll(self.rm, ev3.Leds.RIGHT, 900)
133+
rc1.on_blue_down = roll(self.rm, ev3.Leds.RIGHT, -900)
134+
135+
136+
def shoot(direction):
137+
def on_press(state):
138+
if state: self.shoot(direction)
139+
return on_press
140+
141+
rc2 = ev3.RemoteControl(self.ir, 2)
142+
rc2.on_red_up = shoot('up')
143+
rc2.on_blue_up = shoot('up')
144+
rc2.on_red_down = shoot('down')
145+
rc2.on_blue_down = shoot('down')
146+
147+
# Now that the event handlers are assigned,
148+
# lets enter the processing loop:
149+
while not self.ts.is_pressed():
150+
rc1.process()
151+
rc2.process()
152+
time.sleep(0.1)
153+
154+
155+
if __name__ == '__main__':
156+
Marvin = ev3rstorm()
157+
Marvin.rc_loop()

0 commit comments

Comments
 (0)