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.*;
012import com.ctre.phoenix6.signals.*;
013
014import edu.wpi.first.units.*;
015
016import edu.wpi.first.units.measure.*;
017import static edu.wpi.first.units.Units.*;
018
019/**
020 * Gains for the specified slot.
021 * <p>
022 * If this slot is selected, these gains are used in closed loop
023 * control requests.
024 */
025public class Slot0Configs implements ParentConfiguration, Cloneable {
026    /**
027     * Proportional gain.
028     * <p>
029     * The units for this gain is dependent on the control mode. Since
030     * this gain is multiplied by error in the input, the units should be
031     * defined as units of output per unit of input error. For example,
032     * when controlling velocity using a duty cycle closed loop, the units
033     * for the proportional gain will be duty cycle per rps of error, or
034     * 1/rps.
035     * 
036     * <ul>
037     *   <li> <b>Minimum Value:</b> 0
038     *   <li> <b>Maximum Value:</b> 3.4e+38
039     *   <li> <b>Default Value:</b> 0
040     *   <li> <b>Units:</b> 
041     * </ul>
042     */
043    public double kP = 0;
044    /**
045     * Integral gain.
046     * <p>
047     * The units for this gain is dependent on the control mode. Since
048     * this gain is multiplied by error in the input integrated over time
049     * (in units of seconds), the units should be defined as units of
050     * output per unit of integrated input error. For example, when
051     * controlling velocity using a duty cycle closed loop, integrating
052     * velocity over time results in rps * s = rotations. Therefore, the
053     * units for the integral gain will be duty cycle per rotation of
054     * accumulated error, or 1/rot.
055     * 
056     * <ul>
057     *   <li> <b>Minimum Value:</b> 0
058     *   <li> <b>Maximum Value:</b> 3.4e+38
059     *   <li> <b>Default Value:</b> 0
060     *   <li> <b>Units:</b> 
061     * </ul>
062     */
063    public double kI = 0;
064    /**
065     * Derivative gain.
066     * <p>
067     * The units for this gain is dependent on the control mode. Since
068     * this gain is multiplied by the derivative of error in the input
069     * with respect to time (in units of seconds), the units should be
070     * defined as units of output per unit of the differentiated input
071     * error. For example, when controlling velocity using a duty cycle
072     * closed loop, the derivative of velocity with respect to time is rot
073     * per sec², which is acceleration. Therefore, the units for the
074     * derivative gain will be duty cycle per unit of acceleration error,
075     * or 1/(rot per sec²).
076     * 
077     * <ul>
078     *   <li> <b>Minimum Value:</b> 0
079     *   <li> <b>Maximum Value:</b> 3.4e+38
080     *   <li> <b>Default Value:</b> 0
081     *   <li> <b>Units:</b> 
082     * </ul>
083     */
084    public double kD = 0;
085    /**
086     * Static feedforward gain.
087     * <p>
088     * This is added to the closed loop output. The unit for this constant
089     * is dependent on the control mode, typically fractional duty cycle,
090     * voltage, or torque current.
091     * <p>
092     * The sign is typically determined by reference velocity when using
093     * position, velocity, and Motion Magic® closed loop modes. However,
094     * when using position closed loop with zero velocity reference (no
095     * motion profiling), the application can instead use the position
096     * closed loop error by setting the Static Feedforward Sign
097     * configuration parameter.  When doing so, we recommend the minimal
098     * amount of kS, otherwise the motor output may dither when closed
099     * loop error is near zero.
100     * 
101     * <ul>
102     *   <li> <b>Minimum Value:</b> -128
103     *   <li> <b>Maximum Value:</b> 127
104     *   <li> <b>Default Value:</b> 0
105     *   <li> <b>Units:</b> 
106     * </ul>
107     */
108    public double kS = 0;
109    /**
110     * Velocity feedforward gain.
111     * <p>
112     * The units for this gain is dependent on the control mode. Since
113     * this gain is multiplied by the requested velocity, the units should
114     * be defined as units of output per unit of requested input velocity.
115     * For example, when controlling velocity using a duty cycle closed
116     * loop, the units for the velocity feedfoward gain will be duty cycle
117     * per requested rps, or 1/rps.
118     * 
119     * <ul>
120     *   <li> <b>Minimum Value:</b> 0
121     *   <li> <b>Maximum Value:</b> 3.4e+38
122     *   <li> <b>Default Value:</b> 0
123     *   <li> <b>Units:</b> 
124     * </ul>
125     */
126    public double kV = 0;
127    /**
128     * Acceleration feedforward gain.
129     * <p>
130     * The units for this gain is dependent on the control mode. Since
131     * this gain is multiplied by the requested acceleration, the units
132     * should be defined as units of output per unit of requested input
133     * acceleration. For example, when controlling velocity using a duty
134     * cycle closed loop, the units for the acceleration feedfoward gain
135     * will be duty cycle per requested rot per sec², or 1/(rot per sec²).
136     * 
137     * <ul>
138     *   <li> <b>Minimum Value:</b> 0
139     *   <li> <b>Maximum Value:</b> 3.4e+38
140     *   <li> <b>Default Value:</b> 0
141     *   <li> <b>Units:</b> 
142     * </ul>
143     */
144    public double kA = 0;
145    /**
146     * Gravity feedforward/feedback gain. The type of gravity compensation
147     * is selected by {@link #GravityType}.
148     * <p>
149     * This is added to the closed loop output. The sign is determined by
150     * the gravity type. The unit for this constant is dependent on the
151     * control mode, typically fractional duty cycle, voltage, or torque
152     * current.
153     * <p>
154     * Note that kG may be negative for some counterbalanced mechanisms.
155     * 
156     * <ul>
157     *   <li> <b>Minimum Value:</b> -128
158     *   <li> <b>Maximum Value:</b> 127
159     *   <li> <b>Default Value:</b> 0
160     *   <li> <b>Units:</b> 
161     * </ul>
162     */
163    public double kG = 0;
164    /**
165     * Gravity feedforward/feedback type.
166     * <p>
167     * This determines the type of the gravity feedforward/feedback.
168     * <p>
169     * Choose Elevator_Static for systems where the gravity feedforward is
170     * constant, such as an elevator. The gravity feedforward output will
171     * always have the same sign.
172     * <p>
173     * Choose Arm_Cosine for systems where the gravity feedback is
174     * dependent on the angular position of the mechanism, such as an arm.
175     * The gravity feedback output will vary depending on the mechanism
176     * angular position. Note that the sensor offset and ratios must be
177     * configured so that the sensor reports a position of 0 when the
178     * mechanism is horizonal (parallel to the ground), and the reported
179     * sensor position is 1:1 with the mechanism.
180     * 
181     */
182    public GravityTypeValue GravityType = GravityTypeValue.Elevator_Static;
183    /**
184     * Static feedforward sign during position closed loop.
185     * <p>
186     * This determines the sign of the applied kS during position
187     * closed-loop modes. The default behavior uses the velocity reference
188     * sign. This works well with velocity closed loop, Motion Magic®
189     * controls, and position closed loop when velocity reference is
190     * specified (motion profiling).
191     * <p>
192     * However, when using position closed loop with zero velocity
193     * reference (no motion profiling), the application may want to apply
194     * static feedforward based on the sign of closed loop error instead.
195     * When doing so, we recommend using the minimal amount of kS,
196     * otherwise the motor output may dither when closed loop error is
197     * near zero.
198     * 
199     */
200    public StaticFeedforwardSignValue StaticFeedforwardSign = StaticFeedforwardSignValue.UseVelocitySign;
201    /**
202     * Gravity feedback position offset when using the Arm/Cosine gravity
203     * type.
204     * <p>
205     * This is an offset applied to the position of the arm, within
206     * (-0.25, 0.25) rot, before calculating the output of kG. This is
207     * useful when the center of gravity of the arm is offset from the
208     * actual zero point of the arm, such as when the arm and intake form
209     * an L shape.
210     * 
211     * <ul>
212     *   <li> <b>Minimum Value:</b> -0.25
213     *   <li> <b>Maximum Value:</b> 0.25
214     *   <li> <b>Default Value:</b> 0
215     *   <li> <b>Units:</b> rotations
216     * </ul>
217     */
218    public double GravityArmPositionOffset = 0;
219    /**
220     * The behavior of the gain scheduler on this slot. This specifies
221     * which gains to use while within the configured
222     * GainSchedErrorThreshold. The default is to continue using the
223     * specified slot.
224     * <p>
225     * Gain scheduling will not take effect when running velocity
226     * closed-loop controls.
227     * 
228     */
229    public GainSchedBehaviorValue GainSchedBehavior = GainSchedBehaviorValue.Inactive;
230    
231    /**
232     * Modifies this configuration's kP parameter and returns itself for
233     * method-chaining and easier to use config API.
234     * <p>
235     * Proportional gain.
236     * <p>
237     * The units for this gain is dependent on the control mode. Since
238     * this gain is multiplied by error in the input, the units should be
239     * defined as units of output per unit of input error. For example,
240     * when controlling velocity using a duty cycle closed loop, the units
241     * for the proportional gain will be duty cycle per rps of error, or
242     * 1/rps.
243     * 
244     * <ul>
245     *   <li> <b>Minimum Value:</b> 0
246     *   <li> <b>Maximum Value:</b> 3.4e+38
247     *   <li> <b>Default Value:</b> 0
248     *   <li> <b>Units:</b> 
249     * </ul>
250     *
251     * @param newKP Parameter to modify
252     * @return Itself
253     */
254    public final Slot0Configs withKP(double newKP)
255    {
256        kP = newKP;
257        return this;
258    }
259    
260    /**
261     * Modifies this configuration's kI parameter and returns itself for
262     * method-chaining and easier to use config API.
263     * <p>
264     * Integral gain.
265     * <p>
266     * The units for this gain is dependent on the control mode. Since
267     * this gain is multiplied by error in the input integrated over time
268     * (in units of seconds), the units should be defined as units of
269     * output per unit of integrated input error. For example, when
270     * controlling velocity using a duty cycle closed loop, integrating
271     * velocity over time results in rps * s = rotations. Therefore, the
272     * units for the integral gain will be duty cycle per rotation of
273     * accumulated error, or 1/rot.
274     * 
275     * <ul>
276     *   <li> <b>Minimum Value:</b> 0
277     *   <li> <b>Maximum Value:</b> 3.4e+38
278     *   <li> <b>Default Value:</b> 0
279     *   <li> <b>Units:</b> 
280     * </ul>
281     *
282     * @param newKI Parameter to modify
283     * @return Itself
284     */
285    public final Slot0Configs withKI(double newKI)
286    {
287        kI = newKI;
288        return this;
289    }
290    
291    /**
292     * Modifies this configuration's kD parameter and returns itself for
293     * method-chaining and easier to use config API.
294     * <p>
295     * Derivative gain.
296     * <p>
297     * The units for this gain is dependent on the control mode. Since
298     * this gain is multiplied by the derivative of error in the input
299     * with respect to time (in units of seconds), the units should be
300     * defined as units of output per unit of the differentiated input
301     * error. For example, when controlling velocity using a duty cycle
302     * closed loop, the derivative of velocity with respect to time is rot
303     * per sec², which is acceleration. Therefore, the units for the
304     * derivative gain will be duty cycle per unit of acceleration error,
305     * or 1/(rot per sec²).
306     * 
307     * <ul>
308     *   <li> <b>Minimum Value:</b> 0
309     *   <li> <b>Maximum Value:</b> 3.4e+38
310     *   <li> <b>Default Value:</b> 0
311     *   <li> <b>Units:</b> 
312     * </ul>
313     *
314     * @param newKD Parameter to modify
315     * @return Itself
316     */
317    public final Slot0Configs withKD(double newKD)
318    {
319        kD = newKD;
320        return this;
321    }
322    
323    /**
324     * Modifies this configuration's kS parameter and returns itself for
325     * method-chaining and easier to use config API.
326     * <p>
327     * Static feedforward gain.
328     * <p>
329     * This is added to the closed loop output. The unit for this constant
330     * is dependent on the control mode, typically fractional duty cycle,
331     * voltage, or torque current.
332     * <p>
333     * The sign is typically determined by reference velocity when using
334     * position, velocity, and Motion Magic® closed loop modes. However,
335     * when using position closed loop with zero velocity reference (no
336     * motion profiling), the application can instead use the position
337     * closed loop error by setting the Static Feedforward Sign
338     * configuration parameter.  When doing so, we recommend the minimal
339     * amount of kS, otherwise the motor output may dither when closed
340     * loop error is near zero.
341     * 
342     * <ul>
343     *   <li> <b>Minimum Value:</b> -128
344     *   <li> <b>Maximum Value:</b> 127
345     *   <li> <b>Default Value:</b> 0
346     *   <li> <b>Units:</b> 
347     * </ul>
348     *
349     * @param newKS Parameter to modify
350     * @return Itself
351     */
352    public final Slot0Configs withKS(double newKS)
353    {
354        kS = newKS;
355        return this;
356    }
357    
358    /**
359     * Modifies this configuration's kV parameter and returns itself for
360     * method-chaining and easier to use config API.
361     * <p>
362     * Velocity feedforward gain.
363     * <p>
364     * The units for this gain is dependent on the control mode. Since
365     * this gain is multiplied by the requested velocity, the units should
366     * be defined as units of output per unit of requested input velocity.
367     * For example, when controlling velocity using a duty cycle closed
368     * loop, the units for the velocity feedfoward gain will be duty cycle
369     * per requested rps, or 1/rps.
370     * 
371     * <ul>
372     *   <li> <b>Minimum Value:</b> 0
373     *   <li> <b>Maximum Value:</b> 3.4e+38
374     *   <li> <b>Default Value:</b> 0
375     *   <li> <b>Units:</b> 
376     * </ul>
377     *
378     * @param newKV Parameter to modify
379     * @return Itself
380     */
381    public final Slot0Configs withKV(double newKV)
382    {
383        kV = newKV;
384        return this;
385    }
386    
387    /**
388     * Modifies this configuration's kA parameter and returns itself for
389     * method-chaining and easier to use config API.
390     * <p>
391     * Acceleration feedforward gain.
392     * <p>
393     * The units for this gain is dependent on the control mode. Since
394     * this gain is multiplied by the requested acceleration, the units
395     * should be defined as units of output per unit of requested input
396     * acceleration. For example, when controlling velocity using a duty
397     * cycle closed loop, the units for the acceleration feedfoward gain
398     * will be duty cycle per requested rot per sec², or 1/(rot per sec²).
399     * 
400     * <ul>
401     *   <li> <b>Minimum Value:</b> 0
402     *   <li> <b>Maximum Value:</b> 3.4e+38
403     *   <li> <b>Default Value:</b> 0
404     *   <li> <b>Units:</b> 
405     * </ul>
406     *
407     * @param newKA Parameter to modify
408     * @return Itself
409     */
410    public final Slot0Configs withKA(double newKA)
411    {
412        kA = newKA;
413        return this;
414    }
415    
416    /**
417     * Modifies this configuration's kG parameter and returns itself for
418     * method-chaining and easier to use config API.
419     * <p>
420     * Gravity feedforward/feedback gain. The type of gravity compensation
421     * is selected by {@link #GravityType}.
422     * <p>
423     * This is added to the closed loop output. The sign is determined by
424     * the gravity type. The unit for this constant is dependent on the
425     * control mode, typically fractional duty cycle, voltage, or torque
426     * current.
427     * <p>
428     * Note that kG may be negative for some counterbalanced mechanisms.
429     * 
430     * <ul>
431     *   <li> <b>Minimum Value:</b> -128
432     *   <li> <b>Maximum Value:</b> 127
433     *   <li> <b>Default Value:</b> 0
434     *   <li> <b>Units:</b> 
435     * </ul>
436     *
437     * @param newKG Parameter to modify
438     * @return Itself
439     */
440    public final Slot0Configs withKG(double newKG)
441    {
442        kG = newKG;
443        return this;
444    }
445    
446    /**
447     * Modifies this configuration's GravityType parameter and returns itself for
448     * method-chaining and easier to use config API.
449     * <p>
450     * Gravity feedforward/feedback type.
451     * <p>
452     * This determines the type of the gravity feedforward/feedback.
453     * <p>
454     * Choose Elevator_Static for systems where the gravity feedforward is
455     * constant, such as an elevator. The gravity feedforward output will
456     * always have the same sign.
457     * <p>
458     * Choose Arm_Cosine for systems where the gravity feedback is
459     * dependent on the angular position of the mechanism, such as an arm.
460     * The gravity feedback output will vary depending on the mechanism
461     * angular position. Note that the sensor offset and ratios must be
462     * configured so that the sensor reports a position of 0 when the
463     * mechanism is horizonal (parallel to the ground), and the reported
464     * sensor position is 1:1 with the mechanism.
465     * 
466     *
467     * @param newGravityType Parameter to modify
468     * @return Itself
469     */
470    public final Slot0Configs withGravityType(GravityTypeValue newGravityType)
471    {
472        GravityType = newGravityType;
473        return this;
474    }
475    
476    /**
477     * Modifies this configuration's StaticFeedforwardSign parameter and returns itself for
478     * method-chaining and easier to use config API.
479     * <p>
480     * Static feedforward sign during position closed loop.
481     * <p>
482     * This determines the sign of the applied kS during position
483     * closed-loop modes. The default behavior uses the velocity reference
484     * sign. This works well with velocity closed loop, Motion Magic®
485     * controls, and position closed loop when velocity reference is
486     * specified (motion profiling).
487     * <p>
488     * However, when using position closed loop with zero velocity
489     * reference (no motion profiling), the application may want to apply
490     * static feedforward based on the sign of closed loop error instead.
491     * When doing so, we recommend using the minimal amount of kS,
492     * otherwise the motor output may dither when closed loop error is
493     * near zero.
494     * 
495     *
496     * @param newStaticFeedforwardSign Parameter to modify
497     * @return Itself
498     */
499    public final Slot0Configs withStaticFeedforwardSign(StaticFeedforwardSignValue newStaticFeedforwardSign)
500    {
501        StaticFeedforwardSign = newStaticFeedforwardSign;
502        return this;
503    }
504    
505    /**
506     * Modifies this configuration's GravityArmPositionOffset parameter and returns itself for
507     * method-chaining and easier to use config API.
508     * <p>
509     * Gravity feedback position offset when using the Arm/Cosine gravity
510     * type.
511     * <p>
512     * This is an offset applied to the position of the arm, within
513     * (-0.25, 0.25) rot, before calculating the output of kG. This is
514     * useful when the center of gravity of the arm is offset from the
515     * actual zero point of the arm, such as when the arm and intake form
516     * an L shape.
517     * 
518     * <ul>
519     *   <li> <b>Minimum Value:</b> -0.25
520     *   <li> <b>Maximum Value:</b> 0.25
521     *   <li> <b>Default Value:</b> 0
522     *   <li> <b>Units:</b> rotations
523     * </ul>
524     *
525     * @param newGravityArmPositionOffset Parameter to modify
526     * @return Itself
527     */
528    public final Slot0Configs withGravityArmPositionOffset(double newGravityArmPositionOffset)
529    {
530        GravityArmPositionOffset = newGravityArmPositionOffset;
531        return this;
532    }
533    
534    /**
535     * Modifies this configuration's GravityArmPositionOffset parameter and returns itself for
536     * method-chaining and easier to use config API.
537     * <p>
538     * Gravity feedback position offset when using the Arm/Cosine gravity
539     * type.
540     * <p>
541     * This is an offset applied to the position of the arm, within
542     * (-0.25, 0.25) rot, before calculating the output of kG. This is
543     * useful when the center of gravity of the arm is offset from the
544     * actual zero point of the arm, such as when the arm and intake form
545     * an L shape.
546     * 
547     * <ul>
548     *   <li> <b>Minimum Value:</b> -0.25
549     *   <li> <b>Maximum Value:</b> 0.25
550     *   <li> <b>Default Value:</b> 0
551     *   <li> <b>Units:</b> rotations
552     * </ul>
553     *
554     * @param newGravityArmPositionOffset Parameter to modify
555     * @return Itself
556     */
557    public final Slot0Configs withGravityArmPositionOffset(Angle newGravityArmPositionOffset)
558    {
559        GravityArmPositionOffset = newGravityArmPositionOffset.in(Rotations);
560        return this;
561    }
562    
563    /**
564     * Helper method to get this configuration's GravityArmPositionOffset parameter converted
565     * to a unit type. If not using the Java units library, {@link #GravityArmPositionOffset}
566     * can be accessed directly instead.
567     * <p>
568     * Gravity feedback position offset when using the Arm/Cosine gravity
569     * type.
570     * <p>
571     * This is an offset applied to the position of the arm, within
572     * (-0.25, 0.25) rot, before calculating the output of kG. This is
573     * useful when the center of gravity of the arm is offset from the
574     * actual zero point of the arm, such as when the arm and intake form
575     * an L shape.
576     * 
577     * <ul>
578     *   <li> <b>Minimum Value:</b> -0.25
579     *   <li> <b>Maximum Value:</b> 0.25
580     *   <li> <b>Default Value:</b> 0
581     *   <li> <b>Units:</b> rotations
582     * </ul>
583     *
584     * @return GravityArmPositionOffset
585     */
586    public final Angle getGravityArmPositionOffsetMeasure()
587    {
588        return Rotations.of(GravityArmPositionOffset);
589    }
590    
591    /**
592     * Modifies this configuration's GainSchedBehavior parameter and returns itself for
593     * method-chaining and easier to use config API.
594     * <p>
595     * The behavior of the gain scheduler on this slot. This specifies
596     * which gains to use while within the configured
597     * GainSchedErrorThreshold. The default is to continue using the
598     * specified slot.
599     * <p>
600     * Gain scheduling will not take effect when running velocity
601     * closed-loop controls.
602     * 
603     *
604     * @param newGainSchedBehavior Parameter to modify
605     * @return Itself
606     */
607    public final Slot0Configs withGainSchedBehavior(GainSchedBehaviorValue newGainSchedBehavior)
608    {
609        GainSchedBehavior = newGainSchedBehavior;
610        return this;
611    }
612
613    /**
614     * Converts the provided value to an instance of this type.
615     *
616     * @param value The value to convert
617     * @return Converted value
618     */
619    public static Slot0Configs from(SlotConfigs value)
620    {
621        return new Slot0Configs() {{
622            kP = value.kP;
623            kI = value.kI;
624            kD = value.kD;
625            kS = value.kS;
626            kV = value.kV;
627            kA = value.kA;
628            kG = value.kG;
629            GravityType = value.GravityType;
630            StaticFeedforwardSign = value.StaticFeedforwardSign;
631            GravityArmPositionOffset = value.GravityArmPositionOffset;
632            GainSchedBehavior = value.GainSchedBehavior;
633        }};
634    }
635
636    @Override
637    public String toString() {
638        String ss = "Config Group: Slot0\n";
639        ss += "    kP: " + kP + "\n";
640        ss += "    kI: " + kI + "\n";
641        ss += "    kD: " + kD + "\n";
642        ss += "    kS: " + kS + "\n";
643        ss += "    kV: " + kV + "\n";
644        ss += "    kA: " + kA + "\n";
645        ss += "    kG: " + kG + "\n";
646        ss += "    GravityType: " + GravityType + "\n";
647        ss += "    StaticFeedforwardSign: " + StaticFeedforwardSign + "\n";
648        ss += "    GravityArmPositionOffset: " + GravityArmPositionOffset + " rotations" + "\n";
649        ss += "    GainSchedBehavior: " + GainSchedBehavior + "\n";
650        return ss;
651    }
652
653    /**
654     * Get the serialized form of this configuration group.
655     *
656     * @return Serialized form of this config group
657     */
658    @Override
659    public final String serialize() {
660        String ss = "";
661        ss += ConfigJNI.Serializedouble(SpnValue.Slot0_kP.value, kP);
662        ss += ConfigJNI.Serializedouble(SpnValue.Slot0_kI.value, kI);
663        ss += ConfigJNI.Serializedouble(SpnValue.Slot0_kD.value, kD);
664        ss += ConfigJNI.Serializedouble(SpnValue.Slot0_kS.value, kS);
665        ss += ConfigJNI.Serializedouble(SpnValue.Slot0_kV.value, kV);
666        ss += ConfigJNI.Serializedouble(SpnValue.Slot0_kA.value, kA);
667        ss += ConfigJNI.Serializedouble(SpnValue.Slot0_kG.value, kG);
668        ss += ConfigJNI.Serializeint(SpnValue.Slot0_kG_Type.value, GravityType.value);
669        ss += ConfigJNI.Serializeint(SpnValue.Slot0_kS_Sign.value, StaticFeedforwardSign.value);
670        ss += ConfigJNI.Serializedouble(SpnValue.Slot0_kG_PosOffset.value, GravityArmPositionOffset);
671        ss += ConfigJNI.Serializeint(SpnValue.Slot0_GainSchedBehavior.value, GainSchedBehavior.value);
672        return ss;
673    }
674
675    /**
676     * Take a string and deserialize it to this configuration group.
677     *
678     * @return Return code of the deserialize method
679     */
680    @Override
681    public final StatusCode deserialize(String to_deserialize) {
682        kP = ConfigJNI.Deserializedouble(SpnValue.Slot0_kP.value, to_deserialize);
683        kI = ConfigJNI.Deserializedouble(SpnValue.Slot0_kI.value, to_deserialize);
684        kD = ConfigJNI.Deserializedouble(SpnValue.Slot0_kD.value, to_deserialize);
685        kS = ConfigJNI.Deserializedouble(SpnValue.Slot0_kS.value, to_deserialize);
686        kV = ConfigJNI.Deserializedouble(SpnValue.Slot0_kV.value, to_deserialize);
687        kA = ConfigJNI.Deserializedouble(SpnValue.Slot0_kA.value, to_deserialize);
688        kG = ConfigJNI.Deserializedouble(SpnValue.Slot0_kG.value, to_deserialize);
689        GravityType = GravityTypeValue.valueOf(ConfigJNI.Deserializeint(SpnValue.Slot0_kG_Type.value, to_deserialize));
690        StaticFeedforwardSign = StaticFeedforwardSignValue.valueOf(ConfigJNI.Deserializeint(SpnValue.Slot0_kS_Sign.value, to_deserialize));
691        GravityArmPositionOffset = ConfigJNI.Deserializedouble(SpnValue.Slot0_kG_PosOffset.value, to_deserialize);
692        GainSchedBehavior = GainSchedBehaviorValue.valueOf(ConfigJNI.Deserializeint(SpnValue.Slot0_GainSchedBehavior.value, to_deserialize));
693        return  StatusCode.OK;
694    }
695
696    @Override
697    public Slot0Configs clone() {
698        try {
699            return (Slot0Configs)super.clone();
700        } catch (CloneNotSupportedException ex) {
701            /* this should never happen */
702            throw new RuntimeException(ex);
703        }
704    }
705}
706