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