Skip to content

Commit ad9cbef

Browse files
committedFeb 23, 2018
added sun moon coordinates utils, set car steering via kbd to softer
1 parent e169e65 commit ad9cbef

File tree

11 files changed

+268
-7
lines changed

11 files changed

+268
-7
lines changed
 

‎AirLib/AirLib.vcxproj

+1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
<ClInclude Include="include\common\common_utils\type_utils.hpp" />
5252
<ClInclude Include="include\common\common_utils\Utils.hpp" />
5353
<ClInclude Include="include\common\common_utils\WorkerThread.hpp" />
54+
<ClInclude Include="include\common\EarthCelestial.hpp" />
5455
<ClInclude Include="include\common\SteppableClock.hpp" />
5556
<ClInclude Include="include\common\DelayLine.hpp" />
5657
<ClInclude Include="include\common\EarthUtils.hpp" />

‎AirLib/AirLib.vcxproj.filters

+3
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,9 @@
486486
<ClInclude Include="include\vehicles\multirotor\firmwares\simple_flight\firmware\RungKuttaPidIntegrator.hpp">
487487
<Filter>Header Files</Filter>
488488
</ClInclude>
489+
<ClInclude Include="include\common\EarthCelestial.hpp">
490+
<Filter>Header Files</Filter>
491+
</ClInclude>
489492
</ItemGroup>
490493
<ItemGroup>
491494
<ClCompile Include="src\safety\ObstacleMap.cpp">
+209
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
/*
2+
Adopted from SunCalc by Vladimir Agafonkin
3+
https://github.com/mourner/suncalc
4+
*/
5+
6+
#ifndef airsim_core_EarthCelestial_hpp
7+
#define airsim_core_EarthCelestial_hpp
8+
9+
10+
#include "common/Common.hpp"
11+
#include "EarthUtils.hpp"
12+
#include <chrono>
13+
#include <ctime>
14+
15+
namespace msr { namespace airlib {
16+
17+
18+
class EarthCelestial {
19+
public:
20+
21+
struct CelestialGlobalCoord
22+
{
23+
double declination;
24+
double rightAscension;
25+
double distance = Utils::nan<double>();
26+
double parallacticAngle = Utils::nan<double>();
27+
};
28+
29+
struct CelestialLocalCoord
30+
{
31+
double azimuth;
32+
double altitude;
33+
double distance = Utils::nan<double>();
34+
double parallacticAngle = Utils::nan<double>();
35+
};
36+
37+
struct CelestialPhase
38+
{
39+
double fraction;
40+
double phase;
41+
double angle;
42+
};
43+
44+
45+
public:
46+
static CelestialLocalCoord getSunCoordinates(uint64_t date, double lat, double lng)
47+
{
48+
double lw = Utils::degreesToRadians(-lng);
49+
double phi = Utils::degreesToRadians(lat);
50+
double d = toDays(date);
51+
52+
CelestialGlobalCoord c = getGlobalSunCoords(d);
53+
double H = siderealTime(d, lw) - c.rightAscension;
54+
55+
CelestialLocalCoord coord;
56+
coord.azimuth = Utils::radiansToDegrees( azimuth(H, phi, c.declination) ) + 180.0;
57+
coord.altitude = Utils::radiansToDegrees( altitude(H, phi, c.declination) );
58+
59+
return coord;
60+
}
61+
62+
63+
static CelestialLocalCoord getMoonCoordinates(uint64_t date, double lat, double lng)
64+
{
65+
66+
double lw = Utils::degreesToRadians(-lng);
67+
double phi = Utils::degreesToRadians(lat);
68+
double d = toDays(date);
69+
70+
CelestialGlobalCoord c = getGlobalMoonCoords(d);
71+
double H = siderealTime(d, lw) - c.rightAscension;
72+
73+
// formula 14.1 of "Astronomical Algorithms" 2nd edition by Jean Meeus (Willmann-Bell, Richmond) 1998.
74+
double pa = std::atan2(std::sin(H), std::tan(phi) * std::cos(c.declination) - std::sin(c.declination) * std::cos(H));
75+
76+
double h = altitude(H, phi, c.declination);
77+
h = h + astroRefraction(h); // altitude correction for refraction
78+
79+
CelestialLocalCoord coord;
80+
coord.azimuth = Utils::radiansToDegrees( azimuth(H, phi, c.declination) );
81+
coord.altitude = Utils::radiansToDegrees(h);
82+
coord.distance = c.distance;
83+
coord.parallacticAngle = Utils::radiansToDegrees(pa);
84+
return coord;
85+
};
86+
87+
88+
// calculations for illumination parameters of the moon,
89+
// based on http://idlastro.gsfc.nasa.gov/ftp/pro/astro/mphase.pro formulas and
90+
// Chapter 48 of "Astronomical Algorithms" 2nd edition by Jean Meeus (Willmann-Bell, Richmond) 1998.
91+
static CelestialPhase getMoonPhase(uint64_t date)
92+
{
93+
double d = toDays(date);
94+
CelestialGlobalCoord s = getGlobalSunCoords(d);
95+
CelestialGlobalCoord m = getGlobalMoonCoords(d);
96+
97+
double sdist = EarthUtils::DistanceFromSun / 1000; // distance from Earth to Sun in km
98+
99+
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));
100+
double inc = std::atan2(sdist * std::sin(phi), m.distance - sdist * std::cos(phi));
101+
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));
102+
103+
CelestialPhase moonPhase;
104+
moonPhase.fraction = (1 + cos(inc)) / 2;
105+
moonPhase.phase = 0.5 + 0.5 * inc * (angle < 0 ? -1 : 1) / M_PI;
106+
moonPhase.angle = angle;
107+
return moonPhase;
108+
};
109+
110+
111+
private:
112+
113+
static double toDays(uint64_t date)
114+
{
115+
static constexpr double kJulianDaysOnY2000 = 2451545;
116+
static constexpr double kDaysToHours = 60 * 60 * 24;
117+
static constexpr double kJulianDaysOnEpoch = 2440588;
118+
119+
double julian_days = date / kDaysToHours - 0.5 + kJulianDaysOnEpoch;;
120+
return julian_days - kJulianDaysOnY2000;
121+
}
122+
123+
124+
static double rightAscension(double l, double b)
125+
{
126+
return std::atan2(std::sin(l) * std::cos(EarthUtils::Obliquity) - std::tan(b) * std::sin(EarthUtils::Obliquity), std::cos(l));
127+
}
128+
129+
static double declination(double l, double b)
130+
{
131+
return std::asin(std::sin(b) * std::cos(EarthUtils::Obliquity) + std::cos(b) * std::sin(EarthUtils::Obliquity) * std::sin(l));
132+
}
133+
134+
static double azimuth(double H, double phi, double declination)
135+
{
136+
return std::atan2(std::sin(H), std::cos(H) * std::sin(phi) - std::tan(declination) * std::cos(phi));
137+
}
138+
139+
static double altitude(double H, double phi, double declination)
140+
{
141+
return std::asin(std::sin(phi) * std::sin(declination) + std::cos(phi) * std::cos(declination) * std::cos(H));
142+
}
143+
144+
static double siderealTime(double d, double lw)
145+
{
146+
return Utils::degreesToRadians((280.16 + 360.9856235 * d)) - lw;
147+
}
148+
149+
static double astroRefraction(double h)
150+
{
151+
if (h < 0) // the following formula works for positive altitudes only.
152+
h = 0; // if h = -0.08901179 a div/0 would occur.
153+
154+
// formula 16.4 of "Astronomical Algorithms" 2nd edition by Jean Meeus (Willmann-Bell, Richmond) 1998.
155+
// 1.02 / tan(h + 10.26 / (h + 5.10)) h in degrees, result in arc minutes -> converted to rad:
156+
return 0.0002967 / std::tan(h + 0.00312536 / (h + 0.08901179));
157+
}
158+
159+
160+
static double solarMeanAnomaly(double d)
161+
{
162+
return Utils::degreesToRadians((357.5291 + 0.98560028 * d));
163+
}
164+
165+
static double eclipticLongitude(double M)
166+
{
167+
double C = Utils::degreesToRadians((1.9148 * std::sin(M) + 0.02 * std::sin(2 * M) + 0.0003 * std::sin(3 * M))); // equation of center
168+
169+
return M + C + EarthUtils::Perihelion + M_PI;
170+
}
171+
172+
static CelestialGlobalCoord getGlobalSunCoords(double d)
173+
{
174+
double M = solarMeanAnomaly(d);
175+
double L = eclipticLongitude(M);
176+
177+
CelestialGlobalCoord sunCoords;
178+
sunCoords.declination = declination(L, 0);
179+
sunCoords.rightAscension = rightAscension(L, 0);
180+
181+
return sunCoords;
182+
}
183+
184+
185+
// moon calculations, based on http://aa.quae.nl/en/reken/hemelpositie.html formulas
186+
static CelestialGlobalCoord getGlobalMoonCoords(double d)
187+
{
188+
// geocentric ecliptic coordinates of the moon
189+
190+
double L = Utils::degreesToRadians((218.316 + 13.176396 * d)); // ecliptic longitude
191+
double M = Utils::degreesToRadians((134.963 + 13.064993 * d)); // mean anomaly
192+
double F = Utils::degreesToRadians((93.272 + 13.229350 * d)); // mean distance
193+
194+
double l = L + Utils::degreesToRadians(6.289 * std::sin(M)); // longitude
195+
double b = Utils::degreesToRadians(5.128 * std::sin(F)); // latitude
196+
double dt = 385001 - 20905 * std::cos(M); // distance to the moon in km
197+
198+
CelestialGlobalCoord moonCoords;
199+
moonCoords.rightAscension = rightAscension(l, b);
200+
moonCoords.declination = declination(l, b);
201+
moonCoords.distance = dt;
202+
203+
return moonCoords;
204+
}
205+
};
206+
207+
208+
}} //namespace
209+
#endif

‎AirLib/include/common/EarthUtils.hpp

+3
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,9 @@ class EarthUtils {
357357
static constexpr float Gravity = 9.80665f; //m/s^2
358358
static constexpr float Radius = EARTH_RADIUS; //m
359359
static constexpr float SpeedOfLight = 299792458.0f; //m
360+
static constexpr float Obliquity = Utils::degreesToRadians(23.4397f);
361+
static constexpr double Perihelion = Utils::degreesToRadians(102.9372); // perihelion of the Earth
362+
static constexpr double DistanceFromSun = 149597870700.0; // meters
360363

361364
private:
362365
/* magnetic field */

‎AirLib/include/common/common_utils/Utils.hpp

+15-4
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,15 @@ class Utils {
481481
*/
482482
}
483483

484+
static std::time_t to_time_t(const std::string& str, bool is_dst = false, const std::string& format = "%Y-%b-%d %H:%M:%S")
485+
{
486+
std::tm t = {0};
487+
t.tm_isdst = is_dst ? 1 : 0;
488+
std::istringstream ss(str);
489+
ss >> std::get_time(&t, format.c_str());
490+
return mktime(&t);
491+
}
492+
484493
static string to_string(time_point<system_clock> time, const char* format)
485494
{
486495
time_t tt = system_clock::to_time_t(time);
@@ -503,12 +512,14 @@ class Utils {
503512
return ptr ? ptr : "";
504513
}
505514

506-
static uint64_t getUnixTimeStamp(std::time_t* t = nullptr)
515+
static uint64_t getUnixTimeStamp(const std::time_t* t = nullptr)
507516
{
508-
std::time_t st = std::time(t);
509-
auto millies = static_cast<std::chrono::milliseconds>(st).count();
510-
return static_cast<uint64_t>(millies);
517+
//if specific time is not passed then get current time
518+
std::time_t st = t == nullptr ? std::time(nullptr) : *t;
519+
auto secs = static_cast<std::chrono::seconds>(st).count();
520+
return static_cast<uint64_t>(secs);
511521
}
522+
512523
//high precision time in seconds since epoch
513524
static double getTimeSinceEpochSecs(std::chrono::high_resolution_clock::time_point* t = nullptr)
514525
{

‎AirLibUnitTests/AirLibUnitTests.vcxproj

+1
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@
187187
</ProjectReference>
188188
</ItemGroup>
189189
<ItemGroup>
190+
<ClInclude Include="CelestialTests.hpp" />
190191
<ClInclude Include="QuaternionTest.hpp" />
191192
<ClInclude Include="RosFlightTest.hpp" />
192193
<ClInclude Include="SettingsTest.hpp" />

‎AirLibUnitTests/AirLibUnitTests.vcxproj.filters

+3
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@
3939
<ClInclude Include="SettingsTest.hpp">
4040
<Filter>Header Files</Filter>
4141
</ClInclude>
42+
<ClInclude Include="CelestialTests.hpp">
43+
<Filter>Header Files</Filter>
44+
</ClInclude>
4245
</ItemGroup>
4346
<ItemGroup>
4447
<ClCompile Include="main.cpp">

‎AirLibUnitTests/CelestialTests.hpp

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#ifndef msr_AirLibUnitTests_CelestialTest_hpp
2+
#define msr_AirLibUnitTests_CelestialTest_hpp
3+
4+
#include "TestBase.hpp"
5+
#include "common/EarthCelestial.hpp"
6+
7+
8+
namespace msr { namespace airlib {
9+
10+
class CelestialTest : public TestBase
11+
{
12+
public:
13+
virtual void run() override
14+
{
15+
auto t = static_cast<uint64_t>(Utils::to_time_t("2018-February-22 15:24:00"));
16+
auto c_sun = EarthCelestial::getSunCoordinates(t, 47.673988, -122.121513);
17+
auto c_moon = EarthCelestial::getMoonCoordinates(t, 47.673988, -122.121513);
18+
auto c_moon_phase = EarthCelestial::getMoonPhase(t);
19+
20+
testAssert(Utils::isApproximatelyEqual(c_sun.altitude, 19.67, 0.1), "Sun azimuth is not correct");
21+
testAssert(Utils::isApproximatelyEqual(c_moon.altitude, 45.02, 0.1), "Monn azimuth is not correct");
22+
testAssert(Utils::isApproximatelyEqual(c_moon_phase.fraction, 0.47, 0.1), "Moon fraction is not correct");
23+
}
24+
};
25+
26+
} }
27+
28+
#endif

‎AirLibUnitTests/main.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@
55
#include "SimpleFlightTest.hpp"
66
#include "WorkerThreadTest.hpp"
77
#include "QuaternionTest.hpp"
8+
#include "CelestialTests.hpp"
89

910
int main()
1011
{
1112
using namespace msr::airlib;
1213

1314
std::unique_ptr<TestBase> tests[] = {
15+
std::unique_ptr<TestBase>(new CelestialTest()),
1416
std::unique_ptr<TestBase>(new SettingsTest()),
1517
std::unique_ptr<TestBase>(new SimpleFlightTest())
1618
//,

‎PythonClient/PythonClient.pyproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<SchemaVersion>2.0</SchemaVersion>
66
<ProjectGuid>e2049e20-b6dd-474e-8bca-1c8dc54725aa</ProjectGuid>
77
<ProjectHome>.</ProjectHome>
8-
<StartupFile>cv_mode.py</StartupFile>
8+
<StartupFile>hello_car.py</StartupFile>
99
<SearchPath>
1010
</SearchPath>
1111
<WorkingDirectory>.</WorkingDirectory>

‎Unreal/Plugins/AirSim/Source/Car/CarPawn.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -299,10 +299,10 @@ void ACarPawn::setupInputBindings()
299299
UAirBlueprintLib::BindAxisToKey(FInputAxisKeyMapping("MoveForward", EKeys::Down, -1), this,
300300
this, &ACarPawn::MoveForward);
301301

302-
UAirBlueprintLib::BindAxisToKey(FInputAxisKeyMapping("MoveRight", EKeys::Right, 1), this,
302+
UAirBlueprintLib::BindAxisToKey(FInputAxisKeyMapping("MoveRight", EKeys::Right, 0.1), this,
303303
this, &ACarPawn::MoveRight);
304304

305-
UAirBlueprintLib::BindAxisToKey(FInputAxisKeyMapping("MoveRight", EKeys::Left, -1), this,
305+
UAirBlueprintLib::BindAxisToKey(FInputAxisKeyMapping("MoveRight", EKeys::Left, -0.1), this,
306306
this, &ACarPawn::MoveRight);
307307

308308
UAirBlueprintLib::BindActionToKey("Handbrake", EKeys::End, this, &ACarPawn::OnHandbrakePressed, true);

0 commit comments

Comments
 (0)
Please sign in to comment.