 
In-situ Sensing Hands-On Lesson (IDL)
===========================================================================
 
     October 14, 2004
 
 
Overview
--------------------------------------------------------
 
     In this lesson you will develop a simple program illustrating how
     SPICE can be used to compute various kinds of geometry information
     applicable to the experiments carried out by an in-situ instrument
     flown on an interplanetary spacecraft.
 
 
References
--------------------------------------------------------
 
     This section provides a list of SPICE documents that are referred to
     in this lesson.
 
     Of these documents, the ``Tutorials'' contains the highest level
     descriptions with the least number of details while the ``Required
     Reading'' documents contain much more detailed specifications. The
     most complete specifications are provided in the ``Headers'' -- the
     comments in the top section of the source file.
 
     In some cases the lesson explanations also refer to the information
     provided in the meta-data area of the kernels used in the lesson
     examples. It is especially true in case of the FK and IK files, which
     often contain comprehensive descriptions of the frames, instrument
     FOVs, etc. Since both FK and IK are text kernels, the information
     provided in them can be viewed using any text editor, while the meta
     information provided in binary kernels -- SPKs and CKs -- can be
     viewed using ``commnt'' or ``spacit'' utility programs located in
     ``icy/exe'' of Toolkit installation tree.
 
 
Tutorials
 
     The following SPICE tutorials are referred to by the explanation
     provided in this lesson:
 
        Name             Lesson steps/routines that it describes
        ---------------  -----------------------------------------
        Time             UTC to ET and SCLK to ET
        Loading Kernels  Loading SPICE kernels
        SCLK             SCLK to ET time conversion
        SPK              Computing positions and velocities
        Frames           Computing transformations between frames
 
     These tutorials are available in printed form and as MS Office or PDF
     files from NAIF server at JPL:
 
        ftp://naif.jpl.nasa.gov/pub/naif/toolkit_docs/Tutorials
 
 
Required Reading Documents
 
     The Required Reading documents are provided with the Toolkit and are
     located in ``icy/doc'' directory of the Toolkit installation trees.
 
        Name             Lesson steps/routines that it describes
        ---------------  -----------------------------------------
        time.req         UTC to ET time conversion
        kernel.req       Loading SPICE kernels
        sclk.req         SCLK to ET time conversion
        naif_ids.req     Body and reference frame names
        spk.req          Computing positions and velocities
 
     Another very useful document, also distributed with the Toolkit, is
     ``Permuted Index'', called ``spicelib.idx'' for FORTRAN or
     ``cspice.idx'' for C and IDL located under ``doc'' directory in the
     Toolkit installation tree.
 
     This text document provides an easy way to find what SPICE routine(s)
     performs a particular function of interest and the name of the source
     file that contains this function (this is especially useful for
     FORTRAN because some of the routines are entry points and, therefore,
     their name is different from the name of the source file in which they
     are located.)
 
 
Icy API Documentation
 
     An Icy routine's specification is found in the API documentation page
     located under ``icy/doc/html/icy''.
 
     For example, the document
 
        icy/doc/html/icy/cspice_str2et.html
 
     describes the cspice_str2et routine.
 
 
Kernels Used
--------------------------------------------------------
 
     The following kernels are used in examples provided in this lesson:
 
        File Name                 Type Description
        ------------------------- ---- --------------------------
        naif0007.tls              LSK  Generic LSK
        cpck05Mar2004.tpc         PCK  Cassini project PCK
        cas00084.tsc              SCLK Cassini SCLK
        020514_SE_SAT105.bsp      SPK  Saturnian Satellite Ephemeris SPK
        030201AP_SK_SM546_T45.bsp SPK  Cassini Spacecraft SPK
        981005_PLTEPH-DE405S.bsp  SPK  Planetary Ephemeris SPK
        sat128.bsp                SPK  Saturnian Satellite Ephemeris SPK
        04135_04171pc_psiv2.bc    CK   Cassini Spacecraft CK
        cas_v37.tf                FK   Cassini FK
 
     These kernels are available from the NAIF server at JPL:
 
        ftp://naif.jpl.nasa.gov/pub/naif/CASSINI/kernels
 
 
ICY Routines Used
--------------------------------------------------------
 
     The example provided in this lesson uses the following ICY routines:
 
        Name             Function that it performs
        ----------       ----------------------------------------------
        cspice_furnsh    Loads kernels, individually or listed in
                         meta-kernel
        cspice_str2et    Converts UTC to ET
        cspice_scs2e     Converts SCLK to ET
        cspice_spkezr    Computes states (position & velocity)
        cspice_spkpos    Computes positions
        cspice_vhat      Find unit vector along a 3d vector
        cspice_subpt     Computes body-fixed coordinates of sub-observer
                         point
        cspice_reclat    Converts rectangular coordinated to latitudinal
        cspice_vsub      Subtracts 3d vectors
        cspice_pxform    Computes 3x3 matrix rotating vectors between
                         frames
        cspice_mxv       Multiplies 3d vector by 3x3 matrix
 
 
Step-1: ``UTC to ET''
===========================================================================
 
 
``UTC to ET'' Task Statement
--------------------------------------------------------
 
     Write a program that computes and prints Ephemeris Time (ET),
     expressed as the number of ephemeris seconds past J2000, that
     corresponds to ``2004-06-11T19:32:00'' UTC.
 
 
``UTC to ET'' Hints
--------------------------------------------------------
 
     Find out what SPICE kernel(s) is(are) needed to support this
     conversion. Look at the ``time.req'' and/or ``Time'' tutorial.
 
     Find necessary kernel(s) on the NAIF's FTP site.
 
     Find out what routine should be called to load necessary kernel(s).
     Look at the ``kernel.req'' and/or ``Loading Kernels'' tutorial.
 
     Find the ``loader'' routine calling sequence specification. Look at
     the ``time.req'' and that routine's source code header. This routine
     may be an entry point, in which case there will be no source file with
     the same name. To find out in which source file this entry point is,
     search for its name in the ``Permuted Index''.
 
     Find the routine(s) used to convert time between UTC and ET. Look at
     the ``time.req'' and/or ``Time'' tutorial.
 
     Find the ``converter'' routine(s) calling sequence specification. Look
     in the ``time.req'' and the routine's source code header.
 
     Put all calls together in a program, add variable declarations (the
     routine header's ``Declarations'' and ``Examples'' sections are a good
     place to look for declaration specification and examples) and output
     print statements. Compile it and link it against ICY.
 
 
``UTC to ET'' Solution Steps
--------------------------------------------------------
 
     Only one kernel file is needed to support this conversion -- an LSK
     file ``naif0007.tls''.
 
     As any other SPICE kernel this file can be loaded by the cspice_furnsh
     routine. For that, the name of the file can put be provided as a sole
     argument of this routine:
 
        ...
        lskfle =  'naif0007.tls'
 
        cspice_furnsh, lskfle
 
     or it can be listed in a meta-kernel:
 
        \begindata
           KERNELS_TO_LOAD = (
                             'kernels/lsk/naif0007.tls'
                             )
        \begintext
 
     the name of which, let's call it ``spice_example.mk'', can be then
     provided as a sole argument of the cspice_furnsh routine:
 
        ...
        mkfile = 'spice_example.mk'
 
        cspice_furnsh, mkfile
 
     While the second option seems to involve a bit more work -- it
     requires making an extra file -- it is a much better way to go if you
     plan to load more kernels as you extend the program. With the
     meta-kernel approach simply adding more kernels to the list in
     KERNEL_TO_LOAD without changing the program code will accomplish that.
 
     The highest level ICY time routine converting UTC to ET is
     cspice_str2et (``icy/doc/html/icy/cspice_str2et.html'').
 
     It has two arguments -- input time string representing UTC in a
     variety of formats (see cspice_str2et header's section ``Particulars''
     for the complete description of input time formats) and output DP
     number of ET seconds past J2000. A call to cspice_str2et converting a
     given UTC to ET could look like this:
 
        utc = '2004-06-11T19:32:00'
        ...
        cspice_str2et, utc, et
 
     By combining cspice_furnsh and cspice_str2et calls and required
     declarations and by adding a simple print statement, one would get a
     complete program that prints ET for the given UTC epoch.
 
     The program's source code then needs to be compiled and linked against
     ICY. Assuming that the program was saved in a file called
     "spice_example.pro", this can be done with the following IDL command
     (the command below assumes that the library file(s) ``icy.so'' and the
     IDL dlm file ``icy.dlm'' are located in current directory, which may
     not be the case):
 
        $ idl
 
        IDL> .compile spice_example.pro
 
     When you run the compiled script, ``spice_example'', it will produce
     the following output (the output below was generated by this script
     compiled on a OS X; your output may differ slightly in its format and
     numeric precision):
 
        IDL > spice_example
        utc  = 2004-06-11T19:32:00
        et   =     140254384.184625
        IDL >
 
 
``UTC to ET'' Code
--------------------------------------------------------
 
     Program ``spice_example.pro'':
 
        PRO spice_example
 
           mkfile  =  'spice_example.mk'
           cspice_furnsh, mkfile
 
           utc     =  '2004-06-11T19:32:00'
           cspice_str2et, utc, et
 
           print,                      "utc  = ", utc
           print, FORMAT='(A7,F20.6)', "et   = ", et
 
           cspice_unload, mkfile
 
        END
 
     Meta-kernel file ``spice_example.mk'':
 
        \begindata
           KERNELS_TO_LOAD = (
                             'kernels/lsk/naif0007.tls'
                             )
        \begintext
 
 
Step-2: ``SCLK to ET''
===========================================================================
 
 
``SCLK to ET'' Task Statement
--------------------------------------------------------
 
     Extend the program from Step-1 to compute and print ET for the
     following CASSINI on-board clock epoch ``1465674964.105''.
 
 
``SCLK to ET'' Hints
--------------------------------------------------------
 
     Find out what additional (to those already loaded in Step-1) SPICE
     kernel(s) is(are) needed to support SCLK to ET conversion. Look at the
     ``sclk.req'' and/or ``SCLK'' tutorial.
 
     Find necessary kernel(s) on the NAIF's FTP site.
 
     Modify the program or meta-kernel to load this(these) kernels.
 
     Find the routine(s) that is(are) used to convert time between SCLK and
     ET. Look at the ``sclk.req'' and/or ``Time'' and ``SCLK'' tutorials.
 
     Find the ``converter'' routine's calling sequence specification. Look
     in the ``sclk.req'' and the routine's source code header.
 
     Look at ``naif_ids.req'' and the comments in the additional kernel(s)
     that you have loaded for information on proper values of input
     arguments of this routine.
 
     Add calls to the ``converter'' routine(s), necessary variable
     declarations (the routine header's ``Declarations'' and ``Examples''
     sections are a good place to look for declaration specification and
     examples), and output print statements to the program. Re-compile and
     re-link it against ICY.
 
 
``SCLK to ET'' Solution Steps
--------------------------------------------------------
 
     A CASSINI SCLK file is needed additionally to the LSK file loaded in
     the Step-1 to support this conversion.
 
     No code change is needed in the loading portion of the program if a
     meta-kernel approach was used in the Step-1. The program will load the
     file if it will be added to the list of kernels in the KERNELS_TO_LOAD
     variable:
 
        \begindata
           KERNELS_TO_LOAD = (
                             'kernels/lsk/naif0007.tls'
                             'kernels/sclk/cas00084.tsc'
                             )
        \begintext
 
     The highest level ICY routine converting SCLK to ET is cspice_scs2e
     (``icy/doc/html/icy/cspice_scs2e.html'').
 
     It has three arguments -- NAIF ID for CASSINI s/c (-82 as described by
     ``naif_ids.req'' document), input time string representing CASSINI
     SCLK, and output DP number of ET seconds past J2000. A call to
     cspice_str2et converting given SCLK to ET could look like this:
 
        scid   = -82
        sclk   = '1465674964.105'
        ...
        cspice_scs2e, scid, sclk, et
 
     By adding the cspice_scs2e call, required declarations and a simple
     print statement, one would get a complete program that prints ET for
     the given SCLK epoch.
 
     The program's source code then needs to be re-compiled and re-linked
     against ICY. It can be done using the same compile command as in
     Step-1:
 
        $ idl
 
        IDL> .compile spice_example.pro
 
     When you run the compiled script, ``spice_example'', it will produce
     the following output (the output below was generated by this script
     compiled on a OS X; your output may differ slightly in its format and
     numeric precision):
 
        IDL > spice_example
        utc  = 2004-06-11T19:32:00
        et   =     140254384.184625
        sclk = 1465674964.105
        et   =     140254384.183426
        IDL >
 
 
``SCLK to ET'' Code
--------------------------------------------------------
 
     Program ``spice_example.pro'':
 
        PRO spice_example
 
           mkfile  =  'spice_example.mk'
           cspice_furnsh, mkfile
 
           utc     =  '2004-06-11T19:32:00'
           cspice_str2et, utc, et
 
           print,                      "utc  = ", utc
           print, FORMAT='(A7,F20.6)', "et   = ", et
 
           scid   = -82
           sclk   = '1465674964.105'
           cspice_scs2e, scid, sclk, et
 
           print,                      "sclk = ", sclk
           print, FORMAT='(A7,F20.6)', "et   = ", et
 
           cspice_unload, mkfile
 
        END
 
     Meta-kernel file ``spice_example.mk'':
 
        \begindata
           KERNELS_TO_LOAD = (
                             'kernels/lsk/naif0007.tls'
                             'kernels/sclk/cas00084.tsc'
                             )
        \begintext
 
 
Step-3: ``Spacecraft State''
===========================================================================
 
 
``Spacecraft State'' Task Statement
--------------------------------------------------------
 
     Extend the program from Step-2 to compute geometric state -- position
     and velocity -- of the CASSINI spacecraft with respect to the Sun in
     Ecliptic frame at the epoch specified by SCLK time from Step-2.
 
 
``Spacecraft State'' Hints
--------------------------------------------------------
 
     Find out what additional (to those already loaded in Steps-1&2) SPICE
     kernel(s) is(are) needed to support state computation. Look at the
     ``spk.req'' and/or ``SPK'' tutorial.
 
     Find necessary kernel(s) on the NAIF's FTP site.
 
     Verify that the kernels contain enough data to compute the state of
     interest. Use ``brief'' utility program located under ``toolkit/exe''
     directory for that.
 
     Modify the meta-kernel to load this(these) kernels.
 
     Find the routine(s) that is(are) used to compute states. Look at the
     ``spk.req'' and/or ``SPK'' tutorial presentation.
 
     Find the the routine(s) calling sequence specification. Look in the
     ``spk.req'' and the routine's source code header.
 
     Look at the ``naif_ids.req'' and ``frames.req'' and the routine(s)
     header ``Inputs'' and ``Particulars'' sections to determine proper
     values of the input arguments of this routine.
 
     Add calls to the routine(s), necessary variable declarations and
     output print statements to the program. Re-compile and re-link it
     against ICY.
 
 
``Spacecraft State'' Solution Steps
--------------------------------------------------------
 
     A CASSINI spacecraft trajectory SPK and generic planetary ephemeris
     SPK files are needed to support computation of the state of interest.
 
     The file names can be added to the meta-kernel to get them loaded into
     the program:
 
        \begindata
           KERNELS_TO_LOAD = (
                             'kernels/lsk/naif0007.tls'
                             'kernels/sclk/cas00084.tsc'
                             'kernels/spk/020514_SE_SAT105.bsp'
                             'kernels/spk/030201AP_SK_SM546_T45.bsp'
                             'kernels/spk/981005_PLTEPH-DE405S.bsp'
                             'kernels/spk/sat128.bsp'
                             )
        \begintext
 
     The highest level ICY routine computing states is cspice_spkezr
     (``icy/doc/html/icy/cspice_spkezr.html'').
 
     We are interested in computing CASSINI position and velocity with
     respect to the Sun, therefore the target and observer names should be
     set to 'CASSINI' and 'Sun' (both names can be found in
     ``naif_ids.req'').
 
     The state should be in ecliptic frame, therefore the name of the frame
     in which the state should be computed is 'ECLIPJ2000' (see
     ``frames.req'' document.)
 
     Since the geometric position is sought for, the abcorr argument of the
     routine should be set to 'NONE' (see aberration correction discussion
     in the (``icy/src/cspice/spkezr_c.c''). header).
 
     Putting it all together, we get:
 
        target = 'CASSINI'
        frame  = 'ECLIPJ2000'
        corrtn = 'NONE'
        observ = 'SUN'
 
        cspice_spkezr, target, et, frame, corrtn, observ, state, ltime
 
     The updated program with added calls, required declarations and a
     simple print statements produces the following output (the output
     below was generated by this script compiled on a OS X; your output may
     differ slightly in its format and numeric precision):
 
        IDL> spice_example
        utc  = 2004-06-11T19:32:00
        et   =     140254384.184625
        sclk = 1465674964.105
        et   =     140254384.183426
        state =   -3.7659906e+08   1.2944878e+09      -7064853.1
              -5.1642262   0.80171891     0.040603057
        IDL >
 
 
``Spacecraft State'' Code
--------------------------------------------------------
 
     Program
 
        PRO spice_example
 
           mkfile  =  'spice_example.mk'
           cspice_furnsh, mkfile
 
           utc     =  '2004-06-11T19:32:00'
           cspice_str2et, utc, et
 
           print,                      "utc  = ", utc
           print, FORMAT='(A7,F20.6)', "et   = ", et
 
           scid   = -82
           sclk   = '1465674964.105'
           cspice_scs2e, scid, sclk, et
 
           print,                      "sclk = ", sclk
           print, FORMAT='(A7,F20.6)', "et   = ", et
 
           target = 'CASSINI'
           frame  = 'ECLIPJ2000'
           corrtn = 'NONE'
           observ = 'SUN'
 
           cspice_spkezr, target, et, frame, corrtn, observ, state, ltime
 
           print, 'state = ', state
 
           cspice_unload, mkfile
 
        END
 
     Meta-kernel file ``spice_example.mk'':
 
        \begindata
           KERNELS_TO_LOAD = (
                             'kernels/lsk/naif0007.tls'
                             'kernels/sclk/cas00084.tsc'
                             'kernels/spk/020514_SE_SAT105.bsp'
                             'kernels/spk/030201AP_SK_SM546_T45.bsp'
                             'kernels/spk/981005_PLTEPH-DE405S.bsp'
                             'kernels/spk/sat128.bsp'
                             )
        \begintext
 
 
Step-4: ``Sun Direction''
===========================================================================
 
 
``Sun Direction'' Task Statement
--------------------------------------------------------
 
     Extend the program from Step-3 to compute apparent direction of the
     Sun in the INMS frame at the epoch specified by SCLK time from Step-2.
 
 
``Sun Direction'' Hints
--------------------------------------------------------
 
     Find out what additional (to those already loaded in previous steps)
     SPICE kernel(s) is(are) needed to support the direction computation,
     knowing that they should provide the s/c and instrument frame
     orientation. Get these kernels from the NAIF's FTP site.
 
     Verify that the orientation data in the kernels have adequate coverage
     to support computation of the direction of interest. Use ``ckbrief''
     utility program located under ``toolkit/exe'' directory for that.
 
     Modify the meta-kernel to load this(these) kernels.
 
     Determine which input arguments should used in the call to
     cspice_spkpos in order to compute this direction (which is the
     position portion of the output state). Look through the Frames Kernel
     find the name of the frame to used.
 
     Add calls to the routine(s), necessary variable declarations and
     output print statements to the program. Re-compile and re-link it
     against ICY.
 
 
``Sun Direction'' Solution Steps
--------------------------------------------------------
 
     A CASSINI spacecraft orientation CK file, providing s/c orientation
     with respect to an inertial frame, and CASSINI FK file, providing
     orientation of the INMS frame with respect to the s/ frame, are needed
     additionally to already loaded kernels to support computation of this
     direction.
 
     The file names can be added to the meta-kernel to get them loaded into
     the program:
 
        \begindata
           KERNELS_TO_LOAD = (
                             'kernels/lsk/naif0007.tls'
                             'kernels/sclk/cas00084.tsc'
                             'kernels/spk/020514_SE_SAT105.bsp'
                             'kernels/spk/030201AP_SK_SM546_T45.bsp'
                             'kernels/spk/981005_PLTEPH-DE405S.bsp'
                             'kernels/spk/sat128.bsp'
                             'kernels/ck/04135_04171pc_psiv2.bc'
                             'kernels/fk/cas_v37.tf'
                             )
        \begintext
 
     The same highest level ICY routine computing positions, cspice_spkpos,
     can be used to compute this direction.
 
     Since this is the direction of the Sun as seen from the s/c, the
     target argument should be set to 'Sun' and the observer argument
     should be set to 'CASSINI'. The name of the INMS frame is
     'CASSINI_INMS', the definition and description of this frame are
     provided in the CASSINI FK file, ``cassini_v02.tf''.
 
     Since the apparent, or ``as seen'', position is sought for, the abcorr
     argument of the routine should be set to 'LT+S' (see aberration
     correction discussion in the (``icy/src/cspice/spkpos_c.c'') header).
 
     If desired, the position can then be turned into a unit vector using
     cspice_vhat routine (``icy/doc/html/icy/cspice_vhat.html''). Putting
     it all together, we get:
 
        target = 'SUN'
        frame  = 'CASSINI_INMS'
        corrtn = 'LT+S'
        observ = 'CASSINI'
 
        cspice_spkpos, target, et, frame, corrtn, observ, sundir, ltime
        cspice_vhat, sundir, sundir
 
     The updated program with added calls, required declarations and a
     simple print statements produces the following output (the output
     below was generated by this script compiled on a OS X; your output may
     differ slightly in its format and numeric precision):
 
        IDL> spice_example
        utc  = 2004-06-11T19:32:00
        et   =     140254384.184625
        sclk = 1465674964.105
        et   =     140254384.183426
        state =   -3.7659906e+08   1.2944878e+09      -7064853.1
              -5.1642262   0.80171891     0.040603057
        sundir =      -0.29020402      0.88163119      0.37216673
        IDL >
 
 
``Sun Direction'' Code
--------------------------------------------------------
 
     Program ``spice_example.pro'':
 
        PRO spice_example
 
           mkfile  =  'spice_example.mk'
           cspice_furnsh, mkfile
 
           utc     =  '2004-06-11T19:32:00'
           cspice_str2et, utc, et
 
           print,                      "utc  = ", utc
           print, FORMAT='(A7,F20.6)', "et   = ", et
 
           scid   = -82
           sclk   = '1465674964.105'
           cspice_scs2e, scid, sclk, et
 
           print,                      "sclk = ", sclk
           print, FORMAT='(A7,F20.6)', "et   = ", et
 
           target = 'CASSINI'
           frame  = 'ECLIPJ2000'
           corrtn = 'NONE'
           observ = 'SUN'
 
           cspice_spkezr, target, et, frame, corrtn, observ, state, ltime
 
           print, "state = ", state
 
           target = 'SUN'
           frame  = 'CASSINI_INMS'
           corrtn = 'LT+S'
           observ = 'CASSINI'
 
           cspice_spkpos, target, et, frame, corrtn, observ, sundir, ltime
           cspice_vhat, sundir, sundir
 
           print, "sundir = ", sundir
 
           cspice_unload, mkfile
 
        END
 
     Meta-kernel file ``spice_example.mk'':
 
        \begindata
           KERNELS_TO_LOAD = (
                             'kernels/lsk/naif0007.tls'
                             'kernels/sclk/cas00084.tsc'
                             'kernels/spk/020514_SE_SAT105.bsp'
                             'kernels/spk/030201AP_SK_SM546_T45.bsp'
                             'kernels/spk/981005_PLTEPH-DE405S.bsp'
                             'kernels/spk/sat128.bsp'
                             'kernels/ck/04135_04171pc_psiv2.bc'
                             'kernels/fk/cas_v37.tf'
                             )
        \begintext
 
 
Step-5: ``Sub-Spacecraft Point''
===========================================================================
 
 
``Sub-Spacecraft Point'' Task Statement
--------------------------------------------------------
 
     Extend the program from Step-4 to compute planetocentric longitude and
     and latitude of the sub-spacecraft point and the direction from the
     spacecraft to that point in the INMS frame.
 
 
``Sub-Spacecraft Point'' Hints
--------------------------------------------------------
 
     Find the ICY routine that computes sub-observer point coordinates. Use
     ``Permuted Index'' or ``subpt'' cookbook program for that.
 
     Refer to the routine's header to determine which additional kernels
     should be loaded to support this direction computation. Get these
     kernels from the NAIF's FTP site. Modify the meta-kernel to load
     this(these) kernels.
 
     Determine which input arguments should used in the call to this
     routine. Use the routine's header for that.
 
     Convert Cartesian vector returned by this routine to latitudinal
     coordinates. Use ``Permuted Index'' to find the routine that does this
     conversion. Refer to the routine's header for input/output argument
     specifications.
 
     Given that the direction from the spacecraft to the sub-spacecraft
     point is the difference between the sub-point position vector (which
     you already have) and the spacecraft position vector (which you don't
     have), compute the spacecraft position vector in the same frame
     (Phoebe body-fixed frame) using cspice_spkpos and subtract the two
     vectors. Use ``frames.req'' and/or ``Frames'' tutorial to find the
     name of the frame to be used in cspice_spkpos call.
 
     Since the difference vector is computed in the Phoebe body-fixed
     frame, it should be transformed into the instrument frame get the
     direction we are looking for. Refer to ``frames.req'' and/or
     ``Frames'' tutorial to determine the name of the routine computing
     transformations and use it to compute transformation from Phoebe
     body-fixed to the INMS frame.
 
     Using ``Permuted Index'' find the routine that multiplies 3x3 matrix
     by 3d vector and use it to rotate the difference vector to the
     instrument frame.
 
     Add calls to the routine(s), necessary variable declarations and
     output print statements to the program. Re-compile and re-link it
     against ICY.
 
 
``Sub-Spacecraft Point'' Solution Steps
--------------------------------------------------------
 
     The cspice_subpt routine (``icy/doc/html/icy/cspice_subpt.html'') can
     be used to compute sub-observer point with a single call. To determine
     this point as the closest point on the Phoebe ellipsoid, the method
     argument has to be set to 'Near point'. For our case the target is
     'PHOEBE' and the observer is 'CASSINI'.
 
     Since the s/c is close to Phoebe, light time does not need to be taken
     into account and, therefore, the abcorr argument can be set to 'NONE'.
 
     In order for cspice_subpt to compute the nearest point location, a PCK
     file containing Phoebe radii has to be loaded into the program (see
     ``Files'' section of the routine's header.) All other files required
     for this computation are already being loaded by the program. With PCK
     file name added to it, the updated meta-kernel will look like this:
 
        \begindata
           KERNELS_TO_LOAD = (
                             'kernels/lsk/naif0007.tls'
                             'kernels/sclk/cas00084.tsc'
                             'kernels/spk/020514_SE_SAT105.bsp'
                             'kernels/spk/030201AP_SK_SM546_T45.bsp'
                             'kernels/spk/981005_PLTEPH-DE405S.bsp'
                             'kernels/spk/sat128.bsp'
                             'kernels/ck/04135_04171pc_psiv2.bc'
                             'kernels/fk/cas_v37.tf'
                             'kernels/pck/cpck05Mar2004.tpc'
                             )
        \begintext
 
     The sub-spacecraft point Cartesian vector can be converted to
     planetocentric radius, longitude and latitude using the cspice_reclat
     routine (``icy/doc/html/icy/cspice_reclat.html'').
 
     The other vector needed to compute direction from the spacecraft to
     the sub-spacecraft point -- the spacecraft position with respect to
     Phoebe -- can be computed using a call to cspice_spkpos. Note that
     both positions -- one of the sub-spacecraft point and the other of the
     spacecraft -- must be in the same frame in order to find the
     difference between them. Therefore, the frame in the cspice_spkpos
     call should be 'IAU_PHOEBE' which is ICY's built-in name for Phoebe
     body-fixed frame. The other arguments will be 'CASSINI' (TARG),
     'PHOEBE' (OBS), and 'NONE' (ABCORR), as the correction is also not
     essential in this case.
 
     The cspice_vsub routine (``icy/doc/html/icy/cspice_vsub.html'') can be
     used to subtract the spacecraft position from the sub-spacecraft point
     position.
 
     The computed difference vector has to be rotated from the body-fixed
     frame to the instrument frame. The name of the routine that computes
     3x3 matrices rotating vectors from one frame to another is
     cspice_pxform (``icy/doc/html/icy/cspice_pxform.html''). In our case
     the from argument should be set to 'IAU_PHOEBE' and the to argument
     should be set to 'CASSINI_INMS' The difference vector should be then
     multiplied by this matrix using cspice_mxv routine
     (``icy/doc/html/icy/cspice_mxv.html'') to rotate it to the instrument
     frame. Then, if desired, it can be unitized using the cspice_vhat
     routine.
 
     For output the longitude and latitude angles returned by cspice_reclat
     in radians can be converted to degrees by multiplying by cspice_dpr
     function (``icy/doc/html/icy/cspice_dpr.html''). Putting it all
     together, we get:
 
        method = 'NEAR POINT'
        target = 'PHOEBE'
        corrtn = 'NONE'
        observ = 'CASSINI'
 
        cspice_subpt, method, target, et, corrtn, observ, spoint, alt
 
        cspice_reclat, spoint, srad, slon, slat
 
        target = 'CASSINI'
        frame  = 'IAU_PHOEBE'
        corrtn = 'NONE'
        observ = 'PHOEBE'
 
        cspice_spkpos, target, et, frame, corrtn, observ, scpos, ltime
 
        cspice_vsub, spoint, scpos, sbpdir
 
        fromfr = 'IAU_PHOEBE'
        tofr   = 'CASSINI_INMS'
 
        cspice_pxform, fromfr, tofr, et, m2imat
 
        cspice_mxv,  m2imat, sbpdir, sbpdir
        cspice_vhat, sbpdir, sbpdir
 
        print, "alt    =  ", alt
        print, "lon    =  ", slon * cspice_dpr()
        print, "lat    =  ", slat * cspice_dpr()
        print, "sbpdir =  ", sbpdir
 
     The updated program with added calls, required declarations and a
     simple print statements produces the following output (the output
     below was generated by this script compiled on a OS X; your output may
     differ slightly in its format and numeric precision):
 
        IDL> spice_example
        utc  = 2004-06-11T19:32:00
        et   =     140254384.184625
        sclk = 1465674964.105
        et   =     140254384.183426
        state =   -3.7659906e+08   1.2944878e+09      -7064853.1
              -5.1642262   0.80171891     0.040603057
        sundir =      -0.29020402      0.88163119      0.37216673
        alt    =         2084.1129
        lon    =         23.423158
        lat    =         3.7097972
        sbpdir =    -0.00077620706     -0.99987320    -0.015905456
 
 
``Sub-Spacecraft Point'' Code
--------------------------------------------------------
 
     Program ``spice_example.pro'':
 
        PRO spice_example
 
           mkfile  =  'spice_example.mk'
           cspice_furnsh, mkfile
 
           utc     =  '2004-06-11T19:32:00'
           cspice_str2et, utc, et
 
           print,                      "utc  = ", utc
           print, FORMAT='(A7,F20.6)', "et   = ", et
 
           scid   = -82
           sclk   = '1465674964.105'
           cspice_scs2e, scid, sclk, et
 
           print,                      "sclk = ", sclk
           print, FORMAT='(A7,F20.6)', "et   = ", et
 
           target = 'CASSINI'
           frame  = 'ECLIPJ2000'
           corrtn = 'NONE'
           observ = 'SUN'
 
           cspice_spkezr, target, et, frame, corrtn, observ, state, ltime
 
           print, "state = ", state
 
           target = 'SUN'
           frame  = 'CASSINI_INMS'
           corrtn = 'LT+S'
           observ = 'CASSINI'
 
           cspice_spkpos, target, et, frame, corrtn, observ, sundir, ltime
           cspice_vhat, sundir, sundir
 
           print, "sundir = ", sundir
 
           method = 'NEAR POINT'
           target = 'PHOEBE'
           corrtn = 'NONE'
           observ = 'CASSINI'
 
           cspice_subpt, method, target, et, corrtn, observ, spoint, alt
 
           cspice_reclat, spoint, srad, slon, slat
 
           target = 'CASSINI';
           frame  = 'IAU_PHOEBE';
           corrtn = 'NONE';
           observ = 'PHOEBE';
 
           cspice_spkpos, target, et, frame, corrtn, observ, scpos, ltime
 
           cspice_vsub, spoint, scpos, sbpdir
 
           fromfr = 'IAU_PHOEBE'
           tofr   = 'CASSINI_INMS'
 
           cspice_pxform, fromfr, tofr, et, m2imat
 
           cspice_mxv,  m2imat, sbpdir, sbpdir
           cspice_vhat, sbpdir, sbpdir
 
           print, "alt    =  ", alt
           print, "lon    =  ", slon * cspice_dpr()
           print, "lat    =  ", slat * cspice_dpr()
           print, "sbpdir =  ", sbpdir
 
           cspice_unload, mkfile
 
        END
 
     Meta-kernel file ``spice_example.mk'':
 
        \begindata
           KERNELS_TO_LOAD = (
                             'kernels/lsk/naif0007.tls'
                             'kernels/sclk/cas00084.tsc'
                             'kernels/spk/020514_SE_SAT105.bsp'
                             'kernels/spk/030201AP_SK_SM546_T45.bsp'
                             'kernels/spk/981005_PLTEPH-DE405S.bsp'
                             'kernels/spk/sat128.bsp'
                             'kernels/ck/04135_04171pc_psiv2.bc'
                             'kernels/fk/cas_v37.tf'
                             'kernels/pck/cpck05Mar2004.tpc'
                             )
        \begintext
 
 
Step-6: ``Spacecraft Velocity''
===========================================================================
 
 
``Spacecraft Velocity'' Task Statement
--------------------------------------------------------
 
     Extend the program from Step-5 to compute the spacecraft velocity with
     respect to Phoebe in the INMS frame.
 
 
``Spacecraft Velocity'' Hints
--------------------------------------------------------
 
     Compute velocity of the spacecraft with respect to Phoebe in some
     inertial frame, for example J2000. Recall that velocity is the last
     three components of the state vector returned by cspice_spkezr.
 
     Since the velocity vector is computed in the inertial frame, it should
     be rotated to the instrument frame. Look at the previous step the
     routine that compute necessary rotation and rotate vectors.
 
     Add calls to the routine(s), necessary variable declarations and
     output print statements to the program. Re-compile and re-link it
     against ICY.
 
 
``Spacecraft Velocity'' Solution Steps
--------------------------------------------------------
 
     All kernels required for computations in this step are already being
     loaded by the program, therefore, the meta-kernel does not need to be
     changed.
 
     The spacecraft velocity vector is the last three components of the
     state returned by cspice_spkezr. To compute velocity of CASSINI with
     respect to Phoebe in the J2000 inertial frame the cspice_spkezr
     arguments should be set to 'CASSINI' (TARG), 'PHOEBE' (OBS), 'J2000'
     (REF) and 'NONE' (ABCORR).
 
     The computed velocity vector has to be rotated from the J2000 frame to
     the instrument frame. The cspice_pxform routine used in the previous
     step can be used to compute the rotation matrix needed for that. In
     this case the frame name arguments should be set to 'J2000' (FROM) and
     'CASSINI_INMS' (TO).
 
     As in the previous step the difference vector should be then
     multiplied by this matrix using the cspice_mxv routine. Then, if
     desired, it can be unitize using the cspice_vhat routine.
 
     Putting it all together, we get:
 
           target = 'CASSINI'
           frame  = 'J2000'
           corrtn = 'NONE'
           observ = 'PHOEBE'
 
           cspice_spkezr, target, et, frame, corrtn, observ, state, ltime
           scvdir = state[3:5]
 
           fromfr = 'J2000'
           tofr   = 'CASSINI_INMS'
           cspice_pxform, fromfr, tofr, et, j2imat
 
           cspice_mxv, j2imat, scvdir, scvdir
           cspice_vhat, scvdir, scvdir
 
           print, "scvdir = ", scvdir[0:2]
 
     The updated program with added calls, required declarations and a
     simple print statements produces the following output (the output
     below was generated by this script compiled on a OS X; your output may
     differ slightly in its format and numeric precision):
 
        IDL> spice_example
        utc  = 2004-06-11T19:32:00
        et   =     140254384.184625
        sclk = 1465674964.105
        et   =     140254384.183426
        state =   -3.7659906e+08   1.2944878e+09      -7064853.1
              -5.1642262   0.80171891     0.040603057
        sundir =      -0.29020402      0.88163119      0.37216673
        alt    =         2084.1129
        lon    =         23.423158
        lat    =         3.7097972
        sbpdir =    -0.00077620706     -0.99987320    -0.015905456
        scvdir =       0.39578487     -0.29280767      0.87041255
        IDL>
 
     Note that computing the spacecraft velocity in the instrument frame by
     a single call to cspice_spkezr by specifying 'CASSINI_INMS' in the ref
     argument will produce an incorrect result. Such computation will take
     into account the spacecraft angular velocity from the CK files, which
     should not be considered in this case.
 
 
``Spacecraft Velocity'' Code Program ``spice_example.pro'':
--------------------------------------------------------
 
        PRO spice_example
 
           mkfile  =  'spice_example.mk'
           cspice_furnsh, mkfile
 
           utc     =  '2004-06-11T19:32:00'
           cspice_str2et, utc, et
 
           print,                      "utc  = ", utc
           print, FORMAT='(A7,F20.6)', "et   = ", et
 
           scid   = -82
           sclk   = '1465674964.105'
           cspice_scs2e, scid, sclk, et
 
           print,                      "sclk = ", sclk
           print, FORMAT='(A7,F20.6)', "et   = ", et
 
           target = 'CASSINI'
           frame  = 'ECLIPJ2000'
           corrtn = 'NONE'
           observ = 'SUN'
 
           cspice_spkezr, target, et, frame, corrtn, observ, state, ltime
 
           print, "state = ", state
 
           target = 'SUN'
           frame  = 'CASSINI_INMS'
           corrtn = 'LT+S'
           observ = 'CASSINI'
 
           cspice_spkpos, target, et, frame, corrtn, observ, sundir, ltime
           cspice_vhat, sundir, sundir
 
           print, "sundir = ", sundir
 
           method = 'NEAR POINT'
           target = 'PHOEBE'
           corrtn = 'NONE'
           observ = 'CASSINI'
 
           cspice_subpt, method, target, et, corrtn, observ, spoint, alt
 
           cspice_reclat, spoint, srad, slon, slat
 
           target = 'CASSINI';
           frame  = 'IAU_PHOEBE';
           corrtn = 'NONE';
           observ = 'PHOEBE';
 
           cspice_spkpos, target, et, frame, corrtn, observ, scpos, ltime
 
           cspice_vsub, spoint, scpos, sbpdir
 
           fromfr = 'IAU_PHOEBE'
           tofr   = 'CASSINI_INMS'
 
           cspice_pxform, fromfr, tofr, et, m2imat
 
           cspice_mxv,  m2imat, sbpdir, sbpdir
           cspice_vhat, sbpdir, sbpdir
 
           print, "alt    =  ", alt
           print, "lon    =  ", slon * cspice_dpr()
           print, "lat    =  ", slat * cspice_dpr()
           print, "sbpdir =  ", sbpdir
 
           target = 'CASSINI'
           frame  = 'J2000'
           corrtn = 'NONE'
           observ = 'PHOEBE'
 
           cspice_spkezr, target, et, frame, corrtn, observ, state, ltime
           scvdir = state[3:5]
 
           fromfr = 'J2000'
           tofr   = 'CASSINI_INMS'
           cspice_pxform, fromfr, tofr, et, j2imat
 
           cspice_mxv, j2imat, scvdir, scvdir
           cspice_vhat, scvdir, scvdir
 
           print, "scvdir = ", scvdir[0:2]
 
        END
 
     Meta-kernel file ``spice_example.mk'':
 
        \begindata
           KERNELS_TO_LOAD = (
                             'kernels/lsk/naif0007.tls'
                             'kernels/sclk/cas00084.tsc'
                             'kernels/spk/020514_SE_SAT105.bsp'
                             'kernels/spk/030201AP_SK_SM546_T45.bsp'
                             'kernels/spk/981005_PLTEPH-DE405S.bsp'
                             'kernels/spk/sat128.bsp'
                             'kernels/ck/04135_04171pc_psiv2.bc'
                             'kernels/fk/cas_v37.tf'
                             'kernels/pck/cpck05Mar2004.tpc'
                             )
        \begintext
 
