Ev3rstorm
Python code and building instructions for the LEGO MINDSTORMS EV3 Main models (31313).

EV3RSTORM is the most advanced of the LEGO® MINDSTORMS® robots. Equipped with a blasting bazooka and a spinning tri-blade, EV3RSTORM is superior in both intelligence as well as in fighting power.
This program requires LEGO® EV3 MicroPython v2.0 downloadable at https://education.lego.com/en-us/support/mindstorms-ev3/python-for-ev3.
Ev3rstorm works as follows:
-
You can drive Ev3rstorm around with the IR beacon.
-
Ev3rstorm dances by turning by random angles on the spot when the Beacon button is pressed.
-
Ev3rstorm blasts his bazooka when his Touch Sensor is pressed. If you cover the Color Sensor then he will shoot upwards, or he will shoot downwards.
The code for the Ev3rstorm
class is in ev3rstorm.py
as follows:
from pybricks.hubs import EV3Brick
from pybricks.ev3devices import Motor, TouchSensor, ColorSensor
from pybricks.media.ev3dev import SoundFile
from pybricks.parameters import Button, Direction, Port, Stop
from random import randint
from rc_tank_util import RemoteControlledTank
class Ev3rstorm(RemoteControlledTank):
WHEEL_DIAMETER = 26 # milimeters
AXLE_TRACK = 102 # milimeters
def __init__(
self,
left_track_motor_port: Port = Port.B,
right_track_motor_port: Port = Port.C,
bazooka_blast_motor_port: Port = Port.A,
touch_sensor_port: Port = Port.S1,
color_sensor_port: Port = Port.S3,
ir_sensor_port: Port = Port.S4,
ir_beacon_channel: int = 1):
super().__init__(
wheel_diameter=self.WHEEL_DIAMETER,
axle_track=self.AXLE_TRACK,
left_motor_port=left_track_motor_port,
right_motor_port=right_track_motor_port,
ir_sensor_port=ir_sensor_port,
ir_beacon_channel=ir_beacon_channel)
self.ev3_brick = EV3Brick()
self.bazooka_blast_motor = \
Motor(port=bazooka_blast_motor_port,
positive_direction=Direction.CLOCKWISE)
self.touch_sensor = TouchSensor(port=touch_sensor_port)
self.color_sensor = ColorSensor(port=color_sensor_port)
def dance_randomly_if_ir_beacon_button_pressed(self):
"""
Ev3rstorm dances by turning by random angles on the spot
when the Beacon button is pressed
"""
while Button.BEACON in \
self.ir_sensor.buttons(channel=self.ir_beacon_channel):
self.drive_base.turn(angle=randint(-360, 360))
def blast_bazooka_if_touched(self):
"""
Ev3rstorm blasts his bazooka when his Touch Sensor is pressed
(inspiration from LEGO Mindstorms EV3 Home Ed.: Ev3rstorm: Tutorial #5)
"""
MEDIUM_MOTOR_ROTATIONAL_DEGREES_PER_BLAST = 3 * 360
if self.touch_sensor.pressed():
if self.color_sensor.ambient() < 15:
self.ev3_brick.speaker.play_file(file=SoundFile.UP)
self.bazooka_blast_motor.run_angle(
speed=2 * MEDIUM_MOTOR_ROTATIONAL_DEGREES_PER_BLAST,
rotation_angle=-MEDIUM_MOTOR_ROTATIONAL_DEGREES_PER_BLAST,
then=Stop.HOLD,
wait=True)
self.ev3_brick.speaker.play_file(file=SoundFile.LAUGHING_1)
else:
self.ev3_brick.speaker.play_file(file=SoundFile.DOWN)
self.bazooka_blast_motor.run_angle(
speed=2 * MEDIUM_MOTOR_ROTATIONAL_DEGREES_PER_BLAST,
rotation_angle=MEDIUM_MOTOR_ROTATIONAL_DEGREES_PER_BLAST,
then=Stop.HOLD,
wait=True)
self.ev3_brick.speaker.play_file(file=SoundFile.LAUGHING_2)
Ev3rstorm
uses a remote-controlled tank driving utility whose code is in rc_tank_util.py
as follows:
from pybricks.ev3devices import Motor, InfraredSensor
from pybricks.robotics import DriveBase
from pybricks.parameters import Button, Direction, Port
class RemoteControlledTank:
"""
This reusable mixin provides the capability of driving a robot
with a Driving Base by the IR beacon
"""
def __init__(
self,
wheel_diameter: float, axle_track: float, # both in milimeters
left_motor_port: Port = Port.B, right_motor_port: Port = Port.C,
ir_sensor_port: Port = Port.S4, ir_beacon_channel: int = 1):
self.drive_base = \
DriveBase(
left_motor=Motor(port=left_motor_port,
positive_direction=Direction.CLOCKWISE),
right_motor=Motor(port=right_motor_port,
positive_direction=Direction.CLOCKWISE),
wheel_diameter=wheel_diameter,
axle_track=axle_track)
self.ir_sensor = InfraredSensor(port=ir_sensor_port)
self.ir_beacon_channel = ir_beacon_channel
def drive_by_ir_beacon(
self,
speed: float = 1000, # mm/s
turn_rate: float = 90 # rotational speed deg/s
):
ir_beacon_button_pressed = \
set(self.ir_sensor.buttons(channel=self.ir_beacon_channel))
# forward
if ir_beacon_button_pressed == {Button.LEFT_UP, Button.RIGHT_UP}:
self.drive_base.drive(
speed=speed,
turn_rate=0)
# backward
elif ir_beacon_button_pressed == {Button.LEFT_DOWN, Button.RIGHT_DOWN}:
self.drive_base.drive(
speed=-speed,
turn_rate=0)
# turn left on the spot
elif ir_beacon_button_pressed == {Button.LEFT_UP, Button.RIGHT_DOWN}:
self.drive_base.drive(
speed=0,
turn_rate=-turn_rate)
# turn right on the spot
elif ir_beacon_button_pressed == {Button.RIGHT_UP, Button.LEFT_DOWN}:
self.drive_base.drive(
speed=0,
turn_rate=turn_rate)
# turn left forward
elif ir_beacon_button_pressed == {Button.LEFT_UP}:
self.drive_base.drive(
speed=speed,
turn_rate=-turn_rate)
# turn right forward
elif ir_beacon_button_pressed == {Button.RIGHT_UP}:
self.drive_base.drive(
speed=speed,
turn_rate=turn_rate)
# turn left backward
elif ir_beacon_button_pressed == {Button.LEFT_DOWN}:
self.drive_base.drive(
speed=-speed,
turn_rate=turn_rate)
# turn right backward
elif ir_beacon_button_pressed == {Button.RIGHT_DOWN}:
self.drive_base.drive(
speed=-speed,
turn_rate=-turn_rate)
# otherwise stop
else:
self.drive_base.stop()
The code for the main program is in main.py
as follows:
#!/usr/bin/env pybricks-micropython
from pybricks.media.ev3dev import ImageFile
from pybricks.tools import wait
from ev3rstorm import Ev3rstorm
ev3rstorm = Ev3rstorm()
ev3rstorm.ev3_brick.screen.load_image(ImageFile.TARGET)
while True:
ev3rstorm.drive_by_ir_beacon(speed=1000)
ev3rstorm.dance_randomly_if_ir_beacon_button_pressed()
ev3rstorm.blast_bazooka_if_touched()
wait(1)
This project was submitted by The Lương-Phạm Family.