rewrite signal parser

main
Andy Haden 2018-09-24 18:53:05 -07:00
parent 774b4758ec
commit 6c40a51809
4 changed files with 97 additions and 61 deletions

View File

@ -30,7 +30,6 @@
"husky": "^0.14.3",
"int64-buffer": "^0.1.9",
"js-cookie": "^2.1.4",
"left-pad": "^1.1.3",
"lint-staged": "^6.0.0",
"localforage": "^1.7.1",
"moment": "^2.18.1",
@ -49,6 +48,7 @@
"react-test-renderer": "^16.2.0",
"react-vega": "^3.0.0",
"react-visibility-sensor": "^3.10.1",
"right-pad": "^1.0.1",
"simple-statistics": "^4.1.0",
"socket.io-client": "^2.0.3",
"stream-selector": "^0.1.1",

View File

@ -136,6 +136,15 @@ VAL_TABLE_ DI_state 4 "DI_STATE_ENABLE" 3 "DI_STATE_FAULT" 2 "DI_STATE_CLEAR_FAU
VAL_TABLE_ DI_speedUnits 1 "DI_SPEED_KPH" 0 "DI_SPEED_MPH" ;
`;
const DBC_WHEEL_SPEEDS = `
BO_ 464 WHEEL_SPEEDS: 8 VSA
SG_ WHEEL_SPEED_FL : 7|15@0+ (0.01,0) [0|250] "kph" EON
SG_ WHEEL_SPEED_FR : 8|15@0+ (0.01,0) [0|250] "kph" EON
SG_ WHEEL_SPEED_RL : 25|15@0+ (0.01,0) [0|250] "kph" EON
SG_ WHEEL_SPEED_RR : 42|15@0+ (0.01,0) [0|250] "kph" EON
SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON
`;
const steerTorqueSignal = new Signal({
name: "STEER_TORQUE",
startBit: 7,
@ -150,6 +159,20 @@ const steerTorqueSignal = new Signal({
unit: ""
});
// for debugging contents of a Bitarray
// let ba = Bitarray;
// let str = '';
// for (let i = 0; i < ba.bitLength(bitsSwapped); i++) {
// str += ba.extract(bitsSwapped, i, 1).toString();
// }
function dbcInt32SignalValue(dbc, signalSpec, hex) {
// expects hex string to represent 8 bytes, left-justified with zeroes if frame size is smaller
const buffer = Buffer.from(hex, "hex");
return dbc.valueForInt32Signal(signalSpec, buffer);
}
test("DBC parses steering control message", () => {
const dbcParsed = new DBC(DBC_MESSAGE_DEF);
const { signals } = dbcParsed.getMessageFrame(228);
@ -252,12 +275,11 @@ test("int32 parser produces correct value for steer torque signal", () => {
const dbc = new DBC(DBC_MESSAGE_DEF);
const hex = "e2d62a0bd0d3b5e5";
const buffer = Buffer.from(hex, "hex");
const bufferSwapped = Buffer.from(buffer).swap64();
const bitArr = Bitarray.fromBytes(buffer);
const bitsSwapped = Bitarray.fromBytes(bufferSwapped);
const value = dbc.valueForInt32Signal(steerTorqueSignal, bitArr, bitsSwapped);
const value = dbcInt32SignalValue(
dbc,
dbc.getMessageFrame(228).signals["STEER_TORQUE"],
hex
);
expect(value).toBe(-7466);
});
@ -271,30 +293,38 @@ test("int64 parser produces correct value for steer torque signal", () => {
expect(value).toBe(-7466);
});
// for debugging contents of a Bitarray
// let ba = Bitarray;
// let str = '';
// for (let i = 0; i < Bitarray.bitLength(bitsSwapped); i++) {
// str += Bitarray.extract(bitsSwapped, i, 1).toString();
// }
test("int32 parser produces correct value for wheel speeds", () => {
const dbc = new DBC(DBC_WHEEL_SPEEDS);
function dbcInt32SignalValue(dbc, signalSpec, hex, frameSizeBytes) {
// expects hex string to represent 8 bytes, left-padded with zeroes if frame size is smaller
const buffer = Buffer.from(hex, "hex");
const bufferSwapped = Buffer.from(buffer).swap64();
const bits = Bitarray.bitSlice(
Bitarray.fromBytes(buffer),
64 - frameSizeBytes * 8
);
const bitsSwapped = Bitarray.bitSlice(
Bitarray.fromBytes(bufferSwapped),
0,
frameSizeBytes * 8
const hex = "36806cd8d8f1b0b7";
const rearRight = dbcInt32SignalValue(
dbc,
dbc.getMessageFrame(464).signals["WHEEL_SPEED_RR"],
hex
);
expect(rearRight).toBe(69.23);
return dbc.valueForInt32Signal(signalSpec, bits, bitsSwapped);
}
const rearLeft = dbcInt32SignalValue(
dbc,
dbc.getMessageFrame(464).signals["WHEEL_SPEED_RL"],
hex
);
expect(rearLeft).toBe(69.42);
const frontLeft = dbcInt32SignalValue(
dbc,
dbc.getMessageFrame(464).signals["WHEEL_SPEED_FL"],
hex
);
expect(frontLeft).toBe(69.76);
const frontRight = dbcInt32SignalValue(
dbc,
dbc.getMessageFrame(464).signals["WHEEL_SPEED_FR"],
hex
);
expect(frontRight).toBe(69.66);
});
const DBC_BINARY_LE_SIGNAL = `
BO_ 768 NEW_MSG_1: 8 XXX
@ -368,7 +398,7 @@ test("int32 parser produces correct value for 4-bit little endian signal within
const frame = dbc.getMessageFrame(1265);
const signalSpec = frame.signals["CF_Clu_AliveCnt1"];
const hexData = "0000000020006620";
const hexData = "2000662000000000";
const value = dbcInt32SignalValue(dbc, signalSpec, hexData, frame.size);
expect(value).toEqual(2);
});
@ -388,7 +418,11 @@ test("int32 parser produces correct value for 2-byte signed little endian signal
const hexData = "000000fafe000700";
const value = dbcInt32SignalValue(dbc, signalSpec, hexData, frame.size);
expect(value).toEqual(-26.200000000000003);
expect(value).toEqual(0.0);
const hexData2 = "0b000907d8b30000";
const value2 = dbcInt32SignalValue(dbc, signalSpec, hexData2, frame.size);
expect(value2).toEqual(1.1);
});
const DBC_CHFFR_METRIC_COMMENT = `

View File

@ -1,5 +1,5 @@
import Bitarray from "../bitarray";
import leftPad from "left-pad";
import rightPad from "right-pad";
import CloudLog from "../../logging/CloudLog";
import Signal from "./signal";
import Frame from "./frame";
@ -573,24 +573,35 @@ export default class DBC {
return ival;
}
valueForInt32Signal(signalSpec, bits, bitsSwapped) {
let startBit, bitArr;
valueForInt32Signal(signalSpec, buf) {
var startBit;
if (signalSpec.isLittleEndian) {
bitArr = bitsSwapped;
startBit =
Bitarray.bitLength(bitArr) - signalSpec.startBit - signalSpec.size;
startBit = 64 - signalSpec.startBit - signalSpec.size;
} else {
bitArr = bits;
startBit = DbcUtils.bigEndianBitIndex(signalSpec.startBit);
}
let ival = Bitarray.extract(bitArr, startBit, signalSpec.size);
var bitPos = (-signalSpec.startBit - 1) % 8;
if (bitPos < 0) {
bitPos += 8; // mimic python modulo behavior
}
if (signalSpec.isSigned && ival & Math.pow(2, signalSpec.size - 1)) {
ival -= Math.pow(2, signalSpec.size);
startBit = Math.floor(signalSpec.startBit / 8) * 8 + bitPos;
}
ival = ival * signalSpec.factor + signalSpec.offset;
return ival;
var shiftAmount, signalValue;
let byteOffset = Math.min(4, Math.floor(signalSpec.startBit / 8));
if (signalSpec.isLittleEndian) {
signalValue = buf.readUInt32LE(byteOffset);
shiftAmount = signalSpec.startBit - 8 * byteOffset;
} else {
signalValue = buf.readUInt32BE(byteOffset);
shiftAmount = 32 - (startBit - 8 * byteOffset + signalSpec.size);
}
signalValue = (signalValue >>> shiftAmount) & ((1 << signalSpec.size) - 1);
if (signalSpec.isSigned && signalValue >>> (signalSpec.size - 1)) {
signalValue -= 1 << signalSpec.size;
}
return signalValue * signalSpec.factor + signalSpec.offset;
}
getSignalValues(messageId, data) {
@ -601,21 +612,12 @@ export default class DBC {
let buffer = Buffer.from(data);
let paddedBuffer = buffer;
if (buffer.length % 8 !== 0) {
if (buffer.length !== 8) {
// pad data it's 64 bits long
const paddedDataHex = leftPad(buffer.toString("hex"), 16, "0");
const paddedDataHex = rightPad(buffer.toString("hex"), 16, "0");
paddedBuffer = Buffer.from(paddedDataHex, "hex");
}
const hexData = paddedBuffer.toString("hex");
const bufferSwapped = Buffer.from(paddedBuffer).swap64();
const bits = Bitarray.fromBytes(data);
const bitsSwapped = Bitarray.bitSlice(
Bitarray.fromBytes(bufferSwapped),
0,
frame.size * 8
);
const signalValuesByName = {};
Object.values(frame.signals).forEach(signalSpec => {
@ -623,7 +625,7 @@ export default class DBC {
if (signalSpec.size > 32) {
value = this.valueForInt64Signal(signalSpec, hexData);
} else {
value = this.valueForInt32Signal(signalSpec, bits, bitsSwapped);
value = this.valueForInt32Signal(signalSpec, paddedBuffer);
}
signalValuesByName[signalSpec.name] = value;
});

View File

@ -5336,10 +5336,6 @@ lcid@^1.0.0:
dependencies:
invert-kv "^1.0.0"
left-pad@^1.1.3:
version "1.3.0"
resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.3.0.tgz#5b8a3a7765dfe001261dde915589e782f8c94d1e"
leven@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/leven/-/leven-2.1.0.tgz#c2e7a9f772094dee9d34202ae8acce4687875580"
@ -7678,6 +7674,10 @@ right-align@^0.1.1:
dependencies:
align-text "^0.1.1"
right-pad@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/right-pad/-/right-pad-1.0.1.tgz#8ca08c2cbb5b55e74dafa96bf7fd1a27d568c8d0"
rimraf@2, rimraf@^2.2.8, rimraf@^2.5.1, rimraf@^2.6.1:
version "2.6.2"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36"