Project: precision parking
Round a box and into a bay facing east, on the worst robot in the course.
Do this lesson in the simulatorA box in the middle of the mat, a parking bay in the far corner, and the worst robot in the course: it curves and it leaks. Get round the box, into the bay, and finish facing east. Every controller from this module, in one program.
The plan
# start at the bottom left, facing up
# 1. hold the line x = 0 (relative) up the left side of the box, to y = 67
# 2. slide right along the top of the box, holding y = 67 and heading 0, to x = 55
# 3. turn to face 90 and hold it
position() is relative to the start, so x = 0 means "the line I started on", which passes left of the box. Look at the scene before you run anything.
Leg one as a function
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
def wrapped(h):
return (h + 180) % 360 - 180
def hold_line(target_x, until_y):
while position()[1] < until_y:
# where am I? (cm from where I started)
x, y = position()
# forward, sideways, rotation: -100 to 100 each, until the next command
drive(70, (target_x - x) * 10, wrapped(0 - heading()) * 4)
# pause 0.1 s (the robot keeps doing what it was told)
wait(0.1)
# all motors off
stop()
hold_line(0, 67)
print("top of leg one:", position(), "facing", round(heading()))
Leg two: sideways, holding two things
Now the robot slides right. The forward part of drive holds y, the rotation holds the heading, and the sideways part is the speed:
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
def wrapped(h):
return (h + 180) % 360 - 180
def hold_line(target_x, until_y):
while position()[1] < until_y:
# where am I? (cm from where I started)
x, y = position()
# forward, sideways, rotation: -100 to 100 each, until the next command
drive(70, (target_x - x) * 10, wrapped(0 - heading()) * 4)
# pause 0.1 s (the robot keeps doing what it was told)
wait(0.1)
# all motors off
stop()
def slide_right(target_y, until_x):
while position()[0] < until_x:
# where am I? (cm from where I started)
x, y = position()
# forward, sideways, rotation: -100 to 100 each, until the next command
drive((target_y - y) * 10, 70, wrapped(0 - heading()) * 4)
# pause 0.1 s (the robot keeps doing what it was told)
wait(0.1)
# all motors off
stop()
hold_line(0, 67)
slide_right(67, 55)
print("end of leg two:", position(), "facing", round(heading()))
Leg three: turn and hold
A heading controller with no driving, the proper version of lesson 3.1:
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
def wrapped(h):
return (h + 180) % 360 - 180
def hold_heading(target):
error = wrapped(target - heading())
while abs(error) > 2:
# forward, sideways, rotation: -100 to 100 each, until the next command
drive(0, 0, max(-60, min(60, error * 3)))
# pause 0.05 s (the robot keeps doing what it was told)
wait(0.05)
error = wrapped(target - heading())
# all motors off
stop()
hold_heading(90)
# pause 0.5 s (the robot keeps doing what it was told)
wait(0.5)
print("facing", round(heading(), 1))
Task: precision parking
Reach the bay without touching the box and finish facing 90, within 6 degrees.
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
def wrapped(h):
return (h + 180) % 360 - 180
def hold_line(target_x, until_y):
while position()[1] < until_y:
# where am I? (cm from where I started)
x, y = position()
# forward, sideways, rotation: -100 to 100 each, until the next command
drive(70, (target_x - x) * 10, wrapped(0 - heading()) * 4)
# pause 0.1 s (the robot keeps doing what it was told)
wait(0.1)
# all motors off
stop()
hold_line(0, 67)
Where next
The Precision Park competition is this project against the clock: three bays, each smaller than the last, and points for stopping dead centre and square. Module 4 gives the robot a camera so it can control on what it sees, not just where it thinks it is.
Challenges
- Park in under 10 seconds.
- Go round the right of the box instead and arrive from below.
- Write
go_to(x, y)that drives to any point usingmath.atan2for the heading and the two-loop line holder, and park with two calls to it.