7#include "SpiceRotation.h"
22#include "BasisFunction.h"
23#include "IException.h"
25#include "LeastSquares.h"
26#include "LineEquation.h"
27#include "NaifStatus.h"
28#include "PolynomialUnivariate.h"
29#include "Quaternion.h"
31#include "TableField.h"
33using json = nlohmann::json;
37extern int refchg_(integer *frame1, integer *frame2, doublereal *et,
39extern int frmchg_(integer *frame1, integer *frame2, doublereal *et,
41extern int invstm_(doublereal *mat, doublereal *invmat);
45extern int ck3sdn(
double sdntol,
bool avflag,
int *nrec,
46 double *sclkdp,
double *quats,
double *avvs,
47 int nints,
double *starts,
double *dparr,
119 m_orientation = NULL;
122 QString key =
"INS" +
toString(frameCode) +
"_TRANSX";
123 SpiceDouble transX[2];
127 gdpool_c(key.toLatin1().data(), 1, 2, &number, transX, &found);
130 QString msg =
"Cannot find [" + key +
"] in text kernels";
135 if (transX[0] < transX[1])
p_axisV = 1;
170 for (
int i = 0; i < 3; i++)
187 if (rotToCopy.m_orientation) {
188 m_orientation =
new ale::Orientations;
189 *m_orientation = *rotToCopy.m_orientation;
192 m_orientation = NULL;
202 delete m_orientation;
203 m_orientation = NULL;
263 if (
p_et == et)
return;
317 return (m_orientation != NULL);
353 QString msg =
"Argument cacheSize must not be less or equal to zero";
357 if (startTime > endTime) {
358 QString msg =
"Argument startTime must be less than or equal to endTime";
362 if ((startTime != endTime) && (size == 1)) {
363 QString msg =
"Cache size must be more than 1 if startTime and endTime differ";
369 QString msg =
"A SpiceRotation cache has already been created";
378 if (m_orientation != NULL) {
379 delete m_orientation;
380 m_orientation = NULL;
395 std::vector<ale::Rotation> rotationCache;
396 std::vector< std::vector<double> > cache;
397 std::vector<ale::Vec3d> avCache;
398 for (
int i = 0; i < cacheSize; i++) {
401 rotationCache.push_back(ale::Rotation(
p_CJ));
402 cache.push_back(
p_CJ);
405 avCache.push_back(ale::Vec3d(
p_av));
409 if (
p_TC.size() > 1) {
410 m_orientation =
new ale::Orientations(rotationCache,
p_cacheTime, avCache,
414 m_orientation =
new ale::Orientations(rotationCache,
p_cacheTime, avCache,
466 delete m_orientation;
467 m_orientation = NULL;
474 p_cacheTime = isdRot[
"ephemeris_times"].get<std::vector<double>>();
475 p_timeFrames = isdRot[
"time_dependent_frames"].get<std::vector<int>>();
477 std::vector<ale::Rotation> rotationCache;
478 for (
auto it = isdRot[
"quaternions"].begin(); it != isdRot[
"quaternions"].end(); it++) {
479 std::vector<double> quat = {it->at(0).get<
double>(), it->at(1).get<
double>(), it->at(2).get<
double>(), it->at(3).get<
double>()};
481 std::vector<double> CJ = q.
ToMatrix();
482 rotationCache.push_back(ale::Rotation(CJ));
485 std::vector<ale::Vec3d> avCache;
486 if (isdRot[
"angular_velocities"].size() != 0) {
487 for (
auto it = isdRot[
"angular_velocities"].begin(); it != isdRot[
"angular_velocities"].end(); it++) {
488 std::vector<double> av = {it->at(0).get<
double>(), it->at(1).get<
double>(), it->at(2).get<
double>()};
489 avCache.push_back(ale::Vec3d(av));
494 if (isdRot.contains(
"constant_frames")) {
496 p_TC = isdRot[
"constant_rotation"].get<std::vector<double>>();
497 m_orientation =
new ale::Orientations(rotationCache,
p_cacheTime, avCache,
502 ident_c((SpiceDouble( *)[3]) &
p_TC[0]);
503 m_orientation =
new ale::Orientations(rotationCache,
p_cacheTime, avCache,
546 delete m_orientation;
547 m_orientation = NULL;
553 for (
int i = 0; i < labelTimeFrames.
size(); i++) {
566 for (
int i = 0; i < labelConstantFrames.
size(); i++) {
571 for (
int i = 0; i < labelConstantRotation.
size(); i++) {
577 ident_c((SpiceDouble( *)[3]) &
p_TC[0]);
603 int recFields = table[0].Fields();
610 std::vector<ale::Rotation> rotationCache;
611 std::vector<ale::Vec3d> avCache;
612 if (recFields == 5) {
613 for (
int r = 0; r < table.
Records(); r++) {
616 if (rec.
Fields() != recFields) {
620 std::vector<double> j2000Quat;
621 j2000Quat.push_back((
double)rec[0]);
622 j2000Quat.push_back((
double)rec[1]);
623 j2000Quat.push_back((
double)rec[2]);
624 j2000Quat.push_back((
double)rec[3]);
627 std::vector<double> CJ = q.
ToMatrix();
628 rotationCache.push_back(ale::Rotation(CJ));
632 if (
p_TC.size() > 1) {
633 m_orientation =
new ale::Orientations(rotationCache,
p_cacheTime, avCache,
637 m_orientation =
new ale::Orientations(rotationCache,
p_cacheTime, avCache,
644 else if (recFields == 8) {
645 for (
int r = 0; r < table.
Records(); r++) {
648 if (rec.
Fields() != recFields) {
652 std::vector<double> j2000Quat;
653 j2000Quat.push_back((
double)rec[0]);
654 j2000Quat.push_back((
double)rec[1]);
655 j2000Quat.push_back((
double)rec[2]);
656 j2000Quat.push_back((
double)rec[3]);
660 std::vector<double> CJ = q.
ToMatrix();
661 rotationCache.push_back(ale::Rotation(CJ));
663 std::vector<double> av;
664 av.push_back((
double)rec[4]);
665 av.push_back((
double)rec[5]);
666 av.push_back((
double)rec[6]);
667 avCache.push_back(ale::Vec3d(av));
672 if (
p_TC.size() > 1) {
673 m_orientation =
new ale::Orientations(rotationCache,
p_cacheTime, avCache,
677 m_orientation =
new ale::Orientations(rotationCache,
p_cacheTime, avCache,
684 else if (recFields == 3) {
685 std::vector<double> coeffAng1, coeffAng2, coeffAng3;
687 for (
int r = 0; r < table.
Records() - 1; r++) {
690 if (rec.
Fields() != recFields) {
693 coeffAng1.push_back((
double)rec[0]);
694 coeffAng2.push_back((
double)rec[1]);
695 coeffAng3.push_back((
double)rec[2]);
700 double baseTime = (double)rec[0];
701 double timeScale = (double)rec[1];
702 double degree = (double)rec[2];
708 if (degree == 0 && m_orientation->getAngularVelocities().size() > 0) {
713 QString msg =
"Expecting either three, five, or eight fields in the SpiceRotation table";
733 std::vector<ale::Rotation> rotationCache;
734 std::vector<ale::Vec3d> avCache;
745 for (std::vector<double>::size_type pos = 0; pos <
p_cacheTime.size(); pos++) {
747 rotationCache.push_back(ale::Rotation(
p_CJ));
748 avCache.push_back(ale::Vec3d(
p_av));
754 rotationCache.push_back(ale::Rotation(
p_CJ));
755 avCache.push_back(ale::Vec3d(
p_av));
769 for (std::vector<double>::size_type pos = 0; pos < maxSize; pos++) {
772 rotationCache.push_back(ale::Rotation(CJ));
779 QString msg =
"The SpiceRotation has not yet been fit to a function";
784 delete m_orientation;
785 m_orientation = NULL;
788 if (
p_TC.size() > 1) {
789 m_orientation =
new ale::Orientations(rotationCache,
p_cacheTime, avCache,
793 m_orientation =
new ale::Orientations(rotationCache,
p_cacheTime, avCache,
825 QString msg =
"Only cached rotations can be returned as a line cache of quaternions and time";
829 return Cache(tableName);
894 Table table(tableName, record);
896 std::vector<ale::Rotation> rots = m_orientation->getRotations();
897 std::vector<ale::Vec3d> angularVelocities = m_orientation->getAngularVelocities();
898 for (
int i = 0; i < (int)
p_cacheTime.size(); i++) {
899 std::vector<double> quat = rots[i].toQuaternion();
904 quat[0] = -1 * quat[0];
905 quat[1] = -1 * quat[1];
906 quat[2] = -1 * quat[2];
907 quat[3] = -1 * quat[3];
916 ale::Vec3d angularVelocity = angularVelocities[i];
917 record[4] = angularVelocity.x;
918 record[5] = angularVelocity.y;
919 record[6] = angularVelocity.z;
944 Table table(tableName, record);
946 for (
int cindex = 0; cindex <
p_degree + 1; cindex++) {
965 QString msg =
"To create table source of data must be either Memcache or PolyFunction";
980 SpiceInt centerBodyCode = (SpiceInt) centerBody;
996 QString naifKeyword =
"BODY" +
toString(centerBodyCode) +
"_CONSTANTS_REF_FRAME" ;
997 SpiceInt numExpected;
998 SpiceInt numReturned;
1000 SpiceDouble relativeFrameCode = 0;
1002 dtpool_c(naifKeyword.toLatin1().data(), &found, &numExpected, &naifType);
1006 SpiceDouble relativeFrameCode;
1007 bodvcd_c(centerBodyCode,
"CONSTANTS_REF_FRAME", 1,
1008 &numReturned, &relativeFrameCode);
1011 if (!found || relativeFrameCode == 1) {
1015 naifKeyword =
"BODY" +
toString(centerBodyCode) +
"_POLE_RA" ;
1016 dtpool_c(naifKeyword.toLatin1().data(), &found, &numExpected, &naifType);
1019 std::vector<SpiceDouble> d(3);
1022 m_pm.resize(numExpected);
1024 bodvcd_c(centerBodyCode,
"POLE_RA", numExpected, &numReturned, &d[0]);
1029 bodvcd_c(centerBodyCode,
"POLE_DEC", numExpected, &numReturned, &d[0]);
1034 bodvcd_c(centerBodyCode,
"PM", numExpected, &numReturned, &d[0]);
1035 m_pm[0].setDegrees(d[0]);
1036 m_pm[1].setDegrees(d[1]);
1037 m_pm[2].setDegrees(d[2]);
1044 naifKeyword =
"BODY" +
toString(centerBodyCode) +
"_NUT_PREC_RA" ;
1045 dtpool_c(naifKeyword.toLatin1().data(), &found, &numReturned, &naifType);
1049 SpiceInt bcCode = centerBodyCode/100;
1050 naifKeyword =
"BODY" +
toString(bcCode) +
"_NUT_PREC_ANGLES" ;
1051 dtpool_c(naifKeyword.toLatin1().data(), &found, &numExpected, &naifType);
1052 std::vector<double>npAngles(numExpected, 0.);
1053 bodvcd_c(bcCode,
"NUT_PREC_ANGLES", numExpected, &numReturned, &npAngles[0]);
1059 std::vector<SpiceDouble> angles(numExpected);
1060 bodvcd_c(centerBodyCode,
"NUT_PREC_RA", numExpected, &numReturned, &
m_raNutPrec[0]);
1061 bodvcd_c(centerBodyCode,
"NUT_PREC_DEC", numExpected, &numReturned, &
m_decNutPrec[0]);
1062 bodvcd_c(centerBodyCode,
"NUT_PREC_PM", numExpected, &numReturned, &
m_pmNutPrec[0]);
1067 for (
int i = 0; i < numExpected; i++) {
1106 for (
int i = 0; i < labelCoeffs.
size(); i++){
1113 for (
int i = 0; i < labelCoeffs.
size(); i++){
1119 PvlKeyword labelCoeffs = label[
"PrimeMeridian"];
1120 for (
int i = 0; i < labelCoeffs.
size(); i++){
1128 PvlKeyword labelCoeffs = label[
"PoleRaNutPrec"];
1129 for (
int i = 0; i < labelCoeffs.
size(); i++){
1134 PvlKeyword labelCoeffs = label[
"PoleDecNutPrec"];
1135 for (
int i = 0; i < labelCoeffs.
size(); i++){
1141 for (
int i = 0; i < labelCoeffs.
size(); i++){
1146 PvlKeyword labelCoeffs = label[
"SysNutPrec0"];
1147 for (
int i = 0; i < labelCoeffs.
size(); i++){
1152 PvlKeyword labelCoeffs = label[
"SysNutPrec1"];
1153 for (
int i = 0; i < labelCoeffs.
size(); i++){
1190 for (
int i = 0; i < (int)
p_TC.size(); i++) {
1218 for (
int i = 0; i < (int)
m_raPole.size(); i++) {
1224 for (
int i = 0; i < (int)
m_decPole.size(); i++) {
1230 for (
int i = 0; i < (int)
m_pm.size(); i++) {
1237 for (
int i = 0; i < (int)
m_raNutPrec.size(); i++) {
1249 for (
int i = 0; i < (int)
m_pmNutPrec.size(); i++) {
1299 SpiceDouble ang1, ang2, ang3;
1300 m2eul_c((SpiceDouble *) &
p_CJ[0], axis3, axis2, axis1, &ang3, &ang2, &ang1);
1302 std::vector<double> angles;
1303 angles.push_back(ang1);
1304 angles.push_back(ang2);
1305 angles.push_back(ang3);
1324 eul2m_c(angles[2], angles[1], angles[0], axis3, axis2, axis1, (SpiceDouble (*)[3]) &(
p_CJ[0]));
1326 if (m_orientation) {
1327 delete m_orientation;
1328 m_orientation = NULL;
1330 std::vector<ale::Rotation> rotationCache;
1331 rotationCache.push_back(ale::Rotation(
p_CJ));
1332 if (
p_TC.size() > 1) {
1333 m_orientation =
new ale::Orientations(rotationCache,
p_cacheTime, std::vector<ale::Vec3d>(),
1337 m_orientation =
new ale::Orientations(rotationCache,
p_cacheTime, std::vector<ale::Vec3d>(),
1398 std::vector<double> jVec;
1399 if (rVec.size() == 3) {
1401 mxm_c((SpiceDouble *) &
p_TC[0], (SpiceDouble *) &
p_CJ[0], TJ);
1403 mtxv_c(TJ, (SpiceDouble *) &rVec[0], (SpiceDouble *) &jVec[0]);
1406 else if (rVec.size() == 6) {
1412 std::vector<double> stateTJ(36);
1416 xpose6_c(&stateTJ[0], (SpiceDouble( *) [6]) &stateTJ[0]);
1417 double stateJT[6][6];
1418 invstm_((doublereal *) &stateTJ[0], (doublereal *) stateJT);
1419 xpose6_c(stateJT, stateJT);
1422 mxvg_c(stateJT, (SpiceDouble *) &rVec[0], 6, 6, (SpiceDouble *) &jVec[0]);
1599 std::vector<double> jVec;
1603 int angleIndex = partialVar;
1606 double angle = angles.at(angleIndex);
1609 double dmatrix[3][3];
1610 drotat_(&angle, (integer *) axes + angleIndex, (doublereal *) dmatrix);
1612 xpose_c(dmatrix, dmatrix);
1626 msg =
"Body rotation uses a binary PCK. Solutions for this model are not supported";
1630 msg =
"Body rotation uses a PCK not referenced to J2000. "
1631 "Solutions for this model are not supported";
1635 msg =
"Solutions are not supported for this frame type.";
1640 for (
int row = 0; row < 3; row++) {
1641 for (
int col = 0; col < 3; col++) {
1642 dmatrix[row][col] *= dpoly;
1648 switch (angleIndex) {
1650 rotmat_c(dmatrix, angles[1], axes[1], dCJ);
1651 rotmat_c(dCJ, angles[2], axes[2], dCJ);
1654 rotate_c(angles[0], axes[0], dCJ);
1655 mxm_c(dmatrix, dCJ, dCJ);
1656 rotmat_c(dCJ, angles[2], axes[2], dCJ);
1659 rotate_c(angles[0], axes[0], dCJ);
1660 rotmat_c(dCJ, angles[1], axes[1], dCJ);
1661 mxm_c(dmatrix, dCJ, dCJ);
1667 mxm_c((SpiceDouble *) &
p_TC[0], dCJ[0], dTJ);
1671 std::vector<double> lookdJ(3);
1673 mtxv_c(dTJ, (
const SpiceDouble *) &lookT[0], (SpiceDouble *) &lookdJ[0]);
1690 std::vector<double> rVec(3);
1692 if (jVec.size() == 3) {
1694 mxm_c((SpiceDouble *) &
p_TC[0], (SpiceDouble *) &
p_CJ[0], TJ);
1696 mxv_c(TJ, (SpiceDouble *) &jVec[0], (SpiceDouble *) &rVec[0]);
1698 else if (jVec.size() == 6) {
1704 std::vector<double> stateTJ(36);
1707 mxvg_c((SpiceDouble *) &stateTJ[0], (SpiceDouble *) &jVec[0], 6, 6, (SpiceDouble *) &rVec[0]);
1728 std::vector<double> coeffAng1, coeffAng2, coeffAng3;
1739 int size = m_orientation->getRotations().size();
1743 else if (size == 2) {
1749 coeffAng1.assign(
p_degree + 1, 0.);
1750 coeffAng2.assign(
p_degree + 1, 0.);
1751 coeffAng3.assign(
p_degree + 1, 0.);
1766 std::vector<double> time;
1772 coeffAng1.push_back(angles[0]);
1773 coeffAng2.push_back(angles[1]);
1774 coeffAng3.push_back(angles[2]);
1776 else if (size == 2) {
1789 angles2[0] =
WrapAngle(angles1[0], angles2[0]);
1790 angles2[2] =
WrapAngle(angles1[2], angles2[2]);
1792 double intercept[3];
1795 for (
int angleIndex = 0; angleIndex < 3; angleIndex++) {
1797 slope[angleIndex] = angline.
Slope();
1798 intercept[angleIndex] = angline.
Intercept();
1800 coeffAng1.push_back(intercept[0]);
1801 coeffAng1.push_back(slope[0]);
1802 coeffAng2.push_back(intercept[1]);
1803 coeffAng2.push_back(slope[1]);
1804 coeffAng3.push_back(intercept[2]);
1805 coeffAng3.push_back(slope[2]);
1812 for (std::vector<double>::size_type pos = 0; pos <
p_cacheTime.size(); pos++) {
1824 angles[0] =
WrapAngle(start1, angles[0]);
1825 angles[2] =
WrapAngle(start3, angles[2]);
1828 fitAng1->
AddKnown(time, angles[0]);
1829 fitAng2->
AddKnown(time, angles[1]);
1830 fitAng3->
AddKnown(time, angles[2]);
1879 const std::vector<double> &coeffAng2,
1880 const std::vector<double> &coeffAng3,
1884 QString msg =
"The quaternion SPICE tables are no longer available. "
1885 "Either re-run spiceinit or set OVEREXISTING to False.";
1950 QString msg =
"Target body orientation information not available. Rerun spiceinit.";
2021 const std::vector<Angle> &decCoeff,
2022 const std::vector<Angle> &pmCoeff) {
2044 std::vector<double> &coeffAng2,
2045 std::vector<double> &coeffAng3) {
2066 std::vector<Angle> &decCoeff,
2067 std::vector<Angle> &pmCoeff) {
2109 void SpiceRotation::SetCacheTime(std::vector<double> cacheTime) {
2133 if (coeffIndex > 0 && coeffIndex <=
p_degree) {
2134 derivative = pow(time, coeffIndex);
2136 else if (coeffIndex == 0) {
2140 QString msg =
"Unable to evaluate the derivative of the SPICE rotation fit polynomial for "
2141 "the given coefficient index [" +
toString(coeffIndex) +
"]. "
2142 "Index is negative or exceeds degree of polynomial ["
2165 const int coeffIndex) {
2166 const double p_dayScale = 86400;
2168 const double p_centScale = p_dayScale * 36525;
2171 switch (partialVar) {
2174 time =
p_et / p_centScale;
2177 time =
p_et / p_dayScale;
2183 switch (coeffIndex) {
2189 derivative = pow(time, coeffIndex);
2192 QString msg =
"Unable to evaluate the derivative of the target body rotation fit polynomial "
2193 "for the given coefficient index [" +
toString(coeffIndex) +
"]. "
2194 "Index is negative or exceeds degree of polynomial ["
2202 derivative = -derivative;
2232 int angleIndex = partialVar;
2235 double angle = angles.at(angleIndex);
2237 double dmatrix[3][3];
2238 drotat_(&angle, (integer *) axes + angleIndex, (doublereal *) dmatrix);
2240 xpose_c(dmatrix, dmatrix);
2254 QString msg =
"Only CK, DYN, and PCK partials can be calculated";
2259 for (
int row = 0; row < 3; row++) {
2260 for (
int col = 0; col < 3; col++) {
2261 dmatrix[row][col] *= dpoly;
2267 switch (angleIndex) {
2269 rotmat_c(dmatrix, angles[1], axes[1], dCJ);
2270 rotmat_c(dCJ, angles[2], axes[2], dCJ);
2273 rotate_c(angles[0], axes[0], dCJ);
2274 mxm_c(dmatrix, dCJ, dCJ);
2275 rotmat_c(dCJ, angles[2], axes[2], dCJ);
2278 rotate_c(angles[0], axes[0], dCJ);
2279 rotmat_c(dCJ, angles[1], axes[1], dCJ);
2280 mxm_c(dmatrix, dCJ, dCJ);
2286 mxm_c((SpiceDouble *) &
p_TC[0], dCJ[0], dTJ);
2290 std::vector<double> lookdT(3);
2292 mxv_c(dTJ, (
const SpiceDouble *) &lookJ[0], (SpiceDouble *) &lookdT[0]);
2309 double diff1 = compareAngle - angle;
2311 if (diff1 < -1 * pi_c()) {
2314 else if (diff1 > pi_c()) {
2354 for (
int icoef =
p_degree + 1; icoef <= degree; icoef++) {
2355 coefAngle1.push_back(0.);
2356 coefAngle2.push_back(0.);
2357 coefAngle3.push_back(0.);
2364 std::vector<double> coefAngle1(degree + 1),
2365 coefAngle2(degree + 1),
2366 coefAngle3(degree + 1);
2368 for (
int icoef = 0; icoef <= degree; icoef++) {
2443 if (axis1 < 1 || axis2 < 1 || axis3 < 1 || axis1 > 3 || axis2 > 3 || axis3 > 3) {
2444 QString msg =
"A rotation axis is outside the valid range of 1 to 3";
2471 double currentTime = observStart;
2472 bool timeLoaded =
false;
2477 ktotal_c(
"ck", (SpiceInt *) &count);
2486 "Full cache size does NOT match cache size in LoadTimeCache -- should never happen";
2495 std::vector<ale::Rotation> fullRotationCache = m_orientation->getRotations();
2496 std::vector<ale::Vec3d> angularVelocities = m_orientation->getAngularVelocities();
2499 std::vector<double> rotationMatrix = fullRotationCache[r].toRotationMatrix();
2500 SpiceDouble CJ[9] = { rotationMatrix[0], rotationMatrix[1], rotationMatrix[2],
2501 rotationMatrix[3], rotationMatrix[4], rotationMatrix[5],
2502 rotationMatrix[6], rotationMatrix[7], rotationMatrix[8]
2504 m2q_c(CJ, quats[r]);
2506 ale::Vec3d angularVelocity = angularVelocities[r];
2507 vequ_c((SpiceDouble *) &angularVelocity.x, avvs[r]);
2511 double cubeStarts = timeSclkdp[0];
2512 double radTol = 0.000000017453;
2513 SpiceInt avflag = 1;
2519 ck3sdn(radTol, avflag, (
int *) &sizOut, timeSclkdp, (doublereal *) quats,
2520 (SpiceDouble *) avvs, nints, &cubeStarts, dparr, (
int *) intarr);
2524 std::vector<double> av;
2527 if (m_orientation) {
2528 delete m_orientation;
2529 m_orientation = NULL;
2532 std::vector<ale::Rotation> rotationCache;
2533 std::vector<ale::Vec3d> avCache;
2535 for (
int r = 0; r < sizOut; r++) {
2540 std::vector<double> CJ(9);
2541 q2m_c(quats[r], (SpiceDouble( *)[3]) &CJ[0]);
2542 rotationCache.push_back(CJ);
2543 vequ_c(avvs[r], (SpiceDouble *) &av[0]);
2544 avCache.push_back(av);
2547 if (
p_TC.size() > 1 ) {
2548 m_orientation =
new ale::Orientations(rotationCache,
p_cacheTime, avCache,
2552 m_orientation =
new ale::Orientations(rotationCache,
p_cacheTime, std::vector<ale::Vec3d>(),
2565 int SOURCESIZ = 128;
2568 SpiceChar file[FILESIZ];
2569 SpiceChar filtyp[TYPESIZ];
2570 SpiceChar source[SOURCESIZ];
2573 bool observationSpansToNextSegment =
false;
2578 kdata_c(0,
"ck", FILESIZ, TYPESIZ, SOURCESIZ, file, filtyp, source, &handle, &found);
2584 observationSpansToNextSegment =
false;
2595 dafus_c(sum, (SpiceInt) 2, (SpiceInt) 6, dc, ic);
2598 if (ic[2] == 5)
break;
2601 if (ic[0] == spCode && ic[2] == 3) {
2602 sct2e_c((
int) spCode / 1000, dc[0], &segStartEt);
2603 sct2e_c((
int) spCode / 1000, dc[1], &segStopEt);
2608 if (currentTime >= segStartEt && currentTime <= segStopEt) {
2612 if (observationSpansToNextSegment && currentTime > segStartEt) {
2613 QString msg =
"Observation crosses segment boundary--unable to interpolate pointing";
2616 if (observEnd > segStopEt) {
2617 observationSpansToNextSegment =
true;
2621 int dovelocity = ic[3];
2624 dafgda_c(handle, end - 1, end, val);
2626 int ninstances = (int) val[1];
2627 int numvel = dovelocity * 3;
2628 int quatnoff = ic[4] + (4 + numvel) * ninstances - 1;
2630 int sclkdp1off = quatnoff + 1;
2631 int sclkdpnoff = sclkdp1off + ninstances - 1;
2634 int sclkSpCode = spCode / 1000;
2637 std::vector<double> sclkdp(ninstances);
2638 dafgda_c(handle, sclkdp1off, sclkdpnoff, (SpiceDouble *) &sclkdp[0]);
2641 sct2e_c(sclkSpCode, sclkdp[0], &et);
2643 while (instance < (ninstances - 1) && et < currentTime) {
2645 sct2e_c(sclkSpCode, sclkdp[instance], &et);
2648 if (instance > 0) instance--;
2649 sct2e_c(sclkSpCode, sclkdp[instance], &et);
2651 while (instance < (ninstances - 1) && et < observEnd) {
2654 sct2e_c(sclkSpCode, sclkdp[instance], &et);
2658 if (!observationSpansToNextSegment) {
2664 currentTime = segStopEt;
2673 QString msg =
"No camera kernels loaded...Unable to determine time cache to downsize";
2680 double cacheSlope = 0.0;
2704 QString msg =
"Time cache not available -- rerun spiceinit";
2708 std::vector<double> fullCacheTime;
2709 double cacheSlope = 0.0;
2717 return fullCacheTime;
2743 std::vector<int> frameCodes;
2744 std::vector<int> frameTypes;
2747 while (frameCodes[frameCodes.size()-1] != J2000Code) {
2748 frmidx = frameCodes.size() - 1;
2756 frinfo_c((SpiceInt) frameCodes[frmidx],
2757 (SpiceInt *) ¢er,
2759 (SpiceInt *) &typid, &found);
2764 frameTypes.push_back(0);
2768 QString msg =
"The frame" +
toString((
int) frameCodes[frmidx]) +
" is not supported by Naif";
2772 double matrix[3][3];
2776 nextFrame = J2000Code;
2778 else if (type == CK) {
2779 ckfrot_((SpiceInt *) &typid, &et, (
double *) matrix, &nextFrame, (logical *) &found);
2784 frameTypes.push_back(0);
2788 QString msg =
"The ck rotation from frame " +
toString(frameCodes[frmidx]) +
" can not "
2789 +
"be found due to no pointing available at requested time or a problem with the "
2794 else if (type == TK) {
2795 tkfram_((SpiceInt *) &typid, (
double *) matrix, &nextFrame, (logical *) &found);
2797 QString msg =
"The tk rotation from frame " +
toString(frameCodes[frmidx]) +
2798 " can not be found";
2802 else if (type == DYN) {
2809 zzdynrot_((SpiceInt *) &typid, (SpiceInt *) ¢er, &et, (
double *) matrix, &nextFrame);
2813 QString msg =
"The frame " +
toString(frameCodes[frmidx]) +
2814 " has a type " +
toString(type) +
" not supported by your version of Naif Spicelib."
2815 +
"You need to update.";
2819 frameCodes.push_back(nextFrame);
2820 frameTypes.push_back(type);
2831 while (frameTypes[nConstants] == TK && nConstants < (
int) frameTypes.size()) nConstants++;
2834 for (
int i = 0; i <= nConstants; i++) {
2839 for (
int i = nConstants; i < (int) frameCodes.size(); i++) {
2859 std::vector<double> TJ;
2861 mxm_c((SpiceDouble *) &
p_TC[0], (SpiceDouble *) &
p_CJ[0], (SpiceDouble( *) [3]) &TJ[0]);
2874 std::vector<double> q;
2876 m2q_c((SpiceDouble( *)[3]) &
p_TC[0], &q[0]);
2898 p_TC = constantMatrix;
2909 std::vector<double> q;
2911 m2q_c((SpiceDouble( *)[3]) &
p_CJ[0], &q[0]);
2933 p_CJ = timeBasedMatrix;
2949 refchg_((SpiceInt *) &fromFrame, (SpiceInt *) &targetFrame, &et, (doublereal *) &
p_TC[0]);
2951 xpose_c((SpiceDouble( *)[3]) &
p_TC[0], (SpiceDouble( *)[3]) &
p_TC[0]);
2979 QString msg =
"The SpiceRotation pointing angles must be fit to polynomials in order to ";
2980 msg +=
"compute angular velocity.";
2984 QString msg =
"Planetary angular velocity must be fit computed with PCK polynomials ";
2987 std::vector<double> dCJdt;
3005 mtxm_c((SpiceDouble( *)[3]) &dCJdt[0], (SpiceDouble( *)[3]) &
p_CJ[0], omega);
3006 p_av[0] = omega[2][1];
3007 p_av[1] = omega[0][2];
3008 p_av[2] = omega[1][0];
3026 double dmatrix[3][3];
3028 double wmatrix[3][3];
3031 for (
int angleIndex = 0; angleIndex < 3; angleIndex++) {
3032 drotat_(&(angles[angleIndex]), (integer *) axes + angleIndex, (doublereal *) dmatrix);
3034 xpose_c(dmatrix, dmatrix);
3046 for (
int row = 0; row < 3; row++) {
3047 for (
int col = 0; col < 3; col++) {
3048 dmatrix[row][col] *= dangle;
3052 switch (angleIndex) {
3054 rotmat_c(dmatrix, angles[1], axes[1], dmatrix);
3055 rotmat_c(dmatrix, angles[2], axes[2], dmatrix);
3058 rotate_c(angles[0], axes[0], wmatrix);
3059 mxm_c(dmatrix, wmatrix, dmatrix);
3060 rotmat_c(dmatrix, angles[2], axes[2], dmatrix);
3063 rotate_c(angles[0], axes[0], wmatrix);
3064 rotmat_c(wmatrix, angles[1], axes[1], wmatrix);
3065 mxm_c(dmatrix, wmatrix, dmatrix);
3069 for (
int index = 0; index < 9; index++) {
3072 dCJ[index] += dmatrix[i][j];
3086 std::vector<double> stateTJ(36);
3089 double stateCJ[6][6];
3090 rav2xf_c(&
p_CJ[0], &
p_av[0], stateCJ);
3096 for (
int row = 3; row < 6; row++) {
3100 for (
int col = 0; col < 3; col++) {
3103 stateTJ[irow*6 + col] =
p_TC[vpos] * stateCJ[0][col] +
p_TC[vpos+1] * stateCJ[1][col]
3104 +
p_TC[vpos+2] * stateCJ[2][col];
3106 stateTJ[row*6 + col] =
p_TC[vpos] * stateCJ[3][col] +
p_TC[vpos+1] * stateCJ[4][col]
3107 +
p_TC[vpos+2] * stateCJ[5][col];
3109 stateTJ[irow*6 + jcol] = 0;
3111 stateTJ[row*6 +jcol] = stateTJ[irow*6 + col];
3135 double diffTime = timeEt -
p_et;
3136 std::vector<double> CJ(9, 0.0);
3141 axisar_c((SpiceDouble *) &
p_av[0], diffTime*vnorm_c((SpiceDouble *) &
p_av[0]), dmat);
3144 mxm_c(dmat, (SpiceDouble *) &
p_CJ[0], (SpiceDouble( *)[3]) &CJ[0]);
3175 ktotal_c(
"PCK", &count);
3180 int SOURCESIZ = 128;
3181 SpiceChar file[FILESIZ];
3182 SpiceChar filetype[TYPESIZ];
3183 SpiceChar source[SOURCESIZ];
3190 for (SpiceInt knum = 0; knum < count; knum++){
3191 kdata_c(knum,
"PCK", FILESIZ, TYPESIZ, SOURCESIZ, file, filetype, source, &handle, &found);
3194 if (strstr(file,
"bpc") != NULL) {
3211 SpiceInt centerBodyCode;
3212 SpiceInt frameClass;
3214 frinfo_c(frameCode, ¢erBodyCode, &frameClass, &classId, &found);
3217 if (frameClass == 2 || (centerBodyCode > 0 && frameClass != 3)) {
3223 for (std::vector<int>::size_type idx = 1; idx <
p_constantFrames.size(); idx++) {
3225 frinfo_c(frameCode, ¢erBodyCode, &frameClass, &classId, &found);
3230 switch (frameClass) {
3264 p_CJ = m_orientation->getRotations()[0].toRotationMatrix();
3266 ale::Vec3d av = m_orientation->getAngularVelocities()[0];
3274 p_CJ = m_orientation->interpolateTimeDep(
p_et).toRotationMatrix();
3277 ale::Vec3d av = m_orientation->interpolateAV(
p_et);
3302 SpiceDouble stateJ[6];
3305 spkez_c((SpiceInt) spkCode,
p_et,
"J2000",
"LT+S",
3309 SpiceDouble sJ[3], svJ[3];
3310 vpack_c(-1 * stateJ[0], -1 * stateJ[1], -1 * stateJ[2], sJ);
3311 vpack_c(stateJ[3], stateJ[4], stateJ[5], svJ);
3316 (SpiceDouble( *)[3]) &
p_CJ[0]);
3333 SpiceInt j2000 = J2000Code;
3341 double stateCJ[6][6];
3342 frmchg_((integer *) &j2000, (integer *) &toFrame, &time, (doublereal *) stateCJ);
3347 SpiceBoolean ckfailure = failed_c();
3351 xpose6_c(stateCJ, stateCJ);
3352 xf2rav_c(stateCJ, (SpiceDouble( *)[3]) &
p_CJ[0], (SpiceDouble *) &
p_av[0]);
3356 refchg_((integer *) &j2000, (integer *) &toFrame, &time, (SpiceDouble *) &
p_CJ[0]);
3360 getmsg_c(
"SHORT",
sizeof(naifstr), naifstr);
3363 if (eqstr_c(naifstr,
"SPICE(UNKNOWNFRAME)")) {
3365 "reference frame code. Has the mission frames kernel been loaded?";
3369 Isis::IString msg =
"No pointing available at requested time [" +
3377 xpose_c((SpiceDouble( *)[3]) &
p_CJ[0], (SpiceDouble( *)[3]) &
p_CJ[0]);
3400 std::vector<double> rtime;
3402 std::vector<double> angles;
3403 angles.push_back(function1.
Evaluate(rtime));
3404 angles.push_back(function2.
Evaluate(rtime));
3405 angles.push_back(function3.
Evaluate(rtime));
3408 if (angles[0] <= -1 * pi_c()) {
3409 angles[0] += twopi_c();
3411 else if (angles[0] > pi_c()) {
3412 angles[0] -= twopi_c();
3435 std::vector<double> rtime;
3437 double angle1 = function1.
Evaluate(rtime);
3438 double angle2 = function2.
Evaluate(rtime);
3439 double angle3 = function3.
Evaluate(rtime);
3442 if (angle1 < -1 * pi_c()) {
3443 angle1 += twopi_c();
3445 else if (angle1 > pi_c()) {
3446 angle1 -= twopi_c();
3449 eul2m_c((SpiceDouble) angle3, (SpiceDouble) angle2, (SpiceDouble) angle1,
3451 (SpiceDouble( *)[3]) &
p_CJ[0]);
3455 ale::Vec3d av = m_orientation->getAngularVelocities()[0];
3477 std::vector<double> cacheAngles(3);
3478 std::vector<double> cacheVelocity(3);
3480 cacheVelocity =
p_av;
3482 std::vector<double> polyAngles(3);
3486 std::vector<double> polyVelocity(3);
3487 polyVelocity =
p_av;
3488 std::vector<double> angles(3);
3490 for (
int index = 0; index < 3; index++) {
3491 angles[index] = cacheAngles[index] + polyAngles[index];
3492 p_av[index] += cacheVelocity[index];
3495 if (angles[0] <= -1 * pi_c()) {
3496 angles[0] += twopi_c();
3498 else if (angles[0] > pi_c()) {
3499 angles[0] -= twopi_c();
3502 if (angles[2] <= -1 * pi_c()) {
3503 angles[2] += twopi_c();
3505 else if (angles[2] > pi_c()) {
3506 angles[2] -= twopi_c();
3509 eul2m_c((SpiceDouble) angles[2], (SpiceDouble) angles[1], (SpiceDouble) angles[0],
3511 (SpiceDouble( *)[3]) &
p_CJ[0]);
3522 double dTime =
p_et / 86400.;
3523 double centTime = dTime / 36525;
3524 double secondsPerJulianCentury = 86400. * 36525.;
3542 for (
int ia = 0; ia < numNutPrec; ia++) {
3545 costheta = cos(theta.
radians());
3546 sintheta = sin(theta.
radians());
3558 if (ra.
radians() < -1 * pi_c()) {
3561 else if (ra.
radians() > pi_c()) {
3565 if (pm.radians() < -1 * pi_c()) {
3568 else if (pm.radians() > pi_c()) {
3574 SpiceDouble delta =
HALFPI - dec.radians();
3575 SpiceDouble w = pm.radians();
3576 SpiceDouble dphi = dra.radians();
3577 SpiceDouble ddelta = -ddec.
radians();
3578 SpiceDouble dw = dpm.
radians();
3581 SpiceDouble angsDangs[6];
3582 SpiceDouble BJs[6][6];
3583 vpack_c(w, delta, phi, angsDangs);
3584 vpack_c(dw, ddelta, dphi, &angsDangs[3]);
3588 xf2rav_c(BJs, (SpiceDouble( *)[3]) &
p_CJ[0], (SpiceDouble *) &
p_av[0]);
Defines an angle and provides unit conversions.
double radians() const
Convert an angle to a double.
@ Degrees
Degrees are generally considered more human readable, 0-360 is one circle, however most math does not...
@ Radians
Radians are generally used in mathematical equations, 0-2*PI is one circle, however these are more di...
double Evaluate(const std::vector< double > &vars)
Compute the equation using the input variables.
int Coefficients() const
Returns the number of coefficients for the equation.
double Coefficient(int i) const
Returns the ith coefficient.
void SetCoefficients(const std::vector< double > &coefs)
Set the coefficients for the equation.
@ User
A type of error that could only have occurred due to a mistake on the user's part (e....
@ Programmer
This error is for when a programmer made an API call that was illegal.
@ Io
A type of error that occurred when performing an actual I/O operation.
Adds specific functionality to C++ strings.
Generic least square fitting class.
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...
void AddKnown(const std::vector< double > &input, double expected, double weight=1.0)
Invoke this method for each set of knowns.
Utility class for creating and using cartesean line equations.
double Slope()
Compute the slope of the line.
double Intercept()
Compute the intercept of the line.
static void CheckErrors(bool resetNaif=true)
This method looks for any naif errors that might have occurred.
Nth degree Polynomial with one variable.
double DerivativeVar(const double value)
This will take the Derivative with respect to the variable and evaluate at given value.
A single keyword-value pair.
int size() const
Returns the number of values stored in this keyword.
Contains Pvl Groups and Pvl Objects.
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 ...
PvlKeyword & findKeyword(const QString &kname, FindOptions opts)
Finds a keyword in the current PvlObject, or deeper inside other PvlObjects and Pvlgroups within this...
Provide operations for quaternion arithmetic.
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...
void setEphemerisTimePolyFunction()
When setting the ephemeris time, updates the rotation according to a polynomial that defines the thre...
std::vector< double > GetFullCacheTime()
Return full listing (cache) of original time coverage requested.
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...
std::vector< double > m_decNutPrec
Coefficients of pole decliniation nut/prec terms.
void loadPCFromTable(const PvlObject &Label)
Initialize planetary orientation constants from an cube body rotation label.
void SetConstantMatrix(std::vector< double > constantMatrix)
Set the constant 3x3 rotation TC matrix from a vector of length 9.
void SetFullCacheParameters(double startTime, double endTime, int cacheSize)
Set the full cache time parameters.
double GetTimeScale()
Accessor method to get the rotation time scale.
int Frame()
Accessor method that returns the frame code.
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...
void setFrameType()
Cached orientation information.
FrameType getFrameType()
Accessor method to get the rotation frame type.
int p_targetCode
For computing Nadir rotation only.
double p_fullCacheStartTime
Initial requested starting time of cache.
int p_degree
Degree of fit polynomial for angles.
Source p_source
The source of the rotation data.
void setEphemerisTimePckPolyFunction()
When setting the ephemeris time, updates the rotation state based on the PcK polynomial.
void CacheLabel(Table &table)
Add labels to a SpiceRotation table.
void SetTimeBasedMatrix(std::vector< double > timeBasedMatrix)
Set the time-based 3x3 rotation CJ matrix from a vector of length 9.
double p_fullCacheEndTime
Initial requested ending time of cache.
std::vector< double > Matrix()
Return the full rotation TJ as a matrix.
double EphemerisTime() const
Accessor method to get current ephemeris time.
void SetAxes(int axis1, int axis2, int axis3)
Set the axes of rotation for decomposition of a rotation matrix into 3 angles.
double GetBaseTime()
Accessor method to get the rotation base time.
std::vector< double > EvaluatePolyFunction()
Evaluate the polynomial fit function for the three pointing angles for the current ephemeris time.
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...
int p_axisV
The axis defined by the velocity vector for defining a nadir rotation.
void ReloadCache()
Cache J2000 rotation over existing cached time range using polynomials.
bool p_hasAngularVelocity
Flag indicating whether the rotation includes angular velocity.
double p_baseTime
Base time used in fit equations.
std::vector< Angle > poleDecCoefs()
Return the coefficients used to calculate the target body pole dec.
int p_axisP
The axis defined by the spacecraft vector for defining a nadir rotation.
std::vector< Angle > m_pm
Coefficients of a quadratic polynomial fitting pole pm.
double WrapAngle(double compareAngle, double angle)
Wrap the input angle to keep it within 2pi radians of the angle to compare.
std::vector< double > GetCenterAngles()
Return the camera angles at the center time of the observation.
void setEphemerisTimeNadir()
When setting the ephemeris time, uses spacecraft nadir source to update the rotation state.
Source GetSource()
Accessor method to get the rotation source.
std::vector< Angle > m_decPole
Coefficients of a quadratic polynomial fitting pole dec.
void LoadTimeCache()
Load the time cache.
std::vector< double > & TimeBasedMatrix()
Return time-based 3x3 rotation CJ matrix as a vector of length 9.
std::vector< double > p_CJ
Rotation matrix from J2000 to first constant rotation.
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.
void InitConstantRotation(double et)
Initialize the constant rotation.
int p_axis1
Axis of rotation for angle 1 of rotation.
int p_axis3
Axis of rotation for angle 3 of rotation.
Table Cache(const QString &tableName)
Return a table with J2000 to reference rotations.
void LoadCache(double startTime, double endTime, int size)
Cache J2000 rotation quaternion over a time range.
std::vector< double > ConstantRotation()
Return the constant 3x3 rotation TC matrix as a quaternion.
std::vector< double > ReferenceVector(const std::vector< double > &jVec)
Given a direction vector in J2000, return a reference frame direction.
std::vector< double > AngularVelocity()
Accessor method to get the angular velocity.
double p_overrideBaseTime
Value set by caller to override computed base time.
double p_overrideTimeScale
Value set by caller to override computed time scale.
std::vector< Angle > sysNutPrecCoefs()
Return the coefficients used to calculate the target body system nut/prec angles.
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...
Table LineCache(const QString &tableName)
Return a table with J2000 to reference rotations.
std::vector< double > J2000Vector(const std::vector< double > &rVec)
Given a direction vector in the reference frame, return a J2000 direction.
double DPckPolynomial(PartialType partialVar, const int coeffIndex)
Evaluate the derivative of the fit polynomial defined by the given coefficients with respect to the c...
DownsizeStatus p_minimizeCache
Status of downsizing the cache (set to No to ignore)
void SetEphemerisTime(double et)
Return the J2000 to reference frame quaternion at given time.
void SetFrame(int frameCode)
Change the frame to the given frame code.
std::vector< double > m_raNutPrec
Coefficients of pole right ascension nut/prec terms.
std::vector< int > TimeFrameChain()
Accessor method to get the frame chain for the rotation (begins in J2000).
std::vector< double > p_coefficients[3]
Coefficients defining functions fit to 3 pointing angles.
SpiceRotation(int frameCode)
Construct an empty SpiceRotation class using a valid Naif frame code to set up for getting rotation f...
double p_timeScale
Time scale used in fit equations.
std::vector< Angle > sysNutPrecConstants()
Return the constants used to calculate the target body system nut/prec angles.
std::vector< double > Extrapolate(double timeEt)
Extrapolate pointing for a given time assuming a constant angular velocity.
bool p_degreeApplied
Flag indicating whether or not a polynomial of degree p_degree has been created and used to fill the ...
std::vector< double > poleRaNutPrecCoefs()
Return the coefficients used to calculate the target body pole ra nut/prec coefficients.
std::vector< double > p_cacheTime
iTime for corresponding rotation
DownsizeStatus
Status of downsizing the cache.
@ Done
Cache is downsized.
@ No
Do not downsize the cache.
void checkForBinaryPck()
Check loaded pck to see if any are binary and set frame type to indicate binary pck.
std::vector< Angle > poleRaCoefs()
Return the coefficients used to calculate the target body pole ra.
void setEphemerisTimePolyFunctionOverSpice()
When setting the ephemeris time, updates the rotation state based on a polynomial fit over spice kern...
std::vector< double > p_av
Angular velocity for rotation at time p_et.
void SetSource(Source source)
Resets the source of the rotation to the given value.
int p_fullCacheSize
Initial requested cache size.
void setEphemerisTimeSpice()
When setting the ephemeris time, updates the rotation state based on data read directly from NAIF ker...
bool p_noOverride
Flag to compute base time;.
bool m_tOrientationAvailable
Target orientation constants are available.
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...
std::vector< double > StateTJ()
State matrix (6x6) for rotating state vectors from J2000 to target frame.
Source
The rotation can come from one of 3 places for an Isis cube.
@ PolyFunction
From nth degree polynomial.
@ Spice
Directly from the kernels.
@ PckPolyFunction
Quadratic polynomial function with linear trignometric terms.
@ Memcache
From cached table.
@ PolyFunctionOverSpice
Kernels plus nth degree polynomial.
PartialType
This enumeration indicates whether the partial derivative is taken with respect to Right Ascension,...
@ WRT_RightAscension
With respect to Right Ascension.
@ WRT_Twist
With respect to Twist or Prime Meridian Rotation.
@ WRT_Declination
With respect to Declination.
void loadPCFromSpice(int CenterBodyCode)
Initialize planetary orientation constants from Spice PCK.
void setEphemerisTimeMemcache()
Updates rotation state based on the rotation cache.
void ComputeAv()
Compute the angular velocity from the time-based functions fit to the pointing angles This method com...
double DPolynomial(const int coeffIndex)
Evaluate the derivative of the fit polynomial defined by the given coefficients with respect to the c...
void ComputeBaseTime()
Compute the base time using cached times.
void SetPolynomialDegree(int degree)
Set the degree of the polynomials to be fit to the three camera angles for the time period covered by...
void MinimizeCache(DownsizeStatus status)
Set the downsize status to minimize cache.
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.
bool HasAngularVelocity()
Checks whether the rotation has angular velocities.
double p_et
Current ephemeris time.
std::vector< double > m_pmNutPrec
Coefficients of prime meridian nut/prec terms.
std::vector< Angle > m_raPole
Coefficients of a quadratic polynomial fitting pole ra.
std::vector< int > p_timeFrames
Chain of Naif frame codes in time-based rotation CJ.
void DCJdt(std::vector< double > &dRJ)
Compute the derivative of the 3x3 rotation matrix CJ with respect to time.
void SetTimeBias(double timeBias)
Apply a time bias when invoking SetEphemerisTime method.
bool p_matrixSet
Flag indicating p_TJ has been set.
std::vector< int > ConstantFrameChain()
Accessor method to get the frame chain for the constant part of the rotation (ends in target)
std::vector< double > p_TC
Rotation matrix from first constant rotation (after all time-based rotations in frame chain from J200...
void FrameTrace(double et)
Compute frame trace chain from target frame to J2000.
int p_axis2
Axis of rotation for angle 2 of rotation.
std::vector< Angle > m_sysNutPrec0
Constants of planetary system nut/prec periods.
std::vector< double > & ConstantMatrix()
Return the constant 3x3 rotation TC matrix as a vector of length 9.
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 p_timeBias
iTime bias when reading kernels
std::vector< double > pmNutPrecCoefs()
Return the coefficients used to calculate the target body pm nut/prec coefficients.
FrameType
Enumeration for the frame type of the rotation.
@ INERTL
See Naif Frames.req document for.
@ NOTJ2000PCK
PCK frame not referenced to J2000.
@ UNKNOWN
Isis specific code for unknown frame type.
@ BPC
Isis specific code for binary pck.
bool IsCached() const
Checks if the cache is empty.
FrameType m_frameType
The type of rotation frame.
std::vector< double > poleDecNutPrecCoefs()
Return the coefficients used to calculate the target body pole dec nut/prec coefficients.
std::vector< Angle > pmCoefs()
Return the coefficients used to calculate the target body prime meridian.
std::vector< Angle > m_sysNutPrec1
Linear terms of planetary system nut/prec periods.
std::vector< int > p_constantFrames
Chain of Naif frame codes in constant rotation TC.
virtual ~SpiceRotation()
Destructor for SpiceRotation object.
Quaternion p_quaternion
Quaternion for J2000 to reference rotation at et.
void usePckPolynomial()
Set the coefficients of a polynomial fit to each of the three planet angles for the time period cover...
std::vector< double > TimeBasedRotation()
Return time-based 3x3 rotation CJ matrix as a quaternion.
Class for storing an Isis::Table's field information.
@ Double
The values in the field are 8 byte doubles.
Class for storing Table blobs information.
int Records() const
Returns the number of records.
PvlObject & Label()
The Table's label.
int Fields() const
Returns the number of fields that are currently in the record.
This is free and unencumbered software released into the public domain.
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
int toInt(const QString &string)
Global function to convert from a string to an integer.
const double DEG2RAD
Multiplier for converting from degrees to radians.
const double HALFPI
The mathematical constant PI/2.
double toDouble(const QString &string)
Global function to convert from a string to a double.