rclnodejs 0.21.3 → 0.22.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/.github/workflows/identify-ros-distro.yml +1 -0
- package/.github/workflows/linux-build-and-test-compatibility.yml +9 -8
- package/.github/workflows/linux-build-and-test.yml +3 -3
- package/.github/workflows/windows-build-and-test-compatibility.yml +9 -7
- package/.github/workflows/windows-build-and-test.yml +9 -4
- package/README.md +1 -1
- package/bin/linux-x64-110/rclnodejs.node +0 -0
- package/binding.gyp +5 -3
- package/index.js +4 -0
- package/lib/action/client.js +1 -2
- package/lib/action/server.js +1 -2
- package/lib/client.js +3 -2
- package/lib/distro.js +1 -1
- package/lib/entity.js +40 -0
- package/lib/node.js +86 -38
- package/lib/rmw.js +29 -0
- package/lib/subscription.js +52 -2
- package/package.json +13 -6
- package/rosidl_gen/blocklist.json +5 -0
- package/rosidl_gen/filter.js +104 -0
- package/rosidl_gen/idl_generator.js +7 -0
- package/rosidl_gen/index.js +19 -6
- package/rosidl_gen/packages.js +39 -39
- package/rostsd_gen/index.js +9 -1
- package/scripts/npmjs-readme.md +1 -1
- package/scripts/run_test.js +0 -6
- package/src/rcl_bindings.cpp +185 -1
- package/types/entity.d.ts +1 -0
- package/types/interfaces.d.ts +123 -0
- package/types/node.d.ts +79 -2
- package/types/subscription.d.ts +28 -0
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
name: rclnodejs - Linux Build & Compatibility Test
|
|
2
|
+
|
|
1
3
|
on:
|
|
2
4
|
workflow_dispatch:
|
|
3
5
|
|
|
@@ -7,14 +9,14 @@ jobs:
|
|
|
7
9
|
strategy:
|
|
8
10
|
fail-fast: false
|
|
9
11
|
matrix:
|
|
10
|
-
node-version: [
|
|
12
|
+
node-version: [14.X, 16.X, 18.X, 19.X]
|
|
11
13
|
ros_distribution:
|
|
12
14
|
- humble
|
|
13
15
|
- rolling
|
|
14
16
|
|
|
15
17
|
steps:
|
|
16
18
|
- name: Setup ROS2
|
|
17
|
-
uses: ros-tooling/setup-ros@v0.
|
|
19
|
+
uses: ros-tooling/setup-ros@v0.6
|
|
18
20
|
with:
|
|
19
21
|
required-ros-distributions: ${{ matrix.ros_distribution }}
|
|
20
22
|
|
|
@@ -24,7 +26,7 @@ jobs:
|
|
|
24
26
|
- uses: actions/checkout@v3
|
|
25
27
|
|
|
26
28
|
- name: Setup Node.js ${{ matrix.node-version }}
|
|
27
|
-
uses: actions/setup-node@
|
|
29
|
+
uses: actions/setup-node@v3
|
|
28
30
|
with:
|
|
29
31
|
node-version: ${{ matrix.node-version }}
|
|
30
32
|
|
|
@@ -34,19 +36,18 @@ jobs:
|
|
|
34
36
|
npm i
|
|
35
37
|
npm test
|
|
36
38
|
|
|
37
|
-
build-foxy
|
|
39
|
+
build-foxy: # foxy distros
|
|
38
40
|
runs-on: ubuntu-20.04
|
|
39
41
|
strategy:
|
|
40
42
|
fail-fast: false
|
|
41
43
|
matrix:
|
|
42
|
-
node-version: [
|
|
44
|
+
node-version: [14.X, 16.11.X, 18.X, 19.X]
|
|
43
45
|
ros_distribution:
|
|
44
46
|
- foxy
|
|
45
|
-
- galactic
|
|
46
47
|
|
|
47
48
|
steps:
|
|
48
49
|
- name: Setup ROS2
|
|
49
|
-
uses: ros-tooling/setup-ros@v0.
|
|
50
|
+
uses: ros-tooling/setup-ros@v0.6
|
|
50
51
|
with:
|
|
51
52
|
required-ros-distributions: ${{ matrix.ros_distribution }}
|
|
52
53
|
|
|
@@ -56,7 +57,7 @@ jobs:
|
|
|
56
57
|
- uses: actions/checkout@v3
|
|
57
58
|
|
|
58
59
|
- name: Setup Node.js ${{ matrix.node-version }}
|
|
59
|
-
uses: actions/setup-node@
|
|
60
|
+
uses: actions/setup-node@v3
|
|
60
61
|
with:
|
|
61
62
|
node-version: ${{ matrix.node-version }}
|
|
62
63
|
|
|
@@ -26,15 +26,15 @@ jobs:
|
|
|
26
26
|
strategy:
|
|
27
27
|
fail-fast: false
|
|
28
28
|
matrix:
|
|
29
|
-
node-version: [
|
|
29
|
+
node-version: [14.X, 16.X, 18.X, 19.X]
|
|
30
30
|
steps:
|
|
31
31
|
- name: Setup Node.js ${{ matrix.node-version }}
|
|
32
|
-
uses: actions/setup-node@
|
|
32
|
+
uses: actions/setup-node@v3
|
|
33
33
|
with:
|
|
34
34
|
node-version: ${{ matrix.node-version }}
|
|
35
35
|
|
|
36
36
|
- name: Setup ROS2
|
|
37
|
-
uses: ros-tooling/setup-ros@v0.
|
|
37
|
+
uses: ros-tooling/setup-ros@v0.6
|
|
38
38
|
with:
|
|
39
39
|
required-ros-distributions: ${{ needs.identify-ros-distro.outputs.distro }}
|
|
40
40
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
name: rclnodejs - Windows Build & Test
|
|
2
|
+
name: rclnodejs - Windows Build & Compatibility Test
|
|
3
3
|
|
|
4
4
|
on:
|
|
5
5
|
workflow_dispatch:
|
|
@@ -10,20 +10,19 @@ jobs:
|
|
|
10
10
|
strategy:
|
|
11
11
|
fail-fast: false
|
|
12
12
|
matrix:
|
|
13
|
-
node-version: [
|
|
13
|
+
node-version: [14.21.2, 16.19.0, 18.14.1, 19.X]
|
|
14
14
|
ros_distribution:
|
|
15
15
|
- foxy
|
|
16
|
-
- galactic
|
|
17
16
|
- humble
|
|
18
17
|
- rolling
|
|
19
18
|
steps:
|
|
20
19
|
- name: Setup Node.js ${{ matrix.node-version }}
|
|
21
|
-
uses: actions/setup-node@
|
|
20
|
+
uses: actions/setup-node@v3
|
|
22
21
|
with:
|
|
23
22
|
node-version: ${{ matrix.node-version }}
|
|
24
23
|
|
|
25
24
|
- name: Setup ROS2
|
|
26
|
-
uses: ros-tooling/setup-ros@v0.
|
|
25
|
+
uses: ros-tooling/setup-ros@v0.6
|
|
27
26
|
with:
|
|
28
27
|
required-ros-distributions: ${{ matrix.ros_distribution }}
|
|
29
28
|
|
|
@@ -45,8 +44,11 @@ jobs:
|
|
|
45
44
|
call "c:\dev\${{ matrix.ros_distribution }}\ros2-windows\setup.bat"
|
|
46
45
|
npm i
|
|
47
46
|
|
|
47
|
+
# On the windows/foxy combination the Eclipse CycloneDDS RMW implementation is used to workaround
|
|
48
|
+
# an error when loading the default fastrtps ddl
|
|
48
49
|
- name: Test rclnodejs
|
|
49
50
|
shell: cmd
|
|
50
51
|
run: |
|
|
51
|
-
call "c:\dev\${{
|
|
52
|
-
npm test
|
|
52
|
+
call "c:\dev\${{ matrix.ros_distribution }}\ros2-windows\setup.bat"
|
|
53
|
+
cmd /c "if ${{ matrix.ros_distribution }}==foxy (set RMW_IMPLEMENTATION=rmw_cyclonedds_cpp&&npm test)"
|
|
54
|
+
cmd /c "if NOT ${{ matrix.ros_distribution }}==foxy (npm test)"
|
|
@@ -26,15 +26,17 @@ jobs:
|
|
|
26
26
|
strategy:
|
|
27
27
|
fail-fast: false
|
|
28
28
|
matrix:
|
|
29
|
-
node
|
|
29
|
+
# Explicit node versions are used to workaround an error
|
|
30
|
+
# where node-gyp fails due to some silly cacheing
|
|
31
|
+
node-version: [14.21.2, 16.19.0, 18.14.1, 19.X]
|
|
30
32
|
steps:
|
|
31
33
|
- name: Setup Node.js ${{ matrix.node-version }}
|
|
32
|
-
uses: actions/setup-node@
|
|
34
|
+
uses: actions/setup-node@v3
|
|
33
35
|
with:
|
|
34
36
|
node-version: ${{ matrix.node-version }}
|
|
35
37
|
|
|
36
38
|
- name: Setup ROS2
|
|
37
|
-
uses: ros-tooling/setup-ros@v0.
|
|
39
|
+
uses: ros-tooling/setup-ros@v0.6
|
|
38
40
|
with:
|
|
39
41
|
required-ros-distributions: ${{ needs.identify-ros-distro.outputs.distro }}
|
|
40
42
|
|
|
@@ -56,8 +58,11 @@ jobs:
|
|
|
56
58
|
call "c:\dev\${{ needs.identify-ros-distro.outputs.distro }}\ros2-windows\setup.bat"
|
|
57
59
|
npm i
|
|
58
60
|
|
|
61
|
+
# On the windows/foxy combination the Eclipse CycloneDDS RMW implementation is used to workaround
|
|
62
|
+
# an error when loading the default fastrtps ddl
|
|
59
63
|
- name: Test rclnodejs
|
|
60
64
|
shell: cmd
|
|
61
65
|
run: |
|
|
62
66
|
call "c:\dev\${{ needs.identify-ros-distro.outputs.distro }}\ros2-windows\setup.bat"
|
|
63
|
-
npm test
|
|
67
|
+
cmd /c "if ${{ needs.identify-ros-distro.outputs.distro }}==foxy (set RMW_IMPLEMENTATION=rmw_cyclonedds_cpp&&npm test)"
|
|
68
|
+
cmd /c "if NOT ${{ needs.identify-ros-distro.outputs.distro }}==foxy (npm test)"
|
package/README.md
CHANGED
|
@@ -45,7 +45,7 @@ npm i rclnodejs@x.y.z
|
|
|
45
45
|
|
|
46
46
|
| RCLNODEJS Version | Compatible ROS 2 Release |
|
|
47
47
|
| :-------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
|
|
48
|
-
| [0.21.
|
|
48
|
+
| [0.21.4 (current)](https://www.npmjs.com/package/rclnodejs/v/0.21.4) ([API](http://robotwebtools.org/rclnodejs/docs/0.21.3/index.html)) | [Humble Hawksbill](https://github.com/ros2/ros2/releases/tag/release-humble-20220523)<br>[Galactic Geochelone](https://github.com/ros2/ros2/releases/tag/release-galactic-20210716)<br>[Foxy Fitzroy](https://github.com/ros2/ros2/releases/tag/release-foxy-20201211)<br>[Eloquent Elusor](https://github.com/ros2/ros2/releases/tag/release-eloquent-20200124) |
|
|
49
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) |
|
|
50
50
|
|
|
51
51
|
## Documentation
|
|
Binary file
|
package/binding.gyp
CHANGED
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
'OS_LINUX'
|
|
60
60
|
],
|
|
61
61
|
'cflags_cc': [
|
|
62
|
-
'-std=c++
|
|
62
|
+
'-std=c++17'
|
|
63
63
|
],
|
|
64
64
|
'include_dirs':
|
|
65
65
|
[
|
|
@@ -82,6 +82,7 @@
|
|
|
82
82
|
"<!@(node -e \"console.log(process.env.AMENT_PREFIX_PATH.replace(/:/g, '/include/rosidl_typesupport_interface/ ') + '/include/rosidl_typesupport_interface/')\")",
|
|
83
83
|
"<!@(node -e \"console.log(process.env.AMENT_PREFIX_PATH.replace(/:/g, '/include/rcl_action/ ') + '/include/rcl_action/')\")",
|
|
84
84
|
"<!@(node -e \"console.log(process.env.AMENT_PREFIX_PATH.replace(/:/g, '/include/action_msgs/ ') + '/include/action_msgs/')\")",
|
|
85
|
+
"<!@(node -e \"console.log(process.env.AMENT_PREFIX_PATH.replace(/:/g, '/include/service_msgs/ ') + '/include/service_msgs/')\")",
|
|
85
86
|
"<!@(node -e \"console.log(process.env.AMENT_PREFIX_PATH.replace(/:/g, '/include/unique_identifier_msgs/ ') + '/include/unique_identifier_msgs/')\")",
|
|
86
87
|
"<!@(node -e \"console.log(process.env.AMENT_PREFIX_PATH.replace(/:/g, '/include/builtin_interfaces/ ') + '/include/builtin_interfaces/')\")",
|
|
87
88
|
"<!@(node -e \"console.log(process.env.AMENT_PREFIX_PATH.replace(/:/g, '/include/rcl_lifecycle/ ') + '/include/rcl_lifecycle/')\")",
|
|
@@ -100,7 +101,7 @@
|
|
|
100
101
|
'OS_WINDOWS'
|
|
101
102
|
],
|
|
102
103
|
'cflags_cc': [
|
|
103
|
-
'-std=c++
|
|
104
|
+
'-std=c++17'
|
|
104
105
|
],
|
|
105
106
|
'include_dirs': [
|
|
106
107
|
'./src/third_party/dlfcn-win32/',
|
|
@@ -129,6 +130,7 @@
|
|
|
129
130
|
"<!@(node -e \"console.log(process.env.AMENT_PREFIX_PATH.replace(/;/g, '/include/rosidl_typesupport_interface ').replace(/\\\/g, '/') + '/include/rosidl_typesupport_interface')\")",
|
|
130
131
|
"<!@(node -e \"console.log(process.env.AMENT_PREFIX_PATH.replace(/;/g, '/include/rcl_action ').replace(/\\\/g, '/') + '/include/rcl_action')\")",
|
|
131
132
|
"<!@(node -e \"console.log(process.env.AMENT_PREFIX_PATH.replace(/;/g, '/include/action_msgs ').replace(/\\\/g, '/') + '/include/action_msgs')\")",
|
|
133
|
+
"<!@(node -e \"console.log(process.env.AMENT_PREFIX_PATH.replace(/;/g, '/include/service_msgs ').replace(/\\\/g, '/') + '/include/service_msgs')\")",
|
|
132
134
|
"<!@(node -e \"console.log(process.env.AMENT_PREFIX_PATH.replace(/;/g, '/include/unique_identifier_msgs ').replace(/\\\/g, '/') + '/include/unique_identifier_msgs')\")",
|
|
133
135
|
"<!@(node -e \"console.log(process.env.AMENT_PREFIX_PATH.replace(/;/g, '/include/builtin_interfaces ').replace(/\\\/g, '/') + '/include/builtin_interfaces')\")",
|
|
134
136
|
"<!@(node -e \"console.log(process.env.AMENT_PREFIX_PATH.replace(/;/g, '/include/rcl_lifecycle ').replace(/\\\/g, '/') + '/include/rcl_lifecycle')\")",
|
|
@@ -156,7 +158,7 @@
|
|
|
156
158
|
'GCC_ENABLE_CPP_EXCEPTIONS': 'YES',
|
|
157
159
|
'CLANG_CXX_LIBRARY': 'libc++',
|
|
158
160
|
'MACOS_DEPLOYMENT_TARGET': '10.12',
|
|
159
|
-
'CLANG_CXX_LANGUAGE_STANDARD': 'c++
|
|
161
|
+
'CLANG_CXX_LANGUAGE_STANDARD': 'c++17'
|
|
160
162
|
}
|
|
161
163
|
}
|
|
162
164
|
],
|
package/index.js
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
'use strict';
|
|
16
16
|
|
|
17
17
|
const DistroUtils = require('./lib/distro.js');
|
|
18
|
+
const RMWUtils = require('./lib/rmw.js');
|
|
18
19
|
const { Clock, ROSClock } = require('./lib/clock.js');
|
|
19
20
|
const ClockType = require('./lib/clock_type.js');
|
|
20
21
|
const compareVersions = require('compare-versions');
|
|
@@ -136,6 +137,9 @@ let rcl = {
|
|
|
136
137
|
/** {@link QoS} class */
|
|
137
138
|
QoS: QoS,
|
|
138
139
|
|
|
140
|
+
/** {@link RMWUtils} */
|
|
141
|
+
RMWUtils: RMWUtils,
|
|
142
|
+
|
|
139
143
|
/** {@link ROSClock} class */
|
|
140
144
|
ROSClock: ROSClock,
|
|
141
145
|
|
package/lib/action/client.js
CHANGED
|
@@ -363,14 +363,13 @@ class ActionClient extends Entity {
|
|
|
363
363
|
* @return {undefined}
|
|
364
364
|
*/
|
|
365
365
|
destroy() {
|
|
366
|
-
if (this.
|
|
366
|
+
if (this.isDestroyed()) {
|
|
367
367
|
return;
|
|
368
368
|
}
|
|
369
369
|
|
|
370
370
|
this._goalHandles.clear();
|
|
371
371
|
|
|
372
372
|
this._node._destroyEntity(this, this._node._actionClients);
|
|
373
|
-
this._destroyed = true;
|
|
374
373
|
}
|
|
375
374
|
}
|
|
376
375
|
|
package/lib/action/server.js
CHANGED
|
@@ -440,7 +440,7 @@ class ActionServer extends Entity {
|
|
|
440
440
|
* @return {undefined}
|
|
441
441
|
*/
|
|
442
442
|
destroy() {
|
|
443
|
-
if (this.
|
|
443
|
+
if (this.isDestroyed()) {
|
|
444
444
|
return;
|
|
445
445
|
}
|
|
446
446
|
|
|
@@ -451,7 +451,6 @@ class ActionServer extends Entity {
|
|
|
451
451
|
this._goalHandles.clear();
|
|
452
452
|
|
|
453
453
|
this._node._destroyEntity(this, this._node._actionServers);
|
|
454
|
-
this._destroyed = true;
|
|
455
454
|
}
|
|
456
455
|
}
|
|
457
456
|
|
package/lib/client.js
CHANGED
|
@@ -70,8 +70,9 @@ class Client extends Entity {
|
|
|
70
70
|
this._sequenceNumberToCallbackMap.delete(sequenceNumber);
|
|
71
71
|
callback(response.toPlainObject(this.typedArrayEnabled));
|
|
72
72
|
} else {
|
|
73
|
-
|
|
74
|
-
|
|
73
|
+
throw new Error(
|
|
74
|
+
`Client has received an unexpected ${this._serviceName} with sequence number ${sequenceNumber}.`
|
|
75
|
+
);
|
|
75
76
|
}
|
|
76
77
|
}
|
|
77
78
|
|
package/lib/distro.js
CHANGED
|
@@ -42,7 +42,7 @@ const DistroUtils = {
|
|
|
42
42
|
* @return {number} Return the rclnodejs distro identifier
|
|
43
43
|
*/
|
|
44
44
|
getDistroId: function (distroName) {
|
|
45
|
-
const dname = distroName ? distroName : this.getDistroName();
|
|
45
|
+
const dname = distroName ? distroName.toLowerCase() : this.getDistroName();
|
|
46
46
|
|
|
47
47
|
return DistroNameIdMap.has(dname)
|
|
48
48
|
? DistroNameIdMap.get(dname)
|
package/lib/entity.js
CHANGED
|
@@ -14,16 +14,36 @@
|
|
|
14
14
|
|
|
15
15
|
'use strict';
|
|
16
16
|
|
|
17
|
+
// Destroying an entity for which there is immediate i/o activity can
|
|
18
|
+
// results in a SEGFAULT. To mitigate this situation we hold a
|
|
19
|
+
// reference to released handles to prevent them from being
|
|
20
|
+
// GC'ed prematurely.
|
|
21
|
+
const OBSOLETE_HANDLES = new Set();
|
|
22
|
+
function registerObsoleteHandle(handle) {
|
|
23
|
+
OBSOLETE_HANDLES.add(handle);
|
|
24
|
+
}
|
|
25
|
+
|
|
17
26
|
/**
|
|
18
27
|
* @class - Class representing a common object in RCL.
|
|
19
28
|
* @ignore
|
|
20
29
|
*/
|
|
21
30
|
|
|
22
31
|
class Entity {
|
|
32
|
+
/**
|
|
33
|
+
* Clears the internal short-lived cache of references to
|
|
34
|
+
* destroyed entities.
|
|
35
|
+
*
|
|
36
|
+
* @ignore
|
|
37
|
+
*/
|
|
38
|
+
static _gcHandles() {
|
|
39
|
+
OBSOLETE_HANDLES.clear();
|
|
40
|
+
}
|
|
41
|
+
|
|
23
42
|
constructor(handle, typeClass, options) {
|
|
24
43
|
this._handle = handle;
|
|
25
44
|
this._typeClass = typeClass;
|
|
26
45
|
this._options = options;
|
|
46
|
+
this._destroyed = false;
|
|
27
47
|
}
|
|
28
48
|
|
|
29
49
|
get handle() {
|
|
@@ -49,6 +69,26 @@ class Entity {
|
|
|
49
69
|
get typeClass() {
|
|
50
70
|
return this._typeClass;
|
|
51
71
|
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Release all resources held by this entity.
|
|
75
|
+
* Do not call this method directly.
|
|
76
|
+
*/
|
|
77
|
+
_destroy() {
|
|
78
|
+
if (this.isDestroyed()) return;
|
|
79
|
+
|
|
80
|
+
this._destroyed = true;
|
|
81
|
+
this.handle.release();
|
|
82
|
+
registerObsoleteHandle(this._handle);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Test if this entity has been destroyed and resources released.
|
|
87
|
+
* @returns {boolean} - true when destroyed has previously been called.
|
|
88
|
+
*/
|
|
89
|
+
isDestroyed() {
|
|
90
|
+
return this._destroyed;
|
|
91
|
+
}
|
|
52
92
|
}
|
|
53
93
|
|
|
54
94
|
module.exports = Entity;
|
package/lib/node.js
CHANGED
|
@@ -38,6 +38,7 @@ const Service = require('./service.js');
|
|
|
38
38
|
const Subscription = require('./subscription.js');
|
|
39
39
|
const TimeSource = require('./time_source.js');
|
|
40
40
|
const Timer = require('./timer.js');
|
|
41
|
+
const Entity = require('./entity.js');
|
|
41
42
|
|
|
42
43
|
// Parameter event publisher constants
|
|
43
44
|
const PARAMETER_EVENT_MSG_TYPE = 'rcl_interfaces/msg/ParameterEvent';
|
|
@@ -148,26 +149,26 @@ class Node extends rclnodejs.ShadowNode {
|
|
|
148
149
|
}
|
|
149
150
|
|
|
150
151
|
execute(handles) {
|
|
151
|
-
let timersReady = this._timers.filter(
|
|
152
|
-
|
|
152
|
+
let timersReady = this._timers.filter((timer) =>
|
|
153
|
+
handles.includes(timer.handle)
|
|
153
154
|
);
|
|
154
|
-
let guardsReady = this._guards.filter(
|
|
155
|
-
|
|
155
|
+
let guardsReady = this._guards.filter((guard) =>
|
|
156
|
+
handles.includes(guard.handle)
|
|
156
157
|
);
|
|
157
|
-
let subscriptionsReady = this._subscriptions.filter(
|
|
158
|
-
|
|
158
|
+
let subscriptionsReady = this._subscriptions.filter((subscription) =>
|
|
159
|
+
handles.includes(subscription.handle)
|
|
159
160
|
);
|
|
160
|
-
let clientsReady = this._clients.filter(
|
|
161
|
-
|
|
161
|
+
let clientsReady = this._clients.filter((client) =>
|
|
162
|
+
handles.includes(client.handle)
|
|
162
163
|
);
|
|
163
|
-
let servicesReady = this._services.filter(
|
|
164
|
-
|
|
164
|
+
let servicesReady = this._services.filter((service) =>
|
|
165
|
+
handles.includes(service.handle)
|
|
165
166
|
);
|
|
166
|
-
let actionClientsReady = this._actionClients.filter(
|
|
167
|
-
|
|
167
|
+
let actionClientsReady = this._actionClients.filter((actionClient) =>
|
|
168
|
+
handles.includes(actionClient.handle)
|
|
168
169
|
);
|
|
169
|
-
let actionServersReady = this._actionServers.filter(
|
|
170
|
-
|
|
170
|
+
let actionServersReady = this._actionServers.filter((actionServer) =>
|
|
171
|
+
handles.includes(actionServer.handle)
|
|
171
172
|
);
|
|
172
173
|
|
|
173
174
|
timersReady.forEach((timer) => {
|
|
@@ -177,7 +178,8 @@ class Node extends rclnodejs.ShadowNode {
|
|
|
177
178
|
}
|
|
178
179
|
});
|
|
179
180
|
|
|
180
|
-
|
|
181
|
+
for (const subscription of subscriptionsReady) {
|
|
182
|
+
if (subscription.isDestroyed()) continue;
|
|
181
183
|
if (subscription.isRaw) {
|
|
182
184
|
let rawMessage = rclnodejs.rclTakeRaw(subscription.handle);
|
|
183
185
|
if (rawMessage) {
|
|
@@ -185,6 +187,7 @@ class Node extends rclnodejs.ShadowNode {
|
|
|
185
187
|
}
|
|
186
188
|
return;
|
|
187
189
|
}
|
|
190
|
+
|
|
188
191
|
this._runWithMessageType(
|
|
189
192
|
subscription.typeClass,
|
|
190
193
|
(message, deserialize) => {
|
|
@@ -194,13 +197,16 @@ class Node extends rclnodejs.ShadowNode {
|
|
|
194
197
|
}
|
|
195
198
|
}
|
|
196
199
|
);
|
|
197
|
-
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
for (const guard of guardsReady) {
|
|
203
|
+
if (guard.isDestroyed()) continue;
|
|
198
204
|
|
|
199
|
-
guardsReady.forEach((guard) => {
|
|
200
205
|
guard.callback();
|
|
201
|
-
}
|
|
206
|
+
}
|
|
202
207
|
|
|
203
|
-
|
|
208
|
+
for (const client of clientsReady) {
|
|
209
|
+
if (client.isDestroyed()) continue;
|
|
204
210
|
this._runWithMessageType(
|
|
205
211
|
client.typeClass.Response,
|
|
206
212
|
(message, deserialize) => {
|
|
@@ -213,9 +219,10 @@ class Node extends rclnodejs.ShadowNode {
|
|
|
213
219
|
}
|
|
214
220
|
}
|
|
215
221
|
);
|
|
216
|
-
}
|
|
222
|
+
}
|
|
217
223
|
|
|
218
|
-
|
|
224
|
+
for (const service of servicesReady) {
|
|
225
|
+
if (service.isDestroyed()) continue;
|
|
219
226
|
this._runWithMessageType(
|
|
220
227
|
service.typeClass.Request,
|
|
221
228
|
(message, deserialize) => {
|
|
@@ -229,9 +236,11 @@ class Node extends rclnodejs.ShadowNode {
|
|
|
229
236
|
}
|
|
230
237
|
}
|
|
231
238
|
);
|
|
232
|
-
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
for (const actionClient of actionClientsReady) {
|
|
242
|
+
if (actionClient.isDestroyed()) continue;
|
|
233
243
|
|
|
234
|
-
actionClientsReady.forEach((actionClient) => {
|
|
235
244
|
const properties = actionClient.handle.properties;
|
|
236
245
|
|
|
237
246
|
if (properties.isGoalResponseReady) {
|
|
@@ -242,7 +251,7 @@ class Node extends rclnodejs.ShadowNode {
|
|
|
242
251
|
actionClient.handle,
|
|
243
252
|
message
|
|
244
253
|
);
|
|
245
|
-
if (sequence !=
|
|
254
|
+
if (sequence != undefined) {
|
|
246
255
|
actionClient.processGoalResponse(sequence, deserialize());
|
|
247
256
|
}
|
|
248
257
|
}
|
|
@@ -257,7 +266,7 @@ class Node extends rclnodejs.ShadowNode {
|
|
|
257
266
|
actionClient.handle,
|
|
258
267
|
message
|
|
259
268
|
);
|
|
260
|
-
if (sequence !=
|
|
269
|
+
if (sequence != undefined) {
|
|
261
270
|
actionClient.processCancelResponse(sequence, deserialize());
|
|
262
271
|
}
|
|
263
272
|
}
|
|
@@ -272,7 +281,7 @@ class Node extends rclnodejs.ShadowNode {
|
|
|
272
281
|
actionClient.handle,
|
|
273
282
|
message
|
|
274
283
|
);
|
|
275
|
-
if (sequence !=
|
|
284
|
+
if (sequence != undefined) {
|
|
276
285
|
actionClient.processResultResponse(sequence, deserialize());
|
|
277
286
|
}
|
|
278
287
|
}
|
|
@@ -308,9 +317,11 @@ class Node extends rclnodejs.ShadowNode {
|
|
|
308
317
|
}
|
|
309
318
|
);
|
|
310
319
|
}
|
|
311
|
-
}
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
for (const actionServer of actionServersReady) {
|
|
323
|
+
if (actionServer.isDestroyed()) continue;
|
|
312
324
|
|
|
313
|
-
actionServersReady.forEach((actionServer) => {
|
|
314
325
|
const properties = actionServer.handle.properties;
|
|
315
326
|
|
|
316
327
|
if (properties.isGoalRequestReady) {
|
|
@@ -371,7 +382,11 @@ class Node extends rclnodejs.ShadowNode {
|
|
|
371
382
|
}
|
|
372
383
|
GoalInfoArray.freeArray(message);
|
|
373
384
|
}
|
|
374
|
-
}
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
// At this point it is safe to clear the cache of any
|
|
388
|
+
// destroyed entity references
|
|
389
|
+
Entity._gcHandles();
|
|
375
390
|
}
|
|
376
391
|
|
|
377
392
|
/**
|
|
@@ -448,11 +463,19 @@ class Node extends rclnodejs.ShadowNode {
|
|
|
448
463
|
}
|
|
449
464
|
|
|
450
465
|
_destroyEntity(entity, array, syncHandles = true) {
|
|
466
|
+
if (entity['isDestroyed'] && entity.isDestroyed()) return;
|
|
467
|
+
|
|
451
468
|
this._removeEntityFromArray(entity, array);
|
|
452
469
|
if (syncHandles) {
|
|
453
470
|
this.syncHandles();
|
|
454
471
|
}
|
|
455
|
-
|
|
472
|
+
|
|
473
|
+
if (entity['_destroy']) {
|
|
474
|
+
entity._destroy();
|
|
475
|
+
} else {
|
|
476
|
+
// guards and timers
|
|
477
|
+
entity.handle.release();
|
|
478
|
+
}
|
|
456
479
|
}
|
|
457
480
|
|
|
458
481
|
_validateOptions(options) {
|
|
@@ -464,12 +487,7 @@ class Node extends rclnodejs.ShadowNode {
|
|
|
464
487
|
}
|
|
465
488
|
|
|
466
489
|
if (options === undefined) {
|
|
467
|
-
|
|
468
|
-
enableTypedArray: true,
|
|
469
|
-
isRaw: false,
|
|
470
|
-
qos: QoS.profileDefault,
|
|
471
|
-
};
|
|
472
|
-
return options;
|
|
490
|
+
return Node.getDefaultOptions();
|
|
473
491
|
}
|
|
474
492
|
|
|
475
493
|
if (options.enableTypedArray === undefined) {
|
|
@@ -608,7 +626,7 @@ class Node extends rclnodejs.ShadowNode {
|
|
|
608
626
|
*/
|
|
609
627
|
|
|
610
628
|
/**
|
|
611
|
-
* Create a Subscription.
|
|
629
|
+
* Create a Subscription with optional content-filtering.
|
|
612
630
|
* @param {function|string|object} typeClass - The ROS message class,
|
|
613
631
|
OR a string representing the message class, e.g. 'std_msgs/msg/String',
|
|
614
632
|
OR an object representing the message class, e.g. {package: 'std_msgs', type: 'msg', name: 'String'}
|
|
@@ -617,9 +635,18 @@ class Node extends rclnodejs.ShadowNode {
|
|
|
617
635
|
* @param {boolean} options.enableTypedArray - The topic will use TypedArray if necessary, default: true.
|
|
618
636
|
* @param {QoS} options.qos - ROS Middleware "quality of service" settings for the subscription, default: QoS.profileDefault.
|
|
619
637
|
* @param {boolean} options.isRaw - The topic is serialized when true, default: false.
|
|
638
|
+
* @param {object} [options.contentFilter=undefined] - The content-filter, default: undefined.
|
|
639
|
+
* Confirm that your RMW supports content-filtered topics before use.
|
|
640
|
+
* @param {string} options.contentFilter.expression - Specifies the criteria to select the data samples of
|
|
641
|
+
* interest. It is similar to the WHERE part of an SQL clause.
|
|
642
|
+
* @param {string[]} [options.contentFilter.parameters=undefined] - Array of strings that give values to
|
|
643
|
+
* the ‘parameters’ (i.e., "%n" tokens) in the filter_expression. The number of supplied parameters must
|
|
644
|
+
* fit with the requested values in the filter_expression (i.e., the number of %n tokens). default: undefined.
|
|
620
645
|
* @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.
|
|
621
646
|
* @return {Subscription} - An instance of Subscription.
|
|
647
|
+
* @throws {ERROR} - May throw an RMW error if content-filter is malformed.
|
|
622
648
|
* @see {@link SubscriptionCallback}
|
|
649
|
+
* @see {@link https://www.omg.org/spec/DDS/1.4/PDF|Content-filter details at DDS 1.4 specification, Annex B}
|
|
623
650
|
*/
|
|
624
651
|
createSubscription(typeClass, topic, options, callback) {
|
|
625
652
|
if (typeof typeClass === 'string' || typeof typeClass === 'object') {
|
|
@@ -1293,7 +1320,7 @@ class Node extends rclnodejs.ShadowNode {
|
|
|
1293
1320
|
* @return {ParameterDescriptor[]} - The parameter descriptors.
|
|
1294
1321
|
*/
|
|
1295
1322
|
getParameterDescriptors(names = []) {
|
|
1296
|
-
|
|
1323
|
+
let descriptors = [];
|
|
1297
1324
|
|
|
1298
1325
|
if (names.length == 0) {
|
|
1299
1326
|
// get all parameters
|
|
@@ -1645,4 +1672,25 @@ class Node extends rclnodejs.ShadowNode {
|
|
|
1645
1672
|
}
|
|
1646
1673
|
}
|
|
1647
1674
|
|
|
1675
|
+
/**
|
|
1676
|
+
* Create an Options instance initialized with default values.
|
|
1677
|
+
* @returns {Options} - The new initialized instance.
|
|
1678
|
+
* @static
|
|
1679
|
+
* @example
|
|
1680
|
+
* {
|
|
1681
|
+
* enableTypedArray: true,
|
|
1682
|
+
* isRaw: false,
|
|
1683
|
+
* qos: QoS.profileDefault,
|
|
1684
|
+
* contentFilter: undefined,
|
|
1685
|
+
* }
|
|
1686
|
+
*/
|
|
1687
|
+
Node.getDefaultOptions = function () {
|
|
1688
|
+
return {
|
|
1689
|
+
enableTypedArray: true,
|
|
1690
|
+
isRaw: false,
|
|
1691
|
+
qos: QoS.profileDefault,
|
|
1692
|
+
contentFilter: undefined,
|
|
1693
|
+
};
|
|
1694
|
+
};
|
|
1695
|
+
|
|
1648
1696
|
module.exports = Node;
|
package/lib/rmw.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const DistroUtils = require('./distro');
|
|
4
|
+
|
|
5
|
+
const RMWNames = {
|
|
6
|
+
FASTRTPS: 'rmw_fastrtps_cpp',
|
|
7
|
+
CONNEXT: 'rmw_connext_cpp',
|
|
8
|
+
CYCLONEDDS: 'rmw_cyclonedds_cpp',
|
|
9
|
+
GURUMDDS: 'rmw_gurumdds_cpp',
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const DefaultRosRMWNameMap = new Map();
|
|
13
|
+
DefaultRosRMWNameMap.set('eloquent', RMWNames.FASTRTPS);
|
|
14
|
+
DefaultRosRMWNameMap.set('foxy', RMWNames.FASTRTPS);
|
|
15
|
+
DefaultRosRMWNameMap.set('galactic', RMWNames.CYCLONEDDS);
|
|
16
|
+
DefaultRosRMWNameMap.set('humble', RMWNames.FASTRTPS);
|
|
17
|
+
DefaultRosRMWNameMap.set('rolling', RMWNames.FASTRTPS);
|
|
18
|
+
|
|
19
|
+
const RMWUtils = {
|
|
20
|
+
RMWNames: RMWNames,
|
|
21
|
+
|
|
22
|
+
getRMWName: function () {
|
|
23
|
+
return process.env.RMW_IMPLEMENTATION
|
|
24
|
+
? process.env.RMW_IMPLEMENTATION
|
|
25
|
+
: DefaultRosRMWNameMap.get(DistroUtils.getDistroName());
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
module.exports = RMWUtils;
|