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