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