Wall Following
Sample code May 2025
It has a Screen, TV remote and Bluetooth
This is a work in progress .....
8th May: view May5.py ..
10th May: view may9.py .
Ideas December 2024
This is a competition that is run by a robot that can sense walls.
The wall in front, the walls on the left and right.
It starts in the starting cell, and makes a timed run, until it reaches the target cell.
Unlike maze solving, it doesn't have to recognize the finish cell, or plan a route to get there.
Instead it follows a simple set of rules for how to progress from the current cell.
- If there is a wall to the left, and none in front - Go forward
- If there is no wall to the left, turn left
- If there are walls to the left and in front, but none to the right - turn right
- If there are walls on the left, front and right, Spin round
Wall follower logic.
The robot should follow the path of the wall seen on its left hand side.
Functional steps in the worksheet
----------------
<Image of corridor with blocked ends>
-------------------------------------------------
Step 1: Corridor
Steer straight along the corridor (using left sensor only):
Measure the left sensor.
Use the difference between this value and the left threshold, to calculate error.
Use the error to calculate motor speed difference.
Extras:
1a: set up thresholds (Left, front) by recording readings when the button is first pressed.
Use a second button press to start motion.
1b: stop if getting close to front wall.
The student should tune the motor speed, the left wall threshold, and the “mult” steering strength,
to get a stable central path.
Derivative steering is probably not needed.
The front sensor stop threshold should make it stop at the right point to turn left or right.
----------------
<Image of corridor with blocked ends>
<Image of corridor with right turn St end>
-------------------------------------------------
Step 2 spin right if front and left sensor both see walls
Stop spinning when the front sensor reading gets very low.
(tune value/time)
[This will give 90 or 180 degree right spins. ]
This is about getting the motor speeds and the sensor thresholds right for 90 degree and 180 degree spins.
There might be issues with the front sensor reading dropping when it points at the corner,after 45 degrees.
The issue of overshoot needs to be considered.(Turning too far)
-------------------------------------------------
Step 3 steer round left corner (tune minimum left speed)
all done on left sensor.
[Might need to ignore front sensor if steering hard left]
<Image of corridor with left 90 degree turn >
<Image of corridor with left 180 degree turn >
The left turn can be performed as part of the corridor steering.
The “error” should be limited (the left wall reading will drop to approx zero),
so that the robot steers a smooth left turn (not spin).
Because the left side sensor is pointing forwards,
the robot may start the turn too early, and graze the left wheel against the corner.
A delay (before starting the turn) may be needed.
The robot would go straight ahead during this delay.
The delay should happen only on first seeing the left sensor reading fall drastically.
It should happen only once.
This will require close monitoring of left sensor changes,
and keeping a record of time since the start of a left turn happened.
An additional left pointing sensor would be a better way of doing it.
Maybe pointing the left sensor further back would be a solution.
-------------------------------------------------
Step 4 Speeding things up
See how far you can get by just increasing the speed.
Eventually, the momentum of travelling so fast will upset the right spin, and the left turn.
The speed can be reduced prior to the right spin, by monitoring the front sensor in the corridor run, and slowing when a wall is seen a long way ahead.
The delay part of the left turn can be shortened as well as being at its normal, slow speed. I suggest that the left turn be done at the same speed, not at the faster speed.
As it enters a cell it can do 4 things:
- Turn left,
- go ahead,
- turn right, (spin actually )
- U turn(180 degrees).
-------------------------------------------------
Step 5. User interface
Pressing the button to stop Initial wall-scanning,
and then again to start the run can be difficult.
Therefore the race should be started by waving ones hand in front of the robot.
The robot should flash the LED while awaiting a wave.
The loop time should be small (0.05), so therefore the LED should be toggled only evey 10 loops.
A User Instruction sheet should be written to explain how to start it.
Program Logic:
It should test for a left wall and a front wall.
If it sees no left wall, it should turn left.
else..(seeing a left wall)
if it sees no front wall it can continue straight ahead.
If it sees a front wall, and a right wall it should turn right 180 degrees.
If it sees a front wall, and no right wall it should turn right 90 degrees.
1. Python Imports
========
from machine import Pin, PWM, ADC
import time
1a Tuning variables
================
mult = 10 # strength of steering
speed = 6000 # how fast
# for step 3…
leftmin =2500 # Left min speed
2 Setting up pins
============= outputs =======
trigger = Pin(14, Pin.OUT) # Wall illumination LED:
led = Pin(25, Pin.OUT) # LED on the Pico board
ledL = Pin(13, Pin.OUT) # Left hand LED on sensor board
ledR = Pin(8, OUT) # Right hand LED on sensor board
============= inputs ========
Lsensor = ADC(27) # left wall
Msensor = ADC(26) # front wall
Rsensor = ADC(28) # right wall
# push button
button = machine.Pin(22,Pin.IN,Pin.PULL_DOWN)
# the 4 switches (1 is the left hand switch)
SW1 = Pin(0, Pin.IN, Pin.PULL_UP)
SW2 = Pin(1, Pin.IN, Pin.PULL_UP)
SW3 = Pin(2, Pin.IN, Pin.PULL_UP)
SW4 = Pin(3, Pin.IN, Pin.PULL_UP)
#Set up motor outputs....
# Direction 0= forward 1= reverse
left_dir = Pin(9, Pin.OUT)
right_dir = Pin(10, Pin.OUT)
# Motor speed control, (must be in range 0-65535)
left_pwm = PWM(Pin(11))
right_pwm = PWM(Pin(12))
# Pulse rate of PWM controller
left_pwm.freq(1000)
right_pwm.freq(1000)
# === Function to read wall sensors
def readWalls():
trigger.off() # Switch off wall illumination
time.sleep(0.005) # wait for light to take effect
LMin = Lsensor.read_u16() # Read left wall
MMin = Msensor.read_u16() # Read front wall
RMin = Rsensor.read_u16() # Read right wall
trigger.on() # Switch on wall illumination
time.sleep(0.005) # wait for light to take effect
MMax = Msensor.read_u16() # Read left wall
RMax = Rsensor.read_u16() # Read front wall
LMax = Lsensor.read_u16() # Read right wall
trigger.off() # Switch off wall illumination
Lside = LMax - LMin
Mside = MMax - MMin
Rside = RMax - RMin
return Lside, Mside, Rside
# ===== Program starts here ====
# Show wall values
# -until button is pressed
while True:
(leftThresh, frontThresh, rightThresh) = readWalls()
print(leftThresh,frontThresh,rightThresh)
time.sleep(0.1)
if button.value() == 1:
break
# Wait till button is released
while button.value() == 1:
pass
# Wait till button is pressed again
while button.value() == 0:
pass
# === Move and steer ========
while True:
(l,f,r) = readWalls()
if f > frontThresh:
break
error = l-leftThresh
# calculate speed difference
sDiff = error*mult
#==== Calculate motor speeds
lSpeed = max(speed+sDiff,0) # Must be >0
lSpeed = min(lSpeed,65000) # Must be <= 65535
rSpeed = max(speed-sDiff,0) # Must be >0
rSpeed = min(rSpeed,65000) # Must be <= 65535
#== output to motors
left_pwm.duty_u16(lSpeed) #Left motor speed
right_pwm.duty_u16(rSpeed) #Right motor speed
# Exit loop when button pressed
if button.value() == 1:
break
# Stop motors
left_pwm.duty_u16(0)
right_pwm.duty_u16(0)
End of step 1: corridor steering that stops at the end
_____________________________
Step 2: spin right at end of corridor
Step 2a: spin 90 degrees for right turn and 180 degrees for I turn
_____________________________
Step 3: Gentle turn round left.
3a: 90 degrees and 180 degrees according to track.
Make sDiff have a minimum negative value that keeps the turn gentle.
Use leftmin as minimum left speed
and rightmax as max right speed
rightmax= speed + (speed-leftmin)
Diary
See the latest program
8th November 2024
WE fixed the bug that caused finger contact with the underside of the circuit board to be a button press.
Also the staggering movements that were happening at the last session
See the latest program
© Copyright St Albans Robots