#ifndef GIMBAL_H #define GIMBAL_H #include #include /* * gimbal.h — Pan/tilt gimbal controller for ST3215 bus servos (Issue #547) * * Manages dual ST3215 serial bus servos: * Pan servo: ID GIMBAL_PAN_ID (config.h, default 1) * Tilt servo: ID GIMBAL_TILT_ID (config.h, default 2) * * Position units: degrees x10 (int16), matching JLink protocol convention. * e.g. 900 = 90.0°, -450 = -45.0° * * Limits: * Pan: -1800..+1800 (x10 deg) = -180..+180 deg * Tilt: -900..+900 (x10 deg) = -90..+90 deg * * The gimbal_tick() function polls servo feedback at GIMBAL_TLM_HZ (50 Hz). * Alternates reading pan position on even ticks, tilt on odd ticks — each * servo polled at 25 Hz to keep bus utilization low. */ typedef struct { /* Command state */ int16_t cmd_pan_x10; /* Commanded pan (deg x10) */ int16_t cmd_tilt_x10; /* Commanded tilt (deg x10) */ uint16_t cmd_speed; /* Servo bus speed (0=max, 1-4095) */ bool torque_enabled; /* True when torques are enabled */ /* Feedback state (updated at ~25 Hz per axis) */ int16_t fb_pan_x10; /* Measured pan (deg x10) */ int16_t fb_tilt_x10; /* Measured tilt (deg x10) */ uint16_t fb_pan_speed; /* Raw speed register, pan servo */ uint16_t fb_tilt_speed; /* Raw speed register, tilt servo */ /* Diagnostics */ uint32_t rx_ok; /* Successful position reads */ uint32_t rx_err; /* Failed position reads */ uint32_t _last_tick_ms; /* Internal: last tick timestamp */ uint8_t _poll_phase; /* Internal: alternates 0=pan 1=tilt */ } gimbal_t; /* * gimbal_init(g) — enable torque on both servos, center them. * servo_bus_init() must be called first. */ void gimbal_init(gimbal_t *g); /* * gimbal_set_pos(g, pan_x10, tilt_x10, speed) — command a new pan/tilt * position. pan_x10 and tilt_x10 are degrees×10, clamped to servo limits. * speed: 0=max servo speed, 1-4095 = scaled. */ void gimbal_set_pos(gimbal_t *g, int16_t pan_x10, int16_t tilt_x10, uint16_t speed); /* * gimbal_torque(g, enable) — enable or disable torque on both servos. */ void gimbal_torque(gimbal_t *g, bool enable); /* * gimbal_tick(g, now_ms) — poll servo feedback at GIMBAL_TLM_HZ. * Call every 1 ms from the main loop; function self-throttles. */ void gimbal_tick(gimbal_t *g, uint32_t now_ms); #endif /* GIMBAL_H */