/*! \brief Calculate the time as Julian day (and fraction) from the TMG widgets. * \param mod Pointer to the GtkSatModule this time manager belongs to. * \returns The current date and time in Julian days and fraction of days. */ static gdouble calculate_time(GtkSatModule *mod) { guint year, month, day; gint hr, min, sec, msec; struct tm tim,utim; gdouble jd = 0.0; /* get date and time from widgets */ gtk_calendar_get_date (GTK_CALENDAR (mod->tmgCal), &year, &month, &day); hr = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (mod->tmgHour)); min = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (mod->tmgMin)); sec = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (mod->tmgSec)); msec = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (mod->tmgMsec)); /* build struct_tm */ tim.tm_year = (int) (year); tim.tm_mon = (int) (month+1); tim.tm_mday = (int) day; tim.tm_hour = (int) hr; tim.tm_min = (int) min; tim.tm_sec = (int) sec; sat_log_log (SAT_LOG_LEVEL_DEBUG, _("%s: %d/%d/%d %d:%d:%d.%d"), __FUNCTION__, tim.tm_year, tim.tm_mon, tim.tm_mday, tim.tm_hour, tim.tm_min, tim.tm_sec, msec); /* convert UTC time to Julian Date */ if (sat_cfg_get_bool (SAT_CFG_BOOL_USE_LOCAL_TIME)) { /* convert local time to UTC */ Time_to_UTC (&tim, &utim); /* Convert to JD */ jd = Julian_Date (&utim); } else { /* Already UTC, just convert to JD */ jd = Julian_Date (&tim); } jd = jd + (gdouble)msec/8.64e+7; return jd; }
//----------------------------------------------------------------------------- void TTime::initFromUnixStamp( unsigned value ) { time_t epoch = (time_t)value; struct tm utc = *gmtime(&epoch); utc.tm_year += 1900; utc.tm_mon += 1; double d = Julian_Date(&utc); m_julianDate = d; }
*/ REBINT Diff_Date(REBDAT d1, REBDAT d2) /* ** Calculate the difference in days between two dates. ** ***********************************************************************/ { REBCNT days; REBINT sign; REBCNT m, y; REBDAT tmp; if (d1.bits == d2.bits) return 0; if (d1.bits < d2.bits) { sign = -1; tmp = d1; d1 = d2; d2 = tmp; } else sign = 1; // if not same year, calculate days to end of month, year and // days in between years plus days in end year if (d1.date.year > d2.date.year) { days = Month_Length(d2.date.month-1, d2.date.year) - d2.date.day; for (m = d2.date.month; m < 12; m++) days += Month_Length(m, d2.date.year); for (y = d2.date.year + 1; y < d1.date.year; y++) { days += (((y % 4) == 0) && // divisible by four is a leap year (((y % 100) != 0) || // except when divisible by 100 ((y % 400) == 0))) // but not when divisible by 400 ? 366u : 365u; } return sign * (REBINT)(days + Julian_Date(d1)); } return sign * (REBINT)(Julian_Date(d1) - Julian_Date(d2)); }
//----------------------------------------------------------------------------- void TTime::initFromNow() { struct tm utc; UTC_Calendar_Now(&utc); double daynum = Julian_Date(&utc); //// microseconds correction //GTimeVal tmval; //g_get_current_time (&tmval); //daynum = daynum + (double)tmval.tv_usec/8.64e+10; m_julianDate = daynum; }
/** \brief Get the current time. * * Read the system clock and return the current Julian day. */ gdouble get_current_daynum () { struct tm utc; //struct timeval tmval; GTimeVal tmval; double daynum; UTC_Calendar_Now (&utc); //gettimeofday (&tmval, NULL); g_get_current_time (&tmval); daynum = Julian_Date (&utc); daynum = daynum + (double)tmval.tv_usec/8.64e+10; return daynum; }
/* as a time greater than 24 hours) and then converting back and comparing.*/ int Check_Date(struct tm *cdate) { double jt; struct tm chkdate; jt = Julian_Date(cdate); Date_Time(jt, &chkdate); if( (cdate->tm_year == chkdate.tm_year) && (cdate->tm_mon == chkdate.tm_mon ) && (cdate->tm_mday == chkdate.tm_mday) && (cdate->tm_hour == chkdate.tm_hour) && (cdate->tm_min == chkdate.tm_min ) && (cdate->tm_sec == chkdate.tm_sec ) ) return ( 1 ); else return( 0 ); } /*Procedure Check_Date*/
//----------------------------------------------------------------------------- bool TTime::initFromStringUTC( const char* datetime ) { // we are expecting 2015-10-12 13:45:01 char buf[80]; size_t pos = 0; strncpy(buf, datetime+pos, 4); buf[4] = 0; int year = atoi(buf); pos += 4; if( datetime[pos] != '-' ) return false; pos += 1; strncpy(buf, datetime+pos, 2); buf[2] = 0; int month = atoi(buf); pos += 2; if( datetime[pos] != '-' ) return false; pos += 1; strncpy(buf, datetime+pos, 2); buf[2] = 0; int day = atoi(buf); pos += 2; if( datetime[pos] != ' ' ) return false; pos += 1; strncpy(buf, datetime+pos, 2); buf[2] = 0; int hours = atoi(buf); pos += 2; if( datetime[pos] != ':' ) return false; pos += 1; strncpy(buf, datetime+pos, 2); buf[2] = 0; int minutes = atoi(buf); pos += 2; if( datetime[pos] != ':' ) return false; pos += 1; strncpy(buf, datetime+pos, 2); buf[2] = 0; int seconds = atoi(buf); pos += 2; if( datetime[pos] != 0 ) return false; struct tm utc; utc.tm_year = year; // 1900 utc.tm_mon = month; // 1 utc.tm_mday = day; utc.tm_hour = hours; utc.tm_min = minutes; utc.tm_sec = seconds; double d = Julian_Date(&utc); m_julianDate = d; return true; }
*/ REBINT PD_Date(REBPVS *pvs) /* ***********************************************************************/ { REBVAL *data = pvs->value; REBVAL *arg = pvs->select; REBVAL *val = pvs->setval; REBINT i; REBINT n; REBI64 secs; REBINT tz; REBDAT date; REBCNT day, month, year; REBINT num; REBVAL dat; REB_TIMEF time; // !zone! - adjust date by zone (unless /utc given) if (IS_WORD(arg)) { //!!! change this to an array!? switch (VAL_WORD_CANON(arg)) { case SYM_YEAR: i = 0; break; case SYM_MONTH: i = 1; break; case SYM_DAY: i = 2; break; case SYM_TIME: i = 3; break; case SYM_ZONE: i = 4; break; case SYM_DATE: i = 5; break; case SYM_WEEKDAY: i = 6; break; case SYM_JULIAN: case SYM_YEARDAY: i = 7; break; case SYM_UTC: i = 8; break; case SYM_HOUR: i = 9; break; case SYM_MINUTE: i = 10; break; case SYM_SECOND: i = 11; break; default: return PE_BAD_SELECT; } } else if (IS_INTEGER(arg)) { i = Int32(arg) - 1; if (i < 0 || i > 8) return PE_BAD_SELECT; } else return PE_BAD_SELECT; if (IS_DATE(data)) { dat = *data; // recode! data = &dat; if (i != 8) Adjust_Date_Zone(data, FALSE); // adjust for timezone date = VAL_DATE(data); day = VAL_DAY(data) - 1; month = VAL_MONTH(data) - 1; year = VAL_YEAR(data); secs = VAL_TIME(data); tz = VAL_ZONE(data); if (i > 8) Split_Time(secs, &time); } else { Trap_Arg_DEAD_END(data); // this should never happen } if (val == 0) { val = pvs->store; switch(i) { case 0: num = year; break; case 1: num = month + 1; break; case 2: num = day + 1; break; case 3: if (secs == NO_TIME) return PE_NONE; *val = *data; VAL_SET(val, REB_TIME); return PE_USE; case 4: if (secs == NO_TIME) return PE_NONE; *val = *data; VAL_TIME(val) = (i64)tz * ZONE_MINS * MIN_SEC; VAL_SET(val, REB_TIME); return PE_USE; case 5: // date *val = *data; VAL_TIME(val) = NO_TIME; VAL_ZONE(val) = 0; return PE_USE; case 6: // weekday num = Week_Day(date); break; case 7: // yearday num = (REBINT)Julian_Date(date); break; case 8: // utc *val = *data; VAL_ZONE(val) = 0; return PE_USE; case 9: num = time.h; break; case 10: num = time.m; break; case 11: if (time.n == 0) num = time.s; else { SET_DECIMAL(val, (REBDEC)time.s + (time.n * NANO)); return PE_USE; } break; default: return PE_NONE; } SET_INTEGER(val, num); return PE_USE; } else { if (IS_INTEGER(val) || IS_DECIMAL(val)) n = Int32s(val, 0); else if (IS_NONE(val)) n = 0; else if (IS_TIME(val) && (i == 3 || i == 4)); else if (IS_DATE(val) && (i == 3 || i == 5)); else return PE_BAD_SET_TYPE; switch(i) { case 0: year = n; break; case 1: month = n - 1; break; case 2: day = n - 1; break; case 3: // time if (IS_NONE(val)) { secs = NO_TIME; tz = 0; break; } else if (IS_TIME(val) || IS_DATE(val)) secs = VAL_TIME(val); else if (IS_INTEGER(val)) secs = n * SEC_SEC; else if (IS_DECIMAL(val)) secs = DEC_TO_SECS(VAL_DECIMAL(val)); else return PE_BAD_SET_TYPE; break; case 4: // zone if (IS_TIME(val)) tz = (REBINT)(VAL_TIME(val) / (ZONE_MINS * MIN_SEC)); else if (IS_DATE(val)) tz = VAL_ZONE(val); else tz = n * (60 / ZONE_MINS); if (tz > MAX_ZONE || tz < -MAX_ZONE) return PE_BAD_RANGE; break; case 5: // date if (!IS_DATE(val)) return PE_BAD_SET_TYPE; date = VAL_DATE(val); goto setDate; case 9: time.h = n; secs = Join_Time(&time, FALSE); break; case 10: time.m = n; secs = Join_Time(&time, FALSE); break; case 11: if (IS_INTEGER(val)) { time.s = n; time.n = 0; } else { //if (f < 0.0) Trap_Range_DEAD_END(val); time.s = (REBINT)VAL_DECIMAL(val); time.n = (REBINT)((VAL_DECIMAL(val) - time.s) * SEC_SEC); } secs = Join_Time(&time, FALSE); break; default: return PE_BAD_SET; } Normalize_Time(&secs, &day); date = Normalize_Date(day, month, year, tz); setDate: data = pvs->value; VAL_SET(data, REB_DATE); VAL_DATE(data) = date; VAL_TIME(data) = secs; Adjust_Date_Zone(data, TRUE); return PE_USE; } }
/* Main program */ int main(void) { /* TLE source file */ char tle_file[] = "./rax.txt"; /* Observer's geodetic co-ordinates. */ /* Lat North, Lon East in rads, Alt in km */ geodetic_t obs_geodetic = {0.7368, -1.4615, 0.251, 0.0}; /* Two-line Orbital Elements for the satellite */ tle_t tle ; /* Zero vector for initializations */ vector_t zero_vector = {0,0,0,0}; /* Satellite position and velocity vectors */ vector_t vel = zero_vector; vector_t pos = zero_vector; /* Satellite Az, El, Range, Range rate */ vector_t obs_set; /* Solar ECI position vector */ vector_t solar_vector = zero_vector; /* Solar observed azi and ele vector */ vector_t solar_set; /* Calendar date and time (UTC) */ struct tm utc; /* Satellite's predicted geodetic position */ geodetic_t sat_geodetic; double tsince, /* Time since epoch (in minutes) */ jul_epoch, /* Julian date of epoch */ jul_utc, /* Julian UTC date */ eclipse_depth = 0, /* Depth of satellite eclipse */ /* Satellite's observed position, range, range rate */ sat_azi, sat_ele, sat_range, sat_range_rate, /* Satellites geodetic position and velocity */ sat_lat, sat_lon, sat_alt, sat_vel, /* Solar azimuth and elevation */ sun_azi, sun_ele; /* Used for storing function return codes */ int flg; char ephem[5], /* Ephemeris in use string */ sat_status[12]; /* Satellite eclipse status */ /* Input one (first!) TLE set from file */ flg = Input_Tle_Set(tle_file, &tle); /* Abort if file open fails */ if( flg == -1 ) { printf(" File open failed - Exiting!\n"); exit(-1); } /* Print satellite name and TLE read status */ printf(" %s: ", tle.sat_name); if( flg == -2 ) { printf("TLE set bad - Exiting!\n"); exit(-2); } else printf("TLE set good - Happy Tracking!\n"); /* Printout of tle set data for tests if needed */ /* printf("\n %s %s %i %i %i\n" " %14f %10f %8f %8f\n" " %8f %8f %9f %8f %8f %12f\n", tle.sat_name, tle.idesg, tle.catnr, tle.elset, tle.revnum, tle.epoch, tle.xndt2o, tle.xndd6o, tle.bstar, tle.xincl, tle.xnodeo, tle.eo, tle.omegao, tle.xmo, tle.xno); */ /** !Clear all flags! **/ /* Before calling a different ephemeris */ /* or changing the TLE set, flow control */ /* flags must be cleared in main(). */ ClearFlag(ALL_FLAGS); /** Select ephemeris type **/ /* Will set or clear the DEEP_SPACE_EPHEM_FLAG */ /* depending on the TLE parameters of the satellite. */ /* It will also pre-process tle members for the */ /* ephemeris functions SGP4 or SDP4 so this function */ /* must be called each time a new tle set is used */ select_ephemeris(&tle); do /* Loop */ { /* Get UTC calendar and convert to Julian */ UTC_Calendar_Now(&utc); jul_utc = Julian_Date(&utc); /* Convert satellite's epoch time to Julian */ /* and calculate time since epoch in minutes */ jul_epoch = Julian_Date_of_Epoch(tle.epoch); tsince = (jul_utc - jul_epoch) * xmnpda; /* Copy the ephemeris type in use to ephem string */ if( isFlagSet(DEEP_SPACE_EPHEM_FLAG) ) strcpy(ephem,"SDP4"); else strcpy(ephem,"SGP4"); /* Call NORAD routines according to deep-space flag */ if( isFlagSet(DEEP_SPACE_EPHEM_FLAG) ) SDP4(tsince, &tle, &pos, &vel); else SGP4(tsince, &tle, &pos, &vel); /* Scale position and velocity vectors to km and km/sec */ Convert_Sat_State( &pos, &vel ); /* Calculate velocity of satellite */ Magnitude( &vel ); sat_vel = vel.w; /** All angles in rads. Distance in km. Velocity in km/s **/ /* Calculate satellite Azi, Ele, Range and Range-rate */ Calculate_Obs(jul_utc, &pos, &vel, &obs_geodetic, &obs_set); /* Calculate satellite Lat North, Lon East and Alt. */ Calculate_LatLonAlt(jul_utc, &pos, &sat_geodetic); /* Calculate solar position and satellite eclipse depth */ /* Also set or clear the satellite eclipsed flag accordingly */ Calculate_Solar_Position(jul_utc, &solar_vector); Calculate_Obs(jul_utc,&solar_vector,&zero_vector,&obs_geodetic,&solar_set); if( Sat_Eclipsed(&pos, &solar_vector, &eclipse_depth) ) SetFlag( SAT_ECLIPSED_FLAG ); else ClearFlag( SAT_ECLIPSED_FLAG ); /* Copy a satellite eclipse status string in sat_status */ if( isFlagSet( SAT_ECLIPSED_FLAG ) ) strcpy( sat_status, "Eclipsed" ); else strcpy( sat_status, "In Sunlight" ); /* Convert and print satellite and solar data */ sat_azi = Degrees(obs_set.x); sat_ele = Degrees(obs_set.y); sat_range = obs_set.z; sat_range_rate = obs_set.w; sat_lat = Degrees(sat_geodetic.lat); sat_lon = Degrees(sat_geodetic.lon); sat_alt = sat_geodetic.alt; sun_azi = Degrees(solar_set.x); sun_ele = Degrees(solar_set.y); printf("\n Date: %02d/%02d/%04d UTC: %02d:%02d:%02d Ephemeris: %s" "\n Azi=%6.1f Ele=%6.1f Range=%8.1f Range Rate=%6.2f" "\n Lat=%6.1f Lon=%6.1f Alt=%8.1f Vel=%8.3f" "\n Stellite Status: %s - Depth: %2.3f" "\n Sun Azi=%6.1f Sun Ele=%6.1f\n", utc.tm_mday, utc.tm_mon, utc.tm_year, utc.tm_hour, utc.tm_min, utc.tm_sec, ephem, sat_azi, sat_ele, sat_range, sat_range_rate, sat_lat, sat_lon, sat_alt, sat_vel, sat_status, eclipse_depth, sun_azi, sun_ele); sleep(1); } /* End of do */ while( 1 ); /* This stops Compaq ccc 'unreachcode' warning! */ return(0); } /* End of main() */