001 /*
002 * $Id: SatelliteTleSGP4.java,v 1.4 2012/02/19 17:35:39 davep Exp $
003 *
004 * This file is part of McIDAS-V
005 *
006 * Copyright 2007-2012
007 * Space Science and Engineering Center (SSEC)
008 * University of Wisconsin - Madison
009 * 1225 W. Dayton Street, Madison, WI 53706, USA
010 * https://www.ssec.wisc.edu/mcidas
011 *
012 * All Rights Reserved
013 *
014 * McIDAS-V is built on Unidata's IDV and SSEC's VisAD libraries, and
015 * some McIDAS-V source code is based on IDV and VisAD source code.
016 *
017 * McIDAS-V is free software; you can redistribute it and/or modify
018 * it under the terms of the GNU Lesser Public License as published by
019 * the Free Software Foundation; either version 3 of the License, or
020 * (at your option) any later version.
021 *
022 * McIDAS-V is distributed in the hope that it will be useful,
023 * but WITHOUT ANY WARRANTY; without even the implied warranty of
024 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
025 * GNU Lesser Public License for more details.
026 *
027 * You should have received a copy of the GNU Lesser Public License
028 * along with this program. If not, see http://www.gnu.org/licenses.
029 */
030
031 package edu.wisc.ssec.mcidasv.data.adde.sgp4;
032 /*
033 import gov.nasa.worldwind.geom.Angle;
034 import gov.nasa.worldwind.geom.Position;
035 import java.awt.Color;
036 import java.util.Random;
037 import javax.swing.JOptionPane;
038 import name.gano.astro.AstroConst;
039 import name.gano.astro.GeoFunctions;
040 import name.gano.astro.Kepler;
041 import jsattrak.utilities.TLE;
042 import name.gano.astro.coordinates.J2kCoordinateConversion;
043 import name.gano.astro.propogators.sgp4_cssi.SGP4SatData;
044 import name.gano.astro.propogators.sgp4_cssi.SGP4unit;
045 import name.gano.astro.propogators.sgp4_cssi.SGP4utils;
046 import name.gano.worldwind.modelloader.WWModel3D_new;
047 import net.java.joglutils.model.ModelFactory;
048 */
049 /**
050 *
051 *
052 * @author ganos
053 */
054 public class SatelliteTleSGP4 extends AbstractSatellite
055 {
056 private TLE tle;
057 private SGP4SatData sgp4SatData; // sgp4 propogator data
058
059 // current time - julian date
060 double currentJulianDate = -1;
061
062 // TLE epoch -- used to calculate how old is TLE - Julian Date
063 double tleEpochJD = -1; // no age
064
065 // J2000 position and velocity vectors
066 private double[] j2kPos = new double[3]; // meters
067 private double[] j2kVel = new double[3]; // meters/sec
068 // true-equator, mean equinox TEME of date
069 private double[] posTEME = new double[3]; // true-equator, mean equinox TEME of date position for LLA calcs, meters
070 private double[] velTEME = new double[3]; // meters/sec
071
072 // lat,long,alt [radians, radians, m ]
073 private double[] lla = new double[3];
074
075 // plot options
076 private boolean plot2d = true;
077 // private Color satColor = Color.RED; // randomize in future
078 private boolean plot2DFootPrint = true;
079 private boolean fillFootPrint = true;
080 private int numPtsFootPrint = 41; // number of points in footprint, used to be 101
081
082 // ground track options -- grounds tracks draw to asending nodes, re-calculated at acending nodes
083 boolean showGroundTrack = true;
084 private int grnTrkPointsPerPeriod = 81; // equally space in time >=2 // used to be 121
085 private double groundTrackLeadPeriodMultiplier = 2.0; // how far forward to draw ground track - in terms of periods
086 private double groundTrackLagPeriodMultiplier = 1.0; // how far behind to draw ground track - in terms of periods
087 double[][] latLongLead; // leading lat/long coordinates for ground track
088 double[][] latLongLag; // laging lat/long coordinates for ground track
089 private double[][] temePosLead; // leading TEME position coordinates for ground track
090 private double[][] temePosLag; // laging TEME position coordinates for ground track
091 private double[] timeLead; // array for holding times associated with lead coordinates (Jul Date)
092 private double[] timeLag; // array - times associated with lag coordinates (Jul Date)
093 boolean groundTrackIni = false; // if ground track has been initialized
094
095 private boolean showName2D = true; // show name in 2D plots
096
097 // 3D Options
098 private boolean show3DOrbitTrace = true;
099 private boolean show3DFootprint = true;
100 private boolean show3DName = true; // not implemented to change yet
101 private boolean show3D = true; // no implemented to change yet, or to modify showing of sat
102 private boolean showGroundTrack3d = false;
103 private boolean show3DOrbitTraceECI = true; // show orbit in ECI mode otherwise , ECEF
104
105 // 3D model parameters
106 private boolean use3dModel = false; // use custom 3D model (or default sphere)
107 private String threeDModelPath = "globalstar/Globalstar.3ds"; // path to the custom model, default= globalstar/Globalstar.3ds ?
108 // private transient WWModel3D_new threeDModel; // DO NOT STORE when saving -- need to reload this -- TOO MUCH DATA!
109 private double threeDModelSizeFactor = 300000;
110
111 /** Creates a new instance of SatelliteProps - default properties with given name and TLE lines
112 * @param name name of satellite
113 * @param tleLine1 first line of two line element
114 * @param tleLine2 second line of two line element
115 * @throws Exception if TLE data is bad
116 */
117 public SatelliteTleSGP4(String name, String tleLine1, String tleLine2) throws Exception
118 {
119 // create internal TLE object
120 tle = new TLE(name,tleLine1,tleLine2);
121
122 // initialize sgp4 propogator data for the satellite
123 sgp4SatData = new SGP4SatData();
124
125 // try to load TLE into propogator
126
127 // options - hard coded
128 char opsmode = SGP4utils.OPSMODE_IMPROVED; // OPSMODE_IMPROVED
129 SGP4unit.Gravconsttype gravconsttype = SGP4unit.Gravconsttype.wgs72;
130
131 // load TLE data as strings and INI all SGP4 data
132 boolean loadSuccess = SGP4utils.readTLEandIniSGP4(name, tleLine1, tleLine2, opsmode, gravconsttype, sgp4SatData);
133
134 // if there is an error loading send an exception
135 if (!loadSuccess)
136 {
137 throw new Exception("Error loading TLE error code:" + sgp4SatData.error);
138 }
139
140 // calculate TLE age
141 tleEpochJD = sgp4SatData.jdsatepoch;
142
143 }
144 /*
145 @Override
146 public void updateTleData(TLE newTLE)
147 {
148 this.tle = newTLE; // save new TLE
149
150 // new spg4 object
151 sgp4SatData = new SGP4SatData();
152
153 // read TLE
154 // options - hard coded
155 char opsmode = SGP4utils.OPSMODE_IMPROVED; // OPSMODE_IMPROVED
156 SGP4unit.Gravconsttype gravconsttype = SGP4unit.Gravconsttype.wgs72;
157
158 // load TLE data as strings and INI all SGP4 data
159 boolean loadSuccess = SGP4utils.readTLEandIniSGP4(tle.getSatName(), tle.getLine1(), tle.getLine2(), opsmode, gravconsttype, sgp4SatData);
160
161 // if there is an error loading send an exception
162 if (!loadSuccess)
163 {
164 JOptionPane.showMessageDialog(null,"Error reading updated TLE, error code:" + sgp4SatData.error + "\n Satellite: "+ tle.getSatName());
165 }
166
167 // calculate TLE age
168 tleEpochJD = sgp4SatData.jdsatepoch;
169
170 // ground track needs to be redone with new data
171 groundTrackIni = false;
172
173 //System.out.println("Updated " + tle.getSatName() );
174 }
175 */
176 public void propogate2JulDate(double julDate)
177 {
178 // save date
179 this.currentJulianDate = julDate;
180
181 // using JulDate because function uses time diff between jultDate of ephemeris, SGP4 uses UTC
182 // propogate satellite to given date - saves result in TEME to posTEME and velTEME in km, km/s
183 boolean propSuccess = SGP4unit.sgp4Prop2JD(sgp4SatData, julDate, posTEME, velTEME);
184 if(!propSuccess)
185 {
186 System.out.println("Error SGP4 Propagation failed for sat: " + sgp4SatData.name + ", JD: " + sgp4SatData.jdsatepoch + ", error code: "+ sgp4SatData.error);
187 }
188
189 // scale output to meters
190 for(int i=0;i<3;i++)
191 {
192 // TEME
193 posTEME[i] = posTEME[i]*1000.0;
194 velTEME[i] = velTEME[i]*1000.0;
195 }
196
197 //print differene TT-UT
198 //System.out.println("TT-UT [days]= " + SDP4TimeUtilities.DeltaT(julDate-2450000)*24.0*60*60);
199
200
201 // SEG - 11 June 2009 -- new information (to me) on SGP4 propogator coordinate system:
202 // SGP4 output is in true equator and mean equinox (TEME) of Date *** note some think of epoch, but STK beleives it is of date from tests **
203 // It depends also on the source for the TLs if from the Nasa MCC might be MEME but most US Gov - TEME
204 // Also the Lat/Lon/Alt calculations are based on TEME (of Date) so that is correct as it was used before!
205 // References:
206 // http://www.stk.com/pdf/STKandSGP4/STKandSGP4.pdf (STK's stance on SGP4)
207 // http://www.agi.com/resources/faqSystem/files/2144.pdf (newer version of above)
208 // http://www.satobs.org/seesat/Aug-2004/0111.html
209 // http://celestrak.com/columns/v02n01/ "Orbital Coordinate Systems, Part I" by Dr. T.S. Kelso
210 // http://en.wikipedia.org/wiki/Earth_Centered_Inertial
211 // http://ccar.colorado.edu/asen5050/projects/projects_2004/aphanuphong/p1.html (bad coefficients? conversion between TEME and J2000 (though slightly off?))
212 // http://www.centerforspace.com/downloads/files/pubs/AIAA-2000-4025.pdf
213 // http://celestrak.com/software/vallado-sw.asp (good software)
214
215 double mjd = julDate-AstroConst.JDminusMJD;
216
217 // get position information back out - convert to J2000 (does TT time need to be used? - no)
218 //j2kPos = CoordinateConversion.EquatorialEquinoxToJ2K(mjd, sdp4Prop.itsR); //julDate-2400000.5
219 //j2kVel = CoordinateConversion.EquatorialEquinoxToJ2K(mjd, sdp4Prop.itsV);
220 // based on new info about coordinate system, to get the J2K other conversions are needed!
221 // precession from rk5 -> mod
222 double ttt = (mjd-AstroConst.MJD_J2000) /36525.0;
223 double[][] A = J2kCoordinateConversion.teme_j2k(J2kCoordinateConversion.Direction.to,ttt, 24, 2, 'a');
224 // rotate position and velocity
225 j2kPos = J2kCoordinateConversion.matvecmult( A, posTEME);
226 j2kVel = J2kCoordinateConversion.matvecmult( A, velTEME);
227
228 //System.out.println("Date: " + julDate +", Pos: " + sdp4Prop.itsR[0] + ", " + sdp4Prop.itsR[1] + ", " + sdp4Prop.itsR[2]);
229
230 // save old lat/long for ascending node check
231 double[] oldLLA = lla.clone(); // copy old LLA
232
233 // calculate Lat,Long,Alt - must use Mean of Date (MOD) Position
234 lla = GeoFunctions.GeodeticLLA(posTEME,julDate-AstroConst.JDminusMJD); // j2kPos
235
236 // Check to see if the ascending node has been passed
237 if(showGroundTrack==true)
238 {
239 if(groundTrackIni == false ) // update ground track needed
240 {
241 initializeGroundTrack();
242 }
243 else if( oldLLA[0] < 0 && lla[0] >=0) // check for ascending node pass
244 {
245 //System.out.println("Ascending NODE passed: " + tle.getSatName() );
246 initializeGroundTrack(); // for new ini each time
247
248 } // ascending node passed
249
250 } // if show ground track is true
251
252 // if 3D model - update its properties -- NOT DONE HERE - done in OrbitModelRenderable (so it can be done for any sat)
253
254 } // propogate2JulDate
255
256
257
258 // initalize the ground track from any starting point, as long as Juldate !=-1
259 private void initializeGroundTrack()
260 {
261 if(currentJulianDate == -1)
262 {
263 // nothing to do yet, we haven't been given an initial time
264 return;
265 }
266
267 // find time of last acending node crossing
268
269 // initial guess -- the current time
270 double lastAscendingNodeTime = currentJulianDate; // time of last ascending Node Time
271
272 // calculate period - in minutes
273 double periodMin = Kepler.CalculatePeriod(AstroConst.GM_Earth,j2kPos,j2kVel)/(60.0);
274 //System.out.println("period [min] = "+periodMin);
275
276 // time step divisions (in fractions of a day)
277 double fracOfPeriod = 15.0;
278 double timeStep = (periodMin/(60.0*24.0)) / fracOfPeriod;
279
280 // first next guess
281 double newGuess1 = lastAscendingNodeTime - timeStep;
282
283 // latitude variables
284 double lat0 = lla[0]; // current latitude
285 double lat1 = (calculateLatLongAltXyz(newGuess1))[0]; // calculate latitude values
286
287 // bracket the crossing using timeStep step sizes
288 while( !( lat0>=0 && lat1<0 ) )
289 {
290 // move back a step
291 lastAscendingNodeTime = newGuess1;
292 lat0 = lat1;
293
294 // next guess
295 newGuess1 = lastAscendingNodeTime - timeStep;
296
297 // calculate latitudes of the new value
298 lat1 = (calculateLatLongAltXyz(newGuess1))[0];
299 } // while searching for ascending node
300
301
302 // secand method -- determine within a second!
303 double outJul = secantMethod(lastAscendingNodeTime-timeStep, lastAscendingNodeTime, 1.0/(60.0*60.0*24.0), 20);
304 //System.out.println("Guess 1:" + (lastAscendingNodeTime-timeStep) );
305 //System.out.println("Guess 2:" + (lastAscendingNodeTime));
306 //System.out.println("Answer: " + outJul);
307
308 // update times: Trust Period Calculations for how far in the future and past to calculate out to
309 // WARNING: period calculation is based on osculating elements may not be 100% accurate
310 // as this is just for graphical updates should be okay (no mid-course corrections assumed)
311 lastAscendingNodeTime = outJul;
312 double leadEndTime = lastAscendingNodeTime + groundTrackLeadPeriodMultiplier*periodMin/(60.0*24); // Julian Date for last lead point (furthest in future)
313 double lagEndTime = lastAscendingNodeTime - groundTrackLagPeriodMultiplier*periodMin/(60.0*24); // Julian Date for the last lag point (furthest in past)
314
315 // fill in lead/lag arrays
316 fillGroundTrack(lastAscendingNodeTime,leadEndTime,lagEndTime);
317
318 groundTrackIni = true;
319 return;
320
321 } // initializeGroundTrack
322
323 // fill in the Ground Track given Jul Dates for
324 //
325 private void fillGroundTrack(double lastAscendingNodeTime, double leadEndTime, double lagEndTime)
326 {
327 // points in the lead direction
328 int ptsLead = (int)Math.ceil(grnTrkPointsPerPeriod*groundTrackLeadPeriodMultiplier);
329 latLongLead = new double[ptsLead][3];
330 temePosLead = new double[ptsLead][3];
331 timeLead = new double[ptsLead];
332
333 for(int i=0;i<ptsLead;i++)
334 {
335 double ptTime = lastAscendingNodeTime + i*(leadEndTime-lastAscendingNodeTime)/(ptsLead-1);
336
337 // PUT HERE calculate lat lon
338 double[] ptLlaXyz = calculateLatLongAltXyz(ptTime);
339
340 latLongLead[i][0] = ptLlaXyz[0]; // save lat
341 latLongLead[i][1] = ptLlaXyz[1]; // save long
342 latLongLead[i][2] = ptLlaXyz[2]; // save altitude
343
344 temePosLead[i][0] = ptLlaXyz[3]; // x
345 temePosLead[i][1] = ptLlaXyz[4]; // y
346 temePosLead[i][2] = ptLlaXyz[5]; // z
347
348 timeLead[i] = ptTime; // save time
349
350 } // for each lead point
351
352 // points in the lag direction
353 int ptsLag = (int)Math.ceil(grnTrkPointsPerPeriod*groundTrackLagPeriodMultiplier);
354 latLongLag = new double[ptsLag][3];
355 temePosLag = new double[ptsLag][3];
356 timeLag = new double[ptsLag];
357
358 for(int i=0;i<ptsLag;i++)
359 {
360 double ptTime = lastAscendingNodeTime + i*(lagEndTime-lastAscendingNodeTime)/(ptsLag-1);
361
362 double[] ptLlaXyz = calculateLatLongAltXyz(ptTime);
363
364 latLongLag[i][0] = ptLlaXyz[0]; // save lat
365 latLongLag[i][1] = ptLlaXyz[1]; // save long
366 latLongLag[i][2] = ptLlaXyz[2]; // save alt
367
368 temePosLag[i][0] = ptLlaXyz[3]; // x
369 temePosLag[i][1] = ptLlaXyz[4]; // y
370 temePosLag[i][2] = ptLlaXyz[5]; // z
371
372 timeLag[i] = ptTime;
373
374 } // for each lag point
375 } // fillGroundTrack
376
377 // takes in JulDate, returns lla and teme position
378 private double[] calculateLatLongAltXyz(double ptTime)
379 {
380 double[] ptPos = calculateTemePositionFromUT(ptTime);
381
382 // get lat and long
383 double[] ptLla = GeoFunctions.GeodeticLLA(ptPos,ptTime-AstroConst.JDminusMJD);
384
385 double[] ptLlaXyz = new double[] {ptLla[0],ptLla[1],ptLla[2],ptPos[0],ptPos[1],ptPos[2]};
386
387 return ptLlaXyz;
388 } // calculateLatLongAlt
389
390 //
391
392 /**
393 * Calculate J2K position of this sat at a given JulDateTime (doesn't save the time) - can be useful for event searches or optimization
394 * @param julDate - julian date
395 * @return j2k position of satellite in meters
396 */
397 /*
398 @Override
399 public double[] calculateJ2KPositionFromUT(double julDate)
400 {
401 double[] ptPos = calculateTemePositionFromUT(julDate);
402
403 double mjd = julDate-AstroConst.JDminusMJD;
404
405 // get position information back out - convert to J2000
406 // precession from rk5 -> mod
407 double ttt = (mjd-AstroConst.MJD_J2000) /36525.0;
408 double[][] A = J2kCoordinateConversion.teme_j2k(J2kCoordinateConversion.Direction.to,ttt, 24, 2, 'a');
409 // rotate position
410 double[] j2kPosI = J2kCoordinateConversion.matvecmult( A, ptPos);
411
412 return j2kPosI;
413
414 } // calculatePositionFromUT
415 */
416 /**
417 * Calculate true-equator, mean equinox (TEME) of date position of this sat at a given JulDateTime (doesn't save the time) - can be useful for event searches or optimization
418 * @param julDate - julian date
419 * @return j2k position of satellite in meters
420 */
421
422 public double[] calculateTemePositionFromUT(double julDate)
423 {
424 double[] ptPos = new double[3];
425 double[] ptVel = new double[3];
426
427 // using JulDate because function uses time diff between jultDate of ephemeris, SGP4 uses UTC
428 // propogate satellite to given date - saves result in TEME to posTEME and velTEME in km, km/s
429 boolean propSuccess = SGP4unit.sgp4Prop2JD(sgp4SatData, julDate, ptPos, ptVel);
430 if(!propSuccess)
431 {
432 System.out.println("Error (2) SGP4 Propagation failed for sat: " + sgp4SatData.name + ", JD: " + sgp4SatData.jdsatepoch + ", error code: "+ sgp4SatData.error);
433 }
434
435 // scale output to meters
436 for(int i=0;i<3;i++)
437 {
438 // TEME
439 ptPos[i] = ptPos[i]*1000.0;
440 }
441
442 return ptPos;
443
444 } // calculatePositionFromUT
445
446
447 //---------------------------------------
448 // SECANT Routines to find Crossings of the Equator (hopefully Ascending Nodes)
449 // xn_1 = date guess 1
450 // xn date guess 2
451 // tol = convergence tolerance
452 // maxIter = maximum iterations allowed
453 // RETURNS: double = julian date of crossing
454 private double secantMethod(double xn_1, double xn, double tol, int maxIter)
455 {
456
457 double d;
458
459 // calculate functional values at guesses
460 double fn_1 = latitudeGivenJulianDate(xn_1);
461 double fn = latitudeGivenJulianDate(xn);
462
463 for (int n = 1; n <= maxIter; n++)
464 {
465 d = (xn - xn_1) / (fn - fn_1) * fn;
466 if (Math.abs(d) < tol) // convergence check
467 {
468 //System.out.println("Iters:"+n);
469 return xn;
470 }
471
472 // save past point
473 xn_1 = xn;
474 fn_1 = fn;
475
476 // new point
477 xn = xn - d;
478 fn = latitudeGivenJulianDate(xn);
479 }
480
481 System.out.println("Warning: Secant Method - Max Iteration limit reached finding Asending Node.");
482
483 return xn;
484 } // secantMethod
485
486 private double latitudeGivenJulianDate(double julDate)
487 {
488 // computer latiude of the spacecraft at a given date
489 double[] ptPos = calculateTemePositionFromUT(julDate);
490
491 // get lat and long
492 double[] ptLla = GeoFunctions.GeodeticLLA(ptPos,julDate-AstroConst.JDminusMJD);
493
494 return ptLla[0]; // pass back latitude
495
496 } // latitudeGivenJulianDate
497
498 //--------------------------------------
499
500 public void setShowGroundTrack(boolean showGrndTrk)
501 {
502 showGroundTrack = showGrndTrk;
503
504 if(showGrndTrk == false)
505 {
506 groundTrackIni = false;
507 latLongLead = new double[][] {{}}; // save some space
508 latLongLag = new double[][] {{}}; // sace some space
509 temePosLag = new double[][] {{}};
510 temePosLead = new double[][] {{}};
511 timeLead = new double[] {};
512 timeLag = new double[] {};
513 }
514 else
515 {
516 // ground track needs to be initalized
517 initializeGroundTrack();
518 }
519 }
520 /*
521 public boolean getShowGroundTrack()
522 {
523 return showGroundTrack;
524 }
525 */
526 public double getLatitude()
527 {
528 return lla[0];
529 }
530
531 public double getLongitude()
532 {
533 return lla[1];
534 }
535
536 public double getAltitude()
537 {
538 return lla[2];
539 }
540
541 public double[] getLLA()
542 {
543 return lla;
544 }
545 /*
546 // TT or UTC? = UTC
547 public double getSatTleEpochJulDate()
548 {
549 return sgp4SatData.jdsatepoch;
550 }
551
552 public double getCurrentJulDate()
553 {
554 return currentJulianDate;
555 }
556
557 public double[] getJ2000Position()
558 {
559 return j2kPos.clone();
560 }
561
562 public double[] getJ2000Velocity()
563 {
564 return j2kVel.clone();
565 }
566
567 public boolean getPlot2D()
568 {
569 return plot2d;
570 }
571
572 public Color getSatColor()
573 {
574 return satColor;
575 }
576
577 public boolean getPlot2DFootPrint()
578 {
579 return plot2DFootPrint;
580 }
581
582 public boolean getGroundTrackIni()
583 {
584 return groundTrackIni;
585 }
586
587 public void setGroundTrackIni2False()
588 {
589 // forces repaint of ground track next update
590 groundTrackIni = false;
591 }
592
593 public int getNumGroundTrackLeadPts()
594 {
595 return latLongLead.length;
596 }
597
598 public int getNumGroundTrackLagPts()
599 {
600 return latLongLag.length;
601 }
602
603 public double[] getGroundTrackLlaLeadPt(int index)
604 {
605 return new double[] {latLongLead[index][0],latLongLead[index][1],latLongLead[index][2]};
606 }
607
608 public double[] getGroundTrackLlaLagPt(int index)
609 {
610 return new double[] {latLongLag[index][0],latLongLag[index][1],latLongLag[index][2]};
611 }
612
613 public double[] getGroundTrackXyzLeadPt(int index)
614 {
615 return new double[] {getTemePosLead()[index][0],getTemePosLead()[index][1],getTemePosLead()[index][2]};
616 }
617
618 public double[] getGroundTrackXyzLagPt(int index)
619 {
620 return new double[] {getTemePosLag()[index][0],getTemePosLag()[index][1],getTemePosLag()[index][2]};
621 }
622
623
624 // returns satellite's current perdiod based on current pos/vel in Minutes
625 public double getPeriod()
626 {
627 return Kepler.CalculatePeriod(AstroConst.GM_Earth,j2kPos,j2kVel)/(60.0);
628 }
629
630 public String getName()
631 {
632 return tle.getSatName();
633 }
634
635 public double[] getKeplarianElements()
636 {
637 return Kepler.SingularOsculatingElements( AstroConst.GM_Earth, j2kPos, j2kVel );
638 }
639
640 public double getTleEpochJD()
641 {
642 return tleEpochJD;
643 }
644
645 public double getTleAgeDays()
646 {
647 return currentJulianDate - tleEpochJD;
648 }
649
650 public int getNumPtsFootPrint()
651 {
652 return numPtsFootPrint;
653 }
654
655 public void setNumPtsFootPrint(int numPtsFootPrint)
656 {
657 this.numPtsFootPrint = numPtsFootPrint;
658 }
659
660 public boolean isShowName2D()
661 {
662 return showName2D;
663 }
664
665 public void setShowName2D(boolean showName2D)
666 {
667 this.showName2D = showName2D;
668 }
669
670 public boolean isFillFootPrint()
671 {
672 return fillFootPrint;
673 }
674
675 public void setFillFootPrint(boolean fillFootPrint)
676 {
677 this.fillFootPrint = fillFootPrint;
678 }
679
680 public int getGrnTrkPointsPerPeriod()
681 {
682 return grnTrkPointsPerPeriod;
683 }
684
685 public void setGrnTrkPointsPerPeriod(int grnTrkPointsPerPeriod)
686 {
687 this.grnTrkPointsPerPeriod = grnTrkPointsPerPeriod;
688 }
689
690 public double getGroundTrackLeadPeriodMultiplier()
691 {
692 return groundTrackLeadPeriodMultiplier;
693 }
694
695 public void setGroundTrackLeadPeriodMultiplier(double groundTrackLeadPeriodMultiplier)
696 {
697 this.groundTrackLeadPeriodMultiplier = groundTrackLeadPeriodMultiplier;
698 }
699
700 public double getGroundTrackLagPeriodMultiplier()
701 {
702 return groundTrackLagPeriodMultiplier;
703 }
704
705 public void setGroundTrackLagPeriodMultiplier(double groundTrackLagPeriodMultiplier)
706 {
707 this.groundTrackLagPeriodMultiplier = groundTrackLagPeriodMultiplier;
708 }
709
710 public void setPlot2d(boolean plot2d)
711 {
712 this.plot2d = plot2d;
713 }
714
715 public void setSatColor(Color satColor)
716 {
717 this.satColor = satColor;
718 }
719
720 public void setPlot2DFootPrint(boolean plot2DFootPrint)
721 {
722 this.plot2DFootPrint = plot2DFootPrint;
723 }
724 */
725 public double[] getTEMEPos()
726 {
727 return posTEME.clone();
728 }
729 /*
730 public boolean isShow3DOrbitTrace()
731 {
732 return show3DOrbitTrace;
733 }
734
735 public void setShow3DOrbitTrace(boolean show3DOrbitTrace)
736 {
737 this.show3DOrbitTrace = show3DOrbitTrace;
738 }
739
740 public boolean isShow3DFootprint()
741 {
742 return show3DFootprint;
743 }
744
745 public void setShow3DFootprint(boolean show3DFootprint)
746 {
747 this.show3DFootprint = show3DFootprint;
748 }
749
750 public boolean isShow3DName()
751 {
752 return show3DName;
753 }
754
755 public void setShow3DName(boolean show3DName)
756 {
757 this.show3DName = show3DName;
758 }
759
760 public boolean isShowGroundTrack3d()
761 {
762 return showGroundTrack3d;
763 }
764
765 public void setShowGroundTrack3d(boolean showGroundTrack3d)
766 {
767 this.showGroundTrack3d = showGroundTrack3d;
768 }
769
770 public boolean isShow3DOrbitTraceECI()
771 {
772 return show3DOrbitTraceECI;
773 }
774
775 public void setShow3DOrbitTraceECI(boolean show3DOrbitTraceECI)
776 {
777 this.show3DOrbitTraceECI = show3DOrbitTraceECI;
778 }
779
780 public boolean isShow3D()
781 {
782 return show3D;
783 }
784
785 public void setShow3D(boolean show3D)
786 {
787 this.show3D = show3D;
788 }
789
790 public // laging lat/long coordinates for ground track
791 double[][] getTemePosLead()
792 {
793 return temePosLead;
794 }
795
796 public // leading Mean of date position coordinates for ground track
797 double[][] getTemePosLag()
798 {
799 return temePosLag;
800 }
801
802 public // laging Mean of date position coordinates for ground track
803 double[] getTimeLead()
804 {
805 return timeLead;
806 }
807
808 public // array for holding times associated with lead coordinates (Jul Date)
809 double[] getTimeLag()
810 {
811 return timeLag;
812 }
813
814 // 3D model -------------------------
815 public boolean isUse3dModel()
816 {
817 return use3dModel;
818 }
819
820 public void setUse3dModel(boolean use3dModel)
821 {
822 this.use3dModel = use3dModel;
823
824 if(use3dModel && threeDModelPath.length() > 0)
825 {
826 // check that file exsists? - auto done in loader
827
828 //String path = "data/models/globalstar/Globalstar.3ds";
829 //String path = "data/models/isscomplete/iss_complete.3ds";
830
831 loadNewModel(threeDModelPath);
832 }
833 }
834
835 public String getThreeDModelPath()
836 {
837 return threeDModelPath;
838 }
839 */
840 /**
841 * Relative path to the model -- relative from "user.dir"/data/models/
842 * @param path
843 */
844 /*
845 public void setThreeDModelPath(String path)
846 {
847 if(use3dModel && !(path.equalsIgnoreCase(this.threeDModelPath)) )
848 {
849 // need to load the model
850 loadNewModel(path);//"test/data/globalstar/Globalstar.3ds");
851 }
852
853 this.threeDModelPath = path; // save path no matter
854 }
855
856 private void loadNewModel(String path)
857 {
858 String localPath = "data/models/"; // path to models root from user.dir
859
860 try
861 {
862 net.java.joglutils.model.geometry.Model model3DS = ModelFactory.createModel(localPath + path);
863 //model3DS.setUseLighting(false); // turn off lighting!
864
865 threeDModel = new WWModel3D_new(model3DS,
866 new Position(Angle.fromRadians(this.getLatitude()),
867 Angle.fromRadians(this.getLongitude()),
868 this.getAltitude()));
869
870 threeDModel.setMaitainConstantSize(true);
871 threeDModel.setSize(threeDModelSizeFactor); // this needs to be a property!
872
873 threeDModel.updateAttitude(this); // fixes attitude intitially
874
875 }catch(Exception e)
876 {
877 System.out.println("ERROR LOADING 3D MODEL");
878 }
879 }
880
881 public WWModel3D_new getThreeDModel()
882 {
883 return threeDModel;
884 }
885
886 public double[] getTEMEVelocity()
887 {
888 return velTEME.clone();
889 }
890
891 public double getThreeDModelSizeFactor()
892 {
893 return threeDModelSizeFactor;
894 }
895
896 public void setThreeDModelSizeFactor(double modelSizeFactor)
897 {
898 // should the 3D model be reloaded now?
899 if(modelSizeFactor != threeDModelSizeFactor && use3dModel && threeDModelPath.length()>0)
900 {
901 //loadNewModel(threeDModelPath);
902 if(threeDModel != null)
903 {
904 threeDModel.setSize(modelSizeFactor);
905 }
906 }
907
908 this.threeDModelSizeFactor = modelSizeFactor;
909 }
910
911 @Override
912 public String toString()
913 {
914 return this.tle.getSatName();
915 }
916 */
917 } // SatelliteProps