How to Make an Autonomous Basketball Playing Robot Using an IRobot Create As a Base





Introduction: How to Make an Autonomous Basketball Playing Robot Using an IRobot Create As a Base

This is my entry for the iRobot Create challenge. The hardest part of this whole process for me was deciding what the robot was going to do. I wanted to demonstrate the cool features of the Create, while also adding in some robo flair. All of my ideas seemed to either fall in the category of boring but useful, or cool and impractical. In the end cool and impractical won out and the basketball playing robot was born. After some thought I realized that could be practical. Suppose that you use orange paper, and that all of your trash cans have green backboards...

Step 1: Aquire Parts

Because of the time limit of the contest, most of the parts I used were "off the shelf".

"Stock" Robot Parts Used:
Create (x1) -- from iRobot
XBC V.3.0 (x1) -- from Botball
Create-Roomba cable (x1) -- from Botball
Servo (x2) -- from Botball
Sharp rangefinder (x1) -- from Botball
Assorted LEGO bricks -- from LEGO
6-32 machine screws (x4) -- from McMaster

"Created" Robot Parts Used:
3/8" thick extruded PVC sheet -- this stuff is awesome, but I can't remember where I got it from, but it is just like this stuff

Other parts:
Orange "POOF" ball -- from WalMart
Basketball goal looking trash can -- from Lowes
Green "backboard" -- extra PVC painted bright green

Step 2: Create the Unique Part

The only part that I had to fabricate was a plate that bolted to the Create and offered LEGO spacing. The spacing of the LEGO brick holes is 8mm apart, but I did a double spacing to save time. The extruded PVC is a breeze to work with. It can be cut with a utility knife, but is rigid and strong. I often pick up the robot by this plate and I have not had a problem yet.

Step 1:
Cut the sheet to 3.5" x 9.5", you can cut this with a utility knife.

Step 2:
Drill the holes for the create screws. The create screws make a box that is 2 and 5/8" by 8 and 5/8".

Step 3:
Drill the LEGO brick spaced holes. Use a 3/16" drill bit and I spaced the holes 16mm apart.

I laid out the sheet in a CAD program, printed it out full size and taped it to the sheet. Then I used this as a guide for cutting and drilling.

Step 3: Assembling the Robot

I enjoy building things as simply as possible, that way when they jump off of the table you don't have to rebuild as much!

1. Screw the newly fashioned plate to the top of the Create
2. Build an arm to grab the ball
3. Build an arm to hold the camera
4. Build a mount for the rangefinder
5. Mount the XBC and connect all of the cables

Step 4: Programming the Robot

I decided to use the XBC as my controller mainly because of its built in color tracking. Because I decided to with the XBC as the brains of the operation I programmed my robot in Interactive C, or as I call it IC. IC is free to use and can be downloaded at IC is very similar to C++, but has several built in libraries. As it turns out, David Miller from the University of Oklahoma has written a library for the Create which can be downloaded from his page at

With those resources and the manuals for the create I was ready to program. But the next big challenge was what did I want it to do? I wanted a robot that could go and pick up orange balls and score them in a basket. My goal sounded simple, and probably could have been simple, but the more I got into what the Create could do, the more i wanted it to do. My final list looked like this:

1. Find orange ball
2. Pick up orange ball
3. Locate basket
4. Put ball in basket


1. Avoiding objects
2. Not falling off anything(like a table)
3. Detecting the charge of the battery and docking with the home base when low

Oh, and all of this is completely autonomous, meaning that it is all preprogrammed.

Step 5: Code

It may be messy, but it works.

#use "createlib.ic"
#use "xbccamlib.ic"

#define cam 0//camera servo port
#define arm 3//arm servo port
#define et (analog(0))//et port

/*The create cable also needs to be plugged in. The power jack,
the 3 pronged plug into port 8 and the one labeled U X into JP 28
(next to the USB port) with the U towards the camera*/

#define c_down 5//camera servo down
#define a_down 17//arm servo down
#define hold 50//servo hold ball
#define caught 27//arm servo position to keep from getting caught on table
#define shoot 150//servo throw ball
#define track_c 25//camera servo track close position
#define track_f 45//camera servo track far position

#define center 120//center of camera vision
#define inrange 30//track_y coordinate when ball is in claw
#define ball 0//channel of orange ball
#define ball_x (track_x(ball,0))//x coordinate of ball
#define ball_y (track_y(ball,0))//y coordinate of ball

#define slow 100//speed of slow motor
#define fast 175//speed of fast motor

#define clear 0.2//sleep to back away from obstacles
#define time 0.5 //1.0 is a 90 degree right turn
#define rest 0.05//time to sleep while tracking blobs

#define speeda 175//speed of avoid turn
#define back_s -200//speed to back away from bumped object
#define straight 32767//drive in a straight line

#define backb 2//channel of backboard main color
#define square 1//channel of backboard accent color
#define track_d 250//camera position for tracking goal
#define track_find 70//camera position for long tracking
#define reverse 2.25//sleep time for a 180
#define back_f -150//back fast speed
#define back_sl -125//back slow speed
#define center_x 178//true x center of cam
#define center_y 146//true y center of cam

int pida;//avoid process
int pidb;//track process
int pidc;//score process
int have_ball = 0;//tells which function we are in

void main(){
long ch;
enable_servos();//enable servos
init_camera();//start camera
cconnect();//connect to create with full controll
start_a();//start avoid function
start_b();//start ball_tracking function
if(r_button()||gc_ldrop||gc_rdrop){//if picked up or r shoulder button
printf("charge = %l\n", gc_battery_charge);
printf("charge = %l\n", gc_battery_charge);


void avoid(){

while(1){//repeat forever

create_sensor_update();//update all sensor values
//create_drive (speeda,straight);
if(gc_lbump==1){//left bump
avoid_right();}//turns right to avoid
else if(gc_rbump==1){//right bump
avoid_left();}//turns left to avoid
else if(gc_lfcliff==1){//left front cliff
else if(gc_rfcliff==1){//right front cliff
else if(gc_lcliff==1){//left cliff
else if(gc_rcliff==1){//right cliff

void track_ball(){


while(!have_ball){//repeat until get ball

far();//sets the camera
ready();//sets the arm

while(et<255){//until max value happens when ball is caught

track_update();//update camera picture

if(ball_x<=(center-5)){//if the ball is left
create_drive_direct(slow,fast);//turn left

else if(ball_x>=(center+5)){//if the ball is right
create_drive_direct(fast,slow);// turn right

else if(ball_x<(center+5)&&ball_x>(center-5)){// if the ball is centered
create_drive_straight(fast);//go straight
grab();//grab ball
beep();//make noise
stop();//stop driving
have_ball=1;//make a note that I have ball
start_c();//find the basket
sleep(1.0);//sleep so that I'm not doing anything when I get killed

void find_basket(){

kill(pidb);//kill ball tracking process
find();//put camera up
track_set_minarea(1000);//the backboard is large, so only look for large blobs

while (have_ball){//while I have the ball

while(track_x(backb,0)<=(center_x-20)||track_x(backb,0)>=(center_x+20)){//while not centered

if(track_x(backb,0)>=(center_x+20)){//if the backboard is left
create_spin_CCW(100);}//turn left

else if(track_x(backb,0)<=(center_x-20)){//if the backboard is right
create_spin_CW(300-center_x);}// turn right slowing as the center approaches

while(track_size(backb,0)<=(6000)){//while the target is less than 6000 pixels in size
if(track_x(backb,0)<=(center_x-5)){//if the target is left
create_drive_direct(slow,fast);//turn left

else if(track_x(backb,0)>=(center_x+5)){//if the target is right
create_drive_direct(fast,slow);// turn right

else if(track_x(backb,0)<(center+5)&&track_x(backb,0)>(center_x-5)){// if the target is centered
create_drive_straight(fast);//go straight
//create_drive_straight(fast);// get a little bit closer
create_spin_CW(speeda);//spin right
sleep(reverse);//sleep long enough for a 180 turn
down();//put camera down to track backboard
track_set_minarea(200);//use a smaller min size, since we are pointed at it and going to get closer

while(track_y(backb,0)>=(center_y-140)){//while the target is less than the y coordinate
if(track_x(backb,0)<=(center_x-5)){//if the target is left
back_right();//turn left

else if(track_x(backb,0)>=(center_x+5)){//if the target is right
back_left();// turn right

else if(track_x(backb,0)<(center+5)&&track_x(backb,0)>(center_x-5)){// if the target is centered
back();//go straight

have_ball=0;//reminder I threw ball and don't have it
start_b();//back to ball tracking
sleep(1.0);//don't do anything until this process dies

void cconnect(){
create_full();//for full controll of ledge sensors
create_power_led(0,255);}//green power led

void disconnect(){
stop();//stop moving

void back_away(){

void rotate_l(){

void rotate_r(){

void stop(){

void back(){

void ready(){
set_servo_position(arm, a_down);}

void check(){
set_servo_position(cam, track_c);}

void far(){
set_servo_position(cam, track_f);}

void ledge(){
set_servo_position(arm, caught);}

void throw(){
int a;
for(a=50; a>=30; a-=1){//get ready
set_servo_position(arm, a);}
set_servo_position(arm, shoot);}

void grab(){
int a;
for(a=0; a<=hold; a+=1){//raise the arm smoothly
set_servo_position(arm, a);}}

void down(){
set_servo_position(cam, track_d);}

void find(){
set_servo_position(cam, track_find);}

void start_a(){
pida = start_process(avoid());}

void start_b(){
pidb = start_process(track_ball());}

void start_c(){
pidc = start_process(find_basket());}

void kill(int pid){
CREATE_BUSY;//wait for current create process to finish, and take priority
CREATE_FREE;//i'm done

void avoid_left(){
kill(pidb);//stop everything else
ledge();//pick up claw so it does not get caught on the table
back_away();//back away
rotate_l();//rotate away from obstacle
ready();//put claw back down
if(have_ball){//if i have the ball
start_c();}//start goal tracking
else if(!have_ball){//if i don't have the ball
start_b();}//start ball tracking

void avoid_right(){
else if(!have_ball){

void back_left(){

void back_right(){

Step 6: Was It Worth It?

The costs were:

Create + battery+ doc = $260
XBC starter kit (xbc, cam, LEGO bricks, sensors) = $579
PVC + paint + screws = about $20
Total cost = $859

I already had the XBC starter kit from Botball, so the cost to me was the cost of the Create.

I think that it was worth it, and the best part is that all of the parts I used are reusable, if I could bring myself to part out this bot.

This video shows the avoid sub routine, on a table top.

This video shows the robot scoring 5 orange balls in a goal. I only assisted to speed the process along, it would have found ball 5 eventually on it's own.

Step 7: Conclusion

The final result is a robot that can pick up and score orange balls in a goal all on its own.

I loved working on this project. The more I worked on this robot the more attached I became to it. I now talk to it as if it were a pet. I hope that this has helped you on your next project. There are lots of people that I need to thank, but there are too many.

Like Bernard of Chartres so elegantly stated:

"we are like dwarfs on the shoulders of giants, so that we can see more than they, and things at a greater distance, not by virtue of any sharpness on sight on our part, or any physical distinction, but because we are carried high and raised up by their giant size."



    • Clocks Contest

      Clocks Contest
    • Creative Misuse Contest

      Creative Misuse Contest
    • Oil Contest

      Oil Contest

    26 Discussions


    2 years ago

    A design is quite perfect, but not enough. hope that there will be many more beautiful design for a IROBOT ROOMBA. the current era of technology development and manufacturing company has launched the new ROOMBA with extremely great feature for many users. most of them prefer the IROBOT can completely replace the work of the family.

    hey, ur model was really great, can u also make a robot that can play badminton please.....I'm dancing some problems with buying the correct parts for it

    Have you seen this, pretty cool creation.

    hmmm this is awesome, great job, im definatly using the XBC for my next robot, either for a hexapod or an autonomous race car (using one of those hobby class rc cars)

    The program I am using is called IC, which is basically C. IC has library functions to return information from the camera, like blob size, x axis, y axis, ect. IC supports 16 blobs across 3 channels so I can track up to 48 blobs at a time. Then you just take the values returned and make everything else happen.

    If you are interested in IC check out for more information.

    Nice job! I really like the idea of using a GBA as a microcontroller, but 300 bucks for it is too much for my budget, maybe someone could make a Open Source version, like the Arduino...

    This is so cool! I want to build one but like everyone else i couldn't possably afford it, good work!

    so it senses ledges..... I want to build one and put a orange ball on the edge of the grand canyon

    Nice, the only thing that I would have done, is make it pick up your dirty clothes and put it in the wastebasket. It would be pretty hard determining what not to pick up, things that are to heavy could break the the arms. Still I thought this was a really great idea.

    1 reply

    So this is a great start for a laundry sorting robot or a robot to clean up my house. It goes great with the rest of the roomba products!

    Yes, this robot is completely autonomous. It was loaded with code before hand and then ran the code all on it's own, i.e. no live controls were used.

    Now if only my socks were all orange balls...

    really cool, if it wasnt 900 bucks, id make one. whats the image displayed on the gameboy screen?

    1 reply

    Initially the image is the Gameboy logo as the GBA boots. Then it loads IC and has a main menu. When I run the robot I have it print the battery charge. The XBC is only $292. So if you have some LEGO bricks and/or a Create or a Roomba, It can be done for much less.