/** * Calculates all sun-related important times * depending on time of year and location * @param Location Location to be used in calculation * @param Basic NMEA_INFO for current date * @param Calculated DERIVED_INFO (not yet used) * @param TimeZone The timezone * @return Sunset time */ void SunEphemeris::CalcSunTimes(const GeoPoint &Location, const BrokenDateTime &date_time, const fixed TimeZone) { fixed DaysToJ2000 = FNday(date_time); Angle L = GetMeanSunLongitude(DaysToJ2000); // Use GetEclipticLongitude to find the ecliptic longitude of the Sun Angle Lambda = GetEclipticLongitude(DaysToJ2000, L); // Obliquity of the ecliptic Angle Obliquity = Angle::degrees(fixed(23.439) - fixed(.0000004) * DaysToJ2000); // Find the RA and DEC of the Sun Angle Alpha = Angle::radians(atan2(Obliquity.cos() * Lambda.sin(), Lambda.cos())); Angle Delta = Angle::radians(asin(Obliquity.sin() * Lambda.sin())); // Find the Equation of Time in minutes // Correction suggested by David Smith fixed LL = (L - Alpha).value_radians(); if (L.value_radians() < fixed_pi) LL += fixed_two_pi; fixed equation = fixed(1440) * (fixed_one - LL / fixed_two_pi); Angle HourAngle = GetHourAngle(Location.Latitude, Delta); Angle HourAngleTwilight = GetHourAngleTwilight(Location.Latitude, Delta); // length of twilight in hours fixed TwilightHours = (HourAngleTwilight - HourAngle).value_hours(); // Conversion of angle to hours and minutes DayLength = HourAngle.value_hours() * fixed_two; if (DayLength < fixed(0.0001)) // arctic winter DayLength = fixed_zero; TimeOfSunRise = fixed(12) - HourAngle.value_hours() + TimeZone - Location.Longitude.value_degrees() / 15 + equation / 60; if (TimeOfSunRise > fixed(24)) TimeOfSunRise -= fixed(24); TimeOfSunSet = TimeOfSunRise + DayLength; TimeOfNoon = TimeOfSunRise + HourAngle.value_hours(); // morning twilight begin MorningTwilight = TimeOfSunRise - TwilightHours; // evening twilight end EveningTwilight = TimeOfSunSet + TwilightHours; }
/** Setter method for UTC time at which the satellite is to be observed. This is usually the current tim. \param yearIn The current year in four digits, like 2010 \param monthIn The month in two digits, like '10' for October \param mDayIn the day of the month, like '1' for the first day \param hourIn the hour of the day, like '19' for 19 \param minIn the minute of the day, like '00' for the first \param secIn the seconds **/ void Plan13::setTime(int yearIn, int monthIn, int mDayIn, int hourIn, int minIn, int secIn) { if (DEBUG) { Serial.println("Start setTime()"); } int aYear = yearIn; int aMonth = monthIn; int aMday = mDayIn; int aHour = hourIn; int aMin = minIn; int aSec = secIn; if (TEST) { aYear = 2009; aMonth = 10; aMday = 1; aHour = 19; aMin = 5; aSec = 0; } DN = FNday(aYear, aMonth, aMday); TN = ((float)aHour + ((float)aMin + ((float)aSec/60.0)) /60.0)/24.0; DN = (long)DN; if (DEBUG) { Serial.print(aYear); Serial.print("/"); Serial.print(aMonth); Serial.print("/"); Serial.print(aMday); Serial.print(" "); Serial.print(aHour); Serial.print(":"); Serial.print(aMin); Serial.print(":"); Serial.print(aSec); Serial.print(" "); Serial.print("DN: "); Serial.println(DN); Serial.print("TN: "); Serial.println(TN); Serial.println("End setTime()"); } }
Angle SunEphemeris::CalcAzimuth(const GeoPoint &location, const BrokenDateTime &date_time, const fixed time_zone) { assert(date_time.Plausible()); fixed days_to_j2000 = FNday(date_time); Angle l = GetMeanSunLongitude(days_to_j2000); // Use GetEclipticLongitude to find the ecliptic longitude of the Sun Angle lambda = GetEclipticLongitude(days_to_j2000, l); // Obliquity of the ecliptic Angle obliquity = Angle::Degrees(fixed(23.439) - fixed(.0000004) * days_to_j2000); // Find the DEC of the Sun Angle delta = Angle::asin(obliquity.sin() * lambda.sin()); return CalculateAzimuth(location, date_time, time_zone, delta); }
SunEphemeris::Result SunEphemeris::CalcSunTimes(const GeoPoint &location, const BrokenDateTime &date_time, const fixed time_zone) { Result result; assert(date_time.Plausible()); fixed days_to_j2000 = FNday(date_time); Angle l = GetMeanSunLongitude(days_to_j2000); // Use GetEclipticLongitude to find the ecliptic longitude of the Sun Angle lambda = GetEclipticLongitude(days_to_j2000, l); // Obliquity of the ecliptic Angle obliquity = Angle::Degrees(fixed(23.439) - fixed(.0000004) * days_to_j2000); // Find the RA and DEC of the Sun Angle alpha = Angle::FromXY(lambda.cos(), obliquity.cos() * lambda.sin()); Angle delta = Angle::asin(obliquity.sin() * lambda.sin()); // Find the Equation of Time in minutes // Correction suggested by David Smith fixed ll = (l - alpha).Radians(); if (l.Radians() < fixed_pi) ll += fixed_two_pi; fixed equation = fixed(1440) * (fixed(1) - ll / fixed_two_pi); Angle hour_angle = GetHourAngle(location.latitude, delta); Angle hour_angle_twilight = GetHourAngleTwilight(location.latitude, delta); result.azimuth = CalculateAzimuth(location, date_time, time_zone, delta); // length of twilight in hours fixed twilight_hours = (hour_angle_twilight - hour_angle).Hours(); // Conversion of angle to hours and minutes result.day_length = Double(hour_angle.Hours()); if (result.day_length < fixed(0.0001)) // arctic winter result.day_length = fixed(0); result.time_of_sunrise = fixed(12) - hour_angle.Hours() + time_zone - location.longitude.Degrees() / 15 + equation / 60; if (result.time_of_sunrise > fixed(24)) result.time_of_sunrise -= fixed(24); result.time_of_sunset = result.time_of_sunrise + result.day_length; result.time_of_noon = result.time_of_sunrise + hour_angle.Hours(); // morning twilight begin result.morning_twilight = result.time_of_sunrise - twilight_hours; // evening twilight end result.evening_twilight = result.time_of_sunset + twilight_hours; return result; }
int main(void){ double y,m,day,h,latit,longit; float inlat,inlon,intz; double tzone,d,lambda; double obliq,alpha,delta,LL,equation,ha,hb,twx; double twam,altmax,noont,settm,riset,twpm; time_t sekunnit; struct tm *p; degs = 180.0/pi; rads = pi/180.0; // get the date and time from the user // read system date and extract the year /** First get time **/ time(&sekunnit); /** Next get localtime **/ p=localtime(&sekunnit); y = p->tm_year; // this is Y2K compliant method y+= 1900; m = p->tm_mon + 1; day = p->tm_mday; h = 12; printf("year %4d month %2d\n",(int)y,(int)m); printf("Input latitude, longitude and timezone\n"); scanf("%20f", &inlat); scanf("%20f", &inlon); scanf("%20f", &intz); latit = (double)inlat; longit = (double)inlon; tzone = (double)intz; // testing // m=6; day=10; d = FNday(y, m, day, h); // Use FNsun to find the ecliptic longitude of the // Sun lambda = FNsun(d); // Obliquity of the ecliptic obliq = 23.439 * rads - .0000004 * rads * d; // Find the RA and DEC of the Sun alpha = atan2(cos(obliq) * sin(lambda), cos(lambda)); delta = asin(sin(obliq) * sin(lambda)); // Find the Equation of Time // in minutes // Correction suggested by David Smith LL = L - alpha; if (L < pi) LL += 2.0*pi; equation = 1440.0 * (1.0 - LL / pi/2.0); ha = f0(latit,delta); hb = f1(latit,delta); twx = hb - ha; // length of twilight in radians twx = 12.0*twx/pi; // length of twilight in hours printf("ha= %.2f hb= %.2f \n",ha,hb); // Conversion of angle to hours and minutes // daylen = degs*ha/7.5; if (daylen<0.0001) {daylen = 0.0;} // arctic winter // riset = 12.0 - 12.0 * ha/pi + tzone - longit/15.0 + equation/60.0; settm = 12.0 + 12.0 * ha/pi + tzone - longit/15.0 + equation/60.0; noont = riset + 12.0 * ha/pi; altmax = 90.0 + delta * degs - latit; // Correction for S HS suggested by David Smith // to express altitude as degrees from the N horizon if (latit < delta * degs) altmax = 180.0 - altmax; twam = riset - twx; // morning twilight begin twpm = settm + twx; // evening twilight end if (riset > 24.0) riset-= 24.0; if (settm > 24.0) settm-= 24.0; puts("\n Sunrise and set"); puts("==============="); printf(" year : %d \n",(int)y); printf(" month : %d \n",(int)m); printf(" day : %d \n\n",(int)day); printf("Days since Y2K : %d \n",(int)d); printf("Latitude : %3.1f, longitude: %3.1f, timezone: %3.1f \n",(float)latit,(float)longit,(float)tzone); printf("Declination : %.2f \n",delta * degs); printf("Daylength : "); showhrmn(daylen); puts(" hours \n"); printf("Civil twilight: "); showhrmn(twam); puts(""); printf("Sunrise : "); showhrmn(riset); puts(""); printf("Sun altitude "); // Amendment by D. Smith printf(" %.2f degr",altmax); printf(" %s",latit>=0.0 ? "South" : "North"); printf(" at noontime "); showhrmn(noont); puts(""); printf("Sunset : "); showhrmn(settm); puts(""); printf("Civil twilight: "); showhrmn(twpm); puts("\n"); return 0; }
/** * Calculates all sun-related important times * depending on time of year and location * @param location Location to be used in calculation * @param GPS_INFO GPS_INFO for current date * @param CALCULATED_INFO CALCULATED_INFO (not yet used) * @param tzone Timezone * @return Always 0 */ int SunEphemeris::CalcSunTimes(const GEOPOINT &location, const NMEA_INFO &GPS_INFO, const DERIVED_INFO &CALCULATED_INFO, const double tzone) { // float intz; double d,lambda; double obliq,alpha,delta,LL,equation,ha,hb,twx; int y, m, day, h; // testing // JG Removed simulator conditional code, since GPS_INFO now set up // from system time. m = GPS_INFO.Month; y = GPS_INFO.Year; day = GPS_INFO.Day; h = ((int)GPS_INFO.Time)/3600; h = (h % 24); d = FNday(y, m, day, (float) h); // Use FNsun to find the ecliptic longitude of the Sun lambda = FNsun(d); // Obliquity of the ecliptic obliq = 23.439 * DEG_TO_RAD - .0000004 * DEG_TO_RAD * d; // Find the RA and DEC of the Sun alpha = atan2(cos(obliq) * sin(lambda), cos(lambda)); delta = asin(sin(obliq) * sin(lambda)); // Find the Equation of Time in minutes // Correction suggested by David Smith LL = L - alpha; if (L < PI) LL += 2.0*PI; equation = 1440.0 * (1.0 - LL / PI/2.0); ha = f0(location.Latitude,delta); hb = f1(location.Latitude,delta); twx = hb - ha; // length of twilight in radians twx = 12.0*twx/PI; // length of twilight in hours // printf("ha= %.2f hb= %.2f \n",ha,hb); // Conversion of angle to hours and minutes // daylen = RAD_TO_DEG*ha/7.5; if (daylen<0.0001) { daylen = 0.0; } // arctic winter // riset = 12.0 - 12.0 * ha/PI + tzone - location.Longitude/15.0 + equation/60.0; settm = 12.0 + 12.0 * ha/PI + tzone - location.Longitude/15.0 + equation/60.0; noont = riset + 12.0 * ha/PI; altmax = 90.0 + delta * RAD_TO_DEG - location.Latitude; // Correction for S HS suggested by David Smith // to express altitude as degrees from the N horizon if (location.Latitude < delta * RAD_TO_DEG) { altmax = 180.0 - altmax; } twam = riset - twx; // morning twilight begin twpm = settm + twx; // evening twilight end if (riset > 24.0) riset-= 24.0; if (settm > 24.0) settm-= 24.0; /* puts("\n Sunrise and set"); puts("==============="); printf(" year : %d \n",(int)y); printf(" month : %d \n",(int)m); printf(" day : %d \n\n",(int)day); printf("Days since Y2K : %d \n",(int)d); printf("Latitude : %3.1f, longitude: %3.1f, timezone: %3.1f \n",(float)latit,(float)longit,(float)tzone); printf("Declination : %.2f \n",delta * RAD_TO_DEG); printf("Daylength : "); showhrmn(daylen); puts(" hours \n"); printf("Civil twilight: "); showhrmn(twam); puts(""); printf("Sunrise : "); showhrmn(riset); puts(""); printf("Sun altitude "); // Amendment by D. Smith printf(" %.2f degr",altmax); printf(latit>=0.0 ? " South" : " North"); printf(" at noontime "); showhrmn(noont); puts(""); printf("Sunset : "); showhrmn(settm); puts(""); printf("Civil twilight: "); showhrmn(twpm); puts("\n"); */ // QUESTION TB: why not just void? return 0; }
void Plan13::initSat(void) { //readElements(SAT); //now done beforehand /* Observer's location */ if (DEBUG) {Serial.println("Start initSat()");} LA = rad( observer_lat ); LO = rad( observer_lon ); HT = ((float) observer_height)/1000.0; // this needs to be in km CL = cos(LA); SL = sin(LA); CO = cos(LO); SO = sin(LO); /* WGS-84 Earth Ellipsoid */ RE = 6378.137; FL = 1.0 / 298.257224; /* IAU-76 Earth Ellipsoid */ // RE = 6378.140; // FL = 1.0 / 298.257; RP = RE * (1.0 - FL); XX = RE * RE; ZZ = RP * RP; D = sqrt( XX * CL * CL + ZZ * SL * SL ); Rx = XX / D + HT; Rz = ZZ / D + HT; /* Observer's unit vectors Up EAST and NORTH in geocentric coordinates */ Ux = CL * CO; Ex = -SO; Nx = -SL * CO; Uy = CL * SO; Ey = CO; Ny = -SL * SO; Uz = SL; Ez = 0; Nz = CL; /* Observer's XYZ coordinates at earth's surface */ Ox = Rx * Ux; Oy = Rx * Uy; Oz = Rz * Uz; /* Convert angles to radians, etc. */ RA = rad(RA); IN = rad(IN); WP = rad(WP); MA = rad(MA); MM = MM * 2.0 * M_PI; M2 = M2 * 2.0 * M_PI; // YM = 365.25; /* Mean year, days */ // YT = 365.2421970; /* Tropical year, days */ WW = 2.0 * M_PI / YT; /* Earth's rotation rate, rads/whole day */ WE = 2.0 * M_PI + WW; /* Earth's rotation rate, rads/day */ W0 = WE / 86400; /* Earth's rotation rate, rads/sec */ /* Observer's velocity, geocentric coordinates */ VOx = -Oy * W0; VOy = Ox * W0; /* Convert satellite epoch to Day No. and fraction of a day */ DE = FNday(YE, 1, 0) + (int)TE; TE = TE - (int)TE; if (DEBUG) { Serial.print("DE: "); Serial.println(DE); Serial.print("TE: "); Serial.println(TE); } /* Average Precession rates */ GM = 3.986E5; /* Earth's gravitational constant km^3/s^2 */ J2 = 1.08263E-3; /* 2nd Zonal coeff, Earth's gravity Field */ N0 = MM / 86400.0; /* Mean motion rads/s */ A0 = pow(GM / N0 / N0, 1.0 / 3.0); /* Semi major axis km */ b0 = A0 * sqrt(1.0 - EC * EC); /* Semi minor axis km */ SI = sin(IN); CI = cos(IN); PC = RE * A0 / (b0 * b0); PC = 1.5 * J2 * PC * PC * MM; /* Precession const, rad/day */ QD = -PC * CI; /* Node Precession rate, rad/day */ WD = PC *(5.0 * CI*CI - 1.0) / 2.0; /* Perigee Precession rate, rad/day */ DC = -2.0 * M2 / MM / 3.0; /* Drag coeff */ /* Sideral and solar data. Never needs changing. Valid to year 2000+ */ /* GHAA, Year YG, Jan 0.0 */ YG = 2010; G0 = 99.5578; /* MA Sun and rate, deg, deg/day */ MAS0 = 356.4485; MASD = 0.98560028; /* Sun's inclination */ INS = rad(23.4380); CNS = cos(INS); SNS = sin(INS); /* Sun's equation of center terms */ EQC1 = 0.03341; EQC2 = 0.00035; /* Bring Sun data to satellite epoch */ TEG = (DE - FNday(YG, 1, 0)) + TE; /* Elapsed Time: Epoch - YG */ GHAE = rad(G0) + TEG * WE; /* GHA Aries, epoch */ MRSE = rad(G0) + (TEG * WW) + M_PI; /* Mean RA Sun at Sat Epoch */ MASE = rad(MAS0 + MASD * TEG); /* Mean MA Sun */ /* Antenna unit vector in orbit plane coordinates */ CO = cos(rad(ALON)); SO = sin(rad(ALON)); CL = cos(rad(ALAT)); SL = sin(rad(ALAT)); ax = -CL * CO; ay = -CL * SO; az = -SL; /* Miscellaneous */ OLDRN = -99999; if (DEBUG) { Serial.println("End initSat()");} }