|
1 | | -# ROS2 Car Control Demo with Electron and rclnodejs |
| 1 | +# ROS 2 Car Control Demo (Electron + rclnodejs) |
2 | 2 |
|
3 | | -This demo showcases how to use **rclnodejs** with **Electron** to create an interactive car control application. The demo features a virtual joystick that publishes ROS2 velocity commands and a car visualization that responds to those commands in real-time. |
| 3 | +Interactive car-control app: a virtual joystick publishes `geometry_msgs/Twist` |
| 4 | +velocity commands on `/cmd_vel`, and a visualization subscribes and moves a car |
| 5 | +in real time. |
4 | 6 |
|
5 | | -## 🚗 Features |
6 | | - |
7 | | -### Joystick Control Panel |
8 | | - |
9 | | -- **Directional Controls**: Up/Down/Left/Right buttons for car movement |
10 | | -- **Stop Button**: Emergency stop functionality |
11 | | -- **Keyboard Support**: WASD and arrow keys for control |
12 | | -- **Real-time Status**: Display current command and velocity values |
13 | | - |
14 | | -### Car Visualization |
15 | | - |
16 | | -- **Real-time Movement**: Car moves and rotates based on received commands |
17 | | -- **Position Tracking**: Shows current position (North/South/East/West/Center) |
18 | | -- **Visual Feedback**: Color-coded movement indicators |
19 | | -- **Command Counter**: Tracks total number of commands received |
20 | | - |
21 | | -### ROS2 Integration |
22 | | - |
23 | | -- **Topic**: `cmd_vel` (geometry_msgs/Twist) |
24 | | -- **Publisher**: Sends velocity commands |
25 | | -- **Subscriber**: Receives and displays velocity commands |
26 | | -- **Node Name**: `car_control_node` |
27 | | - |
28 | | -## 🔧 Prerequisites |
29 | | - |
30 | | -Before running this demo, ensure you have: |
31 | | - |
32 | | -1. **ROS2 installed** (Humble, Jazzy, Kilted, Lyrical, or Rolling) |
33 | | -2. **Node.js** (version 20.20.2 or higher) |
34 | | -3. **rclnodejs built** and working |
| 7 | + |
35 | 8 |
|
36 | | -### ROS2 Setup |
| 9 | +## Features |
37 | 10 |
|
38 | | -```bash |
39 | | -# Source your ROS2 installation |
40 | | -source /opt/ros/<your-ros-distro>/setup.bash |
| 11 | +- Joystick plus WASD / arrow-key control with an emergency stop |
| 12 | +- Real-time car movement, position tracking, and command counter |
| 13 | +- ROS 2 node `car_control_node` publishing and subscribing on `cmd_vel` |
41 | 14 |
|
42 | | -# Verify ROS2 is working |
43 | | -ros2 topic list |
44 | | -``` |
| 15 | +## Prerequisites |
45 | 16 |
|
46 | | -### Build rclnodejs |
| 17 | +- ROS 2 (Humble, Jazzy, Kilted, Lyrical, or Rolling), sourced |
| 18 | +- Node.js >= 20.20.2 |
| 19 | +- Linux (prebuilt rclnodejs binaries are provided for Ubuntu) |
47 | 20 |
|
48 | | -From the main rclnodejs directory: |
| 21 | +## Install & Run |
49 | 22 |
|
50 | 23 | ```bash |
| 24 | +cd demo/electron/car |
51 | 25 | npm install |
52 | | -npm run build |
53 | | -``` |
54 | | - |
55 | | -## 🚀 Installation & Running |
56 | | - |
57 | | -1. **Navigate to the demo directory:** |
58 | | - |
59 | | - ```bash |
60 | | - cd electron_car_demo |
61 | | - ``` |
62 | | - |
63 | | -2. **Install dependencies:** |
64 | | - |
65 | | - ```bash |
66 | | - npm install |
67 | | - ``` |
68 | | - |
69 | | -3. **Native modules — no manual rebuild needed:** |
70 | | - |
71 | | - rclnodejs ships prebuilt binaries for Electron and selects the matching one at |
72 | | - runtime from `ROS_DISTRO` + Linux codename + architecture, so just make sure |
73 | | - ROS 2 is sourced (next step) before launching. Do not run `electron-rebuild` |
74 | | - against rclnodejs — it recompiles from source and bypasses the prebuilt binary. |
75 | | - The Forge `rebuildConfig` in `package.json` already excludes `rclnodejs` from |
76 | | - the automatic rebuild step. |
77 | | - |
78 | | -4. **Start the demo:** |
79 | | - ```bash |
80 | | - # Make sure ROS2 is sourced first |
81 | | - source /opt/ros/<your-ros-distro>/setup.bash |
82 | | - npm start |
83 | | - ``` |
84 | | - |
85 | | -## 📦 Packaging for Distribution |
86 | | - |
87 | | -You can package the application into a standalone folder using **Electron Forge**. |
88 | | - |
89 | | -### 1. Build the Package |
90 | | - |
91 | | -Run the following command to create a distributable executable: |
92 | | - |
93 | | -```bash |
94 | | -npm run package |
| 26 | +source /opt/ros/<distro>/setup.bash # required before launch |
| 27 | +npm start |
95 | 28 | ``` |
96 | 29 |
|
97 | | -The output will be located in the `out/` directory. |
| 30 | +rclnodejs ships prebuilt Electron binaries and selects the matching one at |
| 31 | +runtime from `ROS_DISTRO` + Linux codename + architecture, so no compilation is |
| 32 | +needed. Do not run `electron-rebuild` against rclnodejs — it rebuilds from |
| 33 | +source and bypasses the prebuilt binary (the Forge `rebuildConfig` in |
| 34 | +`package.json` already excludes `rclnodejs`). |
98 | 35 |
|
99 | | -**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. |
100 | | - |
101 | | -```json |
102 | | -"config": { |
103 | | - "forge": { |
104 | | - "packagerConfig": { |
105 | | - "asar": { |
106 | | - "unpack": "**/node_modules/rclnodejs/**" |
107 | | - } |
108 | | - } |
109 | | - } |
110 | | -} |
111 | | -``` |
| 36 | +## Controls |
112 | 37 |
|
113 | | -### 2. Create Installers (Optional) |
| 38 | +- Mouse: directional buttons (↑ ↓ ← →) and the red STOP button |
| 39 | +- Keyboard: W/S forward/back, A/D turn, Space or Esc to stop |
114 | 40 |
|
115 | | -To create a `.zip` file or other platform-specific installers (deb/rpm), run: |
116 | | - |
117 | | -```bash |
118 | | -npm run make |
119 | | -``` |
| 41 | +## Message Format & Mapping |
120 | 42 |
|
121 | | -**Note**: Creating DEB/RPM installers requires system tools like `dpkg` and `fakeroot`. For ZIP files, you need `zip`. |
| 43 | +`geometry_msgs/Twist` on `/cmd_vel`: |
122 | 44 |
|
123 | | -### 3. Running the Standalone Application |
| 45 | +| Command | linear.x | angular.z | |
| 46 | +| -------- | -------- | --------- | |
| 47 | +| Forward | +1.0 | 0.0 | |
| 48 | +| Backward | -1.0 | 0.0 | |
| 49 | +| Left | 0.0 | +1.0 | |
| 50 | +| Right | 0.0 | -1.0 | |
| 51 | +| Stop | 0.0 | 0.0 | |
124 | 52 |
|
125 | | -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. |
| 53 | +## Test from the CLI |
126 | 54 |
|
127 | 55 | ```bash |
128 | | -# Source ROS2 environment |
129 | | -source /opt/ros/<your-ros-distro>/setup.bash |
130 | | - |
131 | | -# Run the packaged executable |
132 | | -./out/rclnodejs-electron-car-demo-linux-x64/rclnodejs-electron-car-demo |
133 | | -``` |
134 | | - |
135 | | - |
136 | | - |
137 | | -## 🎮 How to Use |
138 | | - |
139 | | -### Control Methods |
140 | | - |
141 | | -#### Mouse Controls |
142 | | - |
143 | | -- Click the directional buttons (↑↓←→) on the joystick |
144 | | -- Click the red **STOP** button to halt movement |
145 | | - |
146 | | -#### Keyboard Controls |
147 | | - |
148 | | -- **W** or **↑**: Move forward |
149 | | -- **S** or **↓**: Move backward |
150 | | -- **A** or **←**: Turn left |
151 | | -- **D** or **→**: Turn right |
152 | | -- **Space** or **Esc**: Stop |
153 | | - |
154 | | -### Understanding the Interface |
155 | | - |
156 | | -#### Left Panel - Joystick Control |
157 | | - |
158 | | -- **Command**: Shows the current command being sent |
159 | | -- **Linear X**: Forward/backward velocity (m/s) |
160 | | -- **Angular Z**: Rotation velocity (rad/s) |
161 | | -- **Topic**: ROS2 topic name (`cmd_vel`) |
162 | | - |
163 | | -#### Right Panel - Car Visualization |
164 | | - |
165 | | -- **Received Commands**: Total count of commands received |
166 | | -- **Last Command**: Most recent command processed |
167 | | -- **Car Position**: Current position in the visualization area |
168 | | - |
169 | | -## 🔍 Technical Details |
170 | | - |
171 | | -### ROS2 Message Format |
172 | | - |
173 | | -The demo uses `geometry_msgs/Twist` messages with the following structure: |
174 | | - |
175 | | -```javascript |
176 | | -{ |
177 | | - linear: { |
178 | | - x: 1.0, // Forward/backward velocity (m/s) |
179 | | - y: 0.0, // Left/right velocity (typically 0 for cars) |
180 | | - z: 0.0 // Up/down velocity (typically 0 for ground vehicles) |
181 | | - }, |
182 | | - angular: { |
183 | | - x: 0.0, // Roll rate (typically 0 for cars) |
184 | | - y: 0.0, // Pitch rate (typically 0 for cars) |
185 | | - z: 1.0 // Yaw rate (turning left/right in rad/s) |
186 | | - } |
187 | | -} |
188 | | -``` |
189 | | - |
190 | | -### Command Mapping |
191 | | - |
192 | | -| Command | Linear X | Angular Z | Description | |
193 | | -| -------- | -------- | --------- | ---------------------- | |
194 | | -| Forward | +1.0 | 0.0 | Move forward at 1 m/s | |
195 | | -| Backward | -1.0 | 0.0 | Move backward at 1 m/s | |
196 | | -| Left | 0.0 | +1.0 | Turn left at 1 rad/s | |
197 | | -| Right | 0.0 | -1.0 | Turn right at 1 rad/s | |
198 | | -| Stop | 0.0 | 0.0 | Stop all movement | |
199 | | - |
200 | | -### Architecture |
201 | | - |
202 | | -``` |
203 | | -┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐ |
204 | | -│ Renderer │ │ Main Process │ │ ROS2 Network │ |
205 | | -│ (UI/Browser) │ │ (Node.js) │ │ │ |
206 | | -├─────────────────┤ ├──────────────────┤ ├─────────────────┤ |
207 | | -│ • Joystick UI │───▶│ • rclnodejs Node │───▶│ • cmd_vel Topic │ |
208 | | -│ • Car Display │◀───│ • Publisher │ │ • Other Nodes │ |
209 | | -│ • Status Panel │ │ • Subscriber │◀───│ • Robot/Sim │ |
210 | | -└─────────────────┘ └──────────────────┘ └─────────────────┘ |
211 | | -``` |
212 | | - |
213 | | -## 🧪 Testing with ROS2 Tools |
214 | | - |
215 | | -You can test the demo using standard ROS2 command-line tools: |
216 | | - |
217 | | -### Listen to Published Commands |
218 | | - |
219 | | -```bash |
220 | | -# In a new terminal (with ROS2 sourced) |
221 | 56 | ros2 topic echo /cmd_vel |
| 57 | +ros2 topic pub /cmd_vel geometry_msgs/Twist "{linear: {x: 1.0}, angular: {z: 0.0}}" |
222 | 58 | ``` |
223 | 59 |
|
224 | | -### Send Commands from Command Line |
225 | | - |
226 | | -```bash |
227 | | -# Send a forward command |
228 | | -ros2 topic pub /cmd_vel geometry_msgs/Twist "linear: {x: 1.0, y: 0.0, z: 0.0}, angular: {x: 0.0, y: 0.0, z: 0.0}" |
229 | | - |
230 | | -# Send a turn left command |
231 | | -ros2 topic pub /cmd_vel geometry_msgs/Twist "linear: {x: 0.0, y: 0.0, z: 0.0}, angular: {x: 0.0, y: 0.0, z: 1.0}" |
232 | | - |
233 | | -# Stop command |
234 | | -ros2 topic pub /cmd_vel geometry_msgs/Twist "linear: {x: 0.0, y: 0.0, z: 0.0}, angular: {x: 0.0, y: 0.0, z: 0.0}" |
235 | | -``` |
236 | | - |
237 | | -### Check Active Topics |
| 60 | +## Packaging |
238 | 61 |
|
239 | 62 | ```bash |
240 | | -ros2 topic list |
241 | | -ros2 topic info /cmd_vel |
242 | | -ros2 topic hz /cmd_vel |
| 63 | +npm run package # standalone app in out/ |
| 64 | +npm run make # zip / deb / rpm installers (needs zip, dpkg, fakeroot) |
243 | 65 | ``` |
244 | 66 |
|
245 | | -## 🤖 Integration with Real Robots |
246 | | - |
247 | | -This demo can be easily connected to real robots or simulators: |
248 | | - |
249 | | -### TurtleBot3 (Example) |
| 67 | +ASAR is enabled but `rclnodejs` is unpacked (`asar.unpack` in `package.json`) |
| 68 | +because it needs filesystem access to its generated code and native bindings. |
| 69 | +The target machine must still have ROS 2 installed and sourced — rclnodejs links |
| 70 | +dynamically to ROS 2 shared libraries: |
250 | 71 |
|
251 | 72 | ```bash |
252 | | -# Launch TurtleBot3 simulation |
253 | | -ros2 launch turtlebot3_gazebo turtlebot3_world.launch.py |
254 | | - |
255 | | -# The demo will automatically control the robot via cmd_vel topic |
256 | | -``` |
257 | | - |
258 | | -### Custom Robot |
259 | | - |
260 | | -Ensure your robot subscribes to the `/cmd_vel` topic with `geometry_msgs/Twist` messages. |
261 | | - |
262 | | -## 🛠️ Customization |
263 | | - |
264 | | -### Modify Velocity Values |
265 | | - |
266 | | -Edit the `speed` and `turnSpeed` constants in `main.js`: |
267 | | - |
268 | | -```javascript |
269 | | -const speed = 1.0; // Linear velocity (m/s) |
270 | | -const turnSpeed = 1.0; // Angular velocity (rad/s) |
271 | | -``` |
272 | | - |
273 | | -### Change Topic Name |
274 | | - |
275 | | -Modify the topic name in `main.js`: |
276 | | - |
277 | | -```javascript |
278 | | -// Change 'cmd_vel' to your desired topic name |
279 | | -carControlPublisher = carControlNode.createPublisher( |
280 | | - 'geometry_msgs/msg/Twist', |
281 | | - 'your_topic_name' |
282 | | -); |
283 | | -``` |
284 | | - |
285 | | -### Add More Commands |
286 | | - |
287 | | -Extend the joystick commands by modifying the switch statement in `main.js` and adding corresponding UI elements. |
288 | | - |
289 | | -## 🐛 Troubleshooting |
290 | | - |
291 | | -### Common Issues |
292 | | - |
293 | | -1. **"Failed to initialize ROS2" Error** |
294 | | - - Ensure ROS2 is properly sourced before running npm start |
295 | | - - Check that rclnodejs is built correctly |
296 | | - |
297 | | -2. **Native module fails to load** |
298 | | - - Ensure ROS 2 is sourced so rclnodejs can match its prebuilt binary |
299 | | - (`ROS_DISTRO` must be set; prebuilt binaries are provided for Ubuntu). |
300 | | - - As a last resort, force a from-source rebuild by setting |
301 | | - `RCLNODEJS_FORCE_BUILD=1` before `npm start` (needs a compiler toolchain and |
302 | | - network access). |
303 | | - |
304 | | -3. **Topic Not Appearing** |
305 | | - - Verify ROS2 daemon is running: `ros2 daemon status` |
306 | | - - Check topic list: `ros2 topic list` |
307 | | - |
308 | | -4. **Car Not Moving in UI** |
309 | | - - Check browser console for JavaScript errors |
310 | | - - Verify IPC communication between main and renderer processes |
311 | | - |
312 | | -### Debug Mode |
313 | | - |
314 | | -Add debug logging by modifying `main.js`: |
315 | | - |
316 | | -```javascript |
317 | | -// Enable debug logging |
318 | | -console.log('Publishing command:', command, twist); |
| 73 | +source /opt/ros/<distro>/setup.bash |
| 74 | +./out/rclnodejs-electron-car-demo-linux-x64/rclnodejs-electron-car-demo |
319 | 75 | ``` |
320 | 76 |
|
321 | | -## 📚 Learning Resources |
322 | | - |
323 | | -- [rclnodejs Documentation](https://github.com/RobotWebTools/rclnodejs) |
324 | | -- [ROS2 Tutorials](https://docs.ros.org/en/lyrical/Tutorials.html) |
325 | | -- [Electron Documentation](https://www.electronjs.org/docs) |
326 | | -- [geometry_msgs/Twist Documentation](https://docs.ros.org/en/lyrical/p/geometry_msgs/interfaces/msg/Twist.html) |
327 | | - |
328 | | -## 📄 License |
| 77 | +## Troubleshooting |
329 | 78 |
|
330 | | -This demo is licensed under the Apache License 2.0, same as the main rclnodejs project. |
| 79 | +- **"Failed to initialize ROS2"** — source ROS 2 before `npm start`. |
| 80 | +- **Native module fails to load** — ensure `ROS_DISTRO` is set so the prebuilt |
| 81 | + binary matches; as a last resort set `RCLNODEJS_FORCE_BUILD=1` (needs a |
| 82 | + compiler toolchain and network access). |
| 83 | +- **Topic missing** — check `ros2 daemon status` and `ros2 topic list`. |
| 84 | +- **Car not moving** — open the DevTools console and check for errors. |
331 | 85 |
|
332 | | -## 🤝 Contributing |
| 86 | +## License |
333 | 87 |
|
334 | | -Feel free to submit issues and enhancement requests! This demo serves as both a functional example and a starting point for more complex ROS2 Electron applications. |
| 88 | +Apache License 2.0, same as rclnodejs. |
0 commit comments