rclnodejs 0.22.3 → 0.23.1
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 +6 -7
- package/binding.gyp +2 -0
- package/index.js +4 -0
- package/lib/client.js +28 -0
- package/lib/lifecycle.js +4 -1
- package/lib/node_options.js +1 -1
- package/lib/service.js +38 -2
- package/lib/service_introspection.js +30 -0
- package/package.json +24 -24
- package/rosidl_gen/idl_generator.js +23 -3
- package/rosidl_gen/templates/service_event.dot +304 -0
- package/rostsd_gen/index.js +15 -12
- package/scripts/npmjs-readme.md +6 -7
- package/src/rcl_bindings.cpp +72 -1
- package/types/base.d.ts +1 -0
- package/types/client.d.ts +12 -0
- package/types/interfaces.d.ts +750 -0
- package/types/service.d.ts +12 -0
- package/types/service_introspection.d.ts +10 -0
- package/.github/workflows/identify-ros-distro.yml +0 -48
- package/.github/workflows/linux-build-and-test-compatibility.yml +0 -38
- package/.github/workflows/linux-build-and-test.yml +0 -53
- package/.github/workflows/windows-build-and-test-compatibility.yml +0 -54
- package/.github/workflows/windows-build-and-test.yml +0 -70
- package/.prettierrc.yml +0 -4
- package/.vscode/settings.json +0 -79
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# rclnodejs
|
|
1
|
+
# rclnodejs 
|
|
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
|
|
|
@@ -18,7 +18,7 @@ rclnodejs.init().then(() => {
|
|
|
18
18
|
|
|
19
19
|
**Node.js**
|
|
20
20
|
|
|
21
|
-
- [Node.js](https://nodejs.org/en/) version
|
|
21
|
+
- [Node.js](https://nodejs.org/en/) version >= 16.13.0.
|
|
22
22
|
|
|
23
23
|
**ROS 2 SDK**
|
|
24
24
|
|
|
@@ -43,14 +43,13 @@ npm i rclnodejs@x.y.z
|
|
|
43
43
|
|
|
44
44
|
#### RCLNODEJS - ROS 2 Version Compatibility
|
|
45
45
|
|
|
46
|
-
|
|
|
47
|
-
|
|
|
48
|
-
| [
|
|
49
|
-
| [0.10.3](https://github.com/RobotWebTools/rclnodejs/releases/tag/0.10.3) | [Dashing Diademata - Patch 4](https://github.com/ros2/ros2/releases/tag/release-dashing-20191018) |
|
|
46
|
+
| RCLNODEJS Version | Compatible ROS 2 LTS |
|
|
47
|
+
| :------------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------------------------------------------------------------: |
|
|
48
|
+
| latest version (currently [v0.22.3](https://github.com/RobotWebTools/rclnodejs/tree/0.22.3)) | [Humble](https://github.com/RobotWebTools/rclnodejs/tree/humble-hawksbill)<br>[Iron](https://github.com/RobotWebTools/rclnodejs/tree/iron-irwini) |
|
|
50
49
|
|
|
51
50
|
## Documentation
|
|
52
51
|
|
|
53
|
-
API [documentation](
|
|
52
|
+
API [documentation](https://robotwebtools.github.io/rclnodejs/docs/index.html) is available online.
|
|
54
53
|
|
|
55
54
|
## JavaScript Examples
|
|
56
55
|
|
package/binding.gyp
CHANGED
|
@@ -90,6 +90,7 @@
|
|
|
90
90
|
"<!@(node -e \"console.log(process.env.AMENT_PREFIX_PATH.replace(/:/g, '/include/lifecycle_msgs/ ') + '/include/lifecycle_msgs/')\")",
|
|
91
91
|
"<!@(node -e \"console.log(process.env.AMENT_PREFIX_PATH.replace(/:/g, '/include/rosidl_runtime_c/ ') + '/include/rosidl_runtime_c/')\")",
|
|
92
92
|
"<!@(node -e \"console.log(process.env.AMENT_PREFIX_PATH.replace(/:/g, '/include/rosidl_dynamic_typesupport/ ') + '/include/rosidl_dynamic_typesupport/')\")",
|
|
93
|
+
"<!@(node -e \"console.log(process.env.AMENT_PREFIX_PATH.replace(/:/g, '/include/type_description_interfaces/ ') + '/include/type_description_interfaces/')\")",
|
|
93
94
|
],
|
|
94
95
|
}
|
|
95
96
|
],
|
|
@@ -138,6 +139,7 @@
|
|
|
138
139
|
"<!@(node -e \"console.log(process.env.AMENT_PREFIX_PATH.replace(/;/g, '/include/rcl_lifecycle ').replace(/\\\/g, '/') + '/include/rcl_lifecycle')\")",
|
|
139
140
|
"<!@(node -e \"console.log(process.env.AMENT_PREFIX_PATH.replace(/;/g, '/include/lifecycle_msgs ').replace(/\\\/g, '/') + '/include/lifecycle_msgs')\")",
|
|
140
141
|
"<!@(node -e \"console.log(process.env.AMENT_PREFIX_PATH.replace(/;/g, '/include/rosidl_dynamic_typesupport ').replace(/\\\/g, '/') + '/include/rosidl_dynamic_typesupport')\")",
|
|
142
|
+
"<!@(node -e \"console.log(process.env.AMENT_PREFIX_PATH.replace(/;/g, '/include/type_description_interfaces/ ').replace(/\\\/g, '/') + '/include/type_description_interfaces/')\")",
|
|
141
143
|
],
|
|
142
144
|
}
|
|
143
145
|
]
|
package/index.js
CHANGED
|
@@ -52,6 +52,7 @@ const {
|
|
|
52
52
|
getActionServerNamesAndTypesByNode,
|
|
53
53
|
getActionNamesAndTypes,
|
|
54
54
|
} = require('./lib/action/graph.js');
|
|
55
|
+
const ServiceIntrospectionStates = require('./lib/service_introspection.js');
|
|
55
56
|
|
|
56
57
|
/**
|
|
57
58
|
* Get the version of the generator that was used for the currently present interfaces.
|
|
@@ -143,6 +144,9 @@ let rcl = {
|
|
|
143
144
|
/** {@link ROSClock} class */
|
|
144
145
|
ROSClock: ROSClock,
|
|
145
146
|
|
|
147
|
+
/** {@link ServiceIntrospectionStates} */
|
|
148
|
+
ServiceIntrospectionStates: ServiceIntrospectionStates,
|
|
149
|
+
|
|
146
150
|
/** {@link Time} class */
|
|
147
151
|
Time: Time,
|
|
148
152
|
|
package/lib/client.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
|
const Entity = require('./entity.js');
|
|
19
20
|
const debug = require('debug')('rclnodejs:client');
|
|
20
21
|
|
|
@@ -129,6 +130,33 @@ class Client extends Entity {
|
|
|
129
130
|
get serviceName() {
|
|
130
131
|
return this._serviceName;
|
|
131
132
|
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Configure introspection.
|
|
136
|
+
* @param {Clock} clock - Clock to use for service event timestamps
|
|
137
|
+
* @param {QoS} qos - QoSProfile for the service event publisher
|
|
138
|
+
* @param {ServiceIntrospectionState} introspectionState - State to set introspection to
|
|
139
|
+
*/
|
|
140
|
+
configureIntrospection(clock, qos, introspectionState) {
|
|
141
|
+
if (DistroUtils.getDistroId() <= DistroUtils.getDistroId('humble')) {
|
|
142
|
+
console.warn(
|
|
143
|
+
'Service introspection is not supported by this versionof ROS 2'
|
|
144
|
+
);
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
let type = this.typeClass.type();
|
|
149
|
+
rclnodejs.configureServiceIntrospection(
|
|
150
|
+
this.handle,
|
|
151
|
+
this._nodeHandle,
|
|
152
|
+
clock.handle,
|
|
153
|
+
type.interfaceName,
|
|
154
|
+
type.pkgName,
|
|
155
|
+
qos,
|
|
156
|
+
introspectionState,
|
|
157
|
+
false
|
|
158
|
+
);
|
|
159
|
+
}
|
|
132
160
|
}
|
|
133
161
|
|
|
134
162
|
module.exports = Client;
|
package/lib/lifecycle.js
CHANGED
|
@@ -308,6 +308,7 @@ class LifecycleNode extends Node {
|
|
|
308
308
|
'srv_get_state'
|
|
309
309
|
);
|
|
310
310
|
let service = new Service(
|
|
311
|
+
this.handle,
|
|
311
312
|
srvHandleObj.handle,
|
|
312
313
|
srvHandleObj.name,
|
|
313
314
|
loader.loadInterface('lifecycle_msgs/srv/GetState'),
|
|
@@ -321,6 +322,7 @@ class LifecycleNode extends Node {
|
|
|
321
322
|
'srv_get_available_states'
|
|
322
323
|
);
|
|
323
324
|
service = new Service(
|
|
325
|
+
this.handle,
|
|
324
326
|
srvHandleObj.handle,
|
|
325
327
|
srvHandleObj.name,
|
|
326
328
|
loader.loadInterface('lifecycle_msgs/srv/GetAvailableStates'),
|
|
@@ -334,6 +336,7 @@ class LifecycleNode extends Node {
|
|
|
334
336
|
'srv_get_available_transitions'
|
|
335
337
|
);
|
|
336
338
|
service = new Service(
|
|
339
|
+
this.handle,
|
|
337
340
|
srvHandleObj.handle,
|
|
338
341
|
srvHandleObj.name,
|
|
339
342
|
loader.loadInterface('lifecycle_msgs/srv/GetAvailableTransitions'),
|
|
@@ -347,6 +350,7 @@ class LifecycleNode extends Node {
|
|
|
347
350
|
'srv_change_state'
|
|
348
351
|
);
|
|
349
352
|
service = new Service(
|
|
353
|
+
this.handle,
|
|
350
354
|
srvHandleObj.handle,
|
|
351
355
|
srvHandleObj.name,
|
|
352
356
|
loader.loadInterface('lifecycle_msgs/srv/ChangeState'),
|
|
@@ -354,7 +358,6 @@ class LifecycleNode extends Node {
|
|
|
354
358
|
(request, response) => this._onChangeState(request, response)
|
|
355
359
|
);
|
|
356
360
|
this._services.push(service);
|
|
357
|
-
|
|
358
361
|
this.syncHandles();
|
|
359
362
|
}
|
|
360
363
|
|
package/lib/node_options.js
CHANGED
|
@@ -88,7 +88,7 @@ class NodeOptions {
|
|
|
88
88
|
/**
|
|
89
89
|
* Get the automaticallyDeclareParametersFromOverrides.
|
|
90
90
|
*
|
|
91
|
-
* @returns {boolean} - True indicates that a node
|
|
91
|
+
* @returns {boolean} - True indicates that a node should declare parameters from
|
|
92
92
|
* it's parameter-overrides
|
|
93
93
|
*/
|
|
94
94
|
get automaticallyDeclareParametersFromOverrides() {
|
package/lib/service.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
|
const Entity = require('./entity.js');
|
|
19
20
|
const debug = require('debug')('rclnodejs:service');
|
|
20
21
|
|
|
@@ -63,8 +64,9 @@ class Response {
|
|
|
63
64
|
*/
|
|
64
65
|
|
|
65
66
|
class Service extends Entity {
|
|
66
|
-
constructor(handle, serviceName, typeClass, options, callback) {
|
|
67
|
+
constructor(nodeHandle, handle, serviceName, typeClass, options, callback) {
|
|
67
68
|
super(handle, typeClass, options);
|
|
69
|
+
this._nodeHandle = nodeHandle;
|
|
68
70
|
this._callback = callback;
|
|
69
71
|
}
|
|
70
72
|
|
|
@@ -95,7 +97,14 @@ class Service extends Entity {
|
|
|
95
97
|
type.pkgName,
|
|
96
98
|
options.qos
|
|
97
99
|
);
|
|
98
|
-
return new Service(
|
|
100
|
+
return new Service(
|
|
101
|
+
nodeHandle,
|
|
102
|
+
handle,
|
|
103
|
+
serviceName,
|
|
104
|
+
typeClass,
|
|
105
|
+
options,
|
|
106
|
+
callback
|
|
107
|
+
);
|
|
99
108
|
}
|
|
100
109
|
|
|
101
110
|
/**
|
|
@@ -105,6 +114,33 @@ class Service extends Entity {
|
|
|
105
114
|
const fullServiceName = rclnodejs.getServiceName(this._handle); // returns /my_node/myservice
|
|
106
115
|
return fullServiceName.split('/').pop();
|
|
107
116
|
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Configure introspection.
|
|
120
|
+
* @param {Clock} clock - Clock to use for service event timestamps
|
|
121
|
+
* @param {QoS} qos - QoSProfile for the service event publisher
|
|
122
|
+
* @param {ServiceIntrospectionState} introspectionState - State to set introspection to
|
|
123
|
+
*/
|
|
124
|
+
configureIntrospection(clock, qos, introspectionState) {
|
|
125
|
+
if (DistroUtils.getDistroId() <= DistroUtils.getDistroId('humble')) {
|
|
126
|
+
console.warn(
|
|
127
|
+
'Service introspection is not supported by this versionof ROS 2'
|
|
128
|
+
);
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
let type = this.typeClass.type();
|
|
133
|
+
rclnodejs.configureServiceIntrospection(
|
|
134
|
+
this.handle,
|
|
135
|
+
this._nodeHandle,
|
|
136
|
+
clock.handle,
|
|
137
|
+
type.interfaceName,
|
|
138
|
+
type.pkgName,
|
|
139
|
+
qos,
|
|
140
|
+
introspectionState,
|
|
141
|
+
true
|
|
142
|
+
);
|
|
143
|
+
}
|
|
108
144
|
}
|
|
109
145
|
|
|
110
146
|
module.exports = Service;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// Copyright (c) 2023 Wayne Parrott. All rights reserved.
|
|
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
|
+
/**
|
|
16
|
+
* @typedef {number} ServiceIntrospectionState
|
|
17
|
+
**/
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Enum for service introspection states.
|
|
21
|
+
* @readonly
|
|
22
|
+
* @enum {ServiceIntrospectionState}
|
|
23
|
+
*/
|
|
24
|
+
const ServiceIntrospectionStates = {
|
|
25
|
+
OFF: 0,
|
|
26
|
+
METADATA: 1,
|
|
27
|
+
CONTENTS: 2,
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
module.exports = ServiceIntrospectionStates;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rclnodejs",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.23.1",
|
|
4
4
|
"description": "ROS2.0 JavaScript client with Node.js",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "types/index.d.ts",
|
|
@@ -42,44 +42,44 @@
|
|
|
42
42
|
"url": "git+https://github.com/RobotWebTools/rclnodejs.git"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
|
-
"@babel/eslint-parser": "^7.
|
|
46
|
-
"@typescript-eslint/eslint-plugin": "^
|
|
47
|
-
"@typescript-eslint/parser": "^
|
|
45
|
+
"@babel/eslint-parser": "^7.22.15",
|
|
46
|
+
"@typescript-eslint/eslint-plugin": "^6.6.0",
|
|
47
|
+
"@typescript-eslint/parser": "^6.6.0",
|
|
48
48
|
"babel-eslint": "^10.1.0",
|
|
49
|
-
"clang-format": "^1.
|
|
50
|
-
"commander": "^
|
|
49
|
+
"clang-format": "^1.8.0",
|
|
50
|
+
"commander": "^11.0.0",
|
|
51
51
|
"deep-equal": "^1.1.1",
|
|
52
|
-
"eslint": "^
|
|
53
|
-
"eslint-config-prettier": "^
|
|
54
|
-
"eslint-plugin-prettier": "^
|
|
55
|
-
"husky": "^
|
|
56
|
-
"jsdoc": "^
|
|
57
|
-
"lint-staged": "^
|
|
52
|
+
"eslint": "^8.49.0",
|
|
53
|
+
"eslint-config-prettier": "^9.0.0",
|
|
54
|
+
"eslint-plugin-prettier": "^5.0.0",
|
|
55
|
+
"husky": "^8.0.3",
|
|
56
|
+
"jsdoc": "^4.0.2",
|
|
57
|
+
"lint-staged": "^14.0.1",
|
|
58
58
|
"mocha": "^10.2.0",
|
|
59
|
-
"prettier": "^
|
|
60
|
-
"rimraf": "^
|
|
61
|
-
"sinon": "^
|
|
59
|
+
"prettier": "^3.0.3",
|
|
60
|
+
"rimraf": "^5.0.1",
|
|
61
|
+
"sinon": "^15.2.0",
|
|
62
62
|
"tree-kill": "^1.2.2",
|
|
63
|
-
"typescript": "^4.
|
|
63
|
+
"typescript": "^4.9.3"
|
|
64
64
|
},
|
|
65
65
|
"dependencies": {
|
|
66
66
|
"@rclnodejs/ref-array-di": "^1.2.2",
|
|
67
67
|
"@rclnodejs/ref-napi": "^4.0.0",
|
|
68
68
|
"@rclnodejs/ref-struct-di": "^1.1.1",
|
|
69
|
-
"array.prototype.flat": "^1.2
|
|
69
|
+
"array.prototype.flat": "^1.3.2",
|
|
70
70
|
"bindings": "^1.5.0",
|
|
71
|
-
"compare-versions": "^
|
|
72
|
-
"debug": "^4.
|
|
71
|
+
"compare-versions": "^6.1.0",
|
|
72
|
+
"debug": "^4.3.4",
|
|
73
73
|
"dot": "^1.1.3",
|
|
74
74
|
"dtslint": "^4.2.1",
|
|
75
|
-
"fs-extra": "^
|
|
75
|
+
"fs-extra": "^11.1.1",
|
|
76
76
|
"int64-napi": "^1.0.2",
|
|
77
77
|
"is-close": "^1.3.3",
|
|
78
|
-
"mkdirp": "^
|
|
78
|
+
"mkdirp": "^3.0.1",
|
|
79
79
|
"mz": "^2.7.0",
|
|
80
|
-
"nan": "^2.
|
|
81
|
-
"uuid": "^
|
|
82
|
-
"walk": "^2.3.
|
|
80
|
+
"nan": "^2.17.0",
|
|
81
|
+
"uuid": "^9.0.0",
|
|
82
|
+
"walk": "^2.3.15"
|
|
83
83
|
},
|
|
84
84
|
"husky": {
|
|
85
85
|
"hooks": {
|
|
@@ -19,6 +19,7 @@ const fse = require('fs-extra');
|
|
|
19
19
|
const path = require('path');
|
|
20
20
|
const parser = require('../rosidl_parser/rosidl_parser.js');
|
|
21
21
|
const actionMsgs = require('./action_msgs.js');
|
|
22
|
+
const DistroUtils = require('../lib/distro.js');
|
|
22
23
|
|
|
23
24
|
dot.templateSettings.strip = false;
|
|
24
25
|
dot.log = process.env.RCLNODEJS_LOG_VERBOSE || false;
|
|
@@ -42,7 +43,7 @@ async function writeGeneratedCode(dir, fileName, code) {
|
|
|
42
43
|
await fse.writeFile(path.join(dir, fileName), code);
|
|
43
44
|
}
|
|
44
45
|
|
|
45
|
-
function generateServiceJSStruct(serviceInfo, dir) {
|
|
46
|
+
async function generateServiceJSStruct(serviceInfo, dir) {
|
|
46
47
|
dir = path.join(dir, `${serviceInfo.pkgName}`);
|
|
47
48
|
const fileName =
|
|
48
49
|
serviceInfo.pkgName +
|
|
@@ -51,10 +52,29 @@ function generateServiceJSStruct(serviceInfo, dir) {
|
|
|
51
52
|
'__' +
|
|
52
53
|
serviceInfo.interfaceName +
|
|
53
54
|
'.js';
|
|
54
|
-
const
|
|
55
|
+
const generatedSrvCode = removeEmptyLines(
|
|
55
56
|
dots.service({ serviceInfo: serviceInfo })
|
|
56
57
|
);
|
|
57
|
-
|
|
58
|
+
let result = writeGeneratedCode(dir, fileName, generatedSrvCode);
|
|
59
|
+
|
|
60
|
+
if (DistroUtils.getDistroId() <= DistroUtils.getDistroId('humble')) {
|
|
61
|
+
return result;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Otherwise, for post-Humble ROS 2 releases generate service_event msgs
|
|
65
|
+
await result;
|
|
66
|
+
const eventFileName =
|
|
67
|
+
serviceInfo.pkgName +
|
|
68
|
+
'__' +
|
|
69
|
+
serviceInfo.subFolder +
|
|
70
|
+
'__' +
|
|
71
|
+
serviceInfo.interfaceName +
|
|
72
|
+
'_Event.js';
|
|
73
|
+
const generatedSrvEventCode = removeEmptyLines(
|
|
74
|
+
dots.service_event({ serviceInfo: serviceInfo })
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
return writeGeneratedCode(dir, eventFileName, generatedSrvEventCode);
|
|
58
78
|
}
|
|
59
79
|
|
|
60
80
|
async function generateMessageJSStruct(messageInfo, dir) {
|