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