Systems · Reference

How it all connects

Ligmax is five computers, two microcontrollers and one flight controller talking over six different transports. These are the working diagrams the team builds against: what talks to what, which port it uses, where the power goes, and which GPIO pin does what on each ESP32.

Communications

Every link, and the port it runs on

The Raspberry Pi 5 is the hub. Perception runs beside it on the Jetson, hard real-time control runs below it on the Pixhawk, and everything reaching shore goes out through the 5G router — except the RC link, which is deliberately independent of all of it.

SHORE VESSEL Operator browser live.ligmax.no ligmax-server dashboard + telemetry ingest, behind TLS Edge viewer receiver.py — draws boxes, serves MJPEG HTTPS 443 5G router · vessel LAN UDP hole-punched direct link FRSky RC receiver manual + kill/hold fallback UDP 8771 telemetry TCP 3338 frames RC Jetson Orin Nano TensorRT detector + classifier Raspberry Pi 5 planner · world model · uplink Pixhawk 6C PID · thrust mixing · failsafes MAVLink 115200 2× OV5647 fisheye 220° lenses, ±15° aim Lidar ×2 · sonar RPLIDAR front (gimballed) + rear Daly 150 A BMS 12 cells, SoC, temps, alarms Translator + Slider ESP32 roll actuators · battery rail VESC 6.7 ×2 · stern ESC Flipsky 5085 ×2 + F2838 CSI USB CAN 250k PWM CAN IP link with a port Independent radio Serial / USB / CSI CAN bus Servo PWM
Everything that leaves the vessel is coloured and carries a port number — those are the links a firewall sees. The FRSky RC path is drawn separately because it shares no hardware with the 5G link: if the network drops, it still flies.

Listening ports

PortTransportServiceHostReachable from
443 TCP / HTTPS Operator dashboard, via reverse proxy Ground station Internet — live.ligmax.no
3338 TCP / HTTP Dashboard app behind the proxy Ground station localhost only
3338 TCP Jetson frame ingest Viewer host Vessel LAN
8771 UDP Telemetry ingest from the vessel Ground station Vessel LAN / 5G
8080 HTTP MJPEG camera view Viewer host Vessel LAN
5555–5560 TCP (ZeroMQ) Companion-computer node bus Raspberry Pi 5 localhost only
2101 TCP (NTRIP) RTK corrections — planned Ground station Internet — rtk.ligmax.no

The dashboard is served over HTTPS on 443 by a reverse proxy in front of the app, which itself listens only on localhost. Note that 3338 is also the default for the Jetson frame feed, so those two must not share a host without moving one of them.

On-board buses

BusIdentifierBetweenCarries
CAN can1 @ 250 kbit/s Pi 5 ↔ Daly 150 A BMS Pack voltage, current, SoC, per-cell mV, temperatures, alarms
CAN vehicle bus Pixhawk ↔ VESC 6.7 ×2 Field-oriented motor commands
MAVLink /dev/ttyACM0 @ 115200 Pi 5 ↔ Pixhawk 6C Setpoints, RC override ch 6, telemetry, heartbeat
PWM 1000–2000 µs Pixhawk → both ESP32s, stern ESC Actuator and thruster demand
CSI /dev/video0-1 Cameras → Jetson 2592×1944@14, 1920×1080@29 or 1296×972@28
Power

From 144 cells to five kilowatts

One pack feeds everything, split immediately into a high-voltage path for propulsion and a low-voltage path for compute. Two things must both be closed before any propulsion power flows, and one circuit deliberately bypasses the whole system.

Battery pack 12S12P · 144× INR18650-35E ≈44.4 V nominal · ≈1.8 kWh Firebox · structure · trim mass Daly 150 A BMS OV · UV · OC · OT · short Pi 5 → dashboard SoC, cell mV, temps, alarms CAN can1 250k E-stop safety loop physical button + compute-driven relay in series — both must close Main contactor cuts propulsion HV DC-DC buck converter Propulsion ≈5 kW VESC 6.7 ×2 → Flipsky 5085 140 KV · 2500 W each 30 A ESC → F2838 stern LV DC-DC buck converter Compute & sensors Pi 5 · Jetson · Pixhawk 6C 2× ESP32 · DM542C · 160 W driver lidars · sonar · GNSS · 5G router 9 V backup circuit independent of the main pack Locking lid clinch motors + Hall sensor opens it, system down High-voltage / propulsion Low-voltage / compute Telemetry
The safety loop is the part worth reading twice: the E-stop button and a relay driven by the main computer sit in series, so either one opening cuts propulsion. The 9 V lid circuit is independent of everything else by design — it has to work when nothing else does.

Converter part numbers, rail voltages and fuse ratings are not recorded in the software repos. Treat the two DC-DC blocks as placeholders until the hardware values are measured and written down.

GPIO

Two ESP32s, one pinout, different meanings

The active stabilisation runs on two separate ESP32 boards. Both take servo PWM from the Pixhawk and both use the same eight GPIO pins — but those pins drive completely different hardware on each board. Getting the two mixed up is the easiest way to damage something.

ROLL TRIM — the amas PITCH TRIM — the battery rail Pixhawk 6C servo out 1 & 2 Translator ESP32 deadband 25 µs failsafe 200 ms 160 W H-bridge IN1/IN2/ENA · IN3/IN4/ENB Ama linear actuators left + right — righting moment PWM → GPIO 34, 35 GPIO 25,26,27 · 12,14,13 Pixhawk 6C servo out Raspberry Pi 5 homing trigger 3.3 V Slider ESP32 deadband 30 µs failsafe 300 ms DM542C driver PUL+ · DIR+ · ENA+ Nema 23 → battery rail 3200 back · 5000 front (steps) PWM → GPIO 34 GPIO 35 GPIO 25, 26, 27 Endstops → GPIO 12 rear · 14 front · 13 optical centre
Both boards read the same pins; only the wiring differs. GPIO 25 is a stepper step pulse on the slider and an H-bridge input on the translator, and GPIO 12/14/13 are endstop inputs on one board and motor outputs on the other.

Translator ESP32 — roll trim

GPIODirSignalWired to
34 in RC_CH1_PIN Pixhawk out 1 — left actuator demand
35 in RC_CH2_PIN Pixhawk out 2 — right actuator demand
25 out MOTOR_A_IN1 160 W driver IN1
26 out MOTOR_A_IN2 160 W driver IN2
27 out MOTOR_A_ENA 160 W driver ENA (PWM 0–255)
12 out MOTOR_B_IN3 160 W driver IN3
14 out MOTOR_B_IN4 160 W driver IN4
13 out MOTOR_B_ENB 160 W driver ENB (PWM 0–255)

Slider ESP32 — pitch trim

GPIODirSignalWired to
34 in PIXHAWK_PWM_PIN Pixhawk PWM out — rail position demand
35 in RPI_HOMING_PIN Raspberry Pi, 3.3 V homing trigger
25 out PUL_PIN DM542C PUL+ (step)
26 out DIR_PIN DM542C DIR+
27 out ENA_PIN DM542C ENA+
12 in LIMIT_REAR_PIN Rear endstop → GND (pull-up)
14 in LIMIT_FRONT_PIN Front endstop → GND (pull-up)
13 in LIMIT_MID_OPTO_PIN Optical centre endstop → GND (pull-up)

The roll mixer itself runs on the flight controller as a Lua script: a roll PD loop (gains in SCR_USER1/SCR_USER2) summed with a ride-height offset the Pi commands on RC channel 16, output on servo functions 94 and 95 at 20 Hz and clamped to 1000–2000 µs.

Full engineering detail — hull geometry, control loops, test results and the complete component list — is in the technical report.