home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
OSK
/
TELECOM
/
OSKBox.lzh
/
MAILBOX
/
SAT
/
sun.c
< prev
Wrap
C/C++ Source or Header
|
1990-10-28
|
8KB
|
281 lines
#define DRAG 1
#include <stdio.h>
#include <math.h>
#include <ctype.h>
extern double Kepler();
extern long GetDayNum();
#define LC(c) (isupper(c) ? tolower(c) : (c))
#ifndef PI
#define PI 3.14159265
#endif
#ifdef PI2
#undef PI2
#endif
#define PI2 (PI*2)
#define MinutesPerDay (24*60.0)
#define SecondsPerDay (60*MinutesPerDay)
#define HalfSecond (0.5/SecondsPerDay)
#define EarthRadius 6378.16 /* Kilometers */
#define C 2.997925e5 /* Kilometers/Second */
#define TropicalYear 365.24199 /* Mean solar days */
#define EarthEccentricity 0.016713
#define DegreesPerRadian (180/PI)
#define RadiansPerDegree (PI/180)
#define ABS(x) ((x) < 0 ? (-(x)) : (x))
#define SQR(x) ((x)*(x))
#define SunRadius 695000
#define SunSemiMajorAxis 149598845.0 /* Kilometers */
#define MaxModes 10
typedef struct {
int MinPhase,MaxPhase;
char ModeStr[20];
} ModeRec;
char VersionStr[] = "Sun ephemeris 1.0";
/* Keplerian Elements and misc. data for the satellite */
double EpochDay; /* time of epoch */
double EpochMeanAnomaly; /* Mean Anomaly at epoch */
long EpochOrbitNum; /* Integer orbit # of epoch */
double EpochRAAN; /* RAAN at epoch */
double epochMeanMotion; /* Revolutions/day */
double OrbitalDecay; /* Revolutions/day^2 */
double EpochArgPerigee; /* argument of perigee at epoch */
double Eccentricity;
double Inclination;
char SatName[100];
int ElementSet;
double BeaconFreq; /* Mhz, used for doppler calc */
double MaxPhase; /* Phase units in 1 orbit */
double perigeePhase;
int NumModes;
ModeRec Modes[MaxModes];
int PrintApogee;
int PrintEclipses;
int Flip;
/* Simulation Parameters */
double StartTime,EndTime, StepTime; /* In Days, 1 = New Year */
/* of reference year */
/* Site Parameters */
char SiteName[100];
double SiteLat,SiteLong,SiteAltitude,SiteMinElev;
#define SITELAT 37.943
#define SITELONG 122.318
#define SITEALT 73
GetSiteParams()
{
SiteLat = SITELAT*RadiansPerDegree;
SiteLong = SITELONG*RadiansPerDegree;
SiteAltitude = SITEALT/1000.0; /* convert to km */
SiteMinElev = 0;
Flip = PrintEclipses = 0;
}
#define ONEDAY 86400 /* in seconds */
#define FONEDAY 86400.0
#define UTC 8
double LocalTime (Time)
double Time;
{
return Time-UTC/24.0;
}
SPrintTime2(Str,Time)
char *Str;
double Time;
{
int day,hours,minutes,seconds;
char ampm;
day = Time;
Time -= day;
if (Time < 0)
Time += 1.0; /* Correct for truncation problems with negatives */
hours = Time*24;
Time -= hours/24.0;
minutes = Time*MinutesPerDay;
Time -= minutes/MinutesPerDay;
seconds = Time*SecondsPerDay;
seconds -= seconds/SecondsPerDay;
ampm = 'A';
if (hours > 12) {
hours -= 12;
ampm = 'P';
}
sprintf(Str,"%d:%02d%cM",hours,minutes,ampm);
}
PrintTime2(OutFile,Time)
FILE *OutFile;
double Time;
{
char str[100];
SPrintTime2(str,Time);
fprintf(OutFile,"%s",str);
}
GetSimulationParams()
{
int time, date, day, tick;
_sysdate (1, &time, &date, &day, &tick);
if ((time += UTC*60*60) > ONEDAY) {time -= ONEDAY; date++;}
StartTime = date - 2415019.0 + time / FONEDAY;
}
SunPos (CurrentTime, Azimuth, Elevation, SSPLat, SSPLong, Height)
double CurrentTime;
double *Azimuth, *Elevation;
double *SSPLat, *SSPLong, *Height;
{
extern double SunEpochTime,SunInclination,SunRAAN,SunEccentricity,
SunArgPerigee,SunMeanAnomaly,SunMeanMotion;
double MeanAnomaly, TrueAnomaly;
double SatX,SatY,SatZ; /* In Right Ascension based system */
double SatVX,SatVY,SatVZ; /* Kilometers/second */
double SiteX,SiteY,SiteZ;
double SiteVX,SiteVY;
double SiteMatrix[3][3];
double Radius; /* From geocenter */
MeanAnomaly = SunMeanAnomaly+ (CurrentTime-SunEpochTime)*SunMeanMotion*PI2;
TrueAnomaly = Kepler(MeanAnomaly,SunEccentricity);
GetSatPosition(SunEpochTime,SunRAAN,SunArgPerigee,SunSemiMajorAxis,
SunInclination,SunEccentricity,0.0,0.0,CurrentTime,
TrueAnomaly,&SatX,&SatY,&SatZ,&Radius,&SatVX,&SatVY,&SatVZ);
GetSitPosition(SiteLat,SiteLong,SiteAltitude,CurrentTime,
&SiteX,&SiteY,&SiteZ,&SiteVX,&SiteVY,SiteMatrix);
GetBearings(SatX,SatY,SatZ,SiteX,SiteY,SiteZ,SiteMatrix,
Azimuth,Elevation);
if (SSPLat && SSPLong && Height)
GetSubSatPoint(SatX,SatY,SatZ,CurrentTime,SSPLat,SSPLong,Height);
}
double SunSet (CurrentTime)
double CurrentTime;
{
double Azimuth, Elevation;
double StartTime, EndTime;
StartTime = CurrentTime;
EndTime = StartTime + .125;
SunPos (EndTime, &Azimuth, &Elevation, 0, 0, 0);
while (Elevation > 0.0) {
EndTime += .125;
SunPos (EndTime, &Azimuth, &Elevation, 0, 0, 0);
}
do {
CurrentTime = StartTime + ((EndTime - StartTime) / 2);
SunPos (CurrentTime, &Azimuth, &Elevation, 0, 0, 0);
if (Elevation > 0.0)
StartTime = CurrentTime;
else
EndTime = CurrentTime;
}
while (EndTime - StartTime > 1.0 / ONEDAY);
return CurrentTime;
}
double SunRise (CurrentTime)
double CurrentTime;
{
double Azimuth, Elevation;
double StartTime, EndTime;
StartTime = CurrentTime;
EndTime = StartTime + .125;
SunPos (EndTime, &Azimuth, &Elevation, 0, 0, 0);
while (Elevation < 0.0) {
EndTime += .125;
SunPos (EndTime, &Azimuth, &Elevation, 0, 0, 0);
}
do {
CurrentTime = StartTime + ((EndTime - StartTime) / 2);
SunPos (CurrentTime, &Azimuth, &Elevation, 0, 0, 0);
if (Elevation < 0.0)
StartTime = CurrentTime;
else
EndTime = CurrentTime;
}
while (EndTime - StartTime > 1.0 / ONEDAY);
return CurrentTime;
}
main()
{
double ReferenceOrbit; /* Floating point orbit # at epoch */
double CurrentTime; /* In Days */
double CurrentOrbit;
double AverageMotion, /* Corrected for drag */
CurrentMotion;
double MeanAnomaly,TrueAnomaly;
double SemiMajorAxis;
double Height;
double RAANPrecession,PerigeePrecession;
double SSPLat,SSPLong;
long OrbitNum,PrevOrbitNum;
long Day,PrevDay;
double Azimuth,Elevation,Range;
double RangeRate,Doppler;
int Phase;
char FileName[100];
FILE *OutFile;
int DidApogee;
double TmpTime,PrevTime;
int PrevVisible;
GetSiteParams();
GetSimulationParams();
InitOrbitRoutines((StartTime+EndTime)/2);
CurrentTime = StartTime;
SunPos (CurrentTime, &Azimuth, &Elevation, &SSPLat, &SSPLong, &Height);
printf("The sun is currently above %0.2lf%c degrees lattitude, %0.0lf%c degrees longitude.\n",
fabs (SSPLat*DegreesPerRadian),
((SSPLat*DegreesPerRadian > 0) ? 'N' : 'S'),
((SSPLong > PI) ? PI2-SSPLong : SSPLong)*DegreesPerRadian,
(SSPLong > PI) ? 'E' : 'W');
if (Elevation > 0.0) {
printf("It's azimuth is %0.0lf degrees and its elevation is %0.0lf degrees.\n",
Azimuth*DegreesPerRadian,Elevation*DegreesPerRadian);
printf ("The sun will set tonight at ");
CurrentTime = SunSet (CurrentTime);
PrintTime2 (stdout, LocalTime (CurrentTime));
printf (" and will rise tomorrow morning at ");
PrintTime2 (stdout, LocalTime (SunRise (CurrentTime)));
}
else {
printf ("The sun will rise at ");
CurrentTime = SunRise (CurrentTime);
PrintTime2 (stdout, LocalTime (CurrentTime));
printf (" and will set tomorrow evening at ");
PrintTime2 (stdout, LocalTime (SunSet (CurrentTime)));
}
printf (".\n");
}