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.phoenix6.StatusCode; 010import com.ctre.phoenix6.controls.jni.ControlJNI; 011import com.ctre.phoenix6.controls.jni.ControlConfigJNI; 012 013/** 014 * Request a specified motor current (field oriented control). 015 * <p> 016 * This control request will drive the motor to the requested motor (stator) current value. This leverages 017 * field oriented control (FOC), which means greater peak power than what is documented. This scales to 018 * torque based on Motor's kT constant. 019 * 020 * @deprecated Classes in the phoenixpro package will be removed in 2024. 021 * Users should instead use classes from the phoenix6 package. 022 */ 023@Deprecated(forRemoval = true) 024public class TorqueCurrentFOC extends ControlRequest 025{ 026 private boolean applyConfigsOnRequest; 027 /** 028 * Amount of motor current in Amperes 029 */ 030 public double Output; 031 /** 032 * The maximum absolute motor output that can be applied, which effectively 033 * limits the velocity. For example, 0.50 means no more than 50% output in 034 * either direction. This is useful for preventing the motor from spinning to 035 * its terminal velocity when there is no external torque applied unto the 036 * rotor. Note this is absolute maximum, so the value should be between zero 037 * and one. 038 */ 039 public double MaxAbsDutyCycle; 040 /** 041 * Deadband in Amperes. If torque request is within deadband, the bridge output 042 * is neutral. If deadband is set to zero then there is effectively no deadband. 043 * Note if deadband is zero, a free spinning motor will spin for quite a while 044 * as the firmware attempts to hold the motor's bemf. If user expects motor to 045 * cease spinning quickly with a demand of zero, we recommend a deadband of one 046 * Ampere. This value will be converted to an integral value of amps. 047 */ 048 public double Deadband; 049 /** 050 * Set to true to coast the rotor when output is zero (or within deadband). Set 051 * to false to use the NeutralMode configuration setting (default). This flag 052 * exists to provide the fundamental behavior of this control when output is 053 * zero, which is to provide 0A (zero torque). 054 */ 055 public boolean OverrideCoastDurNeutral; 056 057 058 /** 059 * The period at which this control will update at. 060 * This is designated in Hertz, with a minimum of 20 Hz 061 * (every 50 ms) and a maximum of 1000 Hz (every 1 ms). 062 * <p> 063 * If this field is set to 0 Hz, the control request will 064 * be sent immediately as a one-shot frame. This may be useful 065 * for advanced applications that require outputs to be 066 * synchronized with data acquisition. In this case, we 067 * recommend not exceeding 50 ms between control calls. 068 */ 069 public double UpdateFreqHz = 100; // Default to 100Hz 070 071 /** 072 * The timeout when sending configs associated with this control 073 */ 074 public double configTimeout = 0.1; 075 076 /** 077 * Request a specified motor current (field oriented control). 078 * <p> 079 * This control request will drive the motor to the requested motor (stator) 080 * current value. This leverages field oriented control (FOC), which means 081 * greater peak power than what is documented. This scales to torque based 082 * on Motor's kT constant. 083 * 084 * @param Output Amount of motor current in Amperes 085 * @param MaxAbsDutyCycle The maximum absolute motor output that can be 086 * applied, which effectively limits the 087 * velocity. For example, 0.50 means no more than 088 * 50% output in either direction. This is 089 * useful for preventing the motor from spinning 090 * to its terminal velocity when there is no 091 * external torque applied unto the rotor. Note 092 * this is absolute maximum, so the value should 093 * be between zero and one. 094 * @param Deadband Deadband in Amperes. If torque request is within 095 * deadband, the bridge output is neutral. If deadband 096 * is set to zero then there is effectively no deadband. 097 * Note if deadband is zero, a free spinning motor will 098 * spin for quite a while as the firmware attempts to 099 * hold the motor's bemf. If user expects motor to cease 100 * spinning quickly with a demand of zero, we recommend 101 * a deadband of one Ampere. This value will be 102 * converted to an integral value of amps. 103 * @param OverrideCoastDurNeutral Set to true to coast the rotor when 104 * output is zero (or within deadband). 105 * Set to false to use the NeutralMode 106 * configuration setting (default). This 107 * flag exists to provide the fundamental 108 * behavior of this control when output 109 * is zero, which is to provide 0A (zero 110 * torque). 111 * 112 * @deprecated Classes in the phoenixpro package will be removed in 2024. 113 * Users should instead use classes from the phoenix6 package. 114 */ 115 @Deprecated(forRemoval = true) 116 public TorqueCurrentFOC(double Output, double MaxAbsDutyCycle, double Deadband, boolean OverrideCoastDurNeutral) 117 { 118 super("TorqueCurrentFOC"); 119 this.Output = Output; 120 this.MaxAbsDutyCycle = MaxAbsDutyCycle; 121 this.Deadband = Deadband; 122 this.OverrideCoastDurNeutral = OverrideCoastDurNeutral; 123 } 124 125 /** 126 * Request a specified motor current (field oriented control). 127 * <p> 128 * This control request will drive the motor to the requested motor (stator) 129 * current value. This leverages field oriented control (FOC), which means 130 * greater peak power than what is documented. This scales to torque based 131 * on Motor's kT constant. 132 * 133 * @param Output Amount of motor current in Amperes 134 * 135 * @deprecated Classes in the phoenixpro package will be removed in 2024. 136 * Users should instead use classes from the phoenix6 package. 137 */ 138 @Deprecated(forRemoval = true) 139 public TorqueCurrentFOC(double Output) 140 { 141 this(Output, 1.0, 0.0, false); 142 } 143 144 @Override 145 public String toString() 146 { 147 String ss = "class: TorqueCurrentFOC\n"; 148 ss += "Output: " + Output + "\n"; 149 ss += "MaxAbsDutyCycle: " + MaxAbsDutyCycle + "\n"; 150 ss += "Deadband: " + Deadband + "\n"; 151 ss += "OverrideCoastDurNeutral: " + OverrideCoastDurNeutral + "\n"; 152 return ss; 153 } 154 155 @Override 156 public StatusCode sendRequest(String network, int deviceHash, boolean cancelOtherRequests) 157 { 158 var ref = requestReference.getNameValues(); 159 ref.put("Output", String.valueOf(this.Output)); 160 ref.put("MaxAbsDutyCycle", String.valueOf(this.MaxAbsDutyCycle)); 161 ref.put("Deadband", String.valueOf(this.Deadband)); 162 ref.put("OverrideCoastDurNeutral", String.valueOf(this.OverrideCoastDurNeutral)); 163 String ss = ""; 164 165 ControlConfigJNI.JNI_RequestConfigApply(network, deviceHash, configTimeout, ss, applyConfigsOnRequest); 166 applyConfigsOnRequest = false; 167 return StatusCode.valueOf(ControlJNI.JNI_RequestControlTorqueCurrentFOC( 168 network, deviceHash, UpdateFreqHz, cancelOtherRequests, Output, MaxAbsDutyCycle, Deadband, OverrideCoastDurNeutral)); 169 } 170 171 /** 172 * Modifies this Control Request's Output parameter and returns itself for 173 * method-chaining and easier to use request API. 174 * 175 * @param newOutput Parameter to modify 176 * @return Itself 177 */ 178 public TorqueCurrentFOC withOutput(double newOutput) 179 { 180 Output = newOutput; 181 return this; 182 } 183 184 /** 185 * Modifies this Control Request's MaxAbsDutyCycle parameter and returns itself for 186 * method-chaining and easier to use request API. 187 * 188 * @param newMaxAbsDutyCycle Parameter to modify 189 * @return Itself 190 */ 191 public TorqueCurrentFOC withMaxAbsDutyCycle(double newMaxAbsDutyCycle) 192 { 193 MaxAbsDutyCycle = newMaxAbsDutyCycle; 194 return this; 195 } 196 197 /** 198 * Modifies this Control Request's Deadband parameter and returns itself for 199 * method-chaining and easier to use request API. 200 * 201 * @param newDeadband Parameter to modify 202 * @return Itself 203 */ 204 public TorqueCurrentFOC withDeadband(double newDeadband) 205 { 206 Deadband = newDeadband; 207 return this; 208 } 209 210 /** 211 * Modifies this Control Request's OverrideCoastDurNeutral parameter and returns itself for 212 * method-chaining and easier to use request API. 213 * 214 * @param newOverrideCoastDurNeutral Parameter to modify 215 * @return Itself 216 */ 217 public TorqueCurrentFOC withOverrideCoastDurNeutral(boolean newOverrideCoastDurNeutral) 218 { 219 OverrideCoastDurNeutral = newOverrideCoastDurNeutral; 220 return this; 221 } 222 /** 223 * Sets the period at which this control will update at. 224 * This is designated in Hertz, with a minimum of 20 Hz 225 * (every 50 ms) and a maximum of 1000 Hz (every 1 ms). 226 * <p> 227 * If this field is set to 0 Hz, the control request will 228 * be sent immediately as a one-shot frame. This may be useful 229 * for advanced applications that require outputs to be 230 * synchronized with data acquisition. In this case, we 231 * recommend not exceeding 50 ms between control calls. 232 * 233 * @param newUpdateFreqHz Parameter to modify 234 * @return Itself 235 */ 236 public TorqueCurrentFOC withUpdateFreqHz(double newUpdateFreqHz) 237 { 238 UpdateFreqHz = newUpdateFreqHz; 239 return this; 240 } 241 /** 242 * Forces configs to be applied the next time this is used in a setControl. 243 * <p> 244 * This is not necessary in the majority of cases, because Phoenix will make sure configs are 245 * properly set when they are not already set 246 */ 247 public void forceApplyConfigs() { applyConfigsOnRequest = true; } 248} 249