diff --git a/dwarfctl/TEST_RESULTS.md b/dwarfctl/TEST_RESULTS.md index b76177a..f61d915 100644 --- a/dwarfctl/TEST_RESULTS.md +++ b/dwarfctl/TEST_RESULTS.md @@ -101,9 +101,19 @@ Le `motor stop` interrompt un slew en cours instantanément. **Découverte clé — Home par butée** : slewing en 270° (descente) à vitesse modérée jusqu'à ce que le limit switch se déclenche provoque un **home automatique du firmware**. Le télescope revient à la position 0 physique (optique vers le sol). C'est la méthode d'initialisation manuelle des moteurs — pas besoin de `motor reset` (qui ne fait que rebooter). Procédure d'initialisation manuelle : -1. `motor slew 270 0.5` jusqu'à la butée (le firmware home tout seul) -2. Position 0 = optique vers le sol -3. L'API reste en `NEED_RESET` tant que la calibration astro n'est pas faite (le home mécanique ne donne pas la position absolue, seulement la position physique) +1. `motor slew 90 0.4` pendant 5s — monter ~45° pour décoller de la butée basse +2. `motor init down 40` — slew 270° jusqu'à la butée basse → home automatique +3. Position 0 = optique vers le sol +4. L'axe altitude reste **pleinement opérationnel** après le home +5. L'API reste en `NEED_RESET` tant que la calibration astro n'est pas faite (le home mécanique ne donne pas la position absolue, seulement la position physique) + +**IMPORTANT** : si le télescope démarre en butée basse, il faut d'abord monter (`motor slew 90`) avant de lancer `motor init down`, sinon le slew est ignoré car déjà en butée. + +**Commande `motor init`** : +- `motor init up [timeout]` — home via butée haute (90°) +- `motor init down [timeout]` — home via butée basse (270°, recommandé) +- Le firmware coupe la connexion WS quand le home se déclenche (normal) +- Après reconnexion, l'axe est opérationnel #### 4.5 Système de coordonnées joystick découvert (config alt-az, trépied vertical) diff --git a/dwarfctl/cmd/dwarfctl/main.go b/dwarfctl/cmd/dwarfctl/main.go index 5c131e5..8aa3829 100644 --- a/dwarfctl/cmd/dwarfctl/main.go +++ b/dwarfctl/cmd/dwarfctl/main.go @@ -397,6 +397,28 @@ func cmdMotor() *cobra.Command { fmt.Printf("motor %d: id=%d code=%d position=%.2f\n", id, pos.GetId(), pos.GetCode(), pos.GetPosition()) }, }, + &cobra.Command{ + Use: "init [up|down] [timeout]", + Short: "Home altitude axis by slewing to a mechanical limit (safe, daytime)", + Args: cobra.MaximumNArgs(2), + Run: func(_ *cobra.Command, args []string) { + dir := 90.0 // default: up + if len(args) > 0 && args[0] == "down" { + dir = 270.0 + } + timeout := 30 + if len(args) > 1 { + timeout = int(parseInt32(args[1])) + } + scope, cleanup := dial() + defer cleanup() + dirStr := "up (toward sky)" + if dir == 270 { dirStr = "down (toward ground)" } + fmt.Printf("Initializing: slewing %s at 0.5 until limit (max %ds)...\n", dirStr, timeout) + must(scope.MotorInit(dir, timeout)) + fmt.Println("Init complete.") + }, + }, ) return c } diff --git a/dwarfctl/internal/api/client.go b/dwarfctl/internal/api/client.go index b6d55ab..48ffc2c 100644 --- a/dwarfctl/internal/api/client.go +++ b/dwarfctl/internal/api/client.go @@ -210,6 +210,18 @@ func (t *Telescope) MotorGetPosition(id int32) (*pb.ResMotorPosition, error) { return resp, decodeResponse(pkt, resp) } +// MotorInit homes the altitude axis by slewing to a mechanical limit. +// The firmware detects the limit switch and resets position automatically. +// direction: 90 = up (toward sky), 270 = down (toward ground). +// timeoutSec is the maximum time to wait for the limit (typically 30-60s). +func (t *Telescope) MotorInit(direction float64, timeoutSec int) error { + if err := t.SlewJoystick(direction, 0.5); err != nil { + return fmt.Errorf("init slew: %w", err) + } + time.Sleep(time.Duration(timeoutSec) * time.Second) + return t.SlewJoystick(0, 0) +} + // MotorReset resets a motor (finds home via limit switch). // cmd 14003 is inferred. WARNING: causes telescope reboot — but may be // the only way to unblock an axis stuck at a mechanical limit.