use std::collections::BTreeMap;
use async_trait::async_trait;
use rmpv::Value;
use super::{Bus, DriverResult, SampleStream};
#[derive(Debug, Clone, PartialEq)]
pub struct GimbalCandidate {
pub driver_id: String,
pub device_id: String,
pub label: String,
pub bus: Bus,
pub vid_pid: Option<(u16, u16)>,
pub metadata: BTreeMap<String, Value>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct GimbalCapabilities {
pub has_pitch: bool,
pub has_yaw: bool,
pub has_roll: bool,
pub pitch_min_deg: f32,
pub pitch_max_deg: f32,
pub yaw_min_deg: f32,
pub yaw_max_deg: f32,
pub roll_min_deg: f32,
pub roll_max_deg: f32,
pub max_rate_dps: Option<f32>,
pub supports_follow_mode: bool,
pub supports_lock_mode: bool,
}
#[derive(Debug, Clone, PartialEq)]
pub struct GimbalState {
pub timestamp_ns: i64,
pub pitch_deg: f32,
pub yaw_deg: f32,
pub roll_deg: f32,
pub pitch_rate_dps: f32,
pub yaw_rate_dps: f32,
pub roll_rate_dps: f32,
pub mode: String,
pub metadata: BTreeMap<String, Value>,
}
#[async_trait]
pub trait GimbalDriver: Send + Sync {
type Session: Send + Sync;
async fn discover(&self) -> DriverResult<Vec<GimbalCandidate>>;
async fn open(
&self,
candidate: &GimbalCandidate,
config: &BTreeMap<String, Value>,
) -> DriverResult<Self::Session>;
async fn close(&self, session: Self::Session) -> DriverResult<()>;
fn capabilities(&self, session: &Self::Session) -> GimbalCapabilities;
async fn command_attitude(
&self,
session: &Self::Session,
pitch_deg: f32,
yaw_deg: f32,
roll_deg: f32,
) -> DriverResult<()>;
async fn command_rate(
&self,
session: &Self::Session,
pitch_rate_dps: f32,
yaw_rate_dps: f32,
roll_rate_dps: f32,
) -> DriverResult<()>;
fn get_state(&self, session: &Self::Session) -> GimbalState;
async fn state_iterator(
&self,
session: &Self::Session,
) -> DriverResult<SampleStream<GimbalState>>;
}