File: sinexMetadata2SatelliteModel.cpp

package info (click to toggle)
groops 0%2Bgit20250907%2Bds-1
  • links: PTS, VCS
  • area: non-free
  • in suites: forky, sid
  • size: 11,140 kB
  • sloc: cpp: 135,607; fortran: 1,603; makefile: 20
file content (136 lines) | stat: -rw-r--r-- 5,660 bytes parent folder | download | duplicates (2)
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)
  }
}

/***********************************************/