AirControl  1.3.0
Open Source, Modular, and Extensible Flight Simulator For Deep Learning Research
Sun.cs
1 using System;
2 using System.Collections;
3 using System.Collections.Generic;
4 using UnityEngine;
5 using Communicator;
6 using UnityEngine.UI;
7 
8 namespace AirControl
9 {
10 
14  [RequireComponent(typeof(Light))]
15  [ExecuteInEditMode]
16  public class Sun : MonoBehaviour
17  {
18  //UI slider
19  public GameObject sliderAndText;
20  public Toggle sunLocationControl;
21  public Slider longitudeSlider;
22  public Slider latitudeSlider;
23  public Slider sunHourSlider;
24  public Slider sunMinuteSlider;
25 
26  [SerializeField]
27  float longitude;
28 
29  [SerializeField]
30  float latitude;
31 
32  [SerializeField]
33  [Range(0, 24)]
34  int hour;
35 
36  [SerializeField]
37  [Range(0, 60)]
38  int minutes;
39 
40  DateTime time;
41  new Light light;
42 
43  [SerializeField]
44  float timeSpeed = 1;
45 
46  [SerializeField]
47  int frameSteps = 1;
48  int frameStep;
49 
50  [SerializeField]
51  DateTime date;
57  public void SetTime(int hour, int minutes) {
58  this.hour = hour;
59  this.minutes = minutes;
60  OnValidate();
61  }
67  public void SetLocation(float longitude, float latitude){
68  this.longitude = longitude;
69  this.latitude = latitude;
70  }
71 
72  // public void SetDate(DateTime dateTime){
73  // this.hour = dateTime.Hour;
74  // this.minutes = dateTime.Minute;
75  // this.date = dateTime.Date;
76  // OnValidate();
77  // }
78 
79  public void SetUpdateSteps(int i) {
80  frameSteps = i;
81  }
82 
83  public void SetTimeSpeed(float speed) {
84  timeSpeed = speed;
85  }
89  private void Awake()
90  {
91 
92  light = GetComponent<Light>();
93  time = DateTime.Now;
94  hour = time.Hour;
95  minutes = time.Minute;
96  date = time.Date;
97  }
98 
99  private void OnValidate()
100  {
101  time = date + new TimeSpan(hour, minutes, 0);
102  }
103 
104  private void FixedUpdate()
105  {
106 
111 
112 
113  float sunLatitude=-66f;
114  float sunLongitude=-45f;
115  int sunHour=1;
116  int sunMinute=1;
117  bool isActive = sunLocationControl.isOn;
118  sliderAndText.SetActive(isActive);
119  if(isActive)
120  {
122  sunLatitude = longitudeSlider.value;
123  sunLongitude = latitudeSlider.value;
124  sunHour = (int)sunHourSlider.value;
125  sunMinute = (int)sunMinuteSlider.value;
126  SetTime(sunHour, sunMinute);
127  SetLocation(sunLatitude, sunLongitude);
128  }
129  #region IOSwitch
130  if(StaticTODSchema.IsActive )
131  {
132  sunLocationControl.isOn = false;
133  Debug.Log("UI Control is set to " + sunLocationControl.isOn);
134  sunLatitude = StaticTODSchema.SunLatitude;
135  sunLongitude = StaticTODSchema.SunLongitude;
136  sunHour = StaticTODSchema.Hour;
137  sunMinute = StaticTODSchema.Minute;
138  SetTime(sunHour, sunMinute);
139  SetLocation(sunLatitude, sunLongitude);
140  // set is active to false to not let this loop run for all the updates
141  StaticTODSchema.IsActive =false;
142 
143  }
144  #endregion
145 
146 
147  time = time.AddSeconds(timeSpeed * Time.deltaTime);
148  if (frameStep==0) {
149  SetPosition();
150  }
151  frameStep = (frameStep + 1) % frameSteps;
152 
153 
154  }
158  void SetPosition()
159  {
160 
161  Vector3 angles = new Vector3();
162  double alt;
163  double azi;
164  SunPosition.CalculateSunPosition(time, (double)latitude, (double)longitude, out azi, out alt);
165  angles.x = (float)alt * Mathf.Rad2Deg;
166  angles.y = (float)azi * Mathf.Rad2Deg;
167  //UnityEngine.Debug.Log(angles);
168  transform.localRotation = Quaternion.Euler(angles);
169  light.intensity = Mathf.InverseLerp(-12, 0, angles.x);
170  }
171 
172 
173  }
174 
180  public static class SunPosition
181  {
182  private const double Deg2Rad = Math.PI / 180.0;
183  private const double Rad2Deg = 180.0 / Math.PI;
184 
200  public static void CalculateSunPosition(
201  DateTime dateTime, double latitude, double longitude, out double outAzimuth, out double outAltitude)
202  {
203  // Convert to UTC
204  dateTime = dateTime.ToUniversalTime();
205 
206  // Number of days from J2000.0.
207  double julianDate = 367 * dateTime.Year -
208  (int)((7.0 / 4.0) * (dateTime.Year +
209  (int)((dateTime.Month + 9.0) / 12.0))) +
210  (int)((275.0 * dateTime.Month) / 9.0) +
211  dateTime.Day - 730531.5;
212 
213  double julianCenturies = julianDate / 36525.0;
214 
215  // Sidereal Time
216  double siderealTimeHours = 6.6974 + 2400.0513 * julianCenturies;
217 
218  double siderealTimeUT = siderealTimeHours +
219  (366.2422 / 365.2422) * (double)dateTime.TimeOfDay.TotalHours;
220 
221  double siderealTime = siderealTimeUT * 15 + longitude;
222 
223  // Refine to number of days (fractional) to specific time.
224  julianDate += (double)dateTime.TimeOfDay.TotalHours / 24.0;
225  julianCenturies = julianDate / 36525.0;
226 
227  // Solar Coordinates
228  double meanLongitude = CorrectAngle(Deg2Rad *
229  (280.466 + 36000.77 * julianCenturies));
230 
231  double meanAnomaly = CorrectAngle(Deg2Rad *
232  (357.529 + 35999.05 * julianCenturies));
233 
234  double equationOfCenter = Deg2Rad * ((1.915 - 0.005 * julianCenturies) *
235  Math.Sin(meanAnomaly) + 0.02 * Math.Sin(2 * meanAnomaly));
236 
237  double elipticalLongitude =
238  CorrectAngle(meanLongitude + equationOfCenter);
239 
240  double obliquity = (23.439 - 0.013 * julianCenturies) * Deg2Rad;
241 
242  // Right Ascension
243  double rightAscension = Math.Atan2(
244  Math.Cos(obliquity) * Math.Sin(elipticalLongitude),
245  Math.Cos(elipticalLongitude));
246 
247  double declination = Math.Asin(
248  Math.Sin(rightAscension) * Math.Sin(obliquity));
249 
250  // Horizontal Coordinates
251  double hourAngle = CorrectAngle(siderealTime * Deg2Rad) - rightAscension;
252 
253  if (hourAngle > Math.PI)
254  {
255  hourAngle -= 2 * Math.PI;
256  }
257 
258  double altitude = Math.Asin(Math.Sin(latitude * Deg2Rad) *
259  Math.Sin(declination) + Math.Cos(latitude * Deg2Rad) *
260  Math.Cos(declination) * Math.Cos(hourAngle));
261 
262  // Nominator and denominator for calculating Azimuth
263  // angle. Needed to test which quadrant the angle is in.
264  double aziNom = -Math.Sin(hourAngle);
265  double aziDenom =
266  Math.Tan(declination) * Math.Cos(latitude * Deg2Rad) -
267  Math.Sin(latitude * Deg2Rad) * Math.Cos(hourAngle);
268 
269  double azimuth = Math.Atan(aziNom / aziDenom);
270 
271  if (aziDenom < 0) // In 2nd or 3rd quadrant
272  {
273  azimuth += Math.PI;
274  }
275  else if (aziNom < 0) // In 4th quadrant
276  {
277  azimuth += 2 * Math.PI;
278  }
279 
280  outAltitude = altitude;
281  outAzimuth = azimuth;
282  }
283 
289  private static double CorrectAngle(double angleInRadians)
290  {
291  if (angleInRadians < 0)
292  {
293  return 2 * Math.PI - (Math.Abs(angleInRadians) % (2 * Math.PI));
294  }
295  else if (angleInRadians > 2 * Math.PI)
296  {
297  return angleInRadians % (2 * Math.PI);
298  }
299  else
300  {
301  return angleInRadians;
302  }
303  }
304  }
305 
306 }
AirControl.Sun
Function to change sun location and create Day and Night effects.
Definition: Sun.cs:16
AirControl.Sun.SetLocation
void SetLocation(float longitude, float latitude)
Set sun location as per the Longitude and latitude
Definition: Sun.cs:67
AirControl.Sun.SetTime
void SetTime(int hour, int minutes)
set dun location as per Hour and Minute
Definition: Sun.cs:57
AirControl
Definition: AirplaneSelector.cs:8
Communicator
Definition: InputHandle.cs:10