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.phoenixpro.StatusCode;
010import com.ctre.phoenixpro.controls.jni.ControlJNI;
011import com.ctre.phoenixpro.controls.jni.ControlConfigJNI;
012
013/**
014 * Request a specified motor duty cycle.
015 * <p>
016 * This control mode will output a proportion of the supplied voltage which is supplied by the user.
017 */
018public class DutyCycleOut extends ControlRequest
019{
020    private boolean applyConfigsOnRequest;
021    /**
022     * Proportion of supply voltage to apply in fractional units between -1 and +1
023     */
024    public double Output;
025    /**
026     * Set to true to use FOC commutation, which increases peak power by ~15%. Set
027     * to false to use trapezoidal commutation.  FOC improves motor performance by
028     * leveraging torque (current) control.  However, this may be inconvenient for
029     * applications that require specifying duty cycle or voltage.  CTR-Electronics
030     * has developed a hybrid method that combines the performances gains of FOC
031     * while still allowing applications to provide duty cycle or voltage demand. 
032     * This not to be confused with simple sinusoidal control or phase voltage
033     * control which lacks the performance gains.
034     */
035    public boolean EnableFOC;
036    /**
037     * Set to true to static-brake the rotor when output is zero (or within
038     * deadband).  Set to false to use the NeutralMode configuration setting
039     * (default). This flag exists to provide the fundamental behavior of this
040     * control when output is zero, which is to provide 0V to the motor.
041     */
042    public boolean OverrideBrakeDurNeutral;
043
044    
045    /**
046     * The period at which this control will update at.
047     * This is designated in Hertz, with a minimum of 20 Hz
048     * (every 50 ms) and a maximum of 1000 Hz (every 1 ms).
049     * <p>
050     * If this field is set to 0 Hz, the control request will
051     * be sent immediately as a one-shot frame. This may be useful
052     * for advanced applications that require outputs to be
053     * synchronized with data acquisition. In this case, we
054     * recommend not exceeding 50 ms between control calls.
055     */
056    public double UpdateFreqHz = 100; // Default to 100Hz
057
058    /**
059     * The timeout when sending configs associated with this control
060     */
061    public double configTimeout = 0.1;
062
063    /**
064     * Request a specified motor duty cycle.
065     * <p>
066     * This control mode will output a proportion of the supplied voltage which
067     * is supplied by the user.
068     *
069     * @param Output     Proportion of supply voltage to apply in fractional
070     *                   units between -1 and +1
071     * @param EnableFOC     Set to true to use FOC commutation, which increases
072     *                      peak power by ~15%. Set to false to use trapezoidal
073     *                      commutation.  FOC improves motor performance by
074     *                      leveraging torque (current) control.  However, this
075     *                      may be inconvenient for applications that require
076     *                      specifying duty cycle or voltage.  CTR-Electronics
077     *                      has developed a hybrid method that combines the
078     *                      performances gains of FOC while still allowing
079     *                      applications to provide duty cycle or voltage
080     *                      demand.  This not to be confused with simple
081     *                      sinusoidal control or phase voltage control which
082     *                      lacks the performance gains.
083     * @param OverrideBrakeDurNeutral     Set to true to static-brake the rotor
084     *                                    when output is zero (or within
085     *                                    deadband).  Set to false to use the
086     *                                    NeutralMode configuration setting
087     *                                    (default). This flag exists to provide
088     *                                    the fundamental behavior of this
089     *                                    control when output is zero, which is
090     *                                    to provide 0V to the motor.
091     */
092    public DutyCycleOut(double Output, boolean EnableFOC, boolean OverrideBrakeDurNeutral)
093    {
094        super("DutyCycleOut");
095        this.Output = Output;
096        this.EnableFOC = EnableFOC;
097        this.OverrideBrakeDurNeutral = OverrideBrakeDurNeutral;
098    }
099
100    /**
101     * Request a specified motor duty cycle.
102     * <p>
103     * This control mode will output a proportion of the supplied voltage which
104     * is supplied by the user.
105     *
106     * @param Output     Proportion of supply voltage to apply in fractional
107     *                   units between -1 and +1
108     */
109    public DutyCycleOut(double Output)
110    {
111        this(Output, true, false);
112    }
113
114    @Override
115    public String toString()
116    {
117        String ss = "class: DutyCycleOut\n";
118        ss += "Output: " + Output + "\n";
119        ss += "EnableFOC: " + EnableFOC + "\n";
120        ss += "OverrideBrakeDurNeutral: " + OverrideBrakeDurNeutral + "\n";
121        return ss;
122    }
123
124    @Override
125    public StatusCode sendRequest(String network, int deviceHash, boolean cancelOtherRequests)
126    {
127        var ref = requestReference.getNameValues();
128        ref.put("Output", String.valueOf(this.Output));
129        ref.put("EnableFOC", String.valueOf(this.EnableFOC));
130        ref.put("OverrideBrakeDurNeutral", String.valueOf(this.OverrideBrakeDurNeutral));
131        String ss = "";
132        
133        ControlConfigJNI.JNI_RequestConfigApply(network, deviceHash, configTimeout, ss, applyConfigsOnRequest);
134        applyConfigsOnRequest = false;
135        return StatusCode.valueOf(ControlJNI.JNI_RequestControlDutyCycleOut(
136                network, deviceHash, UpdateFreqHz, cancelOtherRequests, Output, EnableFOC, OverrideBrakeDurNeutral));
137    }
138    
139    /**
140     * Modifies this Control Request's Output parameter and returns itself for
141     * method-chaining and easier to use request API.
142     *
143     * @param newOutput Parameter to modify
144     * @return Itself
145     */
146    public DutyCycleOut withOutput(double newOutput)
147    {
148        Output = newOutput;
149        return this;
150    }
151    
152    /**
153     * Modifies this Control Request's EnableFOC parameter and returns itself for
154     * method-chaining and easier to use request API.
155     *
156     * @param newEnableFOC Parameter to modify
157     * @return Itself
158     */
159    public DutyCycleOut withEnableFOC(boolean newEnableFOC)
160    {
161        EnableFOC = newEnableFOC;
162        return this;
163    }
164    
165    /**
166     * Modifies this Control Request's OverrideBrakeDurNeutral parameter and returns itself for
167     * method-chaining and easier to use request API.
168     *
169     * @param newOverrideBrakeDurNeutral Parameter to modify
170     * @return Itself
171     */
172    public DutyCycleOut withOverrideBrakeDurNeutral(boolean newOverrideBrakeDurNeutral)
173    {
174        OverrideBrakeDurNeutral = newOverrideBrakeDurNeutral;
175        return this;
176    }
177    /**
178     * Sets the period at which this control will update at.
179     * This is designated in Hertz, with a minimum of 20 Hz
180     * (every 50 ms) and a maximum of 1000 Hz (every 1 ms).
181     * <p>
182     * If this field is set to 0 Hz, the control request will
183     * be sent immediately as a one-shot frame. This may be useful
184     * for advanced applications that require outputs to be
185     * synchronized with data acquisition. In this case, we
186     * recommend not exceeding 50 ms between control calls.
187     *
188     * @param newUpdateFreqHz Parameter to modify
189     * @return Itself
190     */
191    public DutyCycleOut withUpdateFreqHz(double newUpdateFreqHz)
192    {
193        UpdateFreqHz = newUpdateFreqHz;
194        return this;
195    }
196    /**
197     * Forces configs to be applied the next time this is used in a setControl.
198     * <p>
199     * This is not necessary in the majority of cases, because Phoenix will make sure configs are
200     * properly set when they are not already set
201     */
202    public void forceApplyConfigs() { applyConfigsOnRequest = true; }
203}
204