manipulationumirealsense-d405depth-camerahumanoidmanipulationvlargb-d

Upgrade lên D405: khi nào nên thay GoPro trong UMI và cách làm

Hướng dẫn thực dụng để quyết định khi nào nên upgrade từ GoPro UMI sang RealSense D405: những gì D405 mang lại, những gì bạn phải tự xây, và kiến trúc đúng để không mất data quality.

Nguyễn Anh Tuấn6 tháng 6, 20267 phút đọc
Upgrade lên D405: khi nào nên thay GoPro trong UMI và cách làm

Upgrade lên D405: khi nào nên thay GoPro trong UMI và cách làm

Đây là bài 6 trong series UMI + VLA. Bài này dành cho người đã có working UMI pipeline (bài 2-5) và đang cân nhắc dùng Intel RealSense D405 thay cho GoPro.

Disclosure: Bài viết có thể chứa affiliate/referral links.

TL;DR: D405 thêm RGB-D gần gripper, hữu ích cho contact estimation và object segmentation. Nhưng nó không phải drop-in replacement — bạn phải xây tracking riêng, recorder riêng, và converter riêng. Nếu pipeline GoPro của bạn đang hoạt động, đừng upgrade trừ khi có lý do cụ thể.

Tại sao GoPro và D405 khác nhau hoàn toàn

Trong UMI gốc, GoPro không chỉ là camera. Nó làm 3 việc cùng lúc:

GoPro trong UMI:
  1. Camera observation (fisheye 155° wrist view)
  2. IMU source (accelerometer + gyroscope cho SLAM)
  3. Visual odometry base (feature-rich fisheye cho ORB-SLAM3)

RealSense D405 không có IMU tích hợp (khác với D435i). FOV của D405 hẹp hơn nhiều. Scripts SLAM pipeline trong repo (01_extract_gopro_imu.py, 03_batch_slam.py) được viết đặc biệt cho GoPro format.

Hạng mục GoPro (UMI gốc) RealSense D405
FOV Fisheye ~155° 87° × 58° (RGB)
IMU Có sẵn Không có
Depth Không có Có (short-range, ~0.1–0.5m)
UMI SLAM scripts Hoạt động trực tiếp ✓ Cần custom adapter ✗
Upstream support Đầy đủ ✓ Không có trong upstream ✗

Khi nào D405 thực sự đáng làm

Upgrade sang D405 chỉ đáng khi bạn cần ít nhất 1 trong 4 thứ này:

  1. Contact estimation — bạn muốn biết chính xác khi nào fingertip chạm object. Depth từ D405 cho point cloud gần gripper (~0.1-0.5m range), tốt hơn nhiều so với RGB-only cho grasping.

  2. Object segmentation — task của bạn có nhiều vật thể tương tự, depth giúp segment 3D object bounds chính xác hơn.

  3. Partial occlusion — object bị che khuất một phần trong RGB, depth giúp estimate pose từ visible surface.

  4. Sensor redundancy — bạn muốn cả RGB (observation) và depth (feature) như 2 nguồn thông tin riêng biệt.

Đừng upgrade nếu:

  • Pipeline GoPro đang hoạt động và policy đủ tốt
  • Bạn muốn "cải thiện" mà không biết D405 giải quyết vấn đề gì cụ thể
  • Bạn chưa có working tracker 6DoF (xem bên dưới)

Thứ bạn PHẢI tự xây khi dùng D405

Đây là phần mà nhiều người bỏ qua: D405 cần custom infrastructure, không phải chỉ đổi camera:

1. External 6DoF tracking

D405 không thể tự SLAM giống GoPro. Bạn cần:

Option Độ chính xác Chi phí Setup phức tạp
Mocap (OptiTrack/Vicon) Rất cao (<0.5mm) Cao ($5k-50k) Cao
SteamVR tracker Cao (~1-3mm) Trung bình (~$150/tracker) Trung bình
AprilTag/ArUco rig Trung bình (~5-10mm) Thấp Thấp
RGB-D SLAM (custom) Thấp-trung (drift) Thấp Rất cao

Khuyến nghị: SteamVR tracker hoặc mocap cho lab setup. AprilTag rig cho budget setup nhưng cần cẩn thận với drift ở vùng occlusion.

Nếu chọn RGB-D SLAM tự build (dùng Open3D hoặc ORB-SLAM3 RGB-D mode): đây là research project, không phải engineering task. Bạn phải validate drift với ground truth, xử lý texture-poor surfaces, và handle tracking loss recovery. Không phù hợp cho người mới.

2. Custom recorder

UMI repo không có recorder cho D405. Bạn phải tự viết script sync:

# Skeleton — đây là starting point, KHÔNG phải production code
# Bạn phải thêm: error handling, proper shutdown, latency measurement
import pyrealsense2 as rs
import numpy as np

# Setup D405 streams
pipe = rs.pipeline()
cfg = rs.config()
cfg.enable_stream(rs.stream.color, 640, 480, rs.format.bgr8, 30)
cfg.enable_stream(rs.stream.depth, 640, 480, rs.format.z16, 30)

# Start aligned depth
align = rs.align(rs.stream.color)
profile = pipe.start(cfg)

# Intrinsics (lưu một lần, dùng cho calibration)
color_intr = profile.get_stream(rs.stream.color).as_video_stream_profile().get_intrinsics()
print("D405 intrinsics:", color_intr)

# Recording loop
frames_rgb = []
frames_depth = []
timestamps = []

for i in range(90):  # 3 giây tại 30fps
    frames = pipe.wait_for_frames()
    aligned = align.process(frames)
    color = aligned.get_color_frame()
    depth = aligned.get_depth_frame()
    ts = frames.get_timestamp() / 1000.0  # ms → s

    frames_rgb.append(np.asanyarray(color.get_data()))
    frames_depth.append(np.asanyarray(depth.get_data()))
    timestamps.append(ts)

pipe.stop()
print(f"Recorded {len(timestamps)} frames, FPS ≈ {len(timestamps)/(timestamps[-1]-timestamps[0]):.1f}")

Script thực tế phải sync với tracker poses và gripper width trong cùng loop.

3. Custom data converter

Không có script nào trong UMI repo chuyển D405 data sang replay_buffer.zarr.zip hoặc LeRobot format. Bạn phải tự viết converter map:

D405 color frames + D405 depth frames
+ External tracker poses
+ Gripper width measurements
    ↓ (custom converter)
UMI replay buffer keys:
  robot0_eef_pos, robot0_eef_rot_axis_angle
  robot0_gripper_width
  camera0_rgb, camera0_depth (nếu model support)

Kiến trúc đúng cho UMI-D405

Hardware:
  D405 (wrist RGB-D observation)
  + External tracker gắn cứng vào gripper body
  + Gripper width sensor (ArUco tag hoặc encoder)

Software:
  Custom sync recorder
      → lưu: color.mp4, depth.zarr, poses.csv, width.csv, timestamps.csv
  Calibration:
      → D405 intrinsics (camera_matrix, dist_coeffs)
      → T_gripper_camera (rigid transform từ gripper body → camera)
      → T_tracker_gripper (nếu dùng mocap/VR)
  Custom converter:
      → Ghép RGB-D + pose + width → replay buffer hoặc LeRobot format

Calibration quan trọng nhất: T_gripper_camera — transform cứng từ gripper body đến D405 optical frame. Nếu sai, action của policy sẽ lệch so với camera observation. Dùng ChArUco board và hand-eye calibration.

Depth có dùng được cho VLA không?

Câu hỏi thực tế: VLA của bạn có nhận depth input không?

GR00T/GR00T-LeRobot (NVIDIA): Hỗ trợ tùy version và config. Kiểm tra branch bạn đang dùng có modality.json support depth key không trước khi invest vào depth pipeline.

Diffusion Policy UMI baseline: Config mặc định dùng RGB-only. Để thêm depth, cần custom encoder (ví dụ: concat depth vào RGB channel, hoặc dùng separate depth encoder). Không có trong official config sẵn.

Khuyến nghị thực dụng:

  1. Train RGB-only baseline trước với D405 color stream
  2. Nếu baseline hoạt động, mới thêm depth như feature bổ sung
  3. Test: model có cải thiện với depth không? Nếu không → giữ RGB-only

D405 depth thực tế có vấn đề gì?

Vấn đề Nguyên nhân Fix
Vật thể bóng/trong suốt mất depth Stereo depth fail Dùng matte props khi thu data
Depth lệch RGB Stereo baseline không align Dùng rs.align(), lưu intrinsics/extrinsics
Depth quá nhiễu ở edge Stereo disparity noise Spatial/temporal filter của librealsense
Depth không cover gần <10cm D405 min range limit Điều chỉnh camera position
Model VLA không improve với depth Depth features không được dùng Verify dataloader đọc depth đúng

Checklist quyết định trước khi upgrade

Trả lời những câu hỏi này trước khi mua D405:

[ ] GoPro pipeline hiện tại có hoạt động tốt không?
    → Nếu không, fix GoPro pipeline trước.

[ ] Bạn có vấn đề cụ thể mà D405 giải quyết không?
    → Nếu không biết, giữ GoPro.

[ ] Bạn đã chọn external 6DoF tracking solution chưa?
    → Nếu chưa, D405 sẽ không có pose data.

[ ] Bạn sẵn sàng viết custom recorder + converter không?
    → Ước tính 2-4 tuần cho người có kinh nghiệm.

[ ] VLA bạn dùng support depth input không?
    → Check trước khi invest vào depth pipeline.

[ ] RGB-only D405 baseline đã test chưa?
    → Nếu chưa, test RGB-only trước rồi quyết định thêm depth.

Nguồn tham khảo


Bài viết liên quan

NT

Nguyễn Anh Tuấn

Robotics & AI Engineer. Building VnRobo — sharing knowledge about robot learning, VLA models, and automation.

Khám phá VnRobo

Bài viết liên quan

Lên hai tay: UMI bimanual pipeline với scripts chính thức
manipulation

Lên hai tay: UMI bimanual pipeline với scripts chính thức

5/6/20267 phút đọc
NT
UMI là gì? Cách thu data VLA cho robot mà không cần teleop
manipulation

UMI là gì? Cách thu data VLA cho robot mà không cần teleop

25/5/20268 phút đọc
NT
Train Diffusion Policy đầu tiên với UMI và test trên robot arm
manipulation

Train Diffusion Policy đầu tiên với UMI và test trên robot arm

3/6/20266 phút đọc
NT