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.phoenixpro.controls;
008
009import com.ctre.phoenixpro.StatusCode;
010import com.ctre.phoenixpro.controls.jni.ControlJNI;
011import com.ctre.phoenixpro.controls.jni.ControlConfigJNI;
012
013/**
014 * Requests Motion Magic® to target a final position using a motion profile. 
015 * Users can optionally provide a torque current feedforward.
016 * <p>
017 * Motion Magic® produces a motion profile in real-time while attempting to honor the Cruise Velocity,
018 * Acceleration, and Jerk value specified via the Motion Magic® configuration values.  Target position can be
019 * changed on-the-fly and Motion Magic® will do its best to adjust the profile.  This control mode is based on
020 * torque current, so relevant closed-loop gains will use Amperes for the numerator.
021 */
022public class MotionMagicTorqueCurrentFOC extends ControlRequest
023{
024    private boolean applyConfigsOnRequest;
025    /**
026     * Position to drive toward in rotations.
027     */
028    public double Position;
029    /**
030     * Feedforward to apply in torque current in Amperes.  User can use motor's kT
031     * to scale Newton-meter to Amperes.
032     */
033    public double FeedForward;
034    /**
035     * Select which gains are applied by selecting the slot.  Use the configuration
036     * api to set the gain values for the selected slot before enabling this
037     * feature. Slot must be within [0,2].
038     */
039    public int Slot;
040    /**
041     * Set to true to coast the rotor when output is zero (or within deadband).  Set
042     * to false to use the NeutralMode configuration setting (default). This flag
043     * exists to provide the fundamental behavior of this control when output is
044     * zero, which is to provide 0A (zero torque).
045     */
046    public boolean OverrideCoastDurNeutral;
047
048    
049    /**
050     * The period at which this control will update at.
051     * This is designated in Hertz, with a minimum of 20 Hz
052     * (every 50 ms) and a maximum of 1000 Hz (every 1 ms).
053     * <p>
054     * If this field is set to 0 Hz, the control request will
055     * be sent immediately as a one-shot frame. This may be useful
056     * for advanced applications that require outputs to be
057     * synchronized with data acquisition. In this case, we
058     * recommend not exceeding 50 ms between control calls.
059     */
060    public double UpdateFreqHz = 100; // Default to 100Hz
061
062    /**
063     * The timeout when sending configs associated with this control
064     */
065    public double configTimeout = 0.1;
066
067    /**
068     * Requests Motion Magic® to target a final position using a motion profile.
069     *  Users can optionally provide a torque current feedforward.
070     * <p>
071     * Motion Magic® produces a motion profile in real-time while attempting to
072     * honor the Cruise Velocity, Acceleration, and Jerk value specified via the
073     * Motion Magic® configuration values.  Target position can be changed
074     * on-the-fly and Motion Magic® will do its best to adjust the profile. 
075     * This control mode is based on torque current, so relevant closed-loop
076     * gains will use Amperes for the numerator.
077     *
078     * @param Position     Position to drive toward in rotations.
079     * @param FeedForward     Feedforward to apply in torque current in Amperes.
080     *                         User can use motor's kT to scale Newton-meter to
081     *                        Amperes.
082     * @param Slot     Select which gains are applied by selecting the slot. 
083     *                 Use the configuration api to set the gain values for the
084     *                 selected slot before enabling this feature. Slot must be
085     *                 within [0,2].
086     * @param OverrideCoastDurNeutral     Set to true to coast the rotor when
087     *                                    output is zero (or within deadband). 
088     *                                    Set to false to use the NeutralMode
089     *                                    configuration setting (default). This
090     *                                    flag exists to provide the fundamental
091     *                                    behavior of this control when output
092     *                                    is zero, which is to provide 0A (zero
093     *                                    torque).
094     */
095    public MotionMagicTorqueCurrentFOC(double Position, double FeedForward, int Slot, boolean OverrideCoastDurNeutral)
096    {
097        super("MotionMagicTorqueCurrentFOC");
098        this.Position = Position;
099        this.FeedForward = FeedForward;
100        this.Slot = Slot;
101        this.OverrideCoastDurNeutral = OverrideCoastDurNeutral;
102    }
103
104    /**
105     * Requests Motion Magic® to target a final position using a motion profile.
106     *  Users can optionally provide a torque current feedforward.
107     * <p>
108     * Motion Magic® produces a motion profile in real-time while attempting to
109     * honor the Cruise Velocity, Acceleration, and Jerk value specified via the
110     * Motion Magic® configuration values.  Target position can be changed
111     * on-the-fly and Motion Magic® will do its best to adjust the profile. 
112     * This control mode is based on torque current, so relevant closed-loop
113     * gains will use Amperes for the numerator.
114     *
115     * @param Position     Position to drive toward in rotations.
116     */
117    public MotionMagicTorqueCurrentFOC(double Position)
118    {
119        this(Position, 0.0, 0, false);
120    }
121
122    @Override
123    public String toString()
124    {
125        String ss = "class: MotionMagicTorqueCurrentFOC\n";
126        ss += "Position: " + Position + "\n";
127        ss += "FeedForward: " + FeedForward + "\n";
128        ss += "Slot: " + Slot + "\n";
129        ss += "OverrideCoastDurNeutral: " + OverrideCoastDurNeutral + "\n";
130        return ss;
131    }
132
133    @Override
134    public StatusCode sendRequest(String network, int deviceHash, boolean cancelOtherRequests)
135    {
136        var ref = requestReference.getNameValues();
137        ref.put("Position", String.valueOf(this.Position));
138        ref.put("FeedForward", String.valueOf(this.FeedForward));
139        ref.put("Slot", String.valueOf(this.Slot));
140        ref.put("OverrideCoastDurNeutral", String.valueOf(this.OverrideCoastDurNeutral));
141        String ss = "";
142        
143        ControlConfigJNI.JNI_RequestConfigApply(network, deviceHash, configTimeout, ss, applyConfigsOnRequest);
144        applyConfigsOnRequest = false;
145        return StatusCode.valueOf(ControlJNI.JNI_RequestControlMotionMagicTorqueCurrentFOC(
146                network, deviceHash, UpdateFreqHz, cancelOtherRequests, Position, FeedForward, Slot, OverrideCoastDurNeutral));
147    }
148    
149    /**
150     * Modifies this Control Request's Position parameter and returns itself for
151     * method-chaining and easier to use request API.
152     *
153     * @param newPosition Parameter to modify
154     * @return Itself
155     */
156    public MotionMagicTorqueCurrentFOC withPosition(double newPosition)
157    {
158        Position = newPosition;
159        return this;
160    }
161    
162    /**
163     * Modifies this Control Request's FeedForward parameter and returns itself for
164     * method-chaining and easier to use request API.
165     *
166     * @param newFeedForward Parameter to modify
167     * @return Itself
168     */
169    public MotionMagicTorqueCurrentFOC withFeedForward(double newFeedForward)
170    {
171        FeedForward = newFeedForward;
172        return this;
173    }
174    
175    /**
176     * Modifies this Control Request's Slot parameter and returns itself for
177     * method-chaining and easier to use request API.
178     *
179     * @param newSlot Parameter to modify
180     * @return Itself
181     */
182    public MotionMagicTorqueCurrentFOC withSlot(int newSlot)
183    {
184        Slot = newSlot;
185        return this;
186    }
187    
188    /**
189     * Modifies this Control Request's OverrideCoastDurNeutral parameter and returns itself for
190     * method-chaining and easier to use request API.
191     *
192     * @param newOverrideCoastDurNeutral Parameter to modify
193     * @return Itself
194     */
195    public MotionMagicTorqueCurrentFOC withOverrideCoastDurNeutral(boolean newOverrideCoastDurNeutral)
196    {
197        OverrideCoastDurNeutral = newOverrideCoastDurNeutral;
198        return this;
199    }
200    /**
201     * Sets the period at which this control will update at.
202     * This is designated in Hertz, with a minimum of 20 Hz
203     * (every 50 ms) and a maximum of 1000 Hz (every 1 ms).
204     * <p>
205     * If this field is set to 0 Hz, the control request will
206     * be sent immediately as a one-shot frame. This may be useful
207     * for advanced applications that require outputs to be
208     * synchronized with data acquisition. In this case, we
209     * recommend not exceeding 50 ms between control calls.
210     *
211     * @param newUpdateFreqHz Parameter to modify
212     * @return Itself
213     */
214    public MotionMagicTorqueCurrentFOC withUpdateFreqHz(double newUpdateFreqHz)
215    {
216        UpdateFreqHz = newUpdateFreqHz;
217        return this;
218    }
219    /**
220     * Forces configs to be applied the next time this is used in a setControl.
221     * <p>
222     * This is not necessary in the majority of cases, because Phoenix will make sure configs are
223     * properly set when they are not already set
224     */
225    public void forceApplyConfigs() { applyConfigsOnRequest = true; }
226}
227