1 /*
2 
3 -Procedure ckw02_c ( C-Kernel, write segment to C-kernel, data type 2 )
4 
5 -Abstract
6 
7    Write a type 2 segment to a C-kernel.
8 
9 -Disclaimer
10 
11    THIS SOFTWARE AND ANY RELATED MATERIALS WERE CREATED BY THE
12    CALIFORNIA INSTITUTE OF TECHNOLOGY (CALTECH) UNDER A U.S.
13    GOVERNMENT CONTRACT WITH THE NATIONAL AERONAUTICS AND SPACE
14    ADMINISTRATION (NASA). THE SOFTWARE IS TECHNOLOGY AND SOFTWARE
15    PUBLICLY AVAILABLE UNDER U.S. EXPORT LAWS AND IS PROVIDED "AS-IS"
16    TO THE RECIPIENT WITHOUT WARRANTY OF ANY KIND, INCLUDING ANY
17    WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A
18    PARTICULAR USE OR PURPOSE (AS SET FORTH IN UNITED STATES UCC
19    SECTIONS 2312-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE
20    SOFTWARE AND RELATED MATERIALS, HOWEVER USED.
21 
22    IN NO EVENT SHALL CALTECH, ITS JET PROPULSION LABORATORY, OR NASA
23    BE LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING, BUT NOT
24    LIMITED TO, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND,
25    INCLUDING ECONOMIC DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS,
26    REGARDLESS OF WHETHER CALTECH, JPL, OR NASA BE ADVISED, HAVE
27    REASON TO KNOW, OR, IN FACT, SHALL KNOW OF THE POSSIBILITY.
28 
29    RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF
30    THE SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY
31    CALTECH AND NASA FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE
32    ACTIONS OF RECIPIENT IN THE USE OF THE SOFTWARE.
33 
34 -Required_Reading
35 
36    CK
37    DAF
38    SCLK
39 
40 -Keywords
41 
42    POINTING
43    UTILITY
44 
45 */
46 
47    #include "SpiceUsr.h"
48    #include "SpiceZfc.h"
49    #include "SpiceZmc.h"
50    #include "SpiceZim.h"
51    #undef    ckw02_c
52 
53 
ckw02_c(SpiceInt handle,SpiceDouble begtim,SpiceDouble endtim,SpiceInt inst,ConstSpiceChar * ref,ConstSpiceChar * segid,SpiceInt nrec,ConstSpiceDouble start[],ConstSpiceDouble stop[],ConstSpiceDouble quats[][4],ConstSpiceDouble avvs[][3],ConstSpiceDouble rates[])54    void ckw02_c ( SpiceInt            handle,
55                   SpiceDouble         begtim,
56                   SpiceDouble         endtim,
57                   SpiceInt            inst,
58                   ConstSpiceChar    * ref,
59                   ConstSpiceChar    * segid,
60                   SpiceInt            nrec,
61                   ConstSpiceDouble    start  [],
62                   ConstSpiceDouble    stop   [],
63                   ConstSpiceDouble    quats  [][4],
64                   ConstSpiceDouble    avvs   [][3],
65                   ConstSpiceDouble    rates  []    )
66 
67 /*
68 
69 -Brief_I/O
70 
71    Variable  I/O  Description
72    --------  ---  --------------------------------------------------
73    handle     I   Handle of an open CK file.
74    begtim     I   The beginning encoded SCLK of the segment.
75    endtim     I   The ending encoded SCLK of the segment.
76    inst       I   The NAIF instrument ID code.
77    ref        I   The reference frame of the segment.
78    segid      I   Segment identifier.
79    nrec       I   Number of pointing records.
80    start      I   Encoded SCLK interval start times.
81    stop       I   Encoded SCLK interval stop times.
82    quats      I   Quaternions representing instrument pointing.
83    avvs       I   Angular velocity vectors.
84    rates      I   Number of seconds per tick for each interval.
85 
86 -Detailed_Input
87 
88    handle     is the handle of the CK file to which the segment will
89               be written. The file must have been opened with write
90               access.
91 
92    begtim     is the beginning encoded SCLK time of the segment. This
93               value should be less than or equal to the first START
94               time in the segment.
95 
96    endtim     is the encoded SCLK time at which the segment ends.
97               This value should be greater than or equal to the last
98               STOP time in the segment.
99 
100    inst       is the NAIF integer ID code for the instrument.
101 
102    ref        is a character string that specifies the
103               reference frame of the segment. This should be one of
104               the frames supported by the SPICELIB routine NAMFRM
105               which is an entry point of FRAMEX.
106 
107    segid      is the segment identifier.  A CK segment identifier may
108               contain up to 40 characters.
109 
110    nrec       is the number of pointing intervals that will be
111               written to the segment.
112 
113    start      are the start times of each interval in encoded
114               spacecraft clock. These times must be strictly
115               increasing.
116 
117    stop       are the stop times of each interval in encoded
118               spacecraft clock. These times must be greater than
119               the START times that they correspond to but less
120               than or equal to the START time of the next interval.
121 
122    quats      are the quaternions representing the C-matrices
123               associated with the start times of each interval. See the
124               discussion of "Quaternion Styles" in the Particulars
125               section below.
126 
127    AVVS       are the angular velocity vectors for each interval.
128 
129    RATES      are the number of seconds per encoded spacecraft clock
130               tick for each interval.
131 
132               In most applications this value will be the same for
133               each interval within a segment.  For example, when
134               constructing a predict C-kernel for Mars Observer, the
135               rate would be 1/256 for each interval since this is
136               the smallest time unit expressible by the MO clock. The
137               nominal seconds per tick rates for Galileo and Voyager
138               are 1/120 and 0.06 respectively.
139 
140 -Detailed_Output
141 
142    None.  See Files section.
143 
144 -Parameters
145 
146    None.
147 
148 -Exceptions
149 
150    1)  If handle is not the handle of a C-kernel opened for writing
151        the error will be diagnosed by routines called by this
152        routine.
153 
154    2)  If segid is more than 40 characters long, the error
155        SPICE(SEGIDTOOLONG) is signaled.
156 
157    3)  If segid contains any nonprintable characters, the error
158        SPICE(NONPRINTABLECHARS) is signaled.
159 
160    4)  If the first START time is negative, the error
161        SPICE(INVALIDSCLKTIME) is signaled. If any of the subsequent
162        START times are negative the error SPICE(TIMESOUTOFORDER)
163        will be signaled.
164 
165    5)  If any of the STOP times are negative, the error
166        SPICE(DEGENERATEINTERVAL) is signaled.
167 
168    6)  If the STOP time of any of the intervals is less than or equal
169        to the START time, the error SPICE(DEGENERATEINTERVAL) is
170        signaled.
171 
172    7)  If the START times are not strictly increasing, the
173        error SPICE(TIMESOUTOFORDER) is signaled.
174 
175    8)  If the STOP time of one interval is greater than the START
176        time of the next interval, the error SPICE(BADSTOPTIME)
177        is signaled.
178 
179    9)  If begtim is greater than START[0] or endtim is less than
180        STOP[NREC-1], the error SPICE(INVALIDDESCRTIME) is
181        signaled.
182 
183   10)  If the name of the reference frame is not one of those
184        supported by the routine NAMFRM, the error
185        SPICE(INVALIDREFFRAME) is signaled.
186 
187   11)  If nrec, the number of pointing records, is less than or
188        equal to 0, the error SPICE(INVALIDNUMRECS) is signaled.
189 
190   12)  If any quaternion has magnitude zero, the error
191        SPICE(ZEROQUATERNION) is signaled.
192 
193 
194 -Files
195 
196    This routine adds a type 2 segment to a C-kernel.  The C-kernel
197    may be either a new one or an existing one opened for writing.
198 
199 -Particulars
200 
201    For a detailed description of a type 2 CK segment please see the
202    CK Required Reading.
203 
204    This routine relieves the user from performing the repetitive
205    calls to the DAF routines necessary to construct a CK segment.
206 
207 
208    Quaternion Styles
209    -----------------
210 
211    There are different "styles" of quaternions used in
212    science and engineering applications. Quaternion styles
213    are characterized by
214 
215       - The order of quaternion elements
216 
217       - The quaternion multiplication formula
218 
219       - The convention for associating quaternions
220         with rotation matrices
221 
222    Two of the commonly used styles are
223 
224       - "SPICE"
225 
226          > Invented by Sir William Rowan Hamilton
227          > Frequently used in mathematics and physics textbooks
228 
229       - "Engineering"
230 
231          > Widely used in aerospace engineering applications
232 
233 
234    CSPICE function interfaces ALWAYS use SPICE quaternions.
235    Quaternions of any other style must be converted to SPICE
236    quaternions before they are passed to CSPICE functions.
237 
238 
239    Relationship between SPICE and Engineering Quaternions
240    ------------------------------------------------------
241 
242    Let M be a rotation matrix such that for any vector V,
243 
244       M*V
245 
246    is the result of rotating V by theta radians in the
247    counterclockwise direction about unit rotation axis vector A.
248    Then the SPICE quaternions representing M are
249 
250       (+/-) (  cos(theta/2),
251                sin(theta/2) A(1),
252                sin(theta/2) A(2),
253                sin(theta/2) A(3)  )
254 
255    while the engineering quaternions representing M are
256 
257       (+/-) ( -sin(theta/2) A(1),
258               -sin(theta/2) A(2),
259               -sin(theta/2) A(3),
260                cos(theta/2)       )
261 
262    For both styles of quaternions, if a quaternion q represents
263    a rotation matrix M, then -q represents M as well.
264 
265    Given an engineering quaternion
266 
267       QENG   = ( q0,  q1,  q2,  q3 )
268 
269    the equivalent SPICE quaternion is
270 
271       QSPICE = ( q3, -q0, -q1, -q2 )
272 
273 
274    Associating SPICE Quaternions with Rotation Matrices
275    ----------------------------------------------------
276 
277    Let FROM and TO be two right-handed reference frames, for
278    example, an inertial frame and a spacecraft-fixed frame. Let the
279    symbols
280 
281       V    ,   V
282        FROM     TO
283 
284    denote, respectively, an arbitrary vector expressed relative to
285    the FROM and TO frames. Let M denote the transformation matrix
286    that transforms vectors from frame FROM to frame TO; then
287 
288       V   =  M * V
289        TO         FROM
290 
291    where the expression on the right hand side represents left
292    multiplication of the vector by the matrix.
293 
294    Then if the unit-length SPICE quaternion q represents M, where
295 
296       q = (q0, q1, q2, q3)
297 
298    the elements of M are derived from the elements of q as follows:
299 
300         +-                                                         -+
301         |           2    2                                          |
302         | 1 - 2*( q2 + q3 )   2*(q1*q2 - q0*q3)   2*(q1*q3 + q0*q2) |
303         |                                                           |
304         |                                                           |
305         |                               2    2                      |
306     M = | 2*(q1*q2 + q0*q3)   1 - 2*( q1 + q3 )   2*(q2*q3 - q0*q1) |
307         |                                                           |
308         |                                                           |
309         |                                                   2    2  |
310         | 2*(q1*q3 - q0*q2)   2*(q2*q3 + q0*q1)   1 - 2*( q1 + q2 ) |
311         |                                                           |
312         +-                                                         -+
313 
314    Note that substituting the elements of -q for those of q in the
315    right hand side leaves each element of M unchanged; this shows
316    that if a quaternion q represents a matrix M, then so does the
317    quaternion -q.
318 
319    To map the rotation matrix M to a unit quaternion, we start by
320    decomposing the rotation matrix as a sum of symmetric
321    and skew-symmetric parts:
322 
323                                       2
324       M = [ I  +  (1-cos(theta)) OMEGA  ] + [ sin(theta) OMEGA ]
325 
326                    symmetric                   skew-symmetric
327 
328 
329    OMEGA is a skew-symmetric matrix of the form
330 
331                  +-             -+
332                  |  0   -n3   n2 |
333                  |               |
334        OMEGA  =  |  n3   0   -n1 |
335                  |               |
336                  | -n2   n1   0  |
337                  +-             -+
338 
339    The vector N of matrix entries (n1, n2, n3) is the rotation axis
340    of M and theta is M's rotation angle.  Note that N and theta
341    are not unique.
342 
343    Let
344 
345       C = cos(theta/2)
346       S = sin(theta/2)
347 
348    Then the unit quaternions Q corresponding to M are
349 
350       Q = +/- ( C, S*n1, S*n2, S*n3 )
351 
352    The mappings between quaternions and the corresponding rotations
353    are carried out by the CSPICE routines
354 
355       q2m_c {quaternion to matrix}
356       m2q_c {matrix to quaternion}
357 
358    m2q_c always returns a quaternion with scalar part greater than
359    or equal to zero.
360 
361 
362    SPICE Quaternion Multiplication Formula
363    ---------------------------------------
364 
365    Given a SPICE quaternion
366 
367       Q = ( q0, q1, q2, q3 )
368 
369    corresponding to rotation axis A and angle theta as above, we can
370    represent Q using "scalar + vector" notation as follows:
371 
372       s =   q0           = cos(theta/2)
373 
374       v = ( q1, q2, q3 ) = sin(theta/2) * A
375 
376       Q = s + v
377 
378    Let Q1 and Q2 be SPICE quaternions with respective scalar
379    and vector parts s1, s2 and v1, v2:
380 
381       Q1 = s1 + v1
382       Q2 = s2 + v2
383 
384    We represent the dot product of v1 and v2 by
385 
386       <v1, v2>
387 
388    and the cross product of v1 and v2 by
389 
390       v1 x v2
391 
392    Then the SPICE quaternion product is
393 
394       Q1*Q2 = s1*s2 - <v1,v2>  + s1*v2 + s2*v1 + (v1 x v2)
395 
396    If Q1 and Q2 represent the rotation matrices M1 and M2
397    respectively, then the quaternion product
398 
399       Q1*Q2
400 
401    represents the matrix product
402 
403       M1*M2
404 
405 
406 -Examples
407 
408 
409    This example writes a predict type 2 C-kernel segment for
410    the Mars Observer spacecraft bus to a previously opened CK file
411    attached to handle.
412 
413 
414       /.
415       Assume arrays of quaternions, angular velocities, and interval
416       start and stop times are produced elsewhere.
417       ./
418 
419       .
420       .
421       .
422 
423       /.
424       The nominal number of seconds in a tick for MO is 1/256.
425       ./
426       sectik = 1. / 256.;
427 
428       for ( i = 0; i < nrec;  i++ )
429       {
430          rate[i] = sectik;
431       }
432 
433       /.
434       The subroutine ckw02_c needs the following components of the
435       segment descriptor:
436 
437          1) SCLK limits of the segment.
438          2) Instrument code.
439          3) Reference frame.
440       ./
441       begtim  =  start [    0 ];
442       endtim  =  stop  [nrec-1];
443 
444       inst    =  -94000;
445       ref     =  "j2000";
446 
447       segid = "mo predict seg type 2";
448 
449       /.
450       Write the segment.
451       ./
452       ckw02_c ( handle, begtim, endtim, inst, ref, segid,
453                 nrec,   start,  stop,   quat, avv, rates  );
454 
455 
456 -Restrictions
457 
458    None.
459 
460 -Literature_References
461 
462    None.
463 
464 -Author_and_Institution
465 
466    N.J. Bachman    (JPL)
467    K.R. Gehringer  (JPL)
468    J.M. Lynch      (JPL)
469 
470 -Version
471 
472    -CSPICE Version 2.0.0, 01-JUN-2010 (NJB)
473 
474       The check for non-unit quaternions has been replaced
475       with a check for zero-length quaternions. (The
476       implementation of the check is located in ckw02_.)
477 
478    -CSPICE Version 1.2.1, 27-FEB-2008 (NJB)
479 
480       Updated header; added information about SPICE
481       quaternion conventions.
482 
483    -CSPICE Version 1.2.0, 28-AUG-2001 (NJB)
484 
485        Changed prototype:  inputs start, stop, sclkdp, quats,
486        and avvs are now const-qualified.  Implemented interface
487        macros for casting these inputs to const.
488 
489    -CSPICE Version 1.1.0, 08-FEB-1998 (NJB)
490 
491        References to C2F_CreateStr_Sig were removed; code was
492        cleaned up accordingly.  String checks are now done using
493        the macro CHKFSTR.
494 
495    -CSPICE Version 1.0.0, 25-OCT-1997 (NJB)
496 
497       Based on SPICELIB Version 2.0.0, 28-DEC-1993 (WLT)
498 
499 -Index_Entries
500 
501    write ck type_2 pointing data segment
502 
503 -&
504 */
505 
506 { /* Begin ckw02_c */
507 
508    /*
509    Participate in error handling.
510    */
511    chkin_c ( "ckw02_c" );
512 
513    /*
514    Check the input strings to make sure the pointers
515    are non-null and the string lengths are non-zero.
516    */
517    CHKFSTR ( CHK_STANDARD, "ckw02_c", ref   );
518    CHKFSTR ( CHK_STANDARD, "ckw02_c", segid );
519 
520 
521    /*
522    Write the segment.  Note that the quaternion and angular velocity
523    arrays DO NOT require transposition!
524    */
525 
526    ckw02_( ( integer    * ) &handle,
527            ( doublereal * ) &begtim,
528            ( doublereal * ) &endtim,
529            ( integer    * ) &inst,
530            ( char       * ) ref,
531            ( char       * ) segid,
532            ( integer    * ) &nrec,
533            ( doublereal * ) start,
534            ( doublereal * ) stop,
535            ( doublereal * ) quats,
536            ( doublereal * ) avvs,
537            ( doublereal * ) rates,
538            ( ftnlen       ) strlen(ref),
539            ( ftnlen       ) strlen(segid)  );
540 
541 
542    chkout_c ( "ckw02_c" );
543 
544 } /* End ckw02_c */
545