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