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;
148 p_av = rotToCopy.p_av;
158 p_et = rotToCopy.p_et;
170 for (
int i = 0; i < 3; i++)
180 p_TC = rotToCopy.p_TC;
182 p_CJ = rotToCopy.p_CJ;
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++) {
771 std::vector<double> CJ = tempRot.TimeBasedMatrix();
772 rotationCache.push_back(ale::Rotation(CJ));
774 avCache.push_back(ale::Vec3d(tempRot.AngularVelocity()));
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]);
1848 for (
int i = 0; i < function1.Coefficients(); i++) {
1849 coeffAng1.push_back(function1.Coefficient(i));
1850 coeffAng2.push_back(function2.Coefficient(i));
1851 coeffAng3.push_back(function3.Coefficient(i));
1879 const std::vector<double> &coeffAng2,
1880 const std::vector<double> &coeffAng3,
1889 function1.SetCoefficients(coeffAng1);
1890 function2.SetCoefficients(coeffAng2);
1891 function3.SetCoefficients(coeffAng3);
1945 QString msg =
"Target body orientation information not available. Rerun spiceinit.";
2016 const std::vector<Angle> &decCoeff,
2017 const std::vector<Angle> &pmCoeff) {
2039 std::vector<double> &coeffAng2,
2040 std::vector<double> &coeffAng3) {
2061 std::vector<Angle> &decCoeff,
2062 std::vector<Angle> &pmCoeff) {
2104 void SpiceRotation::SetCacheTime(std::vector<double> cacheTime) {
2128 if (coeffIndex > 0 && coeffIndex <=
p_degree) {
2129 derivative = pow(time, coeffIndex);
2131 else if (coeffIndex == 0) {
2135 QString msg =
"Unable to evaluate the derivative of the SPICE rotation fit polynomial for "
2136 "the given coefficient index [" +
toString(coeffIndex) +
"]. "
2137 "Index is negative or exceeds degree of polynomial ["
2160 const int coeffIndex) {
2161 const double p_dayScale = 86400;
2163 const double p_centScale = p_dayScale * 36525;
2166 switch (partialVar) {
2169 time =
p_et / p_centScale;
2172 time =
p_et / p_dayScale;
2178 switch (coeffIndex) {
2184 derivative = pow(time, coeffIndex);
2187 QString msg =
"Unable to evaluate the derivative of the target body rotation fit polynomial "
2188 "for the given coefficient index [" +
toString(coeffIndex) +
"]. "
2189 "Index is negative or exceeds degree of polynomial ["
2197 derivative = -derivative;
2227 int angleIndex = partialVar;
2230 double angle = angles.at(angleIndex);
2232 double dmatrix[3][3];
2233 drotat_(&angle, (integer *) axes + angleIndex, (doublereal *) dmatrix);
2235 xpose_c(dmatrix, dmatrix);
2249 QString msg =
"Only CK, DYN, and PCK partials can be calculated";
2254 for (
int row = 0; row < 3; row++) {
2255 for (
int col = 0; col < 3; col++) {
2256 dmatrix[row][col] *= dpoly;
2262 switch (angleIndex) {
2264 rotmat_c(dmatrix, angles[1], axes[1], dCJ);
2265 rotmat_c(dCJ, angles[2], axes[2], dCJ);
2268 rotate_c(angles[0], axes[0], dCJ);
2269 mxm_c(dmatrix, dCJ, dCJ);
2270 rotmat_c(dCJ, angles[2], axes[2], dCJ);
2273 rotate_c(angles[0], axes[0], dCJ);
2274 rotmat_c(dCJ, angles[1], axes[1], dCJ);
2275 mxm_c(dmatrix, dCJ, dCJ);
2281 mxm_c((SpiceDouble *) &
p_TC[0], dCJ[0], dTJ);
2285 std::vector<double> lookdT(3);
2287 mxv_c(dTJ, (
const SpiceDouble *) &lookJ[0], (SpiceDouble *) &lookdT[0]);
2304 double diff1 = compareAngle - angle;
2306 if (diff1 < -1 * pi_c()) {
2309 else if (diff1 > pi_c()) {
2349 for (
int icoef =
p_degree + 1; icoef <= degree; icoef++) {
2350 coefAngle1.push_back(0.);
2351 coefAngle2.push_back(0.);
2352 coefAngle3.push_back(0.);
2359 std::vector<double> coefAngle1(degree + 1),
2360 coefAngle2(degree + 1),
2361 coefAngle3(degree + 1);
2363 for (
int icoef = 0; icoef <= degree; icoef++) {
2438 if (axis1 < 1 || axis2 < 1 || axis3 < 1 || axis1 > 3 || axis2 > 3 || axis3 > 3) {
2439 QString msg =
"A rotation axis is outside the valid range of 1 to 3";
2466 double currentTime = observStart;
2467 bool timeLoaded =
false;
2472 ktotal_c(
"ck", (SpiceInt *) &count);
2481 "Full cache size does NOT match cache size in LoadTimeCache -- should never happen";
2490 std::vector<ale::Rotation> fullRotationCache = m_orientation->getRotations();
2491 std::vector<ale::Vec3d> angularVelocities = m_orientation->getAngularVelocities();
2494 std::vector<double> rotationMatrix = fullRotationCache[r].toRotationMatrix();
2495 SpiceDouble CJ[9] = { rotationMatrix[0], rotationMatrix[1], rotationMatrix[2],
2496 rotationMatrix[3], rotationMatrix[4], rotationMatrix[5],
2497 rotationMatrix[6], rotationMatrix[7], rotationMatrix[8]
2499 m2q_c(CJ, quats[r]);
2501 ale::Vec3d angularVelocity = angularVelocities[r];
2502 vequ_c((SpiceDouble *) &angularVelocity.x, avvs[r]);
2506 double cubeStarts = timeSclkdp[0];
2507 double radTol = 0.000000017453;
2508 SpiceInt avflag = 1;
2514 ck3sdn(radTol, avflag, (
int *) &sizOut, timeSclkdp, (doublereal *) quats,
2515 (SpiceDouble *) avvs, nints, &cubeStarts, dparr, (
int *) intarr);
2519 std::vector<double> av;
2522 if (m_orientation) {
2523 delete m_orientation;
2524 m_orientation = NULL;
2527 std::vector<ale::Rotation> rotationCache;
2528 std::vector<ale::Vec3d> avCache;
2530 for (
int r = 0; r < sizOut; r++) {
2535 std::vector<double> CJ(9);
2536 q2m_c(quats[r], (SpiceDouble( *)[3]) &CJ[0]);
2537 rotationCache.push_back(CJ);
2538 vequ_c(avvs[r], (SpiceDouble *) &av[0]);
2539 avCache.push_back(av);
2542 if (
p_TC.size() > 1 ) {
2543 m_orientation =
new ale::Orientations(rotationCache,
p_cacheTime, avCache,
2547 m_orientation =
new ale::Orientations(rotationCache,
p_cacheTime, std::vector<ale::Vec3d>(),
2560 int SOURCESIZ = 128;
2563 SpiceChar file[FILESIZ];
2564 SpiceChar filtyp[TYPESIZ];
2565 SpiceChar source[SOURCESIZ];
2568 bool observationSpansToNextSegment =
false;
2573 kdata_c(0,
"ck", FILESIZ, TYPESIZ, SOURCESIZ, file, filtyp, source, &handle, &found);
2579 observationSpansToNextSegment =
false;
2590 dafus_c(sum, (SpiceInt) 2, (SpiceInt) 6, dc, ic);
2593 if (ic[2] == 5)
break;
2596 if (ic[0] == spCode && ic[2] == 3) {
2597 sct2e_c((
int) spCode / 1000, dc[0], &segStartEt);
2598 sct2e_c((
int) spCode / 1000, dc[1], &segStopEt);
2603 if (currentTime >= segStartEt && currentTime <= segStopEt) {
2607 if (observationSpansToNextSegment && currentTime > segStartEt) {
2608 QString msg =
"Observation crosses segment boundary--unable to interpolate pointing";
2611 if (observEnd > segStopEt) {
2612 observationSpansToNextSegment =
true;
2616 int dovelocity = ic[3];
2619 dafgda_c(handle, end - 1, end, val);
2621 int ninstances = (int) val[1];
2622 int numvel = dovelocity * 3;
2623 int quatnoff = ic[4] + (4 + numvel) * ninstances - 1;
2625 int sclkdp1off = quatnoff + 1;
2626 int sclkdpnoff = sclkdp1off + ninstances - 1;
2629 int sclkSpCode = spCode / 1000;
2632 std::vector<double> sclkdp(ninstances);
2633 dafgda_c(handle, sclkdp1off, sclkdpnoff, (SpiceDouble *) &sclkdp[0]);
2636 sct2e_c(sclkSpCode, sclkdp[0], &et);
2638 while (instance < (ninstances - 1) && et < currentTime) {
2640 sct2e_c(sclkSpCode, sclkdp[instance], &et);
2643 if (instance > 0) instance--;
2644 sct2e_c(sclkSpCode, sclkdp[instance], &et);
2646 while (instance < (ninstances - 1) && et < observEnd) {
2649 sct2e_c(sclkSpCode, sclkdp[instance], &et);
2653 if (!observationSpansToNextSegment) {
2659 currentTime = segStopEt;
2668 QString msg =
"No camera kernels loaded...Unable to determine time cache to downsize";
2675 double cacheSlope = 0.0;
2699 QString msg =
"Time cache not available -- rerun spiceinit";
2703 std::vector<double> fullCacheTime;
2704 double cacheSlope = 0.0;
2712 return fullCacheTime;
2738 std::vector<int> frameCodes;
2739 std::vector<int> frameTypes;
2742 while (frameCodes[frameCodes.size()-1] != J2000Code) {
2743 frmidx = frameCodes.size() - 1;
2751 frinfo_c((SpiceInt) frameCodes[frmidx],
2752 (SpiceInt *) ¢er,
2754 (SpiceInt *) &typid, &found);
2759 frameTypes.push_back(0);
2763 QString msg =
"The frame" +
toString((
int) frameCodes[frmidx]) +
" is not supported by Naif";
2767 double matrix[3][3];
2771 nextFrame = J2000Code;
2773 else if (type == CK) {
2774 ckfrot_((SpiceInt *) &typid, &et, (
double *) matrix, &nextFrame, (logical *) &found);
2779 frameTypes.push_back(0);
2783 QString msg =
"The ck rotation from frame " +
toString(frameCodes[frmidx]) +
" can not "
2784 +
"be found due to no pointing available at requested time or a problem with the "
2789 else if (type == TK) {
2790 tkfram_((SpiceInt *) &typid, (
double *) matrix, &nextFrame, (logical *) &found);
2792 QString msg =
"The tk rotation from frame " +
toString(frameCodes[frmidx]) +
2793 " can not be found";
2797 else if (type == DYN) {
2804 zzdynrot_((SpiceInt *) &typid, (SpiceInt *) ¢er, &et, (
double *) matrix, &nextFrame);
2808 QString msg =
"The frame " +
toString(frameCodes[frmidx]) +
2809 " has a type " +
toString(type) +
" not supported by your version of Naif Spicelib."
2810 +
"You need to update.";
2814 frameCodes.push_back(nextFrame);
2815 frameTypes.push_back(type);
2826 while (frameTypes[nConstants] == TK && nConstants < (
int) frameTypes.size()) nConstants++;
2829 for (
int i = 0; i <= nConstants; i++) {
2834 for (
int i = nConstants; i < (int) frameCodes.size(); i++) {
2854 std::vector<double> TJ;
2856 mxm_c((SpiceDouble *) &
p_TC[0], (SpiceDouble *) &
p_CJ[0], (SpiceDouble( *) [3]) &TJ[0]);
2869 std::vector<double> q;
2871 m2q_c((SpiceDouble( *)[3]) &
p_TC[0], &q[0]);
2893 p_TC = constantMatrix;
2904 std::vector<double> q;
2906 m2q_c((SpiceDouble( *)[3]) &
p_CJ[0], &q[0]);
2928 p_CJ = timeBasedMatrix;
2944 refchg_((SpiceInt *) &fromFrame, (SpiceInt *) &targetFrame, &et, (doublereal *) &
p_TC[0]);
2946 xpose_c((SpiceDouble( *)[3]) &
p_TC[0], (SpiceDouble( *)[3]) &
p_TC[0]);
2974 QString msg =
"The SpiceRotation pointing angles must be fit to polynomials in order to ";
2975 msg +=
"compute angular velocity.";
2979 QString msg =
"Planetary angular velocity must be fit computed with PCK polynomials ";
2982 std::vector<double> dCJdt;
3000 mtxm_c((SpiceDouble( *)[3]) &dCJdt[0], (SpiceDouble( *)[3]) &
p_CJ[0], omega);
3001 p_av[0] = omega[2][1];
3002 p_av[1] = omega[0][2];
3003 p_av[2] = omega[1][0];
3021 double dmatrix[3][3];
3023 double wmatrix[3][3];
3026 for (
int angleIndex = 0; angleIndex < 3; angleIndex++) {
3027 drotat_(&(angles[angleIndex]), (integer *) axes + angleIndex, (doublereal *) dmatrix);
3029 xpose_c(dmatrix, dmatrix);
3041 for (
int row = 0; row < 3; row++) {
3042 for (
int col = 0; col < 3; col++) {
3043 dmatrix[row][col] *= dangle;
3047 switch (angleIndex) {
3049 rotmat_c(dmatrix, angles[1], axes[1], dmatrix);
3050 rotmat_c(dmatrix, angles[2], axes[2], dmatrix);
3053 rotate_c(angles[0], axes[0], wmatrix);
3054 mxm_c(dmatrix, wmatrix, dmatrix);
3055 rotmat_c(dmatrix, angles[2], axes[2], dmatrix);
3058 rotate_c(angles[0], axes[0], wmatrix);
3059 rotmat_c(wmatrix, angles[1], axes[1], wmatrix);
3060 mxm_c(dmatrix, wmatrix, dmatrix);
3064 for (
int index = 0; index < 9; index++) {
3067 dCJ[index] += dmatrix[i][j];
3081 std::vector<double> stateTJ(36);
3084 double stateCJ[6][6];
3085 rav2xf_c(&
p_CJ[0], &
p_av[0], stateCJ);
3091 for (
int row = 3; row < 6; row++) {
3095 for (
int col = 0; col < 3; col++) {
3098 stateTJ[irow*6 + col] =
p_TC[vpos] * stateCJ[0][col] +
p_TC[vpos+1] * stateCJ[1][col]
3099 +
p_TC[vpos+2] * stateCJ[2][col];
3101 stateTJ[row*6 + col] =
p_TC[vpos] * stateCJ[3][col] +
p_TC[vpos+1] * stateCJ[4][col]
3102 +
p_TC[vpos+2] * stateCJ[5][col];
3104 stateTJ[irow*6 + jcol] = 0;
3106 stateTJ[row*6 +jcol] = stateTJ[irow*6 + col];
3130 double diffTime = timeEt -
p_et;
3131 std::vector<double> CJ(9, 0.0);
3136 axisar_c((SpiceDouble *) &
p_av[0], diffTime*vnorm_c((SpiceDouble *) &
p_av[0]), dmat);
3139 mxm_c(dmat, (SpiceDouble *) &
p_CJ[0], (SpiceDouble( *)[3]) &CJ[0]);
3170 ktotal_c(
"PCK", &count);
3175 int SOURCESIZ = 128;
3176 SpiceChar file[FILESIZ];
3177 SpiceChar filetype[TYPESIZ];
3178 SpiceChar source[SOURCESIZ];
3185 for (SpiceInt knum = 0; knum < count; knum++){
3186 kdata_c(knum,
"PCK", FILESIZ, TYPESIZ, SOURCESIZ, file, filetype, source, &handle, &found);
3189 if (strstr(file,
"bpc") != NULL) {
3206 SpiceInt centerBodyCode;
3207 SpiceInt frameClass;
3209 frinfo_c(frameCode, ¢erBodyCode, &frameClass, &classId, &found);
3212 if (frameClass == 2 || (centerBodyCode > 0 && frameClass != 3)) {
3218 for (std::vector<int>::size_type idx = 1; idx <
p_constantFrames.size(); idx++) {
3220 frinfo_c(frameCode, ¢erBodyCode, &frameClass, &classId, &found);
3225 switch (frameClass) {
3259 p_CJ = m_orientation->getRotations()[0].toRotationMatrix();
3261 ale::Vec3d av = m_orientation->getAngularVelocities()[0];
3269 p_CJ = m_orientation->interpolateTimeDep(
p_et).toRotationMatrix();
3272 ale::Vec3d av = m_orientation->interpolateAV(
p_et);
3297 SpiceDouble stateJ[6];
3300 spkez_c((SpiceInt) spkCode,
p_et,
"J2000",
"LT+S",
3304 SpiceDouble sJ[3], svJ[3];
3305 vpack_c(-1 * stateJ[0], -1 * stateJ[1], -1 * stateJ[2], sJ);
3306 vpack_c(stateJ[3], stateJ[4], stateJ[5], svJ);
3311 (SpiceDouble( *)[3]) &
p_CJ[0]);
3328 SpiceInt j2000 = J2000Code;
3336 double stateCJ[6][6];
3337 frmchg_((integer *) &j2000, (integer *) &toFrame, &time, (doublereal *) stateCJ);
3342 SpiceBoolean ckfailure = failed_c();
3346 xpose6_c(stateCJ, stateCJ);
3347 xf2rav_c(stateCJ, (SpiceDouble( *)[3]) &
p_CJ[0], (SpiceDouble *) &
p_av[0]);
3351 refchg_((integer *) &j2000, (integer *) &toFrame, &time, (SpiceDouble *) &
p_CJ[0]);
3355 getmsg_c(
"SHORT",
sizeof(naifstr), naifstr);
3358 if (eqstr_c(naifstr,
"SPICE(UNKNOWNFRAME)")) {
3360 "reference frame code. Has the mission frames kernel been loaded?";
3364 Isis::IString msg =
"No pointing available at requested time [" +
3372 xpose_c((SpiceDouble( *)[3]) &
p_CJ[0], (SpiceDouble( *)[3]) &
p_CJ[0]);
3395 std::vector<double> rtime;
3397 std::vector<double> angles;
3398 angles.push_back(function1.Evaluate(rtime));
3399 angles.push_back(function2.Evaluate(rtime));
3400 angles.push_back(function3.Evaluate(rtime));
3403 if (angles[0] <= -1 * pi_c()) {
3404 angles[0] += twopi_c();
3406 else if (angles[0] > pi_c()) {
3407 angles[0] -= twopi_c();
3430 std::vector<double> rtime;
3432 double angle1 = function1.Evaluate(rtime);
3433 double angle2 = function2.Evaluate(rtime);
3434 double angle3 = function3.Evaluate(rtime);
3437 if (angle1 < -1 * pi_c()) {
3438 angle1 += twopi_c();
3440 else if (angle1 > pi_c()) {
3441 angle1 -= twopi_c();
3444 eul2m_c((SpiceDouble) angle3, (SpiceDouble) angle2, (SpiceDouble) angle1,
3446 (SpiceDouble( *)[3]) &
p_CJ[0]);
3450 ale::Vec3d av = m_orientation->getAngularVelocities()[0];
3472 std::vector<double> cacheAngles(3);
3473 std::vector<double> cacheVelocity(3);
3475 cacheVelocity =
p_av;
3477 std::vector<double> polyAngles(3);
3481 std::vector<double> polyVelocity(3);
3482 polyVelocity =
p_av;
3483 std::vector<double> angles(3);
3485 for (
int index = 0; index < 3; index++) {
3486 angles[index] = cacheAngles[index] + polyAngles[index];
3487 p_av[index] += cacheVelocity[index];
3490 if (angles[0] <= -1 * pi_c()) {
3491 angles[0] += twopi_c();
3493 else if (angles[0] > pi_c()) {
3494 angles[0] -= twopi_c();
3497 if (angles[2] <= -1 * pi_c()) {
3498 angles[2] += twopi_c();
3500 else if (angles[2] > pi_c()) {
3501 angles[2] -= twopi_c();
3504 eul2m_c((SpiceDouble) angles[2], (SpiceDouble) angles[1], (SpiceDouble) angles[0],
3506 (SpiceDouble( *)[3]) &
p_CJ[0]);
3517 double dTime =
p_et / 86400.;
3518 double centTime = dTime / 36525;
3519 double secondsPerJulianCentury = 86400. * 36525.;
3537 for (
int ia = 0; ia < numNutPrec; ia++) {
3540 costheta = cos(theta.radians());
3541 sintheta = sin(theta.radians());
3553 if (ra.radians() < -1 * pi_c()) {
3556 else if (ra.radians() > pi_c()) {
3560 if (pm.radians() < -1 * pi_c()) {
3563 else if (pm.radians() > pi_c()) {
3568 SpiceDouble phi = ra.radians() +
HALFPI;
3569 SpiceDouble delta =
HALFPI - dec.radians();
3570 SpiceDouble w = pm.radians();
3571 SpiceDouble dphi = dra.radians();
3572 SpiceDouble ddelta = -ddec.radians();
3573 SpiceDouble dw = dpm.radians();
3576 SpiceDouble angsDangs[6];
3577 SpiceDouble BJs[6][6];
3578 vpack_c(w, delta, phi, angsDangs);
3579 vpack_c(dw, ddelta, dphi, &angsDangs[3]);
3583 xf2rav_c(BJs, (SpiceDouble( *)[3]) &
p_CJ[0], (SpiceDouble *) &
p_av[0]);
Defines an angle and provides unit conversions.
double degrees() const
Get the angle in units of Degrees.
@ 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...
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.
Utility class for creating and using cartesean line equations.
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.
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 ...
void clear()
Remove everything from the current PvlObject.
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 > p_quaternion
Quaternion.
Obtain SPICE information for a spacecraft.
Obtain SPICE rotation information for a body.
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.
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.