一键导入
camera-vision
Camera configuration, hand-eye calibration, YOLO object detection, and visual reaching demo for the OpenArm V10 bimanual robot.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Camera configuration, hand-eye calibration, YOLO object detection, and visual reaching demo for the OpenArm V10 bimanual robot.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
Architecture and deployment guide for running VLA model inference on OpenArm — the UDP/ZMQ server-bridge pattern, EMA smoothing, action chunking, safety filters, and multi-model support (SmolVLA, pi-0.5, GR00T N1.7).
Complete guide for VLA training data collection on OpenArm — teach mode demonstration recording, LeRobot format conversion, dataset validation, and known pitfalls that caused $40+ in wasted training runs.
CompliantVLA paper architecture mapping, gap analysis between our system and the paper, VLM impedance scheduling roadmap, and end-to-end integration plan.
基于 SOC 职业分类
| name | camera-vision |
| description | Camera configuration, hand-eye calibration, YOLO object detection, and visual reaching demo for the OpenArm V10 bimanual robot. |
| version | 1.0.0 |
This skill covers all camera hardware, calibration, object detection, and the visual reaching demo. Read this before modifying camera topics, adding new cameras, or integrating vision with robot control.
| Camera | Model | Serial | Mount | Resolution | FPS |
|---|---|---|---|---|---|
| Head | Intel D435i | 243122070766 | Fixed, head-mounted (63cm above base) | 640×480 | 30 |
| R-Wrist | Intel D405 | 335122273029 | Right forearm (openarm_right_hand) | 640×480 | 15 |
| L-Wrist | Intel D405 | 323622271581 | Left forearm (openarm_left_hand) | 640×480 | 15 |
D435i = RGB-D stereo camera (color + active IR depth). D405 = close-range depth + color via depth module (no separate RGB sensor — color comes through depth_module.color_profile).
CRITICAL: The RealSense ROS 2 driver uses camera_name as BOTH namespace and node prefix:
Default camera_name = "camera"
→ topics publish at: /camera/camera/color/image_raw
/camera/camera/aligned_depth_to_color/image_raw
/camera/camera/color/camera_info
NOT at: /camera/color/image_raw ← WRONG (common assumption)
Wrist cameras use camera_name: right_wrist_camera / left_wrist_camera:
/right_wrist_camera/color/image_raw
/left_wrist_camera/color/image_raw
The object_detector.py defaults to /camera/camera/... and accepts topic overrides via parameters.
| File | Camera | Key Settings |
|---|---|---|
openarm_vision/config/camera_config.yaml | D435i head | serial _243122070766, RGB 640×480@30, depth 640×480@30, align_depth=true |
openarm_vision/config/wrist_camera_config.yaml | D405 right | serial _335122273029, color via depth_module 640×480@15 |
openarm_vision/config/left_wrist_camera_config.yaml | D405 left | serial _323622271581, color via depth_module 640×480@15 |
Note: Serial numbers in config files have underscore prefix (_243122070766). This is required by the RealSense ROS 2 driver.
Our head camera is fixed relative to the robot base — it does NOT move with the arm. This is "eye-to-hand" calibration: we find a single static transform T_base_to_camera.
The current calibration is hardcoded from physical measurement (NOT from automatic chessboard/ArUco calibration):
# calibration_result.yaml (date: 2026-03-25)
calibration:
method: manual
translation: {x: 0.03, y: -0.01, z: 0.63} # meters from base
rotation: {w: 0.924, x: 0.0, y: 0.382, z: 0.0} # ~45° pitch down
This transform is published as a static TF: openarm_body_link0 → camera_link.
For sub-centimeter accuracy, use the automatic calibration script:
ros2 run openarm_vision hand_eye_calibration.py
This uses chessboard/ArUco detection + SVD point cloud alignment. Requires 5+ calibration positions. See CALIBRATION_GUIDE.md for full procedure.
/camera/camera/color/image_raw → ObjectDetector → /object_detections (2D)
→ /object_poses (3D, in base frame)
→ /object_detection_viz
| Parameter | Default | Notes |
|---|---|---|
confidence_threshold | 0.5 | Lower (0.3) for more detections, higher (0.7) for fewer false positives |
target_classes | ['bottle', 'cup', 'bowl'] | COCO class names; filters out non-target detections |
model_path | yolov8n.pt (6MB) | Use yolov8s.pt (22MB) for better accuracy at cost of speed |
color_topic | /camera/camera/color/image_raw | Override if camera_name differs |
use_depth | true | Requires aligned depth + TF for 3D positions |
If YOLO import fails, object_detector.py falls back to ColorDetector — HSV-based detection for red, green, blue, yellow objects. No ML required but limited.
2D bbox center (u,v) → depth lookup (mm → m)
→ back-project: x_cam = (u - cx) * depth / fx
→ TF transform: camera_color_optical_frame → openarm_body_link0
→ 3D position in robot base frame
visual_reach_demo.py — the "See → Reach → Hold → Return" demo:
IDLE ─── (object detected, in workspace) ───► TARGETING
│ │
│ (no target for 3s) (publish /target_pose)
▼ ▼
RETURNING ◄── (hold complete) ── CONTACT ◄── TRANSIT
│ │ │
▼ │ (SUCCEEDED from IK)
COOLDOWN (2s) ──────────────► IDLE │
│
(hold_duration elapsed)
# Full vision pipeline (sim)
ros2 launch openarm_vision camera_bringup.launch.py mode:=simulation
# Full vision pipeline (real hardware)
ros2 launch openarm_vision camera_bringup.launch.py mode:=real use_rviz:=true
This launches: robot bringup + D435i head camera + D405 right wrist + D405 left wrist + static TFs + RViz.
WARNING: Do NOT also run openarm.bimanual.launch.py — camera_bringup.launch.py already includes it. Running both causes duplicate controllers.
| File | Purpose |
|---|---|
openarm_vision/openarm_vision/object_detector.py | YOLO + color-based detection, 3D position via depth+TF |
openarm_vision/openarm_vision/visual_reach_demo.py | 7-state see→reach→return demo |
openarm_vision/openarm_vision/hand_eye_calibration.py | Automatic chessboard/ArUco calibration |
openarm_vision/launch/camera_bringup.launch.py | Multi-camera + robot bringup |
openarm_vision/config/camera_config.yaml | D435i head camera config |
openarm_vision/config/wrist_camera_config.yaml | D405 right wrist config |
openarm_vision/config/left_wrist_camera_config.yaml | D405 left wrist config |
openarm_vision/config/calibration_result.yaml | Current calibration (manual) |
openarm_vision/CALIBRATION_GUIDE.md | Full calibration procedure |
openarm_vision/PERCEPTION_GUIDE.md | YOLO setup and 3D pipeline docs |
# Check camera topics are publishing (with cameras connected)
ros2 topic list | grep -E "camera|wrist"
# Verify head camera image
ros2 topic hz /camera/camera/color/image_raw
# Expected: ~30 Hz
# Verify calibration TF
ros2 run tf2_ros tf2_echo openarm_body_link0 camera_link
# Expected: Translation: [0.03, -0.01, 0.63], non-zero rotation
# Test object detection (YOLO must be installed: pip install ultralytics)
ros2 run openarm_vision object_detector
ros2 topic echo /object_detections --once
| Pitfall | Solution |
|---|---|
Topics at /camera/color/... but detector expects /camera/camera/... | Use --ros-args -p color_topic:=/camera/color/image_raw or check camera_name |
| "No TF/depth" in detection viz | Ensure camera_bringup.launch.py is running (publishes static TF) |
| D405 color image is black | D405 color is via depth_module.color_profile, NOT rgb_camera.color_profile |
| Both cameras show same serial | Each config YAML has explicit serial_no — verify USB connections |
camera_bringup + bimanual.launch.py = duplicate controllers | Only run ONE — camera_bringup already includes the robot bringup |