[education/kstars] kstars/ekos/align: Fix align hang when a slew completes without an observable IPS_BUSY
Jasem Mutlaq <[email protected]>
| Newsgroups | gmane.comp.kde.cvs |
|---|---|
| Message-ID | <[email protected]> |
Git commit 6b46891bf8018b758b9682938a98a2f0ce62748b by Jasem Mutlaq.
Committed on 15/08/2026 at 10:11.
Pushed by mutlaqja into branch 'master'.
Fix align hang when a slew completes without an observable IPS_BUSY
Some mount drivers finish very short corrective slews (e.g. the small
residual left after a Sync) within a single status tick and never emit
an intermediate IPS_BUSY for EQUATORIAL_EOD_COORD/COORD. Align's
ALIGN_SLEWING handler only trusted an IPS_OK once it had witnessed
IPS_BUSY (or a 10s timer elapsed), and that elapsed-timer fallback is
only re-evaluated when a new property update arrives - so once the
mount settled and stopped pushing updates, align was stuck forever,
never re-triggering capture/plate-solving.
Snapshot the mount's reported RA/DE right before Slew() commands the
move, and also accept an IPS_OK whose position differs from that
snapshot as proof of a genuine completion. IPS_OK means "not busy" by
INDI convention, so a changed position can only mean the mount already
reported completion, never that it's still mid-slew - this can't fire
while a slew, however long, is still genuinely in progress.
M +5 -0 kstars/ekos/align/align.h
M +23 -1 kstars/ekos/align/align_goto.cpp
https://invent.kde.org/education/kstars/-/commit/6b46891bf8018b758b9682938a98a2f0ce62748b
diff --git a/kstars/ekos/align/align.h b/kstars/ekos/align/align.h
index 258a032c30..353e1c55c1 100644
--- a/kstars/ekos/align/align.h
+++ b/kstars/ekos/align/align.h
@@ -915,6 +915,11 @@ class Align : public QWidget, public Ui::Align
// Only wait this many milliseconds for slew to start.
// Otherwise assume it has begun.
static constexpr int MAX_WAIT_FOR_SLEW_START_MSEC = 10000;
+ // Mount's reported RA/DE (raw property values) right before the last Slew() was
+ // commanded. Lets the ALIGN_SLEWING/IPS_OK handler recognize a fresh completion even
+ // when no IPS_BUSY was ever observed for that slew.
+ double m_PreSlewRA { 0 };
+ double m_PreSlewDE { 0 };
// Online and Offline parsers
AstrometryParser* parser { nullptr };
diff --git a/kstars/ekos/align/align_goto.cpp b/kstars/ekos/align/align_goto.cpp
index 484120dfdb..a6c554d0ae 100644
--- a/kstars/ekos/align/align_goto.cpp
+++ b/kstars/ekos/align/align_goto.cpp
@@ -185,7 +185,17 @@ void Align::updateProperty(INDI::Property prop)
case ALIGN_SLEWING:
- if (!didSlewStart())
+ // didSlewStart() only trusts an IPS_OK if we previously witnessed an
+ // IPS_BUSY for this slew (or a 10s timer has elapsed). Some drivers
+ // complete very short slews within a single status tick and never emit
+ // an observable IPS_BUSY, so that condition alone can stay false forever
+ // even though the mount genuinely already moved. Also accept the update
+ // if the reported position differs from what it was right before this
+ // slew was commanded: IPS_OK means "not busy" by INDI convention, so a
+ // changed position can only mean the mount already reported completion,
+ // never that it's still mid-slew.
+ if (!didSlewStart() &&
+ nvp->np[0].value == m_PreSlewRA && nvp->np[1].value == m_PreSlewDE)
{
qCDebug(KSTARS_EKOS_ALIGN) << "Mount slew planned, but not started slewing yet...";
break;
@@ -484,6 +494,18 @@ void Align::Slew()
setState(ALIGN_SLEWING);
Q_EMIT newStatus(state);
+ // Snapshot the mount's currently-reported coordinates before commanding the slew, so the
+ // ALIGN_SLEWING/IPS_OK handler above can tell a fresh completion from a stale, pre-slew
+ // property value that simply hasn't been superseded by an observable IPS_BUSY yet.
+ if (auto pn = m_Mount->getNumber(m_Mount->isJ2000() ? "EQUATORIAL_COORD" : "EQUATORIAL_EOD_COORD"))
+ {
+ if (auto nvp = pn.getNumber())
+ {
+ m_PreSlewRA = nvp->np[0].value;
+ m_PreSlewDE = nvp->np[1].value;
+ }
+ }
+
if (m_Mount->Slew(&m_TargetCoord))
{
slewStartTimer.start();