Files
2022NoWayHome/src/main/java/frc4388/robot/subsystems/Climber.java
T

103 lines
3.6 KiB
Java
Raw Normal View History

2022-01-15 13:24:09 -07:00
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package frc4388.robot.subsystems;
2022-01-15 15:56:17 -07:00
import com.ctre.phoenix.motorcontrol.can.WPI_TalonFX;
2022-01-18 20:00:03 -07:00
import com.ctre.phoenix.sensors.WPI_PigeonIMU;
2022-01-15 15:56:17 -07:00
2022-01-15 13:24:09 -07:00
import edu.wpi.first.wpilibj2.command.SubsystemBase;
2022-01-15 15:56:17 -07:00
import frc4388.robot.Constants.ClimberConstants;
2022-01-15 13:24:09 -07:00
public class Climber extends SubsystemBase {
2022-01-18 20:00:03 -07:00
private WPI_TalonFX m_shoulder;
private WPI_TalonFX m_elbow;
private WPI_PigeonIMU m_gyro;
2022-01-20 17:10:07 -07:00
private double[] position = {0.d, 0.d};
2022-01-15 13:24:09 -07:00
2022-01-18 20:00:03 -07:00
public Climber(WPI_TalonFX shoulder, WPI_TalonFX elbow, WPI_PigeonIMU gyro) {
2022-01-15 15:56:17 -07:00
m_shoulder = shoulder;
m_elbow = elbow;
2022-01-18 20:00:03 -07:00
m_gyro = gyro;
2022-01-15 13:24:09 -07:00
}
2022-01-15 15:56:17 -07:00
/* getJointAngles
* Gets joint angles for climber arm
2022-01-18 20:00:03 -07:00
* xTarget and yTarget are set in the xy plane of the climber, accounting for the
2022-01-15 15:56:17 -07:00
* rotation of the robot. Both parameters should be in cm.
2022-01-18 20:00:03 -07:00
* returns [shoulderAngle, elbowAngle] in radians
2022-01-15 15:56:17 -07:00
* Does not set the motors automatically
*
* IK resource: https://devforum.roblox.com/t/2-joint-2-limb-inverse-kinematics/252399 */
2022-01-18 20:00:03 -07:00
public static double[] getJointAngles(double xTarget, double yTarget, double tiltAngle) {
double [] angles = new double[2];
2022-01-15 15:56:17 -07:00
double mag = Math.hypot(xTarget, yTarget);
2022-01-18 20:00:03 -07:00
if(mag > ClimberConstants.MAX_ARM_LENGTH) {
xTarget = (xTarget / mag) * ClimberConstants.MAX_ARM_LENGTH;
yTarget = (yTarget / mag) * ClimberConstants.MAX_ARM_LENGTH;
} else if(mag < ClimberConstants.MIN_ARM_LENGTH) {
xTarget = (xTarget / mag) * ClimberConstants.MIN_ARM_LENGTH;
yTarget = (yTarget / mag) * ClimberConstants.MIN_ARM_LENGTH;
}
// The angle to the target point
double theta = Math.atan(yTarget / xTarget) + tiltAngle; // TODO rename variable
2022-01-20 16:37:57 -07:00
2022-01-18 20:00:03 -07:00
// Correct target position for tilt
xTarget = Math.cos(theta) * mag;
yTarget = Math.sin(theta) * mag;
// Law and Order: Cosines edition
2022-01-20 16:37:57 -07:00
double shoulderAngle = Math.acos((Math.pow(ClimberConstants.LOWER_ARM_LENGTH, 2) + Math.pow(mag, 2) - Math.pow(ClimberConstants.UPPER_ARM_LENGTH, 2)) /
2022-01-18 20:00:03 -07:00
(2.d * ClimberConstants.LOWER_ARM_LENGTH * mag));
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;
// If the climber is resting on the robot base, rotate the upper arm in the direction of the target
if(shoulderAngle <= 0.d) {
shoulderAngle = 0.d;
double xDiff = xTarget - ClimberConstants.LOWER_ARM_LENGTH;
elbowAngle = Math.atan(-yTarget / xDiff);
elbowAngle = Math.PI - elbowAngle;
2022-01-15 15:56:17 -07:00
2022-01-18 20:00:03 -07:00
if(xDiff >= 0.d) {
elbowAngle += Math.PI;
}
}
return angles;
}
2022-01-20 16:37:57 -07:00
public double getRobotTilt() {
double[] ypr = new double[3];
m_gyro.getYawPitchRoll(ypr);
2022-01-20 17:10:07 -07:00
return Math.toRadians(ypr[1]); // Pitch
2022-01-20 16:37:57 -07:00
}
2022-01-18 20:00:03 -07:00
public void setJointAngles(double[] angles) {
setJointAngles(angles[0], angles[1]);
}
2022-01-15 15:56:17 -07:00
2022-01-18 20:00:03 -07:00
public void setJointAngles(double shoulderAngle, double elbowAngle) {
// Set PIDs
2022-01-15 13:24:09 -07:00
}
2022-01-20 17:10:07 -07:00
public void controlWithInput(double xInput, double yInput) {
position[0] += xInput * ClimberConstants.MOVE_SPEED;
position[1] += yInput * ClimberConstants.MOVE_SPEED;
double tiltAngle = getRobotTilt();
double[] jointAngles = getJointAngles(position[0], position[1], tiltAngle);
setJointAngles(jointAngles);
}
2022-01-15 13:24:09 -07:00
}