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