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