Dinor3x
Python code and building instructions for the LEGO MINDSTORMS EV3 Official Fan Creations (31313).

This charming robotic triceratops dinosaur is capable of walking and turning on all fours.
This program requires LEGO® EV3 MicroPython v2.0 downloadable at https://education.lego.com/en-us/support/mindstorms-ev3/python-for-ev3.
NOTE: please add a Color Sensor to Dinor3x’s back or tail.
Dinor3x works as follows:
-
Dinor3x roars when the Beacon button is pressed
- Dinor3x changes its speed when detecting some colors
- Red: walk fast
- Green: walk normally
- White: walk slowly
- Dinor3x walks or turns according to instructions from the IR Beacon
- 2 top/up buttons together: walk forward
- 2 bottom/down buttons together: walk backward
- Top Left / Red Up: turn left on the spot
- Top Right / Blue Up: turn right on the spot
- Bottom Left / Red Down: stop
- Bottom Right / Blue Down: calibrate to make the legs straight
The code for the Dinor3x
class is in dinor3x.py
as follows:
from pybricks.hubs import EV3Brick
from pybricks.ev3devices import Motor, TouchSensor, ColorSensor, InfraredSensor
from pybricks.media.ev3dev import SoundFile
from pybricks.parameters import Button, Color, Direction, Port, Stop
class Dinor3x:
FAST_WALK_SPEED = 800
NORMAL_WALK_SPEED = 400
SLOW_WALK_SPEED = 200
def __init__(
self,
jaw_motor_port: Port = Port.A,
left_motor_port: Port = Port.B, right_motor_port: Port = Port.C,
touch_sensor_port: Port = Port.S1,
color_sensor_port: Port = Port.S3,
ir_sensor_port: Port = Port.S4, ir_beacon_channel: int = 1):
self.ev3_brick = EV3Brick()
self.jaw_motor = Motor(port=jaw_motor_port,
positive_direction=Direction.CLOCKWISE)
self.left_motor = Motor(port=left_motor_port,
positive_direction=Direction.CLOCKWISE)
self.right_motor = Motor(port=right_motor_port,
positive_direction=Direction.CLOCKWISE)
self.touch_sensor = TouchSensor(port=touch_sensor_port)
self.color_sensor = ColorSensor(port=color_sensor_port)
self.ir_sensor = InfraredSensor(port=ir_sensor_port)
self.ir_beacon_channel = ir_beacon_channel
self.roaring = False
self.walk_speed = self.NORMAL_WALK_SPEED
def roar_by_ir_beacon(self):
"""
Dinor3x roars when the Beacon button is pressed
"""
if Button.BEACON in \
self.ir_sensor.buttons(channel=self.ir_beacon_channel):
self.roaring = True
self.open_mouth()
self.roar()
elif self.roaring:
self.roaring = False
self.close_mouth()
def change_speed_by_color(self):
"""
Dinor3x changes its speed when detecting some colors
- Red: walk fast
- Green: walk normally
- White: walk slowly
"""
if self.color_sensor.color() == Color.RED:
self.ev3_brick.speaker.say(text='RUN!')
self.walk_speed = self.FAST_WALK_SPEED
self.walk(speed=self.walk_speed)
elif self.color_sensor.color() == Color.GREEN:
self.ev3_brick.speaker.say(text='Normal')
self.walk_speed = self.NORMAL_WALK_SPEED
self.walk(speed=self.walk_speed)
elif self.color_sensor.color() == Color.WHITE:
self.ev3_brick.speaker.say(text='slow...')
self.walk_speed = self.SLOW_WALK_SPEED
self.walk(speed=self.walk_speed)
def walk_by_ir_beacon(self):
"""
Dinor3x walks or turns according to instructions from the IR Beacon
- 2 top/up buttons together: walk forward
- 2 bottom/down buttons together: walk backward
- Top Left / Red Up: turn left on the spot
- Top Right / Blue Up: turn right on the spot
- Bottom Left / Red Down: stop
- Bottom Right / Blue Down: calibrate to make the legs straight
"""
ir_buttons_pressed = \
set(self.ir_sensor.buttons(channel=self.ir_beacon_channel))
# forward
if ir_buttons_pressed == {Button.LEFT_UP, Button.RIGHT_UP}:
self.walk(speed=self.walk_speed)
# backward
elif ir_buttons_pressed == {Button.LEFT_DOWN, Button.RIGHT_DOWN}:
self.walk(speed=-self.walk_speed)
# turn left on the spot
elif ir_buttons_pressed == {Button.LEFT_UP}:
self.turn(speed=self.walk_speed)
# turn right on the spot
elif ir_buttons_pressed == {Button.RIGHT_UP}:
self.turn(speed=-self.walk_speed)
# stop
elif ir_buttons_pressed == {Button.LEFT_DOWN}:
self.left_motor.hold()
self.right_motor.hold()
# calibrate legs
elif ir_buttons_pressed == {Button.RIGHT_DOWN}:
self.calibrate_legs()
def calibrate_legs(self):
self.left_motor.run(speed=100)
self.right_motor.run(speed=200)
while self.touch_sensor.pressed():
pass
self.left_motor.hold()
self.right_motor.hold()
self.left_motor.run(speed=400)
while not self.touch_sensor.pressed():
pass
self.left_motor.hold()
self.left_motor.run_angle(
rotation_angle=-0.2 * 360,
speed=500,
then=Stop.HOLD,
wait=True)
self.right_motor.run(speed=400)
while not self.touch_sensor.pressed():
pass
self.right_motor.hold()
self.right_motor.run_angle(
rotation_angle=-0.2 * 360,
speed=500,
then=Stop.HOLD,
wait=True)
self.left_motor.reset_angle(angle=0)
self.right_motor.reset_angle(angle=0)
def walk(self, speed: float = 400):
self.calibrate_legs()
self.left_motor.run(speed=-speed)
self.right_motor.run(speed=-speed)
def turn(self, speed: float = 400):
self.calibrate_legs()
if speed >= 0:
self.left_motor.run_angle(
rotation_angle=180,
speed=speed,
then=Stop.HOLD,
wait=True)
else:
self.right_motor.run_angle(
rotation_angle=180,
speed=-speed,
then=Stop.HOLD,
wait=True)
self.left_motor.run(speed=speed)
self.right_motor.run(speed=-speed)
def close_mouth(self):
self.jaw_motor.run_time(
speed=-200,
time=1000,
then=Stop.COAST,
wait=False)
def open_mouth(self):
self.jaw_motor.run_time(
speed=200,
time=1000,
then=Stop.COAST,
wait=False)
def roar(self):
self.ev3_brick.speaker.play_file(file=SoundFile.T_REX_ROAR)
self.jaw_motor.run_angle(
speed=400,
rotation_angle=-60,
then=Stop.HOLD,
wait=True)
for _ in range(12):
self.jaw_motor.run_time(
speed=-400,
time=0.05 * 1000,
then=Stop.HOLD,
wait=True)
self.jaw_motor.run_time(
speed=400,
time=0.05 * 1000,
then=Stop.HOLD,
wait=True)
self.jaw_motor.run_time(
speed=200,
time=0.5 * 1000,
then=Stop.COAST,
wait=True)
The code for the main program is in main.py
as follows:
#!/usr/bin/env pybricks-micropython
from dinor3x import Dinor3x
dino = Dinor3x()
dino.close_mouth()
while True:
dino.roar_by_ir_beacon()
dino.change_speed_by_color()
dino.walk_by_ir_beacon()
This project was submitted by The Lương-Phạm Family.