|
| 1 | +# Coffee Robot Description Package |
| 2 | + |
| 3 | +A complete 3D robot description package for the Coffee Buddy robot with animatronic head and coffee machine base. This package provides URDF models, TF integration, RViz visualization, and Gazebo simulation capabilities. |
| 4 | + |
| 5 | +## Overview |
| 6 | + |
| 7 | +The `coffee_robot_description` package contains: |
| 8 | + |
| 9 | +- **URDF/Xacro Models**: Complete 3D robot description with coffee machine base, 3DOF neck, animatronic head, LCD display, camera, and movable ears |
| 10 | +- **TF Integration**: Real-time coordinate frame publishing that integrates with your existing head control system |
| 11 | +- **RViz Visualization**: 3D visualization with real-time head movement tracking |
| 12 | +- **Gazebo Simulation**: Physics-based simulation with camera and sensor plugins |
| 13 | +- **ROS2 Control**: Controller configurations for head and ear movements |
| 14 | + |
| 15 | +### Current Status (ROS2 Jazzy) |
| 16 | + |
| 17 | +✅ **Working**: URDF models, TF integration, RViz visualization, real-time head tracking |
| 18 | +✅ **Working**: Integration with existing head control system via `/head_pan_angle` and `/head_tilt_angle` |
| 19 | +✅ **Working**: Complete 3D robot model with coffee machine, neck, head, camera, ears |
| 20 | +⚠️ **Temporarily Disabled**: Manual joint control GUI (due to package availability) |
| 21 | +✅ **Ready for Future**: 3rd DOF roll motor and ear actuation (hardware expansion) |
| 22 | + |
| 23 | +## Hardware Integration |
| 24 | + |
| 25 | +### Current Hardware (Implemented) |
| 26 | +- **Pan Motor**: Dynamixel XM540-W270 (ID: 1) - Neck yaw movement |
| 27 | +- **Tilt Motor**: Dynamixel XM540-W270 (ID: 9) - Neck pitch movement |
| 28 | +- **Camera**: Logitech Brio 4K positioned in forehead above LCD display |
| 29 | +- **Display**: LCD screen for facial expressions (middle of head) |
| 30 | +- **Coffee Machine**: Delonghi Prima Donna base with full model |
| 31 | + |
| 32 | +### Future Hardware (Planned) |
| 33 | +- **Roll Motor**: 3rd DOF for complete neck movement |
| 34 | +- **Ear Motors**: Left and right ear actuation (45° range each) |
| 35 | +- **Additional Sensors**: IMU, additional cameras |
| 36 | + |
| 37 | +## Installation |
| 38 | + |
| 39 | +### Prerequisites |
| 40 | + |
| 41 | +```bash |
| 42 | +# Core ROS2 dependencies (required) |
| 43 | +sudo apt update |
| 44 | +sudo apt install ros-jazzy-robot-state-publisher ros-jazzy-xacro ros-jazzy-rviz2 |
| 45 | + |
| 46 | +# Optional dependencies (for simulation and advanced features) |
| 47 | +sudo apt install ros-jazzy-gazebo-ros-pkgs ros-jazzy-controller-manager ros-jazzy-joint-trajectory-controller |
| 48 | + |
| 49 | +# Note: joint-state-publisher packages temporarily unavailable due to repository issues |
| 50 | +# Manual joint control via GUI is disabled until packages are available |
| 51 | +# The core visualization and TF integration still work perfectly |
| 52 | +``` |
| 53 | + |
| 54 | +### Build the Package |
| 55 | + |
| 56 | +```bash |
| 57 | +cd coffee_ws |
| 58 | + |
| 59 | +# Build the package |
| 60 | +colcon build --packages-select coffee_robot_description |
| 61 | + |
| 62 | +# Source the workspace |
| 63 | +source install/setup.bash |
| 64 | +``` |
| 65 | + |
| 66 | +## Usage |
| 67 | + |
| 68 | +### 1. Basic Robot Visualization |
| 69 | + |
| 70 | +View the robot model in RViz: |
| 71 | + |
| 72 | +```bash |
| 73 | +# Launch robot state publisher and RViz |
| 74 | +ros2 launch coffee_robot_description rviz_display.launch.py |
| 75 | + |
| 76 | +# Or just the robot state publisher |
| 77 | +ros2 launch coffee_robot_description robot_state_publisher.launch.py |
| 78 | +``` |
| 79 | + |
| 80 | +This will: |
| 81 | +- Load the complete URDF model |
| 82 | +- Start robot_state_publisher |
| 83 | +- Launch RViz with pre-configured views |
| 84 | +- Start TF publisher for real-time head movement integration |
| 85 | + |
| 86 | +**Note**: Manual joint control GUI is temporarily disabled due to package availability issues. The robot model will still display correctly and integrate with your existing head control system. |
| 87 | + |
| 88 | +### 2. Integration with Existing Head Control |
| 89 | + |
| 90 | +Start the TF publisher to integrate with your existing head control system: |
| 91 | + |
| 92 | +```bash |
| 93 | +# Start TF integration (subscribes to /head_pan_angle and /head_tilt_angle) |
| 94 | +ros2 run coffee_robot_description tf_publisher |
| 95 | + |
| 96 | +# Or include in your existing launch files |
| 97 | +ros2 launch coffee_robot_description robot_state_publisher.launch.py |
| 98 | +``` |
| 99 | + |
| 100 | +The TF publisher will: |
| 101 | +- Subscribe to `/head_pan_angle` and `/head_tilt_angle` from your existing head control |
| 102 | +- Convert motor coordinates (143-210°, 169-206°) to URDF coordinates (-37° to +30°, -11° to +26°) |
| 103 | +- Publish joint states for robot_state_publisher |
| 104 | +- Provide real-time 3D visualization of head movements |
| 105 | + |
| 106 | +### 3. Gazebo Simulation |
| 107 | + |
| 108 | +Run the complete robot in Gazebo physics simulation: |
| 109 | + |
| 110 | +```bash |
| 111 | +# Launch Gazebo simulation |
| 112 | +ros2 launch coffee_robot_description gazebo_sim.launch.py |
| 113 | + |
| 114 | +# With custom world file |
| 115 | +ros2 launch coffee_robot_description gazebo_sim.launch.py world:=cafe_world.world |
| 116 | + |
| 117 | +# With custom robot position |
| 118 | +ros2 launch coffee_robot_description gazebo_sim.launch.py x_pose:=1.0 y_pose:=2.0 |
| 119 | +``` |
| 120 | + |
| 121 | +### 4. Camera Integration |
| 122 | + |
| 123 | +Access camera feeds from the head-mounted Logitech Brio: |
| 124 | + |
| 125 | +```bash |
| 126 | +# In simulation, camera topics will be available: |
| 127 | +ros2 topic list | grep camera |
| 128 | + |
| 129 | +# Camera info and image topics: |
| 130 | +# /head_camera/image_raw |
| 131 | +# /head_camera/camera_info |
| 132 | +``` |
| 133 | + |
| 134 | +## Package Structure |
| 135 | + |
| 136 | +``` |
| 137 | +coffee_robot_description/ |
| 138 | +├── urdf/ # Robot description files |
| 139 | +│ ├── coffee_robot.urdf.xacro # Main robot assembly |
| 140 | +│ ├── coffee_machine_base.urdf.xacro # Coffee machine base |
| 141 | +│ ├── neck_assembly.urdf.xacro # 3DOF neck assembly |
| 142 | +│ ├── robot_head.urdf.xacro # Head with display, camera, ears |
| 143 | +│ └── sensors.urdf.xacro # Camera and sensor definitions |
| 144 | +├── launch/ # Launch files |
| 145 | +│ ├── robot_state_publisher.launch.py # Basic robot visualization |
| 146 | +│ ├── rviz_display.launch.py # RViz with GUI controls |
| 147 | +│ └── gazebo_sim.launch.py # Gazebo simulation |
| 148 | +├── config/ # Configuration files |
| 149 | +│ ├── joint_limits.yaml # Joint limits and safety |
| 150 | +│ └── controllers.yaml # ROS2 control configuration |
| 151 | +├── rviz/ # RViz configurations |
| 152 | +│ └── coffee_robot.rviz # Pre-configured RViz setup |
| 153 | +├── meshes/ # 3D mesh files (for realistic appearance) |
| 154 | +│ ├── stl/ # STL files for visualization |
| 155 | +│ └── collada/ # DAE files for physics |
| 156 | +└── coffee_robot_description/ # Python modules |
| 157 | + └── tf_publisher.py # TF integration node |
| 158 | +``` |
| 159 | + |
| 160 | +## Coordinate Systems |
| 161 | + |
| 162 | +### Motor Coordinates → URDF Coordinates |
| 163 | + |
| 164 | +The system automatically converts between your existing motor coordinate system and standard URDF conventions: |
| 165 | + |
| 166 | +**Pan Motor (ID: 1)** |
| 167 | +- Motor Range: 143° to 210° (center: 180°) |
| 168 | +- URDF Range: -37° to +30° (center: 0°) |
| 169 | +- Conversion: `urdf_angle = motor_angle - 180°` |
| 170 | + |
| 171 | +**Tilt Motor (ID: 9)** |
| 172 | +- Motor Range: 169° to 206° (center: 180°) |
| 173 | +- URDF Range: -11° to +26° (center: 0°) |
| 174 | +- Conversion: `urdf_angle = motor_angle - 180°` |
| 175 | + |
| 176 | +### Frame Definitions |
| 177 | + |
| 178 | +``` |
| 179 | +world |
| 180 | +└── base_link (coffee machine) |
| 181 | + └── neck_mount_link |
| 182 | + └── neck_yaw_link (pan motor) |
| 183 | + └── neck_pitch_link (tilt motor) |
| 184 | + └── neck_roll_link (future roll motor) |
| 185 | + └── head_link (main head body) |
| 186 | + ├── display_link (LCD screen) |
| 187 | + │ ├── camera_mount_link (Logitech Brio) |
| 188 | + │ └── camera_optical_frame (ROS camera standard) |
| 189 | + ├── left_ear_link (future ear motor) |
| 190 | + ├── right_ear_link (future ear motor) |
| 191 | + └── imu_link (future IMU sensor) |
| 192 | +``` |
| 193 | + |
| 194 | +## Integration Examples |
| 195 | + |
| 196 | +### 1. Add to Existing Launch File |
| 197 | + |
| 198 | +```python |
| 199 | +# In your existing launch file |
| 200 | +from launch.actions import IncludeLaunchDescription |
| 201 | +from launch.launch_description_sources import PythonLaunchDescriptionSource |
| 202 | + |
| 203 | +# Include robot description |
| 204 | +robot_description_launch = IncludeLaunchDescription( |
| 205 | + PythonLaunchDescriptionSource([ |
| 206 | + PathJoinSubstitution([ |
| 207 | + FindPackageShare('coffee_robot_description'), |
| 208 | + 'launch', 'robot_state_publisher.launch.py' |
| 209 | + ]) |
| 210 | + ]) |
| 211 | +) |
| 212 | +``` |
| 213 | + |
| 214 | +### 2. Subscribe to Joint States |
| 215 | + |
| 216 | +```python |
| 217 | +# Monitor joint states in your nodes |
| 218 | +from sensor_msgs.msg import JointState |
| 219 | + |
| 220 | +def joint_state_callback(self, msg): |
| 221 | + # Find neck joints |
| 222 | + try: |
| 223 | + yaw_idx = msg.name.index('neck_yaw_joint') |
| 224 | + pitch_idx = msg.name.index('neck_pitch_joint') |
| 225 | + |
| 226 | + yaw_angle = msg.position[yaw_idx] |
| 227 | + pitch_angle = msg.position[pitch_idx] |
| 228 | + |
| 229 | + # Use joint angles... |
| 230 | + except ValueError: |
| 231 | + pass # Joint not found |
| 232 | +``` |
| 233 | + |
| 234 | +### 3. Command Robot Joints |
| 235 | + |
| 236 | +```python |
| 237 | +# Send joint trajectory commands |
| 238 | +from trajectory_msgs.msg import JointTrajectory, JointTrajectoryPoint |
| 239 | + |
| 240 | +def move_head(self, yaw, pitch): |
| 241 | + trajectory = JointTrajectory() |
| 242 | + trajectory.joint_names = ['neck_yaw_joint', 'neck_pitch_joint'] |
| 243 | + |
| 244 | + point = JointTrajectoryPoint() |
| 245 | + point.positions = [yaw, pitch] |
| 246 | + point.time_from_start = Duration(seconds=2.0) |
| 247 | + |
| 248 | + trajectory.points = [point] |
| 249 | + self.trajectory_publisher.publish(trajectory) |
| 250 | +``` |
| 251 | + |
| 252 | +## Configuration |
| 253 | + |
| 254 | +### Joint Limits |
| 255 | + |
| 256 | +Modify `config/joint_limits.yaml` to adjust: |
| 257 | +- Position limits (based on your hardware) |
| 258 | +- Velocity and acceleration limits |
| 259 | +- Safety factors |
| 260 | +- Emergency stop parameters |
| 261 | + |
| 262 | +### Controllers |
| 263 | + |
| 264 | +Modify `config/controllers.yaml` to configure: |
| 265 | +- Update rates |
| 266 | +- Trajectory constraints |
| 267 | +- Hardware interface parameters |
| 268 | +- Integration settings |
| 269 | + |
| 270 | +## Future Expansion |
| 271 | + |
| 272 | +### Adding Roll Motor (3rd DOF) |
| 273 | + |
| 274 | +When you add the roll motor hardware: |
| 275 | + |
| 276 | +1. **Update Hardware**: Connect roll motor to your Dynamixel chain |
| 277 | +2. **Update TF Publisher**: Add subscription to roll angle topic |
| 278 | +3. **Update Controllers**: Enable roll joint in controller configuration |
| 279 | +4. **No URDF Changes Needed**: The model already includes the roll joint |
| 280 | + |
| 281 | +### Adding Ear Motors |
| 282 | + |
| 283 | +When you add ear actuation hardware: |
| 284 | + |
| 285 | +1. **Update Hardware**: Connect ear motors |
| 286 | +2. **Update TF Publisher**: Add ear angle subscriptions |
| 287 | +3. **Update Controllers**: Enable ear joints in controller configuration |
| 288 | +4. **No URDF Changes Needed**: The model already includes ear joints |
| 289 | + |
| 290 | +## Troubleshooting |
| 291 | + |
| 292 | +### ROS2 Jazzy Launch Issues |
| 293 | + |
| 294 | +**Import Error for FindPackageShare:** |
| 295 | +``` |
| 296 | +ImportError: cannot import name 'FindPackageShare' from 'launch.substitutions' |
| 297 | +``` |
| 298 | +**Solution**: Fixed in our launch files - uses `launch_ros.substitutions.FindPackageShare` |
| 299 | + |
| 300 | +**Parameter Value Error:** |
| 301 | +``` |
| 302 | +Unable to parse the value of parameter robot_description as yaml |
| 303 | +``` |
| 304 | +**Solution**: Fixed in our launch files - uses `ParameterValue(content, value_type=str)` |
| 305 | + |
| 306 | +**Joint State Publisher Package Not Found:** |
| 307 | +``` |
| 308 | +package 'joint_state_publisher' not found |
| 309 | +``` |
| 310 | +**Solution**: Removed dependency on unavailable packages. Our custom TF publisher handles joint states. |
| 311 | + |
| 312 | +### No Robot Visible in RViz |
| 313 | +```bash |
| 314 | +# Check if robot_description topic exists |
| 315 | +ros2 topic echo /robot_description |
| 316 | + |
| 317 | +# Check if joint_states are being published |
| 318 | +ros2 topic echo /joint_states |
| 319 | + |
| 320 | +# Verify TF tree |
| 321 | +ros2 run tf2_tools view_frames |
| 322 | +``` |
| 323 | + |
| 324 | +### TF Integration Issues |
| 325 | +```bash |
| 326 | +# Check if head angle topics exist |
| 327 | +ros2 topic list | grep head |
| 328 | + |
| 329 | +# Monitor head angles |
| 330 | +ros2 topic echo /head_pan_angle |
| 331 | +ros2 topic echo /head_tilt_angle |
| 332 | + |
| 333 | +# Check TF publisher status |
| 334 | +ros2 node info /coffee_robot_tf_publisher |
| 335 | +``` |
| 336 | + |
| 337 | +### URDF Parsing Errors |
| 338 | +```bash |
| 339 | +# Check URDF syntax |
| 340 | +check_urdf coffee_ws/install/coffee_robot_description/share/coffee_robot_description/urdf/coffee_robot.urdf.xacro |
| 341 | + |
| 342 | +# Or use xacro to process and check |
| 343 | +xacro coffee_ws/src/coffee_robot_description/urdf/coffee_robot.urdf.xacro > /tmp/robot.urdf |
| 344 | +check_urdf /tmp/robot.urdf |
| 345 | +``` |
| 346 | + |
| 347 | +## Contributing |
| 348 | + |
| 349 | +When adding new components: |
| 350 | + |
| 351 | +1. **Follow naming conventions**: Use descriptive link and joint names |
| 352 | +2. **Add proper inertial properties**: Ensure realistic mass and inertia |
| 353 | +3. **Include collision geometry**: For physics simulation |
| 354 | +4. **Update configuration files**: Add joint limits and controller configs |
| 355 | +5. **Test in both RViz and Gazebo**: Verify visualization and simulation |
| 356 | + |
| 357 | +## Dependencies |
| 358 | + |
| 359 | +### Required |
| 360 | +- ROS2 Jazzy (or compatible) |
| 361 | +- robot_state_publisher |
| 362 | +- xacro |
| 363 | +- rviz2 |
| 364 | +- tf2_ros |
| 365 | + |
| 366 | +### Optional |
| 367 | +- gazebo_ros (for simulation) |
| 368 | +- controller_manager (for ROS2 control) |
| 369 | +- joint_trajectory_controller (for trajectory control) |
| 370 | + |
| 371 | +### Temporarily Unavailable |
| 372 | +- joint_state_publisher (404 errors from ROS repository) |
| 373 | +- joint_state_publisher_gui (404 errors from ROS repository) |
| 374 | + |
| 375 | +**Note**: Manual joint control functionality is disabled until these packages become available. The core robot visualization and TF integration work without them. |
| 376 | + |
| 377 | +## License |
| 378 | + |
| 379 | +[TODO: Add your license information] |
0 commit comments