Leave a newly installed tower in manual: home at boot, capture only after auto is chosen
This commit is contained in:
parent
da9a9867ed
commit
4b73199e8e
|
|
@ -103,9 +103,20 @@ one yes. In order:
|
|||
6. builds and flashes the firmware (6) - **blocked** while any drivetrain value
|
||||
is still a `; TODO`, because that axis would refuse to move
|
||||
7. `test hardware`
|
||||
8. the boot service ([deployment.md](deployment.md) section 4), if wanted
|
||||
8. the boot service ([deployment.md](deployment.md) section 4), if wanted. A new
|
||||
tower gets `--init`: it homes at every boot, then **waits in manual and
|
||||
captures nothing** until someone chooses auto
|
||||
9. asks whether someone is at the rig; only on a yes does it home the gimbal and
|
||||
take a short capture - through the service, when the service is what homes it
|
||||
take **one** picture (a snapshot), then leave it in manual - through the
|
||||
service, when the service is what homes it
|
||||
|
||||
**Nothing starts capturing by itself.** Choose auto yourself: key `a` on the
|
||||
dashboard, or `mode auto` over MQTT. Once the tower is proven, make it boot into
|
||||
auto, as 111 does:
|
||||
|
||||
```bash
|
||||
scripts/install-tower --answer service_args="--init --start"
|
||||
```
|
||||
|
||||
Every question has a key, so any can be answered up front - `--answer
|
||||
tower_name=north`, `--answer yaw.r_sense_ohm=0.075` - or from a file of
|
||||
|
|
|
|||
|
|
@ -34,14 +34,14 @@ set -euo pipefail
|
|||
here="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
REPO="$(cd "$here/.." && pwd)"
|
||||
FW="$(cd "$REPO/.." && pwd)/firmware"
|
||||
# The two overrides exist to rehearse a FRESH install with --dry-run on a tower
|
||||
# The overrides exist to rehearse a FRESH install with --dry-run on a tower
|
||||
# that is already configured, without its real files being in the way.
|
||||
ETC="${INSTALL_TOWER_ETC:-/etc/fire_gimbal_control}"
|
||||
HW="$ETC/hardware.ini"
|
||||
CRED="$ETC/credentials.env"
|
||||
INSTALL_LOG="$ETC/install.log"
|
||||
CFG="${INSTALL_TOWER_CONFIG:-$REPO/config.ini}"
|
||||
UNIT=/etc/systemd/system/fire-gimbal-control.service
|
||||
UNIT="${INSTALL_TOWER_UNIT:-/etc/systemd/system/fire-gimbal-control.service}"
|
||||
LOGDIR="${XDG_DATA_HOME:-$HOME/.local/share}/fire_gimbal_control/logs"
|
||||
BIN="$REPO/build/fire_gimbal_control"
|
||||
FGC_CONFIG="$REPO/build/fgc-config"
|
||||
|
|
@ -186,6 +186,17 @@ py_serial() {
|
|||
|
||||
app_running() { "$FGC" status >/dev/null 2>&1; }
|
||||
|
||||
# One command line into the running program, whether it shows the dashboard or
|
||||
# the plain console: the dashboard needs ':' to open its command line first.
|
||||
app_cmd() {
|
||||
local pane; pane="$(tmux list-panes -t "=${FGC_SESSION:-fgc}" -F '#{pane_id}' 2>/dev/null | head -1)"
|
||||
[[ -n $pane ]] || return 1
|
||||
if tmux capture-pane -p -t "$pane" | grep -q '╭'; then
|
||||
tmux send-keys -t "$pane" ':'; sleep 0.5
|
||||
fi
|
||||
tmux send-keys -t "$pane" -l "$1"; tmux send-keys -t "$pane" Enter
|
||||
}
|
||||
|
||||
# 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
|
||||
|
|
@ -341,15 +352,8 @@ run_test() {
|
|||
# The app holds the serial port, so a test runs INSIDE it when it is up, and
|
||||
# as a one-shot run of the binary when it is not.
|
||||
if app_running; then
|
||||
local pane before after restore=""
|
||||
pane="$(tmux list-panes -t "=${FGC_SESSION:-fgc}" -F '#{pane_id}' | head -1)"
|
||||
local before after restore=""
|
||||
before="$(ls -t "$LOGDIR"/test_*.log 2>/dev/null | head -1)"
|
||||
app_cmd() { # one command line into the running program, dashboard or console
|
||||
if tmux capture-pane -p -t "$pane" | grep -q '╭'; then
|
||||
tmux send-keys -t "$pane" ':'; sleep 0.5
|
||||
fi
|
||||
tmux send-keys -t "$pane" -l "$1"; tmux send-keys -t "$pane" Enter
|
||||
}
|
||||
# Tests run in manual mode only - auto and pan refuse them. Note the mode,
|
||||
# switch for the test, and put it back afterwards, pan's arguments and all.
|
||||
app_cmd "mode"; sleep 1
|
||||
|
|
@ -759,9 +763,13 @@ installed_args() {
|
|||
[[ -r $UNIT ]] && sed -n 's|^ExecStart=.*/scripts/fgc start *||p' "$UNIT" | head -1
|
||||
}
|
||||
UNIT_TEXT=""
|
||||
SVC_ARGS_DEFAULT="--init --start"
|
||||
[[ -r $UNIT ]] && SVC_ARGS_DEFAULT="$(installed_args)"
|
||||
[[ -z $SVC_ARGS_DEFAULT ]] && SVC_ARGS_DEFAULT=none
|
||||
# A new tower homes at every boot but captures nothing until a person has chosen
|
||||
# auto: --init, not --init --start. Once it is proven, the operator makes it boot
|
||||
# into auto by re-running with --answer service_args="--init --start". A service
|
||||
# of ours keeps the arguments it has; one that is not ours (a legacy tower's old
|
||||
# program) gets the same safe default.
|
||||
SVC_ARGS_DEFAULT="--init"
|
||||
[[ -r $UNIT && -n $(installed_args) ]] && SVC_ARGS_DEFAULT="$(installed_args)"
|
||||
if [[ -r $UNIT && $S_SVC_ENABLED == enabled && $S_LINGER == yes && -z ${ANS[service_args]+x} ]] &&
|
||||
[[ "$(cat "$UNIT")" == "$(render_unit "$(installed_args)")" ]]; then
|
||||
plan service skip "installed and enabled (fgc start ${SVC_ARGS_DEFAULT/#none/})"
|
||||
|
|
@ -770,6 +778,8 @@ else
|
|||
echo "The boot service starts the program at every boot. With --init it HOMES THE"
|
||||
echo "GIMBAL UNATTENDED each time the tower powers up - which is what a tower in"
|
||||
echo "service needs, since the firmware keeps no position across a power cycle."
|
||||
echo "With --init alone it then WAITS IN MANUAL and captures nothing; add --start"
|
||||
echo "(--init --start) to boot straight into auto once the tower is proven."
|
||||
if ask_yn service "Install and enable it?" y; then
|
||||
ask service_args "Arguments it starts the program with ('none' for none)" "$SVC_ARGS_DEFAULT"
|
||||
svc_args="$REPLY_VAL"; [[ $svc_args == none ]] && svc_args=""
|
||||
|
|
@ -808,6 +818,15 @@ put_back() {
|
|||
local rc=$?
|
||||
rm -rf "$WORK"
|
||||
[[ $STOPPED_BY_US -eq 1 ]] && ! app_running || return $rc
|
||||
# The service stopped at the start may no longer be the one installed now: on
|
||||
# a legacy tower it was the old program's, and this run replaced its unit.
|
||||
# Starting the new one here would home the gimbal with nobody asked - the
|
||||
# step this installer only takes after a person at the rig says yes.
|
||||
if [[ $STOPPED_SVC -eq 1 && ${CHANGED[*]:-} == *service* ]]; then
|
||||
warn "the program is not running: the boot service was replaced by this run, and"
|
||||
warn "starting it homes the gimbal. With someone at the rig: sudo systemctl start fire-gimbal-control"
|
||||
return $rc
|
||||
fi
|
||||
warn "stopped before finishing - restarting the program as it was"
|
||||
if [[ $STOPPED_SVC -eq 1 ]]; then sudo systemctl start fire-gimbal-control
|
||||
else
|
||||
|
|
@ -974,30 +993,39 @@ echo "Homing drives each axis into its endstops. On a new or changed drivetrain
|
|||
echo "is the step that can break something, so it needs a person at the rig."
|
||||
if [[ $TEST_RC != 0 ]]; then
|
||||
warn "not offered: test hardware did not pass"
|
||||
elif ask_yn home "Someone is at the rig with a hand on the power - home now and take a short capture?" n; then
|
||||
elif ask_yn home "Someone is at the rig with a hand on the power - home now and take one picture?" n; then
|
||||
stop_app
|
||||
before="$(latest_log)"
|
||||
# Through the service when the service is what homes it, so the tower ends
|
||||
# up running under it; otherwise the same run by hand.
|
||||
# up running under it; otherwise the same run by hand. Never --start here:
|
||||
# the tower is left in manual, and auto is a person's choice (a service
|
||||
# already set to --start is the exception - that choice was made).
|
||||
if [[ $SVC_ON -eq 1 && " $(installed_args) " == *" --init "* ]]; then sudo systemctl start fire-gimbal-control
|
||||
else ( cd "$REPO" && "$FGC" start --init --start ) > /dev/null; fi
|
||||
else ( cd "$REPO" && "$FGC" start --init ) > /dev/null; fi
|
||||
say "homing (this can take a few minutes)"
|
||||
log=""; for _ in $(seq 1 30); do log="$(latest_log)"; [[ -n $log && $log != "$before" ]] && break; sleep 1; done
|
||||
outdir=""; ok=0
|
||||
outdir=""; ok=0; snapped=0
|
||||
for _ in $(seq 1 420); do
|
||||
grep -q 'Gimbal homed' "$log" 2>/dev/null && ok=1
|
||||
outdir="$(sed -n 's/.*capture output dir: //p' "$log" 2>/dev/null | tail -1)"
|
||||
# In manual, one snapshot proves the camera; in auto the sweep does.
|
||||
if [[ $ok -eq 1 && $snapped -eq 0 ]] && grep -q 'Entering control loop' "$log" 2>/dev/null &&
|
||||
! grep -q '\] mode auto' "$log" 2>/dev/null; then
|
||||
sleep 2; app_cmd "snapshot" && snapped=1
|
||||
fi
|
||||
if [[ $ok -eq 1 && -n $outdir ]] && find "$outdir" -name '*.jxl' -newer "$log" 2>/dev/null | grep -q .; then ok=2; break; fi
|
||||
app_running || break
|
||||
sleep 1
|
||||
done
|
||||
grep -E 'homed .* travel|counts_per_deg|Gimbal homed|ERROR' "$log" 2>/dev/null | tail -6 | sed 's/^/ /'
|
||||
case $ok in
|
||||
2) HOMED="homed and captured ($(find "$outdir" -name '*.jxl' -newer "$log" | wc -l) image(s) in $outdir)"; say "$HOMED" ;;
|
||||
2) HOMED="homed and captured ($(find "$outdir" -name '*.jxl' -newer "$log" | wc -l) image(s) in $outdir)"
|
||||
[[ $snapped -eq 1 ]] && HOMED+="; left in manual - nothing more is captured until someone chooses auto"
|
||||
say "$HOMED" ;;
|
||||
1) HOMED="homed, but no image within the wait"; warn "$HOMED" ;;
|
||||
*) HOMED="did not home - read the log above"; warn "$HOMED" ;;
|
||||
esac
|
||||
# Left running: that is the tower in service.
|
||||
# Left running, in the mode it came up in.
|
||||
fi
|
||||
|
||||
# Put the program back if it is not running. Not under the service unless it
|
||||
|
|
@ -1038,6 +1066,12 @@ open=0
|
|||
while read -r t; do [[ -n $t ]] && { echo " - hardware.ini: $t"; open=1; }; done < <(hw_todos)
|
||||
[[ $HOMED == homed* ]] || { echo " - homing: $HOMED"; open=1; }
|
||||
[[ $HOMED == homed* ]] && { echo " - calibration: run 'gimbal heading setup' to tie yaw to true north"; open=1; }
|
||||
if [[ -r $UNIT && " $(installed_args) " != *" --start "* ]]; then
|
||||
echo " - capture: the tower waits in MANUAL at every boot and captures nothing. Choose auto"
|
||||
echo " yourself (key a, or 'mode auto'); once it is proven, make it boot into auto:"
|
||||
echo " scripts/install-tower --answer service_args=\"--init --start\""
|
||||
open=1
|
||||
fi
|
||||
[[ $(ini_get "$CFG" Features enable_mqtt 2>/dev/null) == true ]] &&
|
||||
{ echo " - MQTT: confirm topics reach the broker (a tower with no broker runs degraded, reporting to nobody)"; open=1; }
|
||||
echo " - reboot once and run: scripts/install-tower --verify (the USB preconditions must survive it)"
|
||||
|
|
|
|||
Loading…
Reference in New Issue