CTRE Phoenix Pro C++ 23.0.12
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 phoenixpro {
21namespace controls {
22
23/**
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 bool ApplyConfigsOnRequest;
33
34 ctre::phoenix::StatusCode SendRequest(const char *network, uint32_t deviceHash, bool cancelOtherRequests, std::shared_ptr<ControlRequest> &req)
35 {
36 std::stringstream ss;
37 auto& ref = requestReference.GetNameValues();
38 ss << Output.to<double>(); ref["Output"] = ss.str(); ss.str(std::string());
39 ss << MaxAbsDutyCycle.to<double>(); ref["MaxAbsDutyCycle"] = ss.str(); ss.str(std::string());
40 ss << Deadband.to<double>(); ref["Deadband"] = ss.str(); ss.str(std::string());
41 ss << OverrideCoastDurNeutral; ref["OverrideCoastDurNeutral"] = ss.str(); ss.str(std::string());
42
43 if (req.get() != this)
44 {
45 auto const reqCast = dynamic_cast<TorqueCurrentFOC *>(req.get());
46 if (reqCast != nullptr)
47 {
48 *reqCast = *this;
49 }
50 else
51 {
52 req = std::make_shared<TorqueCurrentFOC>(*this);
53 }
54 }
55
56
57 std::string strs{ss.str()};
58 c_ctre_phoenixpro_requestConfigApply(network, deviceHash, ConfigTimeout.to<double>(), strs.c_str(), strs.length(), ApplyConfigsOnRequest);
59 ApplyConfigsOnRequest = false;
60 return c_ctre_phoenixpro_RequestControlTorqueCurrentFOC(network, deviceHash, UpdateFreqHz.to<double>(), cancelOtherRequests, Output.to<double>(), MaxAbsDutyCycle.to<double>(), Deadband.to<double>(), OverrideCoastDurNeutral);
61 }
62
63public:
64 /**
65 * Amount of motor current in Amperes
66 */
67 units::current::ampere_t Output;
68 /**
69 * The maximum absolute motor output that can be applied, which effectively
70 * limits the velocity. For example, 0.50 means no more than 50% output in
71 * either direction. This is useful for preventing the motor from spinning to
72 * its terminal velocity when there is no external torque applied unto the
73 * rotor. Note this is absolute maximum, so the value should be between zero
74 * and one.
75 */
76 units::dimensionless::scalar_t MaxAbsDutyCycle;
77 /**
78 * Deadband in Amperes. If torque request is within deadband, the bridge output
79 * is neutral. If deadband is set to zero then there is effectively no deadband.
80 * Note if deadband is zero, a free spinning motor will spin for quite a while
81 * as the firmware attempts to hold the motor's bemf. If user expects motor to
82 * cease spinning quickly with a demand of zero, we recommend a deadband of one
83 * Ampere. This value will be converted to an integral value of amps.
84 */
85 units::current::ampere_t Deadband;
86 /**
87 * Set to true to coast the rotor when output is zero (or within deadband). Set
88 * to false to use the NeutralMode configuration setting (default). This flag
89 * exists to provide the fundamental behavior of this control when output is
90 * zero, which is to provide 0A (zero torque).
91 */
93
94
95
96 /**
97 * \brief The timeout when sending configs associated with this control
98 */
99 units::time::second_t ConfigTimeout{0.1_s};
100
101 /**
102 * \brief The period at which this control will update at.
103 * This is designated in Hertz, with a minimum of 20 Hz
104 * (every 50 ms) and a maximum of 1000 Hz (every 1 ms).
105 *
106 * If this field is set to 0 Hz, the control request will
107 * be sent immediately as a one-shot frame. This may be useful
108 * for advanced applications that require outputs to be
109 * synchronized with data acquisition. In this case, we
110 * recommend not exceeding 50 ms between control calls.
111 */
112 units::frequency::hertz_t UpdateFreqHz{100_Hz}; // Default to 100_Hz
113
114 /**
115 *\brief Request a specified motor current (field oriented control).
116 *
117 *\details This control request will drive the motor to the requested motor
118 * (stator) current value. This leverages field oriented control
119 * (FOC), which means greater peak power than what is documented.
120 * This scales to torque based on Motor's kT constant.
121 *
122 * \param Output Amount of motor current in Amperes
123 * \param MaxAbsDutyCycle The maximum absolute motor output that can be
124 * applied, which effectively limits the
125 * velocity. For example, 0.50 means no more than
126 * 50% output in either direction. This is
127 * useful for preventing the motor from spinning
128 * to its terminal velocity when there is no
129 * external torque applied unto the rotor. Note
130 * this is absolute maximum, so the value should
131 * be between zero and one.
132 * \param Deadband Deadband in Amperes. If torque request is within
133 * deadband, the bridge output is neutral. If deadband
134 * is set to zero then there is effectively no deadband.
135 * Note if deadband is zero, a free spinning motor will
136 * spin for quite a while as the firmware attempts to
137 * hold the motor's bemf. If user expects motor to cease
138 * spinning quickly with a demand of zero, we recommend
139 * a deadband of one Ampere. This value will be
140 * converted to an integral value of amps.
141 * \param OverrideCoastDurNeutral Set to true to coast the rotor when
142 * output is zero (or within deadband).
143 * Set to false to use the NeutralMode
144 * configuration setting (default). This
145 * flag exists to provide the fundamental
146 * behavior of this control when output
147 * is zero, which is to provide 0A (zero
148 * torque).
149 */
150 TorqueCurrentFOC(units::current::ampere_t Output, units::dimensionless::scalar_t MaxAbsDutyCycle, units::current::ampere_t Deadband, bool OverrideCoastDurNeutral) : ControlRequest{"TorqueCurrentFOC"}, ApplyConfigsOnRequest{false}
151 {
152 this->Output = Output;
153 this->MaxAbsDutyCycle = MaxAbsDutyCycle;
154 this->Deadband = Deadband;
155 this->OverrideCoastDurNeutral = OverrideCoastDurNeutral;
156 }
157
158 /**
159 *\brief Request a specified motor current (field oriented control).
160 *
161 *\details This control request will drive the motor to the requested motor
162 * (stator) current value. This leverages field oriented control
163 * (FOC), which means greater peak power than what is documented.
164 * This scales to torque based on Motor's kT constant.
165 *
166 * \param Output Amount of motor current in Amperes
167 */
168 TorqueCurrentFOC(units::current::ampere_t Output) : TorqueCurrentFOC{Output, 1.0, 0.0_A, false}
169 {}
170
171 /**
172 * \brief Modifies this Control Request's Output parameter and returns itself for
173 * method-chaining and easier to use request API.
174 * \param newOutput Parameter to modify
175 * \returns Itself
176 */
177 TorqueCurrentFOC& WithOutput(units::current::ampere_t newOutput)
178 {
179 Output = newOutput;
180 return *this;
181 }
182
183 /**
184 * \brief Modifies this Control Request's MaxAbsDutyCycle parameter and returns itself for
185 * method-chaining and easier to use request API.
186 * \param newMaxAbsDutyCycle Parameter to modify
187 * \returns Itself
188 */
189 TorqueCurrentFOC& WithMaxAbsDutyCycle(units::dimensionless::scalar_t newMaxAbsDutyCycle)
190 {
191 MaxAbsDutyCycle = 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 * \param newDeadband Parameter to modify
199 * \returns Itself
200 */
201 TorqueCurrentFOC& WithDeadband(units::current::ampere_t newDeadband)
202 {
203 Deadband = newDeadband;
204 return *this;
205 }
206
207 /**
208 * \brief Modifies this Control Request's OverrideCoastDurNeutral parameter and returns itself for
209 * method-chaining and easier to use request API.
210 * \param newOverrideCoastDurNeutral Parameter to modify
211 * \returns Itself
212 */
213 TorqueCurrentFOC& WithOverrideCoastDurNeutral(bool newOverrideCoastDurNeutral)
214 {
215 OverrideCoastDurNeutral = newOverrideCoastDurNeutral;
216 return *this;
217 }
218 /**
219 * \brief Sets the period at which this control will update at.
220 * This is designated in Hertz, with a minimum of 20 Hz
221 * (every 50 ms) and a maximum of 1000 Hz (every 1 ms).
222 *
223 * If this field is set to 0 Hz, the control request will
224 * be sent immediately as a one-shot frame. This may be useful
225 * for advanced applications that require outputs to be
226 * synchronized with data acquisition. In this case, we
227 * recommend not exceeding 50 ms between control calls.
228 *
229 * \param newUpdateFreqHz Parameter to modify
230 * \returns Itself
231 */
232 TorqueCurrentFOC &WithUpdateFreqHz(units::frequency::hertz_t newUpdateFreqHz)
233 {
234 UpdateFreqHz = newUpdateFreqHz;
235 return *this;
236 }
237 /**
238 * Returns a string representation of the object.
239 *
240 * \returns a string representation of the object.
241 */
242 std::string ToString() const
243 {
244 std::stringstream ss;
245 ss << "class: TorqueCurrentFOC" << std::endl;
246 ss << "Output: " << Output.to<double>() << std::endl;
247 ss << "MaxAbsDutyCycle: " << MaxAbsDutyCycle.to<double>() << std::endl;
248 ss << "Deadband: " << Deadband.to<double>() << std::endl;
249 ss << "OverrideCoastDurNeutral: " << OverrideCoastDurNeutral << std::endl;
250 return ss.str();
251 }
252
253 /**
254 * \brief Forces configs to be applied the next time this is used in a setControl.
255 * This is not necessary in the majority of cases, because Phoenix will make sure configs are
256 * properly set when they are not already set
257 */
258 void ForceApplyConfigs() { ApplyConfigsOnRequest = true; }
259};
260
261}
262}
263}
264
CTREXPORT int c_ctre_phoenixpro_RequestControlTorqueCurrentFOC(const char *canbus, uint32_t ecuEncoding, double updateTime, bool cancelOtherRequests, double Output, double MaxAbsDutyCycle, double Deadband, bool OverrideCoastDurNeutral)
CTREXPORT int c_ctre_phoenixpro_requestConfigApply(const char *canbus, uint32_t ecuEncoding, double timeoutSeconds, const char *str, uint32_t strlen, bool forceApply)
std::map< std::string, std::string > & GetNameValues()
Gets the map of control parameter names to the corresponding applied value.
Definition: ControlRequest.hpp:52
Abstract Control Request class that other control requests extend for use.
Definition: ControlRequest.hpp:65
ControlInfo requestReference
Definition: ControlRequest.hpp:70
Request a specified motor current (field oriented control).
Definition: TorqueCurrentFOC.hpp:31
units::time::second_t ConfigTimeout
The timeout when sending configs associated with this control.
Definition: TorqueCurrentFOC.hpp:99
units::dimensionless::scalar_t MaxAbsDutyCycle
The maximum absolute motor output that can be applied, which effectively limits the velocity.
Definition: TorqueCurrentFOC.hpp:76
units::current::ampere_t Output
Amount of motor current in Amperes.
Definition: TorqueCurrentFOC.hpp:67
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:177
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
std::string ToString() const
Returns a string representation of the object.
Definition: TorqueCurrentFOC.hpp:242
TorqueCurrentFOC(units::current::ampere_t Output)
Request a specified motor current (field oriented control).
Definition: TorqueCurrentFOC.hpp:168
bool OverrideCoastDurNeutral
Set to true to coast the rotor when output is zero (or within deadband).
Definition: TorqueCurrentFOC.hpp:92
TorqueCurrentFOC & WithOverrideCoastDurNeutral(bool newOverrideCoastDurNeutral)
Modifies this Control Request's OverrideCoastDurNeutral parameter and returns itself for method-chain...
Definition: TorqueCurrentFOC.hpp:213
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:201
units::current::ampere_t Deadband
Deadband in Amperes.
Definition: TorqueCurrentFOC.hpp:85
void ForceApplyConfigs()
Forces configs to be applied the next time this is used in a setControl.
Definition: TorqueCurrentFOC.hpp:258
TorqueCurrentFOC(units::current::ampere_t Output, units::dimensionless::scalar_t MaxAbsDutyCycle, units::current::ampere_t Deadband, bool OverrideCoastDurNeutral)
Request a specified motor current (field oriented control).
Definition: TorqueCurrentFOC.hpp:150
units::frequency::hertz_t UpdateFreqHz
The period at which this control will update at.
Definition: TorqueCurrentFOC.hpp:112
TorqueCurrentFOC & WithUpdateFreqHz(units::frequency::hertz_t newUpdateFreqHz)
Sets the period at which this control will update at.
Definition: TorqueCurrentFOC.hpp:232
Definition: string_util.hpp:14