diff --git a/README.md b/README.md index fd6f49d..94fbc6c 100644 --- a/README.md +++ b/README.md @@ -45,8 +45,7 @@ Tip: Click a section title to expand/collapse. 3. After writing the image, eject the card, insert it into your mower’s Pi or xCore, and turn it on. -4. Your Pi will boot multiple times.
- ***Sometimes, after the first boot, it may fail to reboot*** (the Pi/xCore’s green LED doesn’t flicker anymore and remains off for >10 seconds). If that happens, a power cycle will get it back on track. +4. Your Pi will boot multiple times. Be patient and wait till the green activity LED becomes silent for ≥ 10 seconds.
5. ***Optional: Comitup hotspot (if you skipped step 2 "Raspberry Pi Imager configuration")***
If you didn't enter your Wifi settings when asked for the custom settings during Pi Imager (see step 2), or if you accidentally entered the wrong Wifi settings: @@ -61,7 +60,7 @@ If you didn't enter your Wifi settings when asked for the custom settings during 4. The hotspot will disappear and the mower should connect to your WiFi. -6. Two minutes after the second reboot, try pinging your mower via `ping openmower` (or the hostname you entered during Pi Imager). If the host can't be found, check your router for the mower's IP address. +6. Once the green activity LED becomes silent, try pinging your mower via `ping openmower` (or the hostname you entered during Pi Imager). If the host can't be found, check your router for the mower's IP address. 7. ***Optional:***
1. If you didn't configure a custom password during step 2 (Raspberry Pi Imager configuration), login via SSH and change your password now via `passwd`. @@ -75,10 +74,9 @@ If you didn't enter your Wifi settings when asked for the custom settings during Manage OpenMower stack (GUI + CLI) [Dockge](https://dockge.kuma.pet/) (a container manager GUI) and [ttyd](https://tsl0922.github.io/ttyd/) (a web terminal) -are bundled with the OpenMowerOS image and are unpacked and installed during the final second‑boot step. -This may take about 2 minutes. +are bundled together with the OpenMowerOS image, get unpacked and installed during the final boot step. -Please wait while the Pi/xCore’s green LED is flickering or steadily on. +Please wait till Pi/xCore’s green LED becomes silent for ≥ 10 seconds. The WebTerminal is available as a lightweight alternative to SSH for running the same commands. It can be reached via `http://openmower:7681` (adjust if you changed the hostname). @@ -99,18 +97,12 @@ For each relevant GUI action, a CLI alternative is available via a powerful `ope ![Save .env](.github/img/dockge_04_save.jpg) 3. Start the stack (including the initial pull) - - CLI: If you configured your .env file via `openmower configure env` then the stack is pulled and started automatically.
- If not: - - ```bash - openmower pull - openmower start - ``` + - CLI: If you configured your .env file via `openmower configure env` then the stack is pulled and started automatically. - GUI: ![Start Stack](.github/img/dockge_05_start.jpg) 4. Check status and open the OpenMower web app - - CLI: `openmower status` should list three service names (open_mower_ros, Mosquitto and OpenMowerApp), all with status 'up'. If so, open a browser and visit `http://openmower:8080` (or your configured hostname). + - CLI: `openmower status` should list three services (open_mower_ros, Mosquitto and OpenMowerApp), all with status 'up'. If so, open a browser and visit `http://openmower:8080` (or your configured hostname). - GUI: ![Stack Active](.github/img/dockge_06_active.jpg) diff --git a/TESTED_FEATURES.md b/TESTED_FEATURES.md index 89d2d1a..c6ccd21 100644 --- a/TESTED_FEATURES.md +++ b/TESTED_FEATURES.md @@ -2,30 +2,33 @@ Legend: ✅ Pass · ❌ Fail · 🟡 Todo · 🔁 Retry · 🧪 Manual-only -| Feature | Expected | HW‑V1
Pi4 | HW‑V2
CM4 | HW‑V2
CM5 | -| ---------------------------------------- | ----------------------------------------- | :----------: | :----------: | :----------: | -| Auto-reboot after initial boot | yes, but seem to be a bug | ✅ | ❌🧪 | 🟡 | -| Debian release `lsb_release -a` | Debian GNU/Linux 13 (trixie) | ✅ | ✅ | 🟡 | -| OpenMowerOS release `cat /etc/rpi-issue` | OpenMowerOS v2.x YYYY-MM-DD | ✅ | ✅ | 🟡 | -| Hostname (default) `hostname` | openmower | 🟡 | ✅ | 🟡 | -| Hostname (non- default) `hostname` | | ✅ | ✅ | 🟡 | -| Default user/password | openmower/openmower | 🟡 | ✅ | 🟡 | -| SSH enabled | SSH active on first boot | ✅ | ✅ | 🟡 | -| SSH public key | Password less SSH login via SSH-key | 🟡 | ✅ | 🟡 | -| Imager Wi‑Fi | Preseeded Wi‑Fi connects on first boot | ✅ | ✅ | 🟡 | -| Imager openmower pass | Applied when configured | ✅ | ✅ | 🟡 | -| No known Wi‑Fi | Comitup AP appears (default SSID pattern) | 🟡 | ✅ | 🟡 | -| AP portal | Able to configure Wi‑Fi, then joins WLAN | 🟡 | ✅ | 🟡 | -| Internal LAN | xCore is getting an IPv4 | -- | ✅ | 🟡 | -| Home LAN | eth0 IPv4 by your networks DHCP | 🟡 | ✅ | 🟡 | -| SSH | Reachable after network is up | ✅ | ✅ | 🟡 | -| WebTerminal (ttyd) | Reachable at port 7681 | ✅ | ✅ | 🟡 | -| Dockge | Reachable at port 5001 | ✅ | ✅ | 🟡 | -| ESC access | Ports get exposed via `openmower ...` cmd | ✅ | 🟡 | 🟡 | -| GNSS access | Port get exposed via `openmower ...` cmd | ✅ | 🟡 | 🟡 | -| Container shell (prefix) | `openmower shell` has docker prefix | ✅ | ✅ | 🟡 | +| Feature | Expected | HW‑V1
Pi4 | HW‑V2
CM4 | HW‑V2
CM5 | +| ---------------------------------------- | --------------------------------------------- | :----------: | :----------: | :----------: | +| Auto-reboot after initial boot | yes | ✅ | ✅ | ✅ | +| Debian release `lsb_release -a` | Debian GNU/Linux 13 (trixie) | ✅ | ✅ | ✅ | +| OpenMowerOS release `cat /etc/rpi-issue` | OpenMowerOS v2.x YYYY-MM-DD | ✅ | ✅ | ✅ | +| Hostname (default) `hostname` | openmower | 🟡 | ✅ | ✅ | +| Hostname (non-default) `hostname` | | ✅ | ✅ | ✅ | +| Default user/password | openmower/openmower | 🟡 | ✅ | ✅ | +| SSH enabled | SSH active on first boot | ✅ | ✅ | ✅ | +| SSH public key | Password less SSH login via SSH-key | 🟡 | ✅ | ✅ | +| Imager Wi‑Fi | Preseeded Wi‑Fi connects on first boot | ✅ | ✅ | ✅ | +| Imager openmower pass | Applied when configured | ✅ | ✅ | ✅ | +| No known Wi‑Fi | Comitup AP appears (default SSID pattern) | 🟡 | ✅ | ✅ | +| Comitup captive portal | Able to configure Wi‑Fi, then joins WLAN [^1] | 🟡 | ✅ | ✅ | +| Internal LAN | xCore is getting an IPv4 | 🟡 | ✅ | ✅ | +| Home LAN | eth0 IPv4 by your networks DHCP | 🟡 | ✅ | ✅ | +| SSH | Reachable after network is up | ✅ | ✅ | ✅ | +| WebTerminal (ttyd) | Reachable at port 7681 | ✅ | ✅ | ✅ | +| Dockge | Reachable at port 5001 | ✅ | ✅ | ✅ | +| ESC access | Ports get exposed via `openmower ...` cmd | ✅ | ✅ | 🟡 | +| GNSS access | Port get exposed via `openmower ...` cmd | ✅ | 🟡 | 🟡 | +| OpenOCD remote debugging | Remote debugging via `openmower openocd` | 🟡 | ✅ | ✅ | +| Container shell (prefix) | `openmower shell` has docker prefix | ✅ | ✅ | ✅ | ## Notes - Update cells as you validate on each hardware combo. - If Imager Wi‑Fi is set, Comitup should not spawn AP; if not, AP should appear. + +[^1]: You probably need to power-cycle your mower after entering your home WiFi credentials \ No newline at end of file diff --git a/ext/pi-gen b/ext/pi-gen index 7cf36c9..7dadcf1 160000 --- a/ext/pi-gen +++ b/ext/pi-gen @@ -1 +1 @@ -Subproject commit 7cf36c964ba99ff1c75bfcbac4ff53145e377802 +Subproject commit 7dadcf1fc5ce1648ab09409ab978831690c9a955 diff --git a/pi-gen.config b/pi-gen.config index 61eb4cb..6b4695c 100644 --- a/pi-gen.config +++ b/pi-gen.config @@ -33,3 +33,5 @@ STAGE_LIST="/pi-gen/stage0 /pi-gen/stage1 /pi-gen/stage2 /stage-openmower" # Compression of exported image DEPLOY_COMPRESSION=zip COMPRESSION_LEVEL=6 + +ENABLE_CLOUD_INIT=0 diff --git a/stage-openmower/15-pi-config/files/boot/firmware/config.addendum b/stage-openmower/15-pi-config/files/boot/firmware/config.addendum index 4d5f59c..bd1cd10 100644 --- a/stage-openmower/15-pi-config/files/boot/firmware/config.addendum +++ b/stage-openmower/15-pi-config/files/boot/firmware/config.addendum @@ -56,8 +56,8 @@ dtparam=ant1 # External- U.FL/IPEX antenna connector: # dtparam=ant2 -# Fan control (on CM4 it's GPIO18) -dtoverlay=pwm-gpio-fan,fan_gpio=18 +# Fan control (GPIO fan) — enable and set start temperature (in millidegrees C) +dtoverlay=pwm-gpio-fan,fan_gpio=18,temp=70000 [cm5] # CM5 antenna selection — choose Wi‑Fi antenna path @@ -66,6 +66,5 @@ dtparam=ant1 # External- U.FL/IPEX antenna connector: # dtparam=ant2 -# Fan control (on CM5 it's GPIO18) -dtoverlay=pwm-gpio-fan,fan_gpio=18 - +# Fan control (GPIO fan) — enable and set start temperature (in millidegrees C) +dtoverlay=pwm-gpio-fan,fan_gpio=18,temp=70000 diff --git a/stage-openmower/20-comitup/00-run-chroot.sh b/stage-openmower/20-comitup/00-run-chroot.sh index 9c8e507..45b39b0 100755 --- a/stage-openmower/20-comitup/00-run-chroot.sh +++ b/stage-openmower/20-comitup/00-run-chroot.sh @@ -5,11 +5,15 @@ apt-get update apt-get install -y --no-install-recommends comitup network-manager wpasupplicant rfkill systemctl enable comitup.service -systemctl enable comitup-web.service systemctl enable comitup-nm-wifi-ensure.service systemctl mask NetworkManager-wait-online.service +systemctl mask wpa-supplicant.service if ! grep -q '^ap_name:' /etc/comitup.conf 2>/dev/null; then printf '\n# Default OpenMower AP name for provisioning\nap_name: OpenMower-\n' >> /etc/comitup.conf fi + +# Enable external_callback to manage dnsmasq +sed -i 's/^#\s*external_callback:.*/external_callback: \/usr\/local\/bin\/comitup-callback/' /etc/comitup.conf +chown -R root:root /usr/local/bin/comitup-callback diff --git a/stage-openmower/20-comitup/00-run.sh b/stage-openmower/20-comitup/00-run.sh index a60642e..0e3d167 100755 --- a/stage-openmower/20-comitup/00-run.sh +++ b/stage-openmower/20-comitup/00-run.sh @@ -7,3 +7,4 @@ STAGE_DIR="$(dirname "$0")" # Install files install -m 0644 -D "$STAGE_DIR/files/etc/NetworkManager/conf.d/10-comitup.conf" "$ROOTFS_DIR/etc/NetworkManager/conf.d/10-comitup.conf" install -m 0644 -D "$STAGE_DIR/files/etc/systemd/system/comitup-nm-wifi-ensure.service" "$ROOTFS_DIR/etc/systemd/system/comitup-nm-wifi-ensure.service" +install -m 0755 -D "$STAGE_DIR/files/usr/local/bin/comitup-callback" "$ROOTFS_DIR/usr/local/bin/comitup-callback" diff --git a/stage-openmower/20-comitup/files/usr/local/bin/comitup-callback b/stage-openmower/20-comitup/files/usr/local/bin/comitup-callback new file mode 100644 index 0000000..e632790 --- /dev/null +++ b/stage-openmower/20-comitup/files/usr/local/bin/comitup-callback @@ -0,0 +1,32 @@ +#!/bin/bash +# Callback script for comitup to manage dnsmasq +# Argument: $1 = state (HOTSPOT, CONNECTING, CONNECTED) + +LOG="/var/log/comitup-callback.log" +DNSMASQ_SERVICE="dnsmasq.service" + +log() { + echo "$(date): $*" >> "$LOG" +} + +case "$1" in + HOTSPOT) + log "Entering HOTSPOT mode - stopping dnsmasq" + systemctl stop "$DNSMASQ_SERVICE" 2>/dev/null + pkill -9 dnsmasq 2>/dev/null + # Ensure no dnsmasq is listening on port 67 + ss -ulpn | grep :67 && log "WARNING: Port 67 still occupied" + ;; + CONNECTING) + log "Entering CONNECTING mode - dnsmasq remains stopped" + ;; + CONNECTED) + log "Entering CONNECTED mode - restarting dnsmasq" + systemctl start "$DNSMASQ_SERVICE" 2>/dev/null + ;; + *) + log "Unknown state: $1" + ;; +esac + +exit 0 diff --git a/stage-openmower/25-lan/files/etc/dnsmasq.d/10-openmower.conf b/stage-openmower/25-lan/files/etc/dnsmasq.d/10-openmower.conf index 9dfc4e2..c853f0b 100644 --- a/stage-openmower/25-lan/files/etc/dnsmasq.d/10-openmower.conf +++ b/stage-openmower/25-lan/files/etc/dnsmasq.d/10-openmower.conf @@ -2,6 +2,12 @@ # specified interfaces (and the loopback) give the name of the # interface (eg eth0) here. # Repeat the line for more than one interface. +# +# AH20260105: +# bind-interfaces together with interface does not work as expected. +# dnsmasq always bind to 0.0.0.0:67. No 2nd dnsmasq on other interface bindable! +# See workaround in /usr/local/bin/comitup-callback +#bind-interfaces #interface=eth0 # Or you can specify which interface _not_ to listen on #except-interface= diff --git a/stage-openmower/40-openmower/00-run-chroot.sh b/stage-openmower/40-openmower/00-run-chroot.sh index 920bcc9..882cd8f 100755 --- a/stage-openmower/40-openmower/00-run-chroot.sh +++ b/stage-openmower/40-openmower/00-run-chroot.sh @@ -14,6 +14,12 @@ chown -R 1000:1000 /home/openmower/ros mkdir -p /home/openmower/params chown -R 1000:1000 /home/openmower/params +# Create dir and symlink for easy access to "latest" ros log +mkdir -p /data +chown -R 1000:1000 /data +ln -s /home/openmower/ros /data/ros + + export DEBIAN_FRONTEND=noninteractive # Minimal deps for fetching & unpacking diff --git a/stage-openmower/40-openmower/files/home/openmower/params/mower_params.yaml b/stage-openmower/40-openmower/files/home/openmower/params/mower_params.yaml index 7e7554b..21221c9 100644 --- a/stage-openmower/40-openmower/files/home/openmower/params/mower_params.yaml +++ b/stage-openmower/40-openmower/files/home/openmower/params/mower_params.yaml @@ -30,7 +30,7 @@ mower_logic: outline_overlap_count: 1 mow_angle_offset: 0 mow_angle_offset_is_absolute: false - mow_angle_increment: 110 + mow_angle_increment: 0 gps_wait_time: 5.0 gps_timeout: 5.0 rain_mode: 0 @@ -38,7 +38,7 @@ mower_logic: rain_check_seconds: 20 undock_distance: 1.0 undock_angled_distance: 2.0 - undock_angle: 45.0 + undock_angle: 0.0 undock_fixed_angle: false undock_use_curve: true # Once you validated the functionality of your emergency sensors, diff --git a/stage-openmower/45-openocd/00-run-chroot.sh b/stage-openmower/45-openocd/00-run-chroot.sh new file mode 100755 index 0000000..e29ef56 --- /dev/null +++ b/stage-openmower/45-openocd/00-run-chroot.sh @@ -0,0 +1,23 @@ +#!/bin/bash -e + +chown -R 1000:1000 /home/openmower/.config + +export DEBIAN_FRONTEND=noninteractive + +# Install dependencies +apt-get update +apt-get install -y --no-install-recommends autoconf automake build-essential curl libftdi-dev libtool libusb-1.0-0-dev git pkg-config rpi.gpio-common texinfo libgpiod-dev libjim-dev + +# Create directory for OpenOCD +mkdir -p /opt +cd /opt + +# Clone OpenOCD repository +git clone https://github.com/raspberrypi/openocd.git --recursive + +# Bootstrap, configure, compile, and install OpenOCD +cd openocd +./bootstrap +./configure --enable-ftdi --enable-sysfsgpio --enable-bcm2835gpio --enable-linuxgpiod +make -j$(nproc) +make install \ No newline at end of file diff --git a/stage-openmower/45-openocd/00-run.sh b/stage-openmower/45-openocd/00-run.sh new file mode 100755 index 0000000..7ebe620 --- /dev/null +++ b/stage-openmower/45-openocd/00-run.sh @@ -0,0 +1,10 @@ +#!/bin/bash -e + +STAGE_DIR="$(dirname "$0")" + +# Install files +install -m 0755 -d "$ROOTFS_DIR/home/openmower/.config/openmower-cli" +install -m 0664 -D "$STAGE_DIR/files/xcore.cfg" "$ROOTFS_DIR/home/openmower/.config/openmower-cli/xcore.cfg" + +install -o "root" -m 0755 -d "$ROOTFS_DIR/root/.config/openmower-cli" +install -o "root" -m 0664 -D "$STAGE_DIR/files/xcore.cfg" "$ROOTFS_DIR/root/.config/openmower-cli/xcore.cfg" diff --git a/stage-openmower/45-openocd/files/xcore.cfg b/stage-openmower/45-openocd/files/xcore.cfg new file mode 100644 index 0000000..f0e4343 --- /dev/null +++ b/stage-openmower/45-openocd/files/xcore.cfg @@ -0,0 +1,34 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +# Config for Raspberry Pi 5 used as a bitbang adapter. +# https://www.raspberrypi.com/documentation/computers/raspberry-pi.html + +# Raspberry Pi 5 is not compatible with bcm2835gpio native GPIO driver. +# The linuxgpiod driver without configurable adapter speed runs at approximately +# 800 kHz (SWD writes) and 360 kHz (SWD reads) + +adapter driver linuxgpiod + +proc read_file { name } { + if {[catch {open $name r} fd]} { + return "" + } + set result [read $fd] + close $fd + return $result +} + +set pcie_aspm [read_file /sys/module/pcie_aspm/parameters/policy] +if {![string match {*\[performance\]*} $pcie_aspm]} { + echo "Warn : Switch PCIe power saving off or the first couple of pulses gets clocked as fast as 20 MHz" + echo "Warn : Issue 'echo performance | sudo tee /sys/module/pcie_aspm/parameters/policy'" +} + +set _GPIO_CHIP 0 + +# Each of the SWD lines need a gpio number set: swclk swdio +# OpenMower pins +adapter gpio swclk -chip $_GPIO_CHIP 27 +adapter gpio swdio -chip $_GPIO_CHIP 22 + +transport select swd diff --git a/stage-openmower/50-extras/00-packages-nr b/stage-openmower/50-extras/00-packages-nr index fabfb2c..bf56d48 100644 --- a/stage-openmower/50-extras/00-packages-nr +++ b/stage-openmower/50-extras/00-packages-nr @@ -1,6 +1,5 @@ # Install a few helpful packages mc -openocd wavemon aptitude socat