@@ -55,11 +55,11 @@ public class Drive extends SubsystemBase {
55
55
56
56
// Drive parameters
57
57
// 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
59
59
60
60
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
63
63
64
64
private double m_initialWheelDistance = 0.0 ;
65
65
private int m_iterationsSinceRotationCommanded = 0 ;
@@ -102,39 +102,30 @@ public Drive() {
102
102
m_HeadingPid .setAbsoluteTolerance (kToleranceDegreesPIDControl );
103
103
104
104
// 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 );
109
109
110
110
// 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 );
116
113
117
114
// the left motors move the robot forwards with positive power
118
115
// but the right motors are backwards.
119
116
leftFrontTalon .setInverted (false );
120
117
leftRearTalon .setInverted (false );
121
118
rightFrontTalon .setInverted (true );
122
119
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 );
129
120
}
130
121
131
122
public void init () {
132
123
// reset the NavX
133
124
zeroHeadingGyro (0.0 );
134
125
135
126
// talon closed loop config
136
- configureCanTalon (leftFrontTalon );
137
- configureCanTalon (rightFrontTalon );
127
+ configureDriveTalon (leftFrontTalon );
128
+ configureDriveTalon (rightFrontTalon );
138
129
}
139
130
140
131
public void zeroHeadingGyro (double headingOffset ) {
@@ -155,29 +146,22 @@ public void initDefaultCommand() {
155
146
// setDefaultCommand(new SpeedRacerDrive());
156
147
}
157
148
158
- private void configureCanTalon (MayhemTalonSRX talon ) {
149
+ private void configureDriveTalon (MayhemTalonSRX talon ) {
159
150
double wheelP = 1.5 ;
160
151
double wheelI = 0.0 ;
161
152
double wheelD = 0.0 ;
162
153
double wheelF = 1.0 ;
163
154
164
155
talon .setFeedbackDevice (FeedbackDevice .IntegratedSensor );
165
-
166
- // talon.reverseSensor(false);
156
+
167
157
talon .configNominalOutputVoltage (+0.0f , -0.0f );
168
158
talon .configPeakOutputVoltage (+12.0 , -12.0 );
169
159
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
181
165
182
166
DriverStation .reportError ("setWheelPIDF: " + wheelP + " " + wheelI + " " + wheelD + " " + wheelF + "\n " , false );
183
167
}
@@ -210,16 +194,10 @@ public void toggleClosedLoopMode() {
210
194
211
195
public void setClosedLoopMode () {
212
196
m_closedLoopMode = true ;
213
- // reconfigure the "master" drive talons now that we're in closed loop mode
214
- configureCanTalon (leftFrontTalon );
215
- configureCanTalon (rightFrontTalon );
216
197
}
217
198
218
199
public void setOpenLoopMode () {
219
200
m_closedLoopMode = false ;
220
- // reconfigure the "master" drive talons now that we're in open loop mode
221
- configureCanTalon (leftFrontTalon );
222
- configureCanTalon (rightFrontTalon );
223
201
}
224
202
225
203
// ********************* ENCODER-GETTERS ************************************
@@ -417,6 +395,89 @@ public void setAutoAlignFalse() {
417
395
}
418
396
419
397
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 ) {
420
481
double leftPower , rightPower ;
421
482
double rotation = 0 ;
422
483
double adjustedSteeringX = rawSteeringX * throttle ;
@@ -498,7 +559,6 @@ public void speedRacerDrive(double throttle, double rawSteeringX, boolean quickT
498
559
leftPower = throttle + rotation ;
499
560
rightPower = throttle - rotation ;
500
561
setMotorPower (leftPower , rightPower );
501
-
502
562
}
503
563
504
564
public int stage = 0 ;
@@ -597,9 +657,9 @@ public void updateSmartDashboard() {
597
657
// b - divide by 12 (1 foot per 12 inches)
598
658
// c - multiply by distance (in inches) per pulse
599
659
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 );
601
661
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 );
603
663
604
664
SmartDashboard .putNumber ("Left Talon Output Voltage" , leftFrontTalon .getMotorOutputVoltage ());
605
665
SmartDashboard .putNumber ("Right Talon Output Voltage" , rightFrontTalon .getMotorOutputVoltage ());
0 commit comments