Autonomy Software C++ 24.5.1
Welcome to the Autonomy Software repository of the Mars Rover Design Team (MRDT) at Missouri University of Science and Technology (Missouri S&T)! API reference contains the source code and other resources for the development of the autonomy software for our Mars rover. The Autonomy Software project aims to compete in the University Rover Challenge (URC) by demonstrating advanced autonomous capabilities and robust navigation algorithms.
Loading...
Searching...
No Matches
DifferentialDrive.hpp
Go to the documentation of this file.
1
12#ifndef DIFFERENTIAL_DRIVE_HPP
13#define DIFFERENTIAL_DRIVE_HPP
14
15#include "../../AutonomyLogging.h"
16#include "../../util/NumberOperations.hpp"
17#include "../controllers/PIDController.h"
18
20#include <array>
21#include <cmath>
22
24
25
49namespace diffdrive
50{
52 // Declare public enums that are specific to and used within this namespace.
54
55 // Enum for choosing the differential drive method for certain functions.
56 // Enumerator used to specify what method of drive control to use.
57 enum class DifferentialControlMethod
58 {
59 eArcadeDrive, // Typical drive control method for flightsticks. Uses speed and turn input to determine drive powers.
60 eCurvatureDrive // Similar to arcade drive with flightsticks, but the current turning speed of the robot is dampened when moving fast.
61 };
62
63
73 {
74 public:
75 // Define public struct attributes.
76 double dLeftDrivePower;
77 double dRightDrivePower;
78 };
79
80
91 inline DrivePowers CalculateTankDrive(double dLeftSpeed, double dRightSpeed, bool bSquareInputs = false)
92 {
93 // Limit the input powers.
94 dLeftSpeed = std::clamp(dLeftSpeed, -1.0, 1.0);
95 dRightSpeed = std::clamp(dRightSpeed, -1.0, 1.0);
96
97 // Determine if we should square the inputs.
98 if (bSquareInputs)
99 {
100 // Square the inputs but keep the sign.
101 dLeftSpeed = std::copysign(dLeftSpeed * dLeftSpeed, dLeftSpeed);
102 dRightSpeed = std::copysign(dRightSpeed * dRightSpeed, dRightSpeed);
103 }
104
105 // Return result drive powers.
106 return {dLeftSpeed, dRightSpeed};
107 }
108
109
120 inline DrivePowers CalculateArcadeDrive(double dSpeed, double dRotation, const bool bSquareInputs = false)
121 {
122 // Limit the input powers.
123 dSpeed = std::clamp(dSpeed, -1.0, 1.0);
124 dRotation = std::clamp(dRotation, -1.0, 1.0);
125
126 // Determine if we should square the inputs.
127 if (bSquareInputs)
128 {
129 // Square the inputs but keep the sign.
130 dSpeed = std::copysign(dSpeed * dSpeed, dSpeed);
131 dRotation = std::copysign(dRotation * dRotation, dRotation);
132 }
133
134 // Find the maximum possible value of throttle and turn along the vector that the speed and rotation is pointing.
135 double dGreaterInput = std::max(std::abs(dSpeed), std::abs(dRotation));
136 double dLesserInput = std::min(std::abs(dSpeed), std::abs(dRotation));
137 // If the biggest input is zero, then the wheel speeds should be zero.
138 if (dGreaterInput == 0.0)
139 {
140 // Return zero drive power output.
141 return {0.0, 0.0};
142 }
143
144 // Differential drive inverse kinematics for arcade drive.
145 double dLeftSpeed = dSpeed + dRotation;
146 double dRightSpeed = dSpeed - dRotation;
147 // Desaturate the input. Normalize to (-1.0, 1.0).
148 double dSaturatedInput = (dGreaterInput + dLesserInput) / dGreaterInput;
149 dLeftSpeed /= dSaturatedInput;
150 dRightSpeed /= dSaturatedInput;
151
152 // Return result drive powers.
153 return {dLeftSpeed, dRightSpeed};
154 }
155
156
170 inline DrivePowers CalculateCurvatureDrive(double dSpeed, double dRotation, const bool bAllowTurnInPlace, const bool bSquareInputs = false)
171 {
172 // Create instance variables.
173 double dLeftSpeed = 0.0;
174 double dRightSpeed = 0.0;
175
176 // Limit the input powers.
177 dSpeed = std::clamp(dSpeed, -1.0, 1.0);
178 dRotation = std::clamp(dRotation, -1.0, 1.0);
179
180 // Determine if we should square the inputs.
181 if (bSquareInputs)
182 {
183 // Square the inputs but keep the sign.
184 dSpeed = std::copysign(dSpeed * dSpeed, dSpeed);
185 dRotation = std::copysign(dRotation * dRotation, dRotation);
186 }
187
188 // Check if turn-in-place is allowed.
189 if (bAllowTurnInPlace && dSpeed <= 0.05)
190 {
191 // Differential drive inverse kinematics for curvature drive with turn while stopped.
192 dLeftSpeed = dSpeed + dRotation;
193 dRightSpeed = dSpeed - dRotation;
194 }
195 else
196 {
197 // Differential drive inverse kinematics for curvature drive.
198 dLeftSpeed = dSpeed + std::abs(dSpeed) * dRotation;
199 dRightSpeed = dSpeed - std::abs(dSpeed) * dRotation;
200 }
201
202 // Desaturate the input. Normalize to (-1.0, 1.0).
203 double dMaxMagnitude = std::max(std::abs(dLeftSpeed), std::abs(dRightSpeed));
204 if (dMaxMagnitude > 1.0)
205 {
206 dLeftSpeed /= dMaxMagnitude;
207 dRightSpeed /= dMaxMagnitude;
208 }
209
210 // Return result drive powers.
211 return {dLeftSpeed, dRightSpeed};
212 }
213} // namespace diffdrive
214#endif
Namespace containing algorithms related to calculating drive powers, odometry, trajectories,...
Definition DifferentialDrive.hpp:50
DrivePowers CalculateArcadeDrive(double dSpeed, double dRotation, const bool bSquareInputs=false)
Arcade drive inverse kinematics for differential drive robots.
Definition DifferentialDrive.hpp:120
DrivePowers CalculateCurvatureDrive(double dSpeed, double dRotation, const bool bAllowTurnInPlace, const bool bSquareInputs=false)
Curvature drive inverse kinematics for differential drive robots. The rotation parameter controls the...
Definition DifferentialDrive.hpp:170
DrivePowers CalculateTankDrive(double dLeftSpeed, double dRightSpeed, bool bSquareInputs=false)
Tank drive inverse kinematics for differential drive robots.
Definition DifferentialDrive.hpp:91
This struct is used to store the left and right drive powers for the robot. Storing these values in a...
Definition DifferentialDrive.hpp:73