sl-jetson a4a2953326 feat: Here4 DroneCAN GPS driver + NTRIP client (RTK ready) — Issue #725
New packages:
- saltybot_dronecan_gps: DroneCAN driver for CubePilot Here4 RTK GPS
  - Subscribes uavcan.equipment.gnss.Fix2 (ID 1063) on can0 at 1Mbps
  - Publishes /gps/fix (NavSatFix), /gps/vel (TwistStamped), /gps/rtk_status
  - Maps DroneCAN fix_type 0-6 → sensor_msgs NavSatStatus + RTK label
  - Optional compass via uavcan.equipment.ahrs.MagneticFieldStrength
- saltybot_ntrip_client: NTRIP RTCM3 → DroneCAN RTCMStream forwarding
  - Connects to rtk2go.com:2101 (configurable), auto-reconnects
  - Forwards corrections to Here4 via uavcan.equipment.gnss.RTCMStream
  - Publishes /ntrip/status (CONNECTED / DISCONNECTED / ERROR:<reason>)

New launch file:
- here4_gps.launch.py: launches both nodes with unified CAN + NTRIP params

Updated:
- can_setup.sh: adds 1Mbps DroneCAN mode (sudo ./can_setup.sh up dronecan)
  keeping 500kbps VESC default; CAN_BITRATE env var still overrides both
- docker-compose.yml: adds here4-gps service with /dev/can0 device passthrough
  and NET_ADMIN cap; resolves leftover merge conflict markers
- outdoor_nav_params.yaml: adds Here4 config section, updates RTK docs

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-10 20:42:36 -04:00

71 lines
2.0 KiB
Bash
Executable File

#!/usr/bin/env bash
# can_setup.sh — Bring up CANable 2.0 (gs_usb) as can0
# Issue: https://gitea.vayrette.com/seb/saltylab-firmware/issues/643
#
# Usage:
# sudo ./can_setup.sh # bring up (default: 500kbps for VESC)
# sudo ./can_setup.sh up dronecan # bring up at 1Mbps for Here4 DroneCAN
# sudo ./can_setup.sh down
# sudo ./can_setup.sh verify # candump one-shot check (Ctrl-C to stop)
#
# Bitrate modes:
# default / vesc — 500 kbps (VESC IDs 0x3D/0x4F)
# dronecan / here4 — 1000 kbps (CubePilot Here4 RTK GPS, DroneCAN default)
#
# CAN_BITRATE env var overrides both modes.
set -euo pipefail
IFACE="${CAN_IFACE:-can0}"
log() { echo "[can_setup] $*"; }
die() { echo "[can_setup] ERROR: $*" >&2; exit 1; }
cmd="${1:-up}"
mode="${2:-vesc}"
# Resolve bitrate: env var wins, then mode keyword, then 500k default
if [[ -n "${CAN_BITRATE:-}" ]]; then
BITRATE="$CAN_BITRATE"
elif [[ "$mode" == "dronecan" || "$mode" == "here4" ]]; then
BITRATE=1000000
else
BITRATE=500000
fi
case "$cmd" in
up)
# Verify the interface exists (gs_usb module loaded by kernel on plug-in)
if ! ip link show "$IFACE" &>/dev/null; then
die "$IFACE not found — is CANable 2.0 plugged in and gs_usb loaded?"
fi
log "Bringing up $IFACE at ${BITRATE} bps (mode: ${mode})..."
ip link set "$IFACE" down 2>/dev/null || true
ip link set "$IFACE" up type can bitrate "$BITRATE"
ip link set "$IFACE" up
log "$IFACE is up."
ip -details link show "$IFACE"
;;
down)
log "Bringing down $IFACE..."
ip link set "$IFACE" down
log "$IFACE is down."
;;
verify)
if [[ "$mode" == "dronecan" || "$mode" == "here4" ]]; then
log "Listening on $IFACE — expecting DroneCAN frames from Here4 GPS (1Mbps)"
else
log "Listening on $IFACE — expecting frames from VESC IDs 0x3D (61) and 0x4F (79)"
fi
log "Press Ctrl-C to stop."
exec candump "$IFACE"
;;
*)
echo "Usage: $0 [up [vesc|dronecan]|down|verify [dronecan]]"
exit 1
;;
esac