CppEphem
CEPlanet.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * CEPlanet.cpp: CppEphem *
3  * ----------------------------------------------------------------------- *
4  * Copyright © 2017 JCardenzana *
5  * ----------------------------------------------------------------------- *
6  * *
7  * This program is free software: you can redistribute it and/or modify *
8  * it under the terms of the GNU General Public License as published by *
9  * the Free Software Foundation, either version 3 of the License, or *
10  * (at your option) any later version. *
11  * *
12  * This program is distributed in the hope that it will be useful, *
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15  * GNU General Public License for more details. *
16  * *
17  * You should have received a copy of the GNU General Public License *
18  * along with this program. If not, see <http://www.gnu.org/licenses/>. *
19  * *
20  ***************************************************************************/
21 
135 #include <stdio.h>
136 
137 #include "CEPlanet.h"
138 
139 /**********************************************************************/
143  CEBody()
144 {
145  init_members();
146 }
147 
148 /**********************************************************************/
156 CEPlanet::CEPlanet(const std::string& name,
157  const CEAngle& xcoord,
158  const CEAngle& ycoord,
159  const CESkyCoordType& coord_type) :
160  CEBody(name, xcoord, ycoord, coord_type)
161 {
162  init_members();
163 }
164 
165 
166 /**********************************************************************/
171 CEPlanet::CEPlanet(const CEPlanet& other) :
172  CEBody(other)
173 {
174  init_members();
175  copy_members(other);
176 }
177 
178 
179 /**********************************************************************/
183 {
184  free_members();
185 }
186 
187 
188 /**********************************************************************/
195 {
196  if (this != &other) {
197  // Copy parent class members
198  this->CEBody::operator=(other);
199 
200  free_members();
201  init_members();
202  copy_members(other);
203  }
204  return *this;
205 }
206 
207 
208 /**********************************************************************/
213 {
214  CEPlanet mercury("Mercury", 0.0, 0.0) ;
215  mercury.SetSemiMajorAxis_AU(0.38709843, 0.0) ;
216  mercury.SetEccentricity(0.20563661, 0.00002123) ;
217  mercury.SetInclination(7.00559432, -0.00590158, CEAngleType::DEGREES) ;
218  mercury.SetMeanLongitude(252.25166724, 149472.67486623, CEAngleType::DEGREES) ;
219  mercury.SetPerihelionLongitude(77.45771895, 0.15940013, CEAngleType::DEGREES) ;
220  mercury.SetAscendingNodeLongitude(48.33961819, -0.12214182, CEAngleType::DEGREES) ;
221 
222  // Set planet characteristics
223  mercury.SetMeanRadius_m(2440000.0) ;
224  mercury.SetAlbedo(0.106) ;
225  mercury.SetMass_kg(3.302E23) ;
226 
227  // Set the sofa planet ID
228  mercury.SetSofaID(1) ;
229 
230  return mercury ;
231 }
232 
233 /**********************************************************************/
238 {
239  CEPlanet venus("Venus", 0.0, 0.0) ;
240  venus.SetSemiMajorAxis_AU(0.72332102, -0.00000026) ;
241  venus.SetEccentricity(0.00676399, -0.00005107) ;
242  venus.SetInclination(3.39777545, 0.00043494, CEAngleType::DEGREES) ;
243  venus.SetMeanLongitude(181.97970850, 58517.81560260, CEAngleType::DEGREES) ;
244  venus.SetPerihelionLongitude(131.76755713, 0.05679648, CEAngleType::DEGREES) ;
245  venus.SetAscendingNodeLongitude(76.67261496, -0.27274174, CEAngleType::DEGREES) ;
246 
247  // Set the planetary properties
248  venus.SetMeanRadius_m(6051800.0) ;
249  venus.SetAlbedo(0.65) ;
250  venus.SetMass_kg(48.685E23) ;
251 
252  // Set the sofa planet ID
253  venus.SetSofaID(2) ;
254 
255  return venus ;
256 }
257 
258 /**********************************************************************/
263 {
264  CEPlanet earth("Earth", 0.0, 0.0) ;
265  earth.SetSemiMajorAxis_AU(1.00000018, -0.00000003) ;
266  earth.SetEccentricity(0.01673163, -0.00003661) ;
267  earth.SetInclination(-0.00054346, -0.01337178, CEAngleType::DEGREES) ;
268  earth.SetMeanLongitude(100.46691572, 35999.37306329, CEAngleType::DEGREES) ;
269  earth.SetPerihelionLongitude(102.93005885, 0.31795260, CEAngleType::DEGREES) ;
270  earth.SetAscendingNodeLongitude(-5.11260389, -0.24123856, CEAngleType::DEGREES) ;
271 
272  // Set planetary properties
273  earth.SetMeanRadius_m(0.0) ;
274  earth.SetAlbedo(0.0) ;
275  earth.SetMass_kg(0.0) ;
276 
277  // Set the sofa planet ID
278  earth.SetSofaID(3.5) ;
279 
280  return earth ;
281 }
282 
283 /**********************************************************************/
289 {
290  CEPlanet em_barycenter("EMBaryCenter", 0.0, 0.0) ;
291  em_barycenter.SetSemiMajorAxis_AU(1.00000018, -0.00000003) ;
292  em_barycenter.SetEccentricity(0.01673163, -0.00003661) ;
293  em_barycenter.SetInclination(-0.00054346, -0.01337178, CEAngleType::DEGREES) ;
294  em_barycenter.SetMeanLongitude(100.46691572, 35999.37306329, CEAngleType::DEGREES) ;
295  em_barycenter.SetPerihelionLongitude(102.93005885, 0.31795260, CEAngleType::DEGREES) ;
296  em_barycenter.SetAscendingNodeLongitude(-5.11260389, -0.24123856, CEAngleType::DEGREES) ;
297 
298  // Set the sofa planet ID
299  em_barycenter.SetSofaID(3) ;
300 
301  return em_barycenter ;
302 }
303 
304 /**********************************************************************/
310 {
311  CEPlanet mars("Mars", 0.0, 0.0) ;
312  mars.SetSemiMajorAxis_AU(1.52371243, 0.00000097) ;
313  mars.SetEccentricity(0.09336511, 0.00009149) ;
314  mars.SetInclination(1.85181869, -0.00724757, CEAngleType::DEGREES) ;
315  mars.SetMeanLongitude(-4.56813164, 19140.29934243, CEAngleType::DEGREES) ;
316  mars.SetPerihelionLongitude(-23.91744784, 0.45223625, CEAngleType::DEGREES) ;
317  mars.SetAscendingNodeLongitude(49.71320984, -0.26852431, CEAngleType::DEGREES) ;
318 
319  // Set planetary properties
320  mars.SetMeanRadius_m(3389900.0) ;
321  mars.SetAlbedo(0.150) ;
322  mars.SetMass_kg(6.4185E23) ;
323 
324  // Set the sofa planet ID
325  mars.SetSofaID(4) ;
326 
327 
328  return mars ;
329 }
330 
331 /**********************************************************************/
337 {
338  CEPlanet jupiter("Jupiter", 0.0, 0.0) ;
339  jupiter.SetSemiMajorAxis_AU(5.20248019, -0.00002864) ;
340  jupiter.SetEccentricity(0.04853590, -0.00005107) ;
341  jupiter.SetInclination(1.29861416, -0.00322699, CEAngleType::DEGREES) ;
342  jupiter.SetMeanLongitude(34.33479152, 3034.90371757, CEAngleType::DEGREES) ;
343  jupiter.SetPerihelionLongitude(14.27495244, 0.18199196, CEAngleType::DEGREES) ;
344  jupiter.SetAscendingNodeLongitude(100.29282654, 0.13024619, CEAngleType::DEGREES) ;
345 
346  jupiter.SetExtraTerms(-0.00012452, 0.06064060, -0.35635438, 38.35125000) ;
347 
348  // Set planetary properties
349  jupiter.SetMeanRadius_m(69911000.0) ;
350  jupiter.SetAlbedo(0.52) ;
351  jupiter.SetMass_kg(1.89813E27) ;
352 
353  // Set the sofa planet ID
354  jupiter.SetSofaID(5) ;
355 
356  return jupiter ;
357 }
358 
359 /**********************************************************************/
365 {
366  CEPlanet saturn("Saturn", 0.0, 0.0) ;
367  saturn.SetSemiMajorAxis_AU(9.54149883, -0.00003065) ;
368  saturn.SetEccentricity(0.05550825, -0.00032044) ;
369  saturn.SetInclination(2.49424102, 0.00451969, CEAngleType::DEGREES) ;
370  saturn.SetMeanLongitude(50.07571329, 1222.11494724, CEAngleType::DEGREES) ;
371  saturn.SetPerihelionLongitude(92.86136063, 0.54179478, CEAngleType::DEGREES) ;
372  saturn.SetAscendingNodeLongitude(113.63998702, -0.25015002, CEAngleType::DEGREES) ;
373 
374  saturn.SetExtraTerms(0.00025899, -0.13434469, 0.87320147, 38.35125000) ;
375 
376  // Set planetary properties
377  saturn.SetMeanRadius_m(58232000.0) ;
378  saturn.SetAlbedo(0.47) ;
379  saturn.SetMass_kg(5.68319E26) ;
380 
381  // Set the sofa planet ID
382  saturn.SetSofaID(6) ;
383 
384  return saturn ;
385 }
386 
387 /**********************************************************************/
393 {
394  CEPlanet uranus("Uranus", 0.0, 0.0) ;
395  uranus.SetSemiMajorAxis_AU(19.18797948, -0.00020455) ;
396  uranus.SetEccentricity(0.04685740, -0.00001550) ;
397  uranus.SetInclination(0.77298127, -0.00180155, CEAngleType::DEGREES) ;
398  uranus.SetMeanLongitude(314.20276625, 428.49512595, CEAngleType::DEGREES) ;
399  uranus.SetPerihelionLongitude(172.43404441, 0.09266985, CEAngleType::DEGREES) ;
400  uranus.SetAscendingNodeLongitude(73.96250215, 0.05739699, CEAngleType::DEGREES) ;
401 
402  uranus.SetExtraTerms(0.00058331, -0.97731848, 0.17689245, 7.67025000) ;
403 
404  // Set planetary properties
405  uranus.SetMeanRadius_m(25362000.0) ;
406  uranus.SetAlbedo(0.51) ;
407  uranus.SetMass_kg(8.68103E25) ;
408 
409  // Set the sofa planet ID
410  uranus.SetSofaID(7) ;
411 
412  return uranus ;
413 }
414 
415 /**********************************************************************/
421 {
422  CEPlanet neptune("Neptune", 0.0, 0.0) ;
423  neptune.SetSemiMajorAxis_AU(30.06952752, 0.00006447) ;
424  neptune.SetEccentricity(0.00895439, 0.00000818) ;
425  neptune.SetInclination(1.77005520, 0.00022400, CEAngleType::DEGREES) ;
426  neptune.SetMeanLongitude(304.22289287, 218.46515314, CEAngleType::DEGREES) ;
427  neptune.SetPerihelionLongitude(46.68158724, 0.01009938, CEAngleType::DEGREES) ;
428  neptune.SetAscendingNodeLongitude(131.78635853, -0.00606302, CEAngleType::DEGREES) ;
429 
430  neptune.SetExtraTerms(-0.00041348, 0.68346318, -0.10162547, 7.67025000) ;
431 
432  // Set planetary properties
433  neptune.SetMeanRadius_m(24624000.0) ;
434  neptune.SetAlbedo(0.41) ;
435  neptune.SetMass_kg(1.0241E26) ;
436 
437  // Set the sofa planet ID
438  neptune.SetSofaID(8) ;
439 
440  return neptune ;
441 }
442 
443 /**********************************************************************/
450 {
451  CEPlanet pluto("Pluto", 0.0, 0.0) ;
452  pluto.SetSemiMajorAxis_AU(39.48686035, 0.00449751) ;
453  pluto.SetEccentricity(0.24885238, 0.00006016) ;
454  pluto.SetInclination(17.14104260, 0.00000501, CEAngleType::DEGREES) ;
455  pluto.SetMeanLongitude(238.96535011, 145.18042903, CEAngleType::DEGREES) ;
456  pluto.SetPerihelionLongitude(224.09702598, -0.00968827, CEAngleType::DEGREES) ;
457  pluto.SetAscendingNodeLongitude(110.30167986, -0.00809981, CEAngleType::DEGREES) ;
458 
459  pluto.SetExtraTerms(-0.01262724, 0.0, 0.0, 0.0) ;
460 
461  // Set planetary properties
462  pluto.SetMeanRadius_m(1195000.0) ;
463  pluto.SetAlbedo(0.3) ;
464  pluto.SetMass_kg(1.307E22) ;
465 
466  // Set the sofa planet ID
467  // Note that Pluto's positions cannot be computed via the SOFA method
468  pluto.SetSofaID(9) ;
469 
470  return pluto ;
471 }
472 
473 
474 /**********************************************************************/
480 void CEPlanet::SetSemiMajorAxis_AU(double semi_major_axis_au,
481  double semi_major_axis_au_per_cent)
482 {
483  // Make sure the semi_major_axis is positive
484  if (semi_major_axis_au <= 0.0) {
485  std::cerr << "[ERROR] CEPlanet::SetSemiMajorAxis_AU() : Semi major axis must be positive!\n";
486  } else {
487  semi_major_axis_au_ = semi_major_axis_au ;
488  semi_major_axis_au_per_cent_ = semi_major_axis_au_per_cent ;
489  }
490 }
491 
492 /**********************************************************************/
498 void CEPlanet::SetEccentricity(double eccentricity,
499  double eccentricity_per_cent)
500 {
501  eccentricity_ = eccentricity ;
502  eccentricity_per_cent_ = eccentricity_per_cent ;
503 }
504 
505 /**********************************************************************/
512 void CEPlanet::SetInclination(double inclination,
513  double inclination_per_cent,
514  CEAngleType angle_type)
515 {
516  if (angle_type == CEAngleType::RADIANS) {
517  inclination *= DR2D ;
518  inclination_per_cent *= DR2D ;
519  }
520 
521  inclination_deg_ = inclination ;
522  inclination_deg_per_cent_ = inclination_per_cent * DR2D ;
523 }
524 
525 /**********************************************************************/
532 void CEPlanet::SetMeanLongitude(double mean_longitude,
533  double mean_longitude_per_cent,
534  CEAngleType angle_type)
535 {
536  if (angle_type == CEAngleType::RADIANS) {
537  mean_longitude *= DR2D ;
538  mean_longitude_per_cent *= DR2D ;
539  }
540 
541  mean_longitude_deg_ = mean_longitude ;
542  mean_longitude_deg_per_cent_ = mean_longitude_per_cent ;
543 }
544 
545 /**********************************************************************/
552 void CEPlanet::SetPerihelionLongitude(double perihelion_lon,
553  double perihelion_lon_per_cent,
554  CEAngleType angle_type)
555 {
556  if (angle_type == CEAngleType::RADIANS) {
557  perihelion_lon *= DR2D ;
558  perihelion_lon_per_cent *= DR2D ;
559  }
560 
561  perihelion_lon_deg_ = perihelion_lon ;
562  perihelion_long_deg_per_cent_ = perihelion_lon_per_cent ;
563 }
564 
565 /**********************************************************************/
572 void CEPlanet::SetAscendingNodeLongitude(double ascending_node_lon,
573  double ascending_node_lon_per_cent,
574  CEAngleType angle_type)
575 {
576  if (angle_type == CEAngleType::RADIANS) {
577  ascending_node_lon *= DR2D ;
578  ascending_node_lon_per_cent *= DR2D ;
579  }
580 
581  ascending_node_lon_deg_ = ascending_node_lon ;
582  ascending_node_lon_deg_per_cent_ = ascending_node_lon_per_cent ;
583 }
584 
585 
586 /**********************************************************************/
592 double CEPlanet::EarthDist_AU(const CEDate& date)
593 {
594  // Compute the position of the earth relative to the planet to account
595  // for the time delay of the planet
596  CEPlanet earth = CEPlanet::Earth();
597  earth.SetAlgorithm(Algorithm());
598  earth.UpdatePosition(date.JD());
599 
600  std::vector<double> pos = pos_icrs_;
601  double x = pos[0] - earth.GetXICRS();
602  double y = pos[1] - earth.GetYICRS();
603  double z = pos[2] - earth.GetZICRS();
604 
605  // Compute the light travel time from the planet to Earth in days
606  return std::sqrt(x*x + y*y + z*z);
607 }
608 
609 
610 /**********************************************************************/
617 std::vector<double> CEPlanet::PositionICRS_Obs(const CEDate& date) const
618 {
619  // Make a copy of the planet so we dont need to reset values
620  CEPlanet past(*this);
621  past.UpdatePosition(date);
622 
623  // Compute the light travel-time delay
624  double earth_dist = past.EarthDist_AU(date);
625  double delay = earth_dist / CppEphem::c_au_per_day();
626 
627  // Return the positions as observed
628  past.UpdatePosition(date.JD() - delay);
629  return past.PositionICRS();
630 }
631 
632 
633 /**********************************************************************/
641  const CEObserver& observer) const
642 {
643  // Update planet position
644  UpdatePosition(date);
645 
646  // Get the observer ICRS position on a given date and the time-delayed
647  // position of the planet on that date
648  std::vector<double> offset = observer.PositionICRS(date);
649  std::vector<double> pos_obs = PositionICRS_Obs(date);
650 
651  // Compute the difference in coordinates
652  for (int i=0; i<3; i++)
653  offset[i] = pos_obs[i] - offset[i];
654 
655  // Convert the offset into RA,Dec
656  double ra(0.0);
657  double dec(0.0);
658  iauC2s(&offset[0], &ra, &dec);
659 
660  // Note that the coordinate system depends on the planet
662  if (sofa_planet_id_ == 3.5) {
663  coordsys = CESkyCoordType::CIRS;
664  }
665  CESkyCoord coord(ra, dec, coordsys);
666 
667  return coord.ConvertTo(CESkyCoordType::OBSERVED, date, observer);
668 }
669 
670 
671 /**********************************************************************/
678 void CEPlanet::UpdateCoordinates(double new_jd) const
679 {
680  // If no date was supplied, or if the date hasnt changed, do nothing
681  if ((new_jd < -1.0e29) || (new_jd == cached_jd_)) return;
682 
683  // Update the positions given the current julian date
684  UpdatePosition(new_jd);
685 
686  CEDate date(new_jd, CEDateType::JD);
687  std::vector<double> pos_delayed = PositionICRS_Obs(date);
688 
689  // Now compute the actual sky coordinates in ICRS
690  double x;
691  double y;
692  iauC2s(&pos_delayed[0], &x, &y);
693 
694  // Make sure the x-coordinate is in the appropriate range
695  x = iauAnp(x);
696 
697  // Update the coordinates
698  CESkyCoord::SetCoordinates(CEAngle::Rad(x), CEAngle::Rad(y), GetCoordSystem());
699 
700  // Now that the coordinates are updated, reset the time
701  cached_jd_ = new_jd ;
702 }
703 
704 /**********************************************************************/
709 void CEPlanet::UpdatePosition(const double& jd) const
710 {
711  // If no date was supplied, or if the date hasnt changed, do nothing
712  if ((jd < -1.0e29) || (jd == cached_jd_)) {
713  return ;
714  } else if (algorithm_type_ == CEPlanetAlgo::JPL) {
715  Update_JPL(jd) ;
716  } else if (algorithm_type_ == CEPlanetAlgo::SOFA) {
717  Update_SOFA(jd) ;
718  }
719 }
720 
721 /**********************************************************************/
729 void CEPlanet::Update_SOFA(double new_jd) const
730 {
731  // Compute the TDB based on supplied jd
732  double tdb1(0.0);
733  double tdb2(0.0);
734  double mjd = new_jd - CEDate::GetMJD2JDFactor();
735  CEDate::UTC2TDB(mjd, &tdb1, &tdb2);
736 
737  // Compute the Earth relative corrections
738  double pvb[2][3];
739  double pvhe[2][3];
740  int err = iauEpv00(tdb1, tdb2, pvhe, pvb);
741 
742  // If this isn't the earth, compute the planet's heliocentric position
743  if (sofa_planet_id_ != 3.5) {
744  double pvh[2][3];
745  err = iauPlan94(tdb1, tdb2, sofa_planet_id_, pvh) ;
746 
747  // Compute the corrected factors for heliocentric -> barycentric as
748  // bary_planet = helio_planet + (bary_earth - helio_earth)
749  for (int i=0; i<2; i++) {
750  for (int j=0; j<3; j++) {
751  pvb[i][j] = pvh[i][j] + (pvb[i][j] - pvhe[i][j]);
752  }
753  }
754  }
755 
756  // If the returned error code is zero, compute the values
757  if (err == 0) {
758  // position
759  pos_icrs_ = std::vector<double>(pvb[0], pvb[0]+3);
760 
761  // velocity
762  vel_icrs_ = std::vector<double>(pvb[1], pvb[1]+3);
763  } else {
764  std::cerr << "[ERROR] failed to compute planet positions for " << Name() << ". ErrCode=" << err << "\n" ;
765  }
766 }
767 
768 /**********************************************************************/
774 void CEPlanet::Update_JPL(double new_jd) const
775 {
776  /* Date has changed, so we need to recompute the coordinates of this object */
777 
778  // Compute the number of centuries since J2000 epoch
779  double mjd = new_jd - CEDate::GetMJD2JDFactor();
780  double tdb1;
781  double tdb2;
782  CEDate::UTC2TDB(mjd, &tdb1, &tdb2);
783  double T = (tdb1+tdb2 - CppEphem::julian_date_J2000()) / DJC;
784 
785  // Compute the values
786  double a = ComputeElement(semi_major_axis_au_, semi_major_axis_au_per_cent_, T) ;
787  double e = ComputeElement(eccentricity_, eccentricity_per_cent_, T) ;
788  double I = ComputeElement(inclination_deg_, inclination_deg_per_cent_, T) ;
789  double L = ComputeElement(mean_longitude_deg_, mean_longitude_deg_per_cent_, T) ;
790  double w = ComputeElement(perihelion_lon_deg_, perihelion_long_deg_per_cent_, T) ;
791  double O = ComputeElement(ascending_node_lon_deg_, ascending_node_lon_deg_per_cent_, T) ;
792 
793  // Compute the argument of perihelion (W) and mean anomoly (M)
794  double W = w - O ;
795  double M = MeanAnomaly(L, w, T) ;
796 
797  // Iterate on the eccentric anomoly
798  double E = M + e*DR2D * std::sin(M*DD2R) ;
799  double del_E(0.0) ;
800  E = EccentricAnomoly(M, e, E, del_E) ;
801 
802  // Compute the planets heliocentric coordinates in it's orbital plane
803  double x_prime = a * (std::cos(E*DD2R) - e) ;
804  double y_prime = a * std::sqrt(1.0 - (e*e)) * std::sin(E*DD2R) ;
805 // double z_prime = 0.0 ; // by definition
806 
807  // Transform the coordinates into the coordinates of the ecliptic
808  double x_ecl = x_prime * (std::cos(W*DD2R)*std::cos(O*DD2R) - std::sin(W*DD2R)*std::sin(O*DD2R)*std::cos(I*DD2R)) +
809  y_prime * (-std::sin(W*DD2R)*std::cos(O*DD2R) - std::cos(W*DD2R)*std::sin(O*DD2R)*std::cos(I*DD2R)) ;
810  double y_ecl = x_prime * (std::cos(W*DD2R)*std::sin(O*DD2R) + std::sin(W*DD2R)*std::cos(O*DD2R)*std::cos(I*DD2R)) +
811  y_prime * (-std::sin(W*DD2R)*std::sin(O*DD2R) + std::cos(W*DD2R)*std::cos(O*DD2R)*std::cos(I*DD2R)) ;
812  double z_ecl = x_prime * (std::sin(W*DD2R)*std::sin(I*DD2R)) + y_prime * (std::cos(W*DD2R)*std::sin(I*DD2R)) ;
813 
814  // Convert from the ecliptic coordinates to ICRS
815  double obl = DD2R * 23.43928 ;
816  pos_icrs_[0] = x_ecl ;
817  pos_icrs_[1] = y_ecl * std::cos(obl) - z_ecl * std::sin(obl) ;
818  pos_icrs_[2] = y_ecl * std::sin(obl) + z_ecl * std::cos(obl) ;
819 }
820 
821 
822 /**********************************************************************/
830 double CEPlanet::MeanAnomaly(double mean_longitude_deg,
831  double perihelion_long_deg,
832  double T) const
833 {
834  double M = mean_longitude_deg - perihelion_long_deg + (b_*T*T)
835  + c_*std::cos(f_*T*DD2R) + s_*std::sin(f_*T*DD2R) ;
836  // Scale M to be in the range (-180,180)
837  while (M>180.0) M-=360.0 ;
838  while (M<-180.0) M+=360.0 ;
839 
840  return M ;
841 }
842 
843 /**********************************************************************/
851 double CEPlanet::EccentricAnomoly(double& M,
852  double& e,
853  double& En,
854  double& del_E) const
855 {
856  // Note that because this method is called recursively, no
857  // variables should be created inside of this method
858 
859  // compute del_E
860  del_E = (M - (En - e*DR2D*std::sin(En*DD2R))) / (1.0-e*std::cos(En*DD2R)) ;
861 
862  // If the change is less than the tolerance, we're all good!
863  if ( std::fabs(del_E) < E_tol) {
864  return En ;
865  }
866  // If not, then do another iteration
867  else {
868  En += del_E ;
869  return EccentricAnomoly(M, e, En, del_E) ;
870  }
871 }
872 
873 
874 /**********************************************************************/
879 void CEPlanet::SetReference(CEPlanet* reference)
880 {
881  if (reference_ != nullptr) {
882  // redirect and delete
883  delete reference_;
884  reference_ = nullptr;
885  }
886 
887  reference_ = reference;
888 
889  // Reset cached date so that coordinates are recomputed
890  cached_jd_ = -1.0e30;
891 }
892 
893 
894 /**********************************************************************/
899 void CEPlanet::SetSofaID(const double& new_id)
900 {
901  // If the id is outside the acceptable range, then set the algorithm to jpl
902  if ((new_id < 1.0)||(new_id > 8.0)) {
903  SetAlgorithm(CEPlanetAlgo::JPL) ;
904  }
905  sofa_planet_id_ = new_id;
906 }
907 
908 
909 /**********************************************************************/
914 void CEPlanet::copy_members(const CEPlanet& other)
915 {
916  // Basic properties
917  radius_m_ = other.radius_m_;
918  mass_kg_ = other.mass_kg_;
919  albedo_ = other.albedo_;
920 
921  // The following is a reference point for the observer
922  // This will almost always be the Earth-Moon barycenter
923  if (other.reference_ != nullptr) {
924  if (reference_ != nullptr) {
925  delete reference_;
926  reference_ = nullptr;
927  }
928  reference_ = new CEPlanet(*other.reference_);
929  }
930 
931  // Define the algorithm used to compute the planets position
932  algorithm_type_ = other.algorithm_type_;
935  sofa_planet_id_ = other.sofa_planet_id_;
936 
937  // The coordinates representing the current position will need to be
938  // relative to some date, since planets move. This is the cached date
939  cached_jd_ = other.cached_jd_;
940  pos_icrs_ = other.pos_icrs_;
941  vel_icrs_ = other.vel_icrs_;
942 
943  /******************************************
944  * Properties for the JPL algorithm
945  ******************************************/
946  // Orbital properties (element 2 is the derivative)
947  semi_major_axis_au_ = other.semi_major_axis_au_;
948  eccentricity_ = other.eccentricity_;
949  inclination_deg_ = other.inclination_deg_;
950  mean_longitude_deg_ = other.mean_longitude_deg_;
951  perihelion_lon_deg_ = other.perihelion_lon_deg_;
952  ascending_node_lon_deg_ = other.ascending_node_lon_deg_;
953 
954  // Derivatives of orbital properties
955  semi_major_axis_au_per_cent_ = other.semi_major_axis_au_per_cent_;
956  eccentricity_per_cent_ = other.eccentricity_per_cent_;
957  inclination_deg_per_cent_ = other.inclination_deg_per_cent_;
958  mean_longitude_deg_per_cent_ = other.mean_longitude_deg_per_cent_;
959  perihelion_long_deg_per_cent_ = other.perihelion_long_deg_per_cent_;
960  ascending_node_lon_deg_per_cent_ = other.ascending_node_lon_deg_per_cent_;
961 
962  // The following is the tolerance for the computation of eccentric anomoly
963  E_tol = other.E_tol;
964 
965  // Extra terms for outer planets (Jupiter, Saturn, Uranus, Neptune, and Pluto)
966  b_ = other.b_;
967  c_ = other.c_;
968  s_ = other.s_;
969  f_ = other.f_;
970 }
971 
972 
973 /**********************************************************************/
976 void CEPlanet::init_members(void)
977 {
978  // Basic properties
979  radius_m_ = 0.0;
980  mass_kg_ = 0.0;
981  albedo_ = 0.0;
982 
983  // The following is a reference point for the observer
984  // This will almost always be the Earth-Moon barycenter
985  reference_ = nullptr;//new CEPlanet(CEPlanet::EMBarycenter());
986 
987  // Define the algorithm used to compute the planets position
988  algorithm_type_ = CEPlanetAlgo::SOFA;
989  // Sofa planet id (note: 3.5 implies the earth-center which uses a different method
990  // than the other planets)
991  sofa_planet_id_ = 0;
992 
993  // The coordinates representing the current position will need to be
994  // relative to some date, since planets move. This is the cached date
995  cached_jd_ = -1.0e30;
996  pos_icrs_ = std::vector<double>(3, 0.0);
997  // Note, these velocities are only computed for "algorithm_type_=SOFA" at the moment
998  vel_icrs_ = std::vector<double>(3, 0.0);
999 
1000  /******************************************
1001  * Properties for the JPL algorithm
1002  ******************************************/
1003  // Orbital properties (element 2 is the derivative)
1004  semi_major_axis_au_ = 0.0;
1005  eccentricity_ = 0.0;
1006  inclination_deg_ = 0.0;
1007  mean_longitude_deg_ = 0.0;
1008  perihelion_lon_deg_ = 0.0;
1009  ascending_node_lon_deg_ = 0.0;
1010 
1011  // Derivatives of orbital properties
1012  semi_major_axis_au_per_cent_ = 0.0;
1013  eccentricity_per_cent_ = 0.0;
1014  inclination_deg_per_cent_ = 0.0;
1015  mean_longitude_deg_per_cent_ = 0.0;
1016  perihelion_long_deg_per_cent_ = 0.0;
1017  ascending_node_lon_deg_per_cent_ = 0.0;
1018 
1019  // The following is the tolerance for the computation of eccentric anomoly
1020  E_tol = 1.0e-6;
1021 
1022  // Extra terms for outer planets (Jupiter, Saturn, Uranus, Neptune, and Pluto)
1023  b_ = 0.0;
1024  c_ = 0.0;
1025  s_ = 0.0;
1026  f_ = 0.0;
1027 }
1028 
1029 
1030 /**********************************************************************/
1033 void CEPlanet::free_members(void)
1034 {
1035  // Delete the reference object if we no longer need it
1036  if (reference_ != nullptr) {
1037  delete reference_ ;
1038  reference_ = nullptr;
1039  }
1040 }
CEPlanet::SetSemiMajorAxis_AU
virtual void SetSemiMajorAxis_AU(double semi_major_axis_au, double semi_major_axis_au_per_cent=0.0)
Set the semi-major axis (in AU) and it's derivative.
Definition: CEPlanet.cpp:479
CEPlanet::s_
double s_
Definition: CEPlanet.h:194
CEPlanet::SetInclination
virtual void SetInclination(double inclination, double inclination_per_cent=0.0, CEAngleType angle_type=CEAngleType::DEGREES)
Set the inclination angle of the planets orbit.
Definition: CEPlanet.cpp:511
CEPlanet::PositionICRS_Obs
std::vector< double > PositionICRS_Obs(const CEDate &date) const
Get the observed position on a given date.
Definition: CEPlanet.cpp:616
CESkyCoordType::ICRS
RA, Dec (referenced at the barycenter of the solarsystem)
CEPlanet::Uranus
static CEPlanet Uranus()
Returns an object representing Uranus.
Definition: CEPlanet.cpp:391
CEPlanet::E_tol
double E_tol
Definition: CEPlanet.h:189
CEPlanet::SetPerihelionLongitude
virtual void SetPerihelionLongitude(double perihelion_lon, double perihelion_lon_per_cent=0.0, CEAngleType angle_type=CEAngleType::DEGREES)
Set the longitude at perihelion.
Definition: CEPlanet.cpp:551
CESkyCoordType
CESkyCoordType
The following enum specifies what coordinates this object represents.
Definition: CESkyCoord.h:39
CESkyCoordType::CIRS
RA, Dec (referenced at the center of the Earth)
CEPlanet::copy_members
void copy_members(const CEPlanet &other)
Copy data members from another CEPlanet object.
Definition: CEPlanet.cpp:913
CEDate
Definition: CEDate.h:43
CEPlanet::operator=
CEPlanet & operator=(const CEPlanet &other)
Copy assignment operator.
Definition: CEPlanet.cpp:193
CEPlanet::Mercury
static CEPlanet Mercury()
Returns an object representing Mercury.
Definition: CEPlanet.cpp:211
CEPlanet::Pluto
static CEPlanet Pluto()
Returns an object representing Pluto.
Definition: CEPlanet.cpp:448
CEPlanet::Mars
static CEPlanet Mars()
Returns an object representing Mars.
Definition: CEPlanet.cpp:308
CEPlanet::EMBarycenter
static CEPlanet EMBarycenter()
Returns an object representing the Earth-Moon barycenter.
Definition: CEPlanet.cpp:287
CEPlanet::Neptune
static CEPlanet Neptune()
Returns an object representing Neptune.
Definition: CEPlanet.cpp:419
CESkyCoord
Definition: CESkyCoord.h:49
CEPlanet::sofa_planet_id_
double sofa_planet_id_
Sofa planet id (note: 3.5 implies the earth-center which uses a different method than the other plane...
Definition: CEPlanet.h:161
CEPlanet::albedo_
double albedo_
Albedo (0 -> 1)
Definition: CEPlanet.h:151
CEAngleType
CEAngleType
Definition: CEAngle.h:30
CEPlanet::perihelion_lon_deg_
double perihelion_lon_deg_
w - Longitude of perihelion (radians)
Definition: CEPlanet.h:177
CEPlanet::SetAlgorithm
void SetAlgorithm(const CEPlanetAlgo &new_algo)
Set the desired planet computation algorithm.
Definition: CEPlanet.h:425
SOFA
Use methods included in sofa software.
Definition: CEPlanet.h:48
CEPlanet::f_
double f_
Definition: CEPlanet.h:195
CEPlanet::cached_jd_
double cached_jd_
Julian date of the current coordinates.
Definition: CEPlanet.h:165
CEPlanet::GetXICRS
double GetXICRS()
Return X distance from solar system barycenter (AU)
Definition: CEPlanet.h:320
CEPlanet::SetReference
virtual void SetReference(CEPlanet *reference)
Set the reference object for computing more accurate RA,Dec values.
Definition: CEPlanet.cpp:878
CEPlanet::vel_icrs_
std::vector< double > vel_icrs_
XYZ velocity (AU/day) relative to solar system barycenter.
Definition: CEPlanet.h:168
CEPlanet::~CEPlanet
virtual ~CEPlanet()
Destructor.
Definition: CEPlanet.cpp:181
CEPlanet.h
CEBody::operator=
CEBody & operator=(const CEBody &other)
Overloaded assignment operator.
Definition: CEBody.cpp:107
CEPlanet::Earth
static CEPlanet Earth()
Returns an object representing Earth.
Definition: CEPlanet.cpp:261
CEPlanet::ObservedCoords
virtual CESkyCoord ObservedCoords(const CEDate &date, const CEObserver &observer) const
Get the observed coordinates for a given observer/date.
Definition: CEPlanet.cpp:639
CEDate::UTC2TDB
static void UTC2TDB(const double &mjd, double *tdb1, double *tdb2)
Convert the UTC MJD to TDB JD (useful for planet computations)
Definition: CEDate.cpp:429
CEPlanet::SetSofaID
void SetSofaID(const double &new_id)
Set the sofa planet id (note, only values from 1-8 are acceptable)
Definition: CEPlanet.cpp:898
CEPlanet::free_members
void free_members(void)
Free allocated memory.
Definition: CEPlanet.cpp:1030
CEAngle
Definition: CEAngle.h:38
CEAngle::Rad
double Rad(void) const
Return angle in radians as a double.
Definition: CEAngle.cpp:351
CEObserver::PositionICRS
std::vector< double > PositionICRS(const CEDate &date) const
Get the position vector for this observer relative to ICRS (solar system barycenter)
Definition: CEObserver.cpp:145
CEPlanet::ascending_node_lon_deg_per_cent_
double ascending_node_lon_deg_per_cent_
Definition: CEPlanet.h:186
CEPlanet::EccentricAnomoly
double EccentricAnomoly(double &M, double &e, double &En, double &del_E) const
Recursive method for computing the eccentric anomoly.
Definition: CEPlanet.cpp:850
CEPlanet::SetMeanLongitude
virtual void SetMeanLongitude(double mean_longitude, double mean_longitude_per_cent=0.0, CEAngleType angle_type=CEAngleType::DEGREES)
Set the mean longitude.
Definition: CEPlanet.cpp:531
JPL
Use Keplerian algorithm outlined by JPL.
Definition: CEPlanet.h:49
CppEphem::julian_date_J2000
double julian_date_J2000()
Julian Date corresponding to J2000.
Definition: CENamespace.h:67
CEPlanet::UpdatePosition
void UpdatePosition(const double &jd) const
Recomputes the spatial position for a planet based on chosen algorithm.
Definition: CEPlanet.cpp:708
CEPlanet::UpdateCoordinates
virtual void UpdateCoordinates(double new_date=-1.0e30) const
Recomputes the coordinates of the planet if the date has changed from the last time the coordinates w...
Definition: CEPlanet.cpp:677
CEPlanet::inclination_deg_
double inclination_deg_
I - inclination in radians.
Definition: CEPlanet.h:175
CEAngleType::DEGREES
JD
Julian Date.
Definition: CEDate.h:56
CEPlanet::Venus
static CEPlanet Venus()
Returns an object representing Venus.
Definition: CEPlanet.cpp:236
CEDate::GetMJD2JDFactor
static double GetMJD2JDFactor()
Gets the stored SOFA Julian date to Mod Julian date factor 'DJM0'.
Definition: CEDate.h:236
CEPlanet::semi_major_axis_au_per_cent_
double semi_major_axis_au_per_cent_
Definition: CEPlanet.h:181
CEPlanet::radius_m_
double radius_m_
Radius (in meters)
Definition: CEPlanet.h:149
CEPlanet::perihelion_long_deg_per_cent_
double perihelion_long_deg_per_cent_
Definition: CEPlanet.h:185
CEPlanet
Definition: CEPlanet.h:35
CEPlanet::GetYICRS
double GetYICRS()
Y distance from solar system barycenter (AU)
Definition: CEPlanet.h:330
CEPlanet::semi_major_axis_au_
double semi_major_axis_au_
a - Semi major axis in Astronomical Units (AU)
Definition: CEPlanet.h:173
CEPlanet::eccentricity_
double eccentricity_
e - Eccentricity
Definition: CEPlanet.h:174
CEPlanet::Saturn
static CEPlanet Saturn()
Returns an object representing Saturn.
Definition: CEPlanet.cpp:363
CEPlanet::CEPlanet
CEPlanet()
Default constructor.
Definition: CEPlanet.cpp:141
CEPlanet::eccentricity_per_cent_
double eccentricity_per_cent_
Definition: CEPlanet.h:182
CppEphem::c_au_per_day
double c_au_per_day()
speed of light (astronomical units)/day
Definition: CENamespace.h:69
CEPlanet::mean_longitude_deg_per_cent_
double mean_longitude_deg_per_cent_
Definition: CEPlanet.h:184
CEPlanet::Update_JPL
virtual void Update_JPL(double new_date=-1.0e30) const
Recomputes the coordinates of the planet based on the date using the keplerian method outlined by JPL...
Definition: CEPlanet.cpp:773
CEPlanet::reference_
CEPlanet * reference_
Definition: CEPlanet.h:155
CEAngleType::RADIANS
CEObserver
Definition: CEObserver.h:28
CEPlanet::Update_SOFA
virtual void Update_SOFA(double new_date=-1.0e30) const
Recomputes the coordinates of the planet based on the date using the methods included in the sofa pac...
Definition: CEPlanet.cpp:728
CEPlanet::MeanAnomaly
double MeanAnomaly(double mean_longitude_deg, double perihelion_long_deg, double T=0.0) const
Computes the mean anomaly.
Definition: CEPlanet.cpp:829
CEPlanet::mass_kg_
double mass_kg_
Mass (kilograms)
Definition: CEPlanet.h:150
CEPlanet::init_members
void init_members(void)
Initialize data members.
Definition: CEPlanet.cpp:974
CEBody
Definition: CEBody.h:39
CESkyCoord::SetCoordinates
virtual void SetCoordinates(const CEAngle &xcoord, const CEAngle &ycoord, const CESkyCoordType &coord_type=CESkyCoordType::ICRS) const
Set the coordinates of this object.
Definition: CESkyCoord.cpp:1000
CEPlanet::algorithm_type_
CEPlanetAlgo algorithm_type_
Definition: CEPlanet.h:158
CEDate::JD
virtual double JD() const
Get the Julian date represented by this object.
Definition: CEDate.h:150
CEPlanet::EarthDist_AU
virtual double EarthDist_AU(const CEDate &date)
Return the distance to Earth for this planet at a given UTC date.
Definition: CEPlanet.cpp:591
CEPlanet::Jupiter
static CEPlanet Jupiter()
Returns an object representing Jupiter.
Definition: CEPlanet.cpp:335
CEPlanet::c_
double c_
Definition: CEPlanet.h:193
CEPlanet::SetAscendingNodeLongitude
virtual void SetAscendingNodeLongitude(double ascending_node_lon, double ascending_node_lon_per_cent=0.0, CEAngleType angle_type=CEAngleType::DEGREES)
Set the longitude of the ascending node.
Definition: CEPlanet.cpp:571
CEPlanet::ascending_node_lon_deg_
double ascending_node_lon_deg_
Omega - Longitude of ascending node (radians)
Definition: CEPlanet.h:178
CEPlanet::inclination_deg_per_cent_
double inclination_deg_per_cent_
Definition: CEPlanet.h:183
CEPlanet::b_
double b_
Definition: CEPlanet.h:192
CEPlanet::pos_icrs_
std::vector< double > pos_icrs_
XYZ position (AU) relative to solar system barycenter.
Definition: CEPlanet.h:166
CEPlanet::mean_longitude_deg_
double mean_longitude_deg_
L - Mean longitude (radians)
Definition: CEPlanet.h:176
CESkyCoordType::OBSERVED
Azimuth, Zenith (requires additional observer information)
CEPlanet::GetZICRS
double GetZICRS()
Z distance from solar system barycenter (AU)
Definition: CEPlanet.h:340
CEPlanet::SetEccentricity
virtual void SetEccentricity(double eccentricity, double eccentricity_per_cent=0.0)
Set the eccentricity.
Definition: CEPlanet.cpp:497