rclnodejs 1.8.2 → 1.9.0-alpha.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/README.md +46 -37
- package/index.js +62 -23
- package/lib/action/client.js +67 -3
- package/lib/action/server.js +1 -3
- package/lib/distro.js +2 -1
- package/lib/lifecycle_publisher.js +2 -2
- package/lib/message_info.js +94 -0
- package/lib/node.js +90 -14
- package/lib/parameter.js +5 -9
- package/lib/parameter_event_handler.js +468 -0
- package/lib/parameter_watcher.js +12 -12
- package/lib/service.js +8 -4
- package/lib/subscription.js +38 -5
- package/lib/time_source.js +3 -20
- package/lib/timer.js +2 -1
- package/lib/wait_for_message.js +111 -0
- package/package.json +7 -4
- 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/generate_worker.js +3 -13
- package/rosidl_gen/idl_generator.js +210 -0
- package/rosidl_gen/index.js +3 -12
- package/rosidl_gen/packages.js +1 -3
- package/rosidl_gen/primitive_types.js +2 -2
- package/rosidl_parser/idl_parser.py +437 -0
- package/rosidl_parser/parser.py +2 -4
- package/rosidl_parser/rosidl_parser.js +27 -0
- package/scripts/run_asan_test.sh +118 -0
- package/src/executor.cpp +37 -2
- package/src/executor.h +11 -0
- package/src/macros.h +2 -2
- package/src/rcl_action_client_bindings.cpp +88 -12
- package/src/rcl_action_server_bindings.cpp +24 -13
- package/src/rcl_client_bindings.cpp +13 -5
- package/src/rcl_context_bindings.cpp +10 -11
- package/src/rcl_graph_bindings.cpp +2 -2
- package/src/rcl_guard_condition_bindings.cpp +12 -3
- package/src/rcl_lifecycle_bindings.cpp +34 -15
- package/src/rcl_node_bindings.cpp +11 -4
- package/src/rcl_publisher_bindings.cpp +12 -3
- package/src/rcl_service_bindings.cpp +12 -3
- package/src/rcl_subscription_bindings.cpp +92 -21
- package/src/rcl_timer_bindings.cpp +24 -9
- package/src/rcl_type_description_service_bindings.cpp +9 -1
- package/src/rcl_utilities.cpp +2 -2
- package/tools/jsdoc/Makefile +5 -0
- package/tools/jsdoc/README.md +96 -0
- package/tools/jsdoc/build-index.js +610 -0
- package/tools/jsdoc/publish.js +854 -0
- package/tools/jsdoc/regenerate-published-docs.js +605 -0
- package/tools/jsdoc/static/fonts/OpenSans-Bold-webfont.eot +0 -0
- package/tools/jsdoc/static/fonts/OpenSans-Bold-webfont.svg +1830 -0
- package/tools/jsdoc/static/fonts/OpenSans-Bold-webfont.woff +0 -0
- package/tools/jsdoc/static/fonts/OpenSans-BoldItalic-webfont.eot +0 -0
- package/tools/jsdoc/static/fonts/OpenSans-BoldItalic-webfont.svg +1830 -0
- package/tools/jsdoc/static/fonts/OpenSans-BoldItalic-webfont.woff +0 -0
- package/tools/jsdoc/static/fonts/OpenSans-Italic-webfont.eot +0 -0
- package/tools/jsdoc/static/fonts/OpenSans-Italic-webfont.svg +1830 -0
- package/tools/jsdoc/static/fonts/OpenSans-Italic-webfont.woff +0 -0
- package/tools/jsdoc/static/fonts/OpenSans-Light-webfont.eot +0 -0
- package/tools/jsdoc/static/fonts/OpenSans-Light-webfont.svg +1831 -0
- package/tools/jsdoc/static/fonts/OpenSans-Light-webfont.woff +0 -0
- package/tools/jsdoc/static/fonts/OpenSans-LightItalic-webfont.eot +0 -0
- package/tools/jsdoc/static/fonts/OpenSans-LightItalic-webfont.svg +1835 -0
- package/tools/jsdoc/static/fonts/OpenSans-LightItalic-webfont.woff +0 -0
- package/tools/jsdoc/static/fonts/OpenSans-Regular-webfont.eot +0 -0
- package/tools/jsdoc/static/fonts/OpenSans-Regular-webfont.svg +1831 -0
- package/tools/jsdoc/static/fonts/OpenSans-Regular-webfont.woff +0 -0
- package/tools/jsdoc/static/scripts/linenumber.js +25 -0
- package/tools/jsdoc/static/scripts/prettify/Apache-License-2.0.txt +202 -0
- package/tools/jsdoc/static/scripts/prettify/lang-css.js +36 -0
- package/tools/jsdoc/static/scripts/prettify/prettify.js +738 -0
- package/tools/jsdoc/static/styles/jsdoc-default.css +1012 -0
- package/tools/jsdoc/static/styles/prettify-jsdoc.css +111 -0
- package/tools/jsdoc/static/styles/prettify-tomorrow.css +132 -0
- package/tools/jsdoc/tmpl/augments.tmpl +10 -0
- package/tools/jsdoc/tmpl/container.tmpl +193 -0
- package/tools/jsdoc/tmpl/details.tmpl +143 -0
- package/tools/jsdoc/tmpl/example.tmpl +2 -0
- package/tools/jsdoc/tmpl/examples.tmpl +13 -0
- package/tools/jsdoc/tmpl/exceptions.tmpl +17 -0
- package/tools/jsdoc/tmpl/layout.tmpl +83 -0
- package/tools/jsdoc/tmpl/mainpage.tmpl +163 -0
- package/tools/jsdoc/tmpl/members.tmpl +43 -0
- package/tools/jsdoc/tmpl/method.tmpl +124 -0
- package/tools/jsdoc/tmpl/params.tmpl +133 -0
- package/tools/jsdoc/tmpl/properties.tmpl +110 -0
- package/tools/jsdoc/tmpl/returns.tmpl +12 -0
- package/tools/jsdoc/tmpl/source.tmpl +8 -0
- package/tools/jsdoc/tmpl/tutorial.tmpl +19 -0
- package/tools/jsdoc/tmpl/type.tmpl +7 -0
- package/types/action_client.d.ts +8 -0
- package/types/index.d.ts +34 -0
- package/types/message_info.d.ts +72 -0
- package/types/node.d.ts +21 -0
- package/types/parameter_event_handler.d.ts +139 -0
- package/types/subscription.d.ts +14 -2
- package/rosidl_convertor/README.md +0 -298
- package/rosidl_convertor/idl_convertor.js +0 -50
- package/rosidl_convertor/idl_convertor.py +0 -1250
- package/test_data_integrity.js +0 -108
- package/test_repro_exact.js +0 -57
- package/test_repro_hz.js +0 -86
- package/test_repro_pub.js +0 -36
- package/test_repro_stress.js +0 -83
- package/test_repro_sub.js +0 -64
- package/test_xproc_data.js +0 -64
- package/types/interfaces.d.ts +0 -8895
package/src/executor.cpp
CHANGED
|
@@ -48,7 +48,8 @@ Executor::Executor(Napi::Env env, HandleManager* handle_manager,
|
|
|
48
48
|
handle_manager_(handle_manager),
|
|
49
49
|
delegate_(delegate),
|
|
50
50
|
context_(nullptr),
|
|
51
|
-
env_(env)
|
|
51
|
+
env_(env),
|
|
52
|
+
work_pending_(false) {
|
|
52
53
|
running_.store(false);
|
|
53
54
|
}
|
|
54
55
|
|
|
@@ -105,17 +106,20 @@ void Executor::Stop() {
|
|
|
105
106
|
// Stop thread first, and then uv_close
|
|
106
107
|
// Make sure async_ is not used anymore
|
|
107
108
|
running_.store(false);
|
|
109
|
+
// Wake the background thread in case it is waiting on the condvar.
|
|
110
|
+
work_done_cv_.notify_all();
|
|
108
111
|
handle_manager_->StopWaitingHandles();
|
|
109
112
|
uv_thread_join(&background_thread_);
|
|
110
113
|
|
|
111
114
|
if (uv_is_active(reinterpret_cast<uv_handle_t*>(async_))) {
|
|
112
115
|
static bool handle_closed = false;
|
|
116
|
+
handle_closed = false;
|
|
113
117
|
uv_close(reinterpret_cast<uv_handle_t*>(async_),
|
|
114
118
|
[](uv_handle_t* async) -> void {
|
|
115
119
|
// Important Notice:
|
|
116
120
|
// This might be called after Executor::~Executor()
|
|
117
121
|
// Don't free Executor::async_ in Executor's dtor
|
|
118
|
-
delete async;
|
|
122
|
+
delete reinterpret_cast<uv_async_t*>(async);
|
|
119
123
|
handle_closed = true;
|
|
120
124
|
});
|
|
121
125
|
while (!handle_closed) uv_run(uv_default_loop(), UV_RUN_ONCE);
|
|
@@ -132,6 +136,21 @@ bool Executor::IsMainThread() {
|
|
|
132
136
|
|
|
133
137
|
void Executor::DoWork(uv_async_t* handle) {
|
|
134
138
|
Executor* executor = reinterpret_cast<Executor*>(handle->data);
|
|
139
|
+
|
|
140
|
+
// RAII guard: always clear work_pending_ and notify the background thread,
|
|
141
|
+
// even if ExecuteReadyHandles() throws (e.g. from N-API callbacks).
|
|
142
|
+
// Without this, the background thread would block forever on work_done_cv_.
|
|
143
|
+
struct WorkDoneGuard {
|
|
144
|
+
Executor* exec;
|
|
145
|
+
~WorkDoneGuard() {
|
|
146
|
+
{
|
|
147
|
+
std::lock_guard<std::mutex> lock(exec->work_done_mutex_);
|
|
148
|
+
exec->work_pending_ = false;
|
|
149
|
+
}
|
|
150
|
+
exec->work_done_cv_.notify_one();
|
|
151
|
+
}
|
|
152
|
+
} guard{executor};
|
|
153
|
+
|
|
135
154
|
executor->ExecuteReadyHandles();
|
|
136
155
|
}
|
|
137
156
|
|
|
@@ -158,7 +177,23 @@ void Executor::Run(void* arg) {
|
|
|
158
177
|
|
|
159
178
|
if (!uv_is_closing(reinterpret_cast<uv_handle_t*>(executor->async_)) &&
|
|
160
179
|
handle_manager->ready_handles_count() > 0) {
|
|
180
|
+
// Tell the main thread there is work to do, then wait for it to
|
|
181
|
+
// finish before re-entering rcl_wait. This prevents a data race
|
|
182
|
+
// where the background thread holds subscriptions in the wait set
|
|
183
|
+
// while the main thread modifies their state (e.g. content filter).
|
|
184
|
+
{
|
|
185
|
+
std::lock_guard<std::mutex> lock(executor->work_done_mutex_);
|
|
186
|
+
executor->work_pending_ = true;
|
|
187
|
+
}
|
|
161
188
|
uv_async_send(executor->async_);
|
|
189
|
+
|
|
190
|
+
// Wait until DoWork() signals completion.
|
|
191
|
+
{
|
|
192
|
+
std::unique_lock<std::mutex> lock(executor->work_done_mutex_);
|
|
193
|
+
executor->work_done_cv_.wait(lock, [executor] {
|
|
194
|
+
return !executor->work_pending_ || !executor->running_.load();
|
|
195
|
+
});
|
|
196
|
+
}
|
|
162
197
|
}
|
|
163
198
|
}
|
|
164
199
|
|
package/src/executor.h
CHANGED
|
@@ -20,7 +20,9 @@
|
|
|
20
20
|
#include <uv.h>
|
|
21
21
|
|
|
22
22
|
#include <atomic>
|
|
23
|
+
#include <condition_variable>
|
|
23
24
|
#include <exception>
|
|
25
|
+
#include <mutex>
|
|
24
26
|
#include <vector>
|
|
25
27
|
|
|
26
28
|
#include "rcl_handle.h"
|
|
@@ -72,6 +74,15 @@ class Executor {
|
|
|
72
74
|
Napi::Env env_;
|
|
73
75
|
|
|
74
76
|
std::atomic_bool running_;
|
|
77
|
+
|
|
78
|
+
// Synchronization: the background thread waits after uv_async_send until
|
|
79
|
+
// the main thread finishes ExecuteReadyHandles. This prevents the
|
|
80
|
+
// background thread from re-entering rcl_wait (which holds a reference to
|
|
81
|
+
// subscriptions) while the main thread modifies subscription state (e.g.
|
|
82
|
+
// content filter changes).
|
|
83
|
+
std::mutex work_done_mutex_;
|
|
84
|
+
std::condition_variable work_done_cv_;
|
|
85
|
+
bool work_pending_; // true while the main thread is processing handles
|
|
75
86
|
};
|
|
76
87
|
|
|
77
88
|
} // namespace rclnodejs
|
package/src/macros.h
CHANGED
|
@@ -22,8 +22,8 @@
|
|
|
22
22
|
#define CHECK_OP_AND_THROW_ERROR_IF_NOT_TRUE(op, lhs, rhs, message) \
|
|
23
23
|
{ \
|
|
24
24
|
if (lhs op rhs) { \
|
|
25
|
-
rcl_reset_error(); \
|
|
26
25
|
Napi::Error::New(env, message).ThrowAsJavaScriptException(); \
|
|
26
|
+
rcl_reset_error(); \
|
|
27
27
|
return env.Undefined(); \
|
|
28
28
|
} \
|
|
29
29
|
}
|
|
@@ -31,8 +31,8 @@
|
|
|
31
31
|
#define CHECK_OP_AND_THROW_ERROR_IF_NOT_TRUE_NO_RETURN(op, lhs, rhs, message) \
|
|
32
32
|
{ \
|
|
33
33
|
if (lhs op rhs) { \
|
|
34
|
-
rcl_reset_error(); \
|
|
35
34
|
Napi::Error::New(env, message).ThrowAsJavaScriptException(); \
|
|
35
|
+
rcl_reset_error(); \
|
|
36
36
|
} \
|
|
37
37
|
}
|
|
38
38
|
|
|
@@ -70,10 +70,17 @@ Napi::Value ActionCreateClient(const Napi::CallbackInfo& info) {
|
|
|
70
70
|
malloc(sizeof(rcl_action_client_t)));
|
|
71
71
|
*action_client = rcl_action_get_zero_initialized_client();
|
|
72
72
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
73
|
+
{
|
|
74
|
+
rcl_ret_t ret = rcl_action_client_init(
|
|
75
|
+
action_client, node, ts, action_name.c_str(), &action_client_ops);
|
|
76
|
+
if (RCL_RET_OK != ret) {
|
|
77
|
+
std::string error_msg = rcl_get_error_string().str;
|
|
78
|
+
rcl_reset_error();
|
|
79
|
+
free(action_client);
|
|
80
|
+
Napi::Error::New(env, error_msg).ThrowAsJavaScriptException();
|
|
81
|
+
return env.Undefined();
|
|
82
|
+
}
|
|
83
|
+
}
|
|
77
84
|
auto js_obj = RclHandle::NewInstance(
|
|
78
85
|
env, action_client, node_handle, [node, env](void* ptr) {
|
|
79
86
|
rcl_action_client_t* action_client =
|
|
@@ -125,7 +132,7 @@ Napi::Value ActionSendGoalRequest(const Napi::CallbackInfo& info) {
|
|
|
125
132
|
rcl_action_send_goal_request(action_client, buffer, &sequence_number),
|
|
126
133
|
RCL_RET_OK, rcl_get_error_string().str);
|
|
127
134
|
|
|
128
|
-
return Napi::Number::New(env, static_cast<
|
|
135
|
+
return Napi::Number::New(env, static_cast<double>(sequence_number));
|
|
129
136
|
}
|
|
130
137
|
|
|
131
138
|
Napi::Value ActionSendResultRequest(const Napi::CallbackInfo& info) {
|
|
@@ -142,7 +149,7 @@ Napi::Value ActionSendResultRequest(const Napi::CallbackInfo& info) {
|
|
|
142
149
|
rcl_action_send_result_request(action_client, buffer, &sequence_number),
|
|
143
150
|
RCL_RET_OK, rcl_get_error_string().str);
|
|
144
151
|
|
|
145
|
-
return Napi::Number::New(env, static_cast<
|
|
152
|
+
return Napi::Number::New(env, static_cast<double>(sequence_number));
|
|
146
153
|
}
|
|
147
154
|
|
|
148
155
|
Napi::Value ActionTakeFeedback(const Napi::CallbackInfo& info) {
|
|
@@ -156,9 +163,9 @@ Napi::Value ActionTakeFeedback(const Napi::CallbackInfo& info) {
|
|
|
156
163
|
|
|
157
164
|
rcl_ret_t ret = rcl_action_take_feedback(action_client, buffer);
|
|
158
165
|
if (ret != RCL_RET_OK && ret != RCL_RET_ACTION_CLIENT_TAKE_FAILED) {
|
|
159
|
-
|
|
160
|
-
.ThrowAsJavaScriptException();
|
|
166
|
+
std::string error_msg = rcl_get_error_string().str;
|
|
161
167
|
rcl_reset_error();
|
|
168
|
+
Napi::Error::New(env, error_msg).ThrowAsJavaScriptException();
|
|
162
169
|
return Napi::Boolean::New(env, false);
|
|
163
170
|
}
|
|
164
171
|
|
|
@@ -179,9 +186,9 @@ Napi::Value ActionTakeStatus(const Napi::CallbackInfo& info) {
|
|
|
179
186
|
|
|
180
187
|
rcl_ret_t ret = rcl_action_take_status(action_client, buffer);
|
|
181
188
|
if (ret != RCL_RET_OK && ret != RCL_RET_ACTION_CLIENT_TAKE_FAILED) {
|
|
189
|
+
std::string error_msg = rcl_get_error_string().str;
|
|
182
190
|
rcl_reset_error();
|
|
183
|
-
Napi::Error::New(env,
|
|
184
|
-
.ThrowAsJavaScriptException();
|
|
191
|
+
Napi::Error::New(env, error_msg).ThrowAsJavaScriptException();
|
|
185
192
|
return Napi::Boolean::New(env, false);
|
|
186
193
|
}
|
|
187
194
|
|
|
@@ -240,8 +247,69 @@ Napi::Value ActionSendCancelRequest(const Napi::CallbackInfo& info) {
|
|
|
240
247
|
rcl_action_send_cancel_request(action_client, buffer, &sequence_number),
|
|
241
248
|
RCL_RET_OK, rcl_get_error_string().str);
|
|
242
249
|
|
|
243
|
-
return Napi::Number::New(env, static_cast<
|
|
250
|
+
return Napi::Number::New(env, static_cast<double>(sequence_number));
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
#if ROS_VERSION >= 5000 // ROS2 Rolling
|
|
254
|
+
Napi::Value ActionConfigureFeedbackSubFilterAddGoalId(
|
|
255
|
+
const Napi::CallbackInfo& info) {
|
|
256
|
+
Napi::Env env = info.Env();
|
|
257
|
+
|
|
258
|
+
RclHandle* action_client_handle =
|
|
259
|
+
RclHandle::Unwrap(info[0].As<Napi::Object>());
|
|
260
|
+
rcl_action_client_t* action_client =
|
|
261
|
+
reinterpret_cast<rcl_action_client_t*>(action_client_handle->ptr());
|
|
262
|
+
|
|
263
|
+
auto goal_id_buffer = info[1].As<Napi::Buffer<uint8_t>>();
|
|
264
|
+
const uint8_t* goal_id_array = goal_id_buffer.Data();
|
|
265
|
+
size_t goal_id_size = goal_id_buffer.Length();
|
|
266
|
+
|
|
267
|
+
rcl_ret_t ret =
|
|
268
|
+
rcl_action_client_configure_feedback_subscription_filter_add_goal_id(
|
|
269
|
+
action_client, goal_id_array, goal_id_size);
|
|
270
|
+
|
|
271
|
+
if (RCL_RET_OK != ret) {
|
|
272
|
+
std::string error_text{
|
|
273
|
+
"Failed to add goal id to feedback subscription content filter: "};
|
|
274
|
+
error_text += rcl_get_error_string().str;
|
|
275
|
+
rcl_reset_error();
|
|
276
|
+
Napi::Error::New(env, error_text).ThrowAsJavaScriptException();
|
|
277
|
+
return Napi::Boolean::New(env, false);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
return Napi::Boolean::New(env, true);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
Napi::Value ActionConfigureFeedbackSubFilterRemoveGoalId(
|
|
284
|
+
const Napi::CallbackInfo& info) {
|
|
285
|
+
Napi::Env env = info.Env();
|
|
286
|
+
|
|
287
|
+
RclHandle* action_client_handle =
|
|
288
|
+
RclHandle::Unwrap(info[0].As<Napi::Object>());
|
|
289
|
+
rcl_action_client_t* action_client =
|
|
290
|
+
reinterpret_cast<rcl_action_client_t*>(action_client_handle->ptr());
|
|
291
|
+
|
|
292
|
+
auto goal_id_buffer = info[1].As<Napi::Buffer<uint8_t>>();
|
|
293
|
+
const uint8_t* goal_id_array = goal_id_buffer.Data();
|
|
294
|
+
size_t goal_id_size = goal_id_buffer.Length();
|
|
295
|
+
|
|
296
|
+
rcl_ret_t ret =
|
|
297
|
+
rcl_action_client_configure_feedback_subscription_filter_remove_goal_id(
|
|
298
|
+
action_client, goal_id_array, goal_id_size);
|
|
299
|
+
|
|
300
|
+
if (RCL_RET_OK != ret) {
|
|
301
|
+
std::string error_text{
|
|
302
|
+
"Failed to remove goal id from feedback subscription content "
|
|
303
|
+
"filter: "};
|
|
304
|
+
error_text += rcl_get_error_string().str;
|
|
305
|
+
rcl_reset_error();
|
|
306
|
+
Napi::Error::New(env, error_text).ThrowAsJavaScriptException();
|
|
307
|
+
return Napi::Boolean::New(env, false);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
return Napi::Boolean::New(env, true);
|
|
244
311
|
}
|
|
312
|
+
#endif // ROS_VERSION >= 5000
|
|
245
313
|
|
|
246
314
|
#if ROS_VERSION >= 2505 // ROS2 >= Kilted
|
|
247
315
|
Napi::Value ConfigureActionClientIntrospection(const Napi::CallbackInfo& info) {
|
|
@@ -300,7 +368,15 @@ Napi::Object InitActionClientBindings(Napi::Env env, Napi::Object exports) {
|
|
|
300
368
|
#if ROS_VERSION >= 2505 // ROS2 >= Kilted
|
|
301
369
|
exports.Set("configureActionClientIntrospection",
|
|
302
370
|
Napi::Function::New(env, ConfigureActionClientIntrospection));
|
|
303
|
-
#endif
|
|
371
|
+
#endif // ROS_VERSION >= 2505
|
|
372
|
+
#if ROS_VERSION >= 5000 // ROS2 Rolling
|
|
373
|
+
exports.Set(
|
|
374
|
+
"actionConfigureFeedbackSubFilterAddGoalId",
|
|
375
|
+
Napi::Function::New(env, ActionConfigureFeedbackSubFilterAddGoalId));
|
|
376
|
+
exports.Set(
|
|
377
|
+
"actionConfigureFeedbackSubFilterRemoveGoalId",
|
|
378
|
+
Napi::Function::New(env, ActionConfigureFeedbackSubFilterRemoveGoalId));
|
|
379
|
+
#endif // ROS_VERSION >= 5000
|
|
304
380
|
return exports;
|
|
305
381
|
}
|
|
306
382
|
|
|
@@ -76,10 +76,18 @@ Napi::Value ActionCreateServer(const Napi::CallbackInfo& info) {
|
|
|
76
76
|
malloc(sizeof(rcl_action_server_t)));
|
|
77
77
|
*action_server = rcl_action_get_zero_initialized_server();
|
|
78
78
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
79
|
+
{
|
|
80
|
+
rcl_ret_t ret =
|
|
81
|
+
rcl_action_server_init(action_server, node, clock, ts,
|
|
82
|
+
action_name.c_str(), &action_server_ops);
|
|
83
|
+
if (RCL_RET_OK != ret) {
|
|
84
|
+
std::string error_msg = rcl_get_error_string().str;
|
|
85
|
+
rcl_reset_error();
|
|
86
|
+
free(action_server);
|
|
87
|
+
Napi::Error::New(env, error_msg).ThrowAsJavaScriptException();
|
|
88
|
+
return env.Undefined();
|
|
89
|
+
}
|
|
90
|
+
}
|
|
83
91
|
auto js_obj = RclHandle::NewInstance(
|
|
84
92
|
env, action_server, node_handle, [node, env](void* ptr) {
|
|
85
93
|
rcl_action_server_t* action_server =
|
|
@@ -118,6 +126,7 @@ Napi::Value ActionTakeResultRequest(const Napi::CallbackInfo& info) {
|
|
|
118
126
|
return js_obj;
|
|
119
127
|
}
|
|
120
128
|
|
|
129
|
+
free(header);
|
|
121
130
|
return env.Undefined();
|
|
122
131
|
}
|
|
123
132
|
|
|
@@ -140,6 +149,7 @@ Napi::Value ActionTakeGoalRequest(const Napi::CallbackInfo& info) {
|
|
|
140
149
|
return js_obj;
|
|
141
150
|
}
|
|
142
151
|
|
|
152
|
+
free(header);
|
|
143
153
|
return env.Undefined();
|
|
144
154
|
}
|
|
145
155
|
|
|
@@ -213,14 +223,14 @@ Napi::Value ActionTakeGoalResponse(const Napi::CallbackInfo& info) {
|
|
|
213
223
|
free(header);
|
|
214
224
|
|
|
215
225
|
if (ret != RCL_RET_OK && ret != RCL_RET_ACTION_CLIENT_TAKE_FAILED) {
|
|
226
|
+
std::string error_msg = rcl_get_error_string().str;
|
|
216
227
|
rcl_reset_error();
|
|
217
|
-
Napi::Error::New(env,
|
|
218
|
-
.ThrowAsJavaScriptException();
|
|
228
|
+
Napi::Error::New(env, error_msg).ThrowAsJavaScriptException();
|
|
219
229
|
return env.Undefined();
|
|
220
230
|
}
|
|
221
231
|
|
|
222
232
|
if (ret != RCL_RET_ACTION_CLIENT_TAKE_FAILED) {
|
|
223
|
-
return Napi::Number::New(env, static_cast<
|
|
233
|
+
return Napi::Number::New(env, static_cast<double>(sequence_number));
|
|
224
234
|
}
|
|
225
235
|
return env.Undefined();
|
|
226
236
|
}
|
|
@@ -242,14 +252,14 @@ Napi::Value ActionTakeCancelResponse(const Napi::CallbackInfo& info) {
|
|
|
242
252
|
free(header);
|
|
243
253
|
|
|
244
254
|
if (ret != RCL_RET_OK && ret != RCL_RET_ACTION_CLIENT_TAKE_FAILED) {
|
|
255
|
+
std::string error_msg = rcl_get_error_string().str;
|
|
245
256
|
rcl_reset_error();
|
|
246
|
-
Napi::Error::New(env,
|
|
247
|
-
.ThrowAsJavaScriptException();
|
|
257
|
+
Napi::Error::New(env, error_msg).ThrowAsJavaScriptException();
|
|
248
258
|
return env.Undefined();
|
|
249
259
|
}
|
|
250
260
|
|
|
251
261
|
if (ret != RCL_RET_ACTION_CLIENT_TAKE_FAILED) {
|
|
252
|
-
return Napi::Number::New(env, static_cast<
|
|
262
|
+
return Napi::Number::New(env, static_cast<double>(sequence_number));
|
|
253
263
|
}
|
|
254
264
|
return env.Undefined();
|
|
255
265
|
}
|
|
@@ -271,14 +281,14 @@ Napi::Value ActionTakeResultResponse(const Napi::CallbackInfo& info) {
|
|
|
271
281
|
free(header);
|
|
272
282
|
|
|
273
283
|
if (ret != RCL_RET_OK && ret != RCL_RET_ACTION_CLIENT_TAKE_FAILED) {
|
|
284
|
+
std::string error_msg = rcl_get_error_string().str;
|
|
274
285
|
rcl_reset_error();
|
|
275
|
-
Napi::Error::New(env,
|
|
276
|
-
.ThrowAsJavaScriptException();
|
|
286
|
+
Napi::Error::New(env, error_msg).ThrowAsJavaScriptException();
|
|
277
287
|
return env.Undefined();
|
|
278
288
|
}
|
|
279
289
|
|
|
280
290
|
if (ret != RCL_RET_ACTION_CLIENT_TAKE_FAILED) {
|
|
281
|
-
return Napi::Number::New(env, static_cast<
|
|
291
|
+
return Napi::Number::New(env, static_cast<double>(sequence_number));
|
|
282
292
|
}
|
|
283
293
|
return env.Undefined();
|
|
284
294
|
}
|
|
@@ -455,6 +465,7 @@ Napi::Value ActionTakeCancelRequest(const Napi::CallbackInfo& info) {
|
|
|
455
465
|
return js_obj;
|
|
456
466
|
}
|
|
457
467
|
|
|
468
|
+
free(header);
|
|
458
469
|
return env.Undefined();
|
|
459
470
|
}
|
|
460
471
|
|
|
@@ -49,9 +49,17 @@ Napi::Value CreateClient(const Napi::CallbackInfo& info) {
|
|
|
49
49
|
client_ops.qos = *qos_profile;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
52
|
+
{
|
|
53
|
+
rcl_ret_t ret =
|
|
54
|
+
rcl_client_init(client, node, ts, service_name.c_str(), &client_ops);
|
|
55
|
+
if (RCL_RET_OK != ret) {
|
|
56
|
+
std::string error_msg = rcl_get_error_string().str;
|
|
57
|
+
rcl_reset_error();
|
|
58
|
+
free(client);
|
|
59
|
+
Napi::Error::New(env, error_msg).ThrowAsJavaScriptException();
|
|
60
|
+
return env.Undefined();
|
|
61
|
+
}
|
|
62
|
+
}
|
|
55
63
|
|
|
56
64
|
auto js_obj = RclHandle::NewInstance(
|
|
57
65
|
env, client, node_handle, [node, env](void* ptr) {
|
|
@@ -80,7 +88,7 @@ Napi::Value SendRequest(const Napi::CallbackInfo& info) {
|
|
|
80
88
|
THROW_ERROR_IF_NOT_EQUAL(rcl_send_request(client, buffer, &sequence_number),
|
|
81
89
|
RCL_RET_OK, rcl_get_error_string().str);
|
|
82
90
|
|
|
83
|
-
return Napi::Number::New(env, static_cast<
|
|
91
|
+
return Napi::Number::New(env, static_cast<double>(sequence_number));
|
|
84
92
|
}
|
|
85
93
|
|
|
86
94
|
Napi::Value RclTakeResponse(const Napi::CallbackInfo& info) {
|
|
@@ -96,7 +104,7 @@ Napi::Value RclTakeResponse(const Napi::CallbackInfo& info) {
|
|
|
96
104
|
int64_t sequence_number = header.request_id.sequence_number;
|
|
97
105
|
|
|
98
106
|
if (ret == RCL_RET_OK) {
|
|
99
|
-
return Napi::Number::New(env, static_cast<
|
|
107
|
+
return Napi::Number::New(env, static_cast<double>(sequence_number));
|
|
100
108
|
}
|
|
101
109
|
|
|
102
110
|
rcl_reset_error();
|
|
@@ -17,10 +17,10 @@
|
|
|
17
17
|
#include <rcl/logging.h>
|
|
18
18
|
#include <rcl/rcl.h>
|
|
19
19
|
|
|
20
|
-
#include <rcpputils/scope_exit.hpp>
|
|
21
|
-
// NOLINTNEXTLINE
|
|
22
20
|
#include <string>
|
|
23
21
|
|
|
22
|
+
#include <rcpputils/scope_exit.hpp>
|
|
23
|
+
|
|
24
24
|
#include "macros.h"
|
|
25
25
|
#include "rcl_handle.h"
|
|
26
26
|
#include "rcl_utilities.h"
|
|
@@ -54,6 +54,7 @@ Napi::Value Init(const Napi::CallbackInfo& info) {
|
|
|
54
54
|
Napi::Array jsArgv = info[1].As<Napi::Array>();
|
|
55
55
|
size_t argc = jsArgv.Length();
|
|
56
56
|
char** argv = AbstractArgsFromNapiArray(jsArgv);
|
|
57
|
+
RCPPUTILS_SCOPE_EXIT({ FreeArgs(argv, argc); });
|
|
57
58
|
|
|
58
59
|
// Set up the domain id.
|
|
59
60
|
size_t domain_id = RCL_DEFAULT_DOMAIN_ID;
|
|
@@ -82,7 +83,6 @@ Napi::Value Init(const Napi::CallbackInfo& info) {
|
|
|
82
83
|
RCL_RET_OK, rcl_logging_configure(&context->global_arguments, &allocator),
|
|
83
84
|
rcl_get_error_string().str);
|
|
84
85
|
|
|
85
|
-
RCPPUTILS_SCOPE_EXIT({ FreeArgs(argv, argc); });
|
|
86
86
|
return env.Undefined();
|
|
87
87
|
}
|
|
88
88
|
|
|
@@ -120,14 +120,13 @@ Napi::Value CreateContext(const Napi::CallbackInfo& info) {
|
|
|
120
120
|
rcl_context_t* context =
|
|
121
121
|
reinterpret_cast<rcl_context_t*>(malloc(sizeof(rcl_context_t)));
|
|
122
122
|
*context = rcl_get_zero_initialized_context();
|
|
123
|
-
auto js_obj =
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
});
|
|
123
|
+
auto js_obj = RclHandle::NewInstance(env, context, nullptr, [env](void* ptr) {
|
|
124
|
+
rcl_context_t* context = reinterpret_cast<rcl_context_t*>(ptr);
|
|
125
|
+
rcl_ret_t ret = DestroyContext(env, context);
|
|
126
|
+
free(ptr);
|
|
127
|
+
THROW_ERROR_IF_NOT_EQUAL_NO_RETURN(RCL_RET_OK, ret,
|
|
128
|
+
rcl_get_error_string().str);
|
|
129
|
+
});
|
|
131
130
|
|
|
132
131
|
return js_obj;
|
|
133
132
|
}
|
|
@@ -18,10 +18,10 @@
|
|
|
18
18
|
#include <rcl/graph.h>
|
|
19
19
|
#include <rcl/rcl.h>
|
|
20
20
|
|
|
21
|
-
#include <rcpputils/scope_exit.hpp>
|
|
22
|
-
// NOLINTNEXTLINE
|
|
23
21
|
#include <string>
|
|
24
22
|
|
|
23
|
+
#include <rcpputils/scope_exit.hpp>
|
|
24
|
+
|
|
25
25
|
#include "macros.h"
|
|
26
26
|
#include "rcl_handle.h"
|
|
27
27
|
#include "rcl_utilities.h"
|
|
@@ -17,6 +17,8 @@
|
|
|
17
17
|
#include <rcl/error_handling.h>
|
|
18
18
|
#include <rcl/rcl.h>
|
|
19
19
|
|
|
20
|
+
#include <string>
|
|
21
|
+
|
|
20
22
|
#include "macros.h"
|
|
21
23
|
#include "rcl_handle.h"
|
|
22
24
|
#include "rcl_utilities.h"
|
|
@@ -37,9 +39,16 @@ Napi::Value CreateGuardCondition(const Napi::CallbackInfo& info) {
|
|
|
37
39
|
rcl_guard_condition_options_t gc_options =
|
|
38
40
|
rcl_guard_condition_get_default_options();
|
|
39
41
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
42
|
+
{
|
|
43
|
+
rcl_ret_t ret = rcl_guard_condition_init(gc, context, gc_options);
|
|
44
|
+
if (RCL_RET_OK != ret) {
|
|
45
|
+
std::string error_msg = rcl_get_error_string().str;
|
|
46
|
+
rcl_reset_error();
|
|
47
|
+
free(gc);
|
|
48
|
+
Napi::Error::New(env, error_msg).ThrowAsJavaScriptException();
|
|
49
|
+
return env.Undefined();
|
|
50
|
+
}
|
|
51
|
+
}
|
|
43
52
|
|
|
44
53
|
auto handle = RclHandle::NewInstance(env, gc, nullptr, [env](void* ptr) {
|
|
45
54
|
rcl_guard_condition_t* gc = reinterpret_cast<rcl_guard_condition_t*>(ptr);
|
|
@@ -79,11 +79,17 @@ Napi::Value CreateLifecycleStateMachine(const Napi::CallbackInfo& info) {
|
|
|
79
79
|
RclHandle* clock_handle = RclHandle::Unwrap(info[2].As<Napi::Object>());
|
|
80
80
|
rcl_clock_t* clock = reinterpret_cast<rcl_clock_t*>(clock_handle->ptr());
|
|
81
81
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
rcl_get_error_string().str
|
|
82
|
+
{
|
|
83
|
+
rcl_ret_t ret = rcl_lifecycle_state_machine_init(
|
|
84
|
+
state_machine, node, clock, pn, cs, gs, gas, gat, gtg, &options);
|
|
85
|
+
if (RCL_RET_OK != ret) {
|
|
86
|
+
std::string error_msg = rcl_get_error_string().str;
|
|
87
|
+
rcl_reset_error();
|
|
88
|
+
free(state_machine);
|
|
89
|
+
Napi::Error::New(env, error_msg).ThrowAsJavaScriptException();
|
|
90
|
+
return env.Undefined();
|
|
91
|
+
}
|
|
92
|
+
}
|
|
87
93
|
|
|
88
94
|
auto js_obj = RclHandle::NewInstance(
|
|
89
95
|
env, state_machine, node_handle, [node, env](void* ptr) {
|
|
@@ -99,11 +105,17 @@ Napi::Value CreateLifecycleStateMachine(const Napi::CallbackInfo& info) {
|
|
|
99
105
|
rcl_lifecycle_get_default_state_machine_options();
|
|
100
106
|
options.enable_com_interface = info[1].As<Napi::Boolean>().Value();
|
|
101
107
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
rcl_get_error_string().str
|
|
108
|
+
{
|
|
109
|
+
rcl_ret_t ret = rcl_lifecycle_state_machine_init(
|
|
110
|
+
state_machine, node, pn, cs, gs, gas, gat, gtg, &options);
|
|
111
|
+
if (RCL_RET_OK != ret) {
|
|
112
|
+
std::string error_msg = rcl_get_error_string().str;
|
|
113
|
+
rcl_reset_error();
|
|
114
|
+
free(state_machine);
|
|
115
|
+
Napi::Error::New(env, error_msg).ThrowAsJavaScriptException();
|
|
116
|
+
return env.Undefined();
|
|
117
|
+
}
|
|
118
|
+
}
|
|
107
119
|
|
|
108
120
|
auto js_obj = RclHandle::NewInstance(
|
|
109
121
|
env, state_machine, node_handle, [node, env](void* ptr) {
|
|
@@ -118,11 +130,18 @@ Napi::Value CreateLifecycleStateMachine(const Napi::CallbackInfo& info) {
|
|
|
118
130
|
const rcl_node_options_t* node_options =
|
|
119
131
|
reinterpret_cast<const rcl_node_options_t*>(rcl_node_get_options(node));
|
|
120
132
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
133
|
+
{
|
|
134
|
+
rcl_ret_t ret = rcl_lifecycle_state_machine_init(
|
|
135
|
+
state_machine, node, pn, cs, gs, gas, gat, gtg, true,
|
|
136
|
+
&node_options->allocator);
|
|
137
|
+
if (RCL_RET_OK != ret) {
|
|
138
|
+
std::string error_msg = rcl_get_error_string().str;
|
|
139
|
+
rcl_reset_error();
|
|
140
|
+
free(state_machine);
|
|
141
|
+
Napi::Error::New(env, error_msg).ThrowAsJavaScriptException();
|
|
142
|
+
return env.Undefined();
|
|
143
|
+
}
|
|
144
|
+
}
|
|
126
145
|
|
|
127
146
|
auto js_obj = RclHandle::NewInstance(
|
|
128
147
|
env, state_machine, node_handle, [node, node_options, env](void* ptr) {
|
|
@@ -224,10 +224,17 @@ Napi::Value CreateNode(const Napi::CallbackInfo& info) {
|
|
|
224
224
|
options.rosout_qos = *qos_profile;
|
|
225
225
|
}
|
|
226
226
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
227
|
+
{
|
|
228
|
+
rcl_ret_t ret = rcl_node_init(node, node_name.c_str(), name_space.c_str(),
|
|
229
|
+
context, &options);
|
|
230
|
+
if (RCL_RET_OK != ret) {
|
|
231
|
+
std::string error_msg = rcl_get_error_string().str;
|
|
232
|
+
rcl_reset_error();
|
|
233
|
+
free(node);
|
|
234
|
+
Napi::Error::New(env, error_msg).ThrowAsJavaScriptException();
|
|
235
|
+
return env.Undefined();
|
|
236
|
+
}
|
|
237
|
+
}
|
|
231
238
|
|
|
232
239
|
auto handle = RclHandle::NewInstance(env, node, nullptr, [env](void* ptr) {
|
|
233
240
|
rcl_node_t* node = reinterpret_cast<rcl_node_t*>(ptr);
|
|
@@ -51,9 +51,17 @@ Napi::Value CreatePublisher(const Napi::CallbackInfo& info) {
|
|
|
51
51
|
publisher_ops.qos = *qos_profile;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
{
|
|
55
|
+
rcl_ret_t ret = rcl_publisher_init(publisher, node, ts, topic.c_str(),
|
|
56
|
+
&publisher_ops);
|
|
57
|
+
if (RCL_RET_OK != ret) {
|
|
58
|
+
std::string error_msg = rcl_get_error_string().str;
|
|
59
|
+
rcl_reset_error();
|
|
60
|
+
free(publisher);
|
|
61
|
+
Napi::Error::New(env, error_msg).ThrowAsJavaScriptException();
|
|
62
|
+
return env.Undefined();
|
|
63
|
+
}
|
|
64
|
+
}
|
|
57
65
|
|
|
58
66
|
auto js_obj = RclHandle::NewInstance(
|
|
59
67
|
env, publisher, node_handle, [node, env](void* ptr) {
|
|
@@ -66,6 +74,7 @@ Napi::Value CreatePublisher(const Napi::CallbackInfo& info) {
|
|
|
66
74
|
|
|
67
75
|
return js_obj;
|
|
68
76
|
} else {
|
|
77
|
+
free(publisher);
|
|
69
78
|
Napi::Error::New(env, GetErrorMessageAndClear())
|
|
70
79
|
.ThrowAsJavaScriptException();
|
|
71
80
|
return env.Undefined();
|
|
@@ -52,9 +52,17 @@ Napi::Value CreateService(const Napi::CallbackInfo& info) {
|
|
|
52
52
|
service_ops.qos = *qos_profile;
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
55
|
+
{
|
|
56
|
+
rcl_ret_t ret = rcl_service_init(service, node, ts, service_name.c_str(),
|
|
57
|
+
&service_ops);
|
|
58
|
+
if (RCL_RET_OK != ret) {
|
|
59
|
+
std::string error_msg = rcl_get_error_string().str;
|
|
60
|
+
rcl_reset_error();
|
|
61
|
+
free(service);
|
|
62
|
+
Napi::Error::New(env, error_msg).ThrowAsJavaScriptException();
|
|
63
|
+
return env.Undefined();
|
|
64
|
+
}
|
|
65
|
+
}
|
|
58
66
|
auto js_obj = RclHandle::NewInstance(
|
|
59
67
|
env, service, node_handle, [node, env](void* ptr) {
|
|
60
68
|
rcl_service_t* service = reinterpret_cast<rcl_service_t*>(ptr);
|
|
@@ -88,6 +96,7 @@ Napi::Value RclTakeRequest(const Napi::CallbackInfo& info) {
|
|
|
88
96
|
return js_obj;
|
|
89
97
|
}
|
|
90
98
|
|
|
99
|
+
free(header);
|
|
91
100
|
return env.Undefined();
|
|
92
101
|
}
|
|
93
102
|
|