Run the state machine. Returns the next state.
107 {
108
117 LOG_DEBUG(logging::g_qSharedLogger, "ApproachingObjectState: Running state-specific behavior.");
118
119
121
122
124 if (stCurrentMeasurement.dDistanceMeters > m_stGoalWaypoint.dRadius)
125 {
126 LOG_WARNING(logging::g_qSharedLogger,
127 "ApproachingObjectState: Rover broke geofence! Radius threshold is {} m, current distance is {:.2f} m. Triggering ObjectUnseen.",
128 m_stGoalWaypoint.dRadius,
129 stCurrentMeasurement.dDistanceMeters);
130 globals::g_pStateMachineHandler->
HandleEvent(Event::eObjectUnseen);
131 return;
132 }
133
134
137
138 std::chrono::system_clock::time_point tmCurrentTime = std::chrono::system_clock::now();
139 double dSecondsSinceLastSeen = std::chrono::duration_cast<std::chrono::milliseconds>(tmCurrentTime - m_tmLastSeenTime).count() / 1000.0;
140
141
142 if (dSecondsSinceLastSeen > constants::APPROACH_OBJECT_LOST_GIVE_UP_TIME + 5.0)
143 {
144 m_bHasLastGeolocatedPosition = false;
145 }
146
147
148 if (stBestObject.dConfidence > 0.0)
149 {
150 LOG_NOTICE(logging::g_qSharedLogger, "ApproachingObjectState: OBJECT DETECTED ({:.2f}%). Halting to verify!", stBestObject.dConfidence * 100.0);
151
153 globals::g_pStateMachineHandler->
HandleEvent(Event::eReachedObject,
true);
154 return;
155 }
156
157
158 if (dSecondsSinceLastSeen > constants::APPROACH_OBJECT_LOST_GIVE_UP_TIME)
159 {
160 LOG_WARNING(logging::g_qSharedLogger,
161 "ApproachingObjectState: Object has been unseen for {:.2f}s (Threshold: {:.2f}s). Giving up and triggering ObjectUnseen.",
162 dSecondsSinceLastSeen,
163 constants::APPROACH_OBJECT_LOST_GIVE_UP_TIME);
164 globals::g_pStateMachineHandler->
HandleEvent(Event::eObjectUnseen);
165 return;
166 }
167
168 if (!m_bAlreadyPrintedLost)
169 {
170 m_bAlreadyPrintedLost = true;
171 LOG_WARNING(logging::g_qSharedLogger, "ApproachingObjectState: Tracking lost! No valid objects detected across any camera.");
172 }
173
174
175 if (m_bHasLastGeolocatedPosition)
176 {
179 m_dHeadingSetPoint = stLastMeasurement.dStartRelativeBearing;
180
181 if (!m_bAlreadyPrintedVisualLostFallback)
182 {
183 LOG_NOTICE(logging::g_qSharedLogger,
184 "ApproachingObjectState: [FALLBACK 1] Visual lost. Driving to last known geolocated UTM: [{:.2f}E, {:.2f}N]. Target Bearing: {:.2f} degrees",
187 m_dHeadingSetPoint);
188 m_bAlreadyPrintedVisualLostFallback = true;
189 }
190 }
191
192 else if (m_bHasSeenTarget)
193 {
194 if (!m_bAlreadyPrintedVisualLostFallback)
195 {
196 LOG_NOTICE(logging::g_qSharedLogger,
197 "ApproachingObjectState: [FALLBACK 2] Visual lost & no geolocation history. Coasting along last known heading. Target Bearing: {:.2f} degrees",
198 m_dHeadingSetPoint);
199 m_bAlreadyPrintedVisualLostFallback = true;
200 }
201 }
202
203 else
204 {
206 return;
207 }
208
209
211 m_dHeadingSetPoint,
213 diffdrive::DifferentialControlMethod::eArcadeDrive,
214 m_bDriveBackwards,
215 false,
216 false,
217 false);
218 globals::g_pDriveBoard->
SendDrive(stDrivePowers);
219
220
221 if (constants::APPROACH_OBJECT_ENABLE_STUCK_DETECT &&
222 m_StuckDetector.
CheckIfStuck(globals::g_pStateMachineHandler->SmartRetrieveVelocity(),
223 globals::g_pStateMachineHandler->SmartRetrieveAngularVelocity(),
224 constants::APPROACH_OBJECT_STUCK_CHECK_VEL_THRESH * globals::g_pDriveBoard->GetMaxDriveEffort(),
225 constants::APPROACH_OBJECT_STUCK_CHECK_ROT_THRESH))
226 {
227 LOG_WARNING(logging::g_qSharedLogger,
228 "ApproachingObjectState: Rover has become stuck! Triggering Stuck event. Curr Vel: {:.2f}, Ang Vel: {:.2f}",
229 globals::g_pStateMachineHandler->SmartRetrieveVelocity(),
230 globals::g_pStateMachineHandler->SmartRetrieveAngularVelocity());
231 globals::g_pStateMachineHandler->
HandleEvent(Event::eStuck,
true);
232 return;
233 }
234 }
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 SendStop()
Stop the drivetrain of the Rover.
Definition DriveBoard.cpp:246
geoops::RoverPose SmartRetrieveRoverPose(bool bIMUHeading=true)
This method is used to retrieve the rover's current position and heading. It uses the GPS data from t...
Definition StateMachineHandler.cpp:375
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 CheckIfStuck(double dCurrentVelocity, double dCurrentAngularVelocity, double dVelocityThreshold=0.1, double dAngularVelocityThreshold=0.1)
Checks if the rover meets stuck criteria based in the given parameters.
Definition StuckDetection.hpp:96
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
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:101
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
const geoops::UTMCoordinate & GetUTMCoordinate() const
Accessor for the geoops::UTMCoordinate member variable.
Definition GeospatialOperations.hpp:508
Represents a single detected object.
Definition ObjectDetectionUtility.hpp:73