The last post taught the robot to stop its blade before a garden path, as long as the path
was on the map. If a path isn't drawn, or is drawn in the wrong place, the robot would mow straight over it. This post
adds the second layer: the robot sees the paving for itself.
A spinning blade on gravel or paving throws stones. Until now the robot avoided the problem by never leaving the
lawn, so it couldn't cross a garden path, a patio or a driveway at all. That's the first of the three ground hazards in
the perception plan (docs/phase5-perception.md, 5.1c). The
other two are drop-offs and slopes.
Last time, Vector was the one platform still failing its smoke test. It ran
16 to 18 cm off its path (the limit is 15), and its heading estimate was off by about 3° (the limit is 2°). We
blamed its filter. The filter was fine: the simulated tyres weren't.
The first full smoke test of the six platforms had two failures, both at the dock:
Tachyon never left it, and Vector mowed the patch and then missed the dock three times. Neither was about the dock.
One was a clock, one was steering, and fixing them turned up a third problem that isn't finished.
The first back-yard mow with the 3D lidar (backyard-raised-2) ended against the fence. On the outer lap, 35 cm from
the lawn's edge, the robot drove right up to each corner before turning. That put its nose 14 cm past the edge, and
at the fence the safety gate saw the fence inside its stop field and stopped the robot for good, 0.36 m away. Against a
wall it would simply have hit it.
The sim's flowerbed is a 15 cm raised box. To the 3D lidar, its edge is an obstacle like any other, and the safety
gate never lets the robot's nose get closer than about 0.57 m to an obstacle (the lidar's blind range for a 4 cm
object, plus 10 cm). The planner ended stripes 0.26 m from keep-outs. Those two numbers can't both hold, so we decided
on option C: by default the robot keeps further from raised keep-outs and leaves the strip for the trimmer, and
an owner switch lets it mow right up to them.
Building it turned up three more bugs. A raised bed can pass for long grass, and so can a fence. And the robot's route
home could take it into a corner it couldn't get out of.
Last night's result was uncomfortable: the 3D lidar sees a 10 cm hedgehog in 5 cm grass and loses it in 7 cm grass.
Height is all the lidar measures, so the lawn has to stay short enough for an animal to stand out of it. That's the
long-grass rule (decision D2): if the uncut grass ahead is too tall, the robot doesn't mow it. It stops the blade,
goes home and says the lawn is overdue. An owner switch in the app turns the rule off for one mow.
Building it took one measurement that worked first time, one rule that worked first time, and a clearance that
trapped the robot three different ways before we found the version that can't.
Until tonight the sim lawn was a flat green plane. Real grass is 5 to 10 cm tall, and our 3D-lidar safety gate
stopped for anything 3 cm above the ground. So we grew grass the lidar can see, and the robot never left the dock.
Seventeen runs later it mows a whole zone in 7 cm grass, over bumps and a 25 cm mound, with zero false stops. Every
fix in between came from a stop the robot explained itself.
We reviewed the Phase 5 (perception) plan together and made all seven decisions in it. Then we built the first
piece, which needs no camera and no AI: the robot doesn't mow in the dark.
A factory doesn't ship a product because each part passed its own test. At the end of the line, one last test
checks the assembled thing: every sensor, every motor, every way it can stop. Our robot now has one: a single
script, make eol-run, that drives the robot through 33 checks and prints PASS or FAIL. It found two real
problems on its first two runs, in a simulator we thought we knew well.