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