rclnodejs 0.29.0 → 0.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/binding.gyp +25 -77
- package/lib/action/server.js +5 -3
- package/lib/clock.js +2 -2
- package/lib/duration.js +22 -35
- package/lib/node.js +6 -17
- package/lib/parameter.js +34 -28
- package/lib/rate.js +1 -1
- package/lib/time.js +39 -50
- package/lib/time_source.js +1 -1
- package/lib/timer.js +5 -5
- package/package.json +4 -5
- package/rosidl_gen/generator.json +1 -1
- package/rosidl_gen/message_translator.js +17 -4
- package/rosidl_gen/packages.js +2 -6
- package/rosidl_gen/templates/message.dot +22 -2
- package/rosidl_parser/rosidl_parser.js +29 -1
- package/rostsd_gen/index.js +4 -2
- package/scripts/config.js +69 -0
- package/scripts/npmjs-readme.md +1 -1
- package/src/rcl_bindings.cpp +40 -104
- package/types/duration.d.ts +3 -4
- package/types/node.d.ts +1 -1
- package/types/parameter.d.ts +6 -7
- package/types/time.d.ts +3 -9
- package/types/timer.d.ts +6 -6
package/lib/time.js
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
const rclnodejs = require('bindings')('rclnodejs');
|
|
18
18
|
const Duration = require('./duration.js');
|
|
19
19
|
const ClockType = require('./clock_type.js');
|
|
20
|
-
const
|
|
20
|
+
const S_TO_NS = 10n ** 9n;
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
23
|
* @class - Class representing a Time in ROS
|
|
@@ -26,16 +26,20 @@ const int64 = require('int64-napi');
|
|
|
26
26
|
class Time {
|
|
27
27
|
/**
|
|
28
28
|
* Create a Time.
|
|
29
|
-
* @param {
|
|
30
|
-
* @param {
|
|
29
|
+
* @param {bigint} [seconds=0] - The second part of the time.
|
|
30
|
+
* @param {bigint} [nanoseconds=0] - The nanosecond part of the time.
|
|
31
31
|
* @param {ClockType} [clockType=Clock.ClockType.SYSTEM_TIME] - The clock type.
|
|
32
32
|
*/
|
|
33
|
-
constructor(
|
|
34
|
-
|
|
33
|
+
constructor(
|
|
34
|
+
seconds = 0n,
|
|
35
|
+
nanoseconds = 0n,
|
|
36
|
+
clockType = ClockType.SYSTEM_TIME
|
|
37
|
+
) {
|
|
38
|
+
if (typeof seconds !== 'bigint') {
|
|
35
39
|
throw new TypeError('Invalid argument of seconds');
|
|
36
40
|
}
|
|
37
41
|
|
|
38
|
-
if (typeof nanoseconds !== '
|
|
42
|
+
if (typeof nanoseconds !== 'bigint') {
|
|
39
43
|
throw new TypeError('Invalid argument of nanoseconds');
|
|
40
44
|
}
|
|
41
45
|
|
|
@@ -43,25 +47,22 @@ class Time {
|
|
|
43
47
|
throw new TypeError('Invalid argument of clockType');
|
|
44
48
|
}
|
|
45
49
|
|
|
46
|
-
if (
|
|
47
|
-
int64.lt(seconds, 0) ||
|
|
48
|
-
(typeof seconds === 'string' && seconds.startsWith('-'))
|
|
49
|
-
) {
|
|
50
|
+
if (seconds < 0n) {
|
|
50
51
|
throw new RangeError('seconds value must not be negative');
|
|
51
52
|
}
|
|
52
53
|
|
|
53
|
-
if (
|
|
54
|
-
int64.lt(nanoseconds, 0) ||
|
|
55
|
-
(typeof nanoseconds === 'string' && nanoseconds.startsWith('-'))
|
|
56
|
-
) {
|
|
54
|
+
if (nanoseconds < 0n) {
|
|
57
55
|
throw new RangeError('nanoseconds value must not be negative');
|
|
58
56
|
}
|
|
59
57
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
58
|
+
const total = seconds * S_TO_NS + nanoseconds;
|
|
59
|
+
if (total >= 2n ** 63n) {
|
|
60
|
+
throw new RangeError(
|
|
61
|
+
'Total nanoseconds value is too large to store in C time point.'
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
this._nanoseconds = total;
|
|
65
|
+
this._handle = rclnodejs.createTimePoint(this._nanoseconds, clockType);
|
|
65
66
|
this._clockType = clockType;
|
|
66
67
|
}
|
|
67
68
|
|
|
@@ -80,22 +81,11 @@ class Time {
|
|
|
80
81
|
* Get the nanosecond part of the time.
|
|
81
82
|
* @name Time#get:nanoseconds
|
|
82
83
|
* @function
|
|
83
|
-
* @return {
|
|
84
|
+
* @return {bigint} - value in nanosecond.
|
|
84
85
|
*/
|
|
85
86
|
|
|
86
87
|
get nanoseconds() {
|
|
87
|
-
|
|
88
|
-
let nano;
|
|
89
|
-
|
|
90
|
-
if (str.startsWith('-')) {
|
|
91
|
-
nano = int64.negative(int64.from(str));
|
|
92
|
-
} else {
|
|
93
|
-
nano = int64.from(str);
|
|
94
|
-
}
|
|
95
|
-
if (Number.isFinite(nano.toNumber())) {
|
|
96
|
-
return nano.toNumber();
|
|
97
|
-
}
|
|
98
|
-
return nano.toString();
|
|
88
|
+
return rclnodejs.getNanoseconds(this._handle);
|
|
99
89
|
}
|
|
100
90
|
|
|
101
91
|
/**
|
|
@@ -106,9 +96,11 @@ class Time {
|
|
|
106
96
|
*/
|
|
107
97
|
|
|
108
98
|
get secondsAndNanoseconds() {
|
|
109
|
-
const
|
|
110
|
-
|
|
111
|
-
|
|
99
|
+
const nanoseconds = this._nanoseconds;
|
|
100
|
+
return {
|
|
101
|
+
seconds: nanoseconds / S_TO_NS,
|
|
102
|
+
nanoseconds: nanoseconds % S_TO_NS,
|
|
103
|
+
};
|
|
112
104
|
}
|
|
113
105
|
|
|
114
106
|
/**
|
|
@@ -119,8 +111,8 @@ class Time {
|
|
|
119
111
|
add(other) {
|
|
120
112
|
if (other instanceof Duration) {
|
|
121
113
|
return new Time(
|
|
122
|
-
|
|
123
|
-
|
|
114
|
+
0n,
|
|
115
|
+
this._nanoseconds + other.nanoseconds,
|
|
124
116
|
this._clockType
|
|
125
117
|
);
|
|
126
118
|
}
|
|
@@ -137,14 +129,11 @@ class Time {
|
|
|
137
129
|
if (other._clockType !== this._clockType) {
|
|
138
130
|
throw new TypeError("Can't subtract times with different clock types");
|
|
139
131
|
}
|
|
140
|
-
return new Duration(
|
|
141
|
-
0,
|
|
142
|
-
int64.subtract(this._nanoseconds, other._nanoseconds).toString()
|
|
143
|
-
);
|
|
132
|
+
return new Duration(0n, this._nanoseconds - other._nanoseconds);
|
|
144
133
|
} else if (other instanceof Duration) {
|
|
145
134
|
return new Time(
|
|
146
|
-
|
|
147
|
-
|
|
135
|
+
0n,
|
|
136
|
+
this._nanoseconds - other._nanoseconds,
|
|
148
137
|
this._clockType
|
|
149
138
|
);
|
|
150
139
|
}
|
|
@@ -161,7 +150,7 @@ class Time {
|
|
|
161
150
|
if (other._clockType !== this._clockType) {
|
|
162
151
|
throw new TypeError("Can't compare times with different clock types");
|
|
163
152
|
}
|
|
164
|
-
return this._nanoseconds
|
|
153
|
+
return this._nanoseconds === other.nanoseconds;
|
|
165
154
|
}
|
|
166
155
|
throw new TypeError('Invalid argument');
|
|
167
156
|
}
|
|
@@ -176,7 +165,7 @@ class Time {
|
|
|
176
165
|
if (other._clockType !== this._clockType) {
|
|
177
166
|
throw new TypeError("Can't compare times with different clock types");
|
|
178
167
|
}
|
|
179
|
-
return this._nanoseconds
|
|
168
|
+
return this._nanoseconds !== other.nanoseconds;
|
|
180
169
|
}
|
|
181
170
|
}
|
|
182
171
|
|
|
@@ -190,7 +179,7 @@ class Time {
|
|
|
190
179
|
if (other._clockType !== this._clockType) {
|
|
191
180
|
throw new TypeError("Can't compare times with different clock types");
|
|
192
181
|
}
|
|
193
|
-
return this._nanoseconds
|
|
182
|
+
return this._nanoseconds < other.nanoseconds;
|
|
194
183
|
}
|
|
195
184
|
throw new TypeError('Invalid argument');
|
|
196
185
|
}
|
|
@@ -205,7 +194,7 @@ class Time {
|
|
|
205
194
|
if (other._clockType !== this._clockType) {
|
|
206
195
|
throw new TypeError("Can't compare times with different clock types");
|
|
207
196
|
}
|
|
208
|
-
return this._nanoseconds
|
|
197
|
+
return this._nanoseconds <= other.nanoseconds;
|
|
209
198
|
}
|
|
210
199
|
throw new TypeError('Invalid argument');
|
|
211
200
|
}
|
|
@@ -220,7 +209,7 @@ class Time {
|
|
|
220
209
|
if (other._clockType !== this._clockType) {
|
|
221
210
|
throw new TypeError("Can't compare times with different clock types");
|
|
222
211
|
}
|
|
223
|
-
return this._nanoseconds
|
|
212
|
+
return this._nanoseconds > other.nanoseconds;
|
|
224
213
|
}
|
|
225
214
|
throw new TypeError('Invalid argument');
|
|
226
215
|
}
|
|
@@ -235,7 +224,7 @@ class Time {
|
|
|
235
224
|
if (other._clockType !== this._clockType) {
|
|
236
225
|
throw new TypeError("Can't compare times with different clock types");
|
|
237
226
|
}
|
|
238
|
-
return this._nanoseconds
|
|
227
|
+
return this._nanoseconds >= other.nanoseconds;
|
|
239
228
|
}
|
|
240
229
|
throw new TypeError('Invalid argument');
|
|
241
230
|
}
|
|
@@ -261,7 +250,7 @@ class Time {
|
|
|
261
250
|
* @return {Time} Return the created Time object.
|
|
262
251
|
*/
|
|
263
252
|
static fromMsg(msg, clockType = ClockType.ROS_TIME) {
|
|
264
|
-
return new Time(msg.sec, msg.nanosec, clockType);
|
|
253
|
+
return new Time(BigInt(msg.sec), BigInt(msg.nanosec), clockType);
|
|
265
254
|
}
|
|
266
255
|
}
|
|
267
256
|
|
package/lib/time_source.js
CHANGED
|
@@ -37,7 +37,7 @@ class TimeSource {
|
|
|
37
37
|
this._node = node;
|
|
38
38
|
this._associatedClocks = [];
|
|
39
39
|
this._clockSubscription = undefined;
|
|
40
|
-
this._lastTimeSet = new Time(
|
|
40
|
+
this._lastTimeSet = new Time(0n, 0n, ClockType.ROS_TIME);
|
|
41
41
|
this._isRosTimeActive = false;
|
|
42
42
|
|
|
43
43
|
if (this._node) {
|
package/lib/timer.js
CHANGED
|
@@ -29,7 +29,7 @@ class Timer {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
/**
|
|
32
|
-
* @type {
|
|
32
|
+
* @type {bigint} - The period of the timer in nanoseconds.
|
|
33
33
|
*/
|
|
34
34
|
get period() {
|
|
35
35
|
return this._period;
|
|
@@ -73,18 +73,18 @@ class Timer {
|
|
|
73
73
|
|
|
74
74
|
/**
|
|
75
75
|
* Get the interval since the last call of this timer.
|
|
76
|
-
* @return {
|
|
76
|
+
* @return {bigint} - the interval value in nanoseconds.
|
|
77
77
|
*/
|
|
78
78
|
timeSinceLastCall() {
|
|
79
|
-
return
|
|
79
|
+
return rclnodejs.timerGetTimeSinceLastCall(this._handle);
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
/**
|
|
83
83
|
* Get the interval until the next call will happen.
|
|
84
|
-
* @return {
|
|
84
|
+
* @return {bigint} - the interval value in nanoseconds.
|
|
85
85
|
*/
|
|
86
86
|
timeUntilNextCall() {
|
|
87
|
-
return
|
|
87
|
+
return rclnodejs.timerGetTimeUntilNextCall(this._handle);
|
|
88
88
|
}
|
|
89
89
|
}
|
|
90
90
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rclnodejs",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.31.0",
|
|
4
4
|
"description": "ROS2.0 JavaScript client with Node.js",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "types/index.d.ts",
|
|
@@ -50,10 +50,10 @@
|
|
|
50
50
|
"@typescript-eslint/parser": "^8.18.0",
|
|
51
51
|
"babel-eslint": "^10.1.0",
|
|
52
52
|
"clang-format": "^1.8.0",
|
|
53
|
-
"commander": "^
|
|
53
|
+
"commander": "^13.1.0",
|
|
54
54
|
"deep-equal": "^1.1.1",
|
|
55
55
|
"eslint": "^9.16.0",
|
|
56
|
-
"eslint-config-prettier": "^
|
|
56
|
+
"eslint-config-prettier": "^10.0.1",
|
|
57
57
|
"eslint-plugin-prettier": "^5.2.1",
|
|
58
58
|
"husky": "^9.1.7",
|
|
59
59
|
"jsdoc": "^4.0.4",
|
|
@@ -63,7 +63,6 @@
|
|
|
63
63
|
"tree-kill": "^1.2.2",
|
|
64
64
|
"typescript": "^5.7.2"
|
|
65
65
|
},
|
|
66
|
-
"//": "Pin int64-napi to ^1.0.2",
|
|
67
66
|
"dependencies": {
|
|
68
67
|
"@rclnodejs/ref-array-di": "^1.2.2",
|
|
69
68
|
"@rclnodejs/ref-napi": "^4.0.0",
|
|
@@ -75,7 +74,7 @@
|
|
|
75
74
|
"dot": "^1.1.3",
|
|
76
75
|
"dtslint": "^4.2.1",
|
|
77
76
|
"fs-extra": "^11.2.0",
|
|
78
|
-
"
|
|
77
|
+
"json-bigint": "^1.0.0",
|
|
79
78
|
"is-close": "^1.3.3",
|
|
80
79
|
"mkdirp": "^3.0.1",
|
|
81
80
|
"mz": "^2.7.0",
|
|
@@ -27,7 +27,12 @@ function copyMsgObject(msg, obj) {
|
|
|
27
27
|
for (let i in obj) {
|
|
28
28
|
if (msg.hasMember(i)) {
|
|
29
29
|
const type = typeof obj[i];
|
|
30
|
-
if (
|
|
30
|
+
if (
|
|
31
|
+
type === 'string' ||
|
|
32
|
+
type === 'number' ||
|
|
33
|
+
type === 'boolean' ||
|
|
34
|
+
type === 'bigint'
|
|
35
|
+
) {
|
|
31
36
|
// A primitive-type value
|
|
32
37
|
msg[i] = obj[i];
|
|
33
38
|
} else if (Array.isArray(obj[i]) || isTypedArray(obj[i])) {
|
|
@@ -80,17 +85,20 @@ function verifyMessage(message, obj) {
|
|
|
80
85
|
case 'char':
|
|
81
86
|
case 'int16':
|
|
82
87
|
case 'int32':
|
|
83
|
-
case 'int64':
|
|
84
88
|
case 'byte':
|
|
85
89
|
case 'uint16':
|
|
86
90
|
case 'uint32':
|
|
87
|
-
case 'uint64':
|
|
88
91
|
case 'float32':
|
|
89
92
|
case 'float64':
|
|
90
93
|
if (typeof obj[name] != 'number') {
|
|
91
94
|
return false;
|
|
92
95
|
}
|
|
93
96
|
break;
|
|
97
|
+
case 'int64':
|
|
98
|
+
case 'uint64':
|
|
99
|
+
if (typeof obj[name] != 'bigint') {
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
94
102
|
case 'bool':
|
|
95
103
|
if (typeof obj[name] != 'boolean') {
|
|
96
104
|
return false;
|
|
@@ -171,7 +179,12 @@ function toROSMessage(TypeClass, obj) {
|
|
|
171
179
|
|
|
172
180
|
function constructFromPlanObject(msg, obj) {
|
|
173
181
|
const type = typeof obj;
|
|
174
|
-
if (
|
|
182
|
+
if (
|
|
183
|
+
type === 'string' ||
|
|
184
|
+
type === 'number' ||
|
|
185
|
+
type === 'boolean' ||
|
|
186
|
+
type === 'bigint'
|
|
187
|
+
) {
|
|
175
188
|
msg.data = obj;
|
|
176
189
|
} else if (type === 'object') {
|
|
177
190
|
copyMsgObject(msg, obj);
|
package/rosidl_gen/packages.js
CHANGED
|
@@ -161,9 +161,7 @@ async function generateMsgForSrv(filePath, interfaceInfo, pkgMap) {
|
|
|
161
161
|
async function addInterfaceInfos(filePath, dir, pkgMap) {
|
|
162
162
|
const interfaceInfo = grabInterfaceInfo(filePath, true);
|
|
163
163
|
const ignore = pkgFilters.matchesAny(interfaceInfo);
|
|
164
|
-
if (ignore) {
|
|
165
|
-
console.log('Omitting filtered interface: ', interfaceInfo);
|
|
166
|
-
} else {
|
|
164
|
+
if (!ignore) {
|
|
167
165
|
if (path.extname(filePath) === '.msg') {
|
|
168
166
|
// Some .msg files were generated prior to 0.3.2 for .action files,
|
|
169
167
|
// which has been disabled. So these files should be ignored here.
|
|
@@ -232,9 +230,7 @@ async function findPackagesInDirectory(dir) {
|
|
|
232
230
|
amentExecuted
|
|
233
231
|
);
|
|
234
232
|
const ignore = pkgFilters.matchesAny(interfaceInfo);
|
|
235
|
-
if (ignore) {
|
|
236
|
-
console.log('Omitting filtered interface: ', interfaceInfo);
|
|
237
|
-
} else {
|
|
233
|
+
if (!ignore) {
|
|
238
234
|
if (path.extname(file.name) === '.msg') {
|
|
239
235
|
// Some .msg files were generated prior to 0.3.2 for .action files,
|
|
240
236
|
// which has been disabled. So these files should be ignored here.
|
|
@@ -157,6 +157,10 @@ function isTypedArrayType(type) {
|
|
|
157
157
|
return typedArrayType.indexOf(type.type.toLowerCase()) !== -1;
|
|
158
158
|
}
|
|
159
159
|
|
|
160
|
+
function isBigInt(type) {
|
|
161
|
+
return ['int64', 'uint64'].indexOf(type.type.toLowerCase()) !== -1;
|
|
162
|
+
}
|
|
163
|
+
|
|
160
164
|
const willUseTypedArray = isTypedArrayType(it.spec.baseType);
|
|
161
165
|
const currentTypedArray = getTypedArrayName(it.spec.baseType);
|
|
162
166
|
const currentTypedArrayElementType = getTypedArrayElementName(it.spec.baseType);
|
|
@@ -303,7 +307,13 @@ class {{=objectWrapper}} {
|
|
|
303
307
|
this._refObject.{{=field.name}} = {{=field.default_value}};
|
|
304
308
|
{{?}}
|
|
305
309
|
{{?? field.type.isPrimitiveType && !isTypedArrayType(field.type) && field.default_value}}
|
|
306
|
-
|
|
310
|
+
{{? isBigInt(field.type)}}
|
|
311
|
+
{{/* For non-TypedArray like int64/uint64. */}}
|
|
312
|
+
this._{{=field.name}}Array = {{=JSON.stringify(field.default_value)}}.map(num => BigInt(num));
|
|
313
|
+
{{??}}
|
|
314
|
+
{{/* For non-TypedArray like bool. */}}
|
|
315
|
+
this._{{=field.name}}Array = {{=JSON.stringify(field.default_value)}};
|
|
316
|
+
{{?}}
|
|
307
317
|
{{?? field.type.isPrimitiveType && isTypedArrayType(field.type) && field.default_value}}
|
|
308
318
|
this._wrapperFields.{{=field.name}}.fill({{=getTypedArrayName(field.type)}}.from({{=JSON.stringify(field.default_value)}}));
|
|
309
319
|
{{?}}
|
|
@@ -376,8 +386,11 @@ class {{=objectWrapper}} {
|
|
|
376
386
|
}
|
|
377
387
|
}
|
|
378
388
|
}
|
|
389
|
+
{{?? isBigInt(field.type)}}
|
|
390
|
+
{{/* For non-TypedArray like int64/uint64. */}}
|
|
391
|
+
this._refObject.{{=field.name}} = this._{{=field.name}}Array.map(num => num.toString());
|
|
379
392
|
{{??}}
|
|
380
|
-
{{/* For non-TypedArray like
|
|
393
|
+
{{/* For non-TypedArray like bool. */}}
|
|
381
394
|
this._refObject.{{=field.name}} = this._{{=field.name}}Array;
|
|
382
395
|
{{?}}
|
|
383
396
|
{{?? field.type.isArray && field.type.isPrimitiveType && isTypedArrayType(field.type) && field.type.isFixedSizeArray}}
|
|
@@ -527,6 +540,8 @@ class {{=objectWrapper}} {
|
|
|
527
540
|
return this._wrapperFields.{{=field.name}};
|
|
528
541
|
{{?? !field.type.isArray && field.type.type === 'string' && it.spec.msgName !== 'String'}}
|
|
529
542
|
return this._wrapperFields.{{=field.name}}.data;
|
|
543
|
+
{{?? isBigInt(field.type)}}
|
|
544
|
+
return BigInt(this._refObject.{{=field.name}});
|
|
530
545
|
{{??}}
|
|
531
546
|
return this._refObject.{{=field.name}};
|
|
532
547
|
{{?}}
|
|
@@ -559,6 +574,11 @@ class {{=objectWrapper}} {
|
|
|
559
574
|
}
|
|
560
575
|
{{?? !field.type.isArray && field.type.type === 'string' && it.spec.msgName !== 'String'}}
|
|
561
576
|
this._wrapperFields.{{=field.name}}.data = value;
|
|
577
|
+
{{?? isBigInt(field.type)}}
|
|
578
|
+
if (typeof value !== "bigint") {
|
|
579
|
+
throw new TypeError('{{=field.name}} must be type of bigint');
|
|
580
|
+
}
|
|
581
|
+
this._refObject.{{=field.name}} = value.toString();
|
|
562
582
|
{{??}}
|
|
563
583
|
{{? it.spec.msgName === 'String'}}
|
|
564
584
|
this._refObject.size = Buffer.byteLength(value);
|
|
@@ -14,11 +14,20 @@
|
|
|
14
14
|
|
|
15
15
|
'use strict';
|
|
16
16
|
|
|
17
|
+
const compareVersions = require('compare-versions');
|
|
17
18
|
const path = require('path');
|
|
18
19
|
const execFile = require('child_process').execFile;
|
|
19
20
|
|
|
20
21
|
const pythonExecutable = require('./py_utils').getPythonExecutable('python3');
|
|
21
22
|
|
|
23
|
+
const contextSupportedVersion = '21.0.0.0';
|
|
24
|
+
const currentVersion = process.version;
|
|
25
|
+
const isContextSupported = compareVersions.compare(
|
|
26
|
+
currentVersion.substring(1, currentVersion.length),
|
|
27
|
+
contextSupportedVersion,
|
|
28
|
+
'>='
|
|
29
|
+
);
|
|
30
|
+
|
|
22
31
|
const rosidlParser = {
|
|
23
32
|
parseMessageFile(packageName, filePath) {
|
|
24
33
|
return this._parseFile('parse_message_file', packageName, filePath);
|
|
@@ -32,6 +41,25 @@ const rosidlParser = {
|
|
|
32
41
|
return this._parseFile('parse_action_file', packageName, filePath);
|
|
33
42
|
},
|
|
34
43
|
|
|
44
|
+
_parseJSONObject(str) {
|
|
45
|
+
// For nodejs >= `contextSupportedVersion`, we leverage context parameter to
|
|
46
|
+
// convert unsafe integer to string, otherwise, json-bigint is used.
|
|
47
|
+
// See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse
|
|
48
|
+
if (isContextSupported) {
|
|
49
|
+
return JSON.parse(str, (key, value, context) => {
|
|
50
|
+
if (
|
|
51
|
+
Number.isInteger(value) &&
|
|
52
|
+
!Number.isSafeInteger(Number(context.source))
|
|
53
|
+
) {
|
|
54
|
+
return context.source;
|
|
55
|
+
}
|
|
56
|
+
return value;
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
const JSONbigString = require('json-bigint')({ storeAsString: true });
|
|
60
|
+
return JSONbigString.parse(str);
|
|
61
|
+
},
|
|
62
|
+
|
|
35
63
|
_parseFile(command, packageName, filePath) {
|
|
36
64
|
return new Promise((resolve, reject) => {
|
|
37
65
|
const args = [
|
|
@@ -54,7 +82,7 @@ const rosidlParser = {
|
|
|
54
82
|
)
|
|
55
83
|
);
|
|
56
84
|
} else {
|
|
57
|
-
resolve(
|
|
85
|
+
resolve(this._parseJSONObject(stdout));
|
|
58
86
|
}
|
|
59
87
|
}
|
|
60
88
|
);
|
package/rostsd_gen/index.js
CHANGED
|
@@ -478,7 +478,6 @@ function primitiveType2JSName(type) {
|
|
|
478
478
|
case 'int8':
|
|
479
479
|
case 'int16':
|
|
480
480
|
case 'int32':
|
|
481
|
-
case 'int64':
|
|
482
481
|
|
|
483
482
|
// signed explicit float types
|
|
484
483
|
case 'float32':
|
|
@@ -488,7 +487,6 @@ function primitiveType2JSName(type) {
|
|
|
488
487
|
case 'uint8':
|
|
489
488
|
case 'uint16':
|
|
490
489
|
case 'uint32':
|
|
491
|
-
case 'uint64':
|
|
492
490
|
jsName = 'number';
|
|
493
491
|
break;
|
|
494
492
|
case 'bool':
|
|
@@ -499,6 +497,10 @@ function primitiveType2JSName(type) {
|
|
|
499
497
|
case 'wstring':
|
|
500
498
|
jsName = 'string';
|
|
501
499
|
break;
|
|
500
|
+
case 'int64':
|
|
501
|
+
case 'uint64':
|
|
502
|
+
jsName = 'bigint';
|
|
503
|
+
break;
|
|
502
504
|
}
|
|
503
505
|
|
|
504
506
|
return jsName;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
2
|
+
// you may not use this file except in compliance with the License.
|
|
3
|
+
// You may obtain a copy of the License at
|
|
4
|
+
//
|
|
5
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
//
|
|
7
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
8
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
9
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
10
|
+
// See the License for the specific language governing permissions and
|
|
11
|
+
// limitations under the License.
|
|
12
|
+
|
|
13
|
+
'use strict';
|
|
14
|
+
|
|
15
|
+
const os = require('os');
|
|
16
|
+
const path = require('path');
|
|
17
|
+
const { execSync } = require('child_process');
|
|
18
|
+
|
|
19
|
+
const dependencies = [
|
|
20
|
+
'rcl',
|
|
21
|
+
'rcutils',
|
|
22
|
+
'rmw',
|
|
23
|
+
'rcl_yaml_param_parser',
|
|
24
|
+
'rosidl_typesupport_interface',
|
|
25
|
+
'rcl_action',
|
|
26
|
+
'action_msgs',
|
|
27
|
+
'service_msgs',
|
|
28
|
+
'unique_identifier_msgs',
|
|
29
|
+
'builtin_interfaces',
|
|
30
|
+
'rcl_lifecycle',
|
|
31
|
+
'lifecycle_msgs',
|
|
32
|
+
'rosidl_runtime_c',
|
|
33
|
+
'rosidl_dynamic_typesupport',
|
|
34
|
+
'type_description_interfaces',
|
|
35
|
+
];
|
|
36
|
+
|
|
37
|
+
const command = os.type() === 'Windows_NT' ? 'where ros2' : 'which ros2';
|
|
38
|
+
|
|
39
|
+
function getROSRootPath() {
|
|
40
|
+
try {
|
|
41
|
+
// Execute the command to find the ROS2 installation path.
|
|
42
|
+
let ros2Path = execSync(command).toString().trim();
|
|
43
|
+
return path.dirname(path.dirname(ros2Path));
|
|
44
|
+
} catch (error) {
|
|
45
|
+
console.error(`Error: ${error.message}`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function getROSLibPath() {
|
|
50
|
+
return path.join(getROSRootPath(), 'lib');
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function getROSIncludeRootPath() {
|
|
54
|
+
return path.join(getROSRootPath(), 'include');
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function getIncludePaths() {
|
|
58
|
+
const includeRoot = getROSIncludeRootPath();
|
|
59
|
+
return dependencies.map((dependency) => {
|
|
60
|
+
return path.join(includeRoot, dependency);
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
module.exports = {
|
|
65
|
+
getROSRootPath,
|
|
66
|
+
getROSLibPath,
|
|
67
|
+
getROSIncludeRootPath,
|
|
68
|
+
getIncludePaths,
|
|
69
|
+
};
|
package/scripts/npmjs-readme.md
CHANGED
|
@@ -45,7 +45,7 @@ npm i rclnodejs@x.y.z
|
|
|
45
45
|
|
|
46
46
|
| RCLNODEJS Version | Compatible ROS 2 LTS |
|
|
47
47
|
| :------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------: |
|
|
48
|
-
| latest version (currently [v0.
|
|
48
|
+
| latest version (currently [v0.31.0](https://github.com/RobotWebTools/rclnodejs/tree/0.31.0)) | [Humble](https://github.com/RobotWebTools/rclnodejs/tree/humble-hawksbill)<br>[Jazzy](https://github.com/RobotWebTools/rclnodejs/tree/jazzy) |
|
|
49
49
|
|
|
50
50
|
## Documentation
|
|
51
51
|
|