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;
011import com.ctre.phoenix6.hardware.traits.*;
012
013import edu.wpi.first.units.*;
014import edu.wpi.first.units.measure.*;
015import static edu.wpi.first.units.Units.*;
016
017import java.util.HashMap;
018import java.util.Map;
019
020/**
021 * Request neutral output of actuator. The applied brake type is determined by
022 * the NeutralMode configuration.
023 */
024public class NeutralOut extends ControlRequest implements Cloneable
025{
026    /**
027     * Set to true to delay applying this control request until a timesync boundary
028     * (requires Phoenix Pro and CANivore). This eliminates the impact of
029     * nondeterministic network delays in exchange for a larger but deterministic
030     * control latency.
031     * <p>
032     * This requires setting the ControlTimesyncFreqHz config in MotorOutputConfigs.
033     * Additionally, when this is enabled, the UpdateFreqHz of this request should
034     * be set to 0 Hz.
035     */
036    public boolean UseTimesync = false;
037
038    /**
039     * The period at which this control will update at.
040     * This is designated in Hertz, with a minimum of 20 Hz
041     * (every 50 ms) and a maximum of 1000 Hz (every 1 ms).
042     * <p>
043     * If this field is set to 0 Hz, the control request will
044     * be sent immediately as a one-shot frame. This may be useful
045     * for advanced applications that require outputs to be
046     * synchronized with data acquisition. In this case, we
047     * recommend not exceeding 50 ms between control calls.
048     */
049    public double UpdateFreqHz = 20;
050
051    /**
052     * Request neutral output of actuator. The applied brake type is determined by
053     * the NeutralMode configuration.
054     * 
055     */
056    public NeutralOut()
057    {
058        super("NeutralOut");
059    }
060
061    @Override
062    public String toString()
063    {
064        String ss = "Control: NeutralOut\n";
065        ss += "    UseTimesync: " + UseTimesync + "\n";
066        return ss;
067    }
068
069    @Override
070    public StatusCode sendRequest(String network, int deviceHash)
071    {
072        return StatusCode.valueOf(ControlJNI.JNI_RequestControlNeutralOut(
073                network, deviceHash, UpdateFreqHz, UseTimesync));
074    }
075
076    /**
077     * Gets information about this control request.
078     *
079     * @return Map of control parameter names and corresponding applied values
080     */
081    @Override
082    public Map<String, String> getControlInfo()
083    {
084        var controlInfo = new HashMap<String, String>();
085        controlInfo.put("Name", getName());
086        controlInfo.put("UseTimesync", String.valueOf(this.UseTimesync));
087        return controlInfo;
088    }
089    
090    /**
091     * Modifies this Control Request's UseTimesync parameter and returns itself for
092     * method-chaining and easier to use request API.
093     * <p>
094     * Set to true to delay applying this control request until a timesync boundary
095     * (requires Phoenix Pro and CANivore). This eliminates the impact of
096     * nondeterministic network delays in exchange for a larger but deterministic
097     * control latency.
098     * <p>
099     * This requires setting the ControlTimesyncFreqHz config in MotorOutputConfigs.
100     * Additionally, when this is enabled, the UpdateFreqHz of this request should
101     * be set to 0 Hz.
102     *
103     * @param newUseTimesync Parameter to modify
104     * @return Itself
105     */
106    public NeutralOut withUseTimesync(boolean newUseTimesync)
107    {
108        UseTimesync = newUseTimesync;
109        return this;
110    }
111
112    /**
113     * Sets the period at which this control will update at.
114     * This is designated in Hertz, with a minimum of 20 Hz
115     * (every 50 ms) and a maximum of 1000 Hz (every 1 ms).
116     * <p>
117     * If this field is set to 0 Hz, the control request will
118     * be sent immediately as a one-shot frame. This may be useful
119     * for advanced applications that require outputs to be
120     * synchronized with data acquisition. In this case, we
121     * recommend not exceeding 50 ms between control calls.
122     *
123     * @param newUpdateFreqHz Parameter to modify
124     * @return Itself
125     */
126    @Override
127    public NeutralOut withUpdateFreqHz(double newUpdateFreqHz)
128    {
129        UpdateFreqHz = newUpdateFreqHz;
130        return this;
131    }
132
133    /**
134     * Sets the period at which this control will update at.
135     * This is designated in Hertz, with a minimum of 20 Hz
136     * (every 50 ms) and a maximum of 1000 Hz (every 1 ms).
137     * <p>
138     * If this field is set to 0 Hz, the control request will
139     * be sent immediately as a one-shot frame. This may be useful
140     * for advanced applications that require outputs to be
141     * synchronized with data acquisition. In this case, we
142     * recommend not exceeding 50 ms between control calls.
143     *
144     * @param newUpdateFreqHz Parameter to modify
145     * @return Itself
146     */
147    @Override
148    public NeutralOut withUpdateFreqHz(Frequency newUpdateFreqHz)
149    {
150        UpdateFreqHz = newUpdateFreqHz.in(Hertz);
151        return this;
152    }
153
154    @Override
155    public NeutralOut clone()
156    {
157        try {
158            return (NeutralOut)super.clone();
159        } catch (CloneNotSupportedException ex) {
160            /* this should never happen */
161            throw new RuntimeException(ex);
162        }
163    }
164}
165