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