Skip to content

Feature parity review: rclpy-inspired improvements for rclnodejs #1445

@minggangw

Description

@minggangw
# Feature Status Notes
1 Executor Framework Skipped Not needed in rclnodejs. Each Node already has its own background thread via ShadowNode/Executor. Multiple node.spin() calls work independently. Node.js is single-threaded so all JS callbacks are inherently serialized — callback groups are meaningless.
2 Callback Groups Skipped Depends on Executor Framework. Node.js single-threaded model means all callbacks are already mutually exclusive by design.
3 waitForMessage() Utility Implemented PR #1444. Creates a temporary subscription, resolves on first message, auto-cleans up. Uses TimeoutError for timeout rejection. Extracted to lib/wait_for_message.js.
4 Parameter Event Handler Implemented PR #1438. ParameterEventHandler class with per-parameter and event-level callbacks. Refactored ParameterWatcher to use it internally. All Copilot review comments addressed.
5 QoS Overriding via Parameters Implemented PR #1468. QoSOverridingOptions class and QoSPolicyKind enum. Declares read-only parameters (e.g. qos_overrides./topic.subscription.depth) for whitelisted QoS policies on createPublisher() / createSubscription(). Overridable at startup via --ros-args -p, launch files, or parameter files. Includes withDefaultPolicies() factory (history, depth, reliability), entity ID disambiguation, and optional validation callback. Matches rclpy's _declare_qos_parameters() behavior.
6 Better spin() API / spinUntilFutureComplete Dropped Implemented in PR #1442, then evaluated as syntactic sugar with minimal value. In rclnodejs spin() is non-blocking (unlike rclpy where it blocks), so spin/await/stop is already trivial. Decided to drop in favor of documenting the idiomatic pattern.
7 Signal Handler Guard Condition Skipped Not needed. Node.js delivers SIGINT via the libuv event loop to the main thread immediately. The existing process.on('SIGINT') + shutdownAll() mechanism already provides clean, immediate shutdown. The background rcl_wait() thread is woken via StopWaitingHandles(). A guard condition would add complexity without observable benefit.
8 Message Metadata (MessageInfo) Implemented PR #1440. Native rclTakeWithInfo binding, MessageInfo class, auto-detection via callback.length >= 2. TypeScript types updated. Copilot review comments addressed.
8 Pre/Post Set Parameter Callbacks Implemented PR #1470. addPreSetParametersCallback() / removePreSetParametersCallback() and addPostSetParametersCallback() / removePostSetParametersCallback() on Node. Pre callbacks run before validation and can transform the parameter list; post callbacks run after successful set for side effects. Both LIFO ordered. Matches rclpy's add_pre_set_parameters_callback / add_post_set_parameters_callback.
9 Timer autostart + TimerInfo callback support Implemented PR #1472. Latest timer update. Node.createTimer() now accepts { autostart?: boolean } while preserving existing call signatures. Timer callbacks receive TimerInfo when supported, exposing expectedCallTime and actualCallTime. Older distros emulate autostart: false via cancel/reset. Native createTimer also validates that the 4th argument is a boolean. Includes runtime and type test coverage.
10 ParameterEventHandler Node Filtering Implemented PR for #1473. configureNodesFilter(nodeNames?) on ParameterEventHandler. Filters /parameter_events subscription by node name using DDS content filters. Resolves relative names against handler node namespace. Validates fully qualified node paths via existing ROS validators. Normalizes repeated/trailing slashes. Includes runtime tests (absolute/relative/clear/invalid/slash-normalization) and tsd type coverage.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions