Disable dangerous motor reset command after causing telescope reboot
The motor reset command (cmd 14003, inferred from a gap in the WsCmd enum)
caused the telescope to immediately reboot during live testing. The Android
app never uses ReqMotorReset — it only uses joystick (14006-14009), run
(14000) and stop (14002). Motor homing is handled internally by the firmware
during astro calibration or panorama operations.
Changes:
- MotorReset() now returns an error instead of sending the command
- CLI "motor reset" shows the disabled message
- Documented the incident and lessons in TEST_RESULTS.md
- Confirmed motor position query (cmd 14001) works but returns NEED_RESET
- Confirmed slew movements (all directions/speeds) work safely after reboot
💘 Generated with Crush
Assisted-by: Crush:glm-5.2
This commit is contained in:
@ -98,6 +98,25 @@ Le `motor stop` interrompt un slew en cours instantanément.
|
|||||||
|
|
||||||
`ReqMotorRunTo` : moteur ID, position cible, vitesse. Fire-and-forget (pas de ack type=3).
|
`ReqMotorRunTo` : moteur ID, position cible, vitesse. Fire-and-forget (pas de ack type=3).
|
||||||
|
|
||||||
|
#### 4.6 Motor get-position (cmd 14001 — inféré, confirmé fonctionnel)
|
||||||
|
|
||||||
|
| Test | Commande | Résultat |
|
||||||
|
|------|----------|----------|
|
||||||
|
| Position moteur 0 | `motor position 0` | ✅ reply type=3, `code=-14520` (NEED_RESET) |
|
||||||
|
| Position moteur 1 | `motor position 1` | ✅ reply type=3, `code=-14520` (NEED_RESET) |
|
||||||
|
|
||||||
|
L'ID 14001 n'est pas dans le WsCmd enum de l'APK mais fonctionne — le firmware répond avec `ResMotorPosition{id, code, position}`. Le `code=-14520` correspond à `CODE_STEP_MOTOR_NEED_RESET` : les moteurs n'ont pas été homed.
|
||||||
|
|
||||||
|
#### 4.7 Motor reset (cmd 14003 — ⚠️ DANGEREUX, DÉSACTIVÉ)
|
||||||
|
|
||||||
|
| Test | Commande | Résultat |
|
||||||
|
|------|----------|----------|
|
||||||
|
| Reset moteur 0 | `motor reset 0 0` | ⚠️ **A causé le reboot du télescope** |
|
||||||
|
|
||||||
|
L'ID 14003 est inféré (gap entre STOP=14002 et JOYSTICK=14006). L'envoi de `ReqMotorReset{id, direction}` a provoqué un **reboot immédiat du télescope**. La commande est désormais **désactivée** dans le code et retourne une erreur explicite.
|
||||||
|
|
||||||
|
**Leçon** : ne jamais envoyer de commandes inférées (IDs non confirmés dans le WsCmd enum de l'APK) sans validation préalable. L'app Android n'utilise que les commandes joystick (14006-14009), run (14000) et stop (14002). Le reset/home des moteurs est probablement géré côté firmware uniquement, déclenché par la calibration astro ou le panorama.
|
||||||
|
|
||||||
#### 4.6 Observations sur la lecture de position
|
#### 4.6 Observations sur la lecture de position
|
||||||
|
|
||||||
- **`focus_position`** (moteur de mise au point) : visible dans `state` → `focus_position:{pos:593}`, reste stable pendant les mouvements de pointage.
|
- **`focus_position`** (moteur de mise au point) : visible dans `state` → `focus_position:{pos:593}`, reste stable pendant les mouvements de pointage.
|
||||||
|
|||||||
@ -265,7 +265,7 @@ func cmdMotor() *cobra.Command {
|
|||||||
},
|
},
|
||||||
&cobra.Command{
|
&cobra.Command{
|
||||||
Use: "reset <motor-id> [direction]",
|
Use: "reset <motor-id> [direction]",
|
||||||
Short: "Reset motor to home (0=back, 1=forward)",
|
Short: "Reset motor to home (DISABLED — causes reboot)",
|
||||||
Args: cobra.RangeArgs(1, 2),
|
Args: cobra.RangeArgs(1, 2),
|
||||||
Run: func(_ *cobra.Command, args []string) {
|
Run: func(_ *cobra.Command, args []string) {
|
||||||
id := parseInt32(args[0])
|
id := parseInt32(args[0])
|
||||||
@ -276,7 +276,6 @@ func cmdMotor() *cobra.Command {
|
|||||||
scope, cleanup := dial()
|
scope, cleanup := dial()
|
||||||
defer cleanup()
|
defer cleanup()
|
||||||
must(scope.MotorReset(id, dir))
|
must(scope.MotorReset(id, dir))
|
||||||
fmt.Printf("motor %d reset (dir=%v)\n", id, dir)
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
&cobra.Command{
|
&cobra.Command{
|
||||||
|
|||||||
@ -197,14 +197,10 @@ func (t *Telescope) MotorRunTo(id int32, endPos, speed float64) error {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// MotorReset resets a motor (finds home via limit switch).
|
// MotorGetPosition queries a motor's current position (cmd 14001).
|
||||||
// cmd 14003 is inferred (not in WsCmd enum). direction: false=back, true=forward.
|
// Returns code=-14520 (NEED_RESET) if motors haven't been homed.
|
||||||
func (t *Telescope) MotorReset(id int32, direction bool) error {
|
// Note: this command ID is inferred, not in the APK's WsCmd enum, but
|
||||||
return t.sendNotify(CmdMotorReset, &pb.ReqMotorReset{Id: id, Direction: direction})
|
// confirmed working via live testing.
|
||||||
}
|
|
||||||
|
|
||||||
// MotorGetPosition queries a motor's current position.
|
|
||||||
// cmd 14001 is inferred. May timeout if firmware doesn't support it.
|
|
||||||
func (t *Telescope) MotorGetPosition(id int32) (*pb.ResMotorPosition, error) {
|
func (t *Telescope) MotorGetPosition(id int32) (*pb.ResMotorPosition, error) {
|
||||||
pkt, err := t.send(CmdMotorGetPosition, &pb.ReqMotorGetPosition{Id: id})
|
pkt, err := t.send(CmdMotorGetPosition, &pb.ReqMotorGetPosition{Id: id})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -214,6 +210,13 @@ func (t *Telescope) MotorGetPosition(id int32) (*pb.ResMotorPosition, error) {
|
|||||||
return resp, decodeResponse(pkt, resp)
|
return resp, decodeResponse(pkt, resp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WARNING: MotorReset (cmd 14003) is inferred and NOT used by the Android app.
|
||||||
|
// Live testing showed it causes the telescope to reboot. Use with extreme caution.
|
||||||
|
// Disabled until properly reverse-engineered from the native .so libraries.
|
||||||
|
func (t *Telescope) MotorReset(id int32, direction bool) error {
|
||||||
|
return fmt.Errorf("motor reset (cmd 14003) is disabled: causes telescope reboot, not safe")
|
||||||
|
}
|
||||||
|
|
||||||
// GetFocusInfinityPos retrieves the user-defined infinity focus position.
|
// GetFocusInfinityPos retrieves the user-defined infinity focus position.
|
||||||
func (t *Telescope) GetFocusInfinityPos() (int32, error) {
|
func (t *Telescope) GetFocusInfinityPos() (int32, error) {
|
||||||
pkt, err := t.sendEmpty(CmdFocusGetUserInfinity)
|
pkt, err := t.sendEmpty(CmdFocusGetUserInfinity)
|
||||||
|
|||||||
Reference in New Issue
Block a user