Files
Bachelorarbeit-Rover/lib/Navigation/navigation.h
T
kleiax 11d21e2e89 cleaning
refactore
all components now have a base class compnent for loop functions
2023-08-18 10:47:35 +02:00

274 lines
7.8 KiB
C++

/**
* @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 <SparkFun_u-blox_GNSS_Arduino_Library.h>
#include <QMC5883LCompass.h>
#include <Arduino.h>
#include <iostream>
#include <SPI.h>
#include "route.h"
#include "NTRIPClient.h"
#include "calibrateCompass.h"
#include "component.h"
/**
* @brief The minimal distance between Points
*
* This is a very critical option. It have to be
* around the half accuracy of the positioning system
*
*/
#define MIN_DISTANCE_BETWEEN_POINTS 0.3
#define MAX_DISTANCE_BETWEEN_POINTS 10
#define MIN_DISTANCE_TO_REACH_POINT 0.5
#define AZIMUTH_UPDATE_DELAY 20
/**
* @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
};
enum CalcAzimuthState {
Invalid,
Bad,
Ok,
Good,
Super
};
/**
* @brief Construct a new Navigation object and using I2C
*
* @param route with which to navigate
*/
Navigation(Route* route = nullptr);
/**
* @brief Construct a new Navigation object and using SPI
*
* @param route with which to navigate
*/
Navigation(SPIClass* spiPort, uint8_t csPin, 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();
// TODO: can be deleted?
// bool setPointBeforeTurn();
/**
* @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; }
/**
* @brief Set the output status for PVTdata.
*
* If this is true, a lot of information from the gnss module will be printed in
* the interval of navigation frequency.
*
* @param status
*/
static void setOutputStatusPrintPVTdata(bool status);
// map input in range from -180 to 180 degree
static int16_t fixDegree(int16_t degree);
private:
void run() override;
void runAsChild() override;
void updateCurrentLocation();
void updateMagneticDeclination();
void init(Route* route);
bool nextPoint();
bool setTargetPoint(Point target);
int16_t calculateCourseCorrection(Point& point);
SFE_UBLOX_GNSS* gps;
UBX_NAV_PVT_data_t* ubxData = nullptr;
Route* route = nullptr;
NTRIPClient* ntripClient = nullptr;
QMC5883LCompass* compass;
Point lastPointRouteInsert;
Point lastPointCalcCorrection;
Point lastPointDrivingDirectionChange;
Point targetPoint;
Point currentPosition;
Point::Accuracy minAccuracy = Point::Accuracy::twoDigOfCM;
CalcAzimuthState calcAzimuthState = CalcAzimuthState::Invalid;
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 realAzimuth = INT16_MAX;
int16_t calcAzimuth = INT16_MAX;
uint8_t timeToWait = 200;
uint16_t port;
uint32_t lastMillis = 0;
uint32_t ubxUpdateTime = 0;
double minDistanceToReachPoint = 0.5;
static void printPVTdata(UBX_NAV_PVT_data_t *ubxDataStruct);
static void savePVTdata(UBX_NAV_PVT_data_t *ubxDataStruct);
static UBX_NAV_PVT_data_t* ubxDataStatic;
static uint32_t ubxUpdateTimeStatic;
static bool outputStatusPrintPVTdata;
static bool newData;
};
#endif // NAVIGATION_H