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.
- package/README.md +3 -3
- package/binding.gyp +17 -2
- package/lib/client.js +2 -3
- package/lib/context.js +8 -0
- package/lib/logging.js +26 -9
- package/lib/node.js +68 -1
- package/lib/publisher.js +8 -0
- package/lib/service.js +9 -2
- package/lib/subscription.js +8 -0
- package/lib/timer.js +32 -0
- package/package.json +4 -4
- package/rostsd_gen/index.js +167 -67
- package/scripts/config.js +1 -0
- package/scripts/npmjs-readme.md +3 -3
- package/src/addon.cpp +54 -53
- package/src/executor.cpp +19 -10
- package/src/{executor.hpp → executor.h} +7 -5
- package/src/handle_manager.cpp +30 -56
- package/src/{handle_manager.hpp → handle_manager.h} +8 -7
- package/src/{macros.hpp → macros.h} +7 -5
- package/src/rcl_action_client_bindings.cpp +231 -0
- package/src/{rcl_action_bindings.hpp → rcl_action_client_bindings.h} +6 -11
- package/src/rcl_action_goal_bindings.cpp +117 -0
- package/src/rcl_action_goal_bindings.h +26 -0
- package/src/rcl_action_server_bindings.cpp +470 -0
- package/src/rcl_action_server_bindings.h +26 -0
- package/src/rcl_bindings.cpp +42 -1979
- package/src/{rcl_bindings.hpp → rcl_bindings.h} +5 -25
- package/src/rcl_client_bindings.cpp +183 -0
- package/src/rcl_client_bindings.h +26 -0
- package/src/rcl_context_bindings.cpp +156 -0
- package/src/rcl_context_bindings.h +26 -0
- package/src/rcl_graph_bindings.cpp +280 -0
- package/src/rcl_graph_bindings.h +26 -0
- package/src/rcl_guard_condition_bindings.cpp +75 -0
- package/src/rcl_guard_condition_bindings.h +26 -0
- package/src/rcl_handle.cpp +41 -57
- package/src/{rcl_handle.hpp → rcl_handle.h} +18 -17
- package/src/rcl_lifecycle_bindings.cpp +135 -114
- package/src/{rcl_lifecycle_bindings.hpp → rcl_lifecycle_bindings.h} +5 -7
- package/src/rcl_logging_bindings.cpp +96 -0
- package/src/rcl_logging_bindings.h +26 -0
- package/src/rcl_names_bindings.cpp +255 -0
- package/src/rcl_names_bindings.h +26 -0
- package/src/rcl_node_bindings.cpp +447 -0
- package/src/rcl_node_bindings.h +26 -0
- package/src/rcl_publisher_bindings.cpp +141 -0
- package/src/rcl_publisher_bindings.h +26 -0
- package/src/rcl_service_bindings.cpp +185 -0
- package/src/rcl_service_bindings.h +26 -0
- package/src/rcl_subscription_bindings.cpp +335 -0
- package/src/rcl_subscription_bindings.h +26 -0
- package/src/rcl_time_point_bindings.cpp +194 -0
- package/src/rcl_time_point_bindings.h +26 -0
- package/src/rcl_timer_bindings.cpp +237 -0
- package/src/rcl_timer_bindings.h +26 -0
- package/src/rcl_utilities.cpp +166 -1
- package/src/{rcl_utilities.hpp → rcl_utilities.h} +21 -3
- package/src/shadow_node.cpp +56 -75
- package/src/{shadow_node.hpp → shadow_node.h} +18 -17
- package/types/context.d.ts +6 -0
- package/types/interfaces.d.ts +4377 -0
- package/types/node.d.ts +53 -0
- package/types/publisher.d.ts +6 -0
- package/types/service.d.ts +6 -0
- package/types/subscription.d.ts +6 -0
- package/types/timer.d.ts +18 -0
- package/src/rcl_action_bindings.cpp +0 -826
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
// Copyright (c) 2025, The Robot Web Tools Contributors
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
|
|
15
|
+
#include "rcl_time_point_bindings.h"
|
|
16
|
+
|
|
17
|
+
#include <rcl/error_handling.h>
|
|
18
|
+
#include <rcl/rcl.h>
|
|
19
|
+
|
|
20
|
+
#include <memory>
|
|
21
|
+
|
|
22
|
+
#include "macros.h"
|
|
23
|
+
#include "rcl_handle.h"
|
|
24
|
+
#include "rcl_utilities.h"
|
|
25
|
+
|
|
26
|
+
namespace rclnodejs {
|
|
27
|
+
|
|
28
|
+
Napi::Value CreateTimePoint(const Napi::CallbackInfo& info) {
|
|
29
|
+
Napi::Env env = info.Env();
|
|
30
|
+
|
|
31
|
+
if (!info[0].IsBigInt()) {
|
|
32
|
+
Napi::TypeError::New(env, "Timer period must be a BigInt")
|
|
33
|
+
.ThrowAsJavaScriptException();
|
|
34
|
+
return env.Undefined();
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
bool lossless;
|
|
38
|
+
int64_t nanoseconds = info[0].As<Napi::BigInt>().Int64Value(&lossless);
|
|
39
|
+
uint32_t clock_type = info[1].As<Napi::Number>().Uint32Value();
|
|
40
|
+
rcl_time_point_t* time_point =
|
|
41
|
+
reinterpret_cast<rcl_time_point_t*>(malloc(sizeof(rcl_time_point_t)));
|
|
42
|
+
|
|
43
|
+
time_point->nanoseconds = nanoseconds;
|
|
44
|
+
time_point->clock_type = static_cast<rcl_clock_type_t>(clock_type);
|
|
45
|
+
|
|
46
|
+
auto js_obj = RclHandle::NewInstance(env, time_point, nullptr,
|
|
47
|
+
[](void* ptr) { free(ptr); });
|
|
48
|
+
|
|
49
|
+
return js_obj;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
Napi::Value GetNanoseconds(const Napi::CallbackInfo& info) {
|
|
53
|
+
Napi::Env env = info.Env();
|
|
54
|
+
|
|
55
|
+
RclHandle* time_point_handle = RclHandle::Unwrap(info[0].As<Napi::Object>());
|
|
56
|
+
rcl_time_point_t* time_point =
|
|
57
|
+
reinterpret_cast<rcl_time_point_t*>(time_point_handle->ptr());
|
|
58
|
+
|
|
59
|
+
return Napi::BigInt::New(env, time_point->nanoseconds);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
Napi::Value CreateDuration(const Napi::CallbackInfo& info) {
|
|
63
|
+
Napi::Env env = info.Env();
|
|
64
|
+
|
|
65
|
+
if (!info[0].IsBigInt()) {
|
|
66
|
+
Napi::TypeError::New(env, "Timer period must be a BigInt")
|
|
67
|
+
.ThrowAsJavaScriptException();
|
|
68
|
+
return env.Undefined();
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
bool lossless;
|
|
72
|
+
int64_t nanoseconds = info[0].As<Napi::BigInt>().Int64Value(&lossless);
|
|
73
|
+
rcl_duration_t* duration =
|
|
74
|
+
reinterpret_cast<rcl_duration_t*>(malloc(sizeof(rcl_duration_t)));
|
|
75
|
+
duration->nanoseconds = nanoseconds;
|
|
76
|
+
|
|
77
|
+
auto js_obj = RclHandle::NewInstance(env, duration, nullptr,
|
|
78
|
+
[](void* ptr) { free(ptr); });
|
|
79
|
+
|
|
80
|
+
return js_obj;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
Napi::Value GetDurationNanoseconds(const Napi::CallbackInfo& info) {
|
|
84
|
+
Napi::Env env = info.Env();
|
|
85
|
+
|
|
86
|
+
RclHandle* duration_handle = RclHandle::Unwrap(info[0].As<Napi::Object>());
|
|
87
|
+
rcl_duration_t* duration =
|
|
88
|
+
reinterpret_cast<rcl_duration_t*>(duration_handle->ptr());
|
|
89
|
+
|
|
90
|
+
return Napi::BigInt::New(env, duration->nanoseconds);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
Napi::Value SetRosTimeOverrideIsEnabled(const Napi::CallbackInfo& info) {
|
|
94
|
+
Napi::Env env = info.Env();
|
|
95
|
+
|
|
96
|
+
RclHandle* clock_handle = RclHandle::Unwrap(info[0].As<Napi::Object>());
|
|
97
|
+
rcl_clock_t* clock = reinterpret_cast<rcl_clock_t*>(clock_handle->ptr());
|
|
98
|
+
bool enabled = info[1].As<Napi::Boolean>();
|
|
99
|
+
|
|
100
|
+
if (enabled) {
|
|
101
|
+
THROW_ERROR_IF_NOT_EQUAL(RCL_RET_OK, rcl_enable_ros_time_override(clock),
|
|
102
|
+
rcl_get_error_string().str);
|
|
103
|
+
} else {
|
|
104
|
+
THROW_ERROR_IF_NOT_EQUAL(RCL_RET_OK, rcl_disable_ros_time_override(clock),
|
|
105
|
+
rcl_get_error_string().str);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return env.Undefined();
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
Napi::Value SetRosTimeOverride(const Napi::CallbackInfo& info) {
|
|
112
|
+
Napi::Env env = info.Env();
|
|
113
|
+
|
|
114
|
+
RclHandle* clock_handle = RclHandle::Unwrap(info[0].As<Napi::Object>());
|
|
115
|
+
rcl_clock_t* clock = reinterpret_cast<rcl_clock_t*>(clock_handle->ptr());
|
|
116
|
+
RclHandle* time_point_handle = RclHandle::Unwrap(info[1].As<Napi::Object>());
|
|
117
|
+
rcl_time_point_t* time_point =
|
|
118
|
+
reinterpret_cast<rcl_time_point_t*>(time_point_handle->ptr());
|
|
119
|
+
|
|
120
|
+
THROW_ERROR_IF_NOT_EQUAL(
|
|
121
|
+
RCL_RET_OK, rcl_set_ros_time_override(clock, time_point->nanoseconds),
|
|
122
|
+
rcl_get_error_string().str);
|
|
123
|
+
|
|
124
|
+
return env.Undefined();
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
Napi::Value GetRosTimeOverrideIsEnabled(const Napi::CallbackInfo& info) {
|
|
128
|
+
Napi::Env env = info.Env();
|
|
129
|
+
|
|
130
|
+
RclHandle* clock_handle = RclHandle::Unwrap(info[0].As<Napi::Object>());
|
|
131
|
+
rcl_clock_t* clock = reinterpret_cast<rcl_clock_t*>(clock_handle->ptr());
|
|
132
|
+
|
|
133
|
+
bool is_enabled;
|
|
134
|
+
THROW_ERROR_IF_NOT_EQUAL(RCL_RET_OK,
|
|
135
|
+
rcl_is_enabled_ros_time_override(clock, &is_enabled),
|
|
136
|
+
rcl_get_error_string().str);
|
|
137
|
+
|
|
138
|
+
return Napi::Boolean::New(env, is_enabled);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
Napi::Value CreateClock(const Napi::CallbackInfo& info) {
|
|
142
|
+
Napi::Env env = info.Env();
|
|
143
|
+
|
|
144
|
+
auto clock_type =
|
|
145
|
+
static_cast<rcl_clock_type_t>(info[0].As<Napi::Number>().Int32Value());
|
|
146
|
+
rcl_clock_t* clock =
|
|
147
|
+
reinterpret_cast<rcl_clock_t*>(malloc(sizeof(rcl_clock_t)));
|
|
148
|
+
rcl_allocator_t allocator = rcl_get_default_allocator();
|
|
149
|
+
|
|
150
|
+
THROW_ERROR_IF_NOT_EQUAL(RCL_RET_OK,
|
|
151
|
+
rcl_clock_init(clock_type, clock, &allocator),
|
|
152
|
+
rcl_get_error_string().str);
|
|
153
|
+
|
|
154
|
+
return RclHandle::NewInstance(env, clock, nullptr, [](void* ptr) {
|
|
155
|
+
rcl_clock_t* clock = reinterpret_cast<rcl_clock_t*>(ptr);
|
|
156
|
+
rcl_ret_t ret = rcl_clock_fini(clock);
|
|
157
|
+
free(ptr);
|
|
158
|
+
THROW_ERROR_IF_NOT_EQUAL(RCL_RET_OK, ret, rcl_get_error_string().str);
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
Napi::Value ClockGetNow(const Napi::CallbackInfo& info) {
|
|
163
|
+
Napi::Env env = info.Env();
|
|
164
|
+
|
|
165
|
+
rcl_clock_t* clock = reinterpret_cast<rcl_clock_t*>(
|
|
166
|
+
RclHandle::Unwrap(info[0].As<Napi::Object>())->ptr());
|
|
167
|
+
rcl_time_point_t time_point;
|
|
168
|
+
time_point.clock_type = clock->type;
|
|
169
|
+
|
|
170
|
+
THROW_ERROR_IF_NOT_EQUAL(RCL_RET_OK,
|
|
171
|
+
rcl_clock_get_now(clock, &time_point.nanoseconds),
|
|
172
|
+
rcl_get_error_string().str);
|
|
173
|
+
|
|
174
|
+
return Napi::BigInt::New(env, time_point.nanoseconds);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
Napi::Object InitTimePointBindings(Napi::Env env, Napi::Object exports) {
|
|
178
|
+
exports.Set("createClock", Napi::Function::New(env, CreateClock));
|
|
179
|
+
exports.Set("clockGetNow", Napi::Function::New(env, ClockGetNow));
|
|
180
|
+
exports.Set("createTimePoint", Napi::Function::New(env, CreateTimePoint));
|
|
181
|
+
exports.Set("getNanoseconds", Napi::Function::New(env, GetNanoseconds));
|
|
182
|
+
exports.Set("createDuration", Napi::Function::New(env, CreateDuration));
|
|
183
|
+
exports.Set("getDurationNanoseconds",
|
|
184
|
+
Napi::Function::New(env, GetDurationNanoseconds));
|
|
185
|
+
exports.Set("setRosTimeOverrideIsEnabled",
|
|
186
|
+
Napi::Function::New(env, SetRosTimeOverrideIsEnabled));
|
|
187
|
+
exports.Set("setRosTimeOverride",
|
|
188
|
+
Napi::Function::New(env, SetRosTimeOverride));
|
|
189
|
+
exports.Set("getRosTimeOverrideIsEnabled",
|
|
190
|
+
Napi::Function::New(env, GetRosTimeOverrideIsEnabled));
|
|
191
|
+
return exports;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
} // namespace rclnodejs
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// Copyright (c) 2025, The Robot Web Tools Contributors
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
|
|
15
|
+
#ifndef SRC_RCL_TIME_POINT_BINDINGS_H_
|
|
16
|
+
#define SRC_RCL_TIME_POINT_BINDINGS_H_
|
|
17
|
+
|
|
18
|
+
#include <napi.h>
|
|
19
|
+
|
|
20
|
+
namespace rclnodejs {
|
|
21
|
+
|
|
22
|
+
Napi::Object InitTimePointBindings(Napi::Env env, Napi::Object exports);
|
|
23
|
+
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
#endif // SRC_RCL_TIME_POINT_BINDINGS_H_
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
// Copyright (c) 2025, The Robot Web Tools Contributors
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
|
|
15
|
+
#include "rcl_timer_bindings.h"
|
|
16
|
+
|
|
17
|
+
#include <rcl/error_handling.h>
|
|
18
|
+
#include <rcl/rcl.h>
|
|
19
|
+
|
|
20
|
+
#include "macros.h"
|
|
21
|
+
#include "rcl_handle.h"
|
|
22
|
+
#include "rcl_utilities.h"
|
|
23
|
+
|
|
24
|
+
namespace rclnodejs {
|
|
25
|
+
|
|
26
|
+
Napi::Value CreateTimer(const Napi::CallbackInfo& info) {
|
|
27
|
+
Napi::Env env = info.Env();
|
|
28
|
+
|
|
29
|
+
RclHandle* clock_handle = RclHandle::Unwrap(info[0].As<Napi::Object>());
|
|
30
|
+
rcl_clock_t* clock = reinterpret_cast<rcl_clock_t*>(clock_handle->ptr());
|
|
31
|
+
|
|
32
|
+
RclHandle* context_handle = RclHandle::Unwrap(info[1].As<Napi::Object>());
|
|
33
|
+
rcl_context_t* context =
|
|
34
|
+
reinterpret_cast<rcl_context_t*>(context_handle->ptr());
|
|
35
|
+
|
|
36
|
+
if (!info[2].IsBigInt()) {
|
|
37
|
+
Napi::TypeError::New(env, "Timer period must be a BigInt")
|
|
38
|
+
.ThrowAsJavaScriptException();
|
|
39
|
+
return env.Undefined();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
bool lossless;
|
|
43
|
+
int64_t period_nsec = info[2].As<Napi::BigInt>().Int64Value(&lossless);
|
|
44
|
+
rcl_timer_t* timer =
|
|
45
|
+
reinterpret_cast<rcl_timer_t*>(malloc(sizeof(rcl_timer_t)));
|
|
46
|
+
*timer = rcl_get_zero_initialized_timer();
|
|
47
|
+
|
|
48
|
+
#if ROS_VERSION > 2305 // After Iron.
|
|
49
|
+
THROW_ERROR_IF_NOT_EQUAL(
|
|
50
|
+
RCL_RET_OK,
|
|
51
|
+
rcl_timer_init2(timer, clock, context, period_nsec, nullptr,
|
|
52
|
+
rcl_get_default_allocator(), /*autostart=*/true),
|
|
53
|
+
rcl_get_error_string().str);
|
|
54
|
+
#else
|
|
55
|
+
THROW_ERROR_IF_NOT_EQUAL(RCL_RET_OK,
|
|
56
|
+
rcl_timer_init(timer, clock, context, period_nsec,
|
|
57
|
+
nullptr, rcl_get_default_allocator()),
|
|
58
|
+
rcl_get_error_string().str);
|
|
59
|
+
#endif
|
|
60
|
+
|
|
61
|
+
auto js_obj = RclHandle::NewInstance(env, timer, clock_handle, [](void* ptr) {
|
|
62
|
+
rcl_timer_t* timer = reinterpret_cast<rcl_timer_t*>(ptr);
|
|
63
|
+
rcl_ret_t ret = rcl_timer_fini(timer);
|
|
64
|
+
free(ptr);
|
|
65
|
+
THROW_ERROR_IF_NOT_EQUAL(RCL_RET_OK, ret, rcl_get_error_string().str);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
return js_obj;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
Napi::Value IsTimerReady(const Napi::CallbackInfo& info) {
|
|
72
|
+
Napi::Env env = info.Env();
|
|
73
|
+
|
|
74
|
+
RclHandle* timer_handle = RclHandle::Unwrap(info[0].As<Napi::Object>());
|
|
75
|
+
rcl_timer_t* timer = reinterpret_cast<rcl_timer_t*>(timer_handle->ptr());
|
|
76
|
+
bool is_ready = false;
|
|
77
|
+
|
|
78
|
+
THROW_ERROR_IF_NOT_EQUAL(RCL_RET_OK, rcl_timer_is_ready(timer, &is_ready),
|
|
79
|
+
rcl_get_error_string().str);
|
|
80
|
+
|
|
81
|
+
return Napi::Boolean::New(env, is_ready);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
Napi::Value CallTimer(const Napi::CallbackInfo& info) {
|
|
85
|
+
Napi::Env env = info.Env();
|
|
86
|
+
|
|
87
|
+
RclHandle* timer_handle = RclHandle::Unwrap(info[0].As<Napi::Object>());
|
|
88
|
+
rcl_timer_t* timer = reinterpret_cast<rcl_timer_t*>(timer_handle->ptr());
|
|
89
|
+
|
|
90
|
+
THROW_ERROR_IF_NOT_EQUAL(RCL_RET_OK, rcl_timer_call(timer),
|
|
91
|
+
rcl_get_error_string().str);
|
|
92
|
+
|
|
93
|
+
return env.Undefined();
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
Napi::Value CancelTimer(const Napi::CallbackInfo& info) {
|
|
97
|
+
Napi::Env env = info.Env();
|
|
98
|
+
|
|
99
|
+
RclHandle* timer_handle = RclHandle::Unwrap(info[0].As<Napi::Object>());
|
|
100
|
+
rcl_timer_t* timer = reinterpret_cast<rcl_timer_t*>(timer_handle->ptr());
|
|
101
|
+
|
|
102
|
+
THROW_ERROR_IF_NOT_EQUAL(RCL_RET_OK, rcl_timer_cancel(timer),
|
|
103
|
+
rcl_get_error_string().str);
|
|
104
|
+
|
|
105
|
+
return env.Undefined();
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
Napi::Value IsTimerCanceled(const Napi::CallbackInfo& info) {
|
|
109
|
+
Napi::Env env = info.Env();
|
|
110
|
+
|
|
111
|
+
RclHandle* timer_handle = RclHandle::Unwrap(info[0].As<Napi::Object>());
|
|
112
|
+
rcl_timer_t* timer = reinterpret_cast<rcl_timer_t*>(timer_handle->ptr());
|
|
113
|
+
bool is_canceled = false;
|
|
114
|
+
|
|
115
|
+
THROW_ERROR_IF_NOT_EQUAL(RCL_RET_OK,
|
|
116
|
+
rcl_timer_is_canceled(timer, &is_canceled),
|
|
117
|
+
rcl_get_error_string().str);
|
|
118
|
+
|
|
119
|
+
return Napi::Boolean::New(env, is_canceled);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
Napi::Value ResetTimer(const Napi::CallbackInfo& info) {
|
|
123
|
+
Napi::Env env = info.Env();
|
|
124
|
+
|
|
125
|
+
RclHandle* timer_handle = RclHandle::Unwrap(info[0].As<Napi::Object>());
|
|
126
|
+
rcl_timer_t* timer = reinterpret_cast<rcl_timer_t*>(timer_handle->ptr());
|
|
127
|
+
|
|
128
|
+
THROW_ERROR_IF_NOT_EQUAL(RCL_RET_OK, rcl_timer_reset(timer),
|
|
129
|
+
rcl_get_error_string().str);
|
|
130
|
+
|
|
131
|
+
return env.Undefined();
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
Napi::Value TimerGetTimeUntilNextCall(const Napi::CallbackInfo& info) {
|
|
135
|
+
Napi::Env env = info.Env();
|
|
136
|
+
|
|
137
|
+
RclHandle* timer_handle = RclHandle::Unwrap(info[0].As<Napi::Object>());
|
|
138
|
+
rcl_timer_t* timer = reinterpret_cast<rcl_timer_t*>(timer_handle->ptr());
|
|
139
|
+
int64_t remaining_time = 0;
|
|
140
|
+
|
|
141
|
+
THROW_ERROR_IF_NOT_EQUAL(
|
|
142
|
+
RCL_RET_OK, rcl_timer_get_time_until_next_call(timer, &remaining_time),
|
|
143
|
+
rcl_get_error_string().str);
|
|
144
|
+
|
|
145
|
+
return Napi::BigInt::New(env, remaining_time);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
Napi::Value TimerGetTimeSinceLastCall(const Napi::CallbackInfo& info) {
|
|
149
|
+
Napi::Env env = info.Env();
|
|
150
|
+
|
|
151
|
+
RclHandle* timer_handle = RclHandle::Unwrap(info[0].As<Napi::Object>());
|
|
152
|
+
rcl_timer_t* timer = reinterpret_cast<rcl_timer_t*>(timer_handle->ptr());
|
|
153
|
+
int64_t elapsed_time = 0;
|
|
154
|
+
|
|
155
|
+
THROW_ERROR_IF_NOT_EQUAL(
|
|
156
|
+
RCL_RET_OK, rcl_timer_get_time_since_last_call(timer, &elapsed_time),
|
|
157
|
+
rcl_get_error_string().str);
|
|
158
|
+
|
|
159
|
+
return Napi::BigInt::New(env, elapsed_time);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
Napi::Value ChangeTimerPeriod(const Napi::CallbackInfo& info) {
|
|
163
|
+
Napi::Env env = info.Env();
|
|
164
|
+
|
|
165
|
+
RclHandle* timer_handle = RclHandle::Unwrap(info[0].As<Napi::Object>());
|
|
166
|
+
rcl_timer_t* timer = reinterpret_cast<rcl_timer_t*>(timer_handle->ptr());
|
|
167
|
+
|
|
168
|
+
if (!info[1].IsBigInt()) {
|
|
169
|
+
Napi::TypeError::New(env, "Timer period must be a BigInt")
|
|
170
|
+
.ThrowAsJavaScriptException();
|
|
171
|
+
return env.Undefined();
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
bool lossless;
|
|
175
|
+
int64_t period_nsec = info[1].As<Napi::BigInt>().Int64Value(&lossless);
|
|
176
|
+
int64_t old_period;
|
|
177
|
+
THROW_ERROR_IF_NOT_EQUAL(
|
|
178
|
+
RCL_RET_OK, rcl_timer_exchange_period(timer, period_nsec, &old_period),
|
|
179
|
+
rcl_get_error_string().str);
|
|
180
|
+
|
|
181
|
+
return env.Undefined();
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
Napi::Value GetTimerPeriod(const Napi::CallbackInfo& info) {
|
|
185
|
+
Napi::Env env = info.Env();
|
|
186
|
+
|
|
187
|
+
RclHandle* timer_handle = RclHandle::Unwrap(info[0].As<Napi::Object>());
|
|
188
|
+
rcl_timer_t* timer = reinterpret_cast<rcl_timer_t*>(timer_handle->ptr());
|
|
189
|
+
int64_t period_nsec = 0;
|
|
190
|
+
|
|
191
|
+
THROW_ERROR_IF_NOT_EQUAL(RCL_RET_OK,
|
|
192
|
+
rcl_timer_get_period(timer, &period_nsec),
|
|
193
|
+
rcl_get_error_string().str);
|
|
194
|
+
|
|
195
|
+
return Napi::BigInt::New(env, period_nsec);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
#if ROS_VERSION > 2205 // 2205 == Humble
|
|
199
|
+
Napi::Value CallTimerWithInfo(const Napi::CallbackInfo& info) {
|
|
200
|
+
Napi::Env env = info.Env();
|
|
201
|
+
RclHandle* timer_handle = RclHandle::Unwrap(info[0].As<Napi::Object>());
|
|
202
|
+
rcl_timer_t* timer = reinterpret_cast<rcl_timer_t*>(timer_handle->ptr());
|
|
203
|
+
rcl_timer_call_info_t call_info;
|
|
204
|
+
|
|
205
|
+
THROW_ERROR_IF_NOT_EQUAL(RCL_RET_OK,
|
|
206
|
+
rcl_timer_call_with_info(timer, &call_info),
|
|
207
|
+
rcl_get_error_string().str);
|
|
208
|
+
|
|
209
|
+
Napi::Object timer_info = Napi::Object::New(env);
|
|
210
|
+
timer_info.Set("expectedCallTime",
|
|
211
|
+
Napi::BigInt::New(env, call_info.expected_call_time));
|
|
212
|
+
timer_info.Set("actualCallTime",
|
|
213
|
+
Napi::BigInt::New(env, call_info.actual_call_time));
|
|
214
|
+
return timer_info;
|
|
215
|
+
}
|
|
216
|
+
#endif
|
|
217
|
+
|
|
218
|
+
Napi::Object InitTimerBindings(Napi::Env env, Napi::Object exports) {
|
|
219
|
+
exports.Set("createTimer", Napi::Function::New(env, CreateTimer));
|
|
220
|
+
exports.Set("isTimerReady", Napi::Function::New(env, IsTimerReady));
|
|
221
|
+
exports.Set("callTimer", Napi::Function::New(env, CallTimer));
|
|
222
|
+
exports.Set("cancelTimer", Napi::Function::New(env, CancelTimer));
|
|
223
|
+
exports.Set("isTimerCanceled", Napi::Function::New(env, IsTimerCanceled));
|
|
224
|
+
exports.Set("resetTimer", Napi::Function::New(env, ResetTimer));
|
|
225
|
+
exports.Set("timerGetTimeSinceLastCall",
|
|
226
|
+
Napi::Function::New(env, TimerGetTimeSinceLastCall));
|
|
227
|
+
exports.Set("timerGetTimeUntilNextCall",
|
|
228
|
+
Napi::Function::New(env, TimerGetTimeUntilNextCall));
|
|
229
|
+
exports.Set("changeTimerPeriod", Napi::Function::New(env, ChangeTimerPeriod));
|
|
230
|
+
exports.Set("getTimerPeriod", Napi::Function::New(env, GetTimerPeriod));
|
|
231
|
+
#if ROS_VERSION > 2205 // 2205 == Humble
|
|
232
|
+
exports.Set("callTimerWithInfo", Napi::Function::New(env, CallTimerWithInfo));
|
|
233
|
+
#endif
|
|
234
|
+
return exports;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
} // namespace rclnodejs
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// Copyright (c) 2025, The Robot Web Tools Contributors
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
|
|
15
|
+
#ifndef SRC_RCL_TIMER_BINDINGS_H_
|
|
16
|
+
#define SRC_RCL_TIMER_BINDINGS_H_
|
|
17
|
+
|
|
18
|
+
#include <napi.h>
|
|
19
|
+
|
|
20
|
+
namespace rclnodejs {
|
|
21
|
+
|
|
22
|
+
Napi::Object InitTimerBindings(Napi::Env env, Napi::Object exports);
|
|
23
|
+
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
#endif // SRC_RCL_TIMER_BINDINGS_H_
|
package/src/rcl_utilities.cpp
CHANGED
|
@@ -12,16 +12,115 @@
|
|
|
12
12
|
// See the License for the specific language governing permissions and
|
|
13
13
|
// limitations under the License.
|
|
14
14
|
|
|
15
|
-
#include "rcl_utilities.
|
|
15
|
+
#include "rcl_utilities.h"
|
|
16
16
|
|
|
17
17
|
#include <rcl/rcl.h>
|
|
18
18
|
#include <rcl_action/rcl_action.h>
|
|
19
|
+
#include <rmw/topic_endpoint_info.h>
|
|
19
20
|
#include <uv.h>
|
|
20
21
|
|
|
22
|
+
#include <memory>
|
|
21
23
|
#include <string>
|
|
22
24
|
|
|
23
25
|
namespace {
|
|
26
|
+
|
|
27
|
+
const rmw_qos_profile_t* GetQoSProfileFromString(const std::string& profile) {
|
|
28
|
+
const rmw_qos_profile_t* qos_profile = nullptr;
|
|
29
|
+
if (profile == "qos_profile_sensor_data") {
|
|
30
|
+
qos_profile = &rmw_qos_profile_sensor_data;
|
|
31
|
+
} else if (profile == "qos_profile_system_default") {
|
|
32
|
+
qos_profile = &rmw_qos_profile_system_default;
|
|
33
|
+
} else if (profile == "qos_profile_services_default") {
|
|
34
|
+
qos_profile = &rmw_qos_profile_services_default;
|
|
35
|
+
} else if (profile == "qos_profile_parameters") {
|
|
36
|
+
qos_profile = &rmw_qos_profile_parameters;
|
|
37
|
+
} else if (profile == "qos_profile_parameter_events") {
|
|
38
|
+
qos_profile = &rmw_qos_profile_parameter_events;
|
|
39
|
+
} else if (profile == "qos_profile_action_status_default") {
|
|
40
|
+
qos_profile = &rcl_action_qos_profile_status_default;
|
|
41
|
+
} else {
|
|
42
|
+
return &rmw_qos_profile_default;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return qos_profile;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
std::unique_ptr<rmw_qos_profile_t> GetQosProfileFromObject(
|
|
49
|
+
Napi::Object object) {
|
|
50
|
+
std::unique_ptr<rmw_qos_profile_t> qos_profile =
|
|
51
|
+
std::make_unique<rmw_qos_profile_t>();
|
|
52
|
+
|
|
53
|
+
auto history = object.Get("history");
|
|
54
|
+
auto depth = object.Get("depth");
|
|
55
|
+
auto reliability = object.Get("reliability");
|
|
56
|
+
auto durability = object.Get("durability");
|
|
57
|
+
auto avoid_ros_namespace_conventions =
|
|
58
|
+
object.Get("avoidRosNameSpaceConventions");
|
|
59
|
+
|
|
60
|
+
qos_profile->history = static_cast<rmw_qos_history_policy_t>(
|
|
61
|
+
history.As<Napi::Number>().Uint32Value());
|
|
62
|
+
qos_profile->depth = depth.As<Napi::Number>().Uint32Value();
|
|
63
|
+
qos_profile->reliability = static_cast<rmw_qos_reliability_policy_t>(
|
|
64
|
+
reliability.As<Napi::Number>().Uint32Value());
|
|
65
|
+
qos_profile->durability = static_cast<rmw_qos_durability_policy_t>(
|
|
66
|
+
durability.As<Napi::Number>().Uint32Value());
|
|
67
|
+
qos_profile->avoid_ros_namespace_conventions =
|
|
68
|
+
avoid_ros_namespace_conventions.As<Napi::Boolean>();
|
|
69
|
+
|
|
70
|
+
return qos_profile;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
Napi::Value ConvertRMWTimeToDuration(Napi::Env env,
|
|
74
|
+
const rmw_time_t* duration) {
|
|
75
|
+
Napi::Object obj = Napi::Object::New(env);
|
|
76
|
+
obj.Set("seconds", Napi::BigInt::New(env, duration->sec));
|
|
77
|
+
obj.Set("nanoseconds", Napi::Number::New(env, duration->nsec));
|
|
78
|
+
return obj;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
#if ROS_VERSION > 2205 // 2205 == Humble
|
|
82
|
+
Napi::Value ConvertToHashObject(Napi::Env env,
|
|
83
|
+
const rosidl_type_hash_t* type_hash) {
|
|
84
|
+
Napi::Object obj = Napi::Object::New(env);
|
|
85
|
+
obj.Set("version", Napi::Number::New(env, type_hash->version));
|
|
86
|
+
obj.Set("value", Napi::Buffer<char>::Copy(
|
|
87
|
+
env, reinterpret_cast<const char*>(type_hash->value),
|
|
88
|
+
ROSIDL_TYPE_HASH_SIZE));
|
|
89
|
+
return obj;
|
|
90
|
+
}
|
|
91
|
+
#endif
|
|
92
|
+
|
|
93
|
+
Napi::Value ConvertToJSTopicEndpoint(
|
|
94
|
+
Napi::Env env, const rmw_topic_endpoint_info_t* topic_endpoint_info) {
|
|
95
|
+
Napi::Array endpoint_gid = Napi::Array::New(env, RMW_GID_STORAGE_SIZE);
|
|
96
|
+
for (size_t i = 0; i < RMW_GID_STORAGE_SIZE; i++) {
|
|
97
|
+
endpoint_gid.Set(
|
|
98
|
+
i, Napi::Number::New(env, topic_endpoint_info->endpoint_gid[i]));
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
Napi::Object endpoint = Napi::Object::New(env);
|
|
102
|
+
endpoint.Set("node_name",
|
|
103
|
+
Napi::String::New(env, topic_endpoint_info->node_name));
|
|
104
|
+
endpoint.Set("node_namespace",
|
|
105
|
+
Napi::String::New(env, topic_endpoint_info->node_namespace));
|
|
106
|
+
endpoint.Set("topic_type",
|
|
107
|
+
Napi::String::New(env, topic_endpoint_info->topic_type));
|
|
108
|
+
#if ROS_VERSION > 2205 // 2205 == Humble
|
|
109
|
+
endpoint.Set("topic_type_hash",
|
|
110
|
+
ConvertToHashObject(env, &topic_endpoint_info->topic_type_hash));
|
|
111
|
+
#endif
|
|
112
|
+
endpoint.Set("endpoint_type",
|
|
113
|
+
Napi::Number::New(
|
|
114
|
+
env, static_cast<int>(topic_endpoint_info->endpoint_type)));
|
|
115
|
+
endpoint.Set("endpoint_gid", endpoint_gid);
|
|
116
|
+
endpoint.Set("qos_profile",
|
|
117
|
+
rclnodejs::ConvertToQoS(env, &topic_endpoint_info->qos_profile));
|
|
118
|
+
return endpoint;
|
|
119
|
+
}
|
|
120
|
+
|
|
24
121
|
uv_lib_t g_lib;
|
|
122
|
+
Napi::Env g_env = nullptr;
|
|
123
|
+
|
|
25
124
|
} // namespace
|
|
26
125
|
|
|
27
126
|
namespace rclnodejs {
|
|
@@ -95,4 +194,70 @@ std::string GetErrorMessageAndClear() {
|
|
|
95
194
|
return std::string(uv_dlerror(&g_lib));
|
|
96
195
|
}
|
|
97
196
|
|
|
197
|
+
Napi::Env& GetEnv() { return g_env; }
|
|
198
|
+
|
|
199
|
+
void StoreEnv(Napi::Env current_env) { g_env = current_env; }
|
|
200
|
+
|
|
201
|
+
std::unique_ptr<rmw_qos_profile_t> GetQoSProfile(Napi::Value qos) {
|
|
202
|
+
std::unique_ptr<rmw_qos_profile_t> qos_profile =
|
|
203
|
+
std::make_unique<rmw_qos_profile_t>();
|
|
204
|
+
|
|
205
|
+
if (qos.IsString()) {
|
|
206
|
+
*qos_profile = *GetQoSProfileFromString(qos.As<Napi::String>().Utf8Value());
|
|
207
|
+
} else if (qos.IsObject()) {
|
|
208
|
+
qos_profile = GetQosProfileFromObject(qos.As<Napi::Object>());
|
|
209
|
+
} else {
|
|
210
|
+
return qos_profile;
|
|
211
|
+
}
|
|
212
|
+
return qos_profile;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
void ExtractNamesAndTypes(rcl_names_and_types_t names_and_types,
|
|
216
|
+
Napi::Array* result_list) {
|
|
217
|
+
Napi::Env env = result_list->Env();
|
|
218
|
+
|
|
219
|
+
for (size_t i = 0; i < names_and_types.names.size; ++i) {
|
|
220
|
+
Napi::Object item = Napi::Object::New(env);
|
|
221
|
+
std::string topic_name = names_and_types.names.data[i];
|
|
222
|
+
item.Set("name", Napi::String::New(env, names_and_types.names.data[i]));
|
|
223
|
+
|
|
224
|
+
Napi::Array type_list =
|
|
225
|
+
Napi::Array::New(env, names_and_types.types[i].size);
|
|
226
|
+
for (size_t j = 0; j < names_and_types.types[i].size; ++j) {
|
|
227
|
+
type_list.Set(j,
|
|
228
|
+
Napi::String::New(env, names_and_types.types[i].data[j]));
|
|
229
|
+
}
|
|
230
|
+
item.Set("types", type_list);
|
|
231
|
+
result_list->Set(i, item);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
Napi::Value ConvertToQoS(Napi::Env env, const rmw_qos_profile_t* qos_profile) {
|
|
236
|
+
Napi::Object qos = Napi::Object::New(env);
|
|
237
|
+
qos.Set("depth", Napi::Number::New(env, qos_profile->depth));
|
|
238
|
+
qos.Set("history", Napi::Number::New(env, qos_profile->history));
|
|
239
|
+
qos.Set("reliability", Napi::Number::New(env, qos_profile->reliability));
|
|
240
|
+
qos.Set("durability", Napi::Number::New(env, qos_profile->durability));
|
|
241
|
+
qos.Set("lifespan", ConvertRMWTimeToDuration(env, &qos_profile->lifespan));
|
|
242
|
+
qos.Set("deadline", ConvertRMWTimeToDuration(env, &qos_profile->deadline));
|
|
243
|
+
qos.Set("liveliness", Napi::Number::New(env, qos_profile->liveliness));
|
|
244
|
+
qos.Set(
|
|
245
|
+
"liveliness_lease_duration",
|
|
246
|
+
ConvertRMWTimeToDuration(env, &qos_profile->liveliness_lease_duration));
|
|
247
|
+
qos.Set(
|
|
248
|
+
"avoid_ros_namespace_conventions",
|
|
249
|
+
Napi::Boolean::New(env, qos_profile->avoid_ros_namespace_conventions));
|
|
250
|
+
return qos;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
Napi::Array ConvertToJSTopicEndpointInfoList(
|
|
254
|
+
Napi::Env env, const rmw_topic_endpoint_info_array_t* info_array) {
|
|
255
|
+
Napi::Array list = Napi::Array::New(env, info_array->size);
|
|
256
|
+
for (size_t i = 0; i < info_array->size; ++i) {
|
|
257
|
+
rmw_topic_endpoint_info_t topic_endpoint_info = info_array->info_array[i];
|
|
258
|
+
list.Set(i, ConvertToJSTopicEndpoint(env, &topic_endpoint_info));
|
|
259
|
+
}
|
|
260
|
+
return list;
|
|
261
|
+
}
|
|
262
|
+
|
|
98
263
|
} // namespace rclnodejs
|