organization

This commit is contained in:
2023-09-13 16:27:46 -05:00
parent 23802f1572
commit dc1c0523d7
36 changed files with 5 additions and 5 deletions
+131
View File
@@ -0,0 +1,131 @@
const PacketParser = require('./decoders/packet');
const InfoPacket = require('./models/packets/info-packet');
const DataPacket = require('./models/packets/data-packet');
class Decoder {
lastInfoPacketHeader;
lastDataPacketHeader;
infoPacketFrames = {};
dataPacketFrames = {};
constructor() {
this.info = {
trackers: {},
};
this.data = {
trackers: {},
};
}
updateInfo(framePackets) {
framePackets.forEach((packet) => {
packet.subChunks?.forEach((subChunk) => {
if (subChunk.id === 0x0001) {
// NOTE(jwetzell): system name subChunk
this.info.system_name = subChunk.system_name;
} else if (subChunk.id === 0x0002) {
subChunk.trackers?.forEach((tracker) => {
if (this.info.trackers[tracker.id] === undefined) {
this.info.trackers[tracker.id] = {};
}
this.info.trackers[tracker.id].name = tracker.tracker_name.tracker_name;
});
}
});
});
}
updateData(framePackets) {
framePackets.forEach((packet) => {
packet.subChunks?.forEach((subChunk) => {
if (subChunk.id === 0x0001) {
subChunk.trackers?.forEach((tracker) => {
if (this.data.trackers[tracker.id] === undefined) {
this.data.trackers[tracker.id] = {};
}
this.data.trackers[tracker.id] = {
pos: tracker.pos,
speed: tracker.speed,
ori: tracker.ori,
status: tracker.status,
accel: tracker.accel,
trgtpos: tracker.trgtpos,
timestamp: tracker.timestamp,
};
});
}
});
});
}
// TODO(jwetzell): add invalid frame id decoding. Scenario where a frame id is reused before one is complete
decode(packetBuf) {
const packet = PacketParser.parse(packetBuf);
if (packet.id === 0x6756) {
const infoPacket = new InfoPacket(packet);
if (infoPacket) {
if (infoPacket.subChunks?.length > 0) {
const currentInfoPacketHeader = infoPacket.getHeaderPacket();
if (!currentInfoPacketHeader) {
// NOTE(jwetzell): not sure that info packets without a header subchunk are valid?
return;
}
const systemSubChunk = infoPacket.getSystemPacket();
if (!systemSubChunk) {
// NOTE(jwetzell): not sure that info packets without a system subchunk are valid?
return;
}
if (this.infoPacketFrames[currentInfoPacketHeader.frame_id] === undefined) {
this.infoPacketFrames[currentInfoPacketHeader.frame_id] = [];
}
this.infoPacketFrames[currentInfoPacketHeader.frame_id].push(infoPacket);
if (
this.infoPacketFrames[currentInfoPacketHeader.frame_id].length ===
currentInfoPacketHeader.frame_packet_count
) {
this.updateInfo(this.infoPacketFrames[currentInfoPacketHeader.frame_id]);
delete this.infoPacketFrames[currentInfoPacketHeader.frame_id];
}
this.lastInfoPacketHeader = currentInfoPacketHeader;
}
}
} else if (packet.id === 0x6755) {
const dataPacket = new DataPacket(packet);
if (dataPacket) {
if (dataPacket.subChunks?.length > 0) {
const currentDataPacketHeader = dataPacket.getHeaderPacket();
if (!currentDataPacketHeader) {
// NOTE(jwetzell): not sure that info packets without a header subchunk are valid?
return;
}
if (this.dataPacketFrames[currentDataPacketHeader.frame_id] === undefined) {
this.dataPacketFrames[currentDataPacketHeader.frame_id] = [];
}
this.dataPacketFrames[currentDataPacketHeader.frame_id].push(dataPacket);
if (
this.dataPacketFrames[currentDataPacketHeader.frame_id].length ===
currentDataPacketHeader.frame_packet_count
) {
this.updateData(this.dataPacketFrames[currentDataPacketHeader.frame_id]);
delete this.dataPacketFrames[currentDataPacketHeader.frame_id];
}
this.lastDataPacketHeader = currentDataPacketHeader;
}
}
}
}
}
module.exports = Decoder;
+20
View File
@@ -0,0 +1,20 @@
const { Parser } = require('binary-parser');
module.exports = new Parser()
.uint16le('id')
.uint16le('data_len', {
formatter: (item) => {
const binary = item.toString(2).padStart(16, '0');
return Number.parseInt(binary.substring(1), 2);
},
})
.seek(-2)
.uint16le('has_subchunks', {
formatter: (item) => {
const binary = item.toString(2).padStart(16, '0');
return binary.charAt(0) === '1';
},
})
.buffer('chunk_data', {
length: 'data_len',
});
@@ -0,0 +1,29 @@
const Parser = require('binary-parser').Parser;
module.exports = new Parser()
.uint16le('id')
.uint16le('data_len', {
formatter: (item) => {
const binary = item.toString(2).padStart(16, '0');
return Number.parseInt(binary.substring(1), 2);
},
})
.seek(-2)
.uint16le('has_subchunks', {
formatter: (item) => {
const binary = item.toString(2).padStart(16, '0');
return binary.charAt(0) === '1';
},
})
.choice('data', {
tag: 'id',
choices: {
0x0000: new Parser().floatle('x').floatle('y').floatle('z'),
0x0001: new Parser().floatle('x').floatle('y').floatle('z'),
0x0002: new Parser().floatle('x').floatle('y').floatle('z'),
0x0003: new Parser().floatle('validity'),
0x0004: new Parser().floatle('x').floatle('y').floatle('z'),
0x0005: new Parser().floatle('x').floatle('y').floatle('z'),
0x0006: new Parser().uint64le('tracker_timestamp'),
},
});
@@ -0,0 +1,22 @@
const Parser = require('binary-parser').Parser;
const dataTrackerParser = new Parser()
.uint16le('id')
.uint16le('data_len', {
formatter: (item) => {
const binary = item.toString(2).padStart(16, '0');
return Number.parseInt(binary.substring(1), 2);
},
})
.seek(-2)
.uint16le('has_subchunks', {
formatter: (item) => {
const binary = item.toString(2).padStart(16, '0');
return binary.charAt(0) === '1';
},
})
.buffer('data', {
length: 'data_len',
});
module.exports = new Parser().array('trackers', { type: dataTrackerParser, readUntil: 'eof' });
+7
View File
@@ -0,0 +1,7 @@
const TrackerListChunk = require('./data-tracker-list-chunk');
const TrackerFieldChunk = require('./data-tracker-field-chunk');
module.exports = {
TrackerFieldChunk,
TrackerListChunk,
};
+17
View File
@@ -0,0 +1,17 @@
const Chunk = require('./chunk');
const PacketHeaderChunk = require('./packet-header-chunk');
const Packet = require('./packet');
const Info = require('./info');
const Data = require('./data');
module.exports = {
Chunk,
PacketHeaderChunk,
Packet,
Info: {
...Info,
},
Data: {
...Data,
},
};
+7
View File
@@ -0,0 +1,7 @@
const SystemNameChunk = require('./info-system-name-chunk');
const TrackerListChunk = require('./info-tracker-list-chunk');
module.exports = {
SystemNameChunk,
TrackerListChunk,
};
@@ -0,0 +1,3 @@
const Parser = require('binary-parser').Parser;
module.exports = new Parser().string('system_name', { greedy: true });
@@ -0,0 +1,39 @@
const Parser = require('binary-parser').Parser;
const infoTrackerNameParser = new Parser()
.uint16le('id')
.uint16le('data_len', {
formatter: (item) => {
const binary = item.toString(2).padStart(16, '0');
return Number.parseInt(binary.substring(1), 2);
},
})
.seek(-2)
.uint16le('has_subchunks', {
formatter: (item) => {
const binary = item.toString(2).padStart(16, '0');
return binary.charAt(0) === '1';
},
})
.string('tracker_name', { length: 'data_len' });
const infoTrackerParser = new Parser()
.uint16le('id')
.uint16le('data_len', {
formatter: (item) => {
const binary = item.toString(2).padStart(16, '0');
return Number.parseInt(binary.substring(1), 2);
},
})
.seek(-2)
.uint16le('has_subchunks', {
formatter: (item) => {
const binary = item.toString(2).padStart(16, '0');
return binary.charAt(0) === '1';
},
})
.nest('tracker_name', {
type: infoTrackerNameParser,
});
module.exports = new Parser().array('trackers', { type: infoTrackerParser, readUntil: 'eof' });
+9
View File
@@ -0,0 +1,9 @@
const Parser = require('binary-parser').Parser;
module.exports = new Parser()
.uint64le('packet_timestamp')
.uint8('version_high')
.uint8('version_low')
.uint8('frame_id')
.uint8('frame_packet_count')
.seek(4);
+18
View File
@@ -0,0 +1,18 @@
const Parser = require('binary-parser').Parser;
module.exports = new Parser()
.uint16le('id')
.uint16le('data_len', {
formatter: (item) => {
const binary = item.toString(2).padStart(16, '0');
return Number.parseInt(binary.substring(1), 2);
},
})
.seek(-2)
.uint16le('has_subchunks', {
formatter: (item) => {
const binary = item.toString(2).padStart(16, '0');
return binary.charAt(0) === '1';
},
})
.buffer('chunk_data', { readUntil: 'eof' });
+95
View File
@@ -0,0 +1,95 @@
const dataChunk = require('./encoders/data/data-chunk');
const dataTrackerListChunk = require('./encoders/data/data-tracker-list-chunk');
const infoChunk = require('./encoders/info/info-chunk');
const infoSystemNameChunk = require('./encoders/info/info-system-name-chunk');
const infoTrackerListChunk = require('./encoders/info/info-tracker-list-chunk');
const packetHeaderChunk = require('./encoders/packet-header-chunk');
const MAX_TRACKER_LIST_SIZE = 1000;
class Encoder {
constructor(systemName, versionHigh, versionLow) {
this.systemName = systemName;
this.versionHigh = versionHigh;
this.versionLow = versionLow;
this.dataFrameId = 1;
this.infoFrameId = 1;
}
getInfoPackets(timestamp, trackers) {
const trackerChunks = trackers.map((tracker) => tracker.getInfoChunk());
const infoPackets = [];
const trackerChunksLists = [];
let currentTrackerList = [];
let currentTrackerListSize = 0;
trackerChunks.forEach((trackerChunk) => {
if (currentTrackerListSize + trackerChunk.length > MAX_TRACKER_LIST_SIZE) {
trackerChunksLists.push(currentTrackerList);
currentTrackerList = [];
currentTrackerListSize = 0;
}
currentTrackerList.push(trackerChunk);
currentTrackerListSize += trackerChunk.length;
});
trackerChunksLists.push(currentTrackerList);
const header = packetHeaderChunk(
timestamp,
this.versionHigh,
this.versionLow,
this.infoFrameId,
trackerChunksLists.length
);
trackerChunksLists.forEach((trackerChunkList) => {
infoPackets.push(infoChunk(header, infoSystemNameChunk(this.systemName), infoTrackerListChunk(trackerChunkList)));
});
this.dataFrameId += 1;
if (this.dataFrameId > 255) {
this.dataFrameId = 0;
}
return infoPackets;
}
getDataPackets(timestamp, trackers) {
const allTrackerChunks = trackers.map((tracker) => tracker.getDataChunk());
const dataPackets = [];
const trackerChunksLists = [];
let currentTrackerList = [];
let currentTrackerListSize = 0;
allTrackerChunks.forEach((trackerChunk) => {
if (currentTrackerListSize + trackerChunk.length > MAX_TRACKER_LIST_SIZE) {
trackerChunksLists.push(currentTrackerList);
currentTrackerList = [];
currentTrackerListSize = 0;
}
currentTrackerList.push(trackerChunk);
currentTrackerListSize += trackerChunk.length;
});
trackerChunksLists.push(currentTrackerList);
const header = packetHeaderChunk(
timestamp,
this.versionHigh,
this.versionLow,
this.dataFrameId,
trackerChunksLists.length
);
trackerChunksLists.forEach((trackerChunks) => {
dataPackets.push(dataChunk(header, dataTrackerListChunk(trackerChunks)));
});
this.dataFrameId += 1;
if (this.dataFrameId > 255) {
this.dataFrameId = 0;
}
return dataPackets;
}
}
module.exports = Encoder;
+13
View File
@@ -0,0 +1,13 @@
module.exports = (id, chunkData, hasSubchunks) => {
if (chunkData.length > 0x7fff) {
throw new Error('chunkData can not be greater than 32767 bytes');
}
const header = Buffer.alloc(4);
header.writeUInt16LE(id);
const chunkLengthBinaryString = chunkData.length.toString(2).padStart(15, '0');
const secondByteBinary = `${hasSubchunks ? '1' : '0'}${chunkLengthBinaryString}`;
header.writeUInt16LE(parseInt(secondByteBinary, 2), 2);
return Buffer.concat([header, chunkData]);
};
+4
View File
@@ -0,0 +1,4 @@
const chunk = require('../chunk');
module.exports = (packetHeaderChunk, trackerListChunk) =>
chunk(0x6755, Buffer.concat([packetHeaderChunk, trackerListChunk]), true);
@@ -0,0 +1,9 @@
const chunk = require('../chunk');
module.exports = (x, y, z) => {
const buf = Buffer.alloc(12);
buf.writeFloatLE(x);
buf.writeFloatLE(y, 4);
buf.writeFloatLE(z, 8);
return chunk(0x0004, buf, false);
};
+3
View File
@@ -0,0 +1,3 @@
const chunk = require('../chunk');
module.exports = (trackerId, fieldChunks) => chunk(trackerId, Buffer.concat(fieldChunks), true);
@@ -0,0 +1,3 @@
const chunk = require('../chunk');
module.exports = (trackerChunks) => chunk(0x0001, Buffer.concat(trackerChunks), true);
@@ -0,0 +1,9 @@
const chunk = require('../chunk');
module.exports = (x, y, z) => {
const buf = Buffer.alloc(12);
buf.writeFloatLE(x);
buf.writeFloatLE(y, 4);
buf.writeFloatLE(z, 8);
return chunk(0x0002, buf, false);
};
@@ -0,0 +1,9 @@
const chunk = require('../chunk');
module.exports = (x, y, z) => {
const buf = Buffer.alloc(12);
buf.writeFloatLE(x);
buf.writeFloatLE(y, 4);
buf.writeFloatLE(z, 8);
return chunk(0x0000, buf, false);
};
@@ -0,0 +1,9 @@
const chunk = require('../chunk');
module.exports = (x, y, z) => {
const buf = Buffer.alloc(12);
buf.writeFloatLE(x);
buf.writeFloatLE(y, 4);
buf.writeFloatLE(z, 8);
return chunk(0x0001, buf, false);
};
@@ -0,0 +1,7 @@
const chunk = require('../chunk');
module.exports = (validity) => {
const buf = Buffer.alloc(4);
buf.writeFloatLE(validity);
return chunk(0x0003, buf, false);
};
@@ -0,0 +1,10 @@
const chunk = require('../chunk');
module.exports = (timestamp) => {
const buf = Buffer.alloc(8);
const timestampHigh = timestamp.toString(2).padStart(64, '0').substring(0, 32);
const timestampLow = timestamp.toString(2).padStart(64, '0').substring(32);
buf.writeUInt32LE(parseInt(timestampLow, 2));
buf.writeUInt32LE(parseInt(timestampHigh, 2), 4);
return chunk(0x0006, buf, false);
};
@@ -0,0 +1,9 @@
const chunk = require('../chunk');
module.exports = (x, y, z) => {
const buf = Buffer.alloc(12);
buf.writeFloatLE(x);
buf.writeFloatLE(y, 4);
buf.writeFloatLE(z, 8);
return chunk(0x0005, buf, false);
};
+4
View File
@@ -0,0 +1,4 @@
const chunk = require('../chunk');
module.exports = (packetHeaderChunk, systemNameChunk, trackerListChunk) =>
chunk(0x6756, Buffer.concat([packetHeaderChunk, systemNameChunk, trackerListChunk]), true);
@@ -0,0 +1,3 @@
const chunk = require('../chunk');
module.exports = (systemName) => chunk(0x0001, Buffer.from(systemName), false);
+3
View File
@@ -0,0 +1,3 @@
const chunk = require('../chunk');
module.exports = (trackerId, trackerNameChunk) => chunk(trackerId, trackerNameChunk, true);
@@ -0,0 +1,3 @@
const chunk = require('../chunk');
module.exports = (trackerChunks) => chunk(0x0002, Buffer.concat(trackerChunks), true);
@@ -0,0 +1,3 @@
const chunk = require('../chunk');
module.exports = (trackerName) => chunk(0x0000, Buffer.from(trackerName), false);
+15
View File
@@ -0,0 +1,15 @@
const chunk = require('./chunk');
module.exports = (timestamp, versionHigh, versionLow, frameId, framePacketCount) => {
const packetHeader = Buffer.alloc(12);
const timestampHigh = timestamp.toString(2).padStart(64, '0').substring(0, 32);
const timestampLow = timestamp.toString(2).padStart(64, '0').substring(32);
packetHeader.writeUInt32LE(parseInt(timestampLow, 2));
packetHeader.writeUInt32LE(parseInt(timestampHigh, 2), 4);
packetHeader.writeUint8(versionHigh, 8);
packetHeader.writeUint8(versionLow, 9);
packetHeader.writeUint8(frameId, 10);
packetHeader.writeUint8(framePacketCount, 11);
return chunk(0x0000, packetHeader, false);
};
+58
View File
@@ -0,0 +1,58 @@
const dgram = require('dgram');
const Decoder = require('../../decoder');
const client = dgram.createSocket('udp4');
const decoder = new Decoder();
client.on('listening', () => {
client.addMembership('236.10.10.10');
});
client.on('message', (buffer) => {
decoder.decode(buffer);
});
client.bind(56565, '0.0.0.0');
setInterval(() => {
if (decoder.info.system_name) {
console.log(`System Name: ${decoder.info.system_name}`);
}
if (Object.keys(decoder.info.trackers).length > 0) {
console.log(`Tracker Count: ${Object.keys(decoder.info.trackers).length}`);
}
Object.entries(decoder.data.trackers).forEach(([trackerId, tracker]) => {
console.log(
`Tracker - id: ${trackerId} | name: ${
decoder.info.trackers[trackerId]?.name ? decoder.info.trackers[trackerId]?.name : ''
}`
);
if (tracker.pos_x !== undefined && tracker.pos_y !== undefined && tracker.pos_z !== undefined) {
console.log(`\tpos: ${tracker.pos_x}, ${tracker.pos_y}, ${tracker.pos_z}`);
}
if (tracker.speed_x !== undefined && tracker.speed_y !== undefined && tracker.speed_z !== undefined) {
console.log(`\tspeed: ${tracker.speed_x}, ${tracker.speed_y}, ${tracker.speed_z}`);
}
if (tracker.ori_x !== undefined && tracker.ori_y !== undefined && tracker.ori_z !== undefined) {
console.log(`\tori: ${tracker.ori_x}, ${tracker.ori_y}, ${tracker.ori_z}`);
}
if (tracker.validity !== undefined) {
console.log(`\tstatus: ${tracker.validity}`);
}
if (tracker.accel_x !== undefined && tracker.accel_y !== undefined && tracker.accel_z !== undefined) {
console.log(`\taccel: ${tracker.accel_x}, ${tracker.accel_y}, ${tracker.accel_z}`);
}
if (tracker.trgtpos_x !== undefined && tracker.trgtpos_y !== undefined && tracker.trgtpos_z !== undefined) {
console.log(`\ttrgtpos: ${tracker.trgtpos_x}, ${tracker.trgtpos_y}, ${tracker.trgtpos_z}`);
}
if (tracker.tracker_timestamp !== undefined) {
console.log(`\ttimestamp: ${tracker.tracker_timestamp}`);
}
});
}, 1000);
+55
View File
@@ -0,0 +1,55 @@
const dgram = require('dgram');
const Encoder = require('../../encoder');
const Tracker = require('../models/tracker');
const client = dgram.createSocket('udp4');
const encoder = new Encoder('Test PSN Server', 2, 0);
const trackers = [];
trackers.push(new Tracker(0, 'Sun'));
trackers.push(new Tracker(1, 'Mercury'));
trackers.push(new Tracker(2, 'Venus'));
trackers.push(new Tracker(3, 'Earth'));
trackers.push(new Tracker(4, 'Mars'));
trackers.push(new Tracker(5, 'Jupiter'));
trackers.push(new Tracker(6, 'Saturn'));
trackers.push(new Tracker(7, 'Uranus'));
trackers.push(new Tracker(8, 'Neptune'));
trackers.push(new Tracker(9, 'Pluto'));
const orbits = [1.0, 88.0, 224.7, 365.2, 687, 4332, 10760, 30700, 60200, 90600];
const distFromSun = [0, 0.58, 1.08, 1.5, 2.28, 7.78, 14.29, 28.71, 45.04, 59.13];
let timestamp = 0;
setInterval(() => {
for (let index = 0; index < trackers.length; index += 1) {
const a = 1.0 / orbits[index];
const b = distFromSun[index];
const x = timestamp;
const cb = Math.cos(a * x) * b;
const sb = Math.sin(a * x) * b;
trackers[index].setPos(sb, 0, cb);
trackers[index].setSpeed(a * cb, 0, -a * sb);
trackers[index].setOri(0, x / 1000.0, 0);
trackers[index].setAccel(-a * a * sb, 0, -a * a * cb);
trackers[index].setTrgtPos(3, 14, 16);
trackers[index].setStatus(index / 10.0);
trackers[index].setTimestamp(timestamp);
}
const dataPackets = encoder.getDataPackets(timestamp, trackers);
dataPackets.forEach((packet) => {
client.send(packet, 56565, '236.10.10.10');
});
timestamp += 1;
}, 20);
setInterval(() => {
const infoPackets = encoder.getInfoPackets(timestamp, trackers);
infoPackets.forEach((packet) => {
client.send(packet, 56565, '236.10.10.10');
});
}, 1000);
+93
View File
@@ -0,0 +1,93 @@
/* eslint-disable no-case-declarations */
/* eslint-disable no-param-reassign */
const { Parser } = require('binary-parser');
const Decoders = require('../../decoders');
class DataPacket {
constructor(packet) {
this.packet = packet;
this.subChunks = [];
// console.log(this.packet);
if (this.packet.has_subchunks) {
this.subChunkParser = new Parser().array('chunks', {
type: Decoders.Chunk,
lengthInBytes: this.packet.data_len,
});
this.subChunks = this.subChunkParser.parse(this.packet.chunk_data)?.chunks;
this.subChunks = this.subChunks.map((subChunk) => {
let populatedSubChunk = {};
populatedSubChunk.data_len_valid = subChunk.chunk_data.length === subChunk.data_len;
switch (subChunk.id) {
case 0:
populatedSubChunk = {
...subChunk,
...Decoders.PacketHeaderChunk.parse(subChunk.chunk_data),
};
break;
case 1:
const dataTrackerList = Decoders.Data.TrackerListChunk.parse(subChunk.chunk_data);
dataTrackerList.trackers?.forEach((tracker) => {
if (tracker.data && tracker.data_len > 0) {
const fields = new Parser()
.array('fields', {
type: Decoders.Data.TrackerFieldChunk,
lengthInBytes: tracker.data_len,
})
.parse(tracker.data);
if (fields.fields) {
fields.fields.forEach((field) => {
switch (field.id) {
case 0x0000:
tracker.pos = field.data;
break;
case 0x0001:
tracker.speed = field.data;
break;
case 0x0002:
tracker.ori = field.data;
break;
case 0x0003:
tracker.status = field.data;
break;
case 0x0004:
tracker.accel = field.data;
break;
case 0x0005:
tracker.trgtpos = field.data;
break;
case 0x0006:
tracker.timestamp = field.data;
break;
default:
break;
}
});
}
}
});
populatedSubChunk = {
...subChunk,
...dataTrackerList,
};
break;
default:
populatedSubChunk = {
...subChunk,
};
break;
}
return populatedSubChunk;
});
}
}
getHeaderPacket() {
return this.subChunks.find((subChunk) => subChunk.id === 0x0000);
}
getSystemPacket() {
return this.subChunks.find((subChunk) => subChunk.id === 0x0001);
}
}
module.exports = DataPacket;
+7
View File
@@ -0,0 +1,7 @@
const DataPacket = require('./data-packet');
const InfoPacket = require('./info-packet');
module.exports = {
DataPacket,
InfoPacket,
};
+56
View File
@@ -0,0 +1,56 @@
const { Parser } = require('binary-parser');
const Decoders = require('../../decoders');
class InfoPacket {
constructor(packet) {
this.packet = packet;
this.subChunks = [];
if (this.packet.has_subchunks) {
this.subChunkParser = new Parser().array('chunks', {
type: Decoders.Chunk,
lengthInBytes: this.packet.data_len,
});
this.subChunks = this.subChunkParser.parse(this.packet.chunk_data)?.chunks;
this.subChunks = this.subChunks.map((subChunk) => {
let populatedSubChunk = {};
populatedSubChunk.data_len_valid = subChunk.chunk_data.length === subChunk.data_len;
switch (subChunk.id) {
case 0:
populatedSubChunk = {
...subChunk,
...Decoders.PacketHeaderChunk.parse(subChunk.chunk_data),
};
break;
case 1:
populatedSubChunk = {
...subChunk,
...Decoders.Info.SystemNameChunk.parse(subChunk.chunk_data),
};
break;
case 2:
populatedSubChunk = {
...subChunk,
...Decoders.Info.TrackerListChunk.parse(subChunk.chunk_data),
};
break;
default:
populatedSubChunk = {
...subChunk,
};
break;
}
return populatedSubChunk;
});
}
}
getHeaderPacket() {
return this.subChunks.find((subChunk) => subChunk.id === 0x0000);
}
getSystemPacket() {
return this.subChunks.find((subChunk) => subChunk.id === 0x0001);
}
}
module.exports = InfoPacket;
+92
View File
@@ -0,0 +1,92 @@
const dataTrackerAccelChunk = require('../encoders/data/data-tracker-accel-chunk');
const dataTrackerChunk = require('../encoders/data/data-tracker-chunk');
const dataTrackerOriChunk = require('../encoders/data/data-tracker-ori-chunk');
const dataTrackerPosChunk = require('../encoders/data/data-tracker-pos-chunk');
const dataTrackerSpeedChunk = require('../encoders/data/data-tracker-speed-chunk');
const dataTrackerStatusChunk = require('../encoders/data/data-tracker-status-chunk');
const dataTrackerTimestampChunk = require('../encoders/data/data-tracker-timestamp-chunk');
const dataTrackerTrgtposChunk = require('../encoders/data/data-tracker-trgtpos-chunk');
const infoTrackerChunk = require('../encoders/info/info-tracker-chunk');
const infoTrackerNameChunk = require('../encoders/info/info-tracker-name-chunk');
class Tracker {
constructor(id, name) {
this.id = id;
this.name = name;
this.pos = undefined;
this.speed = undefined;
this.ori = undefined;
this.validity = undefined;
this.accel = undefined;
this.trgtpos = undefined;
this.timestamp = undefined;
}
setPos(x, y, z) {
this.pos = [x, y, z];
}
setSpeed(x, y, z) {
this.speed = [x, y, z];
}
setOri(x, y, z) {
this.ori = [x, y, z];
}
setStatus(validity) {
this.validity = validity;
}
setAccel(x, y, z) {
this.accel = [x, y, z];
}
setTrgtPos(x, y, z) {
this.trgtpos = [x, y, z];
}
setTimestamp(timestamp) {
this.timestamp = timestamp;
}
getDataChunk() {
const fieldChunks = [];
if (this.pos) {
fieldChunks.push(dataTrackerPosChunk(...this.pos));
}
if (this.speed) {
fieldChunks.push(dataTrackerSpeedChunk(...this.speed));
}
if (this.ori) {
fieldChunks.push(dataTrackerOriChunk(...this.ori));
}
if (this.validity) {
fieldChunks.push(dataTrackerStatusChunk(this.validity));
}
if (this.accel) {
fieldChunks.push(dataTrackerAccelChunk(...this.accel));
}
if (this.trgtpos) {
fieldChunks.push(dataTrackerTrgtposChunk(...this.trgtpos));
}
if (this.timestamp) {
fieldChunks.push(dataTrackerTimestampChunk(this.timestamp));
}
return dataTrackerChunk(this.id, fieldChunks);
}
getInfoChunk() {
return infoTrackerChunk(this.id, infoTrackerNameChunk(this.name));
}
}
module.exports = Tracker;