/* $Procedure ILLUM ( Illumination angles ) */ /* Subroutine */ int illum_(char *target, doublereal *et, char *abcorr, char * obsrvr, doublereal *spoint, doublereal *phase, doublereal *solar, doublereal *emissn, ftnlen target_len, ftnlen abcorr_len, ftnlen obsrvr_len) { /* Initialized data */ static logical first = TRUE_; extern /* Subroutine */ int zzbods2c_(integer *, char *, integer *, logical *, char *, integer *, logical *, ftnlen, ftnlen); extern doublereal vsep_(doublereal *, doublereal *); extern /* Subroutine */ int vsub_(doublereal *, doublereal *, doublereal * ), vequ_(doublereal *, doublereal *), zzctruin_(integer *); integer n; doublereal radii[3]; extern /* Subroutine */ int chkin_(char *, ftnlen), errch_(char *, char *, ftnlen, ftnlen); logical found; extern /* Subroutine */ int spkez_(integer *, doublereal *, char *, char * , integer *, doublereal *, doublereal *, ftnlen, ftnlen); extern logical eqstr_(char *, char *, ftnlen, ftnlen); static logical svfnd1, svfnd2; static integer svctr1[2], svctr2[2]; integer obscde; doublereal lt; extern /* Subroutine */ int bodvcd_(integer *, char *, integer *, integer *, doublereal *, ftnlen); integer frcode; extern /* Subroutine */ int cidfrm_(integer *, integer *, char *, logical *, ftnlen); char frname[80]; integer trgcde; doublereal offobs[3], obsvec[3], tepoch, normal[3]; static integer svtcde; extern /* Subroutine */ int sigerr_(char *, ftnlen), chkout_(char *, ftnlen); static integer svobsc; doublereal offsun[3]; extern /* Subroutine */ int setmsg_(char *, ftnlen); doublereal sstate[6], sunvec[3], tstate[6]; static char svtarg[36]; extern /* Subroutine */ int surfnm_(doublereal *, doublereal *, doublereal *, doublereal *, doublereal *); extern logical return_(void); static char svobsr[36]; extern /* Subroutine */ int vminus_(doublereal *, doublereal *); doublereal lts; /* $ Abstract */ /* Deprecated: This routine has been superseded by the SPICELIB */ /* routine ILUMIN. This routine is supported for purposes of */ /* backward compatibility only. */ /* Find the illumination angles at a specified surface point of a */ /* target body. */ /* $ Disclaimer */ /* THIS SOFTWARE AND ANY RELATED MATERIALS WERE CREATED BY THE */ /* CALIFORNIA INSTITUTE OF TECHNOLOGY (CALTECH) UNDER A U.S. */ /* GOVERNMENT CONTRACT WITH THE NATIONAL AERONAUTICS AND SPACE */ /* ADMINISTRATION (NASA). THE SOFTWARE IS TECHNOLOGY AND SOFTWARE */ /* PUBLICLY AVAILABLE UNDER U.S. EXPORT LAWS AND IS PROVIDED "AS-IS" */ /* TO THE RECIPIENT WITHOUT WARRANTY OF ANY KIND, INCLUDING ANY */ /* WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A */ /* PARTICULAR USE OR PURPOSE (AS SET FORTH IN UNITED STATES UCC */ /* SECTIONS 2312-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE */ /* SOFTWARE AND RELATED MATERIALS, HOWEVER USED. */ /* IN NO EVENT SHALL CALTECH, ITS JET PROPULSION LABORATORY, OR NASA */ /* BE LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING, BUT NOT */ /* LIMITED TO, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND, */ /* INCLUDING ECONOMIC DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS, */ /* REGARDLESS OF WHETHER CALTECH, JPL, OR NASA BE ADVISED, HAVE */ /* REASON TO KNOW, OR, IN FACT, SHALL KNOW OF THE POSSIBILITY. */ /* RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF */ /* THE SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY */ /* CALTECH AND NASA FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE */ /* ACTIONS OF RECIPIENT IN THE USE OF THE SOFTWARE. */ /* $ Required_Reading */ /* KERNEL */ /* NAIF_IDS */ /* SPK */ /* TIME */ /* $ Keywords */ /* GEOMETRY */ /* MOSPICE */ /* $ Declarations */ /* $ Abstract */ /* This include file defines the dimension of the counter */ /* array used by various SPICE subsystems to uniquely identify */ /* changes in their states. */ /* $ Disclaimer */ /* THIS SOFTWARE AND ANY RELATED MATERIALS WERE CREATED BY THE */ /* CALIFORNIA INSTITUTE OF TECHNOLOGY (CALTECH) UNDER A U.S. */ /* GOVERNMENT CONTRACT WITH THE NATIONAL AERONAUTICS AND SPACE */ /* ADMINISTRATION (NASA). THE SOFTWARE IS TECHNOLOGY AND SOFTWARE */ /* PUBLICLY AVAILABLE UNDER U.S. EXPORT LAWS AND IS PROVIDED "AS-IS" */ /* TO THE RECIPIENT WITHOUT WARRANTY OF ANY KIND, INCLUDING ANY */ /* WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A */ /* PARTICULAR USE OR PURPOSE (AS SET FORTH IN UNITED STATES UCC */ /* SECTIONS 2312-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE */ /* SOFTWARE AND RELATED MATERIALS, HOWEVER USED. */ /* IN NO EVENT SHALL CALTECH, ITS JET PROPULSION LABORATORY, OR NASA */ /* BE LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING, BUT NOT */ /* LIMITED TO, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND, */ /* INCLUDING ECONOMIC DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS, */ /* REGARDLESS OF WHETHER CALTECH, JPL, OR NASA BE ADVISED, HAVE */ /* REASON TO KNOW, OR, IN FACT, SHALL KNOW OF THE POSSIBILITY. */ /* RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF */ /* THE SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY */ /* CALTECH AND NASA FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE */ /* ACTIONS OF RECIPIENT IN THE USE OF THE SOFTWARE. */ /* $ Parameters */ /* CTRSIZ is the dimension of the counter array used by */ /* various SPICE subsystems to uniquely identify */ /* changes in their states. */ /* $ Author_and_Institution */ /* B.V. Semenov (JPL) */ /* $ Literature_References */ /* None. */ /* $ Version */ /* - SPICELIB Version 1.0.0, 29-JUL-2013 (BVS) */ /* -& */ /* End of include file. */ /* $ Brief_I/O */ /* Variable I/O Description */ /* -------- --- -------------------------------------------------- */ /* TARGET I Name of target body. */ /* ET I Epoch in ephemeris seconds past J2000. */ /* ABCORR I Desired aberration correction. */ /* OBSRVR I Name of observing body. */ /* SPOINT I Body-fixed coordinates of a target surface point. */ /* PHASE O Phase angle at the surface point. */ /* SOLAR O Solar incidence angle at the surface point. */ /* EMISSN O Emission angle at the surface point. */ /* $ Detailed_Input */ /* TARGET is the name of the target body. TARGET is */ /* case-insensitive, and leading and trailing blanks */ /* in TARGET are not significant. Optionally, you may */ /* supply a string containing the integer ID code for */ /* the object. For example both 'MOON' and '301' are */ /* legitimate strings that indicate the moon is the */ /* target body. */ /* ET is the epoch, specified in ephemeris seconds past */ /* J2000, at which the apparent illumination angles at */ /* the specified surface point on the target body, as */ /* seen from the observing body, are to be computed. */ /* ABCORR is the aberration correction to be used in */ /* computing the location and orientation of the */ /* target body and the location of the Sun. Possible */ /* values are: */ /* 'NONE' No aberration correction. */ /* 'LT' Correct the position and */ /* orientation of target body for */ /* light time, and correct the */ /* position of the Sun for light */ /* time. */ /* 'LT+S' Correct the observer-target vector */ /* for light time and stellar */ /* aberration, correct the */ /* orientation of the target body */ /* for light time, and correct the */ /* target-Sun vector for light time */ /* and stellar aberration. */ /* 'CN' Converged Newtonian light time */ /* correction. In solving the light */ /* time equation, the 'CN' */ /* correction iterates until the */ /* solution converges (three */ /* iterations on all supported */ /* platforms). Whether the 'CN+S' */ /* solution is substantially more */ /* accurate than the 'LT' solution */ /* depends on the geometry of the */ /* participating objects and on the */ /* accuracy of the input data. In */ /* all cases this routine will */ /* execute more slowly when a */ /* converged solution is computed. */ /* See the Particulars section of */ /* SPKEZR for a discussion of */ /* precision of light time */ /* corrections. */ /* Both the state and rotation of */ /* the target body are corrected for */ /* light time. */ /* 'CN+S' Converged Newtonian light time */ /* correction and stellar aberration */ /* correction. */ /* Both the state and rotation of */ /* the target body are corrected for */ /* light time. */ /* OBSRVR is the name of the observing body, typically a */ /* spacecraft, the earth, or a surface point on the */ /* earth. OBSRVR is case-insensitive, and leading */ /* and trailing blanks in OBSRVR are not significant. */ /* Optionally, you may supply a string containing the */ /* integer ID code for the object. For example both */ /* 'EARTH' and '399' are legitimate strings that */ /* indicate the earth is the observer. */ /* OBSRVR may be not be identical to TARGET. */ /* SPOINT is a surface point on the target body, expressed */ /* in rectangular body-fixed (body equator and prime */ /* meridian) coordinates. SPOINT need not be visible */ /* from the observer's location at time ET. */ /* $ Detailed_Output */ /* PHASE is the phase angle at SPOINT, as seen from OBSRVR */ /* at time ET. This is the angle between the */ /* SPOINT-OBSRVR vector and the SPOINT-Sun vector. */ /* Units are radians. The range of PHASE is [0, pi]. */ /* See Particulars below for a detailed discussion of */ /* the definition. */ /* SOLAR is the solar incidence angle at SPOINT, as seen */ /* from OBSRVR at time ET. This is the angle */ /* between the surface normal vector at SPOINT and the */ /* SPOINT-Sun vector. Units are radians. The range */ /* of SOLAR is [0, pi]. See Particulars below for a */ /* detailed discussion of the definition. */ /* EMISSN is the emission angle at SPOINT, as seen from */ /* OBSRVR at time ET. This is the angle between the */ /* surface normal vector at SPOINT and the */ /* SPOINT-observer vector. Units are radians. The */ /* range of EMISSN is [0, pi]. See Particulars below */ /* for a detailed discussion of the definition. */ /* $ Parameters */ /* None. */ /* $ Exceptions */ /* 1) If TARGET and OBSRVR are not distinct, the error */ /* SPICE(BODIESNOTDISTINCT) will be signaled. */ /* 2) If no SPK (ephemeris) data are available for the observer, */ /* target, and Sun at the time specified by ET, the error will */ /* be diagnosed by routines called by this routine. If light */ /* time corrections are used, SPK data for the target body must */ /* be available at the time ET - LT, where LT is the one-way */ /* light time from the target to the observer at ET. */ /* Additionally, SPK data must be available for the Sun at the */ /* time ET - LT - LT2, where LT2 is the light time from the Sun */ /* to the target body at time ET - LT. */ /* 3) If PCK data defining the orientation or shape of the target */ /* body are unavailable, the error will be diagnosed by routines */ /* called by this routine. */ /* 4) If no body-fixed frame is associated with the target body, */ /* the error SPICE(NOFRAME) is signaled. */ /* 5) If name of target or observer cannot be translated to its */ /* NAIF ID code, the error SPICE(IDCODENOTFOUND) is signaled. */ /* $ Files */ /* No files are input to this routine. However, ILLUM expects */ /* that the appropriate SPK and PCK files have been loaded via */ /* FURNSH. */ /* $ Particulars */ /* The term "illumination angles" refers to following set of */ /* angles: */ /* solar incidence angle Angle between the surface normal at */ /* the specified surface point and the */ /* vector from the surface point to the */ /* Sun. */ /* emission angle Angle between the surface normal at */ /* the specified surface point and the */ /* vector from the surface point to the */ /* observer. */ /* phase angle Angle between the vectors from the */ /* surface point to the observing body's */ /* location and from the surface point */ /* to the Sun. */ /* The diagram below illustrates the geometrical relationships */ /* defining these angles. The labels for the solar incidence, */ /* emission, and phase angles are "s.i.", "e.", and "phase". */ /* * */ /* Sun */ /* surface normal vector */ /* ._ _. */ /* |\ /| Sun vector */ /* \ phase / */ /* \ . . / */ /* . . */ /* \ ___ / */ /* . \/ \/ */ /* _\ s.i./ */ /* . / \ / */ /* . | e. \ / */ /* * <--------------- * surface point on */ /* viewing vector target body */ /* location to viewing */ /* (observer) location */ /* Note that if the target-observer vector, the target normal vector */ /* at the surface point, and the target-sun vector are coplanar, */ /* then phase is the sum of incidence and emission. This is rarely */ /* true; usually */ /* phase angle < solar incidence angle + emission angle */ /* All of the above angles can be computed using light time */ /* corrections, light time and stellar aberration corrections, or */ /* no aberration corrections. The way aberration corrections */ /* are used is described below. */ /* Care must be used in computing light time corrections. The */ /* guiding principle used here is "describe what appears in */ /* an image." We ignore differential light time; the light times */ /* from all points on the target to the observer are presumed to be */ /* equal. */ /* Observer-target body vector */ /* --------------------------- */ /* Let ET be the epoch at which an observation or remote */ /* sensing measurement is made, and let ET - LT ("LT" stands */ /* for "light time") be the epoch at which the photons received */ /* at ET were emitted from the body (we use the term "emitted" */ /* loosely here). */ /* The correct observer-target vector points from the observer's */ /* location at ET to the target body's location at ET - LT. */ /* The target-observer vector points in the opposite direction. */ /* Since light time corrections are not symmetric, the correct */ /* target-observer vector CANNOT be found by computing the light */ /* time corrected position of the observer as seen from the */ /* target body. */ /* Target body's orientation */ /* ------------------------- */ /* Using the definitions of ET and LT above, the target */ /* body's orientation at ET - LT is used. The surface */ /* normal is dependent on the target body's orientation, so */ /* the body's orientation model must be evaluated for the correct */ /* epoch. */ /* Target body -- Sun vector */ /* ------------------------- */ /* All surface features on the target body will appear in */ /* a measurement made at ET as they were at ET-LT. In */ /* particular, lighting on the target body is dependent on */ /* the apparent location of the Sun as seen from the target */ /* body at ET-LT. So, a second light time correction is used */ /* in finding the apparent location of the Sun. */ /* Stellar aberration corrections, when used, are applied as follows: */ /* Observer-target body vector */ /* --------------------------- */ /* In addition to light time correction, stellar aberration is */ /* used in computing the apparent target body position as seen */ /* from the observer's location at time ET. This apparent */ /* position defines the observer-target body vector. */ /* Target body-Sun vector */ /* ---------------------- */ /* The target body-Sun vector is the apparent position of the Sun, */ /* corrected for light time and stellar aberration, as seen from */ /* the target body at time ET-LT. Note that the target body's */ /* position is not affected by the stellar aberration correction */ /* applied in finding its apparent position as seen by the */ /* observer. */ /* Once all of the vectors, as well as the target body's */ /* orientation, have been computed with the proper aberration */ /* corrections, the element of time is eliminated from the */ /* computation. The problem becomes a purely geometrical one, */ /* and is described by the diagram above. */ /* $ Examples */ /* The numerical results shown for this example may differ across */ /* platforms. The results depend on the SPICE kernels used as */ /* input, the compiler and supporting libraries, and the machine */ /* specific arithmetic implementation. */ /* In the following example program, the file */ /* spk_m_031103-040201_030502.bsp */ /* is a binary SPK file containing data for Mars Global Surveyor, */ /* Mars, and the Sun for a time interval bracketing the date */ /* 2004 JAN 1 12:00:00 UTC. */ /* pck00007.tpc is a planetary constants kernel file containing */ /* radii and rotation model constants. naif0007.tls is a */ /* leapseconds kernel. */ /* Find the phase, solar incidence, and emission angles at the */ /* sub-solar and sub-spacecraft points on Mars as seen from the */ /* Mars Global Surveyor spacecraft at a specified UTC time. */ /* Use light time and stellar aberration corrections. */ /* PROGRAM ANGLES */ /* IMPLICIT NONE */ /* C */ /* C SPICELIB functions */ /* C */ /* DOUBLE PRECISION DPR */ /* C */ /* C Local parameters */ /* C */ /* INTEGER NAMLEN */ /* PARAMETER ( NAMLEN = 32 ) */ /* INTEGER TIMLEN */ /* PARAMETER ( TIMLEN = 25 ) */ /* C */ /* C Local variables */ /* C */ /* CHARACTER*(NAMLEN) OBSRVR */ /* CHARACTER*(NAMLEN) TARGET */ /* CHARACTER*(TIMLEN) UTC */ /* DOUBLE PRECISION ALT */ /* DOUBLE PRECISION ET */ /* DOUBLE PRECISION SSCEMI */ /* DOUBLE PRECISION SSCPHS */ /* DOUBLE PRECISION SSCSOL */ /* DOUBLE PRECISION SSLEMI */ /* DOUBLE PRECISION SSLPHS */ /* DOUBLE PRECISION SSLSOL */ /* DOUBLE PRECISION SSOLPT ( 3 ) */ /* DOUBLE PRECISION SSCPT ( 3 ) */ /* C */ /* C Load kernel files. */ /* C */ /* CALL FURNSH ( 'naif0007.tls' ) */ /* CALL FURNSH ( 'pck00007.tpc' ) */ /* CALL FURNSH ( 'spk_m_031103-040201_030502.bsp' ) */ /* C */ /* C Convert our UTC time to ephemeris seconds past J2000. */ /* C */ /* UTC = '2004 JAN 1 12:00:00' */ /* CALL UTC2ET ( UTC, ET ) */ /* C */ /* C Assign observer and target names. The acronym MGS */ /* C indicates Mars Global Surveyor. See NAIF_IDS for a */ /* C list of names recognized by SPICE. */ /* C */ /* TARGET = 'Mars' */ /* OBSRVR = 'MGS' */ /* C */ /* C Find the sub-solar point on the Earth as seen from */ /* C the MGS spacecraft at ET. Use the "surface intercept" */ /* C style of sub-point definition. This makes it easy */ /* C to verify the solar incidence angle. */ /* C */ /* CALL SUBSOL ( 'Near point', TARGET, ET, */ /* . 'LT+S', OBSRVR, SSOLPT ) */ /* C */ /* C Now find the sub-spacecraft point. Use the */ /* C "nearest point" definition of the sub-point */ /* C here---this makes it easy to verify the emission angle. */ /* C */ /* CALL SUBPT ( 'Near point', TARGET, ET, */ /* . 'LT+S', OBSRVR, SSCPT, ALT ) */ /* C */ /* C Find the phase, solar incidence, and emission */ /* C angles at the sub-solar point on the Earth as seen */ /* C from Mars Observer at time ET. */ /* C */ /* CALL ILLUM ( TARGET, ET, 'LT+S', OBSRVR, */ /* . SSOLPT, SSLPHS, SSLSOL, SSLEMI ) */ /* C */ /* C Do the same for the sub-spacecraft point. */ /* C */ /* CALL ILLUM ( TARGET, ET, 'LT+S', OBSRVR, */ /* . SSCPT, SSCPHS, SSCSOL, SSCEMI ) */ /* C */ /* C Convert the angles to degrees and write them out. */ /* C */ /* SSLPHS = DPR() * SSLPHS */ /* SSLSOL = DPR() * SSLSOL */ /* SSLEMI = DPR() * SSLEMI */ /* SSCPHS = DPR() * SSCPHS */ /* SSCSOL = DPR() * SSCSOL */ /* SSCEMI = DPR() * SSCEMI */ /* WRITE (*,*) ' ' */ /* WRITE (*,*) 'UTC epoch is ', UTC */ /* WRITE (*,*) ' ' */ /* WRITE (*,*) 'Illumination angles at the sub-solar point:' */ /* WRITE (*,*) ' ' */ /* WRITE (*,*) 'Phase angle (deg.): ', SSLPHS */ /* WRITE (*,*) 'Solar incidence angle (deg.): ', SSLSOL */ /* WRITE (*,*) 'Emission angle (deg.): ', SSLEMI */ /* WRITE (*,*) ' ' */ /* WRITE (*,*) 'The solar incidence angle should be 0.' */ /* WRITE (*,*) 'The emission and phase angles should be equal.' */ /* WRITE (*,*) ' ' */ /* WRITE (*,*) 'Illumination angles at the sub-s/c point:' */ /* WRITE (*,*) ' ' */ /* WRITE (*,*) 'Phase angle (deg.): ', SSCPHS */ /* WRITE (*,*) 'Solar incidence angle (deg.): ', SSCSOL */ /* WRITE (*,*) 'Emission angle (deg.): ', SSCEMI */ /* WRITE (*,*) ' ' */ /* WRITE (*,*) 'The emission angle should be 0.' */ /* WRITE (*,*) 'The solar incidence and phase angles should '// */ /* . 'be equal.' */ /* END */ /* When this program is executed, the output will be: */ /* UTC epoch is 2004 JAN 1 12:00:00 */ /* Illumination angles at the sub-solar point: */ /* Phase angle (deg.): 150.210714 */ /* Solar incidence angle (deg.): 6.3735213E-15 */ /* Emission angle (deg.): 150.210714 */ /* The solar incidence angle should be 0. */ /* The emission and phase angles should be equal. */ /* Illumination angles at the sub-s/c point: */ /* Phase angle (deg.): 123.398202 */ /* Solar incidence angle (deg.): 123.398202 */ /* Emission angle (deg.): 6.36110936E-15 */ /* The emission angle should be 0. */ /* The solar incidence and phase angles should be equal. */ /* $ Restrictions */ /* None. */ /* $ Literature_References */ /* None. */ /* $ Author_and_Institution */ /* C.H. Acton (JPL) */ /* B.V. Semenov (JPL) */ /* N.J. Bachman (JPL) */ /* $ Version */ /* - SPICELIB Version 1.3.0, 04-JUL-2014 (NJB) (BVS) */ /* Discussion of light time corrections was updated. Assertions */ /* that converged light time corrections are unlikely to be */ /* useful were removed. */ /* Last update was 19-SEP-2013 (BVS) */ /* Updated to save the input body names and ZZBODTRN state */ /* counters and to do name-ID conversions only if the counters */ /* have changed. */ /* - SPICELIB Version 1.2.2, 18-MAY-2010 (BVS) */ /* Index lines now state that this routine is deprecated. */ /* - SPICELIB Version 1.2.1, 07-FEB-2008 (NJB) */ /* Abstract now states that this routine is deprecated. */ /* - SPICELIB Version 1.2.0, 23-OCT-2005 (NJB) */ /* Updated to remove non-standard use of duplicate arguments */ /* in VSUB calls. Replaced call to BODVAR with call to BODVCD. */ /* - SPICELIB Version 1.1.0, 22-JUL-2004 (NJB) */ /* Updated to support representations of integers in the input */ /* arguments TARGET and OBSRVR. */ /* - SPICELIB Version 1.0.2, 27-JUL-2003 (NJB) (CHA) */ /* Various header corrections were made. The example program */ /* was upgraded to use real kernels, and the program's output is */ /* shown. */ /* - SPICELIB Version 1.0.1, 10-JUL-2002 (NJB) */ /* Updated Index_Entries header section. */ /* - SPICELIB Version 1.0.0, 21-MAR-1999 (NJB) */ /* Adapted from the MGSSPICE version dated 10-MAR-1992. */ /* -& */ /* $ Index_Entries */ /* DEPRECATED illumination angles */ /* DEPRECATED lighting angles */ /* DEPRECATED phase angle */ /* DEPRECATED solar incidence angle */ /* DEPRECATED emission angle */ /* -& */ /* $ Revisions */ /* - SPICELIB Version 1.2.0, 23-OCT-2005 (NJB) */ /* Updated to remove non-standard use of duplicate arguments */ /* in VSUB calls. Replaced call to BODVAR with call to BODVCD. */ /* - SPICELIB Version 1.1.0, 22-JUL-2004 (NJB) */ /* Updated to support representations of integers in the */ /* input arguments TARGET and OBSRVR: calls to BODN2C */ /* were replaced by calls to BODS2C. */ /* -& */ /* SPICELIB functions */ /* Local parameters */ /* Saved body name length. */ /* Local variables */ /* Saved name/ID item declarations. */ /* Saved name/ID items. */ /* Initial values. */ /* Standard SPICE error handling. */ if (return_()) { return 0; } else { chkin_("ILLUM", (ftnlen)5); } /* Initialization. */ if (first) { /* Initialize counters. */ zzctruin_(svctr1); zzctruin_(svctr2); first = FALSE_; } /* Obtain integer codes for the target and observer. */ zzbods2c_(svctr1, svtarg, &svtcde, &svfnd1, target, &trgcde, &found, ( ftnlen)36, target_len); if (! found) { setmsg_("The target, '#', is not a recognized name for an ephemeris " "object. The cause of this problem may be that you need an up" "dated version of the SPICE Toolkit. ", (ftnlen)155); errch_("#", target, (ftnlen)1, target_len); sigerr_("SPICE(IDCODENOTFOUND)", (ftnlen)21); chkout_("ILLUM", (ftnlen)5); return 0; } zzbods2c_(svctr2, svobsr, &svobsc, &svfnd2, obsrvr, &obscde, &found, ( ftnlen)36, obsrvr_len); if (! found) { setmsg_("The observer, '#', is not a recognized name for an ephemeri" "s object. The cause of this problem may be that you need an " "updated version of the SPICE Toolkit. ", (ftnlen)157); errch_("#", obsrvr, (ftnlen)1, obsrvr_len); sigerr_("SPICE(IDCODENOTFOUND)", (ftnlen)21); chkout_("ILLUM", (ftnlen)5); return 0; } /* The observer and target must be distinct. */ if (trgcde == obscde) { setmsg_("Target is #; observer is #.", (ftnlen)27); errch_("#", target, (ftnlen)1, target_len); errch_("#", obsrvr, (ftnlen)1, obsrvr_len); sigerr_("SPICE(BODIESNOTDISTINCT)", (ftnlen)24); chkout_("ILLUM", (ftnlen)5); return 0; } /* Find the name of the body-fixed frame associated with the */ /* target body. We'll want the state of the target relative to */ /* the observer in this body-fixed frame. */ cidfrm_(&trgcde, &frcode, frname, &found, (ftnlen)80); if (! found) { setmsg_("No body-fixed frame is associated with target body #; a fra" "me kernel must be loaded to make this association. Consult " "the FRAMES Required Reading for details.", (ftnlen)159); errch_("#", target, (ftnlen)1, target_len); sigerr_("SPICE(NOFRAME)", (ftnlen)14); chkout_("ILLUM", (ftnlen)5); return 0; } /* Find the body-fixed state of the target as seen from the observer */ /* at ET. The appropriate aberration corrections will be used in */ /* evaluating this state. */ spkez_(&trgcde, et, frname, abcorr, &obscde, tstate, <, (ftnlen)80, abcorr_len); /* Determine the epoch to be used in computing the target-Sun vector. */ if (eqstr_(abcorr, "NONE", abcorr_len, (ftnlen)4)) { tepoch = *et; } else { tepoch = *et - lt; } /* Find the body-fixed state of the Sun as seen from the target at */ /* TEPOCH. */ spkez_(&c__10, &tepoch, frname, abcorr, &trgcde, sstate, <s, (ftnlen)80, abcorr_len); /* Grab the position portions of the states (the first three */ /* elements of each state). Negate the observer-target vector, */ /* since the vector required for the illumination angle */ /* computation is the target-observer vector. The vectors we've */ /* found point from the target body center to the observer and */ /* Sun, and already take light time corrections into account. */ vminus_(tstate, obsvec); vequ_(sstate, sunvec); /* Now we'll modify target-observer and target-Sun vectors to */ /* take into account the offset between the target center and the */ /* surface point of interest; we want the vectors to point from */ /* the surface point to the observer and Sun respectively. */ vsub_(obsvec, spoint, offobs); vsub_(sunvec, spoint, offsun); /* Find the surface normal at SPOINT. We'll need the radii of the */ /* target body. */ bodvcd_(&trgcde, "RADII", &c__3, &n, radii, (ftnlen)5); surfnm_(radii, &radii[1], &radii[2], spoint, normal); /* Find the illumination angles. VSEP will give us angular */ /* separation in radians. */ *phase = vsep_(offsun, offobs); *solar = vsep_(normal, offsun); *emissn = vsep_(normal, offobs); chkout_("ILLUM", (ftnlen)5); return 0; } /* illum_ */
/* $Procedure SUBSOL ( Sub-solar point ) */ /* Subroutine */ int subsol_(char *method, char *target, doublereal *et, char *abcorr, char *obsrvr, doublereal *spoint, ftnlen method_len, ftnlen target_len, ftnlen abcorr_len, ftnlen obsrvr_len) { /* Initialized data */ static doublereal origin[3] = { 0.,0.,0. }; doublereal radii[3]; extern /* Subroutine */ int chkin_(char *, ftnlen), errch_(char *, char *, ftnlen, ftnlen), ltime_(doublereal *, integer *, char *, integer *, doublereal *, doublereal *, ftnlen); logical found; extern logical eqstr_(char *, char *, ftnlen, ftnlen); doublereal sunlt; extern /* Subroutine */ int bods2c_(char *, integer *, logical *, ftnlen); integer obscde; doublereal lt; extern /* Subroutine */ int bodvcd_(integer *, char *, integer *, integer *, doublereal *, ftnlen); integer frcode; extern /* Subroutine */ int cidfrm_(integer *, integer *, char *, logical *, ftnlen); integer nradii; char frname[80]; integer trgcde; doublereal ettarg; extern /* Subroutine */ int nearpt_(doublereal *, doublereal *, doublereal *, doublereal *, doublereal *, doublereal *), sigerr_( char *, ftnlen), chkout_(char *, ftnlen), setmsg_(char *, ftnlen); extern logical return_(void); extern /* Subroutine */ int spkpos_(char *, doublereal *, char *, char *, char *, doublereal *, doublereal *, ftnlen, ftnlen, ftnlen, ftnlen), surfpt_(doublereal *, doublereal *, doublereal *, doublereal *, doublereal *, doublereal *, logical *); doublereal alt, pos[3]; /* $ Abstract */ /* Deprecated: This routine has been superseded by the SPICELIB */ /* routine SUBSLR. This routine is supported for purposes of */ /* backward compatibility only. */ /* Determine the coordinates of the sub-solar point on a target */ /* body as seen by a specified observer at a specified epoch, */ /* optionally corrected for planetary (light time) and stellar */ /* aberration. */ /* $ Disclaimer */ /* THIS SOFTWARE AND ANY RELATED MATERIALS WERE CREATED BY THE */ /* CALIFORNIA INSTITUTE OF TECHNOLOGY (CALTECH) UNDER A U.S. */ /* GOVERNMENT CONTRACT WITH THE NATIONAL AERONAUTICS AND SPACE */ /* ADMINISTRATION (NASA). THE SOFTWARE IS TECHNOLOGY AND SOFTWARE */ /* PUBLICLY AVAILABLE UNDER U.S. EXPORT LAWS AND IS PROVIDED "AS-IS" */ /* TO THE RECIPIENT WITHOUT WARRANTY OF ANY KIND, INCLUDING ANY */ /* WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A */ /* PARTICULAR USE OR PURPOSE (AS SET FORTH IN UNITED STATES UCC */ /* SECTIONS 2312-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE */ /* SOFTWARE AND RELATED MATERIALS, HOWEVER USED. */ /* IN NO EVENT SHALL CALTECH, ITS JET PROPULSION LABORATORY, OR NASA */ /* BE LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING, BUT NOT */ /* LIMITED TO, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND, */ /* INCLUDING ECONOMIC DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS, */ /* REGARDLESS OF WHETHER CALTECH, JPL, OR NASA BE ADVISED, HAVE */ /* REASON TO KNOW, OR, IN FACT, SHALL KNOW OF THE POSSIBILITY. */ /* RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF */ /* THE SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY */ /* CALTECH AND NASA FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE */ /* ACTIONS OF RECIPIENT IN THE USE OF THE SOFTWARE. */ /* $ Required_Reading */ /* FRAMES */ /* PCK */ /* SPK */ /* TIME */ /* $ Keywords */ /* GEOMETRY */ /* $ Declarations */ /* $ Brief_I/O */ /* Variable I/O Description */ /* -------- --- -------------------------------------------------- */ /* METHOD I Computation method. */ /* TARGET I Name of target body. */ /* ET I Epoch in ephemeris seconds past J2000 TDB. */ /* ABCORR I Aberration correction. */ /* OBSRVR I Name of observing body. */ /* SPOINT O Sub-solar point on the target body. */ /* $ Detailed_Input */ /* METHOD is a short string specifying the computation method */ /* to be used. The choices are: */ /* 'Near point' The sub-solar point is defined */ /* as the nearest point on the */ /* target to the sun. */ /* 'Intercept' The sub-observer point is */ /* defined as the target surface */ /* intercept of the line */ /* containing the target's center */ /* and the sun's center. */ /* In both cases, the intercept computation treats the */ /* surface of the target body as a triaxial ellipsoid. */ /* The ellipsoid's radii must be available in the kernel */ /* pool. */ /* Neither case nor white space are significant in */ /* METHOD. For example, the string ' NEARPOINT' is */ /* valid. */ /* TARGET is the name of the target body. TARGET is */ /* case-insensitive, and leading and trailing blanks in */ /* TARGET are not significant. Optionally, you may */ /* supply a string containing the integer ID code for */ /* the object. For example both 'MOON' and '301' are */ /* legitimate strings that indicate the moon is the */ /* target body. */ /* This routine assumes that the target body is modeled */ /* by a tri-axial ellipsoid, and that a PCK file */ /* containing its radii has been loaded into the kernel */ /* pool via FURNSH. */ /* ET is the epoch in ephemeris seconds past J2000 at which */ /* the sub-solar point on the target body is to be */ /* computed. */ /* ABCORR indicates the aberration corrections to be applied */ /* when computing the observer-target state. ABCORR */ /* may be any of the following. */ /* 'NONE' Apply no correction. Return the */ /* geometric sub-solar point on the target */ /* body. */ /* 'LT' Correct for planetary (light time) */ /* aberration. Both the state and rotation */ /* of the target body are corrected for one */ /* way light time from target to observer. */ /* The state of the sun relative to the */ /* target is corrected for one way light */ /* from the sun to the target; this state */ /* is evaluated at the epoch obtained by */ /* retarding ET by the one way light time */ /* from target to observer. */ /* 'LT+S' Correct for planetary (light time) and */ /* stellar aberrations. Light time */ /* corrections are the same as in the 'LT' */ /* case above. The target state is */ /* additionally corrected for stellar */ /* aberration as seen by the observer, and */ /* the sun state is corrected for stellar */ /* aberration as seen from the target. */ /* 'CN' Converged Newtonian light time */ /* corrections. This is the same as LT */ /* corrections but with further iterations */ /* to a converged Newtonian light time */ /* solution. Given that relativistic */ /* effects may be as large as the higher */ /* accuracy achieved by this computation, */ /* this is correction is seldom worth the */ /* additional computations required unless */ /* the user incorporates additional */ /* relativistic corrections. Light */ /* time corrections are applied as in the */ /* 'LT' case. */ /* 'CN+S' Converged Newtonian light time */ /* corrections and stellar aberration. */ /* Light time and stellar aberration */ /* corrections are applied as in the */ /* 'LT+S' case. */ /* OBSRVR is the name of the observing body, typically a */ /* spacecraft, the earth, or a surface point on the */ /* earth. OBSRVR is case-insensitive, and leading and */ /* trailing blanks in OBSRVR are not significant. */ /* Optionally, you may supply a string containing the */ /* integer ID code for the object. For example both */ /* 'EARTH' and '399' are legitimate strings that indicate */ /* the earth is the observer. */ /* $ Detailed_Output */ /* SPOINT is the sub-solar point on the target body at ET */ /* expressed relative to the body-fixed frame of the */ /* target body. */ /* The sub-solar point is defined either as the point on */ /* the target body that is closest to the sun, or the */ /* target surface intercept of the line containing the */ /* target's center and the sun's center; the input */ /* argument METHOD selects the definition to be used. */ /* The body-fixed frame, which is time-dependent, is */ /* evaluated at ET if ABCORR is 'NONE'; otherwise the */ /* frame is evaluated at ET-LT, where LT is the one way */ /* light time from target to observer. */ /* The state of the target body is corrected for */ /* aberration as specified by ABCORR; the corrected */ /* state is used in the geometric computation. As */ /* indicated above, the rotation of the target is */ /* retarded by one way light time if ABCORR specifies */ /* that light time correction is to be done. */ /* The state of the sun as seen from the observing */ /* body is also corrected for aberration as specified */ /* by ABCORR. The corrections, when selected, are */ /* applied at the epoch ET-LT, where LT is the one way */ /* light time from target to observer. */ /* $ Parameters */ /* None. */ /* $ Exceptions */ /* If any of the listed errors occur, the output arguments are */ /* left unchanged. */ /* 1) If the input argument METHOD is not recognized, the error */ /* SPICE(DUBIOUSMETHOD) is signaled. */ /* 2) If either of the input body names TARGET or OBSRVR cannot be */ /* mapped to NAIF integer codes, the error SPICE(IDCODENOTFOUND) */ /* is signaled. */ /* 3) If OBSRVR and TARGET map to the same NAIF integer ID codes, the */ /* error SPICE(BODIESNOTDISTINCT) is signaled. */ /* 4) If frame definition data enabling the evaluation of the state */ /* of the target relative to the observer in target body-fixed */ /* coordinates have not been loaded prior to calling SUBSOL, the */ /* error will be diagnosed and signaled by a routine in the call */ /* tree of this routine. */ /* 5) If the specified aberration correction is not recognized, the */ /* error will be diagnosed and signaled by a routine in the call */ /* tree of this routine. */ /* 6) If insufficient ephemeris data have been loaded prior to */ /* calling SUBSOL, the error will be diagnosed and signaled by a */ /* routine in the call tree of this routine. */ /* 7) If the triaxial radii of the target body have not been loaded */ /* into the kernel pool prior to calling SUBSOL, the error will be */ /* diagnosed and signaled by a routine in the call tree of this */ /* routine. */ /* 8) The target must be an extended body: if any of the radii of */ /* the target body are non-positive, the error will be diagnosed */ /* and signaled by routines in the call tree of this routine. */ /* 9) If PCK data supplying a rotation model for the target body */ /* have not been loaded prior to calling SUBSOL, the error will be */ /* diagnosed and signaled by a routine in the call tree of this */ /* routine. */ /* $ Files */ /* Appropriate SPK, PCK, and frame data must be available to */ /* the calling program before this routine is called. Typically */ /* the data are made available by loading kernels; however the */ /* data may be supplied via subroutine interfaces if applicable. */ /* The following data are required: */ /* - SPK data: ephemeris data for sun, target, and observer must */ /* be loaded. If aberration corrections are used, the states of */ /* sun, target, and observer relative to the solar system */ /* barycenter must be calculable from the available ephemeris */ /* data. Ephemeris data are made available by loading */ /* one or more SPK files via FURNSH. */ /* - PCK data: triaxial radii for the target body must be loaded */ /* into the kernel pool. Typically this is done by loading a */ /* text PCK file via FURNSH. */ /* - Further PCK data: a rotation model for the target body must */ /* be loaded. This may be provided in a text or binary PCK */ /* file which is loaded via FURNSH. */ /* - Frame data: if a frame definition is required to convert */ /* the sun, observer, and target states to the body-fixed frame */ /* of the target, that definition must be available in the */ /* kernel pool. Typically the definition is supplied by loading */ /* a frame kernel via FURNSH. */ /* In all cases, kernel data are normally loaded once per program */ /* run, NOT every time this routine is called. */ /* $ Particulars */ /* SUBSOL computes the sub-solar point on a target body, as seen by */ /* a specified observer. */ /* There are two different popular ways to define the sub-solar */ /* point: "nearest point on target to the sun" or "target surface */ /* intercept of line containing target and sun." These coincide */ /* when the target is spherical and generally are distinct otherwise. */ /* When comparing sub-point computations with results from sources */ /* other than SPICE, it's essential to make sure the same geometric */ /* definitions are used. */ /* $ Examples */ /* In the following example program, the file MGS.BSP is a */ /* hypothetical binary SPK ephemeris file containing data for the */ /* Mars Global Surveyor orbiter. The SPK file de405s.bsp contains */ /* data for the planet barycenters as well as the Earth, Moon, and */ /* Sun for the time period including the date 1997 Dec 31 12:000 */ /* UTC. MGS0000A.TPC is a planetary constants kernel file */ /* containing radii and rotation model constants. MGS00001.TLS is */ /* a leapseconds file. (File names shown here that are specific */ /* to MGS are not names of actual files.) */ /* IMPLICIT NONE */ /* CHARACTER*25 METHOD ( 2 ) */ /* INTEGER I */ /* DOUBLE PRECISION DPR */ /* DOUBLE PRECISION ET */ /* DOUBLE PRECISION LAT */ /* DOUBLE PRECISION LON */ /* DOUBLE PRECISION RADIUS */ /* DOUBLE PRECISION SPOINT ( 3 ) */ /* DATA METHOD / 'Intercept', 'Near point' / */ /* C */ /* C Load kernel files. */ /* C */ /* CALL FURNSH ( 'MGS00001.TLS' ) */ /* CALL FURNSH ( 'MGS0000A.TPC' ) */ /* CALL FURNSH ( 'de405s.bsp' ) */ /* CALL FURNSH ( 'MGS.BSP' ) */ /* C */ /* C Convert the UTC request time to ET (seconds past */ /* C J2000, TDB). */ /* C */ /* CALL STR2ET ( '1997 Dec 31 12:00:00', ET ) */ /* C */ /* C Compute sub-spacecraft point using light time and stellar */ /* C aberration corrections. Use the "target surface intercept" */ /* C definition of sub-spacecraft point on the first loop */ /* C iteration, and use the "near point" definition on the */ /* C second. */ /* C */ /* DO I = 1, 2 */ /* CALL SUBSOL ( METHOD(I), */ /* . 'MARS', ET, 'LT+S', 'MGS', SPOINT ) */ /* C */ /* C Convert rectangular coordinates to planetocentric */ /* C latitude and longitude. Convert radians to degrees. */ /* C */ /* CALL RECLAT ( SPOINT, RADIUS, LON, LAT ) */ /* LON = LON * DPR () */ /* LAT = LAT * DPR () */ /* C */ /* C Write the results. */ /* C */ /* WRITE (*,*) ' ' */ /* WRITE (*,*) 'Computation method: ', METHOD(I) */ /* WRITE (*,*) ' ' */ /* WRITE (*,*) ' Radius (km) = ', RADIUS */ /* WRITE (*,*) ' Planetocentric Latitude (deg) = ', LAT */ /* WRITE (*,*) ' Planetocentric Longitude (deg) = ', LON */ /* WRITE (*,*) ' ' */ /* END DO */ /* END */ /* $ Restrictions */ /* The appropriate kernel data must have been loaded before this */ /* routine is called. See the Files section above. */ /* $ Literature_References */ /* None. */ /* $ Author_and_Institution */ /* N.J. Bachman (JPL) */ /* J.E. McLean (JPL) */ /* $ Version */ /* - SPICELIB Version 1.2.3, 18-MAY-2010 (BVS) */ /* Index line now states that this routine is deprecated. */ /* - SPICELIB Version 1.2.2, 17-MAR-2009 (EDW) */ /* Typo correction in Required_Reading, changed */ /* FRAME to FRAMES. */ /* - SPICELIB Version 1.2.1, 07-FEB-2008 (NJB) */ /* Abstract now states that this routine is deprecated. */ /* - SPICELIB Version 1.2.0, 24-OCT-2005 (NJB) */ /* Call to BODVAR was replaced with call to BODVCD. */ /* - SPICELIB Version 1.1.0, 22-JUL-2004 (NJB) */ /* Updated to support representations of integers in the input */ /* arguments TARGET and OBSRVR. Deleted references in header to */ /* kernel-specific loaders. Made miscellaneous minor corrections */ /* to header comments. */ /* - SPICELIB Version 1.0.2, 12-DEC-2002 (NJB) */ /* Corrected and updated code example in header. */ /* - SPICELIB Version 1.0.1, 1-NOV-1999 (WLT) */ /* Declared routine LTIME to be external. */ /* - SPICELIB Version 1.0.0, 03-SEP-1999 (NJB) (JEM) */ /* -& */ /* $ Index_Entries */ /* DEPRECATED sub-solar point */ /* -& */ /* $ Revisions */ /* - SPICELIB Version 1.1.0, 22-JUL-2004 (NJB) */ /* Updated to support representations of integers in the */ /* input arguments TARGET and OBSRVR: calls to BODN2C */ /* were replaced by calls to BODS2C. */ /* -& */ /* SPICELIB functions */ /* Local parameters */ /* Local variables */ /* Saved variables */ /* Initial values */ /* Standard SPICE error handling. */ if (return_()) { return 0; } else { chkin_("SUBSOL", (ftnlen)6); } /* Obtain integer codes for the target and observer. */ bods2c_(target, &trgcde, &found, target_len); if (! found) { setmsg_("The target, '#', is not a recognized name for an ephemeris " "object. The cause of this problem may be that you need an up" "dated version of the SPICE Toolkit. ", (ftnlen)155); errch_("#", target, (ftnlen)1, target_len); sigerr_("SPICE(IDCODENOTFOUND)", (ftnlen)21); chkout_("SUBSOL", (ftnlen)6); return 0; } bods2c_(obsrvr, &obscde, &found, obsrvr_len); if (! found) { setmsg_("The observer, '#', is not a recognized name for an ephemeri" "s object. The cause of this problem may be that you need an " "updated version of the SPICE Toolkit. ", (ftnlen)157); errch_("#", obsrvr, (ftnlen)1, obsrvr_len); sigerr_("SPICE(IDCODENOTFOUND)", (ftnlen)21); chkout_("SUBSOL", (ftnlen)6); return 0; } /* Check the input body codes. If they are equal, signal */ /* an error. */ if (obscde == trgcde) { setmsg_("In computing the sub-observer point, the observing body and" " target body are the same. Both are #.", (ftnlen)97); errch_("#", obsrvr, (ftnlen)1, obsrvr_len); sigerr_("SPICE(BODIESNOTDISTINCT)", (ftnlen)24); chkout_("SUBSOL", (ftnlen)6); return 0; } /* Get the radii of the target body from the kernel pool. */ bodvcd_(&trgcde, "RADII", &c__3, &nradii, radii, (ftnlen)5); /* Find the name of the body-fixed frame associated with the */ /* target body. We'll want the state of the target relative to */ /* the observer in this body-fixed frame. */ cidfrm_(&trgcde, &frcode, frname, &found, (ftnlen)80); if (! found) { setmsg_("No body-fixed frame is associated with target body #; a fra" "me kernel must be loaded to make this association. Consult " "the FRAMES Required Reading for details.", (ftnlen)159); errch_("#", target, (ftnlen)1, target_len); sigerr_("SPICE(NOFRAME)", (ftnlen)14); chkout_("SUBSOL", (ftnlen)6); return 0; } /* If we're using aberration corrections, we'll need the */ /* one way light time from the target to the observer. Otherwise, */ /* we set the time time to zero. */ if (eqstr_(abcorr, "NONE", abcorr_len, (ftnlen)4)) { lt = 0.; ettarg = *et; } else { ltime_(et, &obscde, "<-", &trgcde, &ettarg, <, (ftnlen)2); } /* Determine the position of the sun in target body-fixed */ /* coordinates. */ /* Call SPKEZ to compute the position of the sun as seen from the */ /* target body and the light time between them SUNLT. This state is */ /* evaluated at the target epoch ETTARG. We request that the */ /* coordinates of the target-sun position vector POS be returned */ /* relative to the body fixed reference frame associated with the */ /* target body, using aberration corrections specified by the input */ /* argument ABCORR. */ spkpos_("SUN", &ettarg, frname, abcorr, target, pos, &sunlt, (ftnlen)3, ( ftnlen)80, abcorr_len, target_len); /* Find the sub-solar point using the specified geometric definition. */ if (eqstr_(method, "Near point", method_len, (ftnlen)10)) { /* Locate the nearest point to the sun on the target. */ nearpt_(pos, radii, &radii[1], &radii[2], spoint, &alt); } else if (eqstr_(method, "Intercept", method_len, (ftnlen)9)) { surfpt_(origin, pos, radii, &radii[1], &radii[2], spoint, &found); /* Since the line in question passes through the center of the */ /* target, there will always be a surface intercept. So we should */ /* never have FOUND = .FALSE. */ if (! found) { setmsg_("Call to SURFPT returned FOUND=FALSE even though vertex " "of ray is at target center. This indicates a bug. Please" " contact NAIF.", (ftnlen)125); sigerr_("SPICE(BUG)", (ftnlen)10); chkout_("SUBSOL", (ftnlen)6); return 0; } } else { setmsg_("The computation method # was not recognized. Allowed values" " are \"Near point\" and \"Intercept.\"", (ftnlen)93); errch_("#", method, (ftnlen)1, method_len); sigerr_("SPICE(DUBIOUSMETHOD)", (ftnlen)20); chkout_("SUBSOL", (ftnlen)6); return 0; } chkout_("SUBSOL", (ftnlen)6); return 0; } /* subsol_ */
/* $Procedure ET2LST ( ET to Local Solar Time ) */ /* Subroutine */ int et2lst_(doublereal *et, integer *body, doublereal * long__, char *type__, integer *hr, integer *mn, integer *sc, char * time, char *ampm, ftnlen type_len, ftnlen time_len, ftnlen ampm_len) { /* System generated locals */ address a__1[5], a__2[7]; integer i__1[5], i__2[7]; doublereal d__1; /* Builtin functions */ integer s_cmp(char *, char *, ftnlen, ftnlen); /* Subroutine */ int s_copy(char *, char *, ftnlen, ftnlen), s_cat(char *, char **, integer *, integer *, ftnlen); /* Local variables */ doublereal rate, slat, mins; char h__[2], m[2]; integer n; doublereal q; char s[2]; doublereal angle; char frame[32]; doublereal range; extern /* Subroutine */ int chkin_(char *, ftnlen), ucase_(char *, char *, ftnlen, ftnlen), errch_(char *, char *, ftnlen, ftnlen), dpfmt_( doublereal *, char *, char *, ftnlen, ftnlen); logical found; extern /* Subroutine */ int repmi_(char *, char *, integer *, char *, ftnlen, ftnlen, ftnlen); doublereal state[6], slong; extern /* Subroutine */ int spkez_(integer *, doublereal *, char *, char * , integer *, doublereal *, doublereal *, ftnlen, ftnlen); doublereal hours; extern /* Subroutine */ int ljust_(char *, char *, ftnlen, ftnlen); extern doublereal twopi_(void); extern /* Subroutine */ int bodc2n_(integer *, char *, logical *, ftnlen); extern doublereal pi_(void); char bodnam[36]; doublereal lt; integer frcode; extern /* Subroutine */ int cidfrm_(integer *, integer *, char *, logical *, ftnlen); extern doublereal brcktd_(doublereal *, doublereal *, doublereal *); extern /* Subroutine */ int reclat_(doublereal *, doublereal *, doublereal *, doublereal *), rmaind_(doublereal *, doublereal *, doublereal *, doublereal *); doublereal secnds; extern /* Subroutine */ int pgrrec_(char *, doublereal *, doublereal *, doublereal *, doublereal *, doublereal *, doublereal *, ftnlen); char bpmkwd[32]; integer hrampm; doublereal tmpang; extern /* Subroutine */ int gdpool_(char *, integer *, integer *, integer *, doublereal *, logical *, ftnlen); char amorpm[4]; doublereal tmpsec; extern /* Subroutine */ int sigerr_(char *, ftnlen), chkout_(char *, ftnlen), dtpool_(char *, logical *, integer *, char *, ftnlen, ftnlen), setmsg_(char *, ftnlen), errint_(char *, integer *, ftnlen); doublereal mylong, spoint[3]; extern logical return_(void); char kwtype[1]; extern /* Subroutine */ int intstr_(integer *, char *, ftnlen); char mytype[32]; doublereal lat; /* $ Abstract */ /* Given an ephemeris epoch ET, compute the local solar time for */ /* an object on the surface of a body at a specified longitude. */ /* $ Disclaimer */ /* THIS SOFTWARE AND ANY RELATED MATERIALS WERE CREATED BY THE */ /* CALIFORNIA INSTITUTE OF TECHNOLOGY (CALTECH) UNDER A U.S. */ /* GOVERNMENT CONTRACT WITH THE NATIONAL AERONAUTICS AND SPACE */ /* ADMINISTRATION (NASA). THE SOFTWARE IS TECHNOLOGY AND SOFTWARE */ /* PUBLICLY AVAILABLE UNDER U.S. EXPORT LAWS AND IS PROVIDED "AS-IS" */ /* TO THE RECIPIENT WITHOUT WARRANTY OF ANY KIND, INCLUDING ANY */ /* WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A */ /* PARTICULAR USE OR PURPOSE (AS SET FORTH IN UNITED STATES UCC */ /* SECTIONS 2312-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE */ /* SOFTWARE AND RELATED MATERIALS, HOWEVER USED. */ /* IN NO EVENT SHALL CALTECH, ITS JET PROPULSION LABORATORY, OR NASA */ /* BE LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING, BUT NOT */ /* LIMITED TO, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND, */ /* INCLUDING ECONOMIC DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS, */ /* REGARDLESS OF WHETHER CALTECH, JPL, OR NASA BE ADVISED, HAVE */ /* REASON TO KNOW, OR, IN FACT, SHALL KNOW OF THE POSSIBILITY. */ /* RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF */ /* THE SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY */ /* CALTECH AND NASA FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE */ /* ACTIONS OF RECIPIENT IN THE USE OF THE SOFTWARE. */ /* $ Required_Reading */ /* TIME */ /* $ Keywords */ /* TIME */ /* $ Declarations */ /* $ Brief_I/O */ /* VARIABLE I/O DESCRIPTION */ /* -------- --- -------------------------------------------------- */ /* ET I Epoch in seconds past J2000 epoch */ /* BODY I ID-code of the body of interest */ /* LONG I Longitude of surface point (RADIANS) */ /* TYPE I Type of longitude 'PLANETOCENTRIC', etc. */ /* HR O Local hour on a "24 hour" clock */ /* MN O Minutes past the hour */ /* SC O Seconds past the minute */ /* TIME O String giving local time on 24 hour clock */ /* AMPM O String giving time on A.M./ P.M. scale */ /* $ Detailed_Input */ /* ET is the epoch expressed in TDB seconds past */ /* the J2000 epoch at which a local time is desired. */ /* BODY is the NAIF ID-code of a body on which local */ /* time is to be measured. */ /* LONG is the longitude (either planetocentric or */ /* planetographic) in radians of the site on the */ /* surface of body for which local time should be */ /* computed. */ /* TYPE is the form of longitude supplied by the variable */ /* LONG. Allowed values are 'PLANETOCENTRIC' and */ /* 'PLANETOGRAPHIC'. Note the case of the letters */ /* in TYPE is insignificant. Both 'PLANETOCENTRIC' */ /* and 'planetocentric' are recognized. */ /* $ Detailed_Output */ /* HR is the local "hour" of the site specified at the */ /* epoch ET. Note that an "hour" of local time does not */ /* have the same duration as an hour measured by */ /* conventional clocks. It is simply a representation */ /* of an angle. See the "Particulars" section for a more */ /* complete discussion of the meaning of local time. */ /* MN is the number of "minutes" past the hour of the */ /* local time of the site at the epoch ET. Again note */ /* that a "local minute" is not the same as a minute */ /* you would measure with conventional clocks. */ /* SC is the number of "seconds" past the minute of the */ /* local time of the site at the epoch ET. Again note */ /* that a "local second" is not the same as a second */ /* you would measure with conventional clocks. */ /* TIME is a string expressing the local time */ /* on a "24 hour" local clock. */ /* AMPM is a string expressing the local time on a "12 hour" */ /* local clock together with the traditional AM/PM */ /* label to indicate whether the sun has crossed */ /* the local zenith meridian. */ /* $ Parameters */ /* None. */ /* $ Exceptions */ /* 1) This routine defines local solar time for any point on the */ /* surface of the Sun to be 12:00:00 noon. */ /* 2) If the TYPE of the coordinates is not recognized, the */ /* error 'SPICE(UNKNOWNSYSTEM)' will be signaled. */ /* 3) If the body-fixed frame to associate with BODY cannot be */ /* determined, the error 'SPICE(CANTFINDFRAME)' is signaled. */ /* 4) If insufficient data is available to compute the */ /* location of the sun in body-fixed coordinates, the */ /* error will be diagnosed by a routine called by this one. */ /* 5) If the BODY#_PM keyword required to determine the body */ /* rotation sense is not found in the POOL or if it is found but */ /* is not a numeric keyword with at least two elements, the error */ /* 'SPICE(CANTGETROTATIONTYPE)' is signaled. */ /* $ Files */ /* Suitable SPK and PCK files must be loaded prior to calling this */ /* routine so that the body-fixed position of the sun relative to */ /* BODY can be computed. The PCK files must contain the standard */ /* BODY#_PM keyword need by this routine to determine the body */ /* rotation sense. */ /* When the input longitude is planetographic, the default */ /* interpretation of this value can be overridden using the optional */ /* kernel variable */ /* BODY<body ID>_PGR_POSITIVE_LON */ /* which is normally defined via loading a text kernel. */ /* $ Particulars */ /* This routine returns the local solar time at a user */ /* specified location on a user specified body. */ /* Let SUNLNG be the planetocentric longitude (in degrees) of */ /* the sun as viewed from the center of the body of interest. */ /* Let SITLNG be the planetocentric longitude (in degrees) of */ /* the site for which local time is desired. */ /* We define local time to be 12 + (SITLNG - SUNLNG)/15 */ /* (where appropriate care is taken to map ( SITLNG - SUNLNG ) */ /* into the range from -180 to 180). */ /* Using this definition, we see that from the point of view */ /* of this routine, local solar time is simply a measure of angles */ /* between meridians on the surface of a body. Consequently, */ /* this routine is not appropriate for computing "local times" */ /* in the sense of Pacific Standard Time. For computing times */ /* relative to standard time zones on earth, see the routines */ /* TIMOUT and STR2ET. */ /* Regarding planetographic longitude */ /* ---------------------------------- */ /* In the planetographic coordinate system, longitude is defined */ /* using the spin sense of the body. Longitude is positive to the */ /* west if the spin is prograde and positive to the east if the spin */ /* is retrograde. The spin sense is given by the sign of the first */ /* degree term of the time-dependent polynomial for the body's prime */ /* meridian Euler angle "W": the spin is retrograde if this term is */ /* negative and prograde otherwise. For the sun, planets, most */ /* natural satellites, and selected asteroids, the polynomial */ /* expression for W may be found in a SPICE PCK kernel. */ /* The earth, moon, and sun are exceptions: planetographic longitude */ /* is measured positive east for these bodies. */ /* If you wish to override the default sense of positive */ /* planetographic longitude for a particular body, you can do so by */ /* defining the kernel variable */ /* BODY<body ID>_PGR_POSITIVE_LON */ /* where <body ID> represents the NAIF ID code of the body. This */ /* variable may be assigned either of the values */ /* 'WEST' */ /* 'EAST' */ /* For example, you can have this routine treat the longitude */ /* of the earth as increasing to the west using the kernel */ /* variable assignment */ /* BODY399_PGR_POSITIVE_LON = 'WEST' */ /* Normally such assignments are made by placing them in a text */ /* kernel and loading that kernel via FURNSH. */ /* $ Examples */ /* The following code fragment illustrates how you */ /* could print the local time at a site on Mars with */ /* planetographic longitude 326.17 deg E at epoch ET. */ /* (This example assumes all required SPK and PCK files have */ /* been loaded). */ /* Convert the longitude to radians, set the type of the longitude */ /* and make up a mnemonic for Mars' ID-code. */ /* LONG = 326.17 * RPD() */ /* TYPE = 'PLANETOGRAPHIC' */ /* MARS = 499 */ /* CALL ET2LST ( ET, MARS, LONG, TYPE, HR, MN, SC, TIME, AMPM ) */ /* WRITE (*,*) 'The local time at Mars 326.17 degrees E ' */ /* WRITE (*,*) 'planetographic longitude is: ', AMPM */ /* $ Restrictions */ /* This routine relies on being able to determine the name */ /* of the body-fixed frame associated with BODY through the */ /* frames subsystem. If the BODY specified is NOT one of the */ /* nine planets or their satellites, you will need to load */ /* an appropriate frame definition kernel that contains */ /* the relationship between the body id and the body-fixed frame */ /* name. See the FRAMES required reading for more details */ /* on specifying this relationship. */ /* The routine determines the body rotation sense using the PCK */ /* keyword BODY#_PM. Therefore, you will need to a text PCK file */ /* defining the complete set of the standard PCK body rotation */ /* keywords for the body of interest. The text PCK file must be */ /* loaded independently of whether a binary PCK file providing */ /* rotation data for the same body is loaded or not. */ /* Although it is not currently the case for any of the Solar System */ /* bodies, it is possible that the retrograde rotation rate of a */ /* body would be slower than the orbital rate of the body rotation */ /* around the Sun. The routine does not account for such cases; for */ /* them it will compute incorrect the local time progressing */ /* backwards. */ /* $ Literature_References */ /* None. */ /* $ Author_and_Institution */ /* W.L. Taber (JPL) */ /* $ Version */ /* - SPICELIB Version 3.0.2, 18-APR-2014 (BVS) */ /* Minor edits to long error messages. */ /* - SPICELIB Version 3.0.1, 09-SEP-2009 (EDW) */ /* Header edits: deleted a spurious C$ marker from the */ /* "Detailed_Output" section. The existence of the marker */ /* caused a failure in the HTML documentation creation script. */ /* Deleted the "Revisions" section as it contained several */ /* identical entries from the "Version" section. */ /* Corrected order of header sections. */ /* - SPICELIB Version 3.0.0, 28-OCT-2006 (BVS) */ /* Bug fix: incorrect computation of the local time for the */ /* bodies with the retrograde rotation causing the local time to */ /* flow backwards has been fixed. The local time for all types of */ /* bodies now progresses as expected -- midnight, increasing AM */ /* hours, noon, increasing PM hours, next midnight, and so on. */ /* - SPICELIB Version 2.0.0, 03-NOV-2005 (NJB) */ /* Bug fix: treatment of planetographic longitude has been */ /* updated to be consistent with the SPICE planetographic/ */ /* rectangular coordinate conversion routines. The effect of */ /* this change is that the default sense of positive longitude */ /* for the moon is now east; also, the default sense of positive */ /* planetographic longitude now may be overridden for any body */ /* (see Particulars above). */ /* Updated to remove non-standard use of duplicate arguments */ /* in RMAIND calls. */ /* - SPICELIB Version 1.1.0, 24-MAR-1998 (WLT) */ /* The integer variable SUN was never initialized in the */ /* previous version of the routine. Now it is set to */ /* the proper value of 10. */ /* - SPICELIB Version 1.0.0, 9-JUL-1997 (WLT) */ /* -& */ /* $ Index_Entries */ /* Compute the local time for a point on a body. */ /* -& */ /* SPICELIB Functions */ /* Local parameters */ /* Local Variables */ /* Standard SPICE error handling. */ if (return_()) { return 0; } chkin_("ET2LST", (ftnlen)6); ljust_(type__, mytype, type_len, (ftnlen)32); ucase_(mytype, mytype, (ftnlen)32, (ftnlen)32); if (s_cmp(mytype, "PLANETOGRAPHIC", (ftnlen)32, (ftnlen)14) == 0) { /* Find planetocentric longitude corresponding to the input */ /* longitude. We first represent in rectangular coordinates */ /* a surface point having zero latitude, zero altitude, and */ /* the input planetographic longitude. We then find the */ /* planetocentric longitude of this point. */ /* Since PGRREC accepts a body name, map the input code to */ /* a name, if possible. Otherwise, just convert the input code */ /* to a string. */ bodc2n_(body, bodnam, &found, (ftnlen)36); if (! found) { intstr_(body, bodnam, (ftnlen)36); } /* Convert planetographic coordinates to rectangular coordinates. */ /* All we care about here is longitude. Set the other inputs */ /* as follows: */ /* Latitude = 0 */ /* Altitude = 0 */ /* Equatorial radius = 1 */ /* Flattening factor = 0 */ pgrrec_(bodnam, long__, &c_b4, &c_b4, &c_b6, &c_b4, spoint, (ftnlen) 36); /* The output MYLONG is planetocentric longitude. The other */ /* outputs are not used. Note that the variable RANGE appears */ /* later in another RECLAT call; it's not used after that. */ reclat_(spoint, &range, &mylong, &lat); } else if (s_cmp(mytype, "PLANETOCENTRIC", (ftnlen)32, (ftnlen)14) == 0) { mylong = *long__; } else { setmsg_("The coordinate system '#' is not a recognized system of lon" "gitude. The recognized systems are 'PLANETOCENTRIC' and 'PL" "ANETOGRAPHIC'. ", (ftnlen)134); errch_("#", type__, (ftnlen)1, type_len); sigerr_("SPICE(UNKNOWNSYSTEM)", (ftnlen)20); chkout_("ET2LST", (ftnlen)6); return 0; } /* It's always noon on the surface of the sun. */ if (*body == 10) { *hr = 12; *mn = 0; *sc = 0; s_copy(time, "12:00:00", time_len, (ftnlen)8); s_copy(ampm, "12:00:00 P.M.", ampm_len, (ftnlen)13); chkout_("ET2LST", (ftnlen)6); return 0; } /* Get the body-fixed position of the sun. */ cidfrm_(body, &frcode, frame, &found, (ftnlen)32); if (! found) { setmsg_("The body-fixed frame associated with body # could not be de" "termined. This information needs to be \"loaded\" via a fra" "mes definition kernel. See frames.req for more details. ", ( ftnlen)174); errint_("#", body, (ftnlen)1); sigerr_("SPICE(CANTFINDFRAME)", (ftnlen)20); chkout_("ET2LST", (ftnlen)6); return 0; } spkez_(&c__10, et, frame, "LT+S", body, state, <, (ftnlen)32, (ftnlen)4) ; reclat_(state, &range, &slong, &slat); angle = mylong - slong; /* Force the angle into the region from -PI to PI */ d__1 = twopi_(); rmaind_(&angle, &d__1, &q, &tmpang); angle = tmpang; if (angle > pi_()) { angle -= twopi_(); } /* Get the rotation sense of the body and invert the angle if the */ /* rotation sense is retrograde. Use the BODY#_PM PCK keyword to */ /* determine the sense of the body rotation. */ s_copy(bpmkwd, "BODY#_PM", (ftnlen)32, (ftnlen)8); repmi_(bpmkwd, "#", body, bpmkwd, (ftnlen)32, (ftnlen)1, (ftnlen)32); dtpool_(bpmkwd, &found, &n, kwtype, (ftnlen)32, (ftnlen)1); if (! found || *(unsigned char *)kwtype != 'N' || n < 2) { setmsg_("The rotation type for the body # could not be determined be" "cause the # keyword was either not found in the POOL or or i" "t was not of the expected type and/or dimension. This keywor" "d is usually provided via a planetary constants kernel. See " "pck.req for more details. ", (ftnlen)265); errint_("#", body, (ftnlen)1); errch_("#", bpmkwd, (ftnlen)1, (ftnlen)32); sigerr_("SPICE(CANTGETROTATIONTYPE)", (ftnlen)26); chkout_("ET2LST", (ftnlen)6); return 0; } else { /* If the rotation rate is negative, invert the angle. */ gdpool_(bpmkwd, &c__2, &c__1, &n, &rate, &found, (ftnlen)32); if (rate < 0.) { angle = -angle; } } /* Convert the angle to "angle seconds" before or after local noon. */ secnds = angle * 86400. / twopi_(); secnds = brcktd_(&secnds, &c_b32, &c_b33); /* Get the hour, and minutes components of the local time. */ rmaind_(&secnds, &c_b34, &hours, &tmpsec); rmaind_(&tmpsec, &c_b35, &mins, &secnds); /* Construct the integer components of the local time. */ *hr = (integer) hours + 12; *mn = (integer) mins; *sc = (integer) secnds; /* Set the A.M./P.M. components of local time. */ if (*hr == 24) { *hr = 0; hrampm = 12; s_copy(amorpm, "A.M.", (ftnlen)4, (ftnlen)4); } else if (*hr > 12) { hrampm = *hr - 12; s_copy(amorpm, "P.M.", (ftnlen)4, (ftnlen)4); } else if (*hr == 12) { hrampm = 12; s_copy(amorpm, "P.M.", (ftnlen)4, (ftnlen)4); } else if (*hr == 0) { hrampm = 12; s_copy(amorpm, "A.M.", (ftnlen)4, (ftnlen)4); } else { hrampm = *hr; s_copy(amorpm, "A.M.", (ftnlen)4, (ftnlen)4); } /* Now construct the two strings we need. */ hours = (doublereal) (*hr); mins = (doublereal) (*mn); secnds = (doublereal) (*sc); dpfmt_(&hours, "0x", h__, (ftnlen)2, (ftnlen)2); dpfmt_(&mins, "0x", m, (ftnlen)2, (ftnlen)2); dpfmt_(&secnds, "0x", s, (ftnlen)2, (ftnlen)2); /* Writing concatenation */ i__1[0] = 2, a__1[0] = h__; i__1[1] = 1, a__1[1] = ":"; i__1[2] = 2, a__1[2] = m; i__1[3] = 1, a__1[3] = ":"; i__1[4] = 2, a__1[4] = s; s_cat(time, a__1, i__1, &c__5, time_len); hours = (doublereal) hrampm; dpfmt_(&hours, "0x", h__, (ftnlen)2, (ftnlen)2); /* Writing concatenation */ i__2[0] = 2, a__2[0] = h__; i__2[1] = 1, a__2[1] = ":"; i__2[2] = 2, a__2[2] = m; i__2[3] = 1, a__2[3] = ":"; i__2[4] = 2, a__2[4] = s; i__2[5] = 1, a__2[5] = " "; i__2[6] = 4, a__2[6] = amorpm; s_cat(ampm, a__2, i__2, &c__7, ampm_len); chkout_("ET2LST", (ftnlen)6); return 0; } /* et2lst_ */
/* $Procedure SUBPT ( Sub-observer point ) */ /* Subroutine */ int subpt_(char *method, char *target, doublereal *et, char * abcorr, char *obsrvr, doublereal *spoint, doublereal *alt, ftnlen method_len, ftnlen target_len, ftnlen abcorr_len, ftnlen obsrvr_len) { /* Initialized data */ static doublereal origin[3] = { 0.,0.,0. }; doublereal radii[3]; extern /* Subroutine */ int chkin_(char *, ftnlen), errch_(char *, char *, ftnlen, ftnlen); logical found; extern doublereal vdist_(doublereal *, doublereal *); extern /* Subroutine */ int spkez_(integer *, doublereal *, char *, char * , integer *, doublereal *, doublereal *, ftnlen, ftnlen); extern logical eqstr_(char *, char *, ftnlen, ftnlen); extern /* Subroutine */ int bods2c_(char *, integer *, logical *, ftnlen); integer obscde; doublereal lt; extern /* Subroutine */ int bodvcd_(integer *, char *, integer *, integer *, doublereal *, ftnlen); integer frcode; extern /* Subroutine */ int cidfrm_(integer *, integer *, char *, logical *, ftnlen); integer nradii; char frname[80]; integer trgcde; extern /* Subroutine */ int nearpt_(doublereal *, doublereal *, doublereal *, doublereal *, doublereal *, doublereal *), sigerr_( char *, ftnlen), chkout_(char *, ftnlen), setmsg_(char *, ftnlen); doublereal tstate[6]; extern logical return_(void); extern /* Subroutine */ int vminus_(doublereal *, doublereal *), surfpt_( doublereal *, doublereal *, doublereal *, doublereal *, doublereal *, doublereal *, logical *); doublereal pos[3]; /* $ Abstract */ /* Deprecated: This routine has been superseded by the SPICELIB */ /* routine SUBPNT. This routine is supported for purposes of */ /* backward compatibility only. */ /* Compute the rectangular coordinates of the sub-observer point on */ /* a target body at a particular epoch, optionally corrected for */ /* planetary (light time) and stellar aberration. Return these */ /* coordinates expressed in the body-fixed frame associated with the */ /* target body. Also, return the observer's altitude above the */ /* target body. */ /* $ Disclaimer */ /* THIS SOFTWARE AND ANY RELATED MATERIALS WERE CREATED BY THE */ /* CALIFORNIA INSTITUTE OF TECHNOLOGY (CALTECH) UNDER A U.S. */ /* GOVERNMENT CONTRACT WITH THE NATIONAL AERONAUTICS AND SPACE */ /* ADMINISTRATION (NASA). THE SOFTWARE IS TECHNOLOGY AND SOFTWARE */ /* PUBLICLY AVAILABLE UNDER U.S. EXPORT LAWS AND IS PROVIDED "AS-IS" */ /* TO THE RECIPIENT WITHOUT WARRANTY OF ANY KIND, INCLUDING ANY */ /* WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A */ /* PARTICULAR USE OR PURPOSE (AS SET FORTH IN UNITED STATES UCC */ /* SECTIONS 2312-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE */ /* SOFTWARE AND RELATED MATERIALS, HOWEVER USED. */ /* IN NO EVENT SHALL CALTECH, ITS JET PROPULSION LABORATORY, OR NASA */ /* BE LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING, BUT NOT */ /* LIMITED TO, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND, */ /* INCLUDING ECONOMIC DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS, */ /* REGARDLESS OF WHETHER CALTECH, JPL, OR NASA BE ADVISED, HAVE */ /* REASON TO KNOW, OR, IN FACT, SHALL KNOW OF THE POSSIBILITY. */ /* RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF */ /* THE SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY */ /* CALTECH AND NASA FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE */ /* ACTIONS OF RECIPIENT IN THE USE OF THE SOFTWARE. */ /* $ Required_Reading */ /* FRAMES */ /* PCK */ /* SPK */ /* TIME */ /* $ Keywords */ /* GEOMETRY */ /* $ Declarations */ /* $ Brief_I/O */ /* Variable I/O Description */ /* -------- --- -------------------------------------------------- */ /* METHOD I Computation method. */ /* TARGET I Name of target body. */ /* ET I Epoch in ephemeris seconds past J2000 TDB. */ /* ABCORR I Aberration correction. */ /* OBSRVR I Name of observing body. */ /* SPOINT O Sub-observer point on the target body. */ /* ALT O Altitude of the observer above the target body. */ /* $ Detailed_Input */ /* METHOD is a short string specifying the computation method */ /* to be used. The choices are: */ /* 'Near point' The sub-observer point is */ /* defined as the nearest point on */ /* the target relative to the */ /* observer. */ /* 'Intercept' The sub-observer point is */ /* defined as the target surface */ /* intercept of the line */ /* containing the observer and the */ /* target's center. */ /* In both cases, the intercept computation treats the */ /* surface of the target body as a triaxial ellipsoid. */ /* The ellipsoid's radii must be available in the kernel */ /* pool. */ /* Neither case nor white space are significant in */ /* METHOD. For example, the string ' NEARPOINT' is */ /* valid. */ /* TARGET is the name of a target body. Optionally, you may */ /* supply the integer ID code for the object as */ /* an integer string. For example both 'MOON' and */ /* '301' are legitimate strings that indicate the */ /* moon is the target body. This routine assumes */ /* that this body is modeled by a tri-axial ellipsoid, */ /* and that a PCK file containing its radii has been */ /* loaded into the kernel pool via FURNSH. */ /* ET is the epoch in ephemeris seconds past J2000 at which */ /* the sub-observer point on the target body is to be */ /* computed. */ /* ABCORR indicates the aberration corrections to be applied */ /* when computing the observer-target state. ABCORR */ /* may be any of the following. */ /* 'NONE' Apply no correction. Return the */ /* geometric sub-observer point on the */ /* target body. */ /* 'LT' Correct for planetary (light time) */ /* aberration. Both the state and rotation */ /* of the target body are corrected for */ /* light time. */ /* 'LT+S' Correct for planetary (light time) and */ /* stellar aberrations. Both the state and */ /* rotation of the target body are */ /* corrected for light time. */ /* 'CN' Converged Newtonian light time */ /* corrections. This is the same as LT */ /* corrections but with further iterations */ /* to a converged Newtonian light time */ /* solution. Given that relativistic */ /* effects may be as large as the higher */ /* accuracy achieved by this computation, */ /* this is correction is seldom worth the */ /* additional computations required unless */ /* the user incorporates additional */ /* relativistic corrections. Both the */ /* state and rotation of the target body */ /* are corrected for light time. */ /* 'CN+S' Converged Newtonian light time */ /* corrections and stellar aberration. */ /* Both the state and rotation of the */ /* target body are corrected for light */ /* time. */ /* OBSRVR is the name of the observing body. This is typically */ /* a spacecraft, the earth, or a surface point on the */ /* earth. Optionally, you may supply the ID code of */ /* the object as an integer string. For example, both */ /* 'EARTH' and '399' are legitimate strings to supply */ /* to indicate the observer is Earth. */ /* $ Detailed_Output */ /* SPOINT is the sub-observer point on the target body at ET */ /* expressed relative to the body-fixed frame of the */ /* target body. */ /* The sub-observer point is defined either as the point */ /* on the target body that is closest to the observer, */ /* or the target surface intercept of the line from the */ /* observer to the target's center; the input argument */ /* METHOD selects the definition to be used. */ /* The body-fixed frame, which is time-dependent, is */ /* evaluated at ET if ABCORR is 'NONE'; otherwise the */ /* frame is evaluated at ET-LT, where LT is the one-way */ /* light time from target to observer. */ /* The state of the target body is corrected for */ /* aberration as specified by ABCORR; the corrected */ /* state is used in the geometric computation. As */ /* indicated above, the rotation of the target is */ /* retarded by one-way light time if ABCORR specifies */ /* that light time correction is to be done. */ /* ALT is the "altitude" of the observer above the target */ /* body. When METHOD specifies a "near point" */ /* computation, ALT is truly altitude in the standard */ /* geometric sense: the length of a segment dropped from */ /* the observer to the target's surface, such that the */ /* segment is perpendicular to the surface at the */ /* contact point SPOINT. */ /* When METHOD specifies an "intercept" computation, ALT */ /* is still the length of the segment from the observer */ /* to the surface point SPOINT, but this segment in */ /* general is not perpendicular to the surface. */ /* $ Parameters */ /* None. */ /* $ Exceptions */ /* If any of the listed errors occur, the output arguments are */ /* left unchanged. */ /* 1) If the input argument METHOD is not recognized, the error */ /* SPICE(DUBIOUSMETHOD) is signaled. */ /* 2) If either of the input body names TARGET or OBSRVR cannot be */ /* mapped to NAIF integer codes, the error SPICE(IDCODENOTFOUND) */ /* is signaled. */ /* 3) If OBSRVR and TARGET map to the same NAIF integer ID codes, the */ /* error SPICE(BODIESNOTDISTINCT) is signaled. */ /* 4) If frame definition data enabling the evaluation of the state */ /* of the target relative to the observer in target body-fixed */ /* coordinates have not been loaded prior to calling SUBPT, the */ /* error will be diagnosed and signaled by a routine in the call */ /* tree of this routine. */ /* 5) If the specified aberration correction is not recognized, the */ /* error will be diagnosed and signaled by a routine in the call */ /* tree of this routine. */ /* 6) If insufficient ephemeris data have been loaded prior to */ /* calling SUBPT, the error will be diagnosed and signaled by a */ /* routine in the call tree of this routine. */ /* 7) If the triaxial radii of the target body have not been loaded */ /* into the kernel pool prior to calling SUBPT, the error will be */ /* diagnosed and signaled by a routine in the call tree of this */ /* routine. */ /* 8) The target must be an extended body: if any of the radii of */ /* the target body are non-positive, the error will be diagnosed */ /* and signaled by routines in the call tree of this routine. */ /* 9) If PCK data supplying a rotation model for the target body */ /* have not been loaded prior to calling SUBPT, the error will be */ /* diagnosed and signaled by a routine in the call tree of this */ /* routine. */ /* $ Files */ /* Appropriate SPK, PCK, and frame kernels must be loaded */ /* prior by the calling program before this routine is called. */ /* The following data are required: */ /* - SPK data: ephemeris data for target and observer must be */ /* loaded. If aberration corrections are used, the states of */ /* target and observer relative to the solar system barycenter */ /* must be calculable from the available ephemeris data. */ /* Typically ephemeris data are made available by loading one */ /* or more SPK files via FURNSH. */ /* - PCK data: triaxial radii for the target body must be loaded */ /* into the kernel pool. Typically this is done by loading a */ /* text PCK file via FURNSH. */ /* - Further PCK data: rotation data for the target body must */ /* be loaded. These may be provided in a text or binary PCK */ /* file. Either type of file may be loaded via FURNSH. */ /* - Frame data: if a frame definition is required to convert */ /* the observer and target states to the body-fixed frame of */ /* the target, that definition must be available in the kernel */ /* pool. Typically the definition is supplied by loading a */ /* frame kernel via FURNSH. */ /* In all cases, kernel data are normally loaded once per program */ /* run, NOT every time this routine is called. */ /* $ Particulars */ /* SUBPT computes the sub-observer point on a target body. */ /* (The sub-observer point is commonly called the sub-spacecraft */ /* point when the observer is a spacecraft.) SUBPT also */ /* determines the altitude of the observer above the target body. */ /* There are two different popular ways to define the sub-observer */ /* point: "nearest point on target to observer" or "target surface */ /* intercept of line containing observer and target." These */ /* coincide when the target is spherical and generally are distinct */ /* otherwise. */ /* When comparing sub-point computations with results from sources */ /* other than SPICE, it's essential to make sure the same geometric */ /* definitions are used. */ /* $ Examples */ /* The numerical results shown for this example may differ across */ /* platforms. The results depend on the SPICE kernels used as */ /* input, the compiler and supporting libraries, and the machine */ /* specific arithmetic implementation. */ /* In the following example program, the file */ /* spk_m_031103-040201_030502.bsp */ /* is a binary SPK file containing data for Mars Global Surveyor, */ /* Mars, and the Sun for a time interval bracketing the date */ /* 2004 JAN 1 12:00:00 UTC. */ /* pck00007.tpc is a planetary constants kernel file containing */ /* radii and rotation model constants. naif0007.tls is a */ /* leapseconds kernel. */ /* Find the sub-observer point of the Mars Global Surveyor (MGS) */ /* spacecraft on Mars for a specified time. Perform the computation */ /* twice, using both the "intercept" and "near point" options. */ /* IMPLICIT NONE */ /* CHARACTER*25 METHOD ( 2 ) */ /* INTEGER I */ /* DOUBLE PRECISION ALT */ /* DOUBLE PRECISION DPR */ /* DOUBLE PRECISION ET */ /* DOUBLE PRECISION LAT */ /* DOUBLE PRECISION LON */ /* DOUBLE PRECISION RADIUS */ /* DOUBLE PRECISION SPOINT ( 3 ) */ /* DATA METHOD / 'Intercept', 'Near point' / */ /* C */ /* C Load kernel files. */ /* C */ /* CALL FURNSH ( 'naif0007.tls' ) */ /* CALL FURNSH ( 'pck00007.tpc' ) */ /* CALL FURNSH ( 'spk_m_031103-040201_030502.bsp' ) */ /* C */ /* C Convert the UTC request time to ET (seconds past */ /* C J2000, TDB). */ /* C */ /* CALL STR2ET ( '2004 JAN 1 12:00:00', ET ) */ /* C */ /* C Compute sub-spacecraft point using light time and stellar */ /* C aberration corrections. Use the "target surface intercept" */ /* C definition of sub-spacecraft point on the first loop */ /* C iteration, and use the "near point" definition on the */ /* C second. */ /* C */ /* DO I = 1, 2 */ /* CALL SUBPT ( METHOD(I), */ /* . 'MARS', ET, 'LT+S', */ /* . 'MGS', SPOINT, ALT ) */ /* C */ /* C Convert rectangular coordinates to planetocentric */ /* C latitude and longitude. Convert radians to degrees. */ /* C */ /* CALL RECLAT ( SPOINT, RADIUS, LON, LAT ) */ /* LON = LON * DPR () */ /* LAT = LAT * DPR () */ /* C */ /* C Write the results. */ /* C */ /* WRITE (*,*) ' ' */ /* WRITE (*,*) 'Computation method: ', METHOD(I) */ /* WRITE (*,*) ' ' */ /* WRITE (*,*) ' Radius (km) = ', RADIUS */ /* WRITE (*,*) ' Planetocentric Latitude (deg) = ', LAT */ /* WRITE (*,*) ' Planetocentric Longitude (deg) = ', LON */ /* WRITE (*,*) ' Altitude (km) = ', ALT */ /* WRITE (*,*) ' ' */ /* END DO */ /* END */ /* When this program is executed, the output will be: */ /* Computation method: Intercept */ /* Radius (km) = 3387.97077 */ /* Planetocentric Latitude (deg) = -39.7022724 */ /* Planetocentric Longitude (deg) = -159.226663 */ /* Altitude (km) = 373.173506 */ /* Computation method: Near point */ /* Radius (km) = 3387.9845 */ /* Planetocentric Latitude (deg) = -39.6659329 */ /* Planetocentric Longitude (deg) = -159.226663 */ /* Altitude (km) = 373.166636 */ /* $ Restrictions */ /* None. */ /* $ Literature_References */ /* None. */ /* $ Author_and_Institution */ /* C.H. Acton (JPL) */ /* N.J. Bachman (JPL) */ /* J.E. McLean (JPL) */ /* $ Version */ /* - SPICELIB Version 1.2.3, 18-MAY-2010 (BVS) */ /* Index line now states that this routine is deprecated. */ /* - SPICELIB Version 1.2.2, 17-MAR-2009 (EDW) */ /* Typo correction in Required_Reading, changed */ /* FRAME to FRAMES. */ /* - SPICELIB Version 1.2.1, 07-FEB-2008 (NJB) */ /* Abstract now states that this routine is deprecated. */ /* - SPICELIB Version 1.2.0, 24-OCT-2005 (NJB) */ /* Replaced call to BODVAR with call to BODVCD. */ /* - SPICELIB Version 1.1.0, 21-JUL-2004 (EDW) */ /* Changed BODN2C call to BODS2C giving the routine */ /* the capability to accept string representations of */ /* interger IDs for TARGET and OBSRVR. */ /* - SPICELIB Version 1.0.1, 27-JUL-2003 (NJB) (CHA) */ /* Various header corrections were made. The example program */ /* was upgraded to use real kernels, and the program's output is */ /* shown. */ /* - SPICELIB Version 1.0.0, 03-SEP-1999 (NJB) (JEM) */ /* -& */ /* $ Index_Entries */ /* DEPRECATED sub-observer point */ /* -& */ /* SPICELIB functions */ /* Local parameters */ /* Local variables */ /* Saved variables */ /* Initial values */ /* Standard SPICE error handling. */ if (return_()) { return 0; } else { chkin_("SUBPT", (ftnlen)5); } /* Obtain integer codes for the target and observer. */ /* Target... */ bods2c_(target, &trgcde, &found, target_len); if (! found) { setmsg_("The target, '#', is not a recognized name for an ephemeris " "object. The cause of this problem may be that you need an up" "dated version of the SPICE Toolkit. ", (ftnlen)155); errch_("#", target, (ftnlen)1, target_len); sigerr_("SPICE(IDCODENOTFOUND)", (ftnlen)21); chkout_("SUBPT", (ftnlen)5); return 0; } /* ...observer. */ bods2c_(obsrvr, &obscde, &found, obsrvr_len); if (! found) { setmsg_("The observer, '#', is not a recognized name for an ephemeri" "s object. The cause of this problem may be that you need an " "updated version of the SPICE Toolkit. ", (ftnlen)157); errch_("#", obsrvr, (ftnlen)1, obsrvr_len); sigerr_("SPICE(IDCODENOTFOUND)", (ftnlen)21); chkout_("SUBPT", (ftnlen)5); return 0; } /* Check the input body codes. If they are equal, signal */ /* an error. */ if (obscde == trgcde) { setmsg_("In computing the sub-observer point, the observing body and" " target body are the same. Both are #.", (ftnlen)97); errch_("#", obsrvr, (ftnlen)1, obsrvr_len); sigerr_("SPICE(BODIESNOTDISTINCT)", (ftnlen)24); chkout_("SUBPT", (ftnlen)5); return 0; } /* Get the radii of the target body from the kernel pool. */ bodvcd_(&trgcde, "RADII", &c__3, &nradii, radii, (ftnlen)5); /* Find the name of the body-fixed frame associated with the */ /* target body. We'll want the state of the target relative to */ /* the observer in this body-fixed frame. */ cidfrm_(&trgcde, &frcode, frname, &found, (ftnlen)80); if (! found) { setmsg_("No body-fixed frame is associated with target body #; a fra" "me kernel must be loaded to make this association. Consult " "the FRAMES Required Reading for details.", (ftnlen)159); errch_("#", target, (ftnlen)1, target_len); sigerr_("SPICE(NOFRAME)", (ftnlen)14); chkout_("SUBPT", (ftnlen)5); return 0; } /* Determine the position of the observer in target */ /* body-fixed coordinates. */ /* - Call SPKEZR to compute the position of the target */ /* body as seen from the observing body and the light time */ /* (LT) between them. SPKEZR returns a state which is */ /* the position and velocity, but we'll only use the position */ /* which is the first three elements. We request that the */ /* coordinates of POS be returned relative to the body fixed */ /* reference frame associated with the target body, using */ /* aberration corrections specified by the input argument */ /* ABCORR. */ /* - Call VMINUS to negate the direction of the vector (POS) */ /* so it will be the position of the observer as seen from */ /* the target body in target body fixed coordinates. */ /* Note that this result is not the same as the result of */ /* calling SPKEZR with the target and observer switched. We */ /* computed the vector FROM the observer TO the target in */ /* order to get the proper light time and stellar aberration */ /* corrections (if requested). Now we need the inverse of */ /* that corrected vector in order to compute the sub-point. */ spkez_(&trgcde, et, frname, abcorr, &obscde, tstate, <, (ftnlen)80, abcorr_len); /* Negate the target's state to obtain the position of the observer */ /* relative to the target. */ vminus_(tstate, pos); /* Find the sub-point and "altitude" (distance from observer to */ /* sub-point) using the specified geometric definition. */ if (eqstr_(method, "Near point", method_len, (ftnlen)10)) { /* Locate the nearest point to the observer on the target. */ nearpt_(pos, radii, &radii[1], &radii[2], spoint, alt); } else if (eqstr_(method, "Intercept", method_len, (ftnlen)9)) { surfpt_(origin, pos, radii, &radii[1], &radii[2], spoint, &found); /* Since the line in question passes through the center of the */ /* target, there will always be a surface intercept. So we should */ /* never have FOUND = .FALSE. */ if (! found) { setmsg_("Call to SURFPT returned FOUND=FALSE even though vertex " "of ray is at target center. This indicates a bug. Please" " contact NAIF.", (ftnlen)125); sigerr_("SPICE(BUG)", (ftnlen)10); chkout_("SUBPT", (ftnlen)5); return 0; } /* SURFPT doesn't compute altitude, so do it here. */ *alt = vdist_(pos, spoint); } else { setmsg_("The computation method # was not recognized. Allowed values" " are \"Near point\" and \"Intercept.\"", (ftnlen)93); errch_("#", method, (ftnlen)1, method_len); sigerr_("SPICE(DUBIOUSMETHOD)", (ftnlen)20); chkout_("SUBPT", (ftnlen)5); return 0; } chkout_("SUBPT", (ftnlen)5); return 0; } /* subpt_ */