Files
detections-semantic/_docs/02_plans/components/05_gimbal_driver/description.md
T
Oleksandr Bezdieniezhnykh 8e2ecf50fd Initial commit
Made-with: Cursor
2026-03-26 00:20:30 +02:00

3.9 KiB

GimbalDriver

1. High-Level Overview

Purpose: Implements the ViewLink serial protocol for controlling the ViewPro A40 gimbal. Sends pan/tilt/zoom commands via UART, reads gimbal feedback (current angles), provides PID-based path following, and handles communication integrity.

Architectural Pattern: Hardware adapter with command queue and PID controller.

Upstream dependencies: Config helper (UART port, baud rate, PID gains, mock mode), Types helper

Downstream consumers: ScanController

2. Internal Interfaces

Interface: GimbalDriver

Method Input Output Async Error Types
connect(port, baud) str, int bool No UARTError
disconnect() No
is_alive() bool No
set_angles(pan, tilt, zoom) float, float, float bool No GimbalCommandError
get_state() GimbalState No GimbalReadError
set_sweep_target(pan) float bool No GimbalCommandError
zoom_to_poi(pan, tilt, zoom) float, float, float bool No (blocks ~2s for zoom) GimbalCommandError, TimeoutError
follow_path(direction, pid_error) (dx,dy), float bool No GimbalCommandError
return_to_sweep() bool No GimbalCommandError

GimbalState:

pan: float — current pan angle (degrees)
tilt: float — current tilt angle (degrees)
zoom: float — current zoom level (1-40)
last_heartbeat: float — epoch timestamp of last valid response

5. Implementation Details

ViewLink Protocol:

  • Baud rate: 115200, 8N1
  • Command format: per ViewLink Serial Protocol V3.3.3 spec
  • Implementation note: read full spec during implementation to determine if native checksums exist. If yes, use them. If not, add CRC-16 wrapper.
  • Retry: up to 3 times on checksum failure with 10ms delay

PID Controller (for path following):

  • Dual-axis PID (pan, tilt independently)
  • Input: error = (path_center - frame_center) in pixels
  • Output: pan/tilt angular velocity commands
  • Gains: configurable via YAML, tuned per-camera
  • Anti-windup: integral clamping
  • Update rate: 10 Hz (100ms interval)

Mock Mode (development):

  • TCP socket client instead of UART
  • Connects to mock-gimbal service (Docker)
  • Same interface, simulated delays for zoom transition (1-2s)

Key Dependencies:

Library Version Purpose
pyserial UART communication
crcmod CRC-16 if needed (determined after reading ViewLink spec)
struct (stdlib) Binary packet packing/unpacking

Error Handling Strategy:

  • UART open failure → GimbalDriver.connect() returns false → gimbal_available=false
  • Command send failure → retry 3x → GimbalCommandError
  • No heartbeat for 4s → is_alive() returns false → ScanController sets gimbal_available=false

7. Caveats & Edge Cases

Known limitations:

  • Zoom transition takes 1-2s physical time (40x optical)
  • PID gains need tuning on real hardware (bench testing)
  • Gimbal has physical pan/tilt limits — commands beyond limits are clamped

Physical EMI mitigation (not software — documented here for reference):

  • Shielded UART cable, shortest run
  • Antenna ≥35cm from gimbal
  • Ferrite beads on cable near Jetson

8. Dependency Graph

Must be implemented after: Config helper, Types helper Can be implemented in parallel with: Tier1Detector, Tier2SpatialAnalyzer, VLMClient, OutputManager Blocks: ScanController (needs GimbalDriver for scan control)

9. Logging Strategy

Log Level When Example
ERROR UART open failed, 3x retry exhausted UART /dev/ttyTHS1 open failed: Permission denied
WARN Checksum failure (retrying), slow response Gimbal CRC failure, retry 2/3
INFO Connected, zoom complete, mode change Gimbal connected at /dev/ttyTHS1 115200. Zoom to 20x complete (1.4s)