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