1 /* ckw04a.f -- translated by f2c (version 19980913).
2    You must link the resulting object file with the libraries:
3 	-lf2c -lm   (in that order)
4 */
5 
6 #include "f2c.h"
7 
8 /* Table of constant values */
9 
10 static integer c__142 = 142;
11 static integer c__7 = 7;
12 static doublereal c_b20 = 128.;
13 
14 /* $Procedure      CKW04A ( CK type 04: Add data to a segment ) */
ckw04a_(integer * handle,integer * npkts,integer * pktsiz,doublereal * pktdat,doublereal * sclkdp)15 /* Subroutine */ int ckw04a_(integer *handle, integer *npkts, integer *pktsiz,
16 	 doublereal *pktdat, doublereal *sclkdp)
17 {
18     /* System generated locals */
19     integer i__1, i__2;
20 
21     /* Builtin functions */
22     integer s_rnge(char *, integer, char *, integer);
23 
24     /* Local variables */
25     integer k;
26     extern /* Subroutine */ int chkin_(char *, ftnlen);
27     integer dispm, kk;
28     extern /* Subroutine */ int errhan_(char *, integer *, ftnlen);
29     integer displm;
30     extern /* Subroutine */ int sigerr_(char *, ftnlen);
31     integer numcft[7];
32     extern /* Subroutine */ int chkout_(char *, ftnlen), setmsg_(char *,
33 	    ftnlen), errint_(char *, integer *, ftnlen);
34     extern logical return_(void);
35     extern /* Subroutine */ int sgwvpk_(integer *, integer *, integer *,
36 	    doublereal *, integer *, doublereal *), zzck4i2d_(integer *,
37 	    integer *, doublereal *, doublereal *);
38 
39 /* $ Abstract */
40 
41 /*     Add data to a type 4 CK segment currently being written to */
42 /*     the file associated with HANDLE. See also CKW04B and CKW04E. */
43 
44 /* $ Disclaimer */
45 
46 /*     THIS SOFTWARE AND ANY RELATED MATERIALS WERE CREATED BY THE */
47 /*     CALIFORNIA INSTITUTE OF TECHNOLOGY (CALTECH) UNDER A U.S. */
48 /*     GOVERNMENT CONTRACT WITH THE NATIONAL AERONAUTICS AND SPACE */
49 /*     ADMINISTRATION (NASA). THE SOFTWARE IS TECHNOLOGY AND SOFTWARE */
50 /*     PUBLICLY AVAILABLE UNDER U.S. EXPORT LAWS AND IS PROVIDED "AS-IS" */
51 /*     TO THE RECIPIENT WITHOUT WARRANTY OF ANY KIND, INCLUDING ANY */
52 /*     WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A */
53 /*     PARTICULAR USE OR PURPOSE (AS SET FORTH IN UNITED STATES UCC */
54 /*     SECTIONS 2312-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE */
55 /*     SOFTWARE AND RELATED MATERIALS, HOWEVER USED. */
56 
57 /*     IN NO EVENT SHALL CALTECH, ITS JET PROPULSION LABORATORY, OR NASA */
58 /*     BE LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING, BUT NOT */
59 /*     LIMITED TO, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND, */
60 /*     INCLUDING ECONOMIC DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS, */
61 /*     REGARDLESS OF WHETHER CALTECH, JPL, OR NASA BE ADVISED, HAVE */
62 /*     REASON TO KNOW, OR, IN FACT, SHALL KNOW OF THE POSSIBILITY. */
63 
64 /*     RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF */
65 /*     THE SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY */
66 /*     CALTECH AND NASA FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE */
67 /*     ACTIONS OF RECIPIENT IN THE USE OF THE SOFTWARE. */
68 
69 /* $ Required_Reading */
70 
71 /*     CK */
72 /*     DAF */
73 
74 /* $ Keywords */
75 
76 /*     POINTING */
77 
78 /* $ Declarations */
79 /* $ Abstract */
80 
81 /*     Declarations of the CK data type specific and general CK low */
82 /*     level routine parameters. */
83 
84 /* $ Disclaimer */
85 
86 /*     THIS SOFTWARE AND ANY RELATED MATERIALS WERE CREATED BY THE */
87 /*     CALIFORNIA INSTITUTE OF TECHNOLOGY (CALTECH) UNDER A U.S. */
88 /*     GOVERNMENT CONTRACT WITH THE NATIONAL AERONAUTICS AND SPACE */
89 /*     ADMINISTRATION (NASA). THE SOFTWARE IS TECHNOLOGY AND SOFTWARE */
90 /*     PUBLICLY AVAILABLE UNDER U.S. EXPORT LAWS AND IS PROVIDED "AS-IS" */
91 /*     TO THE RECIPIENT WITHOUT WARRANTY OF ANY KIND, INCLUDING ANY */
92 /*     WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A */
93 /*     PARTICULAR USE OR PURPOSE (AS SET FORTH IN UNITED STATES UCC */
94 /*     SECTIONS 2312-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE */
95 /*     SOFTWARE AND RELATED MATERIALS, HOWEVER USED. */
96 
97 /*     IN NO EVENT SHALL CALTECH, ITS JET PROPULSION LABORATORY, OR NASA */
98 /*     BE LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING, BUT NOT */
99 /*     LIMITED TO, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND, */
100 /*     INCLUDING ECONOMIC DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS, */
101 /*     REGARDLESS OF WHETHER CALTECH, JPL, OR NASA BE ADVISED, HAVE */
102 /*     REASON TO KNOW, OR, IN FACT, SHALL KNOW OF THE POSSIBILITY. */
103 
104 /*     RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF */
105 /*     THE SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY */
106 /*     CALTECH AND NASA FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE */
107 /*     ACTIONS OF RECIPIENT IN THE USE OF THE SOFTWARE. */
108 
109 /* $ Required_Reading */
110 
111 /*     CK.REQ */
112 
113 /* $ Keywords */
114 
115 /*     CK */
116 
117 /* $ Restrictions */
118 
119 /*     1) If new CK types are added, the size of the record passed */
120 /*        between CKRxx and CKExx must be registered as separate */
121 /*        parameter. If this size will be greater than current value */
122 /*        of the CKMRSZ parameter (which specifies the maximum record */
123 /*        size for the record buffer used inside CKPFS) then it should */
124 /*        be assigned to CKMRSZ as a new value. */
125 
126 /* $ Author_and_Institution */
127 
128 /*     N.J. Bachman      (JPL) */
129 /*     B.V. Semenov      (JPL) */
130 
131 /* $ Literature_References */
132 
133 /*     CK Required Reading. */
134 
135 /* $ Version */
136 
137 /* -    SPICELIB Version 3.0.0, 27-JAN-2014 (NJB) */
138 
139 /*        Updated to support CK type 6. Maximum degree for */
140 /*        type 5 was updated to be consistent with the */
141 /*        maximum degree for type 6. */
142 
143 /* -    SPICELIB Version 2.0.0, 19-AUG-2002 (NJB) */
144 
145 /*        Updated to support CK type 5. */
146 
147 /* -    SPICELIB Version 1.0.0, 05-APR-1999 (BVS) */
148 
149 /* -& */
150 
151 /*     Number of quaternion components and number of quaternion and */
152 /*     angular rate components together. */
153 
154 
155 /*     CK Type 1 parameters: */
156 
157 /*     CK1DTP   CK data type 1 ID; */
158 
159 /*     CK1RSZ   maximum size of a record passed between CKR01 */
160 /*              and CKE01. */
161 
162 
163 /*     CK Type 2 parameters: */
164 
165 /*     CK2DTP   CK data type 2 ID; */
166 
167 /*     CK2RSZ   maximum size of a record passed between CKR02 */
168 /*              and CKE02. */
169 
170 
171 /*     CK Type 3 parameters: */
172 
173 /*     CK3DTP   CK data type 3 ID; */
174 
175 /*     CK3RSZ   maximum size of a record passed between CKR03 */
176 /*              and CKE03. */
177 
178 
179 /*     CK Type 4 parameters: */
180 
181 /*     CK4DTP   CK data type 4 ID; */
182 
183 /*     CK4PCD   parameter defining integer to DP packing schema that */
184 /*              is applied when seven number integer array containing */
185 /*              polynomial degrees for quaternion and angular rate */
186 /*              components packed into a single DP number stored in */
187 /*              actual CK records in a file; the value of must not be */
188 /*              changed or compatibility with existing type 4 CK files */
189 /*              will be lost. */
190 
191 /*     CK4MXD   maximum Chebychev polynomial degree allowed in type 4 */
192 /*              records; the value of this parameter must never exceed */
193 /*              value of the CK4PCD; */
194 
195 /*     CK4SFT   number of additional DPs, which are not polynomial */
196 /*              coefficients, located at the beginning of a type 4 */
197 /*              CK record that passed between routines CKR04 and CKE04; */
198 
199 /*     CK4RSZ   maximum size of type 4 CK record passed between CKR04 */
200 /*              and CKE04; CK4RSZ is computed as follows: */
201 
202 /*                 CK4RSZ = ( CK4MXD + 1 ) * QAVSIZ + CK4SFT */
203 
204 
205 /*     CK Type 5 parameters: */
206 
207 
208 /*     CK5DTP   CK data type 5 ID; */
209 
210 /*     CK5MXD   maximum polynomial degree allowed in type 5 */
211 /*              records. */
212 
213 /*     CK5MET   number of additional DPs, which are not polynomial */
214 /*              coefficients, located at the beginning of a type 5 */
215 /*              CK record that passed between routines CKR05 and CKE05; */
216 
217 /*     CK5MXP   maximum packet size for any subtype.  Subtype 2 */
218 /*              has the greatest packet size, since these packets */
219 /*              contain a quaternion, its derivative, an angular */
220 /*              velocity vector, and its derivative.  See ck05.inc */
221 /*              for a description of the subtypes. */
222 
223 /*     CK5RSZ   maximum size of type 5 CK record passed between CKR05 */
224 /*              and CKE05; CK5RSZ is computed as follows: */
225 
226 /*                 CK5RSZ = ( CK5MXD + 1 ) * CK5MXP + CK5MET */
227 
228 
229 /*     CK Type 6 parameters: */
230 
231 
232 /*     CK6DTP   CK data type 6 ID; */
233 
234 /*     CK6MXD   maximum polynomial degree allowed in type 6 */
235 /*              records. */
236 
237 /*     CK6MET   number of additional DPs, which are not polynomial */
238 /*              coefficients, located at the beginning of a type 6 */
239 /*              CK record that passed between routines CKR06 and CKE06; */
240 
241 /*     CK6MXP   maximum packet size for any subtype.  Subtype 2 */
242 /*              has the greatest packet size, since these packets */
243 /*              contain a quaternion, its derivative, an angular */
244 /*              velocity vector, and its derivative.  See ck06.inc */
245 /*              for a description of the subtypes. */
246 
247 /*     CK6RSZ   maximum size of type 6 CK record passed between CKR06 */
248 /*              and CKE06; CK6RSZ is computed as follows: */
249 
250 /*                 CK6RSZ = CK6MET + ( CK6MXD + 1 ) * ( CK6PS3 + 1 ) */
251 
252 /*              where CK6PS3 is equal to the parameter CK06PS3 defined */
253 /*              in ck06.inc. Note that the subtype having the largest */
254 /*              packet size (subtype 2) does not give rise to the */
255 /*              largest record size, because that type is Hermite and */
256 /*              requires half the window size used by subtype 3 for a */
257 /*              given polynomial degree. */
258 
259 
260 /*     The parameter CK6PS3 must be in sync with C06PS3 defined in */
261 /*     ck06.inc. */
262 
263 
264 
265 /*     Maximum record size that can be handled by CKPFS. This value */
266 /*     must be set to the maximum of all CKxRSZ parameters (currently */
267 /*     CK5RSZ.) */
268 
269 /* $ Brief_I/O */
270 
271 /*     VARIABLE  I/O  DESCRIPTION */
272 /*     --------  ---  -------------------------------------------------- */
273 /*     HANDLE     I   The handle of an DAF file opened for writing. */
274 /*     NPKTS      I   Number of data packets to write to a segment. */
275 /*     PKTSIZ     I   The numbers of values in the data packets */
276 /*     PKTDAT     I   The data packets. */
277 /*     SCLKDP     I   The SCLK times associated with the data packets. */
278 
279 /* $ Detailed_Input */
280 
281 /*     HANDLE     is the file handle of a CK file in which a CK type 4 */
282 /*                segment is currently being written. */
283 
284 /*     NPKTS      is the number of data packets to write to a segment. */
285 
286 /*     PKTSIZ     is the number of values in all data packets. */
287 
288 /*     PKTDAT     is the data packets. The data packets in this array */
289 /*                must be organized as described in the $ Particulars */
290 /*                section of the header. */
291 
292 /*     SCLKDP     contains the initial SCLK times corresponding to the */
293 /*                Chebyshev coefficients in PKTSIZ. The I'th time is */
294 /*                start time of the I'th packet coverage interval. */
295 /*                The times must form a strictly increasing sequence. */
296 
297 /* $ Detailed_Output */
298 
299 /*     None.      Data is stored in a segment in the DAF file */
300 /*                associated with HANDLE. */
301 
302 /* $ Parameters */
303 
304 /*     See 'ckparam.inc'. */
305 
306 /* $ Exceptions */
307 
308 /*     1) If the number of coefficient sets and epochs is not positive, */
309 /*        the error SPICE(INVALIDARGUMENT) will be signalled. */
310 
311 /*     2) If size of any input packet is greater that maximum allowed */
312 /*        type 4 CK record size minus one, the error */
313 /*        SPICE(INVALIDARGUMENT) will be signalled. */
314 
315 /* $ Files */
316 
317 /*     See HANDLE in the $ Detailed_Input section. */
318 
319 /* $ Particulars */
320 
321 /*     This routine adds data to a type 4 CK segment that is currently */
322 /*     being written to the associated with HANDLE. The segment must */
323 /*     have been started by a call to the routine CKW04B, the routine */
324 /*     which begins a type 4 CK segment. */
325 
326 /*     This routine is one of a set of three routines for creating and */
327 /*     adding data to type 4 CK segments. These routines are: */
328 
329 /*        CKW04B: Begin a type 4 CK segment. This routine must be */
330 /*                called before any data may be added to a type 4 */
331 /*                segment. */
332 
333 /*        CKW04A: Add data to a type 4 CK segment. This routine may be */
334 /*                called any number of times after a call to CKW04B to */
335 /*                add type 4 records to the CK segment that was */
336 /*                started. */
337 
338 /*        CKW04E: End a type 4 CK segment. This routine is called to */
339 /*                make the type 4 segment a permanent addition to the */
340 /*                DAF file. Once this routine is called, no further type */
341 /*                4 records may be added to the segment. A new segment */
342 /*                must be started. */
343 
344 /*     A type 4 CK segment consists of coefficient sets for variable */
345 /*     order Chebyshev polynomials over consecutive time intervals of a */
346 /*     variable length. The gaps between intervals are allowed. The */
347 /*     Chebyshev polynomials represent individual SPICE-style quaternion */
348 /*     components q0, q1, q2 and q3 and individual angular velocities */
349 /*     AV1, AV2 and AV3 if they are included with the data. */
350 
351 /*     See the discussion of quaternion styles below. */
352 
353 /*     The pointing data supplied to the type 4 CK writer (CKW04A) */
354 /*     is packed into an array as a sequence of records, */
355 
356 /*        ---------------------------------------------------- */
357 /*        | Record 1 | Record 2 | .. | Record N-1 | Record N | */
358 /*        ---------------------------------------------------- */
359 
360 /*     with each record in data packets has the following format. */
361 
362 /*        ---------------------------------------------------- */
363 /*        | The midpoint of the approximation interval       | */
364 /*        ---------------------------------------------------- */
365 /*        | The radius of the approximation interval         | */
366 /*        ---------------------------------------------------- */
367 /*        | Number of coefficients for q0                    | */
368 /*        ---------------------------------------------------- */
369 /*        | Number of coefficients for q1                    | */
370 /*        ---------------------------------------------------- */
371 /*        | Number of coefficients for q2                    | */
372 /*        ---------------------------------------------------- */
373 /*        | Number of coefficients for q3                    | */
374 /*        ---------------------------------------------------- */
375 /*        | Number of coefficients for AV1                   | */
376 /*        ---------------------------------------------------- */
377 /*        | Number of coefficients for AV2                   | */
378 /*        ---------------------------------------------------- */
379 /*        | Number of coefficients for AV3                   | */
380 /*        ---------------------------------------------------- */
381 /*        | q0 Cheby coefficients                            | */
382 /*        ---------------------------------------------------- */
383 /*        | q1 Cheby coefficients                            | */
384 /*        ---------------------------------------------------- */
385 /*        | q2 Cheby coefficients                            | */
386 /*        ---------------------------------------------------- */
387 /*        | q3 Cheby coefficients                            | */
388 /*        ---------------------------------------------------- */
389 /*        | AV1 Cheby coefficients (optional)                | */
390 /*        ---------------------------------------------------- */
391 /*        | AV2 Cheby coefficients (optional)                | */
392 /*        ---------------------------------------------------- */
393 /*        | AV3 Cheby coefficients (optional)                | */
394 /*        ---------------------------------------------------- */
395 
396 
397 
398 /*     Quaternion Styles */
399 /*     ----------------- */
400 
401 /*     There are different "styles" of quaternions used in */
402 /*     science and engineering applications. Quaternion styles */
403 /*     are characterized by */
404 
405 /*        - The order of quaternion elements */
406 
407 /*        - The quaternion multiplication formula */
408 
409 /*        - The convention for associating quaternions */
410 /*          with rotation matrices */
411 
412 /*     Two of the commonly used styles are */
413 
414 /*        - "SPICE" */
415 
416 /*           > Invented by Sir William Rowan Hamilton */
417 /*           > Frequently used in mathematics and physics textbooks */
418 
419 /*        - "Engineering" */
420 
421 /*           > Widely used in aerospace engineering applications */
422 
423 
424 /*     SPICELIB subroutine interfaces ALWAYS use SPICE quaternions. */
425 /*     Quaternions of any other style must be converted to SPICE */
426 /*     quaternions before they are passed to SPICELIB routines. */
427 
428 
429 /*     Relationship between SPICE and Engineering Quaternions */
430 /*     ------------------------------------------------------ */
431 
432 /*     Let M be a rotation matrix such that for any vector V, */
433 
434 /*        M*V */
435 
436 /*     is the result of rotating V by theta radians in the */
437 /*     counterclockwise direction about unit rotation axis vector A. */
438 /*     Then the SPICE quaternions representing M are */
439 
440 /*        (+/-) (  cos(theta/2), */
441 /*                 sin(theta/2) A(1), */
442 /*                 sin(theta/2) A(2), */
443 /*                 sin(theta/2) A(3)  ) */
444 
445 /*     while the engineering quaternions representing M are */
446 
447 /*        (+/-) ( -sin(theta/2) A(1), */
448 /*                -sin(theta/2) A(2), */
449 /*                -sin(theta/2) A(3), */
450 /*                 cos(theta/2)       ) */
451 
452 /*     For both styles of quaternions, if a quaternion q represents */
453 /*     a rotation matrix M, then -q represents M as well. */
454 
455 /*     Given an engineering quaternion */
456 
457 /*        QENG   = ( q0,  q1,  q2,  q3 ) */
458 
459 /*     the equivalent SPICE quaternion is */
460 
461 /*        QSPICE = ( q3, -q0, -q1, -q2 ) */
462 
463 
464 /*     Associating SPICE Quaternions with Rotation Matrices */
465 /*     ---------------------------------------------------- */
466 
467 /*     Let FROM and TO be two right-handed reference frames, for */
468 /*     example, an inertial frame and a spacecraft-fixed frame. Let the */
469 /*     symbols */
470 
471 /*        V    ,   V */
472 /*         FROM     TO */
473 
474 /*     denote, respectively, an arbitrary vector expressed relative to */
475 /*     the FROM and TO frames. Let M denote the transformation matrix */
476 /*     that transforms vectors from frame FROM to frame TO; then */
477 
478 /*        V   =  M * V */
479 /*         TO         FROM */
480 
481 /*     where the expression on the right hand side represents left */
482 /*     multiplication of the vector by the matrix. */
483 
484 /*     Then if the unit-length SPICE quaternion q represents M, where */
485 
486 /*        q = (q0, q1, q2, q3) */
487 
488 /*     the elements of M are derived from the elements of q as follows: */
489 
490 /*          +-                                                         -+ */
491 /*          |           2    2                                          | */
492 /*          | 1 - 2*( q2 + q3 )   2*(q1*q2 - q0*q3)   2*(q1*q3 + q0*q2) | */
493 /*          |                                                           | */
494 /*          |                                                           | */
495 /*          |                               2    2                      | */
496 /*      M = | 2*(q1*q2 + q0*q3)   1 - 2*( q1 + q3 )   2*(q2*q3 - q0*q1) | */
497 /*          |                                                           | */
498 /*          |                                                           | */
499 /*          |                                                   2    2  | */
500 /*          | 2*(q1*q3 - q0*q2)   2*(q2*q3 + q0*q1)   1 - 2*( q1 + q2 ) | */
501 /*          |                                                           | */
502 /*          +-                                                         -+ */
503 
504 /*     Note that substituting the elements of -q for those of q in the */
505 /*     right hand side leaves each element of M unchanged; this shows */
506 /*     that if a quaternion q represents a matrix M, then so does the */
507 /*     quaternion -q. */
508 
509 /*     To map the rotation matrix M to a unit quaternion, we start by */
510 /*     decomposing the rotation matrix as a sum of symmetric */
511 /*     and skew-symmetric parts: */
512 
513 /*                                        2 */
514 /*        M = [ I  +  (1-cos(theta)) OMEGA  ] + [ sin(theta) OMEGA ] */
515 
516 /*                     symmetric                   skew-symmetric */
517 
518 
519 /*     OMEGA is a skew-symmetric matrix of the form */
520 
521 /*                   +-             -+ */
522 /*                   |  0   -n3   n2 | */
523 /*                   |               | */
524 /*         OMEGA  =  |  n3   0   -n1 | */
525 /*                   |               | */
526 /*                   | -n2   n1   0  | */
527 /*                   +-             -+ */
528 
529 /*     The vector N of matrix entries (n1, n2, n3) is the rotation axis */
530 /*     of M and theta is M's rotation angle.  Note that N and theta */
531 /*     are not unique. */
532 
533 /*     Let */
534 
535 /*        C = cos(theta/2) */
536 /*        S = sin(theta/2) */
537 
538 /*     Then the unit quaternions Q corresponding to M are */
539 
540 /*        Q = +/- ( C, S*n1, S*n2, S*n3 ) */
541 
542 /*     The mappings between quaternions and the corresponding rotations */
543 /*     are carried out by the SPICELIB routines */
544 
545 /*        Q2M {quaternion to matrix} */
546 /*        M2Q {matrix to quaternion} */
547 
548 /*     M2Q always returns a quaternion with scalar part greater than */
549 /*     or equal to zero. */
550 
551 
552 /*     SPICE Quaternion Multiplication Formula */
553 /*     --------------------------------------- */
554 
555 /*     Given a SPICE quaternion */
556 
557 /*        Q = ( q0, q1, q2, q3 ) */
558 
559 /*     corresponding to rotation axis A and angle theta as above, we can */
560 /*     represent Q using "scalar + vector" notation as follows: */
561 
562 /*        s =   q0           = cos(theta/2) */
563 
564 /*        v = ( q1, q2, q3 ) = sin(theta/2) * A */
565 
566 /*        Q = s + v */
567 
568 /*     Let Q1 and Q2 be SPICE quaternions with respective scalar */
569 /*     and vector parts s1, s2 and v1, v2: */
570 
571 /*        Q1 = s1 + v1 */
572 /*        Q2 = s2 + v2 */
573 
574 /*     We represent the dot product of v1 and v2 by */
575 
576 /*        <v1, v2> */
577 
578 /*     and the cross product of v1 and v2 by */
579 
580 /*        v1 x v2 */
581 
582 /*     Then the SPICE quaternion product is */
583 
584 /*        Q1*Q2 = s1*s2 - <v1,v2>  + s1*v2 + s2*v1 + (v1 x v2) */
585 
586 /*     If Q1 and Q2 represent the rotation matrices M1 and M2 */
587 /*     respectively, then the quaternion product */
588 
589 /*        Q1*Q2 */
590 
591 /*     represents the matrix product */
592 
593 /*        M1*M2 */
594 
595 
596 /* $ Examples */
597 
598 /*     Assume that we have: */
599 
600 /*        HANDLE   is the handle of an CK file opened with write */
601 /*                 access. */
602 
603 /*        SEGID    is a character string of no more than 40 characters */
604 /*                 which provides a pedigree for the data in the CK */
605 /*                 segment we will create. */
606 
607 /*        INST     is the SPICE ID code for the instrument whose */
608 /*                 pointing data is to be placed into the file. */
609 
610 /*        AVFLAG   angular rates flag. */
611 
612 /*        REFFRM   is the name of the SPICE reference frame for the */
613 /*                 pointing data. */
614 
615 /*        BEGTIM   is the starting encoded SCLK time for which the */
616 /*                 segment is valid. */
617 
618 /*        ENDTIM   is the ending encoded SCLK time for which the segment */
619 /*                 is valid. */
620 
621 /*        N        is the number of type 4 records that we want to */
622 /*                 put into a segment in an CK file. */
623 
624 /*        NPKTS    is integer array which contains the lengths of */
625 /*                 variable size data packets */
626 
627 /*        RECRDS   contains N type 4 records packaged for the CK */
628 /*                 file. */
629 
630 /*        SCSTRT   contains the initial encoded SC time for each of */
631 /*                 the records contained in RECRDS, where */
632 
633 /*                    SCSTRT(I) < SCSTRT(I+1), I = 1, N-1 */
634 
635 /*                    SCSTRT(1) <= FIRST, SCSTRT(N) < LAST */
636 
637 /*     Then the following code fragment demonstrates how to create */
638 /*     a type 4 CK segment if all of the data for the segment is */
639 /*     available at one time. */
640 
641 /*     C */
642 /*     C     Begin the segment. */
643 /*     C */
644 /*           CALL CKW04B ( HANDLE, BEGTIM, INST, REF, AVFLAG, SEGID ) */
645 /*     C */
646 /*     C     Add the data to the segment all at once. */
647 /*     C */
648 /*           CALL CKW04A ( HANDLE, N, NPKTS, RECRDS, SCSTRT ) */
649 /*     C */
650 /*     C     End the segment, making the segment a permanent */
651 /*     C     addition to the CK file. */
652 /*     C */
653 /*           CALL CKW04E ( HANDLE, ENDTIM ) */
654 
655 /* $ Restrictions */
656 
657 /*     1) The type 4 CK segment to which the data is added must have */
658 /*        been started by the routine CKW04B, the routine which begins */
659 /*        a type 4 CK segment. */
660 
661 /* $ Literature_References */
662 
663 /*     None. */
664 
665 /* $ Author_and_Institution */
666 
667 /*     Y.K. Zaiko     (JPL) */
668 /*     B.V. Semenov   (JPL) */
669 
670 /* $ Version */
671 
672 /* -    SPICELIB Version 1.1.2, 18-APR-2014 (BVS) */
673 
674 /*        Minor header edits. */
675 
676 /* -    SPICELIB Version 1.1.1, 26-FEB-2008 (NJB) */
677 
678 /*        Updated header; added information about SPICE */
679 /*        quaternion conventions. */
680 
681 /* -    SPICELIB Version 1.1.0, 07-SEP-2001 (EDW) */
682 
683 /*        Removed DAFHLU call; replaced ERRFNM call with ERRHAN. */
684 /*        Added IMPLICIT NONE. */
685 
686 /* -    SPICELIB Version 1.0.0, 05-MAY-1999 (YKZ) (BVS) */
687 
688 /* -& */
689 /* $ Index_Entries */
690 
691 /*     add data to a type_4 ck segment */
692 
693 /* -& */
694 
695 /*     Spicelib functions. */
696 
697 
698 /*     Local parameters. */
699 
700 
701 /*     The number of elements by which coefficients in each packet */
702 /*     have to be shifted to the left after numbers of coefficients */
703 /*     were packed into a single integer. */
704 
705 
706 /*     Local Variables. */
707 
708 
709 /*     Standard SPICELIB error handling. */
710 
711     if (return_()) {
712 	return 0;
713     } else {
714 	chkin_("CKW04A", (ftnlen)6);
715     }
716 
717 /*     First, check if the number of coefficient sets and epochs */
718 /*     is positive and whether each packet is smaller than the */
719 /*     maximum size of a record that CKPFS can handle. */
720 
721     i__1 = *npkts;
722     for (k = 1; k <= i__1; ++k) {
723 	if (pktsiz[k - 1] <= 0) {
724 	    setmsg_("The number of coefficient sets and epochs in the # data"
725 		    " packet (record) to be added to the DAF segment in the f"
726 		    "ile '#' was not positive. Its value was: #.", (ftnlen)154)
727 		    ;
728 	    errint_("#", &k, (ftnlen)1);
729 	    errhan_("#", handle, (ftnlen)1);
730 	    errint_("#", &pktsiz[k - 1], (ftnlen)1);
731 	    sigerr_("SPICE(INVALIDARGUMENT)", (ftnlen)22);
732 	    chkout_("CKW04A", (ftnlen)6);
733 	    return 0;
734 	}
735 
736 /*        We do .GE. comparison because a type 4 CK record passed */
737 /*        inside CKPFS will have one more element -- time at which */
738 /*        the pointing will be evaluated. */
739 
740 	if (pktsiz[k - 1] >= 143) {
741 	    setmsg_("The total size of the # data packet (record) to be adde"
742 		    "d to the DAF segment in the file '#' is greater than the"
743 		    " maximum allowed type 4 record size #. Its value was: #.",
744 		     (ftnlen)167);
745 	    errint_("#", &k, (ftnlen)1);
746 	    errhan_("#", handle, (ftnlen)1);
747 	    errint_("#", &c__142, (ftnlen)1);
748 	    errint_("#", &pktsiz[k - 1], (ftnlen)1);
749 	    sigerr_("SPICE(INVALIDARGUMENT)", (ftnlen)22);
750 	    chkout_("CKW04A", (ftnlen)6);
751 	    return 0;
752 	}
753     }
754     displm = 0;
755     dispm = 0;
756 
757 /*     The cycle below encodes groups of numbers of coefficients in */
758 /*     data packets to single double precision numbers and shift */
759 /*     data in packets to the left to decrease the data packet */
760 /*     lengths. */
761 
762     i__1 = *npkts;
763     for (k = 1; k <= i__1; ++k) {
764 
765 /*        Encode integer numbers of coefficients for each component */
766 /*        to single double precision variable */
767 
768 	for (kk = 1; kk <= 7; ++kk) {
769 	    numcft[(i__2 = kk - 1) < 7 && 0 <= i__2 ? i__2 : s_rnge("numcft",
770 		    i__2, "ckw04a_", (ftnlen)580)] = (integer) pktdat[kk + 2
771 		    + displm - 1];
772 	}
773 	zzck4i2d_(numcft, &c__7, &c_b20, &pktdat[dispm + 2]);
774 
775 /*        Shift coefficients sets to the left to overwrite numbers of */
776 /*        packets */
777 
778 	i__2 = pktsiz[k - 1];
779 	for (kk = 4; kk <= i__2; ++kk) {
780 	    pktdat[kk + dispm - 1] = pktdat[kk + 6 + displm - 1];
781 	}
782 
783 /*        Shift middle value and radii of interval */
784 
785 	pktdat[dispm] = pktdat[displm];
786 	pktdat[dispm + 1] = pktdat[displm + 1];
787 	displm += pktsiz[k - 1];
788 
789 /*        Length of each data packet became less for 6 elements because */
790 /*        of encoding of 7 double precision numbers, which are the */
791 /*        numbers of polynomial coefficients, to one double precision */
792 /*        number */
793 
794 	pktsiz[k - 1] += -6;
795 	dispm += pktsiz[k - 1];
796     }
797 
798 /*     Add the data. */
799 
800     sgwvpk_(handle, npkts, pktsiz, pktdat, npkts, sclkdp);
801 
802 /*     No need to check FAILED() here, since all we do is check out. */
803 /*     Leave it up to the caller. */
804 
805     chkout_("CKW04A", (ftnlen)6);
806     return 0;
807 } /* ckw04a_ */
808 
809