CTRE Phoenix 6 C++ 25.0.0-beta-4
Loading...
Searching...
No Matches
TorqueCurrentFOC.hpp
Go to the documentation of this file.
1/*
2 * Copyright (C) Cross The Road Electronics.  All rights reserved.
3 * License information can be found in CTRE_LICENSE.txt
4 * For support and suggestions contact support@ctr-electronics.com or file
5 * an issue tracker at https://github.com/CrossTheRoadElec/Phoenix-Releases
6 */
7#pragma once
8
12#include <sstream>
13#include <units/current.h>
14#include <units/dimensionless.h>
15#include <units/frequency.h>
16#include <units/time.h>
17
18
19namespace ctre {
20namespace phoenix6 {
21namespace controls {
22
23/**
24 * Requires Phoenix Pro;
25 * Request a specified motor current (field oriented control).
26 *
27 * This control request will drive the motor to the requested motor (stator) current value. This leverages
28 * field oriented control (FOC), which means greater peak power than what is documented. This scales to
29 * torque based on Motor's kT constant.
30 */
32{
33 ctre::phoenix::StatusCode SendRequest(const char *network, uint32_t deviceHash, std::shared_ptr<ControlRequest> &req) const override
34 {
35 if (req.get() != this)
36 {
37 auto const reqCast = dynamic_cast<TorqueCurrentFOC *>(req.get());
38 if (reqCast != nullptr)
39 {
40 *reqCast = *this;
41 }
42 else
43 {
44 req = std::make_shared<TorqueCurrentFOC>(*this);
45 }
46 }
47
49 }
50
51public:
52 /**
53 * \brief Amount of motor current in Amperes
54 */
55 units::current::ampere_t Output;
56 /**
57 * \brief The maximum absolute motor output that can be applied, which
58 * effectively limits the velocity. For example, 0.50 means no more than 50%
59 * output in either direction. This is useful for preventing the motor from
60 * spinning to its terminal velocity when there is no external torque applied
61 * unto the rotor. Note this is absolute maximum, so the value should be
62 * between zero and one.
63 */
64 units::dimensionless::scalar_t MaxAbsDutyCycle = 1.0;
65 /**
66 * \brief Deadband in Amperes. If torque request is within deadband, the bridge
67 * output is neutral. If deadband is set to zero then there is effectively no
68 * deadband. Note if deadband is zero, a free spinning motor will spin for quite
69 * a while as the firmware attempts to hold the motor's bemf. If user expects
70 * motor to cease spinning quickly with a demand of zero, we recommend a
71 * deadband of one Ampere. This value will be converted to an integral value of
72 * amps.
73 */
74 units::current::ampere_t Deadband = 0.0_A;
75 /**
76 * \brief Set to true to coast the rotor when output is zero (or within
77 * deadband). Set to false to use the NeutralMode configuration setting
78 * (default). This flag exists to provide the fundamental behavior of this
79 * control when output is zero, which is to provide 0A (zero torque).
80 */
82 /**
83 * \brief Set to true to force forward limiting. This allows users to use other
84 * limit switch sensors connected to robot controller. This also allows use of
85 * active sensors that require external power.
86 */
87 bool LimitForwardMotion = false;
88 /**
89 * \brief Set to true to force reverse limiting. This allows users to use other
90 * limit switch sensors connected to robot controller. This also allows use of
91 * active sensors that require external power.
92 */
93 bool LimitReverseMotion = false;
94 /**
95 * \brief Set to true to ignore hardware limit switches and the
96 * LimitForwardMotion and LimitReverseMotion parameters, instead allowing
97 * motion.
98 *
99 * This can be useful on mechanisms such as an intake/feeder, where a limit
100 * switch stops motion while intaking but should be ignored when feeding to a
101 * shooter.
102 *
103 * The hardware limit faults and Forward/ReverseLimit signals will still report
104 * the values of the limit switches regardless of this parameter.
105 */
107 /**
108 * \brief Set to true to delay applying this control request until a timesync
109 * boundary (requires Phoenix Pro and CANivore). This eliminates the impact of
110 * nondeterministic network delays in exchange for a larger but deterministic
111 * control latency.
112 *
113 * This requires setting the ControlTimesyncFreqHz config in MotorOutputConfigs.
114 * Additionally, when this is enabled, the UpdateFreqHz of this request should
115 * be set to 0 Hz.
116 */
117 bool UseTimesync = false;
118
119 /**
120 * \brief The period at which this control will update at.
121 * This is designated in Hertz, with a minimum of 20 Hz
122 * (every 50 ms) and a maximum of 1000 Hz (every 1 ms).
123 *
124 * If this field is set to 0 Hz, the control request will
125 * be sent immediately as a one-shot frame. This may be useful
126 * for advanced applications that require outputs to be
127 * synchronized with data acquisition. In this case, we
128 * recommend not exceeding 50 ms between control calls.
129 */
130 units::frequency::hertz_t UpdateFreqHz{100_Hz};
131
132 /**
133 * \brief Requires Phoenix Pro;
134 * Request a specified motor current (field oriented control).
135 *
136 * \details This control request will drive the motor to the requested motor
137 * (stator) current value. This leverages field oriented control
138 * (FOC), which means greater peak power than what is documented. This
139 * scales to torque based on Motor's kT constant.
140 *
141 * \param Output Amount of motor current in Amperes
142 */
143 TorqueCurrentFOC(units::current::ampere_t Output) : ControlRequest{"TorqueCurrentFOC"},
144 Output{std::move(Output)}
145 {}
146
147 /**
148 * \brief Modifies this Control Request's Output parameter and returns itself for
149 * method-chaining and easier to use request API.
150 *
151 * Amount of motor current in Amperes
152 *
153 * \param newOutput Parameter to modify
154 * \returns Itself
155 */
156 TorqueCurrentFOC &WithOutput(units::current::ampere_t newOutput)
157 {
158 Output = std::move(newOutput);
159 return *this;
160 }
161
162 /**
163 * \brief Modifies this Control Request's MaxAbsDutyCycle parameter and returns itself for
164 * method-chaining and easier to use request API.
165 *
166 * The maximum absolute motor output that can be applied, which effectively
167 * limits the velocity. For example, 0.50 means no more than 50% output in
168 * either direction. This is useful for preventing the motor from spinning to
169 * its terminal velocity when there is no external torque applied unto the
170 * rotor. Note this is absolute maximum, so the value should be between zero
171 * and one.
172 *
173 * \param newMaxAbsDutyCycle Parameter to modify
174 * \returns Itself
175 */
176 TorqueCurrentFOC &WithMaxAbsDutyCycle(units::dimensionless::scalar_t newMaxAbsDutyCycle)
177 {
178 MaxAbsDutyCycle = std::move(newMaxAbsDutyCycle);
179 return *this;
180 }
181
182 /**
183 * \brief Modifies this Control Request's Deadband parameter and returns itself for
184 * method-chaining and easier to use request API.
185 *
186 * Deadband in Amperes. If torque request is within deadband, the bridge output
187 * is neutral. If deadband is set to zero then there is effectively no deadband.
188 * Note if deadband is zero, a free spinning motor will spin for quite a while
189 * as the firmware attempts to hold the motor's bemf. If user expects motor to
190 * cease spinning quickly with a demand of zero, we recommend a deadband of one
191 * Ampere. This value will be converted to an integral value of amps.
192 *
193 * \param newDeadband Parameter to modify
194 * \returns Itself
195 */
196 TorqueCurrentFOC &WithDeadband(units::current::ampere_t newDeadband)
197 {
198 Deadband = std::move(newDeadband);
199 return *this;
200 }
201
202 /**
203 * \brief Modifies this Control Request's OverrideCoastDurNeutral parameter and returns itself for
204 * method-chaining and easier to use request API.
205 *
206 * Set to true to coast the rotor when output is zero (or within deadband). Set
207 * to false to use the NeutralMode configuration setting (default). This flag
208 * exists to provide the fundamental behavior of this control when output is
209 * zero, which is to provide 0A (zero torque).
210 *
211 * \param newOverrideCoastDurNeutral Parameter to modify
212 * \returns Itself
213 */
214 TorqueCurrentFOC &WithOverrideCoastDurNeutral(bool newOverrideCoastDurNeutral)
215 {
216 OverrideCoastDurNeutral = std::move(newOverrideCoastDurNeutral);
217 return *this;
218 }
219
220 /**
221 * \brief Modifies this Control Request's LimitForwardMotion parameter and returns itself for
222 * method-chaining and easier to use request API.
223 *
224 * Set to true to force forward limiting. This allows users to use other limit
225 * switch sensors connected to robot controller. This also allows use of active
226 * sensors that require external power.
227 *
228 * \param newLimitForwardMotion Parameter to modify
229 * \returns Itself
230 */
231 TorqueCurrentFOC &WithLimitForwardMotion(bool newLimitForwardMotion)
232 {
233 LimitForwardMotion = std::move(newLimitForwardMotion);
234 return *this;
235 }
236
237 /**
238 * \brief Modifies this Control Request's LimitReverseMotion parameter and returns itself for
239 * method-chaining and easier to use request API.
240 *
241 * Set to true to force reverse limiting. This allows users to use other limit
242 * switch sensors connected to robot controller. This also allows use of active
243 * sensors that require external power.
244 *
245 * \param newLimitReverseMotion Parameter to modify
246 * \returns Itself
247 */
248 TorqueCurrentFOC &WithLimitReverseMotion(bool newLimitReverseMotion)
249 {
250 LimitReverseMotion = std::move(newLimitReverseMotion);
251 return *this;
252 }
253
254 /**
255 * \brief Modifies this Control Request's IgnoreHardwareLimits parameter and returns itself for
256 * method-chaining and easier to use request API.
257 *
258 * Set to true to ignore hardware limit switches and the LimitForwardMotion and
259 * LimitReverseMotion parameters, instead allowing motion.
260 *
261 * This can be useful on mechanisms such as an intake/feeder, where a limit
262 * switch stops motion while intaking but should be ignored when feeding to a
263 * shooter.
264 *
265 * The hardware limit faults and Forward/ReverseLimit signals will still report
266 * the values of the limit switches regardless of this parameter.
267 *
268 * \param newIgnoreHardwareLimits Parameter to modify
269 * \returns Itself
270 */
271 TorqueCurrentFOC &WithIgnoreHardwareLimits(bool newIgnoreHardwareLimits)
272 {
273 IgnoreHardwareLimits = std::move(newIgnoreHardwareLimits);
274 return *this;
275 }
276
277 /**
278 * \brief Modifies this Control Request's UseTimesync parameter and returns itself for
279 * method-chaining and easier to use request API.
280 *
281 * Set to true to delay applying this control request until a timesync boundary
282 * (requires Phoenix Pro and CANivore). This eliminates the impact of
283 * nondeterministic network delays in exchange for a larger but deterministic
284 * control latency.
285 *
286 * This requires setting the ControlTimesyncFreqHz config in MotorOutputConfigs.
287 * Additionally, when this is enabled, the UpdateFreqHz of this request should
288 * be set to 0 Hz.
289 *
290 * \param newUseTimesync Parameter to modify
291 * \returns Itself
292 */
293 TorqueCurrentFOC &WithUseTimesync(bool newUseTimesync)
294 {
295 UseTimesync = std::move(newUseTimesync);
296 return *this;
297 }
298 /**
299 * \brief Sets the period at which this control will update at.
300 * This is designated in Hertz, with a minimum of 20 Hz
301 * (every 50 ms) and a maximum of 1000 Hz (every 1 ms).
302 *
303 * If this field is set to 0 Hz, the control request will
304 * be sent immediately as a one-shot frame. This may be useful
305 * for advanced applications that require outputs to be
306 * synchronized with data acquisition. In this case, we
307 * recommend not exceeding 50 ms between control calls.
308 *
309 * \param newUpdateFreqHz Parameter to modify
310 * \returns Itself
311 */
312 TorqueCurrentFOC &WithUpdateFreqHz(units::frequency::hertz_t newUpdateFreqHz)
313 {
314 UpdateFreqHz = newUpdateFreqHz;
315 return *this;
316 }
317 /**
318 * \brief Returns a string representation of the object.
319 *
320 * \returns a string representation of the object.
321 */
322 std::string ToString() const override
323 {
324 std::stringstream ss;
325 ss << "Control: TorqueCurrentFOC" << std::endl;
326 ss << " Output: " << Output.to<double>() << " A" << std::endl;
327 ss << " MaxAbsDutyCycle: " << MaxAbsDutyCycle.to<double>() << " fractional" << std::endl;
328 ss << " Deadband: " << Deadband.to<double>() << " A" << std::endl;
329 ss << " OverrideCoastDurNeutral: " << OverrideCoastDurNeutral << std::endl;
330 ss << " LimitForwardMotion: " << LimitForwardMotion << std::endl;
331 ss << " LimitReverseMotion: " << LimitReverseMotion << std::endl;
332 ss << " IgnoreHardwareLimits: " << IgnoreHardwareLimits << std::endl;
333 ss << " UseTimesync: " << UseTimesync << std::endl;
334 return ss.str();
335 }
336
337 /**
338 * \brief Gets information about this control request.
339 *
340 * \returns Map of control parameter names and corresponding applied values
341 */
342 std::map<std::string, std::string> GetControlInfo() const override
343 {
344 std::map<std::string, std::string> controlInfo;
345 std::stringstream ss;
346 controlInfo["Name"] = GetName();
347 ss << Output.to<double>(); controlInfo["Output"] = ss.str(); ss.str(std::string{});
348 ss << MaxAbsDutyCycle.to<double>(); controlInfo["MaxAbsDutyCycle"] = ss.str(); ss.str(std::string{});
349 ss << Deadband.to<double>(); controlInfo["Deadband"] = ss.str(); ss.str(std::string{});
350 ss << OverrideCoastDurNeutral; controlInfo["OverrideCoastDurNeutral"] = ss.str(); ss.str(std::string{});
351 ss << LimitForwardMotion; controlInfo["LimitForwardMotion"] = ss.str(); ss.str(std::string{});
352 ss << LimitReverseMotion; controlInfo["LimitReverseMotion"] = ss.str(); ss.str(std::string{});
353 ss << IgnoreHardwareLimits; controlInfo["IgnoreHardwareLimits"] = ss.str(); ss.str(std::string{});
354 ss << UseTimesync; controlInfo["UseTimesync"] = ss.str(); ss.str(std::string{});
355 return controlInfo;
356 }
357};
358
359}
360}
361}
362
CTREXPORT int c_ctre_phoenix6_RequestControlTorqueCurrentFOC(const char *canbus, uint32_t ecuEncoding, double updateTime, double Output, double MaxAbsDutyCycle, double Deadband, bool OverrideCoastDurNeutral, bool LimitForwardMotion, bool LimitReverseMotion, bool IgnoreHardwareLimits, bool UseTimesync)
Abstract Control Request class that other control requests extend for use.
Definition ControlRequest.hpp:29
std::string const & GetName() const
Definition ControlRequest.hpp:52
Requires Phoenix Pro; Request a specified motor current (field oriented control).
Definition TorqueCurrentFOC.hpp:32
TorqueCurrentFOC & WithDeadband(units::current::ampere_t newDeadband)
Modifies this Control Request's Deadband parameter and returns itself for method-chaining and easier ...
Definition TorqueCurrentFOC.hpp:196
TorqueCurrentFOC & WithLimitForwardMotion(bool newLimitForwardMotion)
Modifies this Control Request's LimitForwardMotion parameter and returns itself for method-chaining a...
Definition TorqueCurrentFOC.hpp:231
TorqueCurrentFOC & WithUseTimesync(bool newUseTimesync)
Modifies this Control Request's UseTimesync parameter and returns itself for method-chaining and easi...
Definition TorqueCurrentFOC.hpp:293
TorqueCurrentFOC & WithUpdateFreqHz(units::frequency::hertz_t newUpdateFreqHz)
Sets the period at which this control will update at.
Definition TorqueCurrentFOC.hpp:312
std::map< std::string, std::string > GetControlInfo() const override
Gets information about this control request.
Definition TorqueCurrentFOC.hpp:342
TorqueCurrentFOC & WithOutput(units::current::ampere_t newOutput)
Modifies this Control Request's Output parameter and returns itself for method-chaining and easier to...
Definition TorqueCurrentFOC.hpp:156
bool IgnoreHardwareLimits
Set to true to ignore hardware limit switches and the LimitForwardMotion and LimitReverseMotion param...
Definition TorqueCurrentFOC.hpp:106
bool UseTimesync
Set to true to delay applying this control request until a timesync boundary (requires Phoenix Pro an...
Definition TorqueCurrentFOC.hpp:117
TorqueCurrentFOC & WithLimitReverseMotion(bool newLimitReverseMotion)
Modifies this Control Request's LimitReverseMotion parameter and returns itself for method-chaining a...
Definition TorqueCurrentFOC.hpp:248
units::current::ampere_t Output
Amount of motor current in Amperes.
Definition TorqueCurrentFOC.hpp:55
bool OverrideCoastDurNeutral
Set to true to coast the rotor when output is zero (or within deadband).
Definition TorqueCurrentFOC.hpp:81
TorqueCurrentFOC & WithOverrideCoastDurNeutral(bool newOverrideCoastDurNeutral)
Modifies this Control Request's OverrideCoastDurNeutral parameter and returns itself for method-chain...
Definition TorqueCurrentFOC.hpp:214
TorqueCurrentFOC & WithMaxAbsDutyCycle(units::dimensionless::scalar_t newMaxAbsDutyCycle)
Modifies this Control Request's MaxAbsDutyCycle parameter and returns itself for method-chaining and ...
Definition TorqueCurrentFOC.hpp:176
bool LimitReverseMotion
Set to true to force reverse limiting.
Definition TorqueCurrentFOC.hpp:93
units::current::ampere_t Deadband
Deadband in Amperes.
Definition TorqueCurrentFOC.hpp:74
TorqueCurrentFOC & WithIgnoreHardwareLimits(bool newIgnoreHardwareLimits)
Modifies this Control Request's IgnoreHardwareLimits parameter and returns itself for method-chaining...
Definition TorqueCurrentFOC.hpp:271
bool LimitForwardMotion
Set to true to force forward limiting.
Definition TorqueCurrentFOC.hpp:87
TorqueCurrentFOC(units::current::ampere_t Output)
Requires Phoenix Pro; Request a specified motor current (field oriented control).
Definition TorqueCurrentFOC.hpp:143
std::string ToString() const override
Returns a string representation of the object.
Definition TorqueCurrentFOC.hpp:322
units::frequency::hertz_t UpdateFreqHz
The period at which this control will update at.
Definition TorqueCurrentFOC.hpp:130
units::dimensionless::scalar_t MaxAbsDutyCycle
The maximum absolute motor output that can be applied, which effectively limits the velocity.
Definition TorqueCurrentFOC.hpp:64
Status codes reported by APIs, including OK, warnings, and errors.
Definition StatusCodes.h:27
Definition StatusCodes.h:18
Definition span.hpp:401