From 1d7d9b8f93fd36a338e9089842f81f6f7791e53d Mon Sep 17 00:00:00 2001 From: Andrei Gherghescu <8067229+andrei-ng@users.noreply.github.com> Date: Thu, 14 Sep 2023 22:28:55 +0200 Subject: [PATCH] implemented decoding of sensor measurement for EsfMeas - fix unittest Signed-off-by: Andrei Gherghescu <8067229+andrei-ng@users.noreply.github.com> --- examples/adr-message-parsing/Cargo.toml | 16 ++ examples/adr-message-parsing/src/main.rs | 272 +++++++++++++++++++++++ examples/basic_cli/Cargo.toml | 2 +- examples/basic_cli/src/main.rs | 121 +++------- ublox/src/ubx_packets/packets.rs | 238 ++++++++++++++------ ublox/tests/parser_tests.rs | 5 +- 6 files changed, 487 insertions(+), 167 deletions(-) create mode 100644 examples/adr-message-parsing/Cargo.toml create mode 100644 examples/adr-message-parsing/src/main.rs diff --git a/examples/adr-message-parsing/Cargo.toml b/examples/adr-message-parsing/Cargo.toml new file mode 100644 index 0000000..5076348 --- /dev/null +++ b/examples/adr-message-parsing/Cargo.toml @@ -0,0 +1,16 @@ +[package] +authors = ["Lane Kolbly ", "Andrei Gherghescu "] +edition = "2021" +name = "example-basic-cli" +publish = false +version = "0.1.0" + +[dependencies] +chrono = "0.4.29" +clap = {version = "4.2.7", features = ["cargo"]} +serde_json = "1.0.105" +serialport = "4.2.2" +ublox = {path = "../../ublox"} + +[features] +alloc = ["ublox/alloc"] diff --git a/examples/adr-message-parsing/src/main.rs b/examples/adr-message-parsing/src/main.rs new file mode 100644 index 0000000..4cfbaf2 --- /dev/null +++ b/examples/adr-message-parsing/src/main.rs @@ -0,0 +1,272 @@ +use clap::{value_parser, Arg, Command}; +use serialport::{ + DataBits as SerialDataBits, FlowControl as SerialFlowControl, Parity as SerialParity, + StopBits as SerialStopBits, +}; +use std::time::Duration; +use ublox::*; + +fn main() { + let matches = Command::new("uBlox CLI example program") + .author(clap::crate_authors!()) + .about("Demonstrates usage of the Rust uBlox API") + .arg_required_else_help(true) + .arg( + Arg::new("port") + .value_name("port") + .short('p') + .long("port") + .required(true) + .help("Serial port to open"), + ) + .arg( + Arg::new("baud") + .value_name("baud") + .short('s') + .long("baud") + .required(false) + .value_parser(value_parser!(u32)) + .help("Baud rate of the port"), + ) + .arg( + Arg::new("stop-bits") + .long("stop-bits") + .help("Number of stop bits to use") + .required(false) + .value_parser(["1", "2"]) + .default_value("1"), + ) + .arg( + Arg::new("data-bits") + .long("data-bits") + .help("Number of data bits to use") + .required(false) + .value_parser(["5", "6", "7", "8"]) + .default_value("8"), + ) + .get_matches(); + + let port = matches + .get_one::("port") + .expect("Expected required 'port' cli argumnet"); + let baud = matches.get_one::("baud").cloned().unwrap_or(115200); + let stop_bits = match matches.get_one::("stop-bits").map(|s| s.as_str()) { + Some("2") => SerialStopBits::Two, + _ => SerialStopBits::One, + }; + let data_bits = match matches.get_one::("data-bits").map(|s| s.as_str()) { + Some("5") => SerialDataBits::Five, + Some("6") => SerialDataBits::Six, + Some("7") => SerialDataBits::Seven, + _ => SerialDataBits::Eight, + }; + + let builder = serialport::new(port, baud) + .stop_bits(stop_bits) + .data_bits(data_bits) + .timeout(Duration::from_millis(1)) + .parity(SerialParity::None) + .flow_control(SerialFlowControl::None); + + println!("{:?}", &builder); + let port = builder.open().unwrap_or_else(|e| { + eprintln!("Failed to open \"{}\". Error: {}", port, e); + ::std::process::exit(1); + }); + let mut device = Device::new(port); + + // Configure the device to talk UBX + println!("Configuring UART1 port ..."); + device + .write_all( + &CfgPrtUartBuilder { + portid: UartPortId::Uart1, + reserved0: 0, + tx_ready: 0, + mode: UartMode::new(DataBits::Eight, Parity::None, StopBits::One), + baud_rate: baud, + in_proto_mask: InProtoMask::UBLOX, + out_proto_mask: OutProtoMask::union(OutProtoMask::NMEA, OutProtoMask::UBLOX), + flags: 0, + reserved5: 0, + } + .into_packet_bytes(), + ) + .expect("Could not configure UBX-CFG-PRT-UART"); + device + .wait_for_ack::() + .expect("Could not acknowledge UBX-CFG-PRT-UART msg"); + + device + .write_all( + &CfgMsgAllPortsBuilder::set_rate_for::([0, 0, 0, 0, 0, 0]).into_packet_bytes(), + ) + .expect("Could not configure ports for UBX-HNR-ATT"); + + device + .write_all( + &CfgMsgAllPortsBuilder::set_rate_for::([0, 0, 0, 0, 0, 0]).into_packet_bytes(), + ) + .expect("Could not configure ports for UBX-HNR-INS"); + + device + .write_all( + &CfgMsgAllPortsBuilder::set_rate_for::([0, 0, 0, 0, 0, 0]).into_packet_bytes(), + ) + .expect("Could not configure ports for UBX-HNR-PVT"); + + device + .write_all( + &CfgMsgAllPortsBuilder::set_rate_for::([0, 1, 0, 1, 0, 0]).into_packet_bytes(), + ) + .expect("Could not configure ports for UBX-ESF-INS"); + + device + .write_all( + &CfgMsgAllPortsBuilder::set_rate_for::([0, 1, 0, 1, 0, 0]).into_packet_bytes(), + ) + .expect("Could not configure ports for UBX-ESF-INS"); + + device + .write_all( + &CfgMsgAllPortsBuilder::set_rate_for::([0, 0, 0, 0, 0, 0]).into_packet_bytes(), + ) + .expect("Could not configure ports for UBX-NAV-PVT"); + + device + .write_all( + &CfgMsgAllPortsBuilder::set_rate_for::([0, 1, 0, 1, 0, 0]) + .into_packet_bytes(), + ) + .expect("Could not configure ports for UBX-ESF-STATUS"); + + device + .write_all( + &CfgMsgAllPortsBuilder::set_rate_for::([0, 1, 0, 1, 0, 0]).into_packet_bytes(), + ) + .expect("Could not configure ports for UBX-ESF-MEAS"); + + // Send a packet request for the MonVer packet + device + .write_all(&UbxPacketRequest::request_for::().into_packet_bytes()) + .expect("Unable to write request/poll for UBX-MON-VER message"); + + // Start reading data + println!("Opened uBlox device, waiting for messages..."); + loop { + device + .update(|packet| match packet { + PacketRef::MonVer(packet) => { + println!( + "SW version: {} HW version: {}; Extensions: {:?}", + packet.software_version(), + packet.hardware_version(), + packet.extension().collect::>() + ); + }, + PacketRef::EsfStatus(status) => { + println!( + "EsfStatus: tow: {}, version: {}, {:?},{:?}, fusion_mode: {:?}, num_sens: {}", + status.itow(), + status.version(), + status.init_status1(), + status.init_status2(), + status.fusion_mode(), + status.num_sens(), + ); + for s in status.data() { + println!("{:?}", s); + } + }, + + PacketRef::EsfMeas(msg) => { + println!("{:?}", msg); + println!("time_tag: {}", msg.time_tag()); + for s in msg.data() { + println!("{:?}", s); + println!("{:?}", s.value()); + } + println!("calib_tag: {:?}", msg.calib_tag()); + }, + + _ => { + println!("{:?}", packet); + }, + }) + .unwrap(); + } +} + +struct Device { + port: Box, + parser: Parser>, +} + +impl Device { + pub fn new(port: Box) -> Device { + let parser = Parser::default(); + Device { port, parser } + } + + pub fn write_all(&mut self, data: &[u8]) -> std::io::Result<()> { + self.port.write_all(data) + } + + pub fn update(&mut self, mut cb: T) -> std::io::Result<()> { + loop { + const MAX_PAYLOAD_LEN: usize = 1240; + let mut local_buf = [0; MAX_PAYLOAD_LEN]; + let nbytes = self.read_port(&mut local_buf)?; + if nbytes == 0 { + break; + } + + // parser.consume adds the buffer to its internal buffer, and + // returns an iterator-like object we can use to process the packets + let mut it = self.parser.consume(&local_buf[..nbytes]); + loop { + match it.next() { + Some(Ok(packet)) => { + cb(packet); + }, + Some(Err(_)) => { + // Received a malformed packet, ignore it + }, + None => { + // We've eaten all the packets we have + break; + }, + } + } + } + Ok(()) + } + + pub fn wait_for_ack(&mut self) -> std::io::Result<()> { + let mut found_packet = false; + while !found_packet { + self.update(|packet| { + if let PacketRef::AckAck(ack) = packet { + if ack.class() == T::CLASS && ack.msg_id() == T::ID { + found_packet = true; + } + } + })?; + } + Ok(()) + } + + /// Reads the serial port, converting timeouts into "no data received" + fn read_port(&mut self, output: &mut [u8]) -> std::io::Result { + match self.port.read(output) { + Ok(b) => Ok(b), + Err(e) => { + if e.kind() == std::io::ErrorKind::TimedOut { + Ok(0) + } else { + Err(e) + } + }, + } + } +} diff --git a/examples/basic_cli/Cargo.toml b/examples/basic_cli/Cargo.toml index 5076348..7081ab2 100644 --- a/examples/basic_cli/Cargo.toml +++ b/examples/basic_cli/Cargo.toml @@ -1,7 +1,7 @@ [package] authors = ["Lane Kolbly ", "Andrei Gherghescu "] edition = "2021" -name = "example-basic-cli" +name = "basic-cli" publish = false version = "0.1.0" diff --git a/examples/basic_cli/src/main.rs b/examples/basic_cli/src/main.rs index 55bc2ea..318880b 100644 --- a/examples/basic_cli/src/main.rs +++ b/examples/basic_cli/src/main.rs @@ -51,7 +51,7 @@ fn main() { let port = matches .get_one::("port") .expect("Expected required 'port' cli argumnet"); - let baud = matches.get_one::("baud").cloned().unwrap_or(115200); + let baud = matches.get_one::("baud").cloned().unwrap_or(9600); let stop_bits = match matches.get_one::("stop-bits").map(|s| s.as_str()) { Some("2") => SerialStopBits::Two, _ => SerialStopBits::One, @@ -99,54 +99,15 @@ fn main() { .wait_for_ack::() .expect("Could not acknowledge UBX-CFG-PRT-UART msg"); + // Enable the NavPvt packet device .write_all( - &CfgMsgAllPortsBuilder::set_rate_for::([0, 0, 0, 0, 0, 0]).into_packet_bytes(), - ) - .expect("Could not configure ports for UBX-HNR-ATT"); - - device - .write_all( - &CfgMsgAllPortsBuilder::set_rate_for::([0, 0, 0, 0, 0, 0]).into_packet_bytes(), - ) - .expect("Could not configure ports for UBX-HNR-INS"); - - device - .write_all( - &CfgMsgAllPortsBuilder::set_rate_for::([0, 0, 0, 0, 0, 0]).into_packet_bytes(), - ) - .expect("Could not configure ports for UBX-HNR-PVT"); - - device - .write_all( - &CfgMsgAllPortsBuilder::set_rate_for::([0, 1, 0, 1, 0, 0]).into_packet_bytes(), - ) - .expect("Could not configure ports for UBX-ESF-INS"); - - device - .write_all( - &CfgMsgAllPortsBuilder::set_rate_for::([0, 1, 0, 1, 0, 0]).into_packet_bytes(), - ) - .expect("Could not configure ports for UBX-ESF-INS"); - - device - .write_all( - &CfgMsgAllPortsBuilder::set_rate_for::([0, 0, 0, 0, 0, 0]).into_packet_bytes(), + &CfgMsgAllPortsBuilder::set_rate_for::([0, 1, 0, 0, 0, 0]).into_packet_bytes(), ) .expect("Could not configure ports for UBX-NAV-PVT"); - device - .write_all( - &CfgMsgAllPortsBuilder::set_rate_for::([0, 1, 0, 1, 0, 0]) - .into_packet_bytes(), - ) - .expect("Could not configure ports for UBX-ESF-STATUS"); - - device - .write_all( - &CfgMsgAllPortsBuilder::set_rate_for::([0, 1, 0, 1, 0, 0]).into_packet_bytes(), - ) - .expect("Could not configure ports for UBX-ESF-MEAS"); + .wait_for_ack::() + .expect("Could not acknowledge UBX-CFG-PRT-UART msg"); // Send a packet request for the MonVer packet device @@ -165,58 +126,36 @@ fn main() { packet.hardware_version(), packet.extension().collect::>() ); + println!("{:?}", packet); }, - // PacketRef::NavPvt(sol) => { - // let has_time = sol.fix_type() == GpsFix::Fix3D - // || sol.fix_type() == GpsFix::GPSPlusDeadReckoning - // || sol.fix_type() == GpsFix::TimeOnlyFix; - // let has_posvel = sol.fix_type() == GpsFix::Fix3D - // || sol.fix_type() == GpsFix::GPSPlusDeadReckoning; - - // if has_posvel { - // let pos: Position = (&sol).into(); - // let vel: Velocity = (&sol).into(); - // println!( - // "Latitude: {:.5} Longitude: {:.5} Altitude: {:.2}m", - // pos.lat, pos.lon, pos.alt - // ); - // println!( - // "Speed: {:.2} m/s Heading: {:.2} degrees", - // vel.speed, vel.heading - // ); - // println!("Sol: {:?}", sol); - // } - - // if has_time { - // let time: DateTime = (&sol) - // .try_into() - // .expect("Could not parse NAV-PVT time field to UTC"); - // println!("Time: {:?}", time); - // } - // }, - PacketRef::EsfStatus(status) => { - println!( - "EsfStatus: tow: {}, version: {}, {:?},{:?}, fusion_mode: {:?}, num_sens: {}", - status.itow(), - status.version(), - status.init_status1(), - status.init_status2(), - status.fusion_mode(), - status.num_sens(), - ); - for s in status.data() { - println!("{:?}", s); + PacketRef::NavPvt(sol) => { + let has_time = sol.fix_type() == GpsFix::Fix3D + || sol.fix_type() == GpsFix::GPSPlusDeadReckoning + || sol.fix_type() == GpsFix::TimeOnlyFix; + let has_posvel = sol.fix_type() == GpsFix::Fix3D + || sol.fix_type() == GpsFix::GPSPlusDeadReckoning; + + if has_posvel { + let pos: Position = (&sol).into(); + let vel: Velocity = (&sol).into(); + println!( + "Latitude: {:.5} Longitude: {:.5} Altitude: {:.2}m", + pos.lat, pos.lon, pos.alt + ); + println!( + "Speed: {:.2} m/s Heading: {:.2} degrees", + vel.speed, vel.heading + ); + println!("Sol: {:?}", sol); } - }, - PacketRef::EsfMeas(msg) => { - println!("time_tag: {}", msg.time_tag()); - for s in msg.data() { - println!("{:?}", s); + if has_time { + let time: DateTime = (&sol) + .try_into() + .expect("Could not parse NAV-PVT time field to UTC"); + println!("Time: {:?}", time); } - println!("calib_tag: {:?}", msg.calib_tag()); }, - _ => { println!("{:?}", packet); }, diff --git a/ublox/src/ubx_packets/packets.rs b/ublox/src/ubx_packets/packets.rs index dacec16..4bf5099 100644 --- a/ublox/src/ubx_packets/packets.rs +++ b/ublox/src/ubx_packets/packets.rs @@ -3061,6 +3061,7 @@ struct RxmRtcm { #[ubx(class = 0x10, id = 0x02, max_payload_len = 1240)] struct EsfMeas { time_tag: u32, + #[ubx(map_type = EsfMeasFlags, from = EsfMeasFlags)] flags: u16, id: u16, #[ubx( @@ -3087,11 +3088,11 @@ impl EsfMeas { impl<'a> EsfMeasRef<'a> { fn data_len(&self) -> usize { - ((self.flags() >> 11 & 0x1f) as usize) * 4 + self.flags().num_meas() as usize * 4 } fn calib_tag_len(&self) -> usize { - if self.flags() & 0x8 != 0 { + if self.flags().calib_tag_valid() { 4 } else { 0 @@ -3102,8 +3103,58 @@ impl<'a> EsfMeasRef<'a> { #[derive(Debug)] #[cfg_attr(feature = "serde", derive(serde::Serialize))] pub struct EsfMeasData { - pub data_type: u8, - pub data_field: u32, + pub data_type: EsfSensorType, + pub data_field: i32, +} + +#[derive(Debug)] +pub enum SensorData { + Tick(i32), + Value(f32), +} + +impl EsfMeasData { + pub fn direction(&self) -> i8 { + if self.data_field.is_negative() { + -1 + } else { + 1 + } + } + + pub fn value(&self) -> SensorData { + match self.data_type { + EsfSensorType::FrontLeftWheelTicks + | EsfSensorType::FrontRightWheelTicks + | EsfSensorType::RearLeftWheelTicks + | EsfSensorType::RearRightWheelTicks + | EsfSensorType::SpeedTick => { + let tick = (self.data_field & 0x7FFFFF) * (self.direction() as i32); + SensorData::Tick(tick) + }, + EsfSensorType::GyroX | EsfSensorType::GyroY | EsfSensorType::GyroZ => { + let value = (self.data_field & 0x7FFFFF) as f32 + * (self.direction() as f32) + * 2_f32.powi(-12); + SensorData::Value(value) + }, + EsfSensorType::AccX | EsfSensorType::AccY | EsfSensorType::AccZ => { + let value = (self.data_field & 0x7FFFFF) as f32 + * (self.direction() as f32) + * 2_f32.powf(-10.0); + SensorData::Value(value) + }, + EsfSensorType::GyroTemp => { + let value = (self.data_field & 0x7FFFFF) as f32 * (self.direction() as f32) * 1e-2; + SensorData::Value(value) + }, + EsfSensorType::Speed => { + let value = (self.data_field & 0x7FFFFF) as f32 * (self.direction() as f32) * 1e-3; + SensorData::Value(value) + }, + _ => SensorData::Value(0f32), + } + } } #[derive(Debug, Clone)] @@ -3124,13 +3175,55 @@ impl<'a> core::iter::Iterator for EsfMeasDataIter<'a> { fn next(&mut self) -> Option { let data = self.0.next()?.try_into().map(u32::from_le_bytes).unwrap(); + let mut data_field = (data & 0x7FFFFF) as i32; + let signed = ((data >> 23) & 0x01) == 1; + if signed { + data_field ^= 0x800000; + data_field = data_field.wrapping_neg(); + } + Some(EsfMeasData { - data_type: ((data & 0x3F000000) >> 24).try_into().unwrap(), - data_field: data & 0xFFFFFF, + data_type: (((data & 0x3F000000) >> 24) as u8).try_into().unwrap(), + data_field, }) } } +/// UBX-ESF-MEAS flags +#[repr(transparent)] +#[derive(Copy, Clone)] +#[cfg_attr(feature = "serde", derive(serde::Serialize))] +pub struct EsfMeasFlags(u16); + +impl EsfMeasFlags { + pub fn time_mark_sent(self) -> u8 { + ((self.0) & 0x2) as u8 + } + + pub fn time_mark_edge(self) -> bool { + (self.0 >> 2) & 0x01 != 0 + } + + pub fn calib_tag_valid(self) -> bool { + (self.0 >> 3) & 0x01 != 0 + } + + pub fn num_meas(self) -> u8 { + ((self.0 >> 11) & 0x1F) as u8 + } +} + +impl fmt::Debug for EsfMeasFlags { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("flags") + .field("timeMarkSent", &self.time_mark_sent()) + .field("timeMarkEdge", &self.time_mark_edge()) + .field("calibTagValid", &self.calib_tag_valid()) + .field("numMeas", &self.num_meas()) + .finish() + } +} + // UBX-ESF-MEAS message for Vehicle Speed #[ubx_packet_recv_send] #[ubx( @@ -3206,6 +3299,34 @@ pub enum EsfAlgStatus { FineAlignment = 4, } +#[ubx_packet_recv] +#[ubx(class = 0x10, id = 0x14, fixed_payload_len = 16)] +struct EsfAlg { + itow: u32, + /// Message version: 0x01 for M8L + version: u8, + + #[ubx(map_type = EsfAlgFlags, from = EsfAlgFlags)] + flags: u8, + + #[ubx(map_type = EsfAlgError)] + error: u8, + + reserved1: u8, + + /// IMU mount yaw angle [0, 360] + #[ubx(map_type = f64, scale = 1e-2, alias = yaw)] + yaw: u32, + + /// IMU mount pitch angle [-90, 90] + #[ubx(map_type = f64, scale = 1e-2, alias = pitch)] + pitch: i16, + + /// IMU mount roll angle [-90, 90] + #[ubx(map_type = f64, scale = 1e-2, alias = roll)] + roll: i16, +} + /// UBX-ESF-ALG flags #[repr(transparent)] #[derive(Copy, Clone)] @@ -3241,34 +3362,6 @@ impl fmt::Debug for EsfAlgFlags { } } -#[ubx_packet_recv] -#[ubx(class = 0x10, id = 0x14, fixed_payload_len = 16)] -struct EsfAlg { - itow: u32, - /// Message version: 0x01 for M8L - version: u8, - - #[ubx(map_type = EsfAlgFlags, from = EsfAlgFlags)] - flags: u8, - - #[ubx(map_type = EsfAlgError)] - error: u8, - - reserved1: u8, - - /// IMU mount yaw angle [0, 360] - #[ubx(map_type = f64, scale = 1e-2, alias = yaw)] - yaw: u32, - - /// IMU mount pitch angle [-90, 90] - #[ubx(map_type = f64, scale = 1e-2, alias = pitch)] - pitch: i16, - - /// IMU mount roll angle [-90, 90] - #[ubx(map_type = f64, scale = 1e-2, alias = roll)] - roll: i16, -} - #[ubx_extend_bitflags] #[ubx(from, rest_reserved)] bitflags! { @@ -3380,13 +3473,13 @@ impl EsfInitStatus1 { } } - pub fn mounting_angle_status(self) -> EsfStatusMountAngleStatus { + pub fn mounting_angle_status(self) -> EsfStatusMountAngle { let bits = (self.0 >> 2) & 0x07; match bits { - 0 => EsfStatusMountAngleStatus::Off, - 1 => EsfStatusMountAngleStatus::Initializing, - 2 => EsfStatusMountAngleStatus::Initialized, - 3 => EsfStatusMountAngleStatus::Initialized2, + 0 => EsfStatusMountAngle::Off, + 1 => EsfStatusMountAngle::Initializing, + 2 => EsfStatusMountAngle::Initialized, + 3 => EsfStatusMountAngle::Initialized, _ => { panic!("Unexpected 3-bit bitfield value {}!", bits); }, @@ -3426,11 +3519,10 @@ pub enum EsfStatusWheelTickInitStatus { #[derive(Copy, Clone, Debug)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -pub enum EsfStatusMountAngleStatus { +pub enum EsfStatusMountAngle { Off = 0, Initializing = 1, Initialized = 2, - Initialized2 = 3, } #[derive(Copy, Clone, Debug)] @@ -3516,16 +3608,16 @@ impl<'a> core::iter::Iterator for EsfStatusDataIter<'a> { #[derive(Copy, Clone, Debug)] #[cfg_attr(feature = "serde", derive(serde::Serialize))] pub struct EsfStatusSensor1 { - pub type_sensor: EsfSensorType, + pub sensor_type: EsfSensorType, pub used: bool, pub ready: bool, } impl From for EsfStatusSensor1 { fn from(s: u8) -> Self { - let type_sensor: EsfSensorType = (s & 0x3F).into(); + let sensor_type: EsfSensorType = (s & 0x3F).into(); Self { - type_sensor, + sensor_type, used: (s >> 6) != 0, ready: (s >> 7) != 0, } @@ -3549,29 +3641,29 @@ pub enum EsfSensorType { AccX = 16, AccY = 17, AccZ = 18, - Unknown = 1, + Unknown = 19, } impl From for EsfSensorType { fn from(orig: u8) -> Self { match orig { - 0 => return EsfSensorType::None, - 1 | 2 | 3 | 4 => return EsfSensorType::Unknown, - 5 => return EsfSensorType::GyroZ, - 6 => return EsfSensorType::FrontLeftWheelTicks, - 7 => return EsfSensorType::FrontRightWheelTicks, - 8 => return EsfSensorType::RearLeftWheelTicks, - 9 => return EsfSensorType::RearRightWheelTicks, - 10 => return EsfSensorType::SpeedTick, - 11 => return EsfSensorType::Speed, - 12 => return EsfSensorType::GyroTemp, - 13 => return EsfSensorType::GyroY, - 14 => return EsfSensorType::GyroX, - 16 => return EsfSensorType::AccX, - 17 => return EsfSensorType::AccY, - 18 => return EsfSensorType::AccZ, - _ => return EsfSensorType::Unknown, - }; + 0 => EsfSensorType::None, + 1 | 2 | 3 | 4 | 15 => EsfSensorType::Unknown, + 5 => EsfSensorType::GyroZ, + 6 => EsfSensorType::FrontLeftWheelTicks, + 7 => EsfSensorType::FrontRightWheelTicks, + 8 => EsfSensorType::RearLeftWheelTicks, + 9 => EsfSensorType::RearRightWheelTicks, + 10 => EsfSensorType::SpeedTick, + 11 => EsfSensorType::Speed, + 12 => EsfSensorType::GyroTemp, + 13 => EsfSensorType::GyroY, + 14 => EsfSensorType::GyroX, + 16 => EsfSensorType::AccX, + 17 => EsfSensorType::AccY, + 18 => EsfSensorType::AccZ, + _ => EsfSensorType::Unknown, + } } } @@ -3604,11 +3696,11 @@ pub enum EsfStatusSensorCalibration { impl From for EsfStatusSensorCalibration { fn from(orig: u8) -> Self { match orig { - 0 => return EsfStatusSensorCalibration::NotCalibrated, - 1 => return EsfStatusSensorCalibration::Calibrating, - 2 => return EsfStatusSensorCalibration::Calibrated, - _ => return EsfStatusSensorCalibration::Calibrated, - }; + 0 => EsfStatusSensorCalibration::NotCalibrated, + 1 => EsfStatusSensorCalibration::Calibrating, + 2 => EsfStatusSensorCalibration::Calibrated, + _ => EsfStatusSensorCalibration::Calibrated, + } } } @@ -3624,12 +3716,12 @@ pub enum EsfStatusSensorTime { impl From for EsfStatusSensorTime { fn from(orig: u8) -> Self { match orig { - 0 => return EsfStatusSensorTime::NoData, - 1 => return EsfStatusSensorTime::OnReceptionFirstByte, - 2 => return EsfStatusSensorTime::OnEventInput, - 3 => return EsfStatusSensorTime::TimeTagFromData, - _ => return EsfStatusSensorTime::NoData, - }; + 0 => EsfStatusSensorTime::NoData, + 1 => EsfStatusSensorTime::OnReceptionFirstByte, + 2 => EsfStatusSensorTime::OnEventInput, + 3 => EsfStatusSensorTime::TimeTagFromData, + _ => EsfStatusSensorTime::NoData, + } } } diff --git a/ublox/tests/parser_tests.rs b/ublox/tests/parser_tests.rs index 08bb381..067cacd 100644 --- a/ublox/tests/parser_tests.rs +++ b/ublox/tests/parser_tests.rs @@ -210,6 +210,7 @@ fn test_esf_meas_serialize() { while let Some(pack) = it.next() { match pack { Ok(pack) => { + // Match full packet including class & msg id let expected = serde_json::json! { { "class": 16, @@ -219,7 +220,7 @@ fn test_esf_meas_serialize() { "id": 0, "data": [ { - "data_type": 11, + "data_type": "Speed", "data_field": 25677 } ], @@ -236,7 +237,7 @@ fn test_esf_meas_serialize() { "id": 0, "data": [ { - "data_type": 11, + "data_type": "Speed", "data_field": 25677 } ],