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 PID to target velocity with duty cycle feedforward.
015 * <p>
016 * This control mode will set the motor's velocity setpoint to the velocity specified by the user. In
017 * addition, it will apply an additional voltage as an arbitrary feedforward value.
018 */
019public class VelocityDutyCycle extends ControlRequest
020{
021    private boolean applyConfigsOnRequest;
022    /**
023     * Velocity to drive toward in rotations per second.
024     */
025    public double Velocity;
026    /**
027     * Set to true to use FOC commutation, which increases peak power by ~15%. Set
028     * to false to use trapezoidal commutation.  FOC improves motor performance by
029     * leveraging torque (current) control.  However, this may be inconvenient for
030     * applications that require specifying duty cycle or voltage.  CTR-Electronics
031     * has developed a hybrid method that combines the performances gains of FOC
032     * while still allowing applications to provide duty cycle or voltage demand. 
033     * This not to be confused with simple sinusoidal control or phase voltage
034     * control which lacks the performance gains.
035     */
036    public boolean EnableFOC;
037    /**
038     * Feedforward to apply in fractional units between -1 and +1.
039     */
040    public double FeedForward;
041    /**
042     * Select which gains are applied by selecting the slot.  Use the configuration
043     * api to set the gain values for the selected slot before enabling this
044     * feature. Slot must be within [0,2].
045     */
046    public int Slot;
047    /**
048     * Set to true to static-brake the rotor when output is zero (or within
049     * deadband).  Set to false to use the NeutralMode configuration setting
050     * (default). This flag exists to provide the fundamental behavior of this
051     * control when output is zero, which is to provide 0V to the motor.
052     */
053    public boolean OverrideBrakeDurNeutral;
054
055    
056    /**
057     * The period at which this control will update at.
058     * This is designated in Hertz, with a minimum of 20 Hz
059     * (every 50 ms) and a maximum of 1000 Hz (every 1 ms).
060     * <p>
061     * If this field is set to 0 Hz, the control request will
062     * be sent immediately as a one-shot frame. This may be useful
063     * for advanced applications that require outputs to be
064     * synchronized with data acquisition. In this case, we
065     * recommend not exceeding 50 ms between control calls.
066     */
067    public double UpdateFreqHz = 100; // Default to 100Hz
068
069    /**
070     * The timeout when sending configs associated with this control
071     */
072    public double configTimeout = 0.1;
073
074    /**
075     * Request PID to target velocity with duty cycle feedforward.
076     * <p>
077     * This control mode will set the motor's velocity setpoint to the velocity
078     * specified by the user. In addition, it will apply an additional voltage
079     * as an arbitrary feedforward value.
080     *
081     * @param Velocity     Velocity to drive toward in rotations per second.
082     * @param EnableFOC     Set to true to use FOC commutation, which increases
083     *                      peak power by ~15%. Set to false to use trapezoidal
084     *                      commutation.  FOC improves motor performance by
085     *                      leveraging torque (current) control.  However, this
086     *                      may be inconvenient for applications that require
087     *                      specifying duty cycle or voltage.  CTR-Electronics
088     *                      has developed a hybrid method that combines the
089     *                      performances gains of FOC while still allowing
090     *                      applications to provide duty cycle or voltage
091     *                      demand.  This not to be confused with simple
092     *                      sinusoidal control or phase voltage control which
093     *                      lacks the performance gains.
094     * @param FeedForward     Feedforward to apply in fractional units between
095     *                        -1 and +1.
096     * @param Slot     Select which gains are applied by selecting the slot. 
097     *                 Use the configuration api to set the gain values for the
098     *                 selected slot before enabling this feature. Slot must be
099     *                 within [0,2].
100     * @param OverrideBrakeDurNeutral     Set to true to static-brake the rotor
101     *                                    when output is zero (or within
102     *                                    deadband).  Set to false to use the
103     *                                    NeutralMode configuration setting
104     *                                    (default). This flag exists to provide
105     *                                    the fundamental behavior of this
106     *                                    control when output is zero, which is
107     *                                    to provide 0V to the motor.
108     */
109    public VelocityDutyCycle(double Velocity, boolean EnableFOC, double FeedForward, int Slot, boolean OverrideBrakeDurNeutral)
110    {
111        super("VelocityDutyCycle");
112        this.Velocity = Velocity;
113        this.EnableFOC = EnableFOC;
114        this.FeedForward = FeedForward;
115        this.Slot = Slot;
116        this.OverrideBrakeDurNeutral = OverrideBrakeDurNeutral;
117    }
118
119    /**
120     * Request PID to target velocity with duty cycle feedforward.
121     * <p>
122     * This control mode will set the motor's velocity setpoint to the velocity
123     * specified by the user. In addition, it will apply an additional voltage
124     * as an arbitrary feedforward value.
125     *
126     * @param Velocity     Velocity to drive toward in rotations per second.
127     */
128    public VelocityDutyCycle(double Velocity)
129    {
130        this(Velocity, true, 0.0, 0, false);
131    }
132
133    @Override
134    public String toString()
135    {
136        String ss = "class: VelocityDutyCycle\n";
137        ss += "Velocity: " + Velocity + "\n";
138        ss += "EnableFOC: " + EnableFOC + "\n";
139        ss += "FeedForward: " + FeedForward + "\n";
140        ss += "Slot: " + Slot + "\n";
141        ss += "OverrideBrakeDurNeutral: " + OverrideBrakeDurNeutral + "\n";
142        return ss;
143    }
144
145    @Override
146    public StatusCode sendRequest(String network, int deviceHash, boolean cancelOtherRequests)
147    {
148        var ref = requestReference.getNameValues();
149        ref.put("Velocity", String.valueOf(this.Velocity));
150        ref.put("EnableFOC", String.valueOf(this.EnableFOC));
151        ref.put("FeedForward", String.valueOf(this.FeedForward));
152        ref.put("Slot", String.valueOf(this.Slot));
153        ref.put("OverrideBrakeDurNeutral", String.valueOf(this.OverrideBrakeDurNeutral));
154        String ss = "";
155        
156        ControlConfigJNI.JNI_RequestConfigApply(network, deviceHash, configTimeout, ss, applyConfigsOnRequest);
157        applyConfigsOnRequest = false;
158        return StatusCode.valueOf(ControlJNI.JNI_RequestControlVelocityDutyCycle(
159                network, deviceHash, UpdateFreqHz, cancelOtherRequests, Velocity, EnableFOC, FeedForward, Slot, OverrideBrakeDurNeutral));
160    }
161    
162    /**
163     * Modifies this Control Request's Velocity parameter and returns itself for
164     * method-chaining and easier to use request API.
165     *
166     * @param newVelocity Parameter to modify
167     * @return Itself
168     */
169    public VelocityDutyCycle withVelocity(double newVelocity)
170    {
171        Velocity = newVelocity;
172        return this;
173    }
174    
175    /**
176     * Modifies this Control Request's EnableFOC parameter and returns itself for
177     * method-chaining and easier to use request API.
178     *
179     * @param newEnableFOC Parameter to modify
180     * @return Itself
181     */
182    public VelocityDutyCycle withEnableFOC(boolean newEnableFOC)
183    {
184        EnableFOC = newEnableFOC;
185        return this;
186    }
187    
188    /**
189     * Modifies this Control Request's FeedForward parameter and returns itself for
190     * method-chaining and easier to use request API.
191     *
192     * @param newFeedForward Parameter to modify
193     * @return Itself
194     */
195    public VelocityDutyCycle withFeedForward(double newFeedForward)
196    {
197        FeedForward = newFeedForward;
198        return this;
199    }
200    
201    /**
202     * Modifies this Control Request's Slot parameter and returns itself for
203     * method-chaining and easier to use request API.
204     *
205     * @param newSlot Parameter to modify
206     * @return Itself
207     */
208    public VelocityDutyCycle withSlot(int newSlot)
209    {
210        Slot = newSlot;
211        return this;
212    }
213    
214    /**
215     * Modifies this Control Request's OverrideBrakeDurNeutral parameter and returns itself for
216     * method-chaining and easier to use request API.
217     *
218     * @param newOverrideBrakeDurNeutral Parameter to modify
219     * @return Itself
220     */
221    public VelocityDutyCycle withOverrideBrakeDurNeutral(boolean newOverrideBrakeDurNeutral)
222    {
223        OverrideBrakeDurNeutral = newOverrideBrakeDurNeutral;
224        return this;
225    }
226    /**
227     * Sets the period at which this control will update at.
228     * This is designated in Hertz, with a minimum of 20 Hz
229     * (every 50 ms) and a maximum of 1000 Hz (every 1 ms).
230     * <p>
231     * If this field is set to 0 Hz, the control request will
232     * be sent immediately as a one-shot frame. This may be useful
233     * for advanced applications that require outputs to be
234     * synchronized with data acquisition. In this case, we
235     * recommend not exceeding 50 ms between control calls.
236     *
237     * @param newUpdateFreqHz Parameter to modify
238     * @return Itself
239     */
240    public VelocityDutyCycle withUpdateFreqHz(double newUpdateFreqHz)
241    {
242        UpdateFreqHz = newUpdateFreqHz;
243        return this;
244    }
245    /**
246     * Forces configs to be applied the next time this is used in a setControl.
247     * <p>
248     * This is not necessary in the majority of cases, because Phoenix will make sure configs are
249     * properly set when they are not already set
250     */
251    public void forceApplyConfigs() { applyConfigsOnRequest = true; }
252}
253