rewrite signal parser
parent
774b4758ec
commit
6c40a51809
|
@ -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",
|
||||
|
|
|
@ -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 = `
|
||||
|
|
|
@ -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;
|
||||
});
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue