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