#![allow(
clippy::approx_constant,
clippy::useless_vec,
clippy::len_zero,
clippy::unnecessary_cast,
clippy::redundant_closure,
clippy::too_many_arguments,
clippy::type_complexity,
clippy::needless_borrow,
clippy::enum_variant_names,
clippy::upper_case_acronyms,
clippy::inconsistent_digit_grouping,
clippy::unit_cmp,
clippy::assertions_on_constants,
clippy::iter_on_single_items,
clippy::expect_fun_call,
clippy::redundant_pattern_matching,
variant_size_differences,
clippy::absurd_extreme_comparisons,
clippy::nonminimal_bool,
clippy::for_kv_map,
clippy::needless_range_loop,
clippy::single_match,
clippy::collapsible_if,
clippy::needless_return,
clippy::redundant_clone,
clippy::map_entry,
clippy::match_single_binding,
clippy::bool_comparison,
clippy::derivable_impls,
clippy::manual_range_contains,
clippy::needless_borrows_for_generic_args,
clippy::manual_map,
clippy::vec_init_then_push,
clippy::identity_op,
clippy::manual_flatten,
clippy::single_char_pattern,
clippy::search_is_some,
clippy::option_map_unit_fn,
clippy::while_let_on_iterator,
clippy::clone_on_copy,
clippy::box_collection,
clippy::redundant_field_names,
clippy::ptr_arg,
clippy::large_enum_variant,
clippy::match_ref_pats,
clippy::needless_pass_by_value,
clippy::unused_unit,
clippy::let_and_return,
clippy::suspicious_else_formatting,
clippy::manual_strip,
clippy::match_like_matches_macro,
clippy::from_over_into,
clippy::wrong_self_convention,
clippy::inherent_to_string,
clippy::new_without_default,
clippy::unnecessary_wraps,
clippy::field_reassign_with_default,
clippy::manual_find,
clippy::unnecessary_lazy_evaluations,
clippy::should_implement_trait,
clippy::missing_safety_doc,
clippy::unusual_byte_groupings,
clippy::bool_assert_comparison,
clippy::zero_prefixed_literal,
clippy::await_holding_lock,
clippy::manual_saturating_arithmetic,
clippy::explicit_counter_loop,
clippy::needless_lifetimes,
clippy::single_component_path_imports,
clippy::uninlined_format_args,
clippy::iter_cloned_collect,
clippy::manual_str_repeat,
clippy::excessive_precision,
clippy::precedence,
clippy::unnecessary_literal_unwrap
)]
use oxicode::{decode_from_slice, encode_to_vec, Decode, Encode};
use proptest::prelude::*;
#[derive(Debug, PartialEq, Clone, Encode, Decode)]
struct LidarPoint {
x_m: f32,
y_m: f32,
z_m: f32,
intensity: u8,
ring: u16,
}
#[derive(Debug, PartialEq, Clone, Encode, Decode)]
struct LidarScan {
seq: u64,
stamp_ns: u64,
points: Vec<LidarPoint>,
}
#[derive(Debug, PartialEq, Clone, Encode, Decode)]
struct JointAngle {
joint_id: u8,
position_rad: f32,
velocity_rad_s: f32,
torque_nm: f32,
}
#[derive(Debug, PartialEq, Clone, Encode, Decode)]
struct GripperForce {
pad_id: u8,
normal_force_n: f32,
shear_force_n: f32,
contact_area_mm2: f32,
slip_detected: bool,
}
#[derive(Debug, PartialEq, Clone, Encode, Decode)]
struct ImuReading {
stamp_us: u64,
accel_x: f32,
accel_y: f32,
accel_z: f32,
gyro_x: f32,
gyro_y: f32,
gyro_z: f32,
}
#[derive(Debug, PartialEq, Clone, Encode, Decode)]
enum SlamCellState {
Free,
Occupied,
Unknown,
Probabilistic { probability: f32 },
}
#[derive(Debug, PartialEq, Clone, Encode, Decode)]
struct SlamMapCell {
col: u32,
row: u32,
state: SlamCellState,
last_update_ms: u64,
}
#[derive(Debug, PartialEq, Clone, Encode, Decode)]
struct PathWaypoint {
index: u32,
x_m: f32,
y_m: f32,
heading_rad: f32,
velocity_m_s: f32,
}
#[derive(Debug, PartialEq, Clone, Encode, Decode)]
struct ObstacleBbox {
confidence: f32,
cx_m: f32,
cy_m: f32,
cz_m: f32,
hx_m: f32,
hy_m: f32,
hz_m: f32,
label: String,
}
#[derive(Debug, PartialEq, Clone, Encode, Decode)]
struct MotorPidParams {
motor_id: u8,
kp: f32,
ki: f32,
kd: f32,
output_limit: f32,
}
#[derive(Debug, PartialEq, Clone, Encode, Decode)]
struct BatteryChargeCycle {
cycle_number: u32,
soc_start: f32,
soc_end: f32,
duration_s: u32,
peak_current_a: f32,
avg_temp_c: f32,
}
#[derive(Debug, PartialEq, Clone, Encode, Decode)]
struct CollisionDistance {
sensor_id: u8,
distance_m: f32,
emergency: bool,
min_safe_m: f32,
}
#[derive(Debug, PartialEq, Clone, Encode, Decode)]
enum TerrainClass {
IndoorFlat,
OutdoorRough,
Gravel { grain_size_mm: f32 },
Grass { moisture_fraction: f32 },
Incline { slope_deg: f32 },
}
#[derive(Debug, PartialEq, Clone, Encode, Decode)]
enum TaskStatus {
Pending,
InProgress { progress: f32 },
Completed { elapsed_ms: u64 },
Failed { error_code: u16, message: String },
Cancelled,
}
#[derive(Debug, PartialEq, Clone, Encode, Decode)]
struct ManipulatorPose {
ee_x_m: f32,
ee_y_m: f32,
ee_z_m: f32,
qw: f32,
qx: f32,
qy: f32,
qz: f32,
joint_angles: Vec<f32>,
}
prop_compose! {
fn arb_lidar_point()(
x_m in -50.0f32..50.0f32,
y_m in -50.0f32..50.0f32,
z_m in -5.0f32..20.0f32,
intensity: u8,
ring in 0u16..128u16,
) -> LidarPoint {
LidarPoint { x_m, y_m, z_m, intensity, ring }
}
}
prop_compose! {
fn arb_joint_angle()(
joint_id in 0u8..12u8,
position_rad in (-3.15f32)..3.15f32,
velocity_rad_s in (-6.28f32)..6.28f32,
torque_nm in (-100.0f32)..100.0f32,
) -> JointAngle {
JointAngle { joint_id, position_rad, velocity_rad_s, torque_nm }
}
}
prop_compose! {
fn arb_waypoint()(
index in 0u32..1000u32,
x_m in -100.0f32..100.0f32,
y_m in -100.0f32..100.0f32,
heading_rad in (-3.15f32)..3.15f32,
velocity_m_s in 0.0f32..3.0f32,
) -> PathWaypoint {
PathWaypoint { index, x_m, y_m, heading_rad, velocity_m_s }
}
}
prop_compose! {
fn arb_slam_cell()(
col in 0u32..1024u32,
row in 0u32..1024u32,
state_kind in 0u8..4u8,
prob in 0.0f32..1.0f32,
last_update_ms: u64,
) -> SlamMapCell {
let state = match state_kind {
0 => SlamCellState::Free,
1 => SlamCellState::Occupied,
2 => SlamCellState::Unknown,
_ => SlamCellState::Probabilistic { probability: prob },
};
SlamMapCell { col, row, state, last_update_ms }
}
}
prop_compose! {
fn arb_collision_distance()(
sensor_id in 0u8..32u8,
distance_m in 0.01f32..10.0f32,
emergency: bool,
min_safe_m in 0.1f32..2.0f32,
) -> CollisionDistance {
CollisionDistance { sensor_id, distance_m, emergency, min_safe_m }
}
}
#[test]
fn test_lidar_point_roundtrip() {
proptest!(|(point in arb_lidar_point())| {
let enc = encode_to_vec(&point).expect("encode LidarPoint failed");
let (dec, consumed): (LidarPoint, usize) =
decode_from_slice(&enc).expect("decode LidarPoint failed");
prop_assert_eq!(&point, &dec, "LidarPoint roundtrip mismatch");
prop_assert_eq!(consumed, enc.len(), "consumed bytes must equal enc.len()");
});
}
#[test]
fn test_lidar_scan_roundtrip() {
proptest!(|(
seq: u64,
stamp_ns: u64,
points in prop::collection::vec(arb_lidar_point(), 0..16usize),
)| {
let val = LidarScan { seq, stamp_ns, points };
let enc = encode_to_vec(&val).expect("encode LidarScan failed");
let (dec, consumed): (LidarScan, usize) =
decode_from_slice(&enc).expect("decode LidarScan failed");
prop_assert_eq!(&val, &dec, "LidarScan roundtrip mismatch");
prop_assert_eq!(consumed, enc.len(), "consumed bytes must equal enc.len()");
});
}
#[test]
fn test_joint_angle_roundtrip() {
proptest!(|(angle in arb_joint_angle())| {
let enc = encode_to_vec(&angle).expect("encode JointAngle failed");
let (dec, consumed): (JointAngle, usize) =
decode_from_slice(&enc).expect("decode JointAngle failed");
prop_assert_eq!(&angle, &dec, "JointAngle roundtrip mismatch");
prop_assert_eq!(consumed, enc.len(), "consumed bytes must equal enc.len()");
});
}
#[test]
fn test_vec_joint_angle_roundtrip() {
proptest!(|(
joints in prop::collection::vec(arb_joint_angle(), 1..8usize),
)| {
let enc = encode_to_vec(&joints).expect("encode Vec<JointAngle> failed");
let (dec, consumed): (Vec<JointAngle>, usize) =
decode_from_slice(&enc).expect("decode Vec<JointAngle> failed");
prop_assert_eq!(&joints, &dec, "Vec<JointAngle> roundtrip mismatch");
prop_assert_eq!(consumed, enc.len(), "consumed bytes must equal enc.len()");
});
}
#[test]
fn test_gripper_force_roundtrip() {
proptest!(|(
pad_id in 0u8..8u8,
normal_force_n in 0.0f32..50.0f32,
shear_force_n in 0.0f32..20.0f32,
contact_area_mm2 in 0.0f32..400.0f32,
slip_detected: bool,
)| {
let val = GripperForce { pad_id, normal_force_n, shear_force_n, contact_area_mm2, slip_detected };
let enc = encode_to_vec(&val).expect("encode GripperForce failed");
let (dec, consumed): (GripperForce, usize) =
decode_from_slice(&enc).expect("decode GripperForce failed");
prop_assert_eq!(&val, &dec, "GripperForce roundtrip mismatch");
prop_assert_eq!(consumed, enc.len(), "consumed bytes must equal enc.len()");
});
}
#[test]
fn test_gripper_force_determinism() {
proptest!(|(
pad_id in 0u8..8u8,
normal_force_n in 0.0f32..50.0f32,
shear_force_n in 0.0f32..20.0f32,
contact_area_mm2 in 0.0f32..400.0f32,
slip_detected: bool,
)| {
let val = GripperForce { pad_id, normal_force_n, shear_force_n, contact_area_mm2, slip_detected };
let enc1 = encode_to_vec(&val).expect("first encode GripperForce failed");
let enc2 = encode_to_vec(&val).expect("second encode GripperForce failed");
prop_assert_eq!(enc1, enc2, "encoding must be deterministic");
});
}
#[test]
fn test_imu_reading_roundtrip() {
proptest!(|(
stamp_us: u64,
accel_x in (-20.0f32)..20.0f32,
accel_y in (-20.0f32)..20.0f32,
accel_z in (-20.0f32)..20.0f32,
gyro_x in (-35.0f32)..35.0f32,
gyro_y in (-35.0f32)..35.0f32,
gyro_z in (-35.0f32)..35.0f32,
)| {
let val = ImuReading { stamp_us, accel_x, accel_y, accel_z, gyro_x, gyro_y, gyro_z };
let enc = encode_to_vec(&val).expect("encode ImuReading failed");
let (dec, consumed): (ImuReading, usize) =
decode_from_slice(&enc).expect("decode ImuReading failed");
prop_assert_eq!(&val, &dec, "ImuReading roundtrip mismatch");
prop_assert_eq!(consumed, enc.len(), "consumed bytes must equal enc.len()");
});
}
#[test]
fn test_imu_reading_reencode_idempotent() {
proptest!(|(
stamp_us: u64,
accel_x in (-20.0f32)..20.0f32,
accel_y in (-20.0f32)..20.0f32,
accel_z in (-20.0f32)..20.0f32,
gyro_x in (-35.0f32)..35.0f32,
gyro_y in (-35.0f32)..35.0f32,
gyro_z in (-35.0f32)..35.0f32,
)| {
let val = ImuReading { stamp_us, accel_x, accel_y, accel_z, gyro_x, gyro_y, gyro_z };
let enc1 = encode_to_vec(&val).expect("first encode ImuReading failed");
let (decoded, _): (ImuReading, usize) =
decode_from_slice(&enc1).expect("decode ImuReading failed");
let enc2 = encode_to_vec(&decoded).expect("re-encode ImuReading failed");
prop_assert_eq!(enc1, enc2, "re-encoding must produce identical bytes");
});
}
#[test]
fn test_slam_map_cell_roundtrip() {
proptest!(|(cell in arb_slam_cell())| {
let enc = encode_to_vec(&cell).expect("encode SlamMapCell failed");
let (dec, consumed): (SlamMapCell, usize) =
decode_from_slice(&enc).expect("decode SlamMapCell failed");
prop_assert_eq!(&cell, &dec, "SlamMapCell roundtrip mismatch");
prop_assert_eq!(consumed, enc.len(), "consumed bytes must equal enc.len()");
});
}
#[test]
fn test_vec_slam_map_cell_roundtrip() {
proptest!(|(
cells in prop::collection::vec(arb_slam_cell(), 0..20usize),
)| {
let enc = encode_to_vec(&cells).expect("encode Vec<SlamMapCell> failed");
let (dec, consumed): (Vec<SlamMapCell>, usize) =
decode_from_slice(&enc).expect("decode Vec<SlamMapCell> failed");
prop_assert_eq!(&cells, &dec, "Vec<SlamMapCell> roundtrip mismatch");
prop_assert_eq!(consumed, enc.len(), "consumed bytes must equal enc.len()");
});
}
#[test]
fn test_path_waypoint_roundtrip() {
proptest!(|(wp in arb_waypoint())| {
let enc = encode_to_vec(&wp).expect("encode PathWaypoint failed");
let (dec, consumed): (PathWaypoint, usize) =
decode_from_slice(&enc).expect("decode PathWaypoint failed");
prop_assert_eq!(&wp, &dec, "PathWaypoint roundtrip mismatch");
prop_assert_eq!(consumed, enc.len(), "consumed bytes must equal enc.len()");
});
}
#[test]
fn test_vec_path_waypoint_roundtrip() {
proptest!(|(
waypoints in prop::collection::vec(arb_waypoint(), 2..16usize),
)| {
let enc = encode_to_vec(&waypoints).expect("encode Vec<PathWaypoint> failed");
let (dec, consumed): (Vec<PathWaypoint>, usize) =
decode_from_slice(&enc).expect("decode Vec<PathWaypoint> failed");
prop_assert_eq!(&waypoints, &dec, "Vec<PathWaypoint> roundtrip mismatch");
prop_assert_eq!(consumed, enc.len(), "consumed bytes must equal enc.len()");
});
}
#[test]
fn test_obstacle_bbox_roundtrip() {
proptest!(|(
confidence in 0.0f32..1.0f32,
cx_m in -30.0f32..30.0f32,
cy_m in -30.0f32..30.0f32,
cz_m in 0.0f32..5.0f32,
hx_m in 0.05f32..5.0f32,
hy_m in 0.05f32..5.0f32,
hz_m in 0.05f32..3.0f32,
label in "(person|vehicle|cone|wall|door|box)",
)| {
let val = ObstacleBbox { confidence, cx_m, cy_m, cz_m, hx_m, hy_m, hz_m, label };
let enc = encode_to_vec(&val).expect("encode ObstacleBbox failed");
let (dec, consumed): (ObstacleBbox, usize) =
decode_from_slice(&enc).expect("decode ObstacleBbox failed");
prop_assert_eq!(&val, &dec, "ObstacleBbox roundtrip mismatch");
prop_assert_eq!(consumed, enc.len(), "consumed bytes must equal enc.len()");
});
}
#[test]
fn test_motor_pid_params_roundtrip() {
proptest!(|(
motor_id in 0u8..16u8,
kp in 0.0f32..100.0f32,
ki in 0.0f32..50.0f32,
kd in 0.0f32..20.0f32,
output_limit in 0.1f32..1000.0f32,
)| {
let val = MotorPidParams { motor_id, kp, ki, kd, output_limit };
let enc = encode_to_vec(&val).expect("encode MotorPidParams failed");
let (dec, consumed): (MotorPidParams, usize) =
decode_from_slice(&enc).expect("decode MotorPidParams failed");
prop_assert_eq!(&val, &dec, "MotorPidParams roundtrip mismatch");
prop_assert_eq!(consumed, enc.len(), "consumed bytes must equal enc.len()");
});
}
#[test]
fn test_battery_charge_cycle_roundtrip() {
proptest!(|(
cycle_number in 0u32..50_000u32,
soc_start in 0.0f32..1.0f32,
soc_end in 0.0f32..1.0f32,
duration_s in 60u32..36_000u32,
peak_current_a in 0.0f32..200.0f32,
avg_temp_c in (-10.0f32)..60.0f32,
)| {
let val = BatteryChargeCycle {
cycle_number, soc_start, soc_end, duration_s, peak_current_a, avg_temp_c,
};
let enc = encode_to_vec(&val).expect("encode BatteryChargeCycle failed");
let (dec, consumed): (BatteryChargeCycle, usize) =
decode_from_slice(&enc).expect("decode BatteryChargeCycle failed");
prop_assert_eq!(&val, &dec, "BatteryChargeCycle roundtrip mismatch");
prop_assert_eq!(consumed, enc.len(), "consumed bytes must equal enc.len()");
});
}
#[test]
fn test_collision_distance_roundtrip() {
proptest!(|(dist in arb_collision_distance())| {
let enc = encode_to_vec(&dist).expect("encode CollisionDistance failed");
let (dec, consumed): (CollisionDistance, usize) =
decode_from_slice(&enc).expect("decode CollisionDistance failed");
prop_assert_eq!(&dist, &dec, "CollisionDistance roundtrip mismatch");
prop_assert_eq!(consumed, enc.len(), "consumed bytes must equal enc.len()");
});
}
#[test]
fn test_vec_collision_distance_roundtrip() {
proptest!(|(
sensors in prop::collection::vec(arb_collision_distance(), 1..12usize),
)| {
let enc = encode_to_vec(&sensors).expect("encode Vec<CollisionDistance> failed");
let (dec, consumed): (Vec<CollisionDistance>, usize) =
decode_from_slice(&enc).expect("decode Vec<CollisionDistance> failed");
prop_assert_eq!(&sensors, &dec, "Vec<CollisionDistance> roundtrip mismatch");
prop_assert_eq!(consumed, enc.len(), "consumed bytes must equal enc.len()");
});
}
#[test]
fn test_terrain_class_roundtrip() {
proptest!(|(
variant in 0u8..5u8,
grain_size_mm in 0.5f32..50.0f32,
moisture_fraction in 0.0f32..1.0f32,
slope_deg in 1.0f32..45.0f32,
)| {
let val = match variant {
0 => TerrainClass::IndoorFlat,
1 => TerrainClass::OutdoorRough,
2 => TerrainClass::Gravel { grain_size_mm },
3 => TerrainClass::Grass { moisture_fraction },
_ => TerrainClass::Incline { slope_deg },
};
let enc = encode_to_vec(&val).expect("encode TerrainClass failed");
let (dec, consumed): (TerrainClass, usize) =
decode_from_slice(&enc).expect("decode TerrainClass failed");
prop_assert_eq!(&val, &dec, "TerrainClass roundtrip mismatch");
prop_assert_eq!(consumed, enc.len(), "consumed bytes must equal enc.len()");
});
}
#[test]
fn test_task_status_roundtrip() {
proptest!(|(
variant in 0u8..5u8,
progress in 0.0f32..1.0f32,
elapsed_ms: u64,
error_code: u16,
message in "[a-z]{3,20}",
)| {
let val = match variant {
0 => TaskStatus::Pending,
1 => TaskStatus::InProgress { progress },
2 => TaskStatus::Completed { elapsed_ms },
3 => TaskStatus::Failed { error_code, message },
_ => TaskStatus::Cancelled,
};
let enc = encode_to_vec(&val).expect("encode TaskStatus failed");
let (dec, consumed): (TaskStatus, usize) =
decode_from_slice(&enc).expect("decode TaskStatus failed");
prop_assert_eq!(&val, &dec, "TaskStatus roundtrip mismatch");
prop_assert_eq!(consumed, enc.len(), "consumed bytes must equal enc.len()");
});
}
#[test]
fn test_manipulator_pose_roundtrip() {
proptest!(|(
ee_x_m in -2.0f32..2.0f32,
ee_y_m in -2.0f32..2.0f32,
ee_z_m in 0.0f32..2.5f32,
qw in (-1.0f32)..1.0f32,
qx in (-1.0f32)..1.0f32,
qy in (-1.0f32)..1.0f32,
qz in (-1.0f32)..1.0f32,
joint_angles in prop::collection::vec((-3.15f32)..3.15f32, 3..8usize),
)| {
let val = ManipulatorPose { ee_x_m, ee_y_m, ee_z_m, qw, qx, qy, qz, joint_angles };
let enc = encode_to_vec(&val).expect("encode ManipulatorPose failed");
let (dec, consumed): (ManipulatorPose, usize) =
decode_from_slice(&enc).expect("decode ManipulatorPose failed");
prop_assert_eq!(&val, &dec, "ManipulatorPose roundtrip mismatch");
prop_assert_eq!(consumed, enc.len(), "consumed bytes must equal enc.len()");
});
}
#[test]
fn test_manipulator_pose_determinism() {
proptest!(|(
ee_x_m in -2.0f32..2.0f32,
ee_y_m in -2.0f32..2.0f32,
ee_z_m in 0.0f32..2.5f32,
qw in (-1.0f32)..1.0f32,
qx in (-1.0f32)..1.0f32,
qy in (-1.0f32)..1.0f32,
qz in (-1.0f32)..1.0f32,
joint_angles in prop::collection::vec((-3.15f32)..3.15f32, 3..8usize),
)| {
let val = ManipulatorPose { ee_x_m, ee_y_m, ee_z_m, qw, qx, qy, qz, joint_angles };
let enc1 = encode_to_vec(&val).expect("first encode ManipulatorPose failed");
let enc2 = encode_to_vec(&val).expect("second encode ManipulatorPose failed");
prop_assert_eq!(enc1, enc2, "encoding must be deterministic");
});
}
#[test]
fn test_mixed_robotics_snapshot_consumed_bytes() {
proptest!(|(
stamp_us: u64,
accel_x in (-20.0f32)..20.0f32,
accel_y in (-20.0f32)..20.0f32,
accel_z in (-20.0f32)..20.0f32,
gyro_x in (-35.0f32)..35.0f32,
motor_id in 0u8..16u8,
kp in 0.0f32..100.0f32,
cycle_number in 0u32..50_000u32,
soc_start in 0.0f32..1.0f32,
)| {
let imu = ImuReading {
stamp_us, accel_x, accel_y, accel_z,
gyro_x, gyro_y: 0.0, gyro_z: 0.0,
};
let pid = MotorPidParams {
motor_id, kp, ki: 0.1, kd: 0.01, output_limit: 255.0,
};
let battery = BatteryChargeCycle {
cycle_number, soc_start, soc_end: 1.0,
duration_s: 3600, peak_current_a: 10.0, avg_temp_c: 25.0,
};
let status = TaskStatus::InProgress { progress: 0.5 };
let enc_imu = encode_to_vec(&imu).expect("encode imu snapshot failed");
let enc_pid = encode_to_vec(&pid).expect("encode pid snapshot failed");
let enc_bat = encode_to_vec(&battery).expect("encode battery snapshot failed");
let enc_status = encode_to_vec(&status).expect("encode status snapshot failed");
let (_, c_imu): (ImuReading, usize) =
decode_from_slice(&enc_imu).expect("decode imu snapshot failed");
let (_, c_pid): (MotorPidParams, usize) =
decode_from_slice(&enc_pid).expect("decode pid snapshot failed");
let (_, c_bat): (BatteryChargeCycle, usize) =
decode_from_slice(&enc_bat).expect("decode battery snapshot failed");
let (_, c_status): (TaskStatus, usize) =
decode_from_slice(&enc_status).expect("decode status snapshot failed");
prop_assert_eq!(c_imu, enc_imu.len(), "imu consumed bytes mismatch");
prop_assert_eq!(c_pid, enc_pid.len(), "pid consumed bytes mismatch");
prop_assert_eq!(c_bat, enc_bat.len(), "battery consumed bytes mismatch");
prop_assert_eq!(c_status, enc_status.len(), "status consumed bytes mismatch");
});
}