/* -Procedure getvects_pdt ( Retrieve FOV vectors in Cassini S/C Coords ) -Abstract Compute the FOV boresight and secondary axis in the Cassini S/C Coordinate frame. -Copyright Copyright (2001), California Institute of Technology. U.S. Government sponsorship acknowledged. -Required_Reading KERNEL */ #include "SpiceUsr.h" #include "SpiceZst.h" #include "SpiceZmc.h" void getvects_pdt ( ConstSpiceChar * name, SpiceDouble epoch, SpiceInt framelen, SpiceChar * frame, SpiceDouble bsight [3], SpiceDouble second [3], SpiceBoolean * found ) /* -Brief_I/O Variable I/O Description -------- --- -------------------------------------------------- name I instrument name. epoch I time in ET when the vectors are to be computed. framelen I space available in the string frame. frame O instrument FOV frame. bsight O boresight unit vector in spacecraft coordinates. second O FOV secondary axis in spacecraft coordinates. found O boolean indicating whether vectors are computed. -Detailed_Input name is the name of the instrument or FOV of interest. epoch is a double containing the epoch at which the vectors are desired in ephemeris time (ET). framelen is the available space in the frame string, counting room for the terminating null. Up to framelen-1 "data" characters will be assigned to the output string. -Detailed_Output frame is the name of the frame the instrument boresight and the FOV secondary axis vector are defined. bsight is the boresight unit vector in the spacecraft coordinate frame, CASSINI_SC_COORD. In the event that the necessary rotation matrix can not be extracted from the frame system, bsight will be the zero vector. second is the FOV secondary axis unit vector in the spacecraft coordinate frame, CASSINI_SC_COORD. In the event that the necessary rotation matrix can not be extracted from the frame system, second will be the zero vector. found SPICETRUE if the necessary rotation matrix from the instrument frame to CASSINI_SC_COORD is computable. SPICEFALSE otherwise. -Exceptions 1) If an ID code is not found for name, then this routine signals the error SPICE(IDCODENOTFOUND). 2) If the ID code associated with name is found, but not in the range [-82999, -82000] then the error SPICE(INVALIDIDCODE) is signalled. This routine functions only with Cassini instrument kernels. 3) If the FOV specification used to describe the instrument field of view is something other than the ANGLES specification, then this routine signals the error SPICE(INVALIDFOVSPEC). 4) If the INS[#]_BORESIGHT keyword contains anything other than 3 double precision values, then this routine signals the error SPICE(BADBORESIGHT) 5) If the INS[#]_FOV_REF_VECTOR keyword contains anything other than 3 double precision values, or if the vector that it contains is parallel to the vector stored in INS[#]_BORESIGHT, then the error SPICE(BADSECONDARYAXIS) is signalled. -Files getvects_pdt relies on the fact that the necessary instrument and frame kernels have been loaded. -Particulars ***THIS ROUTINE TEMPORARILY DISABLES ERROR HANDLING. BEFORE ATTEMPTING TO EMULATE SUCH A PROCEDURE READ 'Error Required Reading' CAREFULLY. IMPROPERLY DISABLING ERROR HANDLING CAN HAVE SEVERE CONSEQUENCES THROUGHOUT THE REST OF YOUR PROGRAM.*** This routine computes the boresight and the FOV secondary axis vectors in the CASSINI_SC_COORD frame if possible. Otherwise it zeroes the boresight vector and clears the frame string. -Examples The following simple code example loads the UVIS instrument kernel and prints the half angular extents and shape of the CASSINI_UVIS_FUV_HI FOV to standard output. #include "SpiceUsr.h" /. Prototypes ./ void getvects_pdt ( ConstSpiceChar * name, ConstSpiceDouble epoch, SpiceInt framelen, SpiceChar * frame, SpiceDouble bsight [3], SpiceDouble second [3], SpiceBoolean * found ); /. Local Parameters ./ #define LNSIZE 32 /. Local Variables ./ SpiceBoolean found; SpiceChar frame[LNSIZE]; SpiceDouble bstout[3]; SpiceDouble secout[3]; /. Load the instrument kernel using furnsh. ./ furnsh_c ( "cas_uvis_v04.ti" ); /. Load the Cassini frame kernel using furnsh. ./ furnsh_c ( "cas_v30.tf" ); /. Compute the boresight and secondary axis for the UVIS FUV HI FOV in the CASSINI_SC_COORD frame. Since it is a fixed offset frame, any epoch will do. Use J2000. ./ getvects_pdt ( "CASSINI_UVIS_FUV_HI", 0.0D0, LNSIZE, frame, bstout, secout, &found ); /. Check found and dump the results. ./ if ( found == SPICETRUE ) { /. Dump the results to standard output. ./ printf ( "CASSINI_UVIS_FUV_HI's boresight points " ); printf ( "(%f,%f,%f) in the CASSINI_SC_COORD frame.\n ", bstout[0], bstout[1], bstout[2] ); printf ( "CASSINI_UVIS_FUV_HI's secondary FOV axis points " ); printf ( "(%f,%f,%f) in the CASSINI_SC_COORD frame.\n ", secout[0], secout[1], secout[2] ); printf ( "\n" ); } else { printf ( "Unable to compute vectors at epoch, %f.\n", 0.0D0 ); printf ( "\n" ); } -Restrictions 1) The name of the instrument must be associated with an ID code that is connected with the Cassini orbiter. 2) This routine requires that all of the elements of the FOV definition are correctly specified and accessible from the kernel pool. 3) This routine additionally requires that the FOV specification utilized by the kernels is the 'ANGLES' format. -Literature_References 1) Rotations Required Reading 2) Frames Required Reading 3) Kernel Required Reading 4) NAIF/SPICE Tutorials -Author_and_Institution F.S. Turner (JPL) -Version -getvects_pdt Version 1.0.0, 11-APR-2001 (FST) */ { /* Begin getvects_pdt */ /* Local Parameters */ #define MAXACTSIZE 80 #define MAXKEYSIZE 32 #define MAXSPECSIZE 32 #define MAXFRMSIZE 32 /* Local Variables */ SpiceBoolean gotit = SPICEFALSE; SpiceChar keyword [ MAXKEYSIZE ]; SpiceChar error_act [ MAXACTSIZE ]; SpiceChar error_dev [ MAXACTSIZE ]; SpiceChar fovspec [ MAXSPECSIZE ] = "CORNERS"; SpiceChar locfram [ MAXFRMSIZE ]; SpiceChar valtype; SpiceDouble locbst [ 3 ]; SpiceDouble locsec [ 3 ]; SpiceDouble xloc [ 3 ]; SpiceDouble locprj [ 3 ]; SpiceDouble rotmat [ 3 ][ 3 ]; SpiceDouble vmag; SpiceInt idcode; SpiceInt n; /* Participate in tracing. */ chkin_c ( "getvects_pdt" ); /* Make certain the output frame string has at least enough room for one output character and a null terminator. Also check to see if the input pointer is null. */ CHKOSTR ( CHK_STANDARD, "getvects_pdt", frame, framelen ); /* Fetch the instrument ID code. */ bodn2c_c ( name, &idcode, &gotit ); if ( gotit == SPICEFALSE ) { setmsg_c ( "Unable to locate ID code for instrument, #." ); errch_c ( "#", name ); sigerr_c ( "SPICE(IDCODENOTFOUND)" ); chkout_c ( "getvects_pdt" ); return; } /* Now verify that this ID code is associated with the Cassini orbiter. */ if ( ( idcode < -89999 ) || ( idcode > -82000 ) ) { setmsg_c ( "The instrument, #, with ID code, #, is not " "associated with the Cassini orbiter. This " "module only functions with Cassini based " "detectors." ); errch_c ( "#", name ); errint_c ( "#", idcode ); sigerr_c ( "SPICE(INVALIDIDCODE)" ); chkout_c ( "getvects_pdt" ); return; } /* Retrieve the FOV parameters for this instrument from the kernel pool. First check to make certain that this instrument is using the proper specification. */ sprintf ( keyword, "INS%ld_FOV_CLASS_SPEC", idcode ); /* Initialize n to 0 just to satiate the gcpool_c wrapper. */ n = 0; gcpool_c ( keyword, 0, 1, MAXSPECSIZE, &n, fovspec, &gotit ); if ( (gotit == SPICEFALSE) || !eqstr_c("ANGLES", fovspec) ) { setmsg_c ( "The instrument, #, utilizes the FOV " "specification, #. This specification is not " "currently supported by this module." ); errch_c ( "#", name ); errch_c ( "#", fovspec ); sigerr_c ( "SPICE(INVALIDFOVSPEC)" ); chkout_c ( "getvects_pdt" ); return; } /* Now retrieve the boresight from the kernel pool. Check first for any abnormalities associated with its definition. */ sprintf ( keyword, "INS%ld_BORESIGHT", idcode ); dtpool_c ( keyword, &gotit, &n, &valtype ); if ( (n != 3) || (gotit == SPICEFALSE) || (valtype != 'N') ) { setmsg_c ( "The boresight for instrument # is missing or " "improperly defined. Check the kernels you " "are loading for INS#_BORESIGHT." ); errch_c ( "#", name ); errint_c ( "#", idcode ); sigerr_c ( "SPICE(BADBORESIGHT)" ); chkout_c ( "getvects_pdt" ); return; } gdpool_c ( keyword, 0, 3, &n, locbst, &gotit ); /* Now retrieve the FOV secondary axis from the kernel pool. As with the boresight, check for any abnormalities associated with its definition. */ sprintf ( keyword, "INS%ld_FOV_REF_VECTOR", idcode ); dtpool_c ( keyword, &gotit, &n, &valtype ); if ( (n != 3) || (gotit == SPICEFALSE) || (valtype != 'N') ) { setmsg_c ( "The FOV reference vector for instrument # is " "missing or improperly defined. Check the " "kernels you are loading for " "INS#_FOV_REF_VECTOR." ); errch_c ( "#", name ); errint_c ( "#", idcode ); sigerr_c ( "SPICE(BADFOVREFVECTOR)" ); chkout_c ( "getvects_pdt" ); return; } gdpool_c ( keyword, 0, 3, &n, locsec, &gotit ); /* Verify that the FOV reference vector listed in the kernel pool is not parallel to the boresight vector. */ vcrss_c ( locbst, locsec, xloc ); if ( vnorm_c ( xloc ) == 0.0 ) { setmsg_c ( "The FOV reference vector for instrument # is " "parallel to the specified boresight vector. " "This produces a degenerate field of view. " "Check the kernels you are loading for " "INS#_FOV_REF_VECTOR." ); errch_c ( "#", name ); errint_c ( "#", idcode ); sigerr_c ( "SPICE(BADFOVREFVECTOR)" ); chkout_c ( "getvects_pdt" ); return; } /* Fetch the name of the frame that the instrument's FOV definition references. */ sprintf ( keyword, "INS%ld_FOV_FRAME", idcode ); dtpool_c ( keyword, &gotit, &n, &valtype ); if ( (n != 1) || (gotit == SPICEFALSE) || (valtype != 'C' ) ) { setmsg_c ( "The FOV frame for instrument # is missing or " "improperly defined. Check the " "kernels you are loading for INS#_FOV_FRAME." ); errch_c ( "#", name ); errint_c ( "#", idcode ); sigerr_c ( "SPICE(BADFOVFRAME)" ); chkout_c ( "getvects_pdt" ); return; } /* Initialize n to 0 just to satiate the gcpool_c wrapper. */ n = 0; gcpool_c ( keyword, 0, 1, MAXFRMSIZE, &n, locfram, &gotit ); /* Convert the string to a C style string, since gcpool_c as of N0051 does not do this. */ F2C_ConvertStr ( MAXFRMSIZE, locfram ); /* Retrieve the current error action and device. */ erract_c ( "GET", MAXACTSIZE, error_act ); errdev_c ( "GET", MAXACTSIZE, error_dev ); /* "Disable" the error signalling mechanism, temporarily. */ erract_c ( "SET", MAXACTSIZE, "RETURN" ); errdev_c ( "SET", MAXACTSIZE, "NULL" ); /* Now that error handling is effectively disabled, try and compute the required rotation matrix. */ pxform_c ( locfram, "CASSINI_SC_COORD", epoch, rotmat ); /* See if the attempt to compute the rotation matrix has failed. */ if ( failed_c() == SPICETRUE ) { /* Clear the boresight, secondary axis and the frame argument. Set found to SPICEFALSE. */ *found = SPICEFALSE; bsight [0] = 0.0; bsight [1] = 0.0; bsight [2] = 0.0; second [0] = 0.0; second [1] = 0.0; second [2] = 0.0; frame = ""; /* Clear the error. */ reset_c(); /* Restore the error handling to it's default state. */ erract_c ( "SET", MAXACTSIZE, error_act ); errdev_c ( "SET", MAXACTSIZE, error_dev ); /* Return to the caller. */ chkout_c ( "getvects_pdt" ); return; } /* Set found to SPICETRUE, since we produced a rotation matrix. */ *found = SPICETRUE; /* Return the error handling to the state prior to disabling it. */ erract_c ( "SET", MAXACTSIZE, error_act ); errdev_c ( "SET", MAXACTSIZE, error_dev ); /* At this point all that remains is to compute the secondary axis and the boresight. First find the projection of the FOV reference vector onto the boresight. */ vproj_c ( locsec, locbst, locprj ); /* Now subtract locprj from locsec, since we are looking for the component of the FOV reference vector that lies in the plane normal to the boresight. */ vsub_c ( locsec, locprj, locsec ); /* Now rotate the vectors into the requested frame. */ mxv_c ( rotmat, locbst, bsight ); mxv_c ( rotmat, locsec, second ); /* Lastly normalize the vectors to unit length. */ unorm_c ( bsight, bsight, &vmag ); unorm_c ( second, second, &vmag ); /* Copy locfram into the frame argument safely. */ strncpy ( frame, locfram, framelen-1 ); /* Check to see if we filled framelen-1 with real characters. If so, pop the terminating null on the end of the expression. */ if ( strnlen( frame, framelen-1 ) == (framelen-1) ) { frame[framelen-1] = '\0'; } chkout_c ( "getvects_pdt" ); return; } /* End getvects_pdt */