rclnodejs 0.33.0 → 1.1.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 +3 -3
- package/binding.gyp +25 -2
- package/lib/action/client.js +40 -0
- package/lib/action/server.js +21 -0
- package/lib/client.js +3 -4
- package/lib/context.js +8 -0
- package/lib/distro.js +2 -0
- package/lib/lifecycle.js +9 -0
- package/lib/logging.js +26 -9
- package/lib/node.js +81 -1
- package/lib/node_options.js +21 -1
- package/lib/publisher.js +27 -0
- package/lib/service.js +10 -3
- package/lib/subscription.js +8 -0
- package/lib/timer.js +32 -0
- package/lib/type_description_service.js +82 -0
- package/package.json +4 -4
- package/scripts/config.js +1 -0
- package/scripts/npmjs-readme.md +3 -3
- package/src/addon.cpp +60 -53
- package/src/executor.cpp +19 -10
- package/src/{executor.hpp → executor.h} +7 -5
- package/src/handle_manager.cpp +30 -56
- package/src/{handle_manager.hpp → handle_manager.h} +8 -7
- package/src/{macros.hpp → macros.h} +7 -5
- package/src/rcl_action_client_bindings.cpp +306 -0
- package/src/{rcl_action_bindings.hpp → rcl_action_client_bindings.h} +6 -11
- package/src/rcl_action_goal_bindings.cpp +117 -0
- package/src/rcl_action_goal_bindings.h +26 -0
- package/src/rcl_action_server_bindings.cpp +520 -0
- package/src/rcl_action_server_bindings.h +26 -0
- package/src/rcl_bindings.cpp +42 -2010
- package/src/{rcl_bindings.hpp → rcl_bindings.h} +5 -25
- package/src/rcl_client_bindings.cpp +183 -0
- package/src/rcl_client_bindings.h +26 -0
- package/src/rcl_context_bindings.cpp +156 -0
- package/src/rcl_context_bindings.h +26 -0
- package/src/rcl_graph_bindings.cpp +280 -0
- package/src/rcl_graph_bindings.h +26 -0
- package/src/rcl_guard_condition_bindings.cpp +75 -0
- package/src/rcl_guard_condition_bindings.h +26 -0
- package/src/rcl_handle.cpp +41 -57
- package/src/{rcl_handle.hpp → rcl_handle.h} +18 -17
- package/src/rcl_lifecycle_bindings.cpp +148 -114
- package/src/{rcl_lifecycle_bindings.hpp → rcl_lifecycle_bindings.h} +5 -7
- package/src/rcl_logging_bindings.cpp +96 -0
- package/src/rcl_logging_bindings.h +26 -0
- package/src/rcl_names_bindings.cpp +255 -0
- package/src/rcl_names_bindings.h +26 -0
- package/src/rcl_node_bindings.cpp +476 -0
- package/src/rcl_node_bindings.h +26 -0
- package/src/rcl_publisher_bindings.cpp +160 -0
- package/src/rcl_publisher_bindings.h +26 -0
- package/src/rcl_service_bindings.cpp +185 -0
- package/src/rcl_service_bindings.h +26 -0
- package/src/rcl_subscription_bindings.cpp +335 -0
- package/src/rcl_subscription_bindings.h +26 -0
- package/src/rcl_time_point_bindings.cpp +194 -0
- package/src/rcl_time_point_bindings.h +26 -0
- package/src/rcl_timer_bindings.cpp +237 -0
- package/src/rcl_timer_bindings.h +26 -0
- package/src/rcl_type_description_service_bindings.cpp +79 -0
- package/src/rcl_type_description_service_bindings.h +27 -0
- package/src/rcl_utilities.cpp +166 -1
- package/src/{rcl_utilities.hpp → rcl_utilities.h} +21 -3
- package/src/shadow_node.cpp +56 -75
- package/src/{shadow_node.hpp → shadow_node.h} +18 -17
- package/types/action_client.d.ts +18 -0
- package/types/action_server.d.ts +12 -0
- package/types/context.d.ts +6 -0
- package/types/lifecycle.d.ts +7 -0
- package/types/node.d.ts +69 -0
- package/types/publisher.d.ts +23 -0
- package/types/service.d.ts +6 -0
- package/types/subscription.d.ts +6 -0
- package/types/timer.d.ts +18 -0
- package/src/rcl_action_bindings.cpp +0 -826
package/README.md
CHANGED
|
@@ -43,9 +43,9 @@ npm i rclnodejs@x.y.z
|
|
|
43
43
|
|
|
44
44
|
#### RCLNODEJS - ROS 2 Version Compatibility
|
|
45
45
|
|
|
46
|
-
|
|
|
47
|
-
|
|
|
48
|
-
| latest version (currently [
|
|
46
|
+
| RCLNODEJS Version | Compatible ROS 2 LTS |
|
|
47
|
+
| :----------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
|
|
48
|
+
| latest version (currently [v1.1.0](https://github.com/RobotWebTools/rclnodejs/tree/1.1.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
|
@@ -21,17 +21,31 @@
|
|
|
21
21
|
'./src/addon.cpp',
|
|
22
22
|
'./src/executor.cpp',
|
|
23
23
|
'./src/handle_manager.cpp',
|
|
24
|
-
'./src/
|
|
24
|
+
'./src/rcl_action_client_bindings.cpp',
|
|
25
|
+
'./src/rcl_action_goal_bindings.cpp',
|
|
26
|
+
'./src/rcl_action_server_bindings.cpp',
|
|
25
27
|
'./src/rcl_bindings.cpp',
|
|
28
|
+
'./src/rcl_client_bindings.cpp',
|
|
29
|
+
'./src/rcl_context_bindings.cpp',
|
|
30
|
+
'./src/rcl_graph_bindings.cpp',
|
|
31
|
+
'./src/rcl_guard_condition_bindings.cpp',
|
|
26
32
|
'./src/rcl_handle.cpp',
|
|
27
33
|
'./src/rcl_lifecycle_bindings.cpp',
|
|
34
|
+
'./src/rcl_logging_bindings.cpp',
|
|
35
|
+
'./src/rcl_names_bindings.cpp',
|
|
36
|
+
'./src/rcl_node_bindings.cpp',
|
|
37
|
+
'./src/rcl_publisher_bindings.cpp',
|
|
38
|
+
'./src/rcl_service_bindings.cpp',
|
|
39
|
+
'./src/rcl_subscription_bindings.cpp',
|
|
40
|
+
'./src/rcl_time_point_bindings.cpp',
|
|
41
|
+
'./src/rcl_timer_bindings.cpp',
|
|
28
42
|
'./src/rcl_utilities.cpp',
|
|
29
43
|
'./src/shadow_node.cpp',
|
|
30
44
|
],
|
|
31
45
|
'include_dirs': [
|
|
32
46
|
'.',
|
|
33
|
-
"<!(node -e \"require('nan')\")",
|
|
34
47
|
'<(ros_include_root)',
|
|
48
|
+
"<!@(node -p \"require('node-addon-api').include\")",
|
|
35
49
|
],
|
|
36
50
|
'cflags!': [
|
|
37
51
|
'-fno-exceptions'
|
|
@@ -51,6 +65,7 @@
|
|
|
51
65
|
'-lrcl_lifecycle',
|
|
52
66
|
'-lrcutils',
|
|
53
67
|
'-lrcl_yaml_param_parser',
|
|
68
|
+
'-lrcpputils',
|
|
54
69
|
'-lrmw',
|
|
55
70
|
'-lrosidl_runtime_c',
|
|
56
71
|
],
|
|
@@ -151,6 +166,14 @@
|
|
|
151
166
|
]
|
|
152
167
|
}
|
|
153
168
|
],
|
|
169
|
+
[
|
|
170
|
+
# After Humble, e.g., Jazzy, Kilted.
|
|
171
|
+
'ros_version > 2205', {
|
|
172
|
+
'sources': [
|
|
173
|
+
'./src/rcl_type_description_service_bindings.cpp',
|
|
174
|
+
]
|
|
175
|
+
}
|
|
176
|
+
],
|
|
154
177
|
[
|
|
155
178
|
'runtime=="electron"', {
|
|
156
179
|
"defines": ["NODE_RUNTIME_ELECTRON=1"]
|
package/lib/action/client.js
CHANGED
|
@@ -19,6 +19,7 @@ const ActionInterfaces = require('./interfaces.js');
|
|
|
19
19
|
const ActionUuid = require('./uuid.js');
|
|
20
20
|
const ClientGoalHandle = require('./client_goal_handle.js');
|
|
21
21
|
const Deferred = require('./deferred.js');
|
|
22
|
+
const DistroUtils = require('../distro.js');
|
|
22
23
|
const Entity = require('../entity.js');
|
|
23
24
|
const loader = require('../interface_loader.js');
|
|
24
25
|
const QoS = require('../qos.js');
|
|
@@ -371,6 +372,45 @@ class ActionClient extends Entity {
|
|
|
371
372
|
|
|
372
373
|
this._node._destroyEntity(this, this._node._actionClients);
|
|
373
374
|
}
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* Get the number of wait set entities that make up an action entity.
|
|
378
|
+
* @return {object} - An object containing the number of various entities.
|
|
379
|
+
* @property {number} subscriptionsNumber - The number of subscriptions.
|
|
380
|
+
* @property {number} guardConditionsNumber - The number of guard conditions.
|
|
381
|
+
* @property {number} timersNumber - The number of timers.
|
|
382
|
+
* @property {number} clientsNumber - The number of clients.
|
|
383
|
+
* @property {number} servicesNumber - The number of services.
|
|
384
|
+
*/
|
|
385
|
+
getNumEntities() {
|
|
386
|
+
return rclnodejs.getNumEntities(this.handle);
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
/**
|
|
390
|
+
* Configure introspection.
|
|
391
|
+
* @param {Clock} clock - Clock to use for service event timestamps
|
|
392
|
+
* @param {QoS} qos - QoSProfile for the service event publisher
|
|
393
|
+
* @param {ServiceIntrospectionState} introspectionState - State to set introspection to
|
|
394
|
+
*/
|
|
395
|
+
configureIntrospection(clock, qos, introspectionState) {
|
|
396
|
+
if (DistroUtils.getDistroId() <= DistroUtils.getDistroId('jazzy')) {
|
|
397
|
+
console.warn(
|
|
398
|
+
'Configure action client introspection is not supported by this version of ROS 2'
|
|
399
|
+
);
|
|
400
|
+
return;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
let type = this.typeClass.type();
|
|
404
|
+
rclnodejs.configureActionClientIntrospection(
|
|
405
|
+
this.handle,
|
|
406
|
+
this._node.handle,
|
|
407
|
+
clock.handle,
|
|
408
|
+
type.interfaceName,
|
|
409
|
+
type.pkgName,
|
|
410
|
+
qos,
|
|
411
|
+
introspectionState
|
|
412
|
+
);
|
|
413
|
+
}
|
|
374
414
|
}
|
|
375
415
|
|
|
376
416
|
module.exports = ActionClient;
|
package/lib/action/server.js
CHANGED
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
const rclnodejs = require('bindings')('rclnodejs');
|
|
18
18
|
const ActionInterfaces = require('./interfaces.js');
|
|
19
19
|
const ActionUuid = require('./uuid.js');
|
|
20
|
+
const DistroUtils = require('../distro.js');
|
|
20
21
|
const Entity = require('../entity.js');
|
|
21
22
|
const { CancelResponse, GoalEvent, GoalResponse } = require('./response.js');
|
|
22
23
|
const loader = require('../interface_loader.js');
|
|
@@ -454,6 +455,26 @@ class ActionServer extends Entity {
|
|
|
454
455
|
|
|
455
456
|
this._node._destroyEntity(this, this._node._actionServers);
|
|
456
457
|
}
|
|
458
|
+
|
|
459
|
+
configureIntrospection(clock, qos, introspectionState) {
|
|
460
|
+
if (DistroUtils.getDistroId() <= DistroUtils.getDistroId('jazzy')) {
|
|
461
|
+
console.warn(
|
|
462
|
+
'Configure action server introspection is not supported by this version of ROS 2'
|
|
463
|
+
);
|
|
464
|
+
return;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
let type = this.typeClass.type();
|
|
468
|
+
rclnodejs.configureActionServerIntrospection(
|
|
469
|
+
this.handle,
|
|
470
|
+
this._node.handle,
|
|
471
|
+
clock.handle,
|
|
472
|
+
type.interfaceName,
|
|
473
|
+
type.pkgName,
|
|
474
|
+
qos,
|
|
475
|
+
introspectionState
|
|
476
|
+
);
|
|
477
|
+
}
|
|
457
478
|
}
|
|
458
479
|
|
|
459
480
|
module.exports = ActionServer;
|
package/lib/client.js
CHANGED
|
@@ -141,21 +141,20 @@ class Client extends Entity {
|
|
|
141
141
|
configureIntrospection(clock, qos, introspectionState) {
|
|
142
142
|
if (DistroUtils.getDistroId() <= DistroUtils.getDistroId('humble')) {
|
|
143
143
|
console.warn(
|
|
144
|
-
'Service introspection is not supported by this
|
|
144
|
+
'Service introspection is not supported by this version of ROS 2'
|
|
145
145
|
);
|
|
146
146
|
return;
|
|
147
147
|
}
|
|
148
148
|
|
|
149
149
|
let type = this.typeClass.type();
|
|
150
|
-
rclnodejs.
|
|
150
|
+
rclnodejs.configureClientIntrospection(
|
|
151
151
|
this.handle,
|
|
152
152
|
this._nodeHandle,
|
|
153
153
|
clock.handle,
|
|
154
154
|
type.interfaceName,
|
|
155
155
|
type.pkgName,
|
|
156
156
|
qos,
|
|
157
|
-
introspectionState
|
|
158
|
-
false
|
|
157
|
+
introspectionState
|
|
159
158
|
);
|
|
160
159
|
}
|
|
161
160
|
}
|
package/lib/context.js
CHANGED
|
@@ -219,6 +219,14 @@ class Context {
|
|
|
219
219
|
}
|
|
220
220
|
return defaultContext;
|
|
221
221
|
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Get the domain ID of this context.
|
|
225
|
+
* @returns {Number} domain ID of this context
|
|
226
|
+
*/
|
|
227
|
+
get domainId() {
|
|
228
|
+
return rclnodejs.getDomainId(this.handle);
|
|
229
|
+
}
|
|
222
230
|
}
|
|
223
231
|
|
|
224
232
|
Context._instances = [];
|
package/lib/distro.js
CHANGED
|
@@ -25,6 +25,7 @@ const DistroId = {
|
|
|
25
25
|
HUMBLE: 2205,
|
|
26
26
|
IRON: 2305,
|
|
27
27
|
JAZZY: 2405,
|
|
28
|
+
KILTED: 2505,
|
|
28
29
|
ROLLING: 5000,
|
|
29
30
|
};
|
|
30
31
|
|
|
@@ -35,6 +36,7 @@ DistroNameIdMap.set('galactic', DistroId.GALACTIC);
|
|
|
35
36
|
DistroNameIdMap.set('humble', DistroId.HUMBLE);
|
|
36
37
|
DistroNameIdMap.set('iron', DistroId.IRON);
|
|
37
38
|
DistroNameIdMap.set('jazzy', DistroId.JAZZY);
|
|
39
|
+
DistroNameIdMap.set('kilted', DistroId.KILTED);
|
|
38
40
|
DistroNameIdMap.set('rolling', DistroId.ROLLING);
|
|
39
41
|
|
|
40
42
|
const DistroUtils = {
|
package/lib/lifecycle.js
CHANGED
|
@@ -591,6 +591,15 @@ class LifecycleNode extends Node {
|
|
|
591
591
|
return this._changeState(SHUTDOWN_TRANSITION_LABEL, callbackReturnValue);
|
|
592
592
|
}
|
|
593
593
|
|
|
594
|
+
/**
|
|
595
|
+
* Check if state machine is initialized.
|
|
596
|
+
*
|
|
597
|
+
* @returns {boolean} true if the state machine is initialized; otherwise false.
|
|
598
|
+
*/
|
|
599
|
+
get isInitialized() {
|
|
600
|
+
return rclnodejs.isInitialized(this._stateMachineHandle);
|
|
601
|
+
}
|
|
602
|
+
|
|
594
603
|
/**
|
|
595
604
|
* The GetState service handler.
|
|
596
605
|
* @param {Object} request - The GetState service request.
|
package/lib/logging.js
CHANGED
|
@@ -39,14 +39,31 @@ let LoggingSeverity = {
|
|
|
39
39
|
|
|
40
40
|
class Caller {
|
|
41
41
|
constructor() {
|
|
42
|
-
this._info = {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
42
|
+
this._info = {
|
|
43
|
+
functionName: 'unknown',
|
|
44
|
+
fileName: 'unknown',
|
|
45
|
+
lineNumber: 'unknown',
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const stackLines = new Error().stack.split('\n');
|
|
49
|
+
|
|
50
|
+
// Adjust the index (usually 3 or 4) to correctly point to the caller frame.
|
|
51
|
+
const callerFrame = stackLines[4] || stackLines[3];
|
|
52
|
+
// Match both named and anonymous function stack frames.
|
|
53
|
+
const frameRegex = /^\s*at\s+(?:(.+)\s+\()?(.+):(\d+):(\d+)\)?$/;
|
|
54
|
+
const match = callerFrame.match(frameRegex);
|
|
55
|
+
if (match && match.length === 5) {
|
|
56
|
+
this._info.functionName = match[1] || '(anonymous)';
|
|
57
|
+
this._info.fileName = path.basename(match[2]);
|
|
58
|
+
this._info.lineNumber = match[3];
|
|
59
|
+
} else {
|
|
60
|
+
// Handle anonymous functions or different stack formats.
|
|
61
|
+
const altMatch = callerFrame.match(/at\s+(.*):(\d+):(\d+)/i);
|
|
62
|
+
if (altMatch && altMatch.length >= 4) {
|
|
63
|
+
this._info.functionName = '(anonymous)';
|
|
64
|
+
this._info.fileName = path.basename(altMatch[1]);
|
|
65
|
+
this._info.lineNumber = altMatch[2];
|
|
66
|
+
}
|
|
50
67
|
}
|
|
51
68
|
}
|
|
52
69
|
|
|
@@ -156,7 +173,7 @@ class Logging {
|
|
|
156
173
|
severity,
|
|
157
174
|
message,
|
|
158
175
|
caller.functionName,
|
|
159
|
-
caller.lineNumber,
|
|
176
|
+
parseInt(caller.lineNumber, 10),
|
|
160
177
|
caller.fileName
|
|
161
178
|
);
|
|
162
179
|
}
|
package/lib/node.js
CHANGED
|
@@ -21,6 +21,7 @@ const Client = require('./client.js');
|
|
|
21
21
|
const Clock = require('./clock.js');
|
|
22
22
|
const Context = require('./context.js');
|
|
23
23
|
const debug = require('debug')('rclnodejs:node');
|
|
24
|
+
const DistroUtils = require('./distro.js');
|
|
24
25
|
const GuardCondition = require('./guard_condition.js');
|
|
25
26
|
const loader = require('./interface_loader.js');
|
|
26
27
|
const Logging = require('./logging.js');
|
|
@@ -38,6 +39,7 @@ const Service = require('./service.js');
|
|
|
38
39
|
const Subscription = require('./subscription.js');
|
|
39
40
|
const TimeSource = require('./time_source.js');
|
|
40
41
|
const Timer = require('./timer.js');
|
|
42
|
+
const TypeDescriptionService = require('./type_description_service.js');
|
|
41
43
|
const Entity = require('./entity.js');
|
|
42
44
|
|
|
43
45
|
// Parameter event publisher constants
|
|
@@ -100,6 +102,7 @@ class Node extends rclnodejs.ShadowNode {
|
|
|
100
102
|
this._parameterDescriptors = new Map();
|
|
101
103
|
this._parameters = new Map();
|
|
102
104
|
this._parameterService = null;
|
|
105
|
+
this._typeDescriptionService = null;
|
|
103
106
|
this._parameterEventPublisher = null;
|
|
104
107
|
this._setParametersCallbacks = [];
|
|
105
108
|
this._logger = new Logging(rclnodejs.getNodeLoggerName(this.handle));
|
|
@@ -146,6 +149,14 @@ class Node extends rclnodejs.ShadowNode {
|
|
|
146
149
|
this._parameterService = new ParameterService(this);
|
|
147
150
|
this._parameterService.start();
|
|
148
151
|
}
|
|
152
|
+
|
|
153
|
+
if (
|
|
154
|
+
DistroUtils.getDistroId() >= DistroUtils.getDistroId('jazzy') &&
|
|
155
|
+
options.startTypeDescriptionService
|
|
156
|
+
) {
|
|
157
|
+
this._typeDescriptionService = new TypeDescriptionService(this);
|
|
158
|
+
this._typeDescriptionService.start();
|
|
159
|
+
}
|
|
149
160
|
}
|
|
150
161
|
|
|
151
162
|
execute(handles) {
|
|
@@ -1013,6 +1024,32 @@ class Node extends rclnodejs.ShadowNode {
|
|
|
1013
1024
|
return rclnodejs.getServiceNamesAndTypes(this.handle);
|
|
1014
1025
|
}
|
|
1015
1026
|
|
|
1027
|
+
/**
|
|
1028
|
+
* Get a list of publishers on a given topic.
|
|
1029
|
+
* @param {string} topic - the topic name to get the publishers for.
|
|
1030
|
+
* @param {boolean} noDemangle - if `true`, `topic_name` needs to be a valid middleware topic name,
|
|
1031
|
+
* otherwise it should be a valid ROS topic name.
|
|
1032
|
+
* @returns {Array} - list of publishers
|
|
1033
|
+
*/
|
|
1034
|
+
getPublishersInfoByTopic(topic, noDemangle) {
|
|
1035
|
+
return rclnodejs.getPublishersInfoByTopic(this.handle, topic, noDemangle);
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
/**
|
|
1039
|
+
* Get a list of subscriptions on a given topic.
|
|
1040
|
+
* @param {string} topic - the topic name to get the subscriptions for.
|
|
1041
|
+
* @param {boolean} noDemangle - if `true`, `topic_name` needs to be a valid middleware topic name,
|
|
1042
|
+
* otherwise it should be a valid ROS topic name.
|
|
1043
|
+
* @returns {Array} - list of subscriptions
|
|
1044
|
+
*/
|
|
1045
|
+
getSubscriptionsInfoByTopic(topic, noDemangle) {
|
|
1046
|
+
return rclnodejs.getSubscriptionsInfoByTopic(
|
|
1047
|
+
this.handle,
|
|
1048
|
+
topic,
|
|
1049
|
+
noDemangle
|
|
1050
|
+
);
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1016
1053
|
/**
|
|
1017
1054
|
* Get the list of nodes discovered by the provided node.
|
|
1018
1055
|
* @return {Array<string>} - An array of the names.
|
|
@@ -1026,7 +1063,15 @@ class Node extends rclnodejs.ShadowNode {
|
|
|
1026
1063
|
* @return {Array<{name: string, namespace: string}>} An array of the names and namespaces.
|
|
1027
1064
|
*/
|
|
1028
1065
|
getNodeNamesAndNamespaces() {
|
|
1029
|
-
return rclnodejs.getNodeNames(this.handle);
|
|
1066
|
+
return rclnodejs.getNodeNames(this.handle, /*getEnclaves=*/ false);
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1069
|
+
/**
|
|
1070
|
+
* Get the list of nodes and their namespaces with enclaves discovered by the provided node.
|
|
1071
|
+
* @return {Array<{name: string, namespace: string, enclave: string}>} An array of the names, namespaces and enclaves.
|
|
1072
|
+
*/
|
|
1073
|
+
getNodeNamesAndNamespacesWithEnclaves() {
|
|
1074
|
+
return rclnodejs.getNodeNames(this.handle, /*getEnclaves=*/ true);
|
|
1030
1075
|
}
|
|
1031
1076
|
|
|
1032
1077
|
/**
|
|
@@ -1061,6 +1106,32 @@ class Node extends rclnodejs.ShadowNode {
|
|
|
1061
1106
|
return rclnodejs.countSubscribers(this.handle, expandedTopic);
|
|
1062
1107
|
}
|
|
1063
1108
|
|
|
1109
|
+
/**
|
|
1110
|
+
* Get the number of clients on a given service name.
|
|
1111
|
+
* @param {string} serviceName - the service name
|
|
1112
|
+
* @returns {Number}
|
|
1113
|
+
*/
|
|
1114
|
+
countClients(serviceName) {
|
|
1115
|
+
if (DistroUtils.getDistroId() <= DistroUtils.getDistroId('humble')) {
|
|
1116
|
+
console.warn('countClients is not supported by this version of ROS 2');
|
|
1117
|
+
return null;
|
|
1118
|
+
}
|
|
1119
|
+
return rclnodejs.countClients(this.handle, serviceName);
|
|
1120
|
+
}
|
|
1121
|
+
|
|
1122
|
+
/**
|
|
1123
|
+
* Get the number of services on a given service name.
|
|
1124
|
+
* @param {string} serviceName - the service name
|
|
1125
|
+
* @returns {Number}
|
|
1126
|
+
*/
|
|
1127
|
+
countServices(serviceName) {
|
|
1128
|
+
if (DistroUtils.getDistroId() <= DistroUtils.getDistroId('humble')) {
|
|
1129
|
+
console.warn('countServices is not supported by this version of ROS 2');
|
|
1130
|
+
return null;
|
|
1131
|
+
}
|
|
1132
|
+
return rclnodejs.countServices(this.handle, serviceName);
|
|
1133
|
+
}
|
|
1134
|
+
|
|
1064
1135
|
/**
|
|
1065
1136
|
* Get the list of parameter-overrides found on the commandline and
|
|
1066
1137
|
* in the NodeOptions.parameter_overrides property.
|
|
@@ -1557,6 +1628,15 @@ class Node extends rclnodejs.ShadowNode {
|
|
|
1557
1628
|
}
|
|
1558
1629
|
}
|
|
1559
1630
|
|
|
1631
|
+
/**
|
|
1632
|
+
* Get the fully qualified name of the node.
|
|
1633
|
+
*
|
|
1634
|
+
* @returns {string} - String containing the fully qualified name of the node.
|
|
1635
|
+
*/
|
|
1636
|
+
getFullyQualifiedName() {
|
|
1637
|
+
return rclnodejs.getFullyQualifiedName(this.handle);
|
|
1638
|
+
}
|
|
1639
|
+
|
|
1560
1640
|
// returns on 1st error or result {successful, reason}
|
|
1561
1641
|
_validateParameters(parameters = [], declareParameterMode = false) {
|
|
1562
1642
|
for (const parameter of parameters) {
|
package/lib/node_options.js
CHANGED
|
@@ -26,16 +26,19 @@ class NodeOptions {
|
|
|
26
26
|
* @param {boolean} [startParameterServices=true]
|
|
27
27
|
* @param {array} [parameterOverrides=[]]
|
|
28
28
|
* @param {boolean} [automaticallyDeclareParametersFromOverrides=false]
|
|
29
|
+
* @param {boolean} [startTypeDescriptionService=true]
|
|
29
30
|
*/
|
|
30
31
|
constructor(
|
|
31
32
|
startParameterServices = true,
|
|
32
33
|
parameterOverrides = [],
|
|
33
|
-
automaticallyDeclareParametersFromOverrides = false
|
|
34
|
+
automaticallyDeclareParametersFromOverrides = false,
|
|
35
|
+
startTypeDescriptionService = true
|
|
34
36
|
) {
|
|
35
37
|
this._startParameterServices = startParameterServices;
|
|
36
38
|
this._parameterOverrides = parameterOverrides;
|
|
37
39
|
this._automaticallyDeclareParametersFromOverrides =
|
|
38
40
|
automaticallyDeclareParametersFromOverrides;
|
|
41
|
+
this._startTypeDescriptionService = startTypeDescriptionService;
|
|
39
42
|
}
|
|
40
43
|
|
|
41
44
|
/**
|
|
@@ -105,6 +108,23 @@ class NodeOptions {
|
|
|
105
108
|
this._automaticallyDeclareParametersFromOverrides = declareParamsFlag;
|
|
106
109
|
}
|
|
107
110
|
|
|
111
|
+
/**
|
|
112
|
+
* Get the startTypeDescriptionService option, only available for ROS2 > Humble.
|
|
113
|
+
* Default value = true;
|
|
114
|
+
* @returns {boolean} - true if the type description service is enabled.
|
|
115
|
+
*/
|
|
116
|
+
get startTypeDescriptionService() {
|
|
117
|
+
return this._startTypeDescriptionService;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Set startTypeDescriptionService, only available for ROS2 > Humble
|
|
122
|
+
* @param {boolean} willStartTypeDescriptionService
|
|
123
|
+
*/
|
|
124
|
+
set startTypeDescriptionService(willStartTypeDescriptionService) {
|
|
125
|
+
this._startTypeDescriptionService = willStartTypeDescriptionService;
|
|
126
|
+
}
|
|
127
|
+
|
|
108
128
|
/**
|
|
109
129
|
* Return an instance configured with default options.
|
|
110
130
|
* @returns {NodeOptions} - An instance with default values.
|
package/lib/publisher.js
CHANGED
|
@@ -72,6 +72,33 @@ class Publisher extends Entity {
|
|
|
72
72
|
);
|
|
73
73
|
return new Publisher(handle, typeClass, topic, options);
|
|
74
74
|
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Get the number of subscriptions to this publisher.
|
|
78
|
+
* @returns {number} The number of subscriptions
|
|
79
|
+
*/
|
|
80
|
+
get subscriptionCount() {
|
|
81
|
+
return rclnodejs.getSubscriptionCount(this._handle);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Wait until all published message data is acknowledged or until the specified timeout elapses
|
|
86
|
+
*
|
|
87
|
+
* If the timeout is negative then this function will block indefinitely until all published
|
|
88
|
+
* message data is acknowledged.
|
|
89
|
+
* If the timeout is 0 then it will check if all published message has been acknowledged without
|
|
90
|
+
* waiting.
|
|
91
|
+
* If the timeout is greater than 0 then it will return after that period of time has elapsed or
|
|
92
|
+
* all published message data is acknowledged.
|
|
93
|
+
*
|
|
94
|
+
* Raises an error if failed, such as the middleware not supporting this feature.
|
|
95
|
+
*
|
|
96
|
+
* @param {timeout} timeout - The duration to wait for all published message data to be acknowledged in nanoseconds.
|
|
97
|
+
* @return {boolean} `true` if all published message data is acknowledged before the timeout, otherwise `false`.
|
|
98
|
+
*/
|
|
99
|
+
waitForAllAcked(timeout) {
|
|
100
|
+
return rclnodejs.waitForAllAcked(this._handle, timeout);
|
|
101
|
+
}
|
|
75
102
|
}
|
|
76
103
|
|
|
77
104
|
module.exports = Publisher;
|
package/lib/service.js
CHANGED
|
@@ -125,7 +125,7 @@ class Service extends Entity {
|
|
|
125
125
|
configureIntrospection(clock, qos, introspectionState) {
|
|
126
126
|
if (DistroUtils.getDistroId() <= DistroUtils.getDistroId('humble')) {
|
|
127
127
|
console.warn(
|
|
128
|
-
'Service introspection is not supported by this
|
|
128
|
+
'Service introspection is not supported by this version of ROS 2'
|
|
129
129
|
);
|
|
130
130
|
return;
|
|
131
131
|
}
|
|
@@ -138,10 +138,17 @@ class Service extends Entity {
|
|
|
138
138
|
type.interfaceName,
|
|
139
139
|
type.pkgName,
|
|
140
140
|
qos,
|
|
141
|
-
introspectionState
|
|
142
|
-
true
|
|
141
|
+
introspectionState
|
|
143
142
|
);
|
|
144
143
|
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Get the options of this service.
|
|
147
|
+
* @return {object} The options of this service.
|
|
148
|
+
*/
|
|
149
|
+
getOptions() {
|
|
150
|
+
return rclnodejs.getOptions(this._handle);
|
|
151
|
+
}
|
|
145
152
|
}
|
|
146
153
|
|
|
147
154
|
module.exports = Service;
|
package/lib/subscription.js
CHANGED
|
@@ -116,6 +116,14 @@ class Subscription extends Entity {
|
|
|
116
116
|
? rclnodejs.clearContentFilter(this.handle)
|
|
117
117
|
: true;
|
|
118
118
|
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Get the number of publishers to this subscription.
|
|
122
|
+
* @returns {number} The number of publishers
|
|
123
|
+
*/
|
|
124
|
+
get publisherCount() {
|
|
125
|
+
return rclnodejs.getPublisherCount(this._handle);
|
|
126
|
+
}
|
|
119
127
|
}
|
|
120
128
|
|
|
121
129
|
module.exports = Subscription;
|
package/lib/timer.js
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
'use strict';
|
|
16
16
|
|
|
17
17
|
const rclnodejs = require('bindings')('rclnodejs');
|
|
18
|
+
const DistroUtils = require('./distro.js');
|
|
18
19
|
|
|
19
20
|
/**
|
|
20
21
|
* @class - Class representing a Timer in ROS
|
|
@@ -86,6 +87,37 @@ class Timer {
|
|
|
86
87
|
timeUntilNextCall() {
|
|
87
88
|
return rclnodejs.timerGetTimeUntilNextCall(this._handle);
|
|
88
89
|
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Change the timer period.
|
|
93
|
+
* @param {bigint} period - The new period in nanoseconds.
|
|
94
|
+
* @return {undefined}
|
|
95
|
+
*/
|
|
96
|
+
changeTimerPeriod(period) {
|
|
97
|
+
rclnodejs.changeTimerPeriod(this._handle, period);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Get the timer period.
|
|
102
|
+
* @return {bigint} - The period in nanoseconds.
|
|
103
|
+
*/
|
|
104
|
+
get timerPeriod() {
|
|
105
|
+
return rclnodejs.getTimerPeriod(this._handle);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Call a timer and starts counting again, retrieves actual and expected call time.
|
|
110
|
+
* @return {object} - The timer information.
|
|
111
|
+
*/
|
|
112
|
+
callTimerWithInfo() {
|
|
113
|
+
if (DistroUtils.getDistroId() <= DistroUtils.getDistroId('humble')) {
|
|
114
|
+
console.warn(
|
|
115
|
+
'callTimerWithInfo is not supported by this version of ROS 2'
|
|
116
|
+
);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
return rclnodejs.callTimerWithInfo(this._handle);
|
|
120
|
+
}
|
|
89
121
|
}
|
|
90
122
|
|
|
91
123
|
module.exports = Timer;
|
|
@@ -0,0 +1,82 @@
|
|
|
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 loader = require('./interface_loader.js');
|
|
18
|
+
const rclnodejs = require('bindings')('rclnodejs');
|
|
19
|
+
const Service = require('./service.js');
|
|
20
|
+
|
|
21
|
+
// This class is used to create a TypeDescriptionService which can be used to
|
|
22
|
+
// retrieve information about types used by the node’s publishers, subscribers,
|
|
23
|
+
// services or actions.
|
|
24
|
+
class TypeDescriptionService {
|
|
25
|
+
constructor(node) {
|
|
26
|
+
this._node = node;
|
|
27
|
+
this._serviceName = this._node.name() + '/get_type_description';
|
|
28
|
+
this._typeDescriptionServiceHandle = rclnodejs.initTypeDescriptionService(
|
|
29
|
+
this._node.handle
|
|
30
|
+
);
|
|
31
|
+
this._typeClass = loader.loadInterface(
|
|
32
|
+
'type_description_interfaces/srv/GetTypeDescription'
|
|
33
|
+
);
|
|
34
|
+
this._typeDescriptionService = null;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
start() {
|
|
38
|
+
if (this._typeDescriptionService) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
this._typeDescriptionService = new Service(
|
|
43
|
+
this._node.handle,
|
|
44
|
+
this._typeDescriptionServiceHandle,
|
|
45
|
+
this._serviceName,
|
|
46
|
+
this._typeClass,
|
|
47
|
+
this._node._validateOptions(undefined),
|
|
48
|
+
(request, response) => {
|
|
49
|
+
const responseToBeSent = new this._typeClass.Response();
|
|
50
|
+
const requestReceived = new this._typeClass.Request(request);
|
|
51
|
+
rclnodejs.handleRequest(
|
|
52
|
+
this._node.handle,
|
|
53
|
+
requestReceived.serialize(),
|
|
54
|
+
responseToBeSent.serialize()
|
|
55
|
+
);
|
|
56
|
+
responseToBeSent.deserialize(responseToBeSent.refObject);
|
|
57
|
+
rclnodejs.sendResponse(
|
|
58
|
+
this._typeDescriptionServiceHandle,
|
|
59
|
+
responseToBeSent.serialize(),
|
|
60
|
+
response._header
|
|
61
|
+
);
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
);
|
|
65
|
+
this._node._services.push(this._typeDescriptionService);
|
|
66
|
+
this._node.syncHandles();
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Get the node this
|
|
71
|
+
* @return {Node} - The supported node.
|
|
72
|
+
*/
|
|
73
|
+
get node() {
|
|
74
|
+
return this._node;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
static toTypeHash(topicTypeHash) {
|
|
78
|
+
return `RIHS0${topicTypeHash.version}_${topicTypeHash.value.toString('hex')}`;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
module.exports = TypeDescriptionService;
|