Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??

I've been interested in space stuff as far back as i can remember. Quite a while back, Scott Manley had a series on the Youtubes explaining how to calculate orbital changes and i implemented this in Javascript on my Blog.

But i always wanted a command line tool in Perl, so lets get to implementing it. It's not the nicest piece of code and it isn't optimizing the transfer burn (check the different options when to do the burns to minimize Delta-V), nor does it try for things like three or (more) burns/multiple intermediate orbits. But it gives a rough idea of "how bad did they miss the target orbit".

Here is the code (long, so in a "readmore" tag):

#!/usr/bin/env perl use strict; use warnings; # magic numbers my $km = 1000; # 1 km = 1000 meter my $pi = 3.14159265359; my $earth_radius = 6371 * $km; # earth radius at equator in meters my $M = 5.97219 * (10 ** 24); # earth mass in kg my $G = 6.67384 * (10 ** -11); # gravitational constant my $mu = $M * $G; print "Constants:\n"; print " Earth radius: $earth_radius meter\n"; print " Earth mass: $M kg\n"; print " Gravity: $G\n"; print " mu: $mu\n"; print "\n"; #my @av = ('1000/e0.5/0', '1000/1000/10'); my %source = convertOrbitDefinition('Source', shift @ARGV); my %target = convertOrbitDefinition('Target', shift @ARGV); my $totaldelta = 0; print "Calculating semi major axis...\n"; $source{semi} = ($source{per} + $source{ap}) / 2; $target{semi} = ($target{per} + $target{ap}) / 2; print "Defining Hohmann orbit...\n"; my %hohmann = ( per => $source{per}, ap => $target{per}, incl => 0, ); $hohmann{semi} = ($hohmann{per} + $hohmann{ap}) / 2; print "Orbital parameters for Hohmann orbit:\n"; print " Periapsis: $hohmann{per} m\n"; print " Apoapsis: $hohmann{ap} m\n"; print " Inclination: $hohmann{incl} deg\n"; print "\n"; print "Calculating first burn...\n"; # Speed at source orbit periapsis my $source_per_speed = sqrt(abs($mu * (2/$source{per} - 1/$source{semi +}))); # Required speed at transfer orbit periapsis (at the same point in orb +it as the source orbit periapsis) my $hohmann_per_speed = sqrt(abs($mu * (2/$hohmann{per} - 1/$hohmann{s +emi}))); # Speed difference my $first_burn = abs($hohmann_per_speed - $source_per_speed); $totaldelta += $first_burn; print "Data for burn at source orbit periapsis:\n"; print " Speed before burn: $source_per_speed m/s\n"; print " Speed after burn: $hohmann_per_speed m/s\n"; print " Required Delta-V: $first_burn m/s\n"; print "\n"; print "Calculating second burn...\n"; # # Speed at source orbit periapsis my $target_per_speed = sqrt(abs($mu * (2/$target{per} - 1/$target{semi +}))); # Required speed at transfer orbit apoapsis (at the same point in orbi +t as the target orbit periapsis) my $hohmann_ap_speed = sqrt(abs($mu * (2/$hohmann{ap} - 1/$hohmann{sem +i}))); my $second_burn; my $change_angle_deg = abs($source{incl} - $target{incl}); if($change_angle_deg == 0) { # No inclination change, just calculate the difference $second_burn = abs($target_per_speed - $hohmann_ap_speed); } else { print "Need to include plane change in second burn...\n"; # Convert to radians my $change_angle_rad = $change_angle_deg * $pi / 180; $second_burn = sqrt(abs(($hohmann_ap_speed ** 2) + ($target_per_sp +eed ** 2) - 2 * $hohmann_ap_speed * $target_per_speed * cos($change_a +ngle_rad) )); } print "Data for burn at Hohmann orbit apoapsis:\n"; print " Speed before burn: $hohmann_ap_speed m/s\n"; print " Speed after burn: $target_per_speed m/s\n"; if($change_angle_deg != 0) { print " Inclination before burn: $source{incl} deg\n"; print " Inclination after burn: $target{incl} deg\n"; print " Inclination change: $change_angle_deg deg\n"; } print " Required Delta-V: $second_burn m/s\n"; print "\n"; $totaldelta += $second_burn; print "Total Delta-V requirement: $totaldelta m/s\n"; exit(0); sub convertOrbitDefinition { my ($name, $rawstring) = @_; my ($per, $ap, $incl) = split/\//, $rawstring; # Periapsis, Apoaps +is, Inclination if($ap =~ /^e/) { print $name, " orbit is using eccentricity notation, convertin +g...\n"; $ap =~ s/^e//g; my $semi = $per; # Semi major axis my $ecc = $ap; # Eccentricity $ap = $semi * (1 + $ecc); $per = $semi * (1 - $ecc); } if($per > $ap) { print "Swapping periapsis and apoapsis for $name orbit...\n"; my $tmp = $per; $per = $ap; $ap = $tmp; } print "Converting to meter...\n"; $per *= $km; $ap *= $km; print "Adding earth radius...\n"; $per += $earth_radius; $ap += $earth_radius; print "Orbital parameters for $name orbit:\n"; print " Periapsis: $per m\n"; print " Apoapsis: $ap m\n"; print " Inclination: $incl deg\n"; print "\n"; return ( ap => $ap, per => $per, incl => $incl, ); }

The basic commandline is perl lithobreak.pl 1000/e0.5/0 1000/1000/10

First argumnent is the source orbit (initial orbit), the second is the target orbit. You can define each orbit in two ways, either using periapsis/apoapsis/inclination or semimajor-axis/eccentricity/inclination. All measurements in kilometers above earth surface. This example uses both:

  1. Source orbit of 1000/e0.5/0: Semi major axis of 1000km, "e" defined eccentricity mode with an eccentricity of 0.5, and an inclination of 0 degrees. Internally, this gets converted to a periapsis of 500km and an apoapsis of 1500km. Could have also been written as 500/1500/0
  2. Target orbit of 1000/1000/10: Circular orbit of 1000km with a 10 degree inclination. Could have also been written as 1000/e0/10.

Note: when using ap/per mode, don't worry about using the wrong order, it gets sorted out internally.

And here is the result of our calculation:

Constants: Earth radius: 6371000 meter Earth mass: 5.97219e+24 kg Gravity: 6.67384e-11 mu: 398574405096000 Source orbit is using eccentricity notation, converting... Converting to meter... Adding earth radius... Orbital parameters for Source orbit: Periapsis: 6871000 m Apoapsis: 7871000 m Inclination: 0 deg Converting to meter... Adding earth radius... Orbital parameters for Target orbit: Periapsis: 7371000 m Apoapsis: 7371000 m Inclination: 10 deg Calculating semi major axis... Defining Hohman orbit... Orbital parameters for Hohman orbit: Periapsis: 6871000 m Apoapsis: 7371000 m Inclination: 0 deg Calculating first burn... Data for burn at source orbit periapsis: Speed before burn: 7870.39409917514 m/s Speed after burn: 7748.85334888779 m/s Required Delta-V: 121.540750287353 m/s Calculating second burn... Need to include plane change in second burn... Data for burn at Hohman orbit apoapsis: Speed before burn: 7223.22227109049 m/s Speed after burn: 7353.45599234394 m/s Inclination before burn: 0 deg Inclination after burn: 10 deg Inclination change: 10 deg Required Delta-V: 1277.04850388302 m/s Total Delta-V requirement: 1398.58925417037 m/s

Yeah, 1.3km/s required Delta-V. Not good. Better call our Kerbals to build us a new sat, this one isn't going to make it...

perl -e 'use MIME::Base64; print decode_base64("4pmsIE5ldmVyIGdvbm5hIGdpdmUgeW91IHVwCiAgTmV2ZXIgZ29ubmEgbGV0IHlvdSBkb3duLi4uIOKZqwo=");'

In reply to Rough Delta-V estimate for Hohmann transfer orbits by cavac

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others taking refuge in the Monastery: (3)
As of 2024-04-19 21:33 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found