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 * Request a specified voltage with a differential position closed-loop. 017 * <p> 018 * This control mode will attempt to apply the specified voltage to the motor. If the supply voltage is below 019 * the requested voltage, the motor controller will output the supply voltage. It will also set the motor's 020 * differential position setpoint to the specified position. 021 */ 022public class DifferentialVoltage extends ControlRequest implements Cloneable 023{ 024 /** 025 * Voltage to attempt to drive at 026 */ 027 public double TargetOutput; 028 /** 029 * Differential position to drive towards in rotations 030 */ 031 public double DifferentialPosition; 032 /** 033 * Set to true to use FOC commutation (requires Phoenix Pro), which increases 034 * peak power by ~15%. Set to false to use trapezoidal commutation. 035 * <p> 036 * FOC improves motor performance by leveraging torque (current) control. 037 * However, this may be inconvenient for applications that require specifying 038 * duty cycle or voltage. CTR-Electronics has developed a hybrid method that 039 * combines the performances gains of FOC while still allowing applications to 040 * provide duty cycle or voltage demand. This not to be confused with simple 041 * sinusoidal control or phase voltage control which lacks the performance 042 * gains. 043 */ 044 public boolean EnableFOC; 045 /** 046 * Select which gains are applied to the differential controller by selecting 047 * the slot. Use the configuration api to set the gain values for the selected 048 * slot before enabling this feature. Slot must be within [0,2]. 049 */ 050 public int DifferentialSlot; 051 /** 052 * Set to true to static-brake the rotor when output is zero (or within 053 * deadband). Set to false to use the NeutralMode configuration setting 054 * (default). This flag exists to provide the fundamental behavior of this 055 * control when output is zero, which is to provide 0V to the motor. 056 */ 057 public boolean OverrideBrakeDurNeutral; 058 /** 059 * Set to true to force forward limiting. This allows users to use other limit 060 * switch sensors connected to robot controller. This also allows use of active 061 * sensors that require external power. 062 */ 063 public boolean LimitForwardMotion; 064 /** 065 * Set to true to force reverse limiting. This allows users to use other limit 066 * switch sensors connected to robot controller. This also allows use of active 067 * sensors that require external power. 068 */ 069 public boolean LimitReverseMotion; 070 071 /** 072 * The period at which this control will update at. 073 * This is designated in Hertz, with a minimum of 20 Hz 074 * (every 50 ms) and a maximum of 1000 Hz (every 1 ms). 075 * <p> 076 * If this field is set to 0 Hz, the control request will 077 * be sent immediately as a one-shot frame. This may be useful 078 * for advanced applications that require outputs to be 079 * synchronized with data acquisition. In this case, we 080 * recommend not exceeding 50 ms between control calls. 081 */ 082 public double UpdateFreqHz = 100; // Default to 100Hz 083 084 /** 085 * Request a specified voltage with a differential position closed-loop. 086 * <p> 087 * This control mode will attempt to apply the specified voltage to the motor. 088 * If the supply voltage is below the requested voltage, the motor controller 089 * will output the supply voltage. It will also set the motor's differential 090 * position setpoint to the specified position. 091 * 092 * @param TargetOutput Voltage to attempt to drive at 093 * @param DifferentialPosition Differential position to drive towards in 094 * rotations 095 * @param EnableFOC Set to true to use FOC commutation (requires Phoenix 096 * Pro), which increases peak power by ~15%. Set to false to 097 * use trapezoidal commutation. 098 * <p> 099 * FOC improves motor performance by leveraging torque 100 * (current) control. However, this may be inconvenient for 101 * applications that require specifying duty cycle or 102 * voltage. CTR-Electronics has developed a hybrid method 103 * that combines the performances gains of FOC while still 104 * allowing applications to provide duty cycle or voltage 105 * demand. This not to be confused with simple sinusoidal 106 * control or phase voltage control which lacks the 107 * performance gains. 108 * @param DifferentialSlot Select which gains are applied to the differential 109 * controller by selecting the slot. Use the 110 * configuration api to set the gain values for the 111 * selected slot before enabling this feature. Slot 112 * must be within [0,2]. 113 * @param OverrideBrakeDurNeutral Set to true to static-brake the rotor when 114 * output is zero (or within deadband). Set 115 * to false to use the NeutralMode 116 * configuration setting (default). This flag 117 * exists to provide the fundamental behavior 118 * of this control when output is zero, which 119 * is to provide 0V to the motor. 120 * @param LimitForwardMotion Set to true to force forward limiting. This 121 * allows users to use other limit switch sensors 122 * connected to robot controller. This also allows 123 * use of active sensors that require external 124 * power. 125 * @param LimitReverseMotion Set to true to force reverse limiting. This 126 * allows users to use other limit switch sensors 127 * connected to robot controller. This also allows 128 * use of active sensors that require external 129 * power. 130 */ 131 public DifferentialVoltage(double TargetOutput, double DifferentialPosition, boolean EnableFOC, int DifferentialSlot, boolean OverrideBrakeDurNeutral, boolean LimitForwardMotion, boolean LimitReverseMotion) 132 { 133 super("DifferentialVoltage"); 134 this.TargetOutput = TargetOutput; 135 this.DifferentialPosition = DifferentialPosition; 136 this.EnableFOC = EnableFOC; 137 this.DifferentialSlot = DifferentialSlot; 138 this.OverrideBrakeDurNeutral = OverrideBrakeDurNeutral; 139 this.LimitForwardMotion = LimitForwardMotion; 140 this.LimitReverseMotion = LimitReverseMotion; 141 } 142 143 /** 144 * Request a specified voltage with a differential position closed-loop. 145 * <p> 146 * This control mode will attempt to apply the specified voltage to the motor. 147 * If the supply voltage is below the requested voltage, the motor controller 148 * will output the supply voltage. It will also set the motor's differential 149 * position setpoint to the specified position. 150 * 151 * @param TargetOutput Voltage to attempt to drive at 152 * @param DifferentialPosition Differential position to drive towards in 153 * rotations 154 */ 155 public DifferentialVoltage(double TargetOutput, double DifferentialPosition) 156 { 157 this(TargetOutput, DifferentialPosition, true, 1, false, false, false); 158 } 159 160 @Override 161 public String toString() 162 { 163 String ss = "class: DifferentialVoltage\n"; 164 ss += "TargetOutput: " + TargetOutput + "\n"; 165 ss += "DifferentialPosition: " + DifferentialPosition + "\n"; 166 ss += "EnableFOC: " + EnableFOC + "\n"; 167 ss += "DifferentialSlot: " + DifferentialSlot + "\n"; 168 ss += "OverrideBrakeDurNeutral: " + OverrideBrakeDurNeutral + "\n"; 169 ss += "LimitForwardMotion: " + LimitForwardMotion + "\n"; 170 ss += "LimitReverseMotion: " + LimitReverseMotion + "\n"; 171 return ss; 172 } 173 174 @Override 175 public StatusCode sendRequest(String network, int deviceHash, boolean cancelOtherRequests) 176 { 177 return StatusCode.valueOf(ControlJNI.JNI_RequestControlDifferentialVoltage( 178 network, deviceHash, UpdateFreqHz, cancelOtherRequests, TargetOutput, DifferentialPosition, EnableFOC, DifferentialSlot, OverrideBrakeDurNeutral, LimitForwardMotion, LimitReverseMotion)); 179 } 180 181 /** 182 * Gets information about this control request. 183 * 184 * @return Map of control parameter names and corresponding applied values 185 */ 186 @Override 187 public Map<String, String> getControlInfo() 188 { 189 var controlInfo = new HashMap<String, String>(); 190 controlInfo.put("Name", getName()); 191 controlInfo.put("TargetOutput", String.valueOf(this.TargetOutput)); 192 controlInfo.put("DifferentialPosition", String.valueOf(this.DifferentialPosition)); 193 controlInfo.put("EnableFOC", String.valueOf(this.EnableFOC)); 194 controlInfo.put("DifferentialSlot", String.valueOf(this.DifferentialSlot)); 195 controlInfo.put("OverrideBrakeDurNeutral", String.valueOf(this.OverrideBrakeDurNeutral)); 196 controlInfo.put("LimitForwardMotion", String.valueOf(this.LimitForwardMotion)); 197 controlInfo.put("LimitReverseMotion", String.valueOf(this.LimitReverseMotion)); 198 return controlInfo; 199 } 200 201 /** 202 * Modifies this Control Request's TargetOutput parameter and returns itself for 203 * method-chaining and easier to use request API. 204 * <p> 205 * Voltage to attempt to drive at 206 * 207 * @param newTargetOutput Parameter to modify 208 * @return Itself 209 */ 210 public DifferentialVoltage withTargetOutput(double newTargetOutput) 211 { 212 TargetOutput = newTargetOutput; 213 return this; 214 } 215 216 /** 217 * Modifies this Control Request's DifferentialPosition parameter and returns itself for 218 * method-chaining and easier to use request API. 219 * <p> 220 * Differential position to drive towards in rotations 221 * 222 * @param newDifferentialPosition Parameter to modify 223 * @return Itself 224 */ 225 public DifferentialVoltage withDifferentialPosition(double newDifferentialPosition) 226 { 227 DifferentialPosition = newDifferentialPosition; 228 return this; 229 } 230 231 /** 232 * Modifies this Control Request's EnableFOC parameter and returns itself for 233 * method-chaining and easier to use request API. 234 * <p> 235 * Set to true to use FOC commutation (requires Phoenix Pro), which increases 236 * peak power by ~15%. Set to false to use trapezoidal commutation. 237 * <p> 238 * FOC improves motor performance by leveraging torque (current) control. 239 * However, this may be inconvenient for applications that require specifying 240 * duty cycle or voltage. CTR-Electronics has developed a hybrid method that 241 * combines the performances gains of FOC while still allowing applications to 242 * provide duty cycle or voltage demand. This not to be confused with simple 243 * sinusoidal control or phase voltage control which lacks the performance 244 * gains. 245 * 246 * @param newEnableFOC Parameter to modify 247 * @return Itself 248 */ 249 public DifferentialVoltage withEnableFOC(boolean newEnableFOC) 250 { 251 EnableFOC = newEnableFOC; 252 return this; 253 } 254 255 /** 256 * Modifies this Control Request's DifferentialSlot parameter and returns itself for 257 * method-chaining and easier to use request API. 258 * <p> 259 * Select which gains are applied to the differential controller by selecting 260 * the slot. Use the configuration api to set the gain values for the selected 261 * slot before enabling this feature. Slot must be within [0,2]. 262 * 263 * @param newDifferentialSlot Parameter to modify 264 * @return Itself 265 */ 266 public DifferentialVoltage withDifferentialSlot(int newDifferentialSlot) 267 { 268 DifferentialSlot = newDifferentialSlot; 269 return this; 270 } 271 272 /** 273 * Modifies this Control Request's OverrideBrakeDurNeutral parameter and returns itself for 274 * method-chaining and easier to use request API. 275 * <p> 276 * Set to true to static-brake the rotor when output is zero (or within 277 * deadband). Set to false to use the NeutralMode configuration setting 278 * (default). This flag exists to provide the fundamental behavior of this 279 * control when output is zero, which is to provide 0V to the motor. 280 * 281 * @param newOverrideBrakeDurNeutral Parameter to modify 282 * @return Itself 283 */ 284 public DifferentialVoltage withOverrideBrakeDurNeutral(boolean newOverrideBrakeDurNeutral) 285 { 286 OverrideBrakeDurNeutral = newOverrideBrakeDurNeutral; 287 return this; 288 } 289 290 /** 291 * Modifies this Control Request's LimitForwardMotion parameter and returns itself for 292 * method-chaining and easier to use request API. 293 * <p> 294 * Set to true to force forward limiting. This allows users to use other limit 295 * switch sensors connected to robot controller. This also allows use of active 296 * sensors that require external power. 297 * 298 * @param newLimitForwardMotion Parameter to modify 299 * @return Itself 300 */ 301 public DifferentialVoltage withLimitForwardMotion(boolean newLimitForwardMotion) 302 { 303 LimitForwardMotion = newLimitForwardMotion; 304 return this; 305 } 306 307 /** 308 * Modifies this Control Request's LimitReverseMotion parameter and returns itself for 309 * method-chaining and easier to use request API. 310 * <p> 311 * Set to true to force reverse limiting. This allows users to use other limit 312 * switch sensors connected to robot controller. This also allows use of active 313 * sensors that require external power. 314 * 315 * @param newLimitReverseMotion Parameter to modify 316 * @return Itself 317 */ 318 public DifferentialVoltage withLimitReverseMotion(boolean newLimitReverseMotion) 319 { 320 LimitReverseMotion = newLimitReverseMotion; 321 return this; 322 } 323 /** 324 * Sets the period at which this control will update at. 325 * This is designated in Hertz, with a minimum of 20 Hz 326 * (every 50 ms) and a maximum of 1000 Hz (every 1 ms). 327 * <p> 328 * If this field is set to 0 Hz, the control request will 329 * be sent immediately as a one-shot frame. This may be useful 330 * for advanced applications that require outputs to be 331 * synchronized with data acquisition. In this case, we 332 * recommend not exceeding 50 ms between control calls. 333 * 334 * @param newUpdateFreqHz Parameter to modify 335 * @return Itself 336 */ 337 public DifferentialVoltage withUpdateFreqHz(double newUpdateFreqHz) 338 { 339 UpdateFreqHz = newUpdateFreqHz; 340 return this; 341 } 342 343 @Override 344 public DifferentialVoltage clone() 345 { 346 try { 347 return (DifferentialVoltage)super.clone(); 348 } catch (CloneNotSupportedException ex) { 349 /* this should never happen */ 350 throw new RuntimeException(ex); 351 } 352 } 353} 354