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