7.6终终
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -18,10 +18,6 @@ public final class Constants {
|
|||||||
public static final int rightConveyorID = 45;
|
public static final int rightConveyorID = 45;
|
||||||
public static final int backboardMotorID = 44;
|
public static final int backboardMotorID = 44;
|
||||||
|
|
||||||
public static final double flywheelVoltsPerRps = 0.12;
|
|
||||||
public static final double flywheelIdleVoltage = 0.0;
|
|
||||||
public static final double shooterConveyorVoltage = 6.0;
|
|
||||||
public static final double shooterConveyorReverseVoltage = -4.0;
|
|
||||||
public static final double flywheelSpeedToleranceRps = 5.0;
|
public static final double flywheelSpeedToleranceRps = 5.0;
|
||||||
public static final double defaultFlywheelTargetRps = 64.0;
|
public static final double defaultFlywheelTargetRps = 64.0;
|
||||||
|
|
||||||
@@ -121,8 +117,8 @@ public final class Constants {
|
|||||||
public static final int leftIntakeRotaterID = 48;
|
public static final int leftIntakeRotaterID = 48;
|
||||||
public static final int rightIntakeRotaterID = 49;
|
public static final int rightIntakeRotaterID = 49;
|
||||||
|
|
||||||
public static final double intakeRollerVoltage = 6.0;
|
public static final double intakeRollerIntakeSpeedRps = 30.0;
|
||||||
public static final double outtakeRollerVoltage = -5.0;
|
public static final double intakeRollerOuttakeSpeedRps = -30.0;
|
||||||
|
|
||||||
public static final double intakeRotaterLoweredPosition = -7.6;
|
public static final double intakeRotaterLoweredPosition = -7.6;
|
||||||
public static final double intakeRotaterShootAssistUpPosition = -2.5;
|
public static final double intakeRotaterShootAssistUpPosition = -2.5;
|
||||||
@@ -134,9 +130,10 @@ public final class Constants {
|
|||||||
public static final double intakeRotaterUpLimit = 0.0;
|
public static final double intakeRotaterUpLimit = 0.0;
|
||||||
public static final double intakeRotaterDownLimit = -7.6;
|
public static final double intakeRotaterDownLimit = -7.6;
|
||||||
|
|
||||||
public static final Slot0Configs intakeGetterSlot0Configs = new Slot0Configs()
|
public static final Slot0Configs intakeRollerSlot0Configs = new Slot0Configs()
|
||||||
.withKP(0.00).withKI(0.00).withKD(0.00)
|
.withKP(0.00).withKI(0.00).withKD(0.00)
|
||||||
.withKV(0.00).withKA(0.00).withKS(0.00);
|
.withKV(0.00).withKA(0.00).withKS(0.00);
|
||||||
|
public static final Slot0Configs intakeGetterSlot0Configs = intakeRollerSlot0Configs;
|
||||||
|
|
||||||
public static final Slot0Configs intakeRotaterSlot0Configs = new Slot0Configs()
|
public static final Slot0Configs intakeRotaterSlot0Configs = new Slot0Configs()
|
||||||
.withKP(0.00).withKI(0.00).withKD(0.00)
|
.withKP(0.00).withKI(0.00).withKD(0.00)
|
||||||
@@ -149,14 +146,18 @@ public final class Constants {
|
|||||||
|
|
||||||
public static class Conveyor {
|
public static class Conveyor {
|
||||||
public static final int mainConveyorID = 50;
|
public static final int mainConveyorID = 50;
|
||||||
public static final double feedVoltage = 6.0;
|
public static final double feedSpeedRps = 30.0;
|
||||||
public static final double reverseVoltage = -5.0;
|
public static final double reverseSpeedRps = -30.0;
|
||||||
|
|
||||||
|
public static final Slot0Configs mainConveyorSlot0Configs = new Slot0Configs()
|
||||||
|
.withKP(0.00).withKI(0.00).withKD(0.00)
|
||||||
|
.withKV(0.00).withKA(0.00).withKS(0.00);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Superstructure {
|
public static class Superstructure {
|
||||||
// 状态机时间和门控容差。真车基础动作验证后,需要现场调这些值。
|
// 状态机时间和门控容差。真车基础动作验证后,需要现场调这些值。
|
||||||
public static final double shooterFeedPercent = 1.0;
|
public static final double shooterFeedSpeedRps = Shooter.conveyorSpeed;
|
||||||
public static final double shooterReversePercent = -0.6;
|
public static final double shooterReverseSpeedRps = -Shooter.conveyorSpeed * 0.6;
|
||||||
public static final double shootTimeoutSeconds = 1.0;
|
public static final double shootTimeoutSeconds = 1.0;
|
||||||
public static final double aimToleranceDegrees = 1.5;
|
public static final double aimToleranceDegrees = 1.5;
|
||||||
public static final double stationarySpeedToleranceMetersPerSecond = 0.5;
|
public static final double stationarySpeedToleranceMetersPerSecond = 0.5;
|
||||||
|
|||||||
@@ -36,23 +36,23 @@ public class DriveControls {
|
|||||||
private final double maxSpeed = TunerConstants.kSpeedAt12Volts.in(MetersPerSecond);
|
private final double maxSpeed = TunerConstants.kSpeedAt12Volts.in(MetersPerSecond);
|
||||||
private final double maxAngularRate = RotationsPerSecond.of(0.75).in(edu.wpi.first.units.Units.RadiansPerSecond);
|
private final double maxAngularRate = RotationsPerSecond.of(0.75).in(edu.wpi.first.units.Units.RadiansPerSecond);
|
||||||
|
|
||||||
// 榛樿閫熷害姣斾緥锛堝钩鏃跺紑杞︼級
|
// 默认速度比例,普通驾驶使用。
|
||||||
private double normalDriveScale = 0.3;
|
private double normalDriveScale = 0.3;
|
||||||
private double normalTurnScale = 0.7;
|
private double normalTurnScale = 0.7;
|
||||||
|
|
||||||
// 鍔犻€熸ā寮忔瘮渚嬶紙鎸変綇 RB锛?
|
// 加速模式比例,按住 RB 时使用。
|
||||||
private double boostDriveScale = 1.0;
|
private double boostDriveScale = 1.0;
|
||||||
private double boostTurnScale = 1.0;
|
private double boostTurnScale = 1.0;
|
||||||
//autoaim妯″紡
|
// 自动瞄准时降低平移速度。
|
||||||
private double slowDriveScale =0.1;
|
private double slowDriveScale =0.1;
|
||||||
|
|
||||||
private boolean boostEnabled = false;
|
private boolean boostEnabled = false;
|
||||||
|
|
||||||
private final SlewRateLimiter vxLimiter = new SlewRateLimiter(5.0); // m/s^2 绛夋晥锛堣皟锛?
|
private final SlewRateLimiter vxLimiter = new SlewRateLimiter(5.0); // m/s^2 等效加速度限制
|
||||||
private final SlewRateLimiter vyLimiter = new SlewRateLimiter(5.0);
|
private final SlewRateLimiter vyLimiter = new SlewRateLimiter(5.0);
|
||||||
private final SlewRateLimiter omegaLimiter = new SlewRateLimiter(9.0); // rad/s^2 绛夋晥锛堣皟锛?
|
private final SlewRateLimiter omegaLimiter = new SlewRateLimiter(9.0); // rad/s^2 等效角加速度限制
|
||||||
|
|
||||||
// ====== 绫绘垚鍛樺彉閲忛噷鏂板锛氳褰曚笂涓€娆¤緭鍑?======
|
// 记录上一周期输出,用于只限制加速、不限制减速。
|
||||||
private double lastVx = 0.0;
|
private double lastVx = 0.0;
|
||||||
private double lastVy = 0.0;
|
private double lastVy = 0.0;
|
||||||
private double lastOmega = 0.0;
|
private double lastOmega = 0.0;
|
||||||
@@ -64,7 +64,7 @@ public class DriveControls {
|
|||||||
boostEnabled = enabled;
|
boostEnabled = enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 鏂板锛氬綋鍓嶆槸鍚︿娇鐢ㄥ満鍦板潗鏍囩郴锛堥粯璁?true锛?
|
// 当前是否使用场地坐标系,默认启用。
|
||||||
private boolean fieldCentricEnabled = true;
|
private boolean fieldCentricEnabled = true;
|
||||||
|
|
||||||
private final SwerveRequest.FieldCentric fieldCentric =
|
private final SwerveRequest.FieldCentric fieldCentric =
|
||||||
@@ -101,7 +101,7 @@ public class DriveControls {
|
|||||||
return fieldCentricEnabled;
|
return fieldCentricEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 搴曣洏鐨勯粯璁ら┚椹跺懡浠わ紙teleop 鏈熼棿鎸佺画鎵ц锛?*/
|
/** 底盘默认驾驶命令,在 teleop 期间持续执行。 */
|
||||||
public Command defaultDriveCommand() {
|
public Command defaultDriveCommand() {
|
||||||
return drivetrain.applyRequest(() -> {
|
return drivetrain.applyRequest(() -> {
|
||||||
WantedState wantedState = superstructure.getWantedState();
|
WantedState wantedState = superstructure.getWantedState();
|
||||||
@@ -168,27 +168,24 @@ public class DriveControls {
|
|||||||
}
|
}
|
||||||
}, () -> fieldCentricEnabled ? DriveMode.FIELD_CENTRIC : DriveMode.ROBOT_CENTRIC);
|
}, () -> fieldCentricEnabled ? DriveMode.FIELD_CENTRIC : DriveMode.ROBOT_CENTRIC);
|
||||||
}
|
}
|
||||||
/**
|
// 返回当前位置到两个目标点中更近目标的位移。
|
||||||
*
|
// 返回到更近目标的带符号位移。
|
||||||
* 杈撳嚭绉诲姩鍒拌窛绂讳袱涓洰鏍囦箣闂磋緝杩戠殑閭d釜鐐圭殑浣嶇Щ
|
|
||||||
* @return 浣嶇Щ 鏈夋璐?
|
|
||||||
*/
|
|
||||||
public double calculateDifferenceToTwoTarget(double current, double target1, double target2){
|
public double calculateDifferenceToTwoTarget(double current, double target1, double target2){
|
||||||
double x1 = target1 - current;
|
double x1 = target1 - current;
|
||||||
double x2 = target2 - current;
|
double x2 = target2 - current;
|
||||||
return Math.abs(x1) < Math.abs(x2) ? x1 : x2;
|
return Math.abs(x1) < Math.abs(x2) ? x1 : x2;
|
||||||
}
|
}
|
||||||
public double[] calculateDistanceAndRotationToHub() {
|
public double[] calculateDistanceAndRotationToHub() {
|
||||||
Pose2d currentPose = drivetrain.getState().Pose; // 鑾峰彇鏈哄櫒浜哄綋鍓嶇殑浣嶇疆鍜岃搴?
|
Pose2d currentPose = drivetrain.getState().Pose; // 当前机器人位姿
|
||||||
double targetX = isRedAlliance ? Constants.Field.RedHubPositionX : Constants.Field.BlueHubPositionX;
|
double targetX = isRedAlliance ? Constants.Field.RedHubPositionX : Constants.Field.BlueHubPositionX;
|
||||||
double targetY = isRedAlliance ? Constants.Field.RedHubPositionY : Constants.Field.BlueHubPositionY;
|
double targetY = isRedAlliance ? Constants.Field.RedHubPositionY : Constants.Field.BlueHubPositionY;
|
||||||
|
|
||||||
// 璁$畻鐩爣瑙掑害锛堢浉瀵逛簬鍦哄湴鍧愭爣绯伙級
|
// 计算目标角度,相对于场地坐标系。
|
||||||
double deltaX = targetX - currentPose.getX();
|
double deltaX = targetX - currentPose.getX();
|
||||||
double deltaY = targetY - currentPose.getY();
|
double deltaY = targetY - currentPose.getY();
|
||||||
double targetAngle = Math.toDegrees(Math.atan2(deltaY, deltaX)); // 杞崲涓哄害
|
double targetAngle = Math.toDegrees(Math.atan2(deltaY, deltaX)); // 转换为角度
|
||||||
|
|
||||||
// 褰撳墠鏈哄櫒浜鸿搴?
|
// 当前机器人朝向。
|
||||||
double currentAngle = currentPose.getRotation().getDegrees();
|
double currentAngle = currentPose.getRotation().getDegrees();
|
||||||
double angleDifference = targetAngle - currentAngle;
|
double angleDifference = targetAngle - currentAngle;
|
||||||
// Normalize angle difference to the range [-180, 180]
|
// Normalize angle difference to the range [-180, 180]
|
||||||
@@ -198,26 +195,26 @@ public class DriveControls {
|
|||||||
angleDifference += 360;
|
angleDifference += 360;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 璁$畻璺濈
|
// 计算距离。
|
||||||
double distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
|
double distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
|
||||||
// 璁$畻璺濈鍜屾棆杞搴?
|
// 返回距离和旋转角度误差。
|
||||||
double[] distanceAndRotation = new double[]{distance, angleDifference};
|
double[] distanceAndRotation = new double[]{distance, angleDifference};
|
||||||
|
|
||||||
// 杩斿洖璺濈鍜岃搴﹀樊
|
// 距离单位为米,角度单位为度。
|
||||||
return distanceAndRotation;
|
return distanceAndRotation;
|
||||||
}
|
}
|
||||||
public double[] calculateDistanceAndRotationToPassBall() {
|
public double[] calculateDistanceAndRotationToPassBall() {
|
||||||
Pose2d currentPose = drivetrain.getState().Pose; // 鑾峰彇鏈哄櫒浜哄綋鍓嶇殑浣嶇疆鍜岃搴?
|
Pose2d currentPose = drivetrain.getState().Pose; // 当前机器人位姿
|
||||||
double targetX = isRedAlliance ? Constants.Field.RedPassingBallPosX : Constants.Field.BluePassingBallPosX; // 鐩爣 X 鍧愭爣
|
double targetX = isRedAlliance ? Constants.Field.RedPassingBallPosX : Constants.Field.BluePassingBallPosX; // 传球目标 X 坐标
|
||||||
double targetY1 = Constants.Field.PassingBallPosY1; // 鐩爣 Y 鍧愭爣
|
double targetY1 = Constants.Field.PassingBallPosY1; // 传球目标 Y 坐标
|
||||||
double targetY2 = Constants.Field.PassingBallPosY2; // 鐩爣 Y 鍧愭爣
|
double targetY2 = Constants.Field.PassingBallPosY2; // 传球目标 Y 坐标
|
||||||
|
|
||||||
// 璁$畻鐩爣瑙掑害锛堢浉瀵逛簬鍦哄湴鍧愭爣绯伙級
|
// 计算目标角度,相对于场地坐标系。
|
||||||
double deltaX = targetX - currentPose.getX();
|
double deltaX = targetX - currentPose.getX();
|
||||||
double deltaY = calculateDifferenceToTwoTarget(currentPose.getY(), targetY1, targetY2);
|
double deltaY = calculateDifferenceToTwoTarget(currentPose.getY(), targetY1, targetY2);
|
||||||
double targetAngle = Math.toDegrees(Math.atan2(deltaY, deltaX)); // 杞崲涓哄害
|
double targetAngle = Math.toDegrees(Math.atan2(deltaY, deltaX)); // 转换为角度
|
||||||
|
|
||||||
// 褰撳墠鏈哄櫒浜鸿搴?
|
// 当前机器人朝向。
|
||||||
double currentAngle = currentPose.getRotation().getDegrees();
|
double currentAngle = currentPose.getRotation().getDegrees();
|
||||||
double angleDifference = targetAngle - currentAngle;
|
double angleDifference = targetAngle - currentAngle;
|
||||||
// Normalize angle difference to the range [-180, 180]
|
// Normalize angle difference to the range [-180, 180]
|
||||||
@@ -227,12 +224,12 @@ public class DriveControls {
|
|||||||
angleDifference += 360;
|
angleDifference += 360;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 璁$畻璺濈
|
// 计算距离。
|
||||||
double distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
|
double distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
|
||||||
// 璁$畻璺濈鍜屾棆杞搴?
|
// 返回距离和旋转角度误差。
|
||||||
double[] distanceAndRotation = new double[]{distance, angleDifference};
|
double[] distanceAndRotation = new double[]{distance, angleDifference};
|
||||||
|
|
||||||
// 杩斿洖璺濈鍜岃搴﹀樊
|
// 距离单位为米,角度单位为度。
|
||||||
return distanceAndRotation;
|
return distanceAndRotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -260,26 +257,26 @@ public class DriveControls {
|
|||||||
} else {
|
} else {
|
||||||
vomega = error * Constants.AutoPositioning.TurningkP;
|
vomega = error * Constants.AutoPositioning.TurningkP;
|
||||||
}
|
}
|
||||||
// 闄愬埗鏈€澶ц閫熷害
|
// 限制最大角速度。
|
||||||
vomega = Math.max(-maxAngularRate, Math.min(maxAngularRate, vomega));
|
vomega = Math.max(-maxAngularRate, Math.min(maxAngularRate, vomega));
|
||||||
return vomega;
|
return vomega;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 鍙檺鍒垛€滃姞閫熲€濓紙骞呭€煎彉澶э級锛屼笉闄愬埗鈥滃噺閫熲€濓紙骞呭€煎彉灏忥級
|
* 只限制加速,也就是输出幅值变大时;不限制减速。
|
||||||
* 杩欐牱鏉炬潌/鍒硅溅浼氭洿鍙婃椂锛屽悓鏃?boost 浠嶇劧鑳芥姂鍒剁數娴佸啿鍑?
|
* 这样松杆或刹车能更及时,同时 boost 仍能抑制电流冲击。
|
||||||
*/
|
*/
|
||||||
private double limitAccelOnly(double target, double last, SlewRateLimiter limiter) {
|
private double limitAccelOnly(double target, double last, SlewRateLimiter limiter) {
|
||||||
// 濡傛灉姝e湪鍑忛€燂紙骞呭€煎彉灏忥級锛岀洿鎺ユ斁琛屽埌鐩爣鍊?
|
// 如果正在减速,直接放行到目标值。
|
||||||
if (Math.abs(target) < Math.abs(last)) {
|
if (Math.abs(target) < Math.abs(last)) {
|
||||||
limiter.reset(target); // 鍚屾 limiter 鍐呴儴鐘舵€侊紝闃叉涓嬩竴娆$獊鍙?
|
limiter.reset(target); // 同步 limiter 内部状态,防止下一次突跳。
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
// 鍚﹀垯鏄姞閫燂紝浣跨敤 limiter
|
// 否则是加速,使用 limiter。
|
||||||
return limiter.calculate(target);
|
return limiter.calculate(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 绱ф€ュ仠姝細娓呴浂闄愰€熷櫒锛岃閫熷害杈撳嚭绔嬪埢褰掗浂 */
|
/** 紧急停止:清零限速器,让速度输出立刻归零。 */
|
||||||
public void emergencyStop() {
|
public void emergencyStop() {
|
||||||
vxLimiter.reset(0.0);
|
vxLimiter.reset(0.0);
|
||||||
vyLimiter.reset(0.0);
|
vyLimiter.reset(0.0);
|
||||||
@@ -317,13 +314,13 @@ public class DriveControls {
|
|||||||
return maxAngularRate;
|
return maxAngularRate;
|
||||||
}
|
}
|
||||||
public void setTeamColors() {
|
public void setTeamColors() {
|
||||||
Optional<Alliance> ally = DriverStation.getAlliance(); // 鑾峰彇闃熶紞棰滆壊
|
Optional<Alliance> ally = DriverStation.getAlliance(); // 获取联盟颜色
|
||||||
if (ally.isPresent()) {
|
if (ally.isPresent()) {
|
||||||
// 鏍规嵁闃熶紞棰滆壊璁剧疆甯冨皵鍊?
|
// 根据联盟颜色更新自动瞄准目标。
|
||||||
if (ally.get() == Alliance.Red) {
|
if (ally.get() == Alliance.Red) {
|
||||||
isRedAlliance = true; // 绾㈤槦
|
isRedAlliance = true; // 红队
|
||||||
} else if (ally.get() == Alliance.Blue) {
|
} else if (ally.get() == Alliance.Blue) {
|
||||||
isRedAlliance = false; // 钃濋槦
|
isRedAlliance = false; // 蓝队
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
isRedAlliance = true;
|
isRedAlliance = true;
|
||||||
@@ -369,20 +366,20 @@ public class DriveControls {
|
|||||||
|
|
||||||
switch (phase) {
|
switch (phase) {
|
||||||
case 0:
|
case 0:
|
||||||
vx = amplitude; // 鍓?
|
vx = amplitude; // 前
|
||||||
vy = 0.0;
|
vy = 0.0;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
vx = 0.0;
|
vx = 0.0;
|
||||||
vy = amplitude; // 鍙?
|
vy = amplitude; // 左
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
vx = -amplitude; // 鍚?
|
vx = -amplitude; // 后
|
||||||
vy = 0.0;
|
vy = 0.0;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
vx = 0.0;
|
vx = 0.0;
|
||||||
vy = -amplitude; // 宸?
|
vy = -amplitude; // 右
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -404,11 +401,11 @@ public class DriveControls {
|
|||||||
|
|
||||||
public void pushDistanceData(){
|
public void pushDistanceData(){
|
||||||
double[] distanceAndRotation = calculateDistanceAndRotationToHub();
|
double[] distanceAndRotation = calculateDistanceAndRotationToHub();
|
||||||
// 灏嗚窛绂诲€煎啓鍏?NetworkTable
|
// 将距离数据写入 NetworkTable。
|
||||||
autoControlNetworkTable.getEntry("distanceToHub").setDouble(distanceAndRotation[0]);
|
autoControlNetworkTable.getEntry("distanceToHub").setDouble(distanceAndRotation[0]);
|
||||||
autoControlNetworkTable.getEntry("angleDifferenceToHub").setDouble(distanceAndRotation[1]);
|
autoControlNetworkTable.getEntry("angleDifferenceToHub").setDouble(distanceAndRotation[1]);
|
||||||
// 鑷姩闃舵榛樿椹鹃┒鍛戒护涓嶈繍琛岋紝杩欓噷鍚屾牱淇濇寔鐩爣鏈濆悜鏈€鏂帮紝
|
// 自动阶段默认驾驶命令不运行,这里同样保持目标朝向最新,
|
||||||
// 璁╄嚜鍔ㄧ▼搴忛噷鐨勫皠鍑婚棬鎺?isAimed() 鏈夋晥銆?
|
// 让自动程序里的射击门控 isAimed() 有效。
|
||||||
drivetrain.setTargetHeading(
|
drivetrain.setTargetHeading(
|
||||||
drivetrain.getRotation().plus(Rotation2d.fromDegrees(distanceAndRotation[1])));
|
drivetrain.getRotation().plus(Rotation2d.fromDegrees(distanceAndRotation[1])));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package frc.robot.subsystems;
|
package frc.robot.subsystems;
|
||||||
|
|
||||||
import com.ctre.phoenix6.controls.VoltageOut;
|
import com.ctre.phoenix6.controls.VelocityVoltage;
|
||||||
import com.ctre.phoenix6.hardware.TalonFX;
|
import com.ctre.phoenix6.hardware.TalonFX;
|
||||||
|
|
||||||
import edu.wpi.first.networktables.NetworkTable;
|
import edu.wpi.first.networktables.NetworkTable;
|
||||||
@@ -13,27 +13,31 @@ import frc.robot.Constants;
|
|||||||
*/
|
*/
|
||||||
public class ConveyorSubsystem extends SubsystemBase {
|
public class ConveyorSubsystem extends SubsystemBase {
|
||||||
public final TalonFX mainConveyor;
|
public final TalonFX mainConveyor;
|
||||||
private final VoltageOut voltageRequest = new VoltageOut(0);
|
private final VelocityVoltage velocityRequest = new VelocityVoltage(0);
|
||||||
private final NetworkTable table = NetworkTableInstance.getDefault().getTable("Conveyor");
|
private final NetworkTable table = NetworkTableInstance.getDefault().getTable("Conveyor");
|
||||||
|
private double targetSpeedRps = 0.0;
|
||||||
|
|
||||||
public ConveyorSubsystem() {
|
public ConveyorSubsystem() {
|
||||||
mainConveyor = new TalonFX(Constants.Conveyor.mainConveyorID);
|
mainConveyor = new TalonFX(Constants.Conveyor.mainConveyorID);
|
||||||
|
mainConveyor.getConfigurator().apply(Constants.Conveyor.mainConveyorSlot0Configs);
|
||||||
}
|
}
|
||||||
public void feedToShooter() {
|
public void feedToShooter() {
|
||||||
setVoltage(Constants.Conveyor.feedVoltage);
|
setSpeedByRPS(Constants.Conveyor.feedSpeedRps);
|
||||||
}
|
}
|
||||||
public void reverse() {
|
public void reverse() {
|
||||||
setVoltage(Constants.Conveyor.reverseVoltage);
|
setSpeedByRPS(Constants.Conveyor.reverseSpeedRps);
|
||||||
}
|
}
|
||||||
public void stop() {
|
public void stop() {
|
||||||
setVoltage(0.0);
|
setSpeedByRPS(0.0);
|
||||||
}
|
}
|
||||||
public void setVoltage(double volts) {
|
public void setSpeedByRPS(double targetSpeedRps) {
|
||||||
mainConveyor.setControl(voltageRequest.withOutput(volts));
|
this.targetSpeedRps = targetSpeedRps;
|
||||||
|
mainConveyor.setControl(velocityRequest.withVelocity(targetSpeedRps));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void periodic() {
|
public void periodic() {
|
||||||
table.getEntry("velocity").setDouble(mainConveyor.getVelocity().getValueAsDouble());
|
table.getEntry("velocity").setDouble(mainConveyor.getVelocity().getValueAsDouble());
|
||||||
|
table.getEntry("targetSpeedRps").setDouble(targetSpeedRps);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
package frc.robot.subsystems;
|
package frc.robot.subsystems;
|
||||||
|
|
||||||
import com.ctre.phoenix6.controls.Follower;
|
import com.ctre.phoenix6.controls.Follower;
|
||||||
import com.ctre.phoenix6.controls.VoltageOut;
|
import com.ctre.phoenix6.controls.VelocityVoltage;
|
||||||
import com.ctre.phoenix6.hardware.TalonFX;
|
import com.ctre.phoenix6.hardware.TalonFX;
|
||||||
import com.ctre.phoenix6.signals.MotorAlignmentValue;
|
import com.ctre.phoenix6.signals.MotorAlignmentValue;
|
||||||
|
|
||||||
import edu.wpi.first.math.MathUtil;
|
|
||||||
import edu.wpi.first.networktables.NetworkTable;
|
import edu.wpi.first.networktables.NetworkTable;
|
||||||
import edu.wpi.first.networktables.NetworkTableInstance;
|
import edu.wpi.first.networktables.NetworkTableInstance;
|
||||||
import edu.wpi.first.wpilibj2.command.SubsystemBase;
|
import edu.wpi.first.wpilibj2.command.SubsystemBase;
|
||||||
@@ -21,31 +20,35 @@ public class IntakeRollerSubsystem extends SubsystemBase {
|
|||||||
private final TalonFX leftIntakeRoller;
|
private final TalonFX leftIntakeRoller;
|
||||||
private final TalonFX rightIntakeRoller;
|
private final TalonFX rightIntakeRoller;
|
||||||
|
|
||||||
private final VoltageOut voltageRequest = new VoltageOut(0);
|
private final VelocityVoltage velocityRequest = new VelocityVoltage(0);
|
||||||
private final Follower rightFollower;
|
private final Follower rightFollower;
|
||||||
private final NetworkTable table = NetworkTableInstance.getDefault().getTable("IntakeRoller");
|
private final NetworkTable table = NetworkTableInstance.getDefault().getTable("IntakeRoller");
|
||||||
|
private double targetSpeedRps = 0.0;
|
||||||
|
|
||||||
public IntakeRollerSubsystem() {
|
public IntakeRollerSubsystem() {
|
||||||
leftIntakeRoller = new TalonFX(Constants.Intaker.leftIntakeRollerID);
|
leftIntakeRoller = new TalonFX(Constants.Intaker.leftIntakeRollerID);
|
||||||
rightIntakeRoller = new TalonFX(Constants.Intaker.rightIntakeRollerID);
|
rightIntakeRoller = new TalonFX(Constants.Intaker.rightIntakeRollerID);
|
||||||
|
leftIntakeRoller.getConfigurator().apply(Constants.Intaker.intakeRollerSlot0Configs);
|
||||||
|
rightIntakeRoller.getConfigurator().apply(Constants.Intaker.intakeRollerSlot0Configs);
|
||||||
rightFollower = new Follower(leftIntakeRoller.getDeviceID(), MotorAlignmentValue.Opposed).withUpdateFreqHz(50);
|
rightFollower = new Follower(leftIntakeRoller.getDeviceID(), MotorAlignmentValue.Opposed).withUpdateFreqHz(50);
|
||||||
followLeft();
|
followLeft();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void intake() {
|
public void intake() {
|
||||||
setVoltage(Constants.Intaker.intakeRollerVoltage);
|
setSpeedByRPS(Constants.Intaker.intakeRollerIntakeSpeedRps);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void outtake() {
|
public void outtake() {
|
||||||
setVoltage(Constants.Intaker.outtakeRollerVoltage);
|
setSpeedByRPS(Constants.Intaker.intakeRollerOuttakeSpeedRps);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void stop() {
|
public void stop() {
|
||||||
setVoltage(0);
|
setSpeedByRPS(0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setVoltage(double left) {
|
public void setSpeedByRPS(double targetSpeedRps) {
|
||||||
leftIntakeRoller.setControl(voltageRequest.withOutput(left));
|
this.targetSpeedRps = targetSpeedRps;
|
||||||
|
leftIntakeRoller.setControl(velocityRequest.withVelocity(targetSpeedRps));
|
||||||
followLeft();
|
followLeft();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,5 +67,6 @@ public class IntakeRollerSubsystem extends SubsystemBase {
|
|||||||
table.getEntry("leftVelocity").setDouble(leftIntakeRoller.getVelocity().getValueAsDouble());
|
table.getEntry("leftVelocity").setDouble(leftIntakeRoller.getVelocity().getValueAsDouble());
|
||||||
table.getEntry("rightVelocity").setDouble(rightIntakeRoller.getVelocity().getValueAsDouble());
|
table.getEntry("rightVelocity").setDouble(rightIntakeRoller.getVelocity().getValueAsDouble());
|
||||||
table.getEntry("velocityDifference").setDouble(getVelocityDifference());
|
table.getEntry("velocityDifference").setDouble(getVelocityDifference());
|
||||||
|
table.getEntry("targetSpeedRps").setDouble(targetSpeedRps);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import com.ctre.phoenix6.configs.MotorOutputConfigs;
|
|||||||
import com.ctre.phoenix6.configs.Slot0Configs;
|
import com.ctre.phoenix6.configs.Slot0Configs;
|
||||||
import com.ctre.phoenix6.controls.Follower;
|
import com.ctre.phoenix6.controls.Follower;
|
||||||
import com.ctre.phoenix6.controls.VelocityVoltage;
|
import com.ctre.phoenix6.controls.VelocityVoltage;
|
||||||
import com.ctre.phoenix6.controls.VoltageOut;
|
|
||||||
import com.ctre.phoenix6.hardware.TalonFX;
|
import com.ctre.phoenix6.hardware.TalonFX;
|
||||||
import com.ctre.phoenix6.hardware.TalonFXS;
|
import com.ctre.phoenix6.hardware.TalonFXS;
|
||||||
import com.ctre.phoenix6.signals.InvertedValue;
|
import com.ctre.phoenix6.signals.InvertedValue;
|
||||||
@@ -39,8 +38,8 @@ public class ShooterSubsystem extends SubsystemBase {
|
|||||||
public final Encoder backboardEncoder;
|
public final Encoder backboardEncoder;
|
||||||
public final ProfiledPIDController backboardPID;
|
public final ProfiledPIDController backboardPID;
|
||||||
|
|
||||||
private final VoltageOut flywheelVoltageRequest = new VoltageOut(0);
|
private final VelocityVoltage flywheelVelocityRequest = new VelocityVoltage(0);
|
||||||
private final VoltageOut conveyorVoltageRequest = new VoltageOut(0);
|
private final VelocityVoltage conveyorVelocityRequest = new VelocityVoltage(0);
|
||||||
private final VelocityVoltage backboardVelocityRequest = new VelocityVoltage(0);
|
private final VelocityVoltage backboardVelocityRequest = new VelocityVoltage(0);
|
||||||
|
|
||||||
private final Follower flywheelFollower;
|
private final Follower flywheelFollower;
|
||||||
@@ -49,7 +48,7 @@ public class ShooterSubsystem extends SubsystemBase {
|
|||||||
private final NetworkTable shooterNetworkTable;
|
private final NetworkTable shooterNetworkTable;
|
||||||
|
|
||||||
private double targetFlywheelRps = 0.0;
|
private double targetFlywheelRps = 0.0;
|
||||||
private double shooterConveyorPercent = 0.0;
|
private double shooterConveyorTargetRps = 0.0;
|
||||||
|
|
||||||
public ShooterSubsystem() {
|
public ShooterSubsystem() {
|
||||||
leftFlywheel = new TalonFX(Constants.Shooter.leftFlywheelID);
|
leftFlywheel = new TalonFX(Constants.Shooter.leftFlywheelID);
|
||||||
@@ -108,11 +107,13 @@ public class ShooterSubsystem extends SubsystemBase {
|
|||||||
|
|
||||||
public void setFlywheelVelocity(double targetRps) {
|
public void setFlywheelVelocity(double targetRps) {
|
||||||
// 右飞轮是 follower,因此对外只暴露一个飞轮目标速度。
|
// 右飞轮是 follower,因此对外只暴露一个飞轮目标速度。
|
||||||
// 实际控制仍是左飞轮电压开环,右飞轮反向跟随左飞轮。
|
// 左飞轮使用 VelocityVoltage 速度闭环,右飞轮反向跟随左飞轮。
|
||||||
|
setFlywheelSpeedByRPS(targetRps);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFlywheelSpeedByRPS(double targetRps) {
|
||||||
targetFlywheelRps = Math.abs(targetRps);
|
targetFlywheelRps = Math.abs(targetRps);
|
||||||
double requestedVoltage = targetFlywheelRps * Constants.Shooter.flywheelVoltsPerRps;
|
leftFlywheel.setControl(flywheelVelocityRequest.withVelocity(targetFlywheelRps));
|
||||||
requestedVoltage = MathUtil.clamp(requestedVoltage, -12.0, 12.0);
|
|
||||||
leftFlywheel.setControl(flywheelVoltageRequest.withOutput(requestedVoltage));
|
|
||||||
setRightFollowLeft();
|
setRightFollowLeft();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,14 +123,8 @@ public class ShooterSubsystem extends SubsystemBase {
|
|||||||
setFlywheelVelocity(targetRps);
|
setFlywheelVelocity(targetRps);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFlywheelVoltage(double volts) {
|
|
||||||
targetFlywheelRps = 0.0;
|
|
||||||
leftFlywheel.setControl(flywheelVoltageRequest.withOutput(MathUtil.clamp(volts, -12.0, 12.0)));
|
|
||||||
setRightFollowLeft();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void stopFlywheel() {
|
public void stopFlywheel() {
|
||||||
setFlywheelVoltage(Constants.Shooter.flywheelIdleVoltage);
|
setFlywheelSpeedByRPS(0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean atSpeed() {
|
public boolean atSpeed() {
|
||||||
@@ -165,14 +160,14 @@ public class ShooterSubsystem extends SubsystemBase {
|
|||||||
/* shooter conveyor */
|
/* shooter conveyor */
|
||||||
/* ====================== */
|
/* ====================== */
|
||||||
|
|
||||||
public void runShooterConveyor(double percent) {
|
public void runShooterConveyorByRPS(double targetRps) {
|
||||||
shooterConveyorPercent = MathUtil.clamp(percent, -1.0, 1.0);
|
shooterConveyorTargetRps = targetRps;
|
||||||
leftConveyor.setControl(conveyorVoltageRequest.withOutput(shooterConveyorPercent * 12.0));
|
leftConveyor.setControl(conveyorVelocityRequest.withVelocity(targetRps));
|
||||||
setRightFollowLeft();
|
setRightFollowLeft();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void stopShooterConveyor() {
|
public void stopShooterConveyor() {
|
||||||
runShooterConveyor(0.0);
|
runShooterConveyorByRPS(0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getConveyorStatorCurrent() {
|
public double getConveyorStatorCurrent() {
|
||||||
@@ -273,7 +268,7 @@ public class ShooterSubsystem extends SubsystemBase {
|
|||||||
shooterNetworkTable.getEntry("flywheelSpeedDifference").setDouble(getFlywheelVelocityDifference());
|
shooterNetworkTable.getEntry("flywheelSpeedDifference").setDouble(getFlywheelVelocityDifference());
|
||||||
shooterNetworkTable.getEntry("flywheelTargetSpeed").setDouble(targetFlywheelRps);
|
shooterNetworkTable.getEntry("flywheelTargetSpeed").setDouble(targetFlywheelRps);
|
||||||
shooterNetworkTable.getEntry("flywheelAtSpeed").setBoolean(atSpeed());
|
shooterNetworkTable.getEntry("flywheelAtSpeed").setBoolean(atSpeed());
|
||||||
shooterNetworkTable.getEntry("shooterConveyorPercent").setDouble(shooterConveyorPercent);
|
shooterNetworkTable.getEntry("shooterConveyorTargetRps").setDouble(shooterConveyorTargetRps);
|
||||||
shooterNetworkTable.getEntry("conveyorSpeed").setDouble(leftConveyor.getVelocity().getValueAsDouble());
|
shooterNetworkTable.getEntry("conveyorSpeed").setDouble(leftConveyor.getVelocity().getValueAsDouble());
|
||||||
shooterNetworkTable.getEntry("backboardCurrentRate").setDouble(getBackboardPosition());
|
shooterNetworkTable.getEntry("backboardCurrentRate").setDouble(getBackboardPosition());
|
||||||
shooterNetworkTable.getEntry("backboardTargetRate").setDouble(backboardPID.getSetpoint().position);
|
shooterNetworkTable.getEntry("backboardTargetRate").setDouble(backboardPID.getSetpoint().position);
|
||||||
|
|||||||
@@ -282,7 +282,7 @@ public class Superstructure extends SubsystemBase {
|
|||||||
// 避免球接触飞轮导致的掉速中断喂球。
|
// 避免球接触飞轮导致的掉速中断喂球。
|
||||||
intakeRotater.shootAssist();
|
intakeRotater.shootAssist();
|
||||||
conveyor.feedToShooter();
|
conveyor.feedToShooter();
|
||||||
shooter.runShooterConveyor(Constants.Superstructure.shooterFeedPercent);
|
shooter.runShooterConveyorByRPS(Constants.Superstructure.shooterFeedSpeedRps);
|
||||||
|
|
||||||
if (timeInState() > Constants.Superstructure.shootTimeoutSeconds) {
|
if (timeInState() > Constants.Superstructure.shootTimeoutSeconds) {
|
||||||
shotCompletedThisRequest = true;
|
shotCompletedThisRequest = true;
|
||||||
@@ -306,7 +306,7 @@ public class Superstructure extends SubsystemBase {
|
|||||||
setSystemState(SystemState.EJECTING);
|
setSystemState(SystemState.EJECTING);
|
||||||
intakeRoller.outtake();
|
intakeRoller.outtake();
|
||||||
conveyor.reverse();
|
conveyor.reverse();
|
||||||
shooter.runShooterConveyor(Constants.Superstructure.shooterReversePercent);
|
shooter.runShooterConveyorByRPS(Constants.Superstructure.shooterReverseSpeedRps);
|
||||||
shooter.stopFlywheel();
|
shooter.stopFlywheel();
|
||||||
shooter.holdBackboardAt(0.0);
|
shooter.holdBackboardAt(0.0);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user