KIPR · Botball Explorer
Activity Sections

Discovery · Coding Project 12

Teaching Your Robot New Moves

Give twenty lines a name. Then just say the name.

Project
Coding Project 12
Strand
Coding
Phase
Make It Reliable
Time
One class period
What You Are Doing
Writing your own commands — drive, turn, grab — and calling them instead of retyping them. Then using one of them twice to double a score.
Mission Anchor
Mission 15 — Hazard Disposal #2 (base + bonus) — 18 points
Before You Start
Project 11 — your drive and turn code must already work in .
What You Need
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.

Try It — Brain Dump

Without looking anything up, write down every command you know. Fill as many boxes as you can.

CommandCommandCommand
Now compare with a partner, then look at your whole list at once.

What do all of them have in common? Find at least two things.

You Should Have Found These

  • Every one of them has a name.
  • Every one of them has a pair of parentheses after the name.
  • Some need information inside the parentheses — motor(0, 100), msleep(3000).
  • Some need nothing at all — ao(), enable_servos().

Every command you have ever typed is a . Somebody wrote them, put them in the KIPR , and gave you the names. Today you join them.

Count your own repetition

Open your Project 11 program. Go through it and count.

How many times did you type…TimesLines each
The clear-then-loop for driving forward
The block for a 90° turn
The six-step grab sequence
Multiply those out. Roughly how many lines of your program are copies of something you already wrote?

Learn It — Three Parts, In This Order

Writing your own function is like adding a word to a dictionary. You need the word listed, you need its meaning written down, and then you can use it in a sentence.

  1. : The prototype goes on the line after #include, before int main(). It is the word in the vocabulary list — it tells the this name exists.
  2. Definition: Goes after the last closing brace of your program. This is the definition of the word — what the robot actually does.
  3. Call: Inside main, where you would have typed all those lines. This is using the word in a sentence.

What void means

means the function does a job but hands nothing back. ao() is like that — it stops the motors, it does not give you an answer.

You have seen the other kind too. digital(0) and gmpc(0) hand you a number. Yours will not, so yours say void.

Naming rules

  • Make it obvious. drive_forward, not thing2.
  • No spaces — use an underscore: drive_forward.
  • It cannot start with a number.
  • It cannot have the same name as a command that already exists. You cannot call yours motor.

The whole thing, side by side

Before — twice

int main()
{
	cmpc(left);
	while (gmpc(left) < 4000)
	{
		motor(left, 50);
		motor(right, 50);
	}
	motor(0, 0);
	motor(3, 0);
	msleep(30);
	msleep(500);

	cmpc(left);
	while (gmpc(left) < 4000)
	{
		motor(left, 50);
		motor(right, 50);
	}
	motor(0, 0);
	motor(3, 0);
	msleep(30);
	msleep(500);

	return 0;
}

After — a function

#include <kipr/wombat.h>

// 1. Prototype
void drive_forward();

int main()
{
	// 3. Call
	drive_forward();
	drive_forward();

	return 0;
}

// 2. Definition
void drive_forward()
{
	cmpc(left);
	while (gmpc(left) < 4000)
	{
		motor(left, 50);
		motor(right, 50);
	}
	motor(0, 0);
	motor(3, 0);
	msleep(30);
	msleep(500);
}

⚠ The Prototype Gets a Semicolon. The Definition Does Not.

void drive_forward();. It is a announcing the name.

void drive_forward() followed by { — no semicolon. The braces do that job, exactly like int main().

Putting a semicolon on the definition is the most common mistake in this project.

Arguments — one function, many distances

drive_forward() always drives 4000 ticks. That is fine until you need 2000.

Put a in the parentheses and you can decide the number every time you call it. That variable is an — the same word you met back in Project 3.

// Prototype says what it needs
void drive_forward(int ticks);

...

// Call: go 4000
drive_forward(4000);
// Call: go 1200
drive_forward(1200);

...

// Definition uses the name
void drive_forward(int ticks)
{
	cmpc(left);
	while (gmpc(left) < ticks)
	{
		motor(left, 50);
		motor(right, 50);
	}
	motor(0, 0);
	motor(3, 0);
	msleep(30);
	msleep(500);
}

Two arguments? Separate them with a comma — exactly like motor(port, power) does.

A function can call another function

Once drive_forward() and turn_right() exist, a bigger function can just use them.

void drive_square()
{
	drive_forward(4000);
	turn_right();
	drive_forward(4000);
	turn_right();
	drive_forward(4000);
	turn_right();
	drive_forward(4000);
	turn_right();
}

Now drive_square(); is one line. This is how a whole match run eventually becomes a short, readable list of things your robot does.

Do It — Build Your Own Commands

Step 1 — My first function

Create a new project called Functions. Take your working drive-forward code from Project 11 and turn it into a function with all three parts.

Call it twice in main. The robot should drive the distance, then drive it again.

What did you name it, and why that name?

Step 2 — Break the prototype on purpose

Delete the prototype line. Compile.

What did the error say?

Put it back. Now add a semicolon to the end of the definition line and compile again.

What happened this time?

Fix it. You have now seen both of the mistakes everyone makes here.

Step 3 — A turn function

Same three parts, using your 90° turn from Project 11.

Step 4 — The square — one more time

You have now driven this square three times. Do it once more, using only function calls.

VersionRoughly how many lines?Did it close?
Project 5 — timed
Project 11 — ticks
Now — functions

Two Different Kinds of Better

Project 11 made the square work. This project makes it readable. Those are separate problems, and you have now solved both.

Step 5 — Add an argument

Change your drive function so the distance comes from an argument. Then drive a rectangle — two long sides, two short ones — with the same function called four times.

drive_forward(4000);
turn_right();
drive_forward(2000);
turn_right();
drive_forward(4000);
turn_right();
drive_forward(2000);
turn_right();

Without the argument, how many separate functions would a rectangle have needed?

Step 6 — Wrap the grab

The six-step grab sequence from Project 8 is your best candidate. Turn it into grab() and release().

void grab()
{
	set_servo_position(arm, down);
	msleep(700);
	set_servo_position(claw, closed);
	msleep(700);
	set_servo_position(arm, up);
	msleep(700);
}

Now write a bigger function that uses them:

void fetch_pom()
{
	drive_forward(2000);
	grab();
	turn_right();
	drive_forward(1500);
	release();
}

Step 7 — Mission 15 — one blue pom for 9 points

Watch Mission 15 video

Base Mission

9 points Final judged

One Blue Pom is a basket.

Bonus Mission

9 points Final judged

Two or more Blue Poms are the same basket.

Scores

  • One Blue Pom is a basket.
  • One Blue Pom partially extends into the interior space of a basket.
  • Two or more Blue Poms are the same basket.

Does Not Score

  • A Blue Pom is touching only the outside of a basket.
  • A Blue Pom is resting above a basket without extending into it.
  • One Blue Pom is in Basket A and one in Basket B — does not satisfy Bonus.

⚠ Not the Basket You Used in Project 8

Mission 11 (orange poms) and Mission 15 (blue poms) must use different baskets. In Project 8 you wrote down which basket you were saving for this. Use that one.

Build the run out of the functions you just wrote. Your whole main should read like a list of instructions, not a wall of code.

Step 8 — Mission 15 Bonus — do it again for 9 points

Here is the payoff for the whole project. To score the bonus you need a second blue pom in the same basket.

You do not write any new code. You call your function a second time.

fetch_pom();
fetch_pom();

Nine Points for One Line

If your function had been twenty lines of copied code, doubling this mission would have meant twenty more lines to write, test, and keep in step. Instead it is one line.

That is the entire argument for functions, and you just got paid for it.

The second pom is somewhere different from the first, so your function will need a way to handle that — an argument, or a small drive between the two calls.

How did you get the second call to reach a different pom?

Step 9 — Run it five times

RunOne pom in?Two in the same basket?Points
1
2
3
4
5

Score It — Checkpoint

My score

Mission partScored?Points
Mission 15 — Base (one blue pom in a basket)9
Mission 15 — Bonus (two in the same basket)9
My total18

My function list

Write down every function you built. This list is the start of something you will finish in Project 16.

Function nameArgumentsWhat it does

Where does each part go?

PartWhere in the program
Prototype
Definition
Call

Can you do it again?

Think about it

Your robot’s turn is 15 ticks off. With functions, how many places do you edit? Without them, how many?

In Project 9 you gave names to numbers. Here you gave names to actions. What is the same about those two ideas?

A new teammate joins and opens your program. They see fetch_pom(); and have no idea how it works. Is that a problem?

Next

Your robot follows the same plan every time, no matter what it finds. If a cube is not where you expected, it grabs at nothing and carries on regardless.

In Project 13 — Deciding What to Do, it stops following orders blindly and starts choosing.

KIPR · Botball Explorer — Discovery Projects · © KISS Institute for Practical Robotics 1997–2026

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

KIPR · Botball Explorer · Discovery