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.phoenixpro.controls; 008 009import com.ctre.phoenixpro.StatusCode; 010import com.ctre.phoenixpro.controls.jni.ControlJNI; 011import com.ctre.phoenixpro.controls.jni.ControlConfigJNI; 012 013/** 014 * Requests Motion Magic® to target a final position using a motion profile. 015 * Users can optionally provide a voltage feedforward. 016 * <p> 017 * Motion Magic® produces a motion profile in real-time while attempting to honor the Cruise Velocity, 018 * Acceleration, and Jerk value specified via the Motion Magic® configuration values. Target position can be 019 * changed on-the-fly and Motion Magic® will do its best to adjust the profile. This control mode is 020 * voltage-based, so relevant closed-loop gains will use Volts for the numerator. 021 */ 022public class MotionMagicVoltage extends ControlRequest 023{ 024 private boolean applyConfigsOnRequest; 025 /** 026 * Position to drive toward in rotations. 027 */ 028 public double Position; 029 /** 030 * Set to true to use FOC commutation, which increases peak power by ~15%. Set 031 * to false to use trapezoidal commutation. FOC improves motor performance by 032 * leveraging torque (current) control. However, this may be inconvenient for 033 * applications that require specifying duty cycle or voltage. CTR-Electronics 034 * has developed a hybrid method that combines the performances gains of FOC 035 * while still allowing applications to provide duty cycle or voltage demand. 036 * This not to be confused with simple sinusoidal control or phase voltage 037 * control which lacks the performance gains. 038 */ 039 public boolean EnableFOC; 040 /** 041 * Feedforward to apply in volts 042 */ 043 public double FeedForward; 044 /** 045 * Select which gains are applied by selecting the slot. Use the configuration 046 * api to set the gain values for the selected slot before enabling this 047 * feature. Slot must be within [0,2]. 048 */ 049 public int Slot; 050 /** 051 * Set to true to static-brake the rotor when output is zero (or within 052 * deadband). Set to false to use the NeutralMode configuration setting 053 * (default). This flag exists to provide the fundamental behavior of this 054 * control when output is zero, which is to provide 0V to the motor. 055 */ 056 public boolean OverrideBrakeDurNeutral; 057 058 059 /** 060 * The period at which this control will update at. 061 * This is designated in Hertz, with a minimum of 20 Hz 062 * (every 50 ms) and a maximum of 1000 Hz (every 1 ms). 063 * <p> 064 * If this field is set to 0 Hz, the control request will 065 * be sent immediately as a one-shot frame. This may be useful 066 * for advanced applications that require outputs to be 067 * synchronized with data acquisition. In this case, we 068 * recommend not exceeding 50 ms between control calls. 069 */ 070 public double UpdateFreqHz = 100; // Default to 100Hz 071 072 /** 073 * The timeout when sending configs associated with this control 074 */ 075 public double configTimeout = 0.1; 076 077 /** 078 * Requests Motion Magic® to target a final position using a motion profile. 079 * Users can optionally provide a voltage feedforward. 080 * <p> 081 * Motion Magic® produces a motion profile in real-time while attempting to 082 * honor the Cruise Velocity, Acceleration, and Jerk value specified via the 083 * Motion Magic® configuration values. Target position can be changed 084 * on-the-fly and Motion Magic® will do its best to adjust the profile. 085 * This control mode is voltage-based, so relevant closed-loop gains will 086 * use Volts for the numerator. 087 * 088 * @param Position Position to drive toward in rotations. 089 * @param EnableFOC Set to true to use FOC commutation, which increases 090 * peak power by ~15%. Set to false to use trapezoidal 091 * commutation. FOC improves motor performance by 092 * leveraging torque (current) control. However, this 093 * may be inconvenient for applications that require 094 * specifying duty cycle or voltage. CTR-Electronics 095 * has developed a hybrid method that combines the 096 * performances gains of FOC while still allowing 097 * applications to provide duty cycle or voltage 098 * demand. This not to be confused with simple 099 * sinusoidal control or phase voltage control which 100 * lacks the performance gains. 101 * @param FeedForward Feedforward to apply in volts 102 * @param Slot Select which gains are applied by selecting the slot. 103 * Use the configuration api to set the gain values for the 104 * selected slot before enabling this feature. Slot must be 105 * within [0,2]. 106 * @param OverrideBrakeDurNeutral Set to true to static-brake the rotor 107 * when output is zero (or within 108 * deadband). Set to false to use the 109 * NeutralMode configuration setting 110 * (default). This flag exists to provide 111 * the fundamental behavior of this 112 * control when output is zero, which is 113 * to provide 0V to the motor. 114 */ 115 public MotionMagicVoltage(double Position, boolean EnableFOC, double FeedForward, int Slot, boolean OverrideBrakeDurNeutral) 116 { 117 super("MotionMagicVoltage"); 118 this.Position = Position; 119 this.EnableFOC = EnableFOC; 120 this.FeedForward = FeedForward; 121 this.Slot = Slot; 122 this.OverrideBrakeDurNeutral = OverrideBrakeDurNeutral; 123 } 124 125 /** 126 * Requests Motion Magic® to target a final position using a motion profile. 127 * Users can optionally provide a voltage feedforward. 128 * <p> 129 * Motion Magic® produces a motion profile in real-time while attempting to 130 * honor the Cruise Velocity, Acceleration, and Jerk value specified via the 131 * Motion Magic® configuration values. Target position can be changed 132 * on-the-fly and Motion Magic® will do its best to adjust the profile. 133 * This control mode is voltage-based, so relevant closed-loop gains will 134 * use Volts for the numerator. 135 * 136 * @param Position Position to drive toward in rotations. 137 */ 138 public MotionMagicVoltage(double Position) 139 { 140 this(Position, true, 0.0, 0, false); 141 } 142 143 @Override 144 public String toString() 145 { 146 String ss = "class: MotionMagicVoltage\n"; 147 ss += "Position: " + Position + "\n"; 148 ss += "EnableFOC: " + EnableFOC + "\n"; 149 ss += "FeedForward: " + FeedForward + "\n"; 150 ss += "Slot: " + Slot + "\n"; 151 ss += "OverrideBrakeDurNeutral: " + OverrideBrakeDurNeutral + "\n"; 152 return ss; 153 } 154 155 @Override 156 public StatusCode sendRequest(String network, int deviceHash, boolean cancelOtherRequests) 157 { 158 var ref = requestReference.getNameValues(); 159 ref.put("Position", String.valueOf(this.Position)); 160 ref.put("EnableFOC", String.valueOf(this.EnableFOC)); 161 ref.put("FeedForward", String.valueOf(this.FeedForward)); 162 ref.put("Slot", String.valueOf(this.Slot)); 163 ref.put("OverrideBrakeDurNeutral", String.valueOf(this.OverrideBrakeDurNeutral)); 164 String ss = ""; 165 166 ControlConfigJNI.JNI_RequestConfigApply(network, deviceHash, configTimeout, ss, applyConfigsOnRequest); 167 applyConfigsOnRequest = false; 168 return StatusCode.valueOf(ControlJNI.JNI_RequestControlMotionMagicVoltage( 169 network, deviceHash, UpdateFreqHz, cancelOtherRequests, Position, EnableFOC, FeedForward, Slot, OverrideBrakeDurNeutral)); 170 } 171 172 /** 173 * Modifies this Control Request's Position parameter and returns itself for 174 * method-chaining and easier to use request API. 175 * 176 * @param newPosition Parameter to modify 177 * @return Itself 178 */ 179 public MotionMagicVoltage withPosition(double newPosition) 180 { 181 Position = newPosition; 182 return this; 183 } 184 185 /** 186 * Modifies this Control Request's EnableFOC parameter and returns itself for 187 * method-chaining and easier to use request API. 188 * 189 * @param newEnableFOC Parameter to modify 190 * @return Itself 191 */ 192 public MotionMagicVoltage withEnableFOC(boolean newEnableFOC) 193 { 194 EnableFOC = newEnableFOC; 195 return this; 196 } 197 198 /** 199 * Modifies this Control Request's FeedForward parameter and returns itself for 200 * method-chaining and easier to use request API. 201 * 202 * @param newFeedForward Parameter to modify 203 * @return Itself 204 */ 205 public MotionMagicVoltage withFeedForward(double newFeedForward) 206 { 207 FeedForward = newFeedForward; 208 return this; 209 } 210 211 /** 212 * Modifies this Control Request's Slot parameter and returns itself for 213 * method-chaining and easier to use request API. 214 * 215 * @param newSlot Parameter to modify 216 * @return Itself 217 */ 218 public MotionMagicVoltage withSlot(int newSlot) 219 { 220 Slot = newSlot; 221 return this; 222 } 223 224 /** 225 * Modifies this Control Request's OverrideBrakeDurNeutral parameter and returns itself for 226 * method-chaining and easier to use request API. 227 * 228 * @param newOverrideBrakeDurNeutral Parameter to modify 229 * @return Itself 230 */ 231 public MotionMagicVoltage withOverrideBrakeDurNeutral(boolean newOverrideBrakeDurNeutral) 232 { 233 OverrideBrakeDurNeutral = newOverrideBrakeDurNeutral; 234 return this; 235 } 236 /** 237 * Sets the period at which this control will update at. 238 * This is designated in Hertz, with a minimum of 20 Hz 239 * (every 50 ms) and a maximum of 1000 Hz (every 1 ms). 240 * <p> 241 * If this field is set to 0 Hz, the control request will 242 * be sent immediately as a one-shot frame. This may be useful 243 * for advanced applications that require outputs to be 244 * synchronized with data acquisition. In this case, we 245 * recommend not exceeding 50 ms between control calls. 246 * 247 * @param newUpdateFreqHz Parameter to modify 248 * @return Itself 249 */ 250 public MotionMagicVoltage withUpdateFreqHz(double newUpdateFreqHz) 251 { 252 UpdateFreqHz = newUpdateFreqHz; 253 return this; 254 } 255 /** 256 * Forces configs to be applied the next time this is used in a setControl. 257 * <p> 258 * This is not necessary in the majority of cases, because Phoenix will make sure configs are 259 * properly set when they are not already set 260 */ 261 public void forceApplyConfigs() { applyConfigsOnRequest = true; } 262} 263