Skip to content

Commit a969116

Browse files
Re-scaled getThrottle() and getSteering() for increased sensitivity.
Added a SpeedRacerDriveNew for closed loop testing. Increased Climb Winch power to full power. Added soft limits for climber. Added ShooterAdjustHood() command. Removed some old methods from MayhemTalonSRX. Various minor naming fixes.
1 parent 4b6d321 commit a969116

File tree

11 files changed

+259
-116
lines changed

11 files changed

+259
-116
lines changed

src/main/java/frc/robot/Robot.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,10 @@ public class Robot extends TimedRobot {
3535
@Override
3636
@SuppressWarnings("deprecation")
3737
public void robotInit() {
38-
// Instantiate our RobotContainer. This will perform all our button bindings,
39-
// and put our
40-
// autonomous chooser on the dashboard.
38+
// Instantiate our RobotContainer. This will perform all our button bindings,
39+
// and put our autonomous chooser on the dashboard.
4140
m_robotContainer = new RobotContainer();
4241

43-
// TODO: Improve below to display something like "Code Last Loaded: 7 minutes ago"
4442
SmartDashboard.putString("Robot Loaded on:", new Date().toLocaleString());
4543
}
4644

src/main/java/org/mayheminc/robot2020/RobotContainer.java

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,15 @@ private void configureDefaultCommands() {
7575
drive.setDefaultCommand(new DriveDefault());
7676
// intake.setDefaultCommand(new IntakeExtenderVBus());
7777
magazine.setDefaultCommand(new MagazineDefault());
78+
79+
// TODO: Figure out if the current approach of "AirCompressorDefault()" is the way to go for compressor control.
80+
// KBS doesn't think the below is the right way to have the compressor be on "by default" because
81+
// it would require there to always be a command running to keep the compressor off. However, that
82+
// is a good way to ensure it doesn't get left off by accident. Not quite sure how to handle this;
83+
// would really rather that other commands which need the compressor off (such as a high-power command
84+
// which wants all the battery power available) would turn the compressor off when the command starts
85+
// and off when the command ends.) Then again, maybe the "defaultCommand" is a good way to do this
86+
// and I just don't understand the style yet.
7887
compressor.setDefaultCommand(new AirCompressorDefault());
7988
}
8089

@@ -188,22 +197,24 @@ private void configureOperatorPadButtons() {
188197
OPERATOR_PAD.OPERATOR_PAD_BUTTON_SIX.whileHeld(new IntakeSetRollers(-1.0));
189198

190199
OPERATOR_PAD.OPERATOR_PAD_BUTTON_SEVEN.whileHeld(new TurretAimToTarget());
191-
200+
OPERATOR_PAD.OPERATOR_PAD_BUTTON_EIGHT.whileHeld(new IntakeSetRollers(1.0));
201+
192202
OPERATOR_PAD.OPERATOR_PAD_BUTTON_NINE.whenPressed(new ClimberSetPistons(true));
193203
OPERATOR_PAD.OPERATOR_PAD_BUTTON_TEN.whenPressed(new ClimberSetPistons(false));
194204

195-
OPERATOR_PAD.OPERATOR_PAD_BUTTON_EIGHT.whileHeld(new IntakeSetRollers(1.0));
205+
196206
// OPERATOR_PAD.OPERATOR_PAD_D_PAD_UP.whenPressed(new
197207
// IntakeSetPosition(RobotContainer.intake.PIVOT_UP));
198208
// OPERATOR_PAD.OPERATOR_PAD_D_PAD_DOWN.whenPressed(new
199209
// IntakeSetPosition(RobotContainer.intake.PIVOT_DOWN));
200210
OPERATOR_PAD.OPERATOR_PAD_D_PAD_LEFT.whileHeld(new ShooterSetTurretVBus(-0.2));
201211
OPERATOR_PAD.OPERATOR_PAD_D_PAD_RIGHT.whileHeld(new ShooterSetTurretVBus(+0.2));
202-
OPERATOR_PAD.OPERATOR_PAD_D_PAD_UP.whileHeld(new ShooterSetHoodVBus(+1.0));
203-
OPERATOR_PAD.OPERATOR_PAD_D_PAD_DOWN.whileHeld(new ShooterSetHoodVBus(-1.0));
212+
OPERATOR_PAD.OPERATOR_PAD_D_PAD_UP.whileHeld(new ShooterAdjustHood(+1000.0));
213+
OPERATOR_PAD.OPERATOR_PAD_D_PAD_DOWN.whileHeld(new ShooterAdjustHood(-1000.0));
204214

205-
OPERATOR_PAD.OPERATOR_PAD_RIGHT_Y_AXIS_UP.whileHeld(new ClimberSetWinchesPower(0.7));
206-
OPERATOR_PAD.OPERATOR_PAD_RIGHT_Y_AXIS_DOWN.whileHeld(new ClimberSetWinchesPower(-0.7));
215+
// TODO: Consider if below should use "variable power" for climber or just always full speed?
216+
OPERATOR_PAD.OPERATOR_PAD_RIGHT_Y_AXIS_UP.whileHeld(new ClimberSetWinchesPower(1.0));
217+
OPERATOR_PAD.OPERATOR_PAD_RIGHT_Y_AXIS_DOWN.whileHeld(new ClimberSetWinchesPower(-1.0));
207218

208219
// OPERATOR_PAD.OPERATOR_PAD_LEFT_Y_AXIS_UP.whenPressed(new
209220
// MagazineSetTurntable());

src/main/java/org/mayheminc/robot2020/commands/DriveStraightOnHeading.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public DriveStraightOnHeading(double arg_targetSpeed, DistanceUnits units, doubl
3535
addRequirements(RobotContainer.drive);
3636

3737
if (units == DistanceUnits.INCHES) {
38-
arg_distance = arg_distance / Drive.DISTANCE_PER_PULSE;
38+
arg_distance = arg_distance / Drive.DISTANCE_PER_PULSE_IN_INCHES;
3939
}
4040
m_targetPower = arg_targetSpeed;
4141
m_desiredDisplacement = Math.abs(arg_distance);
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*----------------------------------------------------------------------------*/
2+
/* Copyright (c) 2019 FIRST. All Rights Reserved. */
3+
/* Open Source Software - may be modified and shared by FRC teams. The code */
4+
/* must be accompanied by the FIRST BSD license file in the root directory of */
5+
/* the project. */
6+
/*----------------------------------------------------------------------------*/
7+
8+
package org.mayheminc.robot2020.commands;
9+
10+
import org.mayheminc.robot2020.RobotContainer;
11+
12+
import edu.wpi.first.wpilibj2.command.CommandBase;
13+
14+
public class ShooterAdjustHood extends CommandBase {
15+
16+
double m_adjust;
17+
18+
/**
19+
* Creates a new ShooterAdjustHood.
20+
*/
21+
public ShooterAdjustHood(double adjust) {
22+
// Use addRequirements() here to declare subsystem dependencies.
23+
addRequirements(RobotContainer.shooter);
24+
25+
m_adjust = adjust;
26+
}
27+
28+
// Called when the command is initially scheduled.
29+
@Override
30+
public void initialize() {
31+
RobotContainer.shooter.setHoodPosition(RobotContainer.shooter.getHoodPosition() + m_adjust);
32+
}
33+
34+
// Returns true when the command should end.
35+
@Override
36+
public boolean isFinished() {
37+
return true;
38+
}
39+
}

src/main/java/org/mayheminc/robot2020/subsystems/AirCompressor.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ public class AirCompressor extends SubsystemBase {
1717
* Creates a new compressor.
1818
*/
1919
public AirCompressor() {
20+
// turn on the compressor in the constructor
21+
setCompressor(true);
2022
}
2123

2224
public void setCompressor(boolean b) {

src/main/java/org/mayheminc/robot2020/subsystems/Climber.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
import edu.wpi.first.wpilibj2.command.SubsystemBase;
1919

2020
public class Climber extends SubsystemBase {
21+
private static final int MAX_HEIGHT_SOFT_LIMIT = 640000;
22+
private static final int MIN_HEIGHT_SOFT_LIMIT = 5000;
23+
2124
private final MayhemTalonSRX winchLeft = new MayhemTalonSRX(Constants.Talon.CLIMBER_WINCH_LEFT);
2225
private final MayhemTalonSRX winchRight = new MayhemTalonSRX(Constants.Talon.CLIMBER_WINCH_RIGHT);
2326
// private final MayhemTalonSRX walkerLeft = new MayhemTalonSRX(Constants.Talon.CLIMBER_WALKER_LEFT);
@@ -37,11 +40,19 @@ public Climber() {
3740
winchLeft.configNominalOutputVoltage(+0.0f, -0.0f);
3841
winchLeft.configPeakOutputVoltage(+12.0, -12.0);
3942
winchLeft.setInverted(true);
43+
winchLeft.configForwardSoftLimitThreshold(MAX_HEIGHT_SOFT_LIMIT);
44+
winchLeft.configForwardSoftLimitEnable(true);
45+
winchLeft.configReverseSoftLimitThreshold(MIN_HEIGHT_SOFT_LIMIT);
46+
winchLeft.configReverseSoftLimitEnable(true);
4047

4148
winchRight.setNeutralMode(NeutralMode.Brake);
4249
winchRight.configNominalOutputVoltage(+0.0f, -0.0f);
4350
winchRight.configPeakOutputVoltage(+12.0, -12.0);
4451
winchRight.setInverted(false);
52+
winchRight.configForwardSoftLimitThreshold(MAX_HEIGHT_SOFT_LIMIT);
53+
winchRight.configForwardSoftLimitEnable(true);
54+
winchRight.configReverseSoftLimitThreshold(MIN_HEIGHT_SOFT_LIMIT);
55+
winchRight.configReverseSoftLimitEnable(true);
4556

4657
// walkerRight.setNeutralMode(NeutralMode.Brake);
4758
// walkerRight.configNominalOutputVoltage(+0.0f, -0.0f);
@@ -50,7 +61,6 @@ public Climber() {
5061
// walkerLeft.setNeutralMode(NeutralMode.Brake);
5162
// walkerLeft.configNominalOutputVoltage(+0.0f, -0.0f);
5263
// walkerLeft.configPeakOutputVoltage(+12.0, -12.0);
53-
5464
}
5565

5666
public void zero() {

src/main/java/org/mayheminc/robot2020/subsystems/Drive.java

Lines changed: 103 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,11 @@ public class Drive extends SubsystemBase {
5555

5656
// Drive parameters
5757
// pi * diameter * (pulley ratios) / (counts per rev * gearbox reduction)
58-
public static final double DISTANCE_PER_PULSE = 3.14 * 5.75 * 36.0 / 42.0 / (2048.0 * 7.56); // corrected for 2020
58+
public static final double DISTANCE_PER_PULSE_IN_INCHES = 3.14 * 5.75 * 36.0 / 42.0 / (2048.0 * 7.56); // corrected for 2020
5959

6060
private boolean m_closedLoopMode = false;
61-
private double m_maxWheelSpeed = 1.0; // set to 1.0 as default for "open loop" percentVBus drive
62-
private double m_voltageRampRate = 48.0;
61+
private double m_maxWheelSpeed = 1.0; // should be maximum wheel speed in native units
62+
private static final double CLOSED_LOOP_RAMP_RATE = 0.1; // time from neutral to full in seconds
6363

6464
private double m_initialWheelDistance = 0.0;
6565
private int m_iterationsSinceRotationCommanded = 0;
@@ -102,39 +102,30 @@ public Drive() {
102102
m_HeadingPid.setAbsoluteTolerance(kToleranceDegreesPIDControl);
103103

104104
// confirm all four drive talons are in coast mode
105-
leftFrontTalon.setNeutralMode(NeutralMode.Coast);
106-
leftRearTalon.setNeutralMode(NeutralMode.Coast);
107-
rightFrontTalon.setNeutralMode(NeutralMode.Coast);
108-
rightRearTalon.setNeutralMode(NeutralMode.Coast);
105+
leftFrontTalon.setNeutralMode(NeutralMode.Brake);
106+
leftRearTalon.setNeutralMode(NeutralMode.Brake);
107+
rightFrontTalon.setNeutralMode(NeutralMode.Brake);
108+
rightRearTalon.setNeutralMode(NeutralMode.Brake);
109109

110110
// set rear talons to follow their respective front talons
111-
leftRearTalon.changeControlMode(ControlMode.Follower);
112-
leftRearTalon.set(leftFrontTalon.getDeviceID());
113-
114-
rightRearTalon.changeControlMode(ControlMode.Follower);
115-
rightRearTalon.set(rightFrontTalon.getDeviceID());
111+
leftRearTalon.follow(leftFrontTalon);
112+
rightRearTalon.follow(rightFrontTalon);
116113

117114
// the left motors move the robot forwards with positive power
118115
// but the right motors are backwards.
119116
leftFrontTalon.setInverted(false);
120117
leftRearTalon.setInverted(false);
121118
rightFrontTalon.setInverted(true);
122119
rightRearTalon.setInverted(true);
123-
124-
// sensor phase is reversed, since there are 3 reduction stages in the gearbox
125-
leftFrontTalon.setSensorPhase(true);
126-
leftRearTalon.setSensorPhase(true);
127-
rightFrontTalon.setSensorPhase(true);
128-
rightRearTalon.setSensorPhase(true);
129120
}
130121

131122
public void init() {
132123
// reset the NavX
133124
zeroHeadingGyro(0.0);
134125

135126
// talon closed loop config
136-
configureCanTalon(leftFrontTalon);
137-
configureCanTalon(rightFrontTalon);
127+
configureDriveTalon(leftFrontTalon);
128+
configureDriveTalon(rightFrontTalon);
138129
}
139130

140131
public void zeroHeadingGyro(double headingOffset) {
@@ -155,29 +146,22 @@ public void initDefaultCommand() {
155146
// setDefaultCommand(new SpeedRacerDrive());
156147
}
157148

158-
private void configureCanTalon(MayhemTalonSRX talon) {
149+
private void configureDriveTalon(MayhemTalonSRX talon) {
159150
double wheelP = 1.5;
160151
double wheelI = 0.0;
161152
double wheelD = 0.0;
162153
double wheelF = 1.0;
163154

164155
talon.setFeedbackDevice(FeedbackDevice.IntegratedSensor);
165-
166-
// talon.reverseSensor(false);
156+
167157
talon.configNominalOutputVoltage(+0.0f, -0.0f);
168158
talon.configPeakOutputVoltage(+12.0, -12.0);
169159

170-
if (m_closedLoopMode) {
171-
talon.changeControlMode(ControlMode.Velocity);
172-
m_maxWheelSpeed = 270;
173-
} else {
174-
talon.changeControlMode(ControlMode.PercentOutput);
175-
m_maxWheelSpeed = 1.0;
176-
}
177-
178-
talon.setPID(wheelP, wheelI, wheelD, wheelF, 0, m_voltageRampRate, 0);
179-
180-
// talon.enableControl();
160+
talon.config_kP(0, wheelP);
161+
talon.config_kI(0, wheelI);
162+
talon.config_kD(0, wheelD);
163+
talon.config_kF(0, wheelF);
164+
talon.configClosedloopRamp(CLOSED_LOOP_RAMP_RATE); // specify minimum time for neutral to full in seconds
181165

182166
DriverStation.reportError("setWheelPIDF: " + wheelP + " " + wheelI + " " + wheelD + " " + wheelF + "\n", false);
183167
}
@@ -210,16 +194,10 @@ public void toggleClosedLoopMode() {
210194

211195
public void setClosedLoopMode() {
212196
m_closedLoopMode = true;
213-
// reconfigure the "master" drive talons now that we're in closed loop mode
214-
configureCanTalon(leftFrontTalon);
215-
configureCanTalon(rightFrontTalon);
216197
}
217198

218199
public void setOpenLoopMode() {
219200
m_closedLoopMode = false;
220-
// reconfigure the "master" drive talons now that we're in open loop mode
221-
configureCanTalon(leftFrontTalon);
222-
configureCanTalon(rightFrontTalon);
223201
}
224202

225203
// ********************* ENCODER-GETTERS ************************************
@@ -417,6 +395,89 @@ public void setAutoAlignFalse() {
417395
}
418396

419397
public void speedRacerDrive(double throttle, double rawSteeringX, boolean quickTurn) {
398+
speedRacerDriveNew(throttle, rawSteeringX, quickTurn);
399+
}
400+
401+
402+
public void speedRacerDriveNew(double throttle, double rawSteeringX, boolean quickTurn) {
403+
double leftPower, rightPower;
404+
double rotation = 0;
405+
final double QUICK_TURN_GAIN = 0.55; // 2019: .75. 2020: .75 was too fast.
406+
407+
int throttleSign;
408+
if (throttle >= 0.0) {
409+
throttleSign = 1;
410+
} else {
411+
throttleSign = -1;
412+
}
413+
414+
// check for if steering input is essentially zero for "DriveStraight" functionality
415+
if ((-0.01 < rawSteeringX) && (rawSteeringX < 0.01)) {
416+
// no turn being commanded, drive straight or stay still
417+
m_iterationsSinceRotationCommanded++;
418+
if ((-0.01 < throttle) && (throttle < 0.01)) {
419+
// no motion commanded, stay still
420+
m_iterationsSinceMovementCommanded++;
421+
rotation = 0.0;
422+
m_desiredHeading = getHeading(); // whenever motionless, set desired heading to current heading
423+
// reset the PID controller loop now that we have a new desired heading
424+
resetAndEnableHeadingPID();
425+
} else {
426+
// driving straight
427+
if ((m_iterationsSinceRotationCommanded == LOOPS_GYRO_DELAY)
428+
|| (m_iterationsSinceMovementCommanded >= LOOPS_GYRO_DELAY)) {
429+
// exactly LOOPS_GYRO_DELAY iterations with no commanded turn,
430+
// or haven't had movement commanded for longer than LOOPS_GYRO_DELAY,
431+
// so we want to take steps to preserve our current heading hereafter
432+
433+
// get current heading as desired heading
434+
m_desiredHeading = getHeading();
435+
436+
// reset the PID controller loop now that we have a new desired heading
437+
resetAndEnableHeadingPID();
438+
rotation = 0.0;
439+
} else if (m_iterationsSinceRotationCommanded < LOOPS_GYRO_DELAY) {
440+
// not long enough since we were last turning,
441+
// just drive straight without special heading maintenance
442+
rotation = 0.0;
443+
} else if (m_iterationsSinceRotationCommanded > LOOPS_GYRO_DELAY) {
444+
// after more then LOOPS_GYRO_DELAY iterations since commanded turn,
445+
// maintain the target heading
446+
rotation = maintainHeading();
447+
}
448+
m_iterationsSinceMovementCommanded = 0;
449+
}
450+
} else {
451+
// commanding a turn, reset iterationsSinceRotationCommanded
452+
m_iterationsSinceRotationCommanded = 0;
453+
m_iterationsSinceMovementCommanded = 0;
454+
}
455+
456+
if (quickTurn) {
457+
// want a high-rate turn (also allows "spin" behavior)
458+
// power to each wheel is a combination of the throttle and rotation
459+
rotation = rawSteeringX * throttleSign * QUICK_TURN_GAIN;
460+
leftPower = throttle + rotation;
461+
rightPower = throttle - rotation;
462+
} else {
463+
// want a standard rate turn (scaled by the throttle)
464+
if (rawSteeringX >= 0.0) {
465+
// turning to the right, derate the right power by turn amount
466+
// note that rawSteeringX is positive in this portion of the "if"
467+
leftPower = throttle;
468+
rightPower = throttle * (1.0 - Math.abs(rawSteeringX));
469+
} else {
470+
// turning to the left, derate the left power by turn amount
471+
// note that rawSteeringX is negative in this portion of the "if"
472+
leftPower = throttle * (1.0 - Math.abs(rawSteeringX));
473+
rightPower = throttle;
474+
}
475+
}
476+
setMotorPower(leftPower, rightPower);
477+
}
478+
479+
480+
public void speedRacerDriveOld(double throttle, double rawSteeringX, boolean quickTurn) {
420481
double leftPower, rightPower;
421482
double rotation = 0;
422483
double adjustedSteeringX = rawSteeringX * throttle;
@@ -498,7 +559,6 @@ public void speedRacerDrive(double throttle, double rawSteeringX, boolean quickT
498559
leftPower = throttle + rotation;
499560
rightPower = throttle - rotation;
500561
setMotorPower(leftPower, rightPower);
501-
502562
}
503563

504564
public int stage = 0;
@@ -597,9 +657,9 @@ public void updateSmartDashboard() {
597657
// b - divide by 12 (1 foot per 12 inches)
598658
// c - multiply by distance (in inches) per pulse
599659
SmartDashboard.putNumber("Left Speed (fps)",
600-
leftFrontTalon.getSelectedSensorVelocity(0) * 10 / 12 * DISTANCE_PER_PULSE);
660+
leftFrontTalon.getSelectedSensorVelocity(0) * 10 / 12 * DISTANCE_PER_PULSE_IN_INCHES);
601661
SmartDashboard.putNumber("Right Speed (fps)",
602-
rightFrontTalon.getSelectedSensorVelocity(0) * 10 / 12 * DISTANCE_PER_PULSE);
662+
rightFrontTalon.getSelectedSensorVelocity(0) * 10 / 12 * DISTANCE_PER_PULSE_IN_INCHES);
603663

604664
SmartDashboard.putNumber("Left Talon Output Voltage", leftFrontTalon.getMotorOutputVoltage());
605665
SmartDashboard.putNumber("Right Talon Output Voltage", rightFrontTalon.getMotorOutputVoltage());

0 commit comments

Comments
 (0)