|
| 1 | +# ROS2 Car Control Demo with Electron and rclnodejs |
| 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. |
| 4 | + |
| 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, or Rolling) |
| 33 | +2. **Node.js** (version 16 or higher) |
| 34 | +3. **rclnodejs built** and working |
| 35 | + |
| 36 | +### ROS2 Setup |
| 37 | + |
| 38 | +```bash |
| 39 | +# Source your ROS2 installation |
| 40 | +source /opt/ros/<your-ros-distro>/setup.bash |
| 41 | + |
| 42 | +# Verify ROS2 is working |
| 43 | +ros2 topic list |
| 44 | +``` |
| 45 | + |
| 46 | +### Build rclnodejs |
| 47 | + |
| 48 | +From the main rclnodejs directory: |
| 49 | + |
| 50 | +```bash |
| 51 | +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. **Rebuild native modules for Electron:** |
| 70 | + |
| 71 | + ```bash |
| 72 | + npm run rebuild |
| 73 | + ``` |
| 74 | + |
| 75 | +4. **Start the demo:** |
| 76 | + ```bash |
| 77 | + # Make sure ROS2 is sourced first |
| 78 | + source /opt/ros/<your-ros-distro>/setup.bash |
| 79 | + npm start |
| 80 | + ``` |
| 81 | + |
| 82 | + |
| 83 | + |
| 84 | +## 🎮 How to Use |
| 85 | + |
| 86 | +### Control Methods |
| 87 | + |
| 88 | +#### Mouse Controls |
| 89 | + |
| 90 | +- Click the directional buttons (↑↓←→) on the joystick |
| 91 | +- Click the red **STOP** button to halt movement |
| 92 | + |
| 93 | +#### Keyboard Controls |
| 94 | + |
| 95 | +- **W** or **↑**: Move forward |
| 96 | +- **S** or **↓**: Move backward |
| 97 | +- **A** or **←**: Turn left |
| 98 | +- **D** or **→**: Turn right |
| 99 | +- **Space** or **Esc**: Stop |
| 100 | + |
| 101 | +### Understanding the Interface |
| 102 | + |
| 103 | +#### Left Panel - Joystick Control |
| 104 | + |
| 105 | +- **Command**: Shows the current command being sent |
| 106 | +- **Linear X**: Forward/backward velocity (m/s) |
| 107 | +- **Angular Z**: Rotation velocity (rad/s) |
| 108 | +- **Topic**: ROS2 topic name (`cmd_vel`) |
| 109 | + |
| 110 | +#### Right Panel - Car Visualization |
| 111 | + |
| 112 | +- **Received Commands**: Total count of commands received |
| 113 | +- **Last Command**: Most recent command processed |
| 114 | +- **Car Position**: Current position in the visualization area |
| 115 | + |
| 116 | +## 🔍 Technical Details |
| 117 | + |
| 118 | +### ROS2 Message Format |
| 119 | + |
| 120 | +The demo uses `geometry_msgs/Twist` messages with the following structure: |
| 121 | + |
| 122 | +```javascript |
| 123 | +{ |
| 124 | + linear: { |
| 125 | + x: 1.0, // Forward/backward velocity (m/s) |
| 126 | + y: 0.0, // Left/right velocity (typically 0 for cars) |
| 127 | + z: 0.0 // Up/down velocity (typically 0 for ground vehicles) |
| 128 | + }, |
| 129 | + angular: { |
| 130 | + x: 0.0, // Roll rate (typically 0 for cars) |
| 131 | + y: 0.0, // Pitch rate (typically 0 for cars) |
| 132 | + z: 1.0 // Yaw rate (turning left/right in rad/s) |
| 133 | + } |
| 134 | +} |
| 135 | +``` |
| 136 | + |
| 137 | +### Command Mapping |
| 138 | + |
| 139 | +| Command | Linear X | Angular Z | Description | |
| 140 | +| -------- | -------- | --------- | ---------------------- | |
| 141 | +| Forward | +1.0 | 0.0 | Move forward at 1 m/s | |
| 142 | +| Backward | -1.0 | 0.0 | Move backward at 1 m/s | |
| 143 | +| Left | 0.0 | +1.0 | Turn left at 1 rad/s | |
| 144 | +| Right | 0.0 | -1.0 | Turn right at 1 rad/s | |
| 145 | +| Stop | 0.0 | 0.0 | Stop all movement | |
| 146 | + |
| 147 | +### Architecture |
| 148 | + |
| 149 | +``` |
| 150 | +┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐ |
| 151 | +│ Renderer │ │ Main Process │ │ ROS2 Network │ |
| 152 | +│ (UI/Browser) │ │ (Node.js) │ │ │ |
| 153 | +├─────────────────┤ ├──────────────────┤ ├─────────────────┤ |
| 154 | +│ • Joystick UI │───▶│ • rclnodejs Node │───▶│ • cmd_vel Topic │ |
| 155 | +│ • Car Display │◀───│ • Publisher │ │ • Other Nodes │ |
| 156 | +│ • Status Panel │ │ • Subscriber │◀───│ • Robot/Sim │ |
| 157 | +└─────────────────┘ └──────────────────┘ └─────────────────┘ |
| 158 | +``` |
| 159 | + |
| 160 | +## 🧪 Testing with ROS2 Tools |
| 161 | + |
| 162 | +You can test the demo using standard ROS2 command-line tools: |
| 163 | + |
| 164 | +### Listen to Published Commands |
| 165 | + |
| 166 | +```bash |
| 167 | +# In a new terminal (with ROS2 sourced) |
| 168 | +ros2 topic echo /cmd_vel |
| 169 | +``` |
| 170 | + |
| 171 | +### Send Commands from Command Line |
| 172 | + |
| 173 | +```bash |
| 174 | +# Send a forward command |
| 175 | +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}" |
| 176 | + |
| 177 | +# Send a turn left command |
| 178 | +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}" |
| 179 | + |
| 180 | +# Stop command |
| 181 | +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}" |
| 182 | +``` |
| 183 | + |
| 184 | +### Check Active Topics |
| 185 | + |
| 186 | +```bash |
| 187 | +ros2 topic list |
| 188 | +ros2 topic info /cmd_vel |
| 189 | +ros2 topic hz /cmd_vel |
| 190 | +``` |
| 191 | + |
| 192 | +## 🤖 Integration with Real Robots |
| 193 | + |
| 194 | +This demo can be easily connected to real robots or simulators: |
| 195 | + |
| 196 | +### TurtleBot3 (Example) |
| 197 | + |
| 198 | +```bash |
| 199 | +# Launch TurtleBot3 simulation |
| 200 | +ros2 launch turtlebot3_gazebo turtlebot3_world.launch.py |
| 201 | + |
| 202 | +# The demo will automatically control the robot via cmd_vel topic |
| 203 | +``` |
| 204 | + |
| 205 | +### Custom Robot |
| 206 | + |
| 207 | +Ensure your robot subscribes to the `/cmd_vel` topic with `geometry_msgs/Twist` messages. |
| 208 | + |
| 209 | +## 🛠️ Customization |
| 210 | + |
| 211 | +### Modify Velocity Values |
| 212 | + |
| 213 | +Edit the `speed` and `turnSpeed` constants in `main.js`: |
| 214 | + |
| 215 | +```javascript |
| 216 | +const speed = 1.0; // Linear velocity (m/s) |
| 217 | +const turnSpeed = 1.0; // Angular velocity (rad/s) |
| 218 | +``` |
| 219 | + |
| 220 | +### Change Topic Name |
| 221 | + |
| 222 | +Modify the topic name in `main.js`: |
| 223 | + |
| 224 | +```javascript |
| 225 | +// Change 'cmd_vel' to your desired topic name |
| 226 | +carControlPublisher = carControlNode.createPublisher( |
| 227 | + 'geometry_msgs/msg/Twist', |
| 228 | + 'your_topic_name' |
| 229 | +); |
| 230 | +``` |
| 231 | + |
| 232 | +### Add More Commands |
| 233 | + |
| 234 | +Extend the joystick commands by modifying the switch statement in `main.js` and adding corresponding UI elements. |
| 235 | + |
| 236 | +## 🐛 Troubleshooting |
| 237 | + |
| 238 | +### Common Issues |
| 239 | + |
| 240 | +1. **"Failed to initialize ROS2" Error** |
| 241 | + |
| 242 | + - Ensure ROS2 is properly sourced before running npm start |
| 243 | + - Check that rclnodejs is built correctly |
| 244 | + |
| 245 | +2. **Native Module Rebuild Issues** |
| 246 | + |
| 247 | + ```bash |
| 248 | + npm run rebuild |
| 249 | + # or manually: |
| 250 | + ./node_modules/.bin/electron-rebuild |
| 251 | + ``` |
| 252 | + |
| 253 | +3. **Topic Not Appearing** |
| 254 | + |
| 255 | + - Verify ROS2 daemon is running: `ros2 daemon status` |
| 256 | + - Check topic list: `ros2 topic list` |
| 257 | + |
| 258 | +4. **Car Not Moving in UI** |
| 259 | + - Check browser console for JavaScript errors |
| 260 | + - Verify IPC communication between main and renderer processes |
| 261 | + |
| 262 | +### Debug Mode |
| 263 | + |
| 264 | +Add debug logging by modifying `main.js`: |
| 265 | + |
| 266 | +```javascript |
| 267 | +// Enable debug logging |
| 268 | +console.log('Publishing command:', command, twist); |
| 269 | +``` |
| 270 | + |
| 271 | +## 📚 Learning Resources |
| 272 | + |
| 273 | +- [rclnodejs Documentation](https://github.com/RobotWebTools/rclnodejs) |
| 274 | +- [ROS2 Tutorials](https://docs.ros.org/en/rolling/Tutorials.html) |
| 275 | +- [Electron Documentation](https://www.electronjs.org/docs) |
| 276 | +- [geometry_msgs/Twist Documentation](https://docs.ros.org/en/rolling/p/geometry_msgs/interfaces/msg/Twist.html) |
| 277 | + |
| 278 | +## 📄 License |
| 279 | + |
| 280 | +This demo is licensed under the Apache License 2.0, same as the main rclnodejs project. |
| 281 | + |
| 282 | +## 🤝 Contributing |
| 283 | + |
| 284 | +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. |
0 commit comments