24#define MAX_N_INTERVAL 1000
26#define MIN_VMC_RATIO 0.5
27#define MAX_N_HISTORY 20
28#define MAX_UNREACHABLE 0
58static inline double distSegmentWithFoot(
double latX,
double lonX,
double latA,
double lonA,
double latB,
double lonB,
double *latH,
double *lonH) {
62 const double xA = lonA * cosLat * 60.0, yA = latA * 60.0;
63 const double xB = lonB * cosLat * 60.0, yB = latB * 60.0;
64 const double xX = lonX * cosLat * 60.0, yX = latX * 60.0;
67 const double ABx = xB - xA, ABy = yB - yA;
68 const double AXx = xX - xA, AXy = yX - yA;
71 const double AB_AB = ABx * ABx + ABy * ABy;
73 if (latH) *latH = latA;
74 if (lonH) *lonH = lonA;
75 return hypot(AXx, AXy);
78 double t = (AXx * ABx + AXy * ABy) / AB_AB;
79 t =
CLAMP(t, 0.0, 1.0);
81 const double xH = xA + t * ABx;
82 const double yH = yA + t * ABy;
84 if (latH) *latH = yH / 60.0;
85 if (lonH) *lonH = (cosLat > 0.0) ? (xH / (60.0 * cosLat)) : lonA;
87 return hypot(xX - xH, yX - yH);
93 double dSquare, dSquareMax = 0.0;
95 if (size <= 1)
return 0;
98 for (
int i = 0; i < size; i++) {
99 next = (i >= size -1) ? 0 : i + 1;
101 double deltaLat =
isocArray [baseIndex + i].
lat - nextLat;
104 dSquare = deltaLat * deltaLat + deltaLon * deltaLon;
105 if (dSquare > dSquareMax) {
106 dSquareMax = dSquare;
125 double focalLat, focalLon;
126 const double epsilonDenominator = 0.01;
127 const int thresholdSector = 5;
129 const double thetaStep = 360.0 / nSectors;
130 const double invThetaStep = 1.0 / thetaStep;
131 const double denominator = cos (
DEG_TO_RAD * (pOr->
lat + pDest->
lat) * 0.5);
133 if (denominator < epsilonDenominator) {
134 fprintf (stderr,
"In forwardSectorOptimize, Error denominator: %.8lf\n", denominator);
146 focalLat = pOr->
lat + dLat / 60.0;
147 focalLon = pOr->
lon + dLon / 60.0;
148 if (focalLat < -90.0 || focalLat > 90.0) {
149 fprintf (stderr,
"In forwardSectorOptimize, Error lat: %.2lf\n", focalLat);
152 if (focalLon < -360.0 || focalLon > 360.0) {
153 fprintf (stderr,
"In forwardSectorOptimize, Error lon: %.2f", focalLon);
160 const int currentSector =
nIsoc % 2;
161 const int previousSector = (
nIsoc - 1) % 2;
165 for (
int i = 0; i < isoLen; i++) {
166 const Pp *iso = &isoList[i];
168 const double alpha =
orthoCap (focalLat, focalLon, iso->
lat, iso->
lon);
171 if (theta < 0) theta += 360.0;
172 else if (theta >= 360.0) theta -= 360.0;
174 int iSector = round ((360.0 - theta) * invThetaStep);
178 if (iso->
vmc > sect->
vmc) {
181 optIsoc [iSector] = *iso;
187 for (iSector = 0; iSector < nSectors; iSector += 1) {
188 const Sector *current = &
sector[currentSector][iSector];
189 const Sector *previous = &
sector[previousSector][iSector];
191 if ((current->
nPt > 0) &&
192 (current->
vmc < pOr->
dd * 1.1) &&
194 ((current->
vmc >= previous->
vmc))) {
196 optIsoc[k] = optIsoc [iSector];
205static inline int optimize (
const Pp *pOr,
const Pp *pDest,
int nIsoc,
int algo,
const Pp *isoList,
int isoLen,
Pp *optIsoc) {
208 memcpy (optIsoc, isoList, isoLen *
sizeof (
Pp));
219 double t,
double dt,
Pp *newList,
double *bestVmc,
double *biggestOrthoVmc) {
220 static const double epsilon = 0.01;
223 double u, v, gust, w, twa, sog, uCurr, vCurr, currTwd, currTws, vDirectCap;
224 double dLat, dLon, penalty, efficiency;
225 double waveCorrection, invDenominator, twd, tws;
229 *biggestOrthoVmc = 0;
231 for (
int k = 0; k < isoLen; k++) {
232 const Pp *isoPt = &isoList[k];
251 for (
double cog = minCog; cog <= maxCog; cog +=
par.
cogStep) {
252 twa =
fTwa (cog, twd);
263 newPt.
motor = useMotor;
264 waveCorrection = 1.0;
268 sog *= waveCorrection;
273 if (fabs (twa) < 90.0) penalty =
par.
penalty0 / 3600.0;
280 double realDt = dt - penalty;
283 dLat = sog * (realDt) * cos (
DEG_TO_RAD * cog);
284 dLon = sog * (realDt) * sin (
DEG_TO_RAD * cog) * invDenominator;
288 dLon +=
MS_TO_KN * uCurr * dt * invDenominator;
291 newPt.
lat = isoPt->
lat + dLat / 60.0;
292 newPt.
lon = isoPt->
lon + dLon / 60.0;
305 if (newPt.
vmc > *bestVmc) *bestVmc = newPt.
vmc;
320 for (
int k = 0; k < lIsoc; k++) {
321 if (iso[k].
id == ptId)
return k;
324 fprintf (stderr,
"In findFather, Error ptId not found: %d, Isoc No:%d, Isoc Len: %d\n", ptId, i, lIsoc);
337 for (
int i = 0; i <
nIsoc; i++) {
340 snprintf (line,
MAX_SIZE_LINE,
"%03d; %03d; %03d; %03d; %03d; %07.2lf; %07.2lf; %s; %s\n", i,
isoDesc [i].toIndexWp,
348 if ((strlen (str) + strlen (line)) > maxLen)
359 if (fileName [0] ==
'\0')
return false;
360 if ((f = fopen (fileName,
"w")) == NULL) {
361 fprintf (stderr,
"In dumpAllIsoc, Error cannot write isoc: %s\n", fileName);
364 fprintf (f,
" n; WP; Lat; Lon; Id; Father; Amure; Sail; Motor; dd; VMC\n");
365 for (
int i = 0; i <
nIsoc; i++) {
368 fprintf (f,
"%03d; %03d; %06.2f; %06.2f; %6d; %6d; %6d; %6d; %6d; %6.2lf; %6.2lf\n",\
369 i, pt.
toIndexWp, pt.
lat, pt.
lon, pt.
id, pt.
father, pt.
amure, pt.
sail, pt.
motor, pt.
dd, pt.
vmc);
381 fprintf (stderr,
"In saveRoute, Error: MAX_N_HISTORY reached: %d\n",
MAX_N_HISTORY);
385 if (newRoutes == NULL) {
386 fprintf (stderr,
"In saveRoute, Error: Memory allocation failed\n");
396 fprintf (stderr,
"In saveRoute, Error: Memory allocation for SailPoint array failed\n");
424 const double epsilon = 0.00001;
425 const double epsilonSog = 0.001;
427 if (
route->
n == 0)
return;
428 fprintf (stdout,
"route.n = %d\n",
route->
n);
431 free (polarFileName);
442 route -> t[0].time = 0;
446 for (
int i = 1; i <
route->
n; i++) {
453 fprintf (stdout,
"i = %d, WayPoint no: %d\n", i,
route-> t[i-1].toIndexWp);
464 if (deltaTime > epsilon) {
465 sog =
route->
t [i-1].
od / deltaTime;
468 if (sog < epsilonSog && i > 1) {
486 if ((i > 1) && (
route-> t [i-1].sail !=
route-> t [i-2].sail)) {
491 if ((i > 1) && (
route-> t [i-1].amure !=
route-> t [i-2].amure)) {
515 if (! manoeuvre && i > 1) {
578 fprintf (stdout,
"pDest with id: %d, father: %d, toIndexWp: %d, route.n: %d\n",
581 for (
int i =
route->
n - 3; i >= 0; i--) {
585 fprintf (stdout,
"In storeRoute: ERROR findFather at isoc: %d\n", i);
590 fprintf (stdout,
"In storeRoute: ERROR isoc: %d pt.toIndexWp: %d\n", i, pt.
toIndexWp);
616 if (motor)
g_strlcpy (str,
"Mot", maxLen);
637 fprintf (stderr,
"In routeToStr, maxLen too small: %zu\n", maxLen);
643 g_strlcpy (str,
" No; WP; Lat; Lon; Date-Time; Sail; M/T/B; HDG;\
644 Dist; SOG; Twd; Twa; Tws; Gust; Awa; Aws; Waves; Stamina\n",
MAX_SIZE_LINE);
646 " pOr; %3d; %-12s;%-12s; %s; %-8s; %6s; %4d°; %7.2lf; %7.2lf; %4d°; %4.0lf°; %7.2lf; %7.2lf; %4.0lf°; %7.2lf; %7.2lf; %7.2lf\n",\
659 for (
int i = 1; i <
route->
n; i++) {
662 if (aws > maxAws) maxAws = aws;
665 snprintf (line,
MAX_SIZE_LINE,
" Isoc %3d: Error on latitude or longitude\n", i-1);
668 "%4d; %3d; %-12s;%-12s; %s; %-8s; %6s; %4d°; %7.2f; %7.2lf; %4d°; %4.0lf°; %7.2lf; %7.2lf; %4.0lf°; %7.2lf; %7.2lf; %7.2lf\n",\
688 snprintf (line,
MAX_SIZE_LINE,
" Total duration : %sHours\n", \
698 snprintf (footer, maxLenFooter,
"%s Arrival: %s Route length: %d, Isoc time Step: %.2lf",
712static inline bool simpleGoalP (
const Pp *pA,
const Pp *pDest,
double t,
double dt,
double *timeTo,
713 double *distance,
bool *motor,
int *amure,
int *sail) {
714 static const double epsilon = 0.1;
715 double u, v, gust, w, twd, tws, sog, efficiency;
722 const double dLat = pDest->
lat - pA->
lat;
723 const double dLon = (pDest->
lon - pA->
lon) * coeffLat;
724 const double cog =
RAD_TO_DEG * atan2(dLon, dLat);
730 const double twa =
fTwa(cog, twd);
754 if (waveCorrection > 0.0) sog *= waveCorrection * 0.01;
757 if (sog <= epsilon) {
766 return (sog * dt) >= d;
772static inline bool simpleGoal (
Pp *pDest,
Pp *isoList,
int len,
double t,
double dt,
double *lastStepDuration,
bool *motor,
int *amure) {
773 double bestTime = DBL_MAX, time, distance;
774 bool destinationReached =
false, locMotor, bestMotor =
false;
775 int sail, locAmure, bestAmure = 0;
777 for (
int k = 0; k < len; k++) {
778 const Pp *curr = &isoList[k];
780 if (
simpleGoalP (curr, pDest, t, dt, &time, &distance, &locMotor, &locAmure, &sail)) {
781 destinationReached =
true;
783 if (time < bestTime) {
785 if (destinationReached) {
787 pDest->
motor = *motor;
788 pDest->
amure = *amure;
790 bestMotor = locMotor;
791 bestAmure = locAmure;
797 *lastStepDuration = bestTime;
800 return destinationReached;
811static inline bool goalP (
const Pp *pA,
const Pp *pB,
const Pp *pDest,
double t,
812 double dt,
double *timeTo,
813 double *distance,
bool *motor,
int *amure,
int *sail,
bool *bestFirst) {
814 static const double epsilon = 0.1;
815 double u, v, gust, w, twd, tws, twa, sog, efficiency;
819 double bestLat, bestLon;
837 const double coeffLat = cos(
DEG_TO_RAD * ((bestLat + pDest->
lat) * 0.5));
838 const double dLat = pDest->
lat - bestLat;
839 const double dLon = (pDest->
lon - bestLon) * coeffLat;
840 const double cog =
RAD_TO_DEG * atan2(dLon, dLat);
843 findWindGrib(bestLat, bestLon, t, &u, &v, &gust, &w, &twd, &tws);
846 twa =
fTwa(cog, twd);
870 if (waveCorrection > 0) sog *= (waveCorrection / 100.0);
873 if (sog <= epsilon) {
879 *timeTo = *distance / sog;
882 return (sog * dt) > fmin (distToSegment, *distance);
889static inline bool goal (
Pp *pDest,
Pp *isoList,
int len,
double t,
double dt,
double *lastStepDuration,
bool *motor,
int *amure) {
890 double bestTime = DBL_MAX;
891 double time, distance;
892 bool destinationReached =
false;
895 const Pp *prev = &isoList[0];
898 for (
int k = 1; k < len; k++) {
899 const Pp *curr = &isoList[k];
901 if (
goalP (prev, curr, pDest, t, dt, &time, &distance, motor, amure, &sail, &bestFirst)) {
902 destinationReached =
true;
904 if (time < bestTime) {
906 if (destinationReached) {
907 pDest->
father = bestFirst ? prev->
id : curr->
id;
908 pDest->
motor = *motor;
909 pDest->
amure = *amure;
918 *lastStepDuration = bestTime;
919 return destinationReached;
925 double lastClosestDist = DBL_MAX;
929 for (i = 0; i < n; i++) {
930 const Pp *curr = &isoc[i];
932 if (d < lastClosestDist) {
949 memcpy(dst, src, len *
sizeof(
Pp));
951 for (
int i = 0; i < len; i++) {
952 int idSrc = src [i].
id;
953 dst[i].id = idSrc + len;
954 dst[i].father = idSrc;
966static int routing (
Pp *pOr,
Pp *pDest,
int toIndexWp,
double t,
double dt,
double *lastStepDuration) {
967 const double minStep = 0.25;
971 double timeToReach = 0;
978 fprintf (stderr,
"In routing: time step for routing <= %.2lf\n", minStep);
983 fprintf (stderr,
"in routing: error in memory templIst allocation\n");
989 fprintf (stderr,
"in routing maxNIsoc exeed MAX_N_ISOC\n");
995 if (tempIsocArray == NULL) {
996 fprintf (stderr,
"in routing: realloc error for isocArray\n");
1003 if (tempIsoDesc == NULL) {
1004 fprintf (stderr,
"in routing: realloc for IsoDesc failed\n");
1012 if (tempSailPoint == NULL) {
1013 fprintf (stderr,
"in routing: realloc for route.t failed\n");
1026 tempList [0] = *pOr;
1029 if (
goalP (pOr, pOr, pDest, t, dt, &timeToReach, &distance, &motor, &amure, &sail, &bidon)) {
1031 pDest->
motor = motor;
1032 pDest->
amure = amure;
1034 *lastStepDuration = timeToReach;
1036 fprintf (stdout,
"destination reached directly. No isochrone\n");
1044 fprintf (stderr,
"In routing: isoc Size error, nIsoc: %d\n",
nIsoc);
1073 fprintf (stderr,
"In routing, goal reached but no wind at isoc: %d\n",
nIsoc);
1079 *lastStepDuration = timeLastStep;
1081 fprintf (stdout,
"pDest.id: %d, pDest.father: %d, pDest.toIndexWP: %d\n", pDest->
id, pDest->
father, pDest->
toIndexWp);
1087 if (lTempList == -1) {
1089 fprintf (stderr,
"In routing: buildNextIsochrone return: -1 value. See MAX_SIZE_ISOC\n");
1094 fprintf (stderr,
"In routing, no wind at isoc: %d\n",
nIsoc);
1103 *lastStepDuration = 0.0;
1143 double foot0Lat, foot0Lon, foot1Lat, foot1Lon;
1147 if (lastI < 1)
return;
1155 int prev = index - 1;
1156 if (prev < 0) prev = size - 1;
1157 int next = index + 1;
1158 if (next >= size) next = 0;
1171 pCurr.
lat, pCurr.
lon, &foot0Lat, &foot0Lon);
1174 pCurr.
lat, pCurr.
lon, &foot1Lat, &foot1Lon);
1178 " \"latDest\": %.6lf, \"lonDest\": %.6lf, \"latCurr\": %.6lf, \"lonCurr\": %.6lf,\n"
1179 " \"latPrev\": %.6lf, \"lonPrev\": %.6lf, \"latNext\": %.6lf, \"lonNext\": %.6lf,\n"
1180 " \"latFoot0\": %.6lf, \"lonFoot0\": %.6lf, \"latFoot1\": %.6lf, \"lonFoot1\": %.6lf,\n"
1181 " \"dSeg0\": %.2lf, \"dSeg1\": %.2lf, \"dCurr\": %.2lf,\n"
1182 " \"dPrev\": %.2lf, \"dNext\": %.2lf, \"dFoot0\": %.2lf, \"dFoot1\": %.2lf\n"
1185 foot0Lat, foot0Lon, foot1Lat, foot1Lon,
1186 dSeg0, dSeg1, dCurr,
1187 dPrev, dNext, dFoot0, dFoot1
1193 struct timeval t0, t1;
1195 double lastStepDuration;
1202 gettimeofday (&t0, NULL);
1203 ut0 = t0.tv_sec *
MILLION + t0.tv_usec;
1222 fprintf (stdout,
"After Waypoint; %d, ret: %d, pNext ID: %d, Father: %d\n", i, ret, pNext.
id, pNext.
father);
1252 fprintf (stdout,
"Number of wayPoints: %d\n",
wayPoints.
n);
1254 gettimeofday (&t1, NULL);
1255 ut1 = t1.tv_sec *
MILLION + t1.tv_usec;
1270 double minDuration = DBL_MAX, maxDuration = 0;
1271 int localRet, nUnreachable = 0;
1280 fprintf (stderr,
"In bestTimeDeparture, chooseDeparture.count exceed limit %d\n",
chooseDeparture.
count);
1296 fprintf (stdout,
"Count: %d, time %.2lf, duration: %.2lf, min: %.2lf, bestTime: %.2lf\n", \
1325 fprintf (stdout,
"No solution\n");
1332 bool existSolution =
false;
1340 fprintf (stdout,
"In allCompetitors: competitor: %d\n", i);
1352 fprintf (stderr,
"In allCompetitors, No solution for competitor: %s with return: %d\n",\
1363 existSolution =
true;
1371 time_t now = time (NULL);
1375 struct tm *timeInfos = gmtime (&now);
1382 fprintf (stderr,
"In logReport, Error opening lo report file: %s\n",
par.
logFileName);
1387 fprintf (f,
"logDate; isocStep; nOcc; Reach; nWP; pOr lat; pOr lon; pDest lat; pDest lon; Start; Arrival; toDest; HDG; polar; grib\n");
1390 startDate, sizeof (startDate));
1393 arrivalDate, sizeof (arrivalDate));
1398 fprintf (f,
"%04d-%02d-%02d %02d:%02d:%02d; %4.2lf; %4d; %c; %d; %s; %s; %s; %s; %s; %s; %.2lf; %3d°; %s; %s\n",
1399 timeInfos->tm_year+1900, timeInfos->tm_mon+1, timeInfos->tm_mday,
1400 timeInfos->tm_hour, timeInfos->tm_min, timeInfos->tm_sec,
1414 free (polarFileName);
1415 free (gribFileName);
1423 if (!
route || ! fileName || fileName [0] ==
'\0')
return false;
1425 if ((f = fopen (fileName,
"w")) == NULL) {
1426 fprintf (stderr,
"In exportRouteToGpx: Impossible to write open %s:", fileName);
1430 fprintf (f,
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
1431 fprintf (f,
"<gpx version=\"1.1\" creator=\"%s\" xmlns=\"http://www.topografix.com/GPX/1/1\">\n",
PROG_NAME);
1432 fprintf (f,
" <rte>\n");
1433 fprintf (f,
" <name>Maritime Route</name>\n");
1436 for (
int i = 0; i <
route->
n; i++) {
1441 fprintf (f,
" <rtept lat=\"%.6f\" lon=\"%.6f\">\n", p->
lat, p->
lon);
1442 fprintf (f,
" <name>%d</name>\n", i);
1443 fprintf (f,
" <time>%s</time>\n", strTime);
1444 fprintf (f,
" <course>%.2f</course>\n", fmod (p->
oCap + 360.0, 360.0));
1445 fprintf (f,
" <speed>%.2f</speed>\n", p->
sog);
1446 fprintf (f,
" </rtept>\n");
1449 fprintf (f,
" <name>Destination</name>\n");
1450 fprintf (f,
" </rtept>\n");
1452 fprintf (f,
" </rte>\n");
1453 fprintf (f,
"</gpx>\n");
1456 printf (
"GPX file:%s generated\n", fileName);
#define MAX_N_INTERVAL
\Engine tws = True Wind Speed twd = True Wind Direction twa = True Wind Angle - the angle of the boat...
void * bestTimeDeparture()
choose best time to reach pDest in minimum time
static double tDeltaCurrent
bool storeRoute(SailRoute *route, const Pp *pOr, const Pp *pDest)
store route response false if error
void freeHistoryRoute()
free space for history route
static char * motorTribordBabord(bool motor, int amure, char *str, size_t maxLen)
produce string that says if Motor, Tribord, Babord
static double distSegmentWithFoot(double latX, double lonX, double latA, double lonA, double latB, double lonB, double *latH, double *lonH)
return distance (nm) from point X do segment [AB].
void saveRoute(SailRoute *route)
store current route in history
static void replicate(int n)
when no wind, build next isochrone as a replica of previous isochrone Manage carefully id and father ...
static int forwardSectorOptimize(const Pp *pOr, const Pp *pDest, int nIsoc, const Pp *isoList, int isoLen, Pp *optIsoc)
reduce the size of Isolist note influence of parameters par.nSector, par.jFactor and par....
static bool goal(Pp *pDest, Pp *isoList, int len, double t, double dt, double *lastStepDuration, bool *motor, int *amure)
true if goal can be reached directly in dt from isochrone update isoDesc side effect : pDest....
static int routing(Pp *pOr, Pp *pDest, int toIndexWp, double t, double dt, double *lastStepDuration)
find optimal routing from p0 to pDest using grib file and polar return number of steps to reach pDest...
static void initSector(int nIsoc, int nMax)
initialization of sector
static void statRoute(SailRoute *route)
add additionnal information to the route
static int findFather(int ptId, int i, int lIsoc)
find father of point in previous isochrone
bool isoDescToStr(char *str, size_t maxLen)
copy isoc Descriptors in a string true if enough space, false if truncated
bool routeToStr(const SailRoute *route, char *str, size_t maxLen, char *footer, size_t maxLenFooter)
copy route in a string true if enough space, false if truncated
static void initRouting(void)
global variable initialization for routing
static bool goalP(const Pp *pA, const Pp *pB, const Pp *pDest, double t, double dt, double *timeTo, double *distance, bool *motor, int *amure, int *sail, bool *bestFirst)
return closest index point to pDest in Isoc, and this point
ChooseDeparture chooseDeparture
static int buildNextIsochrone(const Pp *pOr, const Pp *pDest, const Pp *isoList, int isoLen, double t, double dt, Pp *newList, double *bestVmc, double *biggestOrthoVmc)
build the new list describing the next isochrone, starting from isoList returns length of the newlist...
void * routingLaunch()
launch routing with parameters
static int optimize(const Pp *pOr, const Pp *pDest, int nIsoc, int algo, const Pp *isoList, int isoLen, Pp *optIsoc)
choice of algorithm used to reduce the size of Isolist
SailRoute route
store sail route calculated in engine.c by routing
static bool simpleGoalP(const Pp *pA, const Pp *pDest, double t, double dt, double *timeTo, double *distance, bool *motor, int *amure, int *sail)
return true if pDest can be reached from pA - in less time than dt timeTo give the time to get to pDe...
HistoryRouteList historyRoute
static bool simpleGoal(Pp *pDest, Pp *isoList, int len, double t, double dt, double *lastStepDuration, bool *motor, int *amure)
true if goal can be reached directly in dt from isochrone update isoDesc side effect : pDest....
bool dumpIsocToFile(const char *fileName)
write in CSV file Isochrones
void logReport(int n)
log one CSV line report.
void * allCompetitors()
launch all competitors
Sector sector[2][MAX_N_SECTORS]
bool exportRouteToGpx(const SailRoute *route, const char *fileName)
export route with GPX format
static void checkArrival(SailRoute *route, Pp *pDest)
check arrival between pDest and segments [pPrev-pCurr] and [pCurr-pNext] pFoot0 is the projection of ...
static double calcDuration(SailRoute *route)
return the total duration of the route, taking into acount last steps duration
static int findFirst(int nIsoc)
find first point in isochrone.
Pp * isocArray
global variables
static double pOrToPDestCog
static global variable.
static int fClosest(const Pp *isoc, int n, const Pp *pDest, Pp *closest)
return closest index point to pDest in Isoc, and this point
static void g_atomic_int_set(int *x, int val)
Attention NOT SAFE.
#define g_strlcat(dest, src, size)
static int g_atomic_int_get(int *x)
Attention NOT SAFE.
#define g_strlcpy(dest, src, size)
static char * g_path_get_basename(const char *path)
close to Glib g_path_get_basename
void findCurrentGrib(double lat, double lon, double t, double *uCurr, double *vCurr, double *tcd, double *tcs)
use findflow to get current
double zoneTimeDiff(const Zone *zone1, const Zone *zone0)
return difference in hours between two zones (current zone and Wind zone)
void findWindGrib(double lat, double lon, double t, double *u, double *v, double *gust, double *w, double *twd, double *tws)
use findflow to get wind and waves
static bool isInZone(double lat, double lon, Zone *zone)
true if P (lat, lon) is within the zone
static double fTwa(double heading, double twd)
return TWA between -180 and 180 note : tribord amure if twa < 0
static double maxSpeedInPolarAt(double tws, const PolMat *mat)
return max speed of boat at tws for all twa
static bool isSea(char *isSeaArray, double lat, double lon)
this file contains small inlines functions to be included in source files
static double findPolar(double twa, double w, const PolMat *mat, const PolMat *sailMat, int *sail)
find in polar boat speed or wave coeff
static double directCap(double lat1, double lon1, double lat2, double lon2)
return loxodromic cap from origin to destination
static double orthoDist(double lat1, double lon1, double lat2, double lon2)
return orthodromic distance in nautical miles from origin to destination
static double orthoCap(double lat1, double lon1, double lat2, double lon2)
return initial orthodromic cap from origin to destination equivalent to : return directCap (lat1,...
static bool isDay(double t, long dataDate, long dataTime, double lat, double lon)
true if day light, false if night
static double lonCanonize(double lon)
return lon on ]-180, 180 ] interval
static double loxoDist(double lat1, double lon1, double lat2, double lon2)
return loxodromic distance in nautical miles from origin to destination
static void fAwaAws(double twa, double tws, double sog, double *awa, double *aws)
return AWA and AWS Apparent Wind Angle and Speed
static bool isSeaTolerant(char *isSeaArray, double lat, double lon)
say if point is in sea
#define STAMINA_FULL_PACK
WayPointList wayPoints
list of wayPoint
char * lonToStr(double lon, int type, char *str, size_t maxLen)
convert lon to str according to type
char * durationToStr(double duration, char *res, size_t maxLen)
convert hours in string with days, hours, minutes
double fPointLoss(int shipIndex, int type, double tws, bool fullPack)
for virtual Regatta.
PolMat wavePolMat
polar matrix for waves
char * tIsSea
table describing if sea or earth
PolMat polMat
polar matrix description
char * newDate(long intDate, double nHours, char *res, size_t maxLen)
return date and time using ISO notation after adding myTime (hours) to the Date
PolMat sailPolMat
polar matrix for sails
char * fSailName(int val, char *str, size_t maxLen)
return the name of the sail
Zone zone
geographic zone covered by grib file
CompetitorsList competitors
list of competitors
char * latToStr(double lat, int type, char *str, size_t maxLen)
convert lat to str according to type
double fTimeToRecupOnePoint(double tws)
for virtual Regatta.
double t[MAX_N_TIME_STAMPS]
char strETA[MAX_SIZE_DATE]
Competitor t[MAX_N_COMPETITORS]
History Route description
char polarFileName[MAX_SIZE_FILE_NAME]
char gribFileName[MAX_SIZE_FILE_NAME]
char logFileName[MAX_SIZE_FILE_NAME]
char polarFileName[MAX_SIZE_FILE_NAME]
double lastStepWpDuration[MAX_N_WAY_POINT]
char lastPointInfo[MAX_SIZE_INFO]
WayPoint t[MAX_N_WAY_POINT]
long dataTime[MAX_N_DATA_TIME]
long timeStamp[MAX_N_TIME_STAMPS]
long dataDate[MAX_N_DATA_DATE]