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