feat: ArUco docking detection (Issue #627) #638
Loading…
x
Reference in New Issue
Block a user
No description provided.
Delete Branch "sl-perception/issue-627-aruco-docking"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
New package
saltybot_aruco_detect— detects all DICT_4X4_50 ArUco markers from the RealSense D435i RGB stream, estimates 6-DOF pose for each, and publishes a PoseArray + closest dock-target PoseStamped.Detection pipeline
/camera/color/image_raw(BGR8, 30 Hz)cv2.aruco.ArucoDetector.detectMarkers()(new OpenCV 4.x API)cv2.aruco.estimatePoseSingleMarkers(legacy, still present in cv2 4.x); per-markersolvePnP(IPPE_SQUARE)fallbackdock_marker_idswithinmax_dock_range_mPublished topics
/saltybot/aruco/markerscamera_color_optical_frame/saltybot/aruco/dock_targetposition.z=forward dist,position.x=lateral offset/saltybot/aruco/viz/saltybot/aruco/statusaruco_math.py(pure Python, no ROS2)rot_mat_to_quat(R)— Shepperd's method, all 4 quadrants, normalisedrvec_to_quat(rvec)—cv2.Rodrigues→ quaternion; manual exponential-map fallbacktvec_distance/tvec_yaw_rad— distance + bearing error helpersMarkerPosedataclass — lazy-cacheddistance_m,yaw_rad,lateral_m,forward_m,quatConfiguration
marker_size_m: 0.10— physical marker side lengthdock_marker_ids: [42]— default dock marker; empty = accept any detected markercorner_refinement: CORNER_REFINE_SUBPIX— sub-pixel accuracydraw_debug_image: false— optional annotated image with axes overlayTests
22 unit tests in
test/test_aruco_math.py: identity/90°/180°/arbitrary rotations, unit-norm invariant, Rodrigues roundtrip, tvec distance/yaw sign + magnitude, MarkerPose accessor caching.Closes #627
New package saltybot_aruco_detect — DICT_4X4_50 ArUco detection from RealSense D435i RGB, pose estimation, PoseArray + dock target output. aruco_math.py (pure Python, no ROS2): rot_mat_to_quat (Shepperd), rvec_to_quat (Rodrigues + cv2 fallback), tvec_distance, tvec_yaw_rad, MarkerPose dataclass with lazy-cached distance_m/yaw_rad/lateral_m/quat. aruco_detect_node.py (ROS2 node 'aruco_detect'): Subscribes: /camera/color/image_raw (30Hz BGR8) + /camera/color/camera_info. Converts to greyscale, cv2.aruco.ArucoDetector.detectMarkers(). estimatePoseSingleMarkers (legacy API) with solvePnP(IPPE_SQUARE) fallback. Dock target: closest marker in dock_marker_ids (default=[42], empty=any), filtered to max_dock_range_m (3.0m). Publishes: /saltybot/aruco/markers (PoseArray — all detected, camera frame), /saltybot/aruco/dock_target (PoseStamped — closest dock candidate, position.z=forward, position.x=lateral), /saltybot/aruco/viz (MarkerArray — SPHERE + TEXT per marker, dock in red), /saltybot/aruco/status (JSON 10Hz — detected_count, dock_distance_m, dock_yaw_deg, dock_lateral_m). Optional debug image with drawDetectedMarkers + drawFrameAxes. corner_refinement=CORNER_REFINE_SUBPIX. config/aruco_detect_params.yaml, launch/aruco_detect.launch.py. test/test_aruco_math.py: 22 unit tests (rotation/quat math, distance, yaw sign/magnitude, MarkerPose accessors + caching). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>