2 Commits

Author SHA1 Message Date
062c05cac0 feat: Add Issue #502 - Headscale VPN auto-connect on Orin
Configure Jetson Orin with Tailscale client connecting to Headscale
coordination server at tailscale.vayrette.com:8180. Device registers
as 'saltylab-orin' with persistent auth key for unattended login.

Features:
- systemd auto-start and restart on WiFi drops
- Persistent auth key storage at /opt/saltybot/tailscale-auth.key
- SSH + HTTP access over Tailscale tailnet (encrypted WireGuard)
- IP forwarding enabled for relay/exit node capability
- WiFi resilience with aggressive restart policy
- MQTT reporting of VPN status, IP, and connection type

Components added:
- jetson/scripts/setup-tailscale.sh: Tailscale package installation
- jetson/scripts/headscale-auth-helper.sh: Auth key management utility
- jetson/systemd/tailscale-vpn.service: systemd service unit
- jetson/docs/headscale-vpn-setup.md: Comprehensive setup documentation
- saltybot_cellular/vpn_status_node.py: ROS2 node for MQTT reporting

Updated:
- jetson/systemd/install_systemd.sh: Include tailscale-vpn.service
- jetson/scripts/setup-jetson.sh: Add Tailscale setup steps

Access patterns:
- SSH: ssh user@saltylab-orin.tail12345.ts.net
- HTTP: http://saltylab-orin.tail12345.ts.net:port
- Direct IP: 100.x.x.x (Tailscale allocated address)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-06 10:25:04 -05:00
de9a835cc2 feat: SIM7600X 4G cellular + GPS driver (#58)
Adds saltybot_cellular ROS2 package for the Waveshare SIM7600X 4G HAT
(SIMCom SIM7600A-H) providing GPS telemetry, modem monitoring, and
MQTT relay over cellular for remote operation.

gps_driver_node:
  - Opens /dev/ttyUSB2 (NMEA), optionally sends AT+CGPS=1 on /dev/ttyUSB0
  - Parses GGA (position) + RMC (velocity) from any NMEA talker (GP/GN/GL/GA)
  - Validates NMEA checksum before parsing
  - Publishes /gps/fix (NavSatFix, covariance from HDOP × ±2.5m CEP)
  - Publishes /gps/vel (TwistStamped, ENU vE/vN from course-over-ground)
  - Publishes /diagnostics (fix quality, sat count, HDOP)

cellular_manager_node:
  - Polls AT+CSQ, AT+CREG?, AT+COPS? every 5s over /dev/ttyUSB0
  - Publishes /cellular/status (DiagnosticArray: rssi, network, connected)
  - Publishes /cellular/rssi (Int32, dBm) and /cellular/connected (Bool)
  - Auto-reconnect via nmcli or pppd when data link drops

mqtt_bridge_node:
  - paho-mqtt client (graceful degradation if not installed)
  - ROS2→MQTT QoS 0: /saltybot/imu, /gps/fix, /gps/vel, /uwb/ranges,
      /person/target, /cellular/status
  - MQTT→ROS2 QoS 1: saltybot/cmd→/saltybot/cmd, saltybot/estop→/saltybot/estop
  - Per-topic rate limiting (imu:5Hz, gps:1Hz, person:2Hz) → <<50KB/s budget
  - Optional TLS, configurable broker/port/prefix/auth

Deliverables:
  saltybot_cellular/gps_driver_node.py      — 402 lines
  saltybot_cellular/cellular_manager_node.py — 362 lines
  saltybot_cellular/mqtt_bridge_node.py      — 317 lines
  config/cellular_params.yaml               — full config documented
  launch/cellular.launch.py                 — all nodes, all params as args
  test/test_cellular.py                     — 60 pytest tests, no ROS2

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 00:42:18 -05:00