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
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<section class="doc-section prose-section tutorial-section">
|
|
2
|
+
|
|
3
|
+
<header class="doc-page-header">
|
|
4
|
+
<?js if (children.length > 0) { ?>
|
|
5
|
+
<ul class="tutorial-children"><?js
|
|
6
|
+
var self = this;
|
|
7
|
+
children.forEach(function(t) { ?>
|
|
8
|
+
<li><?js= self.tutoriallink(t.name) ?></li>
|
|
9
|
+
<?js }); ?></ul>
|
|
10
|
+
<?js } ?>
|
|
11
|
+
|
|
12
|
+
<h2 class="doc-heading"><?js= header ?></h2>
|
|
13
|
+
</header>
|
|
14
|
+
|
|
15
|
+
<article class="prose-card">
|
|
16
|
+
<?js= content ?>
|
|
17
|
+
</article>
|
|
18
|
+
|
|
19
|
+
</section>
|
package/types/action_client.d.ts
CHANGED
|
@@ -142,6 +142,14 @@ declare module 'rclnodejs' {
|
|
|
142
142
|
options?: Options<ActionQoS> & {
|
|
143
143
|
validateGoals?: boolean;
|
|
144
144
|
validationOptions?: MessageValidationOptions;
|
|
145
|
+
/**
|
|
146
|
+
* Enable feedback subscription content filter to optimize the handling
|
|
147
|
+
* of feedback messages. When enabled, the content filter is used to
|
|
148
|
+
* configure the goal ID for the subscription, avoiding reception of
|
|
149
|
+
* irrelevant feedback messages. An action client can handle up to 6
|
|
150
|
+
* goals simultaneously with this optimization. Default: false.
|
|
151
|
+
*/
|
|
152
|
+
enableFeedbackMsgOptimization?: boolean;
|
|
145
153
|
}
|
|
146
154
|
);
|
|
147
155
|
|
package/types/index.d.ts
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
/// <reference path="./clock_event.d.ts" />
|
|
3
3
|
/// <reference path="./clock_change.d.ts" />
|
|
4
4
|
/// <reference path="./message_validation.d.ts" />
|
|
5
|
+
/// <reference path="./parameter_event_handler.d.ts" />
|
|
6
|
+
/// <reference path="./message_info.d.ts" />
|
|
5
7
|
|
|
6
8
|
import { ChildProcess } from 'child_process';
|
|
7
9
|
|
|
@@ -85,6 +87,38 @@ declare module 'rclnodejs' {
|
|
|
85
87
|
* @deprecated since 0.18.0, Use Node.spinOnce(timeout)*/
|
|
86
88
|
function spinOnce(node: Node, timeout?: number): void;
|
|
87
89
|
|
|
90
|
+
/**
|
|
91
|
+
* Options for waitForMessage.
|
|
92
|
+
*/
|
|
93
|
+
interface WaitForMessageOptions {
|
|
94
|
+
/** Timeout in milliseconds. If omitted, waits indefinitely. */
|
|
95
|
+
timeout?: number;
|
|
96
|
+
/** QoS profile for the temporary subscription. */
|
|
97
|
+
qos?: QoS;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Wait for a single message on a topic.
|
|
102
|
+
*
|
|
103
|
+
* Creates a temporary subscription, waits for the first message to arrive,
|
|
104
|
+
* and returns it. The node must be spinning before calling this function.
|
|
105
|
+
*
|
|
106
|
+
* This is the rclnodejs equivalent of rclpy's `wait_for_message`.
|
|
107
|
+
*
|
|
108
|
+
* @param typeClass - The ROS message type class.
|
|
109
|
+
* @param node - The node to create the temporary subscription on.
|
|
110
|
+
* @param topic - The topic name to listen on.
|
|
111
|
+
* @param options - Options including timeout and QoS.
|
|
112
|
+
* @returns Resolves with the received message.
|
|
113
|
+
* @throws Error if timeout expires before a message arrives.
|
|
114
|
+
*/
|
|
115
|
+
function waitForMessage<T extends TypeClass<MessageTypeClassName>>(
|
|
116
|
+
typeClass: T,
|
|
117
|
+
node: Node,
|
|
118
|
+
topic: string,
|
|
119
|
+
options?: WaitForMessageOptions
|
|
120
|
+
): Promise<MessageType<T>>;
|
|
121
|
+
|
|
88
122
|
/**
|
|
89
123
|
* Stop all activity, destroy all nodes and node components.
|
|
90
124
|
*
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// Copyright (c) 2026, 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
|
+
declare module 'rclnodejs' {
|
|
16
|
+
/**
|
|
17
|
+
* Contains metadata about a received message, including timestamps,
|
|
18
|
+
* sequence numbers, and the publisher's globally unique identifier (GID).
|
|
19
|
+
*
|
|
20
|
+
* Passed as the second argument to subscription callbacks when the
|
|
21
|
+
* callback accepts two parameters.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```typescript
|
|
25
|
+
* node.createSubscription(
|
|
26
|
+
* 'std_msgs/msg/String',
|
|
27
|
+
* 'topic',
|
|
28
|
+
* (msg: rclnodejs.std_msgs.msg.String, info: MessageInfo) => {
|
|
29
|
+
* console.log('Source timestamp:', info.sourceTimestamp);
|
|
30
|
+
* }
|
|
31
|
+
* );
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
class MessageInfo {
|
|
35
|
+
/**
|
|
36
|
+
* The timestamp when the message was published (nanoseconds since epoch).
|
|
37
|
+
*/
|
|
38
|
+
readonly sourceTimestamp: bigint;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* The timestamp when the message was received by the subscription (nanoseconds since epoch).
|
|
42
|
+
*/
|
|
43
|
+
readonly receivedTimestamp: bigint;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* The publication sequence number assigned by the publisher.
|
|
47
|
+
*/
|
|
48
|
+
readonly publicationSequenceNumber: bigint;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* The reception sequence number assigned by the subscriber.
|
|
52
|
+
*/
|
|
53
|
+
readonly receptionSequenceNumber: bigint;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* The globally unique identifier (GID) of the publisher.
|
|
57
|
+
* A Buffer containing the raw GID bytes.
|
|
58
|
+
*/
|
|
59
|
+
readonly publisherGid: Buffer;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Convert to a plain object representation.
|
|
63
|
+
*/
|
|
64
|
+
toPlainObject(): {
|
|
65
|
+
sourceTimestamp: bigint;
|
|
66
|
+
receivedTimestamp: bigint;
|
|
67
|
+
publicationSequenceNumber: bigint;
|
|
68
|
+
receptionSequenceNumber: bigint;
|
|
69
|
+
publisherGid: Buffer;
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
}
|
package/types/node.d.ts
CHANGED
|
@@ -511,6 +511,27 @@ declare module 'rclnodejs' {
|
|
|
511
511
|
*/
|
|
512
512
|
destroyParameterWatcher(watcher: ParameterWatcher): void;
|
|
513
513
|
|
|
514
|
+
/**
|
|
515
|
+
* Create a ParameterEventHandler that monitors parameter changes on any node.
|
|
516
|
+
*
|
|
517
|
+
* Unlike ParameterWatcher which watches specific parameters on a single
|
|
518
|
+
* remote node, ParameterEventHandler can register callbacks for parameters
|
|
519
|
+
* on any node in the ROS 2 graph by subscribing to /parameter_events.
|
|
520
|
+
*
|
|
521
|
+
* @param options - Options for the handler.
|
|
522
|
+
* @returns An instance of ParameterEventHandler.
|
|
523
|
+
*/
|
|
524
|
+
createParameterEventHandler(
|
|
525
|
+
options?: ParameterEventHandlerOptions
|
|
526
|
+
): ParameterEventHandler;
|
|
527
|
+
|
|
528
|
+
/**
|
|
529
|
+
* Destroy a ParameterEventHandler.
|
|
530
|
+
*
|
|
531
|
+
* @param handler - ParameterEventHandler to be destroyed.
|
|
532
|
+
*/
|
|
533
|
+
destroyParameterEventHandler(handler: ParameterEventHandler): void;
|
|
534
|
+
|
|
514
535
|
/**
|
|
515
536
|
* Destroy a Timer.
|
|
516
537
|
*
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
// Copyright (c) 2026, 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
|
+
declare module 'rclnodejs' {
|
|
16
|
+
/**
|
|
17
|
+
* Options for ParameterEventHandler constructor.
|
|
18
|
+
*/
|
|
19
|
+
export interface ParameterEventHandlerOptions {
|
|
20
|
+
/**
|
|
21
|
+
* QoS profile for the parameter_events subscription.
|
|
22
|
+
*/
|
|
23
|
+
qos?: QoS;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Opaque handle returned when adding a parameter callback.
|
|
28
|
+
* Used to remove the callback later via removeParameterCallback().
|
|
29
|
+
*/
|
|
30
|
+
class ParameterCallbackHandle {
|
|
31
|
+
readonly parameterName: string;
|
|
32
|
+
readonly nodeName: string;
|
|
33
|
+
readonly callback: (parameter: any) => void;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Opaque handle returned when adding a parameter event callback.
|
|
38
|
+
* Used to remove the callback later via removeParameterEventCallback().
|
|
39
|
+
*/
|
|
40
|
+
class ParameterEventCallbackHandle {
|
|
41
|
+
readonly callback: (event: any) => void;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* ParameterEventHandler - Monitors and responds to parameter changes
|
|
46
|
+
* on any node in the ROS 2 graph.
|
|
47
|
+
*
|
|
48
|
+
* Subscribes to `/parameter_events` and dispatches callbacks when
|
|
49
|
+
* parameters are added, changed, or deleted on any node.
|
|
50
|
+
*
|
|
51
|
+
* Two types of callbacks:
|
|
52
|
+
* - **Parameter callbacks**: for a specific parameter on a specific node
|
|
53
|
+
* - **Event callbacks**: for every ParameterEvent message received
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* ```typescript
|
|
57
|
+
* const handler = node.createParameterEventHandler();
|
|
58
|
+
*
|
|
59
|
+
* const handle = handler.addParameterCallback(
|
|
60
|
+
* 'my_param', '/my_node',
|
|
61
|
+
* (param) => console.log(`Changed: ${param.name}`)
|
|
62
|
+
* );
|
|
63
|
+
*
|
|
64
|
+
* handler.removeParameterCallback(handle);
|
|
65
|
+
* handler.destroy();
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
class ParameterEventHandler {
|
|
69
|
+
/**
|
|
70
|
+
* Add a callback for a specific parameter on a specific node.
|
|
71
|
+
*
|
|
72
|
+
* @param parameterName - Name of the parameter to monitor.
|
|
73
|
+
* @param nodeName - Fully qualified name of the node (e.g., '/my_node').
|
|
74
|
+
* @param callback - Called with the parameter message when it changes.
|
|
75
|
+
* @returns A handle for removing this callback later.
|
|
76
|
+
*/
|
|
77
|
+
addParameterCallback(
|
|
78
|
+
parameterName: string,
|
|
79
|
+
nodeName: string,
|
|
80
|
+
callback: (parameter: any) => void
|
|
81
|
+
): ParameterCallbackHandle;
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Remove a previously added parameter callback.
|
|
85
|
+
*
|
|
86
|
+
* @param handle - The handle returned by addParameterCallback.
|
|
87
|
+
*/
|
|
88
|
+
removeParameterCallback(handle: ParameterCallbackHandle): void;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Add a callback that is invoked for every parameter event.
|
|
92
|
+
*
|
|
93
|
+
* @param callback - Called with the full ParameterEvent message.
|
|
94
|
+
* @returns A handle for removing this callback later.
|
|
95
|
+
*/
|
|
96
|
+
addParameterEventCallback(
|
|
97
|
+
callback: (event: any) => void
|
|
98
|
+
): ParameterEventCallbackHandle;
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Remove a previously added parameter event callback.
|
|
102
|
+
*
|
|
103
|
+
* @param handle - The handle returned by addParameterEventCallback.
|
|
104
|
+
*/
|
|
105
|
+
removeParameterEventCallback(handle: ParameterEventCallbackHandle): void;
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Check if the handler has been destroyed.
|
|
109
|
+
*/
|
|
110
|
+
isDestroyed(): boolean;
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Destroy the handler and clean up resources.
|
|
114
|
+
*/
|
|
115
|
+
destroy(): void;
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Get a specific parameter from a ParameterEvent message.
|
|
119
|
+
*
|
|
120
|
+
* @param event - A ParameterEvent message.
|
|
121
|
+
* @param parameterName - The parameter name to look for.
|
|
122
|
+
* @param nodeName - The node name to match.
|
|
123
|
+
* @returns The matching parameter message, or null.
|
|
124
|
+
*/
|
|
125
|
+
static getParameterFromEvent(
|
|
126
|
+
event: any,
|
|
127
|
+
parameterName: string,
|
|
128
|
+
nodeName: string
|
|
129
|
+
): any | null;
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Get all parameters from a ParameterEvent message (new + changed).
|
|
133
|
+
*
|
|
134
|
+
* @param event - A ParameterEvent message.
|
|
135
|
+
* @returns Array of parameter messages.
|
|
136
|
+
*/
|
|
137
|
+
static getParametersFromEvent(event: any): any[];
|
|
138
|
+
}
|
|
139
|
+
}
|
package/types/subscription.d.ts
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
declare module 'rclnodejs' {
|
|
2
2
|
/**
|
|
3
3
|
* A callback for receiving published messages.
|
|
4
|
+
* If the callback accepts two parameters, the second will be a MessageInfo
|
|
5
|
+
* containing metadata about the received message.
|
|
4
6
|
*
|
|
5
7
|
* @param message - The published message.
|
|
8
|
+
* @param messageInfo - Optional metadata about the message (timestamps, publisher GID, etc).
|
|
6
9
|
*
|
|
7
10
|
* @remarks
|
|
8
11
|
* See {@link Node#createSubscription | Node.createSubscription}
|
|
@@ -13,12 +16,15 @@ declare module 'rclnodejs' {
|
|
|
13
16
|
*/
|
|
14
17
|
type SubscriptionCallback<T extends TypeClass<MessageTypeClassName>> =
|
|
15
18
|
// * @param message - The published message
|
|
16
|
-
(message: MessageType<T
|
|
19
|
+
(message: MessageType<T>, messageInfo?: MessageInfo) => void;
|
|
17
20
|
|
|
18
21
|
/**
|
|
19
22
|
* A callback for receiving published raw messages.
|
|
23
|
+
* If the callback accepts a second parameter, it will receive a MessageInfo
|
|
24
|
+
* containing metadata about the received message.
|
|
20
25
|
*
|
|
21
26
|
* @param message - The published message.
|
|
27
|
+
* @param messageInfo - Optional metadata about the message.
|
|
22
28
|
*
|
|
23
29
|
* @remarks
|
|
24
30
|
* See {@link Node#createSubscription | Node.createSubscription}
|
|
@@ -29,7 +35,7 @@ declare module 'rclnodejs' {
|
|
|
29
35
|
*/
|
|
30
36
|
type SubscriptionWithRawMessageCallback =
|
|
31
37
|
// * @param message - The published raw message
|
|
32
|
-
(message: Buffer) => void;
|
|
38
|
+
(message: Buffer, messageInfo?: MessageInfo) => void;
|
|
33
39
|
|
|
34
40
|
/**
|
|
35
41
|
* A ROS Subscription for published messages on a topic.
|
|
@@ -45,6 +51,12 @@ declare module 'rclnodejs' {
|
|
|
45
51
|
*/
|
|
46
52
|
readonly isRaw: boolean;
|
|
47
53
|
|
|
54
|
+
/**
|
|
55
|
+
* Check if content filtering is supported for this subscription.
|
|
56
|
+
* @returns True if the subscription instance supports content filtering; otherwise false.
|
|
57
|
+
*/
|
|
58
|
+
isContentFilterSupported(): boolean;
|
|
59
|
+
|
|
48
60
|
/**
|
|
49
61
|
* Test if the RMW supports content-filtered topics and that this subscription
|
|
50
62
|
* is configured with a well formed content-filter.
|
|
@@ -1,298 +0,0 @@
|
|
|
1
|
-
# ROS2 IDL to Interface Converter
|
|
2
|
-
|
|
3
|
-
This Python tool converts ROS2 `.idl` files to corresponding `.msg`, `.srv`, and `.action` files.
|
|
4
|
-
|
|
5
|
-
## Features
|
|
6
|
-
|
|
7
|
-
- **Complete IDL Parsing**: Parses ROS2 IDL syntax including modules, structs, sequences, and arrays
|
|
8
|
-
- **Type Mapping**: Automatically maps IDL types to ROS2 types (e.g., `double` → `float64`, `sequence<T>` → `T[]`)
|
|
9
|
-
- **Typedef Support**: Handles both simple and array typedefs for complex type definitions
|
|
10
|
-
- **Constants and Default Values**: Supports constant definitions and field default values with `@default` annotations
|
|
11
|
-
- **Comment Preservation**: Extracts and preserves comments from `@verbatim` blocks
|
|
12
|
-
- **Key Annotation Detection**: Automatically skips IDL files with `@key` annotations (not supported in ROS2)
|
|
13
|
-
- **Multi-Interface Support**: Handles messages, services, and actions in a single IDL file
|
|
14
|
-
- **Namespace Support**: Properly handles namespaced types (e.g., `std_msgs::msg::Header` → `std_msgs/Header`)
|
|
15
|
-
- **Command Line Interface**: Easy to use with command line arguments
|
|
16
|
-
- **Verbose Output**: Optional detailed output showing parsed structures and generated files
|
|
17
|
-
|
|
18
|
-
## Usage
|
|
19
|
-
|
|
20
|
-
### Basic Usage
|
|
21
|
-
|
|
22
|
-
```bash
|
|
23
|
-
python3 idl_convertor.py <idl_file>
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
### With Options
|
|
27
|
-
|
|
28
|
-
```bash
|
|
29
|
-
python3 idl_convertor.py <idl_file> [options]
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
### Options
|
|
33
|
-
|
|
34
|
-
- `-o, --output DIR`: Output directory name for generated files (default: `ros_interfaces`)
|
|
35
|
-
- `-r, --root PATH`: Root path where the generated files will be located (default: current directory)
|
|
36
|
-
- `-p, --package NAME`: Package name to use for generated files (overrides package name from IDL)
|
|
37
|
-
- `-v, --verbose`: Enable verbose output showing parsed structures and file contents
|
|
38
|
-
- `-h, --help`: Show help message
|
|
39
|
-
|
|
40
|
-
### Advanced Examples
|
|
41
|
-
|
|
42
|
-
#### Custom Output Directory
|
|
43
|
-
|
|
44
|
-
```bash
|
|
45
|
-
python3 idl_convertor.py JointState.idl -o my_interfaces
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
#### Custom Root Path
|
|
49
|
-
|
|
50
|
-
```bash
|
|
51
|
-
python3 idl_convertor.py SetCameraInfo.idl -r /path/to/workspace -o sensor_msgs
|
|
52
|
-
# Generates files in: /path/to/workspace/sensor_msgs/srv/SetCameraInfo.srv
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
#### Custom Package Name
|
|
56
|
-
|
|
57
|
-
```bash
|
|
58
|
-
python3 idl_convertor.py JointState.idl -p my_package_name
|
|
59
|
-
# Overrides the package name from the IDL file
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
#### Combined Options
|
|
63
|
-
|
|
64
|
-
```bash
|
|
65
|
-
python3 idl_convertor.py SetCameraInfo.idl -r ~/ros2_ws/src -o sensor_msgs -p sensor_msgs -v
|
|
66
|
-
# Generates: ~/ros2_ws/src/sensor_msgs/srv/SetCameraInfo.srv with package name "sensor_msgs"
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
## Examples
|
|
70
|
-
|
|
71
|
-
### 1. Convert a Message IDL
|
|
72
|
-
|
|
73
|
-
Input file `JointState.idl`:
|
|
74
|
-
|
|
75
|
-
```idl
|
|
76
|
-
#include "std_msgs/msg/Header.idl"
|
|
77
|
-
|
|
78
|
-
module sensor_msgs {
|
|
79
|
-
module msg {
|
|
80
|
-
struct JointState {
|
|
81
|
-
std_msgs::msg::Header header;
|
|
82
|
-
sequence<string> name;
|
|
83
|
-
sequence<double> position;
|
|
84
|
-
sequence<double> velocity;
|
|
85
|
-
sequence<double> effort;
|
|
86
|
-
};
|
|
87
|
-
};
|
|
88
|
-
};
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
Output `JointState.msg`:
|
|
92
|
-
|
|
93
|
-
```
|
|
94
|
-
# JointState.msg
|
|
95
|
-
# Generated from IDL file
|
|
96
|
-
|
|
97
|
-
std_msgs/Header header
|
|
98
|
-
string[] name
|
|
99
|
-
float64[] position
|
|
100
|
-
float64[] velocity
|
|
101
|
-
float64[] effort
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
### 2. Convert a Service IDL
|
|
105
|
-
|
|
106
|
-
Input file `SetCameraInfo.idl`:
|
|
107
|
-
|
|
108
|
-
```idl
|
|
109
|
-
#include "sensor_msgs/msg/CameraInfo.idl"
|
|
110
|
-
|
|
111
|
-
module sensor_msgs {
|
|
112
|
-
module srv {
|
|
113
|
-
struct SetCameraInfo_Request {
|
|
114
|
-
sensor_msgs::msg::CameraInfo camera_info;
|
|
115
|
-
};
|
|
116
|
-
struct SetCameraInfo_Response {
|
|
117
|
-
boolean success;
|
|
118
|
-
string status_message;
|
|
119
|
-
};
|
|
120
|
-
};
|
|
121
|
-
};
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
Output `SetCameraInfo.srv`:
|
|
125
|
-
|
|
126
|
-
```
|
|
127
|
-
# SetCameraInfo.srv
|
|
128
|
-
# Generated from IDL file
|
|
129
|
-
|
|
130
|
-
# Request
|
|
131
|
-
sensor_msgs/CameraInfo camera_info
|
|
132
|
-
---
|
|
133
|
-
# Response
|
|
134
|
-
bool success
|
|
135
|
-
string status_message
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
### 3. Convert an Action IDL
|
|
139
|
-
|
|
140
|
-
Input file `Fibonacci.idl`:
|
|
141
|
-
|
|
142
|
-
```idl
|
|
143
|
-
module example_interfaces {
|
|
144
|
-
module action {
|
|
145
|
-
struct FibonacciGoal {
|
|
146
|
-
int32 order;
|
|
147
|
-
};
|
|
148
|
-
|
|
149
|
-
struct FibonacciResult {
|
|
150
|
-
sequence<int32> sequence;
|
|
151
|
-
};
|
|
152
|
-
|
|
153
|
-
struct FibonacciFeedback {
|
|
154
|
-
sequence<int32> partial_sequence;
|
|
155
|
-
};
|
|
156
|
-
};
|
|
157
|
-
};
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
Generates separate message files for goal, result, and feedback components.
|
|
161
|
-
|
|
162
|
-
## Type Mappings
|
|
163
|
-
|
|
164
|
-
### Basic Type Mappings
|
|
165
|
-
|
|
166
|
-
| IDL Type | ROS2 Type |
|
|
167
|
-
| ---------------- | ---------- |
|
|
168
|
-
| `boolean` | `bool` |
|
|
169
|
-
| `octet` | `uint8` |
|
|
170
|
-
| `int8` | `int8` |
|
|
171
|
-
| `uint8` | `uint8` |
|
|
172
|
-
| `int16` | `int16` |
|
|
173
|
-
| `uint16` | `uint16` |
|
|
174
|
-
| `int32` | `int32` |
|
|
175
|
-
| `uint32` | `uint32` |
|
|
176
|
-
| `int64` | `int64` |
|
|
177
|
-
| `uint64` | `uint64` |
|
|
178
|
-
| `float` | `float32` |
|
|
179
|
-
| `double` | `float64` |
|
|
180
|
-
| `string` | `string` |
|
|
181
|
-
| `wstring` | `wstring` |
|
|
182
|
-
| `sequence<T>` | `T[]` |
|
|
183
|
-
| `T[N]` | `T[N]` |
|
|
184
|
-
| `pkg::msg::Type` | `pkg/Type` |
|
|
185
|
-
|
|
186
|
-
### Typedef Support
|
|
187
|
-
|
|
188
|
-
The tool supports both simple and array typedefs:
|
|
189
|
-
|
|
190
|
-
- **Simple typedef**: `typedef double MyDouble;` → Maps `MyDouble` to `float64`
|
|
191
|
-
- **Array typedef**: `typedef double MyArray[9];` → Maps `MyArray` to `float64[9]`
|
|
192
|
-
- **Namespaced typedef**: `typedef std_msgs::msg::Header HeaderType;` → Maps `HeaderType` to `std_msgs/Header`
|
|
193
|
-
|
|
194
|
-
## Output Structure
|
|
195
|
-
|
|
196
|
-
The tool creates the following directory structure:
|
|
197
|
-
|
|
198
|
-
```
|
|
199
|
-
<root>/<output>/
|
|
200
|
-
├── msg/ # Generated .msg files
|
|
201
|
-
├── srv/ # Generated .srv files
|
|
202
|
-
└── action/ # Generated .action files
|
|
203
|
-
```
|
|
204
|
-
|
|
205
|
-
### ROS2 Workspace Integration
|
|
206
|
-
|
|
207
|
-
For proper ROS2 workspace integration, you can use the parameters to match the expected structure:
|
|
208
|
-
|
|
209
|
-
```bash
|
|
210
|
-
# Generate files for a ROS2 package in a workspace
|
|
211
|
-
python3 idl_convertor.py MyMessage.idl \
|
|
212
|
-
-r ~/ros2_ws/src \
|
|
213
|
-
-o my_package_name \
|
|
214
|
-
-p my_package_name
|
|
215
|
-
|
|
216
|
-
# This creates:
|
|
217
|
-
# ~/ros2_ws/src/my_package_name/msg/MyMessage.msg
|
|
218
|
-
# ~/ros2_ws/src/my_package_name/srv/MyService.srv
|
|
219
|
-
# ~/ros2_ws/src/my_package_name/action/MyAction.action
|
|
220
|
-
```
|
|
221
|
-
|
|
222
|
-
The generated files will be compatible with ROS2 build tools like `colcon build`.
|
|
223
|
-
|
|
224
|
-
## Important Notes
|
|
225
|
-
|
|
226
|
-
### DDS @key Annotation Handling
|
|
227
|
-
|
|
228
|
-
The tool automatically detects and skips IDL files that contain:
|
|
229
|
-
|
|
230
|
-
- Direct `@key` annotations (e.g., `@key string identifier;`)
|
|
231
|
-
- References to types that use `@key` annotations (e.g., `KeyedString`, `KeyedLong`)
|
|
232
|
-
|
|
233
|
-
This is because `@key` annotations are DDS-specific features that are not supported in ROS2 .msg files. When such files are encountered, the tool will print a warning and skip processing:
|
|
234
|
-
|
|
235
|
-
```
|
|
236
|
-
Warning: Skipping MyFile.idl - contains @key annotations which are not supported in ROS2 .msg files
|
|
237
|
-
```
|
|
238
|
-
|
|
239
|
-
or
|
|
240
|
-
|
|
241
|
-
```
|
|
242
|
-
Warning: Skipping MyFile.idl - references keyed types which are not supported in ROS2 .msg files
|
|
243
|
-
```
|
|
244
|
-
|
|
245
|
-
## Implementation Details
|
|
246
|
-
|
|
247
|
-
### Classes
|
|
248
|
-
|
|
249
|
-
- **`IdlParser`**: Parses IDL files and extracts interface definitions
|
|
250
|
-
- **`RosInterfaceGenerator`**: Generates ROS2 interface files from parsed data
|
|
251
|
-
- **`IdlField`**: Represents a field in an IDL structure (with support for comments and default values)
|
|
252
|
-
- **`IdlConstant`**: Represents a constant definition in an IDL structure
|
|
253
|
-
- **`IdlStructure`**: Represents an IDL structure (message, service part, etc.)
|
|
254
|
-
- **`IdlInterface`**: Represents a complete IDL interface definition
|
|
255
|
-
|
|
256
|
-
### Key Features
|
|
257
|
-
|
|
258
|
-
- **Robust Parsing**: Handles comments, nested modules, typedefs, and complex type definitions
|
|
259
|
-
- **Key Annotation Detection**: Automatically detects and skips files with `@key` annotations
|
|
260
|
-
- **Comment Preservation**: Extracts comments from `@verbatim` blocks and associates them with fields
|
|
261
|
-
- **Default Value Support**: Processes `@default` annotations and formats them for ROS2
|
|
262
|
-
- **Error Handling**: Graceful error handling with informative messages
|
|
263
|
-
- **Extensible**: Easy to extend for additional IDL features or output formats
|
|
264
|
-
|
|
265
|
-
## Testing
|
|
266
|
-
|
|
267
|
-
The tool has been tested with:
|
|
268
|
-
|
|
269
|
-
- ✅ Basic message types (JointState)
|
|
270
|
-
- ✅ Service definitions (SetCameraInfo) - generates proper .srv files
|
|
271
|
-
- ✅ Action definitions (Fibonacci) - generates proper .action files
|
|
272
|
-
- ✅ Array and sequence types
|
|
273
|
-
- ✅ Namespaced types
|
|
274
|
-
- ✅ Typedef declarations (simple and array types)
|
|
275
|
-
- ✅ Constants and default values with `@default` annotations
|
|
276
|
-
- ✅ Comment preservation from `@verbatim` blocks
|
|
277
|
-
- ✅ `@key` annotation detection and file skipping
|
|
278
|
-
- ✅ Command line interface with all options
|
|
279
|
-
- ✅ Request/Response combination for services
|
|
280
|
-
- ✅ Goal/Result/Feedback combination for actions
|
|
281
|
-
- ✅ Field order preservation from IDL to generated files
|
|
282
|
-
|
|
283
|
-
## Future Enhancements
|
|
284
|
-
|
|
285
|
-
- [ ] Support for nested structures and complex type inheritance
|
|
286
|
-
- [ ] Support for enums and unions
|
|
287
|
-
- [ ] Support for IDL annotations beyond `@verbatim`, `@default`, and `@key`
|
|
288
|
-
- [ ] Validation of generated files against ROS2 interface specifications
|
|
289
|
-
- [ ] Support for composition and inheritance patterns
|
|
290
|
-
- [ ] Batch processing of multiple IDL files
|
|
291
|
-
- [ ] Integration with ROS2 build tools (ament, colcon)
|
|
292
|
-
|
|
293
|
-
## Requirements
|
|
294
|
-
|
|
295
|
-
- Python 3.6+
|
|
296
|
-
- No external dependencies (uses only standard library)
|
|
297
|
-
|
|
298
|
-
This tool provides a robust solution for converting ROS2 IDL files to standard ROS2 interface formats, making it easier to work with interface definitions across different ROS2 tools and languages.
|