|
| 1 | +# Coffee Head Manual Control Package |
| 2 | + |
| 3 | +A ROS2 package for manual control of the Coffee Buddy robot head using various input methods including joystick, keyboard, and other manual interfaces. |
| 4 | + |
| 5 | +## Overview |
| 6 | + |
| 7 | +The `coffee_head_manual_control` package provides manual control capabilities for the Coffee Buddy robot head system. It serves as the counterpart to the autonomous `coffee_head_control` package, allowing operators to take direct control of head movements. |
| 8 | + |
| 9 | +**Current Features:** |
| 10 | +- **Joystick Control**: Direct head control using gaming controllers |
| 11 | +- **Smooth Motion**: Configurable smoothing and deadzone handling |
| 12 | +- **Multi-axis Control**: Independent yaw, pitch, and roll control |
| 13 | +- **Real-time Response**: 50Hz update rate for responsive control |
| 14 | + |
| 15 | +**Planned Features:** |
| 16 | +- **Keyboard Control**: Arrow keys and WASD control schemes |
| 17 | +- **Gamepad Support**: Extended controller compatibility |
| 18 | +- **Mobile App**: Remote control via smartphone/tablet |
| 19 | +- **Voice Commands**: Simple directional voice control |
| 20 | + |
| 21 | +## Architecture |
| 22 | + |
| 23 | +``` |
| 24 | +┌─────────────────────────────────────────────────────────────────┐ |
| 25 | +│ Manual Control Package │ |
| 26 | +│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ |
| 27 | +│ │ JoystickControl │ │ KeyboardControl │ │ Other Inputs │ │ |
| 28 | +│ │ - Pygame input │ │ - Key mapping │ │ - Future expand │ │ |
| 29 | +│ │ - Axis mapping │ │ - Rate control │ │ - Voice/Mobile │ │ |
| 30 | +│ │ - Smoothing │ │ - Combinations │ │ - Custom HID │ │ |
| 31 | +│ └─────────────────┘ └─────────────────┘ └─────────────────┘ │ |
| 32 | +└─────────────────────────────────────────────────────────────────┘ |
| 33 | + │ |
| 34 | + ▼ |
| 35 | + Motor Control Topics: |
| 36 | + • set_position_yaw |
| 37 | + • set_position_pitch |
| 38 | + • set_position_roll |
| 39 | +``` |
| 40 | + |
| 41 | +## Components |
| 42 | + |
| 43 | +### JoystickControlNode |
| 44 | + |
| 45 | +Main node for joystick-based head control using gaming controllers. |
| 46 | + |
| 47 | +**Publishers:** |
| 48 | +- `set_position_yaw` (dynamixel_sdk_custom_interfaces/SetPosition): Horizontal rotation commands |
| 49 | +- `set_position_pitch` (dynamixel_sdk_custom_interfaces/SetPosition): Vertical tilt commands |
| 50 | +- `set_position_roll` (dynamixel_sdk_custom_interfaces/SetPosition): Roll rotation commands |
| 51 | + |
| 52 | +**Input Mapping:** |
| 53 | +- **Left Stick X-axis**: Yaw (horizontal rotation) |
| 54 | +- **Right Stick Y-axis**: Pitch (vertical tilt) |
| 55 | +- **Left Trigger**: Roll left |
| 56 | +- **Right Trigger**: Roll right |
| 57 | +- **Combined Triggers**: Roll control (LT = left, RT = right) |
| 58 | + |
| 59 | +**Features:** |
| 60 | +- **Deadzone Handling**: Configurable deadzone to prevent drift (default: 0.1) |
| 61 | +- **Motion Smoothing**: Adjustable smoothing factor for fluid movement (default: 0.3) |
| 62 | +- **Real-time Processing**: 50Hz update rate for responsive control |
| 63 | +- **Error Handling**: Graceful handling of joystick disconnection |
| 64 | + |
| 65 | +## Installation |
| 66 | + |
| 67 | +### Dependencies |
| 68 | + |
| 69 | +- **ROS2**: rclpy, std_msgs, geometry_msgs |
| 70 | +- **Motor Control**: dynamixel_sdk_custom_interfaces |
| 71 | +- **Input Handling**: python3-pygame |
| 72 | +- **Math**: numpy (included with ROS2) |
| 73 | + |
| 74 | +### Hardware Requirements |
| 75 | + |
| 76 | +- **Joystick/Gamepad**: Any pygame-compatible gaming controller |
| 77 | + - Xbox controllers (wired/wireless) |
| 78 | + - PlayStation controllers (DS4, DualSense) |
| 79 | + - Generic USB gamepads |
| 80 | + - Logitech controllers |
| 81 | + |
| 82 | +### Build Instructions |
| 83 | + |
| 84 | +```bash |
| 85 | +# Navigate to your ROS2 workspace |
| 86 | +cd coffee_ws |
| 87 | + |
| 88 | +# Build the package |
| 89 | +colcon build --packages-select coffee_head_manual_control |
| 90 | + |
| 91 | +# Source the workspace |
| 92 | +source install/setup.bash |
| 93 | +``` |
| 94 | + |
| 95 | +## Usage |
| 96 | + |
| 97 | +### Joystick Control |
| 98 | + |
| 99 | +```bash |
| 100 | +# Connect your joystick/gamepad first |
| 101 | +# Launch joystick control node |
| 102 | +ros2 run coffee_head_manual_control joystick_control |
| 103 | + |
| 104 | +# Verify joystick is detected |
| 105 | +# Check the terminal output for "Initialized joystick: [Controller Name]" |
| 106 | +``` |
| 107 | + |
| 108 | +### Manual Testing |
| 109 | + |
| 110 | +```bash |
| 111 | +# Monitor the motor commands being sent |
| 112 | +ros2 topic echo /set_position_yaw |
| 113 | +ros2 topic echo /set_position_pitch |
| 114 | +ros2 topic echo /set_position_roll |
| 115 | + |
| 116 | +# Check joystick detection |
| 117 | +ros2 node info /joystick_control_node |
| 118 | +``` |
| 119 | + |
| 120 | +## Configuration |
| 121 | + |
| 122 | +### Joystick Parameters |
| 123 | + |
| 124 | +The joystick control can be customized by modifying the following parameters in the code: |
| 125 | + |
| 126 | +```python |
| 127 | +# Control sensitivity and response |
| 128 | +self.deadzone = 0.1 # Ignore movements below this threshold (0.0-1.0) |
| 129 | +self.max_angle = 1.0 # Maximum angle in radians |
| 130 | +self.smooth_factor = 0.3 # Motion smoothing (0.0=none, 1.0=maximum) |
| 131 | + |
| 132 | +# Update rate |
| 133 | +create_timer(0.02, ...) # 50Hz = 0.02s interval |
| 134 | +``` |
| 135 | + |
| 136 | +### Input Mapping |
| 137 | + |
| 138 | +**Standard Gamepad Layout:** |
| 139 | +``` |
| 140 | +Left Stick: |
| 141 | + X-axis → Yaw (head rotation left/right) |
| 142 | + Y-axis → (unused) |
| 143 | +
|
| 144 | +Right Stick: |
| 145 | + X-axis → (unused) |
| 146 | + Y-axis → Pitch (head tilt up/down) |
| 147 | +
|
| 148 | +Triggers: |
| 149 | + Left Trigger → Roll left |
| 150 | + Right Trigger → Roll right |
| 151 | +``` |
| 152 | + |
| 153 | +**Axis Values:** |
| 154 | +- Range: -1.0 to +1.0 |
| 155 | +- Deadzone applied automatically |
| 156 | +- Converted to motor position units (x1000) |
| 157 | + |
| 158 | +## Integration |
| 159 | + |
| 160 | +### Motor Service Integration |
| 161 | + |
| 162 | +Requires compatible motor control service to be running: |
| 163 | +```bash |
| 164 | +# Start motor service (if using dynamixel_sdk_examples) |
| 165 | +ros2 run dynamixel_sdk_examples read_write_node |
| 166 | + |
| 167 | +# Or start your custom motor service |
| 168 | +``` |
| 169 | + |
| 170 | +### Coordination with Autonomous Control |
| 171 | + |
| 172 | +**Important**: Manual control and autonomous head tracking should not run simultaneously as they will conflict. Consider implementing: |
| 173 | + |
| 174 | +1. **Mode Switching**: Toggle between manual and autonomous modes |
| 175 | +2. **Priority System**: Manual input overrides autonomous tracking |
| 176 | +3. **Timeout Handling**: Return to autonomous mode after manual inactivity |
| 177 | + |
| 178 | +### Topic Compatibility |
| 179 | + |
| 180 | +Current topic structure (`set_position_yaw`, `set_position_pitch`, `set_position_roll`) differs from the autonomous control package (`set_position`). Future updates may standardize this interface. |
| 181 | + |
| 182 | +## Troubleshooting |
| 183 | + |
| 184 | +### Joystick Issues |
| 185 | + |
| 186 | +**No joystick detected:** |
| 187 | +```bash |
| 188 | +# Check if joystick is connected |
| 189 | +ls /dev/input/js* |
| 190 | + |
| 191 | +# Test with pygame directly |
| 192 | +python3 -c "import pygame; pygame.init(); pygame.joystick.init(); print(f'Found {pygame.joystick.get_count()} joysticks')" |
| 193 | + |
| 194 | +# Check permissions |
| 195 | +sudo chmod 666 /dev/input/js0 |
| 196 | +``` |
| 197 | + |
| 198 | +**Joystick not responding:** |
| 199 | +- Verify the controller is in the correct mode (if applicable) |
| 200 | +- Check battery level for wireless controllers |
| 201 | +- Try unplugging and reconnecting |
| 202 | +- Restart the node: `Ctrl+C` and rerun |
| 203 | + |
| 204 | +**Erratic movement:** |
| 205 | +- Increase deadzone value if controller has stick drift |
| 206 | +- Check for interference with wireless controllers |
| 207 | +- Calibrate controller using system tools |
| 208 | + |
| 209 | +### Motor Issues |
| 210 | + |
| 211 | +**No motor response:** |
| 212 | +```bash |
| 213 | +# Check if motor service is running |
| 214 | +ros2 service list | grep position |
| 215 | + |
| 216 | +# Verify topics are being published |
| 217 | +ros2 topic hz /set_position_yaw |
| 218 | + |
| 219 | +# Check motor connection and power |
| 220 | +``` |
| 221 | + |
| 222 | +**Jerky movement:** |
| 223 | +- Increase smooth_factor for smoother motion |
| 224 | +- Reduce update rate if system is overloaded |
| 225 | +- Check for network latency if using remote control |
| 226 | + |
| 227 | +## Development |
| 228 | + |
| 229 | +### Adding New Input Methods |
| 230 | + |
| 231 | +To add keyboard control or other input methods: |
| 232 | + |
| 233 | +1. **Create new node file**: |
| 234 | + ```bash |
| 235 | + touch coffee_head_manual_control/keyboard_control_node.py |
| 236 | + ``` |
| 237 | + |
| 238 | +2. **Update setup.py entry points**: |
| 239 | + ```python |
| 240 | + 'console_scripts': [ |
| 241 | + 'joystick_control = coffee_head_manual_control.joystick_control_node:main', |
| 242 | + 'keyboard_control = coffee_head_manual_control.keyboard_control_node:main', |
| 243 | + ], |
| 244 | + ``` |
| 245 | + |
| 246 | +3. **Follow existing patterns**: |
| 247 | + - Use same topic structure |
| 248 | + - Implement similar smoothing and deadzone handling |
| 249 | + - Add proper error handling and cleanup |
| 250 | + |
| 251 | +### Extending Joystick Support |
| 252 | + |
| 253 | +**Custom Controller Mapping:** |
| 254 | +```python |
| 255 | +# Add controller-specific mappings |
| 256 | +CONTROLLER_MAPPINGS = { |
| 257 | + 'Xbox Controller': { |
| 258 | + 'yaw_axis': 0, |
| 259 | + 'pitch_axis': 3, |
| 260 | + 'roll_left': 2, |
| 261 | + 'roll_right': 5 |
| 262 | + }, |
| 263 | + 'PS4 Controller': { |
| 264 | + 'yaw_axis': 0, |
| 265 | + 'pitch_axis': 3, |
| 266 | + 'roll_left': 2, |
| 267 | + 'roll_right': 5 |
| 268 | + } |
| 269 | +} |
| 270 | +``` |
| 271 | + |
| 272 | +**Advanced Features:** |
| 273 | +- Button mapping for preset positions |
| 274 | +- Gesture recognition |
| 275 | +- Force feedback support |
| 276 | +- Multi-controller support |
| 277 | + |
| 278 | +## Future Enhancements |
| 279 | + |
| 280 | +### Planned Input Methods |
| 281 | + |
| 282 | +1. **Keyboard Control**: |
| 283 | + - Arrow keys for basic movement |
| 284 | + - WASD for alternative layout |
| 285 | + - Modifier keys for different speeds |
| 286 | + - Number keys for preset positions |
| 287 | + |
| 288 | +2. **Mobile App**: |
| 289 | + - Touch joystick interface |
| 290 | + - Gesture-based control |
| 291 | + - Preset position buttons |
| 292 | + - Real-time video feedback |
| 293 | + |
| 294 | +3. **Voice Commands**: |
| 295 | + - "Look left", "Look up", "Center head" |
| 296 | + - Speed modifiers: "Slowly look right" |
| 297 | + - Integration with existing voice agent |
| 298 | + |
| 299 | +### Advanced Features |
| 300 | + |
| 301 | +- **Motion Recording**: Record and playback manual movements |
| 302 | +- **Macro Support**: Define complex movement sequences |
| 303 | +- **Collaborative Control**: Multiple operators sharing control |
| 304 | +- **Safety Zones**: Configurable movement limits |
| 305 | +- **Haptic Feedback**: Force feedback for boundaries |
| 306 | + |
| 307 | +## Safety Considerations |
| 308 | + |
| 309 | +- **Movement Limits**: Respect motor angle limits to prevent damage |
| 310 | +- **Emergency Stop**: Implement immediate stop capability |
| 311 | +- **Smooth Transitions**: Avoid sudden jerky movements |
| 312 | +- **Power Management**: Consider motor heating during extended use |
| 313 | +- **Conflict Prevention**: Ensure only one control method is active |
| 314 | + |
| 315 | +## License |
| 316 | + |
| 317 | +TODO: License declaration |
| 318 | + |
| 319 | +## Contributing |
| 320 | + |
| 321 | +When adding new manual control methods: |
| 322 | +1. Follow the existing code structure and patterns |
| 323 | +2. Add comprehensive error handling |
| 324 | +3. Update this README with new features |
| 325 | +4. Include example usage and troubleshooting |
| 326 | +5. Test with various input devices |
| 327 | +6. Consider accessibility requirements |
0 commit comments