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 * Request PID to target position with torque current feedforward. 015 * <p> 016 * This control mode will set the motor's position setpoint to the position specified by the user. In 017 * addition, it will apply an additional torque current as an arbitrary feedforward value. 018 */ 019public class PositionTorqueCurrentFOC extends ControlRequest 020{ 021 private boolean applyConfigsOnRequest; 022 /** 023 * Position to drive toward in rotations. 024 */ 025 public double Position; 026 /** 027 * Feedforward to apply in torque current in Amperes. User can use motor's kT 028 * to scale Newton-meter to Amperes. 029 */ 030 public double FeedForward; 031 /** 032 * Select which gains are applied by selecting the slot. Use the configuration 033 * api to set the gain values for the selected slot before enabling this 034 * feature. Slot must be within [0,2]. 035 */ 036 public int Slot; 037 /** 038 * Set to true to coast the rotor when output is zero (or within deadband). Set 039 * to false to use the NeutralMode configuration setting (default). This flag 040 * exists to provide the fundamental behavior of this control when output is 041 * zero, which is to provide 0A (zero torque). 042 */ 043 public boolean OverrideCoastDurNeutral; 044 045 046 /** 047 * The period at which this control will update at. 048 * This is designated in Hertz, with a minimum of 20 Hz 049 * (every 50 ms) and a maximum of 1000 Hz (every 1 ms). 050 * <p> 051 * If this field is set to 0 Hz, the control request will 052 * be sent immediately as a one-shot frame. This may be useful 053 * for advanced applications that require outputs to be 054 * synchronized with data acquisition. In this case, we 055 * recommend not exceeding 50 ms between control calls. 056 */ 057 public double UpdateFreqHz = 100; // Default to 100Hz 058 059 /** 060 * The timeout when sending configs associated with this control 061 */ 062 public double configTimeout = 0.1; 063 064 /** 065 * Request PID to target position with torque current feedforward. 066 * <p> 067 * This control mode will set the motor's position setpoint to the position 068 * specified by the user. In addition, it will apply an additional torque 069 * current as an arbitrary feedforward value. 070 * 071 * @param Position Position to drive toward in rotations. 072 * @param FeedForward Feedforward to apply in torque current in Amperes. 073 * User can use motor's kT to scale Newton-meter to 074 * Amperes. 075 * @param Slot Select which gains are applied by selecting the slot. 076 * Use the configuration api to set the gain values for the 077 * selected slot before enabling this feature. Slot must be 078 * within [0,2]. 079 * @param OverrideCoastDurNeutral Set to true to coast the rotor when 080 * output is zero (or within deadband). 081 * Set to false to use the NeutralMode 082 * configuration setting (default). This 083 * flag exists to provide the fundamental 084 * behavior of this control when output 085 * is zero, which is to provide 0A (zero 086 * torque). 087 */ 088 public PositionTorqueCurrentFOC(double Position, double FeedForward, int Slot, boolean OverrideCoastDurNeutral) 089 { 090 super("PositionTorqueCurrentFOC"); 091 this.Position = Position; 092 this.FeedForward = FeedForward; 093 this.Slot = Slot; 094 this.OverrideCoastDurNeutral = OverrideCoastDurNeutral; 095 } 096 097 /** 098 * Request PID to target position with torque current feedforward. 099 * <p> 100 * This control mode will set the motor's position setpoint to the position 101 * specified by the user. In addition, it will apply an additional torque 102 * current as an arbitrary feedforward value. 103 * 104 * @param Position Position to drive toward in rotations. 105 */ 106 public PositionTorqueCurrentFOC(double Position) 107 { 108 this(Position, 0.0, 0, false); 109 } 110 111 @Override 112 public String toString() 113 { 114 String ss = "class: PositionTorqueCurrentFOC\n"; 115 ss += "Position: " + Position + "\n"; 116 ss += "FeedForward: " + FeedForward + "\n"; 117 ss += "Slot: " + Slot + "\n"; 118 ss += "OverrideCoastDurNeutral: " + OverrideCoastDurNeutral + "\n"; 119 return ss; 120 } 121 122 @Override 123 public StatusCode sendRequest(String network, int deviceHash, boolean cancelOtherRequests) 124 { 125 var ref = requestReference.getNameValues(); 126 ref.put("Position", String.valueOf(this.Position)); 127 ref.put("FeedForward", String.valueOf(this.FeedForward)); 128 ref.put("Slot", String.valueOf(this.Slot)); 129 ref.put("OverrideCoastDurNeutral", String.valueOf(this.OverrideCoastDurNeutral)); 130 String ss = ""; 131 132 ControlConfigJNI.JNI_RequestConfigApply(network, deviceHash, configTimeout, ss, applyConfigsOnRequest); 133 applyConfigsOnRequest = false; 134 return StatusCode.valueOf(ControlJNI.JNI_RequestControlPositionTorqueCurrentFOC( 135 network, deviceHash, UpdateFreqHz, cancelOtherRequests, Position, FeedForward, Slot, OverrideCoastDurNeutral)); 136 } 137 138 /** 139 * Modifies this Control Request's Position parameter and returns itself for 140 * method-chaining and easier to use request API. 141 * 142 * @param newPosition Parameter to modify 143 * @return Itself 144 */ 145 public PositionTorqueCurrentFOC withPosition(double newPosition) 146 { 147 Position = newPosition; 148 return this; 149 } 150 151 /** 152 * Modifies this Control Request's FeedForward parameter and returns itself for 153 * method-chaining and easier to use request API. 154 * 155 * @param newFeedForward Parameter to modify 156 * @return Itself 157 */ 158 public PositionTorqueCurrentFOC withFeedForward(double newFeedForward) 159 { 160 FeedForward = newFeedForward; 161 return this; 162 } 163 164 /** 165 * Modifies this Control Request's Slot parameter and returns itself for 166 * method-chaining and easier to use request API. 167 * 168 * @param newSlot Parameter to modify 169 * @return Itself 170 */ 171 public PositionTorqueCurrentFOC withSlot(int newSlot) 172 { 173 Slot = newSlot; 174 return this; 175 } 176 177 /** 178 * Modifies this Control Request's OverrideCoastDurNeutral parameter and returns itself for 179 * method-chaining and easier to use request API. 180 * 181 * @param newOverrideCoastDurNeutral Parameter to modify 182 * @return Itself 183 */ 184 public PositionTorqueCurrentFOC withOverrideCoastDurNeutral(boolean newOverrideCoastDurNeutral) 185 { 186 OverrideCoastDurNeutral = newOverrideCoastDurNeutral; 187 return this; 188 } 189 /** 190 * Sets the period at which this control will update at. 191 * This is designated in Hertz, with a minimum of 20 Hz 192 * (every 50 ms) and a maximum of 1000 Hz (every 1 ms). 193 * <p> 194 * If this field is set to 0 Hz, the control request will 195 * be sent immediately as a one-shot frame. This may be useful 196 * for advanced applications that require outputs to be 197 * synchronized with data acquisition. In this case, we 198 * recommend not exceeding 50 ms between control calls. 199 * 200 * @param newUpdateFreqHz Parameter to modify 201 * @return Itself 202 */ 203 public PositionTorqueCurrentFOC withUpdateFreqHz(double newUpdateFreqHz) 204 { 205 UpdateFreqHz = newUpdateFreqHz; 206 return this; 207 } 208 /** 209 * Forces configs to be applied the next time this is used in a setControl. 210 * <p> 211 * This is not necessary in the majority of cases, because Phoenix will make sure configs are 212 * properly set when they are not already set 213 */ 214 public void forceApplyConfigs() { applyConfigsOnRequest = true; } 215} 216