26
26
27
27
28
28
public class Robot extends TimedRobot {
29
- private int counter = 0 ;
29
+ // AUTONOMOUS VARIABLES
30
+ private int counter = 0 ;// TODO: Simple initialization for autonomous duration it takes to kickup counter-> can be adjusted on line 176
31
+ private boolean ready ; // Simple flag used for autonomous staging
32
+ private static final String kDefaultAuto = "Default" ; //types of autos- not used
33
+ private static final String kCustomAuto = "My Auto" ; //types of autos- not currently used
34
+ private String m_autoSelected ;
35
+ private final SendableChooser <String > m_chooser = new SendableChooser <>();
36
+ private boolean stage1 ; // auto staging
37
+
38
+ // CONSTANTS
30
39
private static final double WHEEL_DIAMETER = 6 ; // inches
31
- //NEED TO FIGURE OUT ENCODER MODEL
40
+ //NEED TO FIGURE OUT ENCODER MODEL- changes CPR for drive
32
41
private static final double cpr = 360 ; //if am-3132
33
42
//private static final double cpr = 7/4; //if am-2861a
34
43
// private static final double cpr = 5; //if am-3314a
35
44
// private static final double cpr = 1024; //if am-3445
36
45
// private static final double cpr = 64; //if am-4027
46
+ private static final double drive_dpp = (Math .PI *WHEEL_DIAMETER /cpr ); // Gives in inches per rev FOR DRIVETRAIN WHEELS ONLY
37
47
38
- private static final double drive_dpp = (Math .PI *WHEEL_DIAMETER /cpr ); // FOR DRIVETRAIN WHEELS ONLY
39
-
40
- private boolean ready ;
41
-
42
- private static final String kDefaultAuto = "Default" ;
43
- private static final String kCustomAuto = "My Auto" ;
44
-
45
- private String m_autoSelected ;
46
- private final SendableChooser <String > m_chooser = new SendableChooser <>();
48
+ // TODO: Check what motors should be inverted (.setInverted(false))
49
+ // MOTOR VARIABLES
50
+ private WPI_TalonFX leftSlave , rightSlave , leftMaster , rightMaster , climbRotation , climbExtension , shooterFly , wrist ; //Falcon 500s
51
+ private TalonSRX rollers , hood ; // 775s or BAG motors
47
52
48
- private WPI_TalonFX leftSlave , rightSlave , leftMaster , rightMaster , climbRotation , climbExtension , shooterFly , wrist ;
49
- private TalonSRX rollers , hood ;
50
- private Joystick leftJoy , rightJoy ;
51
- private XboxController controller = new XboxController (2 );
53
+ //CONTROLLERS
54
+ private Joystick leftJoy , rightJoy ; //Used for tank drive
55
+ private XboxController controller ; // Used for button man mechanism controls
52
56
53
- private AHRS gyro ;
54
-
55
- private DifferentialDrive drive ;
56
- private double nonZeroLimelightHorAng ;
57
+ // SENSORS
58
+ private AHRS gyro ; //9-axis-> used mainly to orient shooter hood using roll
57
59
58
- private Encoder rightEncoder , leftEncoder ;
59
- private DigitalInput shooterLimit ;
60
- private DigitalInput intakeLimit ;
61
-
62
- //auto variables
63
- private boolean stage1 ;
60
+ private Encoder rightEncoder , leftEncoder ; // Drivetrain encoders (might just use integrated Falcon stuff who knows)
61
+ private DigitalInput lowerShooterLimit , upperShooterLimit ; // Limit switch to reset hood to its default position
62
+ private DigitalInput intakeLimit ; // Limit switch to know if intake is ready to kickup
64
63
65
- //private ADXRS450_Gyro gyro;
66
- //private LiDARSensor liDAR;
64
+ // MISCELLANEOUS
65
+ private double nonZeroLimelightHorAng ; // Used to orient bot
66
+ private DifferentialDrive drive ; //Used for monitoring tank drive motion
67
67
68
68
/**
69
69
* This function is run when the robot is first started up and should be
70
70
* used for any initialization code.
71
71
*/
72
72
@ Override
73
73
public void robotInit () {
74
+ // STAGING FLAGS
75
+ stage1 = true ; // Auto starts in stage 1 and turns into stage 2
76
+ ready = false ; // Not ready to shoot by default
77
+
78
+ // CONTROLLER PORTS
79
+ controller = new XboxController (2 );
80
+ leftJoy = new Joystick (0 );
81
+ rightJoy = new Joystick (1 );
82
+
83
+ // Used to select autonomous mode
74
84
m_chooser .setDefaultOption ("Default Auto" , kDefaultAuto );
75
85
m_chooser .addOption ("My Auto" , kCustomAuto );
76
86
SmartDashboard .putData ("Auto choices" , m_chooser );
77
- stage1 = true ;
78
- ready = false ;
79
-
87
+
88
+ // SENSOR INITIALIZATIONS
80
89
gyro = new AHRS (SerialPort .Port .kMXP ); //SUBJECT TO CHANGE FROM ELECTRICAL COULD BE SOURCE OF ERROR
90
+ // ALL Ports subject to change from Electrical
91
+ leftEncoder = new Encoder (0 , 1 );
92
+ leftEncoder .setDistancePerPulse (drive_dpp );
93
+ rightEncoder = new Encoder (2 , 3 );
94
+ rightEncoder .setDistancePerPulse (drive_dpp );
95
+ // Limit switches- CHANGE PORTS BASED ON ELECTRICAL
96
+ lowerShooterLimit = new DigitalInput (4 );
97
+ upperShooterLimit = new DigitalInput (5 );
98
+ intakeLimit = new DigitalInput (6 );
81
99
100
+ // MOTORS
82
101
//Drivetrain motors and configuration
83
102
rightMaster = new WPI_TalonFX (RobotMap .DRIVETRAIN_FRONTRIGHT );
84
103
rightSlave = new WPI_TalonFX (RobotMap .DRIVETRAIN_BACKRIGHT );
85
104
rightSlave .follow (rightMaster );
86
105
leftMaster = new WPI_TalonFX (RobotMap .DRIVETRAIN_FRONTLEFT );
87
106
leftSlave = new WPI_TalonFX (RobotMap .DRIVETRAIN_BACKLEFT );
88
107
leftSlave .follow (leftMaster );
89
-
90
- // Used for tank and arcade drive respectively
91
- drive = new DifferentialDrive (leftMaster , rightMaster );
92
-
93
- // Default integrated sensors
108
+ // Set integrated sensor position to 0 for encoder use
94
109
leftMaster .getSensorCollection ().setIntegratedSensorPosition (0 , 10 );
95
110
rightMaster .getSensorCollection ().setIntegratedSensorPosition (0 , 10 );
96
111
97
-
98
- // ALL Ports subject to change from Electrical
99
- leftEncoder = new Encoder (0 , 1 );
100
- leftEncoder .setDistancePerPulse (drive_dpp );
101
- rightEncoder = new Encoder (2 , 3 );
102
- rightEncoder .setDistancePerPulse (drive_dpp );
103
-
104
- // Control Initializations
105
- leftJoy = new Joystick (0 );
106
- rightJoy = new Joystick (1 );
107
-
108
112
//Climb Motors
109
113
climbRotation = new WPI_TalonFX (RobotMap .CLIMBROTATION );
110
114
climbExtension = new WPI_TalonFX (RobotMap .CLIMBEXTENSION );
111
115
112
- //Shooter Motors
113
- shooterFly = new WPI_TalonFX (RobotMap .SHOOTER_FLY );
114
- shooterFly .configSelectedFeedbackSensor (TalonFXFeedbackDevice .IntegratedSensor , 0 , 1 );
115
- shooterFly .configNominalOutputForward (0 , 1 );
116
- shooterFly .configNominalOutputReverse (0 , 1 );
117
- shooterFly .configPeakOutputForward (1 , 1 );
118
- shooterFly .configPeakOutputReverse (-1 , 1 );
119
- shooterFly .setInverted (false );
120
- shooterFly .setSensorPhase (false );
121
- // config P,I,D,F values- start by doubling F, then P, then D, then I (middle values) then increase over time
122
- shooterFly .config_kF (0 , 0.007 , 1 );
123
- shooterFly .config_kP (0 , 0.8192 , 1 );
124
- shooterFly .config_kI (0 , 0.0008 , 1 );
125
- shooterFly .config_kD (0 , 0.0256 , 1 );
126
-
127
116
//Intake Motors
128
117
wrist = new WPI_TalonFX (RobotMap .INTAKE_WRIST );
129
118
rollers = new TalonSRX (RobotMap .INTAKE_ROLLERS );
130
119
131
120
//Hood Motor
132
121
hood = new TalonSRX (RobotMap .SHOOTER_HOOD );
133
122
134
- if (!shooterLimit .get ()) {
135
- hood .set (ControlMode .PercentOutput , -0.1 );
136
- }
137
- gyro .reset ();
123
+ //Shooter Motors
124
+ shooterFly = new WPI_TalonFX (RobotMap .SHOOTER_FLY );
125
+ shooterFly .configSelectedFeedbackSensor (TalonFXFeedbackDevice .IntegratedSensor , 0 , 1 ); // Tells to use in-built falcon 500 sensor
126
+ shooterFly .configNominalOutputForward (0 , 1 );
127
+ shooterFly .configNominalOutputReverse (0 , 1 );
128
+ shooterFly .configPeakOutputForward (1 , 1 );
129
+ shooterFly .configPeakOutputReverse (-1 , 1 );
130
+ shooterFly .setInverted (false );
131
+ shooterFly .setSensorPhase (false );
132
+ // config P,I,D,F values- start by doubling F, then P, then D, then I (middle values) then increase/decrease over time
133
+ shooterFly .config_kF (0 , 0.007 , 1 ); // (F) Feed Forward Term
134
+ shooterFly .config_kP (0 , 0.8192 , 1 ); // (P) Proportional Term
135
+ shooterFly .config_kI (0 , 0.0008 , 1 ); // (I) Integral term
136
+ shooterFly .config_kD (0 , 0.0256 , 1 ); // (D) Differentiable Term
137
+
138
+ // Used for tank and arcade drive respectively
139
+ drive = new DifferentialDrive (leftMaster , rightMaster );
138
140
139
- // Display information
141
+ // TODO- make this choose from sendable chooser to set alliance color
140
142
NetworkTableInstance .getDefault ().getTable ("limelight" ).getEntry ("pipeline" ).setNumber (0 ); //Sets the pipeline to 0
141
143
NetworkTableInstance .getDefault ().getTable ("limelight" ).getEntry ("camMode" ).setNumber (0 ); //Sets the Limelight as a Vision Proccesor
142
144
NetworkTableInstance .getDefault ().getTable ("TalonPi" ).getEntry ("alliance" ).setString ("red" );
@@ -154,26 +156,34 @@ public void autonomousInit() {
154
156
*/
155
157
@ Override
156
158
public void autonomousPeriodic () {
159
+ // Display information relayed by Limelight and RPM information for testing
157
160
double [][] shooterCalculations = getLimelightData ();
158
161
if (shooterCalculations != null ) {
159
162
SmartDashboard .putNumber ("Distance: " ,shooterCalculations [0 ][0 ]);
160
- SmartDashboard .putNumber ("Shooter Angle: " ,shooterCalculations [0 ][1 ]);
163
+ SmartDashboard .putNumber ("Needed Shooter Angle: " ,shooterCalculations [0 ][1 ]);
161
164
SmartDashboard .putNumber ("Ideal Ball Velocity :" ,shooterCalculations [0 ][2 ]);
162
165
SmartDashboard .putNumber ("Limelight H-Angle: " ,shooterCalculations [1 ][0 ]);
163
166
SmartDashboard .putNumber ("Limelight V-Angle: " ,shooterCalculations [1 ][1 ]);
164
167
SmartDashboard .putNumber ("Limelight Latency: " ,shooterCalculations [1 ][2 ]);
165
168
SmartDashboard .putNumber ("Flywheel RPM: " , shooterFly .getSelectedSensorVelocity ()/4 * 2048 );
169
+ SmartDashboard .putNumber ("Current Angle" , gyro .getRoll ());
166
170
}
167
171
172
+ // Resets hood to position 0 and uses that as the 0-angle.
173
+ if (!lowerShooterLimit .get ()) {
174
+ hood .set (ControlMode .PercentOutput , -0.1 );
175
+ }
176
+ gyro .reset (); //sets gyro value to 0
177
+
168
178
if ((Math .abs (shooterCalculations [0 ][0 ]) < 1.5 )) {
169
179
drive .tankDrive (-0.8 , -0.8 ); // backs up until 1.5 meters away
170
180
}
171
- if ((Math .abs (shooterCalculations [0 ][0 ]) >= 1.5 ) && (Math .abs (shooterCalculations [1 ][0 ]) > 1 )) { //adjust to reduce bouncing
181
+ if ((Math .abs (shooterCalculations [0 ][0 ]) >= 1.5 ) && (Math .abs (shooterCalculations [1 ][0 ]) > 1 )) { // TODO: adjust to reduce bouncing
172
182
centerAim ("top_hub" ); // fires a shot into the hub
173
183
}
174
184
if (Math .abs (shooterCalculations [1 ][0 ]) < 1 && (Math .abs (shooterCalculations [0 ][0 ]) >= 1.5 ) && stage1 ) {
175
- if (counter < 1000 ) { // adjust based on how long it takes to shoot a ball
176
- autoFire (); // shoots ball-> changes stage1 to false after having shot a ball
185
+ if (counter < 1000 ) { // TODO: adjust based on how long it takes to shoot a ball
186
+ fire (); // shoots ball-> changes stage1 to false after having shot a ball
177
187
counter ++;
178
188
}
179
189
else if (counter >= 1000 ) {
@@ -190,29 +200,11 @@ else if (counter >= 1000) {
190
200
}
191
201
}
192
202
193
- /**
194
- * The shooter method for auto mode
195
- */
196
-
197
203
/**
198
204
* This function is called periodically during operator control.
199
205
*/
200
206
@ Override
201
207
public void teleopPeriodic () {
202
-
203
-
204
- //xbox.setRumble(RumbleType.kLeftRumble, 0.5);
205
- //xbox.setRumble(RumbleType.kRightRumble, 0.5);
206
-
207
- // reset button
208
- if (leftJoy .getTrigger ()) {
209
- leftMaster .getSensorCollection ().setIntegratedSensorPosition (0 , 10 );
210
- rightMaster .getSensorCollection ().setIntegratedSensorPosition (0 , 10 );
211
- }
212
-
213
- if ((Math .abs (rightJoy .getY ()) > 0.2 ) || Math .abs (leftJoy .getY ()) > 0.2 ) drive .tankDrive (-rightJoy .getY (), -leftJoy .getY ());// deadzones
214
-
215
-
216
208
double [][] shooterCalculations = getLimelightData ();
217
209
if (shooterCalculations != null ) {
218
210
SmartDashboard .putNumber ("Distance: " ,shooterCalculations [0 ][0 ]);
@@ -221,14 +213,34 @@ public void teleopPeriodic() {
221
213
SmartDashboard .putNumber ("Limelight H-Angle: " ,shooterCalculations [1 ][0 ]);
222
214
SmartDashboard .putNumber ("Limelight V-Angle: " ,shooterCalculations [1 ][1 ]);
223
215
SmartDashboard .putNumber ("Limelight Latency: " ,shooterCalculations [1 ][2 ]);
216
+ SmartDashboard .putNumber ("Flywheel RPM: " , shooterFly .getSelectedSensorVelocity ()/4 * 2048 );
217
+ SmartDashboard .putNumber ("Current Angle" , gyro .getRoll ());
224
218
}
225
- if (leftJoy .getRawButton (1 )) { //center robot on top hub (retro reflector)
219
+
220
+ // Driver aims to top hub or to balls
221
+ if (leftJoy .getTrigger ()) { //center robot on top hub (retro reflector)
226
222
centerAim ("top_hub" );
227
223
}
228
- if (rightJoy .getRawButton ( 2 )) { //center robot on ball from Raspberry Pi Data
224
+ if (rightJoy .getTrigger ( )) { //center robot on ball from Raspberry Pi Data
229
225
centerAim ("ball_tracking" );
230
226
}
231
-
227
+
228
+ // DRIVE CALL
229
+ if ((Math .abs (rightJoy .getY ()) > 0.2 ) || Math .abs (leftJoy .getY ()) > 0.2 ) drive .tankDrive (-rightJoy .getY (), -leftJoy .getY ());// TODO: adjust deadzones
230
+
231
+ climbrotation ();
232
+ climb ();
233
+ if (controller .getAButton ()) fire ();
234
+ else ready = false ;
235
+ shooter ();
236
+ hood ();
237
+ wrist ();
238
+ intake ();
239
+ // Reset function (deprecated)
240
+ // if (leftJoy.getTrigger()) {
241
+ // leftMaster.getSensorCollection().setIntegratedSensorPosition(0, 10);
242
+ // rightMaster.getSensorCollection().setIntegratedSensorPosition(0, 10);
243
+ // }
232
244
}
233
245
234
246
public double [][] getLimelightData () {
@@ -294,28 +306,26 @@ public void centerAim(String target) {
294
306
}
295
307
}
296
308
297
- private boolean ballSeen () {
309
+ private boolean ballSeen () {// TODO: Sriman/Ayush code this so we know if there's a ball
298
310
return true ;
299
- } // Sriman/Ayush code this so we know if there's a ball
300
-
311
+ }
301
312
302
-
303
- //Shooter Code
304
313
public void fire () {
305
314
double transferPercent = 0.35 ;
306
315
double [][] limelightData = getLimelightData ();
307
316
double idealAngle = limelightData [0 ][1 ];
308
- double idealVelocity = limelightData [0 ][2 ];
309
- double idealRPM = (((idealVelocity *(1 /transferPercent ))/(Math .PI *0.1016 ))*60 ); // flywheel diameter in meters
317
+ double idealVelocity = limelightData [0 ][2 ]; // flywheel diameter in meters
318
+
319
+ double rpm = getRPM (idealVelocity , transferPercent );
310
320
if (!intakeLimit .get ()) {
311
321
wrist .set (ControlMode .PercentOutput , 0.75 );
312
322
}
313
- shooterFly .set (ControlMode .Velocity , 4 *idealRPM ); //Gear ratio multiplier MIGHT HAVE TO MULTIPLY BY 2048- will test later
314
- if (gyro .getRoll () > idealAngle + 5 ) { // degrees of freedom +- 5
323
+ shooterFly .set (ControlMode .Velocity , 4 *rpm ); //TODO: Gear ratio multiplier MIGHT HAVE TO MULTIPLY BY 2048- will test later
324
+ if (( gyro .getRoll () > idealAngle + 5 ) && ! upperShooterLimit . get ()) { // TODO: Adjust degrees of freedom +- 5
315
325
hood .set (ControlMode .PercentOutput , 0.1 );
316
326
ready = false ;
317
327
}
318
- else if (gyro .getRoll () < idealAngle -5 ) {
328
+ else if (( gyro .getRoll () < idealAngle -5 ) && ! lowerShooterLimit . get () ) {
319
329
hood .set (ControlMode .PercentOutput , -0.1 );
320
330
ready = false ;
321
331
}
@@ -331,41 +341,14 @@ else if (gyro.getRoll() < idealAngle-5) {
331
341
// double flywheelMotor = actualRPM/the maximum rpm of the motor; //The motor output in percentage of the flywheel motor
332
342
}
333
343
334
- public boolean autoFire () {
335
- double transferPercent = 0.35 ;
336
- double [][] limelightData = getLimelightData ();
337
- double idealAngle = limelightData [0 ][1 ];
338
- double idealVelocity = limelightData [0 ][2 ];
339
- double idealRPM = (((idealVelocity *(1 /transferPercent ))/(Math .PI *0.1016 ))*60 ); // flywheel diameter in meters
340
- if (!intakeLimit .get ()) {
341
- wrist .set (ControlMode .PercentOutput , 0.75 );
342
- }
343
- shooterFly .set (ControlMode .Velocity , 4 *idealRPM ); //Gear ratio multiplier MIGHT HAVE TO MULTIPLY BY 2048- will test later
344
- if (gyro .getRoll () > idealAngle + 5 ) { // degrees of freedom +- 5
345
- hood .set (ControlMode .PercentOutput , 0.1 );
346
- ready = false ;
347
- }
348
- else if (gyro .getRoll () < idealAngle -5 ) {
349
- hood .set (ControlMode .PercentOutput , -0.1 );
350
- ready = false ;
351
- }
352
- else {
353
- ready = true ;
354
- }
355
- if (ready ) {
356
- rollers .set (ControlMode .PercentOutput , 1 );
357
- }
358
- return false ;
359
- //adjust to fine tuning
360
- // double OneRPM = (60*idealVelocity)/(8*Math.PI); //RPM required if 100% of speed from flywheel is transferred to the ball
361
- // double actualRPM = 10*OneRPM; //RPM needed bearing 10% of velocity is transferred from flywheel to ball
362
- // double flywheelMotor = actualRPM/the maximum rpm of the motor; //The motor output in percentage of the flywheel motor
344
+ //TODO: Determines the RPM to set flywheel based on what RPM corresponds to what ball velocity
345
+ public double getRPM (double idealVelocity , double transferPercent ) {
346
+ return (((idealVelocity *(1 /transferPercent ))/(Math .PI *0.1016 ))*60 ); // rudimentary calculation that's 70% wrong
363
347
}
364
348
365
-
366
349
//Spinny part of intake, no encoder
367
350
public void intake () {
368
- if (Math .abs (controller .getRightY ()) > 0.2 ) { //Right trigger spins intake from field to robot
351
+ if (Math .abs (controller .getRightY ()) > 0.2 ) { //Right trigger spins intake from field to robot
369
352
rollers .set (ControlMode .PercentOutput , controller .getRightTriggerAxis ());
370
353
}
371
354
else if (Math .abs (controller .getRightY ()) < -0.2 ) { //Left trigger spins intake from entrance of robot to flywheel
@@ -376,6 +359,19 @@ else if(Math.abs(controller.getRightY()) < -0.2 ) { //Left trigger spins intake
376
359
}
377
360
}
378
361
362
+ // Manual hood actuation
363
+ public void hood () {
364
+ if (controller .getXButton ()) {
365
+ hood .set (ControlMode .PercentOutput , 0.1 );
366
+ }
367
+ else if (controller .getYButton ()) {
368
+ hood .set (ControlMode .PercentOutput , -0.1 );
369
+ }
370
+ else {
371
+ hood .set (ControlMode .PercentOutput , 0 );
372
+ }
373
+ }
374
+
379
375
//Wrist for intake, no encoder (for teleop)
380
376
public void wrist () {
381
377
if (controller .getBButton ()) { //sets intake in position to feed ball into flywheel
0 commit comments