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.controls;
008
009import com.ctre.phoenix6.StatusCode;
010import com.ctre.phoenix6.controls.jni.ControlJNI;
011
012import java.util.HashMap;
013import java.util.Map;
014
015/**
016 * Request a specified motor duty cycle.
017 * <p>
018 * This control mode will output a proportion of the supplied voltage which is supplied by the user.
019 */
020public class DutyCycleOut extends ControlRequest implements Cloneable
021{
022    /**
023     * Proportion of supply voltage to apply in fractional units between -1 and +1
024     */
025    public double Output;
026    /**
027     * Set to true to use FOC commutation (requires Phoenix Pro), which increases
028     * peak power by ~15%. Set to false to use trapezoidal commutation.
029     * <p>
030     * FOC improves motor performance by leveraging torque (current) control. 
031     * However, this may be inconvenient for applications that require specifying
032     * duty cycle or voltage.  CTR-Electronics has developed a hybrid method that
033     * combines the performances gains of FOC while still allowing applications to
034     * provide duty cycle or voltage demand.  This not to be confused with simple
035     * sinusoidal control or phase voltage control which lacks the performance
036     * gains.
037     */
038    public boolean EnableFOC;
039    /**
040     * Set to true to static-brake the rotor when output is zero (or within
041     * deadband).  Set to false to use the NeutralMode configuration setting
042     * (default). This flag exists to provide the fundamental behavior of this
043     * control when output is zero, which is to provide 0V to the motor.
044     */
045    public boolean OverrideBrakeDurNeutral;
046    /**
047     * Set to true to force forward limiting.  This allows users to use other limit
048     * switch sensors connected to robot controller.  This also allows use of active
049     * sensors that require external power.
050     */
051    public boolean LimitForwardMotion;
052    /**
053     * Set to true to force reverse limiting.  This allows users to use other limit
054     * switch sensors connected to robot controller.  This also allows use of active
055     * sensors that require external power.
056     */
057    public boolean LimitReverseMotion;
058
059    /**
060     * The period at which this control will update at.
061     * This is designated in Hertz, with a minimum of 20 Hz
062     * (every 50 ms) and a maximum of 1000 Hz (every 1 ms).
063     * <p>
064     * If this field is set to 0 Hz, the control request will
065     * be sent immediately as a one-shot frame. This may be useful
066     * for advanced applications that require outputs to be
067     * synchronized with data acquisition. In this case, we
068     * recommend not exceeding 50 ms between control calls.
069     */
070    public double UpdateFreqHz = 100; // Default to 100Hz
071
072    /**
073     * Request a specified motor duty cycle.
074     * <p>
075     * This control mode will output a proportion of the supplied voltage which is
076     * supplied by the user.
077     * 
078     * @param Output    Proportion of supply voltage to apply in fractional units
079     *                  between -1 and +1
080     * @param EnableFOC    Set to true to use FOC commutation (requires Phoenix
081     *                     Pro), which increases peak power by ~15%. Set to false to
082     *                     use trapezoidal commutation.
083     *                     <p>
084     *                     FOC improves motor performance by leveraging torque
085     *                     (current) control.  However, this may be inconvenient for
086     *                     applications that require specifying duty cycle or
087     *                     voltage.  CTR-Electronics has developed a hybrid method
088     *                     that combines the performances gains of FOC while still
089     *                     allowing applications to provide duty cycle or voltage
090     *                     demand.  This not to be confused with simple sinusoidal
091     *                     control or phase voltage control which lacks the
092     *                     performance gains.
093     * @param OverrideBrakeDurNeutral    Set to true to static-brake the rotor when
094     *                                   output is zero (or within deadband).  Set
095     *                                   to false to use the NeutralMode
096     *                                   configuration setting (default). This flag
097     *                                   exists to provide the fundamental behavior
098     *                                   of this control when output is zero, which
099     *                                   is to provide 0V to the motor.
100     * @param LimitForwardMotion    Set to true to force forward limiting.  This
101     *                              allows users to use other limit switch sensors
102     *                              connected to robot controller.  This also allows
103     *                              use of active sensors that require external
104     *                              power.
105     * @param LimitReverseMotion    Set to true to force reverse limiting.  This
106     *                              allows users to use other limit switch sensors
107     *                              connected to robot controller.  This also allows
108     *                              use of active sensors that require external
109     *                              power.
110     */
111    public DutyCycleOut(double Output, boolean EnableFOC, boolean OverrideBrakeDurNeutral, boolean LimitForwardMotion, boolean LimitReverseMotion)
112    {
113        super("DutyCycleOut");
114        this.Output = Output;
115        this.EnableFOC = EnableFOC;
116        this.OverrideBrakeDurNeutral = OverrideBrakeDurNeutral;
117        this.LimitForwardMotion = LimitForwardMotion;
118        this.LimitReverseMotion = LimitReverseMotion;
119    }
120
121        /**
122     * Request a specified motor duty cycle.
123     * <p>
124     * This control mode will output a proportion of the supplied voltage which is
125     * supplied by the user.
126     * 
127     * @param Output    Proportion of supply voltage to apply in fractional units
128     *                  between -1 and +1
129     */
130    public DutyCycleOut(double Output)
131    {
132        this(Output, true, false, false, false);
133    }
134
135    @Override
136    public String toString()
137    {
138        String ss = "class: DutyCycleOut\n";
139        ss += "Output: " + Output + "\n";
140        ss += "EnableFOC: " + EnableFOC + "\n";
141        ss += "OverrideBrakeDurNeutral: " + OverrideBrakeDurNeutral + "\n";
142        ss += "LimitForwardMotion: " + LimitForwardMotion + "\n";
143        ss += "LimitReverseMotion: " + LimitReverseMotion + "\n";
144        return ss;
145    }
146
147    @Override
148    public StatusCode sendRequest(String network, int deviceHash, boolean cancelOtherRequests)
149    {
150        return StatusCode.valueOf(ControlJNI.JNI_RequestControlDutyCycleOut(
151                network, deviceHash, UpdateFreqHz, cancelOtherRequests, Output, EnableFOC, OverrideBrakeDurNeutral, LimitForwardMotion, LimitReverseMotion));
152    }
153
154    /**
155     * Gets information about this control request.
156     *
157     * @return Map of control parameter names and corresponding applied values
158     */
159    @Override
160    public Map<String, String> getControlInfo()
161    {
162        var controlInfo = new HashMap<String, String>();
163        controlInfo.put("Name", getName());
164        controlInfo.put("Output", String.valueOf(this.Output));
165        controlInfo.put("EnableFOC", String.valueOf(this.EnableFOC));
166        controlInfo.put("OverrideBrakeDurNeutral", String.valueOf(this.OverrideBrakeDurNeutral));
167        controlInfo.put("LimitForwardMotion", String.valueOf(this.LimitForwardMotion));
168        controlInfo.put("LimitReverseMotion", String.valueOf(this.LimitReverseMotion));
169        return controlInfo;
170    }
171    
172    /**
173     * Modifies this Control Request's Output parameter and returns itself for
174     * method-chaining and easier to use request API.
175     * <p>
176     * Proportion of supply voltage to apply in fractional units between -1 and +1
177     *
178     * @param newOutput Parameter to modify
179     * @return Itself
180     */
181    public DutyCycleOut withOutput(double newOutput)
182    {
183        Output = newOutput;
184        return this;
185    }
186    
187    /**
188     * Modifies this Control Request's EnableFOC parameter and returns itself for
189     * method-chaining and easier to use request API.
190     * <p>
191     * Set to true to use FOC commutation (requires Phoenix Pro), which increases
192     * peak power by ~15%. Set to false to use trapezoidal commutation.
193     * <p>
194     * FOC improves motor performance by leveraging torque (current) control. 
195     * However, this may be inconvenient for applications that require specifying
196     * duty cycle or voltage.  CTR-Electronics has developed a hybrid method that
197     * combines the performances gains of FOC while still allowing applications to
198     * provide duty cycle or voltage demand.  This not to be confused with simple
199     * sinusoidal control or phase voltage control which lacks the performance
200     * gains.
201     *
202     * @param newEnableFOC Parameter to modify
203     * @return Itself
204     */
205    public DutyCycleOut withEnableFOC(boolean newEnableFOC)
206    {
207        EnableFOC = newEnableFOC;
208        return this;
209    }
210    
211    /**
212     * Modifies this Control Request's OverrideBrakeDurNeutral parameter and returns itself for
213     * method-chaining and easier to use request API.
214     * <p>
215     * Set to true to static-brake the rotor when output is zero (or within
216     * deadband).  Set to false to use the NeutralMode configuration setting
217     * (default). This flag exists to provide the fundamental behavior of this
218     * control when output is zero, which is to provide 0V to the motor.
219     *
220     * @param newOverrideBrakeDurNeutral Parameter to modify
221     * @return Itself
222     */
223    public DutyCycleOut withOverrideBrakeDurNeutral(boolean newOverrideBrakeDurNeutral)
224    {
225        OverrideBrakeDurNeutral = newOverrideBrakeDurNeutral;
226        return this;
227    }
228    
229    /**
230     * Modifies this Control Request's LimitForwardMotion parameter and returns itself for
231     * method-chaining and easier to use request API.
232     * <p>
233     * Set to true to force forward limiting.  This allows users to use other limit
234     * switch sensors connected to robot controller.  This also allows use of active
235     * sensors that require external power.
236     *
237     * @param newLimitForwardMotion Parameter to modify
238     * @return Itself
239     */
240    public DutyCycleOut withLimitForwardMotion(boolean newLimitForwardMotion)
241    {
242        LimitForwardMotion = newLimitForwardMotion;
243        return this;
244    }
245    
246    /**
247     * Modifies this Control Request's LimitReverseMotion parameter and returns itself for
248     * method-chaining and easier to use request API.
249     * <p>
250     * Set to true to force reverse limiting.  This allows users to use other limit
251     * switch sensors connected to robot controller.  This also allows use of active
252     * sensors that require external power.
253     *
254     * @param newLimitReverseMotion Parameter to modify
255     * @return Itself
256     */
257    public DutyCycleOut withLimitReverseMotion(boolean newLimitReverseMotion)
258    {
259        LimitReverseMotion = newLimitReverseMotion;
260        return this;
261    }
262    /**
263     * Sets the period at which this control will update at.
264     * This is designated in Hertz, with a minimum of 20 Hz
265     * (every 50 ms) and a maximum of 1000 Hz (every 1 ms).
266     * <p>
267     * If this field is set to 0 Hz, the control request will
268     * be sent immediately as a one-shot frame. This may be useful
269     * for advanced applications that require outputs to be
270     * synchronized with data acquisition. In this case, we
271     * recommend not exceeding 50 ms between control calls.
272     *
273     * @param newUpdateFreqHz Parameter to modify
274     * @return Itself
275     */
276    public DutyCycleOut withUpdateFreqHz(double newUpdateFreqHz)
277    {
278        UpdateFreqHz = newUpdateFreqHz;
279        return this;
280    }
281
282    @Override
283    public DutyCycleOut clone()
284    {
285        try {
286            return (DutyCycleOut)super.clone();
287        } catch (CloneNotSupportedException ex) {
288            /* this should never happen */
289            throw new RuntimeException(ex);
290        }
291    }
292}
293