//perform calculation at time for given TLE lines //if you can get at objects from the JS use the commented version //this will make GetPos() and GetVel redundant /*public Vectors calculate(int time, string line1, string line2){ TLE_DATA sat = new TLE_DATA(); sat.TLE_DATA_INIT(line1, line2); return satvec(sat, timeutil.UnixTimeToDayNumber(time),timeutil.UnixTimeToDayFrac(time)); }*/ public void calculate(int time, string line1, string line2){ TLE_DATA sat = new TLE_DATA(); sat.TLE_DATA_INIT(line1, line2); results = satvec(sat, timeutil.UnixTimeToDayNumber(time),timeutil.UnixTimeToDayFrac(time)); }
//get day fraction public double EpochToFract(TLE_DATA tle){ return tle.TE - (int)tle.TE; }
//calculate stalite position at DN, TN private Vectors satvec(TLE_DATA sat,int DN, double TN){ //calculate average precession rates double N0 = sat.MM/86400; //Mean Motion rad/s double A0 = Math.Pow((GM/N0/N0),(1.0/3.0)); //semi major axis km double B0 = A0*Math.Sqrt(1 - sat.EC*sat.EC); //semi minor axis km double SI = Math.Sin(sat.IN); double CI = Math.Cos(sat.IN); double PC = RE*A0/(B0*B0); //precession constant rad/day PC = 1.5*J2*PC*PC*sat.MM; //precession constant rads/day double QD = -PC*CI; //precession rate rad/day double WD = PC*(5*CI*CI-1)/2; //Perigee precession rate rad/day double DC = -2*(sat.M2)/sat.MM/3; //REM Drag coeff. (Angular momentum rate)/(Ang mom) s^-1 //Sidereal and Solar data. NEVER needs changing. valid until year ~2015 //double YG = 2000; //double G0 = 98.9821; //GHAA, year YG Jan 0.0 // UPDATED BY ALEX: Sidereal and Solar data. Valid to year ~2030 double YG = 2014; double G0 = 99.5828; //GHAA, year YG Jan 0.0 //Bring sun data to satellite epoch double TEG = (timeutil.EpochToDay(sat) - timeutil.FNday(Convert.ToInt32(YG),1,0)) + timeutil.EpochToFract(sat); //Elapsed Time: Epoch - YG //there is a wired bug in this line fixed by defining WE explicitly double GHAE = degtorad(G0) + TEG*6.300388; //GHA Aries, epoch //Time double T = (DN - timeutil.EpochToDay(sat)) + (TN - timeutil.EpochToFract(sat)); //Elapsed Time since epoch, days //Linear drag terms double DT = DC*T/2; double KD = 1 + 4*DT; double KDP = 1 - 7*DT; double M = sat.MA + sat.MM*T*(1- 3*DT); //Mean anomaly at YR,TN //orbit number int DR = Convert.ToInt32(M/(2*PI)); //strip out whole number of revs; M = M - DR*2*PI; //M now in range 0 - 2pi //double RN = sat.RV + DR; //current orbit number //solve M = EA - EC*Sin(EA) for EA givne M, using newtons methood double EA = M; //Initial solution //declare here for use later double D = 1; double DNOM = 0; double C = 0; double S = 0; while((Math.Abs(D) >= 1e-5)){ C = Math.Cos(EA); S = Math.Sin(EA); DNOM = 1 - sat.EC*C; D = (EA- (sat.EC*S) -M)/DNOM; //change to EA for better solution EA = EA - D; //by this ammount } //distances double A = A0*KD; double B = B0*KD; //double RS = A*DNOM; //calculate satalite position and velocity in plane of elipse double Sx = A*(C - sat.EC); double Sy = B*S; double Vx = -A*S/DNOM*N0; double Vy = B*C/DNOM*N0; double AP = sat.WP + WD*T*KDP; double RAAN = sat.RA + QD*T*KDP; double CW = Math.Cos(AP); double CQ = Math.Cos(RAAN); double SW = Math.Sin(AP); double SQ = Math.Sin(RAAN); //plane . celestial coordinate transformtation, [C] = [RAAN]*[IN]*[AP] double CXx = CW*CQ - SW*CI*SQ; double CYx = CW*SQ + SW*CI*CQ; double CZx = SW*SI; double CXy = -SW*CQ - CW*CI*SQ; double CYy = -SW*SQ + CW*CI*CQ; double CZy = CW*SI; //double CXz = SI*SQ; //double CYz = -SI*CQ; //double CZz = CI; //Compute satalites position vector and velocity in clestial coordinates double SATx = Sx*CXx + Sy*CXy; double SATy = Sx*CYx + Sy*CYy; double SATz = Sx*CZx + Sy*CZy; double VELx = Vx*CXx + Vy*CXy; double VELy = Vx*CYx + Vy*CYy; double VELz = Vx*CZx + Vy*CZy; //express position and velocity in Geocentric coordinates //weired WE def bug also in this line fixed with explicit definition double GHAA = GHAE + 6.300388*T; //GHA Aries at elapsed time T C = Math.Cos(-GHAA); S = Math.Sin(-GHAA); Sx = SATx*C - SATy*S; Sy = SATx*S + SATy*C; double Sz = SATz; Vx = VELx*C - VELy*S; Vy = VELx*S + VELy*C; double Vz = VELz; Vector pos = new Vector(Sx, Sy, Sz); Vector vel = new Vector(Vx, Vy, Vz);; Vectors output = new Vectors(pos, vel); return output; }
//convert satilite epoch to day No public int EpochToDay(TLE_DATA tle){ return FNday(tle.YE,1,0) + (int)tle.TE; }