diff --git a/hardware/lattepanda-3-delta/NOTES.md b/hardware/lattepanda-3-delta/NOTES.md new file mode 100644 index 0000000..d576d4e --- /dev/null +++ b/hardware/lattepanda-3-delta/NOTES.md @@ -0,0 +1,41 @@ +# LattePanda 3 Delta setup kit + +For the Delta fleet: a LattePanda 3 Delta host, an onboard ATmega32U4 +("Arduino Leonardo") driving two TMC5160 boards, yaw and pitch. Run through +`scripts/install-tower`, or `./install.sh --help` on its own. + +## What is known, from tower 111 (surveyed 2026-09-23, read-only) + +| | | +|---|---| +| OS | Ubuntu 22.04.5 LTS, kernel 6.8 | +| Motor MCU | `/dev/serial/by-id/usb-Arduino_LLC_Arduino_Leonardo-if00`, USB `2341:8036` | +| Camera | Alvium, USB `1ab2:0001`, port `2-2` | +| Modem | Quectel RM520N-GL, four `ttyUSB` nodes | +| Serial / I2C | `/dev/ttyS0..3`, `/dev/i2c-0..15`; the ambient sensor is on `/dev/i2c-2` | +| Packages | every entry in `packages.txt` already installed | +| Preconditions | NOT applied: `usbfs_memory_mb` 16, camera `usb3_lpm_permit` `u1_u2` | +| `hardware.ini` | none - the tower has never been migrated | + +## What this kit has NOT done yet `[untested]` + +Nothing here has been applied to a Delta. In particular: + +- **`pins.ini` is not a traced loom.** It carries the numbers the firmware ran + on before pins moved into `hardware.ini`. Trace one Delta's wiring and replace + it with a table the way the IOTA's was done. +- **The drivetrain is not known in the units `hardware.ini` uses.** The Delta's + firmware carried register values (GLOBALSCALER 80 / 50, IRUN 31, SW_MODE + 0x8A0 / 0x8A3, ENC_DEVIATION 1500). Turning them into milliamps needs each + driver board's sense resistor, which has to be read off the board. Until it + is, the current keys stay `; TODO` - and so the installer will not flash the + new firmware, which would refuse to move without them. +- **Flashing** keeps the Leonardo's own 1200-baud touch, which is how the Delta + fleet has always been flashed; `tools/flash.sh` does nothing extra for it. + +## Migrating an existing Delta tower + +Host first, firmware second (`docs/hardware-config-plan.md` section 13). The +installer's order already is: it writes `hardware.ini`, builds the host and runs +`test hardware` against the OLD firmware before any flash - and blocks the flash +while a drivetrain value is still a `; TODO`. diff --git a/hardware/lattepanda-3-delta/install.sh b/hardware/lattepanda-3-delta/install.sh new file mode 100755 index 0000000..5d43f80 --- /dev/null +++ b/hardware/lattepanda-3-delta/install.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash +# +# install.sh - set up a LattePanda 3 Delta as a fire-watch tower host (the Delta +# fleet: ATmega32U4 "Leonardo" motor MCU, two axes). Run it ON the device; +# --help lists every option. scripts/install-tower drives this for a whole +# install; this stays usable alone. +# +# Everything shared with the other boards' kits is in ../common/kit.sh; what is +# here is what differs on the Delta. See NOTES.md for what has and has not been +# run on a real Delta. +# +set -euo pipefail + +KIT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +KIT_BOARD=lattepanda-3-delta +KIT_FW_ENV=leonardo +KIT_MCU_VID=2341 +KIT_DEFAULT_AXES=yaw,pitch +KIT_IMU_DEVICE=/dev/ttyS0 +KIT_IMU_NOTE="On the Delta the MTi is on the RS-232 header: a hardware UART, not a USB node." +KIT_ENV_DEVICE=/dev/i2c-2 +KIT_ENV_NOTE="The board's own I2C bus - /dev/i2c-2 on the Delta, not the /dev/i2c-1 default. +It MUST be a real I2C adapter (i2cdetect -F N: 'I2C = yes'), and i2cdetect +false-negatives on the SHT4x, so probe with a real measurement." + +# shellcheck source=../common/kit.sh +. "$KIT_DIR/../common/kit.sh" +# scripts/install-tower sources this file for the facts and probes alone. +[[ ${KIT_NO_MAIN:-0} == 1 ]] || kit_main "$@" diff --git a/hardware/lattepanda-3-delta/packages.txt b/hardware/lattepanda-3-delta/packages.txt new file mode 100644 index 0000000..2fa9c2f --- /dev/null +++ b/hardware/lattepanda-3-delta/packages.txt @@ -0,0 +1,31 @@ +# apt packages for a LattePanda 3 Delta tower host. All present on tower 111 +# (Ubuntu 22.04), 2026-09-23. One per line, '#' comments. +# Consumed by install.sh --deps. + +# --- build toolchain ----------------------------------------------------- +build-essential +cmake +git +pkg-config + +# --- fire_gimbal_control build deps -------------------------------------- +# Paho MQTT is fetched by cmake; OpenCV, Boost and libjxl are not. +libopencv-dev +libboost-program-options-dev +libjxl-dev +libssl-dev + +# --- runtime ------------------------------------------------------------- +# tmux: scripts/fgc runs the app detached inside a session. +tmux +rsync + +# --- firmware build (PlatformIO runs ON the tower, see NOTES.md) --------- +python3-venv +python3-pip + +# --- diagnostics --------------------------------------------------------- +# i2c-tools: `i2cdetect -F` proves a bus is real I2C and not SMBus-only. +# usbutils: lsusb, for camera and MCU enumeration. +i2c-tools +usbutils diff --git a/hardware/lattepanda-3-delta/preconditions/10-fwt-usbfs.conf b/hardware/lattepanda-3-delta/preconditions/10-fwt-usbfs.conf new file mode 120000 index 0000000..9df0f05 --- /dev/null +++ b/hardware/lattepanda-3-delta/preconditions/10-fwt-usbfs.conf @@ -0,0 +1 @@ +../../lattepanda-iota/preconditions/10-fwt-usbfs.conf \ No newline at end of file diff --git a/hardware/lattepanda-3-delta/preconditions/99-fwt-alvium-usb.rules b/hardware/lattepanda-3-delta/preconditions/99-fwt-alvium-usb.rules new file mode 120000 index 0000000..d9cc82d --- /dev/null +++ b/hardware/lattepanda-3-delta/preconditions/99-fwt-alvium-usb.rules @@ -0,0 +1 @@ +../../lattepanda-iota/preconditions/99-fwt-alvium-usb.rules \ No newline at end of file diff --git a/scripts/install-tower b/scripts/install-tower index f3ff2f6..211d75c 100755 --- a/scripts/install-tower +++ b/scripts/install-tower @@ -182,12 +182,13 @@ py_serial() { app_running() { "$FGC" status >/dev/null 2>&1; } -# The arguments the running app was started with, from its log header, so a -# restart puts it back the way it was. +# The arguments the running app was started with, so a restart puts it back the +# way it was. From the process itself, not its log: an older build writes no log +# file, and restarting tower 111 without its --init --start would have left it +# running but capturing nothing. app_args() { - local l; l="$(latest_log)" || return 0 - [[ -n $l ]] || return 0 - sed -n 's/^argv *//p' "$l" | head -1 | awk '{ for (i = 2; i <= NF; i++) printf "%s%s", $i, (i < NF ? " " : "") }' + ps -u "$USER" -o args= 2>/dev/null | grep -m1 -E '^[^ ]*/fire_gimbal_control( |$)' | + awk '{ for (i = 2; i <= NF; i++) printf "%s%s", $i, (i < NF ? " " : "") }' || true } # What the firmware on the board reports: "build=... spi=... Y:cs,en P:cs,en". @@ -588,9 +589,16 @@ else plan platformio change "install PlatformIO Core into ~/.platformio"; fi PROFDIR="$REPO/config/camera_profiles/rgb" cams="$(ini_get "$HW_VIEW" Hardware cameras 2>/dev/null || echo none)" if [[ $cams == none || -z $cams ]]; then plan profiles skip "no camera declared" -elif [[ -r $PROFDIR/standard.xml && -r $PROFDIR/night.xml ]]; then plan profiles skip "standard + night present" -elif [[ $HAVE_VIMBA -eq 0 ]]; then plan profiles skip "no Vimba SDK: export later" -else plan profiles change "export night, then standard, from the camera"; fi +else + # Only what is MISSING. An existing profile was tuned on this camera - tower + # 111 has a hand-exported standard.xml and no night.xml - and exporting over + # it would replace that tuning with the recipe's defaults. + PROF_MISSING=() + for prof in night standard; do [[ -r $PROFDIR/$prof.xml ]] || PROF_MISSING+=("$prof"); done + if (( ${#PROF_MISSING[@]} == 0 )); then plan profiles skip "standard + night present" + elif [[ $HAVE_VIMBA -eq 0 ]]; then plan profiles skip "no Vimba SDK: export ${PROF_MISSING[*]} later" + else plan profiles change "export ${PROF_MISSING[*]} from the camera (existing profiles untouched)"; fi +fi # Firmware: flash only what differs, and never onto an axis that would sit in # NEEDCFG because hardware.ini cannot answer it. @@ -752,7 +760,7 @@ if [[ ${DO[profiles]} == change ]]; then python3 -m venv "$HOME/.venvs/vmbpy" "$HOME/.venvs/vmbpy/bin/pip" install -q /opt/VimbaX/api/python/vmbpy-*.whl } - for prof in night standard; do + for prof in "${PROF_MISSING[@]}"; do ( cd "$REPO" && GENICAM_GENTL64_PATH=/opt/VimbaX/cti "$HOME/.venvs/vmbpy/bin/python" \ scripts/export_camera_profile.py --profile "$prof" ) done