30 extern int refchg_(integer *frame1, integer *frame2, doublereal *et,
32 extern int frmchg_(integer *frame1, integer *frame2, doublereal *et,
34 extern int invstm_(doublereal *mat, doublereal *invmat);
38 extern int ck3sdn(
double sdntol,
bool avflag,
int *nrec,
39 double *sclkdp,
double *quats,
double *avvs,
40 int nints,
double *starts,
double *dparr,
113 QString key =
"INS" +
toString(frameCode) +
"_TRANSX";
114 SpiceDouble transX[2];
118 gdpool_c(key.toLatin1().data(), 1, 2, &number, transX, &found);
121 QString msg =
"Cannot find [" + key +
"] in text kernels";
126 if (transX[0] < transX[1])
p_axisV = 1;
163 for (
int i = 0; i < 3; i++)
245 if (
p_et == et)
return;
335 QString msg =
"Argument cacheSize must not be less or equal to zero";
339 if (startTime > endTime) {
340 QString msg =
"Argument startTime must be less than or equal to endTime";
344 if ((startTime != endTime) && (size == 1)) {
345 QString msg =
"Cache size must be more than 1 if startTime and endTime differ";
351 QString msg =
"A SpiceRotation cache has already been created";
372 for (
int i = 0; i < cacheSize; i++) {
441 for (
int i = 0; i < labelTimeFrames.
size(); i++) {
454 for (
int i = 0; i < labelConstantFrames.
size(); i++) {
459 for (
int i = 0; i < labelConstantRotation.
size(); i++) {
465 ident_c((SpiceDouble( *)[3]) &
p_TC[0]);
491 int recFields = table[0].Fields();
497 if (recFields == 5) {
498 for (
int r = 0; r < table.
Records(); r++) {
501 if (rec.
Fields() != recFields) {
505 std::vector<double> j2000Quat;
506 j2000Quat.push_back((
double)rec[0]);
507 j2000Quat.push_back((
double)rec[1]);
508 j2000Quat.push_back((
double)rec[2]);
509 j2000Quat.push_back((
double)rec[3]);
512 std::vector<double> CJ = q.
ToMatrix();
520 else if (recFields == 8) {
521 for (
int r = 0; r < table.
Records(); r++) {
524 if (rec.
Fields() != recFields) {
528 std::vector<double> j2000Quat;
529 j2000Quat.push_back((
double)rec[0]);
530 j2000Quat.push_back((
double)rec[1]);
531 j2000Quat.push_back((
double)rec[2]);
532 j2000Quat.push_back((
double)rec[3]);
536 std::vector<double> CJ = q.
ToMatrix();
539 std::vector<double> av;
540 av.push_back((
double)rec[4]);
541 av.push_back((
double)rec[5]);
542 av.push_back((
double)rec[6]);
552 else if (recFields == 3) {
553 std::vector<double> coeffAng1, coeffAng2, coeffAng3;
555 for (
int r = 0; r < table.
Records() - 1; r++) {
558 if (rec.
Fields() != recFields) {
561 coeffAng1.push_back((
double)rec[0]);
562 coeffAng2.push_back((
double)rec[1]);
563 coeffAng3.push_back((
double)rec[2]);
568 double baseTime = (double)rec[0];
569 double timeScale = (double)rec[1];
570 double degree = (double)rec[2];
579 QString msg =
"Expecting either three, five, or eight fields in the SpiceRotation table";
615 for (std::vector<double>::size_type pos = 0; pos <
p_cacheTime.size(); pos++) {
641 for (std::vector<double>::size_type pos = 0; pos < maxSize; pos++) {
648 QString msg =
"The SpiceRotation has not yet been fit to a function";
680 QString msg =
"Only cached rotations can be returned as a line cache of quaternions and time";
684 return Cache(tableName);
749 Table table(tableName, record);
751 for (
int i = 0; i < (int)
p_cache.size(); i++) {
787 Table table(tableName, record);
789 for (
int cindex = 0; cindex <
p_degree + 1; cindex++) {
808 QString msg =
"To create table source of data must be either Memcache or PolyFunction";
823 SpiceInt centerBodyCode = (SpiceInt) centerBody;
839 QString naifKeyword =
"BODY" +
toString(centerBodyCode) +
"_CONSTANTS_REF_FRAME" ;
840 SpiceInt numExpected;
841 SpiceInt numReturned;
843 SpiceDouble relativeFrameCode = 0;
845 dtpool_c(naifKeyword.toLatin1().data(), &found, &numExpected, &naifType);
849 SpiceDouble relativeFrameCode;
850 bodvcd_c(centerBodyCode,
"CONSTANTS_REF_FRAME", 1,
851 &numReturned, &relativeFrameCode);
854 if (!found || relativeFrameCode == 1) {
858 naifKeyword =
"BODY" +
toString(centerBodyCode) +
"_POLE_RA" ;
859 dtpool_c(naifKeyword.toLatin1().data(), &found, &numExpected, &naifType);
862 std::vector<SpiceDouble> d(3);
865 m_pm.resize(numExpected);
867 bodvcd_c(centerBodyCode,
"POLE_RA", numExpected, &numReturned, &d[0]);
872 bodvcd_c(centerBodyCode,
"POLE_DEC", numExpected, &numReturned, &d[0]);
877 bodvcd_c(centerBodyCode,
"PM", numExpected, &numReturned, &d[0]);
878 m_pm[0].setDegrees(d[0]);
879 m_pm[1].setDegrees(d[1]);
880 m_pm[2].setDegrees(d[2]);
887 naifKeyword =
"BODY" +
toString(centerBodyCode) +
"_NUT_PREC_RA" ;
888 dtpool_c(naifKeyword.toLatin1().data(), &found, &numReturned, &naifType);
892 SpiceInt bcCode = centerBodyCode/100;
893 naifKeyword =
"BODY" +
toString(bcCode) +
"_NUT_PREC_ANGLES" ;
894 dtpool_c(naifKeyword.toLatin1().data(), &found, &numExpected, &naifType);
895 std::vector<double>npAngles(numExpected, 0.);
896 bodvcd_c(bcCode,
"NUT_PREC_ANGLES", numExpected, &numReturned, &npAngles[0]);
902 std::vector<SpiceDouble> angles(numExpected);
903 bodvcd_c(centerBodyCode,
"NUT_PREC_RA", numExpected, &numReturned, &
m_raNutPrec[0]);
904 bodvcd_c(centerBodyCode,
"NUT_PREC_DEC", numExpected, &numReturned, &
m_decNutPrec[0]);
905 bodvcd_c(centerBodyCode,
"NUT_PREC_PM", numExpected, &numReturned, &
m_pmNutPrec[0]);
910 for (
int i = 0; i < numExpected; i++) {
949 for (
int i = 0; i < labelCoeffs.
size(); i++){
956 for (
int i = 0; i < labelCoeffs.
size(); i++){
962 PvlKeyword labelCoeffs = label[
"PrimeMeridian"];
963 for (
int i = 0; i < labelCoeffs.
size(); i++){
971 PvlKeyword labelCoeffs = label[
"PoleRaNutPrec"];
972 for (
int i = 0; i < labelCoeffs.
size(); i++){
977 PvlKeyword labelCoeffs = label[
"PoleDecNutPrec"];
978 for (
int i = 0; i < labelCoeffs.
size(); i++){
984 for (
int i = 0; i < labelCoeffs.
size(); i++){
989 PvlKeyword labelCoeffs = label[
"SysNutPrec0"];
990 for (
int i = 0; i < labelCoeffs.
size(); i++){
995 PvlKeyword labelCoeffs = label[
"SysNutPrec1"];
996 for (
int i = 0; i < labelCoeffs.
size(); i++){
1033 for (
int i = 0; i < (int)
p_TC.size(); i++) {
1061 for (
int i = 0; i < (int)
m_raPole.size(); i++) {
1067 for (
int i = 0; i < (int)
m_decPole.size(); i++) {
1073 for (
int i = 0; i < (int)
m_pm.size(); i++) {
1080 for (
int i = 0; i < (int)
m_raNutPrec.size(); i++) {
1092 for (
int i = 0; i < (int)
m_pmNutPrec.size(); i++) {
1142 SpiceDouble ang1, ang2, ang3;
1143 m2eul_c((SpiceDouble *) &
p_CJ[0], axis3, axis2, axis1, &ang3, &ang2, &ang1);
1145 std::vector<double> angles;
1146 angles.push_back(ang1);
1147 angles.push_back(ang2);
1148 angles.push_back(ang3);
1167 eul2m_c(angles[2], angles[1], angles[0], axis3, axis2, axis1, (SpiceDouble (*)[3]) &(
p_CJ[0]));
1226 std::vector<double> jVec;
1228 if (rVec.size() == 3) {
1230 mxm_c((SpiceDouble *) &
p_TC[0], (SpiceDouble *) &
p_CJ[0], TJ);
1232 mtxv_c(TJ, (SpiceDouble *) &rVec[0], (SpiceDouble *) &jVec[0]);
1235 else if (rVec.size() == 6) {
1241 std::vector<double> stateTJ(36);
1245 xpose6_c(&stateTJ[0], (SpiceDouble( *) [6]) &stateTJ[0]);
1246 double stateJT[6][6];
1247 invstm_((doublereal *) &stateTJ[0], (doublereal *) stateJT);
1248 xpose6_c(stateJT, stateJT);
1251 mxvg_c(stateJT, (SpiceDouble *) &rVec[0], 6, 6, (SpiceDouble *) &jVec[0]);
1429 std::vector<double> jVec;
1433 int angleIndex = partialVar;
1436 double angle = angles.at(angleIndex);
1439 double dmatrix[3][3];
1440 drotat_(&angle, (integer *) axes + angleIndex, (doublereal *) dmatrix);
1442 xpose_c(dmatrix, dmatrix);
1456 msg =
"Body rotation uses a binary PCK. Solutions for this model are not supported";
1460 msg =
"Body rotation uses a PCK not referenced to J2000. " 1461 "Solutions for this model are not supported";
1465 msg =
"Solutions are not supported for this frame type.";
1470 for (
int row = 0; row < 3; row++) {
1471 for (
int col = 0; col < 3; col++) {
1472 dmatrix[row][col] *= dpoly;
1478 switch (angleIndex) {
1480 rotmat_c(dmatrix, angles[1], axes[1], dCJ);
1481 rotmat_c(dCJ, angles[2], axes[2], dCJ);
1484 rotate_c(angles[0], axes[0], dCJ);
1485 mxm_c(dmatrix, dCJ, dCJ);
1486 rotmat_c(dCJ, angles[2], axes[2], dCJ);
1489 rotate_c(angles[0], axes[0], dCJ);
1490 rotmat_c(dCJ, angles[1], axes[1], dCJ);
1491 mxm_c(dmatrix, dCJ, dCJ);
1497 mxm_c((SpiceDouble *) &
p_TC[0], dCJ[0], dTJ);
1501 std::vector<double> lookdJ(3);
1503 mtxv_c(dTJ, (
const SpiceDouble *) &lookT[0], (SpiceDouble *) &lookdJ[0]);
1520 std::vector<double> rVec(3);
1522 if (jVec.size() == 3) {
1524 mxm_c((SpiceDouble *) &
p_TC[0], (SpiceDouble *) &
p_CJ[0], TJ);
1526 mxv_c(TJ, (SpiceDouble *) &jVec[0], (SpiceDouble *) &rVec[0]);
1528 else if (jVec.size() == 6) {
1534 std::vector<double> stateTJ(36);
1537 mxvg_c((SpiceDouble *) &stateTJ[0], (SpiceDouble *) &jVec[0], 6, 6, (SpiceDouble *) &rVec[0]);
1558 std::vector<double> coeffAng1, coeffAng2, coeffAng3;
1572 else if (
p_cache.size() == 2) {
1578 coeffAng1.assign(
p_degree + 1, 0.);
1579 coeffAng2.assign(
p_degree + 1, 0.);
1580 coeffAng3.assign(
p_degree + 1, 0.);
1595 std::vector<double> time;
1601 coeffAng1.push_back(angles[0]);
1602 coeffAng2.push_back(angles[1]);
1603 coeffAng3.push_back(angles[2]);
1605 else if (
p_cache.size() == 2) {
1618 angles2[0] =
WrapAngle(angles1[0], angles2[0]);
1619 angles2[2] =
WrapAngle(angles1[2], angles2[2]);
1621 double intercept[3];
1624 for (
int angleIndex = 0; angleIndex < 3; angleIndex++) {
1626 slope[angleIndex] = angline.
Slope();
1627 intercept[angleIndex] = angline.
Intercept();
1629 coeffAng1.push_back(intercept[0]);
1630 coeffAng1.push_back(slope[0]);
1631 coeffAng2.push_back(intercept[1]);
1632 coeffAng2.push_back(slope[1]);
1633 coeffAng3.push_back(intercept[2]);
1634 coeffAng3.push_back(slope[2]);
1641 for (std::vector<double>::size_type pos = 0; pos <
p_cacheTime.size(); pos++) {
1653 angles[0] =
WrapAngle(start1, angles[0]);
1654 angles[2] =
WrapAngle(start3, angles[2]);
1657 fitAng1->
AddKnown(time, angles[0]);
1658 fitAng2->
AddKnown(time, angles[1]);
1659 fitAng3->
AddKnown(time, angles[2]);
1708 const std::vector<double> &coeffAng2,
1709 const std::vector<double> &coeffAng3,
1774 QString msg =
"Target body orientation information not available. Rerun spiceinit.";
1845 const std::vector<Angle> &decCoeff,
1846 const std::vector<Angle> &pmCoeff) {
1868 std::vector<double> &coeffAng2,
1869 std::vector<double> &coeffAng3) {
1890 std::vector<Angle> &decCoeff,
1891 std::vector<Angle> &pmCoeff) {
1933 void SpiceRotation::SetCacheTime(std::vector<double> cacheTime) {
1957 if (coeffIndex > 0 && coeffIndex <=
p_degree) {
1958 derivative = pow(time, coeffIndex);
1960 else if (coeffIndex == 0) {
1964 QString msg =
"Unable to evaluate the derivative of the SPICE rotation fit polynomial for " 1965 "the given coefficient index [" +
toString(coeffIndex) +
"]. " 1966 "Index is negative or exceeds degree of polynomial [" 1989 const int coeffIndex) {
1990 const double p_dayScale = 86400;
1992 const double p_centScale = p_dayScale * 36525;
1995 switch (partialVar) {
1998 time =
p_et / p_centScale;
2001 time =
p_et / p_dayScale;
2007 switch (coeffIndex) {
2013 derivative = pow(time, coeffIndex);
2016 QString msg =
"Unable to evaluate the derivative of the target body rotation fit polynomial " 2017 "for the given coefficient index [" +
toString(coeffIndex) +
"]. " 2018 "Index is negative or exceeds degree of polynomial [" 2026 derivative = -derivative;
2056 int angleIndex = partialVar;
2059 double angle = angles.at(angleIndex);
2061 double dmatrix[3][3];
2062 drotat_(&angle, (integer *) axes + angleIndex, (doublereal *) dmatrix);
2064 xpose_c(dmatrix, dmatrix);
2078 QString msg =
"Only CK, DYN, and PCK partials can be calculated";
2083 for (
int row = 0; row < 3; row++) {
2084 for (
int col = 0; col < 3; col++) {
2085 dmatrix[row][col] *= dpoly;
2091 switch (angleIndex) {
2093 rotmat_c(dmatrix, angles[1], axes[1], dCJ);
2094 rotmat_c(dCJ, angles[2], axes[2], dCJ);
2097 rotate_c(angles[0], axes[0], dCJ);
2098 mxm_c(dmatrix, dCJ, dCJ);
2099 rotmat_c(dCJ, angles[2], axes[2], dCJ);
2102 rotate_c(angles[0], axes[0], dCJ);
2103 rotmat_c(dCJ, angles[1], axes[1], dCJ);
2104 mxm_c(dmatrix, dCJ, dCJ);
2110 mxm_c((SpiceDouble *) &
p_TC[0], dCJ[0], dTJ);
2114 std::vector<double> lookdT(3);
2116 mxv_c(dTJ, (
const SpiceDouble *) &lookJ[0], (SpiceDouble *) &lookdT[0]);
2133 double diff1 = compareAngle - angle;
2135 if (diff1 < -1 * pi_c()) {
2138 else if (diff1 > pi_c()) {
2178 for (
int icoef =
p_degree + 1; icoef <= degree; icoef++) {
2179 coefAngle1.push_back(0.);
2180 coefAngle2.push_back(0.);
2181 coefAngle3.push_back(0.);
2188 std::vector<double> coefAngle1(degree + 1),
2189 coefAngle2(degree + 1),
2190 coefAngle3(degree + 1);
2192 for (
int icoef = 0; icoef <= degree; icoef++) {
2267 if (axis1 < 1 || axis2 < 1 || axis3 < 1 || axis1 > 3 || axis2 > 3 || axis3 > 3) {
2268 QString msg =
"A rotation axis is outside the valid range of 1 to 3";
2295 double currentTime = observStart;
2296 bool timeLoaded =
false;
2301 ktotal_c(
"ck", (SpiceInt *) &count);
2311 "Full cache size does NOT match cache size in LoadTimeCache -- should never happen";
2326 m2q_c(CJ, quats[r]);
2328 vequ_c((SpiceDouble *) &
p_cacheAv[r][0], avvs[r]);
2332 double cubeStarts = timeSclkdp[0];
2333 double radTol = 0.000000017453;
2334 SpiceInt avflag = 1;
2340 ck3sdn(radTol, avflag, (
int *) &sizOut, timeSclkdp, (doublereal *) quats,
2341 (SpiceDouble *) avvs, nints, &cubeStarts, dparr, (
int *) intarr);
2347 std::vector<double> av;
2350 for (
int r = 0; r < sizOut; r++) {
2355 std::vector<double> CJ(9);
2356 q2m_c(quats[r], (SpiceDouble( *)[3]) &CJ[0]);
2358 vequ_c(avvs[r], (SpiceDouble *) &av[0]);
2372 int SOURCESIZ = 128;
2375 SpiceChar file[FILESIZ];
2376 SpiceChar filtyp[TYPESIZ];
2377 SpiceChar source[SOURCESIZ];
2380 bool observationSpansToNextSegment =
false;
2385 kdata_c(0,
"ck", FILESIZ, TYPESIZ, SOURCESIZ, file, filtyp, source, &handle, &found);
2391 observationSpansToNextSegment =
false;
2402 dafus_c(sum, (SpiceInt) 2, (SpiceInt) 6, dc, ic);
2405 if (ic[2] == 5)
break;
2408 if (ic[0] == spCode && ic[2] == 3) {
2409 sct2e_c((
int) spCode / 1000, dc[0], &segStartEt);
2410 sct2e_c((
int) spCode / 1000, dc[1], &segStopEt);
2415 if (currentTime >= segStartEt && currentTime <= segStopEt) {
2419 if (observationSpansToNextSegment && currentTime > segStartEt) {
2420 QString msg =
"Observation crosses segment boundary--unable to interpolate pointing";
2423 if (observEnd > segStopEt) {
2424 observationSpansToNextSegment =
true;
2428 int dovelocity = ic[3];
2431 dafgda_c(handle, end - 1, end, val);
2433 int ninstances = (int) val[1];
2434 int numvel = dovelocity * 3;
2435 int quatnoff = ic[4] + (4 + numvel) * ninstances - 1;
2437 int sclkdp1off = quatnoff + 1;
2438 int sclkdpnoff = sclkdp1off + ninstances - 1;
2441 int sclkSpCode = spCode / 1000;
2444 std::vector<double> sclkdp(ninstances);
2445 dafgda_c(handle, sclkdp1off, sclkdpnoff, (SpiceDouble *) &sclkdp[0]);
2448 sct2e_c(sclkSpCode, sclkdp[0], &et);
2450 while (instance < (ninstances - 1) && et < currentTime) {
2452 sct2e_c(sclkSpCode, sclkdp[instance], &et);
2455 if (instance > 0) instance--;
2456 sct2e_c(sclkSpCode, sclkdp[instance], &et);
2458 while (instance < (ninstances - 1) && et < observEnd) {
2461 sct2e_c(sclkSpCode, sclkdp[instance], &et);
2465 if (!observationSpansToNextSegment) {
2471 currentTime = segStopEt;
2480 QString msg =
"No camera kernels loaded...Unable to determine time cache to downsize";
2487 double cacheSlope = 0.0;
2511 QString msg =
"Time cache not available -- rerun spiceinit";
2515 std::vector<double> fullCacheTime;
2516 double cacheSlope = 0.0;
2524 return fullCacheTime;
2550 std::vector<int> frameCodes;
2551 std::vector<int> frameTypes;
2554 while (frameCodes[frameCodes.size()-1] != J2000Code) {
2555 frmidx = frameCodes.size() - 1;
2563 frinfo_c((SpiceInt) frameCodes[frmidx],
2564 (SpiceInt *) ¢er,
2566 (SpiceInt *) &typid, &found);
2571 frameTypes.push_back(0);
2575 QString msg =
"The frame" +
toString((
int) frameCodes[frmidx]) +
" is not supported by Naif";
2579 double matrix[3][3];
2583 nextFrame = J2000Code;
2585 else if (type == CK) {
2586 ckfrot_((SpiceInt *) &typid, &et, (
double *) matrix, &nextFrame, (logical *) &found);
2591 frameTypes.push_back(0);
2595 QString msg =
"The ck rotation from frame " +
toString(frameCodes[frmidx]) +
" can not " 2596 +
"be found due to no pointing available at requested time or a problem with the " 2601 else if (type == TK) {
2602 tkfram_((SpiceInt *) &typid, (
double *) matrix, &nextFrame, (logical *) &found);
2604 QString msg =
"The tk rotation from frame " +
toString(frameCodes[frmidx]) +
2605 " can not be found";
2609 else if (type == DYN) {
2616 zzdynrot_((SpiceInt *) &typid, (SpiceInt *) ¢er, &et, (
double *) matrix, &nextFrame);
2620 QString msg =
"The frame " +
toString(frameCodes[frmidx]) +
2621 " has a type " +
toString(type) +
" not supported by your version of Naif Spicelib." 2622 +
"You need to update.";
2626 frameCodes.push_back(nextFrame);
2627 frameTypes.push_back(type);
2638 while (frameTypes[nConstants] == TK && nConstants < (
int) frameTypes.size()) nConstants++;
2641 for (
int i = 0; i <= nConstants; i++) {
2646 for (
int i = nConstants; i < (int) frameCodes.size(); i++) {
2666 std::vector<double> TJ;
2668 mxm_c((SpiceDouble *) &
p_TC[0], (SpiceDouble *) &
p_CJ[0], (SpiceDouble( *) [3]) &TJ[0]);
2681 std::vector<double> q;
2683 m2q_c((SpiceDouble( *)[3]) &
p_TC[0], &q[0]);
2705 p_TC = constantMatrix;
2716 std::vector<double> q;
2718 m2q_c((SpiceDouble( *)[3]) &
p_CJ[0], &q[0]);
2740 p_CJ = timeBasedMatrix;
2756 refchg_((SpiceInt *) &fromFrame, (SpiceInt *) &targetFrame, &et, (doublereal *) &
p_TC[0]);
2758 xpose_c((SpiceDouble( *)[3]) &
p_TC[0], (SpiceDouble( *)[3]) &
p_TC[0]);
2786 QString msg =
"The SpiceRotation pointing angles must be fit to polynomials in order to ";
2787 msg +=
"compute angular velocity.";
2791 QString msg =
"Planetary angular velocity must be fit computed with PCK polynomials ";
2794 std::vector<double> dCJdt;
2812 mtxm_c((SpiceDouble( *)[3]) &dCJdt[0], (SpiceDouble( *)[3]) &
p_CJ[0], omega);
2813 p_av[0] = omega[2][1];
2814 p_av[1] = omega[0][2];
2815 p_av[2] = omega[1][0];
2833 double dmatrix[3][3];
2835 double wmatrix[3][3];
2838 for (
int angleIndex = 0; angleIndex < 3; angleIndex++) {
2839 drotat_(&(angles[angleIndex]), (integer *) axes + angleIndex, (doublereal *) dmatrix);
2841 xpose_c(dmatrix, dmatrix);
2853 for (
int row = 0; row < 3; row++) {
2854 for (
int col = 0; col < 3; col++) {
2855 dmatrix[row][col] *= dangle;
2859 switch (angleIndex) {
2861 rotmat_c(dmatrix, angles[1], axes[1], dmatrix);
2862 rotmat_c(dmatrix, angles[2], axes[2], dmatrix);
2865 rotate_c(angles[0], axes[0], wmatrix);
2866 mxm_c(dmatrix, wmatrix, dmatrix);
2867 rotmat_c(dmatrix, angles[2], axes[2], dmatrix);
2870 rotate_c(angles[0], axes[0], wmatrix);
2871 rotmat_c(wmatrix, angles[1], axes[1], wmatrix);
2872 mxm_c(dmatrix, wmatrix, dmatrix);
2876 for (
int index = 0; index < 9; index++) {
2879 dCJ[index] += dmatrix[i][j];
2893 std::vector<double> stateTJ(36);
2896 double stateCJ[6][6];
2897 rav2xf_c(&
p_CJ[0], &
p_av[0], stateCJ);
2903 for (
int row = 3; row < 6; row++) {
2907 for (
int col = 0; col < 3; col++) {
2910 stateTJ[irow*6 + col] =
p_TC[vpos] * stateCJ[0][col] +
p_TC[vpos+1] * stateCJ[1][col]
2911 +
p_TC[vpos+2] * stateCJ[2][col];
2913 stateTJ[row*6 + col] =
p_TC[vpos] * stateCJ[3][col] +
p_TC[vpos+1] * stateCJ[4][col]
2914 +
p_TC[vpos+2] * stateCJ[5][col];
2916 stateTJ[irow*6 + jcol] = 0;
2918 stateTJ[row*6 +jcol] = stateTJ[irow*6 + col];
2940 double diffTime = timeEt -
p_et;
2941 std::vector<double> CJ(9, 0.0);
2946 axisar_c((SpiceDouble *) &
p_av[0], diffTime*vnorm_c((SpiceDouble *) &
p_av[0]), dmat);
2949 mxm_c(dmat, (SpiceDouble *) &
p_CJ[0], (SpiceDouble( *)[3]) &CJ[0]);
2980 ktotal_c(
"PCK", &count);
2985 int SOURCESIZ = 128;
2986 SpiceChar file[FILESIZ];
2987 SpiceChar filetype[TYPESIZ];
2988 SpiceChar source[SOURCESIZ];
2995 for (SpiceInt knum = 0; knum < count; knum++){
2996 kdata_c(knum,
"PCK", FILESIZ, TYPESIZ, SOURCESIZ, file, filetype, source, &handle, &found);
2999 if (strstr(file,
"bpc") != NULL) {
3016 SpiceInt centerBodyCode;
3017 SpiceInt frameClass;
3019 frinfo_c(frameCode, ¢erBodyCode, &frameClass, &classId, &found);
3022 if (frameClass == 2 || (centerBodyCode > 0 && frameClass != 3)) {
3028 for (std::vector<int>::size_type idx = 1; idx <
p_constantFrames.size(); idx++) {
3030 frinfo_c(frameCode, ¢erBodyCode, &frameClass, &classId, &found);
3035 switch (frameClass) {
3082 std::vector<double>::iterator pos;
3095 if (cacheIndex < 0) cacheIndex = 0;
3102 std::vector<double> CJ2(
p_cache[cacheIndex+1]);
3103 std::vector<double> CJ1(
p_cache[cacheIndex]);
3104 SpiceDouble J2J1[3][3];
3105 mtxm_c((SpiceDouble( *)[3]) &CJ2[0], (SpiceDouble( *)[3]) &CJ1[0], J2J1);
3106 SpiceDouble axis[3];
3108 raxisa_c(J2J1, axis, &angle);
3109 SpiceDouble delta[3][3];
3110 axisar_c(axis, angle * (SpiceDouble)mult, delta);
3111 mxmt_c((SpiceDouble *) &CJ1[0], delta, (SpiceDouble( *) [3]) &
p_CJ[0]);
3114 double v1[3], v2[3];
3115 vequ_c((SpiceDouble *) &
p_cacheAv[cacheIndex][0], v1);
3116 vequ_c((SpiceDouble *) &
p_cacheAv[cacheIndex+1][0], v2);
3117 vscl_c((1. - mult), v1, v1);
3118 vscl_c(mult, v2, v2);
3119 vadd_c(v1, v2, (SpiceDouble *) &
p_av[0]);
3141 SpiceDouble stateJ[6];
3144 spkez_c((SpiceInt) spkCode,
p_et,
"J2000",
"LT+S",
3148 SpiceDouble sJ[3], svJ[3];
3149 vpack_c(-1 * stateJ[0], -1 * stateJ[1], -1 * stateJ[2], sJ);
3150 vpack_c(stateJ[3], stateJ[4], stateJ[5], svJ);
3155 (SpiceDouble( *)[3]) &
p_CJ[0]);
3172 SpiceInt j2000 = J2000Code;
3181 double stateCJ[6][6];
3182 frmchg_((integer *) &j2000, (integer *) &toFrame, &time, (doublereal *) stateCJ);
3187 SpiceBoolean ckfailure = failed_c();
3191 xpose6_c(stateCJ, stateCJ);
3192 xf2rav_c(stateCJ, (SpiceDouble( *)[3]) &
p_CJ[0], (SpiceDouble *) &
p_av[0]);
3196 refchg_((integer *) &j2000, (integer *) &toFrame, &time, (SpiceDouble *) &
p_CJ[0]);
3200 getmsg_c(
"SHORT",
sizeof(naifstr), naifstr);
3203 if (eqstr_c(naifstr,
"SPICE(UNKNOWNFRAME)")) {
3205 "reference frame code. Has the mission frames kernel been loaded?";
3209 Isis::IString msg =
"No pointing available at requested time [" +
3217 xpose_c((SpiceDouble( *)[3]) &
p_CJ[0], (SpiceDouble( *)[3]) &
p_CJ[0]);
3239 std::vector<double> rtime;
3241 std::vector<double> angles;
3242 angles.push_back(function1.
Evaluate(rtime));
3243 angles.push_back(function2.
Evaluate(rtime));
3244 angles.push_back(function3.
Evaluate(rtime));
3247 if (angles[0] <= -1 * pi_c()) {
3248 angles[0] += twopi_c();
3250 else if (angles[0] > pi_c()) {
3251 angles[0] -= twopi_c();
3274 std::vector<double> rtime;
3276 double angle1 = function1.
Evaluate(rtime);
3277 double angle2 = function2.
Evaluate(rtime);
3278 double angle3 = function3.
Evaluate(rtime);
3281 if (angle1 < -1 * pi_c()) {
3282 angle1 += twopi_c();
3284 else if (angle1 > pi_c()) {
3285 angle1 -= twopi_c();
3288 eul2m_c((SpiceDouble) angle3, (SpiceDouble) angle2, (SpiceDouble) angle1,
3290 (SpiceDouble( *)[3]) &
p_CJ[0]);
3311 std::vector<double> cacheAngles(3);
3312 std::vector<double> cacheVelocity(3);
3314 cacheVelocity =
p_av;
3316 std::vector<double> polyAngles(3);
3320 std::vector<double> polyVelocity(3);
3321 polyVelocity =
p_av;
3322 std::vector<double> angles(3);
3324 for (
int index = 0; index < 3; index++) {
3325 angles[index] = cacheAngles[index] + polyAngles[index];
3326 p_av[index] += cacheVelocity[index];
3329 if (angles[0] <= -1 * pi_c()) {
3330 angles[0] += twopi_c();
3332 else if (angles[0] > pi_c()) {
3333 angles[0] -= twopi_c();
3336 if (angles[2] <= -1 * pi_c()) {
3337 angles[2] += twopi_c();
3339 else if (angles[2] > pi_c()) {
3340 angles[2] -= twopi_c();
3343 eul2m_c((SpiceDouble) angles[2], (SpiceDouble) angles[1], (SpiceDouble) angles[0],
3345 (SpiceDouble( *)[3]) &
p_CJ[0]);
3356 double dTime =
p_et / 86400.;
3357 double centTime = dTime / 36525;
3358 double secondsPerJulianCentury = 86400. * 36525.;
3376 for (
int ia = 0; ia < numNutPrec; ia++) {
3379 costheta = cos(theta.
radians());
3380 sintheta = sin(theta.
radians());
3392 if (ra.
radians() < -1 * pi_c()) {
3395 else if (ra.
radians() > pi_c()) {
3399 if (pm.radians() < -1 * pi_c()) {
3402 else if (pm.radians() > pi_c()) {
3408 SpiceDouble delta =
HALFPI - dec.radians();
3409 SpiceDouble w = pm.radians();
3410 SpiceDouble dphi = dra.radians();
3411 SpiceDouble ddelta = -ddec.
radians();
3412 SpiceDouble dw = dpm.
radians();
3415 SpiceDouble angsDangs[6];
3416 SpiceDouble BJs[6][6];
3417 vpack_c(w, delta, phi, angsDangs);
3418 vpack_c(dw, ddelta, dphi, &angsDangs[3]);
3422 xf2rav_c(BJs, (SpiceDouble( *)[3]) &
p_CJ[0], (SpiceDouble *) &
p_av[0]);
Table Cache(const QString &tableName)
Return a table with J2000 to reference rotations.
int Records() const
Returns the number of records.
Isis specific code for binary pck.
Provide operations for quaternion arithmetic.
void SetOverrideBaseTime(double baseTime, double timeScale)
Set an override base time to be used with observations on scanners to allow all images in an observat...
void MinimizeCache(DownsizeStatus status)
Set the downsize status to minimize cache.
std::vector< double > EvaluatePolyFunction()
Evaluate the polynomial fit function for the three pointing angles for the current ephemeris time...
double DPckPolynomial(PartialType partialVar, const int coeffIndex)
Evaluate the derivative of the fit polynomial defined by the given coefficients with respect to the c...
std::vector< double > p_cacheTime
iTime for corresponding rotation
std::vector< double > p_CJ
Rotation matrix from J2000 to first constant rotation.
void SetCoefficients(const std::vector< double > &coefs)
Set the coefficients for the equation.
std::vector< double > Matrix()
Return the full rotation TJ as a matrix.
std::vector< Angle > m_pm
Coefficients of a quadratic polynomial fitting pole pm.
void SetPolynomialDegree(int degree)
Set the degree of the polynomials to be fit to the three camera angles for the time period covered by...
std::vector< double > m_decNutPrec
Coefficients of pole decliniation nut/prec terms.
int p_axis3
Axis of rotation for angle 3 of rotation.
Utility class for creating and using cartesean line equations.
void GetPolynomial(std::vector< double > &abcAng1, std::vector< double > &abcAng2, std::vector< double > &abcAng3)
Return the coefficients of a polynomial fit to each of the three camera angles for the time period co...
void loadPCFromTable(const PvlObject &Label)
Initialize planetary orientation constants from an cube body rotation label.
int p_targetCode
For computing Nadir rotation only.
void SetAxes(int axis1, int axis2, int axis3)
Set the axes of rotation for decomposition of a rotation matrix into 3 angles.
bool m_tOrientationAvailable
Target orientation constants are available.
double radians() const
Convert an angle to a double.
double Intercept()
Compute the intercept of the line.
std::vector< double > m_raNutPrec
Coefficients of pole right ascension nut/prec terms.
int p_degree
Degree of fit polynomial for angles.
void LoadCache(double startTime, double endTime, int size)
Cache J2000 rotation quaternion over a time range.
void setEphemerisTimePolyFunction()
When setting the ephemeris time, updates the rotation according to a polynomial that defines the thre...
Nth degree Polynomial with one variable.
int p_axis1
Axis of rotation for angle 1 of rotation.
void SetConstantMatrix(std::vector< double > constantMatrix)
Set the constant 3x3 rotation TC matrix from a vector of length 9.
int toInt(const QString &string)
Global function to convert from a string to an integer.
const double HALFPI
The mathematical constant PI/2.
void usePckPolynomial()
Set the coefficients of a polynomial fit to each of the three planet angles for the time period cover...
bool p_hasAngularVelocity
Flag indicating whether the rotation includes angular velocity.
void SetEphemerisTime(double et)
Return the J2000 to reference frame quaternion at given time.
std::vector< double > p_TC
Rotation matrix from first constant rotation (after all time-based rotations in frame chain from J200...
std::vector< Angle > m_sysNutPrec0
Constants of planetary system nut/prec periods.
std::vector< double > AngularVelocity()
Accessor method to get the angular velocity.
DownsizeStatus p_minimizeCache
Status of downsizing the cache (set to No to ignore)
void LoadTimeCache()
Load the time cache.
int Frame()
Accessor method that returns the frame code.
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
void getPckPolynomial(std::vector< Angle > &raCoeff, std::vector< Angle > &decCoeff, std::vector< Angle > &pmCoeff)
Return the coefficients of a polynomial fit to each of the three planet angles.
double toDouble(const QString &string)
Global function to convert from a string to a double.
This error is for when a programmer made an API call that was illegal.
A type of error that occurred when performing an actual I/O operation.
std::vector< double > GetCenterAngles()
Return the camera angles at the center time of the observation.
std::vector< double > TimeBasedRotation()
Return time-based 3x3 rotation CJ matrix as a quaternion.
void setPckPolynomial(const std::vector< Angle > &raCoeff, const std::vector< Angle > &decCoeff, const std::vector< Angle > &pmCoeff)
Set the coefficients of a polynomial fit to each of the three planet angles for the time period cover...
double WrapAngle(double compareAngle, double angle)
Wrap the input angle to keep it within 2pi radians of the angle to compare.
std::vector< double > & TimeBasedMatrix()
Return time-based 3x3 rotation CJ matrix as a vector of length 9.
std::vector< Angle > poleRaCoefs()
Return the coefficients used to calculate the target body pole ra.
SpiceRotation(int frameCode)
Construct an empty SpiceRotation class using a valid Naif frame code to set up for getting rotation f...
bool hasKeyword(const QString &kname, FindOptions opts) const
See if a keyword is in the current PvlObject, or deeper inside other PvlObjects and Pvlgroups within ...
Isis specific code for unknown frame type.
int p_axis2
Axis of rotation for angle 2 of rotation.
std::vector< double > Extrapolate(double timeEt)
Extrapolate pointing for a given time assuming a constant angular velocity.
double p_fullCacheStartTime
Initial requested starting time of cache.
PCK frame not referenced to J2000.
std::vector< double > p_av
Angular velocity for rotation at time p_et.
FrameType
Enumeration for the frame type of the rotation.
void SetFrame(int frameCode)
Change the frame to the given frame code.
void loadPCFromSpice(int CenterBodyCode)
Initialize planetary orientation constants from Spice PCK.
double p_overrideTimeScale
Value set by caller to override computed time scale.
DownsizeStatus
Status of downsizing the cache.
int size() const
Returns the number of values stored in this keyword.
bool p_noOverride
Flag to compute base time;.
double GetBaseTime()
Accessor method to get the rotation base time.
std::vector< double > poleDecNutPrecCoefs()
Return the coefficients used to calculate the target body pole dec nut/prec coefficients.
bool p_degreeApplied
Flag indicating whether or not a polynomial of degree p_degree has been created and used to fill the ...
void checkForBinaryPck()
Check loaded pck to see if any are binary and set frame type to indicate binary pck.
Degrees are generally considered more human readable, 0-360 is one circle, however most math does not...
bool IsCached() const
Checks if the cache is empty.
void CacheLabel(Table &table)
Add labels to a SpiceRotation table.
std::vector< double > Angles(int axis3, int axis2, int axis1)
Return the camera angles (right ascension, declination, and twist) for the time-based matrix CJ...
std::vector< double > ReferenceVector(const std::vector< double > &jVec)
Given a direction vector in J2000, return a reference frame direction.
double p_baseTime
Base time used in fit equations.
int p_axisP
The axis defined by the spacecraft vector for defining a nadir rotation.
bool p_matrixSet
Flag indicating p_TJ has been set.
void SetTimeBias(double timeBias)
Apply a time bias when invoking SetEphemerisTime method.
PvlKeyword & findKeyword(const QString &kname, FindOptions opts)
Finds a keyword in the current PvlObject, or deeper inside other PvlObjects and Pvlgroups within this...
Source p_source
The source of the rotation data.
std::vector< double > GetFullCacheTime()
Return full listing (cache) of original time coverage requested.
double p_et
Current ephemeris time.
std::vector< int > TimeFrameChain()
Accessor method to get the frame chain for the rotation (begins in J2000).
#define _FILEINFO_
Macro for the filename and line number.
With respect to Twist or Prime Meridian Rotation.
double p_overrideBaseTime
Value set by caller to override computed base time.
See Naif Frames.req document for.
void SetTimeBasedMatrix(std::vector< double > timeBasedMatrix)
Set the time-based 3x3 rotation CJ matrix from a vector of length 9.
A type of error that could only have occurred due to a mistake on the user's part (e...
A single keyword-value pair.
std::vector< std::vector< double > > p_cache
Cached rotations, stored as rotation matrix from J2000 to 1st constant frame (CJ) or coefficients of ...
void SetFullCacheParameters(double startTime, double endTime, int cacheSize)
Set the full cache time parameters.
Do not downsize the cache.
void setEphemerisTimePolyFunctionOverSpice()
When setting the ephemeris time, updates the rotation state based on a polynomial fit over spice kern...
Kernels plus nth degree polynomial.
std::vector< Angle > sysNutPrecConstants()
Return the constants used to calculate the target body system nut/prec angles.
Source
The rotation can come from one of 3 places for an Isis cube.
std::vector< std::vector< double > > p_cacheAv
Cached angular velocities for corresponding rotactions in p_cache.
FrameType getFrameType()
Accessor method to get the rotation frame type.
std::vector< Angle > pmCoefs()
Return the coefficients used to calculate the target body prime meridian.
double EphemerisTime() const
Accessor method to get current ephemeris time.
void FrameTrace(double et)
Compute frame trace chain from target frame to J2000.
Obtain SPICE rotation information for a body.
Generic least square fitting class.
Quaternion p_quaternion
Quaternion for J2000 to reference rotation at et.
With respect to Declination.
The values in the field are 8 byte doubles.
PartialType
This enumeration indicates whether the partial derivative is taken with respect to Right Ascension...
double p_timeBias
iTime bias when reading kernels
std::vector< int > ConstantFrameChain()
Accessor method to get the frame chain for the constant part of the rotation (ends in target) ...
std::vector< double > pmNutPrecCoefs()
Return the coefficients used to calculate the target body pm nut/prec coefficients.
const double DEG2RAD
Multiplier for converting from degrees to radians.
void ComputeBaseTime()
Compute the base time using cached times.
void setEphemerisTimeNadir()
When setting the ephemeris time, uses spacecraft nadir source to update the rotation state...
int p_fullCacheSize
Initial requested cache size.
void InitConstantRotation(double et)
Initialize the constant rotation.
double DPolynomial(const int coeffIndex)
Evaluate the derivative of the fit polynomial defined by the given coefficients with respect to the c...
void ReloadCache()
Cache J2000 rotation over existing cached time range using polynomials.
void ComputeAv()
Compute the angular velocity from the time-based functions fit to the pointing angles This method com...
Defines an angle and provides unit conversions.
void AddKnown(const std::vector< double > &input, double expected, double weight=1.0)
Invoke this method for each set of knowns.
double Coefficient(int i) const
Returns the ith coefficient.
Directly from the kernels.
void DCJdt(std::vector< double > &dRJ)
Compute the derivative of the 3x3 rotation matrix CJ with respect to time.
void SetSource(Source source)
Resets the source of the rotation to the given value.
std::vector< double > m_pmNutPrec
Coefficients of prime meridian nut/prec terms.
std::vector< double > ToMatrix()
Converts quaternion to 3x3 rotational matrix.
std::vector< double > toJ2000Partial(const std::vector< double > &lookT, PartialType partialVar, int coeffIndex)
Given a direction vector in the reference frame, compute the derivative with respect to one of the co...
std::vector< double > StateTJ()
State matrix (6x6) for rotating state vectors from J2000 to target frame.
void setFrameType()
Set the frame type (m_frameType).
Class for storing Table blobs information.
std::vector< double > J2000Vector(const std::vector< double > &rVec)
Given a direction vector in the reference frame, return a J2000 direction.
std::vector< Angle > m_sysNutPrec1
Linear terms of planetary system nut/prec periods.
std::vector< Angle > sysNutPrecCoefs()
Return the coefficients used to calculate the target body system nut/prec angles. ...
double Evaluate(const std::vector< double > &vars)
Compute the equation using the input variables.
static void CheckErrors(bool resetNaif=true)
This method looks for any naif errors that might have occurred.
FrameType m_frameType
The type of rotation frame.
Adds specific functionality to C++ strings.
Namespace for ISIS/Bullet specific routines.
std::vector< double > p_coefficients[3]
Coefficients defining functions fit to 3 pointing angles.
std::vector< double > GetQuaternion() const
Return the quaternion as a vector.
int Fields() const
Returns the number of fields that are currently in the record.
From nth degree polynomial.
std::vector< double > & ConstantMatrix()
Return the constant 3x3 rotation TC matrix as a vector of length 9.
Obtain SPICE information for a spacecraft.
Class for storing an Isis::Table's field information.
PvlObject & Label()
Accessor method that returns a PvlObject containing the Blob label.
Radians are generally used in mathematical equations, 0-2*PI is one circle, however these are more di...
void setEphemerisTimeSpice()
When setting the ephemeris time, updates the rotation state based on data read directly from NAIF ker...
int p_axisV
The axis defined by the velocity vector for defining a nadir rotation.
std::vector< Angle > poleDecCoefs()
Return the coefficients used to calculate the target body pole dec.
double GetTimeScale()
Accessor method to get the rotation time scale.
std::vector< double > poleRaNutPrecCoefs()
Return the coefficients used to calculate the target body pole ra nut/prec coefficients.
void setEphemerisTimeMemcache()
Updates rotation state based on the rotation cache.
double p_fullCacheEndTime
Initial requested ending time of cache.
void setEphemerisTimePckPolyFunction()
When setting the ephemeris time, updates the rotation state based on the PcK polynomial.
void SetPolynomial(const Source type=PolyFunction)
Set the coefficients of a polynomial fit to each of the three camera angles for the time period cover...
Contains Pvl Groups and Pvl Objects.
std::vector< int > p_constantFrames
Chain of Naif frame codes in constant rotation TC.
double Slope()
Compute the slope of the line.
double p_timeScale
Time scale used in fit equations.
int Solve(Isis::LeastSquares::SolveMethod method=SVD)
After all the data has been registered through AddKnown, invoke this method to solve the system of eq...
bool HasAngularVelocity()
Checks whether the rotation has angular velocities.
void SetAngles(std::vector< double > angles, int axis3, int axis2, int axis1)
Set the rotation angles (phi, delta, and w) for the current time to define the time-based matrix CJ...
Table LineCache(const QString &tableName)
Return a table with J2000 to reference rotations.
std::vector< int > p_timeFrames
Chain of Naif frame codes in time-based rotation CJ.
std::vector< double > ConstantRotation()
Return the constant 3x3 rotation TC matrix as a quaternion.
int Coefficients() const
Returns the number of coefficients for the equation.
Quadratic polynomial function with linear trignometric terms.
virtual ~SpiceRotation()
Destructor for SpiceRotation object.
Source GetSource()
Accessor method to get the rotation source.
std::vector< double > ToReferencePartial(std::vector< double > &lookJ, PartialType partialVar, int coeffIndex)
Compute the derivative with respect to one of the coefficients in the angle polynomial fit equation o...
std::vector< Angle > m_raPole
Coefficients of a quadratic polynomial fitting pole ra.
With respect to Right Ascension.
std::vector< Angle > m_decPole
Coefficients of a quadratic polynomial fitting pole dec.