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 bool bAlreadyPrintedLost = false;
128 static std::chrono::system_clock::time_point tLastSeenTime = std::chrono::system_clock::now();
129 if (stBestObject.dConfidence == 0.0)
130 {
131 std::chrono::system_clock::time_point tmCurrentTime = std::chrono::system_clock::now();
132 if ((std::chrono::duration_cast<std::chrono::milliseconds>(tmCurrentTime - tLastSeenTime).count() / 1000.0) > constants::APPROACH_OBJECT_LOST_GIVE_UP_TIME)
133 {
134
135 globals::g_pStateMachineHandler->
HandleEvent(Event::eObjectUnseen);
136 return;
137 }
138 else
139 {
140 if (!bAlreadyPrintedLost)
141 {
142 bAlreadyPrintedLost = true;
143
144 LOG_WARNING(logging::g_qSharedLogger, "ApproachingObjectState: No objects detected.");
145
146
147 if (stBestObject.dConfidence != 0.0 && stBestObject.stGeolocatedPosition.eType != geoops::WaypointType::eUNKNOWN)
148 {
149
150 LOG_NOTICE(logging::g_qSharedLogger, "ApproachingObjectState: Object is geolocated.");
151 return;
152 }
153
154
156 return;
157 }
158 }
159 }
160
161 else
162 {
163
164 if (bAlreadyPrintedLost)
165 {
166 LOG_NOTICE(logging::g_qSharedLogger, "ApproachingObjectState: Objects were detected again.");
167 }
168
169
170 tLastSeenTime = std::chrono::system_clock::now();
171
172 bAlreadyPrintedLost = false;
173 }
174
175
176 static double dHeadingSetPoint = 0.0;
177 static double dDistanceFromObject = 0.0;
178
179 if (stBestObject.dConfidence != 0.0)
180 {
181 dDistanceFromObject = stBestObject.dStraightLineDistance;
182
183 if (stBestObject.stGeolocatedPosition.eType != geoops::WaypointType::eUNKNOWN)
184 {
185
188
189 dHeadingSetPoint = stObjectMeasurement.dStartRelativeBearing;
190
191 m_pRoverPathPlot->AddDot(stBestObject.stGeolocatedPosition.
GetUTMCoordinate(),
"DetectedObjects");
192 }
193 else
194 {
196 }
197 }
198
199
201 dHeadingSetPoint,
203 diffdrive::DifferentialControlMethod::eArcadeDrive);
204 globals::g_pDriveBoard->
SendDrive(stDrivePowers);
205
206
207 static std::chrono::system_clock::time_point tmLastOLogTime = std::chrono::system_clock::now();
208 std::chrono::system_clock::time_point tmCurrentTime = std::chrono::system_clock::now();
209 if (std::chrono::duration_cast<std::chrono::seconds>(tmCurrentTime - tmLastOLogTime).count() >= 1)
210 {
211
212 tmLastOLogTime = tmCurrentTime;
213
214 if (stBestObject.dConfidence != 0.0)
215 {
216 LOG_NOTICE(logging::g_qSharedLogger,
217 "ApproachingObjectState: Object confidence: {:.2f}, Distance: {:.2f} m, Heading: {:.2f} deg",
218 stBestObject.dConfidence,
219 dDistanceFromObject,
220 dHeadingSetPoint);
221 }
222 }
223
224
225 if (dDistanceFromObject != 0.0 && dDistanceFromObject < constants::APPROACH_OBJECT_PROXIMITY_THRESHOLD)
226 {
227
228 LOG_NOTICE(logging::g_qSharedLogger, "ApproachingObjectState: Rover has reached the target object!");
229
230 if (stBestObject.dConfidence != 0.0 && stBestObject.stGeolocatedPosition.eType == geoops::WaypointType::eObjectWaypoint)
231 {
232
233 m_pRoverPathPlot->AddDot(stBestObject.stGeolocatedPosition.
GetUTMCoordinate(),
"FinalObject", 7);
234 }
235
236
237 dHeadingSetPoint = 0.0;
238 dDistanceFromObject = 0.0;
239
240
241 globals::g_pStateMachineHandler->
HandleEvent(Event::eReachedObject,
true);
242
243 return;
244 }
245
247
249
250
251 if (constants::APPROACH_OBJECT_ENABLE_STUCK_DETECT &&
252 m_StuckDetector.
CheckIfStuck(globals::g_pWaypointHandler->SmartRetrieveVelocity(), globals::g_pWaypointHandler->SmartRetrieveAngularVelocity()))
253 {
254
255 LOG_NOTICE(logging::g_qSharedLogger, "ApproachingObjectState: Rover has become stuck!");
256
257 globals::g_pStateMachineHandler->
HandleEvent(Event::eStuck,
true);
258
259 return;
260 }
261
262 return;
263 }
void SendDrive(const diffdrive::DrivePowers &stDrivePowers)
Sets the left and right drive powers of the drive board.
Definition DriveBoard.cpp:117
void SendStop()
Stop the drivetrain of the Rover.
Definition DriveBoard.cpp:163
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:87
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:350
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 WaypointHandler.cpp:742
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:522
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:82
This struct is used by the WaypointHandler to provide an easy way to store all pose data about the ro...
Definition GeospatialOperations.hpp:677
const geoops::GPSCoordinate & GetGPSCoordinate() const
Accessor for the geoops::GPSCoordinate member variable.
Definition GeospatialOperations.hpp:725
double GetCompassHeading() const
Accessor for the Compass Heading private member.
Definition GeospatialOperations.hpp:756
const geoops::UTMCoordinate & GetUTMCoordinate() const
Accessor for the geoops::UTMCoordinate member variable.
Definition GeospatialOperations.hpp:736
const geoops::GPSCoordinate & GetGPSCoordinate() const
Accessor for the geoops::GPSCoordinate member variable.
Definition GeospatialOperations.hpp:466
const geoops::UTMCoordinate & GetUTMCoordinate() const
Accessor for the geoops::UTMCoordinate member variable.
Definition GeospatialOperations.hpp:477
Represents a single detected object. Combines attributes from TorchObject and TensorflowObject struct...
Definition ObjectDetectionUtility.hpp:73