PageRenderTime 37ms CodeModel.GetById 0ms RepoModel.GetById 0ms app.codeStats 0ms

/src/ckw02.c

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