mirror of
https://github.com/Team4388/2022NoWayHome.git
synced 2026-06-09 08:48:07 -06:00
Fixed IK math
origin: 0.0, 0.0 extended: 0.7853981633974483, 3.141592653589793 just y: 0.1367898269242458, 0.27357965384849187 just x: 0.0, 0.0 just x: 1.7075861537191424, 0.27357965384849187
This commit is contained in:
@@ -55,54 +55,67 @@ public class Climber extends SubsystemBase {
|
||||
* IK resource: https://devforum.roblox.com/t/2-joint-2-limb-inverse-kinematics/252399 */
|
||||
public static double[] getJointAngles(double xTarget, double yTarget, double tiltAngle) {
|
||||
double [] angles = new double[2];
|
||||
|
||||
|
||||
double mag = Math.hypot(xTarget, yTarget);
|
||||
if(mag > ClimberConstants.MAX_ARM_LENGTH) {
|
||||
if(mag >= ClimberConstants.MAX_ARM_LENGTH) {
|
||||
xTarget = (xTarget / mag) * ClimberConstants.MAX_ARM_LENGTH;
|
||||
yTarget = (yTarget / mag) * ClimberConstants.MAX_ARM_LENGTH;
|
||||
mag = ClimberConstants.MAX_ARM_LENGTH;
|
||||
} else if(mag < ClimberConstants.MIN_ARM_LENGTH) {
|
||||
} else if(mag < ClimberConstants.MIN_ARM_LENGTH && mag != 0) {
|
||||
xTarget = (xTarget / mag) * ClimberConstants.MIN_ARM_LENGTH;
|
||||
yTarget = (yTarget / mag) * ClimberConstants.MIN_ARM_LENGTH;
|
||||
mag = ClimberConstants.MIN_ARM_LENGTH;
|
||||
} else if(mag < ClimberConstants.MIN_ARM_LENGTH) {
|
||||
xTarget = ClimberConstants.MIN_ARM_LENGTH;
|
||||
yTarget = 0.d;
|
||||
mag = ClimberConstants.MIN_ARM_LENGTH;
|
||||
}
|
||||
|
||||
|
||||
// The angle to the target point
|
||||
double theta = Math.atan(yTarget / xTarget) + tiltAngle; // TODO rename variable
|
||||
double theta;
|
||||
if(xTarget == 0.d) {
|
||||
theta = Math.PI/2.d; // TODO rename variable
|
||||
} else {
|
||||
theta = Math.atan(yTarget / xTarget);
|
||||
}
|
||||
theta += tiltAngle;
|
||||
|
||||
if(xTarget < 0.d)
|
||||
theta += Math.PI;
|
||||
theta += Math.PI;
|
||||
|
||||
|
||||
// Correct target position for tilt
|
||||
xTarget = Math.cos(theta) * mag;
|
||||
yTarget = Math.sin(theta) * mag;
|
||||
|
||||
// Law and Order: Cosines edition
|
||||
double shoulderAngle = Math.acos((Math.pow(ClimberConstants.LOWER_ARM_LENGTH, 2) + Math.pow(mag, 2) - Math.pow(ClimberConstants.UPPER_ARM_LENGTH, 2)) /
|
||||
double shoulderAngle;
|
||||
if(mag == 0) {
|
||||
shoulderAngle = 0;
|
||||
} else {
|
||||
shoulderAngle = Math.acos((Math.pow(ClimberConstants.LOWER_ARM_LENGTH, 2) + Math.pow(mag, 2) - Math.pow(ClimberConstants.UPPER_ARM_LENGTH, 2)) /
|
||||
(2.d * ClimberConstants.LOWER_ARM_LENGTH * mag));
|
||||
//shoulderAngle = acos(LowerArmLength^2 + mag^2)
|
||||
}
|
||||
shoulderAngle = theta - shoulderAngle;
|
||||
|
||||
double elbowAngle = Math.acos((Math.pow(ClimberConstants.LOWER_ARM_LENGTH, 2) + Math.pow(ClimberConstants.UPPER_ARM_LENGTH, 2) - Math.pow(mag, 2)) /
|
||||
(2.d * ClimberConstants.LOWER_ARM_LENGTH * ClimberConstants.UPPER_ARM_LENGTH));
|
||||
elbowAngle = Math.PI - elbowAngle;
|
||||
|
||||
//elbowAngle = Math.PI - elbowAngle;
|
||||
|
||||
// If the climber is resting on the robot base, rotate the upper arm in the direction of the target
|
||||
if(shoulderAngle <= ClimberConstants.SHOULDER_RESTING_ANGLE) {
|
||||
shoulderAngle = ClimberConstants.SHOULDER_RESTING_ANGLE;
|
||||
double xDiff = xTarget - ClimberConstants.LOWER_ARM_LENGTH;
|
||||
|
||||
|
||||
elbowAngle = Math.atan(-yTarget / xDiff);
|
||||
if(elbowAngle < ClimberConstants.ELBOW_RESTING_ANGLE)
|
||||
elbowAngle = ClimberConstants.ELBOW_RESTING_ANGLE;
|
||||
|
||||
|
||||
elbowAngle = Math.PI - elbowAngle;
|
||||
|
||||
|
||||
// Deal with negative wraparound
|
||||
if(xDiff >= 0.d)
|
||||
elbowAngle += Math.PI;
|
||||
}
|
||||
|
||||
|
||||
angles[0] = shoulderAngle;
|
||||
angles[1] = elbowAngle;
|
||||
return angles;
|
||||
|
||||
Reference in New Issue
Block a user