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