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