Turn OpenVSP CSV forces and moments data into tables
This commit is contained in:
parent
fb36cea04c
commit
83694eabde
1 changed files with 122 additions and 59 deletions
|
@ -6,6 +6,9 @@
|
|||
#include <iomanip>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
#define DEG2RAD(a) (3.141592657*(a)/180.0)
|
||||
|
||||
// https://stackoverflow.com/questions/1120140/how-can-i-read-and-parse-csv-files-in-c
|
||||
class CSVRow
|
||||
|
@ -44,10 +47,10 @@ std::istream& operator>>(std::istream& str, CSVRow& data)
|
|||
{
|
||||
data.readNextRow(str);
|
||||
return str;
|
||||
}
|
||||
}
|
||||
|
||||
class CSVIterator
|
||||
{
|
||||
{
|
||||
public:
|
||||
typedef std::input_iterator_tag iterator_category;
|
||||
typedef CSVRow value_type;
|
||||
|
@ -83,70 +86,117 @@ class CSVRange
|
|||
CSVIterator end() const {return CSVIterator{};}
|
||||
};
|
||||
|
||||
// https://stackoverflow.com/questions/17642882/c-2d-map-like-a-2d-array
|
||||
template<typename T>
|
||||
class Graph {
|
||||
private:
|
||||
typedef std::map<std::pair<size_t,size_t>, T> graph_type;
|
||||
graph_type graph;
|
||||
class SrcVertex {
|
||||
private:
|
||||
graph_type& graph;
|
||||
size_t vert_src;
|
||||
public:
|
||||
SrcVertex(graph_type& graph): graph(graph) {}
|
||||
T& operator[](size_t vert_dst) {
|
||||
return graph[std::make_pair(vert_src, vert_dst)];
|
||||
}
|
||||
void set_vert_src(size_t vert_src) {
|
||||
this->vert_src = vert_src;
|
||||
}
|
||||
} src_vertex_proxy;
|
||||
public:
|
||||
Graph(): src_vertex_proxy(graph) {}
|
||||
SrcVertex& operator[](size_t vert_src) {
|
||||
src_vertex_proxy.set_vert_src(vert_src);
|
||||
return src_vertex_proxy;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// own code by Erik Hofman
|
||||
class JSBSim
|
||||
{
|
||||
public:
|
||||
std::string name;
|
||||
std::vector<int> date;
|
||||
std::vector<int> time;
|
||||
std::vector<double> alpha;
|
||||
std::vector<double> beta;
|
||||
std::vector<double> CDi, CDo, CDtot, CDtrefftz;
|
||||
std::vector<double> CFx, CFy, CFz, CL;
|
||||
std::vector<double> CMx, CMy, CMz;
|
||||
public:
|
||||
std::string name;
|
||||
std::vector<int> date;
|
||||
std::vector<int> time;
|
||||
std::vector<double> a, b;
|
||||
Graph<double> CDi, CDo, CDtot, CDtrefftz;
|
||||
Graph<double> CFx, CFy, CFz, CL;
|
||||
Graph<double> CMx, CMy, CMz;
|
||||
|
||||
JSBSim(std::istream& file)
|
||||
JSBSim(std::istream& file)
|
||||
{
|
||||
// every section contains 39 lines
|
||||
size_t alpha, beta;
|
||||
for(auto& row: CSVRange(file))
|
||||
{
|
||||
for(auto& row: CSVRange(file))
|
||||
{
|
||||
char *end;
|
||||
const char *start = row[1].data();
|
||||
double d = std::strtod(start, &end);
|
||||
if (row[0] == "Results_Name") {
|
||||
name = row[1];
|
||||
} else if (row[0] == "Results_Date") {
|
||||
push_vector<int>(date, row);
|
||||
} else if (row[0] == "Results_Time") {
|
||||
push_vector<int>(time, row);
|
||||
} else if (row[0] == "Alpha") {
|
||||
alpha.push_back(d);
|
||||
} else if (row[0] == "Beta") {
|
||||
beta.push_back(d);
|
||||
} if (row[0] == "CDi") {
|
||||
CDi.push_back(d);
|
||||
} if (row[0] == "CDo") {
|
||||
CDo.push_back(d);
|
||||
} if (row[0] == "CDtot") {
|
||||
CDtot.push_back(d);
|
||||
} if (row[0] == "CDtrefftz") {
|
||||
CDtrefftz.push_back(d);
|
||||
} if (row[0] == "CFx") {
|
||||
CFx.push_back(d);
|
||||
} if (row[0] == "CFy") {
|
||||
CFy.push_back(d);
|
||||
} if (row[0] == "CFz") {
|
||||
CFz.push_back(d);
|
||||
} if (row[0] == "CL") {
|
||||
CL.push_back(d);
|
||||
} if (row[0] == "CMx") {
|
||||
CMx.push_back(d);
|
||||
} if (row[0] == "CMy") {
|
||||
CMy.push_back(d);
|
||||
} if (row[0] == "CMz") {
|
||||
CMz.push_back(d);
|
||||
}
|
||||
if (row[0] == "Results_Name") {
|
||||
if (row[1] != "VSPAERO_History") break;
|
||||
name = row[1];
|
||||
}
|
||||
|
||||
char *end;
|
||||
const char *start = row[row.size()-1].data();
|
||||
double d = std::strtod(start, &end);
|
||||
if (row[0] == "Alpha") {
|
||||
alpha = d*100;
|
||||
if (!a.size() || d > a.back()) a.push_back(d);
|
||||
} else if (row[0] == "Beta") {
|
||||
beta = d*100;
|
||||
if (!b.size() || d > b.back()) b.push_back(d);
|
||||
} if (row[0] == "CDi") {
|
||||
CDi[alpha][beta] = d;
|
||||
} if (row[0] == "CDo") {
|
||||
CDo[alpha][beta] = d;
|
||||
} if (row[0] == "CDtot") {
|
||||
CDtot[alpha][beta] = d;
|
||||
} if (row[0] == "CDtrefftz") {
|
||||
CDtrefftz[alpha][beta] = d;
|
||||
} if (row[0] == "CFx") {
|
||||
CFx[alpha][beta] = d;
|
||||
} if (row[0] == "CFy") {
|
||||
CFy[alpha][beta] = d;
|
||||
} if (row[0] == "CFz") {
|
||||
CFz[alpha][beta] = d;
|
||||
} if (row[0] == "CL") {
|
||||
CL[alpha][beta] = d;
|
||||
} if (row[0] == "CMx") {
|
||||
CMx[alpha][beta] = d;
|
||||
} if (row[0] == "CMy") {
|
||||
CMy[alpha][beta] = d;
|
||||
} if (row[0] == "CMz") {
|
||||
CMz[alpha][beta] = d;
|
||||
}
|
||||
}
|
||||
~JSBSim() = default;
|
||||
}
|
||||
~JSBSim() = default;
|
||||
|
||||
private:
|
||||
void print_table(Graph<double>& type, std::string name) {
|
||||
std::cout << name << std::endl;
|
||||
std::cout << std::setw(10) << " ";
|
||||
for (int j=0; j<b.size(); ++j) {
|
||||
std::cout << std::setw(8) << DEG2RAD(b[j]);
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
for (int i=0; i<a.size(); ++i) {
|
||||
std::cout << std::setw(8) << DEG2RAD(a[i]) << " ";
|
||||
for (int j=0; j<b.size(); ++j) {
|
||||
std::cout << std::setw(8) << type[a[i]*100][b[j]*100];
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename T>
|
||||
void push_vector(std::vector<T>& dst, const CSVRow& row) {
|
||||
for (int i=1; i<row.size(); ++i)
|
||||
{
|
||||
char *end;
|
||||
char *end;
|
||||
const char *start = row[i].data();
|
||||
double d = std::strtod(start, &end);
|
||||
dst.push_back(d);
|
||||
|
@ -161,11 +211,24 @@ int main(int argc, char *argv[])
|
|||
|
||||
std::cout << "Name: " << jsb.name << std::endl;
|
||||
|
||||
std::cout << std::setprecision(3);
|
||||
std::cout << std::fixed << std::showpoint << std::setprecision(3);
|
||||
|
||||
std::cout << "CL:" << std::endl;
|
||||
for (int a=0; a<jsb.alpha.size(); ++a) {
|
||||
std::cout << std::setw(6) << jsb.alpha[a] << " ";
|
||||
std::cout << std::setw(6) << jsb.CL[a] << std::endl;
|
||||
}
|
||||
std::cout << "LIFT:" << std::endl;
|
||||
jsb.print_table(jsb.CL, "CL");
|
||||
|
||||
std::cout << "DRAG:" << std::endl;
|
||||
jsb.print_table(jsb.CDi, "CDi (Induced Drag)");
|
||||
jsb.print_table(jsb.CDo, "CDo (Parasitic Drag)");
|
||||
jsb.print_table(jsb.CDtot, "CDtot (CDi + CDo)");
|
||||
jsb.print_table(jsb.CDtrefftz, "CDtrefftz (Trefftz Method)");
|
||||
|
||||
std::cout << "FORCES:" << std::endl;
|
||||
jsb.print_table(jsb.CFx, "CFx (Drag)");
|
||||
jsb.print_table(jsb.CFy, "CFy (Side)");
|
||||
jsb.print_table(jsb.CFz, "CFz (Lift)");
|
||||
|
||||
std::cout << "MOMENTS:" << std::endl;
|
||||
jsb.print_table(jsb.CMx, "CMx (Roll)");
|
||||
jsb.print_table(jsb.CMy, "CMy (Pitch)");
|
||||
jsb.print_table(jsb.CMz, "CMz (Yaw)");
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue