예제 #1
0
파일: illum.c 프로젝트: Dbelsa/coft
/* $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, &lt, (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, &lts, (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_ */
예제 #2
0
/* $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, &lt, (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_ */
예제 #3
0
파일: et2lst.c 프로젝트: Dbelsa/coft
/* $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, &lt, (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_ */
예제 #4
0
/* $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, &lt, (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_ */