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