diff --git a/ext/ghoul b/ext/ghoul index 21e9aa96f6..5c11a98058 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit 21e9aa96f62fc7aea06dc61827db2acc8ad02024 +Subproject commit 5c11a98058a10078c7802006563a9d8989bd7e27 diff --git a/include/openspace/util/spicemanager.h b/include/openspace/util/spicemanager.h index b3c73cd94f..3be9fa982e 100644 --- a/include/openspace/util/spicemanager.h +++ b/include/openspace/util/spicemanager.h @@ -57,6 +57,64 @@ public: explicit SpiceKernelException(const std::string& msg); }; + /** + * Specifies the aberration correction method for the #targetPosition function. + * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/spkpos_c.html + */ + class AberrationCorrection { + public: + /// The type of the aberration correction + enum class Type { + None = 0, ///< No correction (NONE) + LightTime, ///< One-way light time (LT) + LightTimeStellar, ///< One-way light time and stellar (LT+S) + ConvergedNewtonian, ///< Converged newtonian light time (CN) + ConvergedNewtonianStellar ///< Converged newtonian + stellar (CN+S) + }; + /// The direction of the aberration correct + enum class Direction { + Reception = 0, + Transmission + }; + + /** + * Default constructor initializing the AberrationCorrection to Type::None with a + * Drection::Reception + */ + AberrationCorrection() = default; + + /** + * Constructor initializing the AberrationCorrection to the provided \p type and + * \p direction + * \param type The type of the aberration correction (AberrationCorrection::Type) + * \param direction The used direction (AberrationCorrection::Direction) + */ + AberrationCorrection(Type type, Direction direction); + + /** + * Converts one of the valid aberration correction strings into its enumeration + * format. The valid strings are: + * NONE, LT, LT+S, CN, + * CN+S, XLT, XLT+S, XCN, and + * XCN+S. + * \param identifier The identifier that should be converted into the enumeration + * Type and Direction + * \pre The \p identifier must not be empty and be of one of the valid strings + */ + explicit AberrationCorrection(const std::string& identifier); + + /** + * Returns the string representation of this Aberration Correction + * \return The string representation of this Aberration correction + */ + operator std::string() const; + + /// The type of aberration correction + Type type = Type::None; + /// The direction of the aberration correction + Direction direction = Direction::Reception; + }; + /** * Loads one or more SPICE kernels into a program. The provided path can either be a * binary, text-kernel, or meta-kernel which gets loaded into the kernel pool. The @@ -344,34 +402,37 @@ public: const std::string& formatString = "YYYY MON DDTHR:MN:SC.### ::RND") const; /** - * Returns the \t position of a \t target body relative to an \t observer in a - * specific \t referenceFrame, optionally corrected for \t lightTime (planetary - * aberration) and stellar aberration (\t aberrationCorrection). + * Returns the \p position of a \p target body relative to an \p observer in a + * specific \p referenceFrame, optionally corrected for \p lightTime (planetary + * aberration) and stellar aberration (\p aberrationCorrection). * \param target The target body name or the target body's NAIF ID * \param observer The observing body name or the observing body's NAIF ID * \param referenceFrame The reference frame of the output position vector - * \param aberrationCorrection The aberration correction flag out of the list of - * values (NONE, LT, LT+S, CN, - * CN+S for the reception case or XLT, XLT+S, - * XCN, or XCN+S for the transmission case. + * \param aberrationCorrection The aberration correction used for the position + * calculation * \param ephemerisTime The time at which the position is to be queried - * \param position The output containing the position of the target; if the method - * fails, the target position is unchanged - * \param lightTime If the aberrationCorrection is different from - * NONE, this variable will contain the one-way light time between the - * observer and the target. If the method fails, the lightTime is unchanged - * \return true if the function was successful, false - * otherwise + * \param lightTime If the \p aberrationCorrection is different from + * AbberationCorrection::Type::None, this variable will contain the light time between + * the observer and the target. + * \return The position of the \p target relative to the \p observer in the specified + * \p referenceFrame + * \throws SpiceKernelException If the \p target or \p observer do not name a valid + * NAIF object, \p referenceFrame does not name a valid reference frame or if there is + * not sufficient data available to compute the position or neither the target nor the + * observer have coverage. + * \pre \p target must not be empty + * \pre \p observer must not be empty + * \pre \p referenceFrame must not be empty + * \post If an exception is thrown, \p lightTime will not be modified * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/spkpos_c.html * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/naif_ids.html */ - bool getTargetPosition(const std::string& target, - const std::string& observer, - const std::string& referenceFrame, - const std::string& aberrationCorrection, - double ephemerisTime, - glm::dvec3& position, - double& lightTime) const; + glm::dvec3 targetPosition(const std::string& target, + const std::string& observer, + const std::string& referenceFrame, + AberrationCorrection abberationCorrection, + double ephemerisTime, + double& lightTime) const; /** * If a position is requested for an uncovered time in the SPK kernels, * this function will insert a position in modelPosition. diff --git a/modules/base/ephemeris/spiceephemeris.cpp b/modules/base/ephemeris/spiceephemeris.cpp index b4ec10e344..85e12f474f 100644 --- a/modules/base/ephemeris/spiceephemeris.cpp +++ b/modules/base/ephemeris/spiceephemeris.cpp @@ -81,10 +81,9 @@ void SpiceEphemeris::update(const UpdateData& data) { if (!_kernelsLoadedSuccessfully) return; - glm::dvec3 position(0,0,0); double lightTime = 0.0; - SpiceManager::ref().getTargetPosition(_targetName, _originName, - "GALACTIC", "NONE", data.time, position, lightTime); + glm::dvec3 position = SpiceManager::ref().targetPosition(_targetName, _originName, + "GALACTIC", SpiceManager::AberrationCorrection(), data.time, lightTime); //double interval = openspace::ImageSequencer2::ref().getIntervalLength(); //if (_ghosting == "TRUE" && interval > 60){ diff --git a/modules/base/rendering/renderablemodel.cpp b/modules/base/rendering/renderablemodel.cpp index 964c5bc4bf..d76787cf3b 100644 --- a/modules/base/rendering/renderablemodel.cpp +++ b/modules/base/rendering/renderablemodel.cpp @@ -183,8 +183,8 @@ void RenderableModel::render(const RenderData& data) { else _alpha = 1.0f; - glm::dvec3 p; - SpiceManager::ref().getTargetPosition(_target, "SUN", "GALACTIC", "NONE", time, p, lt); + glm::dvec3 p = + SpiceManager::ref().targetPosition(_target, "SUN", "GALACTIC", SpiceManager::AberrationCorrection(), time, lt); psc tmppos = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); glm::vec3 cam_dir = glm::normalize(data.camera.position().vec3() - tmppos.vec3()); _programObject->setUniform("cam_dir", cam_dir); @@ -246,8 +246,8 @@ void RenderableModel::update(const UpdateData& data) { openspace::SpiceManager::ref().getPositionTransformMatrix(_source, _destination, _time, _stateMatrix); double lt; - glm::dvec3 p; - openspace::SpiceManager::ref().getTargetPosition("SUN", _target, "GALACTIC", "NONE", _time, p, lt); + glm::dvec3 p = + openspace::SpiceManager::ref().targetPosition("SUN", _target, "GALACTIC", SpiceManager::AberrationCorrection(), _time, lt); _sunPosition = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); } diff --git a/modules/base/rendering/renderablepath.cpp b/modules/base/rendering/renderablepath.cpp index fc257a2074..784caa4ba2 100644 --- a/modules/base/rendering/renderablepath.cpp +++ b/modules/base/rendering/renderablepath.cpp @@ -222,8 +222,8 @@ void RenderablePath::calculatePath(std::string observer) { //float g = _lineColor[1]; //float b = _lineColor[2]; for (int i = 0; i < segments; i++) { - glm::dvec3 p; - SpiceManager::ref().getTargetPosition(_target, observer, _frame, "NONE", currentTime, p, lightTime); + glm::dvec3 p = + SpiceManager::ref().targetPosition(_target, observer, _frame, SpiceManager::AberrationCorrection(), currentTime, lightTime); pscPos = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); pscPos[3] += 3; diff --git a/modules/base/rendering/renderableplanet.cpp b/modules/base/rendering/renderableplanet.cpp index ee14c7fcbc..7ef837325c 100644 --- a/modules/base/rendering/renderableplanet.cpp +++ b/modules/base/rendering/renderableplanet.cpp @@ -182,8 +182,8 @@ void RenderablePlanet::render(const RenderData& data) double lt; - glm::dvec3 p; - openspace::SpiceManager::ref().getTargetPosition("SUN", _target, "GALACTIC", "NONE", _time, p, lt); + glm::dvec3 p = + SpiceManager::ref().targetPosition("SUN", _target, "GALACTIC", SpiceManager::AberrationCorrection(), _time, lt); psc sun_pos = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); // setup the data to the shader diff --git a/modules/base/rendering/renderabletrail.cpp b/modules/base/rendering/renderabletrail.cpp index 9abb87ad63..9ce516c87b 100644 --- a/modules/base/rendering/renderabletrail.cpp +++ b/modules/base/rendering/renderabletrail.cpp @@ -219,11 +219,11 @@ void RenderableTrail::update(const UpdateData& data) { glm::dvec3 p; // Update the floating current time if (start > data.time) - SpiceManager::ref().getTargetPosition(_target, _observer, _frame, "NONE", start, p, lightTime); + p = SpiceManager::ref().targetPosition(_target, _observer, _frame, SpiceManager::AberrationCorrection(), start, lightTime); else if (end < data.time) - SpiceManager::ref().getTargetPosition(_target, _observer, _frame, "NONE", end, p, lightTime); + p = SpiceManager::ref().targetPosition(_target, _observer, _frame, SpiceManager::AberrationCorrection(), end, lightTime); else - SpiceManager::ref().getTargetPosition(_target, _observer, _frame, "NONE", data.time, p, lightTime); + p = SpiceManager::ref().targetPosition(_target, _observer, _frame, SpiceManager::AberrationCorrection(), data.time, lightTime); psc pscPos = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); @@ -246,8 +246,8 @@ void RenderableTrail::update(const UpdateData& data) { et = start; else if (end < et) et = end; - glm::dvec3 p; - SpiceManager::ref().getTargetPosition(_target, _observer, _frame, "NONE", et, p, lightTime); + glm::dvec3 p = + SpiceManager::ref().targetPosition(_target, _observer, _frame, SpiceManager::AberrationCorrection(), et, lightTime); pscPos = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); pscPos[3] += 3; _vertexArray[i] = { pscPos[0], pscPos[1], pscPos[2], pscPos[3] }; @@ -289,6 +289,7 @@ void RenderableTrail::fullYearSweep(double time) { _oldTime = time; _vertexArray.resize(segments+2); + glm::dvec3 p; for (int i = 0; i < segments+2; i++) { if (start > time && intervalSet) { time = start; @@ -297,8 +298,16 @@ void RenderableTrail::fullYearSweep(double time) { time = end; } - glm::dvec3 p; - SpiceManager::ref().getTargetPosition(_target, _observer, _frame, "NONE", time, p, lightTime); + try { + p = + SpiceManager::ref().targetPosition(_target, _observer, _frame, SpiceManager::AberrationCorrection(), time, lightTime); + } + catch (const SpiceManager::SpiceKernelException& e) { + // This fires for PLUTO BARYCENTER and SUN and uses the only value sometimes? + // ---abock +// LERROR(e.what()); + } + psc pscPos = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); pscPos[3] += 3; diff --git a/modules/newhorizons/rendering/renderablefov.cpp b/modules/newhorizons/rendering/renderablefov.cpp index aa501b5e7b..5a398a5773 100644 --- a/modules/newhorizons/rendering/renderablefov.cpp +++ b/modules/newhorizons/rendering/renderablefov.cpp @@ -80,7 +80,9 @@ RenderableFov::RenderableFov(const ghoul::Dictionary& dictionary) success = dictionary.getValue(keyInstrumentMethod, _method); ghoul_assert(success, ""); - success = dictionary.getValue(keyInstrumentAberration, _aberrationCorrection); + std::string a = "NONE"; + success = dictionary.getValue(keyInstrumentAberration, a); + a = SpiceManager::AberrationCorrection(a); ghoul_assert(success, ""); ghoul::Dictionary potentialTargets; @@ -241,8 +243,8 @@ psc RenderableFov::checkForIntercept(glm::dvec3 ray) { } // Orthogonal projection next to planets surface psc RenderableFov::orthogonalProjection(glm::dvec3 vecFov) { - glm::dvec3 vecToTarget; - SpiceManager::ref().getTargetPosition(_fovTarget, _spacecraft, _frame, _aberrationCorrection, _time, vecToTarget, _lt); + glm::dvec3 vecToTarget = + SpiceManager::ref().targetPosition(_fovTarget, _spacecraft, _frame, _aberrationCorrection, _time, _lt); openspace::SpiceManager::ref().frameConversion(vecFov, _instrumentID, _frame, _time); glm::dvec3 p = openspace::SpiceManager::ref().orthogonalProjection(vecToTarget, vecFov); @@ -446,13 +448,12 @@ void RenderableFov::computeIntercepts(const RenderData& data){ fovSurfaceIntercept(_interceptTag, _bounds); glm::vec3 aim = (_spacecraftRotation * glm::vec4(_boresight, 1)).xyz(); - glm::dvec3 position; - SpiceManager::ref().getTargetPosition(_fovTarget, + glm::dvec3 position = + SpiceManager::ref().targetPosition(_fovTarget, _spacecraft, _frame, _aberrationCorrection, _time, - position, _lt); psc p = PowerScaledCoordinate::CreatePowerScaledCoordinate(position.x, position.y, position.z); pss length = p.length(); diff --git a/modules/newhorizons/rendering/renderablefov.h b/modules/newhorizons/rendering/renderablefov.h index 5d16737c22..0b2179dd3a 100644 --- a/modules/newhorizons/rendering/renderablefov.h +++ b/modules/newhorizons/rendering/renderablefov.h @@ -36,6 +36,7 @@ #include //#include #include +#include namespace openspace { class RenderableFov : public Renderable{ @@ -96,7 +97,7 @@ public: std::string _frame; std::string _instrumentID; std::string _method; - std::string _aberrationCorrection; + SpiceManager::AberrationCorrection _aberrationCorrection; std::string _fovTarget; glm::dvec3 ipoint, ivec; glm::dvec3 _previousHalf; diff --git a/modules/newhorizons/rendering/renderablemodelprojection.cpp b/modules/newhorizons/rendering/renderablemodelprojection.cpp index 12725cb38c..a2670285b0 100644 --- a/modules/newhorizons/rendering/renderablemodelprojection.cpp +++ b/modules/newhorizons/rendering/renderablemodelprojection.cpp @@ -136,11 +136,12 @@ RenderableModelProjection::RenderableModelProjection(const ghoul::Dictionary& di completeSuccess &= dictionary.getValue(keyInstrumentNear, _nearPlane); completeSuccess &= dictionary.getValue(keyInstrumentFar, _farPlane); ghoul_assert(completeSuccess, "All neccessary attributes not found in modfile"); - - completeSuccess = dictionary.getValue(keyProjAberration, _aberration); - if (!completeSuccess) - _aberration = "NONE"; - + + std::string a = "NONE"; + bool s = dictionary.getValue(keyProjAberration, a); + _aberration = SpiceManager::AberrationCorrection(a); + completeSuccess &= s; + openspace::SpiceManager::ref().addFrame(_target, _source); setBoundingSphere(pss(1.f, 9.f)); @@ -354,8 +355,8 @@ void RenderableModelProjection::update(const UpdateData& data) { openspace::SpiceManager::ref().getPositionTransformMatrix(_source, _destination, _time, _stateMatrix); double lt; - glm::dvec3 p; - openspace::SpiceManager::ref().getTargetPosition("SUN", _target, "GALACTIC", "NONE", _time, p, lt); + glm::dvec3 p = + openspace::SpiceManager::ref().targetPosition("SUN", _target, "GALACTIC", SpiceManager::AberrationCorrection(), _time, lt); _sunPosition = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); } @@ -429,8 +430,8 @@ void RenderableModelProjection::attitudeParameters(double time) { return; double lightTime; - glm::dvec3 p; - found = SpiceManager::ref().getTargetPosition(_projectorID, _projecteeID, _destination, _aberration, time, p, lightTime); + glm::dvec3 p = + SpiceManager::ref().targetPosition(_projectorID, _projecteeID, _destination, _aberration, time, lightTime); psc position = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); position[3] += (3 + _camScaling[1]); diff --git a/modules/newhorizons/rendering/renderablemodelprojection.h b/modules/newhorizons/rendering/renderablemodelprojection.h index 4508094e30..9f24290222 100644 --- a/modules/newhorizons/rendering/renderablemodelprojection.h +++ b/modules/newhorizons/rendering/renderablemodelprojection.h @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -104,7 +105,7 @@ namespace openspace { std::string _instrumentID; std::string _projectorID; std::string _projecteeID; - std::string _aberration; + SpiceManager::AberrationCorrection _aberration; std::vector _potentialTargets; float _fovy; float _aspectRatio; diff --git a/modules/newhorizons/rendering/renderableplaneprojection.cpp b/modules/newhorizons/rendering/renderableplaneprojection.cpp index c3a037988e..1ba59f60f9 100644 --- a/modules/newhorizons/rendering/renderableplaneprojection.cpp +++ b/modules/newhorizons/rendering/renderableplaneprojection.cpp @@ -228,12 +228,18 @@ void RenderablePlaneProjection::updatePlane(const Image img, double currentTime) return; } - glm::dvec3 vecToTarget; double lt; psc projection[4]; - SpiceManager::ref().getTargetPosition(_target.body, _spacecraft, GalacticFrame, "CN+S", currentTime, vecToTarget, lt); - // The apparent position, CN+S, makes image align best with target + glm::dvec3 vecToTarget = SpiceManager::ref().targetPosition( + _target.body, + _spacecraft, + GalacticFrame, + { SpiceManager::AberrationCorrection::Type::ConvergedNewtonianStellar, SpiceManager::AberrationCorrection::Direction::Reception }, + currentTime, + lt + ); + // The apparent position, CN+S, makes image align best with target for (int j = 0; j < bounds.size(); ++j) { openspace::SpiceManager::ref().frameConversion(bounds[j], frame, GalacticFrame, currentTime); @@ -321,9 +327,9 @@ std::string RenderablePlaneProjection::findClosestTarget(double currentTime) { std::string closestTarget = ""; - glm::dvec3 p; double lt; - SpiceManager::ref().getTargetPosition(_spacecraft, "SSB", GalacticFrame, "NONE", currentTime, p, lt); + glm::dvec3 p = + SpiceManager::ref().targetPosition(_spacecraft, "SSB", GalacticFrame, SpiceManager::AberrationCorrection(), currentTime, lt); psc spacecraftPos = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); diff --git a/modules/newhorizons/rendering/renderableplanetprojection.cpp b/modules/newhorizons/rendering/renderableplanetprojection.cpp index 3e1fe3805d..3bca6c46c6 100644 --- a/modules/newhorizons/rendering/renderableplanetprojection.cpp +++ b/modules/newhorizons/rendering/renderableplanetprojection.cpp @@ -120,7 +120,9 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary& bool b1 = dictionary.getValue(keyInstrument, _instrumentID); bool b2 = dictionary.getValue(keyProjObserver, _projectorID); bool b3 = dictionary.getValue(keyProjTarget, _projecteeID); - bool b4 = dictionary.getValue(keyProjAberration, _aberration); + std::string a = "NONE"; + bool b4 = dictionary.getValue(keyProjAberration, a); + _aberration = SpiceManager::AberrationCorrection(a); bool b5 = dictionary.getValue(keyInstrumentFovy, _fovy); bool b6 = dictionary.getValue(keyInstrumentAspect, _aspectRatio); bool b7 = dictionary.getValue(keyInstrumentNear, _nearPlane); @@ -430,8 +432,7 @@ void RenderablePlanetProjection::attitudeParameters(double time){ if (!found) return ; - glm::dvec3 p; - found = SpiceManager::ref().getTargetPosition(_projectorID, _projecteeID, _mainFrame, _aberration, time, p, lightTime); + glm::dvec3 p = SpiceManager::ref().targetPosition(_projectorID, _projecteeID, _mainFrame, _aberration, time, lightTime); psc position = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); //change to KM and add psc camera scaling. @@ -510,8 +511,8 @@ void RenderablePlanetProjection::render(const RenderData& data){ _imageTimes.clear(); double lt; - glm::dvec3 p; - openspace::SpiceManager::ref().getTargetPosition("SUN", _projecteeID, "GALACTIC", "NONE", _time, p, lt); + glm::dvec3 p = + openspace::SpiceManager::ref().targetPosition("SUN", _projecteeID, "GALACTIC", SpiceManager::AberrationCorrection(), _time, lt); psc sun_pos = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); // Main renderpass diff --git a/modules/newhorizons/rendering/renderableplanetprojection.h b/modules/newhorizons/rendering/renderableplanetprojection.h index 031a67da06..be5d2d0523 100644 --- a/modules/newhorizons/rendering/renderableplanetprojection.h +++ b/modules/newhorizons/rendering/renderableplanetprojection.h @@ -40,6 +40,7 @@ #include #include #include +#include #include @@ -117,7 +118,7 @@ private: std::string _instrumentID; std::string _projectorID; std::string _projecteeID; - std::string _aberration; + SpiceManager::AberrationCorrection _aberration; std::vector _potentialTargets; // @TODO copy-n-paste from renderablefov diff --git a/modules/newhorizons/rendering/renderableshadowcylinder.cpp b/modules/newhorizons/rendering/renderableshadowcylinder.cpp index 1e82e75e30..4e4d346ec6 100644 --- a/modules/newhorizons/rendering/renderableshadowcylinder.cpp +++ b/modules/newhorizons/rendering/renderableshadowcylinder.cpp @@ -71,7 +71,9 @@ namespace openspace { ghoul_assert(success, ""); success = dictionary.getValue(_keyMainFrame, _mainFrame); ghoul_assert(success, ""); - success = dictionary.getValue(_keyAberration, _aberration); + std::string a = "NONE"; + success = dictionary.getValue(_keyAberration, a); + _aberration = SpiceManager::AberrationCorrection(a); ghoul_assert(success, ""); } @@ -166,9 +168,9 @@ void RenderableShadowCylinder::createCylinder() { observerPosition, terminatorPoints); - glm::dvec3 vecLightSource; double lt; - bool performs = SpiceManager::ref().getTargetPosition(_body, _lightSource, _mainFrame, _aberration, _time, vecLightSource, lt); + glm::dvec3 vecLightSource = + SpiceManager::ref().targetPosition(_body, _lightSource, _mainFrame, _aberration, _time, lt); glm::dmat3 _stateMatrix; openspace::SpiceManager::ref().getPositionTransformMatrix(_bodyFrame, _mainFrame, _time, _stateMatrix); diff --git a/modules/newhorizons/rendering/renderableshadowcylinder.h b/modules/newhorizons/rendering/renderableshadowcylinder.h index b5caac7f9f..1aaa94551d 100644 --- a/modules/newhorizons/rendering/renderableshadowcylinder.h +++ b/modules/newhorizons/rendering/renderableshadowcylinder.h @@ -30,6 +30,7 @@ #include #include #include +#include namespace ghoul { namespace filesystem { @@ -87,7 +88,7 @@ namespace openspace { std::string _body; std::string _bodyFrame; std::string _mainFrame; - std::string _aberration; + SpiceManager::AberrationCorrection _aberration; double _time; }; diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index f5b7326fa3..64ec5b4b04 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -452,8 +452,8 @@ void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &vi glm::vec4 targetColor(0.00, 0.75, 1.00, 1); double lt; - glm::dvec3 p; - SpiceManager::ref().getTargetPosition("PLUTO", "NEW HORIZONS", "GALACTIC", "NONE", currentTime, p, lt); + glm::dvec3 p = + SpiceManager::ref().targetPosition("PLUTO", "NEW HORIZONS", "GALACTIC", SpiceManager::AberrationCorrection(), currentTime, lt); psc nhPos = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); float a, b, c; SpiceManager::ref().getPlanetEllipsoid("PLUTO", a, b, c); diff --git a/src/util/spicemanager.cpp b/src/util/spicemanager.cpp index 4c7effc223..02e1847115 100644 --- a/src/util/spicemanager.cpp +++ b/src/util/spicemanager.cpp @@ -62,9 +62,52 @@ using std::string; namespace openspace { + SpiceManager::SpiceKernelException::SpiceKernelException(const string& msg) : ghoul::RuntimeError(msg, "Spice") {} + +SpiceManager::AberrationCorrection::AberrationCorrection(Type t, Direction d) + : type(t) + , direction(d) +{} + +SpiceManager::AberrationCorrection::AberrationCorrection(const std::string& identifier) { + static const std::map> Mapping = { + { "NONE" , { Type::None, Direction::Reception } }, + { "LT" , { Type::LightTime, Direction::Reception } }, + { "LT+S" , { Type::LightTimeStellar, Direction::Reception } }, + { "CN" , { Type::ConvergedNewtonian, Direction::Reception } }, + { "CN+S" , { Type::ConvergedNewtonianStellar, Direction::Reception } }, + { "XLT" , { Type::LightTime, Direction::Transmission } }, + { "XLT+S" , { Type::LightTimeStellar, Direction::Transmission } }, + { "XCN" , { Type::ConvergedNewtonian, Direction::Transmission } }, + { "XCN+S" , { Type::ConvergedNewtonianStellar, Direction::Transmission } } + }; + + auto it = Mapping.find(identifier); + + ghoul_assert(!identifier.empty(), "Identifier may not be empty"); + ghoul_assert(it != Mapping.end(), format("Invalid identifer '{}'", identifier)); + + type = it->second.first; + direction = it->second.second; +} + +SpiceManager::AberrationCorrection::operator string() const { + switch (type) { + case Type::None: + return "NONE"; + case Type::LightTime: + return (direction == Direction::Reception) ? "LT" : "XLT"; + case Type::LightTimeStellar: + return (direction == Direction::Reception) ? "LT+S" : "XLT+S"; + case Type::ConvergedNewtonian: + return (direction == Direction::Reception) ? "CN" : "XCN"; + case Type::ConvergedNewtonianStellar: + return (direction == Direction::Reception) ? "CN+S" : "XCN+S"; + } +} SpiceManager::SpiceManager() { // Set the SPICE library to not exit the program if an error occurs @@ -370,40 +413,48 @@ string SpiceManager::dateFromEphemerisTime(double ephemerisTime, } -bool SpiceManager::getTargetPosition(const std::string& target, - const std::string& observer, - const std::string& referenceFrame, - const std::string& aberrationCorrection, - double ephemerisTime, - glm::dvec3& position, - double& lightTime) const +glm::dvec3 SpiceManager::targetPosition(const std::string& target, + const std::string& observer, + const std::string& referenceFrame, + AberrationCorrection abberationCorrection, + double ephemerisTime, + double& lightTime) const { - psc pscPosition = PowerScaledCoordinate::CreatePowerScaledCoordinate(position[0], position[1], position[2]); + ghoul_assert(!target.empty(), "Target is not empty"); + ghoul_assert(!observer.empty(), "Observer is not empty"); + ghoul_assert(!referenceFrame.empty(), "Reference frame is not empty"); bool targetHasCoverage = hasSpkCoverage(target, ephemerisTime); bool observerHasCoverage = hasSpkCoverage(observer, ephemerisTime); if (!targetHasCoverage && !observerHasCoverage){ - return false; + throw SpiceKernelException( + format("Neither the target '{}' nor observer '{}' has SPK coverage", + target, + observer + ) + ); } - else if (targetHasCoverage && observerHasCoverage){ + else if (targetHasCoverage && observerHasCoverage) { + std::string correction = abberationCorrection; + glm::dvec3 position; spkpos_c(target.c_str(), ephemerisTime, referenceFrame.c_str(), - aberrationCorrection.c_str(), observer.c_str(), glm::value_ptr(position), + correction.c_str(), observer.c_str(), glm::value_ptr(position), &lightTime); + throwOnSpiceError(format("Error getting target position from '{}' to '{}' in reference frame '{}", target, observer, referenceFrame)); + return position; } else if (targetHasCoverage) {// observer has no coverage + psc pscPosition; getEstimatedPosition(ephemerisTime, observer, target, pscPosition); pscPosition = pscPosition*(-1.f); // inverse estimated position because the observer is "target" argument in funciton - position = pscPosition.vec3(); + return pscPosition.vec3(); } else { // target has no coverage + psc pscPosition; getEstimatedPosition(ephemerisTime, target, observer, pscPosition); - position = pscPosition.vec3(); + return pscPosition.vec3(); + } - - if (position[0] == 0.0 || position[1] == 0.0 || position[2] == 0.0) - return false; - - return targetHasCoverage && observerHasCoverage; } //bool SpiceManager::getTargetPosition(const std::string& target,