Route Optimization in Practice: What Breaks When You Actually Try It #6
Mission-analyzer
started this conversation in
Show and tell
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
The first post on this described the core method: turn each populated area into a circular exclusion zone, build a tangent visibility graph around every obstacle relevant to a leg, and solve it with Dijkstra. That's the geometry, and it works. What it doesn't tell you is what happens when you point the thing at a real 600+ km mission with dozens of real settlements and see what comes back.
Four things came back that the clean version of the algorithm didn't handle.
Avoiding one village can walk you into another
The obstacle set for a given leg is built from settlements near that leg's original straight line — a margin of 3x the safety threshold around it, generous enough to catch anything the detour might plausibly need to know about. Generous enough for a single settlement, anyway.
Put two settlements close together and the detour needed to clear the first one can genuinely swing wider than that margin — right past the second one, which was never in the graph to begin with, because it never looked close enough to matter until the path bent toward it. The optimizer had correctly avoided everything it was told about. It just hadn't been told about everything.
The fix isn't a wider margin — there's no fixed multiplier that's safe for every possible cluster density. It's a fixed-point loop: build the detour, check the resulting path against every settlement on the route (not just the ones already in the graph), and if it grazes something new, add that settlement to the obstacle set and rebuild. Repeat until nothing new turns up, capped at five rounds as a sanity limit. In testing this converges in one or two extra passes even for legs with a dozen obstacles.
Some legs are just too short to fix
A single obstacle circle sitting near a leg shorter than roughly twice the safety radius leaves no room to route around it while keeping both endpoints fixed — there's nowhere to swing an arc that clears the circle and still gets back to two points that close together. The optimizer already caught this and reported it as a failure rather than silently returning garbage, which was the right call. It just left the operator with two unresolved legs and no next step.
The next step is merging: two adjacent failed legs, tried together as one longer span with the shared waypoint between them temporarily removed. A longer span means more room, and short legs are disproportionately likely to be adjacent to each other, since the same dense cluster of terrain features that made one leg impossible usually makes its neighbor tight too. When the merge succeeds, the shared waypoint is genuinely gone from the final mission — not routed through, gone — and the report says so explicitly, by name, so nobody discovers it by noticing a waypoint count that doesn't match what they expected.
A waypoint disappearing is not just a geometry problem
This is the one that doesn't show up if you only test with plain waypoint lists. Real missions have more than navigation points in them — camera triggers, servo commands, speed changes — and those commands don't float freely, they're anchored to a specific position in the sequence, often right next to a specific waypoint. Delete that waypoint because a merge absorbed it and the naive approach either loses the command outright or leaves it attached to whatever now happens to sit at that list position, which is correct by accident and only when you're lucky.
The fix relocates any command found immediately next to a waypoint being removed to the nearest surviving point on the new detour, measured by actual distance, not by list position. A command anchored to a spot that no longer exists moves to whatever new point sits closest to where that spot used to be — the operator's evident intent (do this near here) survives even though the specific waypoint carrying that intent didn't.
The sharper version of this problem is
DO_JUMP. It doesn't reference a waypoint by identity, it references one by number — a sequence index into the file. Every mission file gets renumbered sequentially on save, and inserting or removing waypoints anywhere in the route shifts every index after that point. A jump target that was correct before optimization silently points at the wrong waypoint after, with no error, no warning, just a mission that loops back to the wrong place in flight. Fixing this means walking thewhole rebuilt sequence, finding every jump target's original waypoint, and re-pointing it at wherever that same waypoint (or, if it was removed, the nearest surviving one) ended up.
None of this is exotic control-flow. It's the ordinary cost of a mission format where meaning is partly encoded in position, and any tool that reshapes the route has to carry that meaning forward on purpose, because nothing does it automatically.
What this cost, concretely
Every one of these was caught by constructing an actual geometry that triggers it — real coordinates, real obstacle placement, real distance checks against the resulting path — not by reasoning about the code in the abstract. Twice, the geometry test caught a mistake in the test itself (wrong reference point, wrong coordinate) before it caught anything in the optimizer, which is a reasonable trade: a test that's hard to get right by accident is also hard to fool by accident.
The honest summary: the geometry was right from the start. Getting a geometrically correct detour to survive contact with a real mission file — adjacent obstacles, short legs, attached commands, jump targets — took four separate rounds of "here's what actually happened when we ran it," each one narrower and more specific than the last.
All reactions