rclnodejs 0.32.5 → 1.0.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.
Files changed (68) hide show
  1. package/README.md +3 -3
  2. package/binding.gyp +17 -2
  3. package/lib/client.js +2 -3
  4. package/lib/context.js +8 -0
  5. package/lib/logging.js +26 -9
  6. package/lib/node.js +68 -1
  7. package/lib/publisher.js +8 -0
  8. package/lib/service.js +9 -2
  9. package/lib/subscription.js +8 -0
  10. package/lib/timer.js +32 -0
  11. package/package.json +4 -4
  12. package/rostsd_gen/index.js +167 -67
  13. package/scripts/config.js +1 -0
  14. package/scripts/npmjs-readme.md +3 -3
  15. package/src/addon.cpp +54 -53
  16. package/src/executor.cpp +19 -10
  17. package/src/{executor.hpp → executor.h} +7 -5
  18. package/src/handle_manager.cpp +30 -56
  19. package/src/{handle_manager.hpp → handle_manager.h} +8 -7
  20. package/src/{macros.hpp → macros.h} +7 -5
  21. package/src/rcl_action_client_bindings.cpp +231 -0
  22. package/src/{rcl_action_bindings.hpp → rcl_action_client_bindings.h} +6 -11
  23. package/src/rcl_action_goal_bindings.cpp +117 -0
  24. package/src/rcl_action_goal_bindings.h +26 -0
  25. package/src/rcl_action_server_bindings.cpp +470 -0
  26. package/src/rcl_action_server_bindings.h +26 -0
  27. package/src/rcl_bindings.cpp +42 -1979
  28. package/src/{rcl_bindings.hpp → rcl_bindings.h} +5 -25
  29. package/src/rcl_client_bindings.cpp +183 -0
  30. package/src/rcl_client_bindings.h +26 -0
  31. package/src/rcl_context_bindings.cpp +156 -0
  32. package/src/rcl_context_bindings.h +26 -0
  33. package/src/rcl_graph_bindings.cpp +280 -0
  34. package/src/rcl_graph_bindings.h +26 -0
  35. package/src/rcl_guard_condition_bindings.cpp +75 -0
  36. package/src/rcl_guard_condition_bindings.h +26 -0
  37. package/src/rcl_handle.cpp +41 -57
  38. package/src/{rcl_handle.hpp → rcl_handle.h} +18 -17
  39. package/src/rcl_lifecycle_bindings.cpp +135 -114
  40. package/src/{rcl_lifecycle_bindings.hpp → rcl_lifecycle_bindings.h} +5 -7
  41. package/src/rcl_logging_bindings.cpp +96 -0
  42. package/src/rcl_logging_bindings.h +26 -0
  43. package/src/rcl_names_bindings.cpp +255 -0
  44. package/src/rcl_names_bindings.h +26 -0
  45. package/src/rcl_node_bindings.cpp +447 -0
  46. package/src/rcl_node_bindings.h +26 -0
  47. package/src/rcl_publisher_bindings.cpp +141 -0
  48. package/src/rcl_publisher_bindings.h +26 -0
  49. package/src/rcl_service_bindings.cpp +185 -0
  50. package/src/rcl_service_bindings.h +26 -0
  51. package/src/rcl_subscription_bindings.cpp +335 -0
  52. package/src/rcl_subscription_bindings.h +26 -0
  53. package/src/rcl_time_point_bindings.cpp +194 -0
  54. package/src/rcl_time_point_bindings.h +26 -0
  55. package/src/rcl_timer_bindings.cpp +237 -0
  56. package/src/rcl_timer_bindings.h +26 -0
  57. package/src/rcl_utilities.cpp +166 -1
  58. package/src/{rcl_utilities.hpp → rcl_utilities.h} +21 -3
  59. package/src/shadow_node.cpp +56 -75
  60. package/src/{shadow_node.hpp → shadow_node.h} +18 -17
  61. package/types/context.d.ts +6 -0
  62. package/types/interfaces.d.ts +4377 -0
  63. package/types/node.d.ts +53 -0
  64. package/types/publisher.d.ts +6 -0
  65. package/types/service.d.ts +6 -0
  66. package/types/subscription.d.ts +6 -0
  67. package/types/timer.d.ts +18 -0
  68. 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
- | RCLNODEJS Version | Compatible ROS 2 LTS |
47
- | :------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------: |
48
- | latest version (currently [v0.32.5](https://github.com/RobotWebTools/rclnodejs/tree/0.32.5)) | [Humble](https://github.com/RobotWebTools/rclnodejs/tree/humble-hawksbill)<br>[Jazzy](https://github.com/RobotWebTools/rclnodejs/tree/jazzy) |
46
+ | RCLNODEJS Version | Compatible ROS 2 LTS |
47
+ | :----------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------: |
48
+ | latest version (currently [v1.0.0](https://github.com/RobotWebTools/rclnodejs/tree/1.0.0)) | [Humble](https://github.com/RobotWebTools/rclnodejs/tree/humble-hawksbill)<br>[Jazzy](https://github.com/RobotWebTools/rclnodejs/tree/jazzy) |
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/rcl_action_bindings.cpp',
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
  ],
package/lib/client.js CHANGED
@@ -147,15 +147,14 @@ class Client extends Entity {
147
147
  }
148
148
 
149
149
  let type = this.typeClass.type();
150
- rclnodejs.configureServiceIntrospection(
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/logging.js CHANGED
@@ -39,14 +39,31 @@ let LoggingSeverity = {
39
39
 
40
40
  class Caller {
41
41
  constructor() {
42
- this._info = {};
43
- let frame = new Error().stack.split('\n').slice(4, 5)[0];
44
- let results = frame.match(/at\s+(.*)\s+\((.*):(\d*):(\d*)\)/i);
45
-
46
- if (results && results.length === 5) {
47
- this._info['functionName'] = results[1];
48
- this._info['lineNumber'] = results[3];
49
- this._info['fileName'] = path.basename(results[2]);
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');
@@ -969,7 +970,7 @@ class Node extends rclnodejs.ShadowNode {
969
970
  }
970
971
 
971
972
  /**
972
- * Get the list of service topics discovered by the provided node for the remote node name.
973
+ * Get service names and types for which a remote node has servers.
973
974
  * @param {string} nodeName - The name of the node.
974
975
  * @param {string} namespace - The name of the namespace.
975
976
  * @return {Array<{name: string, types: Array<string>}>} - An array of the names and types.
@@ -982,6 +983,20 @@ class Node extends rclnodejs.ShadowNode {
982
983
  );
983
984
  }
984
985
 
986
+ /**
987
+ * Get service names and types for which a remote node has clients.
988
+ * @param {string} nodeName - The name of the node.
989
+ * @param {string} namespace - The name of the namespace.
990
+ * @return {Array<{name: string, types: Array<string>}>} - An array of the names and types.
991
+ */
992
+ getClientNamesAndTypesByNode(nodeName, namespace) {
993
+ return rclnodejs.getClientNamesAndTypesByNode(
994
+ this.handle,
995
+ nodeName,
996
+ namespace
997
+ );
998
+ }
999
+
985
1000
  /**
986
1001
  * Get the list of topics discovered by the provided node.
987
1002
  * @param {boolean} noDemangle - If true topic names and types returned will not be demangled, default: false.
@@ -999,6 +1014,32 @@ class Node extends rclnodejs.ShadowNode {
999
1014
  return rclnodejs.getServiceNamesAndTypes(this.handle);
1000
1015
  }
1001
1016
 
1017
+ /**
1018
+ * Get a list of publishers on a given topic.
1019
+ * @param {string} topic - the topic name to get the publishers for.
1020
+ * @param {boolean} noDemangle - if `true`, `topic_name` needs to be a valid middleware topic name,
1021
+ * otherwise it should be a valid ROS topic name.
1022
+ * @returns {Array} - list of publishers
1023
+ */
1024
+ getPublishersInfoByTopic(topic, noDemangle) {
1025
+ return rclnodejs.getPublishersInfoByTopic(this.handle, topic, noDemangle);
1026
+ }
1027
+
1028
+ /**
1029
+ * Get a list of subscriptions on a given topic.
1030
+ * @param {string} topic - the topic name to get the subscriptions for.
1031
+ * @param {boolean} noDemangle - if `true`, `topic_name` needs to be a valid middleware topic name,
1032
+ * otherwise it should be a valid ROS topic name.
1033
+ * @returns {Array} - list of subscriptions
1034
+ */
1035
+ getSubscriptionsInfoByTopic(topic, noDemangle) {
1036
+ return rclnodejs.getSubscriptionsInfoByTopic(
1037
+ this.handle,
1038
+ topic,
1039
+ noDemangle
1040
+ );
1041
+ }
1042
+
1002
1043
  /**
1003
1044
  * Get the list of nodes discovered by the provided node.
1004
1045
  * @return {Array<string>} - An array of the names.
@@ -1047,6 +1088,32 @@ class Node extends rclnodejs.ShadowNode {
1047
1088
  return rclnodejs.countSubscribers(this.handle, expandedTopic);
1048
1089
  }
1049
1090
 
1091
+ /**
1092
+ * Get the number of clients on a given service name.
1093
+ * @param {string} serviceName - the service name
1094
+ * @returns {Number}
1095
+ */
1096
+ countClients(serviceName) {
1097
+ if (DistroUtils.getDistroId() <= DistroUtils.getDistroId('humble')) {
1098
+ console.warn('countClients is not supported by this version of ROS 2');
1099
+ return null;
1100
+ }
1101
+ return rclnodejs.countClients(this.handle, serviceName);
1102
+ }
1103
+
1104
+ /**
1105
+ * Get the number of services on a given service name.
1106
+ * @param {string} serviceName - the service name
1107
+ * @returns {Number}
1108
+ */
1109
+ countServices(serviceName) {
1110
+ if (DistroUtils.getDistroId() <= DistroUtils.getDistroId('humble')) {
1111
+ console.warn('countServices is not supported by this version of ROS 2');
1112
+ return null;
1113
+ }
1114
+ return rclnodejs.countServices(this.handle, serviceName);
1115
+ }
1116
+
1050
1117
  /**
1051
1118
  * Get the list of parameter-overrides found on the commandline and
1052
1119
  * in the NodeOptions.parameter_overrides property.
package/lib/publisher.js CHANGED
@@ -72,6 +72,14 @@ 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
+ }
75
83
  }
76
84
 
77
85
  module.exports = Publisher;
package/lib/service.js CHANGED
@@ -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;
@@ -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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rclnodejs",
3
- "version": "0.32.5",
3
+ "version": "1.0.0",
4
4
  "description": "ROS2.0 JavaScript client with Node.js",
5
5
  "main": "index.js",
6
6
  "types": "types/index.d.ts",
@@ -26,7 +26,7 @@
26
26
  "docs": "cd docs && make",
27
27
  "test": "nyc node --expose-gc ./scripts/run_test.js && tsd",
28
28
  "lint": "eslint && node ./scripts/cpplint.js",
29
- "format": "clang-format -i -style=file ./src/*.cpp ./src/*.hpp && npx --yes prettier --write \"{lib,rosidl_gen,rostsd_gen,rosidl_parser,types,example,test,scripts,benchmark,rostsd_gen}/**/*.{js,md,ts}\" ./*.{js,md,ts}",
29
+ "format": "clang-format -i -style=file ./src/*.cpp ./src/*.h && npx --yes prettier --write \"{lib,rosidl_gen,rostsd_gen,rosidl_parser,types,example,test,scripts,benchmark,rostsd_gen}/**/*.{js,md,ts}\" ./*.{js,md,ts}",
30
30
  "prepare": "husky",
31
31
  "coverage": "cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js"
32
32
  },
@@ -79,9 +79,9 @@
79
79
  "fs-extra": "^11.2.0",
80
80
  "is-close": "^1.3.3",
81
81
  "json-bigint": "^1.0.0",
82
- "nan": "^2.22.0",
83
82
  "terser": "^5.39.0",
84
- "walk": "^2.3.15"
83
+ "walk": "^2.3.15",
84
+ "node-addon-api": "^8.3.1"
85
85
  },
86
86
  "husky": {
87
87
  "hooks": {