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.phoenix6.StatusCode;
010import com.ctre.phoenix6.controls.jni.ControlJNI;
011import com.ctre.phoenix6.controls.jni.ControlConfigJNI;
012
013/**
014 * Requests Motion Magic® to target a final position using a motion profile. 
015 * Users can optionally provide a voltage 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
020 * voltage-based, so relevant closed-loop gains will use Volts for the numerator.
021 *
022 * @deprecated Classes in the phoenixpro package will be removed in 2024.
023 *             Users should instead use classes from the phoenix6 package.
024 */
025@Deprecated(forRemoval = true)
026public class MotionMagicVoltage extends ControlRequest
027{
028    private boolean applyConfigsOnRequest;
029    /**
030     * Position to drive toward in rotations.
031     */
032    public double Position;
033    /**
034     * Set to true to use FOC commutation, which increases peak power by ~15%. Set
035     * to false to use trapezoidal commutation.  FOC improves motor performance by
036     * leveraging torque (current) control.  However, this may be inconvenient for
037     * applications that require specifying duty cycle or voltage.  CTR-Electronics
038     * has developed a hybrid method that combines the performances gains of FOC
039     * while still allowing applications to provide duty cycle or voltage demand. 
040     * This not to be confused with simple sinusoidal control or phase voltage
041     * control which lacks the performance gains.
042     */
043    public boolean EnableFOC;
044    /**
045     * Feedforward to apply in volts
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    
063    /**
064     * The period at which this control will update at.
065     * This is designated in Hertz, with a minimum of 20 Hz
066     * (every 50 ms) and a maximum of 1000 Hz (every 1 ms).
067     * <p>
068     * If this field is set to 0 Hz, the control request will
069     * be sent immediately as a one-shot frame. This may be useful
070     * for advanced applications that require outputs to be
071     * synchronized with data acquisition. In this case, we
072     * recommend not exceeding 50 ms between control calls.
073     */
074    public double UpdateFreqHz = 100; // Default to 100Hz
075
076    /**
077     * The timeout when sending configs associated with this control
078     */
079    public double configTimeout = 0.1;
080
081    /**
082     * Requests Motion Magic® to target a final position using a motion profile.
083     *  Users can optionally provide a voltage feedforward.
084     * <p>
085     * Motion Magic® produces a motion profile in real-time while attempting to
086     * honor the Cruise Velocity, Acceleration, and Jerk value specified via the
087     * Motion Magic® configuration values.  Target position can be changed
088     * on-the-fly and Motion Magic® will do its best to adjust the profile. 
089     * This control mode is voltage-based, so relevant closed-loop gains will
090     * use Volts for the numerator.
091     *
092     * @param Position     Position to drive toward in rotations.
093     * @param EnableFOC     Set to true to use FOC commutation, which increases
094     *                      peak power by ~15%. Set to false to use trapezoidal
095     *                      commutation.  FOC improves motor performance by
096     *                      leveraging torque (current) control.  However, this
097     *                      may be inconvenient for applications that require
098     *                      specifying duty cycle or voltage.  CTR-Electronics
099     *                      has developed a hybrid method that combines the
100     *                      performances gains of FOC while still allowing
101     *                      applications to provide duty cycle or voltage
102     *                      demand.  This not to be confused with simple
103     *                      sinusoidal control or phase voltage control which
104     *                      lacks the performance gains.
105     * @param FeedForward     Feedforward to apply in volts
106     * @param Slot     Select which gains are applied by selecting the slot. 
107     *                 Use the configuration api to set the gain values for the
108     *                 selected slot before enabling this feature. Slot must be
109     *                 within [0,2].
110     * @param OverrideBrakeDurNeutral     Set to true to static-brake the rotor
111     *                                    when output is zero (or within
112     *                                    deadband).  Set to false to use the
113     *                                    NeutralMode configuration setting
114     *                                    (default). This flag exists to provide
115     *                                    the fundamental behavior of this
116     *                                    control when output is zero, which is
117     *                                    to provide 0V to the motor.
118     *
119     * @deprecated Classes in the phoenixpro package will be removed in 2024.
120     *             Users should instead use classes from the phoenix6 package.
121     */
122    @Deprecated(forRemoval = true)
123    public MotionMagicVoltage(double Position, boolean EnableFOC, double FeedForward, int Slot, boolean OverrideBrakeDurNeutral)
124    {
125        super("MotionMagicVoltage");
126        this.Position = Position;
127        this.EnableFOC = EnableFOC;
128        this.FeedForward = FeedForward;
129        this.Slot = Slot;
130        this.OverrideBrakeDurNeutral = OverrideBrakeDurNeutral;
131    }
132
133    /**
134     * Requests Motion Magic® to target a final position using a motion profile.
135     *  Users can optionally provide a voltage feedforward.
136     * <p>
137     * Motion Magic® produces a motion profile in real-time while attempting to
138     * honor the Cruise Velocity, Acceleration, and Jerk value specified via the
139     * Motion Magic® configuration values.  Target position can be changed
140     * on-the-fly and Motion Magic® will do its best to adjust the profile. 
141     * This control mode is voltage-based, so relevant closed-loop gains will
142     * use Volts for the numerator.
143     *
144     * @param Position     Position to drive toward in rotations.
145     *
146     * @deprecated Classes in the phoenixpro package will be removed in 2024.
147     *             Users should instead use classes from the phoenix6 package.
148     */
149    @Deprecated(forRemoval = true)
150    public MotionMagicVoltage(double Position)
151    {
152        this(Position, true, 0.0, 0, false);
153    }
154
155    @Override
156    public String toString()
157    {
158        String ss = "class: MotionMagicVoltage\n";
159        ss += "Position: " + Position + "\n";
160        ss += "EnableFOC: " + EnableFOC + "\n";
161        ss += "FeedForward: " + FeedForward + "\n";
162        ss += "Slot: " + Slot + "\n";
163        ss += "OverrideBrakeDurNeutral: " + OverrideBrakeDurNeutral + "\n";
164        return ss;
165    }
166
167    @Override
168    public StatusCode sendRequest(String network, int deviceHash, boolean cancelOtherRequests)
169    {
170        var ref = requestReference.getNameValues();
171        ref.put("Position", String.valueOf(this.Position));
172        ref.put("EnableFOC", String.valueOf(this.EnableFOC));
173        ref.put("FeedForward", String.valueOf(this.FeedForward));
174        ref.put("Slot", String.valueOf(this.Slot));
175        ref.put("OverrideBrakeDurNeutral", String.valueOf(this.OverrideBrakeDurNeutral));
176        String ss = "";
177        
178        ControlConfigJNI.JNI_RequestConfigApply(network, deviceHash, configTimeout, ss, applyConfigsOnRequest);
179        applyConfigsOnRequest = false;
180        return StatusCode.valueOf(ControlJNI.JNI_RequestControlMotionMagicVoltage(
181                network, deviceHash, UpdateFreqHz, cancelOtherRequests, Position, EnableFOC, FeedForward, Slot, OverrideBrakeDurNeutral));
182    }
183    
184    /**
185     * Modifies this Control Request's Position parameter and returns itself for
186     * method-chaining and easier to use request API.
187     *
188     * @param newPosition Parameter to modify
189     * @return Itself
190     */
191    public MotionMagicVoltage withPosition(double newPosition)
192    {
193        Position = newPosition;
194        return this;
195    }
196    
197    /**
198     * Modifies this Control Request's EnableFOC parameter and returns itself for
199     * method-chaining and easier to use request API.
200     *
201     * @param newEnableFOC Parameter to modify
202     * @return Itself
203     */
204    public MotionMagicVoltage withEnableFOC(boolean newEnableFOC)
205    {
206        EnableFOC = newEnableFOC;
207        return this;
208    }
209    
210    /**
211     * Modifies this Control Request's FeedForward parameter and returns itself for
212     * method-chaining and easier to use request API.
213     *
214     * @param newFeedForward Parameter to modify
215     * @return Itself
216     */
217    public MotionMagicVoltage withFeedForward(double newFeedForward)
218    {
219        FeedForward = newFeedForward;
220        return this;
221    }
222    
223    /**
224     * Modifies this Control Request's Slot parameter and returns itself for
225     * method-chaining and easier to use request API.
226     *
227     * @param newSlot Parameter to modify
228     * @return Itself
229     */
230    public MotionMagicVoltage withSlot(int newSlot)
231    {
232        Slot = newSlot;
233        return this;
234    }
235    
236    /**
237     * Modifies this Control Request's OverrideBrakeDurNeutral parameter and returns itself for
238     * method-chaining and easier to use request API.
239     *
240     * @param newOverrideBrakeDurNeutral Parameter to modify
241     * @return Itself
242     */
243    public MotionMagicVoltage withOverrideBrakeDurNeutral(boolean newOverrideBrakeDurNeutral)
244    {
245        OverrideBrakeDurNeutral = newOverrideBrakeDurNeutral;
246        return this;
247    }
248    /**
249     * Sets the period at which this control will update at.
250     * This is designated in Hertz, with a minimum of 20 Hz
251     * (every 50 ms) and a maximum of 1000 Hz (every 1 ms).
252     * <p>
253     * If this field is set to 0 Hz, the control request will
254     * be sent immediately as a one-shot frame. This may be useful
255     * for advanced applications that require outputs to be
256     * synchronized with data acquisition. In this case, we
257     * recommend not exceeding 50 ms between control calls.
258     *
259     * @param newUpdateFreqHz Parameter to modify
260     * @return Itself
261     */
262    public MotionMagicVoltage withUpdateFreqHz(double newUpdateFreqHz)
263    {
264        UpdateFreqHz = newUpdateFreqHz;
265        return this;
266    }
267    /**
268     * Forces configs to be applied the next time this is used in a setControl.
269     * <p>
270     * This is not necessary in the majority of cases, because Phoenix will make sure configs are
271     * properly set when they are not already set
272     */
273    public void forceApplyConfigs() { applyConfigsOnRequest = true; }
274}
275