Skip to content

Commit

Permalink
Add class for pre-calculating spaceship path
Browse files Browse the repository at this point in the history
A one-dimensional case is considered, given the parameters of the ship
and the length of the path, a flight plan is calculated, which allows
determining the time, speed, and mass of the ship at any point on the
way.

Also added a simple simulator for testing purposes.
  • Loading branch information
Gliese852 committed Nov 21, 2020
1 parent 8b698e1 commit be227fa
Show file tree
Hide file tree
Showing 3 changed files with 559 additions and 0 deletions.
145 changes: 145 additions & 0 deletions src/ship/PPtester.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
#include "PrecalcPath.cpp"
#include <iostream>

// run it with:
// g++ -std=c++11 -pedantic-errors PPtester.cpp && ./a.out
//
// the output has 3 results:
// pre: - algebraic (almost) precalculated with PrecalcPath class, distance is set
// sim: - simulated
// che: - calculated with PrecalcPath class, time is set (the time obtained in the calculation is substituted)

// one-dimensional space ship flight simulator
void simulate_V_and_mf_from_t(
// output:
double &ret_V, // velocity at this point, m/s^2
double &ret_mf, // remaining fuel at this point, kg
double &t_est, // estimate
double &t_full, //
int &ret_state, // -1: deccelerating, 0: free flight, 1: accelerating
// input:
const double &Stotal, // total path length, m
const double &V0, // velocity at start
const double &t_catch, // time when catch parameters
// ship params
const double &EV, // effective exhaust velocity, m/s
const double &F, // main (forward) thruster force , N
const double &acap, // acceleration limit (forward), m/m^2
const double &mh, // hull mass, kg
const double &mf, // fuel mass, kg
const double &mce, // cargo & equipment mass, kg
const double &margin // breaking reserve
)
{
double t_curr = 0;
double S_curr = 0;
double V_curr = V0;
double mf_curr = mf;
double d_t = 0.1; // timestep
double a_curr;
double m_curr;
double t_norm = 0;
double S2 = 0;
double m1 = 0;
double t1 = 0;
bool t_catched = false;
int state = 1; // -1: decc, 0: free, 1: acc
int stadia = 0; // V_curr < 0; V_curr > 0 => stadia = 1; V_curr < 0 => stadia 2;
double setmargin = 1.0;
do {
// timestep
m_curr = mh + mce + mf_curr;
if (state != -1) {
double dv_left = dV_from_dm(m_curr, mf_curr, EV);
double t_decc = t_from_dV_mixed(V_curr, EV, m_curr, F * margin, acap * margin);
double S_decc = S2_from_t2_mixed(t_decc, V_curr, EV, m_curr, F * margin, acap * margin);
if (dv_left <= V_curr) {
state = 0;
if (m1 == 0) m1 = m_curr;
if (t1 == 0) t1 = t_curr;
}
if (S_decc >= Stotal - S_curr) {
state = -1;
setmargin = margin;
if (S2 == 0) S2 = Stotal - S_curr;
}
}
a_curr = F / m_curr * setmargin;
if (a_curr > acap * setmargin) {
a_curr = acap * setmargin;
if (t_norm == 0) t_norm = t_curr;
}
a_curr = a_curr * state;
V_curr = V_curr + a_curr * d_t;
S_curr = S_curr + V_curr * d_t + a_curr * d_t * d_t / 2;
t_curr = t_curr + d_t;
mf_curr = mf_curr - dm_from_t_norm(d_t, EV, std::abs(m_curr * a_curr));
if (t_catch < t_curr && !t_catched) {
ret_V = V_curr;
ret_mf = mf_curr;
ret_state = state;
t_catched = true;
}
if (stadia == 0 && V_curr > 0) stadia = 1;
if (stadia == 1 && V_curr < 0) stadia = 2;
} while (stadia < 2);
t_est = t_curr - t_catch;
t_full = t_curr;
}

int main()
{
// sino params
double F = 2000000;
double EV = 20900000;
double acap = 38.259;
double mh = 20000;
double mf = 30000;
double mce = 10000;
double Stotal = 150000000000 * 30; // ~10 AU
double t_est;
double t_full;
double V0 = 2e6;
double margin = 0.8;

double V_curr, mf_curr;
int state;

const double g = 9.81;
double m = mh + mf + mce;
std::cout << "a_full: " << F / m / g << '\n';
std::cout << "a_empty: " << F / (m - mf) / g << '\n';
std::cout << "acap: " << acap / g << '\n';

PrecalcPath pp(Stotal, V0, EV, F, acap, mh + mf + mce, mf, margin);

for (double i = 0; i < 200000; i += 10000) {
std::cout << "-----------------------------\n";
std::cout << "Total path: " << Stotal << '\n';

pp.setTime(i);
std::cout << "pre: ";
switch (pp.getState()) {
case -1: std::cout << "deccel: "; break;
case 0: std::cout << "freefl: "; break;
case 1: std::cout << "accelr: "; break;
}
std::cout << "V_curr: " << pp.getVel() << " mf_curr: " << pp.getFuel() << " tfull: " << pp.getFullTime() << " est: " << pp.getEstimate() << '\n';
simulate_V_and_mf_from_t(V_curr, mf_curr, t_est, t_full, state, Stotal, V0, pp.getFullTime() - pp.getEstimate(), EV, F, acap, mh, mf, mce, margin);
std::cout << "sim: ";
switch (state) {
case -1: std::cout << "deccel: "; break;
case 0: std::cout << "freefl: "; break;
case 1: std::cout << "accelr: "; break;
}
std::cout << "V_curr: " << V_curr << " mf_curr: " << mf_curr << " tfull: " << t_full << " est: " << t_est << '\n';
pp.setDist(pp.getDist());
std::cout << "chk: ";
switch (pp.getState()) {
case -1: std::cout << "deccel: "; break;
case 0: std::cout << "freefl: "; break;
case 1: std::cout << "accelr: "; break;
}
std::cout << "V_curr: " << pp.getVel() << " mf_curr: " << pp.getFuel() << " tfull: " << pp.getFullTime() << " est: " << pp.getEstimate() << '\n';
}
}
Loading

0 comments on commit be227fa

Please sign in to comment.