Frames







Version



April 26, 1999

The new routine PXFORM is described. A few typos were corrected.



Purpose



This document describes how reference frames are treated within the SPICE system. The document includes: a general discussion of reference frames; instructions on adding ``private'' reference frames to assist in a user's computations; and conventions established for use by NASA's Deep Space Network (DSN) Metric Predicts.



Intended Audience



This document addresses the needs of several groups of users. For those users looking for a basic discussion of reference frames and a list of the frames supported by the SPICE system see the chapter ``Using Frames.'' Users desiring to customize their environment by adding frames that have a constant relationship to one of the frames currently supported should see the chapter ``Creating a Frame Kernel.'' Those users who are part of JPL's Deep Space Network who need to incorporate new Earth fixed frames should see the appendix ``Frame Identifiers Reserved for the DSN.''

This document assumes you have some familiarity with SPICE concepts and terminology. If you are new to the SPICE system, or just a bit rusty with it, you should consider reviewing ``An Overview of the SPICE System'' and ``An Introduction to SPICE.''



Introduction





Several user-level SPICE routines require that the user supply the name of a reference frame as one of the inputs to the routine. The most important of these are the routines SPKEZ and SPKEZR. These routines return the state (position and velocity) of one object relative to another in a user specified reference frame. The choice of reference frame often makes a big difference in the usefulness of a returned state. If the state is relative to a suitable reference frame, computations involving that state can be much simpler than if the state were returned relative to some other reference frame.

The SPICE frame subsystem allows you to easily transform states from one reference frame to another. Usually this can be done without needing to know all of the details of how the transformation is carried out. This allows you to concentrate on questions more closely related to the problem you are trying to solve instead of the details of how to get information in the frame of interest.



Using Frames





There are only two user-level interface routines in the frame subsystem: SXFORM and PXFORM. SXFORM supports transformations of state vectors between reference frames; PXFORM supports transformations of position vectors. PXFORM may be used in cases where the derivatives required for a state transformation are unavailable, for example when one frame is defined by a C-kernel that lacks angular velocity data.

The calling sequences for these routines are

   CALL SXFORM ( FROM, TO, ET, XFORM  )
   CALL PXFORM ( FROM, TO, ET, ROTATE )
The output of SXFORM, XFORM, is a 6 by 6 transformation matrix for converting states relative to the frame specified by FROM to states relative to the frame specified by TO at the epoch ET (specified in seconds past J2000).

The output of PXFORM, ROTATE, is a 3 by 3 transformation matrix equivalent to the upper left 3x3 block of XFORM. This matrix tranforms position as opposed to state vectors.

Most users will not need to call these routines since most frame-to-frame transformations are automatically performed ``behind the scenes'' in other user-level routines.



Frames used in other SPICE routines



There are several routines outside the frame subsystem that require you to specify a reference frame as an input. For example the user-level routines

   CKGP
   CKGPAV
   SPKEZR
require users to specify the frame in which the output quantities should be returned.



Frame Names



In the cases listed above, you specify the frame or frames of interest using a character string that contains the name of the reference frame.

A number of names are automatically recognized by the frame subsystem. Here is a list of the currently recognized frames grouped by the ``class'' to which they belong.



Inertial Frames



The inertial reference frames recognized by the SPICE system are:

   J2000            DE-96       DE-125
   B1950            DE-102      DE-130
   FK4              DE-108      DE-140
   GALACTIC         DE-111      DE-142
   ECLIPJ2000       DE-114      DE-143
   ECLIPB1950       DE-118      DE-200
   MARSIAU          DE-122      DE-202
The DE-96 and DE-1xx frames are all variations of the B1950 frame. These frames were used on missions prior to and including the Galileo mission. Note that the MARSIAU frame above is inertial frame and should not be confused with the rotating IAU_MARS frame mentioned below.



Bodyfixed (PCK) Frames



Bodyfixed frames are reference frames that do not move with respect to ``surface'' features of an object. Note that bodyfixed frames do move with respect to inertial frames. The named bodyfixed frames automatically recognized by the frame subsystem are given below. The prefix ``IAU_'' is used to indicate that the orientation of this frame is typically determined from the International Astronomical Union (IAU) model for the body in question.

   IAU_ADRASTEA           IAU_MERCURY_BARYCENTER
   IAU_AMALTHEA           IAU_METIS
   IAU_ANANKE             IAU_MIMAS
   IAU_ARIEL              IAU_MIRANDA
   IAU_ATLAS              IAU_MOON
   IAU_BELINDA            IAU_NAIAD
   IAU_BIANCA             IAU_NEPTUNE
   IAU_CALLISTO           IAU_NEPTUNE_BARYCENTER
   IAU_CALYPSO            IAU_NEREID
   IAU_CARME              IAU_OBERON
   IAU_CHARON             IAU_OPHELIA
   IAU_CORDELIA           IAU_PANDORA
   IAU_CRESSIDA           IAU_PASIPHAE
   IAU_DEIMOS             IAU_PHOBOS
   IAU_DESDEMONA          IAU_PHOEBE
   IAU_DESPINA            IAU_PLUTO
   IAU_DIONE              IAU_PLUTO_BARYCENTER
   IAU_EARTH              IAU_PORTIA
   IAU_EARTH_BARYCENTER   IAU_PROMETHEUS
   IAU_ELARA              IAU_PROTEUS
   IAU_ENCELADUS          IAU_PUCK
   IAU_EPIMETHEUS         IAU_RHEA
   IAU_EUROPA             IAU_ROSALIND
   IAU_GALATEA            IAU_SATURN
   IAU_GANYMEDE           IAU_SATURN_BARYCENTER
   IAU_HELENE             IAU_SINOPE
   IAU_HIMALIA            IAU_SUN
   IAU_HYPERION           IAU_TELESTO
   IAU_IAPETUS            IAU_TETHYS
   IAU_IO                 IAU_THALASSA
   IAU_JANUS              IAU_THEBE
   IAU_JULIET             IAU_TITAN
   IAU_JUPITER            IAU_TITANIA
   IAU_JUPITER_BARYCENTER IAU_TRITON
   IAU_LARISSA            IAU_UMBRIEL
   IAU_LEDA               IAU_URANUS
   IAU_LYSITHEA           IAU_URANUS_BARYCENTER
   IAU_MARS               IAU_VENUS
   IAU_MARS_BARYCENTER    IAU_VENUS_BARYCENTER
   IAU_MERCURY


Earth Fixed Frames



In addition to the ``IAU_EARTH'' frame given above, the following two frames are ``built into'' the SPICE system.

   ITRF93
   EARTH_FIXED
ITRF93 is a frame ``fixed'' to the Earth's crust together with a high precision model for the orientation of this frame with respect to J2000. In SPICE this is a PCK type frame.

EARTH_FIXED is a ``generic frame'' that gives the orientation of the Earth with respect to some other frame (usually IAU_EARTH or ITRF93) via a constant rotational offset. Such frames are called Text Kernel (TK) frames. See the subsection ``Gaining Flexibility via TK Frames'' for a discussion of the use of TK frames.

If the frame you are interested in is not in one of the three lists above, it is not one of the ``built-in'' frames. However, there are several classes of ``loadable frames.'' The basic information about these loadable frames is supplied via the kernel pool.



Loading Frame Information




If you need to retrieve state information relative to some frame other than one of the frames that is automatically recognized, you must first load a description of that frame into the kernel pool. If you are not creating the frame yourself but are only a ``consumer'' of the frame information, you should already have a SPICE text kernel that specifies the fundamental frame information. It will typically have a file name with extension ``.tfr.'' For example you might have the frame kernel ``myframe.tfr.'' To make the frame recognized by the frame subsystem, load this kernel via a call to LDPOOL.

   CALL LDPOOL ( 'myframe.tfr' )


Computing Frame Transformations




In general the relationship of one frame relative to another is stored in other SPICE kernels. These kernels must be loaded for the SPICE system to compute a frame transformation from a non-inertial frame to any other frame. The only frame transformations that can be performed without loading other SPICE kernels are transformations between inertial frames.

The second class of frames listed above (bodyfixed frames) are fixed to the ``surfaces'' of planets, satellites, asteroids, etc. As a result the orientation of these frames are changing when observed with respect to any of the inertial frames. Information about how these frames are changing with respect to inertial frames is stored in SPICE PCK files. It is important to note that although the names of these frames are ``built-in'' their relationship to inertial frames is not. This information must be ``loaded'' into the SPICE system either through LDPOOL or PCKLOF. Without loading this information you cannot compute the transformation to or from a bodyfixed frame.

The information about what other kernels need to be loaded should be supplied in the comment portion of any frame kernels you are given.



Creating a Frame Kernel





If you need to create a frame kernel you will need to do a bit more work. To begin with you need to understand the concept of a frame class.



Frame Classes




The method by which a frame is related to some other frame is a function of the ``class'' of the frame. You describe the class of a frame with an integer called the frame's ``class number.'' There are four classes of reference frames:



Specifying a New Frame




In addition to the data/model needed to determine the orientation of a frame with respect to some other reference frame, you must tell the SPICE system how to find the data or model. This specification requires 5 pieces of information:

The rules for selecting these items are specified in the next section, but for the moment let's assume that the rules have been obeyed and we have arrived at the following values.

   Frame Name    :  'PHOENIX'
   Frame ID code :   1234567    (A number guaranteed to be suitable
                                 for private use)
   Frame Class   :          3   (C-kernel)
   Frame Center  :     -10001   (Phoenix Spacecraft ID code)
   Frame Class_id:  -10000001   (ID code in C-kernel for Phoenix)
The frame kernel that specifies this frame is given below:

   \begindata
 
   FRAME_PHOENIX           =  1234567
   FRAME_1234567_NAME     = 'PHOENIX'
   FRAME_1234567_CLASS    =  3
   FRAME_1234567_CENTER   = -10001
   FRAME_1234567_CLASS_ID = -10000001


Guidelines for Frame Specification






Selecting a Name



The name chosen for a frame must be fewer than 26 characters in length. It should have some mnemonic value so that users can recognize what the name means. Finally, it should not be the name of one of the built-in frames listed above or the name of any other frame you wish to specify. If you try to use a built-in name, the frame system will ignore your frame specification. In the example given above, we chose the name `PHOENIX' for the name of our reference frame.

The name must be in all upper case letters.



Selecting a Frame ID



What you choose for a frame ID depends upon the class of the frame. If the class is a CK or TK frame, you may use the same ID as you use for the CLASS_ID. If the frame is a PCK frame and you are working without consultation with NAIF, select an integer in the range from 1000000 to 2000000. In the previous example, we selected the Frame ID to be 1234567. (Since our example frame is of class 3, a CK frame, we would normally use the same number for the frame ID as we used for the class ID. However, in this example, we have chosen a different value to illustrate the connection between the frame ID and the variables needed to define the frame.)



Selecting the Class



This is usually the easiest part of specifying a frame. Presumably you know how the frame will be described with respect to some other frame. Simply choose the appropriate class number. In the example above, the class number is 3.



Selecting the Center



This is also fairly easy. A frame is used to specify the orientation of some object. The frame consists of a set of coordinate axes relative to some point---the origin of the reference frame. When viewed from some other frame the axes rotate about the origin. The origin about which the rotation takes place is the center of the frame. For bodyfixed frames this is the center of the body to which they are fixed. For C-kernel frames the center is usually the spacecraft to which the C-kernel is attached. Simply find the SPK ID code for the object to which the frame is attached and use that as the value for the center. In our example, the SPK ID code for the spacecraft -10001.



Selecting a Class ID



A frame's ``CLASS_ID'' is an integer used internally by SPICE software. It is the integer code used by the SPICE reference frame subsystems to look up reference frame information. If your frame is a PCK class frame the CLASS_ID is the ID code for the body described by the PCK file. If your frame is a CK class frame, the CLASS_ID is the ID code used in the C-kernel to describe the orientation of the spacecraft. If the frame is a TK frame, you should use a positive integer in the range from 1000000 to 2000000 (unless you are working in an official project capacity in which case you should ask NAIF to provide a CLASS_ID for you). In the example above, the CLASS_ID is the ID code for the C-kernel structure: -10000001.



Frame IDs Reserved for Public Use



The range 1000000 to 2000000 has been set aside by NAIF as a range of Frame IDs that can be used freely by SPICE users without fear of conflict with ``officially recognized'' frames. However, if you and a colleague plan to create several such frames, you will need to coordinate your work to ensure that your definitions are not in conflict with one another.



Why have a Frame ID and a Class ID?



When the SPICE software receives a request to compute a frame transformation, it first translates the name of the frame to the corresponding frame ID. There is a one to one correspondence between frame names and frame IDs. Once the frame ID is in hand, the class of the frame can be located and an appropriate subsystem identified for carrying out the initial computations needed to construct a frame transformation matrix. However, the frame system evolved to unify several distinct reference frame systems. In each of these systems, reference frames are identified by integer codes. Unfortunately, since these subsystems evolved independently, the numeric codes used to identify the reference systems overlapped from one system to the next. Moreover, to support backward compatibility, NAIF was not free to change the numeric codes used by the various subsystems or the meaning of the frame codes that were already present in existing data products.

To support existing data products and allow extension of the SPICE system, NAIF needed to associate the old ID code with the new frame ID. The CLASS_ID fills this role. When the frame is identified, the ID code suitable for the frame class is located and passed on the frame's class so that the initial portion of the frame transformation can be carried out.



Putting the Pieces Together




Once you've determined the name, ID code, center, class and class ID of your frame, you create the frame specification by filling in the frame template below. This should be stored in a text kernel.

   \begindata
 
   FRAME_<name>             = <ID code>
   FRAME_<ID code>_NAME     = '<name>'
   FRAME_<ID code>_CLASS    = <class>
   FRAME_<ID code>_CLASS_ID = <classid>
   FRAME_<ID code>_CENTER   = <center>
The example we used for the frame 'PHOENIX' illustrates this.

   \begindata
 
   FRAME_PHOENIX            =  1234567
   FRAME_1234567_NAME     = 'PHOENIX'
   FRAME_1234567_CLASS    =  3
   FRAME_1234567_CENTER   = -10001
   FRAME_1234567_CLASS_ID = -10000001
The resulting text file is called a ``frame'' kernel. Once you've completed the frame specification you tell the SPICE system about the frame by ``loading'' the frame kernel that contains it. As with all text kernels, you load it via the routine LDPOOL. For example if the frame kernel containing your frame specification is contained in the file `frame.ker' you load the kernel via the call

   CALL LDPOOL ( 'frame.ker' )


Connecting an Object to its Bodyfixed Frame




Every extended object has both a position and orientation in space. The SPICE ephemeris system (SPK) allows you to specify the location of such an object. The frame system allows you to name the bodyfixed frame that describes the orientation of the object and to retrieve the orientation of the frame relative to some other frame as a function of time. Given the name or SPK ID code associated with an object we can locate its position through the SPK system. Unfortunately, finding the bodyfixed frame of the object cannot always be determined from the object's name or ID code. For example, we have already mentioned that there are two built-in reference frames that describe the orientation of the Earth: IAU_EARTH and ITRF93. For other objects, such as the asteroid Ceres, there is no built-in frame associated with the object. The bodyfixed frame of Ceres must be defined through a text kernel. In both cases, the connection between the object and its bodyfixed frame needs to be supplied via a kernel pool variable. There are two ways to do this.

   OBJECT_<name or spk_id>_FRAME =  '<frame name>'
or

   OBJECT_<name or spk_id>_FRAME =  <frame ID code>
You may use the ID codes for either the object, the frame or both. All of the following serve to connect the Earth with the ITRF93 frame.

   OBJECT_399_FRAME   =  13000
   OBJECT_399_FRAME   = 'ITRF93'
   OBJECT_EARTH_FRAME =  13000
   OBJECT_EARTH_FRAME = 'ITRF93'
Note: if you use the name of either the object or frame, you must use upper case letters.

Of these four means of specifying an object's bodyfixed frame the second (OBJECT_399_FRAME = 'ITRF93') is the most robust.



Default Bodyfixed Frames



For the sun, planets and their satellites the frame system maintains a default connection between the object and its bodyfixed frame. In all cases the default bodyfixed frame is the corresponding IAU frame listed at the beginning of this document. Thus the default bodyfixed frames for Sun, Earth, Moon and Mars are 'IAU_SUN', 'IAU_EARTH', 'IAU_MOON', 'IAU_MARS' respectively.



The rest of the frame information




The information supplied in the frame specification tells the SPICE system where to look for a particular frame model. However, the specification alone doesn't tell the SPICE system how to actually transform from the specified frame to some other frame of interest. To do this you need to supply other information. How this information is supplied depends upon the class of the frame.



Inertial Frames




Inertial frames are ``built into'' the SPICE system via the routine CHGIRF. Only the frames defined in that routine are available as inertial class frames. For this reason there is rarely a need to specify an inertial frame through a frame specification. Essentially all you can do by creating a frame specification for an inertial frame is to supply a second name for one of the built-in frames. For example you might define EME2000 as another name for the J2000 frame.

NAIF recommends against creating inertial frame specifications. However, if you choose to do so anyway, you are done once you've defined the frame specification. (You may not be done explaining to your colleagues why you've decided to do this.)

In the example cited earlier (EME2000) here's how you'd specify the frame.

   FRAME_EME2000         = 1000000
   FRAME_1000000_NAME    = 'EME2000'
   FRAME_1000000_CLASS   = 1
   FRAME_1000000_CENTER  = 0
   FRAME_1000000_CLASSID = 1
Everything else about this frame is built into the SPICE system.



PCK Frames




If you specify a PCK frame, you will need to load either a text or binary PCK file for the body with which the frame is associated. The construction of PC kernels is discussed in the SPICE document PCK Required Reading.



CK Frames




If a frame is defined as a CK frame, you will need both a C-kernel for the structure identified by the FRAME-CLASSID variable and an SCLK kernel for converting ephemeris time to the ``ticks'' used to represent time in the C-kernel. Both the C-kernel(s) and SCLK kernel must be loaded prior to attempting to use the CK frame.



SCLK and SPK ID codes



For many C-kernels, the spacecraft clock and spacecraft ID codes can be determined by performing an integer division of the C-kernel ID code by -1000 and 1000 respectively. However, under some circumstances this numerical correspondence between C-kernel ID code and the associated SCLK or spacecraft ID may break down. When the numerical relationship fails you need to tell the SPICE system the ID code of the SCLK or spacecraft via two kernel pool variables.

   CK_<ck_ID code>_SCLK = <- ID code of SCLK >
   CK_<ck_ID code>_SPK  = <SPK ID code>
These variables are normally placed in either the SCLK kernel or in the frame specification kernel.

Be sure to note that you need to supply the OPPOSITE of the SCLK ID code in the CK...SCLK variable. This idiosyncrasy is a hold over from the time when the spacecraft clock ID could be inferred from the ID code of the clock's spacecraft. NAIF is aware that this is a bit confusing, but in the interest of backward compatibility we have continued this rather arcane tradition.

To illustrate how you would create a C-kernel frame, we shall suppose that we have a C-kernel for structure -100001 aboard the fictional spacecraft ``Phoenix'' which has ID code -1001. Moreover we shall assume that the clock ID appropriate for this structure is 1002. Below is a frame specification together with the CK...SCLK and CK...SPK variable definitions for the ``Phoenix'' frame.

   FRAME_PHOENIX          = -100001
   FRAME_-100001_NAME     = 'PHOENIX'
   FRAME_-100001_CLASS    = 3
   FRAME_-100001_CLASS_ID = -100001
   FRAME_-100001_CENTER   = -1001
 
   CK_-100001_SCLK        = -1002
   CK_-100001_SPK         = -1001


TK Frames




The relationship between a constant offset Text Kernel frame and the frame it is offset from is given via a text kernel that can be loaded via the kernel pool routine LDPOOL. This text kernel should contain the frame specification required of every frame that is not on the ``built-in'' list.

   \begindata
 
   FRAME_<name>             = <ID code>
   FRAME_<ID code>_NAME     = '<name>'
   FRAME_<ID code>_CLASS    = 4
   FRAME_<ID code>_CLASS_ID = <ID code>
   FRAME_<ID code>_CENTER   = <center>
In addition to the frame specification, you need to supply information that indicates the frame, RELATIVE, from which the TK frame is offset and the rotation that transforms from the TK frame to RELATIVE.

The first of these is defined as shown below.

   TKFRAME_<frame>_RELATIVE = '<name of relative frame>'
where `frame' is the ID code or name you used in the frame specification. The name of the RELATIVE frame must be in upper case letters.

The rotation from the TK frame to the RELATIVE frame can be specified in three different ways.

            V_relative = M * V_tkframe
You let the frame system know which method you've chosen for representing the rotation via the kernel pool variable

   TKFRAME_<frame>_SPEC.
To use a matrix to define the rotation, use the assignment:

   TKFRAME_<frame>_SPEC = 'MATRIX'
To define the rotation via three Euler angles, use the assignment:

   TKFRAME_<frame>_SPEC = 'ANGLES'
To define the rotation via a SPICE quaternion, use the assignment:

   TKFRAME_<frame>_SPEC = 'QUATERNION'
Depending upon the value of the `SPEC' variable, you need to supply one of the following sets of kernel pool variables.



Defining a TK Frame Using a Matrix



If you've chosen to define the rotation using a matrix, supply the matrix using the kernel pool variable assignment below:

   TFRAME_<frame>_MATRIX = ( matrix_value(1,1),
                             matrix_value(2,1),
                             matrix_value(3,1),
                             matrix_value(1,2),
                             matrix_value(2,2),
                             matrix_value(3,2),
                             matrix_value(1,3),
                             matrix_value(2,3),
                             matrix_value(3,3)  )
For example, if the matrix defining your TK frame is

   0.4   -0.6   0.0
   0.6    0.4   0.0
   0.0    0.0   1.0
and the ID code you've selected for the frame is 1234567, then you should supply the following information in a text kernel.

   TKFRAME_1234567_SPEC   = 'MATRIX'
 
   TKFRAME_1234567_MATRIX = (  0.4
                               0.6
                               0.0
                              -0.6
                               0.4
                               0.0
                               0.0
                               0.0
                               1.0 )


Defining a TK Frame Using Euler Angles



If you've chosen to define a TK frame as a sequence of three rotations about specified coordinate axes, you need to supply the following pieces of information:

This information is supplied to the SPICE system using the kernel pool variables shown below.

   TKFRAME_<frame>_ANGLES = ( angle_1, angle_2, angle_3 )
   TKFRAME_<frame>_AXES   = ( axis_1,  axis_2,  axis_3  )
   TKFRAME_<frame>_UNITS  = 'units_of_angles'
The units must be from the list given above. The axes must be chosen from the set of integers 1,2,3 (1 stands for the x-axis, 2 for the y-axis, and 3 for the z-axis). If M is the matrix that converts vectors relative to the TK frame to the RELATIVE frame by left multiplication, then the angles and axes must satisfy the following relationship:

   M = [angle_1]      [angle_2]      [angle_3]
                axis_1         axis_2         axis_3
 
where the symbol

   [ A ]
        i
stands for a rotation by the angle A about the i'th axis.

   +-                     -+
   |   0       0      0    |
   |   0     cos A   sin A |   =  [ A ]
   |   0    -sin A   cos A |           1
   +-                     -+
 
   +-                     -+
   |  cos A    0    -sin A |
   |   0       1      0    |   =  [ A ]
   |  sin A    0     cos A |           2
   +-                     -+
 
   +-                     -+
   |  cos A   sin A   0    |
   | -sin A   cos A   0    |   =  [ A ]
   |   0       0      1    |           3
   +-                     -+
This method of definition is particularly well suited for defining topocentric frames on the surface of the Earth. For example, suppose you have an SPK (ephemeris) file that specifies the location of some surface point on the Earth and that the SPK ID code of this point is 399100. Moreover suppose that you have the geodetic co-latitude (COLAT) and longitude (LONG) measured in degrees for this point. (Note that the co-latitude is the complement of latitude: latitude + co-latitude = 90 degrees.)

Given this information we can easily define a topocentric reference frame at the point such that the x-axis points north along the local meridian, the y-axis points west along the local latitude and the z-axis points up from the reference spheroid.

The transformation from Earth bodyfixed frame to topocentric frame is given by

   BF2TP = [180] [COLAT] [LONG]
                3       2      3
Consequently the transformation from the topocentric frame to the bodyfixed frame is given by

   M = TP2BF = [-LONG] [-COLAT] [180]
                      3        2     3
Let 1234567 be the ID code for the the topocentric frame; let the name of this frame be ``MYTOPO''; and define this relative to the IAU frame for the Earth (one of the built-in frames). The topocentric frame at the ephemeris point 399100 is specified as shown below:

   \begindata
   FRAME_MYTOPO             = 1234567
   FRAME_1234567_NAME       = 'MYTOPO'
   FRAME_1234567_CLASS      = 4
   FRAME_1234567_CLASS_ID   = 1234567
   FRAME_1234567_CENTER     = 399100
 
   TKFRAME_MYTOPO_SPEC     = 'ANGLES'
   TKFRAME_MYTOPO_RELATIVE = 'IAU_EARTH'
   TKFRAME_MYTOPO_ANGLES   = ( <-long>, <-colat>, 180 )
   TKFRAME_MYTOPO_AXES     = (       3,        2,   3 )
   TKFRAME_MYTOPO_UNITS    = 'DEGREES'
As we'll see a bit later, we can make a more flexible definition for this topocentric frame.



Defining a TK Frame Using a Quaternion



If you've chosen to define a TK frame using a quaternion, supply the quaternion using the kernel pool variable assignment below:

   TKFRAME_<frame>_Q = ( q_0, q_1, q_2, q_3 )
Where component zero is the so called ``real'' component of the quaternion (the ``cosine'' component of the quaternion). The last 3 components (components 1 through 3) are the ``axis'' components of the quaternion---the i, j, and k components respectively of the quaternion. The quaternion should be a unit quaternion.

        2        2        2        2
   (q_0)  + (q_1)  + (q_2)  + (q_3)  = 1
Quaternions are discussed in further detail in the reference document ``Rotations Required Reading'' (rotation.req).



Gaining Flexibility via TK Frames




The use of non-inertial frames gives you an easy means of creating ephemerides for points on the surface of a body such as the Earth, Moon or Mars. The ephemeris is simply the bodyfixed location of the object relative to a bodyfixed frame for the same object. However, the model used to relate the bodyfixed frame to other reference frames may not be fixed. Indeed, for the Earth there are several different methods with varying degrees of accuracy that give the orientation of the Earth with respect to inertial space. Each of these different realizations may have a different frame ID code. This ability to ``plug in'' different orientations is one of the strengths of the SPICE system. However, if you create an ephemeris relative to one of these specific models, you won't be able to use it unless you've loaded the correct model. To make the ephemeris usable regardless of the orientation model you happen to have at your disposal, you should define the bodyfixed ephemeris relative to a TK frame. Then define the TK frame so that rotation from the TK frame to the PCK frame is the identity matrix. For example, you can define a lunar bodyfixed frame as shown below.

   \begindata
   FRAME_MOONFIXED          = 3010000
   FRAME_3010000_NAME       = 'MOONFIXED'
   FRAME_3010000_CLASS      = 4
   FRAME_3010000_CLASS_ID   = 3010000
   FRAME_3010000_CENTER     = 301
 
   TKFRAME_MOONFIXED_SPEC     = 'MATRIX'
   TKFRAME_MOONFIXED_RELATIVE = '<name of orientation model>'
   TKFRAME_MOONFIXED_MATRIX   = ( 1,
                                  0,
                                  0,
                                  0,
                                  1,
                                  0,
                                  0,
                                  0,
                                  1 )
 
By editing this definition you can make the MOONFIXED frame be the IAU MOON frame or some other model if one is available. Or you can create several such definitions and, at run-time, load the file that best fits your current environment.

Using this indirect method of defining the various frames for which more than one orientation model may be available, you can avoid limiting how various kernels can be used.



Appendix. Frame Identifiers Reserved for the DSN





NAIF has set aside a range of frame ID codes for use by the DSN. The reserved range is from 13001 to 13999. All of these frames are PCK based frames. They are intended to model the orientation of the Earth with respect to an inertial reference frame such as the J2000 frame. For the purpose of discussion we shall refer to any frame with ID code in the reserved range as a DSN frame.

The class ID to associate with any DSN frame is the frame ID minus 10000. For example, the class ID associated with frame 13003 is 3003. It is this class ID that should be placed in the PCK file that implements the relationship between the DSN frame and the corresponding inertial frame.

The center of any DSN frame is the center of mass of the Earth which has SPK ID code 399.

These frames are partially built-in. Given a frame ID in the range from 13001 to 13999, the frame system ``knows'' that the frame is a PCK frame, the center of the frame is 399 and the class ID of the frame is the frame ID - 10000. This knowledge cannot be overridden. However, the frame system does not ``know'' the relationship between the names of these frames and their ID codes. The relationship must be specified via the appropriate kernel pool frame definition.

   FRAME_<name>              = <DSN Frame-ID>
   FRAME_<DSN Frame-ID>_NAME = '<name>'
   OBJECT_EARTH_FRAME        = <DSN Frame-ID>
Note that this specification leaves out the items below

   FRAME_<DSN Frame-ID>_CENTER  = 399
   FRAME_<DSN Frame-ID>_CLASS   = 2
   FRAME_<DSN Frame-ID>_CLASSID = <DSN Frame-ID  - 10000>
You may supply these values if you like, but they have no effect on the frame system's recognition and interpretation of the frame with the specified frame ID.



Appendix. Frame Definition Templates





Below are examples that you can modify to create frame specifications for similar situations.



Inertial Frame



Inertial frames can be defined only as aliases for the built-in inertial frames. This example defines EME50 to be the same frame as B1950.

   \begindata
 
      FRAME_EME50            = 1000000
      FRAME_1000000_NAME     = 'EME50'
      FRAME_1000000_CLASS    =  1
      FRAME_1000000_CLASS_ID =  2
      FRAME_1000000_CENTER   =  0


PCK Frame



This definition shows how you create a frame definition for the asteroid Eros. Note we also define which frame is associated with the asteroid Eros.

   \begindata
 
      FRAME_EROSFIXED        =  1000001
      FRAME_1000001_NAME     = 'EROSFIXED'
      FRAME_1000001_CLASS    =  2
      FRAME_1000001_CLASS_ID =  2000433
      FRAME_1000001_CENTER   =  2000433
 
      OBJECT_2000433_FRAME   = 'EROSFIXED'


CK Frames



This definition shows how you create a frame definition for the MGS spacecraft. Note this frame definition includes the appropriate SCLK definition as well as which frame to attach to the MGS spacecraft.

   \begindata
 
      FRAME_MGS_PLATFORM     = -94000
      FRAME_1000001_NAME     = 'MGS_PLATFORM'
      FRAME_1000001_CLASS    =  3
      FRAME_1000001_CLASS_ID = -94000
      FRAME_1000001_CENTER   = -94
 
      CK_-94000_SCLK         = -94
      CK_-94000_SPK          = -94
 
      OBJECT_-94_FRAME       = 'MGS_PLATFORM'


TK frame --- Alias



This example shows how you can make up an alias for a frame using a TK frame. Note we make the reference frame to associate with Mars the MARS_FIXED frame.

   \begindata
 
      FRAME_MARS_FIXED       =  1000499
      FRAME_1000499_NAME     = 'MARS_FIXED'
      FRAME_1000499_CLASS    =  4
      FRAME_1000499_CLASS_ID =  1000499
      FRAME_1000499_CENTER   =  499
 
      OBJECT_499_FRAME       = 'MARS_FIXED'
 
   \begintext
   To make this point to another frame model just replace
   'IAU_MARS' below with the name of the new model.
 
   \begindata
 
      TKFRAME_1000499_RELATIVE = 'IAU_MARS'
      TKFRAME_1000499_SPEC     = 'MATRIX'
      TKFRAME_1000499_MATRIX   = ( 1   0   0
                                   0   1   0
                                   0   0   1 )


TK frame --- Topographic



This example shows how you could create a topographic frame for the DSN Station DSS-17.

   \begindata
 
      FRAME_DSS-17_TOPO      =  1399017
      FRAME_1399017_NAME     = 'DSS-17_TOPO'
      FRAME_1399017_CLASS    =  4
      FRAME_1399017_CLASS_ID =  1399017
      FRAME_1399017_CENTER   =   399017
 
      OBJECT_399017_FRAME    = 'DSS-17_TOPO'
 
   \begintext
 
   Note that the geodetic longitude and co-latitude of the
   DSS-17 tracking station are: 243.126496675 and 54.657822839
   respectively.
 
   \begindata
 
      TKFRAME_DSS-17_TOPO_RELATIVE = 'EARTH_FIXED'
      TKFRAME_DSS-17_TOPO_SPEC     = 'ANGLES'
      TKFRAME_DSS-17_TOPO_UNITS    = 'DEGREES'
      TKFRAME_DSS-17_TOPO_AXES     = ( 3, 2, 3 )
      TKFRAME_DSS-17_TOPO_ANGLES   = ( -243.126496675,
                                        -54.657822839,
                                        180.0 )
   \begintext
 
   Recall that the frame `EARTH_FIXED' is a TK frame.  As a result
   its relationship to other frames must be specified via
   a kernel pool variable.  We make that specification here.
 
   If the ITRF93 PCK kernel is not available we can simply rename the
   "RELATIVE" frame to be IAU_EARTH and still have the topocentric
   frame well defined.
 
   \begindata
 
      TKFRAME_EARTH_FIXED_RELATIVE = 'ITRF93'
      TKFRAME_EARTH_FIXED_SPEC     = 'MATRIX'
      TKFRAME_EARTH_FIXED_MATRIX   = ( 1   0   0
                                       0   1   0
                                       0   0   1 )