use crate::data_messages::*;
use crate::receive_error::*;
use std::fmt;
use std::mem::size_of;
#[repr(C)]
#[derive(Clone, Copy)]
pub struct InertialMessage {
pub timestamp: u64,
pub gyroscope_x: f32,
pub gyroscope_y: f32,
pub gyroscope_z: f32,
pub accelerometer_x: f32,
pub accelerometer_y: f32,
pub accelerometer_z: f32,
}
impl Default for InertialMessage {
fn default() -> Self {
Self {
timestamp: 0,
gyroscope_x: 0.0,
gyroscope_y: 0.0,
gyroscope_z: 0.0,
accelerometer_x: 0.0,
accelerometer_y: 0.0,
accelerometer_z: 0.0,
}
}
}
impl DataMessage for InertialMessage {
fn get_ascii_id() -> u8 {
b'I'
}
fn parse_ascii(message: &str) -> Result<Self, ReceiveError> {
match scan_fmt!(message, "{},{d},{f},{f},{f},{f},{f},{f}\n", char, u64, f32, f32, f32, f32, f32, f32) {
Ok((_, timestamp, gyroscope_x, gyroscope_y, gyroscope_z, accelerometer_x, accelerometer_y, accelerometer_z)) => Ok(Self {
timestamp,
gyroscope_x,
gyroscope_y,
gyroscope_z,
accelerometer_x,
accelerometer_y,
accelerometer_z,
}),
Err(_) => Err(ReceiveError::UnableToParseAsciiMessage),
}
}
fn parse_binary(message: &[u8]) -> Result<Self, ReceiveError> {
#[repr(C, packed)]
struct BinaryMessage {
_id: u8,
timestamp: u64,
gyroscope_x: f32,
gyroscope_y: f32,
gyroscope_z: f32,
accelerometer_x: f32,
accelerometer_y: f32,
accelerometer_z: f32,
_termination: u8,
}
if message.len() != size_of::<BinaryMessage>() {
return Err(ReceiveError::InvalidBinaryMessageLength);
}
let binary_message = unsafe {
let ref binary_message = *(message.as_ptr() as *const BinaryMessage);
binary_message
};
Ok(Self {
timestamp: binary_message.timestamp,
gyroscope_x: binary_message.gyroscope_x,
gyroscope_y: binary_message.gyroscope_y,
gyroscope_z: binary_message.gyroscope_z,
accelerometer_x: binary_message.accelerometer_x,
accelerometer_y: binary_message.accelerometer_y,
accelerometer_z: binary_message.accelerometer_z,
})
}
fn get_csv_file_name(&self) -> &'static str {
"Inertial.csv"
}
fn get_csv_headings(&self) -> &'static str {
"Timestamp (us),Gyroscope X (deg/s),Gyroscope Y (deg/s),Gyroscope Z (deg/s),Accelerometer X (g),Accelerometer Y (g),Accelerometer Z (g)\n"
}
fn to_csv_row(&self) -> String {
format!("{},{:.6},{:.6},{:.6},{:.6},{:.6},{:.6}\n", self.timestamp, self.gyroscope_x, self.gyroscope_y, self.gyroscope_z, self.accelerometer_x, self.accelerometer_y, self.accelerometer_z)
}
}
impl fmt::Display for InertialMessage {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "{:>8} us {:>8.3} deg/s {:>8.3} deg/s {:>8.3} deg/s {:>8.3} g {:>8.3} g {:>8.3} g", self.timestamp, self.gyroscope_x, self.gyroscope_y, self.gyroscope_z, self.accelerometer_x, self.accelerometer_y, self.accelerometer_z)
}
}