9#ifndef _DOVES_LAP_TIMER_H
10#define _DOVES_LAP_TIMER_H
12#include "ArxTypeTraits.h"
15#define CROSSING_LINE_SIDE_A -1
16#define CROSSING_LINE_SIDE_EXACT 0
17#define CROSSING_LINE_SIDE_B 1
20#define COURSE_DETECT_SPEED_THRESHOLD_MPH 20
21#define COURSE_DETECT_WAYPOINT_PROXIMITY_METERS 10.0
22#define COURSE_DETECT_MIN_DISTANCE_METERS 200.0
23#define COURSE_DETECT_DISTANCE_TOLERANCE_PCT 0.25
24#define COURSE_DETECT_MAX_REJECTIONS 3
25#define METERS_TO_FEET 3.28084
28#define WAYPOINT_LAP_MIN_DISTANCE_METERS 100.0
29#define WAYPOINT_LAP_PROXIMITY_METERS 30.0
30#define WAYPOINT_LAP_BUFFER_SIZE 50
38#define DETECT_STATE_IDLE 0
39#define DETECT_STATE_WAITING_FOR_SPEED 1
40#define DETECT_STATE_WAYPOINT_SET 2
41#define DETECT_STATE_CANDIDATES_READY 3
42#define DETECT_STATE_DETECTED 4
88 DovesLapTimer(
double crossingThresholdMeters = 7, Stream *debugSerial = NULL);
101 int loop(
double currentLat,
double currentLng,
float currentAltitudeMeters,
float currentSpeedKnots);
116 bool isObtuseTriangle(
double lat1,
double lon1,
double lat2,
double lon2,
double lat3,
double lon3);
148 int pointOnSideOfLine(
double driverLat,
double driverLng,
double pointALat,
double pointALng,
double pointBLat,
double pointBLng);
166 double pointLineSegmentDistance(
double pointX,
double pointY,
double startX,
double startY,
double endX,
double endY);
182 double haversine(
double lat1,
double lon1,
double lat2,
double lon2);
198 double haversine3D(
double prevLat,
double prevLng,
double prevAlt,
double currentLat,
double currentLng,
double currentAlt);
214 void setStartFinishLine(
double pointALat,
double pointALng,
double pointBLat,
double pointBLng);
223 void setSector2Line(
double pointALat,
double pointALng,
double pointBLat,
double pointBLng);
232 void setSector3Line(
double pointALat,
double pointALng,
double pointBLat,
double pointBLng);
435 template<
typename... Args>
436 void debug_print(Args&&... args) {
438 _serial->print(std::forward<Args>(args)...);
441 template<
typename... Args>
442 void debug_println(Args&&... args) {
444 _serial->println(std::forward<Args>(args)...);
461 bool checkStartFinish(
double currentLat,
double currentLng);
475 bool checkSectorLine(
double currentLat,
double currentLng,
double pointALat,
double pointALng,
double pointBLat,
double pointBLng,
bool& crossingFlag,
int sectorNumber);
491 double currentLat,
double currentLng,
492 double pointALat,
double pointALng,
493 double pointBLat,
double pointBLng,
496 double& outLat,
double& outLng,
497 unsigned long& outTime,
498 double& outOdometer);
505 void handleLineCrossing(
unsigned long crossingTime,
int sectorNumber);
509 void updateBestSectors();
520 double catmullRom(
double p0,
double p1,
double p2,
double p3,
double t);
530 double interpolateWeight(
double distA,
double distB,
float speedA,
float speedB);
547 void interpolateCrossingPoint(
double& crossingLat,
double& crossingLng,
unsigned long& crossingTime,
double& crossingOdometer,
double pointALat,
double pointALng,
double pointBLat,
double pointBLng);
552 unsigned long millisecondsSinceMidnight = 0;
554 double crossingThresholdMeters;
555 bool raceStarted =
false;
556 bool crossing =
false;
557 bool forceLinear =
true;
558 unsigned long currentLapStartTime = 0;
559 unsigned long lastLapTime = 0;
560 unsigned long bestLapTime = 0;
561 float currentLapOdometerStart = 0.0;
562 float lastLapDistance = 0.0;
563 float bestLapDistance = 0.0;
564 float currentSpeedkmh = 0.0;
565 int bestLapNumber = 0;
569 int currentSector = 0;
570 unsigned long currentSectorStartTime = 0;
571 bool crossingSector2 =
false;
572 bool crossingSector3 =
false;
575 unsigned long currentLapSector1Time = 0;
576 unsigned long currentLapSector2Time = 0;
577 unsigned long currentLapSector3Time = 0;
580 unsigned long bestSector1Time = 0;
581 unsigned long bestSector2Time = 0;
582 unsigned long bestSector3Time = 0;
585 int bestSector1LapNumber = 0;
586 int bestSector2LapNumber = 0;
587 int bestSector3LapNumber = 0;
589 float totalDistanceTraveled = 0;
590 float positionPrevAlt = 0.00;
591 double positionPrevLat = 0.00;
592 double positionPrevLng = 0.00;
593 bool firstPositionReceived =
false;
596 double prevFixLat = 0;
597 double prevFixLng = 0;
598 unsigned long prevFixTime = 0;
599 float prevFixOdometer = 0;
600 float prevFixSpeedKmh = 0;
601 bool hasPrevFix =
false;
603 double startFinishPointALat;
604 double startFinishPointALng;
605 double startFinishPointBLat;
606 double startFinishPointBLng;
609 double sector2PointALat;
610 double sector2PointALng;
611 double sector2PointBLat;
612 double sector2PointBLng;
615 double sector3PointALat;
616 double sector3PointALng;
617 double sector3PointBLat;
618 double sector3PointBLng;
621 bool sector2LineConfigured =
false;
622 bool sector3LineConfigured =
false;
625 static constexpr double radiusEarth = 6371.0 * 1000;
631 #if defined(RAMEND) && defined(RAMSTART)
632 #if ((RAMEND - RAMSTART) > 3000)
633 static const int crossingPointBufferSize = 100;
635 static const int crossingPointBufferSize = 25;
638 static const int crossingPointBufferSize = 100;
642 int crossingPointBufferIndex = 0;
643 bool crossingPointBufferFull =
false;
double TRITYPE
Definition DovesLapTimer.h:13
#define DIR_REVERSE
Definition DovesLapTimer.h:35
#define DIR_UNKNOWN
Definition DovesLapTimer.h:33
LineDetectResult
Definition DovesLapTimer.h:48
@ LINE_DETECT_IN_ZONE
Definition DovesLapTimer.h:50
@ LINE_DETECT_NONE
Definition DovesLapTimer.h:49
@ LINE_DETECT_COMPLETED
Definition DovesLapTimer.h:51
const double crossingPointBLat
Definition basic_oled_example.ino:21
const double crossingPointALat
Definition basic_oled_example.ino:19
void loop()
Definition basic_oled_example.ino:116
Definition DovesLapTimer.h:86
unsigned long getBestSector2Time() const
Gets the best sector 2 time.
Definition DovesLapTimer.cpp:843
unsigned long getLastLapTime() const
Gets the last lap time.
Definition DovesLapTimer.cpp:792
unsigned long getCurrentLapStartTime() const
Gets the current lap start time.
Definition DovesLapTimer.cpp:786
double pointLineSegmentDistance(double pointX, double pointY, double startX, double startY, double endX, double endY)
Calculate the shortest distance between a point and a line segment.
Definition DovesLapTimer.cpp:336
void updateCurrentTime(unsigned long currentTimeMilliseconds)
Updates the current GPS time since midnight.
Definition DovesLapTimer.cpp:771
unsigned long getOptimalLapTime() const
Gets the optimal lap time calculated from best sector times.
Definition DovesLapTimer.cpp:858
float getTotalDistanceTraveled() const
Gets the total distance traveled.
Definition DovesLapTimer.cpp:810
void forceLinearInterpolation()
forces linear interpolation when checking crossing line
Definition DovesLapTimer.cpp:774
float getLastLapDistance() const
Gets the last lap distance.
Definition DovesLapTimer.cpp:804
int getBestSector1LapNumber() const
Gets the lap number that achieved the best sector 1 time.
Definition DovesLapTimer.cpp:865
unsigned long getCurrentLapTime() const
Gets the current lap time.
Definition DovesLapTimer.cpp:789
float getPaceDifference() const
Calculates the pace difference between the current lap and the best lap in milliseconds.
Definition DovesLapTimer.cpp:819
bool getRaceStarted() const
Gets the race started status (passed the line one time).
Definition DovesLapTimer.cpp:780
int getDirection() const
Gets the detected driving direction.
Definition DovesLapTimer.cpp:883
unsigned long getCurrentLapSector2Time() const
Gets the current lap sector 2 time.
Definition DovesLapTimer.cpp:852
void reset()
Reset all parameters back to 0.
Definition DovesLapTimer.cpp:698
void setSector2Line(double pointALat, double pointALng, double pointBLat, double pointBLng)
Sets the sector 2 line using two points (A and B).
Definition DovesLapTimer.cpp:757
int getBestSector3LapNumber() const
Gets the lap number that achieved the best sector 3 time.
Definition DovesLapTimer.cpp:871
bool isObtuseTriangle(double lat1, double lon1, double lat2, double lon2, double lat3, double lon3)
Checks if the triangle formed by the given coordinates is an obtuse triangle.
Definition DovesLapTimer.cpp:288
bool insideLineThreshold(double driverLat, double driverLon, double crossingPointALat, double crossingPointALon, double crossingPointBLat, double crossingPointBLon)
Check if a driver is within a threshold distance of the line formed by the two crossing points.
Definition DovesLapTimer.cpp:262
bool getCrossing() const
Gets the crossing status.
Definition DovesLapTimer.cpp:783
int pointOnSideOfLine(double driverLat, double driverLng, double pointALat, double pointALng, double pointBLat, double pointBLng)
Determines which side of a line a driver is on.
Definition DovesLapTimer.cpp:318
unsigned long getBestSector1Time() const
Gets the best sector 1 time.
Definition DovesLapTimer.cpp:840
void setSector3Line(double pointALat, double pointALng, double pointBLat, double pointBLng)
Sets the sector 3 line using two points (A and B).
Definition DovesLapTimer.cpp:764
int getBestLapNumber() const
Gets the best lap number.
Definition DovesLapTimer.cpp:813
unsigned long getBestSector3Time() const
Gets the best sector 3 time.
Definition DovesLapTimer.cpp:846
float getCurrentLapOdometerStart() const
Gets the current lap odometer start.
Definition DovesLapTimer.cpp:798
unsigned long getCurrentLapSector1Time() const
Gets the current lap sector 1 time.
Definition DovesLapTimer.cpp:849
void setStartFinishLine(double pointALat, double pointALng, double pointBLat, double pointBLng)
Sets the start/finish line using two points (A and B).
Definition DovesLapTimer.cpp:751
bool isDirectionResolved() const
Checks if the driving direction has been resolved.
Definition DovesLapTimer.cpp:886
unsigned long getBestLapTime() const
Gets the best lap time.
Definition DovesLapTimer.cpp:795
void forceCatmullRomInterpolation()
Forces Catmull-Rom spline interpolation when checking crossing line.
Definition DovesLapTimer.cpp:777
float getBestLapDistance() const
Gets the best lap distance.
Definition DovesLapTimer.cpp:807
float getCurrentLapDistance() const
Gets the current lap distance.
Definition DovesLapTimer.cpp:801
double haversine3D(double prevLat, double prevLng, double prevAlt, double currentLat, double currentLng, double currentAlt)
Calculates the distance between two GPS points, including altitude difference.
Definition DovesLapTimer.cpp:371
unsigned long getCurrentLapSector3Time() const
Gets the current lap sector 3 time.
Definition DovesLapTimer.cpp:855
bool areSectorLinesConfigured() const
Checks if sector lines are configured.
Definition DovesLapTimer.cpp:877
int getLaps() const
Gets the total number of laps completed.
Definition DovesLapTimer.cpp:816
int getBestSector2LapNumber() const
Gets the lap number that achieved the best sector 2 time.
Definition DovesLapTimer.cpp:868
double haversine(double lat1, double lon1, double lat2, double lon2)
Calculates the great-circle distance between two points on the Earth's surface using the Haversine fo...
Definition DovesLapTimer.cpp:367
int getCurrentSector() const
Gets the current sector the driver is in.
Definition DovesLapTimer.cpp:874
Definition DovesLapTimer.h:63
DirectionDetector()
Definition DovesLapTimer.h:72
void reset()
Definition DovesLapTimer.h:75
unsigned long lapS2CrossingTime
Definition DovesLapTimer.h:69
void onLineCrossing(int sectorNumber, unsigned long crossingTime)
Definition DovesLapTimer.cpp:524
bool isReverse() const
Definition DovesLapTimer.h:82
bool raceSeen
Definition DovesLapTimer.h:65
unsigned long lapS3CrossingTime
Definition DovesLapTimer.h:70
int direction
Definition DovesLapTimer.h:64
bool isResolved() const
Definition DovesLapTimer.h:83
Definition DovesLapTimer.h:55
double lng
Definition DovesLapTimer.h:57
float speedKmh
Definition DovesLapTimer.h:60
unsigned long time
Definition DovesLapTimer.h:58
float odometer
Definition DovesLapTimer.h:59
double lat
Definition DovesLapTimer.h:56