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.configs;
008
009import com.ctre.phoenix6.StatusCode;
010import com.ctre.phoenix6.configs.jni.ConfigJNI;
011import com.ctre.phoenix6.spns.*;
012
013import edu.wpi.first.units.*;
014
015import edu.wpi.first.units.measure.*;
016import static edu.wpi.first.units.Units.*;
017
018/**
019 * Configs related to the CANdi™ branded device's PWM interface on the
020 * Signal 2 input (S2IN)
021 * <p>
022 * All the configs related to the PWM interface for the CANdi™ branded
023 * device on S1, including absolute sensor offset, absolute sensor
024 * discontinuity point and sensor direction.
025 */
026public class PWM2Configs implements ParentConfiguration
027{
028    /**
029     * The offset applied to the PWM sensor.
030     * <p>
031     * This can be used to zero the sensor position in applications where
032     * the sensor is 1:1 with the mechanism.
033     * 
034     * <ul>
035     *   <li> <b>Minimum Value:</b> -1
036     *   <li> <b>Maximum Value:</b> 1
037     *   <li> <b>Default Value:</b> 0.0
038     *   <li> <b>Units:</b> rotations
039     * </ul>
040     */
041    public double AbsoluteSensorOffset = 0.0;
042    /**
043     * The positive discontinuity point of the absolute sensor in
044     * rotations. This determines the point at which the absolute sensor
045     * wraps around, keeping the absolute position (after offset) in the
046     * range [x-1, x).
047     * 
048     * <ul>
049     *   <li> Setting this to 1 makes the absolute position unsigned [0,
050     * 1)
051     *   <li> Setting this to 0.5 makes the absolute position signed
052     * [-0.5, 0.5)
053     *   <li> Setting this to 0 makes the absolute position always
054     * negative [-1, 0)
055     * </ul>
056     * 
057     * Many rotational mechanisms such as arms have a region of motion
058     * that is unreachable. This should be set to the center of that
059     * region of motion, in non-negative rotations. This affects the
060     * position of the device at bootup.
061     * <p>
062     * For example, consider an arm which can travel from -0.2 to 0.6
063     * rotations with a little leeway, where 0 is horizontally forward.
064     * Since -0.2 rotations has the same absolute position as 0.8
065     * rotations, we can say that the arm typically does not travel in the
066     * range (0.6, 0.8) rotations. As a result, the discontinuity point
067     * would be the center of that range, which is 0.7 rotations. This
068     * results in an absolute sensor range of [-0.3, 0.7) rotations.
069     * <p>
070     * Given a total range of motion less than 1 rotation, users can
071     * calculate the discontinuity point using mean(lowerLimit,
072     * upperLimit) + 0.5. If that results in a value outside the range [0,
073     * 1], either cap the value to [0, 1], or add/subtract 1.0 rotation
074     * from your lower and upper limits of motion.
075     * <p>
076     * On a Talon motor controller, this is only supported when using the
077     * PulseWidth sensor source.
078     * 
079     * <ul>
080     *   <li> <b>Minimum Value:</b> 0.0
081     *   <li> <b>Maximum Value:</b> 1.0
082     *   <li> <b>Default Value:</b> 0.5
083     *   <li> <b>Units:</b> rotations
084     * </ul>
085     */
086    public double AbsoluteSensorDiscontinuityPoint = 0.5;
087    /**
088     * Direction of the PWM sensor to determine positive rotation. Invert
089     * this so that forward motion on the mechanism results in an increase
090     * in PWM position.
091     * 
092     * <ul>
093     *   <li> <b>Default Value:</b> False
094     * </ul>
095     */
096    public boolean SensorDirection = false;
097    
098    /**
099     * Modifies this configuration's AbsoluteSensorOffset parameter and returns itself for
100     * method-chaining and easier to use config API.
101     * <p>
102     * The offset applied to the PWM sensor.
103     * <p>
104     * This can be used to zero the sensor position in applications where
105     * the sensor is 1:1 with the mechanism.
106     * 
107     * <ul>
108     *   <li> <b>Minimum Value:</b> -1
109     *   <li> <b>Maximum Value:</b> 1
110     *   <li> <b>Default Value:</b> 0.0
111     *   <li> <b>Units:</b> rotations
112     * </ul>
113     *
114     * @param newAbsoluteSensorOffset Parameter to modify
115     * @return Itself
116     */
117    public PWM2Configs withAbsoluteSensorOffset(double newAbsoluteSensorOffset)
118    {
119        AbsoluteSensorOffset = newAbsoluteSensorOffset;
120        return this;
121    }
122    
123    /**
124     * Modifies this configuration's AbsoluteSensorOffset parameter and returns itself for
125     * method-chaining and easier to use config API.
126     * <p>
127     * The offset applied to the PWM sensor.
128     * <p>
129     * This can be used to zero the sensor position in applications where
130     * the sensor is 1:1 with the mechanism.
131     * 
132     * <ul>
133     *   <li> <b>Minimum Value:</b> -1
134     *   <li> <b>Maximum Value:</b> 1
135     *   <li> <b>Default Value:</b> 0.0
136     *   <li> <b>Units:</b> rotations
137     * </ul>
138     *
139     * @param newAbsoluteSensorOffset Parameter to modify
140     * @return Itself
141     */
142    public PWM2Configs withAbsoluteSensorOffset(Angle newAbsoluteSensorOffset)
143    {
144        AbsoluteSensorOffset = newAbsoluteSensorOffset.in(Rotations);
145        return this;
146    }
147    
148    /**
149     * Helper method to get this configuration's AbsoluteSensorOffset parameter converted
150     * to a unit type. If not using the Java units library, {@link #AbsoluteSensorOffset}
151     * can be accessed directly instead.
152     * <p>
153     * The offset applied to the PWM sensor.
154     * <p>
155     * This can be used to zero the sensor position in applications where
156     * the sensor is 1:1 with the mechanism.
157     * 
158     * <ul>
159     *   <li> <b>Minimum Value:</b> -1
160     *   <li> <b>Maximum Value:</b> 1
161     *   <li> <b>Default Value:</b> 0.0
162     *   <li> <b>Units:</b> rotations
163     * </ul>
164     *
165     * @return AbsoluteSensorOffset
166     */
167    public Angle getAbsoluteSensorOffsetMeasure()
168    {
169        return Rotations.of(AbsoluteSensorOffset);
170    }
171    
172    /**
173     * Modifies this configuration's AbsoluteSensorDiscontinuityPoint parameter and returns itself for
174     * method-chaining and easier to use config API.
175     * <p>
176     * The positive discontinuity point of the absolute sensor in
177     * rotations. This determines the point at which the absolute sensor
178     * wraps around, keeping the absolute position (after offset) in the
179     * range [x-1, x).
180     * 
181     * <ul>
182     *   <li> Setting this to 1 makes the absolute position unsigned [0,
183     * 1)
184     *   <li> Setting this to 0.5 makes the absolute position signed
185     * [-0.5, 0.5)
186     *   <li> Setting this to 0 makes the absolute position always
187     * negative [-1, 0)
188     * </ul>
189     * 
190     * Many rotational mechanisms such as arms have a region of motion
191     * that is unreachable. This should be set to the center of that
192     * region of motion, in non-negative rotations. This affects the
193     * position of the device at bootup.
194     * <p>
195     * For example, consider an arm which can travel from -0.2 to 0.6
196     * rotations with a little leeway, where 0 is horizontally forward.
197     * Since -0.2 rotations has the same absolute position as 0.8
198     * rotations, we can say that the arm typically does not travel in the
199     * range (0.6, 0.8) rotations. As a result, the discontinuity point
200     * would be the center of that range, which is 0.7 rotations. This
201     * results in an absolute sensor range of [-0.3, 0.7) rotations.
202     * <p>
203     * Given a total range of motion less than 1 rotation, users can
204     * calculate the discontinuity point using mean(lowerLimit,
205     * upperLimit) + 0.5. If that results in a value outside the range [0,
206     * 1], either cap the value to [0, 1], or add/subtract 1.0 rotation
207     * from your lower and upper limits of motion.
208     * <p>
209     * On a Talon motor controller, this is only supported when using the
210     * PulseWidth sensor source.
211     * 
212     * <ul>
213     *   <li> <b>Minimum Value:</b> 0.0
214     *   <li> <b>Maximum Value:</b> 1.0
215     *   <li> <b>Default Value:</b> 0.5
216     *   <li> <b>Units:</b> rotations
217     * </ul>
218     *
219     * @param newAbsoluteSensorDiscontinuityPoint Parameter to modify
220     * @return Itself
221     */
222    public PWM2Configs withAbsoluteSensorDiscontinuityPoint(double newAbsoluteSensorDiscontinuityPoint)
223    {
224        AbsoluteSensorDiscontinuityPoint = newAbsoluteSensorDiscontinuityPoint;
225        return this;
226    }
227    
228    /**
229     * Modifies this configuration's AbsoluteSensorDiscontinuityPoint parameter and returns itself for
230     * method-chaining and easier to use config API.
231     * <p>
232     * The positive discontinuity point of the absolute sensor in
233     * rotations. This determines the point at which the absolute sensor
234     * wraps around, keeping the absolute position (after offset) in the
235     * range [x-1, x).
236     * 
237     * <ul>
238     *   <li> Setting this to 1 makes the absolute position unsigned [0,
239     * 1)
240     *   <li> Setting this to 0.5 makes the absolute position signed
241     * [-0.5, 0.5)
242     *   <li> Setting this to 0 makes the absolute position always
243     * negative [-1, 0)
244     * </ul>
245     * 
246     * Many rotational mechanisms such as arms have a region of motion
247     * that is unreachable. This should be set to the center of that
248     * region of motion, in non-negative rotations. This affects the
249     * position of the device at bootup.
250     * <p>
251     * For example, consider an arm which can travel from -0.2 to 0.6
252     * rotations with a little leeway, where 0 is horizontally forward.
253     * Since -0.2 rotations has the same absolute position as 0.8
254     * rotations, we can say that the arm typically does not travel in the
255     * range (0.6, 0.8) rotations. As a result, the discontinuity point
256     * would be the center of that range, which is 0.7 rotations. This
257     * results in an absolute sensor range of [-0.3, 0.7) rotations.
258     * <p>
259     * Given a total range of motion less than 1 rotation, users can
260     * calculate the discontinuity point using mean(lowerLimit,
261     * upperLimit) + 0.5. If that results in a value outside the range [0,
262     * 1], either cap the value to [0, 1], or add/subtract 1.0 rotation
263     * from your lower and upper limits of motion.
264     * <p>
265     * On a Talon motor controller, this is only supported when using the
266     * PulseWidth sensor source.
267     * 
268     * <ul>
269     *   <li> <b>Minimum Value:</b> 0.0
270     *   <li> <b>Maximum Value:</b> 1.0
271     *   <li> <b>Default Value:</b> 0.5
272     *   <li> <b>Units:</b> rotations
273     * </ul>
274     *
275     * @param newAbsoluteSensorDiscontinuityPoint Parameter to modify
276     * @return Itself
277     */
278    public PWM2Configs withAbsoluteSensorDiscontinuityPoint(Angle newAbsoluteSensorDiscontinuityPoint)
279    {
280        AbsoluteSensorDiscontinuityPoint = newAbsoluteSensorDiscontinuityPoint.in(Rotations);
281        return this;
282    }
283    
284    /**
285     * Helper method to get this configuration's AbsoluteSensorDiscontinuityPoint parameter converted
286     * to a unit type. If not using the Java units library, {@link #AbsoluteSensorDiscontinuityPoint}
287     * can be accessed directly instead.
288     * <p>
289     * The positive discontinuity point of the absolute sensor in
290     * rotations. This determines the point at which the absolute sensor
291     * wraps around, keeping the absolute position (after offset) in the
292     * range [x-1, x).
293     * 
294     * <ul>
295     *   <li> Setting this to 1 makes the absolute position unsigned [0,
296     * 1)
297     *   <li> Setting this to 0.5 makes the absolute position signed
298     * [-0.5, 0.5)
299     *   <li> Setting this to 0 makes the absolute position always
300     * negative [-1, 0)
301     * </ul>
302     * 
303     * Many rotational mechanisms such as arms have a region of motion
304     * that is unreachable. This should be set to the center of that
305     * region of motion, in non-negative rotations. This affects the
306     * position of the device at bootup.
307     * <p>
308     * For example, consider an arm which can travel from -0.2 to 0.6
309     * rotations with a little leeway, where 0 is horizontally forward.
310     * Since -0.2 rotations has the same absolute position as 0.8
311     * rotations, we can say that the arm typically does not travel in the
312     * range (0.6, 0.8) rotations. As a result, the discontinuity point
313     * would be the center of that range, which is 0.7 rotations. This
314     * results in an absolute sensor range of [-0.3, 0.7) rotations.
315     * <p>
316     * Given a total range of motion less than 1 rotation, users can
317     * calculate the discontinuity point using mean(lowerLimit,
318     * upperLimit) + 0.5. If that results in a value outside the range [0,
319     * 1], either cap the value to [0, 1], or add/subtract 1.0 rotation
320     * from your lower and upper limits of motion.
321     * <p>
322     * On a Talon motor controller, this is only supported when using the
323     * PulseWidth sensor source.
324     * 
325     * <ul>
326     *   <li> <b>Minimum Value:</b> 0.0
327     *   <li> <b>Maximum Value:</b> 1.0
328     *   <li> <b>Default Value:</b> 0.5
329     *   <li> <b>Units:</b> rotations
330     * </ul>
331     *
332     * @return AbsoluteSensorDiscontinuityPoint
333     */
334    public Angle getAbsoluteSensorDiscontinuityPointMeasure()
335    {
336        return Rotations.of(AbsoluteSensorDiscontinuityPoint);
337    }
338    
339    /**
340     * Modifies this configuration's SensorDirection parameter and returns itself for
341     * method-chaining and easier to use config API.
342     * <p>
343     * Direction of the PWM sensor to determine positive rotation. Invert
344     * this so that forward motion on the mechanism results in an increase
345     * in PWM position.
346     * 
347     * <ul>
348     *   <li> <b>Default Value:</b> False
349     * </ul>
350     *
351     * @param newSensorDirection Parameter to modify
352     * @return Itself
353     */
354    public PWM2Configs withSensorDirection(boolean newSensorDirection)
355    {
356        SensorDirection = newSensorDirection;
357        return this;
358    }
359
360    
361
362    @Override
363    public String toString()
364    {
365        String ss = "Config Group: PWM2\n";
366        ss += "    AbsoluteSensorOffset: " + AbsoluteSensorOffset + " rotations" + "\n";
367        ss += "    AbsoluteSensorDiscontinuityPoint: " + AbsoluteSensorDiscontinuityPoint + " rotations" + "\n";
368        ss += "    SensorDirection: " + SensorDirection + "\n";
369        return ss;
370    }
371
372    /**
373     *
374     */
375    public StatusCode deserialize(String to_deserialize)
376    {
377        AbsoluteSensorOffset = ConfigJNI.Deserializedouble(SpnValue.Config_PWM2_AbsoluteSensorOffset.value, to_deserialize);
378        AbsoluteSensorDiscontinuityPoint = ConfigJNI.Deserializedouble(SpnValue.Config_PWM2_AbsoluteSensorDiscontinuityPoint.value, to_deserialize);
379        SensorDirection = ConfigJNI.Deserializeboolean(SpnValue.Config_PWM2_SensorDirection.value, to_deserialize);
380        return  StatusCode.OK;
381    }
382
383    /**
384     *
385     */
386    public String serialize()
387    {
388        String ss = "";
389        ss += ConfigJNI.Serializedouble(SpnValue.Config_PWM2_AbsoluteSensorOffset.value, AbsoluteSensorOffset);
390        ss += ConfigJNI.Serializedouble(SpnValue.Config_PWM2_AbsoluteSensorDiscontinuityPoint.value, AbsoluteSensorDiscontinuityPoint);
391        ss += ConfigJNI.Serializeboolean(SpnValue.Config_PWM2_SensorDirection.value, SensorDirection);
392        return ss;
393    }
394}
395