Workspace mô phỏng robot JetRover (Hiwonder) — chassis Mecanum + tay máy 5
bậc tự do + kẹp, chạy trên ROS 2 Humble + Gazebo Sim (Ignition Fortress
6.18) + MoveIt 2. Nguồn gốc URDF/mesh: chính chủ
github.com/Hiwonder/JetRover
(branch Jetson_Orin_ros2).
src/simulations/
├── jetrover_description/ # URDF/xacro + mesh + RViz display
├── jetrover_gazebo/ # World, bridge config, launch tích hợp Gazebo
└── jetrover_moveit_config/ # SRDF, controller, planning — sinh bởi MoveIt Setup Assistant
cd ~/ros2_ws
source /opt/ros/humble/setup.bash
colcon build --symlink-install
source install/setup.bashMọi launch bên dưới đều cần khai báo loại chassis + loại LiDAR trước khi
chạy (đọc bởi jetrover.xacro/jetrover_sim.xacro):
export MACHINE_TYPE=JetRover_Mecanum # hoặc JetRover_Tank / JetRover_Acker
export LIDAR_TYPE=A1 # hoặc G4 / A2 / S2L / LD14Pcolor_pick.yaml dùng bốn action group dẫn xuất có hậu tố
_release. Sau khi clone workspace, tạo chúng từ các group
place_left/center/center1/right.d6a đã có trong thư viện:
python3 ~/ros2_ws/scripts/provision_color_pick_release_groups.pyScript mặc định đọc/ghi ~/ActionGroups (hoặc
ARM_MOTION_LIBRARY_DIR), không ghi đè file _release đã có, và sẽ
báo lỗi nếu thiếu group gốc. Mỗi bản _release giữ nguyên toàn bộ group
gốc, ngoại trừ giá trị kẹp của bước cuối cùng được đặt về detent OPEN
theo profile jetrover_arm.yaml.
Quy trình dạy lại: mở và dạy group gốc place_* trong arm editor, lưu nó,
sau đó tạo lại các bản dẫn xuất bằng:
python3 ~/ros2_ws/scripts/provision_color_pick_release_groups.py --forceKhông dạy trực tiếp group _release. Arm editor có thể chuẩn hoá mọi giá
trị kẹp trong file gốc về pulse detent (ví dụ khoảng 596 cho CLOSED); đó
là bình thường. Script không tìm pulse 400: nó chỉ mở kẹp ở bước cuối,
vì vậy quy trình trên vẫn hoạt động sau khi editor lưu lại file.
⚠️ Chỉ JetRover_Mecanum có bánh xe quay được trong vật lý Gazebo (khớpcontinuous). Tank/Acker vẫn hiển thị đúng hình dạng trong RViz nhưng bánh xe hiện là khớpfixed(chỉ để hiển thị, chưa lái được trong Gazebo).
ros2 launch jetrover_description sim_display.launch.pyDùng robot_state_publisher + node tự viết default_joint_state_publisher
(thay cho joint_state_publisher_gui) + rviz2. Không cần Gazebo.
ros2 launch jetrover_gazebo gazebo.launch.pySinh ra: world với 2 khối vật cản, robot spawn bằng plugin
MecanumDrive + OdometryPublisher + JointStatePublisher + cảm biến
gpu_lidar/imu/rgbd_camera. Topic ROS2 chính:
| Topic | Chiều | Ghi chú |
|---|---|---|
/cmd_vel |
ROS→Gazebo | geometry_msgs/Twist |
/odom, /tf |
Gazebo→ROS | odom→base_footprint |
/scan |
Gazebo→ROS | LiDAR |
/imu |
Gazebo→ROS | |
/depth_cam/image, /depth_cam/depth_image, /depth_cam/camera_info |
Gazebo→ROS | camera depth |
/joint_states |
Gazebo→ROS | tất cả khớp không-fixed |
Test lái thử:
ros2 topic pub -r 10 /cmd_vel geometry_msgs/msg/Twist \
"{linear: {x: 0.3}}"ros2 launch jetrover_gazebo gazebo_moveit.launch.pyGồm tất cả kịch bản 2, cộng thêm:
gz_ros2_controlhostcontroller_managerbên trong tiến trình Gazebo, điều khiển 5 khớp tay (joint1..joint5) + kẹp (r_joint) quaarm_controller/gripper_controller(JointTrajectoryController).move_group+ RViz MotionPlanning panel — kéo-thả mục tiêu, bấm Plan & Execute, tay máy tự lập quỹ đạo tránh 2 khối vật cản trong world và tự-va-chạm (self-collision) nhờ Octomap từ camera depth (/depth_cam/depth_image).- GPU NVIDIA được ép dùng cho render Gazebo (xem phần GPU bên dưới).
Đổi chassis: export MACHINE_TYPE=JetRover_Tank (v.v.) trước khi launch —
lưu ý phần lái vật lý chỉ hoạt động với Mecanum như đã nói ở trên.
Máy dùng đồ họa lai (Intel iGPU + NVIDIA rời, chế độ PRIME on-demand). Cả
2 launch Gazebo (gazebo.launch.py, gazebo_moveit.launch.py) đã tự set
__NV_PRIME_RENDER_OFFLOAD=1 + __GLX_VENDOR_LIBRARY_NAME=nvidia để ép
render (GUI Gazebo, camera depth, LiDAR gpu_lidar) chạy trên GPU rời thay
vì Intel iGPU. Kiểm tra đang dùng đúng GPU:
nvidia-smi --query-gpu=utilization.gpu,memory.used --format=csvOctomap (MoveIt) và costmap (Nav2) luôn chạy CPU — đây là kiến trúc chuẩn của ROS 2/MoveIt, không có bản GPU chính thức cho phần này trong Humble; chỉ việc tạo dữ liệu cảm biến (raycasting LiDAR, render ảnh camera) mới đẩy được sang GPU.
| Vấn đề | Nguyên nhân | Đã sửa ở đâu |
|---|---|---|
| Mesh không hiện trong Gazebo | package:// bị đổi thành model://, thiếu GZ_SIM_RESOURCE_PATH |
gazebo.launch.py, gazebo_moveit.launch.py |
| Bánh xe quay nhưng xe không chạy | Khớp bánh xe là fixed (chỉ để hiển thị) |
jetrover_description/urdf/car_mecanum.gazebo.urdf.xacro (bản copy đổi sang continuous) |
| Tay máy "xệ" dưới trọng lực | Thiếu position_proportional_gain cho gz_ros2_control |
jetrover_moveit_config/config/jetrover.ros2_control.xacro |
| Ngón kẹp "gãy"/đung đưa | Gazebo Fortress (6.18) không hỗ trợ vật lý cho tag <mimic> |
Thêm <dynamics damping friction> vào 5 khớp mimic, jetrover_description/urdf/gripper.urdf.xacro |
move_group crash khi khởi động |
max_velocity/max_acceleration là số nguyên thay vì số thực trong YAML |
jetrover_moveit_config/config/joint_limits.yaml |
| Octomap không nhận dữ liệu camera | Frame TF của camera trong Gazebo (jetrover/link4/depth_camera) khác tên link URDF (depth_cam_frame) |
Static TF bridge trong gazebo_moveit.launch.py |
| Tên package dính ký tự xuống dòng | Lỗi khi gõ đường dẫn lưu trong MoveIt Setup Assistant | Đã quét & sửa toàn bộ jetrover_moveit_config |
Toàn bộ workspace JetRover đầy đủ (driver phần cứng thật, SLAM, Nav2,
tích hợp LLM...) nằm trong file zip gốc trên USB:
ros2_ws-20260717T132335Z-1-002.zip. Workspace này chỉ giữ lại phần liên
quan tới mô phỏng (simulations/) — các phần khác đã bị xóa vì thiếu
package.xml/setup.py (không build được, do lỗi export zip).