Run the state machine. Returns the next state.
99 {
100
101 LOG_DEBUG(logging::g_qSharedLogger, "ApproachingObjectState: Running state-specific behavior.");
102
103
105
106
107 m_pRoverPathPlot->AddPathPoint(stCurrentRoverPose.
GetUTMCoordinate(),
"RoverPath");
108
109
111 if (stCurrentMeasurement.dDistanceMeters > m_stGoalWaypoint.dRadius)
112 {
113
114 LOG_WARNING(logging::g_qSharedLogger,
115 "ApproachingObjectState: Rover is too far from the original waypoint! Waypoint radius is {} meters, current distance is {} meters.",
116 m_stGoalWaypoint.dRadius,
117 stCurrentMeasurement.dDistanceMeters);
118 globals::g_pStateMachineHandler->
HandleEvent(Event::eObjectUnseen);
119 return;
120 }
121
122
125
126
127 static double dHeadingSetPoint = 0.0;
128 static double dDistanceFromObject = 0.0;
130 static bool bHasLastGeolocatedPosition = false;
131 static std::chrono::system_clock::time_point tLastSeenTime = std::chrono::system_clock::now();
132 static bool bAlreadyPrintedLost = false;
133 static bool bAlreadyPrintedVisualLostFallback = false;
134
135
136 if (std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now() - tLastSeenTime).count() >
137 constants::APPROACH_OBJECT_LOST_GIVE_UP_TIME + 5.0)
138 {
139 bHasLastGeolocatedPosition = false;
140 }
141
142
143 if (stBestObject.dConfidence == 0.0)
144 {
145 std::chrono::system_clock::time_point tmCurrentTime = std::chrono::system_clock::now();
146 if ((std::chrono::duration_cast<std::chrono::milliseconds>(tmCurrentTime - tLastSeenTime).count() / 1000.0) > constants::APPROACH_OBJECT_LOST_GIVE_UP_TIME)
147 {
148
149 globals::g_pStateMachineHandler->
HandleEvent(Event::eObjectUnseen);
150 return;
151 }
152 else
153 {
154 if (!bAlreadyPrintedLost)
155 {
156 bAlreadyPrintedLost = true;
157
158 LOG_WARNING(logging::g_qSharedLogger, "ApproachingObjectState: No objects detected.");
159 }
160
161
162 if (bHasLastGeolocatedPosition)
163 {
164
167
168
169 dHeadingSetPoint = stLastMeasurement.dStartRelativeBearing;
170 dDistanceFromObject = stLastMeasurement.dDistanceMeters;
171
172 if (!bAlreadyPrintedVisualLostFallback)
173 {
174 LOG_NOTICE(logging::g_qSharedLogger, "ApproachingObjectState: Visual lost, driving to last known geolocated position.");
175 bAlreadyPrintedVisualLostFallback = true;
176 }
177 }
178 else
179 {
180
182 return;
183 }
184 }
185 }
186 else
187 {
188
189 if (bAlreadyPrintedLost)
190 {
191 LOG_NOTICE(logging::g_qSharedLogger, "ApproachingObjectState: Objects were detected again.");
192 }
193
194
195 tLastSeenTime = std::chrono::system_clock::now();
196
197 bAlreadyPrintedLost = false;
198 bAlreadyPrintedVisualLostFallback = false;
199
200
201 if (stBestObject.dConfidence != 0.0)
202 {
203 dDistanceFromObject = stBestObject.dStraightLineDistance;
204
205 if (stBestObject.stGeolocatedPosition.eType != geoops::WaypointType::eUNKNOWN)
206 {
207
210
211 dHeadingSetPoint = stObjectMeasurement.dStartRelativeBearing;
212
213
214 stLastGeolocatedPosition = stBestObject.stGeolocatedPosition;
215 bHasLastGeolocatedPosition = true;
216
217
218 m_pRoverPathPlot->AddDot(stBestObject.stGeolocatedPosition.
GetUTMCoordinate(),
"DetectedObjects");
219 }
220 else
221 {
222
224 }
225 }
226 }
227
228
230 dHeadingSetPoint,
232 diffdrive::DifferentialControlMethod::eArcadeDrive);
233 globals::g_pDriveBoard->
SendDrive(stDrivePowers);
234
235
236 static std::chrono::system_clock::time_point tmLastOLogTime = std::chrono::system_clock::now();
237 std::chrono::system_clock::time_point tmCurrentTime = std::chrono::system_clock::now();
238 if (std::chrono::duration_cast<std::chrono::seconds>(tmCurrentTime - tmLastOLogTime).count() >= 1)
239 {
240
241 tmLastOLogTime = tmCurrentTime;
242
243 if (stBestObject.dConfidence != 0.0)
244 {
245 LOG_NOTICE(logging::g_qSharedLogger,
246 "ApproachingObjectState: Object confidence: {:.2f}, Distance: {:.2f} m, Heading: {:.2f} deg",
247 stBestObject.dConfidence,
248 dDistanceFromObject,
249 dHeadingSetPoint);
250 }
251 }
252
253
254 if (dDistanceFromObject != 0.0 && dDistanceFromObject < constants::APPROACH_OBJECT_PROXIMITY_THRESHOLD)
255 {
256
257 LOG_NOTICE(logging::g_qSharedLogger, "ApproachingObjectState: Rover has reached the target object!");
258
259 if (stBestObject.dConfidence != 0.0 && stBestObject.stGeolocatedPosition.eType == geoops::WaypointType::eObjectWaypoint)
260 {
261
262 m_pRoverPathPlot->AddDot(stBestObject.stGeolocatedPosition.
GetUTMCoordinate(),
"FinalObject", 7);
263 }
264
265
266 dHeadingSetPoint = 0.0;
267 dDistanceFromObject = 0.0;
268 bHasLastGeolocatedPosition = false;
269
270
271 globals::g_pStateMachineHandler->
HandleEvent(Event::eReachedObject,
true);
272
273 return;
274 }
275
277
279
280
281 if (constants::APPROACH_OBJECT_ENABLE_STUCK_DETECT &&
282 m_StuckDetector.
CheckIfStuck(globals::g_pStateMachineHandler->SmartRetrieveVelocity(), globals::g_pStateMachineHandler->SmartRetrieveAngularVelocity()))
283 {
284
285 LOG_NOTICE(logging::g_qSharedLogger, "ApproachingObjectState: Rover has become stuck!");
286
287 globals::g_pStateMachineHandler->
HandleEvent(Event::eStuck,
true);
288
289 return;
290 }
291
292 return;
293 }
void SendDrive(const diffdrive::DrivePowers &stDrivePowers, const bool bEnableVariableDriveEffort=true)
Sets the left and right drive powers of the drive board.
Definition DriveBoard.cpp:118
void SendStop()
Stop the drivetrain of the Rover.
Definition DriveBoard.cpp:195
diffdrive::DrivePowers CalculateMove(const double dGoalSpeed, const double dGoalHeading, const double dActualHeading, const diffdrive::DifferentialControlMethod eKinematicsMethod=diffdrive::DifferentialControlMethod::eArcadeDrive, const bool bAlwaysProgressForward=false)
This method determines drive powers to make the Rover drive towards a given heading at a given speed.
Definition DriveBoard.cpp:88
geoops::RoverPose SmartRetrieveRoverPose(bool bVIOHeading=true, bool bVIOTracking=false)
Retrieve the rover's current position and heading. Automatically picks between getting the position/h...
Definition StateMachineHandler.cpp:445
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:353
bool CheckIfStuck(double dCurrentVelocity, double dCurrentAngularVelocity)
Checks if the rover meets stuck criteria based in the given parameters.
Definition StuckDetection.hpp:105
GeoMeasurement CalculateGeoMeasurement(const GPSCoordinate &stCoord1, const GPSCoordinate &stCoord2)
The shortest path between two points on an ellipsoid at (lat1, lon1) and (lat2, lon2) is called the g...
Definition GeospatialOperations.hpp:553
constexpr T InputAngleModulus(T tValue, T tMinValue, T tMaxValue)
Calculates the modulus of an input angle.
Definition NumberOperations.hpp:165
int IdentifyTargetObject(const std::vector< std::shared_ptr< ObjectDetector > > &vObjectDetectors, objectdetectutils::Object &stObjectTarget, const geoops::WaypointType &eDesiredDetectionType=geoops::WaypointType::eUNKNOWN)
Identify a target object in the rover's vision, using Torch detection.
Definition ObjectDetectionChecker.hpp:90
This struct is used to store the left and right drive powers for the robot. Storing these values in a...
Definition DifferentialDrive.hpp:73
This struct is used to store the distance, arc length, and relative bearing for a calculated geodesic...
Definition GeospatialOperations.hpp:83
This struct is used by the WaypointHandler to provide an easy way to store all pose data about the ro...
Definition GeospatialOperations.hpp:708
const geoops::GPSCoordinate & GetGPSCoordinate() const
Accessor for the geoops::GPSCoordinate member variable.
Definition GeospatialOperations.hpp:756
double GetCompassHeading() const
Accessor for the Compass Heading private member.
Definition GeospatialOperations.hpp:787
const geoops::UTMCoordinate & GetUTMCoordinate() const
Accessor for the geoops::UTMCoordinate member variable.
Definition GeospatialOperations.hpp:767
This struct is used by the WaypointHandler class to store location, size, and type information about ...
Definition GeospatialOperations.hpp:423
const geoops::GPSCoordinate & GetGPSCoordinate() const
Accessor for the geoops::GPSCoordinate member variable.
Definition GeospatialOperations.hpp:497
const geoops::UTMCoordinate & GetUTMCoordinate() const
Accessor for the geoops::UTMCoordinate member variable.
Definition GeospatialOperations.hpp:508
Represents a single detected object. Combines attributes from TorchObject and TensorflowObject struct...
Definition ObjectDetectionUtility.hpp:74