Robots That Plan: The Piano Mover's Problem
Why motion planning is a discipline with theorems rather than a bag of heuristics — the piano mover, Choset's taxonomy of planners, a complete planner in forty lines, and the one idea the whole book rests on, that a robot is a point in the right space.
The prototypical task is to find a path for a robot, whether it is a robot arm, a mobile robot, or a magically free-flying piano, from one configuration to another while avoiding obstacles.
In this chapter
You already know how to make a robot move. This book is about making it decide where to move, and its thesis is that this is a discipline with theorems, not a bag of heuristics. The discipline rests on one idea that Choset and his co-authors put in their first paragraph and never let go of: a robot, however many joints it has, is a point in the right space. Motion planning does not happen in the room; it happens in configuration space, where the piano is a point and the walls have become shapes the point must avoid. Everything else in the book — bugs, potentials, roadmaps, samplers, trajectories, Lie brackets — is a way of finding a curve for that point.
This chapter sets the voice for the other twenty-two: hook first, playful when it helps, and every
playful claim backed immediately by a figure you can drag, a number you can check, or a cargo run
that prints that number. It is the one chapter where intuition outweighs mathematics, but nothing
stated here is retracted later.
The problem
Below, a point robot with nothing but a contact sensor is crawling toward a goal it cannot see past. Its entire strategy is two sentences long: walk toward the goal; if you bump into something, go around it. Watch it arrive.
This is a provably complete planner, and it fits in forty lines.
"Complete" is a technical word and the whole book is careful about it: the planner finds a path whenever one exists and reports failure in finite time when none does. It needs no map. It never plans ahead. It has a theorem — the counter under the canvas never exceeds the bound printed beside it, and the bound is a formula, not a measurement. Drag the goal behind the larger obstacle: the walk around it gets longer and the bound grows with it, exactly as the formula says it must. Switch to Bug2, the greedy sibling that leaves an obstacle the first time it can, and the two totals tell you something that is true of search in general: greed is usually faster and sometimes disastrous. The "comb" preset is a world built so that greed loses.
Everything in this chapter is a first look at something a later chapter proves. The Bugs are Chapter 3's. The deeper claim — that the robot's shape can be made to disappear — is Chapter 4's, and it comes next.
Building intuition
The piano is a point
Choset's opening problem is the piano mover's problem: a rigid body, a known set of stationary obstacles, a start and a goal; find a collision-free path. In the plane it becomes the sofa mover's problem, and a sofa is enough to make the point.
On the left is the room: a wall with a doorway, and a sofa you can drag and turn. On the right is something you have probably never looked at before. It is the same sofa, drawn as a single dot, in a space whose axes are the sofa's position — and the amber shapes around the dot are the sofa's configurations that would put it through a wall, at the heading it currently has.
Drag the sofa into the wall. The dot touches amber at the same instant. Not before, not after: the two pictures are the same fact drawn twice. Now turn the sofa and watch the amber reshape itself. The walls did not move. The robot changed, and the obstacle the planner fights changed with it. At one heading the doorway is a wide channel between two amber blobs; turn the sofa broadside and the channel closes. A sofa that only fits diagonally has a channel that exists at some headings and not at others — your first sighting of a narrow passage, the thing that makes Part III hard.
Three vocabulary words have just been used informally, and the Foundation section pins them down. A configuration is a complete description of where every point of the robot is: for the sofa, its position and heading, . The configuration space is the set of all of them. A C-obstacle is the set of configurations at which the robot overlaps a workspace obstacle. The right-hand pane shows one slice of — fixed — because is three-dimensional and the screen is not. Toggle "stack all θ-slices" to see the slices pile into the translucent block of Choset's figure F.8, and notice the channel twisting as it climbs.
Choset's gallery
Choset's Chapter 1 opens with a gallery of problems, and each one carries a definition this book will need. The piano mover is the pure geometric problem: obstacles known and stationary, execution exact, planning finished before the robot moves — offline planning. NASA's Mini AERCam, a free-flying inspection camera with twelve cold-gas thrusters, is the same problem with one word changed: because it moves by applying forces, it needs not just a path but the speed along the path — a trajectory, and with it dynamics (Part V). The CyCab and the Segway, small vehicles that must parallel park, look like the sofa mover's problem until you notice that a car cannot slide sideways; that velocity constraint is called nonholonomic, the car is called nonholonomic too, and Chapters 20 and 21 are about it. Demining — passing a sensor over every point of a field — is the first time completeness is the whole point: a planner that might miss a mine is not a planner. The painting arm wants its coverage to be time-optimal, because robots in factories cost money by the second. Snake robots have more joints than their task needs — redundant, or hyper-redundant — and non-Euclidean configuration spaces of high dimension. The surgical robots, the digital actors, and the protein-folding problem each get a paragraph in Choset and a pointer here: Chapter 14 picks up the molecule as an articulated linkage.
Two of Choset's examples are handed to the sister book, which tells them properly. RHINO, the museum tour guide, is a localization story — a robot comparing its sensors against a stored map because exact execution is a fiction — and Sojourner on Mars is a mapping story. Probabilistic Robotics via Rust owns both; this book borrows their estimation only as far as a planner needs it, in Part IV.
The cast
Choset's protagonists were the robots of 2005. This book's are built in Chapter 2 and used until the end. Rusty is a disc-shaped differential-drive rover, shared with the sister book, whose home is the Apartment — five rooms off a long corridor. Its configuration is a planar pose, and for collision purposes a point of . Reach is a planar two-link arm, with a three-link variant for redundancy, bolted to the Workbench; its configuration is two angles, a point on a torus. Hitch is a car that may pull one trailer, living in the Lot; its configuration is a pose in , plus one more circle for the trailer. Three robots, three configuration spaces of three different shapes, so that when the book says "a point in " it can mean three concretely different things.
The planner's taxonomy
What kind of thing is a planner? Choset's Table 1.1 answers with three axes, and the board below is that table with the chapters of this book placed on it.
The task comes first: navigate (one configuration to another), cover (a tool over every point), localize (a map and sensors to a configuration), map (an unknown environment to a representation). Then the robot: how many degrees of freedom and what the configuration space looks like; whether it can move instantaneously in any direction of (omnidirectional) or is subject to velocity constraints (nonholonomic); whether velocities are its controls (kinematic) or forces are (dynamic). Then the algorithm: optimal or merely feasible; its computational complexity; which of three kinds of completeness it has; online or offline; sensor-based or working from a model.
Hover "Optimal" and count. Most of this book — most of the field — is not about shortest paths. It is about finding a path, with a guarantee about when you will find one, for a robot whose shape and constraints make "a path" hard to define. Hover "Complete" and notice that two of its chapters, 3 and 9, are sensor-based planners with no map at all. A planner without a map is not a heuristic. The hook above was one.
The mathematics
This chapter's mathematics is deliberately light, and nothing in it is retracted later. The symbols below are the book's global notation, making their first appearance; each is formalized in the chapter named.
| Symbol | Meaning | Note |
|---|---|---|
| Workspace: the ambient space the robot's body lives in. | Chapter 2 | |
| The i-th workspace obstacle; the free workspace. | Chapter 2 | |
| Configuration space; one configuration — a point the planner imagines. | Chapters 4–5 | |
| Footprint: the set of workspace points the robot occupies at q. | Chapter 2 | |
| C-obstacle, the configurations whose footprint meets WO_i; free configuration space. | Chapter 4 | |
| A path; a trajectory when the parameter is time. | Chapter 18 | |
| The query. | Chapter 3 | |
| Euclidean distance in the plane (the Bug algorithms); a metric in general. | Chapter 5 | |
| Perimeter of workspace obstacle i (the Bug bounds). | Chapter 3 |
Definitions
The robot is a point
DerivationThe configuration-space reduction
Statement. For any robot and any workspace obstacles, a curve in is a collision-free motion of the robot's body if and only if it is a curve in . Planning for a body is planning for a point in a different space.
Step 1 — the footprint is a function of . By the definition of configuration, fixes the position of every point of the robot, so the occupied set is a function of alone.
Step 2 — collision is membership. The robot at collides with obstacle iff , which by definition is :
Step 3 — along a curve. A motion avoids every collision iff for every and every , i.e. iff avoids .
Step 4 — the complement. , so "avoids every C-obstacle" is exactly "lies in ", which is the last clause of eq. (1.1).
Why the reduction is not free. Three things are hidden in the word "different". The C-obstacles are usually not computable in closed form — Chapter 4 does the cases that are, a disc and a polygon that translates, and the Piano Mover widget above computes its amber by brute force, asking the collision checker at every cell. The space is usually not : the sofa's wraps, Reach's two angles make a torus, and Chapter 5 is about what that costs. And the dimension is the enemy: the volume of grows exponentially with the number of joints, which is why Part III exists and why Appendix D says "PSPACE-hard".
DerivationDimension counting for the piano
Statement. A free rigid body in has six degrees of freedom; in the plane, three.
Step 1 — one point. Pick a reference point on the body. Placing it takes three coordinates in , two in the plane.
Step 2 — orientation. With one point fixed, the body can still rotate about it: three parameters in (roll, pitch, yaw, or any chart of ), one in the plane.
Step 3 — rigidity. Once the reference point and the orientation are fixed, rigidity fixes every other point. ; .
The warning. Six coordinates do not make equal to . Yaw by returns the piano to where it was, so the orientation coordinates wrap, and some charts of become singular (the gimbal lock of Chapter 5's Rotation Zoo). Chapter 4 does the counting argument with holonomic constraints the way Choset's §3.3 does — points, then constraints, then the dimension that remains.
DerivationBug1 is complete and its path is bounded (quoted, not yet proved)
Statement (Choset eq. 2.1). For a point robot with a contact sensor in a bounded planar workspace, the length of Bug1's path satisfies
and Bug1 reports failure in finite time when no path exists.
Step 1 — straight segments. Between obstacles the robot moves straight toward the goal from a point that is strictly closer than its previous hit point; those segments total at most .
Step 2 — each obstacle. Meeting obstacle costs one full circumnavigation () to survey the perimeter, plus the walk to the perimeter point nearest the goal — at most half the perimeter the shorter way round ().
Step 3 — finitely many. A bounded workspace with finitely many obstacles is met finitely often; sum.
What is deferred. The proof that the leave point is well defined, the test that detects an unreachable goal, and Bug2's weaker bound are Chapter 3's. Here the inequality is checked, numerically, on the text world below — with one grid-specific footnote stated where it arises.
DerivationWhy 'just drive toward the goal' is not a planner
Statement. A controller that always moves to reduce gets stuck in any workspace with a concave obstacle facing the start.
Step 1 — build the trap. Put a U-shaped obstacle between the start and the goal, open toward the start.
Step 2 — enter it. Driving toward the goal takes the robot into the U, because every step into the mouth reduces .
Step 3 — the bottom. At the bottom of the U every admissible direction increases . The controller stops. It has reached a local minimum of the function it descends, and by its own definition of success it has succeeded.
This is Choset's warning that "purely reactive gradient-following potential field approaches always run the risk of getting stuck in local minima", and the book's first instance of the local-minimum disease that Chapter 7 names and cures. Bug1 escapes the U because boundary following is a second behavior that does not descend at all — it deliberately walks away from the goal, and a rule that only ever descends can never decide to do that.
The algorithm
Bug1 is stated informally here and formally as Choset's Algorithm 1 in Chapter 3. Two behaviors, one memory, one test.
- In
- a bounded planar workspace W seen only through a contact sensor; the robot measures d(x, y) and its own position exactly
- Out
- a path to q_goal, or the conclusion that q_goal is unreachable
- ,
- repeat
- motion-to-goal: from move toward until it is reached or an obstacle is hit at
- if is reached, exit
- boundary-following: follow the obstacle's boundary until is re-encountered, recording the perimeter point closest to
- go to the shorter way round
- if moving toward from would re-enter the obstacle, conclude is unreachable and exit
Line 5 is the exhaustive search: Bug1 walks the whole perimeter before committing to a leave point, which is why its leave point is optimal and its cost is a full . Bug2, Choset's Algorithm 2, replaces lines 5–6 with a greedy exit: fix the m-line from to once, and leave the boundary the first time the robot is back on the m-line, closer to the goal than the hit point, and able to step toward the goal. Bug2 is quick when obstacles are simple and can be arbitrarily worse than Bug1 when they are not.
The worked example, by hand
The book's first "numeric example equals unit test". A text world, nine columns by five rows, origin
at the top left, 4-connected unit moves, a point robot that occupies one cell and whose contact
sensor reports whether the next cell is #:
.........
...###...
S..###..G
...###...
........., , one obstacle in columns 3–5, rows 1–3. Its perimeter, measured as the ring of free cells the robot walks when going round it, is .
- Motion-to-goal along row 2: , — 2 steps. The next cell is
#, so . - Circumnavigate the ring back to with the obstacle on the right hand: 16 steps, recording at every cell. The unique minimum is , at distance 2.
- Walk to the leave point the shorter way round. The ring is symmetric about row 2, so both ways are 8 steps; the code breaks the tie clockwise. 8 steps.
- Motion-to-goal: , — 2 steps.
Total steps. The bound: . For contrast, Bug2 on the same world leaves the ring the first time it is back on row 2 and closer to the goal — at , after 8 steps of boundary following — for , which here is also the shortest 4-connected path.
The grid-specific footnote promised above. On a 4-connected grid "move straight toward the goal" is a staircase whose length is , not the Euclidean . The bound the Bug Preview prints, and the one the library checks on random worlds, is Choset's inequality with that grid distance in place of ; on the worked example the m-line is a row, so and the two bounds coincide. Chapter 3 does the continuous version, where the footnote disappears.
Make the obstacle 4 × 4 (columns 3–6, rows 1–4) in a 10 × 6 world with S at (0, 2) and G at (9, 2). How many steps does Bug1 take?
Implementation in Rust
The first program is a dependency-free Rust binary, edition 2024, by design: your first build must
finish in seconds and cannot fail on a native dependency. The workspace Cargo.toml already pins the
book's stack (nalgebra 0.35, parry2d 0.30, rand 0.9, petgraph 0.8, pathfinding 4.15), but
nothing in this chapter touches it.
Setup (CI-tested on Linux, macOS, Windows): install rustup and the stable toolchain (edition
2024 needs 1.85 or later); clone the book's repository; then
cargo run -p ch01_hello
cargo test -p ch01_helloOptional, and deferred to Chapter 2: rustup target add wasm32-unknown-unknown for the browser
cross-check, and Node 20.9 or later for the site in web/.
The world and the sensor
//! Bug1 on a text world. Zero dependencies, edition 2024.
/// '#' is obstacle, everything else is free. 4-connected unit moves.
struct TextWorld { rows: Vec<Vec<u8>> }
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
struct Cell { x: i32, y: i32 }
/// Headings in screen coordinates (y grows downward): E, S, W, N. Turning right adds one.
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
enum Dir { E, S, W, N }
/// The index into STEP back to a heading: 0 → E, 1 → S, 2 → W, 3 → N.
impl From<usize> for Dir {
fn from(i: usize) -> Dir { [Dir::E, Dir::S, Dir::W, Dir::N][i % 4] }
}
impl Dir {
fn right(self) -> Dir { Dir::from(self as usize + 1) }
fn left(self) -> Dir { Dir::from(self as usize + 3) }
fn back(self) -> Dir { Dir::from(self as usize + 2) }
}
impl Cell {
/// One unit move; STEP is defined with the behaviors below.
fn step(self, d: Dir) -> Cell {
let (dx, dy) = STEP[d as usize];
Cell { x: self.x + dx, y: self.y + dy }
}
}
impl TextWorld {
/// The contact sensor: is the cell blocked — or outside the bounded workspace?
/// Choset assumes W is bounded; here the border is simply a wall the sensor feels.
fn blocked(&self, c: Cell) -> bool {
if c.y < 0 || c.x < 0 { return true; }
match self.rows.get(c.y as usize).and_then(|r| r.get(c.x as usize)) {
Some(b'#') => true,
Some(_) => false,
None => true,
}
}
/// Parse a map; S and G are the query.
fn parse(s: &str) -> (Self, Cell, Cell) {
let rows: Vec<Vec<u8>> = s.lines().filter(|l| !l.is_empty()).map(|l| l.bytes().collect()).collect();
let find = |ch: u8| rows.iter().enumerate()
.find_map(|(y, r)| r.iter().position(|&b| b == ch).map(|x| Cell { x: x as i32, y: y as i32 }))
.expect("the map marks S and G");
let (s, g) = (find(b'S'), find(b'G'));
(TextWorld { rows }, s, g)
}
}
/// Euclidean distance d(x, y) — Bug1 may measure it, by assumption (Choset §2.1).
fn dist(a: Cell, b: Cell) -> f64 {
(((a.x - b.x).pow(2) + (a.y - b.y).pow(2)) as f64).sqrt()
}The two behaviors
const STEP: [(i32, i32); 4] = [(1, 0), (0, 1), (-1, 0), (0, -1)]; // E, S, W, N
/// One step of motion-to-goal: the 4-neighbor that most reduces d(·, goal).
/// `Err(dir)` when that neighbor is blocked — the robot has hit the obstacle,
/// pushing in direction `dir`.
fn motion_to_goal(w: &TextWorld, x: Cell, goal: Cell) -> Result<Cell, Dir> {
let (best, dir) = (0..4)
.map(|d| (Cell { x: x.x + STEP[d].0, y: x.y + STEP[d].1 }, d))
.min_by(|a, b| dist(a.0, goal).total_cmp(&dist(b.0, goal)))
.expect("four neighbors");
if w.blocked(best) { Err(Dir::from(dir)) } else { Ok(best) }
}
/// One step of boundary following with the obstacle on the robot's right hand —
/// the grid analogue of the surface-normal rule of Choset §2.3.1. O(1) sensing.
///
/// Try to turn toward the wall (it may have turned away), else go straight,
/// else turn away, else reverse. On the ring around a block this traces the
/// 8-neighborhood of the obstacle, which is the perimeter the bound counts.
fn follow_boundary(w: &TextWorld, x: Cell, heading: Dir) -> (Cell, Dir) {
for h in [heading.right(), heading, heading.left(), heading.back()] {
let n = x.step(h);
if !w.blocked(n) { return (n, h); }
}
(x, heading) // boxed in on all four sides: cannot happen from a free start
}
/// Walk the whole boundary from the hit point until it is re-encountered.
/// Returns the cells visited after the hit, ending with the hit itself —
/// so the length is the perimeter p_i as the robot measures it.
fn circumnavigate(w: &TextWorld, hit: Cell, toward: Dir) -> Vec<Cell> {
let (mut cell, mut heading, mut ring) = (hit, toward.left(), Vec::new());
loop {
(cell, heading) = follow_boundary(w, cell, heading);
ring.push(cell);
if cell == hit { return ring; }
}
}Bug1 and the program
enum Outcome { Reached(Vec<Cell>), Unreachable { at: Cell } }
/// Bug1, Choset Algorithm 1: motion-to-goal; on contact circumnavigate fully,
/// remembering the perimeter point closest to the goal; return to it the shorter
/// way; repeat. If leaving the leave point toward the goal would re-enter the
/// obstacle, the goal is unreachable.
fn bug1(w: &TextWorld, start: Cell, goal: Cell) -> (Outcome, Vec<usize>) {
let (mut path, mut perimeters, mut x) = (vec![start], Vec::new(), start);
while x != goal {
match motion_to_goal(w, x, goal) {
Ok(next) => { x = next; path.push(x); }
Err(dir) => {
let hit = x;
let ring = circumnavigate(w, hit, dir);
perimeters.push(ring.len());
path.extend(&ring);
// The leave point: closest to the goal; the first wins a tie.
let (i, _) = ring.iter().enumerate()
.min_by(|a, b| dist(*a.1, goal).total_cmp(&dist(*b.1, goal))).unwrap();
// The shorter way round; a tie goes forward (clockwise).
if i + 1 <= ring.len() - 1 - i { path.extend(&ring[..=i]); }
else { path.extend(ring[i..ring.len() - 1].iter().rev()); }
x = ring[i];
if motion_to_goal(w, x, goal).is_err() {
return (Outcome::Unreachable { at: x }, perimeters);
}
}
}
}
(Outcome::Reached(path), perimeters)
}
/// The map with the executed path marked `·`, and S and G on top.
fn render(w: &TextWorld, s: Cell, g: Cell, path: &[Cell]) -> String {
let mut rows: Vec<Vec<char>> = w.rows.iter()
.map(|r| r.iter().map(|&b| if b == b'#' { '#' } else { '.' }).collect())
.collect();
for c in path { rows[c.y as usize][c.x as usize] = '·'; }
rows[s.y as usize][s.x as usize] = 'S';
rows[g.y as usize][g.x as usize] = 'G';
rows.iter().map(|r| r.iter().collect::<String>()).collect::<Vec<_>>().join("\n")
}
const WORLD: &str = "\
.........
...###...
S..###..G
...###...
.........
";
fn main() {
let (w, s, g) = TextWorld::parse(WORLD);
match bug1(&w, s, g) {
(Outcome::Reached(path), perimeters) => {
let steps = path.len() - 1;
let p: usize = perimeters.iter().sum();
println!("{}", render(&w, s, g, &path));
println!("steps: {steps} straight-line: {} bound d + 1.5·Σp: {}", dist(s, g), dist(s, g) + 1.5 * p as f64);
}
(Outcome::Unreachable { at }, _) => println!("goal unreachable; detected at {at:?}"),
}
}..·····..
..·###·..
S··###··G
..·###·..
..·····..
steps: 28 straight-line: 8 bound d + 1.5·Σp: 32(The rendering marks the executed path with ·: out along row 2, once around the block, then the
shorter way back to the leave point. The Bug Preview above also marks the hit point H at
and the leave point L at .) The tests lock the number, and lock the failure mode:
#[test]
fn worked_example_ch01() {
let (w, s, g) = TextWorld::parse(WORLD);
let (Outcome::Reached(path), perimeters) = bug1(&w, s, g) else { panic!("reachable") };
assert_eq!(path.len() - 1, 28);
assert_eq!(perimeters, vec![16]);
assert!(28.0 <= 8.0 + 1.5 * 16.0);
}
#[test]
fn unreachable_is_detected() {
let (w, s, g) = TextWorld::parse(".........\n.....###.\nS....#G#.\n.....###.\n.........\n");
let (outcome, perimeters) = bug1(&w, s, g);
assert!(matches!(outcome, Outcome::Unreachable { .. }));
assert_eq!(perimeters.len(), 1, "one circumnavigation, then give up");
}
/// Exercise 6: implement `bug2`, then `cargo test --features exercise-bug2`.
#[cfg(feature = "exercise-bug2")]
#[test]
fn bug2_text_world() {
// Chapter 3 derives Bug2 properly; the expected count on this world is 12.
let (w, s, g) = TextWorld::parse(WORLD);
assert_eq!(bug2(&w, s, g).len() - 1, 12);
}The Bug Preview at the top of this chapter runs web/lib/robots/bug-preview.ts, a line-for-line
port of this program onto a rasterized board, and the book's self-checks assert the same 28, the
same 16, the same 12, and the same unreachable verdict on the same text worlds. The animation you
watched and the number you printed are one computation.
Putting it together
The integration lab is your own machine. Clone the workspace, build, reproduce the 28. Then edit
WORLD to the block of the exercise above, predict the new length and the new bound
before running, run, and check. The point is not the number; it is that you have just watched a
guarantee stay true while the world changed under it, and that a test will tell you if a future edit
ever breaks it.
Two conventions begin here and never change. Every worked number in this book is reproduced by a test: a Rust test in the crate and an invariant in the browser library, so that the prose, the program, and the animation cannot drift apart without the build going red. And every chapter runs the same rhythm, in the same colors.
The color code is not decoration. Hover a tinted term in an equation on any page — try the
in the first derivation above — and every figure on the page
fades every other role. The amber in the Piano Mover, the amber term-cobstacle in the definition
of , and a // --rm-cobstacle comment in a Rust listing are the same object seen three ways.
Green is where you start, red is where you are going (and, in Chapter 2's simulator, the flash of a
collision — a collision is where a plan ends), slate is a wall, amber hatched is a wall seen from
configuration space, blue is a roadmap or tree, purple is the path a planner found, orange is the
robot and the path it actually drove.
A map of what comes next, by cell of the taxonomy board. Chapter 2 builds the cast and the collision checker that every planner asks its four questions of. Chapter 3 proves what this chapter only checked: Bug1, Bug2, and Tangent Bug, with their bounds. Chapters 4 and 5 are configuration space done properly — the amber computed exactly, the torus and as manifolds. Part II is the classical planners for a point in : search, potentials, roadmaps, cells. Part III trades completeness for speed and gets probabilistic completeness back. Part IV is what a planner must know about not knowing where it is. Part V puts time, dynamics, and Hitch's constraint back in. Part VI closes the loop the hook above opened: three robots, one planning stack, running live.
Exercises
- Foundation exerciseDifficulty 1 of 3Classify the gallery
Classify each of Choset's motivating examples — the piano mover, the Mini AERCam, the CyCab and Segway, RHINO, Sojourner, demining, the painting arm, snake robots, surgical robots, digital actors, protein folding — on all three axes of the taxonomy board. Which cells of Table 1.1 does the gallery leave empty? Name one robot deployed since 2020 that fills each empty cell.
- Foundation exerciseDifficulty 2 of 3Count the degrees of freedom
The sofa in the Piano Mover has . Count the degrees of freedom of (a) two sofas in the same room, (b) two sofas tied by a rope of fixed length pulled taut, (c) one sofa on casters that cannot roll sideways. For each, say whether the constraint changes , and why — this is the holonomic versus nonholonomic distinction of Choset §3.3, met early.
- Conceptual exerciseDifficulty 1 of 3Predict the leave side
In the Bug Preview, set the goal directly behind the larger of the two obstacles.
Predict firstBefore pressing play: which side will Bug1 leave the obstacle from, and will the counter land closer to d or to the bound?
- Conceptual exerciseDifficulty 2 of 3The widest channel
In the Piano Mover, shorten the sofa until it fits the doorway nose-first. Predict how the amber slice changes as you rotate the sofa by , then verify. Which heading gives the widest channel through the doorway, and why is that heading not when the doorway is in a side wall?
- Practical exerciseDifficulty 2 of 3A C-shaped obstacle and a lying sensor
Modify
ch01_helloso the obstacle is aCshape opening toward the start. Predict the path length and the bound before running. Then make the contact sensor lie with probability , using a fixed seed and a tiny hand-rolled linear congruential generator — still zero dependencies — and report what breaks: the length, the guarantee, or both. - Practical exerciseDifficulty 3 of 3Bug2, and a world where it loses
Implement Bug2 in
ch01_helloby changing only the exit condition of boundary following: leave when back on the fixed m-line, closer to the goal than the hit point, and able to step toward it. Makebug2_text_worldpass with 12 — it compiles only when you ask for it, withcargo test --features exercise-bug2. Then construct a text world where Bug2's count exceeds Bug1's. The comb preset in the Bug Preview is one answer — a hook whose nearest-to-goal point sits high above the m-line, so that Bug1 leaves from there on a fresh line over a row of teeth that Bug2, welded to the m-line, must climb one by one. You have just drawn Choset's figure 2.4.
References
- Choset, H., Lynch, K. M., Hutchinson, S., Kantor, G., Burgard, W., Kavraki, L. E., and Thrun, S. (2005) Principles of Robot Motion: Theory, Algorithms, and Implementations. MIT Press.link to Principles of Robot Motion: Theory, Algorithms, and Implementations (opens in a new tab)
Chapter 1 is the source of the gallery, Table 1.1, eq. (1.1), and the notation this book adopts; §2.1 is the source of Bug1, Bug2, and the bound checked here. Lumelsky and Stepanov's 1987 Algorithmica paper, 'Path-planning strategies for a point mobile automaton moving amidst unknown obstacles of arbitrary shape', is the Bug algorithms' original, cited there as [301].
- Lozano-Pérez, T. (1983) Spatial Planning: A Configuration Space Approach. IEEE Transactions on Computers C-32(2), 108–120.doi:10.1109/TC.1983.1676196 (opens in a new tab)
The paper that made 'the robot is a point' an algorithm: C-obstacles computed for polygons, the ancestor of the Piano Mover's amber.
- Latombe, J.-C. (1991) Robot Motion Planning. Kluwer Academic Publishers (The Springer International Series in Engineering and Computer Science, vol. 124).doi:10.1007/978-1-4615-4022-9 (opens in a new tab)
The reference text for the decade before Choset, and the source of the piano-mover framing of configuration space that Chapter 1 inherits; its author wrote Choset's foreword.
- Kavraki, L. E., Švestka, P., Latombe, J.-C., and Overmars, M. H. (1996) Probabilistic roadmaps for path planning in high-dimensional configuration spaces. IEEE Transactions on Robotics and Automation 12(4), 566–580.doi:10.1109/70.508439 (opens in a new tab)
Where 'probabilistically complete' — the third kind of completeness on the taxonomy board — enters the field. Chapter 11.
- Karaman, S. and Frazzoli, E. (2011) Sampling-based Algorithms for Optimal Motion Planning. International Journal of Robotics Research 30(7), 846–894.doi:10.1177/0278364911406761 (opens in a new tab)
The modern occupant of the board's 'Optimal' cell: asymptotic optimality for sampling-based planners. Chapter 13.
- Şucan, I. A., Moll, M., and Kavraki, L. E. (2012) The Open Motion Planning Library. IEEE Robotics & Automation Magazine 19(4), 72–82.doi:10.1109/MRA.2012.2205651 (opens in a new tab)
What a planner is today: infrastructure, not a research artifact. The systems framing behind the taxonomy board's chapter links.
