Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
156 changes: 58 additions & 98 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

**rclnodejs** is a Node.js client library for [ROS 2](https://www.ros.org/) that provides comprehensive JavaScript and TypeScript APIs for developing ROS 2 solutions.

**Key features:** Topics, Services, Actions, Parameters, Lifecycle Nodes, TypeScript support, RxJS Observables, Electron integration, and prebuilt binaries for Linux x64/arm64.
**Key features:** Topics, Services, Actions, Parameters, Lifecycle Nodes, TypeScript support, RxJS Observables, Electron integration, browser ↔ ROS 2 WebSocket bridge (rosocket), and prebuilt binaries for Linux x64/arm64.

```javascript
const rclnodejs = require('rclnodejs');
Expand All @@ -32,18 +32,15 @@ This example assumes your ROS 2 environment is already sourced.
- Get started:
[Installation](#installation), [Quick Start](#quick-start), [Tutorials](./tutorials/)
- Reference:
[API Documentation](#api-documentation), [Using TypeScript](#using-rclnodejs-with-typescript), [ROS 2 Interface Message Generation](#ros-2-interface-message-generation)
[API Documentation](https://robotwebtools.github.io/rclnodejs/docs/index.html), [Using TypeScript](#using-rclnodejs-with-typescript), [ROS 2 Interface Message Generation](#ros-2-interface-message-generation)
- Features and examples:
[rclnodejs-cli](#rclnodejs-cli), [Electron-based Visualization](#electron-based-visualization), [Observable Subscriptions](#observable-subscriptions), [rosocket](#rosocket--ros-2-in-the-browser-no-library-required), [Performance Benchmarks](#performance-benchmarks)
[rosocket](#rosocket--browser--ros-2-bridge), [Observable Subscriptions](#observable-subscriptions), [Electron-based Visualization](#electron-based-visualization), [Performance Benchmarks](#performance-benchmarks), [rclnodejs-cli](#rclnodejs-cli)
- Project docs:
[Efficient Usage Tips](./docs/EFFICIENCY.md), [FAQ and Known Issues](./docs/FAQ.md), [Building from Scratch](./docs/BUILDING.md), [Contributing](./docs/CONTRIBUTING.md)

## Installation

Choose the path that matches how you plan to use rclnodejs:

- Install from npm: add rclnodejs to your own application.
- Quick Start: run the examples from this repository checkout.
Most users only need [Install from npm](#install-from-npm) below. If you have cloned this repository and want to run the bundled examples, see [Quick Start](#quick-start) instead.

### Prerequisites

Expand All @@ -68,23 +65,19 @@ After installation, use the example at the top of this README as a minimal publi

### Install from GitHub

Use this path only if you need a branch or commit that is not yet published to npm.

GitHub installs normally build from source. The published npm package includes prebuilt binaries for supported Linux targets, but this repository does not track those prebuilt artifacts.
Use this path only if you need a branch or commit not yet published to npm. GitHub installs build from source.

```bash
npm install RobotWebTools/rclnodejs#<branch>
```

Or add `"rclnodejs":"RobotWebTools/rclnodejs#<branch>"` to your `package.json` dependency section.

> **Docker:** For containerized development, see the included [Dockerfile](./Dockerfile) for building and testing with different ROS distributions and Node.js versions.

See the [features](./docs/FEATURES.md) and try the [examples](https://github.com/RobotWebTools/rclnodejs/tree/develop/example) to get started.

### Prebuilt Binaries

rclnodejs ships with prebuilt native binaries for common Linux configurations since `v1.5.2`, eliminating the need for compilation during installation. This applies to supported Linux environments when installing the published npm package.
rclnodejs ships with prebuilt native binaries for common Linux configurations, so most installs skip compilation.

**Supported Platforms:**

Expand All @@ -94,11 +87,7 @@ rclnodejs ships with prebuilt native binaries for common Linux configurations si
- **Architectures:** x64, arm64
- **Node.js:** >= 20.20.2 (N-API compatible)

Installations outside this prebuilt matrix automatically fall back to building from source.

**Force Building from Source:**

If you need to build from source even when a prebuilt binary is available, set the environment variable:
Installations outside this matrix automatically fall back to building from source. To force a source build even when a prebuilt binary is available:

```bash
export RCLNODEJS_FORCE_BUILD=1
Expand All @@ -107,9 +96,7 @@ npm install rclnodejs

## Quick Start

Use these steps if you are working from this repository checkout and want to run one of the included examples.

These steps assume the [installation prerequisites](#prerequisites) are already satisfied and your ROS 2 environment has been sourced.
From a clone of this repository, after sourcing your ROS 2 environment:

1. Install the repository dependencies from the project root.

Expand All @@ -123,32 +110,39 @@ npm install
node example/topics/publisher/publisher-example.js
```

You should see messages being published once per second.
More runnable examples in [example/](https://github.com/RobotWebTools/rclnodejs/tree/develop/example) and step-by-step guides in [tutorials/](./tutorials/).

If you want to build an application instead of running the repository examples, install rclnodejs into your own project with [Install from npm](#install-from-npm) and start from the sample code near the top of this README.
## ROS 2 Interface Message Generation

Explore more runnable examples in [example/](https://github.com/RobotWebTools/rclnodejs/tree/develop/example) and step-by-step guides in [tutorials/](./tutorials/).
rclnodejs auto-generates JavaScript bindings and TypeScript declarations for every ROS 2 `.msg`, `.srv`, and `.action` interface available in your sourced ROS 2 environment. This happens during `npm install`, so in most projects you do not need to run anything by hand.

## rclnodejs-cli
Use the generated types directly:

```javascript
import * as rclnodejs from 'rclnodejs';
let stringMsgObject = rclnodejs.createMessageObject('std_msgs/msg/String');
stringMsgObject.data = 'hello world';
```

[rclnodejs-cli](https://github.com/RobotWebTools/rclnodejs-cli/) is a separate companion project that provides command-line tooling for working with rclnodejs-based ROS 2 applications. It is particularly useful for creating ROS 2 Node.js packages and working with launch files for multi-node orchestration.
### Re-running message generation

See the rclnodejs-cli repository for installation instructions and the current command set.
If you install additional ROS packages **after** rclnodejs was installed, re-run the generator from your project so the new interfaces are picked up:

## API Documentation
```bash
npx generate-ros-messages
```

API documentation is available [online](https://robotwebtools.github.io/rclnodejs/docs/index.html). To generate it locally from this repository checkout, run `npm run docs`.
Generated files are written to `<your-project>/node_modules/rclnodejs/generated/`.

## Electron-based Visualization
### IDL Message Generation

Create rich, interactive desktop applications using Electron and web technologies like Three.js. Demos leverage **Electron Forge** for easy packaging on Windows, macOS, and Linux.
In addition to the standard ROS 2 message generation (`.msg`, `.srv`, `.action`), rclnodejs can also generate JavaScript message files directly from IDL (Interface Definition Language) files. This is useful for custom IDL files or when you need finer control over the generation process.

| Demo | Description | Screenshot |
| :-----------------------------------------------: | :-----------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------: |
| **🐢 [turtle_tf2](./demo/electron/turtle_tf2)** | Real-time coordinate frame visualization with turtle control. Features TF2 transforms, keyboard control, and dynamic frame updates. | ![turtle_tf2](./demo/electron/turtle_tf2/turtle-tf2-demo.png) |
| **🦾 [manipulator](./demo/electron/manipulator)** | Interactive two-joint robotic arm simulation. Features 3D joint visualization, manual/automatic control, and visual movement markers. | ![manipulator](./demo/electron/manipulator/manipulator-demo.png) |
To generate messages from IDL files:

Explore more examples in [demo/electron](https://github.com/RobotWebTools/rclnodejs/tree/develop/demo/electron).
```bash
npm run generate-messages-idl
```

## Using rclnodejs with TypeScript

Expand All @@ -164,46 +158,11 @@ TypeScript declaration files are included in the package and exposed through the
}
```

TypeScript example:
Then `import * as rclnodejs from 'rclnodejs'` works the same as the JavaScript example at the top of this README. See [TypeScript demos](https://github.com/RobotWebTools/rclnodejs/tree/develop/demo/typescript) for more.

```typescript
import * as rclnodejs from 'rclnodejs';
rclnodejs.init().then(() => {
const node = new rclnodejs.Node('publisher_example_node');
const publisher = node.createPublisher('std_msgs/msg/String', 'topic');
publisher.publish(`Hello ROS 2 from rclnodejs`);
node.spin();
});
```

See [TypeScript demos](https://github.com/RobotWebTools/rclnodejs/tree/develop/demo/typescript) for more examples.

## Observable Subscriptions
## rosocket — Browser ↔ ROS 2 bridge

rclnodejs supports [RxJS](https://rxjs.dev/) Observable subscriptions for reactive programming with ROS 2 messages. Use operators like `throttleTime()`, `debounceTime()`, `map()`, and `combineLatest()` to build declarative message processing pipelines.

```javascript
const { throttleTime, map } = require('rxjs');

const obsSub = node.createObservableSubscription(
'sensor_msgs/msg/LaserScan',
'/scan'
);
obsSub.observable
.pipe(
throttleTime(200),
map((msg) => msg.ranges)
)
.subscribe((ranges) => console.log('Ranges:', ranges.length));
```

See the [Observable Subscriptions Tutorial](./tutorials/observable-subscriptions.md) for more details.

## rosocket — ROS 2 in the browser, no library required

> A tiny WebSocket gateway to ROS 2 — built into `rclnodejs`.

> **Availability:** new in `2.0.0-beta.0`.
> A tiny WebSocket gateway to ROS 2 — built into `rclnodejs`. _New in `2.0.0-beta.0`._

**rosocket** exposes ROS 2 topics/services as plain WebSocket URLs — a
**lightweight** alternative to the rosbridge + roslibjs stack. Zero browser
Expand All @@ -222,39 +181,36 @@ ws.onopen = () => ws.send(JSON.stringify({ data: 'hi' }));

See [rosocket/README.md](./rosocket/README.md) for the URL scheme, service calls, and the programmatic `startRosocket()` API.

## ROS 2 Interface Message Generation

ROS client libraries convert IDL message descriptions into target language source code. rclnodejs provides the `generate-ros-messages` script to generate JavaScript message interface files and TypeScript declarations.
## Observable Subscriptions

**Example usage:**
rclnodejs supports [RxJS](https://rxjs.dev/) Observable subscriptions for reactive programming with ROS 2 messages. Use operators like `throttleTime()`, `debounceTime()`, `map()`, and `combineLatest()` to build declarative message processing pipelines.

```javascript
import * as rclnodejs from 'rclnodejs';
let stringMsgObject = rclnodejs.createMessageObject('std_msgs/msg/String');
stringMsgObject.data = 'hello world';
```

### Running Message Generation

Run the message generation script in your project when new ROS packages are installed:
const { throttleTime, map } = require('rxjs');

```bash
npx generate-ros-messages
const obsSub = node.createObservableSubscription(
'sensor_msgs/msg/LaserScan',
'/scan'
);
obsSub.observable
.pipe(
throttleTime(200),
map((msg) => msg.ranges)
)
.subscribe((ranges) => console.log('Ranges:', ranges.length));
```

Generated files are located at `<yourproject>/node_modules/rclnodejs/generated/`.

> **Note:** This step is not needed for `rclnodejs > 1.5.0` because bundled interfaces are generated during installation. Rerun this command only after adding new ROS packages to your environment.
See the [Observable Subscriptions Tutorial](./tutorials/observable-subscriptions.md) for more details.

### IDL Message Generation
## Electron-based Visualization

In addition to the standard ROS2 message generation (`.msg`, `.srv`, and `.action`), rclnodejs provides advanced support for generating JavaScript message files directly from IDL (Interface Definition Language) files. This feature is particularly useful when working with custom IDL files or when you need more control over the message generation process.
Build interactive desktop ROS 2 apps with Electron + Three.js, packaged for Windows/macOS/Linux via **Electron Forge**. Featured demo: 🦾 **[manipulator](./demo/electron/manipulator)** — a two-joint arm with manual/automatic control.

To generate messages from IDL files, use the `generate-messages-idl` npm script:
<p align="left">
<a href="./demo/electron/manipulator"><img src="./demo/electron/manipulator/manipulator-demo.png" alt="manipulator demo" width="320"></a>
</p>

```bash
npm run generate-messages-idl
```
More in [demo/electron](https://github.com/RobotWebTools/rclnodejs/tree/develop/demo/electron).

## Performance Benchmarks

Expand All @@ -266,7 +222,11 @@ Benchmark results for 1000 iterations with 1024 KB messages (Ubuntu 24.04 WSL2,
| **rclnodejs** (Node.js) | 744 | 927 |
| **rclpy** (Python) | 1,618 | 15,380 |

These numbers are workload- and environment-specific. See [benchmark/README.md](./benchmark/README.md) for the full setup and methodology.
See [benchmark/README.md](./benchmark/README.md) for the full setup and methodology.

## rclnodejs-cli

[rclnodejs-cli](https://github.com/RobotWebTools/rclnodejs-cli/) is a companion project providing command-line tooling for scaffolding rclnodejs application skeletons and working with launch files for multi-node orchestration.

## Contributing

Expand Down
39 changes: 20 additions & 19 deletions scripts/npmjs-readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,9 @@ To install from GitHub instead of npm, run:
npm install RobotWebTools/rclnodejs#<branch>
```

Or add `"rclnodejs":"RobotWebTools/rclnodejs#<branch>"` to your `package.json` dependencies.

### Prebuilt Binaries

rclnodejs ships with prebuilt native binaries for common Linux configurations since `v1.5.2`, eliminating the need for compilation during installation. This applies to supported Linux environments when installing the published npm package.
rclnodejs ships with prebuilt native binaries for common Linux configurations, so most installs skip compilation.

**Supported Platforms:**

Expand All @@ -55,9 +53,7 @@ rclnodejs ships with prebuilt native binaries for common Linux configurations si
- **Architectures:** x64, arm64
- **Node.js:** >= 20.20.2 (N-API compatible)

Installations outside this prebuilt matrix automatically fall back to building from source.

**Force Building from Source:**
Installations outside this matrix automatically fall back to building from source. To force a source build even when a prebuilt binary is available:

```bash
export RCLNODEJS_FORCE_BUILD=1
Expand All @@ -70,22 +66,20 @@ npm install rclnodejs
- Tutorials: [tutorials/](https://github.com/RobotWebTools/rclnodejs/tree/develop/tutorials)
- JavaScript examples: [example/](https://github.com/RobotWebTools/rclnodejs/tree/develop/example)
- TypeScript demos: [demo/typescript/](https://github.com/RobotWebTools/rclnodejs/tree/develop/demo/typescript)
- WebSocket bridge demo (rosocket): [demo/rosocket/](https://github.com/RobotWebTools/rclnodejs/tree/develop/demo/rosocket)
- Electron demos: [demo/electron/](https://github.com/RobotWebTools/rclnodejs/tree/develop/demo/electron)
- WebSocket bridge demo: [demo/rosocket/](https://github.com/RobotWebTools/rclnodejs/tree/develop/demo/rosocket)
- Companion CLI: [rclnodejs-cli](https://github.com/RobotWebTools/rclnodejs-cli/)

## Message Generation

rclnodejs generates JavaScript message interfaces and TypeScript declarations during installation for `rclnodejs > 1.5.0`. If you install additional ROS packages later, rerun the generator in your project:
rclnodejs auto-generates JavaScript message interfaces and TypeScript declarations during `npm install`, so in most projects you do not need to run anything by hand. If you install additional ROS packages **after** rclnodejs was installed, re-run the generator from your project so the new interfaces are picked up:

```bash
npx generate-ros-messages
```

Generated files are written to `<your-project>/node_modules/rclnodejs/generated/`.

This step is only needed after adding ROS packages that were not present when rclnodejs was installed.

## Using rclnodejs with TypeScript

TypeScript declaration files are included in the package. In most projects, configuring your `tsconfig.json` is sufficient:
Expand All @@ -100,17 +94,24 @@ TypeScript declaration files are included in the package. In most projects, conf
}
```

```typescript
import * as rclnodejs from 'rclnodejs';
Then `import * as rclnodejs from 'rclnodejs'` works the same as the JavaScript example at the top of this README.

rclnodejs.init().then(() => {
const node = new rclnodejs.Node('publisher_example_node');
const publisher = node.createPublisher('std_msgs/msg/String', 'topic');
publisher.publish(`Hello ROS 2 from rclnodejs`);
node.spin();
});
## rosocket — Browser ↔ ROS 2 bridge

A tiny WebSocket gateway to ROS 2, built into `rclnodejs`. Exposes ROS 2 topics and services as plain WebSocket URLs — a lightweight alternative to the rosbridge + roslibjs stack. Browsers use only built-in `WebSocket` + `JSON`; no JavaScript library required.

```bash
npx rosocket --port 9000 --topic /chatter:std_msgs/msg/String
```

```js
const ws = new WebSocket('ws://host:9000/topic/chatter');
ws.onmessage = (e) => console.log(JSON.parse(e.data).data);
ws.onopen = () => ws.send(JSON.stringify({ data: 'hi' }));
```

See the [rosocket guide](https://github.com/RobotWebTools/rclnodejs/tree/develop/rosocket) for the URL scheme, service calls, and the programmatic `startRosocket()` API.

## License

Apache License Version 2.0
Apache License 2.0
Loading