rclnodejs 1.2.0 → 1.3.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 +1 -0
- package/index.js +26 -3
- package/lib/context.js +4 -2
- package/lib/lifecycle.js +9 -0
- package/lib/node.js +106 -18
- package/lib/serialization.js +60 -0
- package/lib/type_description_service.js +27 -1
- package/package.json +1 -1
- package/rosidl_gen/templates/message.dot +1 -1
- package/scripts/npmjs-readme.md +1 -1
- package/src/addon.cpp +2 -0
- package/src/macros.h +17 -1
- package/src/rcl_action_client_bindings.cpp +3 -2
- package/src/rcl_action_goal_bindings.cpp +3 -2
- package/src/rcl_action_server_bindings.cpp +7 -5
- package/src/rcl_client_bindings.cpp +4 -3
- package/src/rcl_context_bindings.cpp +29 -19
- package/src/rcl_guard_condition_bindings.cpp +3 -2
- package/src/rcl_lifecycle_bindings.cpp +18 -4
- package/src/rcl_node_bindings.cpp +105 -3
- package/src/rcl_publisher_bindings.cpp +4 -3
- package/src/rcl_serialization_bindings.cpp +116 -0
- package/src/rcl_serialization_bindings.h +26 -0
- package/src/rcl_service_bindings.cpp +4 -3
- package/src/rcl_subscription_bindings.cpp +3 -2
- package/src/rcl_time_point_bindings.cpp +3 -2
- package/src/rcl_timer_bindings.cpp +8 -6
- package/src/rcl_utilities.cpp +31 -0
- package/src/rcl_utilities.h +7 -0
- package/tsconfig.json +2 -2
- package/types/context.d.ts +3 -2
- package/types/index.d.ts +26 -1
- package/types/lifecycle.d.ts +7 -0
- package/types/node.d.ts +48 -8
package/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 [v1.
|
|
48
|
+
| latest version (currently [v1.3.0](https://github.com/RobotWebTools/rclnodejs/tree/1.3.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
|
@@ -35,6 +35,7 @@
|
|
|
35
35
|
'./src/rcl_names_bindings.cpp',
|
|
36
36
|
'./src/rcl_node_bindings.cpp',
|
|
37
37
|
'./src/rcl_publisher_bindings.cpp',
|
|
38
|
+
'./src/rcl_serialization_bindings.cpp',
|
|
38
39
|
'./src/rcl_service_bindings.cpp',
|
|
39
40
|
'./src/rcl_subscription_bindings.cpp',
|
|
40
41
|
'./src/rcl_time_point_bindings.cpp',
|
package/index.js
CHANGED
|
@@ -53,6 +53,10 @@ const {
|
|
|
53
53
|
getActionNamesAndTypes,
|
|
54
54
|
} = require('./lib/action/graph.js');
|
|
55
55
|
const ServiceIntrospectionStates = require('./lib/service_introspection.js');
|
|
56
|
+
const {
|
|
57
|
+
serializeMessage,
|
|
58
|
+
deserializeMessage,
|
|
59
|
+
} = require('./lib/serialization.js');
|
|
56
60
|
|
|
57
61
|
/**
|
|
58
62
|
* Get the version of the generator that was used for the currently present interfaces.
|
|
@@ -183,12 +187,22 @@ let rcl = {
|
|
|
183
187
|
/** {@link getActionNamesAndTypes} function */
|
|
184
188
|
getActionNamesAndTypes: getActionNamesAndTypes,
|
|
185
189
|
|
|
190
|
+
/** {@link serializeMessage} function */
|
|
191
|
+
serializeMessage: serializeMessage,
|
|
192
|
+
|
|
193
|
+
/** {@link deserializeMessage} function */
|
|
194
|
+
deserializeMessage: deserializeMessage,
|
|
195
|
+
|
|
186
196
|
/**
|
|
187
197
|
* Create and initialize a node.
|
|
188
198
|
* @param {string} nodeName - The name used to register in ROS.
|
|
189
199
|
* @param {string} [namespace=''] - The namespace used in ROS.
|
|
190
200
|
* @param {Context} [context=Context.defaultContext()] - The context to create the node in.
|
|
191
201
|
* @param {NodeOptions} [options=NodeOptions.defaultOptions] - The options to configure the new node behavior.
|
|
202
|
+
* @param {Array} [args=[]] - The arguments to pass to the node.
|
|
203
|
+
* @param {boolean} [useGlobalArguments=true] - If true, the node will use the global arguments
|
|
204
|
+
* from the context, otherwise it will only use the arguments
|
|
205
|
+
* passed in the args parameter.
|
|
192
206
|
* @return {Node} A new instance of the specified node.
|
|
193
207
|
* @throws {Error} If the given context is not registered.
|
|
194
208
|
* @deprecated since 0.18.0, Use new Node constructor.
|
|
@@ -197,9 +211,18 @@ let rcl = {
|
|
|
197
211
|
nodeName,
|
|
198
212
|
namespace = '',
|
|
199
213
|
context = Context.defaultContext(),
|
|
200
|
-
options = NodeOptions.defaultOptions
|
|
214
|
+
options = NodeOptions.defaultOptions,
|
|
215
|
+
args = [],
|
|
216
|
+
useGlobalArguments = true
|
|
201
217
|
) {
|
|
202
|
-
return new this.Node(
|
|
218
|
+
return new this.Node(
|
|
219
|
+
nodeName,
|
|
220
|
+
namespace,
|
|
221
|
+
context,
|
|
222
|
+
options,
|
|
223
|
+
args,
|
|
224
|
+
useGlobalArguments
|
|
225
|
+
);
|
|
203
226
|
},
|
|
204
227
|
|
|
205
228
|
/**
|
|
@@ -255,7 +278,7 @@ let rcl = {
|
|
|
255
278
|
throw new TypeError('argv elements must be strings (and not null).');
|
|
256
279
|
}
|
|
257
280
|
|
|
258
|
-
rclnodejs.init(context.handle, argv);
|
|
281
|
+
rclnodejs.init(context.handle, argv, context._domainId);
|
|
259
282
|
|
|
260
283
|
if (_rosVersionChecked) {
|
|
261
284
|
// no further processing required
|
package/lib/context.js
CHANGED
|
@@ -63,11 +63,13 @@ class Context {
|
|
|
63
63
|
* Call rcl.init(context) to initialize this context state for
|
|
64
64
|
* use in creating nodes, etc.
|
|
65
65
|
* @constructor
|
|
66
|
+
* @param {bigint} - Optional, The domain ID of this context.
|
|
66
67
|
*/
|
|
67
|
-
constructor() {
|
|
68
|
+
constructor(domainId) {
|
|
68
69
|
this._handle = rclnodejs.createContext();
|
|
69
70
|
this._isShutdown = false;
|
|
70
71
|
this._nodes = [];
|
|
72
|
+
this._domainId = domainId;
|
|
71
73
|
Context._instances.push(this);
|
|
72
74
|
}
|
|
73
75
|
|
|
@@ -222,7 +224,7 @@ class Context {
|
|
|
222
224
|
|
|
223
225
|
/**
|
|
224
226
|
* Get the domain ID of this context.
|
|
225
|
-
* @returns {
|
|
227
|
+
* @returns {bigint} domain ID of this context
|
|
226
228
|
*/
|
|
227
229
|
get domainId() {
|
|
228
230
|
return rclnodejs.getDomainId(this.handle);
|
package/lib/lifecycle.js
CHANGED
|
@@ -600,6 +600,15 @@ class LifecycleNode extends Node {
|
|
|
600
600
|
return rclnodejs.isInitialized(this._stateMachineHandle);
|
|
601
601
|
}
|
|
602
602
|
|
|
603
|
+
/**
|
|
604
|
+
* Log the state machine data.
|
|
605
|
+
*
|
|
606
|
+
* @returns {undefined} void.
|
|
607
|
+
*/
|
|
608
|
+
print() {
|
|
609
|
+
rclnodejs.print(this._stateMachineHandle);
|
|
610
|
+
}
|
|
611
|
+
|
|
603
612
|
/**
|
|
604
613
|
* The GetState service handler.
|
|
605
614
|
* @param {Object} request - The GetState service request.
|
package/lib/node.js
CHANGED
|
@@ -43,6 +43,7 @@ const TypeDescriptionService = require('./type_description_service.js');
|
|
|
43
43
|
const Entity = require('./entity.js');
|
|
44
44
|
const { SubscriptionEventCallbacks } = require('../lib/event_handler.js');
|
|
45
45
|
const { PublisherEventCallbacks } = require('../lib/event_handler.js');
|
|
46
|
+
const { validateFullTopicName } = require('./validator.js');
|
|
46
47
|
|
|
47
48
|
// Parameter event publisher constants
|
|
48
49
|
const PARAMETER_EVENT_MSG_TYPE = 'rcl_interfaces/msg/ParameterEvent';
|
|
@@ -66,7 +67,9 @@ class Node extends rclnodejs.ShadowNode {
|
|
|
66
67
|
nodeName,
|
|
67
68
|
namespace = '',
|
|
68
69
|
context = Context.defaultContext(),
|
|
69
|
-
options = NodeOptions.defaultOptions
|
|
70
|
+
options = NodeOptions.defaultOptions,
|
|
71
|
+
args = [],
|
|
72
|
+
useGlobalArguments = true
|
|
70
73
|
) {
|
|
71
74
|
super();
|
|
72
75
|
|
|
@@ -74,7 +77,7 @@ class Node extends rclnodejs.ShadowNode {
|
|
|
74
77
|
throw new TypeError('Invalid argument.');
|
|
75
78
|
}
|
|
76
79
|
|
|
77
|
-
this._init(nodeName, namespace, options, context);
|
|
80
|
+
this._init(nodeName, namespace, options, context, args, useGlobalArguments);
|
|
78
81
|
debug(
|
|
79
82
|
'Finish initializing node, name = %s and namespace = %s.',
|
|
80
83
|
nodeName,
|
|
@@ -82,8 +85,14 @@ class Node extends rclnodejs.ShadowNode {
|
|
|
82
85
|
);
|
|
83
86
|
}
|
|
84
87
|
|
|
85
|
-
_init(name, namespace, options, context) {
|
|
86
|
-
this.handle = rclnodejs.createNode(
|
|
88
|
+
_init(name, namespace, options, context, args, useGlobalArguments) {
|
|
89
|
+
this.handle = rclnodejs.createNode(
|
|
90
|
+
name,
|
|
91
|
+
namespace,
|
|
92
|
+
context.handle,
|
|
93
|
+
args,
|
|
94
|
+
useGlobalArguments
|
|
95
|
+
);
|
|
87
96
|
Object.defineProperty(this, 'handle', {
|
|
88
97
|
configurable: false,
|
|
89
98
|
writable: false,
|
|
@@ -1064,27 +1073,57 @@ class Node extends rclnodejs.ShadowNode {
|
|
|
1064
1073
|
}
|
|
1065
1074
|
|
|
1066
1075
|
/**
|
|
1067
|
-
*
|
|
1068
|
-
*
|
|
1069
|
-
*
|
|
1070
|
-
*
|
|
1076
|
+
* Return a list of publishers on a given topic.
|
|
1077
|
+
*
|
|
1078
|
+
* The returned parameter is a list of TopicEndpointInfo objects, where each will contain
|
|
1079
|
+
* the node name, node namespace, topic type, topic endpoint's GID, and its QoS profile.
|
|
1080
|
+
*
|
|
1081
|
+
* When the `no_mangle` parameter is `true`, the provided `topic` should be a valid
|
|
1082
|
+
* topic name for the middleware (useful when combining ROS with native middleware (e.g. DDS)
|
|
1083
|
+
* apps). When the `no_mangle` parameter is `false`, the provided `topic` should
|
|
1084
|
+
* follow ROS topic name conventions.
|
|
1085
|
+
*
|
|
1086
|
+
* `topic` may be a relative, private, or fully qualified topic name.
|
|
1087
|
+
* A relative or private topic will be expanded using this node's namespace and name.
|
|
1088
|
+
* The queried `topic` is not remapped.
|
|
1089
|
+
*
|
|
1090
|
+
* @param {string} topic - The topic on which to find the publishers.
|
|
1091
|
+
* @param {boolean} [noDemangle=false] - If `true`, `topic` needs to be a valid middleware topic
|
|
1092
|
+
* name, otherwise it should be a valid ROS topic name. Defaults to `false`.
|
|
1071
1093
|
* @returns {Array} - list of publishers
|
|
1072
1094
|
*/
|
|
1073
|
-
getPublishersInfoByTopic(topic, noDemangle) {
|
|
1074
|
-
return rclnodejs.getPublishersInfoByTopic(
|
|
1095
|
+
getPublishersInfoByTopic(topic, noDemangle = false) {
|
|
1096
|
+
return rclnodejs.getPublishersInfoByTopic(
|
|
1097
|
+
this.handle,
|
|
1098
|
+
this._getValidatedTopic(topic, noDemangle),
|
|
1099
|
+
noDemangle
|
|
1100
|
+
);
|
|
1075
1101
|
}
|
|
1076
1102
|
|
|
1077
1103
|
/**
|
|
1078
|
-
*
|
|
1079
|
-
*
|
|
1080
|
-
*
|
|
1081
|
-
*
|
|
1104
|
+
* Return a list of subscriptions on a given topic.
|
|
1105
|
+
*
|
|
1106
|
+
* The returned parameter is a list of TopicEndpointInfo objects, where each will contain
|
|
1107
|
+
* the node name, node namespace, topic type, topic endpoint's GID, and its QoS profile.
|
|
1108
|
+
*
|
|
1109
|
+
* When the `no_mangle` parameter is `true`, the provided `topic` should be a valid
|
|
1110
|
+
* topic name for the middleware (useful when combining ROS with native middleware (e.g. DDS)
|
|
1111
|
+
* apps). When the `no_mangle` parameter is `false`, the provided `topic` should
|
|
1112
|
+
* follow ROS topic name conventions.
|
|
1113
|
+
*
|
|
1114
|
+
* `topic` may be a relative, private, or fully qualified topic name.
|
|
1115
|
+
* A relative or private topic will be expanded using this node's namespace and name.
|
|
1116
|
+
* The queried `topic` is not remapped.
|
|
1117
|
+
*
|
|
1118
|
+
* @param {string} topic - The topic on which to find the subscriptions.
|
|
1119
|
+
* @param {boolean} [noDemangle=false] - If `true`, `topic` needs to be a valid middleware topic
|
|
1120
|
+
name, otherwise it should be a valid ROS topic name. Defaults to `false`.
|
|
1082
1121
|
* @returns {Array} - list of subscriptions
|
|
1083
1122
|
*/
|
|
1084
|
-
getSubscriptionsInfoByTopic(topic, noDemangle) {
|
|
1123
|
+
getSubscriptionsInfoByTopic(topic, noDemangle = false) {
|
|
1085
1124
|
return rclnodejs.getSubscriptionsInfoByTopic(
|
|
1086
1125
|
this.handle,
|
|
1087
|
-
topic,
|
|
1126
|
+
this._getValidatedTopic(topic, noDemangle),
|
|
1088
1127
|
noDemangle
|
|
1089
1128
|
);
|
|
1090
1129
|
}
|
|
@@ -1420,7 +1459,7 @@ class Node extends rclnodejs.ShadowNode {
|
|
|
1420
1459
|
* Determine if a parameter descriptor exists.
|
|
1421
1460
|
*
|
|
1422
1461
|
* @param {string} name - The name of a descriptor to for.
|
|
1423
|
-
* @return {boolean} -
|
|
1462
|
+
* @return {boolean} - true if a descriptor has been declared; otherwise false.
|
|
1424
1463
|
*/
|
|
1425
1464
|
hasParameterDescriptor(name) {
|
|
1426
1465
|
return !!this.getParameterDescriptor(name);
|
|
@@ -1684,6 +1723,42 @@ class Node extends rclnodejs.ShadowNode {
|
|
|
1684
1723
|
return rclnodejs.getRMWImplementationIdentifier();
|
|
1685
1724
|
}
|
|
1686
1725
|
|
|
1726
|
+
/**
|
|
1727
|
+
* Return a topic name expanded and remapped.
|
|
1728
|
+
* @param {string} topicName - Topic name to be expanded and remapped.
|
|
1729
|
+
* @param {boolean} [onlyExpand=false] - If `true`, remapping rules won't be applied.
|
|
1730
|
+
* @returns {string} - A fully qualified topic name.
|
|
1731
|
+
*/
|
|
1732
|
+
resolveTopicName(topicName, onlyExpand = false) {
|
|
1733
|
+
if (typeof topicName !== 'string') {
|
|
1734
|
+
throw new TypeError('Invalid argument: expected string');
|
|
1735
|
+
}
|
|
1736
|
+
return rclnodejs.resolveName(
|
|
1737
|
+
this.handle,
|
|
1738
|
+
topicName,
|
|
1739
|
+
onlyExpand,
|
|
1740
|
+
/*isService=*/ false
|
|
1741
|
+
);
|
|
1742
|
+
}
|
|
1743
|
+
|
|
1744
|
+
/**
|
|
1745
|
+
* Return a service name expanded and remapped.
|
|
1746
|
+
* @param {string} service - Service name to be expanded and remapped.
|
|
1747
|
+
* @param {boolean} [onlyExpand=false] - If `true`, remapping rules won't be applied.
|
|
1748
|
+
* @returns {string} - A fully qualified service name.
|
|
1749
|
+
*/
|
|
1750
|
+
resolveServiceName(service, onlyExpand = false) {
|
|
1751
|
+
if (typeof service !== 'string') {
|
|
1752
|
+
throw new TypeError('Invalid argument: expected string');
|
|
1753
|
+
}
|
|
1754
|
+
return rclnodejs.resolveName(
|
|
1755
|
+
this.handle,
|
|
1756
|
+
service,
|
|
1757
|
+
onlyExpand,
|
|
1758
|
+
/*isService=*/ true
|
|
1759
|
+
);
|
|
1760
|
+
}
|
|
1761
|
+
|
|
1687
1762
|
// returns on 1st error or result {successful, reason}
|
|
1688
1763
|
_validateParameters(parameters = [], declareParameterMode = false) {
|
|
1689
1764
|
for (const parameter of parameters) {
|
|
@@ -1808,7 +1883,7 @@ class Node extends rclnodejs.ShadowNode {
|
|
|
1808
1883
|
return result;
|
|
1809
1884
|
});
|
|
1810
1885
|
|
|
1811
|
-
Type.
|
|
1886
|
+
Type.destroyRawROS(message);
|
|
1812
1887
|
}
|
|
1813
1888
|
|
|
1814
1889
|
_addActionClient(actionClient) {
|
|
@@ -1820,6 +1895,19 @@ class Node extends rclnodejs.ShadowNode {
|
|
|
1820
1895
|
this._actionServers.push(actionServer);
|
|
1821
1896
|
this.syncHandles();
|
|
1822
1897
|
}
|
|
1898
|
+
|
|
1899
|
+
_getValidatedTopic(topicName, noDemangle) {
|
|
1900
|
+
if (noDemangle) {
|
|
1901
|
+
return topicName;
|
|
1902
|
+
}
|
|
1903
|
+
const fqTopicName = rclnodejs.expandTopicName(
|
|
1904
|
+
topicName,
|
|
1905
|
+
this.name(),
|
|
1906
|
+
this.namespace()
|
|
1907
|
+
);
|
|
1908
|
+
validateFullTopicName(fqTopicName);
|
|
1909
|
+
return rclnodejs.remapTopicName(this.handle, fqTopicName);
|
|
1910
|
+
}
|
|
1823
1911
|
}
|
|
1824
1912
|
|
|
1825
1913
|
/**
|
|
@@ -0,0 +1,60 @@
|
|
|
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
|
+
|
|
19
|
+
class Serialization {
|
|
20
|
+
/**
|
|
21
|
+
* Serialize a message to a buffer.
|
|
22
|
+
* @param {object} message - The message to serialize.
|
|
23
|
+
* @param {function} typeClass - The class of the message type to serialize.
|
|
24
|
+
* @return {Buffer} The serialized message as a Buffer.
|
|
25
|
+
*/
|
|
26
|
+
static serializeMessage(message, typeClass) {
|
|
27
|
+
if (!(message instanceof typeClass)) {
|
|
28
|
+
throw new TypeError('Message must be a valid ros2 message type');
|
|
29
|
+
}
|
|
30
|
+
return rclnodejs.serialize(
|
|
31
|
+
typeClass.type().pkgName,
|
|
32
|
+
typeClass.type().subFolder,
|
|
33
|
+
typeClass.type().interfaceName,
|
|
34
|
+
message.serialize()
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Deserialize a message from a buffer.
|
|
40
|
+
* @param {Buffer} buffer - The buffer containing the serialized message.
|
|
41
|
+
* @param {function} typeClass - The class of the message type to deserialize into.
|
|
42
|
+
* @return {object} The deserialized message object.
|
|
43
|
+
*/
|
|
44
|
+
static deserializeMessage(buffer, typeClass) {
|
|
45
|
+
if (!(buffer instanceof Buffer)) {
|
|
46
|
+
throw new TypeError('Buffer is required for deserialization');
|
|
47
|
+
}
|
|
48
|
+
const rosMsg = new typeClass();
|
|
49
|
+
rclnodejs.deserialize(
|
|
50
|
+
typeClass.type().pkgName,
|
|
51
|
+
typeClass.type().subFolder,
|
|
52
|
+
typeClass.type().interfaceName,
|
|
53
|
+
buffer,
|
|
54
|
+
rosMsg.toRawROS()
|
|
55
|
+
);
|
|
56
|
+
return rosMsg;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
module.exports = Serialization;
|
|
@@ -18,6 +18,12 @@ const loader = require('./interface_loader.js');
|
|
|
18
18
|
const rclnodejs = require('bindings')('rclnodejs');
|
|
19
19
|
const Service = require('./service.js');
|
|
20
20
|
|
|
21
|
+
const {
|
|
22
|
+
ParameterType,
|
|
23
|
+
Parameter,
|
|
24
|
+
ParameterDescriptor,
|
|
25
|
+
} = require('../lib/parameter.js');
|
|
26
|
+
|
|
21
27
|
// This class is used to create a TypeDescriptionService which can be used to
|
|
22
28
|
// retrieve information about types used by the node’s publishers, subscribers,
|
|
23
29
|
// services or actions.
|
|
@@ -32,10 +38,30 @@ class TypeDescriptionService {
|
|
|
32
38
|
'type_description_interfaces/srv/GetTypeDescription'
|
|
33
39
|
);
|
|
34
40
|
this._typeDescriptionService = null;
|
|
41
|
+
|
|
42
|
+
this._enabled = false;
|
|
43
|
+
const startTypeDescriptionServiceParam = 'start_type_description_service';
|
|
44
|
+
if (!node.hasParameter(startTypeDescriptionServiceParam)) {
|
|
45
|
+
node.declareParameter(
|
|
46
|
+
new Parameter(
|
|
47
|
+
startTypeDescriptionServiceParam,
|
|
48
|
+
ParameterType.PARAMETER_BOOL,
|
|
49
|
+
true
|
|
50
|
+
),
|
|
51
|
+
new ParameterDescriptor(
|
|
52
|
+
startTypeDescriptionServiceParam,
|
|
53
|
+
ParameterType.PARAMETER_BOOL,
|
|
54
|
+
'If enabled, start the ~/get_type_description service.',
|
|
55
|
+
true
|
|
56
|
+
)
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
const param = node.getParameter(startTypeDescriptionServiceParam);
|
|
60
|
+
this._enabled = param.value;
|
|
35
61
|
}
|
|
36
62
|
|
|
37
63
|
start() {
|
|
38
|
-
if (this._typeDescriptionService) {
|
|
64
|
+
if (!this._enabled || this._typeDescriptionService) {
|
|
39
65
|
return;
|
|
40
66
|
}
|
|
41
67
|
|
package/package.json
CHANGED
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 [v1.
|
|
48
|
+
| latest version (currently [v1.3.0](https://github.com/RobotWebTools/rclnodejs/tree/1.3.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/src/addon.cpp
CHANGED
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
#include "rcl_names_bindings.h"
|
|
31
31
|
#include "rcl_node_bindings.h"
|
|
32
32
|
#include "rcl_publisher_bindings.h"
|
|
33
|
+
#include "rcl_serialization_bindings.h"
|
|
33
34
|
#include "rcl_service_bindings.h"
|
|
34
35
|
#include "rcl_subscription_bindings.h"
|
|
35
36
|
#include "rcl_time_point_bindings.h"
|
|
@@ -88,6 +89,7 @@ Napi::Object InitModule(Napi::Env env, Napi::Object exports) {
|
|
|
88
89
|
rclnodejs::InitEventHandleBindings(env, exports);
|
|
89
90
|
#endif
|
|
90
91
|
rclnodejs::InitLifecycleBindings(env, exports);
|
|
92
|
+
rclnodejs::InitSerializationBindings(env, exports);
|
|
91
93
|
rclnodejs::ShadowNode::Init(env, exports);
|
|
92
94
|
rclnodejs::RclHandle::Init(env, exports);
|
|
93
95
|
|
package/src/macros.h
CHANGED
|
@@ -23,17 +23,33 @@
|
|
|
23
23
|
{ \
|
|
24
24
|
if (lhs op rhs) { \
|
|
25
25
|
rcl_reset_error(); \
|
|
26
|
-
Napi::Error::New(
|
|
26
|
+
Napi::Error::New(env, message) \
|
|
27
27
|
.ThrowAsJavaScriptException(); \
|
|
28
|
+
return env.Undefined(); \
|
|
28
29
|
} \
|
|
29
30
|
}
|
|
30
31
|
|
|
32
|
+
#define CHECK_OP_AND_THROW_ERROR_IF_NOT_TRUE_NO_RETURN(op, lhs, rhs, message) \
|
|
33
|
+
{ \
|
|
34
|
+
if (lhs op rhs) { \
|
|
35
|
+
rcl_reset_error(); \
|
|
36
|
+
Napi::Error::New(env, message) \
|
|
37
|
+
.ThrowAsJavaScriptException(); \
|
|
38
|
+
} \
|
|
39
|
+
}
|
|
40
|
+
|
|
31
41
|
#define THROW_ERROR_IF_NOT_EQUAL(lhs, rhs, message) \
|
|
32
42
|
CHECK_OP_AND_THROW_ERROR_IF_NOT_TRUE(!=, lhs, rhs, message)
|
|
33
43
|
|
|
34
44
|
#define THROW_ERROR_IF_EQUAL(lhs, rhs, message) \
|
|
35
45
|
CHECK_OP_AND_THROW_ERROR_IF_NOT_TRUE(==, lhs, rhs, message)
|
|
36
46
|
|
|
47
|
+
#define THROW_ERROR_IF_NOT_EQUAL_NO_RETURN(lhs, rhs, message) \
|
|
48
|
+
CHECK_OP_AND_THROW_ERROR_IF_NOT_TRUE_NO_RETURN(!=, lhs, rhs, message)
|
|
49
|
+
|
|
50
|
+
#define THROW_ERROR_IF_EQUAL_NO_RETURN(lhs, rhs, message) \
|
|
51
|
+
CHECK_OP_AND_THROW_ERROR_IF_NOT_TRUE_NO_RETURN(==, lhs, rhs, message)
|
|
52
|
+
|
|
37
53
|
#define PACKAGE_NAME "rclnodejs"
|
|
38
54
|
|
|
39
55
|
#ifdef DEBUG_ON
|
|
@@ -75,12 +75,13 @@ Napi::Value ActionCreateClient(const Napi::CallbackInfo& info) {
|
|
|
75
75
|
&action_client_ops),
|
|
76
76
|
RCL_RET_OK, rcl_get_error_string().str);
|
|
77
77
|
auto js_obj = RclHandle::NewInstance(
|
|
78
|
-
env, action_client, node_handle, [node](void* ptr) {
|
|
78
|
+
env, action_client, node_handle, [node, env](void* ptr) {
|
|
79
79
|
rcl_action_client_t* action_client =
|
|
80
80
|
reinterpret_cast<rcl_action_client_t*>(ptr);
|
|
81
81
|
rcl_ret_t ret = rcl_action_client_fini(action_client, node);
|
|
82
82
|
free(ptr);
|
|
83
|
-
|
|
83
|
+
THROW_ERROR_IF_NOT_EQUAL_NO_RETURN(RCL_RET_OK, ret,
|
|
84
|
+
rcl_get_error_string().str);
|
|
84
85
|
});
|
|
85
86
|
|
|
86
87
|
return js_obj;
|
|
@@ -49,12 +49,13 @@ Napi::Value ActionAcceptNewGoal(const Napi::CallbackInfo& info) {
|
|
|
49
49
|
malloc(sizeof(rcl_action_goal_handle_t)));
|
|
50
50
|
*goal_handle = *new_goal;
|
|
51
51
|
auto js_obj =
|
|
52
|
-
RclHandle::NewInstance(env, goal_handle, nullptr, [](void* ptr) {
|
|
52
|
+
RclHandle::NewInstance(env, goal_handle, nullptr, [env](void* ptr) {
|
|
53
53
|
rcl_action_goal_handle_t* goal_handle =
|
|
54
54
|
reinterpret_cast<rcl_action_goal_handle_t*>(ptr);
|
|
55
55
|
rcl_ret_t ret = rcl_action_goal_handle_fini(goal_handle);
|
|
56
56
|
free(ptr);
|
|
57
|
-
|
|
57
|
+
THROW_ERROR_IF_NOT_EQUAL_NO_RETURN(RCL_RET_OK, ret,
|
|
58
|
+
rcl_get_error_string().str);
|
|
58
59
|
});
|
|
59
60
|
|
|
60
61
|
return js_obj;
|
|
@@ -81,12 +81,13 @@ Napi::Value ActionCreateServer(const Napi::CallbackInfo& info) {
|
|
|
81
81
|
action_name.c_str(), &action_server_ops),
|
|
82
82
|
RCL_RET_OK, rcl_get_error_string().str);
|
|
83
83
|
auto js_obj = RclHandle::NewInstance(
|
|
84
|
-
env, action_server, node_handle, [node](void* ptr) {
|
|
84
|
+
env, action_server, node_handle, [node, env](void* ptr) {
|
|
85
85
|
rcl_action_server_t* action_server =
|
|
86
86
|
reinterpret_cast<rcl_action_server_t*>(ptr);
|
|
87
87
|
rcl_ret_t ret = rcl_action_server_fini(action_server, node);
|
|
88
88
|
free(ptr);
|
|
89
|
-
|
|
89
|
+
THROW_ERROR_IF_NOT_EQUAL_NO_RETURN(RCL_RET_OK, ret,
|
|
90
|
+
rcl_get_error_string().str);
|
|
90
91
|
});
|
|
91
92
|
|
|
92
93
|
return js_obj;
|
|
@@ -390,13 +391,14 @@ Napi::Value ActionProcessCancelRequest(const Napi::CallbackInfo& info) {
|
|
|
390
391
|
}
|
|
391
392
|
|
|
392
393
|
*response = cancel_response_ptr->msg;
|
|
393
|
-
auto js_obj =
|
|
394
|
-
|
|
394
|
+
auto js_obj = RclHandle::NewInstance(
|
|
395
|
+
env, cancel_response_ptr, nullptr, [env](void* ptr) {
|
|
395
396
|
rcl_action_cancel_response_t* cancel_response_ptr =
|
|
396
397
|
reinterpret_cast<rcl_action_cancel_response_t*>(ptr);
|
|
397
398
|
rcl_ret_t ret = rcl_action_cancel_response_fini(cancel_response_ptr);
|
|
398
399
|
free(ptr);
|
|
399
|
-
|
|
400
|
+
THROW_ERROR_IF_NOT_EQUAL_NO_RETURN(RCL_RET_OK, ret,
|
|
401
|
+
rcl_get_error_string().str);
|
|
400
402
|
});
|
|
401
403
|
return js_obj;
|
|
402
404
|
}
|
|
@@ -53,12 +53,13 @@ Napi::Value CreateClient(const Napi::CallbackInfo& info) {
|
|
|
53
53
|
rcl_client_init(client, node, ts, service_name.c_str(), &client_ops),
|
|
54
54
|
RCL_RET_OK, rcl_get_error_string().str);
|
|
55
55
|
|
|
56
|
-
auto js_obj =
|
|
57
|
-
|
|
56
|
+
auto js_obj = RclHandle::NewInstance(
|
|
57
|
+
env, client, node_handle, [node, env](void* ptr) {
|
|
58
58
|
rcl_client_t* client = reinterpret_cast<rcl_client_t*>(ptr);
|
|
59
59
|
rcl_ret_t ret = rcl_client_fini(client, node);
|
|
60
60
|
free(ptr);
|
|
61
|
-
|
|
61
|
+
THROW_ERROR_IF_NOT_EQUAL_NO_RETURN(RCL_RET_OK, ret,
|
|
62
|
+
rcl_get_error_string().str);
|
|
62
63
|
});
|
|
63
64
|
|
|
64
65
|
return js_obj;
|