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 again: it says 46 cm every time, because the simulator's spring is exactly the same on every kick. A real spring varies a little from kick to kick.

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.

Two charts against time after the kick: the ball's speed falling from 66 cm/s to nothing, and the distance it has rolled levelling off at 46 cm0123403366seconds after the kickspeed, cm/sspeedhalf gone after 0.5 sstops at 3.2 s0123402550seconds after the kickrolled, cmdistancestops 46 cm on
After the kick the ball loses the same fraction of its speed every second, so it is down to half in 0.5 s and stopped by 3.2 s. The distance climbs fast and then levels off at 46 cm. Same kick, same speed, same distance every time.

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()

# close the jaws (it waits while they move)
gripper("close")
# slide left at 50 for 25 cm, then stop
left(50, distance=25)
# turn 90 degrees anticlockwise, then stop
turn_left(30, angle=90)
# kick: one turn of the kicker winds the spring and lets it go
kick()
# pause 3 s (the robot keeps doing what it was told)
wait(3)
print("kicked at the left wall; watch it come back off")

Run this in the simulator

The robot carries the ball to within 25 cm of the left wall first, because a kick from further away runs out of speed before it gets there. The ball hits the wall and rolls back about 14 cm before it stops.

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.

From above: kicked at the left wall from 25 cm away, the ball hits it and rolls back 14 cmwallrobot66 cm/s43 at the wallleaves at 21, halfstops 14 cm out
The ball slows on the way out, from 66 cm/s at the kick to about 43 at the wall. The wall sends it back with half of that, about 21, which is only enough to roll 14 cm.

Task: stop in the box

The box is 23 to 31 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. The simulator gives the same number each time; on the real robot, 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.