1 /* 2 3 -Procedure spkcvo_c ( SPK, constant velocity observer state ) 4 5 -Abstract 6 7 Return the state of a specified target relative to an "observer," 8 where the observer has constant velocity in a specified reference 9 frame. The observer's state is provided by the calling program 10 rather than by loaded SPK files. 11 12 -Disclaimer 13 14 THIS SOFTWARE AND ANY RELATED MATERIALS WERE CREATED BY THE 15 CALIFORNIA INSTITUTE OF TECHNOLOGY (CALTECH) UNDER A U.S. 16 GOVERNMENT CONTRACT WITH THE NATIONAL AERONAUTICS AND SPACE 17 ADMINISTRATION (NASA). THE SOFTWARE IS TECHNOLOGY AND SOFTWARE 18 PUBLICLY AVAILABLE UNDER U.S. EXPORT LAWS AND IS PROVIDED "AS-IS" 19 TO THE RECIPIENT WITHOUT WARRANTY OF ANY KIND, INCLUDING ANY 20 WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A 21 PARTICULAR USE OR PURPOSE (AS SET FORTH IN UNITED STATES UCC 22 SECTIONS 2312-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE 23 SOFTWARE AND RELATED MATERIALS, HOWEVER USED. 24 25 IN NO EVENT SHALL CALTECH, ITS JET PROPULSION LABORATORY, OR NASA 26 BE LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING, BUT NOT 27 LIMITED TO, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND, 28 INCLUDING ECONOMIC DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS, 29 REGARDLESS OF WHETHER CALTECH, JPL, OR NASA BE ADVISED, HAVE 30 REASON TO KNOW, OR, IN FACT, SHALL KNOW OF THE POSSIBILITY. 31 32 RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF 33 THE SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY 34 CALTECH AND NASA FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE 35 ACTIONS OF RECIPIENT IN THE USE OF THE SOFTWARE. 36 37 -Required_Reading 38 39 FRAMES 40 PCK 41 SPK 42 TIME 43 44 -Keywords 45 46 EPHEMERIS 47 48 */ 49 50 #include "SpiceUsr.h" 51 #include "SpiceZfc.h" 52 #include "SpiceZst.h" 53 #include "SpiceZmc.h" 54 #undef spkcvo_c 55 56 spkcvo_c(ConstSpiceChar * target,SpiceDouble et,ConstSpiceChar * outref,ConstSpiceChar * refloc,ConstSpiceChar * abcorr,ConstSpiceDouble obssta[6],SpiceDouble obsepc,ConstSpiceChar * obsctr,ConstSpiceChar * obsref,SpiceDouble state[6],SpiceDouble * lt)57 void spkcvo_c ( ConstSpiceChar * target, 58 SpiceDouble et, 59 ConstSpiceChar * outref, 60 ConstSpiceChar * refloc, 61 ConstSpiceChar * abcorr, 62 ConstSpiceDouble obssta [6], 63 SpiceDouble obsepc, 64 ConstSpiceChar * obsctr, 65 ConstSpiceChar * obsref, 66 SpiceDouble state [6], 67 SpiceDouble * lt ) 68 /* 69 70 -Brief_I/O 71 72 Variable I/O Description 73 -------- --- -------------------------------------------------- 74 target I Name of target ephemeris object. 75 et I Observation epoch. 76 outref I Reference frame of output state. 77 refloc I Output reference frame evaluation locus. 78 abcorr I Aberration correction. 79 obssta I Observer state relative to center of motion. 80 obsepc I Epoch of observer state. 81 obsctr I Center of motion of observer. 82 obsref I Frame of observer state. 83 state O State of target with respect to observer. 84 lt O One way light time between target and 85 observer. 86 87 -Detailed_Input 88 89 target is the name of a target body. Optionally, you may supply 90 the ID code of the object as an integer string. For 91 example, both "EARTH" and "399" are legitimate strings 92 to supply to indicate the target is earth. 93 94 Case and leading and trailing blanks are not significant 95 in the string `target'. 96 97 98 et is the ephemeris time at which the state of the target 99 relative to the observer is to be computed. `et' is 100 expressed as seconds past J2000 TDB. `et' refers to time 101 at the observer's location. 102 103 `et' is independent of the observer epoch `obsepc'. 104 105 106 outref is the name of the reference frame with respect to which 107 the output state is expressed. 108 109 When `outref' is time-dependent (non-inertial), its 110 orientation relative to the J2000 frame is evaluated in 111 the manner commanded by the input argument `refloc' (see 112 description below). 113 114 Case and leading and trailing blanks are not significant 115 in the string `outref'. 116 117 118 refloc is a string indicating the output reference frame 119 evaluation locus: this is the location associated 120 with the epoch at which this routine is to evaluate 121 the orientation, relative to the J2000 frame, of the 122 output frame `outref'. The values and meanings of 123 `refloc' are: 124 125 "OBSERVER" Evaluate `outref' at the observer's 126 epoch `et'. 127 128 Normally the locus "OBSERVER" should 129 be selected when `outref' is centered 130 at the observer. 131 132 133 "TARGET" Evaluate `outref' at the target epoch; 134 letting `lt' be the one-way light time 135 between the target and observer, the 136 target epoch is 137 138 et-lt if reception aberration 139 corrections are used 140 141 et+lt if transmission aberration 142 corrections are used 143 144 et if no aberration corrections 145 are used 146 147 Normally the locus "TARGET" should 148 be selected when `outref' is centered 149 at the target object. 150 151 152 "CENTER" Evaluate the frame `outref' at the epoch 153 associated its center. This epoch, 154 which we'll call `etctr', is determined 155 as follows: 156 157 Let `ltctr' be the one-way light time 158 between the observer and the center 159 of `outref'. Then `etctr' is 160 161 et-ltctr if reception 162 aberration corrections 163 are used 164 165 et+ltctr if transmission 166 aberration corrections 167 are used 168 169 et if no aberration 170 corrections are used 171 172 173 The locus "CENTER" should be selected 174 when the user intends to obtain 175 results compatible with those produced 176 by spkezr_c. 177 178 When `outref' is inertial, all choices of `refloc' 179 yield the same results. 180 181 Case and leading and trailing blanks are not 182 significant in the string `refloc'. 183 184 185 abcorr indicates the aberration corrections to be applied to 186 the observer-target state to account for one-way 187 light time and stellar aberration. 188 189 `abcorr' may be any of the following: 190 191 "NONE" Apply no correction. Return the 192 geometric state of the target 193 relative to the observer. 194 195 The following values of `abcorr' apply to the 196 "reception" case in which photons depart from the 197 target's location at the light-time corrected epoch 198 et-lt and *arrive* at the observer's location at `et': 199 200 "LT" Correct for one-way light time (also 201 called "planetary aberration") using a 202 Newtonian formulation. This correction 203 yields the state of the target at the 204 moment it emitted photons arriving at 205 the observer at `et'. 206 207 The light time correction uses an 208 iterative solution of the light time 209 equation. The solution invoked by the 210 "LT" option uses one iteration. 211 212 "LT+S" Correct for one-way light time and 213 stellar aberration using a Newtonian 214 formulation. This option modifies the 215 state obtained with the "LT" option to 216 account for the observer's velocity 217 relative to the solar system 218 barycenter. The result is the apparent 219 state of the target---the position and 220 velocity of the target as seen by the 221 observer. 222 223 "CN" Converged Newtonian light time 224 correction. In solving the light time 225 equation, the "CN" correction iterates 226 until the solution converges. 227 228 "CN+S" Converged Newtonian light time 229 and stellar aberration corrections. 230 231 232 The following values of `abcorr' apply to the 233 "transmission" case in which photons *depart* from 234 the observer's location at `et' and arrive at the 235 target's location at the light-time corrected epoch 236 et+lt: 237 238 "XLT" "Transmission" case: correct for 239 one-way light time using a Newtonian 240 formulation. This correction yields the 241 state of the target at the moment it 242 receives photons emitted from the 243 observer's location at `et'. 244 245 "XLT+S" "Transmission" case: correct for 246 one-way light time and stellar 247 aberration using a Newtonian 248 formulation This option modifies the 249 state obtained with the "XLT" option to 250 account for the observer's velocity 251 relative to the solar system 252 barycenter. The position component of 253 the computed target state indicates the 254 direction that photons emitted from the 255 observer's location must be "aimed" to 256 hit the target. 257 258 "XCN" "Transmission" case: converged 259 Newtonian light time correction. 260 261 "XCN+S" "Transmission" case: converged 262 Newtonian light time and stellar 263 aberration corrections. 264 265 266 Neither special nor general relativistic effects are 267 accounted for in the aberration corrections applied 268 by this routine. 269 270 Case and leading and trailing blanks are not 271 significant in the string `abcorr'. 272 273 274 obssta is the geometric state of an observer moving at 275 constant velocity relative to its center of motion 276 `obsctr', expressed in the reference frame `obsref', at 277 the epoch `obsepc'. 278 279 `obssta' is a six-dimensional vector representing 280 position and velocity in cartesian coordinates: the 281 first three components represent the position of an 282 observer relative to its center of motion; the last 283 three components represent the velocity of the 284 observer. 285 286 Units are always km and km/sec. 287 288 289 obsepc is the epoch, expressed as seconds past J2000 TDB, at 290 which the observer state `obssta' is applicable. For 291 other epochs, the position of the observer relative 292 to its center of motion is linearly extrapolated 293 using the velocity component of `obssta'. 294 295 `obsepc' is independent of the epoch `et' at which the 296 state of the target relative to the observer is to be 297 computed. 298 299 obsctr is the name of the center of motion of `obssta'. The 300 ephemeris of `obsctr' is provided by loaded SPK files. 301 302 Optionally, you may supply the integer ID code for 303 the object as an integer string. For example both 304 "MOON" and "301" are legitimate strings that indicate 305 the moon is the center of motion. 306 307 Case and leading and trailing blanks are not 308 significant in the string `obsctr'. 309 310 311 obsref is the name of the reference frame relative to which 312 the input state `obssta' is expressed. The observer has 313 constant velocity relative to its center of motion 314 in this reference frame. 315 316 Case and leading and trailing blanks are not 317 significant in the string `obsref'. 318 319 320 -Detailed_Output 321 322 323 state is a Cartesian state vector representing the position 324 and velocity of the target relative to the specified 325 observer. `state' is corrected for the specified 326 aberrations and is expressed with respect to the 327 reference frame specified by `outref'. The first three 328 components of `state' represent the x-, y- and 329 z-components of the target's position; the last three 330 components form the corresponding velocity vector. 331 332 The position component of `state' points from the 333 observer's location at `et' to the aberration-corrected 334 location of the target. Note that the sense of the 335 position vector is independent of the direction of 336 radiation travel implied by the aberration 337 correction. 338 339 The velocity component of `state' is the derivative 340 with respect to time of the position component of 341 `state'. 342 343 Units are always km and km/sec. 344 345 When `state' is expressed in a time-dependent 346 (non-inertial) output frame, the orientation of that 347 frame relative to the J2000 frame is evaluated in the 348 manner indicated by the input argument `refloc' (see 349 description above). 350 351 352 lt is the one-way light time between the observer and 353 target in seconds. If the target state is corrected 354 for aberrations, then `lt' is the one-way light time 355 between the observer and the light time corrected 356 target location. 357 358 359 -Parameters 360 361 None. 362 363 -Exceptions 364 365 1) If either the name of the center of motion or the target 366 cannot be translated to its NAIF ID code, the error 367 SPICE(IDCODENOTFOUND) is signaled. 368 369 2) If the reference frame `outref' is unrecognized, the error 370 SPICE(IDCODENOTFOUND) is signaled. 371 372 3) If the reference frame `obsref' is unrecognized, the error will 373 be diagnosed by a routine in the call tree of this routine. 374 375 4) If the frame evaluation locus `refloc' is not recognized, 376 the error SPICE(NOTSUPPORTED) is signaled. 377 378 5) If the loaded kernels provide insufficient data to compute 379 the requested state vector, the deficiency will be diagnosed 380 by a routine in the call tree of this routine. 381 382 6) If an error occurs while reading an SPK or other kernel file, 383 the error will be diagnosed by a routine in the call tree of 384 this routine. 385 386 7) If the aberration correction `abcorr' is not recognized, 387 the error will be diagnosed by a routine in the call tree of 388 this routine. 389 390 8) If any input string pointer is null, or if the output state 391 pointer is null, the error SPICE(NULLPOINTER) will be signaled. 392 393 9) If any input string has length zero, the error SPICE(EMPTYSTRING) 394 will be signaled. 395 396 -Files 397 398 Appropriate kernels must be loaded by the calling program before 399 this routine is called. 400 401 The following data are required: 402 403 - SPK data: ephemeris data for the observer center and target 404 must be loaded. If aberration corrections are used, the 405 states of the observer center and target relative to the solar 406 system barycenter must be calculable from the available 407 ephemeris data. Typically ephemeris data are made available 408 by loading one or more SPK files using furnsh_c. 409 410 The following data may be required: 411 412 - PCK data: if the target frame is a PCK frame, rotation data 413 for the target frame must be loaded. These may be provided 414 in a text or binary PCK file. 415 416 - Frame data: if a frame definition not built into SPICE is 417 required, for example to convert the observer-target state 418 to the output frame, that definition must be available in 419 the kernel pool. Typically frame definitions are supplied 420 by loading a frame kernel using furnsh_c. 421 422 - Additional kernels: if any frame used in this routine's 423 state computation is a CK frame, then at least one CK and 424 corresponding SCLK kernel is required. If dynamic frames 425 are used, additional SPK, PCK, CK, or SCLK kernels may be 426 required. 427 428 In all cases, kernel data are normally loaded once per program 429 run, NOT every time this routine is called. 430 431 -Particulars 432 433 This routine computes observer-target states for observers whose 434 trajectories are not provided by SPK files. 435 436 Observers supported by this routine must have constant velocity 437 with respect to a specified center of motion, expressed in a 438 caller-specified reference frame. The state of the center of 439 motion relative to the target must be computable using 440 loaded SPK data. 441 442 For applications in which the observer has zero velocity 443 relative to its center of motion, the CSPICE routine 444 445 spkcpo_c { SPK, constant position observer } 446 447 can be used. spkcpo_c has a simpler interface than that of spkcvo_c. 448 449 This routine is suitable for computing states of target ephemeris 450 objects, as seen from landmarks on the surface of an extended 451 object, in cases where no SPK data are available for those 452 landmarks. 453 454 This routine's treatment of the output reference frame differs 455 from that of the principal SPK API routines 456 457 spkezr_c 458 spkez_c 459 spkpos_c 460 spkezp_c 461 462 which require both observer and target ephemerides to be provided 463 by loaded SPK files: 464 465 The SPK API routines listed above evaluate the orientation of the 466 output reference frame (with respect to the J2000 frame) at an 467 epoch corrected for one-way light time between the observer and 468 the center of the output frame. When the center of the output 469 frame is not the target (for example, when the target is on the 470 surface of Mars and the output frame is centered at Mars' 471 center), the epoch of evaluation may not closely match the 472 light-time corrected epoch associated with the target itself. A 473 similar problem may occur when the observer is a surface point on 474 an extended body and the output frame is centered at the body 475 center: the listed routines will correct the orientation of the 476 output frame for one-way light time between the frame center and 477 the observer. 478 479 This routine allows the caller to dictate how the orientation 480 of the output reference frame is to be evaluated. The caller 481 passes to this routine an input string called the output 482 frame's evaluation "locus." This string specifies the location 483 associated with the output frame's evaluation epoch. The three 484 possible values of the locus are 485 486 "TARGET" 487 "OBSERVER" 488 "CENTER" 489 490 The choice of locus has an effect when aberration corrections 491 are used and the output frame is non-inertial. 492 493 When the locus is "TARGET" and light time corrections are 494 used, the orientation of the output frame is evaluated at the 495 epoch obtained by correcting the observation epoch `et' for 496 one-way light time `lt'. The evaluation epoch will be either 497 et-lt or et+lt for reception or transmission corrections 498 respectively. 499 500 For remote sensing applications where the target is a surface 501 point on an extended object, and the orientation of that 502 object should be evaluated at the emission time, the locus 503 "TARGET" should be used. 504 505 When the output frame's orientation should be evaluated at 506 the observation epoch `et', which is the case when the 507 output frame is centered at the observer, the locus 508 "OBSERVER" should be used. 509 510 The locus option "CENTER" is provided for compatibility 511 with existing SPK state computation APIs such as spkezr_c. 512 513 Note that the output frame evaluation locus does not affect 514 the computation of light time between the target and 515 observer. 516 517 518 The SPK routines that compute observer-target states for 519 combinations of objects having ephemerides provided by the SPK 520 system and objects having constant position or constant velocity 521 are 522 523 spkcpo_c {SPK, Constant position observer} 524 spkcpt_c {SPK, Constant position target} 525 spkcvo_c {SPK, Constant velocity observer} 526 spkcvt_c {SPK, Constant velocity target} 527 528 -Examples 529 530 The numerical results shown for these examples may differ across 531 platforms. The results depend on the SPICE kernels used as 532 input, the compiler and supporting libraries, and the machine 533 specific arithmetic implementation. 534 535 536 1) Compute apparent solar azimuth and elevation as seen from a 537 specified surface point on the earth. 538 539 Task Description 540 ================ 541 542 In this example we'll use the location of the DSN station 543 DSS-14 as our surface point. 544 545 We'll perform the solar azimuth and elevation computation two 546 ways: 547 548 - Using a station frame kernel to provide the 549 specification of a topocentric reference frame 550 centered at DSS-14. 551 552 - Computing inline the transformation from the earth-fixed, 553 earth-centered frame ITRF93 to a topocentric frame 554 centered at DSS-14. 555 556 Note that results of the two computations will differ 557 slightly. This is due to differences in the orientations 558 of the topocentric frames. There are two sources of the 559 differences: 560 561 1) The station position is time-dependent due to tectonic 562 plate motion, and epochs of the station positions used 563 to specify the axes of the topocentric frame are 564 different in the two cases. This gives rise to different 565 orientations of the frame's axes relative to the frame 566 ITRF93. 567 568 2) The two computations use different earth radii; this 569 results in computation of different geodetic latitudes 570 of the station. This difference also affects the 571 topocentric frame orientation relative to ITRF93. 572 573 574 Kernels 575 ======= 576 577 Use the meta-kernel shown below to load the required SPICE 578 kernels. 579 580 581 KPL/MK 582 583 File name: spkcvo.tm 584 585 This is the meta-kernel file for the header code example for 586 the subroutine spkcvo_c. These kernel files can be found on 587 the NAIF website. 588 589 In order for an application to use this meta-kernel, the 590 kernels referenced here must be present in the user's 591 current working directory. 592 593 The names and contents of the kernels referenced 594 by this meta-kernel are as follows: 595 596 File name Contents 597 --------- -------- 598 de421.bsp Planetary ephemeris 599 pck00010.tpc Planet orientation and 600 radii 601 naif0010.tls Leapseconds 602 earth_720101_070426.bpc Earth historical 603 binary PCK 604 earthstns_itrf93_050714.bsp DSN station SPK 605 earth_topo_050714.tf DSN station FK 606 mgs_moc_v20.ti MGS MOC instrument 607 parameters 608 mgs_sclkscet_00061.tsc MGS SCLK coefficients 609 mgs_sc_ext12.bc MGS s/c bus attitude 610 mgs_ext12_ipng_mgs95j.bsp MGS ephemeris 611 612 \begindata 613 614 KERNELS_TO_LOAD = ( 'de421.bsp', 615 'pck00010.tpc', 616 'naif0010.tls', 617 'earth_720101_070426.bpc', 618 'earthstns_itrf93_050714.bsp', 619 'earth_topo_050714.tf', 620 'mgs_moc_v20.ti', 621 'mgs_sclkscet_00061.tsc', 622 'mgs_sc_ext12.bc', 623 'mgs_ext12_ipng_mgs95j.bsp' ) 624 625 \begintext 626 627 End of meta-kernel. 628 629 630 Example code begins here. 631 632 /. 633 Program spkcvo_ex1 634 635 This program uses spkcvo_c to compute solar azimuth 636 and elevation at a given surface point on the earth. 637 638 ./ 639 640 #include <stdio.h> 641 #include <string.h> 642 #include <stdlib.h> 643 #include "SpiceUsr.h" 644 645 int main() 646 { 647 /. 648 Local constants 649 ./ 650 #define META "spkcvo.tm" 651 #define FRNMLN 33 652 #define SHAPLN 33 653 #define TIMFMT "YYYY MON DD HR:MN:SC.###### UTC" 654 #define TIMFM2 "YYYY MON DD HR:MN:SC.###### TDB ::TDB" 655 #define TIMLEN 41 656 657 /. 658 Local variables 659 ./ 660 SpiceChar * abcorr; 661 SpiceChar emitim [ TIMLEN ]; 662 SpiceChar epcstr [ TIMLEN ]; 663 SpiceChar * refloc; 664 SpiceChar * obsctr; 665 SpiceChar * obsref; 666 SpiceChar * obstim; 667 SpiceChar * outref; 668 SpiceChar * target; 669 670 SpiceDouble az; 671 SpiceDouble el; 672 SpiceDouble et; 673 SpiceDouble f; 674 SpiceDouble lat; 675 SpiceDouble lon; 676 SpiceDouble lt0; 677 SpiceDouble lt1; 678 SpiceDouble normal [ 3 ] ; 679 SpiceDouble obsalt; 680 SpiceDouble obslat; 681 SpiceDouble obslon; 682 SpiceDouble obsepc; 683 SpiceDouble obssta [ 6 ]; 684 SpiceDouble r; 685 SpiceDouble radii [ 3 ]; 686 SpiceDouble re; 687 SpiceDouble rp; 688 SpiceDouble state0 [ 6 ]; 689 SpiceDouble state1 [ 6 ]; 690 SpiceDouble topvec [ 3 ]; 691 SpiceDouble xform [ 3 ][ 3 ]; 692 693 SpiceDouble z [ 3 ] = { 0.0, 0.0, 1.0 }; 694 695 SpiceInt n; 696 697 698 /. 699 Load SPICE kernels. 700 ./ 701 furnsh_c ( META ); 702 703 /. 704 Convert the observation time to seconds past J2000 TDB. 705 ./ 706 obstim = "2003 OCT 13 06:00:00.000000 UTC"; 707 708 str2et_c ( obstim, &et ); 709 710 /. 711 Set the target, observer center, and observer frame. 712 ./ 713 target = "SUN"; 714 obsctr = "EARTH"; 715 obsref = "ITRF93"; 716 717 /. 718 Set the state of DSS-14 relative to the earth's 719 center at the J2000 epoch, expressed in the 720 ITRF93 reference frame. Values come from the 721 earth station SPK specified in the meta-kernel. 722 723 The velocity is non-zero due to tectonic 724 plate motion. 725 ./ 726 obsepc = 0.0; 727 728 obssta[0] = -2353.6213656676991; 729 obssta[1] = -4641.3414911499403; 730 obssta[2] = 3677.0523293197439; 731 obssta[3] = -0.00000000000057086; 732 obssta[4] = 0.00000000000020549; 733 obssta[5] = -0.00000000000012171; 734 735 /. 736 Find the apparent state of the sun relative 737 to the station in the DSS-14_TOPO reference frame. 738 Evaluate the output frame's orientation, that is the 739 orientation of the DSS-14_TOPO frame relative to the 740 J2000 frame, at the observation epoch. This 741 correction is obtained by setting `refloc' to 742 "OBSERVER". 743 ./ 744 745 outref = "DSS-14_TOPO"; 746 abcorr = "CN+S"; 747 748 refloc = "OBSERVER"; 749 750 /. 751 Compute the observer-target state. 752 ./ 753 spkcvo_c ( target, et, outref, refloc, 754 abcorr, obssta, obsepc, obsctr, 755 obsref, state0, <0 ); 756 757 /. 758 Compute planetocentric coordinates of the 759 observer-target position in the local 760 topocentric reference frame DSS-14_TOPO. 761 ./ 762 reclat_c ( state0, &r, &lon, &lat ); 763 764 /. 765 Compute solar azimuth. The latitude we've 766 already computed is the elevation. Express 767 both angles in degrees. 768 ./ 769 el = lat * dpr_c(); 770 az = - lon * dpr_c(); 771 772 if ( az < 0.0 ) 773 { 774 az += 360.0; 775 } 776 777 /. 778 Display the computed state, light time. and angles. 779 ./ 780 timout_c ( et-lt0, TIMFMT, TIMLEN, emitim ); 781 timout_c ( obsepc, TIMFM2, TIMLEN, epcstr ); 782 783 printf ( "\n" 784 " Frame evaluation locus: %s\n" 785 "\n" 786 " Target: %s\n" 787 " Observation time: %s\n" 788 " Observer center: %s\n" 789 " Observer-center state time: %s\n" 790 " Observer frame: %s\n" 791 " Emission time: %s\n" 792 " Output reference frame: %s\n" 793 " Aberration correction: %s\n" 794 "\n" 795 " Observer-target position (km):\n" 796 " %20.8f %20.8f %20.8f\n" 797 " Observer-target velocity (km/s):\n" 798 " %20.8f %20.8f %20.8f\n" 799 " Light time (s): %20.8f\n", 800 801 refloc, target, obstim, obsctr, 802 epcstr, obsref, emitim, outref, 803 abcorr, state0[0], state0[1], state0[2], 804 state0[3], state0[4], state0[5], lt0 ); 805 806 printf ( "\n" 807 " Solar azimuth (deg): %20.8f\n" 808 " Solar elevation (deg): %20.8f\n", 809 az, el ); 810 811 812 /. 813 For an arbitrary surface point, we might not 814 have a frame kernel available. In this case 815 we can look up the state in the observer frame 816 using spkcvo_c and then convert the state to 817 the local topocentric frame. We'll first 818 create the transformation matrix for converting 819 vectors in the observer frame to the topocentric 820 frame. 821 822 First step: find the geodetic (planetodetic) 823 coordinates of the observer. We need the 824 equatorial radius and flattening coefficient 825 of the reference ellipsoid. 826 ./ 827 bodvrd_c ( "EARTH", "RADII", 3, &n, radii ); 828 829 re = radii[0]; 830 rp = radii[2]; 831 832 f = ( re - rp ) / re; 833 834 recgeo_c ( obssta, re, f, &obslon, &obslat, &obsalt ); 835 836 /. 837 Find the outward surface normal on the reference 838 ellipsoid at the observer's longitude and latitude. 839 ./ 840 latrec_c ( 1.0, obslon, obslat, normal ); 841 842 /. 843 The topocentric frame has its +Z axis aligned 844 with NORMAL and its +X axis pointed north. 845 The north direction is aligned with the component 846 of the ITRF93 +Z axis orthogonal to the topocentric 847 +Z axis. 848 ./ 849 twovec_c ( normal, 3, z, 1, xform ); 850 851 outref = "ITRF93"; 852 abcorr = "CN+S"; 853 854 refloc = "OBSERVER"; 855 856 /. 857 Compute the observer-target state. 858 ./ 859 spkcvo_c ( target, et, outref, refloc, 860 abcorr, obssta, obsepc, obsctr, 861 obsref, state1, <1 ); 862 /. 863 Convert the position to the topocentric frame. 864 ./ 865 mxv_c ( xform, state1, topvec ); 866 867 /. 868 Compute azimuth and elevation. 869 ./ 870 reclat_c ( topvec, &r, &lon, &lat ); 871 872 el = lat * dpr_c(); 873 az = - lon * dpr_c(); 874 875 if ( az < 0.0 ) 876 { 877 az += 360.0; 878 } 879 880 printf ( "\n\n\n" 881 " AZ/EL computed without frame kernel:\n\n" 882 " Distance between last two " 883 "positions (km): %20.8f\n", 884 vdist_c( state0, topvec ) ); 885 886 printf ( "\n" 887 " Solar azimuth (deg): %20.8f\n" 888 " Solar elevation (deg): %20.8f\n" 889 "\n", 890 az, el ); 891 892 return ( 0 ); 893 } 894 895 896 When this program was executed on a PC/Linux/gcc 897 platform, the output was: 898 899 900 Frame evaluation locus: OBSERVER 901 902 Target: SUN 903 Observation time: 2003 OCT 13 06:00:00.000000 UTC 904 Observer center: EARTH 905 Observer-center state time: 2000 JAN 01 12:00:00.000000 TDB 906 Observer frame: ITRF93 907 Emission time: 2003 OCT 13 05:51:42.068322 UTC 908 Output reference frame: DSS-14_TOPO 909 Aberration correction: CN+S 910 911 Observer-target position (km): 912 62512272.82076501 58967494.42506485 -122059095.46751761 913 Observer-target velocity (km/s): 914 2475.97326517 -9870.26706232 -3499.90809969 915 Light time (s): 497.93167797 916 917 Solar azimuth (deg): 316.67141599 918 Solar elevation (deg): -54.85253168 919 920 921 922 AZ/EL computed without frame kernel: 923 924 Distance between last two positions (km): 3.07056970 925 926 Solar azimuth (deg): 316.67141786 927 Solar elevation (deg): -54.85253216 928 929 930 931 932 2) Demonstrate applications of the output frame evaluation locus. 933 934 The following program is not necessarily realistic: for 935 brevity, it combines several unrelated computations. 936 937 Task Description 938 ================ 939 940 Find the state of the Mars Global Surveyor spacecraft, as seen 941 from a given surface point on earth, corrected for light time 942 and stellar aberration, expressed in the earth fixed reference 943 frame ITRF93. The surface point is the position of the DSN 944 station DSS-14. 945 946 Contrast the states computed by setting the output frame 947 evaluation locus to "OBSERVER" and to "CENTER". Show that the 948 latter choice produces results very close to those that 949 can be obtained using spkezr_c. 950 951 Also compute the central meridian longitude on Mars of DSS-14. 952 This computation performs aberration corrections for the center 953 of Mars. 954 955 Note that in general, the routine subpnt_c should be used for 956 sub-observer point computations when high-accuracy aberration 957 corrections are desired. 958 959 The observation epoch is 2003 OCT 13 06:00:00 UTC. 960 961 962 Kernels 963 ======= 964 965 Use the meta-kernel of example 1 above. 966 967 968 Example code begins here. 969 970 971 /. 972 Program spkcvo_ex2 973 974 975 This program demonstrates the use of spkcvo_c. 976 Computations are performed using all three possible 977 values of the output frame evaluation locus `refloc': 978 979 "OBSERVER" 980 "CENTER" 981 "TARGET" 982 983 Several unrelated computations are performed in this 984 program. In particular, computation of the 985 central meridian longitude on Mars is included simply 986 to demonstrate use of the "TARGET" option. 987 ./ 988 989 #include <stdio.h> 990 #include <string.h> 991 #include <stdlib.h> 992 #include "SpiceUsr.h" 993 994 int main() 995 { 996 /. 997 Local constants 998 ./ 999 1000 #define META "spkcvo.tm" 1001 #define FRNMLN 33 1002 #define SHAPLN 33 1003 #define TIMFMT "YYYY MON DD HR:MN:SC.###### UTC" 1004 #define TIMFM2 "YYYY MON DD HR:MN:SC.###### TDB ::TDB" 1005 #define TIMLEN 41 1006 1007 /. 1008 Local variables 1009 ./ 1010 SpiceChar * abcorr; 1011 SpiceChar emitim [ TIMLEN ]; 1012 SpiceChar epcstr [ TIMLEN ]; 1013 SpiceChar * refloc; 1014 SpiceChar * obsctr; 1015 SpiceChar * obsref; 1016 SpiceChar * obsrvr; 1017 SpiceChar * obstim; 1018 SpiceChar * outref; 1019 SpiceChar * target; 1020 1021 SpiceDouble et; 1022 SpiceDouble lat; 1023 SpiceDouble lon; 1024 SpiceDouble lt0; 1025 SpiceDouble lt1; 1026 SpiceDouble lt2; 1027 SpiceDouble lt3; 1028 SpiceDouble obsepc; 1029 SpiceDouble obssta [ 6 ]; 1030 SpiceDouble obsvec [ 3 ]; 1031 SpiceDouble r; 1032 SpiceDouble state0 [ 6 ]; 1033 SpiceDouble state1 [ 6 ]; 1034 SpiceDouble state2 [ 6 ]; 1035 SpiceDouble state3 [ 6 ]; 1036 1037 1038 /. 1039 Load SPICE kernels. 1040 ./ 1041 furnsh_c ( META ); 1042 1043 /. 1044 Convert the observation time to seconds past J2000 TDB. 1045 ./ 1046 obstim = "2003 OCT 13 06:00:00.000000 UTC"; 1047 1048 str2et_c ( obstim, &et ); 1049 1050 /. 1051 Set the target, observer center, and observer frame. 1052 ./ 1053 target = "MGS"; 1054 obsctr = "EARTH"; 1055 obsref = "ITRF93"; 1056 1057 /. 1058 Set the state of DSS-14 relative to the earth's 1059 center at the J2000 epoch, expressed in the 1060 ITRF93 reference frame. Values come from the 1061 earth station SPK specified in the meta-kernel. 1062 1063 The velocity is non-zero due to tectonic 1064 plate motion. 1065 ./ 1066 obsepc = 0.0; 1067 1068 obssta[0] = -2353.6213656676991; 1069 obssta[1] = -4641.3414911499403; 1070 obssta[2] = 3677.0523293197439; 1071 obssta[3] = -0.00000000000057086; 1072 obssta[4] = 0.00000000000020549; 1073 obssta[5] = -0.00000000000012171; 1074 1075 /. 1076 Find the apparent state of the spacecraft relative 1077 to the station in the ITRF93 reference frame. 1078 Evaluate the earth's orientation, that is the 1079 orientation of the ITRF93 frame relative to the 1080 J2000 frame, at the observation epoch. This 1081 correction is obtained by setting `refloc' to 1082 "OBSERVER". 1083 ./ 1084 1085 outref = "ITRF93"; 1086 abcorr = "CN+S"; 1087 1088 refloc = "OBSERVER"; 1089 1090 /. 1091 Compute the observer-target state. 1092 ./ 1093 spkcvo_c ( target, et, outref, refloc, 1094 abcorr, obssta, obsepc, obsctr, 1095 obsref, state0, <0 ); 1096 1097 /. 1098 Display the computed state and light time. 1099 ./ 1100 timout_c ( et-lt0, TIMFMT, TIMLEN, emitim ); 1101 timout_c ( obsepc, TIMFM2, TIMLEN, epcstr ); 1102 1103 printf ( "\n" 1104 " Frame evaluation locus: %s\n" 1105 "\n" 1106 " Target: %s\n" 1107 " Observation time: %s\n" 1108 " Observer center: %s\n" 1109 " Observer-center state time: %s\n" 1110 " Observer frame: %s\n" 1111 " Emission time: %s\n" 1112 " Output reference frame: %s\n" 1113 " Aberration correction: %s\n" 1114 "\n" 1115 " Observer-target position (km):\n" 1116 " %20.8f %20.8f %20.8f\n" 1117 " Observer-target velocity (km/s):\n" 1118 " %20.8f %20.8f %20.8f\n" 1119 " Light time (s): %20.8f\n", 1120 1121 refloc, target, obstim, obsctr, 1122 epcstr, obsref, emitim, outref, 1123 abcorr, state0[0], state0[1], state0[2], 1124 state0[3], state0[4], state0[5], lt0 ); 1125 1126 /. 1127 Repeat the computation, this time evaluating the 1128 earth's orientation at the epoch obtained by 1129 subtracting from the observation time the one way 1130 light time from the earth's center. 1131 1132 This is equivalent to looking up the observer-target 1133 state using spkezr_c. 1134 ./ 1135 refloc = "CENTER"; 1136 1137 spkcvo_c ( target, et, outref, refloc, 1138 abcorr, obssta, obsepc, obsctr, 1139 obsref, state1, <1 ); 1140 1141 /. 1142 Display the computed state and light time. 1143 ./ 1144 timout_c ( et-lt1, TIMFMT, TIMLEN, emitim ); 1145 1146 printf ( "\n\n" 1147 " Frame evaluation locus: %s\n" 1148 "\n" 1149 " Target: %s\n" 1150 " Observation time: %s\n" 1151 " Observer center: %s\n" 1152 " Observer-center state time: %s\n" 1153 " Observer frame: %s\n" 1154 " Emission time: %s\n" 1155 " Output reference frame: %s\n" 1156 " Aberration correction: %s\n" 1157 "\n" 1158 " Observer-target position (km):\n" 1159 " %20.8f %20.8f %20.8f\n" 1160 " Observer-target velocity (km/s):\n" 1161 " %20.8f %20.8f %20.8f\n" 1162 " Light time (s): %20.8f\n", 1163 1164 refloc, target, obstim, obsctr, 1165 epcstr, obsref, emitim, outref, 1166 abcorr, state1[0], state1[1], state1[2], 1167 state1[3], state1[4], state1[5], lt1 ); 1168 1169 printf ( "\n" 1170 " Distance between above positions (km): " 1171 " %20.8f\n" 1172 " Velocity difference magnitude (km/s):" 1173 " %20.8f\n", 1174 vdist_c( state0, state1 ), 1175 vdist_c( state0+3, state1+3 ) ); 1176 1177 /. 1178 Check: compare the state computed directly above 1179 to one produced by spkezr_c: 1180 ./ 1181 obsrvr = "DSS-14"; 1182 1183 spkezr_c ( target, et, outref, abcorr, 1184 obsrvr, state2, <2 ); 1185 1186 printf ( "\n\n" 1187 " State computed using spkezr_c:\n" 1188 "\n" 1189 " Target: %s\n" 1190 " Observation time: %s\n" 1191 " Output reference frame: %s\n" 1192 " Aberration correction: %s\n" 1193 " Observer: %s\n" 1194 "\n" 1195 " Observer-target position (km):\n" 1196 " %20.8f %20.8f %20.8f\n" 1197 " Observer-target velocity (km/s):\n" 1198 " %20.8f %20.8f %20.8f\n" 1199 " Light time (s): %20.8f\n", 1200 1201 target, obstim, outref, 1202 abcorr, obsrvr, 1203 state2[0], state2[1], state2[2], 1204 state2[3], state2[4], state2[5], lt2 ); 1205 1206 printf ( "\n" 1207 " Distance between last two " 1208 "positions (km): %20.8f\n" 1209 " Velocity difference magnitude " 1210 " (km/s): %20.8f\n", 1211 vdist_c( state1, state2 ), 1212 vdist_c( state1+3, state2+3 ) ); 1213 1214 /. 1215 Finally, compute an observer-target state in 1216 a frame centered at the target. 1217 This state can be used to compute the sub-observer 1218 longitude. The reference frame is the Mars-fixed 1219 frame IAU_MARS. 1220 ./ 1221 1222 target = "MARS"; 1223 outref = "IAU_MARS"; 1224 1225 refloc = "TARGET"; 1226 1227 spkcvo_c ( target, et, outref, refloc, 1228 abcorr, obssta, obsepc, obsctr, 1229 obsref, state3, <3 ); 1230 1231 /. 1232 Central meridian longitude is the longitude of the 1233 observer relative to the target center, so we must 1234 negate the position portion of the state we just 1235 computed. 1236 ./ 1237 vminus_c ( state3, obsvec ); 1238 1239 reclat_c ( obsvec, &r, &lon, &lat ); 1240 1241 printf ( "\n\n" 1242 " Frame evaluation locus: %s\n" 1243 "\n" 1244 " Target: %s\n" 1245 " Observation time: %s\n" 1246 " Observer center: %s\n" 1247 " Observer-center state time: %s\n" 1248 " Observer frame: %s\n" 1249 " Emission time: %s\n" 1250 " Output reference frame: %s\n" 1251 " Aberration correction: %s\n" 1252 "\n" 1253 " Observer-target position (km):\n" 1254 " %20.8f %20.8f %20.8f\n" 1255 " Observer-target velocity (km/s):\n" 1256 " %20.8f %20.8f %20.8f\n" 1257 " Light time (s): %20.8f\n", 1258 1259 refloc, target, obstim, obsctr, 1260 epcstr, obsref, emitim, outref, 1261 abcorr, state3[0], state3[1], state3[2], 1262 state3[3], state3[4], state3[5], lt3 ); 1263 1264 printf ( "\n" 1265 " Central meridian\n" 1266 " longitude (deg): %20.8f\n\n\n", 1267 lon * dpr_c() ); 1268 1269 1270 return ( 0 ); 1271 } 1272 1273 1274 When this program was executed on a PC/Linux/gcc 1275 platform, the output was: 1276 1277 1278 Frame evaluation locus: OBSERVER 1279 1280 Target: MGS 1281 Observation time: 2003 OCT 13 06:00:00.000000 UTC 1282 Observer center: EARTH 1283 Observer-center state time: 2000 JAN 01 12:00:00.000000 TDB 1284 Observer frame: ITRF93 1285 Emission time: 2003 OCT 13 05:55:44.201144 UTC 1286 Output reference frame: ITRF93 1287 Aberration correction: CN+S 1288 1289 Observer-target position (km): 1290 -53720675.37940782 -51381249.05338467 -18838416.34716543 1291 Observer-target velocity (km/s): 1292 -3751.69274754 3911.73417167 -2.17503628 1293 Light time (s): 255.79885530 1294 1295 1296 Frame evaluation locus: CENTER 1297 1298 Target: MGS 1299 Observation time: 2003 OCT 13 06:00:00.000000 UTC 1300 Observer center: EARTH 1301 Observer-center state time: 2000 JAN 01 12:00:00.000000 TDB 1302 Observer frame: ITRF93 1303 Emission time: 2003 OCT 13 05:55:44.201144 UTC 1304 Output reference frame: ITRF93 1305 Aberration correction: CN+S 1306 1307 Observer-target position (km): 1308 -53720595.74378239 -51381332.31467460 -18838416.34737090 1309 Observer-target velocity (km/s): 1310 -3751.69880992 3911.72835653 -2.17503628 1311 Light time (s): 255.79885530 1312 1313 Distance between above positions (km): 115.21404098 1314 Velocity difference magnitude (km/s): 0.00840050 1315 1316 1317 State computed using spkezr_c: 1318 1319 Target: MGS 1320 Observation time: 2003 OCT 13 06:00:00.000000 UTC 1321 Output reference frame: ITRF93 1322 Aberration correction: CN+S 1323 Observer: DSS-14 1324 1325 Observer-target position (km): 1326 -53720595.74378239 -51381332.31467460 -18838416.34737090 1327 Observer-target velocity (km/s): 1328 -3751.69880992 3911.72835653 -2.17503628 1329 Light time (s): 255.79885530 1330 1331 Distance between last two positions (km): 0.00000000 1332 Velocity difference magnitude (km/s): 0.00000000 1333 1334 1335 Frame evaluation locus: TARGET 1336 1337 Target: MARS 1338 Observation time: 2003 OCT 13 06:00:00.000000 UTC 1339 Observer center: EARTH 1340 Observer-center state time: 2000 JAN 01 12:00:00.000000 TDB 1341 Observer frame: ITRF93 1342 Emission time: 2003 OCT 13 05:55:44.201144 UTC 1343 Output reference frame: IAU_MARS 1344 Aberration correction: CN+S 1345 1346 Observer-target position (km): 1347 -71445232.12767348 2312773.74169024 27766441.52046534 1348 Observer-target velocity (km/s): 1349 155.65895286 5061.78618477 5.09447029 1350 Light time (s): 255.79702283 1351 1352 Central meridian 1353 longitude (deg): -1.85409037 1354 1355 1356 1357 -Restrictions 1358 1359 1) This routine may not be suitable for work with stars or other 1360 objects having large distances from the observer, due to loss 1361 of precision in position vectors. 1362 1363 -Literature_References 1364 1365 None. 1366 1367 -Author_and_Institution 1368 1369 N.J. Bachman (JPL) 1370 S.C. Krening (JPL) 1371 B.V. Semenov (JPL) 1372 1373 -Version 1374 1375 -CSPICE Version 1.0.1, 09-SEP-2015 (NJB) 1376 1377 The Exceptions section of the header was updated 1378 to mention exceptions involving null pointers and 1379 empty input strings. 1380 1381 -CSPICE Version 1.0.0, 27-MAR-2012 (NJB) (SCK) (BVS) 1382 1383 -Index_Entries 1384 1385 state relative to constant_velocity_observer 1386 state relative to constant_velocity surface_point 1387 state relative to surface_point on extended_object 1388 state relative to landmark on extended_object 1389 1390 -& 1391 */ 1392 1393 { /* Begin spkcvo_c */ 1394 1395 1396 1397 /* 1398 Participate in error tracing. 1399 */ 1400 chkin_c ( "spkcvo_c" ); 1401 1402 /* 1403 Check the input state pointer. 1404 */ 1405 CHKPTR ( CHK_STANDARD, "spkcvo_c", obssta ); 1406 1407 /* 1408 Check the input strings. 1409 */ 1410 CHKFSTR ( CHK_STANDARD, "spkcvo_c", target ); 1411 CHKFSTR ( CHK_STANDARD, "spkcvo_c", outref ); 1412 CHKFSTR ( CHK_STANDARD, "spkcvo_c", refloc ); 1413 CHKFSTR ( CHK_STANDARD, "spkcvo_c", abcorr ); 1414 CHKFSTR ( CHK_STANDARD, "spkcvo_c", obsctr ); 1415 CHKFSTR ( CHK_STANDARD, "spkcvo_c", obsref ); 1416 1417 /* 1418 Check the output pointers. 1419 */ 1420 CHKPTR ( CHK_STANDARD, "spkcvo_c", state ); 1421 CHKPTR ( CHK_STANDARD, "spkcvo_c", lt ); 1422 1423 /* 1424 Let the f2c'd routine do the work. 1425 */ 1426 spkcvo_ ( ( char * ) target, 1427 ( doublereal * ) &et, 1428 ( char * ) outref, 1429 ( char * ) refloc, 1430 ( char * ) abcorr, 1431 ( doublereal * ) obssta, 1432 ( doublereal * ) &obsepc, 1433 ( char * ) obsctr, 1434 ( char * ) obsref, 1435 ( doublereal * ) state, 1436 ( doublereal * ) lt, 1437 ( ftnlen ) strlen(target), 1438 ( ftnlen ) strlen(outref), 1439 ( ftnlen ) strlen(refloc), 1440 ( ftnlen ) strlen(abcorr), 1441 ( ftnlen ) strlen(obsctr), 1442 ( ftnlen ) strlen(obsref) ); 1443 1444 chkout_c ( "spkcvo_c" ); 1445 1446 } /* End spkcvo_c */ 1447