CTRE Phoenix 6 C++ 24.3.0
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/angular_jerk.h>
17#include <units/dimensionless.h>
18#include <units/frequency.h>
19#include <units/time.h>
20
21
22namespace ctre {
23namespace phoenix6 {
24namespace controls {
25
26/**
27 * Requires Phoenix Pro and CANivore;
28 * Requests Motion Magic® to target a final position using a motion profile.
29 * This dynamic request allows runtime changes to Cruise Velocity, Acceleration,
30 * and Jerk. Users can optionally provide a duty cycle feedforward. This
31 * control requires use of a CANivore.
32 *
33 * Motion Magic® produces a motion profile in real-time while attempting to honor the specified Cruise
34 * Velocity, Acceleration, and Jerk value. This control mode does not use the Expo_kV or Expo_kA configs.
35 * Target position can be changed on-the-fly and Motion Magic® will do its best to adjust the profile. This
36 * control mode is duty cycle based, so relevant closed-loop gains will use fractional duty cycle for the
37 * numerator: +1.0 represents full forward output.
38 */
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 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, LimitForwardMotion, LimitReverseMotion);
57 }
58
59public:
60 /**
61 * Position to drive toward in rotations.
62 */
63 units::angle::turn_t Position;
64 /**
65 * Cruise velocity for profiling. The signage does not matter as the device
66 * will use the absolute value for profile generation.
67 */
68 units::angular_velocity::turns_per_second_t Velocity;
69 /**
70 * Acceleration for profiling. The signage does not matter as the device will
71 * use the absolute value for profile generation
72 */
73 units::angular_acceleration::turns_per_second_squared_t Acceleration;
74 /**
75 * Jerk for profiling. The signage does not matter as the device will use the
76 * absolute value for profile generation
77 */
78 units::angular_jerk::turns_per_second_cubed_t Jerk;
79 /**
80 * Set to true to use FOC commutation (requires Phoenix Pro), which increases
81 * peak power by ~15%. Set to false to use trapezoidal commutation.
82 *
83 * FOC improves motor performance by leveraging torque (current) control.
84 * However, this may be inconvenient for applications that require specifying
85 * duty cycle or voltage. CTR-Electronics has developed a hybrid method that
86 * combines the performances gains of FOC while still allowing applications to
87 * provide duty cycle or voltage demand. This not to be confused with simple
88 * sinusoidal control or phase voltage control which lacks the performance
89 * gains.
90 */
92 /**
93 * Feedforward to apply in fractional units between -1 and +1.
94 */
95 units::dimensionless::scalar_t FeedForward;
96 /**
97 * Select which gains are applied by selecting the slot. Use the configuration
98 * api to set the gain values for the selected slot before enabling this
99 * feature. Slot must be within [0,2].
100 */
101 int Slot;
102 /**
103 * Set to true to static-brake the rotor when output is zero (or within
104 * deadband). Set to false to use the NeutralMode configuration setting
105 * (default). This flag exists to provide the fundamental behavior of this
106 * control when output is zero, which is to provide 0V to the motor.
107 */
109 /**
110 * Set to true to force forward limiting. This allows users to use other limit
111 * switch sensors connected to robot controller. This also allows use of active
112 * sensors that require external power.
113 */
115 /**
116 * Set to true to force reverse limiting. This allows users to use other limit
117 * switch sensors connected to robot controller. This also allows use of active
118 * sensors that require external power.
119 */
121
122 /**
123 * \brief The period at which this control will update at.
124 * This is designated in Hertz, with a minimum of 20 Hz
125 * (every 50 ms) and a maximum of 1000 Hz (every 1 ms).
126 *
127 * If this field is set to 0 Hz, the control request will
128 * be sent immediately as a one-shot frame. This may be useful
129 * for advanced applications that require outputs to be
130 * synchronized with data acquisition. In this case, we
131 * recommend not exceeding 50 ms between control calls.
132 */
133 units::frequency::hertz_t UpdateFreqHz{100_Hz}; // Default to 100_Hz
134
135 /**
136 * \brief Requires Phoenix Pro and CANivore;
137 * Requests Motion Magic® to target a final position using a motion
138 * profile. This dynamic request allows runtime changes to Cruise
139 * Velocity, Acceleration, and Jerk. Users can optionally provide a duty
140 * cycle feedforward. This control requires use of a CANivore.
141 *
142 * \details Motion Magic® produces a motion profile in real-time while
143 * attempting to honor the specified Cruise Velocity, Acceleration, and
144 * Jerk value. This control mode does not use the Expo_kV or Expo_kA
145 * configs. Target position can be changed on-the-fly and Motion
146 * Magic® will do its best to adjust the profile. This control mode is
147 * duty cycle based, so relevant closed-loop gains will use fractional
148 * duty cycle for the numerator: +1.0 represents full forward output.
149 *
150 * \param Position Position to drive toward in rotations.
151 * \param Velocity Cruise velocity for profiling. The signage does not
152 * matter as the device will use the absolute value for
153 * profile generation.
154 * \param Acceleration Acceleration for profiling. The signage does not
155 * matter as the device will use the absolute value for
156 * profile generation
157 * \param Jerk Jerk for profiling. The signage does not matter as the device
158 * will use the absolute value for profile generation
159 * \param EnableFOC Set to true to use FOC commutation (requires Phoenix
160 * Pro), which increases peak power by ~15%. Set to false to
161 * use trapezoidal commutation.
162 *
163 * FOC improves motor performance by leveraging torque
164 * (current) control. However, this may be inconvenient for
165 * applications that require specifying duty cycle or
166 * voltage. CTR-Electronics has developed a hybrid method
167 * that combines the performances gains of FOC while still
168 * allowing applications to provide duty cycle or voltage
169 * demand. This not to be confused with simple sinusoidal
170 * control or phase voltage control which lacks the
171 * performance gains.
172 * \param FeedForward Feedforward to apply in fractional units between -1 and
173 * +1.
174 * \param Slot Select which gains are applied by selecting the slot. Use the
175 * configuration api to set the gain values for the selected slot
176 * before enabling this feature. Slot must be within [0,2].
177 * \param OverrideBrakeDurNeutral Set to true to static-brake the rotor when
178 * output is zero (or within deadband). Set
179 * to false to use the NeutralMode
180 * configuration setting (default). This flag
181 * exists to provide the fundamental behavior
182 * of this control when output is zero, which
183 * is to provide 0V to the motor.
184 * \param LimitForwardMotion Set to true to force forward limiting. This
185 * allows users to use other limit switch sensors
186 * connected to robot controller. This also allows
187 * use of active sensors that require external
188 * power.
189 * \param LimitReverseMotion Set to true to force reverse limiting. This
190 * allows users to use other limit switch sensors
191 * connected to robot controller. This also allows
192 * use of active sensors that require external
193 * power.
194 */
195 DynamicMotionMagicDutyCycle(units::angle::turn_t Position, units::angular_velocity::turns_per_second_t Velocity, units::angular_acceleration::turns_per_second_squared_t Acceleration, units::angular_jerk::turns_per_second_cubed_t Jerk, bool EnableFOC = true, units::dimensionless::scalar_t FeedForward = 0.0, int Slot = 0, bool OverrideBrakeDurNeutral = false, bool LimitForwardMotion = false, bool LimitReverseMotion = false) : ControlRequest{"DynamicMotionMagicDutyCycle"},
196 Position{std::move(Position)},
197 Velocity{std::move(Velocity)},
198 Acceleration{std::move(Acceleration)},
199 Jerk{std::move(Jerk)},
200 EnableFOC{std::move(EnableFOC)},
201 FeedForward{std::move(FeedForward)},
202 Slot{std::move(Slot)},
206 {}
207
208 /**
209 * \brief Modifies this Control Request's Position parameter and returns itself for
210 * method-chaining and easier to use request API.
211 *
212 * Position to drive toward in rotations.
213 *
214 * \param newPosition Parameter to modify
215 * \returns Itself
216 */
217 DynamicMotionMagicDutyCycle& WithPosition(units::angle::turn_t newPosition)
218 {
219 Position = std::move(newPosition);
220 return *this;
221 }
222
223 /**
224 * \brief Modifies this Control Request's Velocity parameter and returns itself for
225 * method-chaining and easier to use request API.
226 *
227 * Cruise velocity for profiling. The signage does not matter as the device
228 * will use the absolute value for profile generation.
229 *
230 * \param newVelocity Parameter to modify
231 * \returns Itself
232 */
233 DynamicMotionMagicDutyCycle& WithVelocity(units::angular_velocity::turns_per_second_t newVelocity)
234 {
235 Velocity = std::move(newVelocity);
236 return *this;
237 }
238
239 /**
240 * \brief Modifies this Control Request's Acceleration parameter and returns itself for
241 * method-chaining and easier to use request API.
242 *
243 * Acceleration for profiling. The signage does not matter as the device will
244 * use the absolute value for profile generation
245 *
246 * \param newAcceleration Parameter to modify
247 * \returns Itself
248 */
249 DynamicMotionMagicDutyCycle& WithAcceleration(units::angular_acceleration::turns_per_second_squared_t newAcceleration)
250 {
251 Acceleration = std::move(newAcceleration);
252 return *this;
253 }
254
255 /**
256 * \brief Modifies this Control Request's Jerk parameter and returns itself for
257 * method-chaining and easier to use request API.
258 *
259 * Jerk for profiling. The signage does not matter as the device will use the
260 * absolute value for profile generation
261 *
262 * \param newJerk Parameter to modify
263 * \returns Itself
264 */
265 DynamicMotionMagicDutyCycle& WithJerk(units::angular_jerk::turns_per_second_cubed_t newJerk)
266 {
267 Jerk = std::move(newJerk);
268 return *this;
269 }
270
271 /**
272 * \brief Modifies this Control Request's EnableFOC parameter and returns itself for
273 * method-chaining and easier to use request API.
274 *
275 * Set to true to use FOC commutation (requires Phoenix Pro), which increases
276 * peak power by ~15%. Set to false to use trapezoidal commutation.
277 *
278 * FOC improves motor performance by leveraging torque (current) control.
279 * However, this may be inconvenient for applications that require specifying
280 * duty cycle or voltage. CTR-Electronics has developed a hybrid method that
281 * combines the performances gains of FOC while still allowing applications to
282 * provide duty cycle or voltage demand. This not to be confused with simple
283 * sinusoidal control or phase voltage control which lacks the performance
284 * gains.
285 *
286 * \param newEnableFOC Parameter to modify
287 * \returns Itself
288 */
290 {
291 EnableFOC = std::move(newEnableFOC);
292 return *this;
293 }
294
295 /**
296 * \brief Modifies this Control Request's FeedForward parameter and returns itself for
297 * method-chaining and easier to use request API.
298 *
299 * Feedforward to apply in fractional units between -1 and +1.
300 *
301 * \param newFeedForward Parameter to modify
302 * \returns Itself
303 */
304 DynamicMotionMagicDutyCycle& WithFeedForward(units::dimensionless::scalar_t newFeedForward)
305 {
306 FeedForward = std::move(newFeedForward);
307 return *this;
308 }
309
310 /**
311 * \brief Modifies this Control Request's Slot parameter and returns itself for
312 * method-chaining and easier to use request API.
313 *
314 * Select which gains are applied by selecting the slot. Use the configuration
315 * api to set the gain values for the selected slot before enabling this
316 * feature. Slot must be within [0,2].
317 *
318 * \param newSlot Parameter to modify
319 * \returns Itself
320 */
322 {
323 Slot = std::move(newSlot);
324 return *this;
325 }
326
327 /**
328 * \brief Modifies this Control Request's OverrideBrakeDurNeutral parameter and returns itself for
329 * method-chaining and easier to use request API.
330 *
331 * Set to true to static-brake the rotor when output is zero (or within
332 * deadband). Set to false to use the NeutralMode configuration setting
333 * (default). This flag exists to provide the fundamental behavior of this
334 * control when output is zero, which is to provide 0V to the motor.
335 *
336 * \param newOverrideBrakeDurNeutral Parameter to modify
337 * \returns Itself
338 */
340 {
341 OverrideBrakeDurNeutral = std::move(newOverrideBrakeDurNeutral);
342 return *this;
343 }
344
345 /**
346 * \brief Modifies this Control Request's LimitForwardMotion parameter and returns itself for
347 * method-chaining and easier to use request API.
348 *
349 * Set to true to force forward limiting. This allows users to use other limit
350 * switch sensors connected to robot controller. This also allows use of active
351 * sensors that require external power.
352 *
353 * \param newLimitForwardMotion Parameter to modify
354 * \returns Itself
355 */
357 {
358 LimitForwardMotion = std::move(newLimitForwardMotion);
359 return *this;
360 }
361
362 /**
363 * \brief Modifies this Control Request's LimitReverseMotion parameter and returns itself for
364 * method-chaining and easier to use request API.
365 *
366 * Set to true to force reverse limiting. This allows users to use other limit
367 * switch sensors connected to robot controller. This also allows use of active
368 * sensors that require external power.
369 *
370 * \param newLimitReverseMotion Parameter to modify
371 * \returns Itself
372 */
374 {
375 LimitReverseMotion = std::move(newLimitReverseMotion);
376 return *this;
377 }
378 /**
379 * \brief Sets the period at which this control will update at.
380 * This is designated in Hertz, with a minimum of 20 Hz
381 * (every 50 ms) and a maximum of 1000 Hz (every 1 ms).
382 *
383 * If this field is set to 0 Hz, the control request will
384 * be sent immediately as a one-shot frame. This may be useful
385 * for advanced applications that require outputs to be
386 * synchronized with data acquisition. In this case, we
387 * recommend not exceeding 50 ms between control calls.
388 *
389 * \param newUpdateFreqHz Parameter to modify
390 * \returns Itself
391 */
392 DynamicMotionMagicDutyCycle &WithUpdateFreqHz(units::frequency::hertz_t newUpdateFreqHz)
393 {
394 UpdateFreqHz = newUpdateFreqHz;
395 return *this;
396 }
397 /**
398 * Returns a string representation of the object.
399 *
400 * \returns a string representation of the object.
401 */
402 std::string ToString() const override
403 {
404 std::stringstream ss;
405 ss << "class: DynamicMotionMagicDutyCycle" << std::endl;
406 ss << "Position: " << Position.to<double>() << std::endl;
407 ss << "Velocity: " << Velocity.to<double>() << std::endl;
408 ss << "Acceleration: " << Acceleration.to<double>() << std::endl;
409 ss << "Jerk: " << Jerk.to<double>() << std::endl;
410 ss << "EnableFOC: " << EnableFOC << std::endl;
411 ss << "FeedForward: " << FeedForward.to<double>() << std::endl;
412 ss << "Slot: " << Slot << std::endl;
413 ss << "OverrideBrakeDurNeutral: " << OverrideBrakeDurNeutral << std::endl;
414 ss << "LimitForwardMotion: " << LimitForwardMotion << std::endl;
415 ss << "LimitReverseMotion: " << LimitReverseMotion << std::endl;
416 return ss.str();
417 }
418
419 /**
420 * \brief Gets information about this control request.
421 *
422 * \returns Map of control parameter names and corresponding applied values
423 */
424 std::map<std::string, std::string> GetControlInfo() const override
425 {
426 std::map<std::string, std::string> controlInfo;
427 std::stringstream ss;
428 controlInfo["Name"] = GetName();
429 ss << Position.to<double>(); controlInfo["Position"] = ss.str(); ss.str(std::string{});
430 ss << Velocity.to<double>(); controlInfo["Velocity"] = ss.str(); ss.str(std::string{});
431 ss << Acceleration.to<double>(); controlInfo["Acceleration"] = ss.str(); ss.str(std::string{});
432 ss << Jerk.to<double>(); controlInfo["Jerk"] = ss.str(); ss.str(std::string{});
433 ss << EnableFOC; controlInfo["EnableFOC"] = ss.str(); ss.str(std::string{});
434 ss << FeedForward.to<double>(); controlInfo["FeedForward"] = ss.str(); ss.str(std::string{});
435 ss << Slot; controlInfo["Slot"] = ss.str(); ss.str(std::string{});
436 ss << OverrideBrakeDurNeutral; controlInfo["OverrideBrakeDurNeutral"] = ss.str(); ss.str(std::string{});
437 ss << LimitForwardMotion; controlInfo["LimitForwardMotion"] = ss.str(); ss.str(std::string{});
438 ss << LimitReverseMotion; controlInfo["LimitReverseMotion"] = ss.str(); ss.str(std::string{});
439 return controlInfo;
440 }
441};
442
443}
444}
445}
446
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, 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 and CANivore; Requests Motion Magic® to target a final position using a motion p...
Definition: DynamicMotionMagicDutyCycle.hpp:40
std::string ToString() const override
Returns a string representation of the object.
Definition: DynamicMotionMagicDutyCycle.hpp:402
units::angular_velocity::turns_per_second_t Velocity
Cruise velocity for profiling.
Definition: DynamicMotionMagicDutyCycle.hpp:68
units::angular_acceleration::turns_per_second_squared_t Acceleration
Acceleration for profiling.
Definition: DynamicMotionMagicDutyCycle.hpp:73
bool OverrideBrakeDurNeutral
Set to true to static-brake the rotor when output is zero (or within deadband).
Definition: DynamicMotionMagicDutyCycle.hpp:108
units::frequency::hertz_t UpdateFreqHz
The period at which this control will update at.
Definition: DynamicMotionMagicDutyCycle.hpp:133
bool EnableFOC
Set to true to use FOC commutation (requires Phoenix Pro), which increases peak power by ~15%.
Definition: DynamicMotionMagicDutyCycle.hpp:91
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:233
units::angular_jerk::turns_per_second_cubed_t Jerk
Jerk for profiling.
Definition: DynamicMotionMagicDutyCycle.hpp:78
DynamicMotionMagicDutyCycle & WithSlot(int newSlot)
Modifies this Control Request's Slot parameter and returns itself for method-chaining and easier to u...
Definition: DynamicMotionMagicDutyCycle.hpp:321
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:249
bool LimitForwardMotion
Set to true to force forward limiting.
Definition: DynamicMotionMagicDutyCycle.hpp:114
DynamicMotionMagicDutyCycle & WithLimitForwardMotion(bool newLimitForwardMotion)
Modifies this Control Request's LimitForwardMotion parameter and returns itself for method-chaining a...
Definition: DynamicMotionMagicDutyCycle.hpp:356
DynamicMotionMagicDutyCycle & WithUpdateFreqHz(units::frequency::hertz_t newUpdateFreqHz)
Sets the period at which this control will update at.
Definition: DynamicMotionMagicDutyCycle.hpp:392
bool LimitReverseMotion
Set to true to force reverse limiting.
Definition: DynamicMotionMagicDutyCycle.hpp:120
DynamicMotionMagicDutyCycle & WithOverrideBrakeDurNeutral(bool newOverrideBrakeDurNeutral)
Modifies this Control Request's OverrideBrakeDurNeutral parameter and returns itself for method-chain...
Definition: DynamicMotionMagicDutyCycle.hpp:339
DynamicMotionMagicDutyCycle(units::angle::turn_t Position, units::angular_velocity::turns_per_second_t Velocity, units::angular_acceleration::turns_per_second_squared_t Acceleration, units::angular_jerk::turns_per_second_cubed_t Jerk, bool EnableFOC=true, units::dimensionless::scalar_t FeedForward=0.0, int Slot=0, bool OverrideBrakeDurNeutral=false, bool LimitForwardMotion=false, bool LimitReverseMotion=false)
Requires Phoenix Pro and CANivore; Requests Motion Magic® to target a final position using a motion p...
Definition: DynamicMotionMagicDutyCycle.hpp:195
DynamicMotionMagicDutyCycle & WithEnableFOC(bool newEnableFOC)
Modifies this Control Request's EnableFOC parameter and returns itself for method-chaining and easier...
Definition: DynamicMotionMagicDutyCycle.hpp:289
DynamicMotionMagicDutyCycle & WithJerk(units::angular_jerk::turns_per_second_cubed_t newJerk)
Modifies this Control Request's Jerk parameter and returns itself for method-chaining and easier to u...
Definition: DynamicMotionMagicDutyCycle.hpp:265
std::map< std::string, std::string > GetControlInfo() const override
Gets information about this control request.
Definition: DynamicMotionMagicDutyCycle.hpp:424
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:304
DynamicMotionMagicDutyCycle & WithLimitReverseMotion(bool newLimitReverseMotion)
Modifies this Control Request's LimitReverseMotion parameter and returns itself for method-chaining a...
Definition: DynamicMotionMagicDutyCycle.hpp:373
units::angle::turn_t Position
Position to drive toward in rotations.
Definition: DynamicMotionMagicDutyCycle.hpp:63
int Slot
Select which gains are applied by selecting the slot.
Definition: DynamicMotionMagicDutyCycle.hpp:101
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:217
units::dimensionless::scalar_t FeedForward
Feedforward to apply in fractional units between -1 and +1.
Definition: DynamicMotionMagicDutyCycle.hpp:95
Definition: string_util.hpp:15