Migrate to radians instead of degrees to lessen conversion errors
This commit is contained in:
parent
07487e9e51
commit
115e4d9265
@ -6,6 +6,17 @@ namespace file
|
|||||||
{
|
{
|
||||||
namespace simdata
|
namespace simdata
|
||||||
{
|
{
|
||||||
|
Gate::Gate(std::string designator,
|
||||||
|
double latitude,
|
||||||
|
double longitude,
|
||||||
|
std::uint8_t radius)
|
||||||
|
{
|
||||||
|
this->designator = designator;
|
||||||
|
this->center = {geodata::toRadians(latitude),
|
||||||
|
geodata::toRadians(longitude)};
|
||||||
|
this->radius = radius;
|
||||||
|
}
|
||||||
|
|
||||||
Gate::Gate(std::string designator,
|
Gate::Gate(std::string designator,
|
||||||
struct geodata::point center,
|
struct geodata::point center,
|
||||||
std::uint8_t radius)
|
std::uint8_t radius)
|
||||||
|
|||||||
@ -21,11 +21,9 @@ namespace file
|
|||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Representation of gate
|
* Representation of gate
|
||||||
* Heading in degrees (0...360)
|
* Center in lat/lon radians
|
||||||
* Radius in metres
|
* Radius in metres
|
||||||
*
|
*
|
||||||
* Designator must be null terminated
|
|
||||||
*
|
|
||||||
* UINT8 | CHAR[] | POINT | UINT8
|
* UINT8 | CHAR[] | POINT | UINT8
|
||||||
* -------+------------+--------+-------
|
* -------+------------+--------+-------
|
||||||
* STRLEN | DESIGNATOR | CENTER | RADIUS
|
* STRLEN | DESIGNATOR | CENTER | RADIUS
|
||||||
@ -38,6 +36,12 @@ namespace file
|
|||||||
std::uint8_t radius;
|
std::uint8_t radius;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
// From X-Plane or MakeRwys
|
||||||
|
Gate(std::string designator,
|
||||||
|
double latitude,
|
||||||
|
double longitude,
|
||||||
|
std::uint8_t radius);
|
||||||
|
// From Database
|
||||||
Gate(std::string designator,
|
Gate(std::string designator,
|
||||||
struct geodata::point center,
|
struct geodata::point center,
|
||||||
std::uint8_t radius);
|
std::uint8_t radius);
|
||||||
@ -48,8 +52,9 @@ namespace file
|
|||||||
inline const std::string to_string() const
|
inline const std::string to_string() const
|
||||||
{
|
{
|
||||||
std::ostringstream str;
|
std::ostringstream str;
|
||||||
str << "Gate " << this->designator << " at " << this->center.latitude
|
str << "Gate " << this->designator << " at "
|
||||||
<< "N " << this->center.longitude << "E, Radius "
|
<< geodata::toDegrees(this->center.latitude) << "N "
|
||||||
|
<< geodata::toDegrees(this->center.longitude) << "E, Radius "
|
||||||
<< (int)this->radius;
|
<< (int)this->radius;
|
||||||
return str.str();
|
return str.str();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,24 +21,22 @@ namespace file
|
|||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Representation of one runway with supplementary information
|
* Representation of one runway with supplementary information
|
||||||
* Heading in degrees (0...360) true
|
* Heading in radians true
|
||||||
|
* Threshold center in lat/lon radians
|
||||||
* Width and length in meters
|
* Width and length in meters
|
||||||
*
|
*
|
||||||
* Designator must be null terminated
|
* UINT8 | CHAR[] | POINT | UINT8 | UINT16 | DOUBLE
|
||||||
*
|
|
||||||
* UINT8 | CHAR[] | BOX | UINT8 | UINT16 | UINT16
|
|
||||||
* -------+------------+--------+-------+--------+-------
|
* -------+------------+--------+-------+--------+-------
|
||||||
* STRLEN | DESIGNATOR | BOUNDS | WIDTH | LENGTH | TRUHDG
|
* STRLEN | DESIGNATOR | CENTER | WIDTH | LENGTH | TRUHDG
|
||||||
*/
|
*/
|
||||||
class Runway
|
class Runway
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
std::string designator;
|
std::string designator;
|
||||||
struct geodata::box bounds;
|
struct geodata::point center;
|
||||||
std::uint8_t width;
|
std::uint8_t width;
|
||||||
std::uint16_t length;
|
std::uint16_t length;
|
||||||
std::uint16_t trueHeading;
|
double trueHeading;
|
||||||
std::vector<std::uint8_t> file;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// From X-Plane or MakeRwys
|
// From X-Plane or MakeRwys
|
||||||
@ -50,27 +48,22 @@ namespace file
|
|||||||
double width);
|
double width);
|
||||||
// From database
|
// From database
|
||||||
Runway(std::string designator,
|
Runway(std::string designator,
|
||||||
struct geodata::box bounds,
|
struct geodata::point center,
|
||||||
std::uint8_t width,
|
std::uint8_t width,
|
||||||
std::uint16_t length,
|
std::uint16_t length,
|
||||||
std::uint16_t trueHeading);
|
double trueHeading);
|
||||||
|
|
||||||
void toFile(std::ofstream &out) const;
|
void toFile(std::ofstream &out) const;
|
||||||
|
|
||||||
inline const std::string to_string() const
|
inline const std::string to_string() const
|
||||||
{
|
{
|
||||||
std::ostringstream str;
|
std::ostringstream str;
|
||||||
str << "Runway " << this->designator << " with bounds "
|
str << "Runway " << this->designator << " with threshold center "
|
||||||
<< this->bounds.topLeft.latitude << "N "
|
<< geodata::toDegrees(this->center.latitude) << "N "
|
||||||
<< this->bounds.topLeft.longitude << "E, "
|
<< geodata::toDegrees(this->center.longitude) << "E, Width "
|
||||||
<< this->bounds.topRight.latitude << "N "
|
<< (int)this->width << "m, Length " << this->length
|
||||||
<< this->bounds.topRight.longitude << "E, "
|
<< "m, True Heading " << geodata::toDegrees(this->trueHeading)
|
||||||
<< this->bounds.bottomRight.latitude << "N "
|
<< "°";
|
||||||
<< this->bounds.bottomRight.longitude << "E, "
|
|
||||||
<< this->bounds.bottomLeft.latitude << "N "
|
|
||||||
<< this->bounds.bottomLeft.longitude << "E, "
|
|
||||||
<< "Width " << (int)this->width << "m, Length " << this->length
|
|
||||||
<< "m, True Heading " << this->trueHeading << "°";
|
|
||||||
return str.str();
|
return str.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -19,25 +19,22 @@ namespace file
|
|||||||
longitudeStart,
|
longitudeStart,
|
||||||
latitudeEnd,
|
latitudeEnd,
|
||||||
longitudeEnd);
|
longitudeEnd);
|
||||||
this->trueHeading =
|
this->trueHeading = geodata::bearingDR(latitudeStart,
|
||||||
(std::uint16_t)std::round(geodata::bearingDD(latitudeStart,
|
longitudeStart,
|
||||||
longitudeStart,
|
latitudeEnd,
|
||||||
latitudeEnd,
|
longitudeEnd);
|
||||||
longitudeEnd));
|
this->center = {geodata::toRadians(latitudeStart),
|
||||||
this->bounds = geodata::calculateBoxDD({latitudeStart, longitudeStart},
|
geodata::toRadians(longitudeStart)};
|
||||||
{latitudeEnd, longitudeEnd},
|
|
||||||
this->trueHeading,
|
|
||||||
this->width);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Runway::Runway(std::string designator,
|
Runway::Runway(std::string designator,
|
||||||
geodata::box bounds,
|
geodata::point center,
|
||||||
std::uint8_t width,
|
std::uint8_t width,
|
||||||
std::uint16_t length,
|
std::uint16_t length,
|
||||||
std::uint16_t trueHeading)
|
double trueHeading)
|
||||||
{
|
{
|
||||||
this->designator = designator;
|
this->designator = designator;
|
||||||
this->bounds = bounds;
|
this->center = center;
|
||||||
this->width = width;
|
this->width = width;
|
||||||
this->length = length;
|
this->length = length;
|
||||||
this->trueHeading = trueHeading;
|
this->trueHeading = trueHeading;
|
||||||
@ -46,7 +43,7 @@ namespace file
|
|||||||
void Runway::toFile(std::ofstream &out) const
|
void Runway::toFile(std::ofstream &out) const
|
||||||
{
|
{
|
||||||
writeString(out, this->designator);
|
writeString(out, this->designator);
|
||||||
write<decltype(this->bounds)>(out, this->bounds);
|
write<decltype(this->center)>(out, this->center);
|
||||||
write<decltype(this->width)>(out, this->width);
|
write<decltype(this->width)>(out, this->width);
|
||||||
write<decltype(this->length)>(out, this->length);
|
write<decltype(this->length)>(out, this->length);
|
||||||
write<decltype(this->trueHeading)>(out, this->trueHeading);
|
write<decltype(this->trueHeading)>(out, this->trueHeading);
|
||||||
|
|||||||
@ -25,6 +25,8 @@ namespace file
|
|||||||
toLog("Sim Database updated");
|
toLog("Sim Database updated");
|
||||||
} else {
|
} else {
|
||||||
this->fromFile();
|
this->fromFile();
|
||||||
|
|
||||||
|
toLog("Sim Database loaded");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,14 +67,14 @@ namespace file
|
|||||||
std::uint8_t numRunways = read<std::uint8_t>(in);
|
std::uint8_t numRunways = read<std::uint8_t>(in);
|
||||||
for (int j = 0; j < numRunways; j++) {
|
for (int j = 0; j < numRunways; j++) {
|
||||||
std::string designator = readString(in);
|
std::string designator = readString(in);
|
||||||
// Bounds
|
// Center
|
||||||
struct geodata::box bounds = read<struct geodata::box>(in);
|
struct geodata::point center = read<struct geodata::point>(in);
|
||||||
std::uint8_t width = read<std::uint8_t>(in);
|
std::uint8_t width = read<std::uint8_t>(in);
|
||||||
std::uint16_t length = read<std::uint16_t>(in);
|
std::uint16_t length = read<std::uint16_t>(in);
|
||||||
std::uint16_t trueHeading = read<std::uint16_t>(in);
|
double trueHeading = read<double>(in);
|
||||||
|
|
||||||
this->airports[icao].second.emplace_back(designator,
|
this->airports[icao].second.emplace_back(designator,
|
||||||
bounds,
|
center,
|
||||||
width,
|
width,
|
||||||
length,
|
length,
|
||||||
trueHeading);
|
trueHeading);
|
||||||
|
|||||||
@ -153,10 +153,10 @@ namespace file
|
|||||||
}
|
}
|
||||||
gateName += fields.back();
|
gateName += fields.back();
|
||||||
gateName = std::regex_replace(gateName, std::regex{","}, "0");
|
gateName = std::regex_replace(gateName, std::regex{","}, "0");
|
||||||
struct geodata::point pt {
|
gates.emplace_back(gateName,
|
||||||
std::stod(fields[1]), std::stod(fields[2])
|
std::stod(fields[1]),
|
||||||
};
|
std::stod(fields[2]),
|
||||||
gates.emplace_back(gateName, pt, 40);
|
40);
|
||||||
}
|
}
|
||||||
|
|
||||||
void makeRunway(std::vector<Runway> &runways,
|
void makeRunway(std::vector<Runway> &runways,
|
||||||
@ -186,10 +186,10 @@ namespace file
|
|||||||
gateName += fields.back();
|
gateName += fields.back();
|
||||||
gateName = std::regex_replace(gateName, std::regex{","}, "0");
|
gateName = std::regex_replace(gateName, std::regex{","}, "0");
|
||||||
|
|
||||||
struct geodata::point pt {
|
gates.emplace_back(gateName,
|
||||||
std::stod(fields[1]), std::stod(fields[2])
|
std::stod(fields[1]),
|
||||||
};
|
std::stod(fields[2]),
|
||||||
gates.emplace_back(gateName, pt, 40);
|
40);
|
||||||
}
|
}
|
||||||
} // namespace simdata
|
} // namespace simdata
|
||||||
} // namespace file
|
} // namespace file
|
||||||
|
|||||||
@ -41,11 +41,16 @@ namespace geodata
|
|||||||
|
|
||||||
static inline double toRadians(double value) { return value * M_PI / 180; }
|
static inline double toRadians(double value) { return value * M_PI / 180; }
|
||||||
|
|
||||||
static inline double normalize(double value)
|
static inline double normalizeD(double value)
|
||||||
{
|
{
|
||||||
return fmod(value + 360, 360);
|
return fmod(value + 360, 360);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline double normalizeR(double value)
|
||||||
|
{
|
||||||
|
return value < 0 ? 2 * M_PI + value : value;
|
||||||
|
}
|
||||||
|
|
||||||
// Input and Output in degrees
|
// Input and Output in degrees
|
||||||
static inline double bearingDD(double fromLatitude,
|
static inline double bearingDD(double fromLatitude,
|
||||||
double fromLongitude,
|
double fromLongitude,
|
||||||
@ -58,7 +63,22 @@ namespace geodata
|
|||||||
sin(toRadians(fromLatitude)) * cos(toRadians(toLatitude)) *
|
sin(toRadians(fromLatitude)) * cos(toRadians(toLatitude)) *
|
||||||
cos(toRadians(toLongitude) - toRadians(fromLongitude));
|
cos(toRadians(toLongitude) - toRadians(fromLongitude));
|
||||||
|
|
||||||
return normalize(toDegrees(atan2(y, x)));
|
return normalizeD(toDegrees(atan2(y, x)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Input in degrees, Output in radians
|
||||||
|
static inline double bearingDR(double fromLatitude,
|
||||||
|
double fromLongitude,
|
||||||
|
double toLatitude,
|
||||||
|
double toLongitude)
|
||||||
|
{
|
||||||
|
double y = sin(toRadians(toLongitude) - toRadians(fromLongitude)) *
|
||||||
|
cos(toRadians(toLatitude));
|
||||||
|
double x = cos(toRadians(fromLatitude)) * sin(toRadians(toLatitude)) -
|
||||||
|
sin(toRadians(fromLatitude)) * cos(toRadians(toLatitude)) *
|
||||||
|
cos(toRadians(toLongitude) - toRadians(fromLongitude));
|
||||||
|
|
||||||
|
return normalizeR(atan2(y, x));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Input in degrees, Output in metres
|
// Input in degrees, Output in metres
|
||||||
|
|||||||
@ -130,6 +130,19 @@ PLUGIN_API int XPluginStart(char *outName, char *outSig, char *outDesc)
|
|||||||
toLog);
|
toLog);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toLog("Readback test of sim database using EDDF");
|
||||||
|
auto ap = (*database)["EDDF"];
|
||||||
|
for (const auto &it : ap.first) {
|
||||||
|
toLog(" " + it.to_string());
|
||||||
|
}
|
||||||
|
for (const auto &it : ap.second) {
|
||||||
|
toLog(" " + it.to_string());
|
||||||
|
}
|
||||||
|
toLog("Readback test of sim database using XXXX");
|
||||||
|
auto ap2 = (*database)["XXXX"];
|
||||||
|
ap2.first.size() == 0 ? toLog(" SUCCESS") : toLog(" ERROR");
|
||||||
|
|
||||||
|
|
||||||
// Thread for sending data to websocket
|
// Thread for sending data to websocket
|
||||||
serverThread = std::thread(&serverWorker);
|
serverThread = std::thread(&serverWorker);
|
||||||
recordingThread = std::thread(&recordingWorker);
|
recordingThread = std::thread(&recordingWorker);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user