Autonomous vehicles
Autonomous vehicles
main.py
Delete all the code in main.py
, replacing it with the code below:
#!/bin/bash
##############################################
# Runs script first through bash to remove
# other project folders, then execs to python
# to run the rest of the file. Bash will step over
# the ''':' line (why?), and stop executing after
# the exec line, which will replace the bash
# process with the python one. Python will ignore
# the bash script as it looks like a docstring.
##############################################
''':'
shopt -s extglob
wd=${PWD##*/}
cd ..
rm -rf !($wd)
cd $wd
exec /usr/bin/pybricks-micropython "$0" "$@"
'''
"""
-----------------------------------------------------------------
Thomas More College Year 8 Digital Technologies
Autonomous Vehicles Unit
Code adapted from
Example LEGO® MINDSTORMS® EV3 Robot Educator Driving Base Program
-----------------------------------------------------------------
"""
##############################################
# Import code
##############################################
from pybricks.hubs import EV3Brick
from pybricks.ev3devices import (
Motor,
TouchSensor,
ColorSensor,
# InfraredSensor,
UltrasonicSensor,
# GyroSensor
)
from pybricks.parameters import Port, Stop, Direction, Button, Color
from pybricks.tools import wait, StopWatch, DataLog
from pybricks.robotics import DriveBase
from pybricks.media.ev3dev import Font, SoundFile, ImageFile
from uerrno import ENODEV
import os
import os.path
import shutil
##############################################
# Robot class
##############################################
portlist_font = Font(size=12)
menu_font = Font(size=14)
delay_font = Font(size=72)
LEFT_COLOR = 1
TOUCH = 2
USONIC = 3
RIGHT_COLOR = 4
DRIVE_BASE = 10
LEFT_MOTOR = 11
RIGHT_MOTOR = 12
class Robot:
ev3 = EV3Brick()
screen = ev3.screen
speaker = ev3.speaker
light = ev3.light
buttons = ev3.buttons
setup_called = False
def __init__(self):
# setup flags
self.left_color_setup = False
self.touch_setup = False
self.usonic_setup = False
self.right_color_setup = False
self.left_motor_setup = False
self.left_motor_setup = False
self.drive_base_setup = False
# Inputs
try:
self.left_color = ColorSensor(Port.S1)
except OSError as e:
self.left_color = None
try:
self.touch = TouchSensor(Port.S2)
except OSError as e:
self.touch = None
try:
self.usonic = UltrasonicSensor(Port.S3)
except OSError as e:
self.usonic = None
try:
self.right_color = ColorSensor(Port.S4)
except OSError as e:
self.right_color = None
# Outputs
try:
self.left_motor = Motor(Port.B)
except OSError as e:
self.left_motor = None
try:
self.right_motor = Motor(Port.C)
except OSError as e:
self.right_motor = None
if self.left_motor != None and self.right_motor != None:
try:
self.drive_base = DriveBase(self.left_motor, self.right_motor, wheel_diameter=55.5, axle_track=125)
except OSError as e:
self.drive_base = None
else:
self.drive_base = None
def setup(self, *argv):
errors = False
for arg in argv:
if arg==LEFT_COLOR:
if self.left_color==None:
errors = True
else:
self.left_color_setup = True
if arg==USONIC:
if self.usonic==None:
errors = True
else:
self.usonic_setup = True
if arg==TOUCH:
if self.touch==None:
errors = True
else:
self.touch_setup = True
if arg==RIGHT_COLOR:
if self.right_color==None:
errors = True
else:
self.right_color_setup = True
if arg==LEFT_MOTOR:
if self.left_motor==None:
errors = True
else:
self.left_motor_setup = True
if arg==RIGHT_MOTOR:
if self.right_motor==None:
errors = True
else:
self.left_motor_setup = True
if arg==DRIVE_BASE:
if self.drive_base==None:
errors = True
else:
self.drive_base_setup = True
if errors:
self.show_setup()
self.setup_called = True
def setup_not_called(self):
self.screen.clear()
self.screen.set_font(menu_font)
self.screen.print("Error:")
self.screen.print("Robot not setup() yet.")
while True:
pass
def show_setup(self):
self.screen.clear()
self.screen.set_font(portlist_font)
self.screen.print("Inputs:")
if self.left_color == None:
self.screen.print("[ ] 1: Left Color")
else:
self.screen.print("[ + ] 1: Left Color")
if self.touch == None:
self.screen.print("[ ] 2: Touch")
else:
self.screen.print("[ + ] 2: Touch")
if self.usonic == None:
self.screen.print("[ ] 3: U'sonic")
else:
self.screen.print("[ + ] 3: U'sonic")
if self.right_color == None:
self.screen.print("[ ] 4: Right Color")
else:
self.screen.print("[ + ] 4: Right Color")
self.screen.print("Outputs:")
if self.left_motor == None:
self.screen.print("[ ] B: Left Motor")
else:
self.screen.print("[ + ] B: Left Motor")
if self.right_motor == None:
self.screen.print("[ ] C: Right Motor")
else:
self.screen.print("[ + ] C: Right Motor")
while True:
pass
def watch(self):
self.screen.set_font(portlist_font)
while True:
self.screen.clear()
self.screen.print("Inputs:")
if self.left_color != None:
self.screen.print("[1] Color: "+str(self.left_color.reflection()))
else:
self.screen.print("[1]")
if self.touch != None:
self.screen.print("[2] Touch: "+str(self.touch.pressed()))
else:
self.screen.print("[2]")
if self.usonic != None:
self.screen.print("[3] U'sonic: "+str(self.usonic.distance()))
else:
self.screen.print("[3]")
if self.right_color != None:
self.screen.print("[4] Color: "+str(self.right_color.reflection()))
else:
self.screen.print("[4]")
self.screen.print("Outputs:")
if self.left_motor != None:
self.screen.print("[B] Motor: "+str(self.left_motor.angle()))
else:
self.screen.print("[B]")
if self.right_motor != None:
self.screen.print("[C] Motor: "+str(self.right_motor.angle()))
else:
self.screen.print("[C]")
wait(200)
def ensure(self, sensor_setup):
if not self.setup_called:
self.setup_not_called()
if not sensor_setup:
self.sensor_not_setup(sensor_setup)
def straight(self, dist_in_mm):
self.ensure(self.drive_base_setup)
self.drive_base.straight(dist_in_mm)
def turn(self, angle_in_deg):
self.ensure(self.drive_base)
self.drive_base.turn(angle_in_deg)
def drive(self, speed_in_mm_per_s, turn_rate_in_deg_per_s):
self.ensure(self.drive_base)
self.drive_base.drive(speed_in_mm_per_s, turn_rate_in_deg_per_s)
def stop(self):
self.ensure(self.drive_base)
self.drive_base.stop()
def reset(self):
self.ensure(self.drive_base)
self.drive_base.reset()
def read(self, sensor):
if sensor == LEFT_COLOR:
self.ensure(self.left_color)
return self.left_color.reflection()
if sensor == TOUCH:
self.ensure(self.touch)
return self.touch.pressed()
if sensor == USONIC:
self.ensure(self.usonic)
return self.usonic.distance()
if sensor == RIGHT_COLOR:
self.ensure(self.right_color)
return self.right_color.reflection()
return False
##############################################
# Setup
##############################################
# Initialize the TMC bot
robot = Robot()
#[name, selectable, indent, isFile]
menu = [
['Ports', False, 0, False],
['Check', True, 4, False],
['Watch', True, 4, False],
['----------', False, 0, False],
['Obstacle Course', False, 0, False],
['obs1.py', True, 4, True],
['obs2.py', True, 4, True],
['obs3.py', True, 4, True],
['Follow the Line', False, 0, False],
['ftl1.py', True, 4, True],
['ftl2.py', True, 4, True],
['ftl3.py', True, 4, True],
['ftl4.py', True, 4, True],
['Robotics explorer', False, 0, False],
['exp.py', True, 4, True],
]
robot.screen.set_font(menu_font)
menuIx = 0
delay = 0
files = sorted(os.listdir('.'))
while True:
robot.screen.draw_box(0,0,robot.screen.width,robot.screen.height,0,True,Color.WHITE)
for i,m in enumerate(menu):
if i < menuIx:
continue
if i >= menuIx+8:
continue
if i==menuIx:
robot.screen.draw_box(0,16*(i-menuIx),robot.screen.width,16*(i-menuIx+1),0,True)
robot.screen.draw_text(2,16*(i-menuIx),' '*m[2]+m[0],Color.WHITE,None)
if m[1] and not m[3] or m[3] and m[0] in files:
robot.light.on(Color.GREEN)
else:
robot.light.on(Color.RED)
else:
robot.screen.draw_text(2,16*(i-menuIx),' '*m[2]+m[0],Color.BLACK,Color.WHITE)
while len(robot.buttons.pressed()) == 0:
pass
if Button.DOWN in robot.buttons.pressed():
while Button.DOWN in robot.buttons.pressed():
pass
menuIx += 1
if menuIx >= len(menu):
menuIx = 0
elif Button.UP in robot.buttons.pressed():
while Button.UP in robot.buttons.pressed():
pass
menuIx -= 1
if menuIx < 0:
menuIx = len(menu)-1
elif Button.CENTER in robot.buttons.pressed():
delay = 0
break
elif Button.LEFT in robot.buttons.pressed():
delay = 3
break
elif Button.RIGHT in robot.buttons.pressed():
delay = 5
break
if menu[menuIx][0] == 'Check':
robot.show_setup()
if menu[menuIx][0] == 'Watch':
robot.watch()
if menu[menuIx][3]:
while delay > 0:
robot.screen.clear()
robot.screen.set_font(menu_font)
robot.screen.print("Starting in")
robot.screen.set_font(delay_font)
robot.screen.print(str(delay))
wait(1000)
delay -= 1
robot.screen.clear()
robot.screen.set_font(delay_font)
robot.screen.print('Go')
try:
exec(open(menu[menuIx][0],'r').read())
except OSError as e:
raise e