Run the state machine. Returns the next state.
101 {
102
103 LOG_DEBUG(logging::g_qSharedLogger, "StuckState: Running state-specific behavior.");
104
105
107
108 std::chrono::system_clock::time_point tmCurrentTime = std::chrono::system_clock::now();
109
110
112 {
113
114 LOG_NOTICE(logging::g_qSharedLogger,
115 "StuckState: Rover has successfully unstuckith itself! A total of {} seconds was wasted being stuck.",
116 std::chrono::duration_cast<std::chrono::seconds>(tmCurrentTime - m_tmStuckStartTime).count());
117
118 globals::g_pStateMachineHandler->
HandleEvent(Event::eUnstuck,
false);
119 }
120 else
121 {
122
123 switch (m_eAttemptType)
124 {
125
126 case AttemptType::eReverseCurrentHeading:
127 {
128
129 LOG_INFO(logging::g_qSharedLogger, "StuckState: Maintaining current heading and reversing...");
130
131 m_eAttemptType = AttemptType::eReverseLeft;
132
133 globals::g_pStateMachineHandler->
HandleEvent(Event::eReverse,
true);
134 break;
135 }
136
137 case AttemptType::eReverseLeft:
138 {
139
140 if (!m_bIsCurrentlyAligning)
141 {
142
143 LOG_INFO(logging::g_qSharedLogger, "StuckState: Aligning rover heading {} degrees clockwise...", constants::STUCK_ALIGN_DEGREES);
144
145 m_bIsCurrentlyAligning = true;
146
148
149 m_tmAlignStartTime = std::chrono::system_clock::now();
150 }
151 else
152 {
153
154 double dTimeElapsed = std::chrono::duration_cast<std::chrono::milliseconds>(tmCurrentTime - m_tmAlignStartTime).count() / 1000.0;
155
156 double dGoalHeading = numops::InputAngleModulus<double>(m_dOriginalHeading + constants::STUCK_ALIGN_DEGREES, 0, 360);
157
158 double dRealignmentDegrees = numops::AngularDifference<double>(stCurrentRoverPose.
GetCompassHeading(), dGoalHeading);
159
160
162 dGoalHeading,
164 diffdrive::DifferentialControlMethod::eArcadeDrive);
165
166 globals::g_pDriveBoard->
SendDrive(stTurnPowers);
167
168
169 if (dRealignmentDegrees <= constants::STUCK_ALIGN_TOLERANCE)
170 {
171
172 LOG_INFO(logging::g_qSharedLogger, "StuckState: Realignment complete! Reversing...");
173
174 m_eAttemptType = AttemptType::eReverseRight;
175
176 m_bIsCurrentlyAligning = false;
177
178 globals::g_pStateMachineHandler->
HandleEvent(Event::eReverse,
true);
179 }
180
181 else if (dTimeElapsed >= constants::STUCK_HEADING_ALIGN_TIMEOUT)
182 {
183
184 LOG_NOTICE(logging::g_qSharedLogger,
185 "StuckState: Rotated/Realigned {} degrees in {} seconds before timeout was reached. Rover is still stuck...",
186 constants::STUCK_ALIGN_DEGREES - dRealignmentDegrees,
187 dTimeElapsed);
188
189 m_eAttemptType = AttemptType::eReverseRight;
190
191 m_bIsCurrentlyAligning = false;
192
193 globals::g_pStateMachineHandler->
HandleEvent(Event::eReverse,
true);
194 }
195 }
196 break;
197 }
198
199 case AttemptType::eReverseRight:
200 {
201
202 if (!m_bIsCurrentlyAligning)
203 {
204
205 LOG_INFO(logging::g_qSharedLogger, "StuckState: Aligning rover heading {} degrees counter-clockwise...", constants::STUCK_ALIGN_DEGREES);
206
207 m_bIsCurrentlyAligning = true;
208
209
211
212 m_tmAlignStartTime = std::chrono::system_clock::now();
213 }
214 else
215 {
216
217 double dTimeElapsed = std::chrono::duration_cast<std::chrono::milliseconds>(tmCurrentTime - m_tmAlignStartTime).count() / 1000.0;
218
219 double dGoalHeading = numops::InputAngleModulus<double>(m_dOriginalHeading - constants::STUCK_ALIGN_DEGREES, 0, 360);
220
221 double dRealignmentDegrees = numops::AngularDifference<double>(stCurrentRoverPose.
GetCompassHeading(), dGoalHeading);
222
223
225 dGoalHeading,
227 diffdrive::DifferentialControlMethod::eArcadeDrive);
228
229 globals::g_pDriveBoard->
SendDrive(stTurnPowers);
230
231
232 if (dRealignmentDegrees <= constants::STUCK_ALIGN_TOLERANCE)
233 {
234
235 LOG_INFO(logging::g_qSharedLogger, "StuckState: Realignment complete! Reversing...");
236
237 m_eAttemptType = AttemptType::eGiveUp;
238
239 m_bIsCurrentlyAligning = false;
240
241 globals::g_pStateMachineHandler->
HandleEvent(Event::eReverse,
true);
242 }
243
244 else if (dTimeElapsed >= constants::STUCK_HEADING_ALIGN_TIMEOUT)
245 {
246
247 LOG_NOTICE(logging::g_qSharedLogger,
248 "StuckState: Rotated/Realigned {} degrees in {} seconds before timeout was reached. Rover is still stuck...",
249 constants::STUCK_ALIGN_DEGREES - dRealignmentDegrees,
250 dTimeElapsed);
251
252 m_eAttemptType = AttemptType::eGiveUp;
253
254 m_bIsCurrentlyAligning = false;
255
256 globals::g_pStateMachineHandler->
HandleEvent(Event::eReverse,
true);
257 }
258 }
259 break;
260 }
261 case AttemptType::eGiveUp:
262 {
263
264 LOG_WARNING(logging::g_qSharedLogger, "StuckState: After multiple attempts, autonomy was unable to get the rover unstuck. Giving Up...");
265
266 globals::g_pStateMachineHandler->
HandleEvent(Event::eAbort);
267 break;
268 }
269 default:
270 {
271
272 LOG_ERROR(logging::g_qSharedLogger, "StuckState: Unknown attempt type!");
273
274 globals::g_pStateMachineHandler->
HandleEvent(Event::eAbort);
275 break;
276 }
277 }
278 }
279 }
void SendDrive(const diffdrive::DrivePowers &stDrivePowers, const bool bEnableVariableDriveEffort=true)
Sets the left and right drive powers of the drive board.
Definition DriveBoard.cpp:166
diffdrive::DrivePowers CalculateMove(const double dGoalSpeed, const double dGoalHeading, const double dActualHeading, const diffdrive::DifferentialControlMethod eKinematicsMethod=diffdrive::DifferentialControlMethod::eArcadeDrive, const bool bDriveBackwards=false, const bool bAlwaysProgressForward=false, const bool bSquareControlInput=false, const bool bCurvatureDriveAllowTurningWhileStopped=true)
This method determines drive powers to make the Rover drive towards a given heading at a given speed.
Definition DriveBoard.cpp:89
void HandleEvent(statemachine::Event eEvent, const bool bSaveCurrentState=false)
This method Handles Events that are passed to the State Machine Handler. It will check the current st...
Definition StateMachineHandler.cpp:285
bool SamePosition(const geoops::GPSCoordinate &stOriginalPosition, const geoops::GPSCoordinate &stCurrPosition)
Checks if the rover is approximately in the same position.
Definition StuckState.cpp:370
This struct is used to store the left and right drive powers for the robot. Storing these values in a...
Definition DifferentialDrive.hpp:73