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