decoder: signed layouts (two's complement, lengths 8 and 16)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DDwfd6Ki8UfG4hK6W5YpJz
This commit is contained in:
+13
-1
@@ -21,6 +21,8 @@ pub struct Layout {
|
||||
pub bit: u32,
|
||||
/// Length 16 only: true = `byte` is the most significant.
|
||||
pub big: bool,
|
||||
/// Lengths 8 and 16: two's complement (`"signed": true` in the can block).
|
||||
pub signed: bool,
|
||||
pub scale: f64,
|
||||
pub offset: f64,
|
||||
pub kind: Kind,
|
||||
@@ -48,7 +50,12 @@ impl Layout {
|
||||
Some(match self.kind {
|
||||
Kind::Bool => Value::Bool(raw != 0),
|
||||
Kind::Number => {
|
||||
let v = raw as f64 * self.scale + self.offset;
|
||||
let raw = match (self.signed, self.length) {
|
||||
(true, 8) => raw as u8 as i8 as f64,
|
||||
(true, 16) => raw as u16 as i16 as f64,
|
||||
_ => raw as f64,
|
||||
};
|
||||
let v = raw * self.scale + self.offset;
|
||||
// Three decimals: 0.4 × 98 should read 39.2, not 39.200000000000003.
|
||||
let v = (v * 1000.0).round() / 1000.0;
|
||||
serde_json::Number::from_f64(v).map(Value::Number).unwrap_or(Value::Null)
|
||||
@@ -97,6 +104,7 @@ pub fn load(registry: &str) -> Result<Vec<Layout>, String> {
|
||||
length,
|
||||
bit,
|
||||
big,
|
||||
signed: c["signed"].as_bool().unwrap_or(false),
|
||||
scale: c["scale"].as_f64().unwrap_or(1.0),
|
||||
offset: c["offset"].as_f64().unwrap_or(0.0),
|
||||
kind,
|
||||
@@ -136,6 +144,10 @@ mod tests {
|
||||
let pedal = &one(json!({"id": "0x210", "byte": 0, "length": 8, "scale": 0.4}), "number").unwrap()[0];
|
||||
assert_eq!(pedal.value(&[0xFA]), Some(json!(100.0)));
|
||||
assert_eq!(pedal.value(&[98]), Some(json!(39.2)));
|
||||
// Signed: 0C0's steering angle, 0.1° per count, little-endian two's complement.
|
||||
let steer = &one(json!({"id": "0x0C0", "byte": 0, "length": 16, "order": "little", "signed": true, "scale": 0.1}), "number").unwrap()[0];
|
||||
assert_eq!(steer.value(&[0x41, 0xED]), Some(json!(-479.9))); // 0xED41 = -4799
|
||||
assert_eq!(steer.value(&[0x69, 0x12]), Some(json!(471.3))); // 0x1269 = 4713
|
||||
let brake = &one(json!({"id": "0x231", "byte": 4, "bit": 1, "length": 1}), "boolean").unwrap()[0];
|
||||
assert_eq!(brake.value(&[0, 0, 0, 0, 0x02]), Some(json!(true)));
|
||||
assert_eq!(brake.value(&[0, 0, 0, 0, 0xFD]), Some(json!(false)));
|
||||
|
||||
Reference in New Issue
Block a user