001/*
002 * Copyright (C) Cross The Road Electronics.  All rights reserved.
003 * License information can be found in CTRE_LICENSE.txt
004 * For support and suggestions contact support@ctr-electronics.com or file
005 * an issue tracker at https://github.com/CrossTheRoadElec/Phoenix-Releases
006 */
007package com.ctre.phoenix6.swerve;
008
009import com.ctre.phoenix6.configs.ClosedLoopGeneralConfigs;
010import com.ctre.phoenix6.configs.CurrentLimitsConfigs;
011import com.ctre.phoenix6.configs.FeedbackConfigs;
012import com.ctre.phoenix6.configs.MagnetSensorConfigs;
013import com.ctre.phoenix6.configs.MotionMagicConfigs;
014import com.ctre.phoenix6.configs.MotorOutputConfigs;
015import com.ctre.phoenix6.configs.ParentConfiguration;
016import com.ctre.phoenix6.configs.Slot0Configs;
017import com.ctre.phoenix6.configs.TorqueCurrentConfigs;
018import com.ctre.phoenix6.swerve.SwerveModuleConstants.ClosedLoopOutputType;
019import com.ctre.phoenix6.swerve.SwerveModuleConstants.DriveMotorArrangement;
020import com.ctre.phoenix6.swerve.SwerveModuleConstants.SteerFeedbackType;
021import com.ctre.phoenix6.swerve.SwerveModuleConstants.SteerMotorArrangement;
022
023import edu.wpi.first.units.measure.*;
024import static edu.wpi.first.units.Units.*;
025
026/**
027 * Constants that are common across the swerve modules, used
028 * for creating instances of module-specific {@link SwerveModuleConstants}.
029 */
030public class SwerveModuleConstantsFactory<
031    DriveMotorConfigsT extends ParentConfiguration,
032    SteerMotorConfigsT extends ParentConfiguration,
033    EncoderConfigsT extends ParentConfiguration
034> {
035    /**
036     * Gear ratio between the drive motor and the wheel.
037     */
038    public double DriveMotorGearRatio = 0;
039    /**
040     * Gear ratio between the steer motor and the azimuth encoder. For example, the
041     * SDS Mk4 has a steering ratio of 12.8.
042     */
043    public double SteerMotorGearRatio = 0;
044    /**
045     * Coupled gear ratio between the azimuth encoder and the drive motor.
046     * <p>
047     * For a typical swerve module, the azimuth turn motor also drives the wheel a
048     * nontrivial amount, which affects the accuracy of odometry and control. This
049     * ratio represents the number of rotations of the drive motor caused by a
050     * rotation of the azimuth.
051     */
052    public double CouplingGearRatio = 0;
053    /**
054     * Radius of the driving wheel in meters.
055     */
056    public double WheelRadius = 0;
057    /**
058     * The steer motor closed-loop gains.
059     * <p>
060     * The steer motor uses the control ouput type specified by {@link
061     * #SteerMotorClosedLoopOutput} and any {@link SwerveModule.SteerRequestType}.
062     * These gains operate on azimuth rotations (after the gear ratio).
063     */
064    public Slot0Configs SteerMotorGains = new Slot0Configs();
065    /**
066     * The drive motor closed-loop gains.
067     * <p>
068     * When using closed-loop control, the drive motor uses the control output type
069     * specified by {@link #DriveMotorClosedLoopOutput} and any closed-loop {@link
070     * SwerveModule.DriveRequestType}. These gains operate on motor rotor rotations
071     * (before the gear ratio).
072     */
073    public Slot0Configs DriveMotorGains = new Slot0Configs();
074    /**
075     * The closed-loop output type to use for the steer motors.
076     */
077    public ClosedLoopOutputType SteerMotorClosedLoopOutput = ClosedLoopOutputType.Voltage;
078    /**
079     * The closed-loop output type to use for the drive motors.
080     */
081    public ClosedLoopOutputType DriveMotorClosedLoopOutput = ClosedLoopOutputType.Voltage;
082    /**
083     * The maximum amount of stator current the drive motors can apply without
084     * slippage.
085     */
086    public double SlipCurrent = 120;
087    /**
088     * When using open-loop drive control, this specifies the measured speed at
089     * which the robot travels when driven with 12 volts. This is used to
090     * approximate the output for a desired velocity; it cannot be used to change
091     * the desired max speed of the robot. If using closed loop control, this value
092     * is ignored.
093     */
094    public double SpeedAt12Volts = 0;
095    /**
096     * Choose the motor used for the drive motor.
097     * <p>
098     * If using a Talon FX, this should be set to TalonFX_Integrated. If using a
099     * Talon FXS, this should be set to the motor attached to the Talon FXS.
100     */
101    public DriveMotorArrangement DriveMotorType = DriveMotorArrangement.TalonFX_Integrated;
102    /**
103     * Choose the motor used for the steer motor.
104     * <p>
105     * If using a Talon FX, this should be set to TalonFX_Integrated. If using a
106     * Talon FXS, this should be set to the motor attached to the Talon FXS.
107     */
108    public SteerMotorArrangement SteerMotorType = SteerMotorArrangement.TalonFX_Integrated;
109    /**
110     * Choose how the feedback sensors should be configured.
111     * <p>
112     * If the robot does not support Pro, then this should be set to RemoteCANcoder.
113     * Otherwise, users have the option to use either FusedCANcoder or SyncCANcoder
114     * depending on if there is a risk that the CANcoder can fail in a way to
115     * provide "good" data.
116     * <p>
117     * If this is set to FusedCANcoder or SyncCANcoder when the steer motor is not
118     * Pro-licensed, the device will automatically fall back to RemoteCANcoder and
119     * report a UsingProFeatureOnUnlicensedDevice status code.
120     */
121    public SteerFeedbackType FeedbackSource = SteerFeedbackType.FusedCANcoder;
122    /**
123     * The initial configs used to configure the drive motor of the swerve module.
124     * The default value is the factory-default.
125     * <p>
126     * Users may change the initial configuration as they need. Any config that's
127     * not referenced in the {@link SwerveModuleConstants} class is available to be
128     * changed.
129     * <p>
130     * The list of configs that will be overwritten is as follows:
131     * 
132     * <ul>
133     *   <li> {@link MotorOutputConfigs#NeutralMode} (Brake mode, overwritten with
134     *        {@link SwerveDrivetrain#configNeutralMode})
135     *   <li> {@link MotorOutputConfigs#Inverted} ({@link
136     *        SwerveModuleConstants#DriveMotorInverted})
137     *   <li> {@link Slot0Configs} ({@link #DriveMotorGains})
138     *   <li> {@link CurrentLimitsConfigs#StatorCurrentLimit} / {@link
139     *        TorqueCurrentConfigs#PeakForwardTorqueCurrent} / {@link
140     *        TorqueCurrentConfigs#PeakReverseTorqueCurrent} ({@link #SlipCurrent})
141     *   <li> {@link CurrentLimitsConfigs#StatorCurrentLimitEnable} (Enabled)
142     *   <li> {@link FeedbackConfigs#RotorToSensorRatio} / {@link
143     *        FeedbackConfigs#SensorToMechanismRatio} (1.0)
144     * </ul>
145     * 
146     */
147    public DriveMotorConfigsT DriveMotorInitialConfigs = null;
148    /**
149     * The initial configs used to configure the steer motor of the swerve module.
150     * The default value is the factory-default.
151     * <p>
152     * Users may change the initial configuration as they need. Any config that's
153     * not referenced in the {@link SwerveModuleConstants} class is available to be
154     * changed.
155     * <p>
156     * The list of configs that will be overwritten is as follows:
157     * 
158     * <ul>
159     *   <li> {@link MotorOutputConfigs#NeutralMode} (Brake mode)
160     *   <li> {@link MotorOutputConfigs#Inverted} ({@link
161     *        SwerveModuleConstants#SteerMotorInverted})
162     *   <li> {@link Slot0Configs} ({@link #SteerMotorGains})
163     *   <li> {@link FeedbackConfigs#FeedbackRemoteSensorID} ({@link
164     *        SwerveModuleConstants#EncoderId})
165     *   <li> {@link FeedbackConfigs#FeedbackSensorSource} ({@link #FeedbackSource})
166     *   <li> {@link FeedbackConfigs#RotorToSensorRatio} ({@link
167     *        #SteerMotorGearRatio})
168     *   <li> {@link FeedbackConfigs#SensorToMechanismRatio} (1.0)
169     *   <li> {@link MotionMagicConfigs#MotionMagicExpo_kV} / {@link
170     *        MotionMagicConfigs#MotionMagicExpo_kA} (Calculated from gear ratios)
171     *   <li> {@link ClosedLoopGeneralConfigs#ContinuousWrap} (true)
172     * </ul>
173     * 
174     */
175    public SteerMotorConfigsT SteerMotorInitialConfigs = null;
176    /**
177     * The initial configs used to configure the azimuth encoder of the swerve
178     * module. The default value is the factory-default.
179     * <p>
180     * Users may change the initial configuration as they need. Any config that's
181     * not referenced in the {@link SwerveModuleConstants} class is available to be
182     * changed.
183     * <p>
184     * For CANcoder, the list of configs that will be overwritten is as follows:
185     * 
186     * <ul>
187     *   <li> {@link MagnetSensorConfigs#MagnetOffset} ({@link
188     *        SwerveModuleConstants#EncoderOffset})
189     *   <li> {@link MagnetSensorConfigs#SensorDirection} ({@link
190     *        SwerveModuleConstants#EncoderInverted})
191     * </ul>
192     * 
193     */
194    public EncoderConfigsT EncoderInitialConfigs = null;
195    /**
196     * Simulated azimuthal inertia.
197     */
198    public double SteerInertia = 0.01;
199    /**
200     * Simulated drive inertia.
201     */
202    public double DriveInertia = 0.035;
203    /**
204     * Simulated steer voltage required to overcome friction.
205     */
206    public double SteerFrictionVoltage = 0.2;
207    /**
208     * Simulated drive voltage required to overcome friction.
209     */
210    public double DriveFrictionVoltage = 0.2;
211    
212    /**
213     * Modifies the DriveMotorGearRatio parameter and returns itself.
214     * <p>
215     * Gear ratio between the drive motor and the wheel.
216     *
217     * @param newDriveMotorGearRatio Parameter to modify
218     * @return this object
219     */
220    public SwerveModuleConstantsFactory<DriveMotorConfigsT, SteerMotorConfigsT, EncoderConfigsT> withDriveMotorGearRatio(double newDriveMotorGearRatio) {
221        this.DriveMotorGearRatio = newDriveMotorGearRatio;
222        return this;
223    }
224    
225    /**
226     * Modifies the SteerMotorGearRatio parameter and returns itself.
227     * <p>
228     * Gear ratio between the steer motor and the azimuth encoder. For example, the
229     * SDS Mk4 has a steering ratio of 12.8.
230     *
231     * @param newSteerMotorGearRatio Parameter to modify
232     * @return this object
233     */
234    public SwerveModuleConstantsFactory<DriveMotorConfigsT, SteerMotorConfigsT, EncoderConfigsT> withSteerMotorGearRatio(double newSteerMotorGearRatio) {
235        this.SteerMotorGearRatio = newSteerMotorGearRatio;
236        return this;
237    }
238    
239    /**
240     * Modifies the CouplingGearRatio parameter and returns itself.
241     * <p>
242     * Coupled gear ratio between the azimuth encoder and the drive motor.
243     * <p>
244     * For a typical swerve module, the azimuth turn motor also drives the wheel a
245     * nontrivial amount, which affects the accuracy of odometry and control. This
246     * ratio represents the number of rotations of the drive motor caused by a
247     * rotation of the azimuth.
248     *
249     * @param newCouplingGearRatio Parameter to modify
250     * @return this object
251     */
252    public SwerveModuleConstantsFactory<DriveMotorConfigsT, SteerMotorConfigsT, EncoderConfigsT> withCouplingGearRatio(double newCouplingGearRatio) {
253        this.CouplingGearRatio = newCouplingGearRatio;
254        return this;
255    }
256    
257    /**
258     * Modifies the WheelRadius parameter and returns itself.
259     * <p>
260     * Radius of the driving wheel in meters.
261     *
262     * @param newWheelRadius Parameter to modify
263     * @return this object
264     */
265    public SwerveModuleConstantsFactory<DriveMotorConfigsT, SteerMotorConfigsT, EncoderConfigsT> withWheelRadius(double newWheelRadius) {
266        this.WheelRadius = newWheelRadius;
267        return this;
268    }
269    
270    /**
271     * Modifies the WheelRadius parameter and returns itself.
272     * <p>
273     * Radius of the driving wheel in meters.
274     *
275     * @param newWheelRadius Parameter to modify
276     * @return this object
277     */
278    public SwerveModuleConstantsFactory<DriveMotorConfigsT, SteerMotorConfigsT, EncoderConfigsT> withWheelRadius(Distance newWheelRadius) {
279        this.WheelRadius = newWheelRadius.in(Meters);
280        return this;
281    }
282    
283    /**
284     * Modifies the SteerMotorGains parameter and returns itself.
285     * <p>
286     * The steer motor closed-loop gains.
287     * <p>
288     * The steer motor uses the control ouput type specified by {@link
289     * #SteerMotorClosedLoopOutput} and any {@link SwerveModule.SteerRequestType}.
290     * These gains operate on azimuth rotations (after the gear ratio).
291     *
292     * @param newSteerMotorGains Parameter to modify
293     * @return this object
294     */
295    public SwerveModuleConstantsFactory<DriveMotorConfigsT, SteerMotorConfigsT, EncoderConfigsT> withSteerMotorGains(Slot0Configs newSteerMotorGains) {
296        this.SteerMotorGains = newSteerMotorGains;
297        return this;
298    }
299    
300    /**
301     * Modifies the DriveMotorGains parameter and returns itself.
302     * <p>
303     * The drive motor closed-loop gains.
304     * <p>
305     * When using closed-loop control, the drive motor uses the control output type
306     * specified by {@link #DriveMotorClosedLoopOutput} and any closed-loop {@link
307     * SwerveModule.DriveRequestType}. These gains operate on motor rotor rotations
308     * (before the gear ratio).
309     *
310     * @param newDriveMotorGains Parameter to modify
311     * @return this object
312     */
313    public SwerveModuleConstantsFactory<DriveMotorConfigsT, SteerMotorConfigsT, EncoderConfigsT> withDriveMotorGains(Slot0Configs newDriveMotorGains) {
314        this.DriveMotorGains = newDriveMotorGains;
315        return this;
316    }
317    
318    /**
319     * Modifies the SteerMotorClosedLoopOutput parameter and returns itself.
320     * <p>
321     * The closed-loop output type to use for the steer motors.
322     *
323     * @param newSteerMotorClosedLoopOutput Parameter to modify
324     * @return this object
325     */
326    public SwerveModuleConstantsFactory<DriveMotorConfigsT, SteerMotorConfigsT, EncoderConfigsT> withSteerMotorClosedLoopOutput(ClosedLoopOutputType newSteerMotorClosedLoopOutput) {
327        this.SteerMotorClosedLoopOutput = newSteerMotorClosedLoopOutput;
328        return this;
329    }
330    
331    /**
332     * Modifies the DriveMotorClosedLoopOutput parameter and returns itself.
333     * <p>
334     * The closed-loop output type to use for the drive motors.
335     *
336     * @param newDriveMotorClosedLoopOutput Parameter to modify
337     * @return this object
338     */
339    public SwerveModuleConstantsFactory<DriveMotorConfigsT, SteerMotorConfigsT, EncoderConfigsT> withDriveMotorClosedLoopOutput(ClosedLoopOutputType newDriveMotorClosedLoopOutput) {
340        this.DriveMotorClosedLoopOutput = newDriveMotorClosedLoopOutput;
341        return this;
342    }
343    
344    /**
345     * Modifies the SlipCurrent parameter and returns itself.
346     * <p>
347     * The maximum amount of stator current the drive motors can apply without
348     * slippage.
349     *
350     * @param newSlipCurrent Parameter to modify
351     * @return this object
352     */
353    public SwerveModuleConstantsFactory<DriveMotorConfigsT, SteerMotorConfigsT, EncoderConfigsT> withSlipCurrent(double newSlipCurrent) {
354        this.SlipCurrent = newSlipCurrent;
355        return this;
356    }
357    
358    /**
359     * Modifies the SlipCurrent parameter and returns itself.
360     * <p>
361     * The maximum amount of stator current the drive motors can apply without
362     * slippage.
363     *
364     * @param newSlipCurrent Parameter to modify
365     * @return this object
366     */
367    public SwerveModuleConstantsFactory<DriveMotorConfigsT, SteerMotorConfigsT, EncoderConfigsT> withSlipCurrent(Current newSlipCurrent) {
368        this.SlipCurrent = newSlipCurrent.in(Amps);
369        return this;
370    }
371    
372    /**
373     * Modifies the SpeedAt12Volts parameter and returns itself.
374     * <p>
375     * When using open-loop drive control, this specifies the measured speed at
376     * which the robot travels when driven with 12 volts. This is used to
377     * approximate the output for a desired velocity; it cannot be used to change
378     * the desired max speed of the robot. If using closed loop control, this value
379     * is ignored.
380     *
381     * @param newSpeedAt12Volts Parameter to modify
382     * @return this object
383     */
384    public SwerveModuleConstantsFactory<DriveMotorConfigsT, SteerMotorConfigsT, EncoderConfigsT> withSpeedAt12Volts(double newSpeedAt12Volts) {
385        this.SpeedAt12Volts = newSpeedAt12Volts;
386        return this;
387    }
388    
389    /**
390     * Modifies the SpeedAt12Volts parameter and returns itself.
391     * <p>
392     * When using open-loop drive control, this specifies the measured speed at
393     * which the robot travels when driven with 12 volts. This is used to
394     * approximate the output for a desired velocity; it cannot be used to change
395     * the desired max speed of the robot. If using closed loop control, this value
396     * is ignored.
397     *
398     * @param newSpeedAt12Volts Parameter to modify
399     * @return this object
400     */
401    public SwerveModuleConstantsFactory<DriveMotorConfigsT, SteerMotorConfigsT, EncoderConfigsT> withSpeedAt12Volts(LinearVelocity newSpeedAt12Volts) {
402        this.SpeedAt12Volts = newSpeedAt12Volts.in(MetersPerSecond);
403        return this;
404    }
405    
406    /**
407     * Modifies the DriveMotorType parameter and returns itself.
408     * <p>
409     * Choose the motor used for the drive motor.
410     * <p>
411     * If using a Talon FX, this should be set to TalonFX_Integrated. If using a
412     * Talon FXS, this should be set to the motor attached to the Talon FXS.
413     *
414     * @param newDriveMotorType Parameter to modify
415     * @return this object
416     */
417    public SwerveModuleConstantsFactory<DriveMotorConfigsT, SteerMotorConfigsT, EncoderConfigsT> withDriveMotorType(DriveMotorArrangement newDriveMotorType) {
418        this.DriveMotorType = newDriveMotorType;
419        return this;
420    }
421    
422    /**
423     * Modifies the SteerMotorType parameter and returns itself.
424     * <p>
425     * Choose the motor used for the steer motor.
426     * <p>
427     * If using a Talon FX, this should be set to TalonFX_Integrated. If using a
428     * Talon FXS, this should be set to the motor attached to the Talon FXS.
429     *
430     * @param newSteerMotorType Parameter to modify
431     * @return this object
432     */
433    public SwerveModuleConstantsFactory<DriveMotorConfigsT, SteerMotorConfigsT, EncoderConfigsT> withSteerMotorType(SteerMotorArrangement newSteerMotorType) {
434        this.SteerMotorType = newSteerMotorType;
435        return this;
436    }
437    
438    /**
439     * Modifies the FeedbackSource parameter and returns itself.
440     * <p>
441     * Choose how the feedback sensors should be configured.
442     * <p>
443     * If the robot does not support Pro, then this should be set to RemoteCANcoder.
444     * Otherwise, users have the option to use either FusedCANcoder or SyncCANcoder
445     * depending on if there is a risk that the CANcoder can fail in a way to
446     * provide "good" data.
447     * <p>
448     * If this is set to FusedCANcoder or SyncCANcoder when the steer motor is not
449     * Pro-licensed, the device will automatically fall back to RemoteCANcoder and
450     * report a UsingProFeatureOnUnlicensedDevice status code.
451     *
452     * @param newFeedbackSource Parameter to modify
453     * @return this object
454     */
455    public SwerveModuleConstantsFactory<DriveMotorConfigsT, SteerMotorConfigsT, EncoderConfigsT> withFeedbackSource(SteerFeedbackType newFeedbackSource) {
456        this.FeedbackSource = newFeedbackSource;
457        return this;
458    }
459    
460    /**
461     * Modifies the DriveMotorInitialConfigs parameter and returns itself.
462     * <p>
463     * The initial configs used to configure the drive motor of the swerve module.
464     * The default value is the factory-default.
465     * <p>
466     * Users may change the initial configuration as they need. Any config that's
467     * not referenced in the {@link SwerveModuleConstants} class is available to be
468     * changed.
469     * <p>
470     * The list of configs that will be overwritten is as follows:
471     * 
472     * <ul>
473     *   <li> {@link MotorOutputConfigs#NeutralMode} (Brake mode, overwritten with
474     *        {@link SwerveDrivetrain#configNeutralMode})
475     *   <li> {@link MotorOutputConfigs#Inverted} ({@link
476     *        SwerveModuleConstants#DriveMotorInverted})
477     *   <li> {@link Slot0Configs} ({@link #DriveMotorGains})
478     *   <li> {@link CurrentLimitsConfigs#StatorCurrentLimit} / {@link
479     *        TorqueCurrentConfigs#PeakForwardTorqueCurrent} / {@link
480     *        TorqueCurrentConfigs#PeakReverseTorqueCurrent} ({@link #SlipCurrent})
481     *   <li> {@link CurrentLimitsConfigs#StatorCurrentLimitEnable} (Enabled)
482     *   <li> {@link FeedbackConfigs#RotorToSensorRatio} / {@link
483     *        FeedbackConfigs#SensorToMechanismRatio} (1.0)
484     * </ul>
485     * 
486     *
487     * @param newDriveMotorInitialConfigs Parameter to modify
488     * @return this object
489     */
490    public SwerveModuleConstantsFactory<DriveMotorConfigsT, SteerMotorConfigsT, EncoderConfigsT> withDriveMotorInitialConfigs(DriveMotorConfigsT newDriveMotorInitialConfigs) {
491        this.DriveMotorInitialConfigs = newDriveMotorInitialConfigs;
492        return this;
493    }
494    
495    /**
496     * Modifies the SteerMotorInitialConfigs parameter and returns itself.
497     * <p>
498     * The initial configs used to configure the steer motor of the swerve module.
499     * The default value is the factory-default.
500     * <p>
501     * Users may change the initial configuration as they need. Any config that's
502     * not referenced in the {@link SwerveModuleConstants} class is available to be
503     * changed.
504     * <p>
505     * The list of configs that will be overwritten is as follows:
506     * 
507     * <ul>
508     *   <li> {@link MotorOutputConfigs#NeutralMode} (Brake mode)
509     *   <li> {@link MotorOutputConfigs#Inverted} ({@link
510     *        SwerveModuleConstants#SteerMotorInverted})
511     *   <li> {@link Slot0Configs} ({@link #SteerMotorGains})
512     *   <li> {@link FeedbackConfigs#FeedbackRemoteSensorID} ({@link
513     *        SwerveModuleConstants#EncoderId})
514     *   <li> {@link FeedbackConfigs#FeedbackSensorSource} ({@link #FeedbackSource})
515     *   <li> {@link FeedbackConfigs#RotorToSensorRatio} ({@link
516     *        #SteerMotorGearRatio})
517     *   <li> {@link FeedbackConfigs#SensorToMechanismRatio} (1.0)
518     *   <li> {@link MotionMagicConfigs#MotionMagicExpo_kV} / {@link
519     *        MotionMagicConfigs#MotionMagicExpo_kA} (Calculated from gear ratios)
520     *   <li> {@link ClosedLoopGeneralConfigs#ContinuousWrap} (true)
521     * </ul>
522     * 
523     *
524     * @param newSteerMotorInitialConfigs Parameter to modify
525     * @return this object
526     */
527    public SwerveModuleConstantsFactory<DriveMotorConfigsT, SteerMotorConfigsT, EncoderConfigsT> withSteerMotorInitialConfigs(SteerMotorConfigsT newSteerMotorInitialConfigs) {
528        this.SteerMotorInitialConfigs = newSteerMotorInitialConfigs;
529        return this;
530    }
531    
532    /**
533     * Modifies the EncoderInitialConfigs parameter and returns itself.
534     * <p>
535     * The initial configs used to configure the azimuth encoder of the swerve
536     * module. The default value is the factory-default.
537     * <p>
538     * Users may change the initial configuration as they need. Any config that's
539     * not referenced in the {@link SwerveModuleConstants} class is available to be
540     * changed.
541     * <p>
542     * For CANcoder, the list of configs that will be overwritten is as follows:
543     * 
544     * <ul>
545     *   <li> {@link MagnetSensorConfigs#MagnetOffset} ({@link
546     *        SwerveModuleConstants#EncoderOffset})
547     *   <li> {@link MagnetSensorConfigs#SensorDirection} ({@link
548     *        SwerveModuleConstants#EncoderInverted})
549     * </ul>
550     * 
551     *
552     * @param newEncoderInitialConfigs Parameter to modify
553     * @return this object
554     */
555    public SwerveModuleConstantsFactory<DriveMotorConfigsT, SteerMotorConfigsT, EncoderConfigsT> withEncoderInitialConfigs(EncoderConfigsT newEncoderInitialConfigs) {
556        this.EncoderInitialConfigs = newEncoderInitialConfigs;
557        return this;
558    }
559    
560    /**
561     * Modifies the SteerInertia parameter and returns itself.
562     * <p>
563     * Simulated azimuthal inertia.
564     *
565     * @param newSteerInertia Parameter to modify
566     * @return this object
567     */
568    public SwerveModuleConstantsFactory<DriveMotorConfigsT, SteerMotorConfigsT, EncoderConfigsT> withSteerInertia(double newSteerInertia) {
569        this.SteerInertia = newSteerInertia;
570        return this;
571    }
572    
573    /**
574     * Modifies the SteerInertia parameter and returns itself.
575     * <p>
576     * Simulated azimuthal inertia.
577     *
578     * @param newSteerInertia Parameter to modify
579     * @return this object
580     */
581    public SwerveModuleConstantsFactory<DriveMotorConfigsT, SteerMotorConfigsT, EncoderConfigsT> withSteerInertia(MomentOfInertia newSteerInertia) {
582        this.SteerInertia = newSteerInertia.in(KilogramSquareMeters);
583        return this;
584    }
585    
586    /**
587     * Modifies the DriveInertia parameter and returns itself.
588     * <p>
589     * Simulated drive inertia.
590     *
591     * @param newDriveInertia Parameter to modify
592     * @return this object
593     */
594    public SwerveModuleConstantsFactory<DriveMotorConfigsT, SteerMotorConfigsT, EncoderConfigsT> withDriveInertia(double newDriveInertia) {
595        this.DriveInertia = newDriveInertia;
596        return this;
597    }
598    
599    /**
600     * Modifies the DriveInertia parameter and returns itself.
601     * <p>
602     * Simulated drive inertia.
603     *
604     * @param newDriveInertia Parameter to modify
605     * @return this object
606     */
607    public SwerveModuleConstantsFactory<DriveMotorConfigsT, SteerMotorConfigsT, EncoderConfigsT> withDriveInertia(MomentOfInertia newDriveInertia) {
608        this.DriveInertia = newDriveInertia.in(KilogramSquareMeters);
609        return this;
610    }
611    
612    /**
613     * Modifies the SteerFrictionVoltage parameter and returns itself.
614     * <p>
615     * Simulated steer voltage required to overcome friction.
616     *
617     * @param newSteerFrictionVoltage Parameter to modify
618     * @return this object
619     */
620    public SwerveModuleConstantsFactory<DriveMotorConfigsT, SteerMotorConfigsT, EncoderConfigsT> withSteerFrictionVoltage(double newSteerFrictionVoltage) {
621        this.SteerFrictionVoltage = newSteerFrictionVoltage;
622        return this;
623    }
624    
625    /**
626     * Modifies the SteerFrictionVoltage parameter and returns itself.
627     * <p>
628     * Simulated steer voltage required to overcome friction.
629     *
630     * @param newSteerFrictionVoltage Parameter to modify
631     * @return this object
632     */
633    public SwerveModuleConstantsFactory<DriveMotorConfigsT, SteerMotorConfigsT, EncoderConfigsT> withSteerFrictionVoltage(Voltage newSteerFrictionVoltage) {
634        this.SteerFrictionVoltage = newSteerFrictionVoltage.in(Volts);
635        return this;
636    }
637    
638    /**
639     * Modifies the DriveFrictionVoltage parameter and returns itself.
640     * <p>
641     * Simulated drive voltage required to overcome friction.
642     *
643     * @param newDriveFrictionVoltage Parameter to modify
644     * @return this object
645     */
646    public SwerveModuleConstantsFactory<DriveMotorConfigsT, SteerMotorConfigsT, EncoderConfigsT> withDriveFrictionVoltage(double newDriveFrictionVoltage) {
647        this.DriveFrictionVoltage = newDriveFrictionVoltage;
648        return this;
649    }
650    
651    /**
652     * Modifies the DriveFrictionVoltage parameter and returns itself.
653     * <p>
654     * Simulated drive voltage required to overcome friction.
655     *
656     * @param newDriveFrictionVoltage Parameter to modify
657     * @return this object
658     */
659    public SwerveModuleConstantsFactory<DriveMotorConfigsT, SteerMotorConfigsT, EncoderConfigsT> withDriveFrictionVoltage(Voltage newDriveFrictionVoltage) {
660        this.DriveFrictionVoltage = newDriveFrictionVoltage.in(Volts);
661        return this;
662    }
663    
664    /**
665     * Creates the constants for a swerve module with the given properties.
666     *
667     * @param steerMotorId CAN ID of the steer motor.
668     * @param driveMotorId CAN ID of the drive motor.
669     * @param encoderId CAN ID of the absolute encoder used for azimuth.
670     * @param encoderOffset Offset of the azimuth encoder.
671     * @param locationX The location of this module's wheels relative to the
672     *                  physical center of the robot in meters along the X axis of
673     *                  the robot.
674     * @param locationY The location of this module's wheels relative to the
675     *                  physical center of the robot in meters along the Y axis of
676     *                  the robot.
677     * @param driveMotorInverted True if the drive motor is inverted.
678     * @param steerMotorInverted True if the steer motor is inverted from the
679     *                           azimuth. The azimuth should rotate
680     *                           counter-clockwise (as seen from the top of the
681     *                           robot) for a positive motor output.
682     * @param encoderInverted True if the azimuth encoder is inverted from the
683     *                        azimuth. The encoder should report a positive velocity
684     *                        when the azimuth rotates counter-clockwise (as seen
685     *                        from the top of the robot).
686     * @return Constants for the swerve module
687     */
688    public final SwerveModuleConstants<DriveMotorConfigsT, SteerMotorConfigsT, EncoderConfigsT> createModuleConstants(
689            int steerMotorId,
690            int driveMotorId,
691            int encoderId,
692            double encoderOffset,
693            double locationX,
694            double locationY,
695            boolean driveMotorInverted,
696            boolean steerMotorInverted,
697            boolean encoderInverted)
698    {
699        return new SwerveModuleConstants<DriveMotorConfigsT, SteerMotorConfigsT, EncoderConfigsT>()
700            .withSteerMotorId(steerMotorId)
701            .withDriveMotorId(driveMotorId)
702            .withEncoderId(encoderId)
703            .withEncoderOffset(encoderOffset)
704            .withLocationX(locationX)
705            .withLocationY(locationY)
706            .withDriveMotorInverted(driveMotorInverted)
707            .withSteerMotorInverted(steerMotorInverted)
708            .withEncoderInverted(encoderInverted)
709            .withDriveMotorGearRatio(DriveMotorGearRatio)
710            .withSteerMotorGearRatio(SteerMotorGearRatio)
711            .withCouplingGearRatio(CouplingGearRatio)
712            .withWheelRadius(WheelRadius)
713            .withSteerMotorGains(SteerMotorGains)
714            .withDriveMotorGains(DriveMotorGains)
715            .withSteerMotorClosedLoopOutput(SteerMotorClosedLoopOutput)
716            .withDriveMotorClosedLoopOutput(DriveMotorClosedLoopOutput)
717            .withSlipCurrent(SlipCurrent)
718            .withSpeedAt12Volts(SpeedAt12Volts)
719            .withDriveMotorType(DriveMotorType)
720            .withSteerMotorType(SteerMotorType)
721            .withFeedbackSource(FeedbackSource)
722            .withDriveMotorInitialConfigs(DriveMotorInitialConfigs)
723            .withSteerMotorInitialConfigs(SteerMotorInitialConfigs)
724            .withEncoderInitialConfigs(EncoderInitialConfigs)
725            .withSteerInertia(SteerInertia)
726            .withDriveInertia(DriveInertia)
727            .withSteerFrictionVoltage(SteerFrictionVoltage)
728            .withDriveFrictionVoltage(DriveFrictionVoltage);
729    }
730    
731    /**
732     * Creates the constants for a swerve module with the given properties.
733     *
734     * @param steerMotorId CAN ID of the steer motor.
735     * @param driveMotorId CAN ID of the drive motor.
736     * @param encoderId CAN ID of the absolute encoder used for azimuth.
737     * @param encoderOffset Offset of the azimuth encoder.
738     * @param locationX The location of this module's wheels relative to the
739     *                  physical center of the robot in meters along the X axis of
740     *                  the robot.
741     * @param locationY The location of this module's wheels relative to the
742     *                  physical center of the robot in meters along the Y axis of
743     *                  the robot.
744     * @param driveMotorInverted True if the drive motor is inverted.
745     * @param steerMotorInverted True if the steer motor is inverted from the
746     *                           azimuth. The azimuth should rotate
747     *                           counter-clockwise (as seen from the top of the
748     *                           robot) for a positive motor output.
749     * @param encoderInverted True if the azimuth encoder is inverted from the
750     *                        azimuth. The encoder should report a positive velocity
751     *                        when the azimuth rotates counter-clockwise (as seen
752     *                        from the top of the robot).
753     * @return Constants for the swerve module
754     */
755    public final SwerveModuleConstants<DriveMotorConfigsT, SteerMotorConfigsT, EncoderConfigsT> createModuleConstants(
756            int steerMotorId,
757            int driveMotorId,
758            int encoderId,
759            Angle encoderOffset,
760            Distance locationX,
761            Distance locationY,
762            boolean driveMotorInverted,
763            boolean steerMotorInverted,
764            boolean encoderInverted)
765    {
766        return new SwerveModuleConstants<DriveMotorConfigsT, SteerMotorConfigsT, EncoderConfigsT>()
767            .withSteerMotorId(steerMotorId)
768            .withDriveMotorId(driveMotorId)
769            .withEncoderId(encoderId)
770            .withEncoderOffset(encoderOffset.in(Rotations))
771            .withLocationX(locationX.in(Meters))
772            .withLocationY(locationY.in(Meters))
773            .withDriveMotorInverted(driveMotorInverted)
774            .withSteerMotorInverted(steerMotorInverted)
775            .withEncoderInverted(encoderInverted)
776            .withDriveMotorGearRatio(DriveMotorGearRatio)
777            .withSteerMotorGearRatio(SteerMotorGearRatio)
778            .withCouplingGearRatio(CouplingGearRatio)
779            .withWheelRadius(WheelRadius)
780            .withSteerMotorGains(SteerMotorGains)
781            .withDriveMotorGains(DriveMotorGains)
782            .withSteerMotorClosedLoopOutput(SteerMotorClosedLoopOutput)
783            .withDriveMotorClosedLoopOutput(DriveMotorClosedLoopOutput)
784            .withSlipCurrent(SlipCurrent)
785            .withSpeedAt12Volts(SpeedAt12Volts)
786            .withDriveMotorType(DriveMotorType)
787            .withSteerMotorType(SteerMotorType)
788            .withFeedbackSource(FeedbackSource)
789            .withDriveMotorInitialConfigs(DriveMotorInitialConfigs)
790            .withSteerMotorInitialConfigs(SteerMotorInitialConfigs)
791            .withEncoderInitialConfigs(EncoderInitialConfigs)
792            .withSteerInertia(SteerInertia)
793            .withDriveInertia(DriveInertia)
794            .withSteerFrictionVoltage(SteerFrictionVoltage)
795            .withDriveFrictionVoltage(DriveFrictionVoltage);
796    }
797}