CTRE Phoenix 6 C++ 24.3.0
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, bool cancelOtherRequests, std::shared_ptr<ControlRequest> &req) 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
48 return c_ctre_phoenix6_RequestControlTorqueCurrentFOC(network, deviceHash, UpdateFreqHz.to<double>(), cancelOtherRequests, Output.to<double>(), MaxAbsDutyCycle.to<double>(), Deadband.to<double>(), OverrideCoastDurNeutral, LimitForwardMotion, LimitReverseMotion);
49 }
50
51public:
52 /**
53 * Amount of motor current in Amperes
54 */
55 units::current::ampere_t Output;
56 /**
57 * The maximum absolute motor output that can be applied, which effectively
58 * limits the velocity. For example, 0.50 means no more than 50% output in
59 * either direction. This is useful for preventing the motor from spinning to
60 * its terminal velocity when there is no external torque applied unto the
61 * rotor. Note this is absolute maximum, so the value should be between zero
62 * and one.
63 */
64 units::dimensionless::scalar_t MaxAbsDutyCycle;
65 /**
66 * Deadband in Amperes. If torque request is within deadband, the bridge output
67 * is neutral. If deadband is set to zero then there is effectively no deadband.
68 * Note if deadband is zero, a free spinning motor will spin for quite a while
69 * as the firmware attempts to hold the motor's bemf. If user expects motor to
70 * cease spinning quickly with a demand of zero, we recommend a deadband of one
71 * Ampere. This value will be converted to an integral value of amps.
72 */
73 units::current::ampere_t Deadband;
74 /**
75 * Set to true to coast the rotor when output is zero (or within deadband). Set
76 * to false to use the NeutralMode configuration setting (default). This flag
77 * exists to provide the fundamental behavior of this control when output is
78 * zero, which is to provide 0A (zero torque).
79 */
81 /**
82 * Set to true to force forward limiting. This allows users to use other limit
83 * switch sensors connected to robot controller. This also allows use of active
84 * sensors that require external power.
85 */
87 /**
88 * Set to true to force reverse limiting. This allows users to use other limit
89 * switch sensors connected to robot controller. This also allows use of active
90 * sensors that require external power.
91 */
93
94 /**
95 * \brief The period at which this control will update at.
96 * This is designated in Hertz, with a minimum of 20 Hz
97 * (every 50 ms) and a maximum of 1000 Hz (every 1 ms).
98 *
99 * If this field is set to 0 Hz, the control request will
100 * be sent immediately as a one-shot frame. This may be useful
101 * for advanced applications that require outputs to be
102 * synchronized with data acquisition. In this case, we
103 * recommend not exceeding 50 ms between control calls.
104 */
105 units::frequency::hertz_t UpdateFreqHz{100_Hz}; // Default to 100_Hz
106
107 /**
108 * \brief Requires Phoenix Pro;
109 * Request a specified motor current (field oriented control).
110 *
111 * \details This control request will drive the motor to the requested motor
112 * (stator) current value. This leverages field oriented control
113 * (FOC), which means greater peak power than what is documented. This
114 * scales to torque based on Motor's kT constant.
115 *
116 * \param Output Amount of motor current in Amperes
117 * \param MaxAbsDutyCycle The maximum absolute motor output that can be
118 * applied, which effectively limits the velocity. For
119 * example, 0.50 means no more than 50% output in
120 * either direction. This is useful for preventing
121 * the motor from spinning to its terminal velocity
122 * when there is no external torque applied unto the
123 * rotor. Note this is absolute maximum, so the value
124 * should be between zero and one.
125 * \param Deadband Deadband in Amperes. If torque request is within
126 * deadband, the bridge output is neutral. If deadband is set
127 * to zero then there is effectively no deadband. Note if
128 * deadband is zero, a free spinning motor will spin for
129 * quite a while as the firmware attempts to hold the motor's
130 * bemf. If user expects motor to cease spinning quickly with
131 * a demand of zero, we recommend a deadband of one Ampere.
132 * This value will be converted to an integral value of amps.
133 * \param OverrideCoastDurNeutral Set to true to coast the rotor when output
134 * is zero (or within deadband). Set to false
135 * to use the NeutralMode configuration
136 * setting (default). This flag exists to
137 * provide the fundamental behavior of this
138 * control when output is zero, which is to
139 * provide 0A (zero torque).
140 * \param LimitForwardMotion Set to true to force forward limiting. This
141 * allows users to use other limit switch sensors
142 * connected to robot controller. This also allows
143 * use of active sensors that require external
144 * power.
145 * \param LimitReverseMotion Set to true to force reverse limiting. This
146 * allows users to use other limit switch sensors
147 * connected to robot controller. This also allows
148 * use of active sensors that require external
149 * power.
150 */
151 TorqueCurrentFOC(units::current::ampere_t Output, units::dimensionless::scalar_t MaxAbsDutyCycle = 1.0, units::current::ampere_t Deadband = 0.0_A, bool OverrideCoastDurNeutral = false, bool LimitForwardMotion = false, bool LimitReverseMotion = false) : ControlRequest{"TorqueCurrentFOC"},
152 Output{std::move(Output)},
154 Deadband{std::move(Deadband)},
158 {}
159
160 /**
161 * \brief Modifies this Control Request's Output parameter and returns itself for
162 * method-chaining and easier to use request API.
163 *
164 * Amount of motor current in Amperes
165 *
166 * \param newOutput Parameter to modify
167 * \returns Itself
168 */
169 TorqueCurrentFOC& WithOutput(units::current::ampere_t newOutput)
170 {
171 Output = std::move(newOutput);
172 return *this;
173 }
174
175 /**
176 * \brief Modifies this Control Request's MaxAbsDutyCycle parameter and returns itself for
177 * method-chaining and easier to use request API.
178 *
179 * The maximum absolute motor output that can be applied, which effectively
180 * limits the velocity. For example, 0.50 means no more than 50% output in
181 * either direction. This is useful for preventing the motor from spinning to
182 * its terminal velocity when there is no external torque applied unto the
183 * rotor. Note this is absolute maximum, so the value should be between zero
184 * and one.
185 *
186 * \param newMaxAbsDutyCycle Parameter to modify
187 * \returns Itself
188 */
189 TorqueCurrentFOC& WithMaxAbsDutyCycle(units::dimensionless::scalar_t newMaxAbsDutyCycle)
190 {
191 MaxAbsDutyCycle = std::move(newMaxAbsDutyCycle);
192 return *this;
193 }
194
195 /**
196 * \brief Modifies this Control Request's Deadband parameter and returns itself for
197 * method-chaining and easier to use request API.
198 *
199 * Deadband in Amperes. If torque request is within deadband, the bridge output
200 * is neutral. If deadband is set to zero then there is effectively no deadband.
201 * Note if deadband is zero, a free spinning motor will spin for quite a while
202 * as the firmware attempts to hold the motor's bemf. If user expects motor to
203 * cease spinning quickly with a demand of zero, we recommend a deadband of one
204 * Ampere. This value will be converted to an integral value of amps.
205 *
206 * \param newDeadband Parameter to modify
207 * \returns Itself
208 */
209 TorqueCurrentFOC& WithDeadband(units::current::ampere_t newDeadband)
210 {
211 Deadband = std::move(newDeadband);
212 return *this;
213 }
214
215 /**
216 * \brief Modifies this Control Request's OverrideCoastDurNeutral parameter and returns itself for
217 * method-chaining and easier to use request API.
218 *
219 * Set to true to coast the rotor when output is zero (or within deadband). Set
220 * to false to use the NeutralMode configuration setting (default). This flag
221 * exists to provide the fundamental behavior of this control when output is
222 * zero, which is to provide 0A (zero torque).
223 *
224 * \param newOverrideCoastDurNeutral Parameter to modify
225 * \returns Itself
226 */
227 TorqueCurrentFOC& WithOverrideCoastDurNeutral(bool newOverrideCoastDurNeutral)
228 {
229 OverrideCoastDurNeutral = std::move(newOverrideCoastDurNeutral);
230 return *this;
231 }
232
233 /**
234 * \brief Modifies this Control Request's LimitForwardMotion parameter and returns itself for
235 * method-chaining and easier to use request API.
236 *
237 * Set to true to force forward limiting. This allows users to use other limit
238 * switch sensors connected to robot controller. This also allows use of active
239 * sensors that require external power.
240 *
241 * \param newLimitForwardMotion Parameter to modify
242 * \returns Itself
243 */
244 TorqueCurrentFOC& WithLimitForwardMotion(bool newLimitForwardMotion)
245 {
246 LimitForwardMotion = std::move(newLimitForwardMotion);
247 return *this;
248 }
249
250 /**
251 * \brief Modifies this Control Request's LimitReverseMotion parameter and returns itself for
252 * method-chaining and easier to use request API.
253 *
254 * Set to true to force reverse limiting. This allows users to use other limit
255 * switch sensors connected to robot controller. This also allows use of active
256 * sensors that require external power.
257 *
258 * \param newLimitReverseMotion Parameter to modify
259 * \returns Itself
260 */
261 TorqueCurrentFOC& WithLimitReverseMotion(bool newLimitReverseMotion)
262 {
263 LimitReverseMotion = std::move(newLimitReverseMotion);
264 return *this;
265 }
266 /**
267 * \brief Sets the period at which this control will update at.
268 * This is designated in Hertz, with a minimum of 20 Hz
269 * (every 50 ms) and a maximum of 1000 Hz (every 1 ms).
270 *
271 * If this field is set to 0 Hz, the control request will
272 * be sent immediately as a one-shot frame. This may be useful
273 * for advanced applications that require outputs to be
274 * synchronized with data acquisition. In this case, we
275 * recommend not exceeding 50 ms between control calls.
276 *
277 * \param newUpdateFreqHz Parameter to modify
278 * \returns Itself
279 */
280 TorqueCurrentFOC &WithUpdateFreqHz(units::frequency::hertz_t newUpdateFreqHz)
281 {
282 UpdateFreqHz = newUpdateFreqHz;
283 return *this;
284 }
285 /**
286 * Returns a string representation of the object.
287 *
288 * \returns a string representation of the object.
289 */
290 std::string ToString() const override
291 {
292 std::stringstream ss;
293 ss << "class: TorqueCurrentFOC" << std::endl;
294 ss << "Output: " << Output.to<double>() << std::endl;
295 ss << "MaxAbsDutyCycle: " << MaxAbsDutyCycle.to<double>() << std::endl;
296 ss << "Deadband: " << Deadband.to<double>() << std::endl;
297 ss << "OverrideCoastDurNeutral: " << OverrideCoastDurNeutral << std::endl;
298 ss << "LimitForwardMotion: " << LimitForwardMotion << std::endl;
299 ss << "LimitReverseMotion: " << LimitReverseMotion << std::endl;
300 return ss.str();
301 }
302
303 /**
304 * \brief Gets information about this control request.
305 *
306 * \returns Map of control parameter names and corresponding applied values
307 */
308 std::map<std::string, std::string> GetControlInfo() const override
309 {
310 std::map<std::string, std::string> controlInfo;
311 std::stringstream ss;
312 controlInfo["Name"] = GetName();
313 ss << Output.to<double>(); controlInfo["Output"] = ss.str(); ss.str(std::string{});
314 ss << MaxAbsDutyCycle.to<double>(); controlInfo["MaxAbsDutyCycle"] = ss.str(); ss.str(std::string{});
315 ss << Deadband.to<double>(); controlInfo["Deadband"] = ss.str(); ss.str(std::string{});
316 ss << OverrideCoastDurNeutral; controlInfo["OverrideCoastDurNeutral"] = ss.str(); ss.str(std::string{});
317 ss << LimitForwardMotion; controlInfo["LimitForwardMotion"] = ss.str(); ss.str(std::string{});
318 ss << LimitReverseMotion; controlInfo["LimitReverseMotion"] = ss.str(); ss.str(std::string{});
319 return controlInfo;
320 }
321};
322
323}
324}
325}
326
CTREXPORT int c_ctre_phoenix6_RequestControlTorqueCurrentFOC(const char *canbus, uint32_t ecuEncoding, double updateTime, bool cancelOtherRequests, double Output, double MaxAbsDutyCycle, double Deadband, bool OverrideCoastDurNeutral, bool LimitForwardMotion, bool LimitReverseMotion)
Abstract Control Request class that other control requests extend for use.
Definition: ControlRequest.hpp:28
std::string const & GetName() const
Definition: ControlRequest.hpp:51
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:209
TorqueCurrentFOC & WithLimitForwardMotion(bool newLimitForwardMotion)
Modifies this Control Request's LimitForwardMotion parameter and returns itself for method-chaining a...
Definition: TorqueCurrentFOC.hpp:244
TorqueCurrentFOC & WithUpdateFreqHz(units::frequency::hertz_t newUpdateFreqHz)
Sets the period at which this control will update at.
Definition: TorqueCurrentFOC.hpp:280
std::map< std::string, std::string > GetControlInfo() const override
Gets information about this control request.
Definition: TorqueCurrentFOC.hpp:308
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:169
TorqueCurrentFOC & WithLimitReverseMotion(bool newLimitReverseMotion)
Modifies this Control Request's LimitReverseMotion parameter and returns itself for method-chaining a...
Definition: TorqueCurrentFOC.hpp:261
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:80
TorqueCurrentFOC & WithOverrideCoastDurNeutral(bool newOverrideCoastDurNeutral)
Modifies this Control Request's OverrideCoastDurNeutral parameter and returns itself for method-chain...
Definition: TorqueCurrentFOC.hpp:227
TorqueCurrentFOC & WithMaxAbsDutyCycle(units::dimensionless::scalar_t newMaxAbsDutyCycle)
Modifies this Control Request's MaxAbsDutyCycle parameter and returns itself for method-chaining and ...
Definition: TorqueCurrentFOC.hpp:189
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
bool LimitForwardMotion
Set to true to force forward limiting.
Definition: TorqueCurrentFOC.hpp:86
TorqueCurrentFOC(units::current::ampere_t Output, units::dimensionless::scalar_t MaxAbsDutyCycle=1.0, units::current::ampere_t Deadband=0.0_A, bool OverrideCoastDurNeutral=false, bool LimitForwardMotion=false, bool LimitReverseMotion=false)
Requires Phoenix Pro; Request a specified motor current (field oriented control).
Definition: TorqueCurrentFOC.hpp:151
std::string ToString() const override
Returns a string representation of the object.
Definition: TorqueCurrentFOC.hpp:290
units::frequency::hertz_t UpdateFreqHz
The period at which this control will update at.
Definition: TorqueCurrentFOC.hpp:105
units::dimensionless::scalar_t MaxAbsDutyCycle
The maximum absolute motor output that can be applied, which effectively limits the velocity.
Definition: TorqueCurrentFOC.hpp:64
Definition: string_util.hpp:15