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