From 754ca53a88868c411db7ef2ad87302037cd45952 Mon Sep 17 00:00:00 2001 From: Christoffer Fremling Date: Sun, 7 Jun 2026 22:45:48 -0700 Subject: [PATCH] Query ACAM directly for guide state in "put on slit" routing "Put on slit" intermittently failed when guiding was off. slicecam's offset_acam_goal() decides between updating ACAM's guide goal (guiding) and sending a PT offset directly to the TCS (not guiding) from a cached pub/sub flag (is_acam_guiding), populated from ACAM's status broadcasts. ACAM publishes its status only on change and skips frames between solves, so the cached flag can read "guiding" while stale, or lag a state change. Trusting it for this decision is unsafe in both directions: a wrong "not guiding" sends a PT offset and moves the telescope while ACAM is actively guiding (fighting the guider); a wrong "guiding" sends a no-op offsetgoal and never moves. Query acamd directly instead. ACAMD_ACQUIRE with no args returns the current mode { stopped | acquiring | guiding }, which is authoritative and current, so the routing decision no longer depends on pub/sub freshness. Co-Authored-By: Claude Opus 4.8 (1M context) --- slicecamd/slicecam_interface.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/slicecamd/slicecam_interface.cpp b/slicecamd/slicecam_interface.cpp index 01604a4b..e6d09b58 100644 --- a/slicecamd/slicecam_interface.cpp +++ b/slicecamd/slicecam_interface.cpp @@ -2507,7 +2507,21 @@ namespace Slicecam { // If ACAM is guiding then slicecam must not move the telescope, // but must allow ACAM to perform the offset. // - bool is_guiding = this->is_acam_guiding.load(); + // Ask acamd directly for its guide state instead of trusting the cached + // pub/sub flag (is_acam_guiding). ACAM publishes its status only on change + // and skips frames between solves, so the cache can read "guiding" while + // stale or lag a state change. Routing on a wrong "not guiding" would send + // a PT offset and move the telescope while ACAM is actively guiding; a + // wrong "guiding" would send a no-op offsetgoal and never move. A direct + // query is authoritative and current. ACAMD_ACQUIRE with no args returns + // the mode string { stopped | acquiring | guiding }. + // + std::string acam_mode; + if ( this->acamd.command( ACAMD_ACQUIRE, acam_mode ) != NO_ERROR ) { + logwrite( function, "ERROR querying ACAM guide state" ); + return ERROR; + } + bool is_guiding = ( acam_mode.find("guiding") != std::string::npos ); // send the offsets now //