For initial testing and proof of concept, ArUco tags (AR tag) were used to determine the positioning of the dartboard in space. We used the ar_track_alvar package's built-in functionality to first find the AR tag in the frame, then determine its relative transform with respect to the robot's base. Finally, we would ensure a consistent displacement of the AR tag above the target, then use this later for aiming the launcher.
With a working concept, we made the system more robust by implementing a computer-vision powered dartboard detection pipeline, to remove the need for a bulky and inconvenient ArUco tag. First, the camera image was preprocessed with a conversion to grayscale and thresholding of both bright and dark pixel values, increasing the contrast between the dark and light rings on the dartboard. This image was then fed into the Circle Hough Transform, which detected the largest circle in the frame of view. To reduce the effect of noise, we sampled the Circle Hough Transform with the same image 10 times, then took the average center coordinates and radius length of the circle. After calibration with measurements, the depth of the dartboard could be reliably extracted. From there, we simply apply the camera matrix to extract the world X-Y coordinates of the dartboard.
After getting the target's location, we still need to determine where our launcher would move to. This required a few steps in sequence, combined with some experimental characterization of our launcher and the Sawyer robot itself. First, we established that the desired π₯ (lateral) position of the launcher would be set equal to that of the target, and the desired π§ (target-aligned-axis) position of the launcher would be set to a given constant (0.5 meters in our final implementation). By doing this, we greatly simplified our implementation, and ensured that by staying relatively close to the origin we would stay within the robot's dexterous workspace. Next, using standard kinematics calculations, we determined the launch angle of the launcher in order to hit the target. If no angle was found (the target was too far), we incremented the launcher desired height, then recalculated. Once a desired launcher angle is was found, we picked the smaller (flatter) angle, and sent the entire resulting twist to the path planner.
Repeat N times for consistency:
Preprocess the image (grayscale, threshold)
Find the target using Circle Hough Transform (Canny edge detection for circles)
Extract the average radius and the center coordinates of the target in frame
Determine the distance of the target using
d = πΌ r + π½
Determine spatial coordinates as
ππ₯ οΌ πΎπ βΉ π οΌ πΎ -1ππ₯
Initialize π¦dispοΌ0
While we haven't found a successful angle and launcher position:
Set desired launcher position:
π₯ οΌ π₯target , π¦ οΌ π¦target + π¦disp , π§ οΌ 0.5
Solve for theta using kinematic equations:
π₯οΌπ₯0 + π£π₯ π‘ + Β½ aπ₯ π‘2οΌπ₯0 + π£0 cos(π) π‘
βΉ Ξπ₯ = π£0 cos(π) π‘
π¦οΌπ¦0 + π£π¦ π‘ + Β½ aπ¦ π‘2οΌπ¦0 + π£0 sin(π) π‘ - Β½ π¨π‘2
βΉ Ξπ¦ = π£0 sin(π) π‘ - Β½ π¨π‘2
If no solution found:
π¦disp οΌ π¦disp + 0.1
else we have found our π (if multiple solutions, pick the solution closest to zero)
Set our pitch = π from kinematics, send the entire result to Path Planner