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.*;
013import com.ctre.phoenix6.hardware.core.CoreCANcoder;
014
015/**
016 * Configs that affect the feedback of this motor controller.
017 * <p>
018 * Includes feedback sensor source, any offsets for the feedback
019 * sensor, and various ratios to describe the relationship between the
020 * sensor and the mechanism for closed looping.
021 */
022public class FeedbackConfigs implements ParentConfiguration
023{
024    /**
025     * This offset is applied to the absolute integrated rotor sensor. 
026     * This can be used to zero the rotor in applications that are within
027     * one rotor rotation.
028     * 
029     * <ul>
030     *   <li> <b>Minimum Value:</b> -1
031     *   <li> <b>Maximum Value:</b> 1
032     *   <li> <b>Default Value:</b> 0.0
033     *   <li> <b>Units:</b> rotations
034     * </ul>
035     */
036    public double FeedbackRotorOffset = 0.0;
037    /**
038     * This is the ratio of sensor rotations to the mechanism's output. 
039     * This is equivalent to the mechanism's gear ratio if the sensor is
040     * located on the input of a gearbox.  If sensor is on the output of a
041     * gearbox, then this is typically set to 1.  Note if this is set to
042     * zero, device will reset back to one.
043     * 
044     * <ul>
045     *   <li> <b>Minimum Value:</b> -1000
046     *   <li> <b>Maximum Value:</b> 1000
047     *   <li> <b>Default Value:</b> 1.0
048     *   <li> <b>Units:</b> scalar
049     * </ul>
050     */
051    public double SensorToMechanismRatio = 1.0;
052    /**
053     * Talon FX is capable of fusing a remote CANcoder with its rotor
054     * sensor to produce a high-bandwidth sensor source.  This feature
055     * requires specifying the ratio between the remote sensor and the
056     * motor rotor.  Note if this is set to zero, device will reset back
057     * to one.
058     * 
059     * <ul>
060     *   <li> <b>Minimum Value:</b> -1000
061     *   <li> <b>Maximum Value:</b> 1000
062     *   <li> <b>Default Value:</b> 1.0
063     *   <li> <b>Units:</b> scalar
064     * </ul>
065     */
066    public double RotorToSensorRatio = 1.0;
067    /**
068     * Choose what sensor source is reported via API and used by
069     * closed-loop and limit features.  The default is RotorSensor, which
070     * uses the internal rotor sensor in the Talon FX.
071     * <p>
072     * Choose RemoteCANcoder to use another CANcoder on the same CAN bus
073     * (this also requires setting FeedbackRemoteSensorID).  Talon FX will
074     * update its position and velocity whenever CANcoder publishes its
075     * information on CAN bus.
076     * <p>
077     * Choose FusedCANcoder (requires Phoenix Pro) and Talon FX will fuse
078     * another CANcoder's information with the internal rotor, which
079     * provides the best possible position and velocity for accuracy and
080     * bandwidth (this also requires setting FeedbackRemoteSensorID). 
081     * FusedCANcoder was developed for applications such as
082     * swerve-azimuth.
083     * <p>
084     * Choose SyncCANcoder (requires Phoenix Pro) and Talon FX will
085     * synchronize its internal rotor position against another CANcoder,
086     * then continue to use the rotor sensor for closed loop control (this
087     * also requires setting FeedbackRemoteSensorID).  The TalonFX will
088     * report if its internal position differs significantly from the
089     * reported CANcoder position.  SyncCANcoder was developed for
090     * mechanisms where there is a risk of the CANcoder failing in such a
091     * way that it reports a position that does not match the mechanism,
092     * such as the sensor mounting assembly breaking off.
093     * <p>
094     * Choose RemotePigeon2_Yaw, RemotePigeon2_Pitch, and
095     * RemotePigeon2_Roll to use another Pigeon2 on the same CAN bus (this
096     * also requires setting FeedbackRemoteSensorID).  Talon FX will
097     * update its position to match the selected value whenever Pigeon2
098     * publishes its information on CAN bus. Note that the Talon FX
099     * position will be in rotations and not degrees.
100     * <p>
101     * Note: When the feedback source is changed to FusedCANcoder, the
102     * Talon FX needs a period of time to fuse before sensor-based
103     * (soft-limit, closed loop, etc.) features are used. This period of
104     * time is determined by the update frequency of the CANcoder's
105     * Position signal.
106     * 
107     */
108    public FeedbackSensorSourceValue FeedbackSensorSource = FeedbackSensorSourceValue.RotorSensor;
109    /**
110     * Device ID of which remote device to use.  This is not used if the
111     * Sensor Source is the internal rotor sensor.
112     * 
113     * <ul>
114     *   <li> <b>Minimum Value:</b> 0
115     *   <li> <b>Maximum Value:</b> 62
116     *   <li> <b>Default Value:</b> 0
117     *   <li> <b>Units:</b> 
118     * </ul>
119     */
120    public int FeedbackRemoteSensorID = 0;
121    
122    /**
123     * Modifies this configuration's FeedbackRotorOffset parameter and returns itself for
124     * method-chaining and easier to use config API.
125     * <p>
126     * This offset is applied to the absolute integrated rotor sensor. 
127     * This can be used to zero the rotor in applications that are within
128     * one rotor rotation.
129     * 
130     * <ul>
131     *   <li> <b>Minimum Value:</b> -1
132     *   <li> <b>Maximum Value:</b> 1
133     *   <li> <b>Default Value:</b> 0.0
134     *   <li> <b>Units:</b> rotations
135     * </ul>
136     *
137     * @param newFeedbackRotorOffset Parameter to modify
138     * @return Itself
139     */
140    public FeedbackConfigs withFeedbackRotorOffset(double newFeedbackRotorOffset)
141    {
142        FeedbackRotorOffset = newFeedbackRotorOffset;
143        return this;
144    }
145    /**
146     * Modifies this configuration's SensorToMechanismRatio parameter and returns itself for
147     * method-chaining and easier to use config API.
148     * <p>
149     * This is the ratio of sensor rotations to the mechanism's output. 
150     * This is equivalent to the mechanism's gear ratio if the sensor is
151     * located on the input of a gearbox.  If sensor is on the output of a
152     * gearbox, then this is typically set to 1.  Note if this is set to
153     * zero, device will reset back to one.
154     * 
155     * <ul>
156     *   <li> <b>Minimum Value:</b> -1000
157     *   <li> <b>Maximum Value:</b> 1000
158     *   <li> <b>Default Value:</b> 1.0
159     *   <li> <b>Units:</b> scalar
160     * </ul>
161     *
162     * @param newSensorToMechanismRatio Parameter to modify
163     * @return Itself
164     */
165    public FeedbackConfigs withSensorToMechanismRatio(double newSensorToMechanismRatio)
166    {
167        SensorToMechanismRatio = newSensorToMechanismRatio;
168        return this;
169    }
170    /**
171     * Modifies this configuration's RotorToSensorRatio parameter and returns itself for
172     * method-chaining and easier to use config API.
173     * <p>
174     * Talon FX is capable of fusing a remote CANcoder with its rotor
175     * sensor to produce a high-bandwidth sensor source.  This feature
176     * requires specifying the ratio between the remote sensor and the
177     * motor rotor.  Note if this is set to zero, device will reset back
178     * to one.
179     * 
180     * <ul>
181     *   <li> <b>Minimum Value:</b> -1000
182     *   <li> <b>Maximum Value:</b> 1000
183     *   <li> <b>Default Value:</b> 1.0
184     *   <li> <b>Units:</b> scalar
185     * </ul>
186     *
187     * @param newRotorToSensorRatio Parameter to modify
188     * @return Itself
189     */
190    public FeedbackConfigs withRotorToSensorRatio(double newRotorToSensorRatio)
191    {
192        RotorToSensorRatio = newRotorToSensorRatio;
193        return this;
194    }
195    /**
196     * Modifies this configuration's FeedbackSensorSource parameter and returns itself for
197     * method-chaining and easier to use config API.
198     * <p>
199     * Choose what sensor source is reported via API and used by
200     * closed-loop and limit features.  The default is RotorSensor, which
201     * uses the internal rotor sensor in the Talon FX.
202     * <p>
203     * Choose RemoteCANcoder to use another CANcoder on the same CAN bus
204     * (this also requires setting FeedbackRemoteSensorID).  Talon FX will
205     * update its position and velocity whenever CANcoder publishes its
206     * information on CAN bus.
207     * <p>
208     * Choose FusedCANcoder (requires Phoenix Pro) and Talon FX will fuse
209     * another CANcoder's information with the internal rotor, which
210     * provides the best possible position and velocity for accuracy and
211     * bandwidth (this also requires setting FeedbackRemoteSensorID). 
212     * FusedCANcoder was developed for applications such as
213     * swerve-azimuth.
214     * <p>
215     * Choose SyncCANcoder (requires Phoenix Pro) and Talon FX will
216     * synchronize its internal rotor position against another CANcoder,
217     * then continue to use the rotor sensor for closed loop control (this
218     * also requires setting FeedbackRemoteSensorID).  The TalonFX will
219     * report if its internal position differs significantly from the
220     * reported CANcoder position.  SyncCANcoder was developed for
221     * mechanisms where there is a risk of the CANcoder failing in such a
222     * way that it reports a position that does not match the mechanism,
223     * such as the sensor mounting assembly breaking off.
224     * <p>
225     * Choose RemotePigeon2_Yaw, RemotePigeon2_Pitch, and
226     * RemotePigeon2_Roll to use another Pigeon2 on the same CAN bus (this
227     * also requires setting FeedbackRemoteSensorID).  Talon FX will
228     * update its position to match the selected value whenever Pigeon2
229     * publishes its information on CAN bus. Note that the Talon FX
230     * position will be in rotations and not degrees.
231     * <p>
232     * Note: When the feedback source is changed to FusedCANcoder, the
233     * Talon FX needs a period of time to fuse before sensor-based
234     * (soft-limit, closed loop, etc.) features are used. This period of
235     * time is determined by the update frequency of the CANcoder's
236     * Position signal.
237     * 
238     *
239     * @param newFeedbackSensorSource Parameter to modify
240     * @return Itself
241     */
242    public FeedbackConfigs withFeedbackSensorSource(FeedbackSensorSourceValue newFeedbackSensorSource)
243    {
244        FeedbackSensorSource = newFeedbackSensorSource;
245        return this;
246    }
247    /**
248     * Modifies this configuration's FeedbackRemoteSensorID parameter and returns itself for
249     * method-chaining and easier to use config API.
250     * <p>
251     * Device ID of which remote device to use.  This is not used if the
252     * Sensor Source is the internal rotor sensor.
253     * 
254     * <ul>
255     *   <li> <b>Minimum Value:</b> 0
256     *   <li> <b>Maximum Value:</b> 62
257     *   <li> <b>Default Value:</b> 0
258     *   <li> <b>Units:</b> 
259     * </ul>
260     *
261     * @param newFeedbackRemoteSensorID Parameter to modify
262     * @return Itself
263     */
264    public FeedbackConfigs withFeedbackRemoteSensorID(int newFeedbackRemoteSensorID)
265    {
266        FeedbackRemoteSensorID = newFeedbackRemoteSensorID;
267        return this;
268    }
269    
270    /**
271     * Helper method to configure this feedback group to use
272     * RemoteCANcoder by passing in the CANcoder object. When using
273     * RemoteCANcoder, the Talon FX will use another CANcoder on the same
274     * CAN bus. Talon FX will update its position and velocity whenever
275     * CANcoder publishes its information on CAN bus.
276     * 
277     * @param device    CANcoder reference to use for RemoteCANcoder
278     * @return Itself
279     */
280    public FeedbackConfigs withRemoteCANcoder(CoreCANcoder device)
281    {
282        this.FeedbackSensorSource = FeedbackSensorSourceValue.RemoteCANcoder;
283        this.FeedbackRemoteSensorID = device.getDeviceID();
284        return this;
285    }
286    
287    /**
288     * Helper method to configure this feedback group to use FusedCANcoder
289     * by passing in the CANcoder object. When using FusedCANcoder
290     * (requires Phoenix Pro), the Talon FX will fuse another CANcoder's
291     * information with the internal rotor, which provides the best
292     * possible position and velocity for accuracy and bandwidth.
293     * FusedCANcoder was developed for applications such as
294     * swerve-azimuth.
295     * 
296     * @param device    CANcoder reference to use for FusedCANcoder
297     * @return Itself
298     */
299    public FeedbackConfigs withFusedCANcoder(CoreCANcoder device)
300    {
301        this.FeedbackSensorSource = FeedbackSensorSourceValue.FusedCANcoder;
302        this.FeedbackRemoteSensorID = device.getDeviceID();
303        return this;
304    }
305    
306    /**
307     * Helper method to configure this feedback group to use SyncCANcoder
308     * by passing in the CANcoder object. When using SyncCANcoder
309     * (requires Phoenix Pro), the Talon FX will synchronize its internal
310     * rotor position against another CANcoder, then continue to use the
311     * rotor sensor for closed loop control. The TalonFX will report if
312     * its internal position differs significantly from the reported
313     * CANcoder position. SyncCANcoder was developed for mechanisms where
314     * there is a risk of the CANcoder failing in such a way that it
315     * reports a position that does not match the mechanism, such as the
316     * sensor mounting assembly breaking off.
317     * 
318     * @param device    CANcoder reference to use for SyncCANcoder
319     * @return Itself
320     */
321    public FeedbackConfigs withSyncCANcoder(CoreCANcoder device)
322    {
323        this.FeedbackSensorSource = FeedbackSensorSourceValue.SyncCANcoder;
324        this.FeedbackRemoteSensorID = device.getDeviceID();
325        return this;
326    }
327    
328    
329
330    @Override
331    public String toString()
332    {
333        String ss = "Config Group: Feedback\n";
334        ss += "Name: \"FeedbackRotorOffset\" Value: \"" + FeedbackRotorOffset + "rotations\"" + "\n";
335        ss += "Name: \"SensorToMechanismRatio\" Value: \"" + SensorToMechanismRatio + "scalar\"" + "\n";
336        ss += "Name: \"RotorToSensorRatio\" Value: \"" + RotorToSensorRatio + "scalar\"" + "\n";
337        ss += "Name: \"FeedbackSensorSource\" Value: \"" + FeedbackSensorSource + "\"" + "\n";
338        ss += "Name: \"FeedbackRemoteSensorID\" Value: \"" + FeedbackRemoteSensorID + "\"" + "\n";
339        return ss;
340    }
341
342    /**
343     *
344     */
345    public StatusCode deserialize(String to_deserialize)
346    {
347        FeedbackRotorOffset = ConfigJNI.Deserializedouble(SpnValue.Config_FeedbackRotorOffset.value, to_deserialize);
348        SensorToMechanismRatio = ConfigJNI.Deserializedouble(SpnValue.Config_SensorToMechanismRatio.value, to_deserialize);
349        RotorToSensorRatio = ConfigJNI.Deserializedouble(SpnValue.Config_RotorToSensorRatio.value, to_deserialize);
350        FeedbackSensorSource = FeedbackSensorSourceValue.valueOf(ConfigJNI.Deserializeint(SpnValue.Config_FeedbackSensorSource.value, to_deserialize));
351        FeedbackRemoteSensorID = ConfigJNI.Deserializeint(SpnValue.Config_FeedbackRemoteSensorID.value, to_deserialize);
352        return  StatusCode.OK;
353    }
354
355    /**
356     *
357     */
358    public String serialize()
359    {
360        String ss = "";
361        ss += ConfigJNI.Serializedouble(SpnValue.Config_FeedbackRotorOffset.value, FeedbackRotorOffset);
362        ss += ConfigJNI.Serializedouble(SpnValue.Config_SensorToMechanismRatio.value, SensorToMechanismRatio);
363        ss += ConfigJNI.Serializedouble(SpnValue.Config_RotorToSensorRatio.value, RotorToSensorRatio);
364        ss += ConfigJNI.Serializeint(SpnValue.Config_FeedbackSensorSource.value, FeedbackSensorSource.value);
365        ss += ConfigJNI.Serializeint(SpnValue.Config_FeedbackRemoteSensorID.value, FeedbackRemoteSensorID);
366        return ss;
367    }
368}
369