diff --git a/Cargo.lock b/Cargo.lock index 27a7b8d..ff9e049 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -185,9 +185,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.21" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" +checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d" dependencies = [ "anstyle", "anstyle-parse", @@ -206,9 +206,9 @@ checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" [[package]] name = "anstyle-parse" -version = "0.2.7" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e" dependencies = [ "utf8parse", ] @@ -649,9 +649,9 @@ dependencies = [ [[package]] name = "can-dbc" -version = "8.1.0" +version = "9.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "912874d84099e530055bac10893f2d2b09c63bcf41c02e854e42ca42ec33ade1" +checksum = "981d5d67fc4c1d4822a3ff07095e69453099981d93eb4cd1d8ed9c5ec3549890" dependencies = [ "can-dbc-pest", "encoding_rs", @@ -672,9 +672,9 @@ dependencies = [ [[package]] name = "can_decode" -version = "0.6.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d1bd086644329fd52e9b85f8f054ecdbd21fbabbb087eec18c6bc46fbc59f7" +checksum = "ee15cd65fe9658282fe6fce2e567bee770dd622ab08a9aad2a49516f56d43c68" dependencies = [ "can-dbc", "indexmap", @@ -942,7 +942,7 @@ dependencies = [ "env_logger", "hashbrown 0.16.1", "log", - "rand 0.10.0", + "rand 0.10.1", "rfd", "serde", "serde_json", @@ -1286,9 +1286,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.11.9" +version = "0.11.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2daee4ea451f429a58296525ddf28b45a3b64f1acf6587e2067437bb11e218d" +checksum = "0621c04f2196ac3f488dd583365b9c09be011a4ab8b9f37248ffcc8f6198b56a" dependencies = [ "anstream", "anstyle", @@ -1746,6 +1746,12 @@ dependencies = [ "foldhash 0.2.0", ] +[[package]] +name = "hashbrown" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51" + [[package]] name = "heapless" version = "0.9.2" @@ -1928,12 +1934,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.13.0" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" dependencies = [ "equivalent", - "hashbrown 0.16.1", + "hashbrown 0.17.0", "serde", "serde_core", ] @@ -3025,9 +3031,9 @@ dependencies = [ [[package]] name = "rand" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc266eb313df6c5c09c1c7b1fbe2510961e5bcd3add930c1e31f7ed9da0feff8" +checksum = "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207" dependencies = [ "chacha20", "getrandom 0.4.2", diff --git a/Cargo.toml b/Cargo.toml index f9b817c..d89ad28 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,20 +11,20 @@ egui_extras = "0.33.3" rfd = "0.17.2" -can_decode = "0.6.1" -can-dbc = "8.1.0" +can_decode = "0.7.2" +can-dbc = "9.0.0" chrono = "0.4.44" hashbrown = "0.16.1" log = "0.4.29" -env_logger = "0.11.9" +env_logger = "0.11.10" slcan = { git = "https://github.com/LelsersLasers/slcan", features = ["sync"] } serialport = "4.8.1" -rand = "0.10.0" +rand = "0.10.1" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" diff --git a/src/can/driver.rs b/src/can/driver.rs index 422c72e..313c5ee 100644 --- a/src/can/driver.rs +++ b/src/can/driver.rs @@ -244,7 +244,7 @@ impl Driver for SimulatedDriver { Ok(vec![can_frame.into()]) } else { // If no DBC is loaded, just return random frames with random IDs and data - let id = rng.random_range(0..=util::msg_id::STANDARD_ID_MASK) as u16; + let id = rng.random_range(0..=util::can::STANDARD_ID_MASK) as u16; let sid = slcan::StandardId::new(id).expect("invalid standard id"); let mut data = [0u8; 8]; rng.fill_bytes(&mut data); diff --git a/src/can/thread.rs b/src/can/thread.rs index a534d9d..ddf52e7 100644 --- a/src/can/thread.rs +++ b/src/can/thread.rs @@ -8,8 +8,8 @@ const BUS_LOAD_UPDATE_MS: u128 = 200; fn process_can_frame(frame: slcan::CanFrame, state: &can::state::State) -> usize { match frame { slcan::CanFrame::Can2(frame2) => { - let decode_msg_id = util::msg_id::slcan_to_u32_with_extid_flag(&frame2.id()); - let raw_msg_id = util::msg_id::slcan_to_u32_without_extid_flag(&frame2.id()); + let decode_msg_id = util::can::slcan_to_u32_with_extid_flag(&frame2.id()); + let raw_msg_id = util::can::slcan_to_u32_without_extid_flag(&frame2.id()); let data = frame2.data().unwrap_or(&[]); @@ -44,7 +44,7 @@ fn process_can_frame(frame: slcan::CanFrame, state: &can::state::State) -> usize data.len() } slcan::CanFrame::CanFd(frame_fd) => { - let msg_id_raw = util::msg_id::slcan_to_u32_without_extid_flag(&frame_fd.id()); + let msg_id_raw = util::can::slcan_to_u32_without_extid_flag(&frame_fd.id()); log::warn!( "Received CAN FD frame id=0x{:X} len={}", msg_id_raw, @@ -103,9 +103,9 @@ pub fn start_can_thread( for msg in msgs_to_send { if let Some(ref mut active_driver) = state.driver { let id = if msg.is_msg_id_extended { - slcan::ExtendedId::new(msg.msg_id & util::msg_id::EXTENDED_ID_MASK) + slcan::ExtendedId::new(msg.msg_id & util::can::EXTENDED_ID_MASK) .map(slcan::Id::Extended) - } else if msg.msg_id <= util::msg_id::STANDARD_ID_MASK { + } else if msg.msg_id <= util::can::STANDARD_ID_MASK { slcan::StandardId::new(msg.msg_id as u16).map(slcan::Id::Standard) } else { log::warn!( diff --git a/src/daq_log_parse/correlate.rs b/src/daq_log_parse/correlate.rs index 0343d6f..2271d3c 100644 --- a/src/daq_log_parse/correlate.rs +++ b/src/daq_log_parse/correlate.rs @@ -55,11 +55,8 @@ impl CorrelationChunkResult { } } -pub fn sig_to_value(dsv: &can_decode::DecodedSignalValue) -> u64 { - match &dsv { - can_decode::DecodedSignalValue::Numeric(v) => v.round() as u64, - can_decode::DecodedSignalValue::Enum(v, _) => *v as u64, - } +pub fn physical_to_u64(dsv: &can_decode::DecodedSignalValue) -> u64 { + dsv.physical.round() as u64 } pub fn time_correlate_chunk(chunk: Vec) -> CorrelationChunkResult { @@ -77,37 +74,37 @@ pub fn time_correlate_chunk(chunk: Vec) -> CorrelationChunkResult .decoded .signals .get("millisecond") - .map(|sig| sig_to_value(&sig.value)); + .map(|sig| physical_to_u64(&sig.value)); let second = msg .decoded .signals .get("second") - .map(|sig| sig_to_value(&sig.value)); + .map(|sig| physical_to_u64(&sig.value)); let minute = msg .decoded .signals .get("minute") - .map(|sig| sig_to_value(&sig.value)); + .map(|sig| physical_to_u64(&sig.value)); let hour = msg .decoded .signals .get("hour") - .map(|sig| sig_to_value(&sig.value)); + .map(|sig| physical_to_u64(&sig.value)); let day = msg .decoded .signals .get("day") - .map(|sig| sig_to_value(&sig.value)); + .map(|sig| physical_to_u64(&sig.value)); let month = msg .decoded .signals .get("month") - .map(|sig| sig_to_value(&sig.value)); + .map(|sig| physical_to_u64(&sig.value)); let year = msg .decoded .signals .get("year") - .map(|sig| sig_to_value(&sig.value)); + .map(|sig| physical_to_u64(&sig.value)); if let (Some(ms), Some(s), Some(min), Some(h), Some(d), Some(mon), Some(y)) = (millisecond, second, minute, hour, day, month, year) diff --git a/src/daq_log_parse/parse.rs b/src/daq_log_parse/parse.rs index b9f1059..82dec24 100644 --- a/src/daq_log_parse/parse.rs +++ b/src/daq_log_parse/parse.rs @@ -83,9 +83,9 @@ fn parse_log_file( } let arb_id = if (frame.identity & consts::IS_EID_MASK) != 0 { - frame.identity & util::msg_id::EXTENDED_ID_MASK + frame.identity & util::can::EXTENDED_ID_MASK } else { - frame.identity & util::msg_id::STANDARD_ID_MASK + frame.identity & util::can::STANDARD_ID_MASK }; let bus_id = if (frame.identity & consts::BUS_ID_MASK) != 0 { diff --git a/src/daq_log_parse/table.rs b/src/daq_log_parse/table.rs index 6587e77..d9a665e 100644 --- a/src/daq_log_parse/table.rs +++ b/src/daq_log_parse/table.rs @@ -1,5 +1,4 @@ use crate::daq_log_parse::{consts, correlate}; -use can_decode::DecodedSignalValue; pub struct TableBuilder { bus_row: Vec, @@ -105,9 +104,10 @@ impl TableBuilder { if let Some(row) = csv_table.get_mut(row_idx as usize + 4) && let Some(cell) = row.get_mut(col_idx) { - *cell = match &sig_value.value { - DecodedSignalValue::Numeric(v) => v.to_string(), - DecodedSignalValue::Enum(_, label) => label.clone(), + *cell = if let Some(enum_label) = &sig_value.value.enum_label { + format!("{} ({})", enum_label, sig_value.value.int_rounded()) + } else { + sig_value.value.physical.to_string() }; } } diff --git a/src/ui/battery.rs b/src/ui/battery.rs index 29d6f6d..9a2605f 100644 --- a/src/ui/battery.rs +++ b/src/ui/battery.rs @@ -38,6 +38,7 @@ impl CellData { } } +#[derive(Default)] struct ChargingTelemetry { pack_voltage: f64, pack_current: f64, @@ -77,25 +78,16 @@ impl BatteryViewer { for (_, sig) in parsed.decoded.signals.iter() { match sig.name.as_str() { - "module_num" => { - if let can_decode::DecodedSignalValue::Numeric(v) = &sig.value { - module_num = Some(v.round() as usize); - } - } - "cell_num" => { - if let can_decode::DecodedSignalValue::Numeric(v) = &sig.value { - cell_num = Some(v.round() as usize); - } - } - "voltage" => { - if let can_decode::DecodedSignalValue::Numeric(v) = &sig.value { - voltage = Some(*v); - } - } + "module_num" => module_num = Some(sig.value.physical.round() as usize), + "cell_num" => cell_num = Some(sig.value.physical.round() as usize), + "voltage" => voltage = Some(sig.value.physical), "balance_status" => { - if let can_decode::DecodedSignalValue::Enum(v, _) = &sig.value { - balancing = Some(*v != 0); - } + balancing = Some( + sig.value + .raw + .map(|v| v != 0) + .unwrap_or(sig.value.physical > 0.5), + ) } _ => {} } @@ -117,52 +109,22 @@ impl BatteryViewer { for (_, sig) in parsed.decoded.signals.iter() { match sig.name.as_str() { "pack_voltage" => { - if let can_decode::DecodedSignalValue::Numeric(v) = &sig.value { - self.charging_telemetry - .get_or_insert(ChargingTelemetry { - pack_voltage: *v, - pack_current: 0.0, - min_cell_voltage: 0.0, - max_cell_voltage: 0.0, - }) - .pack_voltage = *v; - } + self.charging_telemetry.get_or_insert_default().pack_voltage = + sig.value.physical; } "pack_current" => { - if let can_decode::DecodedSignalValue::Numeric(v) = &sig.value { - self.charging_telemetry - .get_or_insert(ChargingTelemetry { - pack_voltage: 0.0, - pack_current: *v, - min_cell_voltage: 0.0, - max_cell_voltage: 0.0, - }) - .pack_current = *v; - } + self.charging_telemetry.get_or_insert_default().pack_current = + sig.value.physical; } "min_cell_voltage" => { - if let can_decode::DecodedSignalValue::Numeric(v) = &sig.value { - self.charging_telemetry - .get_or_insert(ChargingTelemetry { - pack_voltage: 0.0, - pack_current: 0.0, - min_cell_voltage: *v, - max_cell_voltage: 0.0, - }) - .min_cell_voltage = *v; - } + self.charging_telemetry + .get_or_insert_default() + .min_cell_voltage = sig.value.physical; } "max_cell_voltage" => { - if let can_decode::DecodedSignalValue::Numeric(v) = &sig.value { - self.charging_telemetry - .get_or_insert(ChargingTelemetry { - pack_voltage: 0.0, - pack_current: 0.0, - min_cell_voltage: 0.0, - max_cell_voltage: *v, - }) - .max_cell_voltage = *v; - } + self.charging_telemetry + .get_or_insert_default() + .max_cell_voltage = sig.value.physical; } _ => {} } diff --git a/src/ui/dbc_msg_picker.rs b/src/ui/dbc_msg_picker.rs index 5bd9cfe..d42ecb2 100644 --- a/src/ui/dbc_msg_picker.rs +++ b/src/ui/dbc_msg_picker.rs @@ -24,7 +24,7 @@ impl DbcMsgPickerState { .filter(|msg| { let id_str = format!( "0x{:03X}", - util::msg_id::can_dbc_to_u32_without_extid_flag(&msg.id) + util::can::can_dbc_to_u32_without_extid_flag(&msg.id) ); id_str.contains(&search_lower) || msg.name.to_lowercase().contains(&search_lower) @@ -76,7 +76,7 @@ impl DbcMsgPickerState { .button(format!( "{} (0x{:03X})", msg.name, - util::msg_id::can_dbc_to_u32_without_extid_flag(&msg.id) + util::can::can_dbc_to_u32_without_extid_flag(&msg.id) )) .clicked() { diff --git a/src/ui/dynamics.rs b/src/ui/dynamics.rs index 222930b..d17d57d 100644 --- a/src/ui/dynamics.rs +++ b/src/ui/dynamics.rs @@ -52,16 +52,8 @@ impl Dynamics { "IMU_acceleration" => { for (_, sig) in parsed.decoded.signals.iter() { match sig.name.as_str() { - "X_axis" => { - if let can_decode::DecodedSignalValue::Numeric(v) = &sig.value { - self.accel_x = *v as f32; - } - } - "Y_axis" => { - if let can_decode::DecodedSignalValue::Numeric(v) = &sig.value { - self.accel_y = *v as f32; - } - } + "X_axis" => self.accel_x = sig.value.physical as f32, + "Y_axis" => self.accel_y = sig.value.physical as f32, _ => {} } } @@ -70,13 +62,8 @@ impl Dynamics { } "IMU_angular_rate" => { for (_, sig) in parsed.decoded.signals.iter() { - match sig.name.as_str() { - "Z_axis" => { - if let can_decode::DecodedSignalValue::Numeric(v) = &sig.value { - self.yaw_rate_rads = v.to_radians() as f32; // DBC is in deg/s - } - } - _ => {} + if sig.name.as_str() == "Z_axis" { + self.yaw_rate_rads = sig.value.physical.to_radians() as f32 } } self.last_update = Instant::now(); @@ -85,9 +72,7 @@ impl Dynamics { "steering_angle" => { for (_, sig) in parsed.decoded.signals.iter() { if sig.name == "angle" { - if let can_decode::DecodedSignalValue::Numeric(v) = &sig.value { - self.steer_angle_rad = v.to_radians() as f32; - } + self.steer_angle_rad = sig.value.physical.to_radians() as f32; } } self.last_update = Instant::now(); diff --git a/src/ui/gg_plot.rs b/src/ui/gg_plot.rs index cb2a66c..3e24e54 100644 --- a/src/ui/gg_plot.rs +++ b/src/ui/gg_plot.rs @@ -78,16 +78,8 @@ impl GgPlot { let mut left_g = None; for (_, sig) in &parsed.decoded.signals { match sig.name.as_str() { - "X_axis" => { - if let can_decode::DecodedSignalValue::Numeric(v) = &sig.value { - forward_g = Some(*v as f32); - } - } - "Y_axis" => { - if let can_decode::DecodedSignalValue::Numeric(v) = &sig.value { - left_g = Some(*v as f32); - } - } + "X_axis" => forward_g = Some(sig.value.physical as f32), + "Y_axis" => left_g = Some(sig.value.physical as f32), _ => {} } } diff --git a/src/ui/jitter.rs b/src/ui/jitter.rs index 22e093e..ef02a8a 100644 --- a/src/ui/jitter.rs +++ b/src/ui/jitter.rs @@ -48,7 +48,7 @@ impl Jitter { fn selected_msg_id(&self) -> Option { self.selected_msg .as_ref() - .map(|m| util::msg_id::can_dbc_to_u32_without_extid_flag(&m.id)) + .map(|m| util::can::can_dbc_to_u32_without_extid_flag(&m.id)) } pub fn handle_can_message(&mut self, msg: &messages::MsgFromCan) { @@ -112,7 +112,7 @@ impl Jitter { egui::RichText::new(format!( "Selected Message: {} (0x{:03X})", selected_msg.name, - util::msg_id::can_dbc_to_u32_without_extid_flag(&selected_msg.id) + util::can::can_dbc_to_u32_without_extid_flag(&selected_msg.id) )) .strong() .size(16.0), diff --git a/src/ui/scope.rs b/src/ui/scope.rs index 292cd84..d02eb45 100644 --- a/src/ui/scope.rs +++ b/src/ui/scope.rs @@ -177,12 +177,7 @@ impl Scope { return; }; - let value = match signal.value { - can_decode::DecodedSignalValue::Numeric(f) => f, - can_decode::DecodedSignalValue::Enum(i, _) => i as f64, - }; - - self.add_point(parsed_msg.timestamp, value); + self.add_point(parsed_msg.timestamp, signal.value.physical); } } } diff --git a/src/ui/send.rs b/src/ui/send.rs index 542e5a7..75b4f64 100644 --- a/src/ui/send.rs +++ b/src/ui/send.rs @@ -152,7 +152,7 @@ impl SendUi { egui::RichText::new(format!( "Selected Message: {} (0x{:03X})", selected_msg.name, - util::msg_id::can_dbc_to_u32_without_extid_flag(&selected_msg.id) + util::can::can_dbc_to_u32_without_extid_flag(&selected_msg.id) )) .strong() .size(16.0), @@ -222,7 +222,7 @@ impl SendUi { if ui.button("Send Message").clicked() { let msg_id_with_ext_flag = - util::msg_id::can_dbc_to_u32_with_extid_flag(&selected_msg.id); + util::can::can_dbc_to_u32_with_extid_flag(&selected_msg.id); let encoded = encode_msg_from_signals( &parser.parser, msg_id_with_ext_flag, @@ -253,7 +253,7 @@ impl SendUi { }; let msg_id_u32 = - util::msg_id::can_dbc_to_u32_without_extid_flag(&selected_msg.id); + util::can::can_dbc_to_u32_without_extid_flag(&selected_msg.id); self.sending_messages.push(SendingMessage { amount: send_amount, @@ -496,13 +496,13 @@ fn encode_msg_from_signals( fn signal_range(sig: &can_dbc::Signal) -> (f64, f64) { let fallback = (-1000.0, 1000.0); - let mut min = sig.min; - let mut max = sig.max; + + let min = util::can::can_dbc_numeric_to_f64(&sig.min); + let max = util::can::can_dbc_numeric_to_f64(&sig.max); if !min.is_finite() || !max.is_finite() || min >= max { - min = fallback.0; - max = fallback.1; + fallback + } else { + (min, max) } - - (min, max) } diff --git a/src/ui/viewer_list.rs b/src/ui/viewer_list.rs index 66ebe66..7b2744f 100644 --- a/src/ui/viewer_list.rs +++ b/src/ui/viewer_list.rs @@ -77,16 +77,20 @@ impl ViewerList { row.col(|ui| { ui.label(sig_name.to_string()); }); - row.col(|ui| match signal.value { - can_decode::DecodedSignalValue::Numeric(f) => { - if signal.unit.is_empty() { - ui.label(format!("{:.2}", f)); - } else { - ui.label(format!("{:.2} {}", f, signal.unit)); - } - } - can_decode::DecodedSignalValue::Enum(raw_value, ref enum_str) => { - ui.label(format!("{} ({})", enum_str, raw_value)); + row.col(|ui| { + if let Some(ref enum_label) = signal.value.enum_label { + ui.label(format!( + "{} ({})", + enum_label, + signal.value.int_rounded() + )); + } else if signal.unit.is_empty() { + ui.label(format!("{:.2}", signal.value.physical)); + } else { + ui.label(format!( + "{:.2} {}", + signal.value.physical, signal.unit + )); } }); }); diff --git a/src/ui/viewer_table.rs b/src/ui/viewer_table.rs index b3ece93..952df36 100644 --- a/src/ui/viewer_table.rs +++ b/src/ui/viewer_table.rs @@ -104,18 +104,20 @@ impl ViewerTable { .decoded .signals .iter() - .map(|(sig_name, signal)| match signal.value { - can_decode::DecodedSignalValue::Numeric(f) => { - if signal.unit.is_empty() { - (sig_name.as_str(), format!("{:.2}", f)) - } else { - (sig_name.as_str(), format!("{:.2} {}", f, signal.unit)) - } + .map(|(sig_name, signal)| { + if let Some(ref enum_label) = signal.value.enum_label { + ( + sig_name.as_str(), + format!("{} ({})", enum_label, signal.value.int_rounded()), + ) + } else if signal.unit.is_empty() { + (sig_name.as_str(), format!("{:.2}", signal.value.physical)) + } else { + ( + sig_name.as_str(), + format!("{:.2} {}", signal.value.physical, signal.unit), + ) } - can_decode::DecodedSignalValue::Enum(raw_value, ref enum_str) => ( - sig_name.as_str(), - format!("{} ({})", enum_str.clone(), raw_value), - ), }) .collect(); let raw_bytes_str = msg diff --git a/src/util.rs b/src/util.rs index 34e2719..732f199 100644 --- a/src/util.rs +++ b/src/util.rs @@ -45,7 +45,7 @@ pub fn hsv_to_color32(h: f64, s: f64, v: f64) -> eframe::egui::Color32 { eframe::egui::Color32::from_rgb(r, g, b) } -pub mod msg_id { +pub mod can { const EXTENDED_ID_FLAG: u32 = 0x80000000; pub const STANDARD_ID_MASK: u32 = 0x7FF; pub const EXTENDED_ID_MASK: u32 = 0x1FFFFFFF; @@ -91,4 +91,13 @@ pub mod msg_id { slcan::Id::Extended(eid) => eid.as_raw() & EXTENDED_ID_MASK, } } + + // Converts all arms of a can_dbc::NumericValue to an f64. + pub fn can_dbc_numeric_to_f64(numeric: &can_dbc::NumericValue) -> f64 { + match numeric { + can_dbc::NumericValue::Uint(v) => *v as f64, + can_dbc::NumericValue::Int(v) => *v as f64, + can_dbc::NumericValue::Double(v) => *v, + } + } }