rclnodejs 1.1.0 → 1.2.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 +4 -4
- package/binding.gyp +4 -0
- package/lib/event_handler.js +474 -0
- package/lib/lifecycle_publisher.js +2 -2
- package/lib/node.js +57 -10
- package/lib/publisher.js +31 -4
- package/lib/subscription.js +48 -4
- package/package.json +1 -1
- package/scripts/npmjs-readme.md +4 -4
- package/src/addon.cpp +2 -0
- package/src/executor.cpp +3 -4
- package/src/handle_manager.cpp +13 -2
- package/src/handle_manager.h +4 -1
- package/src/rcl_event_handle_bindings.cpp +294 -0
- package/src/rcl_event_handle_bindings.h +26 -0
- package/src/rcl_node_bindings.cpp +6 -0
- package/types/node.d.ts +12 -2
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# rclnodejs ](https://github.com/RobotWebTools/rclnodejs/actions/workflows/linux-x64-build-and-test.yml?query=branch%3Adevelop)[](https://github.com/RobotWebTools/rclnodejs/actions/workflows/linux-arm64-build-and-test.yml?query=branch%3Adevelop)
|
|
2
2
|
|
|
3
3
|
`rclnodejs` is a Node.js client for the Robot Operating System (ROS 2). It provides a simple and easy JavaScript API for ROS 2 programming. TypeScript declarations are included to support use of rclnodejs in TypeScript projects.
|
|
4
4
|
|
|
@@ -22,8 +22,8 @@ rclnodejs.init().then(() => {
|
|
|
22
22
|
|
|
23
23
|
**ROS 2 SDK**
|
|
24
24
|
|
|
25
|
-
- See the ROS 2 SDK [Installation Guide](https://docs.ros.org/en/
|
|
26
|
-
- **DON'T FORGET TO [SOURCE THE ROS 2 STARTUP FILES](https://docs.ros.org/en/
|
|
25
|
+
- See the ROS 2 SDK [Installation Guide](https://docs.ros.org/en/kilted/Installation.html) for details.
|
|
26
|
+
- **DON'T FORGET TO [SOURCE THE ROS 2 STARTUP FILES](https://docs.ros.org/en/kilted/Tutorials/Beginner-CLI-Tools/Configuring-ROS2-Environment.htmls)**
|
|
27
27
|
|
|
28
28
|
## Install rclnodejs
|
|
29
29
|
|
|
@@ -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 [v1.
|
|
48
|
+
| latest version (currently [v1.2.0](https://github.com/RobotWebTools/rclnodejs/tree/1.2.0)) | [Kilted](https://github.com/RobotWebTools/rclnodejs/tree/kilted)<br>[Jazzy](https://github.com/RobotWebTools/rclnodejs/tree/jazzy)<br>[Humble](https://github.com/RobotWebTools/rclnodejs/tree/humble-hawksbill) |
|
|
49
49
|
|
|
50
50
|
## Documentation
|
|
51
51
|
|
package/binding.gyp
CHANGED
|
@@ -120,6 +120,9 @@
|
|
|
120
120
|
'include_dirs': [
|
|
121
121
|
'./src/third_party/dlfcn-win32/',
|
|
122
122
|
],
|
|
123
|
+
'libraries': [
|
|
124
|
+
'-lrmw_fastrtps_cpp',
|
|
125
|
+
],
|
|
123
126
|
'msvs_settings': {
|
|
124
127
|
'VCCLCompilerTool': {
|
|
125
128
|
'ExceptionHandling': '2', # /EHsc
|
|
@@ -170,6 +173,7 @@
|
|
|
170
173
|
# After Humble, e.g., Jazzy, Kilted.
|
|
171
174
|
'ros_version > 2205', {
|
|
172
175
|
'sources': [
|
|
176
|
+
'./src/rcl_event_handle_bindings.cpp',
|
|
173
177
|
'./src/rcl_type_description_service_bindings.cpp',
|
|
174
178
|
]
|
|
175
179
|
}
|
|
@@ -0,0 +1,474 @@
|
|
|
1
|
+
// Copyright (c) 2025, The Robot Web Tools Contributors
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
|
|
15
|
+
'use strict';
|
|
16
|
+
|
|
17
|
+
const rclnodejs = require('bindings')('rclnodejs');
|
|
18
|
+
const DistroUtils = require('./distro.js');
|
|
19
|
+
const Entity = require('./entity.js');
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Enumeration for PublisherEventCallbacks event types.
|
|
23
|
+
* @enum {number}
|
|
24
|
+
*/
|
|
25
|
+
const PublisherEventType = {
|
|
26
|
+
/** @member {number} */
|
|
27
|
+
PUBLISHER_OFFERED_DEADLINE_MISSED: 0,
|
|
28
|
+
/** @member {number} */
|
|
29
|
+
PUBLISHER_LIVELINESS_LOST: 1,
|
|
30
|
+
/** @member {number} */
|
|
31
|
+
PUBLISHER_OFFERED_INCOMPATIBLE_QOS: 2,
|
|
32
|
+
/** @member {number} */
|
|
33
|
+
PUBLISHER_INCOMPATIBLE_TYPE: 3,
|
|
34
|
+
/** @member {number} */
|
|
35
|
+
PUBLISHER_MATCHED: 4,
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Enumeration for SubscriptionEventCallbacks event types.
|
|
40
|
+
* @enum {number}
|
|
41
|
+
*/
|
|
42
|
+
const SubscriptionEventType = {
|
|
43
|
+
/** @member {number} */
|
|
44
|
+
SUBSCRIPTION_REQUESTED_DEADLINE_MISSED: 0,
|
|
45
|
+
/** @member {number} */
|
|
46
|
+
SUBSCRIPTION_LIVELINESS_CHANGED: 1,
|
|
47
|
+
/** @member {number} */
|
|
48
|
+
SUBSCRIPTION_REQUESTED_INCOMPATIBLE_QOS: 2,
|
|
49
|
+
/** @member {number} */
|
|
50
|
+
SUBSCRIPTION_MESSAGE_LOST: 3,
|
|
51
|
+
/** @member {number} */
|
|
52
|
+
SUBSCRIPTION_INCOMPATIBLE_TYPE: 4,
|
|
53
|
+
/** @member {number} */
|
|
54
|
+
SUBSCRIPTION_MATCHED: 5,
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
class EventHandler extends Entity {
|
|
58
|
+
constructor(handle, callback, eventType, eventTypeName) {
|
|
59
|
+
super(handle, null, null);
|
|
60
|
+
this._callback = callback;
|
|
61
|
+
this._eventType = eventType;
|
|
62
|
+
this._eventTypeName = eventTypeName;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
takeData() {
|
|
66
|
+
const data = rclnodejs.takeEvent(this._handle, {
|
|
67
|
+
[this._eventTypeName]: this._eventType,
|
|
68
|
+
});
|
|
69
|
+
if (this._callback) {
|
|
70
|
+
this._callback(data);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* @class - Class representing a ROS 2 PublisherEventCallbacks
|
|
77
|
+
* @hideconstructor
|
|
78
|
+
*/
|
|
79
|
+
class PublisherEventCallbacks {
|
|
80
|
+
constructor() {
|
|
81
|
+
if (DistroUtils.getDistroId() < DistroUtils.getDistroId('jazzy')) {
|
|
82
|
+
throw new Error(
|
|
83
|
+
'PublisherEventCallbacks is only available in ROS 2 Jazzy and later.'
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
this._deadline = null;
|
|
87
|
+
this._incompatible_qos = null;
|
|
88
|
+
this._liveliness = null;
|
|
89
|
+
this._incompatible_type = null;
|
|
90
|
+
this._matched = null;
|
|
91
|
+
this._eventHandlers = [];
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Set deadline missed callback.
|
|
96
|
+
* @param {function} callback - The callback function to be called.
|
|
97
|
+
*/
|
|
98
|
+
set deadline(callback) {
|
|
99
|
+
this._deadline = callback;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Get deadline missed callback.
|
|
104
|
+
* @return {function} - The callback function.
|
|
105
|
+
*/
|
|
106
|
+
get deadline() {
|
|
107
|
+
return this._deadline;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Set incompatible QoS callback.
|
|
112
|
+
* @param {function} callback - The callback function to be called.
|
|
113
|
+
*/
|
|
114
|
+
set incompatibleQos(callback) {
|
|
115
|
+
this._incompatible_qos = callback;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Get incompatible QoS callback.
|
|
120
|
+
* @return {function} - The callback function.
|
|
121
|
+
*/
|
|
122
|
+
get incompatibleQos() {
|
|
123
|
+
return this._incompatible_qos;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Set liveliness lost callback.
|
|
128
|
+
* @param {function} callback - The callback function to be called.
|
|
129
|
+
*/
|
|
130
|
+
set liveliness(callback) {
|
|
131
|
+
this._liveliness = callback;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Get liveliness lost callback.
|
|
136
|
+
* @return {function} - The callback function.
|
|
137
|
+
*/
|
|
138
|
+
get liveliness() {
|
|
139
|
+
return this._liveliness;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Set incompatible type callback.
|
|
144
|
+
* @param {function} callback - The callback function to be called.
|
|
145
|
+
*/
|
|
146
|
+
set incompatibleType(callback) {
|
|
147
|
+
this._incompatible_type = callback;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Get incompatible type callback.
|
|
152
|
+
* @return {function} - The callback function.
|
|
153
|
+
*/
|
|
154
|
+
get incompatibleType() {
|
|
155
|
+
return this._incompatible_type;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Set matched callback.
|
|
160
|
+
* @param {function} callback - The callback function to be called.
|
|
161
|
+
*/
|
|
162
|
+
set matched(callback) {
|
|
163
|
+
this._matched = callback;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Get matched callback.
|
|
168
|
+
* @return {function} - The callback function.
|
|
169
|
+
*/
|
|
170
|
+
get matched() {
|
|
171
|
+
return this._matched;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
createEventHandlers(publisherHandle) {
|
|
175
|
+
if (this._deadline) {
|
|
176
|
+
const deadlineHandle = rclnodejs.createPublisherEventHandle(
|
|
177
|
+
publisherHandle,
|
|
178
|
+
PublisherEventType.PUBLISHER_OFFERED_DEADLINE_MISSED
|
|
179
|
+
);
|
|
180
|
+
this._eventHandlers.push(
|
|
181
|
+
new EventHandler(
|
|
182
|
+
deadlineHandle,
|
|
183
|
+
this._deadline,
|
|
184
|
+
PublisherEventType.PUBLISHER_OFFERED_DEADLINE_MISSED,
|
|
185
|
+
'publisher_event_type'
|
|
186
|
+
)
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
if (this._incompatible_qos) {
|
|
191
|
+
const incompatibleQosHandle = rclnodejs.createPublisherEventHandle(
|
|
192
|
+
publisherHandle,
|
|
193
|
+
PublisherEventType.PUBLISHER_OFFERED_INCOMPATIBLE_QOS
|
|
194
|
+
);
|
|
195
|
+
this._eventHandlers.push(
|
|
196
|
+
new EventHandler(
|
|
197
|
+
incompatibleQosHandle,
|
|
198
|
+
this._incompatible_qos,
|
|
199
|
+
PublisherEventType.PUBLISHER_OFFERED_INCOMPATIBLE_QOS,
|
|
200
|
+
'publisher_event_type'
|
|
201
|
+
)
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
if (this._liveliness) {
|
|
206
|
+
const livelinessHandle = rclnodejs.createPublisherEventHandle(
|
|
207
|
+
publisherHandle,
|
|
208
|
+
PublisherEventType.PUBLISHER_LIVELINESS_LOST
|
|
209
|
+
);
|
|
210
|
+
this._eventHandlers.push(
|
|
211
|
+
new EventHandler(
|
|
212
|
+
livelinessHandle,
|
|
213
|
+
this._liveliness,
|
|
214
|
+
PublisherEventType.PUBLISHER_LIVELINESS_LOST,
|
|
215
|
+
'publisher_event_type'
|
|
216
|
+
)
|
|
217
|
+
);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
if (this._incompatible_type) {
|
|
221
|
+
const incompatibleTypeHandle = rclnodejs.createPublisherEventHandle(
|
|
222
|
+
publisherHandle,
|
|
223
|
+
PublisherEventType.PUBLISHER_INCOMPATIBLE_TYPE
|
|
224
|
+
);
|
|
225
|
+
this._eventHandlers.push(
|
|
226
|
+
new EventHandler(
|
|
227
|
+
incompatibleTypeHandle,
|
|
228
|
+
this._incompatible_type,
|
|
229
|
+
PublisherEventType.PUBLISHER_INCOMPATIBLE_TYPE,
|
|
230
|
+
'publisher_event_type'
|
|
231
|
+
)
|
|
232
|
+
);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
if (this._matched) {
|
|
236
|
+
const matchedHandle = rclnodejs.createPublisherEventHandle(
|
|
237
|
+
publisherHandle,
|
|
238
|
+
PublisherEventType.PUBLISHER_MATCHED
|
|
239
|
+
);
|
|
240
|
+
this._eventHandlers.push(
|
|
241
|
+
new EventHandler(
|
|
242
|
+
matchedHandle,
|
|
243
|
+
this._matched,
|
|
244
|
+
PublisherEventType.PUBLISHER_MATCHED,
|
|
245
|
+
'publisher_event_type'
|
|
246
|
+
)
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
return this._eventHandlers;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
get eventHandlers() {
|
|
254
|
+
return this._eventHandlers;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* @class - Class representing a ROS 2 SubscriptionEventCallbacks
|
|
260
|
+
* @hideconstructor
|
|
261
|
+
*/
|
|
262
|
+
class SubscriptionEventCallbacks {
|
|
263
|
+
constructor() {
|
|
264
|
+
if (DistroUtils.getDistroId() < DistroUtils.getDistroId('jazzy')) {
|
|
265
|
+
throw new Error(
|
|
266
|
+
'SubscriptionEventCallbacks is only available in ROS 2 Jazzy and later.'
|
|
267
|
+
);
|
|
268
|
+
}
|
|
269
|
+
this._deadline = null;
|
|
270
|
+
this._incompatible_qos = null;
|
|
271
|
+
this._liveliness = null;
|
|
272
|
+
this._message_lost = null;
|
|
273
|
+
this._incompatible_type = null;
|
|
274
|
+
this._matched = null;
|
|
275
|
+
this._eventHandlers = [];
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Set the callback for deadline missed event.
|
|
280
|
+
* @param {function} callback - The callback function to be called.
|
|
281
|
+
*/
|
|
282
|
+
set deadline(callback) {
|
|
283
|
+
this._deadline = callback;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Get the callback for deadline missed event.
|
|
288
|
+
* @return {function} - The callback function.
|
|
289
|
+
*/
|
|
290
|
+
get deadline() {
|
|
291
|
+
return this._deadline;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Set the callback for incompatible QoS event.
|
|
296
|
+
* @param {function} callback - The callback function to be called.
|
|
297
|
+
*/
|
|
298
|
+
set incompatibleQos(callback) {
|
|
299
|
+
this._incompatible_qos = callback;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* Get the callback for incompatible QoS event.
|
|
304
|
+
* @return {function} - The callback function.
|
|
305
|
+
*/
|
|
306
|
+
get incompatibleQos() {
|
|
307
|
+
return this._incompatible_qos;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* Set the callback for liveliness changed event.
|
|
312
|
+
* @param {function} callback - The callback function to be called.
|
|
313
|
+
*/
|
|
314
|
+
set liveliness(callback) {
|
|
315
|
+
this._liveliness = callback;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Get the callback for liveliness changed event.
|
|
320
|
+
* @return {function} - The callback function.
|
|
321
|
+
*/
|
|
322
|
+
get liveliness() {
|
|
323
|
+
return this._liveliness;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* Set the callback for message lost event.
|
|
328
|
+
* @param {function} callback - The callback function to be called.
|
|
329
|
+
*/
|
|
330
|
+
set messageLost(callback) {
|
|
331
|
+
this._message_lost = callback;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Get the callback for message lost event.
|
|
336
|
+
* @return {function} - The callback function.
|
|
337
|
+
*/
|
|
338
|
+
get messageLost() {
|
|
339
|
+
return this._message_lost;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* Set the callback for incompatible type event.
|
|
344
|
+
* @param {function} callback - The callback function to be called.
|
|
345
|
+
*/
|
|
346
|
+
set incompatibleType(callback) {
|
|
347
|
+
this._incompatible_type = callback;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* Get the callback for incompatible type event.
|
|
352
|
+
* @return {function} - The callback function.
|
|
353
|
+
*/
|
|
354
|
+
get incompatibleType() {
|
|
355
|
+
return this._incompatible_type;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* Set the callback for matched event.
|
|
360
|
+
* @param {function} callback - The callback function to be called.
|
|
361
|
+
*/
|
|
362
|
+
set matched(callback) {
|
|
363
|
+
this._matched = callback;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
/**
|
|
367
|
+
* Get the callback for matched event.
|
|
368
|
+
* @return {function} - The callback function.
|
|
369
|
+
*/
|
|
370
|
+
get matched() {
|
|
371
|
+
return this._matched;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
createEventHandlers(subscriptionHandle) {
|
|
375
|
+
if (this._deadline) {
|
|
376
|
+
const deadlineHandle = rclnodejs.createSubscriptionEventHandle(
|
|
377
|
+
subscriptionHandle,
|
|
378
|
+
SubscriptionEventType.SUBSCRIPTION_REQUESTED_DEADLINE_MISSED
|
|
379
|
+
);
|
|
380
|
+
this._eventHandlers.push(
|
|
381
|
+
new EventHandler(
|
|
382
|
+
deadlineHandle,
|
|
383
|
+
this._deadline,
|
|
384
|
+
SubscriptionEventType.SUBSCRIPTION_REQUESTED_DEADLINE_MISSED,
|
|
385
|
+
'subscription_event_type'
|
|
386
|
+
)
|
|
387
|
+
);
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
if (this._incompatible_qos) {
|
|
391
|
+
const incompatibleQosHandle = rclnodejs.createSubscriptionEventHandle(
|
|
392
|
+
subscriptionHandle,
|
|
393
|
+
SubscriptionEventType.SUBSCRIPTION_REQUESTED_INCOMPATIBLE_QOS
|
|
394
|
+
);
|
|
395
|
+
this._eventHandlers.push(
|
|
396
|
+
new EventHandler(
|
|
397
|
+
incompatibleQosHandle,
|
|
398
|
+
this._incompatible_qos,
|
|
399
|
+
SubscriptionEventType.SUBSCRIPTION_REQUESTED_INCOMPATIBLE_QOS,
|
|
400
|
+
'subscription_event_type'
|
|
401
|
+
)
|
|
402
|
+
);
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
if (this._liveliness) {
|
|
406
|
+
const livelinessHandle = rclnodejs.createSubscriptionEventHandle(
|
|
407
|
+
subscriptionHandle,
|
|
408
|
+
SubscriptionEventType.SUBSCRIPTION_LIVELINESS_CHANGED
|
|
409
|
+
);
|
|
410
|
+
this._eventHandlers.push(
|
|
411
|
+
new EventHandler(
|
|
412
|
+
livelinessHandle,
|
|
413
|
+
this._liveliness,
|
|
414
|
+
SubscriptionEventType.SUBSCRIPTION_LIVELINESS_CHANGED,
|
|
415
|
+
'subscription_event_type'
|
|
416
|
+
)
|
|
417
|
+
);
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
if (this._message_lost) {
|
|
421
|
+
const messageLostHandle = rclnodejs.createSubscriptionEventHandle(
|
|
422
|
+
subscriptionHandle,
|
|
423
|
+
SubscriptionEventType.SUBSCRIPTION_MESSAGE_LOST
|
|
424
|
+
);
|
|
425
|
+
this._eventHandlers.push(
|
|
426
|
+
new EventHandler(
|
|
427
|
+
messageLostHandle,
|
|
428
|
+
this._message_lost,
|
|
429
|
+
SubscriptionEventType.SUBSCRIPTION_MESSAGE_LOST,
|
|
430
|
+
'subscription_event_type'
|
|
431
|
+
)
|
|
432
|
+
);
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
if (this._incompatible_type) {
|
|
436
|
+
const incompatibleTypeHandle = rclnodejs.createSubscriptionEventHandle(
|
|
437
|
+
subscriptionHandle,
|
|
438
|
+
SubscriptionEventType.SUBSCRIPTION_INCOMPATIBLE_TYPE
|
|
439
|
+
);
|
|
440
|
+
this._eventHandlers.push(
|
|
441
|
+
new EventHandler(
|
|
442
|
+
incompatibleTypeHandle,
|
|
443
|
+
this._incompatible_type,
|
|
444
|
+
SubscriptionEventType.SUBSCRIPTION_INCOMPATIBLE_TYPE,
|
|
445
|
+
'subscription_event_type'
|
|
446
|
+
)
|
|
447
|
+
);
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
if (this._matched) {
|
|
451
|
+
const matchedHandle = rclnodejs.createSubscriptionEventHandle(
|
|
452
|
+
subscriptionHandle,
|
|
453
|
+
SubscriptionEventType.SUBSCRIPTION_MATCHED
|
|
454
|
+
);
|
|
455
|
+
this._eventHandlers.push(
|
|
456
|
+
new EventHandler(
|
|
457
|
+
matchedHandle,
|
|
458
|
+
this._matched,
|
|
459
|
+
SubscriptionEventType.SUBSCRIPTION_MATCHED,
|
|
460
|
+
'subscription_event_type'
|
|
461
|
+
)
|
|
462
|
+
);
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
return this._eventHandlers;
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
module.exports = {
|
|
470
|
+
PublisherEventCallbacks,
|
|
471
|
+
PublisherEventType,
|
|
472
|
+
SubscriptionEventCallbacks,
|
|
473
|
+
SubscriptionEventType,
|
|
474
|
+
};
|
|
@@ -93,10 +93,10 @@ class LifecyclePublisher extends Publisher {
|
|
|
93
93
|
this.deactivate();
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
-
static createPublisher(
|
|
96
|
+
static createPublisher(node, typeClass, topic, options) {
|
|
97
97
|
let type = typeClass.type();
|
|
98
98
|
let handle = rclnodejs.createPublisher(
|
|
99
|
-
|
|
99
|
+
node.handle,
|
|
100
100
|
type.pkgName,
|
|
101
101
|
type.subFolder,
|
|
102
102
|
type.interfaceName,
|
package/lib/node.js
CHANGED
|
@@ -41,6 +41,8 @@ const TimeSource = require('./time_source.js');
|
|
|
41
41
|
const Timer = require('./timer.js');
|
|
42
42
|
const TypeDescriptionService = require('./type_description_service.js');
|
|
43
43
|
const Entity = require('./entity.js');
|
|
44
|
+
const { SubscriptionEventCallbacks } = require('../lib/event_handler.js');
|
|
45
|
+
const { PublisherEventCallbacks } = require('../lib/event_handler.js');
|
|
44
46
|
|
|
45
47
|
// Parameter event publisher constants
|
|
46
48
|
const PARAMETER_EVENT_MSG_TYPE = 'rcl_interfaces/msg/ParameterEvent';
|
|
@@ -96,6 +98,7 @@ class Node extends rclnodejs.ShadowNode {
|
|
|
96
98
|
this._services = [];
|
|
97
99
|
this._timers = [];
|
|
98
100
|
this._guards = [];
|
|
101
|
+
this._events = [];
|
|
99
102
|
this._actionClients = [];
|
|
100
103
|
this._actionServers = [];
|
|
101
104
|
this._rateTimerServer = null;
|
|
@@ -181,6 +184,9 @@ class Node extends rclnodejs.ShadowNode {
|
|
|
181
184
|
let actionServersReady = this._actionServers.filter((actionServer) =>
|
|
182
185
|
handles.includes(actionServer.handle)
|
|
183
186
|
);
|
|
187
|
+
let eventsReady = this._events.filter((event) =>
|
|
188
|
+
handles.includes(event.handle)
|
|
189
|
+
);
|
|
184
190
|
|
|
185
191
|
timersReady.forEach((timer) => {
|
|
186
192
|
if (timer.isReady()) {
|
|
@@ -189,6 +195,10 @@ class Node extends rclnodejs.ShadowNode {
|
|
|
189
195
|
}
|
|
190
196
|
});
|
|
191
197
|
|
|
198
|
+
eventsReady.forEach((event) => {
|
|
199
|
+
event.takeData();
|
|
200
|
+
});
|
|
201
|
+
|
|
192
202
|
for (const subscription of subscriptionsReady) {
|
|
193
203
|
if (subscription.isDestroyed()) continue;
|
|
194
204
|
if (subscription.isRaw) {
|
|
@@ -588,27 +598,39 @@ class Node extends rclnodejs.ShadowNode {
|
|
|
588
598
|
* @param {object} options - The options argument used to parameterize the publisher.
|
|
589
599
|
* @param {boolean} options.enableTypedArray - The topic will use TypedArray if necessary, default: true.
|
|
590
600
|
* @param {QoS} options.qos - ROS Middleware "quality of service" settings for the publisher, default: QoS.profileDefault.
|
|
601
|
+
* @param {PublisherEventCallbacks} eventCallbacks - The event callbacks for the publisher.
|
|
591
602
|
* @return {Publisher} - An instance of Publisher.
|
|
592
603
|
*/
|
|
593
|
-
createPublisher(typeClass, topic, options) {
|
|
594
|
-
return this._createPublisher(
|
|
604
|
+
createPublisher(typeClass, topic, options, eventCallbacks) {
|
|
605
|
+
return this._createPublisher(
|
|
606
|
+
typeClass,
|
|
607
|
+
topic,
|
|
608
|
+
options,
|
|
609
|
+
Publisher,
|
|
610
|
+
eventCallbacks
|
|
611
|
+
);
|
|
595
612
|
}
|
|
596
613
|
|
|
597
|
-
_createPublisher(typeClass, topic, options, publisherClass) {
|
|
614
|
+
_createPublisher(typeClass, topic, options, publisherClass, eventCallbacks) {
|
|
598
615
|
if (typeof typeClass === 'string' || typeof typeClass === 'object') {
|
|
599
616
|
typeClass = loader.loadInterface(typeClass);
|
|
600
617
|
}
|
|
601
618
|
options = this._validateOptions(options);
|
|
602
619
|
|
|
603
|
-
if (
|
|
620
|
+
if (
|
|
621
|
+
typeof typeClass !== 'function' ||
|
|
622
|
+
typeof topic !== 'string' ||
|
|
623
|
+
(eventCallbacks && !(eventCallbacks instanceof PublisherEventCallbacks))
|
|
624
|
+
) {
|
|
604
625
|
throw new TypeError('Invalid argument');
|
|
605
626
|
}
|
|
606
627
|
|
|
607
628
|
let publisher = publisherClass.createPublisher(
|
|
608
|
-
this
|
|
629
|
+
this,
|
|
609
630
|
typeClass,
|
|
610
631
|
topic,
|
|
611
|
-
options
|
|
632
|
+
options,
|
|
633
|
+
eventCallbacks
|
|
612
634
|
);
|
|
613
635
|
debug('Finish creating publisher, topic = %s.', topic);
|
|
614
636
|
this._publishers.push(publisher);
|
|
@@ -643,12 +665,13 @@ class Node extends rclnodejs.ShadowNode {
|
|
|
643
665
|
* the ‘parameters’ (i.e., "%n" tokens) in the filter_expression. The number of supplied parameters must
|
|
644
666
|
* fit with the requested values in the filter_expression (i.e., the number of %n tokens). default: undefined.
|
|
645
667
|
* @param {SubscriptionCallback} callback - The callback to be call when receiving the topic subscribed. The topic will be an instance of null-terminated Buffer when options.isRaw is true.
|
|
668
|
+
* @param {SubscriptionEventCallbacks} eventCallbacks - The event callbacks for the subscription.
|
|
646
669
|
* @return {Subscription} - An instance of Subscription.
|
|
647
670
|
* @throws {ERROR} - May throw an RMW error if content-filter is malformed.
|
|
648
671
|
* @see {@link SubscriptionCallback}
|
|
649
672
|
* @see {@link https://www.omg.org/spec/DDS/1.4/PDF|Content-filter details at DDS 1.4 specification, Annex B}
|
|
650
673
|
*/
|
|
651
|
-
createSubscription(typeClass, topic, options, callback) {
|
|
674
|
+
createSubscription(typeClass, topic, options, callback, eventCallbacks) {
|
|
652
675
|
if (typeof typeClass === 'string' || typeof typeClass === 'object') {
|
|
653
676
|
typeClass = loader.loadInterface(typeClass);
|
|
654
677
|
}
|
|
@@ -662,17 +685,20 @@ class Node extends rclnodejs.ShadowNode {
|
|
|
662
685
|
if (
|
|
663
686
|
typeof typeClass !== 'function' ||
|
|
664
687
|
typeof topic !== 'string' ||
|
|
665
|
-
typeof callback !== 'function'
|
|
688
|
+
typeof callback !== 'function' ||
|
|
689
|
+
(eventCallbacks &&
|
|
690
|
+
!(eventCallbacks instanceof SubscriptionEventCallbacks))
|
|
666
691
|
) {
|
|
667
692
|
throw new TypeError('Invalid argument');
|
|
668
693
|
}
|
|
669
694
|
|
|
670
695
|
let subscription = Subscription.createSubscription(
|
|
671
|
-
this
|
|
696
|
+
this,
|
|
672
697
|
typeClass,
|
|
673
698
|
topic,
|
|
674
699
|
options,
|
|
675
|
-
callback
|
|
700
|
+
callback,
|
|
701
|
+
eventCallbacks
|
|
676
702
|
);
|
|
677
703
|
debug('Finish creating subscription, topic = %s.', topic);
|
|
678
704
|
this._subscriptions.push(subscription);
|
|
@@ -836,6 +862,12 @@ class Node extends rclnodejs.ShadowNode {
|
|
|
836
862
|
if (!(publisher instanceof Publisher)) {
|
|
837
863
|
throw new TypeError('Invalid argument');
|
|
838
864
|
}
|
|
865
|
+
if (publisher.events) {
|
|
866
|
+
publisher.events.forEach((event) => {
|
|
867
|
+
this._destroyEntity(event, this._events);
|
|
868
|
+
});
|
|
869
|
+
publisher.events = [];
|
|
870
|
+
}
|
|
839
871
|
this._destroyEntity(publisher, this._publishers, false);
|
|
840
872
|
}
|
|
841
873
|
|
|
@@ -848,6 +880,13 @@ class Node extends rclnodejs.ShadowNode {
|
|
|
848
880
|
if (!(subscription instanceof Subscription)) {
|
|
849
881
|
throw new TypeError('Invalid argument');
|
|
850
882
|
}
|
|
883
|
+
if (subscription.events) {
|
|
884
|
+
subscription.events.forEach((event) => {
|
|
885
|
+
this._destroyEntity(event, this._events);
|
|
886
|
+
});
|
|
887
|
+
subscription.events = [];
|
|
888
|
+
}
|
|
889
|
+
|
|
851
890
|
this._destroyEntity(subscription, this._subscriptions);
|
|
852
891
|
}
|
|
853
892
|
|
|
@@ -1637,6 +1676,14 @@ class Node extends rclnodejs.ShadowNode {
|
|
|
1637
1676
|
return rclnodejs.getFullyQualifiedName(this.handle);
|
|
1638
1677
|
}
|
|
1639
1678
|
|
|
1679
|
+
/**
|
|
1680
|
+
* Get the RMW implementation identifier
|
|
1681
|
+
* @returns {string} - The RMW implementation identifier.
|
|
1682
|
+
*/
|
|
1683
|
+
getRMWImplementationIdentifier() {
|
|
1684
|
+
return rclnodejs.getRMWImplementationIdentifier();
|
|
1685
|
+
}
|
|
1686
|
+
|
|
1640
1687
|
// returns on 1st error or result {successful, reason}
|
|
1641
1688
|
_validateParameters(parameters = [], declareParameterMode = false) {
|
|
1642
1689
|
for (const parameter of parameters) {
|