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