node-mavlink 1.1.1 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +21 -1
- package/dist/lib/logger.d.ts +2 -1
- package/dist/lib/logger.d.ts.map +1 -0
- package/dist/lib/logger.js +119 -1
- package/dist/lib/mavesp.d.ts +3 -1
- package/dist/lib/mavesp.d.ts.map +1 -0
- package/dist/lib/mavesp.js +101 -1
- package/dist/lib/mavlink.d.ts +16 -9
- package/dist/lib/mavlink.d.ts.map +1 -0
- package/dist/lib/mavlink.js +704 -1
- package/dist/lib/serialization.d.ts +9 -49
- package/dist/lib/serialization.d.ts.map +1 -0
- package/dist/lib/serialization.js +184 -1
- package/dist/lib/utils.d.ts +5 -4
- package/dist/lib/utils.d.ts.map +1 -0
- package/dist/lib/utils.js +77 -1
- package/examples/parse-tlog-file.ts +43 -0
- package/examples/send-receive-file.ts +6 -2
- package/examples/vtol.tlog +0 -0
- package/package.json +11 -9
- package/sanity-check.cjs +8 -0
- package/sanity-check.mjs +8 -0
- package/.vscode/launch.json +0 -19
- package/.vscode/settings.json +0 -3
- package/coverage/coverage-final.json +0 -1
- package/coverage/lcov-report/base.css +0 -224
- package/coverage/lcov-report/block-navigation.js +0 -87
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +0 -101
- package/coverage/lcov-report/prettify.css +0 -1
- package/coverage/lcov-report/prettify.js +0 -2
- package/coverage/lcov-report/serialization.ts.html +0 -613
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +0 -196
- package/coverage/lcov.info +0 -0
- package/index.ts +0 -5
- package/jest.config.js +0 -5
- package/lib/logger.ts +0 -128
- package/lib/mavesp.ts +0 -112
- package/lib/mavlink.ts +0 -796
- package/lib/serialization.test.ts +0 -256
- package/lib/serialization.ts +0 -176
- package/lib/utils.ts +0 -75
- package/tests/data.mavlink +0 -0
- package/tests/main.ts +0 -59
- package/tsconfig.json +0 -16
@@ -1,196 +0,0 @@
|
|
1
|
-
/* eslint-disable */
|
2
|
-
var addSorting = (function() {
|
3
|
-
'use strict';
|
4
|
-
var cols,
|
5
|
-
currentSort = {
|
6
|
-
index: 0,
|
7
|
-
desc: false
|
8
|
-
};
|
9
|
-
|
10
|
-
// returns the summary table element
|
11
|
-
function getTable() {
|
12
|
-
return document.querySelector('.coverage-summary');
|
13
|
-
}
|
14
|
-
// returns the thead element of the summary table
|
15
|
-
function getTableHeader() {
|
16
|
-
return getTable().querySelector('thead tr');
|
17
|
-
}
|
18
|
-
// returns the tbody element of the summary table
|
19
|
-
function getTableBody() {
|
20
|
-
return getTable().querySelector('tbody');
|
21
|
-
}
|
22
|
-
// returns the th element for nth column
|
23
|
-
function getNthColumn(n) {
|
24
|
-
return getTableHeader().querySelectorAll('th')[n];
|
25
|
-
}
|
26
|
-
|
27
|
-
function onFilterInput() {
|
28
|
-
const searchValue = document.getElementById('fileSearch').value;
|
29
|
-
const rows = document.getElementsByTagName('tbody')[0].children;
|
30
|
-
for (let i = 0; i < rows.length; i++) {
|
31
|
-
const row = rows[i];
|
32
|
-
if (
|
33
|
-
row.textContent
|
34
|
-
.toLowerCase()
|
35
|
-
.includes(searchValue.toLowerCase())
|
36
|
-
) {
|
37
|
-
row.style.display = '';
|
38
|
-
} else {
|
39
|
-
row.style.display = 'none';
|
40
|
-
}
|
41
|
-
}
|
42
|
-
}
|
43
|
-
|
44
|
-
// loads the search box
|
45
|
-
function addSearchBox() {
|
46
|
-
var template = document.getElementById('filterTemplate');
|
47
|
-
var templateClone = template.content.cloneNode(true);
|
48
|
-
templateClone.getElementById('fileSearch').oninput = onFilterInput;
|
49
|
-
template.parentElement.appendChild(templateClone);
|
50
|
-
}
|
51
|
-
|
52
|
-
// loads all columns
|
53
|
-
function loadColumns() {
|
54
|
-
var colNodes = getTableHeader().querySelectorAll('th'),
|
55
|
-
colNode,
|
56
|
-
cols = [],
|
57
|
-
col,
|
58
|
-
i;
|
59
|
-
|
60
|
-
for (i = 0; i < colNodes.length; i += 1) {
|
61
|
-
colNode = colNodes[i];
|
62
|
-
col = {
|
63
|
-
key: colNode.getAttribute('data-col'),
|
64
|
-
sortable: !colNode.getAttribute('data-nosort'),
|
65
|
-
type: colNode.getAttribute('data-type') || 'string'
|
66
|
-
};
|
67
|
-
cols.push(col);
|
68
|
-
if (col.sortable) {
|
69
|
-
col.defaultDescSort = col.type === 'number';
|
70
|
-
colNode.innerHTML =
|
71
|
-
colNode.innerHTML + '<span class="sorter"></span>';
|
72
|
-
}
|
73
|
-
}
|
74
|
-
return cols;
|
75
|
-
}
|
76
|
-
// attaches a data attribute to every tr element with an object
|
77
|
-
// of data values keyed by column name
|
78
|
-
function loadRowData(tableRow) {
|
79
|
-
var tableCols = tableRow.querySelectorAll('td'),
|
80
|
-
colNode,
|
81
|
-
col,
|
82
|
-
data = {},
|
83
|
-
i,
|
84
|
-
val;
|
85
|
-
for (i = 0; i < tableCols.length; i += 1) {
|
86
|
-
colNode = tableCols[i];
|
87
|
-
col = cols[i];
|
88
|
-
val = colNode.getAttribute('data-value');
|
89
|
-
if (col.type === 'number') {
|
90
|
-
val = Number(val);
|
91
|
-
}
|
92
|
-
data[col.key] = val;
|
93
|
-
}
|
94
|
-
return data;
|
95
|
-
}
|
96
|
-
// loads all row data
|
97
|
-
function loadData() {
|
98
|
-
var rows = getTableBody().querySelectorAll('tr'),
|
99
|
-
i;
|
100
|
-
|
101
|
-
for (i = 0; i < rows.length; i += 1) {
|
102
|
-
rows[i].data = loadRowData(rows[i]);
|
103
|
-
}
|
104
|
-
}
|
105
|
-
// sorts the table using the data for the ith column
|
106
|
-
function sortByIndex(index, desc) {
|
107
|
-
var key = cols[index].key,
|
108
|
-
sorter = function(a, b) {
|
109
|
-
a = a.data[key];
|
110
|
-
b = b.data[key];
|
111
|
-
return a < b ? -1 : a > b ? 1 : 0;
|
112
|
-
},
|
113
|
-
finalSorter = sorter,
|
114
|
-
tableBody = document.querySelector('.coverage-summary tbody'),
|
115
|
-
rowNodes = tableBody.querySelectorAll('tr'),
|
116
|
-
rows = [],
|
117
|
-
i;
|
118
|
-
|
119
|
-
if (desc) {
|
120
|
-
finalSorter = function(a, b) {
|
121
|
-
return -1 * sorter(a, b);
|
122
|
-
};
|
123
|
-
}
|
124
|
-
|
125
|
-
for (i = 0; i < rowNodes.length; i += 1) {
|
126
|
-
rows.push(rowNodes[i]);
|
127
|
-
tableBody.removeChild(rowNodes[i]);
|
128
|
-
}
|
129
|
-
|
130
|
-
rows.sort(finalSorter);
|
131
|
-
|
132
|
-
for (i = 0; i < rows.length; i += 1) {
|
133
|
-
tableBody.appendChild(rows[i]);
|
134
|
-
}
|
135
|
-
}
|
136
|
-
// removes sort indicators for current column being sorted
|
137
|
-
function removeSortIndicators() {
|
138
|
-
var col = getNthColumn(currentSort.index),
|
139
|
-
cls = col.className;
|
140
|
-
|
141
|
-
cls = cls.replace(/ sorted$/, '').replace(/ sorted-desc$/, '');
|
142
|
-
col.className = cls;
|
143
|
-
}
|
144
|
-
// adds sort indicators for current column being sorted
|
145
|
-
function addSortIndicators() {
|
146
|
-
getNthColumn(currentSort.index).className += currentSort.desc
|
147
|
-
? ' sorted-desc'
|
148
|
-
: ' sorted';
|
149
|
-
}
|
150
|
-
// adds event listeners for all sorter widgets
|
151
|
-
function enableUI() {
|
152
|
-
var i,
|
153
|
-
el,
|
154
|
-
ithSorter = function ithSorter(i) {
|
155
|
-
var col = cols[i];
|
156
|
-
|
157
|
-
return function() {
|
158
|
-
var desc = col.defaultDescSort;
|
159
|
-
|
160
|
-
if (currentSort.index === i) {
|
161
|
-
desc = !currentSort.desc;
|
162
|
-
}
|
163
|
-
sortByIndex(i, desc);
|
164
|
-
removeSortIndicators();
|
165
|
-
currentSort.index = i;
|
166
|
-
currentSort.desc = desc;
|
167
|
-
addSortIndicators();
|
168
|
-
};
|
169
|
-
};
|
170
|
-
for (i = 0; i < cols.length; i += 1) {
|
171
|
-
if (cols[i].sortable) {
|
172
|
-
// add the click event handler on the th so users
|
173
|
-
// dont have to click on those tiny arrows
|
174
|
-
el = getNthColumn(i).querySelector('.sorter').parentElement;
|
175
|
-
if (el.addEventListener) {
|
176
|
-
el.addEventListener('click', ithSorter(i));
|
177
|
-
} else {
|
178
|
-
el.attachEvent('onclick', ithSorter(i));
|
179
|
-
}
|
180
|
-
}
|
181
|
-
}
|
182
|
-
}
|
183
|
-
// adds sorting functionality to the UI
|
184
|
-
return function() {
|
185
|
-
if (!getTable()) {
|
186
|
-
return;
|
187
|
-
}
|
188
|
-
cols = loadColumns();
|
189
|
-
loadData();
|
190
|
-
addSearchBox();
|
191
|
-
addSortIndicators();
|
192
|
-
enableUI();
|
193
|
-
};
|
194
|
-
})();
|
195
|
-
|
196
|
-
window.addEventListener('load', addSorting);
|
package/coverage/lcov.info
DELETED
File without changes
|
package/index.ts
DELETED
package/jest.config.js
DELETED
package/lib/logger.ts
DELETED
@@ -1,128 +0,0 @@
|
|
1
|
-
import EventEmitter = require('events')
|
2
|
-
|
3
|
-
/**
|
4
|
-
* Level of the log entry
|
5
|
-
*/
|
6
|
-
export enum LogLevel {
|
7
|
-
trace = 5,
|
8
|
-
debug = 4,
|
9
|
-
info = 3,
|
10
|
-
warn = 2,
|
11
|
-
error = 1,
|
12
|
-
fatal = 0,
|
13
|
-
}
|
14
|
-
|
15
|
-
type LoggerRegistry = { [x: string]: Logger }
|
16
|
-
type LoggerEvents = 'log'
|
17
|
-
type LoggerEventHandler = (context: string, level: LogLevel, message: any[]) => void
|
18
|
-
|
19
|
-
/**
|
20
|
-
* Simplified interface for logging facilities
|
21
|
-
*/
|
22
|
-
export class Logger {
|
23
|
-
private static readonly events: EventEmitter = new EventEmitter()
|
24
|
-
private static registry: LoggerRegistry = {}
|
25
|
-
|
26
|
-
/**
|
27
|
-
* Gets a logger by name
|
28
|
-
*
|
29
|
-
* @param context logger context
|
30
|
-
*/
|
31
|
-
static getLogger(context) {
|
32
|
-
let name = ''
|
33
|
-
if (typeof context === 'function') name = context.name
|
34
|
-
else if (typeof context === 'object') name = (<any>context).constructor.name
|
35
|
-
else if (typeof context === 'string') name = context
|
36
|
-
else throw new Error(`Do not know how to get logger for ${context} (${typeof context})`)
|
37
|
-
|
38
|
-
if (!Logger.registry[name]) Logger.registry[name] = new Logger(name)
|
39
|
-
|
40
|
-
return Logger.registry[name]
|
41
|
-
}
|
42
|
-
|
43
|
-
/**
|
44
|
-
* Binds an event handler
|
45
|
-
*
|
46
|
-
* @param event event to react to
|
47
|
-
* @param handler event handler
|
48
|
-
*/
|
49
|
-
static on(event: LoggerEvents, handler: (context, level, message) => void) {
|
50
|
-
this.events.on(event, handler)
|
51
|
-
}
|
52
|
-
|
53
|
-
/**
|
54
|
-
* Removes an event handler
|
55
|
-
*
|
56
|
-
* @param event event to react to
|
57
|
-
* @param handler event handler
|
58
|
-
*/
|
59
|
-
static off(event: LoggerEvents, handler: LoggerEventHandler) {
|
60
|
-
this.events.off(event, handler)
|
61
|
-
}
|
62
|
-
|
63
|
-
private context: string
|
64
|
-
|
65
|
-
/**
|
66
|
-
* Constructs a new logger instance
|
67
|
-
*
|
68
|
-
* @param context logger context
|
69
|
-
*/
|
70
|
-
constructor(context: string) {
|
71
|
-
this.context = context
|
72
|
-
Logger.events.emit('logger-created', Logger.registry[context])
|
73
|
-
}
|
74
|
-
|
75
|
-
/**
|
76
|
-
* Sends a log message if the trace level is enabled for this logger
|
77
|
-
*
|
78
|
-
* @param args parameters for the log entry
|
79
|
-
*/
|
80
|
-
trace(...args: any) {
|
81
|
-
Logger.events.emit('log', { context: this.context, level: LogLevel.trace, message: args })
|
82
|
-
}
|
83
|
-
|
84
|
-
/**
|
85
|
-
* Sends a log message if the debug level is enabled for this logger
|
86
|
-
*
|
87
|
-
* @param args parameters for the log entry
|
88
|
-
*/
|
89
|
-
debug(...args: any) {
|
90
|
-
Logger.events.emit('log', { context: this.context, level: LogLevel.debug, message: args })
|
91
|
-
}
|
92
|
-
|
93
|
-
/**
|
94
|
-
* Sends a log message if the info level is enabled for this logger
|
95
|
-
*
|
96
|
-
* @param args parameters for the log entry
|
97
|
-
*/
|
98
|
-
info(...args: any) {
|
99
|
-
Logger.events.emit('log', { context: this.context, level: LogLevel.info, message: args })
|
100
|
-
}
|
101
|
-
|
102
|
-
/**
|
103
|
-
* Sends a log message if the warn level is enabled for this logger
|
104
|
-
*
|
105
|
-
* @param args parameters for the log entry
|
106
|
-
*/
|
107
|
-
warn(...args: any) {
|
108
|
-
Logger.events.emit('log', { context: this.context, level: LogLevel.warn, message: args })
|
109
|
-
}
|
110
|
-
|
111
|
-
/**
|
112
|
-
* Sends a log message if the error level is enabled for this logger
|
113
|
-
*
|
114
|
-
* @param args parameters for the log entry
|
115
|
-
*/
|
116
|
-
error(...args: any) {
|
117
|
-
Logger.events.emit('log', { context: this.context, level: LogLevel.error, message: args })
|
118
|
-
}
|
119
|
-
|
120
|
-
/**
|
121
|
-
* Sends a log message if the fatal level is enabled for this logger
|
122
|
-
*
|
123
|
-
* @param args parameters for the log entry
|
124
|
-
*/
|
125
|
-
fatal(...args: any) {
|
126
|
-
Logger.events.emit('log', { context: this.context, level: LogLevel.fatal, message: args })
|
127
|
-
}
|
128
|
-
}
|
package/lib/mavesp.ts
DELETED
@@ -1,112 +0,0 @@
|
|
1
|
-
import { EventEmitter } from 'events'
|
2
|
-
|
3
|
-
import { Socket, createSocket } from 'dgram'
|
4
|
-
import { Writable, PassThrough } from 'stream'
|
5
|
-
import { MavLinkPacketSplitter, MavLinkPacketParser, MavLinkPacketSignature } from './mavlink'
|
6
|
-
import { MavLinkProtocol, MavLinkProtocolV2 } from './mavlink'
|
7
|
-
import { waitFor } from './utils'
|
8
|
-
import { uint8_t, MavLinkData } from 'mavlink-mappings'
|
9
|
-
|
10
|
-
/**
|
11
|
-
* Encapsulation of communication with MavEsp8266
|
12
|
-
*/
|
13
|
-
export class MavEsp8266 extends EventEmitter {
|
14
|
-
private input: Writable
|
15
|
-
private socket: Socket
|
16
|
-
private ip: string = ''
|
17
|
-
private sendPort: number = 14555
|
18
|
-
private seq: number = 0
|
19
|
-
|
20
|
-
constructor() {
|
21
|
-
super()
|
22
|
-
|
23
|
-
this.input = new PassThrough()
|
24
|
-
|
25
|
-
this.processIncommingUDPData = this.processIncommingUDPData.bind(this)
|
26
|
-
this.processIncommingPacket = this.processIncommingPacket.bind(this)
|
27
|
-
|
28
|
-
// Create the reader as usual by piping the source stream through the splitter
|
29
|
-
// and packet parser
|
30
|
-
const reader = this.input
|
31
|
-
.pipe(new MavLinkPacketSplitter())
|
32
|
-
.pipe(new MavLinkPacketParser())
|
33
|
-
|
34
|
-
reader.on('data', this.processIncommingPacket)
|
35
|
-
}
|
36
|
-
|
37
|
-
/**
|
38
|
-
* Start communication with the controller via MAVESP2866
|
39
|
-
*
|
40
|
-
* @param receivePort port to receive messages on (default: 14550)
|
41
|
-
* @param sendPort port to send messages to (default: 14555)
|
42
|
-
*/
|
43
|
-
async start(receivePort: number = 14550, sendPort: number = 14555) {
|
44
|
-
this.sendPort = sendPort
|
45
|
-
|
46
|
-
// Create a UDP socket
|
47
|
-
this.socket = createSocket({ type: 'udp4', reuseAddr: true })
|
48
|
-
this.socket.on('message', this.processIncommingUDPData)
|
49
|
-
|
50
|
-
// Start listening on the socket
|
51
|
-
return new Promise((resolve, reject) => {
|
52
|
-
this.socket.bind(receivePort, () => {
|
53
|
-
// Wait for the first package to be returned to read the ip address
|
54
|
-
// of the controller
|
55
|
-
waitFor(() => this.ip !== '')
|
56
|
-
.then(() => { resolve(this.ip) })
|
57
|
-
.catch(e => { reject(e) })
|
58
|
-
})
|
59
|
-
})
|
60
|
-
}
|
61
|
-
|
62
|
-
/**
|
63
|
-
* Send a packet
|
64
|
-
*
|
65
|
-
* @param msg message to send
|
66
|
-
* @param sysid system id
|
67
|
-
* @param compid component id
|
68
|
-
*/
|
69
|
-
send(msg: MavLinkData, sysid: uint8_t = MavLinkProtocol.SYS_ID, compid: uint8_t = MavLinkProtocol.COMP_ID) {
|
70
|
-
const protocol = new MavLinkProtocolV2(sysid, compid)
|
71
|
-
const buffer = protocol.serialize(msg, this.seq++)
|
72
|
-
this.seq &= 255
|
73
|
-
this.sendBuffer(buffer)
|
74
|
-
}
|
75
|
-
|
76
|
-
/**
|
77
|
-
* Send a signed packet
|
78
|
-
*
|
79
|
-
* @param msg message to send
|
80
|
-
* @param sysid system id
|
81
|
-
* @param compid component id
|
82
|
-
* @param linkId link id for the signature
|
83
|
-
*/
|
84
|
-
sendSigned(msg: MavLinkData, key: Buffer, linkId: uint8_t = 1, sysid: uint8_t = MavLinkProtocol.SYS_ID, compid: uint8_t = MavLinkProtocol.COMP_ID) {
|
85
|
-
const protocol = new MavLinkProtocolV2(sysid, compid, MavLinkProtocolV2.IFLAG_SIGNED)
|
86
|
-
const b1 = protocol.serialize(msg, this.seq++)
|
87
|
-
this.seq &= 255
|
88
|
-
const b2 = protocol.sign(b1, linkId, key)
|
89
|
-
this.sendBuffer(b2)
|
90
|
-
}
|
91
|
-
|
92
|
-
/**
|
93
|
-
* Send raw data over the socket. Useful for custom implementation of data sending
|
94
|
-
*
|
95
|
-
* @param buffer buffer to send
|
96
|
-
*/
|
97
|
-
sendBuffer(buffer: Buffer) {
|
98
|
-
this.socket.send(buffer, this.sendPort, this.ip)
|
99
|
-
}
|
100
|
-
|
101
|
-
private processIncommingUDPData(buffer, metadata) {
|
102
|
-
// store the remote ip address
|
103
|
-
if (this.ip === '') this.ip = metadata.address
|
104
|
-
// pass on the data to the input stream
|
105
|
-
this.input.write(buffer)
|
106
|
-
}
|
107
|
-
|
108
|
-
private processIncommingPacket(packet) {
|
109
|
-
// let the user know we received the packet
|
110
|
-
this.emit('data', packet)
|
111
|
-
}
|
112
|
-
}
|