@@ -44,57 +44,50 @@ public final class PositionalMotor<P extends Enum<P> & Supplier<Angle>> implemen
4444 /**
4545 * Creates a new builder for a {@code PositionalMotor}.
4646 *
47- * <p>The default acceptable error is {@value #DEFAULT_ERROR} and the PID constants are set to 0.
47+ * <p>The default acceptable error is {@value #DEFAULT_ERROR}, the PID constants are set to 0, and
48+ * the rotational unit is set to {@link edu.wpi.first.units.Units#Rotations}.
4849 *
4950 * @param periodicRegistry periodic registry that the motor should use
5051 * @param motor the motor to control
5152 * @param encoder the encoder providing feedback
52- * @param initialPosition the initial position of the controller
5353 * @return builder instance
5454 */
55- public static <P extends Enum <P > & Supplier <Angle >> Builder <P > builder (
56- PeriodicRegistry periodicRegistry , Motor motor , Encoder encoder , P initialPosition ) {
57- return new Builder <>(periodicRegistry , motor , encoder , initialPosition );
55+ public static Builder builder (PeriodicRegistry periodicRegistry , Motor motor , Encoder encoder ) {
56+ return new Builder (periodicRegistry , motor , encoder );
5857 }
5958
6059 /**
6160 * Creates a new builder for a {@code PositionalMotor} using a motor that has a built-in encoder.
6261 *
63- * <p>The default acceptable error is {@value #DEFAULT_ERROR} and the PID constants are set to 0.
62+ * <p>The default acceptable error is {@value #DEFAULT_ERROR},the PID constants are set to 0, and
63+ * the rotational unit is set to {@link edu.wpi.first.units.Units#Rotations}.
6464 *
6565 * @param periodicRegistry periodic registry that the motor should use
6666 * @param motor the integrated motor controller
67- * @param initialPosition the initial position of the controller
6867 * @return builder instance
6968 */
70- public static <P extends Enum <P > & Supplier <Angle >> Builder <P > builder (
71- PeriodicRegistry periodicRegistry , PIDMotor motor , P initialPosition ) {
72- return new Builder <>(periodicRegistry , motor , motor , initialPosition );
69+ public static Builder builder (PeriodicRegistry periodicRegistry , PIDMotor motor ) {
70+ return new Builder (periodicRegistry , motor , motor );
7371 }
7472
7573 /** A builder for a {@code PositionalMotor}. */
76- public static class Builder < P extends Enum < P > & Supplier < Angle >> {
74+ public static class Builder {
7775
7876 private final PeriodicRegistry periodicRegistry ;
7977 private final Motor motor ;
8078 private final Encoder encoder ;
81- private double initialPosition ;
8279 private ControlMode controlMode = ControlMode .DUTY_CYCLE ;
8380 private AngleUnit rotationUnit = Units .Rotations ;
8481 private PIDController controller ;
8582 private double acceptableError = DEFAULT_ERROR ;
8683 private Clamper clamper = value -> value ;
8784 private NetworkTable networkTable ;
8885
89- private Builder (
90- PeriodicRegistry periodicRegistry , Motor motor , Encoder encoder , P initialPosition ) {
86+ private Builder (PeriodicRegistry periodicRegistry , Motor motor , Encoder encoder ) {
9187 this .periodicRegistry =
9288 Objects .requireNonNull (periodicRegistry , "periodicRegistry should not be null" );
9389 this .motor = Objects .requireNonNull (motor , "motor should not be null" );
9490 this .encoder = Objects .requireNonNull (encoder , "encoder should not be null" );
95- Objects .requireNonNull (initialPosition , "initialPosition should not be null" );
96- this .initialPosition = initialPosition .get ().in (rotationUnit );
97- controller = new PIDController (0 , 0 , 0 );
9891 }
9992
10093 /**
@@ -103,8 +96,12 @@ private Builder(
10396 * @param controller The PID controller
10497 * @return {@code this} for chaining
10598 */
106- public Builder <P > controller (PIDController controller ) {
107- this .controller = Objects .requireNonNull (controller , "controller should not be null" );
99+ public Builder controller (PIDController controller ) {
100+ Objects .requireNonNull (controller , "controller should not be null" );
101+ if (this .controller != null ) {
102+ this .controller .close ();
103+ }
104+ this .controller = controller ;
108105 return this ;
109106 }
110107
@@ -116,7 +113,7 @@ public Builder<P> controller(PIDController controller) {
116113 * @return {@code this} for chaining
117114 * @throws IllegalArgumentException If {@code controlMode} is for positional control
118115 */
119- public Builder < P > controlMode (ControlMode controlMode ) {
116+ public Builder controlMode (ControlMode controlMode ) {
120117 if (controlMode .isPositionalControl ()) {
121118 throw new IllegalArgumentException (
122119 String .format (
@@ -136,8 +133,12 @@ public Builder<P> controlMode(ControlMode controlMode) {
136133 * @param d the derivative
137134 * @return {@code this} for chaining
138135 */
139- public Builder <P > PID (double p , double i , double d ) {
140- controller .setPID (p , i , d );
136+ public Builder PID (double p , double i , double d ) {
137+ if (controller == null ) {
138+ controller = new PIDController (p , i , d );
139+ } else {
140+ controller .setPID (p , i , d );
141+ }
141142 return this ;
142143 }
143144
@@ -146,7 +147,7 @@ public Builder<P> PID(double p, double i, double d) {
146147 *
147148 * @return {@code this} for chaining
148149 */
149- public Builder < P > acceptableError (double error ) {
150+ public Builder acceptableError (double error ) {
150151 this .acceptableError = error ;
151152 return this ;
152153 }
@@ -157,7 +158,7 @@ public Builder<P> acceptableError(double error) {
157158 * @param clamper Function to use to clamp output values
158159 * @return {@code this} for chaining
159160 */
160- public Builder < P > clamper (Clamper clamper ) {
161+ public Builder clamper (Clamper clamper ) {
161162 this .clamper = Objects .requireNonNull (clamper , "clamper should not be null" );
162163 return this ;
163164 }
@@ -167,8 +168,7 @@ public Builder<P> clamper(Clamper clamper) {
167168 *
168169 * @param rotationUnit The angle unit to use for calculations
169170 */
170- public Builder <P > rotationUnit (AngleUnit rotationUnit ) {
171- initialPosition = rotationUnit .convertFrom (initialPosition , this .rotationUnit );
171+ public Builder rotationUnit (AngleUnit rotationUnit ) {
172172 this .rotationUnit = rotationUnit ;
173173 return this ;
174174 }
@@ -179,18 +179,26 @@ public Builder<P> rotationUnit(AngleUnit rotationUnit) {
179179 * @param networkTable Table to publish to
180180 * @return {@code this} for chaining
181181 */
182- public Builder < P > publishTo (NetworkTable networkTable ) {
182+ public Builder publishTo (NetworkTable networkTable ) {
183183 this .networkTable = Objects .requireNonNull (networkTable , "networkTable should not be null" );
184184 return this ;
185185 }
186186
187- /** Builds a {@code PositionalMotor} using the current values of this builder. */
188- public PositionalMotor <P > build () {
189- return new PositionalMotor <>(this );
187+ /**
188+ * Builds a {@code PositionalMotor} using the current values of this builder.
189+ *
190+ * @param initialPosition the initial position of the controller
191+ */
192+ public <P extends Enum <P > & Supplier <Angle >> PositionalMotor <P > build (P initialPosition ) {
193+ Objects .requireNonNull (initialPosition , "initialPosition should not be null" );
194+ if (controller == null ) {
195+ controller = new PIDController (0 , 0 , 0 );
196+ }
197+ return new PositionalMotor <>(this , initialPosition );
190198 }
191199 }
192200
193- private PositionalMotor (Builder < P > builder ) {
201+ private PositionalMotor (Builder builder , P initialPosition ) {
194202 controller = builder .controller ;
195203 acceptableError = builder .acceptableError ;
196204 motor = builder .motor ;
@@ -205,11 +213,10 @@ private PositionalMotor(Builder<P> builder) {
205213 publishers = null ;
206214 }
207215
208- controller .setTolerance (builder .acceptableError );
209- controller .setSetpoint (builder .initialPosition );
210- encoder .setPosition (rotationUnit .of (builder .initialPosition ));
211-
212- // TODO: Should we update the position of the controller using controller.calculate()?
216+ controller .setTolerance (acceptableError );
217+ double initialPositionAsDouble = initialPosition .get ().in (rotationUnit );
218+ controller .setSetpoint (initialPositionAsDouble );
219+ encoder .setPosition (rotationUnit .of (initialPositionAsDouble ));
213220
214221 builder .periodicRegistry .addPeriodic (this ::periodic );
215222 }
0 commit comments