Loading [MathJax]/extensions/tex2jax.js
CTRE Phoenix 6 C++ 23.10.0-alpha-8
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
DynamicMotionMagicDutyCycle.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/angle.h>
14#include <units/angular_velocity.h>
15#include <units/angular_acceleration.h>
16#include <units/dimensionless.h>
17#include <units/frequency.h>
18#include <units/time.h>
19
20
21namespace ctre {
22namespace phoenix6 {
23namespace controls {
24
25/**
26 * Requires Phoenix Pro and CANivore;
27 * Requests Motion Magic® to target a final position using a motion profile.
28 * This dynamic request allows runtime changes to Cruise Velocity, Acceleration,
29 * and Jerk. Users can optionally provide a duty cycle feedforward. This
30 * control requires use of a CANivore.
31 *
32 * Motion Magic® produces a motion profile in real-time while attempting to honor the specified Cruise
33 * Velocity, Acceleration, and Jerk value. Target position can be changed on-the-fly and Motion Magic® will
34 * do its best to adjust the profile. This control mode is duty cycle based, so relevant closed-loop gains
35 * will use fractional duty cycle for the numerator: +1.0 represents full forward output.
36 */
38{
39 bool ApplyConfigsOnRequest{false};
40
41 ctre::phoenix::StatusCode SendRequest(const char *network, uint32_t deviceHash, bool cancelOtherRequests, std::shared_ptr<ControlRequest> &req) override
42 {
43 if (req.get() != this)
44 {
45 auto const reqCast = dynamic_cast<DynamicMotionMagicDutyCycle *>(req.get());
46 if (reqCast != nullptr)
47 {
48 *reqCast = *this;
49 }
50 else
51 {
52 req = std::make_shared<DynamicMotionMagicDutyCycle>(*this);
53 }
54 }
55
56 std::stringstream ss;
57
58 std::string strs{ss.str()};
59 c_ctre_phoenix6_requestConfigApply(network, deviceHash, ConfigTimeout.to<double>(), strs.c_str(), strs.length(), ApplyConfigsOnRequest);
60 ApplyConfigsOnRequest = false;
61 return c_ctre_phoenix6_RequestControlDynamicMotionMagicDutyCycle(network, deviceHash, UpdateFreqHz.to<double>(), cancelOtherRequests, Position.to<double>(), Velocity.to<double>(), Acceleration.to<double>(), Jerk.to<double>(), EnableFOC, FeedForward.to<double>(), Slot, OverrideBrakeDurNeutral);
62 }
63
64public:
65 /**
66 * Position to drive toward in rotations.
67 */
68 units::angle::turn_t Position;
69 /**
70 * Cruise velocity for profiling. The signage does not matter as the device
71 * will use the absolute value for profile generation.
72 */
73 units::angular_velocity::turns_per_second_t Velocity;
74 /**
75 * Acceleration for profiling. The signage does not matter as the device will
76 * use the absolute value for profile generation
77 */
78 units::angular_acceleration::turns_per_second_squared_t Acceleration;
79 /**
80 * Jerk for profiling. The signage does not matter as the device will use the
81 * absolute value for profile generation
82 */
83 units::dimensionless::scalar_t Jerk;
84 /**
85 * Set to true to use FOC commutation (requires Phoenix Pro), which increases
86 * peak power by ~15%. Set to false to use trapezoidal commutation. FOC
87 * improves motor performance by leveraging torque (current) control. However,
88 * this may be inconvenient for applications that require specifying duty cycle
89 * or voltage. CTR-Electronics has developed a hybrid method that combines the
90 * performances gains of FOC while still allowing applications to provide duty
91 * cycle or voltage demand. This not to be confused with simple sinusoidal
92 * control or phase voltage control which lacks the performance gains.
93 */
95 /**
96 * Feedforward to apply in fractional units between -1 and +1.
97 */
98 units::dimensionless::scalar_t FeedForward;
99 /**
100 * Select which gains are applied by selecting the slot. Use the configuration
101 * api to set the gain values for the selected slot before enabling this
102 * feature. Slot must be within [0,2].
103 */
104 int Slot;
105 /**
106 * Set to true to static-brake the rotor when output is zero (or within
107 * deadband). Set to false to use the NeutralMode configuration setting
108 * (default). This flag exists to provide the fundamental behavior of this
109 * control when output is zero, which is to provide 0V to the motor.
110 */
112
113
114
115 /**
116 * \brief The timeout when sending configs associated with this control
117 */
118 units::time::second_t ConfigTimeout{0.1_s};
119
120 /**
121 * \brief The period at which this control will update at.
122 * This is designated in Hertz, with a minimum of 20 Hz
123 * (every 50 ms) and a maximum of 1000 Hz (every 1 ms).
124 *
125 * If this field is set to 0 Hz, the control request will
126 * be sent immediately as a one-shot frame. This may be useful
127 * for advanced applications that require outputs to be
128 * synchronized with data acquisition. In this case, we
129 * recommend not exceeding 50 ms between control calls.
130 */
131 units::frequency::hertz_t UpdateFreqHz{100_Hz}; // Default to 100_Hz
132
133 /**
134 * \brief Requires Phoenix Pro and CANivore;
135 * Requests Motion Magic® to target a
136 * final position using a motion profile. This dynamic request allows
137 * runtime changes to Cruise Velocity, Acceleration, and Jerk. Users can
138 * optionally provide a duty cycle feedforward. This control requires
139 * use of a CANivore.
140 *
141 * \details Motion Magic® produces a motion profile in real-time while
142 * attempting to honor the specified Cruise Velocity, Acceleration, and
143 * Jerk value. Target position can be changed on-the-fly and Motion
144 * Magic® will do its best to adjust the profile. This control mode is
145 * duty cycle based, so relevant closed-loop gains will use fractional
146 * duty cycle for the numerator: +1.0 represents full forward output.
147 *
148 * \param Position Position to drive toward in rotations.
149 * \param Velocity Cruise velocity for profiling. The signage does not
150 * matter as the device will use the absolute value for
151 * profile generation.
152 * \param Acceleration Acceleration for profiling. The signage does not
153 * matter as the device will use the absolute value for
154 * profile generation
155 * \param Jerk Jerk for profiling. The signage does not matter as the device
156 * will use the absolute value for profile generation
157 * \param EnableFOC Set to true to use FOC commutation (requires Phoenix
158 * Pro), which increases peak power by ~15%. Set to false to
159 * use trapezoidal commutation. FOC improves motor
160 * performance by leveraging torque (current) control.
161 * However, this may be inconvenient for applications that
162 * require specifying duty cycle or voltage.
163 * CTR-Electronics has developed a hybrid method that
164 * combines the performances gains of FOC while still
165 * allowing applications to provide duty cycle or voltage
166 * demand. This not to be confused with simple sinusoidal
167 * control or phase voltage control which lacks the
168 * performance gains.
169 * \param FeedForward Feedforward to apply in fractional units between -1 and
170 * +1.
171 * \param Slot Select which gains are applied by selecting the slot. Use the
172 * configuration api to set the gain values for the selected slot
173 * before enabling this feature. Slot must be within [0,2].
174 * \param OverrideBrakeDurNeutral Set to true to static-brake the rotor when
175 * output is zero (or within deadband). Set
176 * to false to use the NeutralMode
177 * configuration setting (default). This flag
178 * exists to provide the fundamental behavior
179 * of this control when output is zero, which
180 * is to provide 0V to the motor.
181 */
182 DynamicMotionMagicDutyCycle(units::angle::turn_t Position, units::angular_velocity::turns_per_second_t Velocity, units::angular_acceleration::turns_per_second_squared_t Acceleration, units::dimensionless::scalar_t Jerk, bool EnableFOC, units::dimensionless::scalar_t FeedForward, int Slot, bool OverrideBrakeDurNeutral) : ControlRequest{"DynamicMotionMagicDutyCycle"},
183 Position{std::move(Position)},
184 Velocity{std::move(Velocity)},
185 Acceleration{std::move(Acceleration)},
186 Jerk{std::move(Jerk)},
187 EnableFOC{std::move(EnableFOC)},
188 FeedForward{std::move(FeedForward)},
189 Slot{std::move(Slot)},
191 {}
192
193 /**
194 * \brief Requires Phoenix Pro and CANivore;
195 * Requests Motion Magic® to target a
196 * final position using a motion profile. This dynamic request allows
197 * runtime changes to Cruise Velocity, Acceleration, and Jerk. Users can
198 * optionally provide a duty cycle feedforward. This control requires
199 * use of a CANivore.
200 *
201 * \details Motion Magic® produces a motion profile in real-time while
202 * attempting to honor the specified Cruise Velocity, Acceleration, and
203 * Jerk value. Target position can be changed on-the-fly and Motion
204 * Magic® will do its best to adjust the profile. This control mode is
205 * duty cycle based, so relevant closed-loop gains will use fractional
206 * duty cycle for the numerator: +1.0 represents full forward output.
207 *
208 * \param Position Position to drive toward in rotations.
209 * \param Velocity Cruise velocity for profiling. The signage does not
210 * matter as the device will use the absolute value for
211 * profile generation.
212 * \param Acceleration Acceleration for profiling. The signage does not
213 * matter as the device will use the absolute value for
214 * profile generation
215 * \param Jerk Jerk for profiling. The signage does not matter as the device
216 * will use the absolute value for profile generation
217 */
218 DynamicMotionMagicDutyCycle(units::angle::turn_t Position, units::angular_velocity::turns_per_second_t Velocity, units::angular_acceleration::turns_per_second_squared_t Acceleration, units::dimensionless::scalar_t Jerk) : DynamicMotionMagicDutyCycle{Position, Velocity, Acceleration, Jerk, true, 0.0, 0, false}
219 {}
220
221 /**
222 * \brief Modifies this Control Request's Position parameter and returns itself for
223 * method-chaining and easier to use request API.
224 * \param newPosition Parameter to modify
225 * \returns Itself
226 */
227 DynamicMotionMagicDutyCycle& WithPosition(units::angle::turn_t newPosition)
228 {
229 Position = std::move(newPosition);
230 return *this;
231 }
232
233 /**
234 * \brief Modifies this Control Request's Velocity parameter and returns itself for
235 * method-chaining and easier to use request API.
236 * \param newVelocity Parameter to modify
237 * \returns Itself
238 */
239 DynamicMotionMagicDutyCycle& WithVelocity(units::angular_velocity::turns_per_second_t newVelocity)
240 {
241 Velocity = std::move(newVelocity);
242 return *this;
243 }
244
245 /**
246 * \brief Modifies this Control Request's Acceleration parameter and returns itself for
247 * method-chaining and easier to use request API.
248 * \param newAcceleration Parameter to modify
249 * \returns Itself
250 */
251 DynamicMotionMagicDutyCycle& WithAcceleration(units::angular_acceleration::turns_per_second_squared_t newAcceleration)
252 {
253 Acceleration = std::move(newAcceleration);
254 return *this;
255 }
256
257 /**
258 * \brief Modifies this Control Request's Jerk parameter and returns itself for
259 * method-chaining and easier to use request API.
260 * \param newJerk Parameter to modify
261 * \returns Itself
262 */
263 DynamicMotionMagicDutyCycle& WithJerk(units::dimensionless::scalar_t newJerk)
264 {
265 Jerk = std::move(newJerk);
266 return *this;
267 }
268
269 /**
270 * \brief Modifies this Control Request's EnableFOC parameter and returns itself for
271 * method-chaining and easier to use request API.
272 * \param newEnableFOC Parameter to modify
273 * \returns Itself
274 */
276 {
277 EnableFOC = std::move(newEnableFOC);
278 return *this;
279 }
280
281 /**
282 * \brief Modifies this Control Request's FeedForward parameter and returns itself for
283 * method-chaining and easier to use request API.
284 * \param newFeedForward Parameter to modify
285 * \returns Itself
286 */
287 DynamicMotionMagicDutyCycle& WithFeedForward(units::dimensionless::scalar_t newFeedForward)
288 {
289 FeedForward = std::move(newFeedForward);
290 return *this;
291 }
292
293 /**
294 * \brief Modifies this Control Request's Slot parameter and returns itself for
295 * method-chaining and easier to use request API.
296 * \param newSlot Parameter to modify
297 * \returns Itself
298 */
300 {
301 Slot = std::move(newSlot);
302 return *this;
303 }
304
305 /**
306 * \brief Modifies this Control Request's OverrideBrakeDurNeutral parameter and returns itself for
307 * method-chaining and easier to use request API.
308 * \param newOverrideBrakeDurNeutral Parameter to modify
309 * \returns Itself
310 */
312 {
313 OverrideBrakeDurNeutral = std::move(newOverrideBrakeDurNeutral);
314 return *this;
315 }
316 /**
317 * \brief Sets the period at which this control will update at.
318 * This is designated in Hertz, with a minimum of 20 Hz
319 * (every 50 ms) and a maximum of 1000 Hz (every 1 ms).
320 *
321 * If this field is set to 0 Hz, the control request will
322 * be sent immediately as a one-shot frame. This may be useful
323 * for advanced applications that require outputs to be
324 * synchronized with data acquisition. In this case, we
325 * recommend not exceeding 50 ms between control calls.
326 *
327 * \param newUpdateFreqHz Parameter to modify
328 * \returns Itself
329 */
330 DynamicMotionMagicDutyCycle &WithUpdateFreqHz(units::frequency::hertz_t newUpdateFreqHz)
331 {
332 UpdateFreqHz = newUpdateFreqHz;
333 return *this;
334 }
335 /**
336 * Returns a string representation of the object.
337 *
338 * \returns a string representation of the object.
339 */
340 std::string ToString() const override
341 {
342 std::stringstream ss;
343 ss << "class: DynamicMotionMagicDutyCycle" << std::endl;
344 ss << "Position: " << Position.to<double>() << std::endl;
345 ss << "Velocity: " << Velocity.to<double>() << std::endl;
346 ss << "Acceleration: " << Acceleration.to<double>() << std::endl;
347 ss << "Jerk: " << Jerk.to<double>() << std::endl;
348 ss << "EnableFOC: " << EnableFOC << std::endl;
349 ss << "FeedForward: " << FeedForward.to<double>() << std::endl;
350 ss << "Slot: " << Slot << std::endl;
351 ss << "OverrideBrakeDurNeutral: " << OverrideBrakeDurNeutral << std::endl;
352 return ss.str();
353 }
354
355 /**
356 * \brief Forces configs to be applied the next time this is used in a setControl.
357 * This is not necessary in the majority of cases, because Phoenix will make sure configs are
358 * properly set when they are not already set
359 */
360 void ForceApplyConfigs() { ApplyConfigsOnRequest = true; }
361
362 /**
363 * \brief Gets information about this control request.
364 *
365 * \returns Map of control parameter names and corresponding applied values
366 */
367 std::map<std::string, std::string> GetControlInfo() const override
368 {
369 std::map<std::string, std::string> controlInfo;
370 std::stringstream ss;
371 controlInfo["Name"] = GetName();
372 ss << Position.to<double>(); controlInfo["Position"] = ss.str(); ss.str(std::string{});
373 ss << Velocity.to<double>(); controlInfo["Velocity"] = ss.str(); ss.str(std::string{});
374 ss << Acceleration.to<double>(); controlInfo["Acceleration"] = ss.str(); ss.str(std::string{});
375 ss << Jerk.to<double>(); controlInfo["Jerk"] = ss.str(); ss.str(std::string{});
376 ss << EnableFOC; controlInfo["EnableFOC"] = ss.str(); ss.str(std::string{});
377 ss << FeedForward.to<double>(); controlInfo["FeedForward"] = ss.str(); ss.str(std::string{});
378 ss << Slot; controlInfo["Slot"] = ss.str(); ss.str(std::string{});
379 ss << OverrideBrakeDurNeutral; controlInfo["OverrideBrakeDurNeutral"] = ss.str(); ss.str(std::string{});
380 return controlInfo;
381 }
382};
383
384}
385}
386}
387
CTREXPORT int c_ctre_phoenix6_requestConfigApply(const char *canbus, uint32_t ecuEncoding, double timeoutSeconds, const char *str, uint32_t strlen, bool forceApply)
CTREXPORT int c_ctre_phoenix6_RequestControlDynamicMotionMagicDutyCycle(const char *canbus, uint32_t ecuEncoding, double updateTime, bool cancelOtherRequests, double Position, double Velocity, double Acceleration, double Jerk, bool EnableFOC, double FeedForward, int Slot, bool OverrideBrakeDurNeutral)
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 and CANivore; Requests Motion Magic® to target a final position using a motion p...
Definition: DynamicMotionMagicDutyCycle.hpp:38
std::string ToString() const override
Returns a string representation of the object.
Definition: DynamicMotionMagicDutyCycle.hpp:340
units::angular_velocity::turns_per_second_t Velocity
Cruise velocity for profiling.
Definition: DynamicMotionMagicDutyCycle.hpp:73
units::angular_acceleration::turns_per_second_squared_t Acceleration
Acceleration for profiling.
Definition: DynamicMotionMagicDutyCycle.hpp:78
units::time::second_t ConfigTimeout
The timeout when sending configs associated with this control.
Definition: DynamicMotionMagicDutyCycle.hpp:118
bool OverrideBrakeDurNeutral
Set to true to static-brake the rotor when output is zero (or within deadband).
Definition: DynamicMotionMagicDutyCycle.hpp:111
units::frequency::hertz_t UpdateFreqHz
The period at which this control will update at.
Definition: DynamicMotionMagicDutyCycle.hpp:131
bool EnableFOC
Set to true to use FOC commutation (requires Phoenix Pro), which increases peak power by ~15%.
Definition: DynamicMotionMagicDutyCycle.hpp:94
DynamicMotionMagicDutyCycle & WithVelocity(units::angular_velocity::turns_per_second_t newVelocity)
Modifies this Control Request's Velocity parameter and returns itself for method-chaining and easier ...
Definition: DynamicMotionMagicDutyCycle.hpp:239
DynamicMotionMagicDutyCycle & WithSlot(int newSlot)
Modifies this Control Request's Slot parameter and returns itself for method-chaining and easier to u...
Definition: DynamicMotionMagicDutyCycle.hpp:299
DynamicMotionMagicDutyCycle & WithAcceleration(units::angular_acceleration::turns_per_second_squared_t newAcceleration)
Modifies this Control Request's Acceleration parameter and returns itself for method-chaining and eas...
Definition: DynamicMotionMagicDutyCycle.hpp:251
DynamicMotionMagicDutyCycle & WithUpdateFreqHz(units::frequency::hertz_t newUpdateFreqHz)
Sets the period at which this control will update at.
Definition: DynamicMotionMagicDutyCycle.hpp:330
DynamicMotionMagicDutyCycle(units::angle::turn_t Position, units::angular_velocity::turns_per_second_t Velocity, units::angular_acceleration::turns_per_second_squared_t Acceleration, units::dimensionless::scalar_t Jerk, bool EnableFOC, units::dimensionless::scalar_t FeedForward, int Slot, bool OverrideBrakeDurNeutral)
Requires Phoenix Pro and CANivore; Requests Motion Magic® to target a final position using a motion p...
Definition: DynamicMotionMagicDutyCycle.hpp:182
DynamicMotionMagicDutyCycle & WithOverrideBrakeDurNeutral(bool newOverrideBrakeDurNeutral)
Modifies this Control Request's OverrideBrakeDurNeutral parameter and returns itself for method-chain...
Definition: DynamicMotionMagicDutyCycle.hpp:311
DynamicMotionMagicDutyCycle & WithEnableFOC(bool newEnableFOC)
Modifies this Control Request's EnableFOC parameter and returns itself for method-chaining and easier...
Definition: DynamicMotionMagicDutyCycle.hpp:275
std::map< std::string, std::string > GetControlInfo() const override
Gets information about this control request.
Definition: DynamicMotionMagicDutyCycle.hpp:367
DynamicMotionMagicDutyCycle & WithFeedForward(units::dimensionless::scalar_t newFeedForward)
Modifies this Control Request's FeedForward parameter and returns itself for method-chaining and easi...
Definition: DynamicMotionMagicDutyCycle.hpp:287
DynamicMotionMagicDutyCycle(units::angle::turn_t Position, units::angular_velocity::turns_per_second_t Velocity, units::angular_acceleration::turns_per_second_squared_t Acceleration, units::dimensionless::scalar_t Jerk)
Requires Phoenix Pro and CANivore; Requests Motion Magic® to target a final position using a motion p...
Definition: DynamicMotionMagicDutyCycle.hpp:218
DynamicMotionMagicDutyCycle & WithJerk(units::dimensionless::scalar_t newJerk)
Modifies this Control Request's Jerk parameter and returns itself for method-chaining and easier to u...
Definition: DynamicMotionMagicDutyCycle.hpp:263
units::angle::turn_t Position
Position to drive toward in rotations.
Definition: DynamicMotionMagicDutyCycle.hpp:68
int Slot
Select which gains are applied by selecting the slot.
Definition: DynamicMotionMagicDutyCycle.hpp:104
DynamicMotionMagicDutyCycle & WithPosition(units::angle::turn_t newPosition)
Modifies this Control Request's Position parameter and returns itself for method-chaining and easier ...
Definition: DynamicMotionMagicDutyCycle.hpp:227
void ForceApplyConfigs()
Forces configs to be applied the next time this is used in a setControl.
Definition: DynamicMotionMagicDutyCycle.hpp:360
units::dimensionless::scalar_t FeedForward
Feedforward to apply in fractional units between -1 and +1.
Definition: DynamicMotionMagicDutyCycle.hpp:98
units::dimensionless::scalar_t Jerk
Jerk for profiling.
Definition: DynamicMotionMagicDutyCycle.hpp:83
Definition: ManualEvent.hpp:12