forked from microsoft/AirSim
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
added sun moon coordinates utils, set car steering via kbd to softer
- Loading branch information
Showing
11 changed files
with
268 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,209 @@ | ||
/* | ||
Adopted from SunCalc by Vladimir Agafonkin | ||
https://github.com/mourner/suncalc | ||
*/ | ||
|
||
#ifndef airsim_core_EarthCelestial_hpp | ||
#define airsim_core_EarthCelestial_hpp | ||
|
||
|
||
#include "common/Common.hpp" | ||
#include "EarthUtils.hpp" | ||
#include <chrono> | ||
#include <ctime> | ||
|
||
namespace msr { namespace airlib { | ||
|
||
|
||
class EarthCelestial { | ||
public: | ||
|
||
struct CelestialGlobalCoord | ||
{ | ||
double declination; | ||
double rightAscension; | ||
double distance = Utils::nan<double>(); | ||
double parallacticAngle = Utils::nan<double>(); | ||
}; | ||
|
||
struct CelestialLocalCoord | ||
{ | ||
double azimuth; | ||
double altitude; | ||
double distance = Utils::nan<double>(); | ||
double parallacticAngle = Utils::nan<double>(); | ||
}; | ||
|
||
struct CelestialPhase | ||
{ | ||
double fraction; | ||
double phase; | ||
double angle; | ||
}; | ||
|
||
|
||
public: | ||
static CelestialLocalCoord getSunCoordinates(uint64_t date, double lat, double lng) | ||
{ | ||
double lw = Utils::degreesToRadians(-lng); | ||
double phi = Utils::degreesToRadians(lat); | ||
double d = toDays(date); | ||
|
||
CelestialGlobalCoord c = getGlobalSunCoords(d); | ||
double H = siderealTime(d, lw) - c.rightAscension; | ||
|
||
CelestialLocalCoord coord; | ||
coord.azimuth = Utils::radiansToDegrees( azimuth(H, phi, c.declination) ) + 180.0; | ||
coord.altitude = Utils::radiansToDegrees( altitude(H, phi, c.declination) ); | ||
|
||
return coord; | ||
} | ||
|
||
|
||
static CelestialLocalCoord getMoonCoordinates(uint64_t date, double lat, double lng) | ||
{ | ||
|
||
double lw = Utils::degreesToRadians(-lng); | ||
double phi = Utils::degreesToRadians(lat); | ||
double d = toDays(date); | ||
|
||
CelestialGlobalCoord c = getGlobalMoonCoords(d); | ||
double H = siderealTime(d, lw) - c.rightAscension; | ||
|
||
// formula 14.1 of "Astronomical Algorithms" 2nd edition by Jean Meeus (Willmann-Bell, Richmond) 1998. | ||
double pa = std::atan2(std::sin(H), std::tan(phi) * std::cos(c.declination) - std::sin(c.declination) * std::cos(H)); | ||
|
||
double h = altitude(H, phi, c.declination); | ||
h = h + astroRefraction(h); // altitude correction for refraction | ||
|
||
CelestialLocalCoord coord; | ||
coord.azimuth = Utils::radiansToDegrees( azimuth(H, phi, c.declination) ); | ||
coord.altitude = Utils::radiansToDegrees(h); | ||
coord.distance = c.distance; | ||
coord.parallacticAngle = Utils::radiansToDegrees(pa); | ||
return coord; | ||
}; | ||
|
||
|
||
// calculations for illumination parameters of the moon, | ||
// based on http://idlastro.gsfc.nasa.gov/ftp/pro/astro/mphase.pro formulas and | ||
// Chapter 48 of "Astronomical Algorithms" 2nd edition by Jean Meeus (Willmann-Bell, Richmond) 1998. | ||
static CelestialPhase getMoonPhase(uint64_t date) | ||
{ | ||
double d = toDays(date); | ||
CelestialGlobalCoord s = getGlobalSunCoords(d); | ||
CelestialGlobalCoord m = getGlobalMoonCoords(d); | ||
|
||
double sdist = EarthUtils::DistanceFromSun / 1000; // distance from Earth to Sun in km | ||
|
||
double phi = std::acos(std::sin(s.declination) * std::sin(m.declination) + std::cos(s.declination) * std::cos(m.declination) * std::cos(s.rightAscension - m.rightAscension)); | ||
double inc = std::atan2(sdist * std::sin(phi), m.distance - sdist * std::cos(phi)); | ||
double angle = std::atan2(std::cos(s.declination) * std::sin(s.rightAscension - m.rightAscension), std::sin(s.declination) * std::cos(m.declination) - std::cos(s.declination) * std::sin(m.declination) * std::cos(s.rightAscension - m.rightAscension)); | ||
|
||
CelestialPhase moonPhase; | ||
moonPhase.fraction = (1 + cos(inc)) / 2; | ||
moonPhase.phase = 0.5 + 0.5 * inc * (angle < 0 ? -1 : 1) / M_PI; | ||
moonPhase.angle = angle; | ||
return moonPhase; | ||
}; | ||
|
||
|
||
private: | ||
|
||
static double toDays(uint64_t date) | ||
{ | ||
static constexpr double kJulianDaysOnY2000 = 2451545; | ||
static constexpr double kDaysToHours = 60 * 60 * 24; | ||
static constexpr double kJulianDaysOnEpoch = 2440588; | ||
|
||
double julian_days = date / kDaysToHours - 0.5 + kJulianDaysOnEpoch;; | ||
return julian_days - kJulianDaysOnY2000; | ||
} | ||
|
||
|
||
static double rightAscension(double l, double b) | ||
{ | ||
return std::atan2(std::sin(l) * std::cos(EarthUtils::Obliquity) - std::tan(b) * std::sin(EarthUtils::Obliquity), std::cos(l)); | ||
} | ||
|
||
static double declination(double l, double b) | ||
{ | ||
return std::asin(std::sin(b) * std::cos(EarthUtils::Obliquity) + std::cos(b) * std::sin(EarthUtils::Obliquity) * std::sin(l)); | ||
} | ||
|
||
static double azimuth(double H, double phi, double declination) | ||
{ | ||
return std::atan2(std::sin(H), std::cos(H) * std::sin(phi) - std::tan(declination) * std::cos(phi)); | ||
} | ||
|
||
static double altitude(double H, double phi, double declination) | ||
{ | ||
return std::asin(std::sin(phi) * std::sin(declination) + std::cos(phi) * std::cos(declination) * std::cos(H)); | ||
} | ||
|
||
static double siderealTime(double d, double lw) | ||
{ | ||
return Utils::degreesToRadians((280.16 + 360.9856235 * d)) - lw; | ||
} | ||
|
||
static double astroRefraction(double h) | ||
{ | ||
if (h < 0) // the following formula works for positive altitudes only. | ||
h = 0; // if h = -0.08901179 a div/0 would occur. | ||
|
||
// formula 16.4 of "Astronomical Algorithms" 2nd edition by Jean Meeus (Willmann-Bell, Richmond) 1998. | ||
// 1.02 / tan(h + 10.26 / (h + 5.10)) h in degrees, result in arc minutes -> converted to rad: | ||
return 0.0002967 / std::tan(h + 0.00312536 / (h + 0.08901179)); | ||
} | ||
|
||
|
||
static double solarMeanAnomaly(double d) | ||
{ | ||
return Utils::degreesToRadians((357.5291 + 0.98560028 * d)); | ||
} | ||
|
||
static double eclipticLongitude(double M) | ||
{ | ||
double C = Utils::degreesToRadians((1.9148 * std::sin(M) + 0.02 * std::sin(2 * M) + 0.0003 * std::sin(3 * M))); // equation of center | ||
|
||
return M + C + EarthUtils::Perihelion + M_PI; | ||
} | ||
|
||
static CelestialGlobalCoord getGlobalSunCoords(double d) | ||
{ | ||
double M = solarMeanAnomaly(d); | ||
double L = eclipticLongitude(M); | ||
|
||
CelestialGlobalCoord sunCoords; | ||
sunCoords.declination = declination(L, 0); | ||
sunCoords.rightAscension = rightAscension(L, 0); | ||
|
||
return sunCoords; | ||
} | ||
|
||
|
||
// moon calculations, based on http://aa.quae.nl/en/reken/hemelpositie.html formulas | ||
static CelestialGlobalCoord getGlobalMoonCoords(double d) | ||
{ | ||
// geocentric ecliptic coordinates of the moon | ||
|
||
double L = Utils::degreesToRadians((218.316 + 13.176396 * d)); // ecliptic longitude | ||
double M = Utils::degreesToRadians((134.963 + 13.064993 * d)); // mean anomaly | ||
double F = Utils::degreesToRadians((93.272 + 13.229350 * d)); // mean distance | ||
|
||
double l = L + Utils::degreesToRadians(6.289 * std::sin(M)); // longitude | ||
double b = Utils::degreesToRadians(5.128 * std::sin(F)); // latitude | ||
double dt = 385001 - 20905 * std::cos(M); // distance to the moon in km | ||
|
||
CelestialGlobalCoord moonCoords; | ||
moonCoords.rightAscension = rightAscension(l, b); | ||
moonCoords.declination = declination(l, b); | ||
moonCoords.distance = dt; | ||
|
||
return moonCoords; | ||
} | ||
}; | ||
|
||
|
||
}} //namespace | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
#ifndef msr_AirLibUnitTests_CelestialTest_hpp | ||
#define msr_AirLibUnitTests_CelestialTest_hpp | ||
|
||
#include "TestBase.hpp" | ||
#include "common/EarthCelestial.hpp" | ||
|
||
|
||
namespace msr { namespace airlib { | ||
|
||
class CelestialTest : public TestBase | ||
{ | ||
public: | ||
virtual void run() override | ||
{ | ||
auto t = static_cast<uint64_t>(Utils::to_time_t("2018-February-22 15:24:00")); | ||
auto c_sun = EarthCelestial::getSunCoordinates(t, 47.673988, -122.121513); | ||
auto c_moon = EarthCelestial::getMoonCoordinates(t, 47.673988, -122.121513); | ||
auto c_moon_phase = EarthCelestial::getMoonPhase(t); | ||
|
||
testAssert(Utils::isApproximatelyEqual(c_sun.altitude, 19.67, 0.1), "Sun azimuth is not correct"); | ||
testAssert(Utils::isApproximatelyEqual(c_moon.altitude, 45.02, 0.1), "Monn azimuth is not correct"); | ||
testAssert(Utils::isApproximatelyEqual(c_moon_phase.fraction, 0.47, 0.1), "Moon fraction is not correct"); | ||
} | ||
}; | ||
|
||
} } | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters