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 * Follow the motor output of another Talon.
015 * <p>
016 * If Talon is in torque control, the torque is copied - which will increase the total torque applied. If
017 * Talon is in percent supply output control, the duty cycle is matched.  Motor direction either matches
018 * master's configured direction or opposes it based on OpposeMasterDirection.
019 */
020public class Follower extends ControlRequest
021{
022    private boolean applyConfigsOnRequest;
023    /**
024     * Device ID of the master to follow.
025     */
026    public int MasterID;
027    /**
028     * Set to false for motor invert to match the master's configured Invert - which
029     * is typical when master and follower are mechanically linked and spin in the
030     * same direction.  Set to true for motor invert to oppose the master's
031     * configured Invert - this is typical where the the master and follower
032     * mechanically spin in opposite directions.
033     */
034    public boolean OpposeMasterDirection;
035
036    
037    /**
038     * The period at which this control will update at.
039     * This is designated in Hertz, with a minimum of 20 Hz
040     * (every 50 ms) and a maximum of 1000 Hz (every 1 ms).
041     * <p>
042     * If this field is set to 0 Hz, the control request will
043     * be sent immediately as a one-shot frame. This may be useful
044     * for advanced applications that require outputs to be
045     * synchronized with data acquisition. In this case, we
046     * recommend not exceeding 50 ms between control calls.
047     */
048    public double UpdateFreqHz = 20; // Default to 20Hz
049
050    /**
051     * The timeout when sending configs associated with this control
052     */
053    public double configTimeout = 0.1;
054
055    /**
056     * Follow the motor output of another Talon.
057     * <p>
058     * If Talon is in torque control, the torque is copied - which will increase
059     * the total torque applied. If Talon is in percent supply output control,
060     * the duty cycle is matched.  Motor direction either matches master's
061     * configured direction or opposes it based on OpposeMasterDirection.
062     *
063     * @param MasterID     Device ID of the master to follow.
064     * @param OpposeMasterDirection     Set to false for motor invert to match
065     *                                  the master's configured Invert - which
066     *                                  is typical when master and follower are
067     *                                  mechanically linked and spin in the same
068     *                                  direction.  Set to true for motor invert
069     *                                  to oppose the master's configured Invert
070     *                                  - this is typical where the the master
071     *                                  and follower mechanically spin in
072     *                                  opposite directions.
073     */
074    public Follower(int MasterID, boolean OpposeMasterDirection)
075    {
076        super("Follower");
077        this.MasterID = MasterID;
078        this.OpposeMasterDirection = OpposeMasterDirection;
079    }
080
081    @Override
082    public String toString()
083    {
084        String ss = "class: Follower\n";
085        ss += "MasterID: " + MasterID + "\n";
086        ss += "OpposeMasterDirection: " + OpposeMasterDirection + "\n";
087        return ss;
088    }
089
090    @Override
091    public StatusCode sendRequest(String network, int deviceHash, boolean cancelOtherRequests)
092    {
093        var ref = requestReference.getNameValues();
094        ref.put("MasterID", String.valueOf(this.MasterID));
095        ref.put("OpposeMasterDirection", String.valueOf(this.OpposeMasterDirection));
096        String ss = "";
097        
098        ControlConfigJNI.JNI_RequestConfigApply(network, deviceHash, configTimeout, ss, applyConfigsOnRequest);
099        applyConfigsOnRequest = false;
100        return StatusCode.valueOf(ControlJNI.JNI_RequestControlFollower(
101                network, deviceHash, UpdateFreqHz, cancelOtherRequests, MasterID, OpposeMasterDirection));
102    }
103    
104    /**
105     * Modifies this Control Request's MasterID parameter and returns itself for
106     * method-chaining and easier to use request API.
107     *
108     * @param newMasterID Parameter to modify
109     * @return Itself
110     */
111    public Follower withMasterID(int newMasterID)
112    {
113        MasterID = newMasterID;
114        return this;
115    }
116    
117    /**
118     * Modifies this Control Request's OpposeMasterDirection parameter and returns itself for
119     * method-chaining and easier to use request API.
120     *
121     * @param newOpposeMasterDirection Parameter to modify
122     * @return Itself
123     */
124    public Follower withOpposeMasterDirection(boolean newOpposeMasterDirection)
125    {
126        OpposeMasterDirection = newOpposeMasterDirection;
127        return this;
128    }
129    /**
130     * Sets the period at which this control will update at.
131     * This is designated in Hertz, with a minimum of 20 Hz
132     * (every 50 ms) and a maximum of 1000 Hz (every 1 ms).
133     * <p>
134     * If this field is set to 0 Hz, the control request will
135     * be sent immediately as a one-shot frame. This may be useful
136     * for advanced applications that require outputs to be
137     * synchronized with data acquisition. In this case, we
138     * recommend not exceeding 50 ms between control calls.
139     *
140     * @param newUpdateFreqHz Parameter to modify
141     * @return Itself
142     */
143    public Follower withUpdateFreqHz(double newUpdateFreqHz)
144    {
145        UpdateFreqHz = newUpdateFreqHz;
146        return this;
147    }
148    /**
149     * Forces configs to be applied the next time this is used in a setControl.
150     * <p>
151     * This is not necessary in the majority of cases, because Phoenix will make sure configs are
152     * properly set when they are not already set
153     */
154    public void forceApplyConfigs() { applyConfigsOnRequest = true; }
155}
156