To enable the poolstick to hit the ball accurately we decided that a Linear Trajectory based path would be our best option as the motion in pool only needs to be linear as well as a constant velocity as accelerating the poolstick may cause issues if there is any error in the arm
Our custom Linear Trajectory class consists of 3 components, where we take in start point (3d), end point (3d), desired velocity (1d), end-effector orientation
To determine the position our end effector should be in at all times, we use the formula: pos = start_position + displacement * direction_vector
Where start_posistion is the robot's starting state, displacement is found by the formula d = vt, and the direction vector is the normalized end-effector orientation
We determine the total time the robot runs for by doing t = d/v, where d is the displacement (||end_point - start_point||) and v is desired velocity (scalar value)
As we have a constant velocity, we return the desired_velocity * normalized_orientation
As we have constant velocity, there is no acceleration, so we always return 0
To make sure the robot doesn't run longer than it needs to, we compare the current time vs the total time it should run (t = d/v), and if it is outside our margin of error, position stays the same, velocity and acceleration both return 0
Example Linear Trajectory
To allow for smooth motion of the sawyer arm, we implemented the PID controller over an edited joint controller:
We utilized the pseudo-inverse of the robot's jacobian (Derived from Sawyer PYKDL) to determine the joint velocities for a desired end effector velocity
From there we implemented the PID Closed-Loop Controller to reduce error in our linear path, as we need to make sure the ball is always on it's target trajectory to not miss the ball
We tuned our PID gains to tend to overshoot compared to undershooting (increasing P values) as we tended to have very small total paths (short but fast shots)
Implementation of Linear Trajectory shown above
With these two parts and the MoveIt! controller here is our final process for robot control:
Get desired ball's pose
Move to ball and pull back in desired direction (MoveIt! controller)
Move ball in linear trajectory (Linear Trajectory and Custom Arm Controller)