rclnodejs 0.22.2 → 0.23.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.
@@ -0,0 +1,304 @@
1
+ // This file is automatically generated by Intel rclnodejs
2
+ //
3
+ // *** DO NOT EDIT directly
4
+ //
5
+ 'use strict';
6
+
7
+ {{
8
+ const interfaceName = it.serviceInfo.interfaceName;
9
+ const pkgName = it.serviceInfo.pkgName;
10
+ const subFolder = it.serviceInfo.subFolder;
11
+
12
+ const baseName = it.serviceInfo.pkgName + '__' + it.serviceInfo.subFolder + '__' + it.serviceInfo.interfaceName;
13
+ }}
14
+
15
+ const ref = require('@rclnodejs/ref-napi');
16
+ const StructType = require('@rclnodejs/ref-struct-di')(ref);
17
+ const ArrayType = require('@rclnodejs/ref-array-di')(ref);
18
+ const primitiveTypes = require('../../rosidl_gen/primitive_types.js');
19
+ const deallocator = require('../../rosidl_gen/deallocator.js');
20
+ const translator = require('../../rosidl_gen/message_translator.js');
21
+ const ServiceEventInfoWrapper = require('../service_msgs/service_msgs__msg__ServiceEventInfo.js');
22
+ const {{=interfaceName}}_RequestWrapper = require('./{{=pkgName}}__{{=subFolder}}__{{=interfaceName}}_Request.js');
23
+ const {{=interfaceName}}_ResponseWrapper = require('./{{=pkgName}}__{{=subFolder}}__{{=interfaceName}}_Response.js');
24
+ const {{=interfaceName}}_EventRefStruct = StructType({
25
+ info: ServiceEventInfoWrapper.refObjectType,
26
+ request: {{=interfaceName}}_RequestWrapper.refObjectArrayType,
27
+ response: {{=interfaceName}}_ResponseWrapper.refObjectArrayType,
28
+ });
29
+ const {{=interfaceName}}_EventRefArray = ArrayType({{=interfaceName}}_EventRefStruct);
30
+ const {{=interfaceName}}_EventRefStructArray = StructType({
31
+ data: {{=interfaceName}}_EventRefArray,
32
+ size: ref.types.size_t,
33
+ capacity: ref.types.size_t
34
+ });
35
+ // Define the wrapper class.
36
+ class {{=interfaceName}}_EventWrapper {
37
+ constructor(other) {
38
+ this._wrapperFields = {};
39
+ if (typeof other === 'object' && other._refObject) {
40
+ this._refObject = new {{=interfaceName}}_EventRefStruct(other._refObject.toObject());
41
+ this._wrapperFields.info = new ServiceEventInfoWrapper(other._wrapperFields.info);
42
+ this._wrapperFields.request = {{=interfaceName}}_RequestWrapper.createArray();
43
+ this._wrapperFields.request.copy(other._wrapperFields.request);
44
+ this._wrapperFields.response = {{=interfaceName}}_ResponseWrapper.createArray();
45
+ this._wrapperFields.response.copy(other._wrapperFields.response);
46
+ } else if (typeof other !== 'undefined') {
47
+ this._initMembers();
48
+ translator.constructFromPlanObject(this, other);
49
+ } else {
50
+ this._initMembers();
51
+ }
52
+ this.freeze();
53
+ }
54
+ _initMembers() {
55
+ this._refObject = new {{=interfaceName}}_EventRefStruct();
56
+ this._wrapperFields.info = new ServiceEventInfoWrapper();
57
+ this._wrapperFields.request = {{=interfaceName}}_RequestWrapper.createArray();
58
+ this._wrapperFields.response = {{=interfaceName}}_ResponseWrapper.createArray();
59
+ }
60
+ static createFromRefObject(refObject) {
61
+ let self = new {{=interfaceName}}_EventWrapper();
62
+ self.copyRefObject(refObject);
63
+ return self;
64
+ }
65
+ static createArray() {
66
+ return new {{=interfaceName}}_EventArrayWrapper;
67
+ }
68
+ static get ArrayType() {
69
+ return {{=interfaceName}}_EventArrayWrapper;
70
+ }
71
+ static get refObjectArrayType() {
72
+ return {{=interfaceName}}_EventRefStructArray
73
+ }
74
+ static get refObjectType() {
75
+ return {{=interfaceName}}_EventRefStruct;
76
+ }
77
+ toRawROS() {
78
+ this.freeze(true);
79
+ return this._refObject.ref();
80
+ }
81
+ freeze(own = false, checkConsistency = false) {
82
+ if (checkConsistency) {
83
+ }
84
+ this._wrapperFields.info.freeze(own, checkConsistency);
85
+ this._refObject.info = this._wrapperFields.info.refObject;
86
+ this._wrapperFields.request.freeze(own, checkConsistency);
87
+ this._refObject.request = this._wrapperFields.request.refObject;
88
+ this._wrapperFields.response.freeze(own, checkConsistency);
89
+ this._refObject.response = this._wrapperFields.response.refObject;
90
+ }
91
+ serialize() {
92
+ this.freeze(false, true);
93
+ return this._refObject.ref();
94
+ }
95
+ deserialize(refObject) {
96
+ this._wrapperFields.info.copyRefObject(refObject.info);
97
+ this._wrapperFields.request.copyRefObject(refObject.request);
98
+ this._wrapperFields.response.copyRefObject(refObject.response);
99
+ }
100
+ toPlainObject(enableTypedArray) {
101
+ return translator.toPlainObject(this, enableTypedArray);
102
+ }
103
+ static freeStruct(refObject) {
104
+ ServiceEventInfoWrapper.freeStruct(refObject.info);
105
+ if (refObject.request.size != 0) {
106
+ {{=interfaceName}}_RequestWrapper.ArrayType.freeArray(refObject.request);
107
+ if ({{=interfaceName}}_RequestWrapper.ArrayType.useTypedArray) {
108
+ // Do nothing, the v8 will take the ownership of the ArrayBuffer used by the typed array.
109
+ } else {
110
+ deallocator.freeStructMember(refObject.request, {{=interfaceName}}_RequestWrapper.refObjectArrayType, 'data');
111
+ }
112
+ }
113
+ if (refObject.response.size != 0) {
114
+ {{=interfaceName}}_ResponseWrapper.ArrayType.freeArray(refObject.response);
115
+ if ({{=interfaceName}}_ResponseWrapper.ArrayType.useTypedArray) {
116
+ // Do nothing, the v8 will take the ownership of the ArrayBuffer used by the typed array.
117
+ } else {
118
+ deallocator.freeStructMember(refObject.response, {{=interfaceName}}_ResponseWrapper.refObjectArrayType, 'data');
119
+ }
120
+ }
121
+ }
122
+ static destoryRawROS(msg) {
123
+ {{=interfaceName}}_EventWrapper.freeStruct(msg.refObject);
124
+ }
125
+ static type() {
126
+ return {pkgName: '{{=pkgName}}', subFolder: '{{=subFolder}}', interfaceName: '{{=interfaceName}}_Event'};
127
+ }
128
+ static isPrimitive() {
129
+ return false;
130
+ }
131
+ static get isROSArray() {
132
+ return false;
133
+ }
134
+ get refObject() {
135
+ return this._refObject;
136
+ }
137
+ get info() {
138
+ return this._wrapperFields.info;
139
+ }
140
+ set info(value) {
141
+ if (value instanceof ServiceEventInfoWrapper) {
142
+ this._wrapperFields.info.copy(value);
143
+ } else {
144
+ this._wrapperFields.info.copy(new ServiceEventInfoWrapper(value));
145
+ }
146
+ }
147
+ get request() {
148
+ return this._wrapperFields.request;
149
+ }
150
+ set request(value) {
151
+ if (value.length > 1) {
152
+ throw new RangeError('The length of array request must be <= 1.');
153
+ }
154
+ this._wrapperFields.request.fill(value);
155
+ }
156
+ get response() {
157
+ return this._wrapperFields.response;
158
+ }
159
+ set response(value) {
160
+ if (value.length > 1) {
161
+ throw new RangeError('The length of array response must be <= 1.');
162
+ }
163
+ this._wrapperFields.response.fill(value);
164
+ }
165
+ copyRefObject(refObject) {
166
+ this._refObject = new {{=interfaceName}}_EventRefStruct(refObject.toObject());
167
+ this._wrapperFields.info.copyRefObject(this._refObject.info);
168
+ this._wrapperFields.request.copyRefObject(this._refObject.request);
169
+ this._wrapperFields.response.copyRefObject(this._refObject.response);
170
+ }
171
+ copy(other) {
172
+ this._refObject = new {{=interfaceName}}_EventRefStruct(other._refObject.toObject());
173
+ this._wrapperFields.info.copy(other._wrapperFields.info);
174
+ this._wrapperFields.request.copy(other._wrapperFields.request);
175
+ this._wrapperFields.response.copy(other._wrapperFields.response);
176
+ }
177
+ static get classType() {
178
+ return {{=interfaceName}}_EventWrapper;
179
+ }
180
+ static get ROSMessageDef() {
181
+ return {"constants":[],"fields":[{"name":"info","type":{"isArray":false,"arraySize":null,"isUpperBound":false,"isDynamicArray":false,"isFixedSizeArray":false,"pkgName":"service_msgs","type":"ServiceEventInfo","stringUpperBound":null,"isPrimitiveType":false},"default_value":null},{"name":"request","type":{"isArray":true,"arraySize":1,"isUpperBound":true,"isDynamicArray":true,"isFixedSizeArray":false,"pkgName":"{{=pkgName}}","type":"{{=interfaceName}}_Request","stringUpperBound":null,"isPrimitiveType":false},"default_value":null},{"name":"response","type":{"isArray":true,"arraySize":1,"isUpperBound":true,"isDynamicArray":true,"isFixedSizeArray":false,"pkgName":"{{=pkgName}}","type":"{{=interfaceName}}_Response","stringUpperBound":null,"isPrimitiveType":false},"default_value":null}],"baseType":{"pkgName":"{{=pkgName}}","type":"{{=interfaceName}}_Event","stringUpperBound":null,"isPrimitiveType":false},"msgName":"{{=interfaceName}}_Event"};
182
+ }
183
+ hasMember(name) {
184
+ let memberNames = ["info","request","response"];
185
+ return memberNames.indexOf(name) !== -1;
186
+ }
187
+ }
188
+ // Define the wrapper of array class.
189
+ class {{=interfaceName}}_EventArrayWrapper {
190
+ constructor(size = 0) {
191
+ this._resize(size);
192
+ }
193
+ toRawROS() {
194
+ return this._refObject.ref();
195
+ }
196
+ fill(values) {
197
+ const length = values.length;
198
+ this._resize(length);
199
+ values.forEach((value, index) => {
200
+ if (value instanceof {{=interfaceName}}_EventWrapper) {
201
+ this._wrappers[index].copy(value);
202
+ } else {
203
+ this._wrappers[index] = new {{=interfaceName}}_EventWrapper(value);
204
+ }
205
+ });
206
+ }
207
+ // Put all data currently stored in `this._wrappers` into `this._refObject`
208
+ freeze(own) {
209
+ this._wrappers.forEach((wrapper, index) => {
210
+ wrapper.freeze(own);
211
+ this._refArray[index] = wrapper.refObject;
212
+ });
213
+ this._refObject.size = this._wrappers.length;
214
+ this._refObject.capacity = this._wrappers.length;
215
+ if (this._refObject.capacity === 0) {
216
+ this._refObject.data = null
217
+ } else {
218
+ this._refObject.data = this._refArray.buffer;
219
+ }
220
+ }
221
+ get refObject() {
222
+ return this._refObject;
223
+ }
224
+ get data() {
225
+ return this._wrappers;
226
+ }
227
+ get size() {
228
+ return this._wrappers.length;
229
+ }
230
+ set size(value) {
231
+ if (typeof value != 'number') {
232
+ throw new TypeError('Invalid argument: should provide a number to {{=interfaceName}}_EventArrayWrapper.size setter');
233
+ return;
234
+ }
235
+ return this._resize(value);
236
+ }
237
+ get capacity() {
238
+ return this._wrappers.length;
239
+ }
240
+ set capacity(value) {
241
+ if (typeof value != 'number') {
242
+ throw new TypeError('Invalid argument: should provide a number to {{=interfaceName}}_EventArrayWrapper.capacity setter');
243
+ }
244
+ return this._resize(value);
245
+ }
246
+ get refObject() {
247
+ return this._refObject;
248
+ }
249
+ _resize(size) {
250
+ if (size < 0) {
251
+ throw new RangeError('Invalid argument: should provide a positive number');
252
+ return;
253
+ }
254
+ this._refArray = new {{=interfaceName}}_EventRefArray(size);
255
+ this._refObject = new {{=interfaceName}}_EventRefStructArray();
256
+ this._refObject.size = size;
257
+ this._refObject.capacity = size;
258
+ this._wrappers = new Array();
259
+ for (let i = 0; i < size; i++) {
260
+ this._wrappers.push(new {{=interfaceName}}_EventWrapper());
261
+ }
262
+ }
263
+ // Copy all data from `this._refObject` into `this._wrappers`
264
+ copyRefObject(refObject) {
265
+ this._refObject = refObject;
266
+ let refObjectArray = this._refObject.data;
267
+ refObjectArray.length = this._refObject.size;
268
+ this._resize(this._refObject.size);
269
+ for (let index = 0; index < this._refObject.size; index++) {
270
+ this._wrappers[index].copyRefObject(refObjectArray[index]);
271
+ }
272
+ }
273
+ copy(other) {
274
+ if (! (other instanceof {{=interfaceName}}_EventArrayWrapper)) {
275
+ throw new TypeError('Invalid argument: should provide "{{=interfaceName}}_EventArrayWrapper".');
276
+ }
277
+ this._resize(other.size);
278
+ // Array deep copy
279
+ other._wrappers.forEach((wrapper, index) => {
280
+ this._wrappers[index].copy(wrapper);
281
+ });
282
+ }
283
+ static freeArray(refObject) {
284
+ let refObjectArray = refObject.data;
285
+ refObjectArray.length = refObject.size;
286
+ for (let index = 0; index < refObject.size; index++) {
287
+ {{=interfaceName}}_EventWrapper.freeStruct(refObjectArray[index]);
288
+ }
289
+ }
290
+ static get elementType() {
291
+ return {{=interfaceName}}_EventWrapper;
292
+ }
293
+ static get isROSArray() {
294
+ return true;
295
+ }
296
+ static get useTypedArray() {
297
+ return false;
298
+ }
299
+ get classType() {
300
+ return {{=interfaceName}}_EventArrayWrapper;
301
+ }
302
+ }
303
+ module.exports = {{=interfaceName}}_EventWrapper;
304
+
@@ -38,9 +38,9 @@ async function generateAll() {
38
38
  const generatedPath = path.join(__dirname, '../generated/');
39
39
  const pkgInfos = getPkgInfos(generatedPath);
40
40
 
41
- // write message.d.ts file
42
- const messagesFilePath = path.join(__dirname, '../types/interfaces.d.ts');
43
- const fd = fs.openSync(messagesFilePath, 'w');
41
+ // write interfaces.d.ts file
42
+ const interfacesFilePath = path.join(__dirname, '../types/interfaces.d.ts');
43
+ const fd = fs.openSync(interfacesFilePath, 'w');
44
44
  savePkgInfoAsTSD(pkgInfos, fd);
45
45
  await wait(500); // hack to avoid random segfault
46
46
  fs.closeSync(fd);
@@ -235,7 +235,9 @@ function saveMsgAsTSD(rosMsgInterface, fd) {
235
235
  fd,
236
236
  ` export interface ${rosMsgInterface.type().interfaceName} {\n`
237
237
  );
238
- const useSamePkg = isInternalActionMsgInterface(rosMsgInterface);
238
+ const useSamePkg =
239
+ isInternalActionMsgInterface(rosMsgInterface) ||
240
+ isInternalServiceEventMsgInterface(rosMsgInterface);
239
241
  saveMsgFieldsAsTSD(rosMsgInterface, fd, 8, ';', '', useSamePkg);
240
242
  fs.writeSync(fd, ' }\n');
241
243
  }
@@ -270,7 +272,6 @@ function saveMsgFieldsAsTSD(
270
272
  useSamePackageSubFolder && field.type.pkgName === type.pkgName
271
273
  ? type.subFolder
272
274
  : 'msg';
273
-
274
275
  let fieldType = fieldType2JSName(field, subFolder);
275
276
  let tp = field.type.isPrimitiveType ? '' : typePrefix;
276
277
  if (typePrefix === 'rclnodejs.') {
@@ -346,13 +347,6 @@ function isMsgInterface(rosInterface) {
346
347
  return rosInterface.hasOwnProperty('ROSMessageDef');
347
348
  }
348
349
 
349
- function isServiceMsgInterface(rosMsgInterface) {
350
- if (!isMsgInterface(rosMsgInterface)) return false;
351
-
352
- let name = rosMsgInterface.type().interfaceName;
353
- return name.endsWith('_Request') || name.endsWith('_Response');
354
- }
355
-
356
350
  function isInternalActionMsgInterface(rosMsgInterface) {
357
351
  let name = rosMsgInterface.type().interfaceName;
358
352
  return (
@@ -364,6 +358,15 @@ function isInternalActionMsgInterface(rosMsgInterface) {
364
358
  );
365
359
  }
366
360
 
361
+ function isInternalServiceEventMsgInterface(rosMsgInterface) {
362
+ let name = rosMsgInterface.type().interfaceName;
363
+ let subFolder = rosMsgInterface.type().subFolder;
364
+ return (
365
+ (subFolder == 'srv' || subFolder == 'action')
366
+ && name.endsWith('_Event')
367
+ );
368
+ }
369
+
367
370
  function isSrvInterface(rosInterface) {
368
371
  return (
369
372
  rosInterface.hasOwnProperty('Request') &&
@@ -1,4 +1,4 @@
1
- # rclnodejs [![Build Status](https://travis-ci.org/RobotWebTools/rclnodejs.svg?branch=develop)](https://travis-ci.org/RobotWebTools/rclnodejs)
1
+ # rclnodejs ![GitHub Workflow Status](https://github.com/RobotWebTools/rclnodejs/actions/workflows/linux-build-and-test.yml/badge.svg?branch=iron-irwini)
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 between 10.23 - 17.x.
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
- | RCLNODEJS Version | Compatible ROS 2 Release |
47
- | :-------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
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
- | [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](http://robotwebtools.org/rclnodejs/docs/index.html) is available online.
52
+ API [documentation](https://robotwebtools.github.io/rclnodejs/docs/index.html) is available online.
54
53
 
55
54
  ## JavaScript Examples
56
55
 
@@ -36,6 +36,10 @@
36
36
  #include <rosidl_generator_c/string_functions.h>
37
37
  #endif
38
38
 
39
+ #if ROS_VERSION > 2205
40
+ #include <rcl/service_introspection.h>
41
+ #endif
42
+
39
43
  #include <iostream>
40
44
  #include <memory>
41
45
  #include <string>
@@ -1120,6 +1124,68 @@ NAN_METHOD(SendResponse) {
1120
1124
  RCL_RET_OK, rcl_get_error_string().str);
1121
1125
  }
1122
1126
 
1127
+ #if ROS_VERSION > 2205 // 2205 == Humble
1128
+ NAN_METHOD(ConfigureServiceIntrospection) {
1129
+ v8::Local<v8::Context> currentContent = Nan::GetCurrentContext();
1130
+
1131
+ RclHandle* node_handle = RclHandle::Unwrap<RclHandle>(
1132
+ Nan::To<v8::Object>(info[1]).ToLocalChecked());
1133
+ rcl_node_t* node = reinterpret_cast<rcl_node_t*>(node_handle->ptr());
1134
+
1135
+ rcl_clock_t* clock = reinterpret_cast<rcl_clock_t*>(
1136
+ RclHandle::Unwrap<RclHandle>(
1137
+ Nan::To<v8::Object>(info[2]).ToLocalChecked())
1138
+ ->ptr());
1139
+
1140
+ std::string interface_name(
1141
+ *Nan::Utf8String(info[3]->ToString(currentContent).ToLocalChecked()));
1142
+ std::string package_name(
1143
+ *Nan::Utf8String(info[4]->ToString(currentContent).ToLocalChecked()));
1144
+ const rosidl_service_type_support_t* ts =
1145
+ GetServiceTypeSupport(package_name, interface_name);
1146
+
1147
+ if (ts) {
1148
+ rcl_publisher_options_t publisher_ops = rcl_publisher_get_default_options();
1149
+ auto qos_profile = GetQoSProfile(info[5]);
1150
+ if (qos_profile) {
1151
+ publisher_ops.qos = *qos_profile;
1152
+ }
1153
+
1154
+ rcl_service_introspection_state_t state =
1155
+ static_cast<rcl_service_introspection_state_t>(
1156
+ Nan::To<uint32_t>(info[6]).ToChecked());
1157
+
1158
+ bool configureForService = Nan::To<bool>(info[7]).FromJust();
1159
+
1160
+ if (configureForService) {
1161
+ RclHandle* service_handle = RclHandle::Unwrap<RclHandle>(
1162
+ Nan::To<v8::Object>(info[0]).ToLocalChecked());
1163
+ rcl_service_t* service =
1164
+ reinterpret_cast<rcl_service_t*>(service_handle->ptr());
1165
+
1166
+ THROW_ERROR_IF_NOT_EQUAL(
1167
+ rcl_service_configure_service_introspection(service, node, clock, ts,
1168
+ publisher_ops, state),
1169
+ RCL_RET_OK, rcl_get_error_string().str);
1170
+
1171
+ } else {
1172
+ RclHandle* client_handle = RclHandle::Unwrap<RclHandle>(
1173
+ Nan::To<v8::Object>(info[0]).ToLocalChecked());
1174
+ rcl_client_t* client =
1175
+ reinterpret_cast<rcl_client_t*>(client_handle->ptr());
1176
+
1177
+ THROW_ERROR_IF_NOT_EQUAL(
1178
+ rcl_client_configure_service_introspection(client, node, clock, ts,
1179
+ publisher_ops, state),
1180
+ RCL_RET_OK, rcl_get_error_string().str);
1181
+ }
1182
+
1183
+ } else {
1184
+ Nan::ThrowError(GetErrorMessageAndClear().c_str());
1185
+ }
1186
+ }
1187
+ #endif
1188
+
1123
1189
  NAN_METHOD(ValidateFullTopicName) {
1124
1190
  v8::Local<v8::Context> currentContent = Nan::GetCurrentContext();
1125
1191
  int validation_result;
@@ -2011,6 +2077,11 @@ std::vector<BindingMethod> binding_methods = {
2011
2077
  {"serviceServerIsAvailable", ServiceServerIsAvailable},
2012
2078
  {"publishRawMessage", PublishRawMessage},
2013
2079
  {"rclTakeRaw", RclTakeRaw},
2014
- {"", nullptr}};
2080
+ {"", nullptr}
2081
+ #if ROS_VERSION > 2205 // 2205 == Humble
2082
+ ,
2083
+ {"configureServiceIntrospection", ConfigureServiceIntrospection}
2084
+ #endif
2085
+ };
2015
2086
 
2016
2087
  } // namespace rclnodejs
package/types/base.d.ts CHANGED
@@ -21,6 +21,7 @@
21
21
  /// <reference path="qos.d.ts" />
22
22
  /// <reference path="rate.d.ts" />
23
23
  /// <reference path="service.d.ts" />
24
+ /// <reference path="service_introspection.d.ts" />
24
25
  /// <reference path="subscription.d.ts" />
25
26
  /// <reference path="time_source.d.ts" />
26
27
  /// <reference path="time.d.ts" />
package/types/client.d.ts CHANGED
@@ -40,6 +40,18 @@ declare module 'rclnodejs' {
40
40
  * Name of the service to which requests are made.
41
41
  */
42
42
  readonly serviceName: string;
43
+
44
+ /**
45
+ * Configure introspection.
46
+ * @param clock - Clock to use for service event timestamps
47
+ * @param QoSProfile - QOS profile for the service event publisher
48
+ * @param introspectionState - The state to set introspection to
49
+ */
50
+ configureIntrospection(
51
+ clock: Clock,
52
+ serviceEventPubQOS: QoS,
53
+ introspectionState: ServiceIntrospectionStates
54
+ ): void;
43
55
  }
44
56
 
45
57
  namespace Client {