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.phoenixpro.controls;
008
009import com.ctre.phoenix6.StatusCode;
010import com.ctre.phoenix6.controls.jni.ControlJNI;
011import com.ctre.phoenix6.controls.jni.ControlConfigJNI;
012
013/**
014 * Request a specified motor current (field oriented control).
015 * <p>
016 * This control request will drive the motor to the requested motor (stator) current value.  This leverages
017 * field oriented control (FOC), which means greater peak power than what is documented.  This scales to
018 * torque based on Motor's kT constant.
019 *
020 * @deprecated Classes in the phoenixpro package will be removed in 2024.
021 *             Users should instead use classes from the phoenix6 package.
022 */
023@Deprecated(forRemoval = true)
024public class TorqueCurrentFOC extends ControlRequest
025{
026    private boolean applyConfigsOnRequest;
027    /**
028     * Amount of motor current in Amperes
029     */
030    public double Output;
031    /**
032     * The maximum absolute motor output that can be applied, which effectively
033     * limits the velocity. For example, 0.50 means no more than 50% output in
034     * either direction.  This is useful for preventing the motor from spinning to
035     * its terminal velocity when there is no external torque applied unto the
036     * rotor.  Note this is absolute maximum, so the value should be between zero
037     * and one.
038     */
039    public double MaxAbsDutyCycle;
040    /**
041     * Deadband in Amperes.  If torque request is within deadband, the bridge output
042     * is neutral. If deadband is set to zero then there is effectively no deadband.
043     * Note if deadband is zero, a free spinning motor will spin for quite a while
044     * as the firmware attempts to hold the motor's bemf. If user expects motor to
045     * cease spinning quickly with a demand of zero, we recommend a deadband of one
046     * Ampere. This value will be converted to an integral value of amps.
047     */
048    public double Deadband;
049    /**
050     * Set to true to coast the rotor when output is zero (or within deadband).  Set
051     * to false to use the NeutralMode configuration setting (default). This flag
052     * exists to provide the fundamental behavior of this control when output is
053     * zero, which is to provide 0A (zero torque).
054     */
055    public boolean OverrideCoastDurNeutral;
056
057    
058    /**
059     * The period at which this control will update at.
060     * This is designated in Hertz, with a minimum of 20 Hz
061     * (every 50 ms) and a maximum of 1000 Hz (every 1 ms).
062     * <p>
063     * If this field is set to 0 Hz, the control request will
064     * be sent immediately as a one-shot frame. This may be useful
065     * for advanced applications that require outputs to be
066     * synchronized with data acquisition. In this case, we
067     * recommend not exceeding 50 ms between control calls.
068     */
069    public double UpdateFreqHz = 100; // Default to 100Hz
070
071    /**
072     * The timeout when sending configs associated with this control
073     */
074    public double configTimeout = 0.1;
075
076    /**
077     * Request a specified motor current (field oriented control).
078     * <p>
079     * This control request will drive the motor to the requested motor (stator)
080     * current value.  This leverages field oriented control (FOC), which means
081     * greater peak power than what is documented.  This scales to torque based
082     * on Motor's kT constant.
083     *
084     * @param Output     Amount of motor current in Amperes
085     * @param MaxAbsDutyCycle     The maximum absolute motor output that can be
086     *                            applied, which effectively limits the
087     *                            velocity. For example, 0.50 means no more than
088     *                            50% output in either direction.  This is
089     *                            useful for preventing the motor from spinning
090     *                            to its terminal velocity when there is no
091     *                            external torque applied unto the rotor.  Note
092     *                            this is absolute maximum, so the value should
093     *                            be between zero and one.
094     * @param Deadband     Deadband in Amperes.  If torque request is within
095     *                     deadband, the bridge output is neutral. If deadband
096     *                     is set to zero then there is effectively no deadband.
097     *                     Note if deadband is zero, a free spinning motor will
098     *                     spin for quite a while as the firmware attempts to
099     *                     hold the motor's bemf. If user expects motor to cease
100     *                     spinning quickly with a demand of zero, we recommend
101     *                     a deadband of one Ampere. This value will be
102     *                     converted to an integral value of amps.
103     * @param OverrideCoastDurNeutral     Set to true to coast the rotor when
104     *                                    output is zero (or within deadband). 
105     *                                    Set to false to use the NeutralMode
106     *                                    configuration setting (default). This
107     *                                    flag exists to provide the fundamental
108     *                                    behavior of this control when output
109     *                                    is zero, which is to provide 0A (zero
110     *                                    torque).
111     *
112     * @deprecated Classes in the phoenixpro package will be removed in 2024.
113     *             Users should instead use classes from the phoenix6 package.
114     */
115    @Deprecated(forRemoval = true)
116    public TorqueCurrentFOC(double Output, double MaxAbsDutyCycle, double Deadband, boolean OverrideCoastDurNeutral)
117    {
118        super("TorqueCurrentFOC");
119        this.Output = Output;
120        this.MaxAbsDutyCycle = MaxAbsDutyCycle;
121        this.Deadband = Deadband;
122        this.OverrideCoastDurNeutral = OverrideCoastDurNeutral;
123    }
124
125    /**
126     * Request a specified motor current (field oriented control).
127     * <p>
128     * This control request will drive the motor to the requested motor (stator)
129     * current value.  This leverages field oriented control (FOC), which means
130     * greater peak power than what is documented.  This scales to torque based
131     * on Motor's kT constant.
132     *
133     * @param Output     Amount of motor current in Amperes
134     *
135     * @deprecated Classes in the phoenixpro package will be removed in 2024.
136     *             Users should instead use classes from the phoenix6 package.
137     */
138    @Deprecated(forRemoval = true)
139    public TorqueCurrentFOC(double Output)
140    {
141        this(Output, 1.0, 0.0, false);
142    }
143
144    @Override
145    public String toString()
146    {
147        String ss = "class: TorqueCurrentFOC\n";
148        ss += "Output: " + Output + "\n";
149        ss += "MaxAbsDutyCycle: " + MaxAbsDutyCycle + "\n";
150        ss += "Deadband: " + Deadband + "\n";
151        ss += "OverrideCoastDurNeutral: " + OverrideCoastDurNeutral + "\n";
152        return ss;
153    }
154
155    @Override
156    public StatusCode sendRequest(String network, int deviceHash, boolean cancelOtherRequests)
157    {
158        var ref = requestReference.getNameValues();
159        ref.put("Output", String.valueOf(this.Output));
160        ref.put("MaxAbsDutyCycle", String.valueOf(this.MaxAbsDutyCycle));
161        ref.put("Deadband", String.valueOf(this.Deadband));
162        ref.put("OverrideCoastDurNeutral", String.valueOf(this.OverrideCoastDurNeutral));
163        String ss = "";
164        
165        ControlConfigJNI.JNI_RequestConfigApply(network, deviceHash, configTimeout, ss, applyConfigsOnRequest);
166        applyConfigsOnRequest = false;
167        return StatusCode.valueOf(ControlJNI.JNI_RequestControlTorqueCurrentFOC(
168                network, deviceHash, UpdateFreqHz, cancelOtherRequests, Output, MaxAbsDutyCycle, Deadband, OverrideCoastDurNeutral));
169    }
170    
171    /**
172     * Modifies this Control Request's Output parameter and returns itself for
173     * method-chaining and easier to use request API.
174     *
175     * @param newOutput Parameter to modify
176     * @return Itself
177     */
178    public TorqueCurrentFOC withOutput(double newOutput)
179    {
180        Output = newOutput;
181        return this;
182    }
183    
184    /**
185     * Modifies this Control Request's MaxAbsDutyCycle parameter and returns itself for
186     * method-chaining and easier to use request API.
187     *
188     * @param newMaxAbsDutyCycle Parameter to modify
189     * @return Itself
190     */
191    public TorqueCurrentFOC withMaxAbsDutyCycle(double newMaxAbsDutyCycle)
192    {
193        MaxAbsDutyCycle = newMaxAbsDutyCycle;
194        return this;
195    }
196    
197    /**
198     * Modifies this Control Request's Deadband parameter and returns itself for
199     * method-chaining and easier to use request API.
200     *
201     * @param newDeadband Parameter to modify
202     * @return Itself
203     */
204    public TorqueCurrentFOC withDeadband(double newDeadband)
205    {
206        Deadband = newDeadband;
207        return this;
208    }
209    
210    /**
211     * Modifies this Control Request's OverrideCoastDurNeutral parameter and returns itself for
212     * method-chaining and easier to use request API.
213     *
214     * @param newOverrideCoastDurNeutral Parameter to modify
215     * @return Itself
216     */
217    public TorqueCurrentFOC withOverrideCoastDurNeutral(boolean newOverrideCoastDurNeutral)
218    {
219        OverrideCoastDurNeutral = newOverrideCoastDurNeutral;
220        return this;
221    }
222    /**
223     * Sets the period at which this control will update at.
224     * This is designated in Hertz, with a minimum of 20 Hz
225     * (every 50 ms) and a maximum of 1000 Hz (every 1 ms).
226     * <p>
227     * If this field is set to 0 Hz, the control request will
228     * be sent immediately as a one-shot frame. This may be useful
229     * for advanced applications that require outputs to be
230     * synchronized with data acquisition. In this case, we
231     * recommend not exceeding 50 ms between control calls.
232     *
233     * @param newUpdateFreqHz Parameter to modify
234     * @return Itself
235     */
236    public TorqueCurrentFOC withUpdateFreqHz(double newUpdateFreqHz)
237    {
238        UpdateFreqHz = newUpdateFreqHz;
239        return this;
240    }
241    /**
242     * Forces configs to be applied the next time this is used in a setControl.
243     * <p>
244     * This is not necessary in the majority of cases, because Phoenix will make sure configs are
245     * properly set when they are not already set
246     */
247    public void forceApplyConfigs() { applyConfigsOnRequest = true; }
248}
249