/** * @file navigation.h * @author Alexander Klein (alex@kleiax.de) * @brief Contains a class which navigate an object by the given route * @version 0.1 * @date 2022-01-10 * * @copyright Copyright (c) 2022 * */ #ifndef NAVIGATION_H #define NAVIGATION_H #include #include #include "route.h" #include "NTRIPClient.h" #include "component.h" /** * @brief This struct inherits the result of the navigation * * The drive get objects of this struct and should * correct the direction in dependency on this. * */ struct CourseCorrection { int16_t correction; double distance; }; /** * @brief This class navigate an object * * The class use the given Route and the gps device * to tell the driver in which direction he have to * be drive and the distance to the next checkpoint. * */ class Navigation : public Component { public: enum Status { InsufficientAccuracy, Unchanged, Updated, Complete }; /** * @brief Construct a new Navigation object and using I2C * * @param route with which to navigate */ Navigation(Route* route = nullptr); /** * @brief Destroy the Navigation object * */ ~Navigation(); /** * @brief * * @param host * @param port * @param mountPoint * @param user * @param password */ void initNtrip(String host, uint16_t port, String mountPoint, String user, String password); /** * @brief creates a new empty route * */ void newRoute(); /** * @brief Tries to start the route * * For example the route can not be started * if there are no Points or wrong Points. * * @return true route is started * @return false route can not be started */ bool startNavigation(); void freezeTargetPoint(bool val = true) { this->preventNextPoint = val; }; void drivingDirectionChange(); void disableCalcAzimuth() { this->directionChangeMode = false; } double increaseMinDistanceToReachPoint() { return this->minDistanceToReachPoint += 0.1; } double decreaseMinDistanceToReachPoint() { return this->minDistanceToReachPoint -= 0.1; } // TODO: Dokumentation korrigieren. /** * @brief Get the Course Correction object * * This should be called by the driver to get new instructions. * * @param correction passed as refernce to get the data * @return true if new correction data provided * @return false if route is finished */ Status getCourseCorrection(CourseCorrection& correction, bool forceUpdate = false); // TODO: Dokumentation korrigieren. /** * @brief Tries to add the current Position to the route * * This can be go wrong if there is no valid GPS signal * * @return true successful added point * @return false no point added to route */ Status addCurrentPosToRoute(); /** * @brief Get the Ubx Data object * * This struct includes the most Data from the GNSS-Module. * * @return UBX_NAV_PVT_data_t* */ UBX_NAV_PVT_data_t* getUbxData() { return this->ubxData; } /** * @brief Returns the NTRIPClient object * * @return NTRIPClient* */ NTRIPClient* getNTRIPClient() { return this->ntripClient; } /** * @brief Get the Route Info object * * This object contains information about the route. * For example the stored points. * * @return RouteInfo */ RouteInfo getRouteInfo() const { return this->route->getRouteInfo(); } Route* getRoute() const { return this->route; } Point getCurrentPosition() const { return this->currentPosition; } /** * @brief Get realAzimuth * * This value represents the angle between north and * the line of sight. Clockwise. * * @return uint16_t degree */ int16_t getAzimuth() const { return this->realAzimuth; } QMC5883LCompass* getCompass() const { return this->compass; } int16_t getCalcAzimuth() const { return this->calcAzimuth; } CalcAzimuthState getCalcAzimuthState() const { return this->calcAzimuthState; } bool getLastUsedCalcAzimuth() const { return this->lastUsedCalcAzimuth; } Point::Accuracy getMinAccuracy() const { return this->minAccuracy; } void setMinAccuracy(Point::Accuracy accuracy) { this->minAccuracy = accuracy; } // map input in range from -180 to 180 degree static int16_t fixDegree(int16_t degree); private: void run() override; void updateMagneticDeclination(); void init(Route* route); bool nextPoint(); bool setTargetPoint(Point target); int16_t calculateCourseCorrection(Point& point); static constexpr uint8_t loopDelay = 20; static constexpr uint8_t maxDisBetweenPoints = 10; static constexpr float minDisBetweenPoints = 0.3; UBX_NAV_PVT_data_t* ubxData = nullptr; Route* route = nullptr; NTRIPClient* ntripClient = nullptr; Point lastPointRouteInsert; Point lastPointCalcCorrection; Point lastPointDrivingDirectionChange; Point targetPoint; Point currentPosition; Point::Accuracy minAccuracy = Point::Accuracy::twoDigOfCM; bool navigationStarted = false; bool navigationFinished = false; bool isNtripInit = false; bool preventNextPoint = false; bool directionChangeMode = false; bool lastUsedCalcAzimuth = false; char* host; char* mountPoint; char* user; char* password; int16_t calcAzimuth = INT16_MAX; uint8_t timeToWait = 200; uint16_t port; uint32_t lastMillis = 0; uint32_t ubxUpdateTime = 0; double minDistanceToReachPoint = 0.5; }; #endif // NAVIGATION_H