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