An autonomous sailboat system based on Dragonforce 65 hull, running on Orange Pi Zero 2W with ROS2. The system includes comprehensive sensor integration, autonomous navigation, and safety monitoring.
argo.freecad.3d.webm
- May 2026: After ignominious series of problems at CCNW with cabling, water leaks, GPS and many other issues and only 30m of actual seawater sailing, came back to INI to fix these problems. Now IMU is working, GPS is working, dashboard has map display, there are new cable glands and a new hull that has been air-pressure tested for leaks. We are ready now for water trials again.
- Mar 2026: Version 4 of argo PCB with bug fixes, wind sensor on separate I2C bus, and new buzzer. Version 3 of the wind sensor PCB with RGBW LED controller. See Argo2: Robot Sailboat slides presented online at Embodied Intelligence Conference 20 March 2026.
- Feb 2026: Updated wind sensor design PCB and housing complete. 3D parts for wind sensor I2C cable and mast step up completed and printed.
- Jan 2026: Argo main PCB version 3 completed and seems fully functional with no surgery needed.
- Aug-Dec 2025: Intense development of new Argo PCB and ROS2 software framework. System services developed (see
power_control/argo_power_control.pyandlaunch/argo_lifecycle_manager.py) along with robust lifecycle management and battery/power control. - Oct-Nov 2025: Developed first version of Argo simulator.
- See simulator/sailboat-playground/README.md for usage and architecture.
- Additional docs: Simulation Guide, Debug Simulation Guide
Pick Argo (boat) or Host (PC) below. ROS 2 must match your Ubuntu LTS: 22.04 (Jammy) → Humble; 24.04 (Noble) → Jazzy. Use the official ROS 2 Ubuntu (deb) install page that corresponds to your ROS release.
On the robot, the stack targets Ubuntu 22.04–based Armbian and ROS 2 Humble. Bring up I²C/UART/PWM overlays, the radio/servo kernel module, Python dependencies, systemd services, and power control as described in the launch tree.
cd ~/argo # or your clone path
sudo apt update && sudo apt upgrade -y
# Install ROS 2 Humble (.deb), then in each shell you use for builds:
# source /opt/ros/humble/setup.bash
make install-all # Python deps + optional hardware (see Makefile / messages)
make install-argo-cli
source ~/.bashrc
make -C launch install # install systemd units; enable per docs1. Flash Orange Pi OS using Orange Pi Imager or equivalent.
2. Initial system setup
sudo apt update && sudo apt upgrade -y
sudo apt install python3-pip python3-dev build-essential
sudo apt install i2c-tools device-tree-compiler git
sudo apt install ros-humble-desktop3. Clone repository
cd /home/orangepi
git clone https://github.com/SensorsINI/argo.git
cd argo4. Python and ROS helpers
make install-python-deps # requirements.txt on the boat
# If needed:
sudo apt install python3-rclpy python3-std-msgs python3-geometry-msgs5. Hardware configuration
Edit /boot/orangepiEnv.txt and add overlays:
overlays=pi-i2c0 disable-uart0 ph-uart5 pi-pwm2 pi-pwm4
user_overlays=argo_radio_servo_overlay
Build and load the PWM capture module:
cd ~/argo/nodes/pwm_capture_module
make all
sudo modprobe argo_radio_servo_module # or rebootAdd your user to hardware groups:
sudo usermod -a -G i2c,dialout $USER
# log out and back in6. Verify
sudo i2cdetect -y 0
lsmod | grep argo
ls -la /sys/kernel/argo_radio_servo/
sudo cat /dev/ttyS57. CLI and services
make install-argo-cli && source ~/.bashrc
make -C launch install
sudo systemctl daemon-reload
sudo systemctl enable argo_launch.serviceUse this on a laptop or workstation for local simulation (asim), Foxglove Studio (same Wi‑Fi, VPN, or SSH tunnel), log playback, and shore-side scripts. The boat still runs ROS 2 on the Orange Pi; your host subscribes/records like any ROS 2 client. LoRa is a boat link—the monitoring machine uses normal network ROS 2 or recorded bags unless you run a separate LoRa gateway stack.
Prerequisites: Ubuntu 22.04 or 24.04 (see mapping to Humble/Jazzy above), git, make, sudo, and network access for apt.
One-shot bootstrap (Ubuntu 22.04 or 24.04):
cd /path/to/argo
make host-setup
source ~/.bashrc # reload Argo dotfiles in this terminal (or open a new tab)
# Dotfiles auto-source the first ROS found under /opt/ros (jazzy, iron, humble, rolling) when ROS_DISTRO is unset.
source .venv/bin/activate # optional; pip tooling (argcomplete, pyglet, …)
asimIf a command in this terminal cannot find rclpy or ros2 right after host-setup, the ROS underlay is not loaded yet: run source ~/.bashrc (as above), or explicitly source /opt/ros/humble/setup.bash / source /opt/ros/jazzy/setup.bash matching your install.
make host-setup refuses to run on Orange Pi (use make install-all on the boat). It:
- Adds
/etc/apt/sources.list.d/ros2-latest.listonly if no file already references packages.ros.org/ros2/ubuntu (avoids a secondSigned-Byif you installed ROS 2 from the official doc first) - Installs
ros-<distro>-ros-basewhen/opt/ros/<distro>is absent (Jammy →humble, Noble →jazzy, or override withROS_DISTRO=) - Runs
make install-deps(singleapt-get update, then Argo’s ROS .deb set, Foxglove bridge, MCAP storage) - Runs
make setup-venv(creates.venvwith uv if available, otherwisepython3 -m venv, and installsrequirements-host.txt) thenmake install-python-deps(same host requirements file again into.venv—idempotent on a PC) - Runs
make install-argo-cliandmake submodule-init(install-argo-cliappendssource <repo>/dotfiles/bashrcto~/.bashrc; that file auto-sources/opt/ros/<distro>/setup.bashwhenROS_DISTROis not already set)
Tab completion (optional): Global argcomplete is not installed automatically on every shell (keeps login fast). After host-setup, run once: activate-global-python-argcomplete3 --user or activate-global-python-argcomplete --user, or see dotfiles/README.md — Tab Completion Setup.
Force a distro explicitly, e.g. on non-LTS or mixed images:
make host-setup ROS_DISTRO=jazzyIf apt-get update reports conflicting Signed-By for packages.ros.org/ros2/ubuntu, you have two ROS 2 source files—keep one. For example, if you already used the official installer, remove Argo’s duplicate and refresh: sudo rm -f /etc/apt/sources.list.d/ros2-latest.list && sudo apt-get update.
install-ros2-apt-repo checks for an existing ROS 2 source with sudo grep because some sources.list.d entries are root-only; without that, Make could miss your working repo and add a second file.
Foxglove: with ROS sourced on the machine that runs the bridge, start ros2 run foxglove_bridge foxglove_bridge and connect from Foxglove Studio to ws://<that-host-ip>:8765.
make host-setup— host-only full bootstrap (see above)make install-deps— ROS packages for the currentROS_DISTRO(Foxglove, MCAP, …)make install-python-deps— robot usesrequirements.txt; host usesrequirements-host.txt(prefers.venvif present)make install-hardware— PWM module (boat)make install-all— boat-oriented dependency + hardware pathmake -C launch …— lifecycle systemd helpers
After make install-argo-cli, common aliases include al / aq / ars (services), as / asq (status), asim (local sim), ar / ac (recording), alog, ah. Run make help and see dotfiles/.
The Argo system consists of multiple ROS2 nodes that work together to provide autonomous sailing capabilities:
- Sensor Nodes: GPS (u-blox NEO-M9N), IMU (Adafruit BNO085), Wind sensors (3x Sensirion SDP3x), Battery/Water monitoring
- Control Interface: PWM capture for radio control and servo output
- Autonomous Control: Navigation and sail trimming algorithms
- Safety Systems: Manual override, battery monitoring, water intrusion detection
See the Argo autonomous sailboat in action at the 2024 CCNW (before current waterproofing and PCB developements): Argo Sailboat Demo
The main PCB design for Argo is available in the pcb/ folder. The latest board version is rev4, which contains the current sailboat control and sensor interface design.
- Orange Pi Zero 2W (Allwinner H618 SoC)
- GPS: u-blox NEO-M9N via UART5 (/dev/ttyS5)
- IMU: Adafruit BNO085 9-DOF Orientation IMU via I2C0 (0x4a)
- Wind Sensor: 3x Sensirion SDP3x differential pressure sensors via I2C0 (0x21, 0x22, 0x23). This PCB includes an RGBW LED and its I2C controller PCA9632 at individual address 0x62 (0x70 is LED All Call).
- Design files: See
pcb/WindSensor/WindSensor-rev1/directory for full hardware schematics, layout, and BOM.
- Design files: See
- ADC: MAX11612 for battery/water sensing via I2C0 (0x34)
- Environment: SHT45 temperature/humidity via I2C0 (0x44)
- PWM I/O: Custom kernel module for radio control and servo interfaces with high impedance safety mode
- LORA: Long range radio based on RA-01 radio module from ai-thinker.com using SX1276 LORA chip
The Argo system is designed to handle frequent SBC hardware replacements (due to damage) while maintaining network identity. The WiFi MAC address is frozen to a consistent value (c8:26:e2:6c:58:ba) stored in network/ARGO_MAC_ID.txt and committed to git. This ensures:
- Network Stability: Same MAC address across hardware changes maintains network access (uzh-iot, ZeroTier, tobi-wlan)
- SD Card Portability: Same SD card works seamlessly with different SBC hardware
- Automatic Configuration: Run
make freeze-mac-addressafter hardware replacement to restore network identity
See Network Improvements Documentation for details.
The Argo system uses a shared control circuit design that allows both radio control and autonomous software control of servos through a fail-safe high impedance switching mechanism:
-
Sail Winch Servo: Joysway #880545
- Type: Standard sail winch servo with high-precision plastic gears
- Operating voltage: 4.8V to 6.0V
- PWM frequency: 1520μs/50Hz
- Input impedance: 12kΩ (measured)
- Circuit resistor: 3.3kΩ (optimized for proper signal level)
-
Rudder Servo: Joysway #881504
- Type: Digital metal gear servo
- Operating voltage: 4.8V to 6.0V
- PWM frequency: 1520μs/330Hz
- Input impedance: 400kΩ (measured)
- Circuit resistor: 10kΩ (standard value works well)
The hardware implements a fail-safe shared control circuit where:
- High Impedance Safety Mode: When PWM outputs are disabled (high impedance), radio control signals pass through resistors directly to servo inputs
- Software Control Mode: When PWM outputs are enabled, software generates servo control signals
- Voltage Divider Considerations: Resistor values are optimized based on servo input impedance:
- Sail servo: 3.3V × (12kΩ / (3.3kΩ + 12kΩ)) = 2.6V (adequate signal level)
- Rudder servo: 3.3V × (400kΩ / (10kΩ + 400kΩ)) = 3.2V (excellent signal level)
- PI11 (Pin 7): Radio Rudder Input - GPIO input with interrupt capability
- PI13 (Pin 26): Radio Sail Input - GPIO input with interrupt capability
- PI12 (Pin 33): Servo Rudder Output - PWM2 channel, high impedance when disabled
- PI14 (Pin 16): Servo Sail Output - PWM4 channel, high impedance when disabled
This design ensures radio control always works when software is not running, providing maximum safety for autonomous sailboat operation.
flowchart TB
subgraph OUTPUTS[Output Nodes]
RSR[rudder_sail_radio primary actuation output]
LORA[lora long range communications]
end
CTRL[controller primary decision and control logic]
subgraph SAFETY[Critical Safety Services]
BW[battery_water critical]
LA[launch critical]
end
subgraph SENSORS[Sensor Input Layer]
GPS[gps]
IMU[imu BNO085]
ANEM[anem]
end
VR[Visualization and Recording]
GPS --> CTRL
IMU --> CTRL
ANEM --> CTRL
CTRL --> RSR
BW --> LA
LA --> CTRL
CTRL --> VR
CTRL -.-> LORA
The Argo system follows a modular ROS2 architecture with clear separation of concerns:
Directory Structure:
nodes/- Individual ROS2 nodes (Python-based sensor interfaces)launch/- Lifecycle management, systemd services, and launch configurationspower_control/- Power management system (separate ROS2 package)foxglove/- Visualization layouts for Foxglove Studiosimulator/- Sailboat simulation submodule (sailboat-playground)
- Systemd Services Architecture - Service dependencies, boot sequence, and troubleshooting
- Network Improvements - WiFi reconnection, MAC address cloning, and NetworkManager configuration
- ZeroTier VPN Setup - ZeroTier VPN configuration, SSH access, and network management
- Power Control System - Power button, LED control, and graceful shutdown
- Systemd Integration - Launch system and lifecycle management
- Shutdown Fixes - Shutdown procedure fixes and improvements
- LED Status Guide - LED status display and hatch cover indicators
- Simulation System Overview - Sailboat simulation framework
- Simulation Documentation - Simulation setup and usage
- Debug Simulation - Debugging simulation issues
- I2C Configuration - I2C bus setup and troubleshooting
- LoRa (onboard ↔ shore) - SX1276 / Waveshare hardware, link parameters, packet header
- IMU BNO085 - C++ driver, Python bridge, calibration,
argo_bno085service - Thermal monitoring (SBC) - Orange Pi GPU/CPU/DDR temperature logging (
argo_thermal_monitor) - Watchdog Configuration - Watchdog setup for Orange Pi Zero 2W
- CPU Frequency Tuning - CPU governor configuration
- Battery & Power Monitoring - Battery monitoring system
- Battery Panel Setup - Battery panel configuration
- SD Card Backup - SD card backup procedures
- DVFS Userspace Access - Dynamic voltage and frequency scaling
- Foxglove Visualization - Real-time visualization setup
- Foxglove Debugging - Debugging Foxglove issues
- Foxglove Joystick Setup - Joystick control configuration
- 3D Visualization - 3D visualization configuration
- Visualization Marker Persistence - Marker persistence in visualization
- Adding Sailing Maps - Map integration guide
- Maps Documentation - Sailing area maps
- Remote Desktop VNC - VNC remote desktop setup
- Web Dashboard - Mobile-friendly web interface
- CLI Completion - Command-line completion setup
- Completion Quickstart - Quick start guide for CLI completion
- MOTD Customization - Message of the day customization
- ROS2 Nodes - Node documentation and configuration
- Scripts - Utility scripts documentation
- Dotfiles Setup - CLI aliases and shell configuration
- Persistent Logging - Logging configuration
Argo includes comprehensive simulation support for development and testing:
Local Simulation:
- Runs simulator directly on Orange Pi
- Uses sailboat-playground or mock simulator
- Excludes conflicting hardware nodes (GPS, IMU, anemometer, radio control)
- Perfect for algorithm development and testing
Remote Simulation:
- Offloads CPU-intensive simulation to remote machine
- SSH tunnel for ROS2 communication
- Centralized configuration management
- Ideal for resource-constrained environments
Quick Start:
# Local simulation
python3 launch/argo_lifecycle_manager.py simulate_local
# Remote simulation (requires setup)
python3 launch/argo_lifecycle_manager.py simulate_remote
# Or use helper scripts (equivalent flow):
./scripts/remote_simulator_tunnel.sh &
python3 scripts/remote_simulator_launch.py &
./scripts/launch_simulator_remote.shCentral control hub for the entire Argo system:
argo_lifecycle_manager.py- Core lifecycle management with intelligent monitoringargo_*.sh- Shell scripts for start/stop/restart/status operationsargo-launch.service- Systemd service configurationargo_gui.py- GTK-based status monitoring GUIargo_storage_monitor.py- Storage space monitoring and notificationsMakefile- Service installation and management automation
Hardware interface and control nodes:
- Sensor Nodes:
gps.py,bno085.py,anem.py,argo_battery_water.py,temp_monitor.py - Control Nodes:
rudder_sail_radio.py,controller.py,record.py pwm_capture_module/- Custom kernel module for radio control and servo interfaces- Configuration files:
argo.yaml, calibration data, and support utilities
Standalone ROS2 package for power button and LED control:
argo_power_control.py- Main power control node with GPIO management- Hardware Functions: Power button monitoring, LED patterns (heartbeat/SOS), graceful shutdown
- ROS2 Services: LED control, system health monitoring
Makefile- Independent installation and service management
Custom PCB development for production-ready integration:
argo-v9-stable/- Current stable PCB design (KiCad project files)datasheets/- Component specifications and reference materialsorange-pi/- Orange Pi Zero 2W integration documentation and pin definitions- Bill of Materials: Component sourcing and assembly documentation
Foxglove Studio integration for live system monitoring:
argo_ros2.json- Pre-configured dashboard layout for Argo sailboatcustom-argo-panel/- TypeScript custom panel for specialized boat visualizationsetup_foxglove.sh- Automated Foxglove Bridge configuration and startup
Optional system-level monitoring services for debugging and development:
Makefile- Installation and management of system monitoring servicesservices/- Systemd service files for system monitoringscripts/- Monitoring scripts for boot history, memory, processes, etc.- Not installed by default - Use
make install-system-monitoringto install
Core ROS2 Nodes:
gps.py- GPS receiver interface (UART5, u-blox NEO-M9N)bno085.py- 9-DOF Orientation IMU with sensor fusion (I2C, Adafruit BNO085)anem.py- Wind sensor array (3x SDP3x pressure sensors)argo_battery_water.py- Power monitoring and safety systemsrudder_sail_radio.py- Radio control input and servo output interfacecontroller.py- Autonomous navigation and sail control algorithmsrecord.py- Data recording management (ROS2 bag files)temp_monitor.py- System temperature monitoringargo_unified_simulator_bridge.py- Unified simulator bridge for local and remote simulation
The Argo system uses a sophisticated lifecycle management approach centered around argo_lifecycle_manager.py:
Key Features:
- Real-time Monitoring: Active process detection during startup stabilization (not static sleeps)
- Failure Detection: Immediate FATAL error detection and reporting from systemd journal
- Auto-restart: Configurable restart policies with exponential backoff
- Graceful Shutdown: Proper cleanup and process termination
- Status Reporting: Comprehensive system health monitoring
Lifecycle Management Modes:
python3 launch/argo_lifecycle_manager.py run # Launch all nodes
python3 launch/argo_lifecycle_manager.py stop # Graceful shutdown
python3 launch/argo_lifecycle_manager.py restart # Restart all nodes
python3 launch/argo_lifecycle_manager.py status # Show system status
python3 launch/argo_lifecycle_manager.py monitor # Continuous monitoring
python3 launch/argo_lifecycle_manager.py simulate_local # Local simulation mode
python3 launch/argo_lifecycle_manager.py simulate_remote # Remote simulation modeCritical Node Management:
- Critical Nodes:
rudder_sail_radio.py,controller.py(essential for boat operation) - Success Criteria: All critical nodes + minimum 3 total nodes running
- Failure Handling: Intelligent restart with failure analysis and error reporting
Startup Monitoring Pattern:
- Launch Phase - Start all node processes
- Detection Phase - Wait for nodes to register (30s timeout)
- Stabilization Phase - Active monitoring for failures (15s with 1s intervals)
- Validation Phase - Final status check and success determination
Systemd Integration:
- Service:
argo-launch.serviceruns lifecycle manager in continuous mode - Dependencies: Waits for network and hardware module initialization
- Restart Policy: Automatic restart on failure with 5-second delay
- Environment: ROS2 Humble sourcing and logging configuration
cd ~/argo
source /opt/ros/humble/setup.bash
python3 launch/argo_lifecycle_manager.py run# Test individual sensors with debug output
python3 nodes/gps.py --debug
python3 nodes/bno085.py bridge # IMU bridge mode
python3 nodes/bno085.py status # Check IMU health
python3 nodes/anem.py --debug
python3 nodes/argo_battery_water.py --debug
python3 nodes/rudder_sail_radio.py
python3 nodes/controller.py# Monitor ROS2 topics
ros2 topic list
ros2 topic echo /battery_voltage
ros2 topic echo /anem_speed_angle_temp
ros2 topic echo /rudder_sail_radiogps.py: GPS interface via UART5, publishes/gps_databno085.py: Adafruit BNO085 IMU with sensor fusion, publishes/compass,/pose,/accel,/gyro,/imu_healthanem.py: Wind speed/direction from 3 pressure sensors, publishes/anem_speed_angle_tempargo_battery_water.py: Power and safety monitoring, publishes battery/water alertsrudder_sail_radio.py: Radio control interface and servo outputcontroller.py: Autonomous navigation controllerargo_unified_simulator_bridge.py: Unified simulator bridge for local and remote simulationlora.py: Long range radio node for LORA module
argo.yaml: Main control parameters (mode, gains, etc.)argo.env: ROS2 environment variables for systemd servicesRTIMULib.ini: IMU calibration and sensor fusion settings
- High Impedance Safety Mode: Servo outputs default to high impedance (PWM disabled), allowing radio control to pass through directly to servos via resistor network
- Manual Override: Human can take control via radio at any time, with immediate priority over autonomous control
- Shared Control Circuit: Fail-safe design where radio control always works when software is not running
- Battery Monitoring: Automatic low battery alerts (7.2V threshold)
- Water Intrusion Detection: Immediate alerts on water sensor activation
- Sensor Fault Detection: Automatic reconnection and error handling
- Timeout Protection: Safe defaults if communication is lost
To plot recorded bag file data, see argo-plots-2025.py (or argo-plots-2023.py).
- I2C Permission Errors: Ensure user is in
i2cgroup - UART Permission Errors: Ensure user is in
dialoutgroup - PWM Module Not Loading: Check device tree overlay installation
- Sensor Not Found: Verify I2C connections and addresses
- GPS No Data: Check UART5 overlay and baud rate settings
- Servo Low Signal Levels: Check servo input impedance and adjust resistor values accordingly:
- High-power servos (e.g., winch servos) may have low input impedance (12kΩ) requiring smaller resistors (3.3kΩ)
- Standard digital servos typically have high input impedance (400kΩ) working well with 10kΩ resistors
# Check system health
ah # show aliases
adevcheck # check for argo devices present and communicating
alog # follow argo logs - see help options
sudo i2cdetect -y 0 # check i2c bus
ros2 topic list
ros2 node list # check nodes
systemctl status argo-launch.serviceExciting developments are underway for 2025:
- Custom PCB Design: A dedicated PCB is being designed to integrate all sensors and control systems into a single, robust board
- Enhanced Seaworthiness: Significant improvements to waterproofing, structural integrity, and marine-grade components for extended autonomous operation
- Production Readiness: Moving from prototype to production-ready autonomous sailboat system
For detailed technical documentation, see the Google Doc README
BSD License - See package.xml for details
