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