1 /* pckmat.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__2 = 2;
11 static integer c__5 = 5;
12 static integer c__3 = 3;
13 static integer c__1 = 1;
14 static integer c__130 = 130;
15 
16 /* $Procedure PCKMAT ( PCK, get transformation matrix at time ) */
pckmat_(integer * body,doublereal * et,integer * ref,doublereal * tsipm,logical * found)17 /* Subroutine */ int pckmat_(integer *body, doublereal *et, integer *ref,
18 	doublereal *tsipm, logical *found)
19 {
20     integer type__;
21     extern /* Subroutine */ int pcke02_(doublereal *, doublereal *,
22 	    doublereal *), pcke03_(doublereal *, doublereal *, doublereal *),
23 	    pcke20_(doublereal *, doublereal *, doublereal *), chkin_(char *,
24 	    ftnlen);
25     doublereal descr[5];
26     extern /* Subroutine */ int pckr02_(integer *, doublereal *, doublereal *,
27 	     doublereal *), dafus_(doublereal *, integer *, integer *,
28 	    doublereal *, integer *);
29     char ident[40];
30     extern /* Subroutine */ int pckr03_(integer *, doublereal *, doublereal *,
31 	     doublereal *), pckr20_(integer *, doublereal *, doublereal *,
32 	    doublereal *), eul2xf_(doublereal *, integer *, integer *,
33 	    integer *, doublereal *);
34     extern logical failed_(void);
35     integer handle;
36     doublereal eulang[6], record[130];
37     extern /* Subroutine */ int sgfcon_(integer *, doublereal *, integer *,
38 	    integer *, doublereal *);
39     doublereal estate[6];
40     extern /* Subroutine */ int pcksfs_(integer *, doublereal *, integer *,
41 	    doublereal *, char *, logical *, ftnlen), sigerr_(char *, ftnlen),
42 	     chkout_(char *, ftnlen);
43     integer recsiz;
44     extern /* Subroutine */ int setmsg_(char *, ftnlen), errint_(char *,
45 	    integer *, ftnlen);
46     extern logical return_(void);
47     doublereal dcd[2];
48     integer icd[5];
49 
50 /* $ Abstract */
51 
52 /*      Given a body and epoch, return the name of an inertial */
53 /*      reference frame and the 6 x 6 state transformation matrix */
54 /*      from that frame to the body fixed frame. */
55 
56 /* $ Disclaimer */
57 
58 /*     THIS SOFTWARE AND ANY RELATED MATERIALS WERE CREATED BY THE */
59 /*     CALIFORNIA INSTITUTE OF TECHNOLOGY (CALTECH) UNDER A U.S. */
60 /*     GOVERNMENT CONTRACT WITH THE NATIONAL AERONAUTICS AND SPACE */
61 /*     ADMINISTRATION (NASA). THE SOFTWARE IS TECHNOLOGY AND SOFTWARE */
62 /*     PUBLICLY AVAILABLE UNDER U.S. EXPORT LAWS AND IS PROVIDED "AS-IS" */
63 /*     TO THE RECIPIENT WITHOUT WARRANTY OF ANY KIND, INCLUDING ANY */
64 /*     WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A */
65 /*     PARTICULAR USE OR PURPOSE (AS SET FORTH IN UNITED STATES UCC */
66 /*     SECTIONS 2312-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE */
67 /*     SOFTWARE AND RELATED MATERIALS, HOWEVER USED. */
68 
69 /*     IN NO EVENT SHALL CALTECH, ITS JET PROPULSION LABORATORY, OR NASA */
70 /*     BE LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING, BUT NOT */
71 /*     LIMITED TO, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND, */
72 /*     INCLUDING ECONOMIC DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS, */
73 /*     REGARDLESS OF WHETHER CALTECH, JPL, OR NASA BE ADVISED, HAVE */
74 /*     REASON TO KNOW, OR, IN FACT, SHALL KNOW OF THE POSSIBILITY. */
75 
76 /*     RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF */
77 /*     THE SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY */
78 /*     CALTECH AND NASA FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE */
79 /*     ACTIONS OF RECIPIENT IN THE USE OF THE SOFTWARE. */
80 
81 /* $ Required_Reading */
82 
83 /*     NAIF_IDS */
84 /*     ROTATION */
85 /*     TIME */
86 /*     PCK */
87 
88 /* $ Keywords */
89 
90 /*     TRANSFORMATION */
91 /*     ROTATION */
92 
93 /* $ Declarations */
94 /* $ Brief_I/O */
95 
96 /*     VARIABLE  I/O  DESCRIPTION */
97 /*     --------  ---  -------------------------------------------------- */
98 /*     BODY       I   ID code of some body. */
99 /*     ET         I   Epoch of transformation. */
100 /*     REF        O   Integer code for inertial reference frame. */
101 /*     TSIPM      O   Transformation from Inertial to PM for BODY at ET. */
102 /*     FOUND      O   True if data for BODY and ET are found. */
103 
104 /* $ Detailed_Input */
105 
106 /*     BODY        is the integer ID code of the body for which the */
107 /*                 state transformation matrix is requested. Bodies */
108 /*                 are numbered according to the standard NAIF */
109 /*                 numbering scheme.  The numbering scheme is */
110 /*                 explained in the NAIF_IDS required reading file. */
111 
112 /*     ET          is the epoch at which the state transformation */
113 /*                 matrix is requested. */
114 
115 /* $ Detailed_Output */
116 
117 /*     REF         is the integer code for the inertial reference frame */
118 /*                 of the state transformation matrix TSIPM. (See the */
119 /*                 routine CHGIRF for a full list of inertial reference */
120 /*                 frame names.) */
121 
122 /*     TSIPM       is a 6x6 transformation matrix. It is used to */
123 /*                 transform states from inertial coordinates to body */
124 /*                 fixed (also called equator and prime meridian --- PM) */
125 /*                 coordinates. */
126 
127 /*                 Given a state S in the inertial reference frame */
128 /*                 specified by REF, the corresponding state in the body */
129 /*                 fixed reference frame is given by the matrix vector */
130 /*                 product: */
131 
132 /*                    TSIPM * S */
133 
134 /*                 See the PCK required reading for further details */
135 /*                 concerning PCK reference frames. */
136 
137 /*                 NOTE: The inverse of TSIPM is NOT its transpose. The */
138 /*                 matrix, TSIPM, has the structure shown below: */
139 
140 /*                             -            - */
141 /*                            |       :      | */
142 /*                            |   R   :  0   | */
143 /*                            | ......:......| */
144 /*                            |       :      | */
145 /*                            | dR_dt :  R   | */
146 /*                            |       :      | */
147 /*                             -            - */
148 
149 /*                 where R is a time varying rotation matrix and dR_dt */
150 /*                 is its derivative.  The inverse of this matrix is: */
151 
152 /*                             -              - */
153 /*                            |     T  :       | */
154 /*                            |    R   :  0    | */
155 /*                            | .......:.......| */
156 /*                            |        :       | */
157 /*                            |      T :   T   | */
158 /*                            | dR_dt  :  R    | */
159 /*                            |        :       | */
160 /*                             -              - */
161 
162 /*                 The SPICE routine INVSTM is available for producing */
163 /*                 this inverse. */
164 
165 /*      FOUND      if the data allowing the computation of a state */
166 /*                 transformation matrix for the requested time and body */
167 /*                 are found in a binary PCK file, FOUND will have the */
168 /*                 value .TRUE., otherwise it will have the value */
169 /*                 .FALSE.. */
170 
171 /* $ Parameters */
172 
173 /*     None. */
174 
175 /* $ Exceptions */
176 
177 /*     1)  If the size of the type 20 PCK record to be  retrieved is too */
178 /*         large to fit into RECORD, the error SPICE(PCKRECTOOLARGE) */
179 /*         will be signaled. */
180 
181 /*     2)  Any error that occurs while reading PCK data will be */
182 /*         diagnosed by a routine in the call tree of this routine. */
183 
184 /*     3)  If the requested transformation matrix cannot be computed */
185 /*         using data from loaded binary PCK files, FOUND is returned */
186 /*         with the value .FALSE.. This is not a SPICE error. */
187 
188 /* $ Files */
189 
190 /*     This routine computes transformation matrices using data */
191 /*     provided by a loaded binary PCK kernel. */
192 
193 /* $ Particulars */
194 
195 /*     The matrix for transforming an inertial state into a body fixed */
196 /*     states is the 6x6 matrix shown below as a block structured */
197 /*     matrix. */
198 
199 /*                 -            - */
200 /*                |       :      | */
201 /*                | TIPM  :  0   | */
202 /*                | ......:......| */
203 /*                |       :      | */
204 /*                | DTIPM : TIPM | */
205 /*                |       :      | */
206 /*                 -            - */
207 
208 /*     If a binary PCK file record can be found for the time and body */
209 /*     requested, it will be used. The most recently loaded binary PCK */
210 /*     file has first priority, followed by previously loaded binary PCK */
211 /*     files in backward time order. If no binary PCK file has been */
212 /*     loaded, the text P_constants kernel file is used. */
213 
214 
215 /* $ Examples */
216 
217 /*     Here we load a binary PCK files and use PCKEUL to get the */
218 /*     Euler angles. */
219 
220 /*     C */
221 /*     C  Load binary PCK file. */
222 /*     C */
223 /*        CALL PCKLOF ('example.pck', HANDLE) */
224 
225 /*     C  Call routine to get transformation matrix. */
226 
227 /*        CALL PCKMAT ( BODY, ET, REF, TIPM, FOUND ) */
228 
229 /* $ Restrictions */
230 
231 /*      None. */
232 
233 /* $ Literature_References */
234 
235 /*      None. */
236 
237 /* $ Author_and_Institution */
238 
239 /*      K. S. Zukor     (JPL) */
240 /*      K. R. Gehringer (JPL) */
241 /*      N. J. Bachman   (JPL) */
242 
243 /* $ Version */
244 
245 /* -     SPICELIB Version 3.0.0, 03-JAN-2014 (NJB) (EDW) */
246 
247 /*         Minor edits to Procedure; clean trailing whitespace. */
248 /*         Removed unneeded Revisions section. */
249 
250 /*         Updated to support type 20. Changed long error message */
251 /*         for the case of RECORD having insufficient room: the */
252 /*         user is no longer advised to modify the record size. */
253 
254 /* -     SPICELIB Version 2.0.0, 22-MAR-1995 (KRG) (KSZ) */
255 
256 /*         Added PCK type 03. Added a new exception. Made some minor */
257 /*         comment changes. */
258 
259 /* -     SPICELIB Version 1.0.0, 21-MAR-1995 (KSZ) */
260 
261 /*         Replaces PCKEUL and returns the transformation */
262 /*         matrix rather than the Euler angles. */
263 
264 /* -& */
265 /* $ Index_Entries */
266 
267 /*     get state transformation matrix from binary PCK file */
268 
269 /* -& */
270 
271 /*     SPICELIB functions */
272 
273 
274 /*     Local Parameters */
275 
276 /*     ND and NI values for a PCK file. */
277 
278 
279 /*     Index for the reference frame code in the integer summary. */
280 
281 
282 /*     Length of the descriptor for a PCK file. */
283 
284 
285 /*     Index for the data type code in the integer summary. */
286 
287 
288 /*     Maximum size allowed for a record in a segment of a binary PCK */
289 /*     file. */
290 
291 
292 /*     Number of components in a state vector. */
293 
294 
295 /*     Local Variables */
296 
297 
298 /*     Standard SPICE Error handling. */
299 
300     if (return_()) {
301 	return 0;
302     }
303     chkin_("PCKMAT", (ftnlen)6);
304 
305 /*     Get a segment applicable to a specified body and epoch. */
306 
307     pcksfs_(body, et, &handle, descr, ident, found, (ftnlen)40);
308     if (failed_()) {
309 	*found = FALSE_;
310 	chkout_("PCKMAT", (ftnlen)6);
311 	return 0;
312     }
313     if (*found) {
314 
315 /*        Look at parts of the descriptor. */
316 
317 	dafus_(descr, &c__2, &c__5, dcd, icd);
318 	type__ = icd[2];
319 	*ref = icd[1];
320 	if (type__ == 2) {
321 
322 /*           Read in Chebyshev coefficients from segment. */
323 
324 	    pckr02_(&handle, descr, et, record);
325 
326 /*           Call evaluation routine to get Euler angles */
327 /*           phi, delta, w. */
328 
329 	    pcke02_(et, record, eulang);
330 	    if (failed_()) {
331 		*found = FALSE_;
332 		chkout_("PCKMAT", (ftnlen)6);
333 		return 0;
334 	    }
335 
336 /*           From the PCK type two file the Euler angles are */
337 /*           retrieved in a particular order.  The routine to */
338 /*           get the TSIPM matrix from expects them in another */
339 /*           order.  Here we change from EULANG to ESTATE, which */
340 /*           has this proper order. */
341 
342 	    estate[0] = eulang[2];
343 	    estate[1] = eulang[1];
344 	    estate[2] = eulang[0];
345 	    estate[3] = eulang[5];
346 	    estate[4] = eulang[4];
347 	    estate[5] = eulang[3];
348 
349 /*           Call routine which takes Euler angles to transformation */
350 /*           matrix. */
351 
352 	    eul2xf_(estate, &c__3, &c__1, &c__3, tsipm);
353 	    if (failed_()) {
354 		*found = FALSE_;
355 		chkout_("PCKMAT", (ftnlen)6);
356 		return 0;
357 	    }
358 	} else if (type__ == 3) {
359 
360 /*           Fetch the number of Chebyshev coefficients, compute the */
361 /*           record size needed, and signal an error if there is not */
362 /*           enough storage in RECORD. The number of coefficients is the */
363 /*           first constant value in the generic segment. */
364 
365 	    sgfcon_(&handle, descr, &c__1, &c__1, record);
366 	    if (failed_()) {
367 		*found = FALSE_;
368 		chkout_("PCKMAT", (ftnlen)6);
369 		return 0;
370 	    }
371 	    recsiz = (integer) record[0] * 6 + 2;
372 	    if (recsiz > 130) {
373 		setmsg_("Storage for # double precision numbers is needed fo"
374 			"r a PCK data record and only # locations were availa"
375 			"ble. Notify the NAIF group of this problem.", (ftnlen)
376 			146);
377 		errint_("#", &recsiz, (ftnlen)1);
378 		errint_("#", &c__130, (ftnlen)1);
379 		sigerr_("SPICE(PCKKRECTOOLARGE)", (ftnlen)22);
380 		chkout_("PCKMAT", (ftnlen)6);
381 		return 0;
382 	    }
383 	    pckr03_(&handle, descr, et, record);
384 	    pcke03_(et, record, tsipm);
385 	    if (failed_()) {
386 		*found = FALSE_;
387 		chkout_("PCKMAT", (ftnlen)6);
388 		return 0;
389 	    }
390 	} else if (type__ == 20) {
391 
392 /*           Read in Chebyshev coefficients from segment. */
393 
394 	    pckr20_(&handle, descr, et, record);
395 
396 /*           Call evaluation routine to get Euler angles */
397 /*           phi, delta, w. */
398 
399 	    pcke20_(et, record, eulang);
400 	    if (failed_()) {
401 		*found = FALSE_;
402 		chkout_("PCKMAT", (ftnlen)6);
403 		return 0;
404 	    }
405 
406 /*           From the PCK type 20 file the Euler angles are */
407 /*           retrieved in a particular order. The routine to */
408 /*           get the TSIPM matrix from expects them in another */
409 /*           order. Here we change from EULANG to ESTATE, which */
410 /*           has this proper order. */
411 
412 	    estate[0] = eulang[2];
413 	    estate[1] = eulang[1];
414 	    estate[2] = eulang[0];
415 	    estate[3] = eulang[5];
416 	    estate[4] = eulang[4];
417 	    estate[5] = eulang[3];
418 
419 /*           Call routine which takes Euler angles to transformation */
420 /*           matrix. */
421 
422 	    eul2xf_(estate, &c__3, &c__1, &c__3, tsipm);
423 	    if (failed_()) {
424 		*found = FALSE_;
425 		chkout_("PCKMAT", (ftnlen)6);
426 		return 0;
427 	    }
428 	} else {
429 
430 /*           If data matching the requested body and time was not */
431 /*           found, FOUND is false. */
432 
433 	    *found = FALSE_;
434 	}
435     }
436     chkout_("PCKMAT", (ftnlen)6);
437     return 0;
438 } /* pckmat_ */
439 
440