The depth grid
64 readings, 8 columns: seeing left and right, not just ahead.
Do this lesson in the simulatordistance() is one number: straight ahead. The sensor actually measures 64 distances at once, in an 8 by 8 grid across a 45 degree view. That grid is how the robot sees left and right, and it is the raw material for finding gaps and avoiding things.
tof_grid()
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
# 64 distances, 8 rows of 8
grid = tof_grid()
print("readings:", len(grid))
print("row 3, level:", grid[24:32])
print("row 7, the mat:", grid[56:64])
64 numbers in a list, in centimetres. They are arranged in 8 rows of 8, and the rows look up and down: row 0 is the top of the view, row 7 the bottom. The sensor sits 3 cm above the mat, so the bottom rows see the mat itself a few centimetres ahead, and the top rows look over most things and see nothing. Rows 2 and 3 look level, straight ahead. Column 0 is the left edge of the view, column 7 the right.
Seeing it as a picture
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
# 64 distances, 8 rows of 8
grid = tof_grid()
# do this 8 times (row counts from 0)
for row in range(8):
line = ""
# do this 8 times (col counts from 0)
for col in range(8):
d = grid[row * 8 + col]
line += "#" if d < 40 else ("+" if d < 80 else ".")
print(line)
# is close, + medium, . far. The bottom rows are always #: that is the mat. The two blocks show up in the level rows, with the gap between them. Drive forward(60, distance=20) before the print and run again and watch the blocks fill more of the picture.
Columns are directions
Each column looks in a slightly different direction. Column 0 looks about 20 degrees left, column 7 about 20 degrees right, columns 3 and 4 straight ahead. Only the level rows are worth reading for this: the rows below them see the mat. distance() is the smallest reading in the middle columns of the level rows.
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
# 64 distances, 8 rows of 8
grid = tof_grid()
# do this 8 times (col counts from 0)
for col in range(8):
# the level rows
nearest_in_col = min(grid[row * 8 + col] for row in (2, 3))
print(f"column {col}: {nearest_in_col} cm")
This is the useful form: one number per direction.
Left and right
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
# 64 distances, 8 rows of 8
grid = tof_grid()
left_side = min(grid[row * 8 + 0] for row in (2, 3))
right_side = min(grid[row * 8 + 7] for row in (2, 3))
print("left:", left_side, "right:", right_side)
if left_side < right_side:
print("more room on the right")
else:
print("more room on the left")
Task: widest gap
There are two blocks ahead, one left and one right, with a gap between. Without moving, print clear: column <n> for the column with the largest reading in the level rows: that is the way through.
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
# 64 distances, 8 rows of 8
grid = tof_grid()
best_col = 0
best = 0
# find the column whose reading in the level rows is the largest
print("clear: column", best_col)
Challenges
- Print the grid picture every half second while driving slowly forward.
- Write
column_distances()that returns the 8 per-column numbers from the level rows as a list. - Steer towards the widest gap: strafe left if it is in columns 0 to 3, right if 4 to 7, then drive forward.