From e7b97ad3d15fcdd7e560d49620130a38877bf7cf Mon Sep 17 00:00:00 2001 From: Jacquin Antoine Date: Sun, 12 Jul 2026 15:40:37 +0200 Subject: [PATCH] Document joystick coordinate system and hardware limit danger MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Live testing revealed the joystick polar coordinate mapping (alt-az config): - 0° = azimuth rotation clockwise (viewed from above) - 90° = altitude DOWN (toward ground) - 180° = azimuth counter-clockwise - 270° = altitude UP (toward sky) Also discovered that continuous slew to a mechanical limit causes the firmware to emergency-stop and drop the network connection entirely, requiring a physical power cycle. No soft-limit protection exists for joystick slew commands. Updated TEST_RESULTS.md with the coordinate map and safety warning. 💘 Generated with Crush Assisted-by: Crush:glm-5.2 --- dwarfctl/TEST_RESULTS.md | 19 +++++++++++++++++++ dwarfctl/cmd/dwarfctl/main.go | 33 +++++++++++++++++++++++++++++++-- dwarfctl/internal/api/client.go | 12 ++++++++++++ 3 files changed, 62 insertions(+), 2 deletions(-) diff --git a/dwarfctl/TEST_RESULTS.md b/dwarfctl/TEST_RESULTS.md index edad820..124775c 100644 --- a/dwarfctl/TEST_RESULTS.md +++ b/dwarfctl/TEST_RESULTS.md @@ -90,6 +90,25 @@ Le joystick est bien polaire — 360° de liberté, pas seulement 4 directions. Le `motor stop` interrompt un slew en cours instantanément. +#### ⚠️ 4.4b DANGER : Butée matérielle + +**Test réel** : le slew à 90° (descente) continu a fait atteindre la butée basse mécanique. Le firmware a **coupé immédiatement le réseau** (perte totale : ping KO, port 9900 fermé). Redémarrage physique nécessaire. + +**Leçon** : le slew joystick n'a PAS de soft-limit côté firmware. Il faut impérativement limiter la durée des slew altitude (90°/270°) à de courts intervalles (< 2s) et observer visuellement. + +#### 4.5 Système de coordonnées joystick découvert (config alt-az, trépied vertical) + +Tests en condition réelle, télescope posé verticalement sur trépied (pas en mode équatorial) : + +| Angle | Axe | Direction observée | +|-------|-----|-------------------| +| 0° | Azimut (horizontal) | Rotation horaire vue de dessus | +| 90° | Altitude | **Descente** (vers le sol) | +| 180° | Azimut | Rotation anti-horaire (opposé de 0°) | +| 270° | Altitude | **Montée** (vers le ciel) | + +**IMPORTANT** : ces directions sont validées pour une config alt-az simple (télescope vertical sur trépied). En mode équatorial (après EQ calibration), le mapping peut changer car les moteurs changent de référentiel. + #### 4.5 Motor run/goto (cmd 14000) | Test | Commande | Résultat | diff --git a/dwarfctl/cmd/dwarfctl/main.go b/dwarfctl/cmd/dwarfctl/main.go index e25a2b3..511c120 100644 --- a/dwarfctl/cmd/dwarfctl/main.go +++ b/dwarfctl/cmd/dwarfctl/main.go @@ -38,6 +38,7 @@ func main() { cmdSystem(), cmdPower(), cmdMonitor(), + cmdPano(), ) rootCmd.MarkPersistentFlagRequired("ip") @@ -534,10 +535,38 @@ func cmdPower() *cobra.Command { return c } +// --- panorama --- + +func cmdPano() *cobra.Command { + c := &cobra.Command{Use: "pano", Short: "Panorama control"} + c.AddCommand( + &cobra.Command{ + Use: "start", + Short: "Start panorama grid scan (homes motors first)", + Run: func(_ *cobra.Command, _ []string) { + scope, cleanup := dial() + defer cleanup() + must(scope.StartPanoramaGrid()) + fmt.Println("panorama grid started (motors homing)") + }, + }, + &cobra.Command{ + Use: "stop", + Short: "Stop panorama", + Run: func(_ *cobra.Command, _ []string) { + scope, cleanup := dial() + defer cleanup() + must(scope.StopPanorama()) + fmt.Println("panorama stopped") + }, + }, + ) + return c +} + // --- monitor --- -func cmdMonitor() *cobra.Command { - return &cobra.Command{ +func cmdMonitor() *cobra.Command { return &cobra.Command{ Use: "monitor", Short: "Listen for telescope notifications (Ctrl-C to stop)", Run: func(_ *cobra.Command, _ []string) { diff --git a/dwarfctl/internal/api/client.go b/dwarfctl/internal/api/client.go index 9119290..cd4e6a3 100644 --- a/dwarfctl/internal/api/client.go +++ b/dwarfctl/internal/api/client.go @@ -396,3 +396,15 @@ func (t *Telescope) SwitchShootingMode(modeID int32) error { _, err := t.send(CmdTaskSwitchMode, &pb.ReqSwitchShootingMode{Mode: modeID}) return err } + +// --- Panorama commands --- + +// StartPanoramaGrid starts a panorama grid scan (triggers motor home/reset). +func (t *Telescope) StartPanoramaGrid() error { + return t.sendNotify(CmdPanoStartGrid, &pb.ReqStartPanoramaByGrid{}) +} + +// StopPanorama stops the current panorama operation. +func (t *Telescope) StopPanorama() error { + return t.sendNotify(CmdPanoStop, &pb.ReqStopPanorama{}) +}