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.  Choose
071     * RemoteCANcoder to use another CANcoder on the same CAN bus (this
072     * also requires setting FeedbackRemoteSensorID).  Talon FX will
073     * update its position and velocity whenever CANcoder publishes its
074     * information on CAN bus.  Choose FusedCANcoder (requires Phoenix
075     * Pro) and Talon FX will fuse another CANcoder's information with the
076     * internal rotor, which provides the best possible position and
077     * velocity for accuracy and bandwidth (note this requires setting
078     * FeedbackRemoteSensorID).  FusedCANcoder was developed for
079     * applications such as swerve-azimuth.  Choose SyncCANcoder (requires
080     * Phoenix Pro) and Talon FX will synchronize its internal rotor
081     * position against another CANcoder, then continue to use the rotor
082     * sensor for closed loop control (note this requires setting
083     * FeedbackRemoteSensorID).  The TalonFX will report if its internal
084     * position differs significantly from the reported CANcoder position.
085     *  SyncCANcoder was developed for mechanisms where there is a risk of
086     * the CANcoder failing in such a way that it reports a position that
087     * does not match the mechanism, such as the sensor mounting assembly
088     * breaking off.  Choose RemotePigeon2_Yaw, RemotePigeon2_Pitch, and
089     * RemotePigeon2_Roll to use another Pigeon2 on the same CAN bus (this
090     * also requires setting FeedbackRemoteSensorID).  Talon FX will
091     * update its position to match the selected value whenever Pigeon2
092     * publishes its information on CAN bus. Note that the Talon FX
093     * position will be in rotations and not degrees.
094     * <p>
095     * Note: When the Talon Source is changed to FusedCANcoder, the Talon
096     * needs a period of time to fuse before sensor-based (soft-limit,
097     * closed loop, etc.) features are used. This period of time is
098     * determined by the update frequency of the CANcoder's Position
099     * signal.
100     * 
101     */
102    public FeedbackSensorSourceValue FeedbackSensorSource = FeedbackSensorSourceValue.RotorSensor;
103    /**
104     * Device ID of which remote device to use.  This is not used if the
105     * Sensor Source is the internal rotor sensor.
106     * 
107     *   <ul>
108     *   <li> <b>Minimum Value:</b> 0
109     *   <li> <b>Maximum Value:</b> 62
110     *   <li> <b>Default Value:</b> 0
111     *   <li> <b>Units:</b> 
112     *   </ul>
113     */
114    public int FeedbackRemoteSensorID = 0;
115    
116    /**
117     * Helper method to configure this feedback group to use Fused
118     * CANcoder by passing in the CANcoder object
119     * 
120     * @param device    CANcoder reference to use for FusedCANcoder
121     */
122    FeedbackConfigs withFusedCANcoder(CoreCANcoder device)
123    {
124        this.FeedbackSensorSource = FeedbackSensorSourceValue.FusedCANcoder;
125        this.FeedbackRemoteSensorID = device.getDeviceID();
126        return this;
127    }
128    
129    /**
130     * Helper method to configure this feedback group to use Remote
131     * CANcoder by passing in the CANcoder object
132     * 
133     * @param device    CANcoder reference to use for FusedCANcoder
134     */
135    FeedbackConfigs withRemoteCANcoder(CoreCANcoder device)
136    {
137        this.FeedbackSensorSource = FeedbackSensorSourceValue.RemoteCANcoder;
138        this.FeedbackRemoteSensorID = device.getDeviceID();
139        return this;
140    }
141    
142    
143
144    @Override
145    public String toString()
146    {
147        String ss = "Config Group: Feedback\n";
148        ss += "Name: \"FeedbackRotorOffset\" Value: \"" + FeedbackRotorOffset + "rotations\"" + "\n";
149        ss += "Name: \"SensorToMechanismRatio\" Value: \"" + SensorToMechanismRatio + "scalar\"" + "\n";
150        ss += "Name: \"RotorToSensorRatio\" Value: \"" + RotorToSensorRatio + "scalar\"" + "\n";
151        ss += "Name: \"FeedbackSensorSource\" Value: \"" + FeedbackSensorSource + "\"" + "\n";
152        ss += "Name: \"FeedbackRemoteSensorID\" Value: \"" + FeedbackRemoteSensorID + "\"" + "\n";
153        return ss;
154    }
155
156    /**
157     *
158     */
159    public StatusCode deserialize(String to_deserialize)
160    {
161        FeedbackRotorOffset = ConfigJNI.Deserializedouble(SpnValue.Config_FeedbackRotorOffset.value, to_deserialize);
162        SensorToMechanismRatio = ConfigJNI.Deserializedouble(SpnValue.Config_SensorToMechanismRatio.value, to_deserialize);
163        RotorToSensorRatio = ConfigJNI.Deserializedouble(SpnValue.Config_RotorToSensorRatio.value, to_deserialize);
164        FeedbackSensorSource = FeedbackSensorSourceValue.valueOf(ConfigJNI.Deserializeint(SpnValue.Config_FeedbackSensorSource.value, to_deserialize));
165        FeedbackRemoteSensorID = ConfigJNI.Deserializeint(SpnValue.Config_FeedbackRemoteSensorID.value, to_deserialize);
166        return  StatusCode.OK;
167    }
168
169    /**
170     *
171     */
172    public String serialize()
173    {
174        String ss = "";
175        ss += ConfigJNI.Serializedouble(SpnValue.Config_FeedbackRotorOffset.value, FeedbackRotorOffset);
176        ss += ConfigJNI.Serializedouble(SpnValue.Config_SensorToMechanismRatio.value, SensorToMechanismRatio);
177        ss += ConfigJNI.Serializedouble(SpnValue.Config_RotorToSensorRatio.value, RotorToSensorRatio);
178        ss += ConfigJNI.Serializeint(SpnValue.Config_FeedbackSensorSource.value, FeedbackSensorSource.value);
179        ss += ConfigJNI.Serializeint(SpnValue.Config_FeedbackRemoteSensorID.value, FeedbackRemoteSensorID);
180        return ss;
181    }
182}
183