00001
00002
00008
00009
00010
00012
00013 #include "Keplerian.h"
00014 namespace O_SESSAME {
00015
00017 Keplerian::~Keplerian()
00018 {
00019 }
00020
00021
00029 Keplerian* Keplerian::NewPointer()
00030 {
00031 return new Keplerian();
00032 }
00033
00034
00042 Keplerian* Keplerian::Clone()
00043 {
00044 return new Keplerian(*this);
00045 }
00046
00047
00049 Keplerian::Keplerian() : m_OrbitalElements(NUM_KEPLERIAN_ELEMENTS)
00050 {
00051 }
00052
00053
00057 Keplerian::Keplerian(const Vector& _Elements)
00058 {
00059 SetState(_Elements);
00060 }
00061
00062
00070 void Keplerian::SetPositionVelocity(const Vector& _Position, const Vector& _Velocity)
00071 {
00072 Vector K_Vector(3); K_Vector(VectorIndexBase+2) = 1;
00073 Vector AngMomentum = crossP(_Position, _Velocity);
00074 Vector LineNodes = crossP(K_Vector, AngMomentum);
00075 double r = norm2(_Position);
00076 double v = norm2(_Velocity);
00077 double n = norm2(LineNodes);
00078 Vector Eccentricity = 1/MU * (pow(v,2) - MU/r) * _Position - _Position.dot(_Velocity)*_Velocity;
00079 m_OrbitalElements(ECCENTRICITY) = norm2(Eccentricity);
00080 double xi = pow(v,2) / 2 - MU/r;
00081
00082
00083 m_OrbitalElements(SEMIMAJOR_AXIS) = -MU / (2 * xi);
00084
00085
00086 m_OrbitalElements(INCLINATION) = acos(AngMomentum(VectorIndexBase + 2) / norm2(AngMomentum));
00087
00088
00089 m_OrbitalElements(LONG_ASC_NODE) = LineNodes(VectorIndexBase) / norm2(LineNodes);
00090 if (LineNodes(VectorIndexBase+1) < 0)
00091 m_OrbitalElements(LONG_ASC_NODE) = 2*PI - m_OrbitalElements(LONG_ASC_NODE);
00092
00093
00094 m_OrbitalElements(ARG_PERIGEE) = LineNodes.dot(Eccentricity) / (n * m_OrbitalElements(ECCENTRICITY));
00095 if (Eccentricity(VectorIndexBase+2) < 0)
00096 m_OrbitalElements(ARG_PERIGEE) = 2*PI - m_OrbitalElements(ARG_PERIGEE);
00097
00098
00099 m_OrbitalElements(TRUE_ANOMALY) = Eccentricity.dot(_Position) / (r * m_OrbitalElements(ECCENTRICITY));
00100 if (_Position.dot(_Velocity) < 0)
00101 m_OrbitalElements(TRUE_ANOMALY) = 2*PI - m_OrbitalElements(TRUE_ANOMALY);
00102
00103
00104 if(m_OrbitalElements(ECCENTRICITY) == 0)
00105 {
00106 m_OrbitalElements(ARG_PERIGEE) = 0;
00107 if(m_OrbitalElements(INCLINATION) == 0)
00108 {
00109 m_OrbitalElements(LONG_ASC_NODE) = 0;
00110 m_OrbitalElements(TRUE_ANOMALY) = _Position(VectorIndexBase) / r;
00111 if(_Position(VectorIndexBase+1) < 0)
00112 m_OrbitalElements(TRUE_ANOMALY) = 2*PI - m_OrbitalElements(TRUE_ANOMALY);
00113 }
00114 else
00115 {
00116 m_OrbitalElements(TRUE_ANOMALY) = LineNodes.dot(_Position)/(n * r);
00117 if(_Position(VectorIndexBase+2) < 0)
00118 m_OrbitalElements(TRUE_ANOMALY) = 2*PI - m_OrbitalElements(TRUE_ANOMALY);
00119 }
00120 }
00121 else if(m_OrbitalElements(INCLINATION) == 0)
00122 {
00123 m_OrbitalElements(LONG_ASC_NODE) = 0;
00124 m_OrbitalElements(ARG_PERIGEE) = Eccentricity(VectorIndexBase) / m_OrbitalElements(ECCENTRICITY);
00125 if (Eccentricity(VectorIndexBase+2) < 0)
00126 m_OrbitalElements(ARG_PERIGEE) = 2*PI - m_OrbitalElements(ARG_PERIGEE);
00127 }
00128 return;
00129 }
00130
00131
00138 void Keplerian::SetPositionVelocity(const Vector& _PositionVelocity)
00139 {
00140 Vector Pos(3); Pos(_) = _PositionVelocity(_(VectorIndexBase, VectorIndexBase+2));
00141 Vector Vel(3); Vel(_) = _PositionVelocity(_(VectorIndexBase+3, VectorIndexBase+5));
00142
00143 SetPositionVelocity(Pos, Vel);
00144 }
00145
00146
00153 void Keplerian::SetPositionVelocity(const Vector& _Position, const Vector& _Velocity, const OrbitFrame& _OrbFrame)
00154 {
00155
00156 Vector Position = _OrbFrame.GetRotation2IJK() * _Position;
00157 Vector Velocity = _OrbFrame.GetRotation2IJK() * _Velocity;
00158
00159
00160 SetPositionVelocity(Position, Velocity);
00161 }
00162
00163
00169 void Keplerian::SetPositionVelocity(const Vector& _PositionVelocity, const OrbitFrame& _OrbFrame)
00170 {
00171 Vector Pos(3); Pos(_) = _PositionVelocity(_(VectorIndexBase, VectorIndexBase+2));
00172 Vector Vel(3); Vel(_) = _PositionVelocity(_(VectorIndexBase+3, VectorIndexBase+5));
00173
00174 SetPositionVelocity(Pos, Vel, _OrbFrame);
00175 }
00176
00177
00183 Vector Keplerian::GetPositionVelocity() const
00184 {
00185 Vector rv(6);
00186 rv(VectorIndexBase + 0) = (GetSemiParameter() * cos(GetTrueAnomaly())) / (1 + GetEccentricity() * cos(GetTrueAnomaly()));
00187 rv(VectorIndexBase + 1) = (GetSemiParameter() * sin(GetTrueAnomaly())) / (1 + GetEccentricity() * cos(GetTrueAnomaly()));
00188
00189 rv(VectorIndexBase + 3) = -sqrt(MU/GetSemiParameter()) * sin(GetTrueAnomaly());
00190 rv(VectorIndexBase + 4) = sqrt(MU/GetSemiParameter()) * (GetEccentricity() + cos(GetTrueAnomaly()));
00191
00192 return rv;
00193 }
00194
00195
00200 Vector Keplerian::GetPositionVelocity(const OrbitFrame& _TargetOrbFrame) const
00201 {
00202
00203 Vector rv = GetPositionVelocity();
00204
00205
00206 rv(_(VectorIndexBase, VectorIndexBase+2)) = _TargetOrbFrame.GetRotationFromIJK() * rv(_(VectorIndexBase, VectorIndexBase+2));
00207 rv(_(VectorIndexBase+3, VectorIndexBase+5)) = _TargetOrbFrame.GetRotationFromIJK() * rv(_(VectorIndexBase+3, VectorIndexBase+5));
00208 return rv;
00209 }
00210
00211
00219 void Keplerian::GetPositionVelocity(Vector& _Position, Vector& _Velocity) const
00220 {
00221 _Position(VectorIndexBase + 0) = (GetSemiParameter() * cos(GetTrueAnomaly())) / (1 + GetEccentricity() * cos(GetTrueAnomaly()));
00222 _Position(VectorIndexBase + 1) = (GetSemiParameter() * sin(GetTrueAnomaly())) / (1 + GetEccentricity() * cos(GetTrueAnomaly()));
00223 _Position(VectorIndexBase + 2) = 0;
00224 _Velocity(VectorIndexBase + 0) = -sqrt(MU/GetSemiParameter()) * sin(GetTrueAnomaly());
00225 _Velocity(VectorIndexBase + 1) = sqrt(MU/GetSemiParameter()) * (GetEccentricity() + cos(GetTrueAnomaly()));
00226 _Velocity(VectorIndexBase + 2) = 0;
00227 return;
00228 }
00229
00230
00236 void Keplerian::GetPositionVelocity(Vector& _Position, Vector& _Velocity, const OrbitFrame& _TargetOrbFrame) const
00237 {
00238
00239 GetPositionVelocity(_Position, _Velocity);
00240
00241
00242 _Position = _TargetOrbFrame.GetRotationFromIJK() * _Position;
00243 _Velocity = _TargetOrbFrame.GetRotationFromIJK() * _Velocity;
00244 return;
00245 }
00246
00247
00253 double Keplerian::GetEccentricAnomalyFromMeanAnomaly(const double& _MeanAnomaly)
00254 {
00255
00256 double tolerance = 1e-11;
00258 double _EccentricAnomaly;
00259 double testEccAnomaly;
00260 double eccentricity = m_OrbitalElements(ECCENTRICITY);
00261
00262
00263 testEccAnomaly = _MeanAnomaly;
00264 _EccentricAnomaly = testEccAnomaly -
00265 ( testEccAnomaly - eccentricity*sin(testEccAnomaly) - _MeanAnomaly ) /
00266 ( 1 - eccentricity*cos(testEccAnomaly) );
00267
00268 while ( fabs(_EccentricAnomaly-testEccAnomaly) > tolerance )
00269 {
00270 testEccAnomaly = _EccentricAnomaly;
00271 _EccentricAnomaly = testEccAnomaly -
00272 ( testEccAnomaly - eccentricity*sin(testEccAnomaly) - _MeanAnomaly ) /
00273 ( 1 - eccentricity*cos(testEccAnomaly) );
00274 }
00275
00276 return _EccentricAnomaly;
00277 }
00278
00279
00287 void Keplerian::GetTrueAnomalyFromEccentricAnomaly(const double& _EccentricAnomaly)
00288 {
00289
00290 double cosTrueAnomaly;
00291 double sinTrueAnomaly;
00292 double semimajoraxis = m_OrbitalElements(SEMIMAJOR_AXIS);
00293 double eccentricity = m_OrbitalElements(ECCENTRICITY);
00294
00295 cosTrueAnomaly = ( eccentricity - cos(_EccentricAnomaly) ) /
00296 ( eccentricity*cos(_EccentricAnomaly) - 1 );
00297 sinTrueAnomaly = ( ( semimajoraxis*sqrt(1 - eccentricity*eccentricity) ) /
00298 ( semimajoraxis*(1 - eccentricity*cos(_EccentricAnomaly)) ) ) *
00299 sin(_EccentricAnomaly);
00300
00301 m_OrbitalElements(TRUE_ANOMALY) = atan2( sinTrueAnomaly, cosTrueAnomaly );
00302 if ( m_OrbitalElements(TRUE_ANOMALY) < 0 );
00303 {
00304 m_OrbitalElements(TRUE_ANOMALY) = m_OrbitalElements(TRUE_ANOMALY) + 2*PI;
00305 }
00306
00307 return;
00308 }
00309
00310
00337 tleStruct Keplerian::ReadTwoLineElementSet(const string& _TwoLineElementSet)
00338 {
00339
00340 int finder = 0;
00341 int endlfinder;
00342 int finderLength;
00343
00344 string LineZero;
00345 string LineOne;
00346 string LineTwo;
00347
00348 stringstream placeholder;
00349 int exponent;
00350
00351
00352 endlfinder = _TwoLineElementSet.find('\n',finder);
00353 finderLength = endlfinder - finder;
00354 LineZero = _TwoLineElementSet.substr(finder,finderLength);
00355
00356 finder = endlfinder + 1;
00357 endlfinder = _TwoLineElementSet.find('\n',finder);
00358 finderLength = endlfinder - finder;
00359 LineOne = _TwoLineElementSet.substr(finder,finderLength);
00360
00361 finder = endlfinder + 1;
00362 endlfinder = _TwoLineElementSet.size();
00363 finderLength = endlfinder - finder;
00364 LineTwo = _TwoLineElementSet.substr(finder,finderLength);
00365
00367
00368
00369
00370
00371
00372
00373 m_tleData.satName = LineZero.substr(0,24);
00374
00375
00376
00377
00378
00379
00380 finder = 2;
00381 endlfinder = LineOne.find(' ',finder);
00382 finderLength = endlfinder - finder;
00383 placeholder << LineOne.substr(finder,finderLength-1);
00384 placeholder >> m_tleData.satNumber;
00385
00386 placeholder.clear();
00387 placeholder << LineOne.substr(endlfinder-1,1);
00388 placeholder >> m_tleData.satClassification;
00389
00390
00391 finder = endlfinder + 1;
00392 endlfinder = LineOne.find(' ',finder);
00393 placeholder.clear();
00394 placeholder << LineOne.substr(finder,2);
00395 placeholder >> m_tleData.launchYear;
00398
00399 placeholder.clear();
00400 placeholder << LineOne.substr(finder+2,3);
00401 placeholder >> m_tleData.launchNumber;
00402
00403 placeholder.clear();
00404 finderLength = endlfinder - finder;
00405 placeholder << LineOne.substr(finder+5,finderLength-5);
00406 placeholder >> m_tleData.launchPiece;
00407
00408
00409 finder = endlfinder + 1;
00410 endlfinder = LineOne.find(' ',finder);
00411 placeholder.clear();
00412 placeholder << LineOne.substr(finder,2);
00413 placeholder >> m_tleData.epochYear;
00414
00415 placeholder.clear();
00416 finderLength = endlfinder - finder;
00417 placeholder << LineOne.substr(finder+2,finderLength-2);
00418 placeholder >> m_tleData.epochDay;
00419
00420
00421 finder = endlfinder + 1;
00422 endlfinder = LineOne.find(' ',finder);
00423 finderLength = endlfinder - finder;
00424 placeholder.clear();
00425 placeholder << LineOne.substr(finder,finderLength);
00426 placeholder >> m_tleData.meanmotion1stDeriv;
00427
00428
00429 finder = endlfinder + 1;
00430 endlfinder = LineOne.find_first_of("-+",finder+1);
00431 finderLength = endlfinder - finder;
00432 placeholder.clear();
00433 placeholder << LineOne.substr(finder,finderLength);
00434 placeholder >> m_tleData.meanmotion2ndDeriv;
00435 finder = endlfinder;
00436 endlfinder = LineOne.find(' ',finder);
00437 finderLength = endlfinder - finder;
00438 placeholder.clear();
00439 placeholder << LineOne.substr(finder,finderLength);
00440 placeholder >> exponent;
00441 m_tleData.meanmotion2ndDeriv *= pow(10.0,exponent);
00442 if ( LineOne[finder] == '+' || LineOne[finder] == '-' )
00443 m_tleData.meanmotion2ndDeriv /= pow(10.0,finderLength-1);
00444 else
00445 m_tleData.meanmotion2ndDeriv /= pow(10.0,finderLength);
00446
00447
00448 finder = endlfinder + 1;
00449 endlfinder = LineOne.find_first_of("-+",finder+1);
00450 finderLength = endlfinder - finder;
00451 placeholder.clear();
00452 placeholder << LineOne.substr(finder,finderLength);
00453 placeholder >> m_tleData.bstarDrag;
00454 finder = endlfinder;
00455 endlfinder = LineOne.find(' ',finder);
00456 placeholder.clear();
00457 placeholder << LineOne.substr(finder,finderLength);
00458 placeholder >> exponent;
00459 m_tleData.bstarDrag *= pow(10.0,exponent);
00460 if ( LineOne[finder] == '+' || LineOne[finder] == '-' )
00461 m_tleData.bstarDrag /= pow(10.0,finderLength-1);
00462 else
00463 m_tleData.bstarDrag /= pow(10.0,finderLength);
00464
00465
00466 finder = endlfinder + 1;
00467 endlfinder = LineOne.find(' ',finder);
00468 finderLength = endlfinder - finder;
00469 placeholder.clear();
00470 placeholder << LineOne.substr(finder,finderLength);
00471 placeholder >> m_tleData.ephemerisType;
00472
00473
00474 finder = endlfinder + 1;
00475 endlfinder = LineOne.size()-1;
00476 finderLength = endlfinder - finder;
00477 placeholder.clear();
00478 placeholder << LineOne.substr(finder,finderLength);
00479 placeholder >> m_tleData.elementNumber;
00480
00481
00482 placeholder.clear();
00483 placeholder << LineOne.substr(endlfinder,1);
00484 placeholder >> m_tleData.checksumLine1;
00485
00486
00487
00488
00489
00490
00491
00492 endlfinder = LineTwo.find(' ',2);
00493 finder = endlfinder + 1;
00494 endlfinder = LineTwo.find(' ',finder);
00495 finderLength = endlfinder - finder;
00496 placeholder.clear();
00497 placeholder << LineTwo.substr(finder,finderLength);
00498 placeholder >> m_OrbitalElements(INCLINATION);
00499 m_OrbitalElements(INCLINATION) *= PI/180.0;
00500
00501
00502 finder = endlfinder + 1;
00503 endlfinder = LineTwo.find(' ',finder);
00504 finderLength = endlfinder - finder;
00505 placeholder.clear();
00506 placeholder << LineTwo.substr(finder,finderLength);
00507 placeholder >> m_OrbitalElements(LONG_ASC_NODE);
00508 m_OrbitalElements(LONG_ASC_NODE) *= PI/180.0;
00511
00512 finder = endlfinder + 1;
00513 endlfinder = LineTwo.find(' ',finder);
00514 finderLength = endlfinder - finder;
00515 placeholder.clear();
00516 placeholder << "0." << LineTwo.substr(finder,finderLength);
00517 placeholder >> m_OrbitalElements(ECCENTRICITY);
00518 m_OrbitalElements(ECCENTRICITY) *= PI/180.0;
00519
00520
00521 finder = endlfinder + 1;
00522 endlfinder = LineTwo.find(' ',finder);
00523 finderLength = endlfinder - finder;
00524 placeholder.clear();
00525 placeholder << LineTwo.substr(finder,finderLength);
00526 placeholder >> m_OrbitalElements(ARG_PERIGEE);
00527 m_OrbitalElements(ARG_PERIGEE) *= PI/180.0;
00528
00529
00530 finder = endlfinder + 1;
00531 endlfinder = LineTwo.find(' ',finder);
00532 finderLength = endlfinder - finder;
00533 placeholder.clear();
00534 placeholder << LineTwo.substr(finder,finderLength);
00535 placeholder >> m_tleData.meanAnomaly;
00536 m_tleData.meanAnomaly *= PI/180.0;
00537 m_tleData.eccentricAnomaly = GetEccentricAnomalyFromMeanAnomaly(m_tleData.meanAnomaly);
00538
00539
00540 finder = endlfinder + 1;
00541 endlfinder = LineTwo.size()-1;
00542 placeholder.clear();
00543 placeholder << LineTwo.substr(finder,11);
00544 placeholder >> m_tleData.meanMotion;
00545
00546 m_OrbitalElements(SEMIMAJOR_AXIS) = pow( (MU/pow(m_tleData.meanMotion,2)), (1.0/3.0) );
00547
00548 GetTrueAnomalyFromEccentricAnomaly(m_tleData.eccentricAnomaly);
00549
00550
00551 placeholder.clear();
00552 placeholder << LineTwo.substr(finder+11,5);
00553 placeholder >> m_tleData.revolutionNumber;
00554
00555
00556 placeholder.clear();
00557 placeholder << LineTwo.substr(endlfinder,1);
00558 placeholder >> m_tleData.checksumLine2;
00559
00560 return m_tleData;
00561 }
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00584 void Keplerian::SetState(const Vector& _Elements)
00585 {
00586 m_OrbitalElements = _Elements;
00587 return;
00588 }
00589
00590
00594 Vector Keplerian::GetState() const
00595 {
00596 return m_OrbitalElements;
00597 }
00598
00599
00603 void Keplerian::GetState(Vector& _Elements) const
00604 {
00605 _Elements = m_OrbitalElements;
00606 return;
00607 }
00608
00609
00610
00611
00612 }
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652