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 PID to target velocity with voltage feedforward.
017 * <p>
018 * This control mode will set the motor's velocity setpoint to the velocity specified by the user. In
019 * addition, it will apply an additional voltage as an arbitrary feedforward value.
020 */
021public class VelocityVoltage extends ControlRequest implements Cloneable
022{
023    /**
024     * Velocity to drive toward in rotations per second.
025     */
026    public double Velocity;
027    /**
028     * Acceleration to drive toward in rotations per second squared. This is
029     * typically used for motion profiles generated by the robot program.
030     */
031    public double Acceleration;
032    /**
033     * Set to true to use FOC commutation (requires Phoenix Pro), which increases
034     * peak power by ~15%. Set to false to use trapezoidal commutation.
035     * <p>
036     * FOC improves motor performance by leveraging torque (current) control. 
037     * However, this may be inconvenient for applications that require specifying
038     * duty cycle or voltage.  CTR-Electronics has developed a hybrid method that
039     * combines the performances gains of FOC while still allowing applications to
040     * provide duty cycle or voltage demand.  This not to be confused with simple
041     * sinusoidal control or phase voltage control which lacks the performance
042     * gains.
043     */
044    public boolean EnableFOC;
045    /**
046     * Feedforward to apply in volts
047     */
048    public double FeedForward;
049    /**
050     * Select which gains are applied by selecting the slot.  Use the configuration
051     * api to set the gain values for the selected slot before enabling this
052     * feature. Slot must be within [0,2].
053     */
054    public int Slot;
055    /**
056     * Set to true to static-brake the rotor when output is zero (or within
057     * deadband).  Set to false to use the NeutralMode configuration setting
058     * (default). This flag exists to provide the fundamental behavior of this
059     * control when output is zero, which is to provide 0V to the motor.
060     */
061    public boolean OverrideBrakeDurNeutral;
062    /**
063     * Set to true to force forward limiting.  This allows users to use other limit
064     * switch sensors connected to robot controller.  This also allows use of active
065     * sensors that require external power.
066     */
067    public boolean LimitForwardMotion;
068    /**
069     * Set to true to force reverse limiting.  This allows users to use other limit
070     * switch sensors connected to robot controller.  This also allows use of active
071     * sensors that require external power.
072     */
073    public boolean LimitReverseMotion;
074
075    /**
076     * The period at which this control will update at.
077     * This is designated in Hertz, with a minimum of 20 Hz
078     * (every 50 ms) and a maximum of 1000 Hz (every 1 ms).
079     * <p>
080     * If this field is set to 0 Hz, the control request will
081     * be sent immediately as a one-shot frame. This may be useful
082     * for advanced applications that require outputs to be
083     * synchronized with data acquisition. In this case, we
084     * recommend not exceeding 50 ms between control calls.
085     */
086    public double UpdateFreqHz = 100; // Default to 100Hz
087
088    /**
089     * Request PID to target velocity with voltage feedforward.
090     * <p>
091     * This control mode will set the motor's velocity setpoint to the velocity
092     * specified by the user. In addition, it will apply an additional voltage as an
093     * arbitrary feedforward value.
094     * 
095     * @param Velocity    Velocity to drive toward in rotations per second.
096     * @param Acceleration    Acceleration to drive toward in rotations per second
097     *                        squared. This is typically used for motion profiles
098     *                        generated by the robot program.
099     * @param EnableFOC    Set to true to use FOC commutation (requires Phoenix
100     *                     Pro), which increases peak power by ~15%. Set to false to
101     *                     use trapezoidal commutation.
102     *                     <p>
103     *                     FOC improves motor performance by leveraging torque
104     *                     (current) control.  However, this may be inconvenient for
105     *                     applications that require specifying duty cycle or
106     *                     voltage.  CTR-Electronics has developed a hybrid method
107     *                     that combines the performances gains of FOC while still
108     *                     allowing applications to provide duty cycle or voltage
109     *                     demand.  This not to be confused with simple sinusoidal
110     *                     control or phase voltage control which lacks the
111     *                     performance gains.
112     * @param FeedForward    Feedforward to apply in volts
113     * @param Slot    Select which gains are applied by selecting the slot.  Use the
114     *                configuration api to set the gain values for the selected slot
115     *                before enabling this feature. Slot must be within [0,2].
116     * @param OverrideBrakeDurNeutral    Set to true to static-brake the rotor when
117     *                                   output is zero (or within deadband).  Set
118     *                                   to false to use the NeutralMode
119     *                                   configuration setting (default). This flag
120     *                                   exists to provide the fundamental behavior
121     *                                   of this control when output is zero, which
122     *                                   is to provide 0V to the motor.
123     * @param LimitForwardMotion    Set to true to force forward limiting.  This
124     *                              allows users to use other limit switch sensors
125     *                              connected to robot controller.  This also allows
126     *                              use of active sensors that require external
127     *                              power.
128     * @param LimitReverseMotion    Set to true to force reverse limiting.  This
129     *                              allows users to use other limit switch sensors
130     *                              connected to robot controller.  This also allows
131     *                              use of active sensors that require external
132     *                              power.
133     */
134    public VelocityVoltage(double Velocity, double Acceleration, boolean EnableFOC, double FeedForward, int Slot, boolean OverrideBrakeDurNeutral, boolean LimitForwardMotion, boolean LimitReverseMotion)
135    {
136        super("VelocityVoltage");
137        this.Velocity = Velocity;
138        this.Acceleration = Acceleration;
139        this.EnableFOC = EnableFOC;
140        this.FeedForward = FeedForward;
141        this.Slot = Slot;
142        this.OverrideBrakeDurNeutral = OverrideBrakeDurNeutral;
143        this.LimitForwardMotion = LimitForwardMotion;
144        this.LimitReverseMotion = LimitReverseMotion;
145    }
146
147        /**
148     * Request PID to target velocity with voltage feedforward.
149     * <p>
150     * This control mode will set the motor's velocity setpoint to the velocity
151     * specified by the user. In addition, it will apply an additional voltage as an
152     * arbitrary feedforward value.
153     * 
154     * @param Velocity    Velocity to drive toward in rotations per second.
155     */
156    public VelocityVoltage(double Velocity)
157    {
158        this(Velocity, 0.0, true, 0.0, 0, false, false, false);
159    }
160
161    @Override
162    public String toString()
163    {
164        String ss = "class: VelocityVoltage\n";
165        ss += "Velocity: " + Velocity + "\n";
166        ss += "Acceleration: " + Acceleration + "\n";
167        ss += "EnableFOC: " + EnableFOC + "\n";
168        ss += "FeedForward: " + FeedForward + "\n";
169        ss += "Slot: " + Slot + "\n";
170        ss += "OverrideBrakeDurNeutral: " + OverrideBrakeDurNeutral + "\n";
171        ss += "LimitForwardMotion: " + LimitForwardMotion + "\n";
172        ss += "LimitReverseMotion: " + LimitReverseMotion + "\n";
173        return ss;
174    }
175
176    @Override
177    public StatusCode sendRequest(String network, int deviceHash, boolean cancelOtherRequests)
178    {
179        return StatusCode.valueOf(ControlJNI.JNI_RequestControlVelocityVoltage(
180                network, deviceHash, UpdateFreqHz, cancelOtherRequests, Velocity, Acceleration, EnableFOC, FeedForward, Slot, OverrideBrakeDurNeutral, LimitForwardMotion, LimitReverseMotion));
181    }
182
183    /**
184     * Gets information about this control request.
185     *
186     * @return Map of control parameter names and corresponding applied values
187     */
188    @Override
189    public Map<String, String> getControlInfo()
190    {
191        var controlInfo = new HashMap<String, String>();
192        controlInfo.put("Name", getName());
193        controlInfo.put("Velocity", String.valueOf(this.Velocity));
194        controlInfo.put("Acceleration", String.valueOf(this.Acceleration));
195        controlInfo.put("EnableFOC", String.valueOf(this.EnableFOC));
196        controlInfo.put("FeedForward", String.valueOf(this.FeedForward));
197        controlInfo.put("Slot", String.valueOf(this.Slot));
198        controlInfo.put("OverrideBrakeDurNeutral", String.valueOf(this.OverrideBrakeDurNeutral));
199        controlInfo.put("LimitForwardMotion", String.valueOf(this.LimitForwardMotion));
200        controlInfo.put("LimitReverseMotion", String.valueOf(this.LimitReverseMotion));
201        return controlInfo;
202    }
203    
204    /**
205     * Modifies this Control Request's Velocity parameter and returns itself for
206     * method-chaining and easier to use request API.
207     * <p>
208     * Velocity to drive toward in rotations per second.
209     *
210     * @param newVelocity Parameter to modify
211     * @return Itself
212     */
213    public VelocityVoltage withVelocity(double newVelocity)
214    {
215        Velocity = newVelocity;
216        return this;
217    }
218    
219    /**
220     * Modifies this Control Request's Acceleration parameter and returns itself for
221     * method-chaining and easier to use request API.
222     * <p>
223     * Acceleration to drive toward in rotations per second squared. This is
224     * typically used for motion profiles generated by the robot program.
225     *
226     * @param newAcceleration Parameter to modify
227     * @return Itself
228     */
229    public VelocityVoltage withAcceleration(double newAcceleration)
230    {
231        Acceleration = newAcceleration;
232        return this;
233    }
234    
235    /**
236     * Modifies this Control Request's EnableFOC parameter and returns itself for
237     * method-chaining and easier to use request API.
238     * <p>
239     * Set to true to use FOC commutation (requires Phoenix Pro), which increases
240     * peak power by ~15%. Set to false to use trapezoidal commutation.
241     * <p>
242     * FOC improves motor performance by leveraging torque (current) control. 
243     * However, this may be inconvenient for applications that require specifying
244     * duty cycle or voltage.  CTR-Electronics has developed a hybrid method that
245     * combines the performances gains of FOC while still allowing applications to
246     * provide duty cycle or voltage demand.  This not to be confused with simple
247     * sinusoidal control or phase voltage control which lacks the performance
248     * gains.
249     *
250     * @param newEnableFOC Parameter to modify
251     * @return Itself
252     */
253    public VelocityVoltage withEnableFOC(boolean newEnableFOC)
254    {
255        EnableFOC = newEnableFOC;
256        return this;
257    }
258    
259    /**
260     * Modifies this Control Request's FeedForward parameter and returns itself for
261     * method-chaining and easier to use request API.
262     * <p>
263     * Feedforward to apply in volts
264     *
265     * @param newFeedForward Parameter to modify
266     * @return Itself
267     */
268    public VelocityVoltage withFeedForward(double newFeedForward)
269    {
270        FeedForward = newFeedForward;
271        return this;
272    }
273    
274    /**
275     * Modifies this Control Request's Slot parameter and returns itself for
276     * method-chaining and easier to use request API.
277     * <p>
278     * Select which gains are applied by selecting the slot.  Use the configuration
279     * api to set the gain values for the selected slot before enabling this
280     * feature. Slot must be within [0,2].
281     *
282     * @param newSlot Parameter to modify
283     * @return Itself
284     */
285    public VelocityVoltage withSlot(int newSlot)
286    {
287        Slot = newSlot;
288        return this;
289    }
290    
291    /**
292     * Modifies this Control Request's OverrideBrakeDurNeutral parameter and returns itself for
293     * method-chaining and easier to use request API.
294     * <p>
295     * Set to true to static-brake the rotor when output is zero (or within
296     * deadband).  Set to false to use the NeutralMode configuration setting
297     * (default). This flag exists to provide the fundamental behavior of this
298     * control when output is zero, which is to provide 0V to the motor.
299     *
300     * @param newOverrideBrakeDurNeutral Parameter to modify
301     * @return Itself
302     */
303    public VelocityVoltage withOverrideBrakeDurNeutral(boolean newOverrideBrakeDurNeutral)
304    {
305        OverrideBrakeDurNeutral = newOverrideBrakeDurNeutral;
306        return this;
307    }
308    
309    /**
310     * Modifies this Control Request's LimitForwardMotion parameter and returns itself for
311     * method-chaining and easier to use request API.
312     * <p>
313     * Set to true to force forward limiting.  This allows users to use other limit
314     * switch sensors connected to robot controller.  This also allows use of active
315     * sensors that require external power.
316     *
317     * @param newLimitForwardMotion Parameter to modify
318     * @return Itself
319     */
320    public VelocityVoltage withLimitForwardMotion(boolean newLimitForwardMotion)
321    {
322        LimitForwardMotion = newLimitForwardMotion;
323        return this;
324    }
325    
326    /**
327     * Modifies this Control Request's LimitReverseMotion parameter and returns itself for
328     * method-chaining and easier to use request API.
329     * <p>
330     * Set to true to force reverse limiting.  This allows users to use other limit
331     * switch sensors connected to robot controller.  This also allows use of active
332     * sensors that require external power.
333     *
334     * @param newLimitReverseMotion Parameter to modify
335     * @return Itself
336     */
337    public VelocityVoltage withLimitReverseMotion(boolean newLimitReverseMotion)
338    {
339        LimitReverseMotion = newLimitReverseMotion;
340        return this;
341    }
342    /**
343     * Sets the period at which this control will update at.
344     * This is designated in Hertz, with a minimum of 20 Hz
345     * (every 50 ms) and a maximum of 1000 Hz (every 1 ms).
346     * <p>
347     * If this field is set to 0 Hz, the control request will
348     * be sent immediately as a one-shot frame. This may be useful
349     * for advanced applications that require outputs to be
350     * synchronized with data acquisition. In this case, we
351     * recommend not exceeding 50 ms between control calls.
352     *
353     * @param newUpdateFreqHz Parameter to modify
354     * @return Itself
355     */
356    public VelocityVoltage withUpdateFreqHz(double newUpdateFreqHz)
357    {
358        UpdateFreqHz = newUpdateFreqHz;
359        return this;
360    }
361
362    @Override
363    public VelocityVoltage clone()
364    {
365        try {
366            return (VelocityVoltage)super.clone();
367        } catch (CloneNotSupportedException ex) {
368            /* this should never happen */
369            throw new RuntimeException(ex);
370        }
371    }
372}
373