/* $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 ZZGFSSOB ( GF, state of sub-observer point ) */ /* Subroutine */ int zzgfssob_(char *method, integer *trgid, doublereal *et, char *fixref, char *abcorr, integer *obsid, doublereal *radii, doublereal *state, ftnlen method_len, ftnlen fixref_len, ftnlen abcorr_len) { /* Initialized data */ static logical first = TRUE_; static integer prvobs = 0; static integer prvtrg = 0; static char svobs[36] = " "; static char svtarg[36] = " "; /* System generated locals */ integer i__1; /* Builtin functions */ integer s_rnge(char *, integer, char *, integer); /* Local variables */ doublereal dalt[2]; logical near__, geom; extern /* Subroutine */ int vhat_(doublereal *, doublereal *), vscl_( doublereal *, doublereal *, doublereal *); extern doublereal vdot_(doublereal *, doublereal *); logical xmit; extern /* Subroutine */ int mxvg_(doublereal *, doublereal *, integer *, integer *, doublereal *); doublereal upos[3]; extern /* Subroutine */ int zzstelab_(logical *, doublereal *, doublereal *, doublereal *, doublereal *, doublereal *), zzcorsxf_(logical *, doublereal *, doublereal *, doublereal *); integer i__; extern /* Subroutine */ int zzprscor_(char *, logical *, ftnlen); doublereal t; extern /* Subroutine */ int vaddg_(doublereal *, doublereal *, integer *, doublereal *); doublereal scale; extern /* Subroutine */ int chkin_(char *, ftnlen), errch_(char *, char *, ftnlen, ftnlen); doublereal savel[3]; logical found; extern /* Subroutine */ int moved_(doublereal *, integer *, doublereal *), vsubg_(doublereal *, doublereal *, integer *, doublereal *); doublereal stemp[6]; extern logical eqstr_(char *, char *, ftnlen, ftnlen); doublereal xform[36] /* was [6][6] */; logical uselt; extern /* Subroutine */ int bodc2s_(integer *, char *, ftnlen); doublereal ssbtg0[6]; extern logical failed_(void); doublereal sa[3]; extern /* Subroutine */ int cleard_(integer *, doublereal *); doublereal lt; integer frcode; extern doublereal clight_(void); extern logical return_(void); doublereal corxfi[36] /* was [6][6] */, corxfm[36] /* was [6][6] */, fxosta[6], fxpsta[6], fxpvel[3], fxtsta[6], obspnt[6], obssta[ 12] /* was [6][2] */, obstrg[6], acc[3], pntsta[6], raysta[6], sastat[6], spoint[3], srfvec[3], ssbobs[6], ssbtrg[6], trgepc; integer center, clssid, frclss; logical attblk[6], usestl; extern /* Subroutine */ int setmsg_(char *, ftnlen); logical fnd; extern /* Subroutine */ int sigerr_(char *, ftnlen), chkout_(char *, ftnlen), namfrm_(char *, integer *, ftnlen), frinfo_(integer *, integer *, integer *, integer *, logical *), errint_(char *, integer *, ftnlen), spkgeo_(integer *, doublereal *, char *, integer *, doublereal *, doublereal *, ftnlen), vminug_( doublereal *, integer *, doublereal *), dnearp_(doublereal *, doublereal *, doublereal *, doublereal *, doublereal *, doublereal *, logical *), surfpv_(doublereal *, doublereal *, doublereal *, doublereal *, doublereal *, doublereal *, logical *) , subpnt_(char *, char *, doublereal *, char *, char *, char *, doublereal *, doublereal *, doublereal *, ftnlen, ftnlen, ftnlen, ftnlen, ftnlen), spkssb_(integer *, doublereal *, char *, doublereal *, ftnlen); doublereal dlt; extern /* Subroutine */ int sxform_(char *, char *, doublereal *, doublereal *, ftnlen, ftnlen), qderiv_(integer *, doublereal *, doublereal *, doublereal *, doublereal *), invstm_(doublereal *, doublereal *); /* $ Abstract */ /* SPICE private routine intended solely for the support of SPICE */ /* routines. Users should not call this routine directly due to the */ /* volatile nature of this routine. */ /* Return the state of a sub-observer point used to define */ /* coordinates referenced in a GF search. */ /* $ 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 */ /* GF */ /* SPK */ /* TIME */ /* NAIF_IDS */ /* FRAMES */ /* $ Keywords */ /* GEOMETRY */ /* PRIVATE */ /* SEARCH */ /* $ Declarations */ /* $ Abstract */ /* This file contains public, global parameter declarations */ /* for the SPICELIB Geometry Finder (GF) subsystem. */ /* $ 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 */ /* GF */ /* $ Keywords */ /* GEOMETRY */ /* ROOT */ /* $ Restrictions */ /* None. */ /* $ Author_and_Institution */ /* N.J. Bachman (JPL) */ /* L.E. Elson (JPL) */ /* E.D. Wright (JPL) */ /* $ Literature_References */ /* None. */ /* $ Version */ /* - SPICELIB Version 1.3.0, 01-OCT-2011 (NJB) */ /* Added NWILUM parameter. */ /* - SPICELIB Version 1.2.0, 14-SEP-2010 (EDW) */ /* Added NWPA parameter. */ /* - SPICELIB Version 1.1.0, 08-SEP-2009 (EDW) */ /* Added NWRR parameter. */ /* Added NWUDS parameter. */ /* - SPICELIB Version 1.0.0, 21-FEB-2009 (NJB) (LSE) (EDW) */ /* -& */ /* Root finding parameters: */ /* CNVTOL is the default convergence tolerance used by the */ /* high-level GF search API routines. This tolerance is */ /* used to terminate searches for binary state transitions: */ /* when the time at which a transition occurs is bracketed */ /* by two times that differ by no more than CNVTOL, the */ /* transition time is considered to have been found. */ /* Units are TDB seconds. */ /* NWMAX is the maximum number of windows allowed for user-defined */ /* workspace array. */ /* DOUBLE PRECISION WORK ( LBCELL : MW, NWMAX ) */ /* Currently no more than twelve windows are required; the three */ /* extra windows are spares. */ /* Callers of GFEVNT can include this file and use the parameter */ /* NWMAX to declare the second dimension of the workspace array */ /* if necessary. */ /* Callers of GFIDST should declare their workspace window */ /* count using NWDIST. */ /* Callers of GFSEP should declare their workspace window */ /* count using NWSEP. */ /* Callers of GFRR should declare their workspace window */ /* count using NWRR. */ /* Callers of GFUDS should declare their workspace window */ /* count using NWUDS. */ /* Callers of GFPA should declare their workspace window */ /* count using NWPA. */ /* Callers of GFILUM should declare their workspace window */ /* count using NWILUM. */ /* ADDWIN is a parameter used to expand each interval of the search */ /* (confinement) window by a small amount at both ends in order to */ /* accommodate searches using equality constraints. The loaded */ /* kernel files must accommodate these expanded time intervals. */ /* FRMNLN is a string length for frame names. */ /* NVRMAX is the maximum number of vertices if FOV type is "POLYGON" */ /* FOVTLN -- maximum length for FOV string. */ /* Specify the character strings that are allowed in the */ /* specification of field of view shapes. */ /* Character strings that are allowed in the */ /* specification of occultation types: */ /* Occultation target shape specifications: */ /* Specify the number of supported occultation types and occultation */ /* type string length: */ /* Instrument field-of-view (FOV) parameters */ /* Maximum number of FOV boundary vectors: */ /* FOV shape parameters: */ /* circle */ /* ellipse */ /* polygon */ /* rectangle */ /* End of file gf.inc. */ /* $ Abstract */ /* SPICE private include file intended solely for the support of */ /* SPICE routines. Users should not include this routine in their */ /* source code due to the volatile nature of this file. */ /* This file contains private, global parameter declarations */ /* for the SPICELIB Geometry Finder (GF) subsystem. */ /* $ 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 */ /* GF */ /* $ Keywords */ /* GEOMETRY */ /* ROOT */ /* $ Restrictions */ /* None. */ /* $ Author_and_Institution */ /* N.J. Bachman (JPL) */ /* E.D. Wright (JPL) */ /* $ Literature_References */ /* None. */ /* $ Version */ /* - SPICELIB Version 1.0.0, 17-FEB-2009 (NJB) (EDW) */ /* -& */ /* The set of supported coordinate systems */ /* System Coordinates */ /* ---------- ----------- */ /* Rectangular X, Y, Z */ /* Latitudinal Radius, Longitude, Latitude */ /* Spherical Radius, Colatitude, Longitude */ /* RA/Dec Range, Right Ascension, Declination */ /* Cylindrical Radius, Longitude, Z */ /* Geodetic Longitude, Latitude, Altitude */ /* Planetographic Longitude, Latitude, Altitude */ /* Below we declare parameters for naming coordinate systems. */ /* User inputs naming coordinate systems must match these */ /* when compared using EQSTR. That is, user inputs must */ /* match after being left justified, converted to upper case, */ /* and having all embedded blanks removed. */ /* Below we declare names for coordinates. Again, user */ /* inputs naming coordinates must match these when */ /* compared using EQSTR. */ /* Note that the RA parameter value below matches */ /* 'RIGHT ASCENSION' */ /* when extra blanks are compressed out of the above value. */ /* Parameters specifying types of vector definitions */ /* used for GF coordinate searches: */ /* All string parameter values are left justified, upper */ /* case, with extra blanks compressed out. */ /* POSDEF indicates the vector is defined by the */ /* position of a target relative to an observer. */ /* SOBDEF indicates the vector points from the center */ /* of a target body to the sub-observer point on */ /* that body, for a given observer and target. */ /* SOBDEF indicates the vector points from the center */ /* of a target body to the surface intercept point on */ /* that body, for a given observer, ray, and target. */ /* Number of workspace windows used by ZZGFREL: */ /* Number of additional workspace windows used by ZZGFLONG: */ /* Index of "existence window" used by ZZGFCSLV: */ /* Progress report parameters: */ /* MXBEGM, */ /* MXENDM are, respectively, the maximum lengths of the progress */ /* report message prefix and suffix. */ /* Note: the sum of these lengths, plus the length of the */ /* "percent complete" substring, should not be long enough */ /* to cause wrap-around on any platform's terminal window. */ /* Total progress report message length upper bound: */ /* End of file zzgf.inc. */ /* $ Abstract */ /* Include file zzabcorr.inc */ /* SPICE private file intended solely for the support of SPICE */ /* routines. Users should not include this file directly due */ /* to the volatile nature of this file */ /* The parameters below define the structure of an aberration */ /* correction attribute block. */ /* $ 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 */ /* An aberration correction attribute block is an array of logical */ /* flags indicating the attributes of the aberration correction */ /* specified by an aberration correction string. The attributes */ /* are: */ /* - Is the correction "geometric"? */ /* - Is light time correction indicated? */ /* - Is stellar aberration correction indicated? */ /* - Is the light time correction of the "converged */ /* Newtonian" variety? */ /* - Is the correction for the transmission case? */ /* - Is the correction relativistic? */ /* The parameters defining the structure of the block are as */ /* follows: */ /* NABCOR Number of aberration correction choices. */ /* ABATSZ Number of elements in the aberration correction */ /* block. */ /* GEOIDX Index in block of geometric correction flag. */ /* LTIDX Index of light time flag. */ /* STLIDX Index of stellar aberration flag. */ /* CNVIDX Index of converged Newtonian flag. */ /* XMTIDX Index of transmission flag. */ /* RELIDX Index of relativistic flag. */ /* The following parameter is not required to define the block */ /* structure, but it is convenient to include it here: */ /* CORLEN The maximum string length required by any aberration */ /* correction string */ /* $ Author_and_Institution */ /* N.J. Bachman (JPL) */ /* $ Literature_References */ /* None. */ /* $ Version */ /* - SPICELIB Version 1.0.0, 18-DEC-2004 (NJB) */ /* -& */ /* Number of aberration correction choices: */ /* Aberration correction attribute block size */ /* (number of aberration correction attributes): */ /* Indices of attributes within an aberration correction */ /* attribute block: */ /* Maximum length of an aberration correction string: */ /* End of include file zzabcorr.inc */ /* $ Brief_I/O */ /* VARIABLE I/O DESCRIPTION */ /* -------- --- -------------------------------------------------- */ /* METHOD I Computation method. */ /* TRGID I Target ID code. */ /* ET I Computation epoch. */ /* FIXREF I Reference frame name. */ /* ABCORR I Aberration correction. */ /* OBSID I Observer ID code. */ /* RADII I Target radii. */ /* STATE O State used to define coordinates. */ /* $ Detailed_Input */ /* METHOD is a short string providing parameters defining */ /* the computation method to be used. Any value */ /* supported by SUBPNT may be used. */ /* TRGID is the NAIF ID code of the target object. */ /* *This routine assumes that the target is modeled */ /* as a tri-axial ellipsoid.* */ /* ET is the time, expressed as ephemeris seconds past J2000 */ /* TDB, at which the specified state is to be computed. */ /* FIXREF is the name of the reference frame relative to which */ /* the state of interest is specified. */ /* FIXREF must be centered on the target body. */ /* Case, leading and trailing blanks are not significant */ /* in the string FIXREF. */ /* ABCORR indicates the aberration corrections to be applied to */ /* the state of the target body to account for one-way */ /* light time and stellar aberration. The orientation */ /* of the target body will also be corrected for one-way */ /* light time when light time corrections are requested. */ /* Supported aberration correction options for */ /* observation (case where radiation is received by */ /* observer at ET) are: */ /* NONE No correction. */ /* LT Light time only. */ /* LT+S Light time and stellar aberration. */ /* CN Converged Newtonian (CN) light time. */ /* CN+S CN light time and stellar aberration. */ /* Supported aberration correction options for */ /* transmission (case where radiation is emitted from */ /* observer at ET) are: */ /* XLT Light time only. */ /* XLT+S Light time and stellar aberration. */ /* XCN Converged Newtonian (CN) light time. */ /* XCN+S CN light time and stellar aberration. */ /* For detailed information, see the geometry finder */ /* required reading, gf.req. Also see the header of */ /* SPKEZR, which contains a detailed discussion of */ /* aberration corrections. */ /* Case, leading and trailing blanks are not significant */ /* in the string ABCORR. */ /* OBSID is the NAIF ID code of the observer. */ /* RADII is an array containing three radii defining */ /* a reference ellipsoid for the target body. */ /* $ Detailed_Output */ /* STATE is the state of the sub-observer point at ET. */ /* The first three components of STATE contain the */ /* sub-observer point itself; the last three */ /* components contain the derivative with respect to */ /* time of the position. The state is expressed */ /* relative to the body-fixed frame designated by */ /* FIXREF. */ /* Units are km and km/s. */ /* $ Parameters */ /* None. */ /* $ Exceptions */ /* 1) If the aberration correction ABCORR is not recognized, */ /* the error will be diagnosed by routines in the call tree */ /* of this routine. */ /* 2) If the frame FIXREF is not recognized by the frames */ /* subsystem, the error will be diagnosed by routines in the */ /* call tree of this routine. */ /* 3) FIXREF must be centered on the target body; if it isn't, */ /* the error will be diagnosed by routines in the call tree */ /* of this routine. */ /* 4) Any error that occurs while look up the state of the target */ /* or observer will be diagnosed by routines in the call tree of */ /* this routine. */ /* 5) Any error that occurs while look up the orientation of */ /* the target will be diagnosed by routines in the call tree of */ /* this routine. */ /* 6) If the input method is not recognized, the error */ /* SPICE(NOTSUPPORTED) will be signaled. */ /* $ Files */ /* Appropriate kernels must be loaded 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: if the target body shape is modeled as an */ /* ellipsoid, 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. */ /* - 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 */ /* This routine isolates the computation of the sub-observer state */ /* (that is, the sub-observer point and its derivative with respect */ /* to time). */ /* This routine is used by the GF coordinate utility routines in */ /* order to solve for time windows on which specified mathematical */ /* conditions involving coordinates are satisfied. The role of */ /* this routine is to provide Cartesian state vectors enabling */ /* the GF coordinate utilities to determine the signs of the */ /* derivatives with respect to time of coordinates of interest. */ /* $ Examples */ /* See ZZGFCOST. */ /* $ Restrictions */ /* 1) This routine is restricted to use with ellipsoidal target */ /* shape models. */ /* 2) The computations performed by this routine are intended */ /* to be compatible with those performed by the SPICE */ /* routine SUBPNT. If that routine changes, this routine */ /* may need to be updated. */ /* 3) This routine presumes that error checking of inputs */ /* has, where possible, already been performed by the */ /* GF coordinate utility initialization routine. */ /* 4) The interface and functionality of this set of routines may */ /* change without notice. These routines should be called only */ /* by SPICELIB routines. */ /* $ Literature_References */ /* None. */ /* $ Author_and_Institution */ /* N.J. Bachman (JPL) */ /* $ Version */ /* - SPICELIB Version 2.0.0 12-MAY-2009 (NJB) */ /* Upgraded to support targets and observers having */ /* no names associated with their ID codes. */ /* - SPICELIB Version 1.0.0 05-MAR-2009 (NJB) */ /* -& */ /* $ Index_Entries */ /* sub-observer state */ /* -& */ /* SPICELIB functions */ /* Local parameters */ /* Local variables */ /* Saved variables */ /* Initial values */ /* Standard SPICE error handling. */ if (return_()) { return 0; } chkin_("ZZGFSSOB", (ftnlen)8); if (first || *trgid != prvtrg) { bodc2s_(trgid, svtarg, (ftnlen)36); prvtrg = *trgid; } if (first || *obsid != prvobs) { bodc2s_(obsid, svobs, (ftnlen)36); prvobs = *obsid; } first = FALSE_; /* Parse the aberration correction specifier. */ zzprscor_(abcorr, attblk, abcorr_len); geom = attblk[0]; uselt = attblk[1]; usestl = attblk[2]; xmit = attblk[4]; /* Decide whether the sub-observer point is computed using */ /* the "near point" or "surface intercept" method. Only */ /* ellipsoids may be used a shape models for this computation. */ if (eqstr_(method, "Near point: ellipsoid", method_len, (ftnlen)21)) { near__ = TRUE_; } else if (eqstr_(method, "Intercept: ellipsoid", method_len, (ftnlen)20)) { near__ = FALSE_; } else { setmsg_("Sub-observer point computation method # is not supported by" " this routine.", (ftnlen)73); errch_("#", method, (ftnlen)1, method_len); sigerr_("SPICE(NOTSUPPORTED)", (ftnlen)19); chkout_("ZZGFSSOB", (ftnlen)8); return 0; } if (geom) { /* This is the geometric case. */ /* We need to check the body-fixed reference frame here. */ namfrm_(fixref, &frcode, fixref_len); frinfo_(&frcode, ¢er, &frclss, &clssid, &fnd); if (failed_()) { chkout_("ZZGFSSOB", (ftnlen)8); return 0; } if (! fnd) { setmsg_("Input reference frame # was not recognized.", (ftnlen)43) ; errch_("#", fixref, (ftnlen)1, fixref_len); sigerr_("SPICE(NOFRAME)", (ftnlen)14); chkout_("ZZGFSSOB", (ftnlen)8); return 0; } if (center != *trgid) { setmsg_("Input reference frame # is centered on body # instead o" "f body #.", (ftnlen)64); errch_("#", fixref, (ftnlen)1, fixref_len); errint_("#", ¢er, (ftnlen)1); errint_("#", trgid, (ftnlen)1); sigerr_("SPICE(INVALIDFRAME)", (ftnlen)19); chkout_("ZZGFSSOB", (ftnlen)8); return 0; } /* Get the state of the target with respect to the observer, */ /* expressed relative to the target body-fixed frame. We don't */ /* need to propagate states to the solar system barycenter in */ /* this case. */ spkgeo_(trgid, et, fixref, obsid, fxtsta, <, fixref_len); if (failed_()) { chkout_("ZZGFSSOB", (ftnlen)8); return 0; } /* Compute the state of the observer with respect to the target */ /* in the body-fixed frame. */ vminug_(fxtsta, &c__6, fxosta); /* Now we can obtain the surface velocity of the sub-observer */ /* point. */ if (near__) { /* The sub-observer point method is "near point." */ dnearp_(fxosta, radii, &radii[1], &radii[2], fxpsta, dalt, &found) ; if (! found) { setmsg_("The sub-observer state could could not be computed " "because the velocity was not well defined. DNEARP re" "turned \"not found.\"", (ftnlen)122); sigerr_("SPICE(DEGENERATECASE)", (ftnlen)21); chkout_("ZZGFSSOB", (ftnlen)8); return 0; } } else { /* The sub-observer point method is "surface */ /* intercept point." The ray direction is simply */ /* the negative of the observer's position relative */ /* to the target center. */ vminug_(fxosta, &c__6, raysta); surfpv_(fxosta, raysta, radii, &radii[1], &radii[2], fxpsta, & found); /* Although in general it's not an error for SURFPV to */ /* be unable to compute an intercept state, it *is* */ /* an error in this case, since the ray points toward */ /* the center of the target. */ if (! found) { setmsg_("The sub-observer state could could not be computed " "because the velocity was not well defined. SURFPV re" "turned \"not found.\"", (ftnlen)122); sigerr_("SPICE(DEGENERATECASE)", (ftnlen)21); chkout_("ZZGFSSOB", (ftnlen)8); return 0; } } } else if (uselt) { /* Light time and possibly stellar aberration corrections are */ /* applied. */ /* Most our work consists of getting ready to call either of the */ /* SPICELIB routines DNEARP or SURFPV. In order to make this */ /* call, we'll need the velocity of the observer relative to the */ /* target body's center in the target body-fixed frame. We must */ /* evaluate the rotation state of the target at the correct */ /* epoch, and account for the rate of change of light time, if */ /* light time corrections are used. The algorithm we use depends */ /* on the algorithm used in SUBPNT, since we're computing the */ /* derivative with respect to time of the solution found by that */ /* routine. */ /* In this algorithm, we must take into account the fact that */ /* SUBPNT performs light time and stellar aberration corrections */ /* for the sub-observer point, not for the center of the target */ /* body. */ /* If light time and stellar aberration corrections are used, */ /* - Find the aberration corrected sub-observer point and the */ /* light time-corrected epoch TRGEPC associated with the */ /* sub-observer point. */ /* - Use TRGEPC to find the position of the target relative to */ /* the solar system barycenter. */ /* - Use TRGEPC to find the orientation of the target relative */ /* to the J2000 reference frame. */ /* - Find the light-time corrected position of the */ /* sub-observer point; use this to compute the stellar */ /* aberration offset that applies to the sub-observer point, */ /* as well as the velocity of this offset. */ /* - Find the corrected state of the target center as seen */ /* from the observer, where the corrections are those */ /* applicable to the sub-observer point. */ /* - Negate the corrected target center state to obtain the */ /* state of the observer relative to the target. */ /* - Express the state of the observer relative to the target */ /* in the target body fixed frame at TRGEPC. */ /* Below, we'll use the convention that vectors expressed */ /* relative to the body-fixed frame have names of the form */ /* FX* */ /* Note that SUBPNT will signal an error if FIXREF is not */ /* actually centered on the target body. */ subpnt_(method, svtarg, et, fixref, abcorr, svobs, spoint, &trgepc, srfvec, method_len, (ftnlen)36, fixref_len, abcorr_len, ( ftnlen)36); /* Get J2000-relative states of observer and target with respect */ /* to the solar system barycenter at their respective epochs of */ /* participation. */ spkssb_(obsid, et, "J2000", ssbobs, (ftnlen)5); spkssb_(trgid, &trgepc, "J2000", ssbtg0, (ftnlen)5); /* Get the uncorrected J2000 to body-fixed to state */ /* transformation at TRGEPC. */ sxform_("J2000", fixref, &trgepc, xform, (ftnlen)5, fixref_len); if (failed_()) { chkout_("ZZGFSSOB", (ftnlen)8); return 0; } /* Initialize the state of the sub-observer point in the */ /* body-fixed frame. At this point we don't know the */ /* point's velocity; set it to zero. */ moved_(spoint, &c__3, fxpsta); cleard_(&c__3, &fxpsta[3]); if (usestl) { /* We're going to need the acceleration of the observer */ /* relative to the SSB. Compute this now. */ for (i__ = 1; i__ <= 2; ++i__) { /* The epoch is ET -/+ TDELTA. */ t = *et + ((i__ << 1) - 3) * 1.; spkssb_(obsid, &t, "J2000", &obssta[(i__1 = i__ * 6 - 6) < 12 && 0 <= i__1 ? i__1 : s_rnge("obssta", i__1, "zzgfss" "ob_", (ftnlen)652)], (ftnlen)5); } if (failed_()) { chkout_("ZZGFSSOB", (ftnlen)8); return 0; } /* Compute the observer's acceleration using a quadratic */ /* approximation. */ qderiv_(&c__3, &obssta[3], &obssta[9], &c_b40, acc); } /* The rest of the algorithm is iterative. On the first */ /* iteration, we don't have a good estimate of the velocity */ /* of the sub-observer point relative to the body-fixed */ /* frame. Since we're using this velocity as an input */ /* to the aberration velocity computations, we */ /* expect that treating this velocity as zero on the first */ /* pass yields a reasonable estimate. On the second pass, */ /* we'll use the velocity derived on the first pass. */ cleard_(&c__3, fxpvel); /* We'll also estimate the rate of change of light time */ /* as zero on the first pass. */ dlt = 0.; for (i__ = 1; i__ <= 2; ++i__) { /* Correct the target's velocity for the rate of */ /* change of light time. */ if (xmit) { scale = dlt + 1.; } else { scale = 1. - dlt; } /* Scale the velocity portion of the target state to */ /* correct the velocity for the rate of change of light */ /* time. */ moved_(ssbtg0, &c__3, ssbtrg); vscl_(&scale, &ssbtg0[3], &ssbtrg[3]); /* Get the state of the target with respect to the observer. */ vsubg_(ssbtrg, ssbobs, &c__6, obstrg); /* Correct the J2000 to body-fixed state transformation matrix */ /* for the rate of change of light time. */ zzcorsxf_(&xmit, &dlt, xform, corxfm); /* Invert CORXFM to obtain the corrected */ /* body-fixed to J2000 state transformation. */ invstm_(corxfm, corxfi); /* Convert the sub-observer point state to the J2000 frame. */ mxvg_(corxfi, fxpsta, &c__6, &c__6, pntsta); /* Find the J2000-relative state of the sub-observer */ /* point with respect to the target. */ vaddg_(obstrg, pntsta, &c__6, obspnt); if (usestl) { /* Now compute the stellar aberration correction */ /* applicable to OBSPNT. We need the velocity of */ /* this correction as well. */ zzstelab_(&xmit, acc, &ssbobs[3], obspnt, sa, savel); moved_(sa, &c__3, sastat); moved_(savel, &c__3, &sastat[3]); /* Adding the stellar aberration state to the target center */ /* state gives us the state of the target center with */ /* respect to the observer, corrected for the aberrations */ /* applicable to the sub-observer point. */ vaddg_(obstrg, sastat, &c__6, stemp); } else { moved_(obstrg, &c__6, stemp); } /* Convert STEMP to the body-fixed reference frame. */ mxvg_(corxfm, stemp, &c__6, &c__6, fxtsta); /* At long last, compute the state of the observer */ /* with respect to the target in the body-fixed frame. */ vminug_(fxtsta, &c__6, fxosta); /* Now we can obtain the surface velocity of the */ /* sub-observer point. */ if (near__) { /* The sub-observer point method is "near point." */ dnearp_(fxosta, radii, &radii[1], &radii[2], fxpsta, dalt, & found); if (! found) { setmsg_("The sub-observer state could could not be compu" "ted because the velocity was not well defined. " "DNEARP returned \"not found.\"", (ftnlen)123); sigerr_("SPICE(DEGENERATECASE)", (ftnlen)21); chkout_("ZZGFSSOB", (ftnlen)8); return 0; } } else { /* The sub-observer point method is "surface intercept */ /* point." The ray direction is simply the negative of the */ /* observer's position relative to the target center. */ vminug_(fxosta, &c__6, raysta); surfpv_(fxosta, raysta, radii, &radii[1], &radii[2], fxpsta, & found); /* Although in general it's not an error for SURFPV to be */ /* unable to compute an intercept state, it *is* an error */ /* in this case, since the ray points toward the center of */ /* the target. */ if (! found) { setmsg_("The sub-observer state could could not be compu" "ted because the velocity was not well defined. S" "URFPV returned \"not found.\"", (ftnlen)122); sigerr_("SPICE(DEGENERATECASE)", (ftnlen)21); chkout_("ZZGFSSOB", (ftnlen)8); return 0; } } /* At this point we can update the surface point */ /* velocity and light time derivative estimates. */ /* In order to compute the light time rate, we'll */ /* need the J2000-relative velocity of the sub-observer */ /* point with respect to the observer. First convert */ /* the sub-observer state to the J2000 frame, then */ /* add the result to the state of the target center */ /* with respect to the observer. */ mxvg_(corxfi, fxpsta, &c__6, &c__6, pntsta); vaddg_(obstrg, pntsta, &c__6, obspnt); /* Now that we have an improved estimate of the */ /* sub-observer state, we can estimate the rate of */ /* change of light time as */ /* range rate */ /* ---------- */ /* c */ /* If we're correcting for stellar aberration, *ideally* we */ /* should remove that correction now, since the light time */ /* rate is based on light time between the observer and the */ /* light-time corrected sub-observer point. But the error made */ /* by including stellar aberration is too small to make it */ /* worthwhile to make this adjustment. */ vhat_(obspnt, upos); dlt = vdot_(&obspnt[3], upos) / clight_(); /* With FXPVEL and DLT updated, we'll repeat our */ /* computations. */ } } else { /* We should never get here. */ setmsg_("Aberration correction # was not recognized.", (ftnlen)43); errch_("#", abcorr, (ftnlen)1, abcorr_len); sigerr_("SPICE(NOTSUPPORTED)", (ftnlen)19); chkout_("ZZGFSSOB", (ftnlen)8); return 0; } /* Copy the computed state to the output argument STATE. */ moved_(fxpsta, &c__6, state); chkout_("ZZGFSSOB", (ftnlen)8); return 0; } /* zzgfssob_ */
/* $Procedure LSPCN ( Longitude of the sun, planetocentric ) */ doublereal lspcn_(char *body, doublereal *et, char *abcorr, ftnlen body_len, ftnlen abcorr_len) { /* Initialized data */ static logical first = TRUE_; /* System generated locals */ integer i__1, i__2; doublereal ret_val; /* Builtin functions */ integer s_rnge(char *, integer, char *, integer); /* Local variables */ extern /* Subroutine */ int zzbods2c_(integer *, char *, integer *, logical *, char *, integer *, logical *, ftnlen, ftnlen); doublereal tipm[9] /* was [3][3] */; extern /* Subroutine */ int zzctruin_(integer *); integer i__; extern /* Subroutine */ int chkin_(char *, ftnlen), errch_(char *, char *, ftnlen, ftnlen); logical found; doublereal uavel[3], npole[3], trans[9] /* was [3][3] */; extern /* Subroutine */ int ucrss_(doublereal *, doublereal *, doublereal *); static logical svfnd1; static integer svctr1[2]; extern logical failed_(void); integer idcode; doublereal lt; extern /* Subroutine */ int recrad_(doublereal *, doublereal *, doublereal *, doublereal *); static integer svidcd; extern /* Subroutine */ int tipbod_(char *, integer *, doublereal *, doublereal *, ftnlen); doublereal bstate[6], radius; extern /* Subroutine */ int spkgeo_(integer *, doublereal *, char *, integer *, doublereal *, doublereal *, ftnlen), sigerr_(char *, ftnlen), chkout_(char *, ftnlen), setmsg_(char *, ftnlen); doublereal sstate[6]; static char svbody[36]; extern /* Subroutine */ int twovec_(doublereal *, integer *, doublereal *, integer *, doublereal *); extern logical return_(void); extern /* Subroutine */ int spkezr_(char *, doublereal *, char *, char *, char *, doublereal *, doublereal *, ftnlen, ftnlen, ftnlen, ftnlen); doublereal lat, pos[3]; extern /* Subroutine */ int mxv_(doublereal *, doublereal *, doublereal *) ; /* $ Abstract */ /* Compute L_s, the planetocentric longitude of the sun, as seen */ /* from a specified 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 */ /* NAIF_IDS */ /* PCK */ /* TIME */ /* SPK */ /* $ Keywords */ /* GEOMETRY */ /* TIME */ /* $ 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 */ /* -------- --- -------------------------------------------------- */ /* BODY I Name of central body. */ /* ET I Epoch in seconds past J2000 TDB. */ /* ABCORR I Aberration correction. */ /* The function returns the value of L_s for the specified body */ /* at the specified time. */ /* $ Detailed_Input */ /* BODY is the name of the central body, typically a planet. */ /* ET is the epoch at which the longitude of the sun (L_s) */ /* is to be computed. ET is expressed as seconds past */ /* J2000 TDB (Barycentric Dynamical Time). */ /* ABCORR indicates the aberration corrections to be applied */ /* when computing the longitude of the sun. ABCORR may */ /* be any of the following. */ /* 'NONE' Apply no correction. */ /* 'LT' Correct the position of the sun, */ /* relative to the central body, for */ /* planetary (light time) aberration. */ /* 'LT+S' Correct the position of the sun, */ /* relative to the central body, for */ /* planetary and stellar aberrations. */ /* $ Detailed_Output */ /* The function returns the planetocentric longitude of the sun, */ /* often called "L_s," for the specified body at the specified time. */ /* This is the longitude of the body-sun vector in a right-handed */ /* frame whose basis vectors are defined as follows: */ /* - The positive Z direction is given by the instantaneous */ /* angular velocity vector of the orbit of the body about */ /* the sun. */ /* - The positive X direction is that of the cross product of the */ /* instantaneous north spin axis of the body with the positive */ /* Z direction. */ /* - The positive Y direction is Z x X. */ /* Units are radians; the range is 0 to 2*pi. Longitudes are */ /* positive to the east. */ /* $ Parameters */ /* None. */ /* $ Exceptions */ /* 1) If the input body name cannot be translated to an ID code, */ /* and if the name is not a string representation of an integer */ /* (for example, '399'), the error SPICE(NOTRANSLATION) is */ /* signaled. */ /* 2) If no SPK (ephemeris) file has been loaded prior to calling */ /* this routine, or if the SPK data has insufficient coverage, an */ /* error will be diagnosed and signaled by a routine in the call */ /* tree of this routine. */ /* 3) If a PCK file containing rotational elements for the central */ /* body has not been loaded prior to calling this routine, an */ /* error will be diagnosed and signaled by a routine called by a */ /* routine in the call tree of this routine. */ /* 4) If the instantaneous angular velocity and spin axis of BODY */ /* are parallel, the error will be diagnosed and signaled by a */ /* routine in the call tree of this routine. */ /* $ Files */ /* 1) An SPK file (or file) containing ephemeris data sufficient to */ /* compute the geometric state of the central body relative to */ /* the sun at ET must be loaded before this routine is called. If */ /* light time correction is used, data must be available that */ /* enable computation of the state the sun relative to the solar */ /* system barycenter at the light-time corrected epoch. If */ /* stellar aberration correction is used, data must be available */ /* that enable computation of the state the central body relative */ /* to the solar system barycenter at ET. */ /* 2) A PCK file containing rotational elements for the central body */ /* must be loaded before this routine is called. */ /* $ Particulars */ /* The direction of the vernal equinox for the central body is */ /* determined from the instantaneous equatorial and orbital planes */ /* of the central body. This equinox definition is specified in */ /* reference [1]. The "instantaneous orbital plane" is interpreted */ /* in this routine as the plane normal to the cross product of the */ /* position and velocity of the central body relative to the sun. */ /* The geometric state of the central body relative to the sun is */ /* used for this normal vector computation. The "instantaneous */ /* equatorial plane" is normal to the central body's north pole */ /* at the requested epoch. The pole direction is determined from */ /* rotational elements loaded via a PCK file. */ /* The result returned by this routine will depend on the */ /* ephemeris data and rotational elements used. The result may */ /* differ from that given in any particular version of the */ /* Astronomical Almanac, due to differences in these input data, */ /* and due to differences in precision of the computations. */ /* $ Examples */ /* 1) A simple program that computes L_s for a body and time */ /* supplied interactively. The geometric state of the sun is */ /* used. */ /* PROGRAM EX1 */ /* IMPLICIT NONE */ /* DOUBLE PRECISION DPR */ /* DOUBLE PRECISION LSPCN */ /* CHARACTER*(*) ABCORR */ /* PARAMETER ( ABCORR = 'NONE' ) */ /* INTEGER FILSIZ */ /* PARAMETER ( FILSIZ = 255 ) */ /* INTEGER NAMLEN */ /* PARAMETER ( NAMLEN = 36 ) */ /* INTEGER TIMLEN */ /* PARAMETER ( TIMLEN = 40 ) */ /* CHARACTER*(NAMLEN) BODY */ /* CHARACTER*(FILSIZ) LSK */ /* CHARACTER*(FILSIZ) PCK */ /* CHARACTER*(FILSIZ) SPK */ /* CHARACTER*(TIMLEN) TIMSTR */ /* DOUBLE PRECISION ET */ /* DOUBLE PRECISION LON */ /* CALL PROMPT ( 'Enter name of leapseconds kernel > ', LSK ) */ /* CALL PROMPT ( 'Enter name of PCK file > ', PCK ) */ /* CALL PROMPT ( 'Enter name of SPK file > ', SPK ) */ /* CALL FURNSH ( LSK ) */ /* CALL FURNSH ( PCK ) */ /* CALL FURNSH ( SPK ) */ /* WRITE (*,*) ' ' */ /* WRITE (*,*) 'Kernels have been loaded.' */ /* WRITE (*,*) ' ' */ /* DO WHILE ( .TRUE. ) */ /* CALL PROMPT ( 'Enter name of central body > ', */ /* . BODY ) */ /* CALL PROMPT ( 'Enter calendar, JD, or DOY time > ', */ /* . TIMSTR ) */ /* CALL STR2ET ( TIMSTR, ET ) */ /* C */ /* C Convert longitude to degrees. */ /* C */ /* LON = DPR() * LSPCN ( BODY, ET, ABCORR ) */ /* WRITE (*,*) ' ' */ /* WRITE (*,*) 'Central body = ', BODY */ /* WRITE (*,*) 'Time = ', TIMSTR */ /* WRITE (*,*) 'Planetocentric L_s (deg.) = ', LON */ /* WRITE (*,*) ' ' */ /* END DO */ /* END */ /* $ Restrictions */ /* None. */ /* $ Literature_References */ /* [1] "The Astronomical Almanac for the Year 2005." U.S. Government */ /* Printing Office, Washington, D.C., 1984, page L9. */ /* $ Author_and_Institution */ /* N.J. Bachman (JPL) */ /* B.V. Semenov (JPL) */ /* $ Version */ /* - SPICELIB Version 1.1.0, 19-SEP-2013 (BVS) */ /* Updated to save the input body name and ZZBODTRN state */ /* counter and to do name-ID conversion only if the counter */ /* has changed. */ /* - SPICELIB Version 1.0.0, 07-JAN-2005 (NJB) */ /* -& */ /* $ Index_Entries */ /* planetocentric longitude of sun */ /* compute L_s */ /* compute Ls */ /* compute L_sub_s */ /* -& */ /* SPICELIB functions */ /* Local parameters */ /* Saved body name length. */ /* Local variables */ /* Saved name/ID item declarations. */ /* Saved name/ID items. */ /* Initial values. */ /* Give the function an initial value. */ ret_val = 0.; /* Standard SPICE error handling. */ if (return_()) { return ret_val; } chkin_("LSPCN", (ftnlen)5); /* Initialization. */ if (first) { /* Initialize counters */ zzctruin_(svctr1); first = FALSE_; } /* Map the body name to an ID code. */ zzbods2c_(svctr1, svbody, &svidcd, &svfnd1, body, &idcode, &found, ( ftnlen)36, body_len); if (! found) { setmsg_("The body name # could not be translated to a NAIF ID code. " " The cause of this problem may be that you need an updated v" "ersion of the SPICE Toolkit.", (ftnlen)147); errch_("#", body, (ftnlen)1, body_len); sigerr_("SPICE(NOTRANSLATION)", (ftnlen)20); chkout_("LSPCN", (ftnlen)5); return ret_val; } /* Look up the direction of the North pole of the central body. */ /* Note that TIPBOD does make use of binary PCK data if available. */ tipbod_("J2000", &idcode, et, tipm, (ftnlen)5); for (i__ = 1; i__ <= 3; ++i__) { npole[(i__1 = i__ - 1) < 3 && 0 <= i__1 ? i__1 : s_rnge("npole", i__1, "lspcn_", (ftnlen)397)] = tipm[(i__2 = i__ * 3 - 1) < 9 && 0 <= i__2 ? i__2 : s_rnge("tipm", i__2, "lspcn_", (ftnlen)397)]; } /* Get the geometric state of the body relative to the sun. */ spkgeo_(&idcode, et, "J2000", &c__10, bstate, <, (ftnlen)5); /* Get the unit direction vector parallel to the angular velocity */ /* vector of the orbit. This is just the unitized cross product of */ /* position and velocity. */ ucrss_(bstate, &bstate[3], uavel); /* We want to create a transformation matrix that maps vectors from */ /* basis REF to the following frame: */ /* Z = UAVEL */ /* X = NPOLE x UAVEL */ /* Y = Z x X */ /* This is a "two-vector" frame with the unit orbital */ /* angular velocity vector UAVEL as the primary vector and the */ /* spin axis NPOLE as the secondary vector. The primary */ /* vector is associated with the +Z axis; the secondary vector */ /* is associated with the +Y axis. */ twovec_(uavel, &c__3, npole, &c__2, trans); if (failed_()) { chkout_("LSPCN", (ftnlen)5); return ret_val; } /* We'll find the position of the Sun relative to this frame. */ /* Get the state of the sun in frame REF. Since we may be using */ /* aberration corrections, this is not necessarily the negative of */ /* the state we've just found. */ spkezr_("SUN", et, "J2000", abcorr, body, sstate, <, (ftnlen)3, (ftnlen) 5, abcorr_len, body_len); /* Now transform the position of the Sun into the "orbit plane */ /* and equinox" frame. */ mxv_(trans, sstate, pos); /* Let RECRAD find the longitude LS for us. RECRAD performs */ /* the same coordinate transformation as the more commonly used */ /* RECLAT, but the range of right ascension is 0:2*pi, which is */ /* what we want for Ls. */ recrad_(pos, &radius, &ret_val, &lat); chkout_("LSPCN", (ftnlen)5); return ret_val; } /* lspcn_ */
/* $Procedure SPKLTC ( S/P Kernel, light time corrected state ) */ /* Subroutine */ int spkltc_(integer *targ, doublereal *et, char *ref, char * abcorr, doublereal *stobs, doublereal *starg, doublereal *lt, doublereal *dlt, ftnlen ref_len, ftnlen abcorr_len) { /* Initialized data */ static logical pass1 = TRUE_; static char prvcor[5] = " "; /* System generated locals */ doublereal d__1, d__2, d__3, d__4; /* Builtin functions */ integer s_cmp(char *, char *, ftnlen, ftnlen); /* Subroutine */ int s_copy(char *, char *, ftnlen, ftnlen); /* Local variables */ doublereal dist; extern doublereal vdot_(doublereal *, doublereal *); static logical xmit; extern /* Subroutine */ int zzvalcor_(char *, logical *, ftnlen); doublereal a, b, c__; integer i__, refid; extern /* Subroutine */ int chkin_(char *, ftnlen); doublereal epoch; extern /* Subroutine */ int errch_(char *, char *, ftnlen, ftnlen); static logical usecn; extern /* Subroutine */ int vlcom_(doublereal *, doublereal *, doublereal *, doublereal *, doublereal *), vsubg_(doublereal *, doublereal *, integer *, doublereal *); doublereal ssblt, lterr; static logical uselt; extern doublereal vnorm_(doublereal *); doublereal prvlt; extern logical failed_(void); extern doublereal clight_(void); logical attblk[15]; extern doublereal touchd_(doublereal *); extern /* Subroutine */ int spkgeo_(integer *, doublereal *, char *, integer *, doublereal *, doublereal *, ftnlen), sigerr_(char *, ftnlen), chkout_(char *, ftnlen); integer ltsign; extern /* Subroutine */ int irfnum_(char *, integer *, ftnlen), setmsg_( char *, ftnlen); doublereal ssbtrg[6]; integer numitr; extern logical return_(void); logical usestl; /* $ Abstract */ /* Return the state (position and velocity) of a target body */ /* relative to an observer, optionally corrected for light time, */ /* expressed relative to an inertial reference frame. */ /* $ 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 */ /* SPK */ /* $ Keywords */ /* EPHEMERIS */ /* $ Declarations */ /* $ Abstract */ /* Include file zzabcorr.inc */ /* SPICE private file intended solely for the support of SPICE */ /* routines. Users should not include this file directly due */ /* to the volatile nature of this file */ /* The parameters below define the structure of an aberration */ /* correction attribute block. */ /* $ 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 */ /* An aberration correction attribute block is an array of logical */ /* flags indicating the attributes of the aberration correction */ /* specified by an aberration correction string. The attributes */ /* are: */ /* - Is the correction "geometric"? */ /* - Is light time correction indicated? */ /* - Is stellar aberration correction indicated? */ /* - Is the light time correction of the "converged */ /* Newtonian" variety? */ /* - Is the correction for the transmission case? */ /* - Is the correction relativistic? */ /* The parameters defining the structure of the block are as */ /* follows: */ /* NABCOR Number of aberration correction choices. */ /* ABATSZ Number of elements in the aberration correction */ /* block. */ /* GEOIDX Index in block of geometric correction flag. */ /* LTIDX Index of light time flag. */ /* STLIDX Index of stellar aberration flag. */ /* CNVIDX Index of converged Newtonian flag. */ /* XMTIDX Index of transmission flag. */ /* RELIDX Index of relativistic flag. */ /* The following parameter is not required to define the block */ /* structure, but it is convenient to include it here: */ /* CORLEN The maximum string length required by any aberration */ /* correction string */ /* $ Author_and_Institution */ /* N.J. Bachman (JPL) */ /* $ Literature_References */ /* None. */ /* $ Version */ /* - SPICELIB Version 1.0.0, 18-DEC-2004 (NJB) */ /* -& */ /* Number of aberration correction choices: */ /* Aberration correction attribute block size */ /* (number of aberration correction attributes): */ /* Indices of attributes within an aberration correction */ /* attribute block: */ /* Maximum length of an aberration correction string: */ /* End of include file zzabcorr.inc */ /* $ Brief_I/O */ /* Variable I/O Description */ /* -------- --- -------------------------------------------------- */ /* TARG I Target body. */ /* ET I Observer epoch. */ /* REF I Inertial reference frame of output state. */ /* ABCORR I Aberration correction flag. */ /* STOBS I State of the observer relative to the SSB. */ /* STARG O State of target. */ /* LT O One way light time between observer and target. */ /* DLT O Derivative of light time with respect to time. */ /* $ Detailed_Input */ /* TARG is the NAIF ID code for a target body. The target */ /* and observer define a state vector whose position */ /* component points from the observer to the target. */ /* ET is the ephemeris time, expressed as seconds past */ /* J2000 TDB, at which the state of the target body */ /* relative to the observer is to be computed. ET */ /* refers to time at the observer's location. */ /* REF is the inertial reference frame with respect to which */ /* the input state STOBS and the output state STARG are */ /* expressed. REF must be recognized by the SPICE */ /* Toolkit. The acceptable frames are listed in the */ /* Frames Required Reading, as well as in the SPICELIB */ /* routine CHGIRF. */ /* Case and blanks are not significant in the string */ /* REF. */ /* ABCORR indicates the aberration corrections to be applied to */ /* the state of the target body to account for one-way */ /* light time. See the discussion in the Particulars */ /* section for recommendations on how to choose */ /* aberration corrections. */ /* If ABCORR includes the stellar aberration correction */ /* symbol '+S', this flag is simply ignored. Aside from */ /* the possible presence of this symbol, ABCORR may be */ /* any of the following: */ /* 'NONE' Apply no correction. Return the */ /* geometric state of the target body */ /* relative to the observer. */ /* The following values of ABCORR apply to the */ /* "reception" case in which photons depart from the */ /* target's location at the light-time corrected epoch */ /* ET-LT and *arrive* at the observer's location at ET: */ /* 'LT' Correct for one-way light time (also */ /* called "planetary aberration") using a */ /* Newtonian formulation. This correction */ /* yields the state of the target at the */ /* moment it emitted photons arriving at */ /* the observer at ET. */ /* The light time correction involves */ /* iterative solution of the light time */ /* equation (see Particulars for details). */ /* The solution invoked by the 'LT' option */ /* uses one iteration. */ /* '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. */ /* The following values of ABCORR apply to the */ /* "transmission" case in which photons *depart* from */ /* the observer's location at ET and arrive at the */ /* target's location at the light-time corrected epoch */ /* ET+LT: */ /* 'XLT' "Transmission" case: correct for */ /* one-way light time using a Newtonian */ /* formulation. This correction yields the */ /* state of the target at the moment it */ /* receives photons emitted from the */ /* observer's location at ET. */ /* 'XCN' "Transmission" case: converged */ /* Newtonian light time correction. */ /* Neither special nor general relativistic effects are */ /* accounted for in the aberration corrections applied */ /* by this routine. */ /* Case and blanks are not significant in the string */ /* ABCORR. */ /* STOBS is the geometric (uncorrected) state of the observer */ /* relative to the solar system barycenter at epoch ET. */ /* STOBS is a 6-vector: the first three components of */ /* STOBS represent a Cartesian position vector; the last */ /* three components represent the corresponding velocity */ /* vector. STOBS is expressed relative to the inertial */ /* reference frame designated by REF. */ /* Units are always km and km/sec. */ /* $ Detailed_Output */ /* STARG is a Cartesian state vector representing the position */ /* and velocity of the target body relative to the */ /* specified observer. STARG is corrected for the */ /* specified aberration, and is expressed with respect */ /* to the specified inertial reference frame. The first */ /* three components of STARG represent the x-, y- and */ /* z-components of the target's position; last three */ /* components form the corresponding velocity vector. */ /* The position component of STARG points from the */ /* observer's location at ET to the aberration-corrected */ /* location of the target. Note that the sense of the */ /* position vector is independent of the direction of */ /* radiation travel implied by the aberration */ /* correction. */ /* Units are always km and km/sec. */ /* LT is the one-way light time between the observer and */ /* target in seconds. If the target state is corrected */ /* for light time, then LT is the one-way light time */ /* between the observer and the light time-corrected */ /* target location. */ /* DLT is the derivative with respect to barycentric */ /* dynamical time of the one way light time between */ /* target and observer: */ /* DLT = d(LT)/d(ET) */ /* DLT can also be described as the rate of change of */ /* one way light time. DLT is unitless, since LT and */ /* ET both have units of TDB seconds. */ /* If the observer and target are at the same position, */ /* then DLT is set to zero. */ /* $ Parameters */ /* None. */ /* $ Exceptions */ /* 1) For the convenience of the caller, the input aberration */ /* correction flag can call for stellar aberration correction via */ /* inclusion of the '+S' suffix. This portion of the aberration */ /* correction flag is ignored if present. */ /* 2) If the value of ABCORR is not recognized, the error */ /* is diagnosed by a routine in the call tree of this */ /* routine. */ /* 3) If the reference frame requested is not a recognized */ /* inertial reference frame, the error SPICE(BADFRAME) */ /* is signaled. */ /* 4) If the state of the target relative to the solar system */ /* barycenter cannot be computed, the error will be diagnosed */ /* by routines in the call tree of this routine. */ /* 5) If the observer and target are at the same position, */ /* then DLT is set to zero. This situation could arise, */ /* for example, when the observer is Mars and the target */ /* is the Mars barycenter. */ /* 6) If a division by zero error would occur in the computation */ /* of DLT, the error SPICE(DIVIDEBYZERO) is signaled. */ /* $ Files */ /* This routine computes states using SPK files that have been */ /* loaded into the SPICE system, normally via the kernel loading */ /* interface routine FURNSH. Application programs typically load */ /* kernels once before this routine is called, for example during */ /* program initialization; kernels need not be loaded repeatedly. */ /* See the routine FURNSH and the SPK and KERNEL Required Reading */ /* for further information on loading (and unloading) kernels. */ /* If any of the ephemeris data used to compute STARG are expressed */ /* relative to a non-inertial frame in the SPK files providing those */ /* data, additional kernels may be needed to enable the reference */ /* frame transformations required to compute the state. Normally */ /* these additional kernels are PCK files or frame kernels. Any */ /* such kernels must already be loaded at the time this routine is */ /* called. */ /* $ Particulars */ /* This routine supports higher-level SPK API routines that can */ /* perform both light time and stellar aberration corrections. */ /* User applications normally will not need to call this routine */ /* directly. */ /* See the header of the routine SPKEZR for a detailed discussion */ /* of aberration corrections. */ /* $ 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. */ /* 1) Look up a sequence of states of the Moon as seen from the */ /* Earth. Use light time corrections. Compute the first state for */ /* the epoch 2000 JAN 1 12:00:00 TDB; compute subsequent states at */ /* intervals of 1 hour. For each epoch, display the states, the */ /* one way light time between target and observer, and the rate of */ /* change of the one way light time. */ /* Use the following meta-kernel to specify the kernels to */ /* load: */ /* KPL/MK */ /* File name: spkltc.tm */ /* This meta-kernel is intended to support operation of SPICE */ /* example programs. The kernels shown here should not be */ /* assumed to contain adequate or correct versions of data */ /* required by SPICE-based user applications. */ /* In order for an application to use this meta-kernel, the */ /* kernels referenced here must be present in the user's */ /* current working directory. */ /* \begindata */ /* KERNELS_TO_LOAD = ( 'de421.bsp', */ /* 'pck00010.tpc', */ /* 'naif0010.tls' ) */ /* \begintext */ /* The code example follows: */ /* PROGRAM EX1 */ /* IMPLICIT NONE */ /* C */ /* C Local constants */ /* C */ /* C The meta-kernel name shown here refers to a file whose */ /* C contents are those shown above. This file and the kernels */ /* C it references must exist in your current working directory. */ /* C */ /* CHARACTER*(*) META */ /* PARAMETER ( META = 'spkltc.tm' ) */ /* C */ /* C Use a time step of 1 hour; look up 5 states. */ /* C */ /* DOUBLE PRECISION STEP */ /* PARAMETER ( STEP = 3600.0D0 ) */ /* INTEGER MAXITR */ /* PARAMETER ( MAXITR = 5 ) */ /* C */ /* C Local variables */ /* C */ /* DOUBLE PRECISION DLT */ /* DOUBLE PRECISION ET */ /* DOUBLE PRECISION ET0 */ /* DOUBLE PRECISION LT */ /* DOUBLE PRECISION STATE ( 6 ) */ /* DOUBLE PRECISION STOBS ( 6 ) */ /* INTEGER I */ /* C */ /* C Load the SPK and LSK kernels via the meta-kernel. */ /* C */ /* CALL FURNSH ( META ) */ /* C */ /* C Convert the start time to seconds past J2000 TDB. */ /* C */ /* CALL STR2ET ( '2000 JAN 1 12:00:00 TDB', ET0 ) */ /* C */ /* C Step through a series of epochs, looking up a */ /* C state vector at each one. */ /* C */ /* DO I = 1, MAXITR */ /* ET = ET0 + (I-1)*STEP */ /* C */ /* C Look up a state vector at epoch ET using the */ /* C following inputs: */ /* C */ /* C Target: Moon (NAIF ID code 301) */ /* C Reference frame: J2000 */ /* C Aberration correction: Light time ('LT') */ /* C Observer: Earth (NAIF ID code 399) */ /* C */ /* C Before we can execute this computation, we'll need the */ /* C geometric state of the observer relative to the solar */ /* C system barycenter at ET, expressed relative to the */ /* C J2000 reference frame: */ /* C */ /* CALL SPKSSB ( 399, ET, 'J2000', STOBS ) */ /* C */ /* C Now compute the desired state vector: */ /* C */ /* CALL SPKLTC ( 301, ET, 'J2000', 'LT', */ /* . STOBS, STATE, LT, DLT ) */ /* WRITE (*,*) 'ET = ', ET */ /* WRITE (*,*) 'J2000 x-position (km): ', STATE(1) */ /* WRITE (*,*) 'J2000 y-position (km): ', STATE(2) */ /* WRITE (*,*) 'J2000 z-position (km): ', STATE(3) */ /* WRITE (*,*) 'J2000 x-velocity (km/s): ', STATE(4) */ /* WRITE (*,*) 'J2000 y-velocity (km/s): ', STATE(5) */ /* WRITE (*,*) 'J2000 z-velocity (km/s): ', STATE(6) */ /* WRITE (*,*) 'One-way light time (s): ', LT */ /* WRITE (*,*) 'Light time rate: ', DLT */ /* WRITE (*,*) ' ' */ /* END DO */ /* END */ /* On a PC/Linux/gfortran platform, the following output was */ /* produced: */ /* ET = 0.0000000000000000 */ /* J2000 x-position (km): -291569.26541282982 */ /* J2000 y-position (km): -266709.18647825718 */ /* J2000 z-position (km): -76099.155118763447 */ /* J2000 x-velocity (km/s): 0.64353061322177041 */ /* J2000 y-velocity (km/s): -0.66608181700820079 */ /* J2000 z-velocity (km/s): -0.30132283179625752 */ /* One-way light time (s): 1.3423106103251679 */ /* Light time rate: 1.07316908698977495E-007 */ /* ET = 3600.0000000000000 */ /* J2000 x-position (km): -289240.78128184378 */ /* J2000 y-position (km): -269096.44087958336 */ /* J2000 z-position (km): -77180.899725757539 */ /* J2000 x-velocity (km/s): 0.65006211520087476 */ /* J2000 y-velocity (km/s): -0.66016273921695667 */ /* J2000 z-velocity (km/s): -0.29964267390571342 */ /* One-way light time (s): 1.3426939548635302 */ /* Light time rate: 1.05652598952224259E-007 */ /* ET = 7200.0000000000000 */ /* J2000 x-position (km): -286888.88736709207 */ /* J2000 y-position (km): -271462.30170547962 */ /* J2000 z-position (km): -78256.555682137609 */ /* J2000 x-velocity (km/s): 0.65653599154284592 */ /* J2000 y-velocity (km/s): -0.65419657680401588 */ /* J2000 z-velocity (km/s): -0.29794027307420823 */ /* One-way light time (s): 1.3430713117337547 */ /* Light time rate: 1.03990456898758609E-007 */ /* ET = 10800.000000000000 */ /* J2000 x-position (km): -284513.79173691198 */ /* J2000 y-position (km): -273806.60031034052 */ /* J2000 z-position (km): -79326.043183274567 */ /* J2000 x-velocity (km/s): 0.66295190054599118 */ /* J2000 y-velocity (km/s): -0.64818380709706158 */ /* J2000 z-velocity (km/s): -0.29621577937090349 */ /* One-way light time (s): 1.3434426890693671 */ /* Light time rate: 1.02330665243423737E-007 */ /* ET = 14400.000000000000 */ /* J2000 x-position (km): -282115.70368389413 */ /* J2000 y-position (km): -276129.16976799071 */ /* J2000 z-position (km): -80389.282965712249 */ /* J2000 x-velocity (km/s): 0.66930950377548726 */ /* J2000 y-velocity (km/s): -0.64212490805688027 */ /* J2000 z-velocity (km/s): -0.29446934336246899 */ /* One-way light time (s): 1.3438080956559786 */ /* Light time rate: 1.00673403630050830E-007 */ /* $ Restrictions */ /* 1) The routine SPKGEO should be used instead of this routine */ /* to compute geometric states. SPKGEO introduces less */ /* round-off error when the observer and target have common */ /* center that is closer to both objects than is the solar */ /* system barycenter. */ /* 2) The kernel files to be used by SPKLTC must be loaded */ /* (normally by the SPICELIB kernel loader FURNSH) before */ /* this routine is called. */ /* 3) Unlike most other SPK state computation routines, this */ /* routine requires that the output state be relative to an */ /* inertial reference frame. */ /* $ Literature_References */ /* None. */ /* $ Author_and_Institution */ /* N.J. Bachman (JPL) */ /* $ Version */ /* - SPICELIB Version 2.0.0, 04-JUL-2014 (NJB) */ /* Discussion of light time corrections was updated. Assertions */ /* that converged light time corrections are unlikely to be */ /* useful were removed. */ /* Last update was 02-MAY-2012 (NJB) */ /* Updated to ensure convergence when CN or XCN light time */ /* corrections are used. The new algorithm also terminates early */ /* (after fewer than three iterations) when convergence is */ /* attained. */ /* Call to ZZPRSCOR was replaced by a call to ZZVALCOR. */ /* - SPICELIB Version 1.0.0, 11-JAN-2008 (NJB) */ /* -& */ /* $ Index_Entries */ /* low-level light time correction */ /* light-time corrected state from spk file */ /* get light-time corrected state */ /* -& */ /* $ Revisions */ /* None. */ /* -& */ /* SPICELIB functions */ /* Local parameters */ /* TOL is the tolerance used for a division-by-zero test */ /* performed prior to computation of DLT. */ /* Convergence limit: */ /* Maximum number of light time iterations for any */ /* aberration correction: */ /* Local variables */ /* Saved variables */ /* Initial values */ /* Standard SPICE error handling. */ if (return_()) { return 0; } else { chkin_("SPKLTC", (ftnlen)6); } if (pass1 || s_cmp(abcorr, prvcor, abcorr_len, (ftnlen)5) != 0) { /* The aberration correction flag differs from the value it */ /* had on the previous call, if any. Analyze the new flag. */ zzvalcor_(abcorr, attblk, abcorr_len); if (failed_()) { chkout_("SPKLTC", (ftnlen)6); return 0; } /* The aberration correction flag is recognized; save it. */ s_copy(prvcor, abcorr, (ftnlen)5, abcorr_len); /* Set logical flags indicating the attributes of the requested */ /* correction: */ /* XMIT is .TRUE. when the correction is for transmitted */ /* radiation. */ /* USELT is .TRUE. when any type of light time correction */ /* (normal or converged Newtonian) is specified. */ /* USECN indicates converged Newtonian light time correction. */ /* The above definitions are consistent with those used by */ /* ZZVALCOR. */ xmit = attblk[4]; uselt = attblk[1]; usecn = attblk[3]; usestl = attblk[2]; pass1 = FALSE_; } /* See if the reference frame is a recognized inertial frame. */ irfnum_(ref, &refid, ref_len); if (refid == 0) { setmsg_("The requested frame '#' is not a recognized inertial frame. " , (ftnlen)60); errch_("#", ref, (ftnlen)1, ref_len); sigerr_("SPICE(BADFRAME)", (ftnlen)15); chkout_("SPKLTC", (ftnlen)6); return 0; } /* Find the geometric state of the target body with respect to */ /* the solar system barycenter. Subtract the state of the */ /* observer to get the relative state. Use this to compute the */ /* one-way light time. */ spkgeo_(targ, et, ref, &c__0, ssbtrg, &ssblt, ref_len); if (failed_()) { chkout_("SPKLTC", (ftnlen)6); return 0; } vsubg_(ssbtrg, stobs, &c__6, starg); dist = vnorm_(starg); *lt = dist / clight_(); if (*lt == 0.) { /* This can happen only if the observer and target are at the */ /* same position. We don't consider this an error, but we're not */ /* going to compute the light time derivative. */ *dlt = 0.; chkout_("SPKLTC", (ftnlen)6); return 0; } if (! uselt) { /* This is a special case: we're not using light time */ /* corrections, so the derivative */ /* of light time is just */ /* (1/c) * d(VNORM(STARG))/dt */ *dlt = vdot_(starg, &starg[3]) / (dist * clight_()); /* LT and DLT are both set, so we can return. */ chkout_("SPKLTC", (ftnlen)6); return 0; } /* To correct for light time, find the state of the target body */ /* at the current epoch minus the one-way light time. Note that */ /* the observer remains where it is. */ /* Determine the sign of the light time offset. */ if (xmit) { ltsign = 1; } else { ltsign = -1; } /* Let NUMITR be the number of iterations we'll perform to */ /* compute the light time. */ if (usecn) { numitr = 5; } else { numitr = 1; } i__ = 0; lterr = 1.; while(i__ < numitr && lterr > 1e-17) { /* LT was set either prior to this loop or */ /* during the previous loop iteration. */ epoch = *et + ltsign * *lt; spkgeo_(targ, &epoch, ref, &c__0, ssbtrg, &ssblt, ref_len); if (failed_()) { chkout_("SPKLTC", (ftnlen)6); return 0; } vsubg_(ssbtrg, stobs, &c__6, starg); prvlt = *lt; d__1 = vnorm_(starg) / clight_(); *lt = touchd_(&d__1); /* LTERR is the magnitude of the change between the current */ /* estimate of light time and the previous estimate, relative to */ /* the previous light time corrected epoch. */ /* Computing MAX */ d__3 = 1., d__4 = abs(epoch); d__2 = (d__1 = *lt - prvlt, abs(d__1)) / max(d__3,d__4); lterr = touchd_(&d__2); ++i__; } /* At this point, STARG contains the light time corrected */ /* state of the target relative to the observer. */ /* Compute the derivative of light time with respect */ /* to time: dLT/dt. Below we derive the formula for */ /* this quantity for the reception case. Let */ /* POBS be the position of the observer relative to the */ /* solar system barycenter. */ /* VOBS be the velocity of the observer relative to the */ /* solar system barycenter. */ /* PTARG be the position of the target relative to the */ /* solar system barycenter. */ /* VTARG be the velocity of the target relative to the */ /* solar system barycenter. */ /* S be the sign of the light time correction. S is */ /* negative for the reception case. */ /* The light-time corrected position of the target relative to */ /* the observer at observation time ET, given the one-way */ /* light time LT is: */ /* PTARG(ET+S*LT) - POBS(ET) */ /* The light-time corrected velocity of the target relative to */ /* the observer at observation time ET is */ /* VTARG(ET+S*LT)*( 1 + S*d(LT)/d(ET) ) - VOBS(ET) */ /* We need to compute dLT/dt. Below, we use the facts that, */ /* for a time-dependent vector X(t), */ /* ||X|| = <X,X> ** (1/2) */ /* d(||X||)/dt = (1/2)<X,X>**(-1/2) * 2 * <X,dX/dt> */ /* = <X,X>**(-1/2) * <X,dX/dt> */ /* = <X,dX/dt> / ||X|| */ /* Newtonian light time equation: */ /* LT = (1/c) * || PTARG(ET+S*LT) - POBS(ET)|| */ /* Differentiate both sides: */ /* dLT/dt = (1/c) * ( 1 / || PTARG(ET+S*LT) - POBS(ET) || ) */ /* * < PTARG(ET+S*LT) - POBS(ET), */ /* VTARG(ET+S*LT)*(1+S*d(LT)/d(ET)) - VOBS(ET) > */ /* = (1/c) * ( 1 / || PTARG(ET+S*LT) - POBS(ET) || ) */ /* * ( < PTARG(ET+S*LT) - POBS(ET), */ /* VTARG(ET+S*LT) - VOBS(ET) > */ /* + < PTARG(ET+S*LT) - POBS(ET), */ /* VTARG(ET+S*LT) > * (S*d(LT)/d(ET)) ) */ /* Let */ /* A = (1/c) * ( 1 / || PTARG(ET+S*LT) - POBS(ET) || ) */ /* B = < PTARG(ET+S*LT) - POBS(ET), VTARG(ET+S*LT) - VOBS(ET) > */ /* C = < PTARG(ET+S*LT) - POBS(ET), VTARG(ET+S*LT) > */ /* Then */ /* d(LT)/d(ET) = A * ( B + C * S*d(LT)/d(ET) ) */ /* which implies */ /* d(LT)/d(ET) = A*B / ( 1 - S*C*A ) */ a = 1. / (clight_() * vnorm_(starg)); b = vdot_(starg, &starg[3]); c__ = vdot_(starg, &ssbtrg[3]); /* For physically realistic target velocities, S*C*A cannot equal 1. */ /* We'll check for this case anyway. */ if (ltsign * c__ * a > .99999999989999999) { setmsg_("Target range rate magnitude is approximately the speed of l" "ight. The light time derivative cannot be computed.", (ftnlen) 110); sigerr_("SPICE(DIVIDEBYZERO)", (ftnlen)19); chkout_("SPKLTC", (ftnlen)6); return 0; } /* Compute DLT: the rate of change of light time. */ *dlt = a * b / (1. - ltsign * c__ * a); /* Overwrite the velocity portion of the output state */ /* with the light-time corrected velocity. */ d__1 = ltsign * *dlt + 1.; vlcom_(&d__1, &ssbtrg[3], &c_b19, &stobs[3], &starg[3]); chkout_("SPKLTC", (ftnlen)6); return 0; } /* spkltc_ */