PageRenderTime 40ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/src/ckw01.c

https://github.com/mattbornski/spice
C | 772 lines | 165 code | 222 blank | 385 comment | 23 complexity | aec8c1f5caebefdc1539096236209480 MD5 | raw file
  1. /* ckw01.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. #include "f2c.h"
  6. /* Table of constant values */
  7. static integer c__2 = 2;
  8. static integer c__6 = 6;
  9. static integer c__4 = 4;
  10. static integer c__3 = 3;
  11. static integer c__1 = 1;
  12. /* $Procedure CKW01 ( C-Kernel, write segment to C-kernel, data type 1 ) */
  13. /* Subroutine */ int ckw01_(integer *handle, doublereal *begtim, doublereal *
  14. endtim, integer *inst, char *ref, logical *avflag, char *segid,
  15. integer *nrec, doublereal *sclkdp, doublereal *quats, doublereal *
  16. avvs, ftnlen ref_len, ftnlen segid_len)
  17. {
  18. /* System generated locals */
  19. integer i__1, i__2;
  20. doublereal d__1;
  21. /* Local variables */
  22. integer ndir, i__;
  23. extern /* Subroutine */ int chkin_(char *, ftnlen), dafps_(integer *,
  24. integer *, doublereal *, integer *, doublereal *);
  25. doublereal descr[5];
  26. extern /* Subroutine */ int errch_(char *, char *, ftnlen, ftnlen);
  27. integer index, value;
  28. extern /* Subroutine */ int errdp_(char *, doublereal *, ftnlen), dafada_(
  29. doublereal *, integer *), dafbna_(integer *, doublereal *, char *,
  30. ftnlen), dafena_(void);
  31. extern logical failed_(void);
  32. integer refcod;
  33. extern /* Subroutine */ int namfrm_(char *, integer *, ftnlen);
  34. extern integer lastnb_(char *, ftnlen);
  35. doublereal dirent;
  36. extern /* Subroutine */ int sigerr_(char *, ftnlen), chkout_(char *,
  37. ftnlen), setmsg_(char *, ftnlen), errint_(char *, integer *,
  38. ftnlen);
  39. extern logical vzerog_(doublereal *, integer *), return_(void);
  40. doublereal dcd[2];
  41. integer icd[6];
  42. /* $ Abstract */
  43. /* Add a type 1 segment to a C-kernel. */
  44. /* $ Disclaimer */
  45. /* THIS SOFTWARE AND ANY RELATED MATERIALS WERE CREATED BY THE */
  46. /* CALIFORNIA INSTITUTE OF TECHNOLOGY (CALTECH) UNDER A U.S. */
  47. /* GOVERNMENT CONTRACT WITH THE NATIONAL AERONAUTICS AND SPACE */
  48. /* ADMINISTRATION (NASA). THE SOFTWARE IS TECHNOLOGY AND SOFTWARE */
  49. /* PUBLICLY AVAILABLE UNDER U.S. EXPORT LAWS AND IS PROVIDED "AS-IS" */
  50. /* TO THE RECIPIENT WITHOUT WARRANTY OF ANY KIND, INCLUDING ANY */
  51. /* WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A */
  52. /* PARTICULAR USE OR PURPOSE (AS SET FORTH IN UNITED STATES UCC */
  53. /* SECTIONS 2312-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE */
  54. /* SOFTWARE AND RELATED MATERIALS, HOWEVER USED. */
  55. /* IN NO EVENT SHALL CALTECH, ITS JET PROPULSION LABORATORY, OR NASA */
  56. /* BE LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING, BUT NOT */
  57. /* LIMITED TO, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND, */
  58. /* INCLUDING ECONOMIC DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS, */
  59. /* REGARDLESS OF WHETHER CALTECH, JPL, OR NASA BE ADVISED, HAVE */
  60. /* REASON TO KNOW, OR, IN FACT, SHALL KNOW OF THE POSSIBILITY. */
  61. /* RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF */
  62. /* THE SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY */
  63. /* CALTECH AND NASA FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE */
  64. /* ACTIONS OF RECIPIENT IN THE USE OF THE SOFTWARE. */
  65. /* $ Required_Reading */
  66. /* CK */
  67. /* DAF */
  68. /* SCLK */
  69. /* $ Keywords */
  70. /* POINTING */
  71. /* UTILITY */
  72. /* $ Declarations */
  73. /* $ Brief_I/O */
  74. /* Variable I/O Description */
  75. /* -------- --- -------------------------------------------------- */
  76. /* HANDLE I Handle of an open CK file. */
  77. /* BEGTIM I The beginning encoded SCLK of the segment. */
  78. /* ENDTIM I The ending encoded SCLK of the segment. */
  79. /* INST I The NAIF instrument ID code. */
  80. /* REF I The reference frame of the segment. */
  81. /* AVFLAG I True if the segment will contain angular velocity. */
  82. /* SEGID I Segment identifier. */
  83. /* NREC I Number of pointing records. */
  84. /* SCLKDP I Encoded SCLK times. */
  85. /* QUATS I SPICE quaternions representing instrument pointing. */
  86. /* AVVS I Angular velocity vectors. */
  87. /* $ Detailed_Input */
  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. /* BEGTIM is the beginning encoded SCLK time of the segment. This */
  92. /* value should be less than or equal to the first time in */
  93. /* the segment. */
  94. /* ENDTIM is the encoded SCLK time at which the segment ends. */
  95. /* This value should be greater than or equal to the last */
  96. /* time in the segment. */
  97. /* INST is the NAIF integer ID code for the instrument. */
  98. /* REF is a character string which specifies the */
  99. /* reference frame of the segment. This should be one of */
  100. /* the frames supported by the SPICELIB routine NAMFRM */
  101. /* which is an entry point of FRAMEX. */
  102. /* AVFLAG is a logical flag which indicates whether or not the */
  103. /* segment will contain angular velocity. */
  104. /* SEGID is the segment identifier. A CK segment identifier may */
  105. /* contain up to 40 characters. */
  106. /* NREC is the number of pointing instances in the segment. */
  107. /* SCLKDP are the encoded spacecraft clock times associated with */
  108. /* each pointing instance. These times must be strictly */
  109. /* increasing. */
  110. /* QUATS is an array of SPICE-style quaternions representing a */
  111. /* sequence of C-matrices. See the discussion of */
  112. /* quaternion styles in Particulars below. */
  113. /* AVVS are the angular velocity vectors ( optional ). */
  114. /* If AVFLAG is FALSE then this array is ignored by the */
  115. /* routine, however it still must be supplied as part of */
  116. /* the calling sequence. */
  117. /* $ Detailed_Output */
  118. /* None. See Files section. */
  119. /* $ Parameters */
  120. /* None. */
  121. /* $ Exceptions */
  122. /* 1) If HANDLE is not the handle of a C-kernel opened for writing */
  123. /* the error will be diagnosed by routines called by this */
  124. /* routine. */
  125. /* 2) If SEGID is more than 40 characters long, the error */
  126. /* SPICE(SEGIDTOOLONG) is signalled. */
  127. /* 3) If SEGID contains any nonprintable characters, the error */
  128. /* SPICE(NONPRINTABLECHARS) is signalled. */
  129. /* 4) If the first encoded SCLK time is negative then the error */
  130. /* SPICE(INVALIDSCLKTIME) is signalled. If any subsequent times */
  131. /* are negative the error SPICE(TIMESOUTOFORDER) is signalled. */
  132. /* 5) If the encoded SCLK times are not strictly increasing, */
  133. /* the error SPICE(TIMESOUTOFORDER) is signalled. */
  134. /* 6) If BEGTIM is greater than SCLKDP(1) or ENDTIM is less than */
  135. /* SCLKDP(NREC), the error SPICE(INVALIDDESCRTIME) is */
  136. /* signalled. */
  137. /* 7) If the name of the reference frame is not one of those */
  138. /* supported by the routine NAMFRM, the error */
  139. /* SPICE(INVALIDREFFRAME) is signalled. */
  140. /* 8) If NREC, the number of pointing records, is less than or */
  141. /* equal to 0, the error SPICE(INVALIDNUMRECS) is signalled. */
  142. /* 9) If the squared length of any quaternion differes from 1 */
  143. /* by more than 1.0D-2, the error SPICE(NONUNITQUATERNION) is */
  144. /* signalled. */
  145. /* $ Files */
  146. /* This routine adds a type 1 segment to a C-kernel. The C-kernel */
  147. /* may be either a new one or an existing one opened for writing. */
  148. /* $ Particulars */
  149. /* For a detailed description of a type 1 CK segment please see the */
  150. /* CK Required Reading. */
  151. /* This routine relieves the user from performing the repetitive */
  152. /* calls to the DAF routines necessary to construct a CK segment. */
  153. /* Quaternion Styles */
  154. /* ----------------- */
  155. /* There are different "styles" of quaternions used in */
  156. /* science and engineering applications. Quaternion styles */
  157. /* are characterized by */
  158. /* - The order of quaternion elements */
  159. /* - The quaternion multiplication formula */
  160. /* - The convention for associating quaternions */
  161. /* with rotation matrices */
  162. /* Two of the commonly used styles are */
  163. /* - "SPICE" */
  164. /* > Invented by Sir William Rowan Hamilton */
  165. /* > Frequently used in mathematics and physics textbooks */
  166. /* - "Engineering" */
  167. /* > Widely used in aerospace engineering applications */
  168. /* SPICELIB subroutine interfaces ALWAYS use SPICE quaternions. */
  169. /* Quaternions of any other style must be converted to SPICE */
  170. /* quaternions before they are passed to SPICELIB routines. */
  171. /* Relationship between SPICE and Engineering Quaternions */
  172. /* ------------------------------------------------------ */
  173. /* Let M be a rotation matrix such that for any vector V, */
  174. /* M*V */
  175. /* is the result of rotating V by theta radians in the */
  176. /* counterclockwise direction about unit rotation axis vector A. */
  177. /* Then the SPICE quaternions representing M are */
  178. /* (+/-) ( cos(theta/2), */
  179. /* sin(theta/2) A(1), */
  180. /* sin(theta/2) A(2), */
  181. /* sin(theta/2) A(3) ) */
  182. /* while the engineering quaternions representing M are */
  183. /* (+/-) ( -sin(theta/2) A(1), */
  184. /* -sin(theta/2) A(2), */
  185. /* -sin(theta/2) A(3), */
  186. /* cos(theta/2) ) */
  187. /* For both styles of quaternions, if a quaternion q represents */
  188. /* a rotation matrix M, then -q represents M as well. */
  189. /* Given an engineering quaternion */
  190. /* QENG = ( q0, q1, q2, q3 ) */
  191. /* the equivalent SPICE quaternion is */
  192. /* QSPICE = ( q3, -q0, -q1, -q2 ) */
  193. /* Associating SPICE Quaternions with Rotation Matrices */
  194. /* ---------------------------------------------------- */
  195. /* Let FROM and TO be two right-handed reference frames, for */
  196. /* example, an inertial frame and a spacecraft-fixed frame. Let the */
  197. /* symbols */
  198. /* V , V */
  199. /* FROM TO */
  200. /* denote, respectively, an arbitrary vector expressed relative to */
  201. /* the FROM and TO frames. Let M denote the transformation matrix */
  202. /* that transforms vectors from frame FROM to frame TO; then */
  203. /* V = M * V */
  204. /* TO FROM */
  205. /* where the expression on the right hand side represents left */
  206. /* multiplication of the vector by the matrix. */
  207. /* Then if the unit-length SPICE quaternion q represents M, where */
  208. /* q = (q0, q1, q2, q3) */
  209. /* the elements of M are derived from the elements of q as follows: */
  210. /* +- -+ */
  211. /* | 2 2 | */
  212. /* | 1 - 2*( q2 + q3 ) 2*(q1*q2 - q0*q3) 2*(q1*q3 + q0*q2) | */
  213. /* | | */
  214. /* | | */
  215. /* | 2 2 | */
  216. /* M = | 2*(q1*q2 + q0*q3) 1 - 2*( q1 + q3 ) 2*(q2*q3 - q0*q1) | */
  217. /* | | */
  218. /* | | */
  219. /* | 2 2 | */
  220. /* | 2*(q1*q3 - q0*q2) 2*(q2*q3 + q0*q1) 1 - 2*( q1 + q2 ) | */
  221. /* | | */
  222. /* +- -+ */
  223. /* Note that substituting the elements of -q for those of q in the */
  224. /* right hand side leaves each element of M unchanged; this shows */
  225. /* that if a quaternion q represents a matrix M, then so does the */
  226. /* quaternion -q. */
  227. /* To map the rotation matrix M to a unit quaternion, we start by */
  228. /* decomposing the rotation matrix as a sum of symmetric */
  229. /* and skew-symmetric parts: */
  230. /* 2 */
  231. /* M = [ I + (1-cos(theta)) OMEGA ] + [ sin(theta) OMEGA ] */
  232. /* symmetric skew-symmetric */
  233. /* OMEGA is a skew-symmetric matrix of the form */
  234. /* +- -+ */
  235. /* | 0 -n3 n2 | */
  236. /* | | */
  237. /* OMEGA = | n3 0 -n1 | */
  238. /* | | */
  239. /* | -n2 n1 0 | */
  240. /* +- -+ */
  241. /* The vector N of matrix entries (n1, n2, n3) is the rotation axis */
  242. /* of M and theta is M's rotation angle. Note that N and theta */
  243. /* are not unique. */
  244. /* Let */
  245. /* C = cos(theta/2) */
  246. /* S = sin(theta/2) */
  247. /* Then the unit quaternions Q corresponding to M are */
  248. /* Q = +/- ( C, S*n1, S*n2, S*n3 ) */
  249. /* The mappings between quaternions and the corresponding rotations */
  250. /* are carried out by the SPICELIB routines */
  251. /* Q2M {quaternion to matrix} */
  252. /* M2Q {matrix to quaternion} */
  253. /* M2Q always returns a quaternion with scalar part greater than */
  254. /* or equal to zero. */
  255. /* SPICE Quaternion Multiplication Formula */
  256. /* --------------------------------------- */
  257. /* Given a SPICE quaternion */
  258. /* Q = ( q0, q1, q2, q3 ) */
  259. /* corresponding to rotation axis A and angle theta as above, we can */
  260. /* represent Q using "scalar + vector" notation as follows: */
  261. /* s = q0 = cos(theta/2) */
  262. /* v = ( q1, q2, q3 ) = sin(theta/2) * A */
  263. /* Q = s + v */
  264. /* Let Q1 and Q2 be SPICE quaternions with respective scalar */
  265. /* and vector parts s1, s2 and v1, v2: */
  266. /* Q1 = s1 + v1 */
  267. /* Q2 = s2 + v2 */
  268. /* We represent the dot product of v1 and v2 by */
  269. /* <v1, v2> */
  270. /* and the cross product of v1 and v2 by */
  271. /* v1 x v2 */
  272. /* Then the SPICE quaternion product is */
  273. /* Q1*Q2 = s1*s2 - <v1,v2> + s1*v2 + s2*v1 + (v1 x v2) */
  274. /* If Q1 and Q2 represent the rotation matrices M1 and M2 */
  275. /* respectively, then the quaternion product */
  276. /* Q1*Q2 */
  277. /* represents the matrix product */
  278. /* M1*M2 */
  279. /* $ Examples */
  280. /* C */
  281. /* C This example writes a type 1 C-kernel segment for the */
  282. /* C Galileo scan platform to a previously opened file attached to */
  283. /* C HANDLE. */
  284. /* C */
  285. /* C Assume arrays of quaternions, angular velocities, and the */
  286. /* C associated SCLK times are produced elsewhere. */
  287. /* C */
  288. /* . */
  289. /* . */
  290. /* . */
  291. /* C */
  292. /* C The subroutine CKW01 needs the following items for the */
  293. /* C segment descriptor: */
  294. /* C */
  295. /* C 1) SCLK limits of the segment. */
  296. /* C 2) Instrument code. */
  297. /* C 3) Reference frame. */
  298. /* C 4) The angular velocity flag. */
  299. /* C */
  300. /* BEGTIM = SCLK ( 1 ) */
  301. /* ENDTIM = SCLK ( NREC ) */
  302. /* INST = -77001 */
  303. /* REF = 'J2000' */
  304. /* AVFLAG = .TRUE. */
  305. /* SEGID = 'GLL SCAN PLT - DATA TYPE 1' */
  306. /* C */
  307. /* C Write the segment. */
  308. /* C */
  309. /* CALL CKW01 ( HANDLE, BEGTIM, ENDTIM, INST, REF, AVFLAG, */
  310. /* . SEGID, NREC, SCLKDP, QUATS, AVVS ) */
  311. /* $ Restrictions */
  312. /* None. */
  313. /* $ Literature_References */
  314. /* None. */
  315. /* $ Author_and_Institution */
  316. /* W.L. Taber (JPL) */
  317. /* K.R. Gehringer (JPL) */
  318. /* N.J. Bachman (JPL) */
  319. /* J.M. Lynch (JPL) */
  320. /* $ Version */
  321. /* - SPICELIB Version 3.0.0, 01-JUN-2010 (NJB) */
  322. /* The check for non-unit quaternions has been replaced */
  323. /* with a check for zero-length quaternions. */
  324. /* - SPICELIB Version 2.2.0, 26-FEB-2008 (NJB) */
  325. /* Updated header; added information about SPICE */
  326. /* quaternion conventions. */
  327. /* Minor typo in a long error message was corrected. */
  328. /* - SPICELIB Version 2.1.0, 22-FEB-1999 (WLT) */
  329. /* Added check to make sure that all quaternions are unit */
  330. /* length to single precision. */
  331. /* - SPICELIB Version 2.0.0, 28-DEC-1993 (WLT) */
  332. /* The routine was upgraded to support non-inertial reference */
  333. /* frames. */
  334. /* - SPICELIB Version 1.1.1, 05-SEP-1993 (KRG) */
  335. /* Removed all references to a specific method of opening the CK */
  336. /* file in the $ Brief_I/O, $ Detailed_Input, $ Exceptions, */
  337. /* $ Files, and $ Examples sections of the header. It is assumed */
  338. /* that a person using this routine has some knowledge of the DAF */
  339. /* system and the methods for obtaining file handles. */
  340. /* - SPICELIB Version 1.1.0, 25-NOV-1992 (JML) */
  341. /* If the number of pointing records is not positive an error */
  342. /* is now signalled. */
  343. /* FAILED is checked after the call to DAFBNA. */
  344. /* The variable HLDCLK was removed from the loop where the times */
  345. /* were checked. */
  346. /* - SPICELIB Version 1.0.1, 10-MAR-1992 (WLT) */
  347. /* Comment section for permuted index source lines was added */
  348. /* following the header. */
  349. /* - SPICELIB Version 1.0.0, 30-AUG-1991 (JML) (NJB) */
  350. /* -& */
  351. /* $ Index_Entries */
  352. /* write ck type_1 pointing data segment */
  353. /* -& */
  354. /* $ Revisions */
  355. /* - SPICELIB Version 1.1.1, 05-SEP-1993 (KRG) */
  356. /* Removed all references to a specific method of opening the CK */
  357. /* file in the $ Brief_I/O, $ Detailed_Input, $ Exceptions, */
  358. /* $ Files, and $ Examples sections of the header. It is assumed */
  359. /* that a person using this routine has some knowledge of the DAF */
  360. /* system and the methods for obtaining file handles. */
  361. /* - SPICELIB Version 1.1.0, 25-NOV-1992 (JML) */
  362. /* If the number of pointing records is not positive an error */
  363. /* is now signalled. */
  364. /* FAILED is checked after the call to DAFBNA. */
  365. /* The variable HLDCLK was removed from the loop where the times */
  366. /* were checked. */
  367. /* - SPICELIB Version 1.0.1, 10-MAR-1992 (WLT) */
  368. /* Comment section for permuted index source lines was added */
  369. /* following the header. */
  370. /* - SPICELIB Version 1.0.0, 30-AUG-1991 (JML) (NJB) */
  371. /* -& */
  372. /* SPICELIB functions */
  373. /* Local parameters */
  374. /* SIDLEN is the maximum number of characters allowed in a CK */
  375. /* segment identifier. */
  376. /* NDC is the size of a packed CK segment descriptor. */
  377. /* ND is the number of double precision components in a CK */
  378. /* segment descriptor. */
  379. /* NI is the number of integer components in a CK segment */
  380. /* descriptor. */
  381. /* DTYPE is the data type of the segment that this routine */
  382. /* operates on. */
  383. /* FPRINT is the integer value of the first printable ASCII */
  384. /* character. */
  385. /* LPRINT is the integer value of the last printable ASCII */
  386. /* character. */
  387. /* Local variables */
  388. /* Standard SPICE error handling. */
  389. if (return_()) {
  390. return 0;
  391. }
  392. chkin_("CKW01", (ftnlen)5);
  393. /* The first thing that we will do is create the segment descriptor. */
  394. /* The structure of the segment descriptor is as follows. */
  395. /* DCD( 1 ) and DCD( 2 ) -- SCLK limits of the segment. */
  396. /* ICD( 1 ) -- Instrument code. */
  397. /* ICD( 2 ) -- Reference frame ID. */
  398. /* ICD( 3 ) -- Data type of the segment. */
  399. /* ICD( 4 ) -- Angular rates flag. */
  400. /* ICD( 5 ) -- Beginning address of segment. */
  401. /* ICD( 6 ) -- Ending address of segment. */
  402. /* Make sure that there is a positive number of pointing records. */
  403. if (*nrec <= 0) {
  404. setmsg_("# is an invalid number of pointing instances for type 1.", (
  405. ftnlen)56);
  406. errint_("#", nrec, (ftnlen)1);
  407. sigerr_("SPICE(INVALIDNUMREC)", (ftnlen)20);
  408. chkout_("CKW01", (ftnlen)5);
  409. return 0;
  410. }
  411. /* Check that the SCLK bounds on the segment are reasonable. */
  412. if (*begtim > sclkdp[0]) {
  413. setmsg_("The first d.p. component of the descriptor is invalid. DCD("
  414. "1) = # and SCLKDP(1) = # ", (ftnlen)84);
  415. errdp_("#", begtim, (ftnlen)1);
  416. errdp_("#", sclkdp, (ftnlen)1);
  417. sigerr_("SPICE(INVALIDDESCRTIME)", (ftnlen)23);
  418. chkout_("CKW01", (ftnlen)5);
  419. return 0;
  420. }
  421. if (*endtim < sclkdp[*nrec - 1]) {
  422. setmsg_("The second d.p. component of the descriptor is invalid. DCD"
  423. "(2) = # and SCLKDP(NREC) = # ", (ftnlen)88);
  424. errdp_("#", endtim, (ftnlen)1);
  425. errdp_("#", &sclkdp[*nrec - 1], (ftnlen)1);
  426. sigerr_("SPICE(INVALIDDESCRTIME)", (ftnlen)23);
  427. chkout_("CKW01", (ftnlen)5);
  428. return 0;
  429. }
  430. dcd[0] = *begtim;
  431. dcd[1] = *endtim;
  432. /* Get the NAIF integer code for the reference frame. */
  433. namfrm_(ref, &refcod, ref_len);
  434. if (refcod == 0) {
  435. setmsg_("The reference frame # is not supported.", (ftnlen)39);
  436. errch_("#", ref, (ftnlen)1, ref_len);
  437. sigerr_("SPICE(INVALIDREFFRAME)", (ftnlen)22);
  438. chkout_("CKW01", (ftnlen)5);
  439. return 0;
  440. }
  441. /* Assign values to the integer components of the segment descriptor. */
  442. icd[0] = *inst;
  443. icd[1] = refcod;
  444. icd[2] = 1;
  445. if (*avflag) {
  446. icd[3] = 1;
  447. } else {
  448. icd[3] = 0;
  449. }
  450. /* Now pack the segment descriptor. */
  451. dafps_(&c__2, &c__6, dcd, icd, descr);
  452. /* Check that all the characters in the segid can be printed. */
  453. i__1 = lastnb_(segid, segid_len);
  454. for (i__ = 1; i__ <= i__1; ++i__) {
  455. value = *(unsigned char *)&segid[i__ - 1];
  456. if (value < 32 || value > 126) {
  457. setmsg_("The segment identifier contains nonprintable characters",
  458. (ftnlen)55);
  459. sigerr_("SPICE(NONPRINTABLECHARS)", (ftnlen)24);
  460. chkout_("CKW01", (ftnlen)5);
  461. return 0;
  462. }
  463. }
  464. /* Also check to see if the segment identifier is too long. */
  465. if (lastnb_(segid, segid_len) > 40) {
  466. setmsg_("Segment identifier contains more than 40 characters.", (
  467. ftnlen)52);
  468. sigerr_("SPICE(SEGIDTOOLONG)", (ftnlen)19);
  469. chkout_("CKW01", (ftnlen)5);
  470. return 0;
  471. }
  472. /* Now check that the encoded SCLK times are positive and strictly */
  473. /* increasing. */
  474. /* Check that the first time is nonnegative. */
  475. if (sclkdp[0] < 0.) {
  476. setmsg_("The first SCLKDP time: # is negative.", (ftnlen)37);
  477. errdp_("#", sclkdp, (ftnlen)1);
  478. sigerr_("SPICE(INVALIDSCLKTIME)", (ftnlen)22);
  479. chkout_("CKW01", (ftnlen)5);
  480. return 0;
  481. }
  482. /* Now check that the times are ordered properly. */
  483. i__1 = *nrec;
  484. for (i__ = 2; i__ <= i__1; ++i__) {
  485. if (sclkdp[i__ - 1] <= sclkdp[i__ - 2]) {
  486. setmsg_("The SCLKDP times are not strictly increasing. SCLKDP(#)"
  487. " = # and SCLKDP(#) = #.", (ftnlen)78);
  488. errint_("#", &i__, (ftnlen)1);
  489. errdp_("#", &sclkdp[i__ - 1], (ftnlen)1);
  490. i__2 = i__ - 1;
  491. errint_("#", &i__2, (ftnlen)1);
  492. errdp_("#", &sclkdp[i__ - 2], (ftnlen)1);
  493. sigerr_("SPICE(TIMESOUTOFORDER)", (ftnlen)22);
  494. chkout_("CKW01", (ftnlen)5);
  495. return 0;
  496. }
  497. }
  498. /* Make sure that the quaternions are non-zero. This is just */
  499. /* a check for uninitialized data. */
  500. i__1 = *nrec;
  501. for (i__ = 1; i__ <= i__1; ++i__) {
  502. if (vzerog_(&quats[(i__ << 2) - 4], &c__4)) {
  503. setmsg_("The quaternion at index # has magnitude zero.", (ftnlen)
  504. 45);
  505. errint_("#", &i__, (ftnlen)1);
  506. sigerr_("SPICE(ZEROQUATERNION)", (ftnlen)21);
  507. chkout_("CKW01", (ftnlen)5);
  508. return 0;
  509. }
  510. }
  511. /* No more checks, begin writing the segment. */
  512. dafbna_(handle, descr, segid, segid_len);
  513. if (failed_()) {
  514. chkout_("CKW01", (ftnlen)5);
  515. return 0;
  516. }
  517. /* Now add the quaternions and optionally, the angular velocity */
  518. /* vectors. */
  519. if (*avflag) {
  520. i__1 = *nrec;
  521. for (i__ = 1; i__ <= i__1; ++i__) {
  522. dafada_(&quats[(i__ << 2) - 4], &c__4);
  523. dafada_(&avvs[i__ * 3 - 3], &c__3);
  524. }
  525. } else {
  526. i__1 = *nrec;
  527. for (i__ = 1; i__ <= i__1; ++i__) {
  528. dafada_(&quats[(i__ << 2) - 4], &c__4);
  529. }
  530. }
  531. /* Add the SCLK times. */
  532. dafada_(sclkdp, nrec);
  533. /* The time tag directory. The Ith element is defined to be the */
  534. /* average of the (I*100)th and the (I*100+1)st SCLK time. */
  535. ndir = (*nrec - 1) / 100;
  536. index = 100;
  537. i__1 = ndir;
  538. for (i__ = 1; i__ <= i__1; ++i__) {
  539. dirent = (sclkdp[index - 1] + sclkdp[index]) / 2.;
  540. dafada_(&dirent, &c__1);
  541. index += 100;
  542. }
  543. /* Finally, the number of records. */
  544. d__1 = (doublereal) (*nrec);
  545. dafada_(&d__1, &c__1);
  546. /* End the segment. */
  547. dafena_();
  548. chkout_("CKW01", (ftnlen)5);
  549. return 0;
  550. } /* ckw01_ */