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