diff --git a/dwarfctl/TEST_RESULTS.md b/dwarfctl/TEST_RESULTS.md index e8c8e32..956c293 100644 --- a/dwarfctl/TEST_RESULTS.md +++ b/dwarfctl/TEST_RESULTS.md @@ -105,9 +105,9 @@ Tests en condition réelle, télescope posé verticalement sur trépied (pas en | Angle | Axe | Direction observée | |-------|-----|-------------------| | 0° | Azimut (horizontal) | Rotation horaire vue de dessus | -| 90° | Altitude | **Descente** (vers le sol) | +| 90° | Altitude | **Montée** (vers le ciel) | | 180° | Azimut | Rotation anti-horaire (opposé de 0°) | -| 270° | Altitude | **Montée** (vers le ciel) | +| 270° | Altitude | **Descente** (vers le sol) | **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. diff --git a/dwarfctl/cmd/dwarfctl/main.go b/dwarfctl/cmd/dwarfctl/main.go index 06e56a4..4e0ba08 100644 --- a/dwarfctl/cmd/dwarfctl/main.go +++ b/dwarfctl/cmd/dwarfctl/main.go @@ -1,6 +1,7 @@ package main import ( + "bufio" "fmt" "math" "os" @@ -9,7 +10,9 @@ import ( "time" "github.com/antitbone/dwarfctl/internal/api" + pb "github.com/antitbone/dwarfctl/proto" "github.com/spf13/cobra" + "google.golang.org/protobuf/proto" ) var ( @@ -39,6 +42,7 @@ func main() { cmdSystem(), cmdPower(), cmdMonitor(), + cmdInteractive(), cmdPano(), ) @@ -667,7 +671,8 @@ func cmdPano() *cobra.Command { // --- 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) { @@ -676,8 +681,71 @@ func cmdMonitor() *cobra.Command { return &cobra.Command{ ch := scope.Notifications() fmt.Println("Monitoring notifications (Ctrl-C to stop)...") for pkt := range ch { - fmt.Printf("[NOTIFY] cmd=%d module=%d type=%d data_len=%d\n", - pkt.GetCmd(), pkt.GetModuleId(), pkt.GetType(), len(pkt.GetData())) + cmdID := pkt.GetCmd() + extra := "" + if cmdID == 15295 && len(pkt.GetData()) > 0 { + att := &pb.DeviceAttitude{} + if proto.Unmarshal(pkt.GetData(), att) == nil { + extra = fmt.Sprintf(" pitch=%.1f yaw=%.1f roll=%.1f", att.GetPitch(), att.GetYaw(), att.GetRoll()) + } + } + fmt.Printf("[NOTIFY] cmd=%d module=%d type=%d data=%d%s\n", + cmdID, pkt.GetModuleId(), pkt.GetType(), len(pkt.GetData()), extra) + } + }, + } +} + +func cmdInteractive() *cobra.Command { + return &cobra.Command{ + Use: "interactive", + Short: "Interactive slew with real-time attitude (Ctrl-C to exit)", + Run: func(_ *cobra.Command, _ []string) { + scope, cleanup := dial() + defer cleanup() + ch := scope.Notifications() + go func() { + for pkt := range ch { + if pkt.GetCmd() == 15295 && len(pkt.GetData()) > 0 { + att := &pb.DeviceAttitude{} + if proto.Unmarshal(pkt.GetData(), att) == nil { + fmt.Printf("\r [ATTITUDE] pitch=%.1f yaw=%.1f roll=%.1f \n", att.GetPitch(), att.GetYaw(), att.GetRoll()) + } + } + } + }() + fmt.Println("Interactive slew. Commands: [duration_s], stop, photo, state, q") + scanner := bufio.NewScanner(os.Stdin) + for { + fmt.Print("> ") + if !scanner.Scan() { break } + line := strings.TrimSpace(scanner.Text()) + if line == "" { continue } + parts := strings.Fields(line) + switch parts[0] { + case "q", "quit", "exit": + return + case "stop": + must(scope.MotorJoystickStop()) + fmt.Println("stopped") + case "photo": + must(scope.TakePhoto(api.CameraTele)) + fmt.Println("photo taken") + case "state": + st, err := scope.GetDeviceState() + must(err) + fmt.Printf("battery=%d%% focus=%d\n", st.GetDeviceStateInfo().GetBatteryInfo().GetPercentage(), st.GetFocusMotorStateInfo().GetFocusPosition().GetPos()) + default: + if len(parts) < 2 { fmt.Println("usage: [duration]"); continue } + angle := parseFloat(parts[0]) + speed := parseFloat(parts[1]) + dur := 1.0 + if len(parts) > 2 { dur = parseFloat(parts[2]) } + must(scope.SlewJoystick(angle, speed)) + time.Sleep(time.Duration(dur * float64(time.Second))) + must(scope.SlewJoystick(0, 0)) + fmt.Println("done") + } } }, }