use vqm::Vector3f32;
use crate::gps::{GeographicCoordinate, GpsSolutionData};
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct GpsPositionMeters {
pub position: Vector3f32,
}
impl GpsPositionMeters {
pub const fn new() -> Self {
Self { position: Vector3f32 { x: 0.0, y: 0.0, z: 0.0 } }
}
}
impl Default for GpsPositionMeters {
fn default() -> Self {
Self::new()
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct GpsPositionLongLatAlt {
pub longitude_degrees_x1e7: i32,
pub latitude_degrees_x1e7: i32,
pub altitude_cm: i32,
}
impl GpsPositionLongLatAlt {
pub const fn new() -> Self {
Self { longitude_degrees_x1e7: 0, latitude_degrees_x1e7: 0, altitude_cm: 0 }
}
}
impl Default for GpsPositionLongLatAlt {
fn default() -> Self {
Self::new()
}
}
impl From<GpsPositionLongLatAlt> for GeographicCoordinate {
#[inline]
#[allow(clippy::cast_precision_loss)]
fn from(position: GpsPositionLongLatAlt) -> Self {
Self {
longitude_degrees: (position.longitude_degrees_x1e7 as f32) * 1e-7,
latitude_degrees: (position.latitude_degrees_x1e7 as f32) * 1e-7,
altitude_meters: (position.altitude_cm as f32) * 0.1,
}
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct GpsData {
pub position: GpsPositionLongLatAlt,
pub distance_to_home_meters: f32,
pub bearing_to_home_degrees: f32,
pub distance_flown_meters: f32,
pub time_of_week_ms: u32,
pub velocity_north_cmps: i16,
pub velocity_east_cmps: i16,
pub velocity_down_cmps: i16,
pub speed3d_cmps: i16,
pub ground_speed_cmps: i16,
pub heading_deci_degrees: i16,
pub dilution_of_precision_positional: i16,
pub satellite_count: u8,
pub fix: u8,
pub is_healthy: u8,
pub update: u8,
}
#[allow(unused)]
impl GpsData {
const FIX_HOME: u8 = 0x01;
const FIX: u8 = 0x02;
const FIX_EVER: u8 = 0x04;
pub const fn new() -> Self {
Self {
position: GpsPositionLongLatAlt::new(),
distance_to_home_meters: 0.0,
bearing_to_home_degrees: 0.0,
distance_flown_meters: 0.0,
time_of_week_ms: 0,
velocity_north_cmps: 0,
velocity_east_cmps: 0,
velocity_down_cmps: 0,
speed3d_cmps: 0,
ground_speed_cmps: 0,
heading_deci_degrees: 0,
dilution_of_precision_positional: 0,
satellite_count: 0,
fix: 0,
is_healthy: 0,
update: 0,
}
}
}
impl Default for GpsData {
fn default() -> Self {
Self::new()
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
#[cfg_attr(feature = "std", derive(derive_more::Display))]
#[cfg_attr(feature = "std", display("Gps{{yaw_rate: {yaw_heading_radians}}}"))]
pub struct GpsYawHeadingMessage {
pub yaw_heading_radians: f32,
pub delta_t: f32,
}
impl GpsYawHeadingMessage {
pub const fn new() -> Self {
Self { yaw_heading_radians: 0.0, delta_t: 0.1 }
}
}
impl Default for GpsYawHeadingMessage {
fn default() -> Self {
Self::new()
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
#[non_exhaustive]
pub enum GpsMessage {
Gps(GpsData),
GpsPositionMeters(GpsPositionMeters),
GpsSolution(GpsSolutionData),
}
#[cfg(test)]
mod tests {
use super::*;
fn _is_normal<T: Sized + Send + Sync + Unpin>() {}
fn is_full<T: Sized + Send + Sync + Unpin + Copy + Clone + Default + PartialEq>() {}
fn is_full_no_default<T: Sized + Send + Sync + Unpin + Copy + Clone + PartialEq>() {}
#[test]
fn normal_types() {
is_full::<GpsPositionMeters>();
is_full::<GpsPositionLongLatAlt>();
is_full::<GpsData>();
is_full::<GpsYawHeadingMessage>();
is_full_no_default::<GpsMessage>();
}
}