Planning & Control
Overview
We design the paddle to shadow the x and y positions of the balloon at a default z height and "pop" to a preset z height when the balloon is expected to reach the paddle's default height.
We keep the paddle tilted toward the center of the drop zone, while holding the paddle at the higher z position for a set number of control ticks.
All target paddle poses are converted into target tool poses and sent to the default MoveIt IK service, which returns target joint states that we convert into velocity commands with a simple custom PID controller.
Balloon Prediction
We subscribe to /ball_poseand maintain a rolling buffer of samples and select the most recent samples to make a simple ballistic model to estimate the ball's position and velocity.
We treat x and y motion as linear, while correcting z motion for gravity. The resulting position and velocity are published as /ball_state for
the horizontal tracker.
Paddle Planning
Shadow (x/y component of motion)
Position
We subscribe to /ball_state, which publishes at about 30 Hz, and set the target x and y positions of the paddle to the most recent x and y positions of the ball in the base_link frame.
We orient the paddle so it points away from the robot and toward the center of the drop zone, keeping in mind that the paddle normal is in the tool frame's -x direction.
desired_normal = p_center - desired_p_tool
current_normal = - first vector of quat_to_rot(current_quat)
normalize desired_normal, current_normal
axis = current_normal × desired_normal
angle = arccos(normalized desired_normal · current_normal)
quat from axis, angle
Strike (z component of motion)
We extract the balloon's z velocity and use two conditions to decide when the paddle should pop: whether the balloon is low enough, or whether it is moving fast enough to hit the paddle within a set time window.
When the paddle is popping, it holds the higher z position for a set number of control ticks and then returns to the default z position.
Control Loop
IK Conversions
We align the paddle, not the robot end effector itself, with the ball position by transforming the target paddle pose back into a target tool pose that accounts for the offset between wrist_3_link and the paddle.
We also clamp the target x/y position away from the robot body using min_body_clearance_radius, to prevent joint collisions or the arm moving through the base.
We use the MoveIt IK service to generate target joint states from the target tool pose.
After IK, we reject solutions with large joint-space jumps using max_ik_joint_delta, which helps avoid sudden branch changes in the IK solution.
Shadow vs. Strike PID
We use stronger PID K_p coefficients when commanding upward paddle velocity so the balloon bounces high enough.
We command stronger motion for joints closer to base_link to compensate for greater joint resistance.