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 position using an exponential motion
017 * profile.  Users can optionally provide a voltage feedforward.
018 * <p>
019 * Motion Magic® Expo produces a motion profile in real-time while attempting to honor the Cruise Velocity
020 * (optional) and the mechanism kV and kA, specified via the Motion Magic® configuration values.  Setting
021 * Cruise Velocity to 0 will allow the profile to run to the max possible velocity based on Expo_kV.  This
022 * control mode does not use the Acceleration or Jerk configs.  Target position can be changed on-the-fly and
023 * Motion Magic® will do its best to adjust the profile.  This control mode is voltage-based, so relevant
024 * closed-loop gains will use Volts for the numerator.
025 */
026public class MotionMagicExpoVoltage extends ControlRequest implements Cloneable
027{
028    /**
029     * Position to drive toward in rotations.
030     */
031    public double Position;
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     * Requests Motion Magic® to target a final position using an exponential motion
090     * profile.  Users can optionally provide a voltage feedforward.
091     * <p>
092     * Motion Magic® Expo produces a motion profile in real-time while attempting to
093     * honor the Cruise Velocity (optional) and the mechanism kV and kA, specified
094     * via the Motion Magic® configuration values.  Setting Cruise Velocity to 0
095     * will allow the profile to run to the max possible velocity based on Expo_kV. 
096     * This control mode does not use the Acceleration or Jerk configs.  Target
097     * position can be changed on-the-fly and Motion Magic® will do its best to
098     * adjust the profile.  This control mode is voltage-based, so relevant
099     * closed-loop gains will use Volts for the numerator.
100     * 
101     * @param Position    Position to drive toward in rotations.
102     * @param EnableFOC    Set to true to use FOC commutation (requires Phoenix
103     *                     Pro), which increases peak power by ~15%. Set to false to
104     *                     use trapezoidal commutation.
105     *                     <p>
106     *                     FOC improves motor performance by leveraging torque
107     *                     (current) control.  However, this may be inconvenient for
108     *                     applications that require specifying duty cycle or
109     *                     voltage.  CTR-Electronics has developed a hybrid method
110     *                     that combines the performances gains of FOC while still
111     *                     allowing applications to provide duty cycle or voltage
112     *                     demand.  This not to be confused with simple sinusoidal
113     *                     control or phase voltage control which lacks the
114     *                     performance gains.
115     * @param FeedForward    Feedforward to apply in volts
116     * @param Slot    Select which gains are applied by selecting the slot.  Use the
117     *                configuration api to set the gain values for the selected slot
118     *                before enabling this feature. Slot must be within [0,2].
119     * @param OverrideBrakeDurNeutral    Set to true to static-brake the rotor when
120     *                                   output is zero (or within deadband).  Set
121     *                                   to false to use the NeutralMode
122     *                                   configuration setting (default). This flag
123     *                                   exists to provide the fundamental behavior
124     *                                   of this control when output is zero, which
125     *                                   is to provide 0V to the motor.
126     * @param LimitForwardMotion    Set to true to force forward limiting.  This
127     *                              allows users to use other limit switch sensors
128     *                              connected to robot controller.  This also allows
129     *                              use of active sensors that require external
130     *                              power.
131     * @param LimitReverseMotion    Set to true to force reverse limiting.  This
132     *                              allows users to use other limit switch sensors
133     *                              connected to robot controller.  This also allows
134     *                              use of active sensors that require external
135     *                              power.
136     */
137    public MotionMagicExpoVoltage(double Position, boolean EnableFOC, double FeedForward, int Slot, boolean OverrideBrakeDurNeutral, boolean LimitForwardMotion, boolean LimitReverseMotion)
138    {
139        super("MotionMagicExpoVoltage");
140        this.Position = Position;
141        this.EnableFOC = EnableFOC;
142        this.FeedForward = FeedForward;
143        this.Slot = Slot;
144        this.OverrideBrakeDurNeutral = OverrideBrakeDurNeutral;
145        this.LimitForwardMotion = LimitForwardMotion;
146        this.LimitReverseMotion = LimitReverseMotion;
147    }
148
149        /**
150     * Requests Motion Magic® to target a final position using an exponential motion
151     * profile.  Users can optionally provide a voltage feedforward.
152     * <p>
153     * Motion Magic® Expo produces a motion profile in real-time while attempting to
154     * honor the Cruise Velocity (optional) and the mechanism kV and kA, specified
155     * via the Motion Magic® configuration values.  Setting Cruise Velocity to 0
156     * will allow the profile to run to the max possible velocity based on Expo_kV. 
157     * This control mode does not use the Acceleration or Jerk configs.  Target
158     * position can be changed on-the-fly and Motion Magic® will do its best to
159     * adjust the profile.  This control mode is voltage-based, so relevant
160     * closed-loop gains will use Volts for the numerator.
161     * 
162     * @param Position    Position to drive toward in rotations.
163     */
164    public MotionMagicExpoVoltage(double Position)
165    {
166        this(Position, true, 0.0, 0, false, false, false);
167    }
168
169    @Override
170    public String toString()
171    {
172        String ss = "class: MotionMagicExpoVoltage\n";
173        ss += "Position: " + Position + "\n";
174        ss += "EnableFOC: " + EnableFOC + "\n";
175        ss += "FeedForward: " + FeedForward + "\n";
176        ss += "Slot: " + Slot + "\n";
177        ss += "OverrideBrakeDurNeutral: " + OverrideBrakeDurNeutral + "\n";
178        ss += "LimitForwardMotion: " + LimitForwardMotion + "\n";
179        ss += "LimitReverseMotion: " + LimitReverseMotion + "\n";
180        return ss;
181    }
182
183    @Override
184    public StatusCode sendRequest(String network, int deviceHash, boolean cancelOtherRequests)
185    {
186        return StatusCode.valueOf(ControlJNI.JNI_RequestControlMotionMagicExpoVoltage(
187                network, deviceHash, UpdateFreqHz, cancelOtherRequests, Position, EnableFOC, FeedForward, Slot, OverrideBrakeDurNeutral, LimitForwardMotion, LimitReverseMotion));
188    }
189
190    /**
191     * Gets information about this control request.
192     *
193     * @return Map of control parameter names and corresponding applied values
194     */
195    @Override
196    public Map<String, String> getControlInfo()
197    {
198        var controlInfo = new HashMap<String, String>();
199        controlInfo.put("Name", getName());
200        controlInfo.put("Position", String.valueOf(this.Position));
201        controlInfo.put("EnableFOC", String.valueOf(this.EnableFOC));
202        controlInfo.put("FeedForward", String.valueOf(this.FeedForward));
203        controlInfo.put("Slot", String.valueOf(this.Slot));
204        controlInfo.put("OverrideBrakeDurNeutral", String.valueOf(this.OverrideBrakeDurNeutral));
205        controlInfo.put("LimitForwardMotion", String.valueOf(this.LimitForwardMotion));
206        controlInfo.put("LimitReverseMotion", String.valueOf(this.LimitReverseMotion));
207        return controlInfo;
208    }
209    
210    /**
211     * Modifies this Control Request's Position parameter and returns itself for
212     * method-chaining and easier to use request API.
213     * <p>
214     * Position to drive toward in rotations.
215     *
216     * @param newPosition Parameter to modify
217     * @return Itself
218     */
219    public MotionMagicExpoVoltage withPosition(double newPosition)
220    {
221        Position = newPosition;
222        return this;
223    }
224    
225    /**
226     * Modifies this Control Request's EnableFOC parameter and returns itself for
227     * method-chaining and easier to use request API.
228     * <p>
229     * Set to true to use FOC commutation (requires Phoenix Pro), which increases
230     * peak power by ~15%. Set to false to use trapezoidal commutation.
231     * <p>
232     * FOC improves motor performance by leveraging torque (current) control. 
233     * However, this may be inconvenient for applications that require specifying
234     * duty cycle or voltage.  CTR-Electronics has developed a hybrid method that
235     * combines the performances gains of FOC while still allowing applications to
236     * provide duty cycle or voltage demand.  This not to be confused with simple
237     * sinusoidal control or phase voltage control which lacks the performance
238     * gains.
239     *
240     * @param newEnableFOC Parameter to modify
241     * @return Itself
242     */
243    public MotionMagicExpoVoltage withEnableFOC(boolean newEnableFOC)
244    {
245        EnableFOC = newEnableFOC;
246        return this;
247    }
248    
249    /**
250     * Modifies this Control Request's FeedForward parameter and returns itself for
251     * method-chaining and easier to use request API.
252     * <p>
253     * Feedforward to apply in volts
254     *
255     * @param newFeedForward Parameter to modify
256     * @return Itself
257     */
258    public MotionMagicExpoVoltage withFeedForward(double newFeedForward)
259    {
260        FeedForward = newFeedForward;
261        return this;
262    }
263    
264    /**
265     * Modifies this Control Request's Slot parameter and returns itself for
266     * method-chaining and easier to use request API.
267     * <p>
268     * Select which gains are applied by selecting the slot.  Use the configuration
269     * api to set the gain values for the selected slot before enabling this
270     * feature. Slot must be within [0,2].
271     *
272     * @param newSlot Parameter to modify
273     * @return Itself
274     */
275    public MotionMagicExpoVoltage withSlot(int newSlot)
276    {
277        Slot = newSlot;
278        return this;
279    }
280    
281    /**
282     * Modifies this Control Request's OverrideBrakeDurNeutral parameter and returns itself for
283     * method-chaining and easier to use request API.
284     * <p>
285     * Set to true to static-brake the rotor when output is zero (or within
286     * deadband).  Set to false to use the NeutralMode configuration setting
287     * (default). This flag exists to provide the fundamental behavior of this
288     * control when output is zero, which is to provide 0V to the motor.
289     *
290     * @param newOverrideBrakeDurNeutral Parameter to modify
291     * @return Itself
292     */
293    public MotionMagicExpoVoltage withOverrideBrakeDurNeutral(boolean newOverrideBrakeDurNeutral)
294    {
295        OverrideBrakeDurNeutral = newOverrideBrakeDurNeutral;
296        return this;
297    }
298    
299    /**
300     * Modifies this Control Request's LimitForwardMotion parameter and returns itself for
301     * method-chaining and easier to use request API.
302     * <p>
303     * Set to true to force forward limiting.  This allows users to use other limit
304     * switch sensors connected to robot controller.  This also allows use of active
305     * sensors that require external power.
306     *
307     * @param newLimitForwardMotion Parameter to modify
308     * @return Itself
309     */
310    public MotionMagicExpoVoltage withLimitForwardMotion(boolean newLimitForwardMotion)
311    {
312        LimitForwardMotion = newLimitForwardMotion;
313        return this;
314    }
315    
316    /**
317     * Modifies this Control Request's LimitReverseMotion parameter and returns itself for
318     * method-chaining and easier to use request API.
319     * <p>
320     * Set to true to force reverse limiting.  This allows users to use other limit
321     * switch sensors connected to robot controller.  This also allows use of active
322     * sensors that require external power.
323     *
324     * @param newLimitReverseMotion Parameter to modify
325     * @return Itself
326     */
327    public MotionMagicExpoVoltage withLimitReverseMotion(boolean newLimitReverseMotion)
328    {
329        LimitReverseMotion = newLimitReverseMotion;
330        return this;
331    }
332    /**
333     * Sets the period at which this control will update at.
334     * This is designated in Hertz, with a minimum of 20 Hz
335     * (every 50 ms) and a maximum of 1000 Hz (every 1 ms).
336     * <p>
337     * If this field is set to 0 Hz, the control request will
338     * be sent immediately as a one-shot frame. This may be useful
339     * for advanced applications that require outputs to be
340     * synchronized with data acquisition. In this case, we
341     * recommend not exceeding 50 ms between control calls.
342     *
343     * @param newUpdateFreqHz Parameter to modify
344     * @return Itself
345     */
346    public MotionMagicExpoVoltage withUpdateFreqHz(double newUpdateFreqHz)
347    {
348        UpdateFreqHz = newUpdateFreqHz;
349        return this;
350    }
351
352    @Override
353    public MotionMagicExpoVoltage clone()
354    {
355        try {
356            return (MotionMagicExpoVoltage)super.clone();
357        } catch (CloneNotSupportedException ex) {
358            /* this should never happen */
359            throw new RuntimeException(ex);
360        }
361    }
362}
363