rclnodejs

repository·develop·Indexed 19 days ago

https://github.com/robotwebtools/rclnodejs

A Node.js client library for ROS 2 (version 2.2.0-beta.0) providing JavaScript and TypeScript APIs. It enables the creation of ROS 2 nodes, services, and actions, with specialized support for web integration and Electron-based desktop applications. The library includes various demos, such as a car control interface and a 3D two-joint manipulator simulation using Three.js, and provides performance benchmarks comparing topic and service performance against rclcpp and rclpy.

Tokens
110K
Snippets
306
Records
454
Agent score
63%

What's inside rclnodejs

  1. Explore rclnodejs tutorials by topic

    develop

    The rclnodejs tutorials are categorized into several functional areas to help you master different aspects of ROS 2 development:

    Fundamentals

    • ROS 2 Basic Concepts: Covers Topics and Services.

    Node Management

    • Lifecycle Nodes: Managing nodes with state machines for controlled startup, shutdown, and error handling.
    • Parameter Service: Dynamic configuration management, including parameter declaration, validation, and runtime updates.

    Advanced Communication

    • ROS 2 Actions: Implementing long-running, cancellable tasks with progress feedback.
    • Service Introspection: Debugging and monitoring service calls and responses.
    • Content Filtering Subscription: Using SQL-like expressions at the DDS middleware level to reduce network traffic.
    • Observable Subscriptions with RxJS: Using RxJS Observables and operators (e.g., throttleTime(), combineLatest()) for reactive message processing.
    • rclnodejs/web (Browser SDK): Connecting to ROS 2 from a web application.

    Introspection & Debugging

    • Type Description Service: Querying message and service type definitions and field descriptions at runtime.
  2. ROS 2 Topics Examples Overview

    develop

    This section provides various implementation patterns for ROS 2 Topics using rclnodejs. Examples cover different ways to publish and subscribe to data, including basic implementations, content filtering, QoS configurations, and raw message handling.

    Key Implementation Notes

    • Initialization: All examples follow the standard rclnodejs initialization pattern.
    • Execution: Most examples are designed to run continuously until the process is terminated (e.g., via Ctrl+C).
    • Content Filtering: Requires ROS 2 Humble or later.
    • Raw Messages: When using raw message examples, ensure that the message types match exactly between the publisher and the subscriber.
    • Service Monitoring: While service event monitoring is compatible with any service, the service must be active for monitoring to function.
  3. What is the Type Description Service?

    develop

    The Type Description Service is an automatic introspection service in ROS 2 that provides detailed information about message and service types used by a node. It allows for the discovery of type definitions (including nested types and dependencies), retrieval of type source code, and understanding of message structures. This is useful for building dynamic debugging tools or web-based interfaces that need to understand ROS 2 data structures at runtime.

    Each node automatically hosts this service at the following path: /<node_name>/get_type_description

  4. What is Service Introspection in rclnodejs?

    develop

    Service Introspection is a ROS 2 feature that automatically publishes detailed information about service calls (requests and responses) to a special event topic. This allows you to monitor service activity, debug interactions by inspecting actual data, and analyze system performance without modifying your existing client or service code.

    When introspection is enabled, ROS 2 creates a special event topic following this pattern: /your_service_name/_service_event

  5. What is Content Filtering and how does it work?

    develop

    Content filtering enables server-side message filtering at the DDS middleware level. Instead of receiving all messages and filtering them in your JavaScript callback, the DDS middleware evaluates SQL-like expressions and only delivers messages that match the criteria.

    Benefits:

    • Reduces network bandwidth: Messages are filtered before transmission.
    • Improves performance: Reduces CPU overhead by processing only relevant messages.

    Mental Model: Think of it as a database query for your ROS 2 topics. The middleware acts as the database engine, and your subscription acts as the query, ensuring only the 'rows' (messages) you care about are sent over the wire.

  6. How ROS 2 Services work in rclnodejs

    develop

    ROS 2 services follow a request-response communication pattern. This is distinct from the publish-subscribe pattern used by topics.

    When to use services:

    • Remote procedure calls (RPC).
    • Getting or setting configuration parameters.
    • Triggering actions that require a confirmation/response.
    • Any communication where the sender requires feedback on the operation's success or result.
  7. What are ROS 2 Actions?

    develop

    ROS 2 Actions are a communication pattern designed for long-running, preemptable tasks that provide periodic feedback. Unlike simple request-response services, actions allow clients to:

    • 📤 Send goals to request task execution
    • 📊 Receive feedback during task execution
    • 🎯 Get results when tasks complete
    • Cancel goals before completion

    Actions are built on top of topics and services, providing a higher-level abstraction for complex interactions.

  8. How rosocket works: Concept and Comparison

    develop

    rosocket is a lightweight WebSocket gateway built into rclnodejs that allows a plain web browser to communicate with ROS 2 using only the built-in WebSocket and JSON APIs. Unlike the classic rosbridge_suite + roslibjs stack, rosocket requires no client-side JavaScript library and runs within the same Node.js process as your rclnodejs application.

    Key Differences

    Featurerosocket (rclnodejs)rosbridge_suite + roslibjs
    Server processSame Node.js process as your rclnodejs appSeparate Python ROS 2 node
    Client-side libraryNone (uses built-in WebSocket + JSON)roslibjs (must be bundled/loaded)
    Wire protocolResource-style URLs; frames are bare JSON ROS messagesCustom JSON envelope (e.g., op: "publish")
    Type discoveryURL ?type= query or server-side defaultsAdvertised at runtime via envelope ops
    FeaturesPub/Sub, ServicesPub/Sub, Services, Actions, TF, Parameters, etc.

    When to use rosocket:

    • When you want zero browser dependencies.
    • When you want to avoid running an extra process.
    • When you want greppable URLs for reverse-proxy ACLs.

    When to use rclnodejs/web instead:

    • When you want a typed SDK (call/publish/subscribe).
    • When you need an allow-list for capabilities (web.json).
    • When you need HTTP transport fallback.
  9. Implement ROS2 Actions in TypeScript

    develop

    The demo demonstrates how to use rclnodejs.require() to load action constructors, which provides full type safety for goals, feedback, and results without manual type annotations.

    Loading an Action

    const Fibonacci = rclnodejs.require('test_msgs/action/Fibonacci');

    Action Server Implementation

    A server requires three main callbacks typed using typeof Fibonacci:

    1. Goal Callback: Validates and accepts/rejects goals. Returns rclnodejs.GoalResponse.
    2. Execute Callback: Performs the long-running task. Returns Promise<rclnodejs.ActionResult<typeof Fibonacci>>.
    3. Cancel Callback: Handles cancellation requests. Returns rclnodejs.CancelResponse.

    Action Client Implementation

    A client sends goals and listens for feedback:

    const goal = new Fibonacci.Goal();
    gol.order = 10;
    
    const goalHandle = await this.actionClient.sendGoal(goal, (feedback) => {
      // feedback is typed as rclnodejs.ActionFeedback<typeof Fibonacci>
      console.log(feedback.sequence);
    });
    // Loading the action class for type safety
    const Fibonacci = rclnodejs.require('test_msgs/action/Fibonacci');
    
    // Example Client Goal Creation
    const goal = new Fibonacci.Goal();
    gol.order = 10;
    
    // Sending the goal with a feedback callback
    const goalHandle = await this.actionClient.sendGoal(goal, (feedback) => {
      // feedback.sequence is automatically typed
      console.log(feedback.sequence);
    });
  10. How Services (Request/Response) work in rclnodejs

    develop

    Services implement a request/response communication pattern used for remote procedure calls (RPC).

    • Service Server: Provides a specific computation or service.
    • Service Client: Requests the service and waits for a response.
    • Synchronous: The client typically waits for the server's response.
    • One-to-one: Usually one server per service name, though multiple clients can connect.
    • Short-lived: Services should be used for tasks that return quickly.

    Services are best suited for occasional, on-demand tasks like configuration changes, triggering calibrations, or performing specific computations (e.g., path planning).

    const rclnodejs = require('rclnodejs');
    
    async function createServiceServer() {
      await rclnodejs.init();
      const node = rclnodejs.createNode('service_example_node');
    
      // Create a service that adds two integers
      const service = node.createService(
        'example_interfaces/srv/AddTwoInts',
        'add_two_ints',
        (request, response) => {
          console.log(`Request: ${request.a} + ${request.b}`);
    
          // Compute the result
          const result = response.template;
          result.sum = request.a + request.b;
    
          console.log(`Sending response: ${typeof result}`, result);
          response.send(result);
        }
      );
    
      console.log('Service server ready');
      rclnodejs.spin(node);
    }
    
    createServiceServer().catch(console.error);
  11. Achieve Type Safety in rclnodejs with TypeScript

    develop

    rclnodejs provides full typing for all ROS 2 messages, services, and actions, enabling compile-time validation and IntelliSense support. There are two ways to identify a type:

    1. String Name: Identify a type using its string identifier (e.g., 'std_msgs/msg/String').
    2. Class/Constructor: Use the class or constructor obtained via rclnodejs.require(...). Using this method allows TypeScript to automatically infer concrete message, service, or action types without requiring explicit manual annotations.
  12. How parameter addressing works

    develop

    Parameters are addressed using a hierarchical system following the pattern: /node_namespace/node_name:parameter_namespace.parameter_name.

    • Node namespace: Optional namespace for the node (e.g., /robot1/).
    • Node name: The name of the node containing the parameter.
    • Parameter namespace: Optional namespace within the parameter name (using . separator).
    • Parameter name: The actual parameter identifier.

    Examples:

    • Global parameter: /my_node:max_speed
    • Namespaced node parameter: /robot1/my_node:max_speed
    • Nested parameter namespace: /my_node:camera.fps
    • Fully qualified parameter: /robot1/sensors/camera_node:config.exposure.auto