What the car senses
- Corner 1: wall ahead; the turret sees the right is open → turn right.
- Corner 2: wall ahead; the turret sees the right is open → turn right.
- Corner 3: wall ahead; right is blocked, left is open → turn left.
- Corner 4: wall ahead; right is blocked, left is open → turn left.
- Green tile under the car → stop and play the sound.
Make these My Blocks
- turn rightmotor D go to position 60° → move forward for 20 cm → motor D go to position 0° · Start values — tune until the car ends up facing sideways.
- turn leftmotor D go to position -60° → move forward for 20 cm → motor D go to position 0° · Mirror of turn right.
- turn aroundturn left → turn left · Two 90° turns make a U-turn inside the lane. Needs room in front to swing.
- look aroundmotor C go to position 90° → wait 0.2 s → set right_open to distance sensor B is farther than 30 cm → motor C go to position -90° → wait 0.3 s → set left_open to distance sensor B is farther than 30 cm → motor C go to position 0° · Look right, look left, face ahead again. 30 cm = about one lane width — measure yours.
- celebrateset hub light to green → play beep 80 for 0.5 s → play beep 100 for 0.5 s · Sound + light on the tile.
Word Blocks
- when program starts
- set movement motors to A + Euse the ports from YOUR car
- set movement speed to 30 %
- repeat until color sensor F sees green
- start moving forward
- wait until distance sensor B closer than 20 cm or color sensor F sees greena wall ahead, or the finish
- stop moving
- if not color sensor F sees green
- look aroundturret scans right then left, sets right_open and left_open
- if right_openthe right-hand rule: right first
- turn rightMy Block
- else if left_open
- turn leftMy Block
- elseright and left and ahead are all blocked: a dead end
- turn aroundMy Block: two turns in a row
- celebrateMy Block: sound + light
Same thing in Python
from hub import port, sound, light_matrix
import runloop, motor, motor_pair, distance_sensor, color_sensor, color
DRIVE = motor_pair.PAIR_1
STEER = port.D # large motor, steers the back
TURRET = port.C # large motor that swings the distance sensor
EYES = port.B # distance sensor (rides on the turret)
BELLY = port.F # color sensor pointing down
STOP_MM = 200 # wall closer than 20 cm ahead = stop and look
OPEN_MM = 300 # farther than this = OPEN (about one lane width - measure yours!)
LOOK_RIGHT = 90 # turret position that looks right (tune for your gearing)
LOOK_LEFT = -90 # turret position that looks left
DEG_PER_CM = 20 # wheel degrees per cm: tune
TURN_CM = 20 # roll while steering: tune
def wall_closer_than(mm):
d = distance_sensor.distance(EYES)
return 0 < d < mm
def on_color(c):
return color_sensor.color(BELLY) == c
async def drive_cm(cm, speed=300):
await motor_pair.move_for_degrees(DRIVE, int(cm * DEG_PER_CM), 0, velocity=speed)
async def turn_right():
await motor.run_to_absolute_position(STEER, 60, 500)
await drive_cm(TURN_CM)
await motor.run_to_absolute_position(STEER, 0, 500)
async def turn_left():
await motor.run_to_absolute_position(STEER, -60, 500)
await drive_cm(TURN_CM)
await motor.run_to_absolute_position(STEER, 0, 500)
async def turn_around():
await turn_left() # two 90-degree turns = a U-turn inside the lane
await turn_left()
async def celebrate():
light_matrix.show_image(light_matrix.IMAGE_HAPPY)
await sound.beep(880, 300)
await sound.beep(1175, 500)
async def look_open(angle):
"""Swing the turret to 'angle' and say whether that way is OPEN."""
await motor.run_to_absolute_position(TURRET, angle, 700)
await runloop.sleep_ms(200) # let the sensor settle
d = distance_sensor.distance(EYES) # -1 = nothing seen = wide open
return d == -1 or d > OPEN_MM
async def look_around():
right_open = await look_open(LOOK_RIGHT)
left_open = await look_open(LOOK_LEFT)
await motor.run_to_absolute_position(TURRET, 0, 700) # face ahead again
return right_open, left_open
async def drive_until_wall_or(stop_color):
"""Drive until a wall is close ahead, or stop_color is under the car."""
motor_pair.move(DRIVE, 0, velocity=300)
await runloop.until(lambda: wall_closer_than(STOP_MM) or on_color(stop_color))
motor_pair.stop(DRIVE)
async def hug_right_wall_until(stop_color):
"""Stop-and-look maze solver (right-hand rule). Returns (route, dead_ends)."""
route = []
dead_ends = 0
while not on_color(stop_color):
await drive_until_wall_or(stop_color)
if on_color(stop_color):
break
right_open, left_open = await look_around()
if right_open:
await turn_right()
route.append("R")
elif left_open:
await turn_left()
route.append("L")
else: # all sides blocked: a dead end
await turn_around()
dead_ends += 1
route.append("U")
return route, dead_ends
async def main():
motor_pair.pair(DRIVE, port.A, port.E) # your drive motor ports
await hug_right_wall_until(color.GREEN)
await celebrate()
runloop.run(main())
Starting values only. Steering angle, roll distances, the OPEN limit and the line target depend on your car and maze. Measure, then tune one at a time. I have not run these on a car — expect to adjust.
Ready for more?
- Run the mirrored S-Curve with the same program.
- Change the 30 cm OPEN number. What is the smallest that still works?