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

9.6 KiB

Test Specification — GimbalDriver

Acceptance Criteria Traceability

AC ID Acceptance Criterion Test IDs Coverage
AC-16 Gimbal control sends pan/tilt/zoom commands to ViewPro A40 IT-01, IT-02, AT-01 Covered
AC-17 Gimbal command latency ≤500ms from decision to physical movement PT-01 Covered
AC-18 Zoom transitions: medium to high zoom within 2 seconds IT-05, PT-02, AT-02 Covered
AC-19 Path-following accuracy: footpath stays within center 50% of frame IT-06, AT-03 Covered
AC-20 Smooth gimbal transitions (no jerky movements) IT-07, PT-03 Covered

Integration Tests

IT-01: Connect to UART (Mock TCP Mode)

Summary: Verify GimbalDriver connects to mock-gimbal service via TCP socket in dev mode.

Traces to: AC-16

Input data:

  • Config: gimbal.mode=mock_tcp, mock_host=localhost, mock_port=9090
  • Mock gimbal TCP server running

Expected result:

  • connect() returns true
  • is_alive() returns true
  • get_state() returns GimbalState with valid initial values

Max execution time: 2s

Dependencies: Mock gimbal TCP server


Summary: Verify set_angles translates pan/tilt/zoom to a valid ViewLink serial packet.

Traces to: AC-16

Input data:

  • Mock server that captures raw bytes received
  • set_angles(pan=15.0, tilt=-30.0, zoom=20.0)

Expected result:

  • Byte packet matches ViewLink protocol format (header, payload, checksum)
  • Mock server acknowledges command
  • set_angles returns true

Max execution time: 500ms

Dependencies: Mock gimbal server with byte capture


IT-03: Connection Failure Returns False

Summary: Verify connect() returns false when UART/TCP port is unavailable.

Traces to: AC-16

Input data:

  • Config: mock_port=9091 (no server listening)

Expected result:

  • connect() returns false
  • is_alive() returns false
  • No crash or hang

Max execution time: 3s (with connection timeout)

Dependencies: None


IT-04: Heartbeat Timeout Marks Gimbal Dead

Summary: Verify is_alive() returns false after 4 seconds without a heartbeat response.

Traces to: AC-16

Input data:

  • Connected mock server that stops responding after initial connection
  • Config: gimbal_timeout_s=4

Expected result:

  • is_alive() returns true initially
  • After 4s without heartbeat → is_alive() returns false

Max execution time: 6s

Dependencies: Mock gimbal server with configurable response behavior


IT-05: zoom_to_poi Blocks Until Zoom Complete

Summary: Verify zoom_to_poi waits for zoom transition to complete before returning.

Traces to: AC-18

Input data:

  • Current zoom=1.0, target zoom=20.0
  • Mock server simulates 1.5s zoom transition

Expected result:

  • zoom_to_poi blocks for ~1.5s
  • Returns true after zoom completes
  • get_state().zoom ≈ 20.0

Max execution time: 3s

Dependencies: Mock gimbal server with simulated zoom delay


IT-06: follow_path PID Updates Direction

Summary: Verify follow_path computes PID output and sends angular velocity commands.

Traces to: AC-19

Input data:

  • direction=(0.7, 0.3)
  • pid_error=50.0 (pixels offset from center)
  • PID gains: P=0.5, I=0.01, D=0.1

Expected result:

  • Pan/tilt velocity commands sent to mock server
  • Command magnitude proportional to error
  • Returns true

Max execution time: 100ms

Dependencies: Mock gimbal server


IT-07: PID Anti-Windup Clamps Integral

Summary: Verify the PID integral term does not wind up during sustained error.

Traces to: AC-20

Input data:

  • 100 consecutive follow_path calls with constant pid_error=200.0
  • PID integral clamp configured

Expected result:

  • Integral term stabilizes at clamp value (does not grow unbounded)
  • Command output reaches a plateau, no overshoot oscillation

Max execution time: 500ms

Dependencies: Mock gimbal server


IT-08: Retry on Checksum Failure

Summary: Verify the driver retries up to 3 times when a checksum mismatch is detected.

Traces to: AC-16

Input data:

  • Mock server returns corrupted response (bad checksum) on first 2 attempts, valid on 3rd

Expected result:

  • set_angles retries 2 times, succeeds on 3rd
  • Returns true
  • If all 3 fail, raises GimbalCommandError

Max execution time: 500ms

Dependencies: Mock gimbal server with configurable corruption


IT-09: return_to_sweep Resets Zoom to Medium

Summary: Verify return_to_sweep zooms out to medium zoom level and resumes sweep angle.

Traces to: AC-16

Input data:

  • Current state: zoom=20.0, pan=15.0
  • Expected return: zoom=1.0 (medium)

Expected result:

  • Zoom command sent to return to medium zoom
  • Returns true after zoom transition completes

Max execution time: 3s

Dependencies: Mock gimbal server


Performance Tests

PT-01: Command-to-Acknowledgement Latency

Summary: Measure round-trip time from set_angles call to server acknowledgement.

Traces to: AC-17

Load scenario:

  • 100 sequential set_angles commands
  • Mock server with 10ms simulated processing
  • Duration: ~15s

Expected results:

Metric Target Failure Threshold
Latency (p50) ≤50ms >500ms
Latency (p95) ≤200ms >500ms
Latency (p99) ≤400ms >500ms

Resource limits:

  • CPU: ≤10%
  • Memory: ≤50MB

PT-02: Zoom Transition Duration

Summary: Measure time from zoom command to zoom-complete acknowledgement.

Traces to: AC-18

Load scenario:

  • 10 zoom transitions: alternating 1x→20x and 20x→1x
  • Mock server with realistic zoom delay (1-2s)
  • Duration: ~30s

Expected results:

Metric Target Failure Threshold
Transition time (p50) ≤1.5s >2.0s
Transition time (p95) ≤2.0s >2.5s

Resource limits:

  • CPU: ≤5%

PT-03: PID Follow Smoothness (Jerk Metric)

Summary: Measure gimbal command smoothness during path following by computing jerk (rate of acceleration change).

Traces to: AC-20

Load scenario:

  • 200 PID updates at 10Hz (20s follow)
  • Path with gentle curve (sinusoidal trajectory)
  • Mock server records all received angular velocity commands

Expected results:

Metric Target Failure Threshold
Max jerk (deg/s³) ≤50 >200
Mean jerk (deg/s³) ≤10 >50

Resource limits:

  • CPU: ≤15% (PID computation)

Security Tests

ST-01: UART Buffer Overflow Protection

Summary: Verify the driver handles oversized responses without buffer overflow.

Traces to: AC-16

Attack vector: Malformed or oversized serial response (EMI corruption, spoofing)

Test procedure:

  1. Mock server sends response exceeding max expected packet size (e.g., 10KB)
  2. Mock server sends response with invalid header bytes

Expected behavior: Driver discards oversized/malformed packets, logs warning, continues operation.

Pass criteria: No crash, no memory corruption; is_alive() still returns true after discarding bad packet.

Fail criteria: Buffer overflow, crash, or undefined behavior.


Acceptance Tests

AT-01: Pan/Tilt/Zoom Control End-to-End

Summary: Verify the full command cycle: set angles, read back state, verify match.

Traces to: AC-16

Preconditions:

  • GimbalDriver connected to mock server

Steps:

Step Action Expected Result
1 set_angles(pan=10, tilt=-20, zoom=5) Returns true
2 get_state() pan≈10, tilt≈-20, zoom≈5 (within tolerance)
3 set_angles(pan=-30, tilt=0, zoom=1) Returns true
4 get_state() pan≈-30, tilt≈0, zoom≈1

AT-02: Zoom Transition Timing Compliance

Summary: Verify zoom from medium to high completes within 2 seconds.

Traces to: AC-18

Preconditions:

  • GimbalDriver connected, current zoom=1.0

Steps:

Step Action Expected Result
1 Record timestamp T0
2 zoom_to_poi(pan=0, tilt=-10, zoom=20) Blocks until complete
3 Record timestamp T1 T1 - T0 ≤ 2.0s
4 get_state().zoom ≈ 20.0

AT-03: Path Following Keeps Error Within Bounds

Summary: Verify PID controller keeps path tracking error within center 50% of frame.

Traces to: AC-19

Preconditions:

  • Mock server simulates gimbal with realistic response dynamics
  • Trajectory: 20 waypoints along a curved path

Steps:

Step Action Expected Result
1 Start follow_path with trajectory PID commands issued
2 Simulate 100 PID cycles at 10Hz Commands recorded by mock
3 Compute simulated frame-center error Error < 50% of frame width for ≥90% of cycles

Test Data Management

Required test data:

Data Set Description Source Size
viewlink_packets Reference ViewLink protocol packets for validation Captured from spec / ArduPilot ~10 KB
pid_trajectories Sinusoidal and curved path trajectories for PID testing Generated ~5 KB
corrupted_responses Oversized and malformed serial response bytes Generated ~1 KB

Setup procedure:

  1. Start mock-gimbal TCP server on configured port
  2. Initialize GimbalDriver with mock_tcp config
  3. Call connect()

Teardown procedure:

  1. Call disconnect()
  2. Stop mock-gimbal server

Data isolation strategy: Each test uses its own GimbalDriver instance connected to a fresh mock server. No shared state.