Base Mission
7 points Live judgedA robot is Botguy.
Unit 2 · Big Idea 3
Student Lab · Touch Botguy with Encoders
Student PIN:
Until now, your robot drove for a set time and hoped it went the right distance — and last lab proved how inconsistent that can be. Today the robot measures its own wheels. Each motor has a built-in counter that up as it turns. By watching that counter, the robot can drive an exact distance instead of an exact time. You’ll use this to drive out from the starting box and touch Botguy — Mission 9.
Core Insight
A robot that can measure its own movement can act precisely. Instead of “drive for one second,” it can say “drive until I’ve turned exactly this far.”
gmpc() and reset it with cmpc().Watch the counter move --- before any code
On the Wombat controller, open the motors / graph widget (the live readout screen). Find the position counter for the motor on 0.
Now turn that wheel by hand, slowly. Watch the number on the screen climb as the wheel turns forward, and fall as you turn it backward. Those are ticks — the counter is counting how far the wheel has rotated.
This is where your robot’s movement data lives. When your code reads gmpc(0), it is reading this exact number.
Turn the port-0 wheel one full turn by hand. About how many ticks did the counter change? Write the number you saw.
Each motor counts how far it has turned, in ticks. Two commands let you use that counter:
cmpc(0); // CLEAR: reset port 0's counter back to 0
gmpc(0); // GET: read how many ticks port 0 has turned
The pattern is: clear the counter to zero, start driving, and keep checking the counter until it reaches the distance you want.
cmpc(0); // start counting from 0
while (gmpc(0) < 2000) // while we haven't gone 2000 ticks yet...
{
motor(0, 50); // ...keep driving
motor(3, 50);
msleep(10);
}We’re reading just port 0 for now. Later, we may come back and read both wheels at once to help the robot drive straighter.
Last unit, your loop watched a touch sensor: digital(0) was only ever 0 or 1 — two possibilities. This loop watches a counter that climbs through thousands of values: 0, 1, 2, … all the way up to your target.
The condition gmpc(0) < 2000 stays true while the count is below 2000, and flips false the instant it reaches it. The loop isn’t waiting for an on/off — it’s waiting for a number to grow big enough.
So far your functions ran the same way every time. A parameter is the named input in a function’s prototype or definition. An argument is the value you supply when you call the function.
void Tick_Drive(int ticks); // PARAMETER: the named input is ticks
Tick_Drive(2000); // ARGUMENT: pass in the value 2000
Tick_Drive(1000); // ARGUMENT: pass in 1000 instead
Inside the function, the parameter ticks receives whichever argument you supplied. One function, any distance — no copying and pasting.
Imagine you’re told “walk to the door.” You could guess at the time it takes — or you could count your steps. If the door is 10 steps away, you walk until your step count reaches 10, then stop. You’re not timing yourself; you’re measuring your own movement and stopping at a number.
Think it through
Why is “walk until I’ve taken 10 steps” more reliable than “walk for 6 seconds”?
The robot’s wheel counter is its version of counting steps. What is one “step” for the robot called?
How is counting your steps to a target like the robot counting encoder ticks to a target? Why does measuring movement beat guessing at time?
Earlier sensors told the robot about the outside world — a wall, a button. An encoder is different: it tells the robot about itself — how far its own wheels have turned. This is called feedback: the robot watches the result of its own action and uses it to decide when to stop.
You’ve built functions that always did exactly the same thing. In void Tick_Drive(int ticks), ticks is the parameter: the named input in the function. In Tick_Drive(2000), 2000 is the argument: the value supplied at that call. Tick_Drive(2000) and Tick_Drive(1000) call the same function with different arguments, so it drives two different distances.
Why this matters for a real run
To touch Botguy you need one exact distance. But a whole mission needs many different distances. With an argument, you write Tick_Drive() once and call it with whatever number each leg of the trip needs — instead of writing a new function for every distance.
In your own words: what is the parameter in void Tick_Drive(int ticks), and what is the argument in Tick_Drive(2000)? How does changing the argument change what the function does?
Mission 9
A robot is Botguy.
Botguy is outside the enclosure AND is touching the warehouse floor.
Your goal today is simply to touch Botguy. The bonus mission requires removing Botguy from his and getting him to the warehouse floor. That needs an arm, which is a manipulation task for a future lesson.
You need to know how many ticks it takes to reach Botguy. Use the motor graph: clear the counter, drive toward Botguy by hand or with a short test, and read the tick count when the robot reaches him. Write your best target.
| Measurement | Your value (ticks) |
|---|---|
| Ticks from start box to Botguy |
Describe your program in order — including clearing the counter, the loop, and the brake.
⚠ Test in your hands first
Hold the robot off the ground and run the program once. Watch the wheels spin and then brake to a stop on their own when the count is reached — before you put it on the field toward Botguy.
Type this program. Notice that int ticks is the parameter in the Tick_Drive prototype and definition. The value in a call such as Tick_Drive(2000) is the argument. above main(), definition below, as always.
// Unit 2, Big Idea 3: Drive by the Numbers
// Name: _______________________ Date: ___________
#include <kipr/wombat.h>
void Tick_Drive(int ticks); // PROTOTYPE: ticks is the parameter
int main()
{
Tick_Drive(2000); // CALL: 2000 is the argument
// (use YOUR target number from Phase 3)
return 0;
}
void Tick_Drive(int ticks) // DEFINITION: ticks receives the argument
{
cmpc(0); // clear port 0's counter to 0
while (gmpc(0) < ticks) // while we haven't reached the target...
{
motor(0, 50); // ...keep driving
motor(3, 50);
msleep(10);
}
motor(0, 0); // BRAKE (from last lab)
motor(3, 0);
msleep(50); // let the brake settle
}Run it, see where the robot stops, and adjust the number you pass to Tick_Drive() until it reaches Botguy. Record each try.
| Try | Ticks you passed in | Where the robot stopped (short / on Botguy / too far) |
|---|---|---|
| 1 | ||
| 2 | ||
| 3 | ||
| 4 |
ticks is the parameter in (int ticks) in both the prototype and the definitionTick_Drive(2000) is the argumentcmpc(0) clears the counter before the loopgmpc(0) < ticksmotor(0,0); motor(3,0); msleep(50); after the loopCommon encoder bugs
Forgot cmpc(0): the counter still holds ticks from a previous run, so the robot stops early (or doesn’t move). Always clear before the loop.
Robot never stops: if the motors aren’t actually turning port 0, gmpc(0) never climbs and the loop runs forever. Check your wiring and that you’re reading the right port.
Brake missing: no motor(0,0) after the loop means the robot coasts past Botguy — remember last lab.
| Try | What went wrong | Why (your best guess) | How you fixed it |
|---|---|---|---|
| 1 | |||
| 2 | |||
| 3 | |||
| 4 |
Once Botguy works, try calling Tick_Drive() twice with different numbers in a row. What happened? Why is one flexible function better than writing a separate function for each distance?
Big Idea --- AI Literacy Thread
Intelligent systems sense their own actions and use that feedback to act precisely.
Your robot didn’t just act — it watched itself act and stopped at exactly the right point. That’s feedback, and it’s everywhere in intelligent systems. A 3D printer counts the steps of its motors to place plastic precisely; a robot arm in a factory knows the angle of every joint; a self-driving car tracks its own wheel rotation to know how far it’s gone. None of them guess — they measure their own motion and adjust. Today your robot joined them: it sensed its own wheels and used that number to reach a goal.
Read each scenario. Think it through, then write your answer.
A delivery robot needs to stop exactly at a doorway. Why is “count my own wheel turns” more reliable than “drive forward for 4 seconds”? What could change between runs that time can’t account for?
An encoder is a system sensing itself, not the outside world. Why is it powerful for an intelligent system to have information about its own actions, not just its surroundings?
Complete this section on your own.
1. What do cmpc(0) and gmpc(0) each do? Why must you clear before you read in a loop?
2. What is the difference between a parameter and an argument? Identify each one in void Tick_Drive(int ticks) and Tick_Drive(2000), then explain how one function can drive many distances.
3. This loop exits on a number climbing to a target, not an on/off button. How is that different from the touch-sensor loop you wrote before?
4. Complete this in 2–3 sentences: “Intelligent systems sense their own actions and use that feedback to act precisely. This means a robot that can measure its own movement can…”
Finished early? Try one or more of these.
Tick_Drive() with one number, then a turn, then Tick_Drive() with another number, to reach Botguy on an L-shaped path.gmpc(0) and the other drive motor’s counter side by side as the robot drives. Do they climb at exactly the same rate?Tick_Drive() handle backward too? Think about what the counter does when the wheel turns backward, and what your loop condition would need.Download saves a local copy of your answers. It does not turn in your work automatically; give the downloaded file to your teacher.
KIPR · Botball Explorer · Unit 2 Big Idea 3 — Student Lab