v1.0-alpha β the start of a new major version. Vanchor-NG is a ground-up, software-first rewrite that replaces the original Vanchor (0.1-alpha).
Vanchor-NG turns a cheap trolling motor into a GPS-guided autopilot and anchor system. Drop a virtual anchor to hold a spot, hold a heading like a real autopilot, or tap the map and say "take me here" β the boat plans a water-only route around islands and steers itself there, correcting for wind and current drift along the way.
New here? The getting-started guide takes you from zero to a simulated boat holding anchor in about ten minutes β no hardware, no coding experience needed.
Prefer to watch first? Open the 3D concept walkthrough β a 90-second holographic film of the whole control loop (drop an anchor, drift, aim, thrust, re-lock), straight in your browser, fully offline.
The headline is that it runs entirely in simulation, with no hardware at all. A built-in physics simulator and simulated NMEA sensors close the control loop on your laptop, so the whole navigation/control stack can be developed and tested without a boat, a Pi, or a single wire. When you do have hardware, the same code drives it β only the device construction changes.
It is a PWA (Progressive Web App): installable, works offline, and served by the boat's own Raspberry Pi.
This is 1.0-alpha β a from-scratch rewrite that supersedes the 0.1-alpha project. See
RELEASE.mdfor release notes and migration notes.
Vanchor = Virtual Anchor. The headline feature: tap a spot and the boat holds it β GPS station-keeping on a cheap trolling motor, no ground tackle. It anticipates wind and current drift (crabbing to stay put rather than orbiting), snaps back if pushed outside a watch circle you set, and takes a jog to nudge the hold point a metre at a time. A rolling hold-quality readout (RMS error, % of time inside the circle) lets you compare how tightly it's holding.
Three anchor styles are available via a Classic | Smart | Leif segmented control in the Anchor panel β switchable live without re-dropping the anchor:
-
Classic (default) β a hand-tuned deadband/drive/reverse PID law: idle in the middle of the circle, drive back toward the mark when pushed out, back straight up when the mark is astern (no wasteful looping). Predictable and dependable.
-
Smart (opt-in) β a tiny neural net that refines the PID rather than replacing it: the command is
clip(pid + 0.3 Β· net(obs)), so the worst case is just the PID. The net is a ~1.6k-parameter tanh MLP (8-dim body-frame observation Γ 4 stacked frames β 32 β 16 β 2), small enough to run on the Raspberry Pi as a few microsecond numpy matrix multiplies β no ML runtime, no GPU. It's trained offline by Evolution Strategies (gradient-free, numpy-only) against the exact Fossen 3-DOF physics across thousands of randomised scenarios β wind 0β12 m/s with gusts, current up to ~1.2 m/s, and the boat itself (mass, hull, motor power, bow/stern/centre mount). A runtime guardrail watches the actual hold and decays the net's influence back toward the pure PID if it ever underperforms. Net result vs the PID baseline: an equally tight (slightly tighter) hold at 3β4Γ less motor energy β easier on the battery while anchored β across bow and stern mounts. -
Leif (experimental) β a pure full-azimuth learned station-keeper with no PID fallback. Holds a stern mount exceptionally tight but runs the motor constantly and is best at β₯ 5 m radius. A research mode.
-
Vectored thrust (opt-in toggle) β works with Classic and Smart; swings the motor through its full rotation to push directly against the wind/current instead of reorienting the whole hull first. In a beam set that tightens the hold dramatically (measured RMS radial error 3.3 m β 1.3 m, 100 % of the time inside the circle), and it's stable on bow and stern mounts.
Everything above runs in the built-in simulator with no hardware β you can watch the anchor hold against a gusting beam current on your laptop.
Vanchor-NG runs on any single-board computer that can reach a motor + steering driver over serial/GPIO β wire it up however suits your boat. If you'd rather not design that part yourself, the companion vanchor-pcb project is an easy, ready-made option: an open-hardware carrier board (~$41, 12 V, 125 Γ 95 mm) that drops an Orange Pi Zero 3 (or a Raspberry Pi) running Vanchor-NG next to a Raspberry Pi Pico 2 real-time motor controller, with an on-board servo bridge, a cabled trolling-motor thrust-driver board, headers for the HWT901B compass/IMU and GPS, and an optional NMEA 2000 / CAN provision. The Pico holds the hardware deadman β it ramps the motor to neutral if Vanchor-NG stops talking, so STOP survives a computer crash. It's just one convenient way to build the helm, not a requirement β and nothing here is needed to try Vanchor-NG, which is sim-first.
β οΈ The vanchor-pcb board is in its prototype stage β under active development, not yet built and validated on the water. Treat the design as a work in progress: review it yourself before ordering or wiring anything.
A typical build wired that way:
graph TD
TAB["π± Phone / tablet<br/>(installable PWA)"] <-->|"WiFi Β· HTTP + WebSocket"| VNG
subgraph SBC["Orange Pi Zero 3 / Raspberry Pi"]
VNG["<b>Vanchor-NG</b><br/>navigator Β· controller Β· safety governor"]
end
GPS["GPS receiver"] -->|"NMEA (serial / TCP)"| VNG
HWT["HWT901B AHRS<br/>compass + IMU"] -->|"UART"| VNG
VNG <-->|"link (helm PCB)"| PICO["Raspberry Pi Pico 2<br/>real-time motor controller<br/>β± 800 ms deadman watchdog"]
N2K[("NMEA 2000 bus")] <-->|"CAN"| PICO
PICO -->|"PWM"| TD["Thrust-driver board<br/>BTN8982TA H-bridge"] --> MOT(("Trolling motor"))
PICO -->|"PWM"| SRV["Servo bridge"] --> WORM["Steering worm servo"]
WORM -->|"AS5600 angle feedback"| PICO
The steering end is a 3D-printable worm-gear steering servo β a small gearmotor turns a worm that swings the trolling-motor shaft (self-locking, so it holds a heading with the motor idle), with an AS5600 magnetic encoder for absolute angle feedback. STLs, an assembly gallery, and build/waterproofing notes live in the dedicated vanchor-cad repo β the current revision is sealed (twin lip seals + silicone-gasket lid) and fully 3D-printable.
All four run on the built-in simulator β no hardware, no boat, just
vanchoron a laptop.
Reach any view at /view/<name> β deep-linkable and offline-capable. Each drops
the chart and rearranges the same live widgets for a job at the helm; every view
keeps an ever-present STOP.
![]() |
![]() |
![]() |
Helm (/view/helm) β big mode grid, quick actions, dominant STOP |
Instruments (/view/instruments) β a large glance HUD |
Manual (/view/manual) β big thrust + steering |
An opt-in Daylight high-contrast theme keeps it readable in direct sun (dark stays default):
One guide per mode lives in
docs/modes/.
Navigation & control
- Virtual GPS anchoring (position hold) β drop a virtual anchor and hold the spot, with heading-aware drift anticipation and an anchor jog to nudge the hold point.
- Autopilot heading-hold β set a compass heading and hold it.
- Waypoint navigation with cross-track correction and predictive drift compensation (crabs into wind/current so the ground track stays true).
- Smart "take me here" water routing β water-only routes that avoid land and islands: Fastest (visibility graph + A*) or Along-shoreline (hugs the coast, into bays). Routes load editable and unstarted for review. An idle tap on the chart opens a pin popup (distance, ETA, depth) with one-tap Anchor here and 600 ms hold-to-engage Take me here.
- Loop-around-island routing and area-survey "map mode" (lawnmower coverage over a drawn box/polygon).
- Work Area mode β work a set of spots: tap them in, or draw an area and auto-generate a grid; the boat travels to each, holds station, then advances β on a dwell timer or a big on-screen "Go to next spot" button β with an optional per-spot hold heading, and loop / there-and-back patrol over the set.
- Cruise control (hold knots) and % engine-power throttle.
- Pause / resume / stop mid-route; record-a-track / replay / retrace; GPX import.
Fishing modes
- Contour-follow β hold a chosen depth contour from the live sounder.
- Circle / Orbit β loop a marked point at a set radius (CW/CCW).
- Trolling pattern β a sinusoidal S-curve weave at a held speed.
Safety pack
- Battery monitor (state-of-charge, voltage, draw, range/time-to-empty) with auto-recommended return-to-launch on low battery.
- Shallow-water / no-go geofence auto-stop.
- Link-loss failsafe β holds position if the controlling phone drops off.
- Man-overboard (mark + return) and a safety governor (thrust slew limiting, reverse delay, loss-of-fix failsafe, anchor-drag alarm).
- Passive anchor alarm β motor-off GPS watch circle over the physical anchor: arm from the Anchor panel; server-side 1 Hz watch keeps alarming while the phone sleeps (banner + sound + telemetry); one-tap Recover engages anchor hold at the alarm point. Persists across restarts. Zero motor commands while passive.
Sensing & data
- Depth mapping β a colour-ramped depth grid (marine shallowβdeep) with radiating coverage from each sounding, plus an isobath contour overlay; persists across sessions.
- Catch logging + analytics β log species, length, weight; per-species stats, best time-of-day, best depth band, and a heatmap.
- Trips + GPX export β live distance/duration/avg-max speed and a past-trips list.
- GPS-offset calibration ("adjust my position") and sensor-anomaly spike rejection.
- Auto-calibration drive that measures top speed / accel / drag / turn-rate / steering sign, then auto-tunes the PIDs.
Boats, devices & systems
- Multiple editable boat profiles with ready presets (jon boat β bow/stern trolling β 15 HP outboard) and a hull-character handling model.
- Per-device simulation OR real hardware β GPS, compass, depth and motor each
choose
sim/serial/nmea; you can even bench-test a steering servo against a fully simulated autopilot. - Versioned backup / restore of all persistent state (one ZIP).
- Measure tool, reference grid, a phone-friendly mobile / remote-helm mode, and PWA / offline support.
- Demo mode β
vanchor --demoboots an instant forced-sim demo (seeded looping route, ephemeral data, DEMO badge, never touches real devices or your data dir).--demo-readonlyadds an observer-only posture for hosted demos (controls dimmed; STOP always works from any client). - Hardware setup wizard β guided 5-step scan-and-probe modal (Settings β Devices β "π§ Guided hardware setupβ¦") that detects your GPS, compass and motor on the correct ports and writes the config. See docs/setup-wizard.md.
- Web Push notifications β anchor drag, anchor watch, battery, depth and
link-loss alarms reach the phone with the app closed. Optional extra
(
pip install vanchor-ng[push]); opt-in per device; needs HTTPS. See docs/push-notifications.md. - Docker + hassio-style supervisor deployment with offline-first sideload updates, health-gated rollback, backups and WiFi management; a ready-made flashable SD image for Raspberry Pi Imager. See docs/deploy-pi.md.
The whole point of Vanchor-NG is that you never need hardware to develop or test it. A built-in physics simulator owns ground truth; simulated GPS, compass and depth sensors emit real NMEA (RMC/HDM/DPT) with realistic noise. The navigator and controller can't tell sim data from a real receiver, so the entire control stack runs and is tested on a laptop. A deterministic harness steps the full loop in lockstep with seeded noise, so closed-loop tests run in milliseconds and never flake.
The data flows around one closed loop. The controller only ever reads the perceived (noisy) sensor state β exactly as it will with real hardware β while ground truth lives only in the simulator:
motor command ββΆ boat physics ββΆ GPS/compass/depth NMEA ββΆ navigator ββΆ state
β² β
βββββββββββββββββ helm βββ control mode ββββββββββββββββββββββββββββ
Every simulated device implements the same hardware interfaces the real serial gear does, so swapping to hardware changes only how devices are constructed β nothing in the control logic. The backend is Python + asyncio + FastAPI with a WebSocket telemetry stream; the front end is vanilla JS + Leaflet (no build step, no framework).
The web UI is a Progressive Web App. It is installable, loads offline, and uses a network-first service worker so it always prefers fresh data but still works when the network drops. In a real deployment the boat's Raspberry Pi serves the app directly to your phone.
On a boat Pi: flash the ready-made SD image β see docs/deploy-pi.md. Paste the URL below into Raspberry Pi Imager (OS β "Use custom β Provide URL"):
https://github.com/AlexAsplund/vanchor-ng/releases/latest/download/os_list.json
On a laptop / dev machine:
python -m venv .venv && . .venv/bin/activate
pip install -e ".[dev,routing]"
vanchor --demo # instant demo: simulated boat driving a charted lake
vanchor --host 0.0.0.0 --port 8000Demo mode never touches real devices or your data dir.
Then open http://localhost:8000. Vanchor-NG defaults to simulation, so this just works with no hardware. You'll see a boat on the map β drop an anchor, set a heading, or tap "take me here" and watch it steer.
Vanchor-NG reads configuration from a YAML file and from environment
variables via a .env file (copy .env.example and edit it). The key
VANCHOR_* variables:
| Variable | Purpose |
|---|---|
VANCHOR_HOST, VANCHOR_PORT |
server bind address / port |
VANCHOR_DATA_DIR |
where persistent data lives (boats, depth map, trips, charts) |
VANCHOR_MODEL |
boat physics model (fossen / simple) |
VANCHOR_HARDWARE |
master switch: simulation vs. real hardware |
VANCHOR_GPS_SOURCE, VANCHOR_COMPASS_SOURCE, VANCHOR_DEPTH_SOURCE, VANCHOR_MOTOR_SOURCE |
per-device source (sim / serial / nmea; motor also both) |
VANCHOR_GPS_PORT, VANCHOR_COMPASS_PORT, VANCHOR_MOTOR_PORT |
serial ports for real devices |
VANCHOR_BAUDRATE |
serial baud rate |
VANCHOR_NMEA_TCP, VANCHOR_NMEA_TCP_HOST, VANCHOR_NMEA_TCP_PORT |
NMEA-over-TCP bridge (feed/read from a phone or plotter) |
VANCHOR_SIM_START_LAT, VANCHOR_SIM_START_LON |
simulator start position |
VANCHOR_OVERPASS_URLS |
OSM Overpass endpoints for water/routing data |
VANCHOR_USER_AGENT |
HTTP User-Agent for OSM requests |
See .env.example for the full list and defaults. Device-config changes
apply on the next restart (see below).
python -m pytest -q # unit + deterministic closed-loop integration tests
python e2e_smoke.py # isolated end-to-end smoke testThe integration tests run the full navigator + controller + simulator loop deterministically (no asyncio, no wall-clock, seeded sensor noise) and assert that, e.g., anchor-hold converges and stays within a few metres under continuous wind + current drift.
src/vanchor/
app.py config-driven Runtime wiring + CLI entrypoint
core/ events, models, geo, pid, state, config, boat profiles, backup
nav/ nmea, navigator, routing/water, depth, survey, track, trip
sim/ fossen (3-DOF) + simple physics, devices, bathymetry, weather, battery
hardware/ real serial / NMEA device + motor drivers (mirror the sim devices)
controller/ controller (+ Helm), modes, calibration, safety
ui/ server.py (FastAPI WS + REST), static/ (Leaflet PWA)
analysis/ headless scenario runner + auto-tuner
tests/ pytest suite + deterministic harness
docs/ human docs + docs/llms/ AI developer guide
- Human docs live in
docs/β start atdocs/README.mdfor an index (architecture, features, APIs, simulator, firmware, analysis, roadmap, assumptions). - The AI / LLM developer guide lives in
docs/llms/β a curated, per-subsystem guide written for LLMs working on the code (also linked fromAGENTS.md).
This is an early alpha (1.0-alpha) intended for development and testing. The project is sim-first: the simulation path is the mature, well-tested one. Real-hardware support is provided and mirrors the simulated devices, but is far less exercised β treat it as experimental. Expect rough edges and breaking changes as 1.0 takes shape.
MIT β see LICENSE.
A clean-room rewrite; no original Vanchor source was copied. The 3-DOF
hydrodynamics follow the marine-craft equations of Prof. Thor I. Fossen
(Handbook of Marine Craft Hydrodynamics and Motion Control, Wiley); our
sim/fossen.py is an independent, dependency-free Python realization of that
framework.











