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);
750 Table table(tableName, record);
752 for (
int i = 0; i < (int)
p_cache.size(); i++) {
788 Table table(tableName, record);
790 for (
int cindex = 0; cindex <
p_degree + 1; cindex++) {
801 record[2] = (double) p_degree;
809 QString msg =
"To create table source of data must be either Memcache or PolyFunction";
824 SpiceInt centerBodyCode = (SpiceInt) centerBody;
840 QString naifKeyword =
"BODY" +
toString(centerBodyCode) +
"_CONSTANTS_REF_FRAME" ;
841 SpiceInt numExpected;
842 SpiceInt numReturned;
844 SpiceDouble relativeFrameCode = 0;
846 dtpool_c(naifKeyword.toLatin1().data(), &found, &numExpected, &naifType);
850 SpiceDouble relativeFrameCode;
851 bodvcd_c(centerBodyCode,
"CONSTANTS_REF_FRAME", 1,
852 &numReturned, &relativeFrameCode);
855 if (!found || relativeFrameCode == 1) {
859 naifKeyword =
"BODY" +
toString(centerBodyCode) +
"_POLE_RA" ;
860 dtpool_c(naifKeyword.toLatin1().data(), &found, &numExpected, &naifType);
863 std::vector<SpiceDouble> d(3);
866 m_pm.resize(numExpected);
868 bodvcd_c(centerBodyCode,
"POLE_RA", numExpected, &numReturned, &d[0]);
873 bodvcd_c(centerBodyCode,
"POLE_DEC", numExpected, &numReturned, &d[0]);
878 bodvcd_c(centerBodyCode,
"PM", numExpected, &numReturned, &d[0]);
879 m_pm[0].setDegrees(d[0]);
880 m_pm[1].setDegrees(d[1]);
881 m_pm[2].setDegrees(d[2]);
888 naifKeyword =
"BODY" +
toString(centerBodyCode) +
"_NUT_PREC_RA" ;
889 dtpool_c(naifKeyword.toLatin1().data(), &found, &numReturned, &naifType);
893 SpiceInt bcCode = centerBodyCode/100;
894 naifKeyword =
"BODY" +
toString(bcCode) +
"_NUT_PREC_ANGLES" ;
895 dtpool_c(naifKeyword.toLatin1().data(), &found, &numExpected, &naifType);
896 std::vector<double>npAngles(numExpected, 0.);
897 bodvcd_c(bcCode,
"NUT_PREC_ANGLES", numExpected, &numReturned, &npAngles[0]);
903 std::vector<SpiceDouble> angles(numExpected);
904 bodvcd_c(centerBodyCode,
"NUT_PREC_RA", numExpected, &numReturned, &
m_raNutPrec[0]);
905 bodvcd_c(centerBodyCode,
"NUT_PREC_DEC", numExpected, &numReturned, &
m_decNutPrec[0]);
906 bodvcd_c(centerBodyCode,
"NUT_PREC_PM", numExpected, &numReturned, &
m_pmNutPrec[0]);
911 for (
int i = 0; i < numExpected; i++) {
950 for (
int i = 0; i < labelCoeffs.
size(); i++){
957 for (
int i = 0; i < labelCoeffs.
size(); i++){
963 PvlKeyword labelCoeffs = label[
"PrimeMeridian"];
964 for (
int i = 0; i < labelCoeffs.
size(); i++){
972 PvlKeyword labelCoeffs = label[
"PoleRaNutPrec"];
973 for (
int i = 0; i < labelCoeffs.
size(); i++){
978 PvlKeyword labelCoeffs = label[
"PoleDecNutPrec"];
979 for (
int i = 0; i < labelCoeffs.
size(); i++){
985 for (
int i = 0; i < labelCoeffs.
size(); i++){
990 PvlKeyword labelCoeffs = label[
"SysNutPrec0"];
991 for (
int i = 0; i < labelCoeffs.
size(); i++){
996 PvlKeyword labelCoeffs = label[
"SysNutPrec1"];
997 for (
int i = 0; i < labelCoeffs.
size(); i++){
1034 for (
int i = 0; i < (int)
p_TC.size(); i++) {
1062 for (
int i = 0; i < (int)
m_raPole.size(); i++) {
1068 for (
int i = 0; i < (int)
m_decPole.size(); i++) {
1074 for (
int i = 0; i < (int)
m_pm.size(); i++) {
1081 for (
int i = 0; i < (int)
m_raNutPrec.size(); i++) {
1093 for (
int i = 0; i < (int)
m_pmNutPrec.size(); i++) {
1143 SpiceDouble ang1, ang2, ang3;
1144 m2eul_c((SpiceDouble *) &
p_CJ[0], axis3, axis2, axis1, &ang3, &ang2, &ang1);
1146 std::vector<double> angles;
1147 angles.push_back(ang1);
1148 angles.push_back(ang2);
1149 angles.push_back(ang3);
1168 eul2m_c(angles[2], angles[1], angles[0], axis3, axis2, axis1, (SpiceDouble (*)[3]) &(
p_CJ[0]));
1227 std::vector<double> jVec;
1229 if (rVec.size() == 3) {
1231 mxm_c((SpiceDouble *) &
p_TC[0], (SpiceDouble *) &
p_CJ[0], TJ);
1233 mtxv_c(TJ, (SpiceDouble *) &rVec[0], (SpiceDouble *) &jVec[0]);
1236 else if (rVec.size() == 6) {
1242 std::vector<double> stateTJ(36);
1246 xpose6_c(&stateTJ[0], (SpiceDouble( *) [6]) &stateTJ[0]);
1247 double stateJT[6][6];
1248 invstm_((doublereal *) &stateTJ[0], (doublereal *) stateJT);
1249 xpose6_c(stateJT, stateJT);
1252 mxvg_c(stateJT, (SpiceDouble *) &rVec[0], 6, 6, (SpiceDouble *) &jVec[0]);
1430 std::vector<double> jVec;
1434 int angleIndex = partialVar;
1437 double angle = angles.at(angleIndex);
1440 double dmatrix[3][3];
1441 drotat_(&angle, (integer *) axes + angleIndex, (doublereal *) dmatrix);
1443 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) {
1951 if (coeffIndex > 0 && coeffIndex <=
p_degree) {
1952 derivative = pow(time, coeffIndex);
1954 else if (coeffIndex == 0) {
1958 QString msg =
"Unable to evaluate the derivative of the SPICE rotation fit polynomial for "
1959 "the given coefficient index [" +
toString(coeffIndex) +
"]. "
1960 "Index is negative or exceeds degree of polynomial ["
1983 const int coeffIndex) {
1984 const double p_dayScale = 86400;
1986 const double p_centScale = p_dayScale * 36525;
1989 switch (partialVar) {
1992 time =
p_et / p_centScale;
1995 time =
p_et / p_dayScale;
2001 switch (coeffIndex) {
2007 derivative = pow(time, coeffIndex);
2010 QString msg =
"Unable to evaluate the derivative of the target body rotation fit polynomial "
2011 "for the given coefficient index [" +
toString(coeffIndex) +
"]. "
2012 "Index is negative or exceeds degree of polynomial ["
2020 derivative = -derivative;
2050 int angleIndex = partialVar;
2053 double angle = angles.at(angleIndex);
2055 double dmatrix[3][3];
2056 drotat_(&angle, (integer *) axes + angleIndex, (doublereal *) dmatrix);
2058 xpose_c(dmatrix, dmatrix);
2071 QString msg =
"Only CK and PCK partials can be calculated";
2076 for (
int row = 0; row < 3; row++) {
2077 for (
int col = 0; col < 3; col++) {
2078 dmatrix[row][col] *= dpoly;
2084 switch (angleIndex) {
2086 rotmat_c(dmatrix, angles[1], axes[1], dCJ);
2087 rotmat_c(dCJ, angles[2], axes[2], dCJ);
2090 rotate_c(angles[0], axes[0], dCJ);
2091 mxm_c(dmatrix, dCJ, dCJ);
2092 rotmat_c(dCJ, angles[2], axes[2], dCJ);
2095 rotate_c(angles[0], axes[0], dCJ);
2096 rotmat_c(dCJ, angles[1], axes[1], dCJ);
2097 mxm_c(dmatrix, dCJ, dCJ);
2103 mxm_c((SpiceDouble *) &
p_TC[0], dCJ[0], dTJ);
2107 std::vector<double> lookdT(3);
2109 mxv_c(dTJ, (
const SpiceDouble *) &lookJ[0], (SpiceDouble *) &lookdT[0]);
2126 double diff1 = compareAngle - angle;
2128 if (diff1 < -1 * pi_c()) {
2131 else if (diff1 > pi_c()) {
2171 for (
int icoef =
p_degree + 1; icoef <= degree; icoef++) {
2172 coefAngle1.push_back(0.);
2173 coefAngle2.push_back(0.);
2174 coefAngle3.push_back(0.);
2181 std::vector<double> coefAngle1(degree + 1),
2182 coefAngle2(degree + 1),
2183 coefAngle3(degree + 1);
2185 for (
int icoef = 0; icoef <= degree; icoef++) {
2260 if (axis1 < 1 || axis2 < 1 || axis3 < 1 || axis1 > 3 || axis2 > 3 || axis3 > 3) {
2261 QString msg =
"A rotation axis is outside the valid range of 1 to 3";
2288 double currentTime = observStart;
2289 bool timeLoaded =
false;
2294 ktotal_c(
"ck", (SpiceInt *) &count);
2304 "Full cache size does NOT match cache size in LoadTimeCache -- should never happen";
2315 SpiceDouble CJ[9] = {
p_cache[r][0],
p_cache[r][1], p_cache[r][2],
2316 p_cache[r][3], p_cache[r][4], p_cache[r][5],
2317 p_cache[r][6], p_cache[r][7], p_cache[r][8]
2319 m2q_c(CJ, quats[r]);
2321 vequ_c((SpiceDouble *) &
p_cacheAv[r][0], avvs[r]);
2325 double cubeStarts = timeSclkdp[0];
2326 double radTol = 0.000000017453;
2327 SpiceInt avflag = 1;
2333 ck3sdn(radTol, avflag, (
int *) &sizOut, timeSclkdp, (doublereal *) quats,
2334 (SpiceDouble *) avvs, nints, &cubeStarts, dparr, (
int *) intarr);
2340 std::vector<double> av;
2343 for (
int r = 0; r < sizOut; r++) {
2348 std::vector<double> CJ(9);
2349 q2m_c(quats[r], (SpiceDouble( *)[3]) &CJ[0]);
2351 vequ_c(avvs[r], (SpiceDouble *) &av[0]);
2365 int SOURCESIZ = 128;
2368 SpiceChar file[FILESIZ];
2369 SpiceChar filtyp[TYPESIZ];
2370 SpiceChar source[SOURCESIZ];
2373 bool observationSpansToNextSegment =
false;
2378 kdata_c(0,
"ck", FILESIZ, TYPESIZ, SOURCESIZ, file, filtyp, source, &handle, &found);
2384 observationSpansToNextSegment =
false;
2395 dafus_c(sum, (SpiceInt) 2, (SpiceInt) 6, dc, ic);
2398 if (ic[2] == 5)
break;
2401 if (ic[0] == spCode && ic[2] == 3) {
2402 sct2e_c((
int) spCode / 1000, dc[0], &segStartEt);
2403 sct2e_c((
int) spCode / 1000, dc[1], &segStopEt);
2408 if (currentTime >= segStartEt && currentTime <= segStopEt) {
2412 if (observationSpansToNextSegment && currentTime > segStartEt) {
2413 QString msg =
"Observation crosses segment boundary--unable to interpolate pointing";
2416 if (observEnd > segStopEt) {
2417 observationSpansToNextSegment =
true;
2421 int dovelocity = ic[3];
2424 dafgda_c(handle, end - 1, end, val);
2426 int ninstances = (int) val[1];
2427 int numvel = dovelocity * 3;
2428 int quatnoff = ic[4] + (4 + numvel) * ninstances - 1;
2430 int sclkdp1off = quatnoff + 1;
2431 int sclkdpnoff = sclkdp1off + ninstances - 1;
2434 int sclkSpCode = spCode / 1000;
2437 std::vector<double> sclkdp(ninstances);
2438 dafgda_c(handle, sclkdp1off, sclkdpnoff, (SpiceDouble *) &sclkdp[0]);
2441 sct2e_c(sclkSpCode, sclkdp[0], &et);
2443 while (instance < (ninstances - 1) && et < currentTime) {
2445 sct2e_c(sclkSpCode, sclkdp[instance], &et);
2448 if (instance > 0) instance--;
2449 sct2e_c(sclkSpCode, sclkdp[instance], &et);
2451 while (instance < (ninstances - 1) && et < observEnd) {
2454 sct2e_c(sclkSpCode, sclkdp[instance], &et);
2458 if (!observationSpansToNextSegment) {
2464 currentTime = segStopEt;
2473 QString msg =
"No camera kernels loaded...Unable to determine time cache to downsize";
2480 double cacheSlope = 0.0;
2502 QString msg =
"Time cache not available -- rerun spiceinit";
2506 std::vector<double> fullCacheTime;
2507 double cacheSlope = 0.0;
2515 return fullCacheTime;
2541 std::vector<int> frameCodes;
2542 std::vector<int> frameTypes;
2545 while (frameCodes[frameCodes.size()-1] != J2000Code) {
2546 frmidx = frameCodes.size() - 1;
2554 frinfo_c((SpiceInt) frameCodes[frmidx],
2555 (SpiceInt *) ¢er,
2557 (SpiceInt *) &typid, &found);
2562 frameTypes.push_back(0);
2566 QString msg =
"The frame" +
toString((
int) frameCodes[frmidx]) +
" is not supported by Naif";
2570 double matrix[3][3];
2574 nextFrame = J2000Code;
2576 else if (type == CK) {
2577 ckfrot_((SpiceInt *) &typid, &et, (
double *) matrix, &nextFrame, (logical *) &found);
2582 frameTypes.push_back(0);
2586 QString msg =
"The ck rotation from frame " +
toString(frameCodes[frmidx]) +
" can not "
2587 +
"be found due to no pointing available at requested time or a problem with the "
2592 else if (type == TK) {
2593 tkfram_((SpiceInt *) &typid, (
double *) matrix, &nextFrame, (logical *) &found);
2595 QString msg =
"The tk rotation from frame " +
toString(frameCodes[frmidx]) +
2596 " can not be found";
2600 else if (type == DYN) {
2607 zzdynrot_((SpiceInt *) &typid, (SpiceInt *) ¢er, &et, (
double *) matrix, &nextFrame);
2611 QString msg =
"The frame " +
toString(frameCodes[frmidx]) +
2612 " has a type " +
toString(type) +
" not supported by your version of Naif Spicelib."
2613 +
"You need to update.";
2617 frameCodes.push_back(nextFrame);
2618 frameTypes.push_back(type);
2629 while (frameTypes[nConstants] == TK && nConstants < (
int) frameTypes.size()) nConstants++;
2632 for (
int i = 0; i <= nConstants; i++) {
2637 for (
int i = nConstants; i < (int) frameCodes.size(); i++) {
2657 std::vector<double> TJ;
2659 mxm_c((SpiceDouble *) &
p_TC[0], (SpiceDouble *) &
p_CJ[0], (SpiceDouble( *) [3]) &TJ[0]);
2672 std::vector<double> q;
2674 m2q_c((SpiceDouble( *)[3]) &
p_TC[0], &q[0]);
2696 p_TC = constantMatrix;
2707 std::vector<double> q;
2709 m2q_c((SpiceDouble( *)[3]) &
p_CJ[0], &q[0]);
2731 p_CJ = timeBasedMatrix;
2747 refchg_((SpiceInt *) &fromFrame, (SpiceInt *) &targetFrame, &et, (doublereal *) &
p_TC[0]);
2749 xpose_c((SpiceDouble( *)[3]) &
p_TC[0], (SpiceDouble( *)[3]) &
p_TC[0]);
2777 QString msg =
"The SpiceRotation pointing angles must be fit to polynomials in order to ";
2778 msg +=
"compute angular velocity.";
2782 QString msg =
"Planetary angular velocity must be fit computed with PCK polynomials ";
2785 std::vector<double> dCJdt;
2803 mtxm_c((SpiceDouble( *)[3]) &dCJdt[0], (SpiceDouble( *)[3]) &
p_CJ[0], omega);
2804 p_av[0] = omega[2][1];
2805 p_av[1] = omega[0][2];
2806 p_av[2] = omega[1][0];
2824 double dmatrix[3][3];
2826 double wmatrix[3][3];
2829 for (
int angleIndex = 0; angleIndex < 3; angleIndex++) {
2830 drotat_(&(angles[angleIndex]), (integer *) axes + angleIndex, (doublereal *) dmatrix);
2832 xpose_c(dmatrix, dmatrix);
2844 for (
int row = 0; row < 3; row++) {
2845 for (
int col = 0; col < 3; col++) {
2846 dmatrix[row][col] *= dangle;
2850 switch (angleIndex) {
2852 rotmat_c(dmatrix, angles[1], axes[1], dmatrix);
2853 rotmat_c(dmatrix, angles[2], axes[2], dmatrix);
2856 rotate_c(angles[0], axes[0], wmatrix);
2857 mxm_c(dmatrix, wmatrix, dmatrix);
2858 rotmat_c(dmatrix, angles[2], axes[2], dmatrix);
2861 rotate_c(angles[0], axes[0], wmatrix);
2862 rotmat_c(wmatrix, angles[1], axes[1], wmatrix);
2863 mxm_c(dmatrix, wmatrix, dmatrix);
2867 for (
int index = 0; index < 9; index++) {
2870 dCJ[index] += dmatrix[i][j];
2884 std::vector<double> stateTJ(36);
2887 double stateCJ[6][6];
2888 rav2xf_c(&
p_CJ[0], &
p_av[0], stateCJ);
2894 for (
int row = 3; row < 6; row++) {
2898 for (
int col = 0; col < 3; col++) {
2901 stateTJ[irow*6 + col] =
p_TC[vpos] * stateCJ[0][col] +
p_TC[vpos+1] * stateCJ[1][col]
2902 +
p_TC[vpos+2] * stateCJ[2][col];
2904 stateTJ[row*6 + col] =
p_TC[vpos] * stateCJ[3][col] +
p_TC[vpos+1] * stateCJ[4][col]
2905 +
p_TC[vpos+2] * stateCJ[5][col];
2907 stateTJ[irow*6 + jcol] = 0;
2909 stateTJ[row*6 +jcol] = stateTJ[irow*6 + col];
2931 double diffTime = timeEt -
p_et;
2932 std::vector<double> CJ(9, 0.0);
2937 axisar_c((SpiceDouble *) &
p_av[0], diffTime*vnorm_c((SpiceDouble *) &
p_av[0]), dmat);
2940 mxm_c(dmat, (SpiceDouble *) &
p_CJ[0], (SpiceDouble( *)[3]) &CJ[0]);
2971 ktotal_c(
"PCK", &count);
2976 int SOURCESIZ = 128;
2977 SpiceChar file[FILESIZ];
2978 SpiceChar filetype[TYPESIZ];
2979 SpiceChar source[SOURCESIZ];
2986 for (SpiceInt knum = 0; knum < count; knum++){
2987 kdata_c(knum,
"PCK", FILESIZ, TYPESIZ, SOURCESIZ, file, filetype, source, &handle, &found);
2990 if (strstr(file,
"bpc") != NULL) {
3007 SpiceInt centerBodyCode;
3008 SpiceInt frameClass;
3010 frinfo_c(frameCode, ¢erBodyCode, &frameClass, &classId, &found);
3013 if (frameClass == 2 || centerBodyCode > 0) {
3019 for (std::vector<int>::size_type idx = 1; idx <
p_constantFrames.size(); idx++) {
3021 frinfo_c(frameCode, ¢erBodyCode, &frameClass, &classId, &found);
3026 switch (frameClass) {
3073 std::vector<double>::iterator pos;
3086 if (cacheIndex < 0) cacheIndex = 0;
3093 std::vector<double> CJ2(
p_cache[cacheIndex+1]);
3094 std::vector<double> CJ1(
p_cache[cacheIndex]);
3095 SpiceDouble J2J1[3][3];
3096 mtxm_c((SpiceDouble( *)[3]) &CJ2[0], (SpiceDouble( *)[3]) &CJ1[0], J2J1);
3097 SpiceDouble axis[3];
3099 raxisa_c(J2J1, axis, &angle);
3100 SpiceDouble delta[3][3];
3101 axisar_c(axis, angle * (SpiceDouble)mult, delta);
3102 mxmt_c((SpiceDouble *) &CJ1[0], delta, (SpiceDouble( *) [3]) &
p_CJ[0]);
3105 double v1[3], v2[3];
3106 vequ_c((SpiceDouble *) &
p_cacheAv[cacheIndex][0], v1);
3107 vequ_c((SpiceDouble *) &
p_cacheAv[cacheIndex+1][0], v2);
3108 vscl_c((1. - mult), v1, v1);
3109 vscl_c(mult, v2, v2);
3110 vadd_c(v1, v2, (SpiceDouble *) &
p_av[0]);
3132 SpiceDouble stateJ[6];
3135 spkez_c((SpiceInt) spkCode,
p_et,
"J2000",
"LT+S",
3139 SpiceDouble sJ[3], svJ[3];
3140 vpack_c(-1 * stateJ[0], -1 * stateJ[1], -1 * stateJ[2], sJ);
3141 vpack_c(stateJ[3], stateJ[4], stateJ[5], svJ);
3146 (SpiceDouble( *)[3]) &
p_CJ[0]);
3163 SpiceInt j2000 = J2000Code;
3172 double stateCJ[6][6];
3173 frmchg_((integer *) &j2000, (integer *) &toFrame, &time, (doublereal *) stateCJ);
3178 SpiceBoolean ckfailure = failed_c();
3182 xpose6_c(stateCJ, stateCJ);
3183 xf2rav_c(stateCJ, (SpiceDouble( *)[3]) &
p_CJ[0], (SpiceDouble *) &
p_av[0]);
3187 refchg_((integer *) &j2000, (integer *) &toFrame, &time, (SpiceDouble *) &
p_CJ[0]);
3191 getmsg_c(
"SHORT",
sizeof(naifstr), naifstr);
3194 if (eqstr_c(naifstr,
"SPICE(UNKNOWNFRAME)")) {
3196 "reference frame code. Has the mission frames kernel been loaded?";
3200 Isis::IString msg =
"No pointing available at requested time [" +
3208 xpose_c((SpiceDouble( *)[3]) &
p_CJ[0], (SpiceDouble( *)[3]) &
p_CJ[0]);
3230 std::vector<double> rtime;
3232 std::vector<double> angles;
3233 angles.push_back(function1.
Evaluate(rtime));
3234 angles.push_back(function2.
Evaluate(rtime));
3235 angles.push_back(function3.
Evaluate(rtime));
3238 if (angles[0] <= -1 * pi_c()) {
3239 angles[0] += twopi_c();
3241 else if (angles[0] > pi_c()) {
3242 angles[0] -= twopi_c();
3265 std::vector<double> rtime;
3267 double angle1 = function1.
Evaluate(rtime);
3268 double angle2 = function2.
Evaluate(rtime);
3269 double angle3 = function3.
Evaluate(rtime);
3272 if (angle1 < -1 * pi_c()) {
3273 angle1 += twopi_c();
3275 else if (angle1 > pi_c()) {
3276 angle1 -= twopi_c();
3279 eul2m_c((SpiceDouble) angle3, (SpiceDouble) angle2, (SpiceDouble) angle1,
3281 (SpiceDouble( *)[3]) &
p_CJ[0]);
3302 std::vector<double> cacheAngles(3);
3303 std::vector<double> cacheVelocity(3);
3305 cacheVelocity =
p_av;
3307 std::vector<double> polyAngles(3);
3311 std::vector<double> polyVelocity(3);
3312 polyVelocity =
p_av;
3313 std::vector<double> angles(3);
3315 for (
int index = 0; index < 3; index++) {
3316 angles[index] = cacheAngles[index] + polyAngles[index];
3317 p_av[index] += cacheVelocity[index];
3320 if (angles[0] <= -1 * pi_c()) {
3321 angles[0] += twopi_c();
3323 else if (angles[0] > pi_c()) {
3324 angles[0] -= twopi_c();
3327 if (angles[2] <= -1 * pi_c()) {
3328 angles[2] += twopi_c();
3330 else if (angles[2] > pi_c()) {
3331 angles[2] -= twopi_c();
3334 eul2m_c((SpiceDouble) angles[2], (SpiceDouble) angles[1], (SpiceDouble) angles[0],
3336 (SpiceDouble( *)[3]) &
p_CJ[0]);
3347 double dTime =
p_et / 86400.;
3348 double centTime = dTime / 36525;
3349 double secondsPerJulianCentury = 86400. * 36525.;
3367 for (
int ia = 0; ia < numNutPrec; ia++) {
3370 costheta = cos(theta.
radians());
3371 sintheta = sin(theta.
radians());
3383 if (ra.
radians() < -1 * pi_c()) {
3386 else if (ra.
radians() > pi_c()) {
3390 if (pm.radians() < -1 * pi_c()) {
3393 else if (pm.radians() > pi_c()) {
3399 SpiceDouble delta =
HALFPI - dec.radians();
3400 SpiceDouble w = pm.radians();
3401 SpiceDouble dphi = dra.radians();
3402 SpiceDouble ddelta = -ddec.
radians();
3403 SpiceDouble dw = dpm.
radians();
3406 SpiceDouble angsDangs[6];
3407 SpiceDouble BJs[6][6];
3408 vpack_c(w, delta, phi, angsDangs);
3409 vpack_c(dw, ddelta, dphi, &angsDangs[3]);
3413 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.
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...
int Records() const
Returns the number of records.
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...
int size() const
Returns the number of values stored in this keyword.
int Coefficients() const
Returns the number of coefficients for the equation.
std::vector< double > p_cacheTime
iTime for corresponding rotation
std::vector< double > p_CJ
Rotation matrix from J2000 to first constant rotation.
std::vector< double > GetQuaternion() const
Return the quaternion as a vector.
double EphemerisTime() const
Accessor method to get current ephemeris time.
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...
double radians() const
Convert an angle to a double.
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 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.
void usePckPolynomial()
Set the coefficients of a polynomial fit to each of the three planet angles for the time period cover...
const double DEG2RAD(0.017453292519943295769237)
Multiplier for converting from degrees to radians.
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.
bool IsCached() const
Checks if the cache is empty.
const double HALFPI(1.57079632679489661923)
The mathematical constant PI/2.
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...
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.
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 ...
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.
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...
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.
int Fields() const
Returns the number of fields that are currently in the record.
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.
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
double Coefficient(int i) const
Returns the ith coefficient.
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.
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.
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.
std::vector< double > p_coefficients[3]
Coefficients defining functions fit to 3 pointing angles.
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.
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.