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 * Follow the motor output of another Talon while ignoring the master's invert
022 * setting.
023 * <p>
024 * If Talon is in torque control, the torque is copied - which will increase the total torque applied. If
025 * Talon is in percent supply output control, the duty cycle is matched.  Motor direction is strictly
026 * determined by the configured invert and not the master.  If you want motor direction to match or oppose the
027 * master, use FollowerRequest instead.
028 */
029public class StrictFollower extends ControlRequest implements Cloneable
030{
031    /**
032     * Device ID of the master to follow.
033     */
034    public int MasterID;
035
036    /**
037     * The period at which this control will update at.
038     * This is designated in Hertz, with a minimum of 20 Hz
039     * (every 50 ms) and a maximum of 1000 Hz (every 1 ms).
040     * <p>
041     * If this field is set to 0 Hz, the control request will
042     * be sent immediately as a one-shot frame. This may be useful
043     * for advanced applications that require outputs to be
044     * synchronized with data acquisition. In this case, we
045     * recommend not exceeding 50 ms between control calls.
046     */
047    public double UpdateFreqHz = 20;
048
049    /**
050     * Follow the motor output of another Talon while ignoring the master's invert
051     * setting.
052     * <p>
053     * If Talon is in torque control, the torque is copied - which will increase the
054     * total torque applied. If Talon is in percent supply output control, the duty
055     * cycle is matched.  Motor direction is strictly determined by the configured
056     * invert and not the master.  If you want motor direction to match or oppose
057     * the master, use FollowerRequest instead.
058     * 
059     * @param MasterID    Device ID of the master to follow.
060     */
061    public StrictFollower(int MasterID)
062    {
063        super("StrictFollower");
064        this.MasterID = MasterID;
065    }
066
067    @Override
068    public String toString()
069    {
070        String ss = "Control: StrictFollower\n";
071        ss += "    MasterID: " + MasterID + "\n";
072        return ss;
073    }
074
075    @Override
076    public StatusCode sendRequest(String network, int deviceHash)
077    {
078        return StatusCode.valueOf(ControlJNI.JNI_RequestControlStrictFollower(
079                network, deviceHash, UpdateFreqHz, MasterID));
080    }
081
082    /**
083     * Gets information about this control request.
084     *
085     * @return Map of control parameter names and corresponding applied values
086     */
087    @Override
088    public Map<String, String> getControlInfo()
089    {
090        var controlInfo = new HashMap<String, String>();
091        controlInfo.put("Name", getName());
092        controlInfo.put("MasterID", String.valueOf(this.MasterID));
093        return controlInfo;
094    }
095    
096    /**
097     * Modifies this Control Request's MasterID parameter and returns itself for
098     * method-chaining and easier to use request API.
099     * <p>
100     * Device ID of the master to follow.
101     *
102     * @param newMasterID Parameter to modify
103     * @return Itself
104     */
105    public StrictFollower withMasterID(int newMasterID)
106    {
107        MasterID = newMasterID;
108        return this;
109    }
110
111    /**
112     * Sets the period at which this control will update at.
113     * This is designated in Hertz, with a minimum of 20 Hz
114     * (every 50 ms) and a maximum of 1000 Hz (every 1 ms).
115     * <p>
116     * If this field is set to 0 Hz, the control request will
117     * be sent immediately as a one-shot frame. This may be useful
118     * for advanced applications that require outputs to be
119     * synchronized with data acquisition. In this case, we
120     * recommend not exceeding 50 ms between control calls.
121     *
122     * @param newUpdateFreqHz Parameter to modify
123     * @return Itself
124     */
125    @Override
126    public StrictFollower withUpdateFreqHz(double newUpdateFreqHz)
127    {
128        UpdateFreqHz = newUpdateFreqHz;
129        return this;
130    }
131
132    /**
133     * Sets the period at which this control will update at.
134     * This is designated in Hertz, with a minimum of 20 Hz
135     * (every 50 ms) and a maximum of 1000 Hz (every 1 ms).
136     * <p>
137     * If this field is set to 0 Hz, the control request will
138     * be sent immediately as a one-shot frame. This may be useful
139     * for advanced applications that require outputs to be
140     * synchronized with data acquisition. In this case, we
141     * recommend not exceeding 50 ms between control calls.
142     *
143     * @param newUpdateFreqHz Parameter to modify
144     * @return Itself
145     */
146    @Override
147    public StrictFollower withUpdateFreqHz(Frequency newUpdateFreqHz)
148    {
149        UpdateFreqHz = newUpdateFreqHz.in(Hertz);
150        return this;
151    }
152
153    @Override
154    public StrictFollower clone()
155    {
156        try {
157            return (StrictFollower)super.clone();
158        } catch (CloneNotSupportedException ex) {
159            /* this should never happen */
160            throw new RuntimeException(ex);
161        }
162    }
163}
164