Ball physics

Rolling, friction, bouncing, and measuring power against distance.

7.5Hands and feetRobot club20 min

Do this lesson in the simulator

A kicked ball rolls, slows, and stops. Kick it at a wall and it comes back slower. The kicker has one strength, so using it well means knowing exactly how far that is and what the ball does afterwards, and the honest way to know is to measure.

Measure the kick

This robot faces up the mat with the ball in front of it. Kick, wait for the ball to stop, and read where it is with the camera:

# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()

# camera: look for red blobs
set_cv("blob", "red")
# kick: one turn of the kicker winds the spring and lets it go
kick()
# pause 4 s (the robot keeps doing what it was told)
wait(4)
b = blobs()[0]
width = b[5] - b[3]
print(f"ball width {width} px, about {round(4 * 92 / width)} cm from the camera")

Run this in the simulator

The blob's width is a distance in disguise: a ball of known size looks smaller the further away it is (lesson 4.4). Half the width, twice the distance; the conversion is the camera's focal length from lesson 4.2. Press Reload, which puts the ball back, and run it a few times: the number is about 45 cm every time, give or take a little.

Why it stops

Rolling friction takes a fixed fraction of the ball's speed every second, so the speed decays and the distance is the speed at the kick divided by that fraction. The spring always gives the same speed, so the ball always goes the same distance. On a real mat the fraction depends on the surface, and the number you measured is the number for your mat.

Closer than a kick

For a short distance the kicker is too strong, and pushing a round ball with a flat front sends it skidding off to one side. The tool for a target closer than 45 cm is the gripper: hold the ball, carry it, and open the jaws where you want it. A released ball stays put.

# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()

# close the jaws (it waits while they move)
gripper("close")
# drive forward at 30 for 20 cm, then stop
forward(30, distance=20)
# open the jaws and let go
gripper("open")
# drive backward at 30 for 10 cm, then stop
backward(30, distance=10)
# camera: look for red blobs
set_cv("blob", "red")
# pause 0.5 s (the robot keeps doing what it was told)
wait(0.5)
b = blobs()[0]
print("carried it 20 cm; the ball is now about", round(4 * 92 / (b[5] - b[3])), "cm from the camera")

Run this in the simulator

The ball ends up about 7 cm ahead of where the robot's centre stopped: 3.5 cm of robot, the jaws, and half a ball.

Bouncing

# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()

# turn 40 degrees anticlockwise, then stop
turn_left(30, angle=40)
# kick: one turn of the kicker winds the spring and lets it go
kick()
# pause 5 s (the robot keeps doing what it was told)
wait(5)
print("kicked at the left wall; watch it come back off")

Run this in the simulator

A wall returns the ball with about half its speed. Real bounces depend on the wall, the ball and the angle, and robots that play ball games learn their arena the same way you just did: by measuring.

Task: stop in the box

The box is 25 to 33 cm ahead of the ball, closer than a kick goes. Get the ball to stop in it: carry it there with the gripper and let go.

# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()

# kick: one turn of the kicker winds the spring and lets it go
kick()
# pause 5 s (the robot keeps doing what it was told)
wait(5)

Challenges

  1. Kick five times from the same spot (Reload between) and print the five distances: how repeatable is the spring?
  2. Write carry_to(cm) that carries the ball a given distance ahead and lets go, and test it on the box.
  3. Kick the ball against the top wall so it comes back and stops within 10 cm of you.