C++ Project: Orbital Mechanics

Download as doc, pdf, or txt
Download as doc, pdf, or txt
You are on page 1of 19

PROJECT 2

HOHMANN TRANSFER ORBIT


GANLATH, AKILA
CSC 5

Introduction

Travel through the solar system can be a dangerous and expensive venture. After
the tremendous amount of fuel/energy expended in simply reaching escape
velocity, there must be remaining fuel for further orientation and to break out of a
stable Earth orbit. This facet and other obstructions are oft cited as reasons to turn
away from space travel, despite its numerous economic, scientific, and social
benefits. Fortunately, there are methods that make covering these vast distances
relatively cheap. One of these cost-effective solutions is known as a Hohmann
transfer orbit. With the correct alignment between Earth and the destination, and
two properly timed burns, a spacecraft can be made to coast across with very little
fuel expenditure.

Summary
Blank lines 30
Comment lines 25
Total 305
55 variables
The program that I have built is a calculator for a highly simplified Hohmann
transfer orbit . It assumes that gravitational effects between the destination planet
and the spacecraft are null, and depends only upon the mutual attraction of Sol as
its gravitational pivot point.
I used the project as an opportunity to implement the different techniques we have
covered in the class. I was able to construct and use variables of different data
types, constants, control structures, I/O manipulation, functions, and Boolean
operators. Furthermore, I used single and two dimensional arrays to hold the dozens
of values that had to be accounted for the rocket motor, destinations, and
propellant types. I used files to store some of the data read into these arrays, such
as the specifications for the different motors.
I ran into problems with choosing the correct data types for my distance functions.
Because I had used such large numbers initially, and had passed these values to
more than one function, the variables became infinite when pushed into lower order

variable data types. In implementing arrays I had to learn the best way to organize
the data, and find efficient techniques to calling these values when needed.
In completion I realize that I should have taken acceleration due to gravitational
effects into account as their absence resulted in unrealistic outcomes. For instance,
to reach the gas giants my program insists that megatons of liquid hydrogen/liquid
oxygen propellant would be necessary to move achieve the delta v necessary to
complete a transfer. However, the Voyager spacecraft were able to achieve much
greater delta v requirements by using the gravity wells of planets to slingshot to
incredible speeds

Psuedocode
Prototype of menu, planets, and equation functions
Begin main function
Introduction
Declare loop variable
Do
Declare choice and mass variables
Call drive function
Prompt user for rerun
Get answer
While prompt is y or Y
End main
Begin drive
Prompt user for mass
Get mass
Display options of drives
Get drive choice
Call switch function and pass choice into it

Case 1: initialize engine variables and pass to specs function


Case 2: initialize engine variables and pass to specs function
Case 3: initialize engine variables and pass to specs function
Case 4: initialize engine variables and pass to specs function
Case 5: initialize engine variables and pass to specs function
Case 6: initialize engine variables and pass to specs function
Default: invalid choice
End drive
Begin Specs
Declare row and column constants
Declare engine variables, specification arrays, and fuel arrays
Open file with corresponding data
Read data into engine arrays
Close file
Open file with fuel data
Read data into fuel arrays
Close file
Initialize engine mass, specific impulse, and dry mass
Pass these values to destination function
End specs
Begin destination
Display destination options
Get choice
Call switch function and pass choice into it
case 1: call mercury function and pass mass, isp, and fuel type
case 2: call venus function and pass mass, isp, and fuel type
case 3: call mars function and pass mass, isp, and fuel type
case 4: call asteroid function and pass mass, isp, and fuel type

case 5: call Jupiter function and pass mass, isp, and fuel type
case 6: call Saturn function and pass mass, isp, and fuel type
case 7: call Uranus function and pass mass, isp, and fuel type
case 8: call Neptune function and pass mass, isp, and fuel type
case 9: call Pluto function and pass mass, isp, and fuel type
case 10: call kuiper function and pass mass, isp, and fuel type
default: tell user it is an invalid option
End destination
Begin Mercury
Declare aphelion, perihelion , name.
Call and pass these values to the Hohmann function alongside mass, isp, and
fuel
Do this routine for each corresponding destination up to kuiper
End Mercury
Begin Hohmann
Call variables passed from one of the destination functions, name, mass,
aphelion, and perihelion
Declare and initialize constants for mass of sun, orbital radius of earth, and
Pi
Declare variables for text, the final, initial, and total delta v, mu, units of time,
units of length, units of mass, and transit time
If called aphelion and perihelion are mutually greater than earth orbit
Calculate delta vs using method 1 for both aphelion and perihelion
then the total
Else
Calculate delta vs using method 2 for both aphelion and perihelion
then the total

Calculate the transit times for both aphelion and perihelion in months
If the transit time for either is > 12
Initialize time unit as years

If the delta v for either perihelion or aphelion is > 1000


Initialize distance unit as kilometers
Call prop mass function and pass delta v for aphelion and perihelion
separately, alongside mass and isp
If resultant masses are greater or equal to 10e9 then mass unit is gigaton
If resultant masses are greater or equal to 10e6 then mass unit is megaton
If resultant masses are greater or equal to 10e3 then mass unit is kiloton
Output the results of the conversions and calculations for delta v, propellant
mass, and transit time
End Hohmann
Begin propellant
Declare constant for natural number e and acceleration due to gravity on
Earths surface
Declare exhaust velocity and mass of propellant
Intialize exhaust velocity as isp*gravitational
Initialize propellant mass as dry mass/(e^(dv/exhaust velocity)-1)
Return mass of propellant to hohmann
End propellant

Flowchart

References

C++ Savitch textbook

www.cpluplus.com

Program
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <iomanip>
#include <fstream>
#include <cstring>
using namespace std;

//Function prototypes
void drive();
void specs(int, int, float);
void destination(long double, float, string);
void mercury(float, float, string);
void venus(float, float, string);
void mars(float, float, string);
void asteroid(float, float, string);
void jupiter(float, float, string);
void saturn(float, float, string);
void uranus(float, float, string);
void neptune(float, float, string);
void pluto(float, float, string);
void kuiper(float, float, string);
void hohmann(long double, float, float, float, string, string);
float propellant(float, float, float);
int main() {
//Program intro, decided it was unnecessary to loop this far back
cout<<"This program will calculate the change in velocity necessary to complete
a"<<endl;
cout<<"Hohmann transfer, an orbit considered 'cheap'in terms of delta-V
budget."<<endl;
cout<<"It will also compute the transit time of the transfer, and the
fuel/oxidizer ."<<endl;
cout<<"required to complete the journey."<<endl;
cout<<"The initial location is Earth orbit, and the destination is assumed to be
aligned."<<endl;
cout<<"on the same orbital plane."<<endl;
cout<<"\n";

char prompt_answer;
//Beginning to program 'run' loop
do{
//calling menu function
drive();
cout<<"\n";
//Prompt user for rerun
cout<<"Press 'y' or 'Y' to run again"<<endl;
cin>>prompt_answer;
}while(prompt_answer=='y'||prompt_answer=='Y');
}
//menu function that is called to display fuel and destination choices each of
void drive(){
int schoice, engine, fuel;
float shell_mass;
cout<<"Please input the mass of your spacecraft in metric tons"<<endl;
cout<<"(For reference the shuttle orbiter was 2,041 metric tons, while"<<endl;
cout<<"the Voyager satellites were each .72 of a metric ton.)"<<endl;
cin>>shell_mass;
cout<<"\n";
cout<<"Choose a drive for the spacecraft"<<endl;
cout<<" Manufacturer
Impulse(sec)"<<endl;

Engine

cout<<"1) Space-X
cout<<"2) Aerojet

Merlin-1c
LR-87

cout<<"3) NPO Energomash


338.0"<<endl;
cout<<"4) Rocketdyne
452.3"<<endl;

Fuel

Thrust(N) Vac. Specific

LOX/RP1
LOX/LH2

RD-180
SSME/RS-25

4.45e3
7.33e3

LOX/RP1
LOX/LH2

342.0"<<endl;
290.0"<<endl;

4.15e6
2.28e3

cout<<"5) Aerojet/Westinghouse NERVA-2


850.0"<<endl;
cout<<"6) Ad Astra

VASIMR

LH2

LH2
5

3.36e5
5000.0"<<endl;

cin>>schoice;
cout<<"\n";
switch(schoice){
case 1: specs(engine=0, fuel=0, shell_mass);break;
case 2: specs(engine=1, fuel=1, shell_mass);break;
case 3: specs(engine=2, fuel=0, shell_mass);break;
case 4: specs(engine=3, fuel=1, shell_mass);break;
case 5: specs(engine=4, fuel=2, shell_mass);break;
case 6: specs(engine=5, fuel=2, shell_mass);break;
default :
cout<<"That is not a valid choice of drive"<<endl;break;
}
cout<<" \n";
}//initialize the spacecraft specifications from the values passed from the drive
function
void specs(int e, int f, float sm){
const int ROWS=2, COLS=6;
long double engine_mass, dry_mass, isp, motor[ROWS][COLS];
string fuels[3];
ifstream input;
input.open("engine.txt");
if(input.fail()){
//cout<<"Input file opening failed . \n";
}//fill motor array from file
for(int row=0;row<ROWS;row++){
int col=0;

input>>motor[row][col];
/*if(row==1){
cout<<"isp ="<<motor[row][col]<<endl;
}else
cout<<"mass ="<<motor[row][col]<<endl;*/
for(col=1;col<COLS;col++){
input>>motor[row][col];
/*if(row==1){
cout<<"isp ="<<motor[row][col]<<endl;
}else
cout<<"mass ="<<motor[row][col]<<endl;*/
}
}
input.close();
input.open("fuel.txt");
if(input.fail()){
cout<<"Input file opening failed . \n";
}//fill fuel array from file
for(int row=0;row<3;row++){
input>>fuels[row];
//cout<<"fuel ="<<fuels[row]<<endl;
}
input.close();
string fuel=fuels[f];
engine_mass=motor[0][e];//cout<<"engine mass ="<<engine_mass<<endl;
isp=motor[1][e];//cout<<"specific impulse ="<<isp<<endl;
dry_mass=engine_mass+sm;//cout<<"dry mass ="<<dry_mass<<endl;
cout<<"The mass of your spacecraft is now "<<dry_mass<<" metric
tons"<<endl;

destination(dry_mass,isp,fuel);
}
void destination(long double m, float i, string f ){
int dchoice;
cout<<"\n";
cout<<"Choose a destination by entering its corresponding number"<<endl;
cout<<"1) Mercury"<<endl;
cout<<"2) Venus"<<endl;
cout<<"3) Mars"<<endl;
cout<<"4) Asteroid Belt"<<endl;
cout<<"5) Jupiter"<<endl;
cout<<"6) Saturn"<<endl;
cout<<"7) Uranus"<<endl;
cout<<"8) Neptune"<<endl;
cout<<"9) Pluto"<<endl;
cout<<"10) Kuiper Belt"<<endl;
cout<<"\n";
cin>>dchoice;
switch(dchoice){
case 1: mercury(m,i,f);break;
case 2: venus(m,i,f);break;
case 3: mars(m,i,f);break;
case 4: asteroid(m,i,f);break;
case 5: jupiter(m,i,f);break;
case 6: saturn(m,i,f);break;
case 7: uranus(m,i,f);break;
case 8: neptune(m,i,f);break;
case 9: pluto(m,i,f);break;

case 10: kuiper(m,i,f);break;


default:
cout<<"That is not a valid choice of destination"<<endl;break;
}
}
//passing mass of rocket to planet function, which contains distance data
void mercury(float mass, float isp, string fuel){
float aphelion=6.98e10;//maximum distance from sun
float perihelion=4.6e10;//minimum distance from sun
string name= "Mercury";//name of destination
hohmann(aphelion, perihelion, isp, mass, name, fuel);//calling and passing values
to
//calculation function hohmann
}
void venus(float mass, float isp, string fuel){
float aphelion=1.08e11;
float perihelion=1.07e11;
string name= "Venus";
hohmann(aphelion, perihelion, isp, mass, name, fuel);
}
void mars(float mass, float isp, string fuel){
float aphelion=2.49e11;
float perihelion=2.06e11;
string name= "Mars";
hohmann(aphelion, perihelion, isp, mass, name, fuel);
}
void asteroid(float mass, float isp, string fuel){
float aphelion=3.27e11;
float perihelion=3.08e11;

string name= "Asteroid Belt";


hohmann(aphelion, perihelion, isp, mass, name, fuel);
}
void jupiter(float mass, float isp, string fuel){
float aphelion=8.165e11;
float perihelion=7.405e11;
string name= "Jupiter";
hohmann(aphelion, perihelion, isp, mass, name, fuel);
}
void saturn(float mass, float isp, string fuel){
float aphelion=1.513e12;
float perihelion=1.353e12;
string name= "Saturn";
hohmann(aphelion, perihelion, isp, mass, name, fuel);
}
void uranus(float mass, float isp, string fuel){
float aphelion=3.01e12;
float perihelion=2.75e12;
string name= "Uranus";
hohmann(aphelion, perihelion, isp, mass, name, fuel);
}
void neptune(float mass, float isp, string fuel){
float aphelion=4.6e12;
float perihelion=4.5e12;
string name= "Neptune";
hohmann(aphelion, perihelion, isp, mass, name, fuel);
}
void pluto(float mass, float isp, string fuel){

float aphelion=7.3e12;
float perihelion=4.4e12;
string name= "Pluto";
hohmann(aphelion, perihelion, isp, mass, name, fuel);
}
void kuiper(float mass, float isp, string fuel){
float aphelion= 7.48e12;
float perihelion=4.49e12;
string name= "Kuiper Belt";
hohmann(aphelion, perihelion, isp, mass, name, fuel);
}
void hohmann(long double r1, float r2, float i, float m, string n, string f ){
//declare and initialize constants, variables
float const M_SUN=1.9e30, R_EARTH=1.5e11,
C_GRAVITY=6.7e-11,PI=4*atan(1);
long double dv1, dv2, dv3, dv4, dvtot_ap, dvtot_pe, transit_ap=0, transit_pe=0,
mu, ap_prop_mass, pe_prop_mass;
string time_unit=" months", distance_unit=" meters", mass_unit=" tons";
m*=10e3;
//Calculate the initial, final, and total delta vee's for aphelion & perihelion
mu=C_GRAVITY*(M_SUN+m);
//Sort which equation to use based on values initialized for orbital radii
if(R_EARTH<r1&&R_EARTH<r2){
dv1=sqrt(mu/R_EARTH)*(sqrt((2.0*r1)/(R_EARTH+r1))-1.0);
dv2=sqrt(mu/r1)*(1.0-sqrt((2.0*r1)/(R_EARTH+r1)));
dvtot_ap=dv1+dv2;//d-vee total at farthest distance

dv3=sqrt(mu/R_EARTH)*(sqrt((2.0*r2)/(R_EARTH+r2))-1.0);
dv4=sqrt(mu/r2)*(1.0-sqrt((2.0*r2)/(R_EARTH+r2)));

dvtot_pe=dv3+dv4;//d-vee total at shortest distance


}else{
dv1=sqrt(mu/r1)*(sqrt((2.0*R_EARTH)/(R_EARTH+r1))-1.0);
dv2=sqrt(mu/R_EARTH)*(1.0-sqrt((2.0*R_EARTH)/(R_EARTH+r1)));
dvtot_ap=dv1+dv2;//d-vee total at farthest distance

dv3=sqrt(mu/r2)*(sqrt((2.0*R_EARTH)/(R_EARTH+r2))-1.0);
dv4=sqrt(mu/R_EARTH)*(1.0-sqrt((2.0*R_EARTH)/(R_EARTH+r2)));
dvtot_pe=dv3+dv4;//d-vee total at shortest distance
}
//Calculate the time to reach destination
transit_ap=PI*sqrt((pow((R_EARTH+r1),3))/(8*mu))/2592000;//convert to
//months from seconds
transit_pe=PI*sqrt((pow((R_EARTH+r2),3))/(8*mu))/2592000;

//convert to appropriate scale of time if necessary


if(transit_ap>12||transit_pe>12){
transit_ap=transit_ap/12.0;
transit_pe=transit_pe/12.0;
time_unit=" years";
}
//convert to appropriate scale of distance if necessary
if(dvtot_ap>1000||dvtot_pe>1000){
dvtot_ap=dvtot_ap/1000;
dvtot_pe=dvtot_pe/1000;
distance_unit=" kilometers";
}
//convert to appropriate scale of mass if necessary

ap_prop_mass=propellant(dvtot_ap,m,i);
pe_prop_mass=propellant(dvtot_pe,m,i);
if(ap_prop_mass>=10e9){
ap_prop_mass/=10e9;
mass_unit=" gigatons";
}
if(pe_prop_mass>=10e9){
pe_prop_mass/=10e9;
mass_unit=" gigatons";
}
if(ap_prop_mass>=10e6){
ap_prop_mass/=10e6;
mass_unit=" megatons";
}
if(pe_prop_mass>=10e6){
pe_prop_mass/=10e6;
mass_unit=" megatons";
}
if(ap_prop_mass>=10e3){
ap_prop_mass/=10e3;
mass_unit=" kilotons";
}
if(pe_prop_mass>=10e3){
pe_prop_mass/=10e3;
mass_unit=" kilotons";
}
//Output results
cout<<"The total delta-V necessary when " <<n<<" is at aphelion is "<<

setprecision(3)<<dvtot_ap<<setprecision(3)<<distance_unit<<"/sec"<<endl;
//convert distance to kilometers
cout<<"With the drive configuration it would require
"<<setprecision(3)<<ap_prop_mass<<mass_unit<<" of "<<f<<endl;
cout<<"At this distance it will take "<<transit_ap<<time_unit<<endl;
cout<<"\n";
cout<<"The total delta-V necessary when " <<n<<" is at perihelion is "<<
setprecision(3)<<dvtot_pe<<setprecision(3)<<distance_unit<<"/sec"<<endl;
cout<<"With the drive configuration it would require
"<<setprecision(3)<<pe_prop_mass<<mass_unit<<" of "<<f<<endl;
cout<<"At this distance it will take "<<transit_pe<<time_unit<<endl;
}
float propellant(float d_vel, float m, float i){
const float G0=9.81;//acceleration due to earth in meters/sec
const float E=2.71828;//base of natural log
long double vel_exh, mass_propel;
vel_exh=i*G0;//exhaust velocity = specific impulse*acceleration due to earths
gravity
//cout<<"exhaust velocity ="<<vel_exh<<"meters/sec"<<endl;
mass_propel=m/(pow(E,(d_vel/vel_exh))-1);//mass of propellant = dry mass/
(e^(dVee/exhaust velocity)-1) in kilograms
return mass_propel/1000;//propellant mass in tons pass this value back to
hohmann
}

You might also like