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