# Sensor Driver Examples

This document provides practical examples for using the motion sensor driver library.

## Example 1: Basic Orientation Tracking

```moonbit
fn track_orientation() {
  let config = SensorConfig::default()
  let controller = MotionController::new(config)
  
  // Simulate sensor readings (typically from hardware)
  let accel = Vec3::new(0.0, 0.0, 9.81)  // Stationary, Z-up
  let gyro = Vec3::zero()                // No rotation
  let mag = Vec3::new(20.0, 0.0, 40.0)   // North-ish
  
  let state = controller.update(accel, gyro, mag, 0L, 0.01)
  
  let (roll, pitch, yaw) = controller.get_euler_degrees()
  println("Orientation - Roll: \{roll}°, Pitch: \{pitch}°, Yaw: \{yaw}°")
}
```

## Example 2: Gesture Detection System

```moonbit
fn gesture_recognition() {
  let controller = MotionController::new(SensorConfig::default())
  
  // Process sensor stream
  for i = 0; i < 100; i = i + 1 {
    let accel = get_accelerometer_reading()  // From hardware
    let gyro = get_gyroscope_reading()
    let mag = get_magnetometer_reading()
    
    controller.update(accel, gyro, mag, i.to_int64() * 10L, 0.01)
    
    match controller.detect_gesture() {
      Shaking => trigger_shake_event()
      FreeFall => trigger_freefall_alert()
      Impact(force) => handle_impact(force)
      Rotating(speed) => handle_rotation(speed)
      Tilting(pitch, roll) => update_tilt_ui(pitch, roll)
      Stationary => ()
    }
  }
}
```

## Example 3: Calibration Procedure

```moonbit
fn calibrate_sensors() {
  let controller = MotionController::new(SensorConfig::default())
  
  println("Place device flat and keep still...")
  
  // Collect calibration samples
  for i = 0; i < 100; i = i + 1 {
    let accel = read_raw_accelerometer()
    let gyro = read_raw_gyroscope()
    let mag = read_raw_magnetometer()
    
    controller.add_calibration_sample(accel, gyro, mag)
    sleep_ms(10)
  }
  
  println("Calibrating...")
  controller.calibrate()
  println("Calibration complete!")
}
```

## Example 4: Compass with Tilt Compensation

```moonbit
fn tilt_compensated_compass() {
  let controller = MotionController::new(SensorConfig::default())
  
  // Update with current readings
  controller.update(
    read_accelerometer(),
    read_gyroscope(),
    read_magnetometer(),
    get_timestamp(),
    0.01,
  )
  
  // Get compass heading (automatically tilt-compensated)
  let heading = controller.get_heading_degrees()
  
  let direction = if heading < 22.5 || heading >= 337.5 {
    "North"
  } else if heading < 67.5 {
    "North-East"
  } else if heading < 112.5 {
    "East"
  } else if heading < 157.5 {
    "South-East"
  } else if heading < 202.5 {
    "South"
  } else if heading < 247.5 {
    "South-West"
  } else if heading < 292.5 {
    "West"
  } else {
    "North-West"
  }
  
  println("Heading: \{heading}° (\{direction})")
}
```

## Example 5: Motion Tracking for Gaming

```moonbit
fn game_controller() {
  let controller = MotionController::new(SensorConfig::default())
  let mut player_rotation = 0.0
  let mut player_position = Vec3::zero()
  
  // Game loop
  for frame = 0; frame < 1000; frame = frame + 1 {
    let accel = read_accelerometer()
    let gyro = read_gyroscope()
    let mag = read_magnetometer()
    
    let state = controller.update(accel, gyro, mag, frame.to_int64() * 16L, 0.016)
    
    // Update player rotation from gyroscope
    player_rotation += gyro.z * 0.016
    
    // Update player position from accelerometer
    let linear_accel = controller.accel.get_linear_acceleration(
      controller.accel.get_gravity()
    )
    player_position = player_position.add(linear_accel.scale(0.016 * 0.016))
    
    // Detect jump (free fall + impact)
    if controller.accel.is_freefall() {
      trigger_jump_animation()
    }
    
    match controller.accel.detect_impact() {
      Some(force) if force > 40.0 => trigger_landing_animation()
      _ => ()
    }
  }
}
```

## Example 6: Different Fusion Algorithms

### Complementary Filter (Fast)
```moonbit
fn use_complementary_filter() {
  let filter = ComplementaryFilter::new(0.02)
  
  let orientation = filter.update(accel, gyro, mag, 0.01)
  let (roll, pitch, yaw) = orientation.to_euler()
}
```

### Kalman Filter (Optimal)
```moonbit
fn use_kalman_filter() {
  let filter = KalmanFilter::new(
    process_noise=0.01,
    measurement_noise=0.1,
  )
  
  let orientation = filter.update(accel, gyro, mag, 0.01)
  let (roll, pitch, yaw) = orientation.to_euler()
}
```

### Madgwick Filter (High Performance)
```moonbit
fn use_madgwick_filter() {
  let filter = MadgwickFilter::new(beta=0.1)
  
  let orientation = filter.update(accel, gyro, mag, 0.01)
  let (roll, pitch, yaw) = orientation.to_euler()
}
```

## Example 7: Fall Detection for Safety

```moonbit
fn fall_detection_system() {
  let controller = MotionController::new(SensorConfig::default())
  let mut falling = false
  let mut fall_start_time = 0L
  
  // Monitor loop
  for i = 0; i < 1000; i = i + 1 {
    let timestamp = i.to_int64() * 10L
    let state = controller.update(
      read_accelerometer(),
      read_gyroscope(),
      read_magnetometer(),
      timestamp,
      0.01,
    )
    
    // Detect free fall
    if controller.accel.is_freefall() && not(falling) {
      falling = true
      fall_start_time = timestamp
      println("WARNING: Free fall detected!")
    }
    
    // Detect impact after fall
    if falling {
      match controller.accel.detect_impact() {
        Some(force) => {
          let fall_duration = timestamp - fall_start_time
          println("ALERT: Impact detected!")
          println("Fall duration: \{fall_duration}ms")
          println("Impact force: \{force} m/s²")
          
          // Trigger emergency alert
          send_emergency_alert(force, fall_duration)
          falling = false
        }
        None => ()
      }
    }
  }
}
```

## Example 8: Device Tilt UI Control

```moonbit
fn tilt_based_ui_control() {
  let controller = MotionController::new(SensorConfig::default())
  
  controller.update(
    read_accelerometer(),
    read_gyroscope(),
    read_magnetometer(),
    get_timestamp(),
    0.01,
  )
  
  let (pitch, roll) = controller.accel.get_tilt()
  
  // Convert to degrees
  let pitch_deg = pitch * 180.0 / @math.PI
  let roll_deg = roll * 180.0 / @math.PI
  
  // Map tilt to UI controls
  let vertical_input = if pitch_deg.abs() > 15.0 {
    if pitch_deg > 0.0 { 1.0 } else { -1.0 }
  } else {
    0.0
  }
  
  let horizontal_input = if roll_deg.abs() > 15.0 {
    if roll_deg > 0.0 { 1.0 } else { -1.0 }
  } else {
    0.0
  }
  
  update_ui_controls(horizontal_input, vertical_input)
}
```

## Example 9: Step Counter

```moonbit
fn step_counter() {
  let controller = MotionController::new(SensorConfig::default())
  let mut steps = 0
  let mut last_peak_time = 0L
  let mut last_accel_mag = 9.81
  
  for i = 0; i < 10000; i = i + 1 {
    let timestamp = i.to_int64() * 10L
    
    controller.update(
      read_accelerometer(),
      read_gyroscope(),
      read_magnetometer(),
      timestamp,
      0.01,
    )
    
    let accel_mag = controller.state.acceleration.magnitude()
    
    // Detect step as acceleration peak
    if accel_mag > 11.0 && last_accel_mag < accel_mag &&
       timestamp - last_peak_time > 300L {
      steps += 1
      last_peak_time = timestamp
      println("Steps: \{steps}")
    }
    
    last_accel_mag = accel_mag
  }
}
```

## Example 10: Vehicle Motion Tracking

```moonbit
fn vehicle_tracking() {
  let controller = MotionController::new(SensorConfig::default())
  let mut velocity = Vec3::zero()
  let mut position = Vec3::zero()
  
  for i = 0; i < 1000; i = i + 1 {
    let dt = 0.01
    
    let state = controller.update(
      read_accelerometer(),
      read_gyroscope(),
      read_magnetometer(),
      i.to_int64() * 10L,
      dt,
    )
    
    // Remove gravity to get linear acceleration
    let gravity = controller.accel.get_gravity()
    let linear_accel = controller.accel.get_linear_acceleration(gravity)
    
    // Integrate acceleration to velocity
    velocity = velocity.add(linear_accel.scale(dt))
    
    // Integrate velocity to position
    position = position.add(velocity.scale(dt))
    
    // Get rotation info
    let (roll, pitch, yaw) = controller.get_euler_degrees()
    
    println("Position: (\{position.x}, \{position.y}, \{position.z})")
    println("Heading: \{yaw}°")
    
    // Detect hard braking or acceleration
    if linear_accel.x.abs() > 5.0 {
      println("WARNING: Sudden acceleration/braking!")
    }
  }
}
```

## Tips for Real Hardware Integration

1. **Calibration**: Always calibrate sensors before use
   - Accelerometer: Keep device flat and still
   - Gyroscope: Keep device completely still
   - Magnetometer: Rotate device in figure-8 pattern

2. **Sample Rate**: 100-200Hz recommended for smooth tracking

3. **Coordinate Systems**: Ensure your sensor data matches expected axes:
   - X: Forward/Backward
   - Y: Left/Right
   - Z: Up/Down (gravity on Z-axis when flat)

4. **Filter Selection**:
   - Complementary: Best for battery-powered devices
   - Kalman: Best for precision applications
   - Madgwick: Best for high-performance gaming/VR

5. **Noise Management**: Use low-pass filtering for noisy sensors

6. **Timestamp**: Use consistent high-resolution timestamps
