diff --git a/README.md b/README.md index f3ebf6fd..b2a6b400 100644 --- a/README.md +++ b/README.md @@ -97,7 +97,7 @@ API documentation is available [online](https://robotwebtools.github.io/rclnodej ## Electron-based Visualization -Create rich, interactive desktop applications using Electron and web technologies like Three.js. Build 3D visualizations, monitoring dashboards, and control interfaces that run on Windows, macOS, and Linux. +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. | Demo | Description | Screenshot | | :-----------------------------------------------: | :-----------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------: | diff --git a/electron_demo/car/README.md b/electron_demo/car/README.md index e198338b..4ffee875 100644 --- a/electron_demo/car/README.md +++ b/electron_demo/car/README.md @@ -79,6 +79,56 @@ npm run build npm start ``` +## 📦 Packaging for Distribution + +You can package the application into a standalone folder using **Electron Forge**. + +### 1. Build the Package + +Run the following command to create a distributable executable: + +```bash +npm run package +``` + +The output will be located in the `out/` directory. + +**Technical Note on ASAR:** We enable ASAR but configure it to **unpack** the `rclnodejs` module. `rclnodejs` (v1.8.1+) requires file system access to generated code and native bindings, so we use the `asar.unpack` configuration in `package.json` to keep `rclnodejs` files accessible on disk while packing the rest of the application. + +```json +"config": { + "forge": { + "packagerConfig": { + "asar": { + "unpack": "**/node_modules/rclnodejs/**" + } + } + } +} +``` + +### 2. Create Installers (Optional) + +To create a `.zip` file or other platform-specific installers (deb/rpm), run: + +```bash +npm run make +``` + +**Note**: Creating DEB/RPM installers requires system tools like `dpkg` and `fakeroot`. For ZIP files, you need `zip`. + +### 3. Running the Standalone Application + +Even as a standalone application, **ROS 2 must be installed and sourced on the target machine** because `rclnodejs` links dynamically to the ROS 2 shared libraries. + +```bash +# Source ROS2 environment +source /opt/ros//setup.bash + +# Run the packaged executable +./out/rclnodejs-electron-car-demo-linux-x64/rclnodejs-electron-car-demo +``` + ![demo screenshot](./car-control-electron.gif) ## 🎮 How to Use diff --git a/electron_demo/car/package.json b/electron_demo/car/package.json index a2c1f1db..29192f43 100644 --- a/electron_demo/car/package.json +++ b/electron_demo/car/package.json @@ -4,8 +4,10 @@ "description": "An Electron application demonstrating car control with joystick using rclnodejs", "main": "main.js", "scripts": { - "start": "electron .", - "rebuild": "electron-rebuild" + "start": "electron-forge start", + "rebuild": "electron-rebuild", + "package": "electron-forge package", + "make": "electron-forge make" }, "keywords": [ "Electron", @@ -17,10 +19,50 @@ ], "license": "Apache-2.0", "dependencies": { - "rclnodejs": "^1.0.0" + "rclnodejs": "^1.8.1" }, "devDependencies": { - "@electron/rebuild": "^3.6.0", - "electron": "^40.0.0" + "@electron-forge/cli": "^7.11.1", + "@electron-forge/maker-deb": "^7.11.1", + "@electron-forge/maker-rpm": "^7.11.1", + "@electron-forge/maker-squirrel": "^7.11.1", + "@electron-forge/maker-zip": "^7.11.1", + "@electron-forge/plugin-auto-unpack-natives": "^7.11.1", + "@electron-forge/plugin-fuses": "^7.11.1", + "@electron/rebuild": "^4.0.3", + "electron": "^40.1.0" + }, + "config": { + "forge": { + "packagerConfig": { + "asar": { + "unpack": "**/node_modules/rclnodejs/**" + } + }, + "makers": [ + { + "name": "@electron-forge/maker-squirrel", + "config": { + "name": "rclnodejs_car_demo" + } + }, + { + "name": "@electron-forge/maker-zip", + "platforms": [ + "darwin", + "linux" + ] + }, + { + "name": "@electron-forge/maker-deb", + "config": {} + }, + { + "name": "@electron-forge/maker-rpm", + "config": {} + } + ], + "plugins": [] + } } } diff --git a/electron_demo/manipulator/README.md b/electron_demo/manipulator/README.md index 63f4b860..c7109230 100644 --- a/electron_demo/manipulator/README.md +++ b/electron_demo/manipulator/README.md @@ -41,7 +41,9 @@ An interactive Electron application demonstrating a two-joint robotic manipulato ## 📜 Available Scripts -- **`npm start`** - Run demo (requires manual ROS2 environment setup) +- **`npm start`** - Launch the application in development mode +- **`npm run package`** - Package the application into a standalone executable folder +- **`npm run make`** - Create platform-specific installers (requires system tools like `zip`, `dpkg`) - **`npm run rebuild`** - Rebuild native modules after dependency changes ## 🚀 Quick Start @@ -156,6 +158,56 @@ ros2 topic hz /joint_states ros2 topic info /joint_states ``` +## 📦 Packaging for Distribution + +You can package the application into a standalone folder using **Electron Forge**. + +### 1. Build the Package + +Run the following command to create a distributable executable: + +```bash +npm run package +``` + +The output will be located in the `out/` directory, for example: `out/rclnodejs-manipulator-demo-linux-x64/`. + +**Technical Note on ASAR:** We enable ASAR but configure it to **unpack** the `rclnodejs` module. `rclnodejs` (v1.8.1+) requires file system access to generated code and native bindings, so we use the `asar.unpack` configuration in `package.json` to keep `rclnodejs` files accessible on disk while packing the rest of the application. + +```json +"config": { + "forge": { + "packagerConfig": { + "asar": { + "unpack": "**/node_modules/rclnodejs/**" + } + } + } +} +``` + +### 2. Create Installers (Optional) + +To create a `.zip` file for distribution, run: + +```bash +npm run make +``` + +**Note**: This will generate a ZIP archive containing the packaged application. + +### 3. Running the Standalone Application + +Even as a standalone application, **ROS 2 must be installed and sourced on the target machine** because `rclnodejs` links dynamically to the ROS 2 shared libraries. + +```bash +# Source ROS2 environment +source /opt/ros/humble/setup.bash + +# Run the packaged executable +./out/rclnodejs-manipulator-demo-linux-x64/rclnodejs-manipulator-demo +``` + ## 🏗️ Architecture ### Main Process (`main.js`) diff --git a/electron_demo/manipulator/index.html b/electron_demo/manipulator/index.html index 83e47a86..d1a27cf2 100644 --- a/electron_demo/manipulator/index.html +++ b/electron_demo/manipulator/index.html @@ -169,7 +169,6 @@
🎯 What to Look For:
- \ No newline at end of file diff --git a/electron_demo/manipulator/main.js b/electron_demo/manipulator/main.js index f3e29946..a0269e1a 100644 --- a/electron_demo/manipulator/main.js +++ b/electron_demo/manipulator/main.js @@ -13,6 +13,11 @@ const { app, BrowserWindow, ipcMain } = require('electron'); const rclnodejs = require('rclnodejs'); +// Fix for WebGL/GPU rendering issues on Linux environment +// Forces software rendering (SwiftShader) if hardware acceleration fails +app.commandLine.appendSwitch('ignore-gpu-blocklist'); +app.commandLine.appendSwitch('disable-gpu-sandbox'); + let mainWindow; let manipulatorNode; let jointStatePublisher; diff --git a/electron_demo/manipulator/package.json b/electron_demo/manipulator/package.json index 0b470c4d..f37c3079 100644 --- a/electron_demo/manipulator/package.json +++ b/electron_demo/manipulator/package.json @@ -4,8 +4,10 @@ "description": "Electron application demonstrating a two-joint manipulator visualization using rclnodejs and Three.js", "main": "main.js", "scripts": { - "start": "electron .", - "rebuild": "electron-rebuild" + "start": "electron-forge start", + "rebuild": "electron-rebuild", + "package": "electron-forge package", + "make": "electron-forge make" }, "keywords": [ "Electron", @@ -20,10 +22,43 @@ ], "license": "Apache-2.0", "dependencies": { - "rclnodejs": "^1.5.1" + "rclnodejs": "^1.8.1", + "three": "^0.182.0" }, "devDependencies": { - "@electron/rebuild": "^3.7.2", - "electron": "^40.0.0" + "@electron-forge/cli": "^7.11.1", + "@electron-forge/maker-deb": "^7.11.1", + "@electron-forge/maker-rpm": "^7.11.1", + "@electron-forge/maker-squirrel": "^7.11.1", + "@electron-forge/maker-zip": "^7.11.1", + "@electron-forge/plugin-auto-unpack-natives": "^7.11.1", + "@electron-forge/plugin-fuses": "^7.11.1", + "@electron/rebuild": "^4.0.3", + "electron": "^40.1.0" + }, + "config": { + "forge": { + "packagerConfig": { + "asar": { + "unpack": "**/node_modules/rclnodejs/**" + } + }, + "makers": [ + { + "name": "@electron-forge/maker-squirrel", + "config": { + "name": "rclnodejs_manipulator_demo" + } + }, + { + "name": "@electron-forge/maker-zip", + "platforms": [ + "darwin", + "linux" + ] + } + ], + "plugins": [] + } } } diff --git a/electron_demo/manipulator/renderer.js b/electron_demo/manipulator/renderer.js index d112ef46..fd4962c6 100644 --- a/electron_demo/manipulator/renderer.js +++ b/electron_demo/manipulator/renderer.js @@ -12,6 +12,7 @@ const { ipcRenderer } = require('electron'); const process = require('process'); +const THREE = require('three'); // Three.js scene components let scene, camera, renderer, controls; diff --git a/electron_demo/topics/README.md b/electron_demo/topics/README.md index 4882c078..6286b3e3 100644 --- a/electron_demo/topics/README.md +++ b/electron_demo/topics/README.md @@ -65,6 +65,56 @@ The demo window will open with: - **Message display area** showing received messages - **Counters** for published and received messages +## 📦 Packaging for Distribution + +You can package the application into a standalone folder using **Electron Forge**. + +### 1. Build the Package + +Run the following command to create a distributable executable: + +```bash +npm run package +``` + +The output will be located in the `out/` directory. + +**Technical Note on ASAR:** We enable ASAR but configure it to **unpack** the `rclnodejs` module. `rclnodejs` (v1.8.1+) requires file system access to generated code and native bindings, so we use the `asar.unpack` configuration in `package.json` to keep `rclnodejs` files accessible on disk while packing the rest of the application. + +```json +"config": { + "forge": { + "packagerConfig": { + "asar": { + "unpack": "**/node_modules/rclnodejs/**" + } + } + } +} +``` + +### 2. Create Installers (Optional) + +To create a `.zip` file or other platform-specific installers (deb/rpm), run: + +```bash +npm run make +``` + +**Note**: Creating DEB/RPM installers requires system tools like `dpkg` and `fakeroot`. For ZIP files, you need `zip`. + +### 3. Running the Standalone Application + +Even as a standalone application, **ROS 2 must be installed and sourced on the target machine** because `rclnodejs` links dynamically to the ROS 2 shared libraries. + +```bash +# Source ROS2 environment +source /opt/ros//setup.bash + +# Run the packaged executable +./out/rclnodejs-electron-demo-linux-x64/rclnodejs-electron-demo +``` + ## 📁 Project Structure - **`package.json`** - Project configuration and dependencies diff --git a/electron_demo/topics/package.json b/electron_demo/topics/package.json index 28c6b5c4..12a2c5ec 100644 --- a/electron_demo/topics/package.json +++ b/electron_demo/topics/package.json @@ -4,7 +4,10 @@ "description": "A minimal rclnodejs Electron application", "main": "main.js", "scripts": { - "start": "electron ." + "start": "electron-forge start", + "rebuild": "electron-rebuild", + "package": "electron-forge package", + "make": "electron-forge make" }, "keywords": [ "Electron", @@ -13,10 +16,50 @@ ], "license": "Apache", "dependencies": { - "rclnodejs": "^1.5.1" + "rclnodejs": "^1.8.1" }, "devDependencies": { - "@electron/rebuild": "^3.6.0", - "electron": "^40.0.0" + "@electron-forge/cli": "^7.11.1", + "@electron-forge/maker-deb": "^7.11.1", + "@electron-forge/maker-rpm": "^7.11.1", + "@electron-forge/maker-squirrel": "^7.11.1", + "@electron-forge/maker-zip": "^7.11.1", + "@electron-forge/plugin-auto-unpack-natives": "^7.11.1", + "@electron-forge/plugin-fuses": "^7.11.1", + "@electron/rebuild": "^4.0.3", + "electron": "^40.1.0" + }, + "config": { + "forge": { + "packagerConfig": { + "asar": { + "unpack": "**/node_modules/rclnodejs/**" + } + }, + "makers": [ + { + "name": "@electron-forge/maker-squirrel", + "config": { + "name": "rclnodejs_topics_demo" + } + }, + { + "name": "@electron-forge/maker-zip", + "platforms": [ + "darwin", + "linux" + ] + }, + { + "name": "@electron-forge/maker-deb", + "config": {} + }, + { + "name": "@electron-forge/maker-rpm", + "config": {} + } + ], + "plugins": [] + } } } diff --git a/electron_demo/turtle_tf2/README.md b/electron_demo/turtle_tf2/README.md index 89e404e1..99356838 100644 --- a/electron_demo/turtle_tf2/README.md +++ b/electron_demo/turtle_tf2/README.md @@ -151,6 +151,42 @@ npm start **⚠️ Important**: The dynamic frame (`carrot1_dynamic`) orbits around the static frame (`carrot1_static`) in a circular pattern with a 2-unit radius, regardless of turtle positions. +## 📦 Packaging for Distribution + +You can package the application into a standalone folder using **Electron Forge**. + +### 1. Build the Package + +Run the following command to create a distributable executable: + +```bash +npm run package +``` + +The output will be located in the `out/` directory. + +### 2. Create Installers (Optional) + +To create a `.zip` file or other platform-specific installers (deb/rpm), run: + +```bash +npm run make +``` + +**Note**: Creating DEB/RPM installers requires system tools like `dpkg` and `fakeroot`. For ZIP files, you need `zip`. + +### 3. Running the Standalone Application + +Even as a standalone application, **ROS 2 must be installed and sourced on the target machine** because `rclnodejs` links dynamically to the ROS 2 shared libraries. + +```bash +# Source ROS2 environment +source /opt/ros/$ROS_DISTRO/setup.bash + +# Run the packaged executable +./out/rclnodejs-turtle-tf2-demo-linux-x64/rclnodejs-turtle-tf2-demo +``` + ## Demo Components ### Main Process (main.js) diff --git a/electron_demo/turtle_tf2/package.json b/electron_demo/turtle_tf2/package.json index c57dc59d..cccf9c83 100644 --- a/electron_demo/turtle_tf2/package.json +++ b/electron_demo/turtle_tf2/package.json @@ -4,8 +4,10 @@ "description": "Electron application demonstrating turtle TF2 transformations using rclnodejs with 3D web visualization", "main": "main.js", "scripts": { - "start": "electron .", - "rebuild": "electron-rebuild" + "start": "electron-forge start", + "rebuild": "electron-rebuild", + "package": "electron-forge package", + "make": "electron-forge make" }, "keywords": [ "Electron", @@ -19,11 +21,51 @@ ], "license": "Apache-2.0", "dependencies": { - "rclnodejs": "^1.5.0", + "rclnodejs": "^1.8.1", "three": "^0.155.0" }, "devDependencies": { - "@electron/rebuild": "^3.7.2", - "electron": "^40.0.0" + "@electron-forge/cli": "^7.11.1", + "@electron-forge/maker-deb": "^7.11.1", + "@electron-forge/maker-rpm": "^7.11.1", + "@electron-forge/maker-squirrel": "^7.11.1", + "@electron-forge/maker-zip": "^7.11.1", + "@electron-forge/plugin-auto-unpack-natives": "^7.11.1", + "@electron-forge/plugin-fuses": "^7.11.1", + "@electron/rebuild": "^4.0.3", + "electron": "^40.1.0" + }, + "config": { + "forge": { + "packagerConfig": { + "asar": { + "unpack": "**/node_modules/rclnodejs/**" + } + }, + "makers": [ + { + "name": "@electron-forge/maker-squirrel", + "config": { + "name": "rclnodejs_turtle_demo" + } + }, + { + "name": "@electron-forge/maker-zip", + "platforms": [ + "darwin", + "linux" + ] + }, + { + "name": "@electron-forge/maker-deb", + "config": {} + }, + { + "name": "@electron-forge/maker-rpm", + "config": {} + } + ], + "plugins": [] + } } }