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