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 that affect the ToF Proximity detection
020 * <p>
021 * Includes proximity mode and the threshold for simple detection
022 */
023public class ProximityParamsConfigs implements ParentConfiguration
024{
025    /**
026     * Threshold for object detection.
027     * 
028     * <ul>
029     *   <li> <b>Minimum Value:</b> 0
030     *   <li> <b>Maximum Value:</b> 4
031     *   <li> <b>Default Value:</b> 0.4
032     *   <li> <b>Units:</b> m
033     * </ul>
034     */
035    public double ProximityThreshold = 0.4;
036    /**
037     * How far above and below the threshold the distance needs to be to
038     * trigger undetected and detected, respectively. This is used to
039     * prevent bouncing between the detected and undetected states for
040     * objects on the threshold.
041     * <p>
042     * If the threshold is set to 0.1 meters, and the hysteresis is 0.01
043     * meters, then an object needs to be within 0.09 meters to be
044     * detected. After the object is first detected, the distance then
045     * needs to exceed 0.11 meters to become undetected again.
046     * 
047     * <ul>
048     *   <li> <b>Minimum Value:</b> 0
049     *   <li> <b>Maximum Value:</b> 1
050     *   <li> <b>Default Value:</b> 0.01
051     *   <li> <b>Units:</b> m
052     * </ul>
053     */
054    public double ProximityHysteresis = 0.01;
055    /**
056     * The minimum allowable signal strength before determining the
057     * measurement is valid.
058     * <p>
059     * If the signal strength is particularly low, this typically means
060     * the object is far away and there's fewer total samples to derive
061     * the distance from. Set this value to be below the lowest strength
062     * you see when you're detecting an object with the CANrange; the
063     * default of 2500 is typically acceptable in most cases.
064     * 
065     * <ul>
066     *   <li> <b>Minimum Value:</b> 1
067     *   <li> <b>Maximum Value:</b> 15000
068     *   <li> <b>Default Value:</b> 2500
069     *   <li> <b>Units:</b> 
070     * </ul>
071     */
072    public double MinSignalStrengthForValidMeasurement = 2500;
073    
074    /**
075     * Modifies this configuration's ProximityThreshold parameter and returns itself for
076     * method-chaining and easier to use config API.
077     * <p>
078     * Threshold for object detection.
079     * 
080     * <ul>
081     *   <li> <b>Minimum Value:</b> 0
082     *   <li> <b>Maximum Value:</b> 4
083     *   <li> <b>Default Value:</b> 0.4
084     *   <li> <b>Units:</b> m
085     * </ul>
086     *
087     * @param newProximityThreshold Parameter to modify
088     * @return Itself
089     */
090    public ProximityParamsConfigs withProximityThreshold(double newProximityThreshold)
091    {
092        ProximityThreshold = newProximityThreshold;
093        return this;
094    }
095    
096    /**
097     * Modifies this configuration's ProximityThreshold parameter and returns itself for
098     * method-chaining and easier to use config API.
099     * <p>
100     * Threshold for object detection.
101     * 
102     * <ul>
103     *   <li> <b>Minimum Value:</b> 0
104     *   <li> <b>Maximum Value:</b> 4
105     *   <li> <b>Default Value:</b> 0.4
106     *   <li> <b>Units:</b> m
107     * </ul>
108     *
109     * @param newProximityThreshold Parameter to modify
110     * @return Itself
111     */
112    public ProximityParamsConfigs withProximityThreshold(Distance newProximityThreshold)
113    {
114        ProximityThreshold = newProximityThreshold.in(Meters);
115        return this;
116    }
117    
118    /**
119     * Helper method to get this configuration's ProximityThreshold parameter converted
120     * to a unit type. If not using the Java units library, {@link #ProximityThreshold}
121     * can be accessed directly instead.
122     * <p>
123     * Threshold for object detection.
124     * 
125     * <ul>
126     *   <li> <b>Minimum Value:</b> 0
127     *   <li> <b>Maximum Value:</b> 4
128     *   <li> <b>Default Value:</b> 0.4
129     *   <li> <b>Units:</b> m
130     * </ul>
131     *
132     * @return ProximityThreshold
133     */
134    public Distance getProximityThresholdMeasure()
135    {
136        return Meters.of(ProximityThreshold);
137    }
138    
139    /**
140     * Modifies this configuration's ProximityHysteresis parameter and returns itself for
141     * method-chaining and easier to use config API.
142     * <p>
143     * How far above and below the threshold the distance needs to be to
144     * trigger undetected and detected, respectively. This is used to
145     * prevent bouncing between the detected and undetected states for
146     * objects on the threshold.
147     * <p>
148     * If the threshold is set to 0.1 meters, and the hysteresis is 0.01
149     * meters, then an object needs to be within 0.09 meters to be
150     * detected. After the object is first detected, the distance then
151     * needs to exceed 0.11 meters to become undetected again.
152     * 
153     * <ul>
154     *   <li> <b>Minimum Value:</b> 0
155     *   <li> <b>Maximum Value:</b> 1
156     *   <li> <b>Default Value:</b> 0.01
157     *   <li> <b>Units:</b> m
158     * </ul>
159     *
160     * @param newProximityHysteresis Parameter to modify
161     * @return Itself
162     */
163    public ProximityParamsConfigs withProximityHysteresis(double newProximityHysteresis)
164    {
165        ProximityHysteresis = newProximityHysteresis;
166        return this;
167    }
168    
169    /**
170     * Modifies this configuration's ProximityHysteresis parameter and returns itself for
171     * method-chaining and easier to use config API.
172     * <p>
173     * How far above and below the threshold the distance needs to be to
174     * trigger undetected and detected, respectively. This is used to
175     * prevent bouncing between the detected and undetected states for
176     * objects on the threshold.
177     * <p>
178     * If the threshold is set to 0.1 meters, and the hysteresis is 0.01
179     * meters, then an object needs to be within 0.09 meters to be
180     * detected. After the object is first detected, the distance then
181     * needs to exceed 0.11 meters to become undetected again.
182     * 
183     * <ul>
184     *   <li> <b>Minimum Value:</b> 0
185     *   <li> <b>Maximum Value:</b> 1
186     *   <li> <b>Default Value:</b> 0.01
187     *   <li> <b>Units:</b> m
188     * </ul>
189     *
190     * @param newProximityHysteresis Parameter to modify
191     * @return Itself
192     */
193    public ProximityParamsConfigs withProximityHysteresis(Distance newProximityHysteresis)
194    {
195        ProximityHysteresis = newProximityHysteresis.in(Meters);
196        return this;
197    }
198    
199    /**
200     * Helper method to get this configuration's ProximityHysteresis parameter converted
201     * to a unit type. If not using the Java units library, {@link #ProximityHysteresis}
202     * can be accessed directly instead.
203     * <p>
204     * How far above and below the threshold the distance needs to be to
205     * trigger undetected and detected, respectively. This is used to
206     * prevent bouncing between the detected and undetected states for
207     * objects on the threshold.
208     * <p>
209     * If the threshold is set to 0.1 meters, and the hysteresis is 0.01
210     * meters, then an object needs to be within 0.09 meters to be
211     * detected. After the object is first detected, the distance then
212     * needs to exceed 0.11 meters to become undetected again.
213     * 
214     * <ul>
215     *   <li> <b>Minimum Value:</b> 0
216     *   <li> <b>Maximum Value:</b> 1
217     *   <li> <b>Default Value:</b> 0.01
218     *   <li> <b>Units:</b> m
219     * </ul>
220     *
221     * @return ProximityHysteresis
222     */
223    public Distance getProximityHysteresisMeasure()
224    {
225        return Meters.of(ProximityHysteresis);
226    }
227    
228    /**
229     * Modifies this configuration's MinSignalStrengthForValidMeasurement parameter and returns itself for
230     * method-chaining and easier to use config API.
231     * <p>
232     * The minimum allowable signal strength before determining the
233     * measurement is valid.
234     * <p>
235     * If the signal strength is particularly low, this typically means
236     * the object is far away and there's fewer total samples to derive
237     * the distance from. Set this value to be below the lowest strength
238     * you see when you're detecting an object with the CANrange; the
239     * default of 2500 is typically acceptable in most cases.
240     * 
241     * <ul>
242     *   <li> <b>Minimum Value:</b> 1
243     *   <li> <b>Maximum Value:</b> 15000
244     *   <li> <b>Default Value:</b> 2500
245     *   <li> <b>Units:</b> 
246     * </ul>
247     *
248     * @param newMinSignalStrengthForValidMeasurement Parameter to modify
249     * @return Itself
250     */
251    public ProximityParamsConfigs withMinSignalStrengthForValidMeasurement(double newMinSignalStrengthForValidMeasurement)
252    {
253        MinSignalStrengthForValidMeasurement = newMinSignalStrengthForValidMeasurement;
254        return this;
255    }
256
257    
258
259    @Override
260    public String toString()
261    {
262        String ss = "Config Group: ProximityParams\n";
263        ss += "    ProximityThreshold: " + ProximityThreshold + " m" + "\n";
264        ss += "    ProximityHysteresis: " + ProximityHysteresis + " m" + "\n";
265        ss += "    MinSignalStrengthForValidMeasurement: " + MinSignalStrengthForValidMeasurement + "\n";
266        return ss;
267    }
268
269    /**
270     *
271     */
272    public StatusCode deserialize(String to_deserialize)
273    {
274        ProximityThreshold = ConfigJNI.Deserializedouble(SpnValue.CANrange_ProximityThreshold.value, to_deserialize);
275        ProximityHysteresis = ConfigJNI.Deserializedouble(SpnValue.CANrange_ProximityHysteresis.value, to_deserialize);
276        MinSignalStrengthForValidMeasurement = ConfigJNI.Deserializedouble(SpnValue.CANrange_MinSigStrengthForValidMeas.value, to_deserialize);
277        return  StatusCode.OK;
278    }
279
280    /**
281     *
282     */
283    public String serialize()
284    {
285        String ss = "";
286        ss += ConfigJNI.Serializedouble(SpnValue.CANrange_ProximityThreshold.value, ProximityThreshold);
287        ss += ConfigJNI.Serializedouble(SpnValue.CANrange_ProximityHysteresis.value, ProximityHysteresis);
288        ss += ConfigJNI.Serializedouble(SpnValue.CANrange_MinSigStrengthForValidMeas.value, MinSignalStrengthForValidMeasurement);
289        return ss;
290    }
291}
292