13
13
import com .revrobotics .spark .config .ClosedLoopConfig .FeedbackSensor ;
14
14
import com .revrobotics .spark .config .SparkBaseConfig .IdleMode ;
15
15
import com .revrobotics .spark .config .SparkMaxConfig ;
16
+ import edu .wpi .first .math .MathUtil ;
17
+ import edu .wpi .first .math .controller .ArmFeedforward ;
16
18
import edu .wpi .first .math .controller .ProfiledPIDController ;
19
+ import edu .wpi .first .wpilibj .XboxController ;
17
20
import edu .wpi .first .wpilibj .smartdashboard .SmartDashboard ;
18
21
import edu .wpi .first .wpilibj2 .command .Command ;
19
22
import edu .wpi .first .wpilibj2 .command .FunctionalCommand ;
@@ -28,12 +31,14 @@ public class CoralWrist extends SubsystemBase {
28
31
private final SparkMaxConfig config = new SparkMaxConfig ();
29
32
private final SparkAbsoluteEncoder encoder = motor .getAbsoluteEncoder ();
30
33
31
- private final ProfiledPIDController controller =
34
+ private final ProfiledPIDController feedback =
32
35
new ProfiledPIDController (
33
36
CoralWristConstants .kP ,
34
37
CoralWristConstants .kI ,
35
38
CoralWristConstants .kD ,
36
39
CoralWristConstants .kConstraints );
40
+ private final ArmFeedforward feedforward =
41
+ new ArmFeedforward (CoralWristConstants .kS , CoralWristConstants .kG , CoralWristConstants .kV );
37
42
38
43
private CoralWristState targetState = CoralWristState .Unknown ;
39
44
@@ -49,24 +54,26 @@ public CoralWrist() {
49
54
.feedbackSensor (FeedbackSensor .kAbsoluteEncoder );
50
55
51
56
config .absoluteEncoder
52
- .inverted (false )
57
+ .inverted (false ) // TODO: determine if has any effect
53
58
.zeroCentered (false )
54
- .zeroOffset (CoralWristConstants .kPositionOffset .in (Rotations ))
59
+ .zeroOffset (CoralWristConstants .kZeroOffset .in (Rotations ))
55
60
.positionConversionFactor (CoralWristConstants .kPositionConversionFactor .in (Radians ))
56
61
.velocityConversionFactor (CoralWristConstants .kVelocityConversionFactor .in (RadiansPerSecond ));
57
62
58
63
config .softLimit
59
64
.reverseSoftLimit (CoralWristState .Min .angle .in (Radians ))
60
65
.reverseSoftLimitEnabled (true )
66
+ // .reverseSoftLimitEnabled(false)
61
67
.forwardSoftLimit (CoralWristState .Max .angle .in (Radians ))
62
68
.forwardSoftLimitEnabled (true );
69
+ // .forwardSoftLimitEnabled(false);
63
70
// spotless:on
64
71
65
72
motor .configure (config , ResetMode .kResetSafeParameters , PersistMode .kNoPersistParameters );
66
73
67
- controller .setTolerance (CoralWristConstants .kAllowableAngleError .in (Radians ));
68
- controller .setIZone (CoralWristConstants .kIZone .in (Radians ));
69
- controller .enableContinuousInput (0 , 2.0 * Math .PI );
74
+ feedback .setTolerance (CoralWristConstants .kAllowableError .in (Radians ));
75
+ feedback .setIZone (CoralWristConstants .kIZone .in (Radians ));
76
+ feedback .enableContinuousInput (0 , 2.0 * Math .PI ); // TODO: determine if has any effect
70
77
// controller.setIntegratorRange();
71
78
72
79
setDefaultCommand (createRemainAtCurrentAngleCommand ());
@@ -79,31 +86,34 @@ public void periodic() {
79
86
SmartDashboard .putNumber ("Coral Wrist/Current Angular Velocity RPS" , encoder .getVelocity ());
80
87
SmartDashboard .putString ("Coral Wrist/Target State" , getTargetState ().name ());
81
88
SmartDashboard .putNumber ("Coral Wrist/Setpoint Angle Degrees" , getSetpointAngleDegrees ());
89
+ SmartDashboard .putNumber ("Coral Wrist/Setpoint Angle Radians" , feedback .getSetpoint ().position );
82
90
SmartDashboard .putNumber (
83
- "Coral Wrist/Setpoint Angle Radians" , controller .getSetpoint ().position );
84
- SmartDashboard .putNumber (
85
- "Coral Wrist/Setpoint Angular Velocity RPS" , controller .getSetpoint ().velocity );
91
+ "Coral Wrist/Setpoint Angular Velocity RPS" , feedback .getSetpoint ().velocity );
86
92
SmartDashboard .putNumber ("Coral Wrist/Applied Duty Cycle" , motor .getAppliedOutput ());
87
93
SmartDashboard .putNumber ("Coral Wrist/Current" , motor .getOutputCurrent ());
88
- SmartDashboard .putBoolean ("Coral Wrist/At Goal" , controller .atGoal ());
94
+ SmartDashboard .putBoolean ("Coral Wrist/At Goal" , feedback .atGoal ());
89
95
}
90
96
91
97
private double getCurrentAngleDegrees () {
92
98
return Radians .of (encoder .getPosition ()).in (Degrees );
93
99
}
94
100
95
101
private double getSetpointAngleDegrees () {
96
- return Radians .of (controller .getSetpoint ().position ).in (Degrees );
102
+ return Radians .of (feedback .getSetpoint ().position ).in (Degrees );
97
103
}
98
104
99
105
public void resetController () {
100
- controller .reset (encoder .getPosition (), encoder .getVelocity ());
106
+ feedback .reset (encoder .getPosition (), encoder .getVelocity ());
101
107
}
102
108
103
109
public void control () {
110
+ double currentPosition = encoder .getPosition ();
111
+ double offsetPosition =
112
+ currentPosition + CoralWristConstants .kCenterOfGravityOffset .in (Radians );
113
+ double currentVelocitySetpoint = feedback .getSetpoint ().velocity ;
104
114
motor .setVoltage (
105
- controller .calculate (encoder . getPosition () )
106
- + CoralWristConstants . kG * Math . cos ( encoder . getPosition () ));
115
+ feedforward .calculate (offsetPosition , currentVelocitySetpoint )
116
+ + feedback . calculate ( currentPosition ));
107
117
}
108
118
109
119
public CoralWristState getTargetState () {
@@ -115,14 +125,14 @@ public Command createSetAngleCommand(CoralWristState state) {
115
125
// initialize
116
126
() -> {
117
127
targetState = state ;
118
- controller .setGoal (targetState .angle .in (Radians ));
128
+ feedback .setGoal (targetState .angle .in (Radians ));
119
129
},
120
130
// execute
121
131
() -> control (),
122
132
// end
123
133
interrupted -> {},
124
134
// isFinished
125
- () -> controller .atGoal (),
135
+ () -> feedback .atGoal (),
126
136
// requirements
127
137
this );
128
138
}
@@ -131,7 +141,7 @@ public Command createRemainAtCurrentAngleCommand() {
131
141
return new FunctionalCommand (
132
142
// initialize
133
143
() -> {
134
- if (targetState == CoralWristState .Unknown ) controller .setGoal (encoder .getPosition ());
144
+ if (targetState == CoralWristState .Unknown ) feedback .setGoal (encoder .getPosition ());
135
145
},
136
146
// execute
137
147
() -> control (),
@@ -142,4 +152,12 @@ public Command createRemainAtCurrentAngleCommand() {
142
152
// requirements
143
153
this );
144
154
}
155
+
156
+ public Command createJoystickControlCommand (XboxController gamepad ) {
157
+ return this .run (
158
+ () -> {
159
+ double joystickInput = 2.0 * MathUtil .applyDeadband (-gamepad .getLeftY (), 0.05 );
160
+ motor .setVoltage (joystickInput );
161
+ });
162
+ }
145
163
}
0 commit comments