KIPR · Botball Explorer
Activity Sections

Unit 5 · Big Idea 2

Ease On, Ease Off

Student Lab · Driving Like a Car, Not a Light Switch

Unit Guiding Question
How can a machine operate reliably in an imperfect world?
Big Idea
Robust Systems Tolerate Uncertainty
AI Literacy Thread
Reliable systems respond proportionally to how close they are to a goal, instead of acting the same way right up until they suddenly stop.
CS1 Concepts
else if Chains · Multi-Branch · Linear in Code (y = mx + b) · Reliability-Oriented Motor Control
Game Context
Mission 18 — move Botguy to the loading zone (final position judged)
What You Need
Explorer robot · full · Botguy · the game field · this lab sheet
Before you start: type your PIN in the box at the top of the page. Your teacher gave you this number. When you finish, press Submit & Download to turn in your work and save a copy.

Overview

Every Drive() you’ve written so far does the same thing the whole way: full speed, then slam to a stop the instant the count is reached. That works, but think about how a car actually drives — it eases onto the gas, cruises, then eases onto the brake well before the stop sign. It never slams from 60 to 0 in one instant. Today you rebuild Drive() to do the same thing: ease on for the first few ticks, cruise in the middle, and ease off for the last several hundred ticks before the target — using a new tool, the else if chain, to decide which of those three zones the robot is in right now.

The Big Idea of This Unit

A robust system doesn’t treat “far from the goal” and “about to arrive” the same way. It measures how close it is and adjusts its behavior smoothly — proportional response instead of all-or-nothing.

By the end of this activity you will be able to:

  • Explain what an else if chain does and when it’s the right tool versus separate if .
  • Describe motor speed as a linear function of position, in the form y = mx + b.
  • Rebuild Drive() so it accelerates, cruises, and decelerates instead of running at one fixed speed.
  • Tune the constants in that linear function by testing, not by guessing.

Phase 1 — The Mission: Move Botguy

Watch Mission 18 video

Base Mission

11 points Final judged

Botguy is the Loading Zone.

Bonus Mission

13 points Final judged

Botguy is the Loading Zone AND at least one Traffic Cone is the Loading Zone.

Advanced Bonus

15 points Final judged

Botguy is the Loading Zone AND both Traffic Cones are the Loading Zone.

Scores

  • Botguy is the Loading Zone.
  • Botguy and one Traffic Cone are the Loading Zone.
  • Botguy and both Traffic Cones are the Loading Zone.

Does Not Score

  • Botguy is outside the Loading Zone.
  • Botguy is touching only the exterior boundary of the Loading Zone.
  • A Traffic Cone is the Loading Zone but Botguy is not.
  • Botguy and only one Traffic Cone are the Loading Zone for the Advanced Bonus.

Here’s why this mission is a perfect fit for today: Botguy isn’t fixed to the floor. If your robot arrives at full speed and slams to a stop, the impact can shove Botguy off target in the last instant — the exact moment accuracy matters most. A robot that eases off its speed as it approaches is far less likely to the zone or knock Botguy out of position on contact.

Say the mission back in your own words. Why would a sudden stop right at the end be especially risky for this mission compared to, say, just driving to an empty spot on the floor?

Phase 2 — Concept: else if Chains

What is else if?

You already know if and else. An else if chain adds one or more extra checks in between, for when there are more than two possible situations:

if (condition_1)
{
	// runs only if condition_1 is true
}
else if (condition_2)
{
	// runs only if condition_1 was false AND condition_2 is true
}
else
{
	// runs only if BOTH conditions above were false
}

The chain is checked top to bottom, and the instant one is true, its runs and every condition below it is skipped — even if one of them would also have been true. Only one block in the whole chain ever runs.

When is it the right tool?

Good fit: when the situations are mutually exclusive zones — a value falls into exactly one of them, never more than one. A speed limit that’s 20 mph in a school zone, 35 in a residential zone, and 55 on the highway is a perfect else if chain: any one location is in exactly one zone.

Poor fit: when the conditions are independent — more than one could be true at the same time, and you need to react to each one separately. “It’s raining” and “it’s nighttime” can both be true at once. Chaining them with else if would silently skip the nighttime check whenever it’s already raining — that’s a bug, not a design choice. Two separate if statements are correct there.

In your own words: what does an else if chain do differently from writing separate if statements? Give one example (robot or not) where else if is the right tool, and one where it would cause a bug.

Phase 3 — Concept: Three Zones, One Drive

A car doesn’t drive at one constant speed and then slam the brakes. It eases onto the gas leaving a stop sign, cruises once it’s up to speed, and eases onto the brake well before the next stop. Your Drive() is going to do the same thing, split into three zones based on tick position:

Accelerate
first 50 ticks
Cruise
full speed
Decelerate
final 500 ticks

Exactly one of these zones applies at any instant while the robot is driving — which makes this a textbook if / else if / else chain.

Speed as a line: y = mx + b

In the deceleration zone, speed isn’t fixed — it depends on how many ticks are left to travel. The fewer ticks remaining, the slower you want to go. That relationship is a straight line, exactly like y = mx + b from math class:

motor_speed = (ticks_remaining) × m + b

Here, ticks_remaining is your x, motor_speed is your y, m is how steeply speed drops as you get closer, and b is a small base speed so the robot never fully stalls before it actually reaches the target. A starting point to test:

motor_speed = (desired_ticks - current_ticks) × 2 + 150

where desired_ticks - current_ticks is exactly ticks_remaining. The acceleration zone works the same way, just measuring from the start instead of the end — speed ramps up as current_ticks grows from 0 toward 50.

Why does deceleration speed depend on ticks remaining rather than ticks already driven? What would go wrong if you used the wrong one?

Phase 4 — Build: Rebuild Drive()

Replace your single fixed-speed loop with the three-zone if / else if / else chain. This checks the zone every trip through the loop, so speed updates continuously as ticks change.

yourname.h
void Drive(double inches)
{
	int desired_ticks = inches * ticks_per_inch;
	int current_ticks;
	int motor_speed;

	cmpc(0);
	current_ticks = gmpc(0);

	while (current_ticks < desired_ticks)
	{
		current_ticks = gmpc(0);

		if (current_ticks < 50)
		{
			// ACCELERATION ZONE: ramp speed UP from a slow start
			motor_speed = current_ticks * 12 + 150;
		}
		else if ((desired_ticks - current_ticks) < 500)
		{
			// DECELERATION ZONE: ramp speed DOWN as ticks remaining shrinks
			motor_speed = (desired_ticks - current_ticks) * 2 + 150;
		}
		else
		{
			// CRUISE ZONE: full speed, neither ramp applies
			motor_speed = 750;
		}

		mav(0, motor_speed);
		mav(1, motor_speed);
	}

	mav(0, 0); mav(1, 0); msleep(50);   // brake
}

Walk through the three branches in your own words: what triggers each one, and what does each one do to motor_speed?

Phase 5 — Run It, Then Tune the Constants

Test your new Drive() on a medium-to-long distance (24+ inches works well, so all three zones actually get used). Watch the robot closely as it drives — does it visibly ease on, cruise, then ease off? Or does something look off?

⚠ Something to watch for

The cruise speed in the skeleton is 750. Plug ticks_remaining = 500 (the instant deceleration begins) into the decel formula: 500 × 2 + 150 = 1150. That’s faster than cruise speed — the robot would speed up right as it’s supposed to start slowing down. Watch for this when you test. If you see it, that’s not a mistake in the lab — it’s your m and b constants not yet matching your cruise speed.

Tune your constants
ConstantStarting valueYour tuned valueWhy you changed it
Accel slope (m)12
Accel base (b)150
Decel slope (m)2
Decel base (b)150
Cruise speed750

Did you hit the speed-jump problem described above? How did you change your constants so decel speed at 500 ticks remaining lines up with your cruise speed instead of exceeding it?

Phase 6 — Run the Mission

Using your tuned Drive(), drive to Botguy and move him into the loading zone. Run it several times.

Run it 4+ times — how consistent is the final position?
RunBotguy fully in the loading zone?Did the stop feel smooth, or still abrupt?
1
2
3
4

Compare this to a flat-speed Drive() from Unit 4. Was Botguy’s final position more consistent with easing on/off? Why would a reliability engineer care about that consistency more than raw speed?

Phase 7 — Connect & Reflect

AI Literacy Thread

Reliable systems respond proportionally to how close they are to a goal, instead of acting the same way right up until they suddenly stop.

This idea shows up everywhere intelligent systems need to be trusted with something delicate. A self-driving car doesn’t brake at one constant rate regardless of following distance — it eases harder the closer it gets to a stopped car ahead. A robotic arm placing a fragile part slows dramatically in its last few millimeters of travel. Even a thermostat easing a heater’s output as room temperature approaches the target, instead of blasting full heat until the exact instant it’s satisfied, is the same pattern: proportional response near the goal, not all-or-nothing action right up to it.

Complete the reflection on your own.

1. What does an else if chain do that separate if statements don’t, and why did the three speed zones need one?

2. Explain the decel formula motor_speed = ticks_remaining × m + b the way you’d explain y = mx + b to a friend who hasn’t seen this lab.

3. Why does tuning constants by testing beat guessing a value and hoping it works?

4. Complete in 2–3 sentences: “Reliable systems respond proportionally instead of all-or-nothing. This means that near a goal, a system should…”

Extension Challenges

Finished early? Try one or more of these.

Extension A — Ease Your Turns Too

  • Apply the same three-zone idea to Turn(). Does a turn need as large a deceleration zone as a long drive? Why or why not?

Extension B — Does It Scale?

  • Test your tuned Drive() on a very short distance (6 inches) and a very long one (48+ inches). Does the same accel/decel zone size work well for both? What would you change if not?

Extension C — Name the Cruise Zone

  • Rewrite the plain else as an explicit else if that checks both bounds of the cruise zone directly. Was else if necessary? What did plain else save you from writing?

Extension D — Should It Exist?

  • Find one credible news article (not a blog or forum post) about a real self-driving car incident, or a robot that failed in the field.
  • In 3-4 sentences: what happened, was the technology more beneficial or harmful overall, and how do you think it will need to change in the next 10 years to be trusted?

Extension E — Round and Check

  • Wrap your motor_speed calculation with round() so it’s always a whole number (motors don’t understand fractional ticks/sec anyway). You’ll need #include <math.h>.
  • Use abs() on the difference between your tuned decel speed at 500 ticks remaining and your cruise speed — how close did your tuning actually get them?

When you are finished, press the button to turn in your work and save a copy.

KIPR · Botball Explorer · Unit 5 Big Idea 2