/* $Procedure LTIME ( Light Time ) */ /* Subroutine */ int ltime_(doublereal *etobs, integer *obs, char *dir, integer *targ, doublereal *ettarg, doublereal *elapsd, ftnlen dir_len) { /* Builtin functions */ integer s_cmp(char *, char *, ftnlen, ftnlen); /* Local variables */ doublereal sobs[6], myet, c__; integer r__; extern /* Subroutine */ int chkin_(char *, ftnlen), errch_(char *, char *, ftnlen, ftnlen); doublereal starg[6]; extern doublereal vdist_(doublereal *, doublereal *); extern integer rtrim_(char *, ftnlen); extern logical failed_(void); doublereal lt; extern doublereal clight_(void); integer bcentr; extern /* Subroutine */ int spkgeo_(integer *, doublereal *, char *, integer *, doublereal *, doublereal *, ftnlen), sigerr_(char *, ftnlen), chkout_(char *, ftnlen), setmsg_(char *, ftnlen); extern logical return_(void); /* $ Abstract */ /* This routine computes the transmit (or receive) time */ /* of a signal at a specified target, given the receive */ /* (or transmit) time at a specified observer. The elapsed */ /* time between transmit and receive is also returned. */ /* $ 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 */ /* None. */ /* $ Keywords */ /* SPK */ /* $ Declarations */ /* $ Brief_I/O */ /* VARIABLE I/O DESCRIPTION */ /* -------- --- -------------------------------------------------- */ /* ETOBS I Epoch of a signal at some observer */ /* OBS I NAIF-id of some observer */ /* DIR I Direction the signal travels ( '->' or '<-' ) */ /* TARG I NAIF-id of the target object */ /* ETTARG O Epoch of the signal at the target */ /* ELAPSD O Time between transmit and receipt of the signal */ /* $ Detailed_Input */ /* ETOBS is an epoch expressed in ephemeris second (TDB) */ /* past the epoch of the J2000 reference system. */ /* This is the time at which an electromagnetic */ /* signal is "at" the observer. */ /* OBS is the NAIF-id of some observer. */ /* DIR is the direction the signal travels. The */ /* acceptable values are '->' and '<-'. When */ /* you read the calling sequence from left to */ /* right, the "arrow" given by DIR indicates */ /* which way the electromagnetic signal is travelling. */ /* If the argument list reads as below, */ /* ..., OBS, '->', TARG, ... */ /* the signal is travelling from the observer to the */ /* target. */ /* If the argument reads as */ /* ..., OBS, '<-', TARG */ /* the signal is travelling from the target to */ /* the observer. */ /* TARG is the NAIF-id of the target. */ /* $ Detailed_Output */ /* ETTARG is the epoch expressed in ephemeris seconds (TDB) */ /* past the epoch of the J2000 reference system */ /* at which the electromagnetic signal is "at" the */ /* target body. */ /* Note ETTARG is computed using only Newtonian */ /* assumptions about the propagation of light. */ /* ELAPSD is the number of ephemeris seconds (TDB) between */ /* transmission and receipt of the signal. */ /* ELAPSD = DABS( ETOBS - ETTARG ) */ /* $ Parameters */ /* None. */ /* $ Files */ /* None. */ /* $ Exceptions */ /* 1) If DIR is not one of '->' or '<-' the error */ /* 'SPICE(BADDIRECTION)' will be signalled. In this case */ /* ETTARG and ELAPSD will not be altered from their */ /* input values. */ /* 2) If insufficient ephemeris information is available to */ /* compute the outputs ETTARG and ELAPSD, or if observer */ /* or target is not recognized, the problems is diagnosed */ /* by a routine in the call tree of this routine. */ /* In this case, the value of ETTARG will be set to ETOBS */ /* and ELAPSD will be set to zero. */ /* $ Particulars */ /* Suppose a radio signal travels between two solar system */ /* objects. Given an ephemeris for the two objects, which way */ /* the signal is travelling, and the time when the signal is */ /* "at" at one of the objects (the observer OBS), this routine */ /* determines when the signal is "at" the other object (the */ /* target TARG). It also returns the elapsed time between */ /* transmission and receipt of the signal. */ /* $ Examples */ /* Example 1. */ /* ---------- */ /* Suppose a signal is transmitted at time ET from the Goldstone */ /* tracking site (id-code 399001) to a spacecraft whose id-code */ /* is -77. */ /* signal travelling to spacecraft */ /* * -._.-._.-._.-._.-._.-._.-._.-._.-> * */ /* Goldstone (OBS=399001) Spacecraft (TARG = -77) */ /* at epoch ETOBS(given) at epoch ETTARG(unknown) */ /* Assuming that all of the required SPICE kernels have been */ /* loaded, the code fragment below shows how to compute the */ /* time (ARRIVE) at which the signal arrives at the spacecraft */ /* and how long (HOWLNG) it took the signal to reach the spacecraft. */ /* (Note that we display the arrival time as the number of seconds */ /* past J2000.) */ /* OBS = 399001 */ /* TARG = -77 */ /* ETOBS = ET */ /* CALL LTIME ( ETOBS, OBS, '->', TARG, ARRIVE, HOWLNG ) */ /* CALL ETCAL */ /* WRITE (*,*) 'The signal arrived at time: ', ARRIVE */ /* WRITE (*,*) 'It took ', HOWLNG, ' seconds to get there.' */ /* Example 2. */ /* ---------- */ /* Suppose a signal is received at the Goldstone tracking sight */ /* at epoch ET from the spacecraft of the previous example. */ /* signal sent from spacecraft */ /* * <-._.-._.-._.-._.-._.-._.-._.-._.- * */ /* Goldstone (OBS=399001) Spacecraft (TARG = -77) */ /* at epoch ETOBS(given) at epoch ETTARG(unknown) */ /* Again assuming that all the required kernels have been loaded */ /* the code fragment below computes the epoch at which the */ /* signal was transmitted from the spacecraft. */ /* OBS = 399001 */ /* TARG = -77 */ /* ETOBS = ET */ /* CALL LTIME ( ETOBS, OBS, '<-', TARG, SENT, HOWLNG ) */ /* CALL ETCAL */ /* WRITE (*,*) 'The signal was transmitted at: ', SENT */ /* WRITE (*,*) 'It took ', HOWLNG, ' seconds to get here.' */ /* EXAMPLE 3 */ /* --------- */ /* Suppose there is a transponder on board the spacecraft of */ /* the previous examples that transmits a signal back to the */ /* sender exactly 1 microsecond after a signal arrives at */ /* the spacecraft. If we send a signal from Goldstone */ /* to the spacecraft and wait to receive it at Canberra. */ /* What will be the epoch at which the return signal arrives */ /* in Canberra? ( The id-code for Canberra is 399002 ). */ /* Again, assuming we've loaded all the necessary kernels, */ /* the fragment below will give us the answer. */ /* GSTONE = 399001 */ /* SC = -77 */ /* CANBER = 399002 */ /* ETGOLD = ET */ /* CALL LTIME ( ETGOLD, GSTONE, '->', SC, SCGET, LT1 ) */ /* Account for the microsecond delay between receipt and transmit */ /* SCSEND = SCGET + 0.000001 */ /* CALL LTIME ( SCSEND, SC, '->', CANBER, ETCANB, LT2 ) */ /* RNDTRP = ETCANB - ETGOLD */ /* WRITE (*,*) 'The signal arrives in Canberra at: ', ETCANB */ /* WRITE (*,*) 'Round trip time for the signal was: ', RNDTRP */ /* $ Restrictions */ /* None. */ /* $ Author_and_Institution */ /* W.L. Taber (JPL) */ /* $ Literature_References */ /* None. */ /* $ Version */ /* - SPICELIB Version 1.1.2, 22-SEP-2004 (EDW) */ /* Placed Copyright after Abstract. */ /* - SPICELIB Version 1.1.1, 18-NOV-1996 (WLT) */ /* Errors in the examples section were corrected. */ /* - SPICELIB Version 1.1.0, 10-JUL-1996 (WLT) */ /* Added Copyright Notice to the header. */ /* - SPICELIB Version 1.0.0, 10-NOV-1995 (WLT) */ /* -& */ /* $ Index_Entries */ /* Compute uplink and downlink light time */ /* -& */ /* SPICELIB Functions */ /* Local Variables */ if (return_()) { return 0; } chkin_("LTIME", (ftnlen)5); /* First perform the obvious error check. */ if (s_cmp(dir, "->", (ftnlen)2, (ftnlen)2) != 0 && s_cmp(dir, "<-", ( ftnlen)2, (ftnlen)2) != 0) { setmsg_("The direction specifier for the signal was '#' it must be " "either '->' or '<-'. ", (ftnlen)80); r__ = rtrim_(dir, (ftnlen)2); errch_("#", dir, (ftnlen)1, r__); sigerr_("SPICE(BADDIRECTION)", (ftnlen)19); chkout_("LTIME", (ftnlen)5); return 0; } /* We need two constants, the speed of light and the id-code */ /* for the solar system barycenter. */ c__ = clight_(); bcentr = 0; myet = *etobs; /* First get the barycenter relative states of the observer */ /* and target. */ spkgeo_(obs, &myet, "J2000", &bcentr, sobs, <, (ftnlen)5); spkgeo_(targ, &myet, "J2000", &bcentr, starg, <, (ftnlen)5); *elapsd = vdist_(sobs, starg) / c__; /* The rest is straight forward. We either add the elapsed */ /* time to get the next state or subtract the elapsed time. */ /* This depends on whether we are receiving or transmitting */ /* at the observer. */ /* Note that 3 iterations as performed here gives us */ /* Newtonian accuracy to the nanosecond level for all */ /* known objects in the solar system. The ephemeris */ /* is certain to be much worse than this. */ if (s_cmp(dir, "->", (ftnlen)2, (ftnlen)2) == 0) { *ettarg = myet + *elapsd; spkgeo_(targ, ettarg, "J2000", &bcentr, starg, <, (ftnlen)5); *elapsd = vdist_(sobs, starg) / c__; *ettarg = myet + *elapsd; spkgeo_(targ, ettarg, "J2000", &bcentr, starg, <, (ftnlen)5); *elapsd = vdist_(sobs, starg) / c__; *ettarg = myet + *elapsd; spkgeo_(targ, ettarg, "J2000", &bcentr, starg, <, (ftnlen)5); *elapsd = vdist_(sobs, starg) / c__; *ettarg = myet + *elapsd; } else { *ettarg = myet - *elapsd; spkgeo_(targ, ettarg, "J2000", &bcentr, starg, <, (ftnlen)5); *elapsd = vdist_(sobs, starg) / c__; *ettarg = myet - *elapsd; spkgeo_(targ, ettarg, "J2000", &bcentr, starg, <, (ftnlen)5); *elapsd = vdist_(sobs, starg) / c__; *ettarg = myet - *elapsd; spkgeo_(targ, ettarg, "J2000", &bcentr, starg, <, (ftnlen)5); *elapsd = vdist_(sobs, starg) / c__; *ettarg = myet - *elapsd; } if (failed_()) { *ettarg = myet; *elapsd = 0.; } chkout_("LTIME", (ftnlen)5); return 0; } /* ltime_ */
/* $Procedure VREL ( Vector relative difference, 3 dimensions ) */ doublereal vrel_(doublereal *v1, doublereal *v2) { /* System generated locals */ doublereal ret_val, d__1, d__2; /* Local variables */ extern doublereal vdist_(doublereal *, doublereal *), vnorm_(doublereal *) ; doublereal denorm, nunorm; /* $ Abstract */ /* Return the relative difference between two 3-dimensional vectors. */ /* $ 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 */ /* None. */ /* $ Keywords */ /* MATH */ /* VECTOR */ /* $ Declarations */ /* $ Brief_I/O */ /* Variable I/O Description */ /* -------- --- -------------------------------------------------- */ /* V1,V2 I Input vectors. */ /* $ Detailed_Input */ /* V1, V2 are two 3-dimensional vectors for which the */ /* relative difference is to be computed. */ /* $ Detailed_Output */ /* VREL is the relative difference between V1 and V2. */ /* It is defined as: */ /* || V1 - V2 || */ /* VREL = ---------------------- */ /* MAX ( ||V1||, ||V2|| ) */ /* where || X || indicates the Euclidean norm of */ /* the vector X. */ /* VREL assumes values in the range [0,2]. If both */ /* V1 and V2 are zero vectors then VREL is defined */ /* to be zero. */ /* $ Parameters */ /* None. */ /* $ Exceptions */ /* Error free. */ /* If both V1 and V2 are zero vectors then VREL is defined */ /* to be zero. */ /* $ Files */ /* None. */ /* $ Particulars */ /* This function computes the relative difference between two */ /* 3-dimensional vectors as defined above. */ /* The function VRELG may be used to find the relative difference */ /* for two vectors of general dimension. */ /* $ Examples */ /* This example code fragment computes the relative difference */ /* between the geometric and light time corrected state of Io */ /* with respect to Voyager 2 at a given UTC time. */ /* C */ /* C The NAIF integer code for Io is 501 and the code for */ /* C Voyager 2 is -32. */ /* C */ /* INTEGER IO */ /* PARAMETER ( IO = 501 ) */ /* INTEGER VG2 */ /* PARAMETER ( VG2 = -32 ) */ /* C */ /* C Spicelib function */ /* C */ /* DOUBLE PRECISION VREL */ /* C */ /* C Local variables */ /* C */ /* DOUBLE PRECISION STATE ( 6 ) */ /* DOUBLE PRECISION POS1 ( 3 ) */ /* DOUBLE PRECISION POS2 ( 3 ) */ /* DOUBLE PRECISION DIFF */ /* DOUBLE PRECISION LT */ /* DOUBLE PRECISION ET */ /* INTEGER HANDLE */ /* CHARACTER*(20) UTC */ /* DATA UTC / '1979 JUN 25 12:00:00' / */ /* C */ /* C Load the sample SPK ephemeris file. */ /* C */ /* CALL SPKLEF ( 'VG2_JUP.BSP', HANDLE ) */ /* C */ /* C Convert the UTC time string to ephemeris time. */ /* C */ /* CALL UTC2ET ( UTC, ET ) */ /* C */ /* C First calculate the geometric state and then the light */ /* C time corrected state. */ /* C */ /* CALL SPKEZ ( IO, ET, 'J2000', 'NONE', VG2, STATE, LT ) */ /* CALL VEQU ( STATE, POS1 ) */ /* CALL SPKEZ ( IO, ET, 'J2000', 'LT', VG2, STATE, LT ) */ /* CALL VEQU ( STATE, POS2 ) */ /* C */ /* C Call VREL to find the relative difference between the */ /* C two states. */ /* C */ /* DIFF = VREL ( POS1, POS2 ) */ /* . */ /* . */ /* . */ /* $ Restrictions */ /* None. */ /* $ Literature_References */ /* None. */ /* $ Author_and_Institution */ /* J.M. Lynch (JPL) */ /* $ Version */ /* - SPICELIB Version 1.0.0, 15-JUN-1992 (JML) */ /* -& */ /* $ Index_Entries */ /* relative difference of 3-dimensional vectors */ /* -& */ /* SPICELIB functions */ /* Local variables */ /* If the numerator is zero then set VREL equal to zero. Otherwise, */ /* perform the rest of the calculation. */ /* This handles the case where both vectors are zero vectors since */ /* the distance between them will be zero. */ nunorm = vdist_(v1, v2); if (nunorm == 0.) { ret_val = 0.; } else { /* Computing MAX */ d__1 = vnorm_(v1), d__2 = vnorm_(v2); denorm = max(d__1,d__2); ret_val = nunorm / denorm; } return ret_val; } /* vrel_ */
/* $Procedure SUBPT ( Sub-observer point ) */ /* Subroutine */ int subpt_(char *method, char *target, doublereal *et, char * abcorr, char *obsrvr, doublereal *spoint, doublereal *alt, ftnlen method_len, ftnlen target_len, ftnlen abcorr_len, ftnlen obsrvr_len) { /* Initialized data */ static doublereal origin[3] = { 0.,0.,0. }; doublereal radii[3]; extern /* Subroutine */ int chkin_(char *, ftnlen), errch_(char *, char *, ftnlen, ftnlen); logical found; extern doublereal vdist_(doublereal *, doublereal *); extern /* Subroutine */ int spkez_(integer *, doublereal *, char *, char * , integer *, doublereal *, doublereal *, ftnlen, ftnlen); extern logical eqstr_(char *, char *, ftnlen, ftnlen); extern /* Subroutine */ int bods2c_(char *, integer *, logical *, ftnlen); integer obscde; doublereal lt; extern /* Subroutine */ int bodvcd_(integer *, char *, integer *, integer *, doublereal *, ftnlen); integer frcode; extern /* Subroutine */ int cidfrm_(integer *, integer *, char *, logical *, ftnlen); integer nradii; char frname[80]; integer trgcde; extern /* Subroutine */ int nearpt_(doublereal *, doublereal *, doublereal *, doublereal *, doublereal *, doublereal *), sigerr_( char *, ftnlen), chkout_(char *, ftnlen), setmsg_(char *, ftnlen); doublereal tstate[6]; extern logical return_(void); extern /* Subroutine */ int vminus_(doublereal *, doublereal *), surfpt_( doublereal *, doublereal *, doublereal *, doublereal *, doublereal *, doublereal *, logical *); doublereal pos[3]; /* $ Abstract */ /* Deprecated: This routine has been superseded by the SPICELIB */ /* routine SUBPNT. This routine is supported for purposes of */ /* backward compatibility only. */ /* Compute the rectangular coordinates of the sub-observer point on */ /* a target body at a particular epoch, optionally corrected for */ /* planetary (light time) and stellar aberration. Return these */ /* coordinates expressed in the body-fixed frame associated with the */ /* target body. Also, return the observer's altitude above the */ /* target body. */ /* $ Disclaimer */ /* THIS SOFTWARE AND ANY RELATED MATERIALS WERE CREATED BY THE */ /* CALIFORNIA INSTITUTE OF TECHNOLOGY (CALTECH) UNDER A U.S. */ /* GOVERNMENT CONTRACT WITH THE NATIONAL AERONAUTICS AND SPACE */ /* ADMINISTRATION (NASA). THE SOFTWARE IS TECHNOLOGY AND SOFTWARE */ /* PUBLICLY AVAILABLE UNDER U.S. EXPORT LAWS AND IS PROVIDED "AS-IS" */ /* TO THE RECIPIENT WITHOUT WARRANTY OF ANY KIND, INCLUDING ANY */ /* WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A */ /* PARTICULAR USE OR PURPOSE (AS SET FORTH IN UNITED STATES UCC */ /* SECTIONS 2312-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE */ /* SOFTWARE AND RELATED MATERIALS, HOWEVER USED. */ /* IN NO EVENT SHALL CALTECH, ITS JET PROPULSION LABORATORY, OR NASA */ /* BE LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING, BUT NOT */ /* LIMITED TO, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND, */ /* INCLUDING ECONOMIC DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS, */ /* REGARDLESS OF WHETHER CALTECH, JPL, OR NASA BE ADVISED, HAVE */ /* REASON TO KNOW, OR, IN FACT, SHALL KNOW OF THE POSSIBILITY. */ /* RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF */ /* THE SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY */ /* CALTECH AND NASA FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE */ /* ACTIONS OF RECIPIENT IN THE USE OF THE SOFTWARE. */ /* $ Required_Reading */ /* FRAMES */ /* PCK */ /* SPK */ /* TIME */ /* $ Keywords */ /* GEOMETRY */ /* $ Declarations */ /* $ Brief_I/O */ /* Variable I/O Description */ /* -------- --- -------------------------------------------------- */ /* METHOD I Computation method. */ /* TARGET I Name of target body. */ /* ET I Epoch in ephemeris seconds past J2000 TDB. */ /* ABCORR I Aberration correction. */ /* OBSRVR I Name of observing body. */ /* SPOINT O Sub-observer point on the target body. */ /* ALT O Altitude of the observer above the target body. */ /* $ Detailed_Input */ /* METHOD is a short string specifying the computation method */ /* to be used. The choices are: */ /* 'Near point' The sub-observer point is */ /* defined as the nearest point on */ /* the target relative to the */ /* observer. */ /* 'Intercept' The sub-observer point is */ /* defined as the target surface */ /* intercept of the line */ /* containing the observer and the */ /* target's center. */ /* In both cases, the intercept computation treats the */ /* surface of the target body as a triaxial ellipsoid. */ /* The ellipsoid's radii must be available in the kernel */ /* pool. */ /* Neither case nor white space are significant in */ /* METHOD. For example, the string ' NEARPOINT' is */ /* valid. */ /* TARGET is the name of a target body. Optionally, you may */ /* supply the integer ID code for the object as */ /* an integer string. For example both 'MOON' and */ /* '301' are legitimate strings that indicate the */ /* moon is the target body. This routine assumes */ /* that this body is modeled by a tri-axial ellipsoid, */ /* and that a PCK file containing its radii has been */ /* loaded into the kernel pool via FURNSH. */ /* ET is the epoch in ephemeris seconds past J2000 at which */ /* the sub-observer point on the target body is to be */ /* computed. */ /* ABCORR indicates the aberration corrections to be applied */ /* when computing the observer-target state. ABCORR */ /* may be any of the following. */ /* 'NONE' Apply no correction. Return the */ /* geometric sub-observer point on the */ /* target body. */ /* 'LT' Correct for planetary (light time) */ /* aberration. Both the state and rotation */ /* of the target body are corrected for */ /* light time. */ /* 'LT+S' Correct for planetary (light time) and */ /* stellar aberrations. Both the state and */ /* rotation of the target body are */ /* corrected for light time. */ /* 'CN' Converged Newtonian light time */ /* corrections. This is the same as LT */ /* corrections but with further iterations */ /* to a converged Newtonian light time */ /* solution. Given that relativistic */ /* effects may be as large as the higher */ /* accuracy achieved by this computation, */ /* this is correction is seldom worth the */ /* additional computations required unless */ /* the user incorporates additional */ /* relativistic corrections. Both the */ /* state and rotation of the target body */ /* are corrected for light time. */ /* 'CN+S' Converged Newtonian light time */ /* corrections and stellar aberration. */ /* Both the state and rotation of the */ /* target body are corrected for light */ /* time. */ /* OBSRVR is the name of the observing body. This is typically */ /* a spacecraft, the earth, or a surface point on the */ /* earth. Optionally, you may supply the ID code of */ /* the object as an integer string. For example, both */ /* 'EARTH' and '399' are legitimate strings to supply */ /* to indicate the observer is Earth. */ /* $ Detailed_Output */ /* SPOINT is the sub-observer point on the target body at ET */ /* expressed relative to the body-fixed frame of the */ /* target body. */ /* The sub-observer point is defined either as the point */ /* on the target body that is closest to the observer, */ /* or the target surface intercept of the line from the */ /* observer to the target's center; the input argument */ /* METHOD selects the definition to be used. */ /* The body-fixed frame, which is time-dependent, is */ /* evaluated at ET if ABCORR is 'NONE'; otherwise the */ /* frame is evaluated at ET-LT, where LT is the one-way */ /* light time from target to observer. */ /* The state of the target body is corrected for */ /* aberration as specified by ABCORR; the corrected */ /* state is used in the geometric computation. As */ /* indicated above, the rotation of the target is */ /* retarded by one-way light time if ABCORR specifies */ /* that light time correction is to be done. */ /* ALT is the "altitude" of the observer above the target */ /* body. When METHOD specifies a "near point" */ /* computation, ALT is truly altitude in the standard */ /* geometric sense: the length of a segment dropped from */ /* the observer to the target's surface, such that the */ /* segment is perpendicular to the surface at the */ /* contact point SPOINT. */ /* When METHOD specifies an "intercept" computation, ALT */ /* is still the length of the segment from the observer */ /* to the surface point SPOINT, but this segment in */ /* general is not perpendicular to the surface. */ /* $ Parameters */ /* None. */ /* $ Exceptions */ /* If any of the listed errors occur, the output arguments are */ /* left unchanged. */ /* 1) If the input argument METHOD is not recognized, the error */ /* SPICE(DUBIOUSMETHOD) is signaled. */ /* 2) If either of the input body names TARGET or OBSRVR cannot be */ /* mapped to NAIF integer codes, the error SPICE(IDCODENOTFOUND) */ /* is signaled. */ /* 3) If OBSRVR and TARGET map to the same NAIF integer ID codes, the */ /* error SPICE(BODIESNOTDISTINCT) is signaled. */ /* 4) If frame definition data enabling the evaluation of the state */ /* of the target relative to the observer in target body-fixed */ /* coordinates have not been loaded prior to calling SUBPT, the */ /* error will be diagnosed and signaled by a routine in the call */ /* tree of this routine. */ /* 5) If the specified aberration correction is not recognized, the */ /* error will be diagnosed and signaled by a routine in the call */ /* tree of this routine. */ /* 6) If insufficient ephemeris data have been loaded prior to */ /* calling SUBPT, the error will be diagnosed and signaled by a */ /* routine in the call tree of this routine. */ /* 7) If the triaxial radii of the target body have not been loaded */ /* into the kernel pool prior to calling SUBPT, the error will be */ /* diagnosed and signaled by a routine in the call tree of this */ /* routine. */ /* 8) The target must be an extended body: if any of the radii of */ /* the target body are non-positive, the error will be diagnosed */ /* and signaled by routines in the call tree of this routine. */ /* 9) If PCK data supplying a rotation model for the target body */ /* have not been loaded prior to calling SUBPT, the error will be */ /* diagnosed and signaled by a routine in the call tree of this */ /* routine. */ /* $ Files */ /* Appropriate SPK, PCK, and frame kernels must be loaded */ /* prior by the calling program before this routine is called. */ /* The following data are required: */ /* - SPK data: ephemeris data for target and observer must be */ /* loaded. If aberration corrections are used, the states of */ /* target and observer relative to the solar system barycenter */ /* must be calculable from the available ephemeris data. */ /* Typically ephemeris data are made available by loading one */ /* or more SPK files via FURNSH. */ /* - PCK data: triaxial radii for the target body must be loaded */ /* into the kernel pool. Typically this is done by loading a */ /* text PCK file via FURNSH. */ /* - Further PCK data: rotation data for the target body must */ /* be loaded. These may be provided in a text or binary PCK */ /* file. Either type of file may be loaded via FURNSH. */ /* - Frame data: if a frame definition is required to convert */ /* the observer and target states to the body-fixed frame of */ /* the target, that definition must be available in the kernel */ /* pool. Typically the definition is supplied by loading a */ /* frame kernel via FURNSH. */ /* In all cases, kernel data are normally loaded once per program */ /* run, NOT every time this routine is called. */ /* $ Particulars */ /* SUBPT computes the sub-observer point on a target body. */ /* (The sub-observer point is commonly called the sub-spacecraft */ /* point when the observer is a spacecraft.) SUBPT also */ /* determines the altitude of the observer above the target body. */ /* There are two different popular ways to define the sub-observer */ /* point: "nearest point on target to observer" or "target surface */ /* intercept of line containing observer and target." These */ /* coincide when the target is spherical and generally are distinct */ /* otherwise. */ /* When comparing sub-point computations with results from sources */ /* other than SPICE, it's essential to make sure the same geometric */ /* definitions are used. */ /* $ Examples */ /* The numerical results shown for this example may differ across */ /* platforms. The results depend on the SPICE kernels used as */ /* input, the compiler and supporting libraries, and the machine */ /* specific arithmetic implementation. */ /* In the following example program, the file */ /* spk_m_031103-040201_030502.bsp */ /* is a binary SPK file containing data for Mars Global Surveyor, */ /* Mars, and the Sun for a time interval bracketing the date */ /* 2004 JAN 1 12:00:00 UTC. */ /* pck00007.tpc is a planetary constants kernel file containing */ /* radii and rotation model constants. naif0007.tls is a */ /* leapseconds kernel. */ /* Find the sub-observer point of the Mars Global Surveyor (MGS) */ /* spacecraft on Mars for a specified time. Perform the computation */ /* twice, using both the "intercept" and "near point" options. */ /* IMPLICIT NONE */ /* CHARACTER*25 METHOD ( 2 ) */ /* INTEGER I */ /* DOUBLE PRECISION ALT */ /* DOUBLE PRECISION DPR */ /* DOUBLE PRECISION ET */ /* DOUBLE PRECISION LAT */ /* DOUBLE PRECISION LON */ /* DOUBLE PRECISION RADIUS */ /* DOUBLE PRECISION SPOINT ( 3 ) */ /* DATA METHOD / 'Intercept', 'Near point' / */ /* C */ /* C Load kernel files. */ /* C */ /* CALL FURNSH ( 'naif0007.tls' ) */ /* CALL FURNSH ( 'pck00007.tpc' ) */ /* CALL FURNSH ( 'spk_m_031103-040201_030502.bsp' ) */ /* C */ /* C Convert the UTC request time to ET (seconds past */ /* C J2000, TDB). */ /* C */ /* CALL STR2ET ( '2004 JAN 1 12:00:00', ET ) */ /* C */ /* C Compute sub-spacecraft point using light time and stellar */ /* C aberration corrections. Use the "target surface intercept" */ /* C definition of sub-spacecraft point on the first loop */ /* C iteration, and use the "near point" definition on the */ /* C second. */ /* C */ /* DO I = 1, 2 */ /* CALL SUBPT ( METHOD(I), */ /* . 'MARS', ET, 'LT+S', */ /* . 'MGS', SPOINT, ALT ) */ /* C */ /* C Convert rectangular coordinates to planetocentric */ /* C latitude and longitude. Convert radians to degrees. */ /* C */ /* CALL RECLAT ( SPOINT, RADIUS, LON, LAT ) */ /* LON = LON * DPR () */ /* LAT = LAT * DPR () */ /* C */ /* C Write the results. */ /* C */ /* WRITE (*,*) ' ' */ /* WRITE (*,*) 'Computation method: ', METHOD(I) */ /* WRITE (*,*) ' ' */ /* WRITE (*,*) ' Radius (km) = ', RADIUS */ /* WRITE (*,*) ' Planetocentric Latitude (deg) = ', LAT */ /* WRITE (*,*) ' Planetocentric Longitude (deg) = ', LON */ /* WRITE (*,*) ' Altitude (km) = ', ALT */ /* WRITE (*,*) ' ' */ /* END DO */ /* END */ /* When this program is executed, the output will be: */ /* Computation method: Intercept */ /* Radius (km) = 3387.97077 */ /* Planetocentric Latitude (deg) = -39.7022724 */ /* Planetocentric Longitude (deg) = -159.226663 */ /* Altitude (km) = 373.173506 */ /* Computation method: Near point */ /* Radius (km) = 3387.9845 */ /* Planetocentric Latitude (deg) = -39.6659329 */ /* Planetocentric Longitude (deg) = -159.226663 */ /* Altitude (km) = 373.166636 */ /* $ Restrictions */ /* None. */ /* $ Literature_References */ /* None. */ /* $ Author_and_Institution */ /* C.H. Acton (JPL) */ /* N.J. Bachman (JPL) */ /* J.E. McLean (JPL) */ /* $ Version */ /* - SPICELIB Version 1.2.3, 18-MAY-2010 (BVS) */ /* Index line now states that this routine is deprecated. */ /* - SPICELIB Version 1.2.2, 17-MAR-2009 (EDW) */ /* Typo correction in Required_Reading, changed */ /* FRAME to FRAMES. */ /* - SPICELIB Version 1.2.1, 07-FEB-2008 (NJB) */ /* Abstract now states that this routine is deprecated. */ /* - SPICELIB Version 1.2.0, 24-OCT-2005 (NJB) */ /* Replaced call to BODVAR with call to BODVCD. */ /* - SPICELIB Version 1.1.0, 21-JUL-2004 (EDW) */ /* Changed BODN2C call to BODS2C giving the routine */ /* the capability to accept string representations of */ /* interger IDs for TARGET and OBSRVR. */ /* - SPICELIB Version 1.0.1, 27-JUL-2003 (NJB) (CHA) */ /* Various header corrections were made. The example program */ /* was upgraded to use real kernels, and the program's output is */ /* shown. */ /* - SPICELIB Version 1.0.0, 03-SEP-1999 (NJB) (JEM) */ /* -& */ /* $ Index_Entries */ /* DEPRECATED sub-observer point */ /* -& */ /* SPICELIB functions */ /* Local parameters */ /* Local variables */ /* Saved variables */ /* Initial values */ /* Standard SPICE error handling. */ if (return_()) { return 0; } else { chkin_("SUBPT", (ftnlen)5); } /* Obtain integer codes for the target and observer. */ /* Target... */ bods2c_(target, &trgcde, &found, target_len); if (! found) { setmsg_("The target, '#', is not a recognized name for an ephemeris " "object. The cause of this problem may be that you need an up" "dated version of the SPICE Toolkit. ", (ftnlen)155); errch_("#", target, (ftnlen)1, target_len); sigerr_("SPICE(IDCODENOTFOUND)", (ftnlen)21); chkout_("SUBPT", (ftnlen)5); return 0; } /* ...observer. */ bods2c_(obsrvr, &obscde, &found, obsrvr_len); if (! found) { setmsg_("The observer, '#', is not a recognized name for an ephemeri" "s object. The cause of this problem may be that you need an " "updated version of the SPICE Toolkit. ", (ftnlen)157); errch_("#", obsrvr, (ftnlen)1, obsrvr_len); sigerr_("SPICE(IDCODENOTFOUND)", (ftnlen)21); chkout_("SUBPT", (ftnlen)5); return 0; } /* Check the input body codes. If they are equal, signal */ /* an error. */ if (obscde == trgcde) { setmsg_("In computing the sub-observer point, the observing body and" " target body are the same. Both are #.", (ftnlen)97); errch_("#", obsrvr, (ftnlen)1, obsrvr_len); sigerr_("SPICE(BODIESNOTDISTINCT)", (ftnlen)24); chkout_("SUBPT", (ftnlen)5); return 0; } /* Get the radii of the target body from the kernel pool. */ bodvcd_(&trgcde, "RADII", &c__3, &nradii, radii, (ftnlen)5); /* Find the name of the body-fixed frame associated with the */ /* target body. We'll want the state of the target relative to */ /* the observer in this body-fixed frame. */ cidfrm_(&trgcde, &frcode, frname, &found, (ftnlen)80); if (! found) { setmsg_("No body-fixed frame is associated with target body #; a fra" "me kernel must be loaded to make this association. Consult " "the FRAMES Required Reading for details.", (ftnlen)159); errch_("#", target, (ftnlen)1, target_len); sigerr_("SPICE(NOFRAME)", (ftnlen)14); chkout_("SUBPT", (ftnlen)5); return 0; } /* Determine the position of the observer in target */ /* body-fixed coordinates. */ /* - Call SPKEZR to compute the position of the target */ /* body as seen from the observing body and the light time */ /* (LT) between them. SPKEZR returns a state which is */ /* the position and velocity, but we'll only use the position */ /* which is the first three elements. We request that the */ /* coordinates of POS be returned relative to the body fixed */ /* reference frame associated with the target body, using */ /* aberration corrections specified by the input argument */ /* ABCORR. */ /* - Call VMINUS to negate the direction of the vector (POS) */ /* so it will be the position of the observer as seen from */ /* the target body in target body fixed coordinates. */ /* Note that this result is not the same as the result of */ /* calling SPKEZR with the target and observer switched. We */ /* computed the vector FROM the observer TO the target in */ /* order to get the proper light time and stellar aberration */ /* corrections (if requested). Now we need the inverse of */ /* that corrected vector in order to compute the sub-point. */ spkez_(&trgcde, et, frname, abcorr, &obscde, tstate, <, (ftnlen)80, abcorr_len); /* Negate the target's state to obtain the position of the observer */ /* relative to the target. */ vminus_(tstate, pos); /* Find the sub-point and "altitude" (distance from observer to */ /* sub-point) using the specified geometric definition. */ if (eqstr_(method, "Near point", method_len, (ftnlen)10)) { /* Locate the nearest point to the observer on the target. */ nearpt_(pos, radii, &radii[1], &radii[2], spoint, alt); } else if (eqstr_(method, "Intercept", method_len, (ftnlen)9)) { surfpt_(origin, pos, radii, &radii[1], &radii[2], spoint, &found); /* Since the line in question passes through the center of the */ /* target, there will always be a surface intercept. So we should */ /* never have FOUND = .FALSE. */ if (! found) { setmsg_("Call to SURFPT returned FOUND=FALSE even though vertex " "of ray is at target center. This indicates a bug. Please" " contact NAIF.", (ftnlen)125); sigerr_("SPICE(BUG)", (ftnlen)10); chkout_("SUBPT", (ftnlen)5); return 0; } /* SURFPT doesn't compute altitude, so do it here. */ *alt = vdist_(pos, spoint); } else { setmsg_("The computation method # was not recognized. Allowed values" " are \"Near point\" and \"Intercept.\"", (ftnlen)93); errch_("#", method, (ftnlen)1, method_len); sigerr_("SPICE(DUBIOUSMETHOD)", (ftnlen)20); chkout_("SUBPT", (ftnlen)5); return 0; } chkout_("SUBPT", (ftnlen)5); return 0; } /* subpt_ */