1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
|
/***********************************************/
/**
* @file sinexMetadata2SatelliteModel.cpp
*
* @brief Create satellite model from IGS SINEX metadata file.
*
* TODO: Consider time-variability in transmit power.
*
* @author Sebastian Strasser
* @date 2018-09-17
*/
/***********************************************/
// Latex documentation
#define DOCSTRING docstring
static const char *docstring = R"(
Create \configFile{outputfileSatelliteModel}{satelliteModel} from \href{https://www.igs.org/mgex/metadata/#metadata}{IGS SINEX metadata format}.
If \configFile{inputfileSatelliteModel}{satelliteModel} is provided it is used as a basis and values are updated from the metadata file.
See also \program{SatelliteModelCreate}.
)";
/***********************************************/
#include "programs/program.h"
#include "base/string.h"
#include "files/fileSatelliteModel.h"
#include "inputOutput/fileSinex.h"
/***** CLASS ***********************************/
/** @brief Create satellite model from IGS SINEX metadata file.
* @ingroup programsConversionGroup */
class SinexMetadata2SatelliteModel
{
public:
void run(Config &config, Parallel::CommunicatorPtr comm);
};
GROOPS_REGISTER_PROGRAM(SinexMetadata2SatelliteModel, SINGLEPROCESS, "Create satellite model from IGS SINEX metadata file.", Conversion, Gnss)
/***********************************************/
void SinexMetadata2SatelliteModel::run(Config &config, Parallel::CommunicatorPtr /*comm*/)
{
try
{
FileName inNameSinexMetadata, inNameSatelliteModel, outNameSatelliteModel;
std::string svn;
readConfig(config, "outputfileSatelliteModel", outNameSatelliteModel, Config::MUSTSET, "", "");
readConfig(config, "inputfileSinexMetadata", inNameSinexMetadata, Config::MUSTSET, "", "IGS SINEX metadata file");
readConfig(config, "inputfileSatelliteModel", inNameSatelliteModel, Config::OPTIONAL, "", "base satellite model");
readConfig(config, "svn", svn, Config::MUSTSET, "", "e.g. G040, R736, E204, C211");
if(isCreateSchema(config)) return;
Sinex sinex;
readFileSinex(inNameSinexMetadata, sinex);
SatelliteModelPtr satellite(new SatelliteModel);
if(!inNameSatelliteModel.empty())
readFileSatelliteModel(inNameSatelliteModel, satellite);
satellite->satelliteName = svn;
// mass and mass changes
std::vector<Double> masses;
std::vector<Time> massTimes;
for(const auto &line : sinex.findBlock("SATELLITE/MASS")->lines)
if(line.size() >= 45 && line.substr(1,4) == svn)
{
massTimes.push_back(Sinex::str2time(line, 6, FALSE/*zeroIsMaxTime*/, TRUE/*fourDigitYear*/));
masses.push_back(String::toDouble(line.substr(36, 9)));
}
if(masses.size())
satellite->mass = masses.back();
else
logWarning<<"mass missing for " + svn<<Log::endl;
if(masses.size() > 1)
{
auto iter = std::remove_if(satellite->modules.begin(), satellite->modules.end(), [&](SatelliteModelModulePtr module){ return module->type() == SatelliteModelModule::MASSCHANGE; });
satellite->modules.erase(iter, satellite->modules.end());
SatelliteModelModuleMassChange *module = new SatelliteModelModuleMassChange;
module->times = massTimes;
module->mass = masses;
satellite->modules.push_back(SatelliteModelModulePtr(module));
}
// antenna thrust
std::vector<std::string> powerLines = sinex.findBlock("SATELLITE/TX_POWER")->lines;
auto powerIter = std::find_if(powerLines.rbegin(), powerLines.rend(), [&](const std::string &line){ return (line.size() >= 40 && line.substr(1,4) == svn); });
if(powerIter != powerLines.rend())
{
auto iter = std::remove_if(satellite->modules.begin(), satellite->modules.end(), [&](SatelliteModelModulePtr module){ return module->type() == SatelliteModelModule::ANTENNATHRUST; });
satellite->modules.erase(iter, satellite->modules.end());
SatelliteModelModuleAntennaThrust *module = new SatelliteModelModuleAntennaThrust;
module->thrust = Vector3d(0, 0, String::toInt(powerIter->substr(36, 4)));
satellite->modules.push_back(SatelliteModelModulePtr(module));
}
else
logWarning<<"transmit power missing for " + svn<<Log::endl;
// surfaces
if(!satellite->surfaces.size())
{
// Box-wing surfaces
satellite->surfaces.resize(8);
satellite->surfaces.at(0).normal = Vector3d( 0, 0, 1); // Z (TOWARDS THE EARTH)
satellite->surfaces.at(1).normal = Vector3d( 0, 0,-1); // -Z
satellite->surfaces.at(2).normal = Vector3d( 0, 1, 0); // Y (ALONG SOLAR PANELS BEAMS)
satellite->surfaces.at(3).normal = Vector3d( 0,-1, 0); // -Y
satellite->surfaces.at(4).normal = Vector3d( 1, 0, 0); // X (ALONG BUS DIRECTION ALWAYS ILLUMINATED BY THE SUN)
satellite->surfaces.at(5).normal = Vector3d(-1, 0, 0); // -X
satellite->surfaces.at(6).normal = Vector3d( 0, 0, 1); // SOLAR PANELS
satellite->surfaces.at(7).normal = Vector3d( 0, 0,-1);
// Rotation of solar panels
SatelliteModelModuleSolarPanel *module = new SatelliteModelModuleSolarPanel;
satellite->modules.push_back(SatelliteModelModulePtr(module));
module->rotationAxis = Vector3d(0,1,0);
module->normal = Vector3d(0,0,1);
module->indexSurface.push_back(6);
module->indexSurface.push_back(7);
}
logStatus<<"write satellite model file <"<<outNameSatelliteModel<<">"<<Log::endl;
writeFileSatelliteModel(outNameSatelliteModel, satellite);
}
catch(std::exception &e)
{
GROOPS_RETHROW(e)
}
}
/***********************************************/
|