rclnodejs 1.7.0 → 1.8.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/binding.gyp +2 -0
- package/index.js +93 -0
- package/lib/action/client.js +54 -1
- package/lib/client.js +66 -1
- package/lib/clock.js +178 -0
- package/lib/clock_change.js +49 -0
- package/lib/clock_event.js +88 -0
- package/lib/errors.js +50 -0
- package/lib/logging.js +78 -0
- package/lib/message_introspector.js +123 -0
- package/lib/message_validation.js +512 -0
- package/lib/node.js +133 -1
- package/lib/node_options.js +40 -1
- package/lib/observable_subscription.js +105 -0
- package/lib/publisher.js +56 -1
- package/lib/qos.js +57 -0
- package/lib/subscription.js +8 -0
- package/lib/timer.js +42 -0
- package/lib/validator.js +63 -7
- package/package.json +4 -2
- package/prebuilds/linux-arm64/humble-jammy-arm64-rclnodejs.node +0 -0
- package/prebuilds/linux-arm64/jazzy-noble-arm64-rclnodejs.node +0 -0
- package/prebuilds/linux-arm64/kilted-noble-arm64-rclnodejs.node +0 -0
- package/prebuilds/linux-x64/humble-jammy-x64-rclnodejs.node +0 -0
- package/prebuilds/linux-x64/jazzy-noble-x64-rclnodejs.node +0 -0
- package/prebuilds/linux-x64/kilted-noble-x64-rclnodejs.node +0 -0
- package/rosidl_gen/message_translator.js +0 -61
- package/scripts/config.js +1 -0
- package/src/addon.cpp +2 -0
- package/src/clock_event.cpp +268 -0
- package/src/clock_event.hpp +62 -0
- package/src/macros.h +2 -4
- package/src/rcl_action_server_bindings.cpp +21 -3
- package/src/rcl_bindings.cpp +59 -0
- package/src/rcl_context_bindings.cpp +5 -0
- package/src/rcl_graph_bindings.cpp +73 -0
- package/src/rcl_logging_bindings.cpp +158 -0
- package/src/rcl_node_bindings.cpp +14 -2
- package/src/rcl_publisher_bindings.cpp +12 -0
- package/src/rcl_service_bindings.cpp +7 -6
- package/src/rcl_subscription_bindings.cpp +51 -14
- package/src/rcl_time_point_bindings.cpp +135 -0
- package/src/rcl_timer_bindings.cpp +140 -0
- package/src/rcl_utilities.cpp +103 -2
- package/src/rcl_utilities.h +7 -1
- package/types/action_client.d.ts +27 -2
- package/types/base.d.ts +3 -0
- package/types/client.d.ts +29 -1
- package/types/clock.d.ts +86 -0
- package/types/clock_change.d.ts +27 -0
- package/types/clock_event.d.ts +51 -0
- package/types/errors.d.ts +49 -0
- package/types/index.d.ts +10 -0
- package/types/interfaces.d.ts +1 -1910
- package/types/logging.d.ts +32 -0
- package/types/message_introspector.d.ts +75 -0
- package/types/message_validation.d.ts +183 -0
- package/types/node.d.ts +67 -0
- package/types/node_options.d.ts +13 -0
- package/types/observable_subscription.d.ts +39 -0
- package/types/publisher.d.ts +28 -1
- package/types/qos.d.ts +18 -0
- package/types/subscription.d.ts +6 -0
- package/types/timer.d.ts +18 -0
- package/types/validator.d.ts +86 -0
|
@@ -17,12 +17,48 @@
|
|
|
17
17
|
#include <rcl/error_handling.h>
|
|
18
18
|
#include <rcl/rcl.h>
|
|
19
19
|
|
|
20
|
+
#include <memory>
|
|
21
|
+
#include <mutex>
|
|
22
|
+
#include <unordered_map>
|
|
23
|
+
|
|
20
24
|
#include "macros.h"
|
|
21
25
|
#include "rcl_handle.h"
|
|
22
26
|
#include "rcl_utilities.h"
|
|
23
27
|
|
|
24
28
|
namespace rclnodejs {
|
|
25
29
|
|
|
30
|
+
struct TimerContext {
|
|
31
|
+
Napi::ThreadSafeFunction on_reset_callback;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
static std::unordered_map<rcl_timer_t*, std::shared_ptr<TimerContext>>
|
|
35
|
+
g_timer_contexts;
|
|
36
|
+
static std::mutex g_timer_contexts_mutex;
|
|
37
|
+
|
|
38
|
+
void TimerOnResetCallbackTrampoline(const void* user_data,
|
|
39
|
+
size_t number_of_events) {
|
|
40
|
+
const rcl_timer_t* timer = static_cast<const rcl_timer_t*>(user_data);
|
|
41
|
+
std::shared_ptr<TimerContext> context;
|
|
42
|
+
|
|
43
|
+
{
|
|
44
|
+
std::lock_guard<std::mutex> lock(g_timer_contexts_mutex);
|
|
45
|
+
auto it = g_timer_contexts.find(const_cast<rcl_timer_t*>(timer));
|
|
46
|
+
if (it != g_timer_contexts.end()) {
|
|
47
|
+
context = it->second;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (context) {
|
|
52
|
+
auto callback = [](Napi::Env env, Napi::Function js_callback,
|
|
53
|
+
size_t* events) {
|
|
54
|
+
js_callback.Call({Napi::Number::New(env, *events)});
|
|
55
|
+
delete events;
|
|
56
|
+
};
|
|
57
|
+
size_t* events_ptr = new size_t(number_of_events);
|
|
58
|
+
context->on_reset_callback.BlockingCall(events_ptr, callback);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
26
62
|
Napi::Value CreateTimer(const Napi::CallbackInfo& info) {
|
|
27
63
|
Napi::Env env = info.Env();
|
|
28
64
|
|
|
@@ -61,6 +97,30 @@ Napi::Value CreateTimer(const Napi::CallbackInfo& info) {
|
|
|
61
97
|
auto js_obj =
|
|
62
98
|
RclHandle::NewInstance(env, timer, clock_handle, [env](void* ptr) {
|
|
63
99
|
rcl_timer_t* timer = reinterpret_cast<rcl_timer_t*>(ptr);
|
|
100
|
+
|
|
101
|
+
#if ROS_VERSION > 2205
|
|
102
|
+
// Clear the callback first to prevent any new callbacks from being
|
|
103
|
+
// triggered
|
|
104
|
+
rcl_ret_t callback_ret =
|
|
105
|
+
rcl_timer_set_on_reset_callback(timer, nullptr, nullptr);
|
|
106
|
+
THROW_ERROR_IF_NOT_EQUAL_NO_RETURN(RCL_RET_OK, callback_ret,
|
|
107
|
+
rcl_get_error_string().str);
|
|
108
|
+
#endif
|
|
109
|
+
|
|
110
|
+
std::shared_ptr<TimerContext> context;
|
|
111
|
+
{
|
|
112
|
+
std::lock_guard<std::mutex> lock(g_timer_contexts_mutex);
|
|
113
|
+
auto it = g_timer_contexts.find(timer);
|
|
114
|
+
if (it != g_timer_contexts.end()) {
|
|
115
|
+
context = it->second;
|
|
116
|
+
g_timer_contexts.erase(it);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (context) {
|
|
121
|
+
context->on_reset_callback.Release();
|
|
122
|
+
}
|
|
123
|
+
|
|
64
124
|
rcl_ret_t ret = rcl_timer_fini(timer);
|
|
65
125
|
free(ptr);
|
|
66
126
|
THROW_ERROR_IF_NOT_EQUAL_NO_RETURN(RCL_RET_OK, ret,
|
|
@@ -197,6 +257,26 @@ Napi::Value GetTimerPeriod(const Napi::CallbackInfo& info) {
|
|
|
197
257
|
return Napi::BigInt::New(env, period_nsec);
|
|
198
258
|
}
|
|
199
259
|
|
|
260
|
+
#if ROS_VERSION > 2205 // 2205 == Humble
|
|
261
|
+
Napi::Value GetTimerNextCallTime(const Napi::CallbackInfo& info) {
|
|
262
|
+
Napi::Env env = info.Env();
|
|
263
|
+
RclHandle* timer_handle = RclHandle::Unwrap(info[0].As<Napi::Object>());
|
|
264
|
+
rcl_timer_t* timer = reinterpret_cast<rcl_timer_t*>(timer_handle->ptr());
|
|
265
|
+
int64_t next_call_time = 0;
|
|
266
|
+
|
|
267
|
+
rcl_ret_t ret = rcl_timer_get_next_call_time(timer, &next_call_time);
|
|
268
|
+
|
|
269
|
+
if (ret == RCL_RET_OK) {
|
|
270
|
+
return Napi::BigInt::New(env, next_call_time);
|
|
271
|
+
} else if (ret == RCL_RET_TIMER_CANCELED) {
|
|
272
|
+
return env.Null();
|
|
273
|
+
} else {
|
|
274
|
+
THROW_ERROR_IF_NOT_EQUAL(RCL_RET_OK, ret, rcl_get_error_string().str);
|
|
275
|
+
return env.Undefined(); // Safeguard return, should not reach here
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
#endif
|
|
279
|
+
|
|
200
280
|
#if ROS_VERSION > 2205 // 2205 == Humble
|
|
201
281
|
Napi::Value CallTimerWithInfo(const Napi::CallbackInfo& info) {
|
|
202
282
|
Napi::Env env = info.Env();
|
|
@@ -215,6 +295,60 @@ Napi::Value CallTimerWithInfo(const Napi::CallbackInfo& info) {
|
|
|
215
295
|
Napi::BigInt::New(env, call_info.actual_call_time));
|
|
216
296
|
return timer_info;
|
|
217
297
|
}
|
|
298
|
+
|
|
299
|
+
Napi::Value SetTimerOnResetCallback(const Napi::CallbackInfo& info) {
|
|
300
|
+
Napi::Env env = info.Env();
|
|
301
|
+
RclHandle* timer_handle = RclHandle::Unwrap(info[0].As<Napi::Object>());
|
|
302
|
+
rcl_timer_t* timer = reinterpret_cast<rcl_timer_t*>(timer_handle->ptr());
|
|
303
|
+
|
|
304
|
+
if (!info[1].IsFunction()) {
|
|
305
|
+
Napi::TypeError::New(env, "Callback must be a function")
|
|
306
|
+
.ThrowAsJavaScriptException();
|
|
307
|
+
return env.Undefined();
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
Napi::Function callback = info[1].As<Napi::Function>();
|
|
311
|
+
|
|
312
|
+
std::lock_guard<std::mutex> lock(g_timer_contexts_mutex);
|
|
313
|
+
std::shared_ptr<TimerContext> context;
|
|
314
|
+
auto it = g_timer_contexts.find(timer);
|
|
315
|
+
if (it == g_timer_contexts.end()) {
|
|
316
|
+
context = std::make_shared<TimerContext>();
|
|
317
|
+
g_timer_contexts[timer] = context;
|
|
318
|
+
} else {
|
|
319
|
+
context = it->second;
|
|
320
|
+
context->on_reset_callback.Release();
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
context->on_reset_callback = Napi::ThreadSafeFunction::New(
|
|
324
|
+
env, callback, "TimerOnResetCallback", 0, 1);
|
|
325
|
+
|
|
326
|
+
THROW_ERROR_IF_NOT_EQUAL(RCL_RET_OK,
|
|
327
|
+
rcl_timer_set_on_reset_callback(
|
|
328
|
+
timer, TimerOnResetCallbackTrampoline, timer),
|
|
329
|
+
rcl_get_error_string().str);
|
|
330
|
+
|
|
331
|
+
return env.Undefined();
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
Napi::Value ClearTimerOnResetCallback(const Napi::CallbackInfo& info) {
|
|
335
|
+
Napi::Env env = info.Env();
|
|
336
|
+
RclHandle* timer_handle = RclHandle::Unwrap(info[0].As<Napi::Object>());
|
|
337
|
+
rcl_timer_t* timer = reinterpret_cast<rcl_timer_t*>(timer_handle->ptr());
|
|
338
|
+
|
|
339
|
+
std::lock_guard<std::mutex> lock(g_timer_contexts_mutex);
|
|
340
|
+
auto it = g_timer_contexts.find(timer);
|
|
341
|
+
if (it != g_timer_contexts.end()) {
|
|
342
|
+
it->second->on_reset_callback.Release();
|
|
343
|
+
g_timer_contexts.erase(it);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
THROW_ERROR_IF_NOT_EQUAL(
|
|
347
|
+
RCL_RET_OK, rcl_timer_set_on_reset_callback(timer, nullptr, nullptr),
|
|
348
|
+
rcl_get_error_string().str);
|
|
349
|
+
|
|
350
|
+
return env.Undefined();
|
|
351
|
+
}
|
|
218
352
|
#endif
|
|
219
353
|
|
|
220
354
|
Napi::Object InitTimerBindings(Napi::Env env, Napi::Object exports) {
|
|
@@ -231,6 +365,12 @@ Napi::Object InitTimerBindings(Napi::Env env, Napi::Object exports) {
|
|
|
231
365
|
exports.Set("changeTimerPeriod", Napi::Function::New(env, ChangeTimerPeriod));
|
|
232
366
|
exports.Set("getTimerPeriod", Napi::Function::New(env, GetTimerPeriod));
|
|
233
367
|
#if ROS_VERSION > 2205 // 2205 == Humble
|
|
368
|
+
exports.Set("getTimerNextCallTime",
|
|
369
|
+
Napi::Function::New(env, GetTimerNextCallTime));
|
|
370
|
+
exports.Set("setTimerOnResetCallback",
|
|
371
|
+
Napi::Function::New(env, SetTimerOnResetCallback));
|
|
372
|
+
exports.Set("clearTimerOnResetCallback",
|
|
373
|
+
Napi::Function::New(env, ClearTimerOnResetCallback));
|
|
234
374
|
exports.Set("callTimerWithInfo", Napi::Function::New(env, CallTimerWithInfo));
|
|
235
375
|
#endif
|
|
236
376
|
return exports;
|
package/src/rcl_utilities.cpp
CHANGED
|
@@ -21,6 +21,8 @@
|
|
|
21
21
|
|
|
22
22
|
#include <cstdio>
|
|
23
23
|
#include <memory>
|
|
24
|
+
#include <rcpputils/scope_exit.hpp>
|
|
25
|
+
// NOLINTNEXTLINE
|
|
24
26
|
#include <string>
|
|
25
27
|
|
|
26
28
|
namespace {
|
|
@@ -55,6 +57,7 @@ std::unique_ptr<rmw_qos_profile_t> GetQosProfileFromObject(
|
|
|
55
57
|
auto depth = object.Get("depth");
|
|
56
58
|
auto reliability = object.Get("reliability");
|
|
57
59
|
auto durability = object.Get("durability");
|
|
60
|
+
auto liveliness = object.Get("liveliness");
|
|
58
61
|
auto avoid_ros_namespace_conventions =
|
|
59
62
|
object.Get("avoidRosNameSpaceConventions");
|
|
60
63
|
|
|
@@ -65,6 +68,8 @@ std::unique_ptr<rmw_qos_profile_t> GetQosProfileFromObject(
|
|
|
65
68
|
reliability.As<Napi::Number>().Uint32Value());
|
|
66
69
|
qos_profile->durability = static_cast<rmw_qos_durability_policy_t>(
|
|
67
70
|
durability.As<Napi::Number>().Uint32Value());
|
|
71
|
+
qos_profile->liveliness = static_cast<rmw_qos_liveliness_policy_t>(
|
|
72
|
+
liveliness.As<Napi::Number>().Uint32Value());
|
|
68
73
|
qos_profile->avoid_ros_namespace_conventions =
|
|
69
74
|
avoid_ros_namespace_conventions.As<Napi::Boolean>();
|
|
70
75
|
|
|
@@ -119,6 +124,48 @@ Napi::Value ConvertToJSTopicEndpoint(
|
|
|
119
124
|
return endpoint;
|
|
120
125
|
}
|
|
121
126
|
|
|
127
|
+
#if ROS_VERSION > 2505
|
|
128
|
+
Napi::Value ConvertToJSServiceEndpointInfo(
|
|
129
|
+
Napi::Env env, const rmw_service_endpoint_info_t* service_endpoint_info) {
|
|
130
|
+
Napi::Object endpoint = Napi::Object::New(env);
|
|
131
|
+
endpoint.Set("node_name",
|
|
132
|
+
Napi::String::New(env, service_endpoint_info->node_name));
|
|
133
|
+
endpoint.Set("node_namespace",
|
|
134
|
+
Napi::String::New(env, service_endpoint_info->node_namespace));
|
|
135
|
+
endpoint.Set("service_type",
|
|
136
|
+
Napi::String::New(env, service_endpoint_info->service_type));
|
|
137
|
+
endpoint.Set(
|
|
138
|
+
"service_type_hash",
|
|
139
|
+
ConvertToHashObject(env, &service_endpoint_info->service_type_hash));
|
|
140
|
+
endpoint.Set(
|
|
141
|
+
"endpoint_type",
|
|
142
|
+
Napi::Number::New(
|
|
143
|
+
env, static_cast<int>(service_endpoint_info->endpoint_type)));
|
|
144
|
+
endpoint.Set("endpoint_count",
|
|
145
|
+
Napi::Number::New(env, service_endpoint_info->endpoint_count));
|
|
146
|
+
|
|
147
|
+
Napi::Array endpoint_gids =
|
|
148
|
+
Napi::Array::New(env, service_endpoint_info->endpoint_count);
|
|
149
|
+
Napi::Array qos_profiles =
|
|
150
|
+
Napi::Array::New(env, service_endpoint_info->endpoint_count);
|
|
151
|
+
|
|
152
|
+
for (size_t i = 0; i < service_endpoint_info->endpoint_count; i++) {
|
|
153
|
+
Napi::Array gid = Napi::Array::New(env, RMW_GID_STORAGE_SIZE);
|
|
154
|
+
for (size_t j = 0; j < RMW_GID_STORAGE_SIZE; j++) {
|
|
155
|
+
gid.Set(j, Napi::Number::New(env,
|
|
156
|
+
service_endpoint_info->endpoint_gids[i][j]));
|
|
157
|
+
}
|
|
158
|
+
endpoint_gids.Set(i, gid);
|
|
159
|
+
qos_profiles.Set(i, rclnodejs::ConvertToQoS(
|
|
160
|
+
env, &service_endpoint_info->qos_profiles[i]));
|
|
161
|
+
}
|
|
162
|
+
endpoint.Set("endpoint_gids", endpoint_gids);
|
|
163
|
+
endpoint.Set("qos_profiles", qos_profiles);
|
|
164
|
+
|
|
165
|
+
return endpoint;
|
|
166
|
+
}
|
|
167
|
+
#endif // ROS_VERSION > 2505
|
|
168
|
+
|
|
122
169
|
uv_lib_t g_lib;
|
|
123
170
|
Napi::Env g_env = nullptr;
|
|
124
171
|
|
|
@@ -261,6 +308,19 @@ Napi::Array ConvertToJSTopicEndpointInfoList(
|
|
|
261
308
|
return list;
|
|
262
309
|
}
|
|
263
310
|
|
|
311
|
+
#if ROS_VERSION > 2505
|
|
312
|
+
Napi::Array ConvertToJSServiceEndpointInfoList(
|
|
313
|
+
Napi::Env env, const rmw_service_endpoint_info_array_t* info_array) {
|
|
314
|
+
Napi::Array list = Napi::Array::New(env, info_array->size);
|
|
315
|
+
for (size_t i = 0; i < info_array->size; ++i) {
|
|
316
|
+
rmw_service_endpoint_info_t service_endpoint_info =
|
|
317
|
+
info_array->info_array[i];
|
|
318
|
+
list.Set(i, ConvertToJSServiceEndpointInfo(env, &service_endpoint_info));
|
|
319
|
+
}
|
|
320
|
+
return list;
|
|
321
|
+
}
|
|
322
|
+
#endif // ROS_VERSION > 2505
|
|
323
|
+
|
|
264
324
|
char** AbstractArgsFromNapiArray(const Napi::Array& jsArgv) {
|
|
265
325
|
size_t argc = jsArgv.Length();
|
|
266
326
|
char** argv = nullptr;
|
|
@@ -286,9 +346,50 @@ void FreeArgs(char** argv, size_t argc) {
|
|
|
286
346
|
}
|
|
287
347
|
}
|
|
288
348
|
|
|
289
|
-
|
|
349
|
+
void ThrowIfUnparsedROSArgs(Napi::Env env, const Napi::Array& jsArgv,
|
|
350
|
+
const rcl_arguments_t& rcl_args) {
|
|
290
351
|
int unparsed_ros_args_count = rcl_arguments_get_count_unparsed_ros(&rcl_args);
|
|
291
|
-
|
|
352
|
+
|
|
353
|
+
if (unparsed_ros_args_count < 0) {
|
|
354
|
+
Napi::Error::New(env, "Failed to count unparsed arguments")
|
|
355
|
+
.ThrowAsJavaScriptException();
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
if (0 == unparsed_ros_args_count) {
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
rcl_allocator_t allocator = rcl_get_default_allocator();
|
|
363
|
+
int* unparsed_indices_c = nullptr;
|
|
364
|
+
rcl_ret_t ret =
|
|
365
|
+
rcl_arguments_get_unparsed_ros(&rcl_args, allocator, &unparsed_indices_c);
|
|
366
|
+
if (RCL_RET_OK != ret) {
|
|
367
|
+
Napi::Error::New(env, "Failed to get unparsed arguments")
|
|
368
|
+
.ThrowAsJavaScriptException();
|
|
369
|
+
return;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
RCPPUTILS_SCOPE_EXIT(
|
|
373
|
+
{ allocator.deallocate(unparsed_indices_c, allocator.state); });
|
|
374
|
+
|
|
375
|
+
std::string unparsed_args_str = "[";
|
|
376
|
+
for (int i = 0; i < unparsed_ros_args_count; ++i) {
|
|
377
|
+
int index = unparsed_indices_c[i];
|
|
378
|
+
if (index < 0 || static_cast<size_t>(index) >= jsArgv.Length()) {
|
|
379
|
+
Napi::Error::New(env, "Got invalid unparsed ROS arg index")
|
|
380
|
+
.ThrowAsJavaScriptException();
|
|
381
|
+
return;
|
|
382
|
+
}
|
|
383
|
+
std::string arg = jsArgv.Get(index).As<Napi::String>().Utf8Value();
|
|
384
|
+
unparsed_args_str += "'" + arg + "'";
|
|
385
|
+
if (i < unparsed_ros_args_count - 1) {
|
|
386
|
+
unparsed_args_str += ", ";
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
unparsed_args_str += "]";
|
|
390
|
+
|
|
391
|
+
Napi::Error::New(env, "Unknown ROS arguments: " + unparsed_args_str)
|
|
392
|
+
.ThrowAsJavaScriptException();
|
|
292
393
|
}
|
|
293
394
|
|
|
294
395
|
} // namespace rclnodejs
|
package/src/rcl_utilities.h
CHANGED
|
@@ -51,6 +51,11 @@ void ExtractNamesAndTypes(rcl_names_and_types_t names_and_types,
|
|
|
51
51
|
Napi::Array ConvertToJSTopicEndpointInfoList(
|
|
52
52
|
Napi::Env env, const rmw_topic_endpoint_info_array_t* info_array);
|
|
53
53
|
|
|
54
|
+
#if ROS_VERSION > 2505
|
|
55
|
+
Napi::Array ConvertToJSServiceEndpointInfoList(
|
|
56
|
+
Napi::Env env, const rmw_service_endpoint_info_array_t* info_array);
|
|
57
|
+
#endif // ROS_VERSION > 2505
|
|
58
|
+
|
|
54
59
|
Napi::Value ConvertToQoS(Napi::Env env, const rmw_qos_profile_t* qos_profile);
|
|
55
60
|
|
|
56
61
|
// `AbstractArgsFromNapiArray` and `FreeArgs` must be called in pairs.
|
|
@@ -58,7 +63,8 @@ char** AbstractArgsFromNapiArray(const Napi::Array& jsArgv);
|
|
|
58
63
|
// `AbstractArgsFromNapiArray` and `FreeArgs` must be called in pairs.
|
|
59
64
|
void FreeArgs(char** argv, size_t argc);
|
|
60
65
|
|
|
61
|
-
|
|
66
|
+
void ThrowIfUnparsedROSArgs(Napi::Env env, const Napi::Array& jsArgv,
|
|
67
|
+
const rcl_arguments_t& rcl_args);
|
|
62
68
|
|
|
63
69
|
} // namespace rclnodejs
|
|
64
70
|
|
package/types/action_client.d.ts
CHANGED
|
@@ -115,6 +115,14 @@ declare module 'rclnodejs' {
|
|
|
115
115
|
statusSubQosProfile?: QoS | QoS.ProfileRef;
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
+
/**
|
|
119
|
+
* Options for sending a goal
|
|
120
|
+
*/
|
|
121
|
+
interface SendGoalOptions {
|
|
122
|
+
/** Override validateGoals setting for this call */
|
|
123
|
+
validate?: boolean;
|
|
124
|
+
}
|
|
125
|
+
|
|
118
126
|
/**
|
|
119
127
|
* ROS Action client.
|
|
120
128
|
*/
|
|
@@ -131,9 +139,23 @@ declare module 'rclnodejs' {
|
|
|
131
139
|
node: Node,
|
|
132
140
|
typeClass: T,
|
|
133
141
|
actionName: string,
|
|
134
|
-
options?: Options<ActionQoS>
|
|
142
|
+
options?: Options<ActionQoS> & {
|
|
143
|
+
validateGoals?: boolean;
|
|
144
|
+
validationOptions?: MessageValidationOptions;
|
|
145
|
+
}
|
|
135
146
|
);
|
|
136
147
|
|
|
148
|
+
/**
|
|
149
|
+
* Whether goals will be validated before sending.
|
|
150
|
+
*/
|
|
151
|
+
willValidateGoal: boolean;
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Set validation options for this action client.
|
|
155
|
+
* @param options - Validation options
|
|
156
|
+
*/
|
|
157
|
+
setValidation(options: MessageValidationOptions): void;
|
|
158
|
+
|
|
137
159
|
/**
|
|
138
160
|
* Send a goal and wait for the goal ACK asynchronously.
|
|
139
161
|
*
|
|
@@ -143,12 +165,15 @@ declare module 'rclnodejs' {
|
|
|
143
165
|
* @param goal - The goal request.
|
|
144
166
|
* @param feedbackCallback - Callback function for feedback associated with the goal.
|
|
145
167
|
* @param goalUuid - Universally unique identifier for the goal. If None, then a random UUID is generated.
|
|
168
|
+
* @param options - Send options (e.g., { validate: true })
|
|
146
169
|
* @returns A Promise to a goal handle that resolves when the goal request has been accepted or rejected.
|
|
170
|
+
* @throws MessageValidationError if validation is enabled and goal is invalid
|
|
147
171
|
*/
|
|
148
172
|
sendGoal(
|
|
149
173
|
goal: ActionGoal<T>,
|
|
150
174
|
feedbackCallback?: (feedbackMessage: ActionFeedback<T>) => void,
|
|
151
|
-
goalUuid?: unique_identifier_msgs.msg.UUID
|
|
175
|
+
goalUuid?: unique_identifier_msgs.msg.UUID,
|
|
176
|
+
options?: SendGoalOptions
|
|
152
177
|
): Promise<ClientGoalHandle<T>>;
|
|
153
178
|
|
|
154
179
|
/**
|
package/types/base.d.ts
CHANGED
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
/// <reference path="./lifecycle.d.ts" />
|
|
15
15
|
/// <reference path="./lifecycle_publisher.d.ts" />
|
|
16
16
|
/// <reference path="./logging.d.ts" />
|
|
17
|
+
/// <reference path="./message_introspector.d.ts" />
|
|
17
18
|
/// <reference path="./node.d.ts" />
|
|
18
19
|
/// <reference path="./node_options.d.ts" />
|
|
19
20
|
/// <reference path="./parameter.d.ts" />
|
|
@@ -25,6 +26,8 @@
|
|
|
25
26
|
/// <reference path="./service.d.ts" />
|
|
26
27
|
/// <reference path="./service_introspection.d.ts" />
|
|
27
28
|
/// <reference path="./subscription.d.ts" />
|
|
29
|
+
/// <reference path="./observable_subscription.d.ts" />
|
|
28
30
|
/// <reference path="./time_source.d.ts" />
|
|
29
31
|
/// <reference path="./time.d.ts" />
|
|
30
32
|
/// <reference path="./timer.d.ts" />
|
|
33
|
+
/// <reference path="./validator.d.ts" />
|
package/types/client.d.ts
CHANGED
|
@@ -1,17 +1,39 @@
|
|
|
1
1
|
declare module 'rclnodejs' {
|
|
2
|
+
/**
|
|
3
|
+
* Options for sending a request
|
|
4
|
+
*/
|
|
5
|
+
interface SendRequestOptions {
|
|
6
|
+
/** Override validateRequests setting for this call */
|
|
7
|
+
validate?: boolean;
|
|
8
|
+
}
|
|
9
|
+
|
|
2
10
|
/**
|
|
3
11
|
* A ROS service client.
|
|
4
12
|
*/
|
|
5
13
|
interface Client<T extends TypeClass<ServiceTypeClassName>> extends Entity {
|
|
14
|
+
/**
|
|
15
|
+
* Whether requests will be validated before sending.
|
|
16
|
+
*/
|
|
17
|
+
willValidateRequest: boolean;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Set validation options for this client.
|
|
21
|
+
* @param options - Validation options
|
|
22
|
+
*/
|
|
23
|
+
setValidation(options: MessageValidationOptions): void;
|
|
24
|
+
|
|
6
25
|
/**
|
|
7
26
|
* Make a service request and wait for to be notified asynchronously through a callback.
|
|
8
27
|
*
|
|
9
28
|
* @param request - Request to be submitted.
|
|
10
29
|
* @param callback - Callback for receiving the server response.
|
|
30
|
+
* @param options - Send options (e.g., { validate: true })
|
|
31
|
+
* @throws MessageValidationError if validation is enabled and request is invalid
|
|
11
32
|
*/
|
|
12
33
|
sendRequest(
|
|
13
34
|
request: ServiceRequestMessage<T>,
|
|
14
|
-
callback: Client.ResponseCallback<T
|
|
35
|
+
callback: Client.ResponseCallback<T>,
|
|
36
|
+
options?: SendRequestOptions
|
|
15
37
|
): void;
|
|
16
38
|
|
|
17
39
|
/**
|
|
@@ -22,6 +44,7 @@ declare module 'rclnodejs' {
|
|
|
22
44
|
* @returns Promise that resolves with the service response.
|
|
23
45
|
* @throws TimeoutError if the request times out (when options.timeout is exceeded).
|
|
24
46
|
* @throws AbortError if the request is manually aborted (via options.signal).
|
|
47
|
+
* @throws MessageValidationError if validation is enabled and request is invalid.
|
|
25
48
|
* @throws Error if the request fails for other reasons.
|
|
26
49
|
*/
|
|
27
50
|
sendRequestAsync(
|
|
@@ -109,6 +132,11 @@ declare module 'rclnodejs' {
|
|
|
109
132
|
* will abort the request.
|
|
110
133
|
*/
|
|
111
134
|
signal?: AbortSignal;
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Override validateRequests setting for this call
|
|
138
|
+
*/
|
|
139
|
+
validate?: boolean;
|
|
112
140
|
}
|
|
113
141
|
}
|
|
114
142
|
}
|
package/types/clock.d.ts
CHANGED
|
@@ -1,4 +1,35 @@
|
|
|
1
1
|
declare module 'rclnodejs' {
|
|
2
|
+
/**
|
|
3
|
+
* Jump information provided to clock jump callbacks.
|
|
4
|
+
*/
|
|
5
|
+
interface ClockJumpInfo {
|
|
6
|
+
/**
|
|
7
|
+
* Type of clock change that occurred.
|
|
8
|
+
*/
|
|
9
|
+
clock_change: ClockChange;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Time delta in nanoseconds.
|
|
13
|
+
*/
|
|
14
|
+
delta: bigint;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Callback object for clock jump events.
|
|
19
|
+
*/
|
|
20
|
+
interface ClockCallbackObject {
|
|
21
|
+
/**
|
|
22
|
+
* Optional callback invoked before a time jump.
|
|
23
|
+
*/
|
|
24
|
+
_pre_callback?: () => void;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Optional callback invoked after a time jump.
|
|
28
|
+
* @param jumpInfo - Information about the time jump.
|
|
29
|
+
*/
|
|
30
|
+
_post_callback?: (jumpInfo: ClockJumpInfo) => void;
|
|
31
|
+
}
|
|
32
|
+
|
|
2
33
|
/**
|
|
3
34
|
* A ROS Clock.
|
|
4
35
|
*/
|
|
@@ -17,12 +48,67 @@ declare module 'rclnodejs' {
|
|
|
17
48
|
*/
|
|
18
49
|
readonly clockType: ClockType;
|
|
19
50
|
|
|
51
|
+
/**
|
|
52
|
+
* Add a clock callback.
|
|
53
|
+
* @param callbackObject - The object containing callback methods.
|
|
54
|
+
* @param onClockChange - Whether to call the callback on clock change.
|
|
55
|
+
* @param minForward - Minimum forward jump in nanoseconds to trigger the callback.
|
|
56
|
+
* @param minBackward - Minimum backward jump in nanoseconds to trigger the callback.
|
|
57
|
+
*/
|
|
58
|
+
addClockCallback(
|
|
59
|
+
callbackObject: ClockCallbackObject,
|
|
60
|
+
onClockChange: boolean,
|
|
61
|
+
minForward: bigint,
|
|
62
|
+
minBackward: bigint
|
|
63
|
+
): void;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Remove a clock callback.
|
|
67
|
+
* @param callbackObject - The callback object that was previously registered with addClockCallback().
|
|
68
|
+
*/
|
|
69
|
+
removeClockCallback(callbackObject: ClockCallbackObject): void;
|
|
70
|
+
|
|
20
71
|
/**
|
|
21
72
|
* Return the current time.
|
|
22
73
|
*
|
|
23
74
|
* @returns The current time.
|
|
24
75
|
*/
|
|
25
76
|
now(): Time;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Sleep until a specific time is reached on this Clock.
|
|
80
|
+
*
|
|
81
|
+
* When using a ROSClock, this may sleep forever if the TimeSource is misconfigured
|
|
82
|
+
* and the context is never shut down. ROS time being activated or deactivated causes
|
|
83
|
+
* this function to cease sleeping and return false.
|
|
84
|
+
*
|
|
85
|
+
* @param until - Time at which this function should stop sleeping.
|
|
86
|
+
* @param context - Context which when shut down will cause this sleep to wake early.
|
|
87
|
+
* If context is null or undefined, then the default context is used.
|
|
88
|
+
* @returns Promise that resolves to true if 'until' was reached,
|
|
89
|
+
* or false if it woke for another reason (time jump, context shutdown).
|
|
90
|
+
* @throws {TypeError} if until is specified for a different type of clock than this one.
|
|
91
|
+
* @throws {Error} if context has not been initialized or is shutdown.
|
|
92
|
+
*/
|
|
93
|
+
sleepUntil(until: Time, context?: Context | null): Promise<boolean>;
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Sleep for a specified duration.
|
|
97
|
+
*
|
|
98
|
+
* Equivalent to: clock.sleepUntil(clock.now() + duration, context)
|
|
99
|
+
*
|
|
100
|
+
* When using a ROSClock, this may sleep forever if the TimeSource is misconfigured
|
|
101
|
+
* and the context is never shut down. ROS time being activated or deactivated causes
|
|
102
|
+
* this function to cease sleeping and return false.
|
|
103
|
+
*
|
|
104
|
+
* @param duration - Duration of time to sleep for.
|
|
105
|
+
* @param context - Context which when shut down will cause this sleep to wake early.
|
|
106
|
+
* If context is null or undefined, then the default context is used.
|
|
107
|
+
* @returns Promise that resolves to true if the full duration was slept,
|
|
108
|
+
* or false if it woke for another reason.
|
|
109
|
+
* @throws {Error} if context has not been initialized or is shutdown.
|
|
110
|
+
*/
|
|
111
|
+
sleepFor(duration: Duration, context?: Context | null): Promise<boolean>;
|
|
26
112
|
}
|
|
27
113
|
|
|
28
114
|
/**
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
declare module 'rclnodejs' {
|
|
2
|
+
/**
|
|
3
|
+
* Clock change type identifiers
|
|
4
|
+
* Represents the type of clock change that occurred during a time jump.
|
|
5
|
+
*/
|
|
6
|
+
enum ClockChange {
|
|
7
|
+
/**
|
|
8
|
+
* The source before and after the jump is ROS_TIME.
|
|
9
|
+
*/
|
|
10
|
+
ROS_TIME_NO_CHANGE = 1,
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* The source switched to ROS_TIME from SYSTEM_TIME.
|
|
14
|
+
*/
|
|
15
|
+
ROS_TIME_ACTIVATED = 2,
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* The source switched to SYSTEM_TIME from ROS_TIME.
|
|
19
|
+
*/
|
|
20
|
+
ROS_TIME_DEACTIVATED = 3,
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* The source before and after the jump is SYSTEM_TIME.
|
|
24
|
+
*/
|
|
25
|
+
SYSTEM_TIME_NO_CHANGE = 4,
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
declare module 'rclnodejs' {
|
|
2
|
+
/**
|
|
3
|
+
* Class representing a ClockEvent in ROS
|
|
4
|
+
*/
|
|
5
|
+
class ClockEvent {
|
|
6
|
+
/**
|
|
7
|
+
* Create a ClockEvent.
|
|
8
|
+
*/
|
|
9
|
+
constructor();
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Wait until a time specified by a steady clock.
|
|
13
|
+
* @param clock - The clock to use for time synchronization.
|
|
14
|
+
* @param until - The time to wait until.
|
|
15
|
+
* @returns A promise that resolves when the time is reached.
|
|
16
|
+
*/
|
|
17
|
+
waitUntilSteady(clock: Clock, until: bigint): Promise<void>;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Wait until a time specified by a system clock.
|
|
21
|
+
* @param clock - The clock to use for time synchronization.
|
|
22
|
+
* @param until - The time to wait until.
|
|
23
|
+
* @returns A promise that resolves when the time is reached.
|
|
24
|
+
*/
|
|
25
|
+
waitUntilSystem(clock: Clock, until: bigint): Promise<void>;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Wait until a time specified by a ROS clock.
|
|
29
|
+
* @param clock - The clock to use for time synchronization.
|
|
30
|
+
* @param until - The time to wait until.
|
|
31
|
+
* @returns A promise that resolves when the time is reached.
|
|
32
|
+
*/
|
|
33
|
+
waitUntilRos(clock: Clock, until: bigint): Promise<void>;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Indicate if the ClockEvent is set.
|
|
37
|
+
* @returns True if the ClockEvent is set.
|
|
38
|
+
*/
|
|
39
|
+
isSet(): boolean;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Set the event.
|
|
43
|
+
*/
|
|
44
|
+
set(): void;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Clear the event.
|
|
48
|
+
*/
|
|
49
|
+
clear(): void;
|
|
50
|
+
}
|
|
51
|
+
}
|