Merge branch 'thesis/2018/dsn' of github.com:OpenSpace/OpenSpace into thesis/2018/dsn

This commit is contained in:
Lovisa Hassler
2018-12-10 17:30:17 -05:00
7 changed files with 154 additions and 46 deletions

View File

@@ -1,5 +1,5 @@
local assetHelper = asset.require('util/asset_helper')
local dataFolder = openspace.absPath("../../../sync/http/dsn_data/1/positioning/MRO")
local dataFolder = openspace.absPath("../../../sync/http/dsn_data/1/positioning/MRO_downlink")
local models = asset.syncedResource({
Name = "Dsn models",

View File

@@ -4,6 +4,8 @@
asset.require('scene/solarsystem/missions/voyager1/voyager1')
asset.require('scene/solarsystem/missions/voyager1/trails')
asset.require('scene/solarsystem/missions/voyager2/voyager2')
-- added specifically for dsn visualization
asset.require('scene/solarsystem/missions/dsn/mro/mro')
asset.require('scene/solarsystem/missions/dsn/marsodyssey/marsodyssey')
asset.require('scene/solarsystem/missions/dsn/marsodyssey/marsodyssey')
asset.require('scene/solarsystem/missions/dsn/stereoa/stereoa')

View File

@@ -0,0 +1,13 @@
local Kernels = asset.syncedResource({
Name = "StereoA Kernels",
Type = "HttpSynchronization",
Identifier = "stereoa_kernels",
Version = 1
})
-- spk kernels
local StereoAKernels = {
Kernels .. '/STEREO_A_merged.bsp',
}
asset.export("StereoAKernels", StereoAKernels)

View File

@@ -0,0 +1,51 @@
local assetHelper = asset.require('util/asset_helper')
local sunTransforms = asset.require('scene/solarsystem/sun/transforms')
local kernels = asset.require('./kernels')
local lights = asset.require('scene/solarsystem/general/lightsources')
local models = asset.syncedResource({
Name = "StereoA Kernels",
Type = "HttpSynchronization",
Identifier = "stereo_model",
Version = 1
})
local StereoA = {
Identifier = "StereoA",
Parent = sunTransforms.SolarSystemBarycenter.Identifier,
Transform = {
Translation = {
Type = "SpiceTranslation",
Target = "STEREO AHEAD",
Observer = "SUN",
Kernels = kernels.StereoAKernels
}
},
GUI = {
Name = "Stereo A",
Path = "/Solar System/Missions/Stereo/Stereo A"
}
}
local StereoAModel = {
Identifier = "StereoA_model",
Parent = StereoA.Identifier,
Renderable = {
Type = "RenderableModel",
Geometry = {
Type = "MultiModelGeometry",
GeometryFile = models .. "/Stereo_main.obj"
},
ColorTexture = models .. "/texture.png",
LightSources = lights.StandardLights
},
GUI = {
Name = "3D Model",
Path = "/Solar System/Missions/Stereo A"
}
}
assetHelper.registerSceneGraphNodesAndExport(asset, {
StereoA,
StereoAModel
})

View File

@@ -33,14 +33,13 @@ namespace openspace {
if (dictionary->hasKeyAndValue<std::string>(KeyIdentifier)) {
objectIdentifier = dictionary->value<std::string>(KeyIdentifier);
}
bool dataFilesSuccess = DataFileHelper::checkFileNames(identifier, dictionary, _dataFiles);
return dataFilesSuccess;
}
bool RadecManager::correctHour(double time) const{
const bool isTimeInFileInterval = (time >= _checkFileTime) &&
(time < _checkFileTime + 3600);
const bool isTimeInFileInterval = (time >= _checkFileTime) &&
(time < _checkFileEndTime);
return isTimeInFileInterval;
}
@@ -52,9 +51,10 @@ namespace openspace {
glm::vec3 RadecManager::getPosForTime(double time) const {
if (!correctHour(time)) {
std::vector<double> timeDoubles = DataFileHelper::getHoursFromFileNames(_dataFiles);
int idx = DataFileHelper::findFileIndexForCurrentTime(time, timeDoubles);
radecParser(idx);
timeDoubles = DataFileHelper::getHoursFromFileNames(_dataFiles);
int idx = DataFileHelper::findFileIndexForCurrentTime(time, timeDoubles);
updateRadecData(idx);
}
if(!correctMinute(time)) {
getPositionInVector(time);
@@ -64,40 +64,26 @@ namespace openspace {
bool RadecManager::radecParser(int index) const{
std::string filename;
if (index == -1 || index > _dataFiles.size())
return false;
filename = _dataFiles[index];
std::string startTimeString = DataFileHelper::getHourFromFileName(filename);
const double triggerTime = Time::convertTime(startTimeString);
_checkFileTime = triggerTime;
std::ifstream ifs(filename);
nlohmann::json j = nlohmann::json::parse(ifs);
RadecManager::Position position;
positions.clear();
positions.reserve(0);
int objectCounter = 0;
for (const auto& pos : j["Positions"]) {
objectCounter++;
try {
position.timeStamp = pos["TimeStamp"].get<std::string>();
position.ra = pos["RADn"].get<double>();
position.dec = pos["DecDn"].get<double>();
position.range = pos["GeoRngDn"].get<double>();
position.lightTravelTime = pos["DLT"].get<double>();
for (const auto& pos : j["Positions"]) {
objectCounter++;
try {
position.timeStamp = pos["TimeStamp"].get<std::string>();
position.ra = pos["RAUp"].get<double>();
position.dec = pos["DecUp"].get<double>();
position.range = pos["GeoRngUp"].get<double>();
}
catch (const std::exception& e) {
LERROR(fmt::format("{}: Error in json object number {} while reading file '{}'", objectIdentifier, objectCounter, filename));
}
RadecManager::positions.push_back(position);
}
}
catch (const std::exception& e) {
LERROR(fmt::format("{}: Error in json object number {} while reading file '{}'", objectIdentifier, objectCounter, filename));
}
RadecManager::positions.push_back(position);
}
return true;
}
@@ -108,9 +94,9 @@ namespace openspace {
for (int i = 0; i < RadecManager::positions.size(); i++) {
minuteTimes.push_back(Time::convertTime(positions[i].timeStamp));
}
int idx = DataFileHelper::findFileIndexForCurrentTime(time, minuteTimes);
activeMinute = minuteTimes[idx];
int idx = DataFileHelper::findFileIndexForCurrentTime(time + position.lightTravelTime, minuteTimes);//Compensate for light travel time to the spacecraft
activeMinute = minuteTimes[idx];
position.timeStamp = positions[idx].timeStamp;
position.ra = positions[idx].ra;
position.dec = positions[idx].dec;
@@ -118,6 +104,46 @@ namespace openspace {
return position;
}
void RadecManager::updateRadecData(int index) const {
std::string filename;
if (index < -1 || index > _dataFiles.size())
return;
positions.clear();
positions.reserve(10);
filename = _dataFiles[index];
std::string startTimeString = DataFileHelper::getHourFromFileName(filename);
const double triggerTime = Time::convertTime(startTimeString);
_checkFileTime = triggerTime;
_checkFileEndTime = triggerTime + 3600;
//Light travel time in hours determines where to search for the correct position
int lightTravelHours = ceil(position.lightTravelTime / 3600);
if (lightTravelHours > 1)
index = index + lightTravelHours;
else if (index < 1) {
radecParser(index);
radecParser(index + 1);
return;
}
else if (index == _dataFiles.size() -1) {
radecParser(index);
radecParser(index -1);
return;
}
else{
radecParser(index - 1);
radecParser(index);
radecParser(index + 1);
}
}
}

View File

@@ -42,20 +42,23 @@ namespace openspace {
mutable double ra;
mutable double dec;
mutable double range;
mutable double lightTravelTime; //Downlink light time travel time in seconds
};
mutable std::vector<Position> positions;
mutable std::vector<double> minuteTimes;
mutable Position position;
mutable glm::vec3 currentMinute;
mutable double activeMinute = 0;
mutable double activeMinute;
/* Identifier for object using the translation, used for logging */
std::string objectIdentifier;
/*Used to check if the loaded file is still relevant or if we should look for another one. */
mutable double _checkFileTime;
/*Time range for the files*/
mutable double _checkFileEndTime;
/* A vector with all our datafile paths*/
std::vector<std::string> _dataFiles;
/* A vector with all our datafile times in j2000*/
mutable std::vector<double> timeDoubles;
/* Extracts all the mandatory information we need from our asset file */
bool extractMandatoryInfoFromDictionary(const char* identifier, std::unique_ptr<ghoul::Dictionary> &dictionary);
/*gets the correct datafile, that matches the current time in open space*/
@@ -68,6 +71,8 @@ namespace openspace {
bool correctHour(double time) const;
/*Check if current minute in open space is already loaded*/
bool correctMinute(double time) const;
/*Update and reate buffer of data so that we can compensate for light travel time without getting out of bounce*/
void updateRadecData(int index) const;
};
}

View File

@@ -65,8 +65,9 @@ RadecTranslation::RadecTranslation(const ghoul::Dictionary& dictionary)
: RadecTranslation()
{
std::unique_ptr<ghoul::Dictionary> dictionaryPtr = std::make_unique<ghoul::Dictionary>(dictionary);
extractData(dictionaryPtr);
radecManager.getPosForTime(0);
documentation::testSpecificationAndThrow(
Documentation(),
@@ -113,9 +114,19 @@ glm::dvec3 RadecTranslation::radecToCartesianCoordinates(glm::vec3 pos) const {
}
glm::dvec3 RadecTranslation::position(const UpdateData& data) const{
glm::vec3 pos = radecManager.getPosForTime(data.time.j2000Seconds());
_position = radecToCartesianCoordinates(pos);
return _position;
const bool haveDataForTime = (data.time.j2000Seconds() >= radecManager.timeDoubles.front()) &&
(data.time.j2000Seconds() < radecManager.timeDoubles.back());
if (!haveDataForTime) {
LDEBUG(fmt::format("No positioning data available for spacecraft: {}", radecManager.objectIdentifier.c_str()));
return radecToCartesianCoordinates({ 0,0,0 });
}
else {
glm::dvec3 pos = radecManager.getPosForTime(data.time.j2000Seconds());
_position = radecToCartesianCoordinates(pos);
return _position;
}
}
} // namespace openspace