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 Oct 26, 2020
1 parent 8b698e1 commit 5a298cd
Show file tree
Hide file tree
Showing 3 changed files with 555 additions and 0 deletions.
141 changes: 141 additions & 0 deletions src/ship/PPtester.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
#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_S_ratio(
// 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 &Sratio, // ratio (0.0 .. 1.0) of path completion
// 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
)
{
double S_end = Stotal * Sratio;
double t_curr = 0;
double S_curr = 0;
double V_curr = 0;
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;
double t_end = 0;
int state = 1; // -1: decc, 0: free, 1: acc
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, acap);
double S_decc = S2_from_t2_mixed(t_decc, V_curr, EV, m_curr, F, acap);
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;
if (S2 == 0) S2 = Stotal - S_curr;
}
}
a_curr = F / m_curr;
if (a_curr > acap) {
a_curr = acap;
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 (S_curr > S_end) {
if (t_end == 0) {
t_end = t_curr;
ret_V = V_curr;
ret_mf = mf_curr;
ret_state = state;
}
}
} while (V_curr >= 0);
t_est = t_curr - t_end;
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 * 10; // ~10 AU
double Sratio;
double t_est;
double t_full;

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, EV, F, acap, mh, mf, mce);

for (double i = 0.01; i < 0.995; i += 0.01) {
Sratio = i;
std::cout << "-----------------------------\n";
std::cout << "Total path: " << Stotal << " ratio: " << Sratio << '\n';

pp.setSRatio(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_S_ratio(V_curr, mf_curr, t_est, t_full, state, Stotal, Sratio, EV, F, acap, mh, mf, mce);
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.setTime(pp.getFullTime() - t_est);
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 5a298cd

Please sign in to comment.