Unit 4 · Big Idea 2
Squaring Up
Student Lab · Two Sensors, Two Wheels, One Straight Line
Student PIN:
Overview
A robot that drives “mostly straight” slowly turns crooked — and a crooked robot misses everything it’s aiming for. Today you’ll fix that with a square-up: using two front sensors, the robot lines itself up perfectly straight against a line, fixing its own heading. This is your setup move for the spilled-cubes mission — squaring up in the right starting box so you can bulldoze straight and true.
Heads-up: this is a first draft
There are a lot of ways to square up, and many are smoother and smarter than this one. We’re starting with the simplest version that works, so you can see the idea clearly. Once you understand it, you’ll have plenty of ideas to make it better — and that’s the point.
By the end of this activity you will be able to:
- Mount and name two front tophat sensors, one per side.
- Let each wheel react to its own sensor independently.
- Use the boolean
andoperator to check two conditions at once. - Square the robot up to a line, skip a gap, and square up on a second line.
Phase 1 — Set Up Two Front Sensors
Until now you had one line sensor. Square-up needs two — one watching each front corner — so the robot can tell if one side reached the line before the other. Move your existing sensor to one side and add a second on the other.
Wiring and names
Mount one tophat sensor at the front-left, one at the front-right. Plug them in so:
TOPHAT_LEFT = k.analog(0) · TOPHAT_RIGHT = k.analog(1)
You’ll add these names to your as , so your code reads k.analog(TOPHAT_LEFT) instead of a bare number — much easier to understand.
# add these to your library, with your other variables
TOPHAT_LEFT = 0 # front-left tophat sensor on analog port 0
TOPHAT_RIGHT = 1 # front-right tophat sensor on analog port 1The key pairing
Each sensor controls the wheel on its own side: TOPHAT_LEFT drives the left wheel k.motor(0), and TOPHAT_RIGHT drives the right wheel k.motor(1). If these get crossed, the robot will chase the line the wrong way — so double-check.
Why does squaring up need two sensors instead of one? What can two sensors tell the robot that one cannot?
Phase 2 — Concept: Each Wheel Watches Its Own Sensor
Picture the robot rolling toward a line at a slight angle. One front corner reaches the black line before the other. Here’s the trick: each wheel only cares about the sensor on its own side.
- If a side’s sensor is still on white (below the midpoint), that wheel keeps driving forward.
- The instant that sensor hits black (above the midpoint), that wheel freezes.
So the side that’s behind keeps creeping forward while the side that arrived waits — and the robot naturally straightens out until both sides are on the line. Then it’s square.
Remember your color convention
Black reads higher than white. So “still on white” means k.analog(...) < MIDPOINT, and “reached black” means the reading has climbed above MIDPOINT.
If the robot approaches the line tilted with its left corner ahead, which wheel reaches black first and freezes? What does the other wheel keep doing until the robot is square?
Phase 3 — New Tool: The and Operator
The square-up is finished only when both sensors are on black at the same time. You need a way to check two conditions together — that’s the logical AND operator, written and in Python.
k.analog(TOPHAT_LEFT) > MIDPOINT and k.analog(TOPHAT_RIGHT) > MIDPOINT
# true ONLY when BOTH sensors are on blackIt’s true only if the thing on its left is true and the thing on its right is true. If either side is still on white, the whole thing is false.
| Left on black? | Right on black? | and result |
|---|---|---|
| no | no | false |
| yes | no | false |
| no | yes | false |
| yes | yes | true |
You want the loop to keep going while it’s NOT yet done. Python’s not keyword flips true and false, so “keep going while we are not yet both-on-black” looks like:
while not (k.analog(TOPHAT_LEFT) > MIDPOINT and k.analog(TOPHAT_RIGHT) > MIDPOINT):
# ... keep squaring up ...When both sensors finally read black, the inside becomes true, not flips it to false, and the loop stops.
In your own words, what does and do? Why is it the right operator for “stop when BOTH sensors are on the line”?
Phase 4 — Build: The square_up
Put it together. The loop runs until both sensors are on black. Inside, each wheel has its own if , checking its own sensor and either driving or freezing. Use a slow speed so it has time to react.
#!/usr/bin/python3
# Unit 4, Big Idea 2: Squaring Up
# Name: _______________________ Date: ___________
import os, sys
sys.path.append("/usr/lib")
import _kipr as k
from yourname import * # has TOPHAT_LEFT, TOPHAT_RIGHT, MIDPOINT
def main():
square_up() # straighten up against the line
def square_up():
# keep going until BOTH sensors are on black
while not (k.analog(TOPHAT_LEFT) > MIDPOINT and k.analog(TOPHAT_RIGHT) > MIDPOINT):
# LEFT wheel watches the LEFT sensor
if k.analog(TOPHAT_LEFT) < MIDPOINT: # still on white?
k.motor(0, 30) # drive the left wheel forward
else: # reached black
k.motor(0, 0) # freeze the left wheel
# RIGHT wheel watches the RIGHT sensor
if k.analog(TOPHAT_RIGHT) < MIDPOINT: # still on white?
k.motor(3, 30) # drive the right wheel forward
else: # reached black
k.motor(3, 0) # freeze the right wheel
k.msleep(10) # small pause so we don't overwork the controller
k.motor(0, 0); k.motor(3, 0) # Both sensors are on black, so stop fully while squared up.
main()⚠ Start slow, hands ready
Use a low speed (around 30) and keep a hand near the robot the first run. If a wheel drives the wrong way or never stops, check your sensor-to-wheel pairing and your MIDPOINT.
Run it from a slight angle. Did the robot straighten out and stop square on the line? Describe what each wheel did.
Phase 5 — Apply: Square Up on Two Lines
Now the full move for the spilled-cubes setup. Starting in the right starting box, the robot squares up on the first line, drives forward just enough to clear that line, then squares up again to land on the second line — straight and true both times.
Use your model from last lab
To skip over the first line, drive a few inches with the Drive function you built: Drive(3.0) moves about 3 inches past the line so your sensors clear it before the second square-up. Adjust the number if your line spacing is different.
def main():
square_up() # straighten up on the FIRST line
Drive(3.0) # skip forward over the line (about 3 inches)
square_up() # straighten up on the SECOND lineSee how clean this reads? Three lines, three clear actions — because square_up and Drive already do the hard work. That’s your library paying off.
Run Log
| Try | What happened (squared line 1? cleared the line? squared line 2?) | What you changed |
|---|---|---|
| 1 | ||
| 2 | ||
| 3 | ||
| 4 |
Did your Drive(3.0) clear the first line cleanly? If the second square-up started while a sensor was still on the first line, what would go wrong — and how would you fix the skip distance?
Phase 6 — Connect: The AI Literacy Bridge
AI Literacy Thread
Intelligent systems use feedback from multiple inputs to correct themselves.
Your robot didn’t just drive blindly — it watched two sensors and corrected its own heading until it was straight. That’s a feedback loop: sense, compare, adjust, repeat, until a goal is met. It’s everywhere in intelligent systems. A plane’s autopilot constantly nudges itself level using multiple sensors; a thermostat watches temperature and corrects; a robot vacuum squares itself to walls. None of them assume they’re aligned — they measure and fix it. You just built the same idea from two sensors and two if statements.
Read each scenario. Think it through, then write your answer.
How is your square-up a “feedback loop”? Name the sense → adjust → repeat steps your robot went through.
We said this is just one simple way to square up. Now that you’ve built it, describe one way you think it could be done better or smoother.
Phase 7 — Individual Reflection
Complete this section on your own.
1. Explain how letting each wheel watch its own sensor makes the robot straighten out.
2. What does the and operator do, and why did the loop need it to know when to stop?
3. Why did you use Drive(3.0) between the two square-ups instead of just squaring up twice in a row?
4. Complete in 2–3 sentences: “Intelligent systems use feedback from multiple inputs to correct themselves. This means that to stay on course, a robot should…”
Extension Challenges
Finished early? Try one or more of these.
Extension A — Add square_up to Your Library
- Move
square_upinto your library, fully commented, so any mission can call it. Where does it belong among your other functions?
Extension B — Tune the Speed
- Try the square-up at speed 20, then 50. Does slower square up more accurately? Does faster the line? Find your best speed.
Extension C — Bulldoze Setup
- This square-up sets you up to bulldoze the spilled cubes. After squaring on the second line, what would your robot do next to push cubes? Sketch the plan in library calls.
Extension D — The Better Way
- Take your idea from Phase 6 for a smoother square-up and try to build it. What changed? Was it actually better?
Extension E — A Basic Building Block of AI
- Your square-up used a sense → compare → adjust loop. Many real AI systems (a self-driving car staying in its lane, a drone stabilizing itself) use this same repeating loop as a basic building block of their decision-making.
- In your own words, describe how a sense-compare-adjust loop like yours could “drive” a bigger AI system — like a self-driving car deciding when to brake.
When you are finished, press the button to turn in your work and save a copy.
KIPR · Botball Explorer · Unit 4 Big Idea 2 — Student Lab