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