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