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