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