More SpiceManager cleanup

This commit is contained in:
Alexander Bock
2014-09-28 16:13:26 +02:00
parent 83e7398fee
commit e97d5f17bc
4 changed files with 320 additions and 175 deletions

View File

@@ -173,7 +173,7 @@ TEST_F(SpiceManagerTest, getValueFromID_1D){
std::string value1D = "MAG_NORTH_POLE_LAT";
double return1D;
bool found = openspace::SpiceManager::ref().getValueFromID(target, value1D, return1D);
bool found = openspace::SpiceManager::ref().getValue(target, value1D, return1D);
ASSERT_TRUE(found) << "Could not retrieve value";
EXPECT_EQ(return1D, 78.565) << "Value not found / differs from expected return";
unload_c(PCK.c_str());
@@ -186,7 +186,7 @@ TEST_F(SpiceManagerTest, getValueFromID_3D){
std::string value3D = "RADII";
glm::dvec3 return3D;
openspace::SpiceManager::ref().getValueFromID(target, value3D, return3D);
openspace::SpiceManager::ref().getValue(target, value3D, return3D);
EXPECT_EQ(return3D.x, 6378.14) << "Value not found / differs from expected return";
EXPECT_EQ(return3D.y, 6378.14) << "Value not found / differs from expected return";
@@ -200,16 +200,15 @@ TEST_F(SpiceManagerTest, getValueFromID_ND){
std::string target = "SATURN";
std::string valueND = "RING6_A";
std::vector<double> returnND;
unsigned int nr = 5;
bool found = openspace::SpiceManager::ref().getValueFromID(target, valueND, returnND, nr);
std::vector<double> returnND(5);
bool found = openspace::SpiceManager::ref().getValue(target, valueND, returnND);
ASSERT_TRUE(found) << "Could not retrieve value for specified kernel";
std::vector<double> controlVec{ 189870.0, 256900.0, 9000.0, 9000.0, 0.000003 };
ASSERT_EQ(controlVec.size(), returnND.size()) << "Vectors differ in size";
for (unsigned int i = 0; i < nr; ++i){
for (unsigned int i = 0; i < returnND.size(); ++i){
EXPECT_EQ(controlVec[i], returnND[i]) << "Vector value not equal";
}
unload_c(PCK.c_str());
@@ -223,7 +222,8 @@ TEST_F(SpiceManagerTest, stringToEphemerisTime){
char date[SRCLEN] = "Thu Mar 20 12:53:29 PST 1997";
str2et_c(date, &control_ephemerisTime);
ephemerisTime = openspace::SpiceManager::ref().convertStringToTdbSeconds(date);
bool success = openspace::SpiceManager::ref().getETfromDate(date, ephemerisTime);
EXPECT_EQ(success, true);
EXPECT_EQ(ephemerisTime, control_ephemerisTime) << "Ephemeries times differ / not found";
unload_c(LSK.c_str());

View File

@@ -30,6 +30,7 @@
#include <string>
#include <ghoul/glm.h>
#include <glm/gtc/type_ptr.hpp>
#include <array>
#include <vector>
#include <map>
@@ -122,62 +123,196 @@ public:
* \return <code>true</code> if the <code>body</code> was found, <code>false</code>
* otherwise
*/
bool getNaifIdForBody(const std::string& body, int& id) const;
/**
* Fetch from the kernel pool the double precision values of an
* item associated with a body.
* For further details, please refer to 'bodvrd_c' in SPICE Docummentation
*
* \param bodyName Body name.
* \param kernelPoolValueName Item for which values are desired. ("RADII", "NUT_PREC_ANGLES", etc. )
* \return Whether the function succeeded or not
*/
bool getValueFromID(const std::string& bodyname,
const std::string& kernelPoolValueName,
double& value) const;
/* Overloaded method for 3dim vectors, see above specification.*/
bool getValueFromID(const std::string& bodyname,
const std::string& kernelPoolValueName,
glm::dvec3& value) const;
/* Overloaded method for 4dim vectors, see above specification.*/
bool getValueFromID(const std::string& bodyname,
const std::string& kernelPoolValueName,
glm::dvec4& value) const;
/* Overloaded method for Ndim vectors, see above specification.*/
bool getValueFromID(const std::string& bodyname,
const std::string& kernelPoolValueName,
std::vector<double>& values, unsigned int num) const;
// Converting between UTC and Ephemeris Time (LSK) ------------------------------------- //
bool getNaifId(const std::string& body, int& id) const;
/**
* Convert a string representing an epoch to a double precision
* value representing the number of TDB seconds past the J2000
* epoch corresponding to the input epoch.
* For further details, please refer to 'str2et_c' in SPICE Docummentation
*
* \param epochString, A string representing an epoch.
* \return Corresponding ephemeris time, equivalent value in seconds past J2000, TDB.
* Retrieves a single <code>value</code> for a certain <code>body</code>. This method
* succeeds iff <code>body</code> is the name of a valid body, <code>value</code>
* is a value associated with the body, and the value consists of only a single
* <code>double</code> value. If all conditions are true, the value is retrieved using
* the method <code>bodvrd_c</code> and stored in <code>v</code>
* http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/bodvrd_c.html. If one of
* the conditions is false an error is logged and the value <code>v</code> is
* unchanged.
* \param body The name of the body whose value should be retrieved
* \param value The value of that should be retrieved, this value is case-sensitive
* \param v The destination for the retrieved value
* \return <code>true</code> if the <code>body</code> named a valid body,
* <code>value</code> is a valid item for the <code>body</code> and the retrieved
* value is only a single value. <code>false</code> otherwise
*/
double convertStringToTdbSeconds(const std::string& epochString) const;
bool getValue(const std::string& body, const std::string& value, double& v) const;
/**
* Convert the number of TDB seconds past the J2000 epoch into a human readable
* string representation. Fur further details, please refer to 'timout_c' in SPICE
* Documentation
*
* \param seconds The number of seconds that have passed since the J2000 epoch
* \param format The output format of the string
* (see ftp://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/timout_c.html)
* \return The formatted date string
* Retrieves a single <code>value</code> for a certain body with a NAIF ID of
* <code>id</code>. This method succeeds iff <code>id</code> is the ID of a valid
* body, <code>value</code> is a value associated with the body, and the value
* consists of only a single <code>double</code> value. If all conditions are true,
* the value is retrieved using the method <code>bodvrd_c</code> and stored in
* <code>v</code>
* http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/bodvrd_c.html. If one of
* the conditions is false an error is logged and the value <code>v</code> is
* unchanged. For a description on NAIF IDs, see
* http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/naif_ids.html.
* \param id The NAIF ID of the body whose information should be retrieved
* \param value The value of that should be retrieved, this value is case-sensitive
* \param v The destination for the retrieved value
* \return <code>true</code> if the <code>body</code> named a valid body,
* <code>value</code> is a valid item for the <code>body</code> and the retrieved
* value is only a single value. <code>false</code> otherwise
*/
std::string convertTdbSecondsToString(double seconds, const std::string& format) const;
bool getValue(int id, const std::string& value, double& v) const;
std::string ephemerisTimeToString(const double et) const;
/**
* Retrieves a <code>value</code> with three components for a certain
* <code>body</code>. This method succeeds iff <code>body</code> is the name of a
* valid body, <code>value</code> is a value associated with the body, and the value
* consists of three <code>double</code> values. If all conditions are true, the value
* is retrieved using the method <code>bodvrd_c</code> and stored in <code>v</code>
* http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/bodvrd_c.html. If one of
* the conditions is false an error is logged and the value <code>v</code> is
* unchanged.
* \param body The name of the body whose value should be retrieved
* \param value The value of that should be retrieved, this value is case-sensitive
* \param v The destination for the retrieved values
* \return <code>true</code> if the <code>body</code> named a valid body,
* <code>value</code> is a valid item for the <code>body</code> and the retrieved
* value is only a single value. <code>false</code> otherwise
*/
bool getValue(const std::string& body, const std::string& value, glm::dvec3& v) const;
// Computing Positions of Spacecraft and Natural Bodies(SPK) ---------------------------- //
/**
* Retrieves a <code>value</code> with three components for a certain body with a
* NAIF ID of <code>id</code>. This method succeeds <code>id</code> is the ID of a
* valid body, <code>value</code> is a value associated with the body, and the value
* consists of three <code>double</code> values. If all conditions are true, the value
* is retrieved using the method <code>bodvrd_c</code> and stored in <code>v</code>
* http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/bodvrd_c.html. If one of
* the conditions is false an error is logged and the value <code>v</code> is
* unchanged. For a description on NAIF IDs, see
* http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/naif_ids.html.
* \param id The NAIF ID of the body whose information should be retrieved
* \param value The value of that should be retrieved, this value is case-sensitive
* \param v The destination for the retrieved values
* \return <code>true</code> if the <code>body</code> named a valid body,
* <code>value</code> is a valid item for the <code>body</code> and the retrieved
* value is only a single value. <code>false</code> otherwise
*/
bool getValue(int id, const std::string& value, glm::dvec3& v) const;
/**
* Retrieves a <code>value</code> with four components for a certain
* <code>body</code>. This method succeeds iff <code>body</code> is the name of a
* valid body, <code>value</code> is a value associated with the body, and the value
* consists of four <code>double</code> values. If all conditions are true, the value
* is retrieved using the method <code>bodvrd_c</code> and stored in <code>v</code>
* http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/bodvrd_c.html. If one of
* the conditions is false an error is logged and the value <code>v</code> is
* unchanged.
* \param body The name of the body whose value should be retrieved
* \param value The value of that should be retrieved, this value is case-sensitive
* \param v The destination for the retrieved values
* \return <code>true</code> if the <code>body</code> named a valid body,
* <code>value</code> is a valid item for the <code>body</code> and the retrieved
* value is only a single value. <code>false</code> otherwise
*/
bool getValue(const std::string& body, const std::string& value, glm::dvec4& v) const;
/**
* Retrieves a <code>value</code> with four components for a certain body with a
* NAIF ID of <code>id</code>. This method succeeds <code>id</code> is the ID of a
* valid body, <code>value</code> is a value associated with the body, and the value
* consists of four <code>double</code> values. If all conditions are true, the value
* is retrieved using the method <code>bodvrd_c</code> and stored in <code>v</code>
* http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/bodvrd_c.html. If one of
* the conditions is false an error is logged and the value <code>v</code> is
* unchanged. For a description on NAIF IDs, see
* http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/naif_ids.html.
* \param id The NAIF ID of the body whose information should be retrieved
* \param value The value of that should be retrieved, this value is case-sensitive
* \param v The destination for the retrieved values
* \return <code>true</code> if the <code>body</code> named a valid body,
* <code>value</code> is a valid item for the <code>body</code> and the retrieved
* value is only a single value. <code>false</code> otherwise
*/
bool getValue(int id, const std::string& value, glm::dvec4& v) const;
/**
* Retrieves a <code>value</code> with an arbitrary number of components for a certain
* <code>body</code>. This method succeeds <code>body</code> is a valid body,
* <code>value</code> is a value associated with the body, and the value consists of a
* number of <code>double</code> values. The requested number is equal to the
* <code>size</code> of the passed vector <code>v</code> which means that this vector
* has to be preallocated. If all conditions are true, the value is retrieved using
* the method <code>bodvrd_c</code> and stored in <code>v</code>
* http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/bodvrd_c.html. If one of
* the conditions is false an error is logged and the value <code>v</code> is
* unchanged.
* \param body The body whose information should be retrieved
* \param value The value of that should be retrieved, this value is case-sensitive
* \param v The destination for the retrieved values. The size of this vector
* determines how many values will be retrieved
* \return <code>true</code> if the <code>body</code> named a valid body,
* <code>value</code> is a valid item for the <code>body</code> and the retrieved
* value is only a single value. <code>false</code> otherwise
*/
bool getValue(const std::string& body, const std::string& value,
std::vector<double>& v) const;
/**
* Retrieves a <code>value</code> with an arbitrary number of components for a certain
* body with a NAIF ID of <code>id</code>. This method succeeds <code>id</code> is the
* ID of a valid body, <code>value</code> is a value associated with the body, and the
* value consists of a number of <code>double</code> values. The requested number is
* equal to the <code>size</code> of the passed vector <code>v</code> which means that
* this vector has to be preallocated. If all conditions are true, the value is
* retrieved using the method <code>bodvrd_c</code> and stored in <code>v</code>
* http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/bodvrd_c.html. If one of
* the conditions is false an error is logged and the value <code>v</code> is
* unchanged. For a description on NAIF IDs, see
* http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/naif_ids.html.
* \param id The NAIF ID of the body whose information should be retrieved
* \param value The value of that should be retrieved, this value is case-sensitive
* \param v The destination for the retrieved values. The size of this vector
* determines how many values will be retrieved
* \return <code>true</code> if the <code>body</code> named a valid body,
* <code>value</code> is a valid item for the <code>body</code> and the retrieved
* value is only a single value. <code>false</code> otherwise
*/
bool getValue(int id, const std::string& value, std::vector<double>& v) const;
/**
* Converts the <code>epochString</code> representing a date to a double precision
* value representing the <code>ephemerisTime</code>; that is the number of TDB
* seconds past the J2000 epoch. For further details, please refer to
* http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/str2et_c.html. If an error
* occurs, an error is logged, the method returns <code>false</code> and the
* <code>ephemerisTime</code> remains unchanged.
* \param epochString A string representing an epoch
* \param ephemerisTime The destination for the converted time; the number of TDB
* seconds past the J2000 epoch, representing the passed <code>epochString</code>
* \return <code>true</code> if the <code>epochString</code> is a valid string and
* the conversion succeeded, <code>false</code> otherwise
*/
bool getETfromDate(const std::string& epochString, double& ephemerisTime) const;
/**
* Converts the passed <code>ephemerisTime</code> into a human-readable
* <code>date</code> string with a specific <code>format</code>. For details on the
* formatting, refer to
* http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/timout_c.html. In case of
* an error, <code>date</code> will not be modified, an error will be logged and the
* method returns <code>false</code>.
* \param ephemerisTime The ephemeris time, that is the number of TDB seconds past the
* J2000 epoch
* \param date The destination for the converted date. This will only be changed if
* the conversion succeeded
* \param format The format string describing the output format for the
* <code>date</code>
* \return <code>true</code> if the conversion succeeded, <code>false</code> otherwise
*/
bool getDateFromET(double ephemerisTime, std::string& date,
const std::string& format = "YYYY MON DDTHR:MN:SC.### ::RND");
/**
* Return the position of a target body relative to an observing

View File

@@ -30,6 +30,8 @@
#include <cassert>
#include <cstring>
#include <glm/gtc/type_ptr.hpp>
//#ifdef WIN32
//#include <Windows.h>
//#endif
@@ -130,145 +132,151 @@ bool SpiceManager::hasValue(int naifId, const std::string& item) const {
bool SpiceManager::hasValue(const std::string& body, const std::string& item) const {
int id;
bool success = getNaifIdForBody(body, id);
bool success = getNaifId(body, id);
if (success)
return hasValue(id, item);
else
return false;
}
bool SpiceManager::getNaifIdForBody(const std::string& body, int& id) const {
bool SpiceManager::getNaifId(const std::string& body, int& id) const {
SpiceBoolean success;
bods2c_c(body.c_str(), &id, &success);
return (success == SPICETRUE);
}
// 1D
bool SpiceManager::getValueFromID(const std::string& bodyname,
const std::string& kernelPoolValue,
double& value) const{
int n;
int code;
int found;
bodn2c_c(bodyname.c_str(), &code, &found);
if (!found) return false;
bodvrd_c(bodyname.c_str(), kernelPoolValue.c_str(), 1, &n, &value);
return true;
}
// 2D
/*
bool SpiceManager::getValueFromID(const std::string& bodyname,
const std::string& kernelPoolValueName,
glm::dvec2& value) const{
int n;
double val[2];
int code;
int found;
bodn2c_c(bodyname.c_str(), &code, &found);
if (!found) return false;
bodvrd_c(bodyname.c_str(), kernelPoolValueName.c_str(), 2, &n, val);
value[0] = val[0];
value[1] = val[1];
return true;
}
*/
// 3D
bool SpiceManager::getValueFromID(const std::string& bodyname,
const std::string& kernelPoolValueName,
glm::dvec3& value) const{
int n;
double val[3];
int code;
int found;
bodn2c_c(bodyname.c_str(), &code, &found);
if (!found) return false;
bodvrd_c(bodyname.c_str(), kernelPoolValueName.c_str(), 3, &n, val);
memcpy(&value, val, sizeof(double)* 3);
return true;
}
// 4D
/*
bool SpiceManager::getValueFromID(const std::string& bodyname,
const std::string& kernelPoolValueName,
glm::dvec4& value) const{
int n;
double val[4];
int code;
int found;
bodn2c_c(bodyname.c_str(), &code, &found);
if (!found) return false;
bodvrd_c(bodyname.c_str(), kernelPoolValueName.c_str(), 4, &n, val);
value[0] = val[0];
value[1] = val[1];
value[2] = val[2];
value[3] = val[3];
return true;
}
*/
// ND
bool SpiceManager::getValueFromID(const std::string& bodyname,
const std::string& kernelPoolValueName,
std::vector<double>& values,
unsigned int num) const{
int n;
double *val;
val = (double*)malloc(num*sizeof(double));
int code;
int found;
bodn2c_c(bodyname.c_str(), &code, &found);
if (!found) return false;
bodvrd_c(bodyname.c_str(), kernelPoolValueName.c_str(), num, &n, val);
for (int i = 0; i < num; i++){
values.push_back(val[i]);
}
return true;
}
double SpiceManager::convertStringToTdbSeconds(const std::string& epochString) const{
double et;
str2et_c(epochString.c_str(), &et);
return et;
}
std::string SpiceManager::ephemerisTimeToString(const double et) const{
char utcstr[40];
timout_c(et, "YYYY MON DD HR:MN:SC.### ::RND", 32, utcstr);
return std::string(utcstr);
}
std::string SpiceManager::convertTdbSecondsToString(double seconds,
const std::string& format) const
bool SpiceManager::getValue(const std::string& body, const std::string& value,
double& v) const
{
const int bufferSize = 128;
SpiceChar buffer[bufferSize];
timout_c(seconds, format.c_str(), bufferSize - 1, buffer);
int n;
bodvrd_c(body.c_str(), value.c_str(), 1, &n, &v);
int failed = failed_c();
if (failed) {
char msg[1024];
getmsg_c("LONG", 1024, msg);
//LERROR("Error retrieving position of target '" + target + "'");
LERROR("Error getting value '" << value << "' for body '" << body << "'");
LERROR("Spice reported: " + std::string(msg));
reset_c();
return "";
return false;
}
return std::string(buffer);
return true;
}
bool SpiceManager::getValue(int id, const std::string& value, double& v) const {
return getValue(std::to_string(id), value, v);
}
bool SpiceManager::getValue(const std::string& body, const std::string& value,
glm::dvec3& v) const
{
int n;
bodvrd_c(body.c_str(), value.c_str(), 3, &n, glm::value_ptr(v));
int failed = failed_c();
if (failed) {
char msg[1024];
getmsg_c("LONG", 1024, msg);
LERROR("Error getting value '" << value << "' for body '" << body << "'");
LERROR("Spice reported: " + std::string(msg));
reset_c();
return false;
}
return true;
}
bool SpiceManager::getValue(int id, const std::string& value, glm::dvec3& v) const
{
return getValue(std::to_string(id), value, v);
}
bool SpiceManager::getValue(const std::string& body, const std::string& value,
glm::dvec4& v) const
{
int n;
bodvrd_c(body.c_str(), value.c_str(), 4, &n, glm::value_ptr(v));
int failed = failed_c();
if (failed) {
char msg[1024];
getmsg_c("LONG", 1024, msg);
LERROR("Error getting value '" << value << "' for body '" << body << "'");
LERROR("Spice reported: " + std::string(msg));
reset_c();
return false;
}
return true;
}
bool SpiceManager::getValue(int id, const std::string& value, glm::dvec4& v) const
{
return getValue(std::to_string(id), value, v);
}
bool SpiceManager::getValue(const std::string& body, const std::string& value,
std::vector<double>& v) const
{
assert(v.size() > 0);
int n;
bodvrd_c(body.c_str(), value.c_str(), static_cast<SpiceInt>(v.size()), &n, &v[0]);
int failed = failed_c();
if (failed) {
char msg[1024];
getmsg_c("LONG", 1024, msg);
LERROR("Error getting value '" << value << "' for body '" << body << "'");
LERROR("Spice reported: " + std::string(msg));
reset_c();
return false;
}
return true;
}
bool SpiceManager::getValue(int id, const std::string& value,
std::vector<double>& v) const
{
return getValue(std::to_string(id), value, v);
}
bool SpiceManager::getETfromDate(const std::string& epochString,
double& ephemerisTime) const
{
str2et_c(epochString.c_str(), &ephemerisTime);
int failed = failed_c();
if (failed) {
char msg[1024];
getmsg_c("LONG", 1024, msg);
LERROR("Error converting date '" + epochString+ "'");
LERROR("Spice reported: " + std::string(msg));
reset_c();
return false;
}
return true;
}
bool SpiceManager::getDateFromET(double ephemerisTime, std::string& date,
const std::string& format)
{
static const int BufferSize = 256;
SpiceChar buffer[BufferSize];
timout_c(ephemerisTime, format.c_str(), BufferSize - 1, buffer);
int failed = failed_c();
if (failed) {
char msg[1024];
getmsg_c("LONG", 1024, msg);
LERROR("Error converting ephemeris time to date with format '" + format + "'");
LERROR("Spice reported: " + std::string(msg));
reset_c();
return false;
}
date = std::string(buffer);
return true;
}
bool SpiceManager::getTargetPosition(const std::string& target,

View File

@@ -193,11 +193,13 @@ double Time::deltaTime() const {
}
void Time::setTime(std::string time) {
_time = SpiceManager::ref().convertStringToTdbSeconds(std::move(time));
SpiceManager::ref().getETfromDate(std::move(time), _time);
}
std::string Time::currentTimeUTC() const {
return SpiceManager::ref().convertTdbSecondsToString(_time, "YYYY-MM-DDTHR:MN:SC.#####");
std::string date;
SpiceManager::ref().getDateFromET(_time, date);
return std::move(date);
}
scripting::ScriptEngine::LuaLibrary Time::luaLibrary() {
scripting::ScriptEngine::LuaLibrary timeLibrary = {