Seems like a lot changed...
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 103 KiB After Width: | Height: | Size: 111 KiB |
@@ -7,7 +7,7 @@
|
||||
viewBox="0 0 279.4 215.9"
|
||||
version="1.1"
|
||||
id="svg5"
|
||||
inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20)"
|
||||
inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20, custom)"
|
||||
sodipodi:docname="mbh.svg"
|
||||
inkscape:export-filename="/home/connor/projects/thesis/LaTeX/flowcharts/mbh.png"
|
||||
inkscape:export-xdpi="150"
|
||||
@@ -27,15 +27,18 @@
|
||||
inkscape:document-units="mm"
|
||||
showgrid="true"
|
||||
units="in"
|
||||
inkscape:zoom="1.1148803"
|
||||
inkscape:cx="548.48938"
|
||||
inkscape:cy="287.02633"
|
||||
inkscape:window-width="1916"
|
||||
inkscape:window-height="1045"
|
||||
inkscape:zoom="0.78833942"
|
||||
inkscape:cx="525.15451"
|
||||
inkscape:cy="378.64401"
|
||||
inkscape:window-width="1912"
|
||||
inkscape:window-height="1040"
|
||||
inkscape:window-x="1920"
|
||||
inkscape:window-y="31"
|
||||
inkscape:window-y="32"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1">
|
||||
inkscape:current-layer="layer1"
|
||||
inkscape:snap-smooth-nodes="false"
|
||||
inkscape:snap-midpoints="false"
|
||||
inkscape:snap-object-midpoints="false">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid9"
|
||||
@@ -270,6 +273,32 @@
|
||||
width="113.38583"
|
||||
height="18.897638"
|
||||
id="rect242401-5-7" />
|
||||
<marker
|
||||
style="overflow:visible"
|
||||
id="Arrow2Mend-7"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow2Mend"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
transform="scale(-0.6)"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
style="fill:context-stroke;fill-rule:evenodd;stroke:context-stroke;stroke-width:0.625;stroke-linejoin:round"
|
||||
id="path184215-5" />
|
||||
</marker>
|
||||
<rect
|
||||
x="368.50394"
|
||||
y="226.77165"
|
||||
width="64.108277"
|
||||
height="14.130817"
|
||||
id="rect242401-2" />
|
||||
<rect
|
||||
x="368.50394"
|
||||
y="226.77165"
|
||||
width="64.108276"
|
||||
height="14.130817"
|
||||
id="rect242401-2-6" />
|
||||
</defs>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
@@ -299,17 +328,17 @@
|
||||
inkscape:export-ydpi="150"><tspan
|
||||
x="51.237262"
|
||||
y="35.095099"
|
||||
id="tspan295134">Generate Random </tspan><tspan
|
||||
id="tspan10729">Generate Random </tspan><tspan
|
||||
x="53.253338"
|
||||
y="38.622885"
|
||||
id="tspan295136">Mission Guess</tspan></text>
|
||||
id="tspan10731">Mission Guess</tspan></text>
|
||||
<rect
|
||||
style="fill:#44aa00;fill-rule:evenodd;stroke:#143b11;stroke-width:0.5;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
style="fill:#44aa00;fill-rule:evenodd;stroke:#143b11;stroke-width:0.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect33-3"
|
||||
width="25"
|
||||
height="15"
|
||||
x="97.5"
|
||||
y="32.5"
|
||||
y="42.5"
|
||||
rx="1"
|
||||
ry="1"
|
||||
inkscape:export-filename="/home/connor/projects/thesis/LaTeX/flowcharts/mbh.png"
|
||||
@@ -326,8 +355,33 @@
|
||||
inkscape:export-xdpi="150"
|
||||
inkscape:export-ydpi="150"><tspan
|
||||
x="98.748283"
|
||||
y="35.095099"
|
||||
id="tspan295138">Correct the Guess</tspan></text>
|
||||
y="45.095099"
|
||||
id="tspan10733">Correct the Guess</tspan></text>
|
||||
<rect
|
||||
style="fill:#44aa00;fill-rule:evenodd;stroke:#143b11;stroke-width:0.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect33-3-9"
|
||||
width="25"
|
||||
height="15"
|
||||
x="97.5"
|
||||
y="22.5"
|
||||
rx="1"
|
||||
ry="1"
|
||||
inkscape:export-filename="/home/connor/projects/thesis/LaTeX/flowcharts/mbh.png"
|
||||
inkscape:export-xdpi="150"
|
||||
inkscape:export-ydpi="150" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
id="text5352-6-7"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.82223px;line-height:1.25;font-family:Roboto;-inkscape-font-specification:Roboto;text-align:center;white-space:pre;shape-inside:url(#rect33-3-9);fill:#000000;fill-opacity:1;stroke:none"
|
||||
x="35.644531"
|
||||
y="0"
|
||||
transform="translate(-0.01239847,5.9494573)"
|
||||
inkscape:export-filename="/home/connor/projects/thesis/LaTeX/flowcharts/mbh.png"
|
||||
inkscape:export-xdpi="150"
|
||||
inkscape:export-ydpi="150"><tspan
|
||||
x="98.748283"
|
||||
y="25.095099"
|
||||
id="tspan10735">Correct the Guess</tspan></text>
|
||||
<rect
|
||||
style="fill:#44aa00;fill-rule:evenodd;stroke:#143b11;stroke-width:0.5;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
id="rect33-3-1"
|
||||
@@ -352,7 +406,7 @@
|
||||
inkscape:export-ydpi="150"><tspan
|
||||
x="201.24829"
|
||||
y="99.141974"
|
||||
id="tspan295140">Correct the Guess</tspan></text>
|
||||
id="tspan10737">Correct the Guess</tspan></text>
|
||||
<rect
|
||||
style="fill:#44aa00;fill-rule:evenodd;stroke:#143b11;stroke-width:0.5;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
id="rect33-3-2"
|
||||
@@ -377,10 +431,10 @@
|
||||
inkscape:export-ydpi="150"><tspan
|
||||
x="227.35348"
|
||||
y="35.095099"
|
||||
id="tspan295142">Store as Current </tspan><tspan
|
||||
id="tspan10739">Store as Current </tspan><tspan
|
||||
x="227.66698"
|
||||
y="38.622885"
|
||||
id="tspan295144">Best, Set Drill=0</tspan></text>
|
||||
id="tspan10741">Best, Set Drill=0</tspan></text>
|
||||
<rect
|
||||
style="fill:#44aa00;fill-rule:evenodd;stroke:#143b11;stroke-width:0.5;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
id="rect33-3-2-9"
|
||||
@@ -405,10 +459,10 @@
|
||||
inkscape:export-ydpi="150"><tspan
|
||||
x="202.34314"
|
||||
y="67.118536"
|
||||
id="tspan295146">Perturb the Best </tspan><tspan
|
||||
id="tspan10743">Perturb the Best </tspan><tspan
|
||||
x="202.27079"
|
||||
y="70.646322"
|
||||
id="tspan295148">Guess (in Basin)</tspan></text>
|
||||
id="tspan10745">Guess (in Basin)</tspan></text>
|
||||
<circle
|
||||
style="fill:#3771c8;stroke:#1d195c;stroke-width:0.5;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
id="path49453"
|
||||
@@ -476,12 +530,12 @@
|
||||
inkscape:export-ydpi="150"><tspan
|
||||
x="37.12022"
|
||||
y="52.132153"
|
||||
id="tspan295150">Hit Search<tspan
|
||||
id="tspan10747">Hit Search<tspan
|
||||
y="52.132153"
|
||||
id="tspan295152"> </tspan></tspan><tspan
|
||||
id="tspan10749"> </tspan></tspan><tspan
|
||||
x="37.12022"
|
||||
y="55.659938"
|
||||
id="tspan295154">Limit?</tspan></text>
|
||||
id="tspan10751">Limit?</tspan></text>
|
||||
<circle
|
||||
style="fill:#3771c8;stroke:#1d195c;stroke-width:0.5;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
id="path49453-9-7"
|
||||
@@ -503,12 +557,12 @@
|
||||
inkscape:export-ydpi="150"><tspan
|
||||
x="107.7821"
|
||||
y="78.232147"
|
||||
id="tspan295156">Hit Drill<tspan
|
||||
id="tspan10753">Hit Drill<tspan
|
||||
y="78.232147"
|
||||
id="tspan295158"> </tspan></tspan><tspan
|
||||
id="tspan10755"> </tspan></tspan><tspan
|
||||
x="107.7821"
|
||||
y="81.759936"
|
||||
id="tspan295160">Limit?</tspan></text>
|
||||
id="tspan10757">Limit?</tspan></text>
|
||||
<circle
|
||||
style="fill:#3771c8;stroke:#1d195c;stroke-width:0.5;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
id="path49453-5"
|
||||
@@ -530,22 +584,22 @@
|
||||
inkscape:export-ydpi="150"><tspan
|
||||
x="141.6602"
|
||||
y="25.945316"
|
||||
id="tspan295162">Better<tspan
|
||||
id="tspan10759">Better<tspan
|
||||
y="25.945316"
|
||||
id="tspan295164"> </tspan></tspan><tspan
|
||||
id="tspan10761"> </tspan></tspan><tspan
|
||||
x="141.6602"
|
||||
y="29.473104"
|
||||
id="tspan295166">than<tspan
|
||||
id="tspan10763">than<tspan
|
||||
y="29.473104"
|
||||
id="tspan295168"> </tspan></tspan><tspan
|
||||
id="tspan10765"> </tspan></tspan><tspan
|
||||
x="141.6602"
|
||||
y="33.000892"
|
||||
id="tspan295170">current<tspan
|
||||
id="tspan10767">current<tspan
|
||||
y="33.000892"
|
||||
id="tspan295172"> </tspan></tspan><tspan
|
||||
id="tspan10769"> </tspan></tspan><tspan
|
||||
x="141.6602"
|
||||
y="36.528678"
|
||||
id="tspan295174">best?</tspan></text>
|
||||
id="tspan10771">best?</tspan></text>
|
||||
<circle
|
||||
style="fill:#3771c8;stroke:#1d195c;stroke-width:0.5;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
id="path49453-5-9"
|
||||
@@ -567,22 +621,22 @@
|
||||
inkscape:export-ydpi="150"><tspan
|
||||
x="141.6602"
|
||||
y="25.945316"
|
||||
id="tspan295176">Better<tspan
|
||||
id="tspan10773">Better<tspan
|
||||
y="25.945316"
|
||||
id="tspan295178"> </tspan></tspan><tspan
|
||||
id="tspan10775"> </tspan></tspan><tspan
|
||||
x="141.6602"
|
||||
y="29.473104"
|
||||
id="tspan295180">than<tspan
|
||||
id="tspan10777">than<tspan
|
||||
y="29.473104"
|
||||
id="tspan295182"> </tspan></tspan><tspan
|
||||
id="tspan10779"> </tspan></tspan><tspan
|
||||
x="141.6602"
|
||||
y="33.000892"
|
||||
id="tspan295184">current<tspan
|
||||
id="tspan10781">current<tspan
|
||||
y="33.000892"
|
||||
id="tspan295186"> </tspan></tspan><tspan
|
||||
id="tspan10783"> </tspan></tspan><tspan
|
||||
x="141.6602"
|
||||
y="36.528678"
|
||||
id="tspan295188">best?</tspan></text>
|
||||
id="tspan10785">best?</tspan></text>
|
||||
<path
|
||||
sodipodi:type="star"
|
||||
style="fill:#cc00ff;stroke:#460e4f;stroke-opacity:1;stroke-width:1.8897638;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
@@ -615,32 +669,42 @@
|
||||
inkscape:export-ydpi="150"><tspan
|
||||
x="-9.077858"
|
||||
y="179.51565"
|
||||
id="tspan295190">Output </tspan><tspan
|
||||
id="tspan10787">Output </tspan><tspan
|
||||
x="-2.361691"
|
||||
y="192.84903"
|
||||
id="tspan295192">Best </tspan><tspan
|
||||
id="tspan10789">Best </tspan><tspan
|
||||
x="-10.317445"
|
||||
y="206.1824"
|
||||
id="tspan295194">Mission</tspan></text>
|
||||
id="tspan10791">Mission</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
transform="scale(0.26458333)"
|
||||
id="text150108"
|
||||
style="line-height:1.25;font-family:sans-serif;font-size:10.66666667px;text-align:center;white-space:pre;shape-inside:url(#rect150110)" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Mend);stroke-miterlimit:4;stroke-dasharray:none"
|
||||
d="m 75,39.999999 c 22.5,0 22.5,0 22.5,0"
|
||||
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2Mend)"
|
||||
d="M 78.75,29.999999 96.25,30"
|
||||
id="path183790"
|
||||
inkscape:export-filename="/home/connor/projects/thesis/LaTeX/flowcharts/mbh.png"
|
||||
inkscape:export-xdpi="150"
|
||||
inkscape:export-ydpi="150" />
|
||||
inkscape:export-ydpi="150"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Mend);stroke-miterlimit:4;stroke-dasharray:none"
|
||||
d="m 122.5,39.999999 c 22.5,0 22.5,0 22.5,0"
|
||||
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2Mend-7)"
|
||||
d="M 78.750001,51.249999 96.25,51.25"
|
||||
id="path183790-2"
|
||||
inkscape:export-filename="/home/connor/projects/thesis/LaTeX/flowcharts/mbh.png"
|
||||
inkscape:export-xdpi="150"
|
||||
inkscape:export-ydpi="150"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2Mend)"
|
||||
d="m 132.5,40 h 11.25"
|
||||
id="path183792"
|
||||
inkscape:export-filename="/home/connor/projects/thesis/LaTeX/flowcharts/mbh.png"
|
||||
inkscape:export-xdpi="150"
|
||||
inkscape:export-ydpi="150" />
|
||||
inkscape:export-ydpi="150"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2Mend)"
|
||||
d="M 153.75,48.75 V 67.5 H 71.249999"
|
||||
@@ -649,12 +713,13 @@
|
||||
inkscape:export-xdpi="150"
|
||||
inkscape:export-ydpi="150" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow2Mend)"
|
||||
d="m 62.499999,62.499999 c 0,-14.999999 0,-14.999999 0,-14.999999"
|
||||
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2Mend)"
|
||||
d="M 62.499999,62.499999 62.5,48.75"
|
||||
id="path184104"
|
||||
inkscape:export-filename="/home/connor/projects/thesis/LaTeX/flowcharts/mbh.png"
|
||||
inkscape:export-xdpi="150"
|
||||
inkscape:export-ydpi="150" />
|
||||
inkscape:export-ydpi="150"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow2Mend)"
|
||||
d="m 62.499999,81.249998 c 0,41.250002 0,41.250002 0,41.250002"
|
||||
@@ -749,7 +814,7 @@
|
||||
inkscape:export-ydpi="150"><tspan
|
||||
x="635.915"
|
||||
y="141.72073"
|
||||
id="tspan295196">True</tspan></text>
|
||||
id="tspan10793">True</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
transform="matrix(0.26458333,0,0,0.26458333,-12.955747,15.101026)"
|
||||
@@ -760,7 +825,7 @@
|
||||
inkscape:export-ydpi="150"><tspan
|
||||
x="633.8551"
|
||||
y="141.72073"
|
||||
id="tspan295198">False</tspan></text>
|
||||
id="tspan10795">False</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
transform="matrix(0.26458333,0,0,0.26458333,26.891584,14.845951)"
|
||||
@@ -771,7 +836,7 @@
|
||||
inkscape:export-ydpi="150"><tspan
|
||||
x="633.8551"
|
||||
y="141.72073"
|
||||
id="tspan295200">False</tspan></text>
|
||||
id="tspan10797">False</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
transform="matrix(0.26458333,0,0,0.26458333,-32.656732,64.804214)"
|
||||
@@ -782,7 +847,7 @@
|
||||
inkscape:export-ydpi="150"><tspan
|
||||
x="633.8551"
|
||||
y="141.72073"
|
||||
id="tspan295202">False</tspan></text>
|
||||
id="tspan10799">False</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
transform="matrix(0.26458333,0,0,0.26458333,-34.796459,97.987154)"
|
||||
@@ -793,7 +858,7 @@
|
||||
inkscape:export-ydpi="150"><tspan
|
||||
x="633.8551"
|
||||
y="141.72073"
|
||||
id="tspan295204">False</tspan></text>
|
||||
id="tspan10801">False</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
transform="matrix(0.26458333,0,0,0.26458333,-56.727236,55.251175)"
|
||||
@@ -804,7 +869,7 @@
|
||||
inkscape:export-ydpi="150"><tspan
|
||||
x="633.8551"
|
||||
y="141.72073"
|
||||
id="tspan295206">False</tspan></text>
|
||||
id="tspan10803">False</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
transform="matrix(0.26458333,0,0,0.26458333,-104.48989,22.217343)"
|
||||
@@ -815,7 +880,7 @@
|
||||
inkscape:export-ydpi="150"><tspan
|
||||
x="633.8551"
|
||||
y="141.72073"
|
||||
id="tspan295208">False</tspan></text>
|
||||
id="tspan10805">False</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
transform="matrix(0.26458333,0,0,0.26458333,40.720808,1.6305782)"
|
||||
@@ -826,7 +891,7 @@
|
||||
inkscape:export-ydpi="150"><tspan
|
||||
x="635.915"
|
||||
y="141.72073"
|
||||
id="tspan295210">True</tspan></text>
|
||||
id="tspan10807">True</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
transform="matrix(0.26458333,0,0,0.26458333,-13.87236,82.629073)"
|
||||
@@ -837,7 +902,7 @@
|
||||
inkscape:export-ydpi="150"><tspan
|
||||
x="635.915"
|
||||
y="141.72073"
|
||||
id="tspan295212">True</tspan></text>
|
||||
id="tspan10809">True</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
transform="matrix(0.26458333,0,0,0.26458333,-1.9337214,98.008192)"
|
||||
@@ -848,7 +913,7 @@
|
||||
inkscape:export-ydpi="150"><tspan
|
||||
x="635.915"
|
||||
y="141.72073"
|
||||
id="tspan295214">True</tspan></text>
|
||||
id="tspan10811">True</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
transform="matrix(0.26458333,0,0,0.26458333,-74.958276,64.67963)"
|
||||
@@ -859,7 +924,7 @@
|
||||
inkscape:export-ydpi="150"><tspan
|
||||
x="635.915"
|
||||
y="141.72073"
|
||||
id="tspan295216">True</tspan></text>
|
||||
id="tspan10813">True</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
transform="matrix(0.26458333,0,0,0.26458333,-104.68725,49.492044)"
|
||||
@@ -870,7 +935,7 @@
|
||||
inkscape:export-ydpi="150"><tspan
|
||||
x="635.915"
|
||||
y="141.72073"
|
||||
id="tspan295218">True</tspan></text>
|
||||
id="tspan10815">True</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
transform="matrix(0.26458333,0,0,0.26458333,1.5394599,3.6362688)"
|
||||
@@ -881,7 +946,29 @@
|
||||
inkscape:export-ydpi="150"><tspan
|
||||
x="391.15289"
|
||||
y="236.20901"
|
||||
id="tspan295220">Search += 1</tspan></text>
|
||||
id="tspan10817">Search += 1</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
transform="matrix(0.26458333,0,0,0.26458333,-19.807533,-12.164499)"
|
||||
id="text242399-8"
|
||||
style="font-size:10.6667px;line-height:1.25;font-family:sans-serif;text-align:center;white-space:pre;shape-inside:url(#rect242401-2)"
|
||||
inkscape:export-filename="/home/connor/projects/thesis/LaTeX/flowcharts/mbh.png"
|
||||
inkscape:export-xdpi="150"
|
||||
inkscape:export-ydpi="150"><tspan
|
||||
x="373.92732"
|
||||
y="236.20901"
|
||||
id="tspan10819">Lambert's</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
transform="matrix(0.26458333,0,0,0.26458333,-19.993321,-33.621446)"
|
||||
id="text242399-8-6"
|
||||
style="font-size:10.6667px;line-height:1.25;font-family:sans-serif;text-align:center;white-space:pre;shape-inside:url(#rect242401-2-6)"
|
||||
inkscape:export-filename="/home/connor/projects/thesis/LaTeX/flowcharts/mbh.png"
|
||||
inkscape:export-xdpi="150"
|
||||
inkscape:export-ydpi="150"><tspan
|
||||
x="376.29452"
|
||||
y="236.20901"
|
||||
id="tspan10821">Standard</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
transform="matrix(0.26458333,0,0,0.26458333,22.069121,44.757718)"
|
||||
@@ -892,7 +979,7 @@
|
||||
inkscape:export-ydpi="150"><tspan
|
||||
x="398.73104"
|
||||
y="236.20901"
|
||||
id="tspan295222">Drill += 1</tspan></text>
|
||||
id="tspan10823">Drill += 1</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
transform="matrix(0.26458333,0,0,0.26458333,22.933651,79.18148)"
|
||||
@@ -903,7 +990,7 @@
|
||||
inkscape:export-ydpi="150"><tspan
|
||||
x="398.73104"
|
||||
y="236.20901"
|
||||
id="tspan295224">Drill += 1</tspan></text>
|
||||
id="tspan10825">Drill += 1</tspan></text>
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.48734;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2Mend)"
|
||||
d="m 145,137.5 c -35,0 -35,0 -35,0 v -23.75"
|
||||
@@ -911,5 +998,25 @@
|
||||
inkscape:export-filename="/home/connor/projects/thesis/LaTeX/flowcharts/mbh.png"
|
||||
inkscape:export-xdpi="150"
|
||||
inkscape:export-ydpi="150" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
d="M 78.75,30 V 51.25"
|
||||
id="path2208" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
d="M 78.75,39.999999 H 75"
|
||||
id="path2210" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
d="m 122.5,30 h 10"
|
||||
id="path10402" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
d="m 122.5,51.25 h 10"
|
||||
id="path10404" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
d="M 132.5,30 V 51.25"
|
||||
id="path10406" />
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 42 KiB |
122
LaTeX/thesis.tex
122
LaTeX/thesis.tex
@@ -12,8 +12,8 @@
|
||||
\degree{Master of Science}{M.S., Aerospace Engineering}
|
||||
\dept{Department of}{Aerospace Engineering}
|
||||
\advisor{Prof.}{Natasha Bosanac}
|
||||
\reader{TBD: Kathryn Davis}
|
||||
\readerThree{TBD: Daniel Scheeres}
|
||||
\reader{Kathryn Davis}
|
||||
\readerThree{Daniel Scheeres}
|
||||
|
||||
\abstract{ \OnePageChapter
|
||||
There are a variety of approaches to finding and optimizing low-thrust trajectories in
|
||||
@@ -573,7 +573,7 @@
|
||||
Englander in his Hybrid Optimal Control Problem paper, but does not allow for missions
|
||||
with multiple targets, simplifying the optimization.
|
||||
|
||||
\section{Inner Loop Implementation}
|
||||
\section{Inner Loop Implementation}\label{inner_loop_section}
|
||||
|
||||
The optimization routine can be reasonable separated into two separate ``loops'' wherein
|
||||
the first loop is used, given an initial guess, to find valid trajectories within the
|
||||
@@ -761,13 +761,117 @@
|
||||
in order to achieve maximum precision.
|
||||
|
||||
\section{Outer Loop Implementation}
|
||||
Overview the outer loop. This may require a final flowchart, but might potentially be too
|
||||
simple to lend itself to one.
|
||||
|
||||
\subsection{Inner Loop Calling Function}
|
||||
The primary reason for including this section is to discuss the error handling.
|
||||
Now we have the tools in place for, given a potential ''mission guess`` in the
|
||||
vicinity of a valid guess, attempting to find a valid and optimal solution in that
|
||||
vicinity. Now what remains is to develop a routine for efficiently generating these
|
||||
random mission guesses in such a way that thoroughly searches the entirety of the
|
||||
solution space with enough granularity that all spaces are considered by the inner loop
|
||||
solver.
|
||||
|
||||
\subsection{Monotonic Basin Hopping}
|
||||
Once that has been accomplished, all that remains is an ''outer loop`` that can generate
|
||||
new guesses or perturb existing valid missions as needed in order to drill down into a
|
||||
specific local minimum. In this thesis, that is accomplished through the use of a
|
||||
Monotonic Basin Hopping algorithm. This will be described more thoroughly in
|
||||
Section~\ref{mbh_subsection}, but Figure~\ref{mbh_flow} outlines the process steps of
|
||||
the algorithm.
|
||||
|
||||
\begin{figure}
|
||||
\centering
|
||||
\includegraphics[width=\textwidth]{flowcharts/mbh}
|
||||
\caption{A flowchart visualizing the steps in the monotonic basin hopping
|
||||
algorithm}
|
||||
\label{mbh_flow}
|
||||
\end{figure}
|
||||
|
||||
\subsection{Random Mission Generation}
|
||||
|
||||
At a basic level, the algorithm needs to produce a mission guess (represented by all
|
||||
of the values described in Section~\ref{inner_loop_section}) that contains random
|
||||
values within reasonable bounds in the space. This leaves a number of variables open
|
||||
to for implementation. For instance, it remains to be determined which distribution
|
||||
function to use for the random values over each of those variables, which bounds to
|
||||
use, as well as the possibilities for any improvements to a purely random search.
|
||||
|
||||
Currently, the first value set for the mission guess is that of $n$, which is the
|
||||
number of sub-trajectories that each arc will be broken into for the Sims-Flanagan
|
||||
based propagator. For this implementation, that was chosen to be 20, based upon a
|
||||
number of tests in which the calculation time for the propagation was compared
|
||||
against the accuracy of a much higher $n$ value for some known thrust controls, such
|
||||
as a simple spiral orbit trajectory. This value of 20 tends to perform well and
|
||||
provide reasonable accuracy, without producing too many variables for the NLP
|
||||
optimizer to control for (since the impulsive thrust at the center of each of the
|
||||
sub-trajectories is a control variable). This leaves some room for future
|
||||
improvements, as will be discussed in Section~\ref{improvement_section}.
|
||||
|
||||
The bounds for the launch date are provided by the user in the form of a launch
|
||||
window, so the initial launch date is just chosen as a standard random value from a
|
||||
uniform distribution within those bounds.
|
||||
|
||||
A unit launch direction is then also chosen as a 3-length vector of uniform random
|
||||
numbers, then normalized. This unit vector is then multiplied by a uniform random
|
||||
number between 0 and the square root of the maximum launch $C_3$ specified by the
|
||||
user to generate an initial $\vec{v_\infty}$ vector at launch.
|
||||
|
||||
Next, the times of flight of each phase of the mission is then decided. Since launch
|
||||
date has already been selected, the maximum time of flight can be calculated by
|
||||
subtracting the launch date from the latest arrival date provided by the mission
|
||||
designer. Then, each leg is chosen from a uniform distribution with bounds currently
|
||||
set to a minimum flight time of 30 days and a maximum of 70\% of the maximum time of
|
||||
flight. These leg flight times are then iteratively re-generated until the total
|
||||
time of flight (represented by the sum of the leg flight times) is less than the
|
||||
maximum time of flight. This allows for a lot of flexibility in the leg flight
|
||||
times, but does tend toward more often producing longer missions, particularly for
|
||||
missions with more flybys.
|
||||
|
||||
Then, the internal components for each phase are generated. It is at this step, that
|
||||
the mission guess generator splits the outputs into two separate outputs. The first
|
||||
is meant to be truly random, as is generally used as input for a monotonic basin
|
||||
hopping algorithm. The second utilizes a Lambert's solver to determine the
|
||||
appropriate hyperbolic velocities (both in and out) at each flyby to generate a
|
||||
natural trajectory arc. For this Lambert's case, the mission guess is simply seeded
|
||||
with zero thrust controls and outputted to the monotonic basin hopper. The intention
|
||||
here is that if the time of flights are randomly chosen so as to produce a
|
||||
trajectory that is possible with a control in the vicinity of a natural trajectory,
|
||||
we want to be sure to find that trajectory. More detail on how this is handled is
|
||||
available in Section~\ref{mbh_subsection}.
|
||||
|
||||
However, for the truly random mission guess, there are still the $v_\infty$ values
|
||||
and the initial thrust guesses to generate. For each of the phases, the incoming
|
||||
excess hyperbolic velocity is calculated in much the same way that the launch
|
||||
velocity was calculated. However, instead of multiplying the randomly generate unit
|
||||
direction vector by a random number between 0 and the square root of the maximum
|
||||
launch $C_3$, bounds of 0 and 10 kilometers per second are used instead, to provide
|
||||
realistic flyby values.
|
||||
|
||||
The outgoing excess hyperbolic velocity at infinity is then calculated by again
|
||||
choosing a uniform random unit direction vector, then by multiplying this value by
|
||||
the magnitude of the incoming $v_{\infty}$ since this is a constraint of a
|
||||
non-powered flyby.
|
||||
|
||||
From these two velocity vectors the turning angle, and thus the periapsis of the
|
||||
flyby, can then be calculated by the following equations:
|
||||
|
||||
\begin{align}
|
||||
\delta &= \arccos \left( \frac{\vec{v}_{\infty,in} \cdot
|
||||
\vec{v}_{\infty,out}}{|v_{\infty,in}| \cdot {|v_{\infty,out}}|} \right) \\
|
||||
r_p &= \frac{\mu}{\vec{v}_{\infty,in} \cdot \vec{v}_{\infty,out}} \cdot \left(
|
||||
\frac{1}{\sin(\delta/2)} - 1 \right)
|
||||
\end{align}
|
||||
|
||||
If this radius of periapse is then found to be less than the minimum safe radius
|
||||
(currently set to the radius of the planet plus 100 kilometers), then the process is
|
||||
repeated with new random flyby velocities until a valid seed flyby is found. These
|
||||
checks are also performed each time a mission is perturbed or generated by the nlp
|
||||
solver.
|
||||
|
||||
The final requirement then, is the thrust controls, which are actually quite simple.
|
||||
Since the thrust is defined as a 3-vector of values between -1 and 1 representing
|
||||
some percentage of the full thrust producible by the spacecraft thrusters in that
|
||||
direction, the initial thrust controls can then be generated as a $20 \times 3$
|
||||
matrix of uniform random numbers within that bound.
|
||||
|
||||
\subsection{Monotonic Basin Hopping}\label{mbh_subsection}
|
||||
Outline the MBH algorithm, going into detail at each step. Mention the long-tailed PDF being
|
||||
used and go into quite a bit of detail. Englander's paper on the MBH algorithm specifically
|
||||
should be a good guide. Mention validation.
|
||||
@@ -798,7 +902,7 @@
|
||||
Talk a bit about why this work is valuable. Missions that could have benefited, missions that
|
||||
this enables, etc.
|
||||
|
||||
\section{Recommendations for Future Work}
|
||||
\section{Recommendations for Future Work}\label{improvement_section}
|
||||
Recommend future work, obviously. There are a \emph{ton} of opportunities for improvement
|
||||
including parallelization, cluster computing, etc.
|
||||
|
||||
|
||||
@@ -99,6 +99,12 @@ git-tree-sha1 = "bdc0937269321858ab2a4f288486cb258b9a0af7"
|
||||
uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
|
||||
version = "1.3.0"
|
||||
|
||||
[[CodeTracking]]
|
||||
deps = ["InteractiveUtils", "UUIDs"]
|
||||
git-tree-sha1 = "9aa8a5ebb6b5bf469a7e0e2b5202cf6f8c291104"
|
||||
uuid = "da1fd8a2-8d9e-5ec2-8556-3022fb5608a2"
|
||||
version = "1.0.6"
|
||||
|
||||
[[CodecBzip2]]
|
||||
deps = ["Bzip2_jll", "Libdl", "TranscodingStreams"]
|
||||
git-tree-sha1 = "2e62a725210ce3c3c2e1a3080190e7ca491f18d7"
|
||||
@@ -329,6 +335,12 @@ git-tree-sha1 = "2f49f7f86762a0fbbeef84912265a1ae61c4ef80"
|
||||
uuid = "7d188eb4-7ad8-530c-ae41-71a32a6d4692"
|
||||
version = "0.3.4"
|
||||
|
||||
[[JuliaInterpreter]]
|
||||
deps = ["CodeTracking", "InteractiveUtils", "Random", "UUIDs"]
|
||||
git-tree-sha1 = "b55aae9a2bf436fc797d9c253a900913e0e90178"
|
||||
uuid = "aa1ae85d-cabe-5617-a682-6adf51b2e16a"
|
||||
version = "0.9.3"
|
||||
|
||||
[[Kaleido_jll]]
|
||||
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
|
||||
git-tree-sha1 = "2ef87eeaa28713cb010f9fb0be288b6c1a4ecd53"
|
||||
@@ -390,6 +402,12 @@ version = "0.3.0"
|
||||
[[Logging]]
|
||||
uuid = "56ddb016-857b-54e1-b83d-db4d58db5568"
|
||||
|
||||
[[LoweredCodeUtils]]
|
||||
deps = ["JuliaInterpreter"]
|
||||
git-tree-sha1 = "6b0440822974cab904c8b14d79743565140567f6"
|
||||
uuid = "6f1432cf-f94c-5a45-995e-cdbf5db27b0b"
|
||||
version = "2.2.1"
|
||||
|
||||
[[METIS_jll]]
|
||||
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
|
||||
git-tree-sha1 = "2dc1a9fc87e57e32b1fc186db78811157b30c118"
|
||||
@@ -559,6 +577,12 @@ git-tree-sha1 = "63ee24ea0689157a1113dbdab10c6cb011d519c4"
|
||||
uuid = "37e2e3b7-166d-5795-8a7a-e32c996b4267"
|
||||
version = "1.9.0"
|
||||
|
||||
[[Revise]]
|
||||
deps = ["CodeTracking", "Distributed", "FileWatching", "JuliaInterpreter", "LibGit2", "LoweredCodeUtils", "OrderedCollections", "Pkg", "REPL", "Requires", "UUIDs", "Unicode"]
|
||||
git-tree-sha1 = "2f9d4d6679b5f0394c52731db3794166f49d5131"
|
||||
uuid = "295af30f-e4ad-537b-8983-00126c2a3abe"
|
||||
version = "3.3.1"
|
||||
|
||||
[[SHA]]
|
||||
uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce"
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
|
||||
PlotlyBase = "a03496cd-edff-5a9b-9e67-9cda94a718b5"
|
||||
PlotlyJS = "f0f68f2c-4968-5e81-91da-67840de0976a"
|
||||
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
|
||||
Revise = "295af30f-e4ad-537b-8983-00126c2a3abe"
|
||||
SNOW = "105f6ee8-0889-46b1-9d4b-65e03cbc8f13"
|
||||
SPICE = "5bab7191-041a-5c2e-a744-024b9c3a5062"
|
||||
SymbolServer = "cf896787-08d5-524d-9de7-132aaa0cb996"
|
||||
|
||||
@@ -7,7 +7,7 @@ module Thesis
|
||||
using PlotlyJS
|
||||
using Distributed
|
||||
using SPICE
|
||||
using Dates: DateTime, Millisecond, Dates, Second, format, datetime2unix, unix2datetime
|
||||
using Dates: DateTime, Millisecond, Dates, Second, format, datetime2julian, julian2datetime
|
||||
|
||||
try
|
||||
furnsh("../../spice_files/naif0012.tls")
|
||||
|
||||
@@ -2,30 +2,27 @@ using SNOW
|
||||
|
||||
export solve_mission
|
||||
|
||||
const pos_scale = ones(3)
|
||||
# const vel_scale = 100. * ones(3)
|
||||
const vel_scale = ones(3)
|
||||
# const v∞_scale = norm(vel_scale)
|
||||
const v∞_scale = 1.
|
||||
const state_scale = [pos_scale; vel_scale ]
|
||||
|
||||
function constraint_bounds(guess::Mission_Guess)
|
||||
low_constraint = Vector{Float64}()
|
||||
high_constraint = Vector{Float64}()
|
||||
|
||||
for phase in guess.phases
|
||||
state_constraint = [100., 100., 100., 0.005, 0.005, 0.005] .* state_scale
|
||||
# Constraints on the final state
|
||||
state_constraint = [10_000., 10_000., 10_000., 0.05, 0.05, 0.05]
|
||||
push!(low_constraint, (-1 * state_constraint)... )
|
||||
push!(high_constraint, state_constraint... )
|
||||
if phase != guess.phases[end]
|
||||
push!(low_constraint, -0.005*v∞_scale, 100.)
|
||||
push!(high_constraint, 0.005*v∞_scale, 1e7)
|
||||
# Constraints on the v∞ and turning angle
|
||||
push!(low_constraint, -0.05, 100.)
|
||||
push!(high_constraint, 0.05, 1e7)
|
||||
else
|
||||
# Constraints on mass
|
||||
push!(low_constraint, 0.)
|
||||
push!(high_constraint, guess.start_mass - guess.sc.dry_mass)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# Constraints on C3 and V∞
|
||||
push!(low_constraint, 0., 0.)
|
||||
push!(high_constraint, 1e3, 1e3)
|
||||
|
||||
@@ -57,8 +54,8 @@ function solve_mission( guess::Mission_Guess,
|
||||
# Establish initial conditions
|
||||
v∞_out = x[2:4]
|
||||
current_planet = Earth
|
||||
launch_date = unix2datetime(x[1])
|
||||
time = utc2et(format(launch_date,"yyyy-mm-ddTHH:MM:SS"))
|
||||
launch_date = julian2datetime(x[1])
|
||||
time = Dates.datetime2julian(launch_date)
|
||||
start = state(current_planet, time, v∞_out, guess.start_mass)
|
||||
final = zeros(7)
|
||||
|
||||
@@ -80,16 +77,16 @@ function solve_mission( guess::Mission_Guess,
|
||||
thrusts = reshape(phase_params[8:end], (n,3))
|
||||
|
||||
# Propagate
|
||||
final = prop(thrusts, start, guess.sc, tof)[2]
|
||||
final = prop(thrusts, start, guess.sc, tof)[end,:]
|
||||
current_planet = flyby
|
||||
time += tof
|
||||
time += tof/86400
|
||||
goal = state(current_planet, time, v∞_in)[1:6]
|
||||
start = state(current_planet, time, v∞_out, final[7])
|
||||
|
||||
# Do Checks
|
||||
g[1+8i:6+8i] .= (final[1:6] .- goal[1:6]) .* state_scale
|
||||
g[1+8i:6+8i] .= (final[1:6] .- goal[1:6])
|
||||
if flyby != flybys[end]
|
||||
g[7+8i] = (norm(v∞_out) - norm(v∞_in)) * v∞_scale
|
||||
g[7+8i] = (norm(v∞_out) - norm(v∞_in))
|
||||
δ = acos( ( v∞_in ⋅ v∞_out ) / ( norm(v∞_in) * norm(v∞_out) ) )
|
||||
g[8+8i] = (current_planet.μ/(v∞_in ⋅ v∞_in)) * ( 1/sin(δ/2) - 1 ) - current_planet.r
|
||||
else
|
||||
@@ -100,7 +97,7 @@ function solve_mission( guess::Mission_Guess,
|
||||
i += 1
|
||||
end
|
||||
|
||||
return 1.0
|
||||
return -final[end]
|
||||
|
||||
catch e
|
||||
|
||||
@@ -114,7 +111,7 @@ function solve_mission( guess::Mission_Guess,
|
||||
end
|
||||
end
|
||||
|
||||
max_time = datetime2unix(latest_arrival) - datetime2unix(launch_window[1])
|
||||
max_time = (datetime2julian(latest_arrival) - datetime2julian(launch_window[1]))*86400
|
||||
lower_x = lowest_mission_vector(launch_window, length(guess.phases), n)
|
||||
upper_x = highest_mission_vector(launch_window, max_time, length(guess.phases), n)
|
||||
num_constraints = 8*(length(guess.phases)-1) + 9
|
||||
@@ -123,7 +120,7 @@ function solve_mission( guess::Mission_Guess,
|
||||
"acceptable_constr_viol_tol" => 100tol,
|
||||
"bound_relax_factor" => 0.,
|
||||
"max_iter" => 100_000,
|
||||
"max_cpu_time" => 5. * length(guess.phases),
|
||||
"max_cpu_time" => 10. * length(guess.phases),
|
||||
"print_level" => print_level)
|
||||
options = Options(solver=IPOPT(ipopt_options), derivatives=ForwardFD())
|
||||
|
||||
|
||||
@@ -1,22 +1,106 @@
|
||||
export state, period
|
||||
|
||||
struct Body
|
||||
μ::Float64
|
||||
r::Float64 # radius
|
||||
μ::Real
|
||||
r::Real # radius
|
||||
color::String
|
||||
id::Int # SPICE id
|
||||
a::Float64 # semi-major axis
|
||||
a::Real # semi-major axis
|
||||
line_color::AbstractString
|
||||
name::AbstractString
|
||||
end
|
||||
|
||||
period(b::Body) = 2π * √(b.a^3 / Sun.μ)
|
||||
|
||||
function state(p::Body, t::DateTime, add_v∞::Vector{T}=[0., 0., 0.], add_mass::Float64=1e10) where T <: Real
|
||||
time = utc2et(format(t,"yyyy-mm-ddTHH:MM:SS"))
|
||||
[ spkssb(p.id, time, "ECLIPJ2000"); 0.0 ] + [ zeros(3); add_v∞; add_mass ]
|
||||
function state(p::Body, t::DateTime, add_v∞::AbstractVector=[0., 0., 0.], add_mass::Float64=1e10)
|
||||
time = Dates.datetime2julian(t)
|
||||
[ basic_ephemeris(p,time); 0.0 ] + [ zeros(3); add_v∞; add_mass ]
|
||||
end
|
||||
|
||||
function state(p::Body, t::S, add_v∞::Vector{T}=[0., 0., 0.], add_mass::Float64=1e10) where {T,S <: Real}
|
||||
[ spkssb(p.id, t, "ECLIPJ2000"); 0.0 ] + [ zeros(3); add_v∞; add_mass ]
|
||||
function state(p::Body, t::Real, add_v∞::AbstractVector=[0., 0., 0.], add_mass::Real=1e10)
|
||||
[ basic_ephemeris(p,t); 0.0 ] + [ zeros(3); add_v∞; add_mass ]
|
||||
end
|
||||
|
||||
"""
|
||||
Provides a really basic, but fast, ephemeris for most planets.
|
||||
"""
|
||||
function basic_ephemeris(planet::Body,date::Real)
|
||||
century = (date-2451545)/36525
|
||||
if planet.name == "Mercury"
|
||||
table = [ 252.250906 149472.6746358 0.00000535 0.000000002 ;
|
||||
0.387098310 0 0 0 ;
|
||||
0.20563175 0.000020406 0.0000000284 0.00000000017 ;
|
||||
7.004986 -0.0059516 0.00000081 0.000000041 ;
|
||||
48.330893 -0.1254229 -0.00008833 -0.000000196 ;
|
||||
77.456119 0.1588643 -0.00001343 0.000000039]
|
||||
elseif planet.name == "Venus"
|
||||
table = [ 181.979801 58517.8156760 0.00000165 -0.000000002 ;
|
||||
0.72332982 0 0 0 ;
|
||||
0.00677188 -0.000047766 0.0000000975 0.00000000044 ;
|
||||
3.394662 -0.0008568 -0.00003244 0.000000010 ;
|
||||
76.679920 -0.2780080 -0.00014256 -0.000000198 ;
|
||||
131.563707 0.0048646 -0.00138232 -0.000005332]
|
||||
elseif planet.name == "Earth"
|
||||
table = [ 100.466449 35999.3728519 -0.00000568 0 ;
|
||||
1.000001018 0 0 0 ;
|
||||
0.01670862 -0.000042037 -0.0000001236 0.00000000004 ;
|
||||
0 0.0130546 -0.00000931 -0.000000034 ;
|
||||
174.873174 -0.2410908 0.00004067 -0.000001327 ;
|
||||
102.937348 0.3225557 0.00015026 0.000000478]
|
||||
elseif planet.name == "Mars"
|
||||
table = [ 355.433275 19140.2993313 0.00000261 -0.000000003 ;
|
||||
1.523679342 0 0 0 ;
|
||||
0.09340062 0.000090483 -0.0000000806 -0.00000000035 ;
|
||||
1.849726 -0.0081479 -0.00002255 -0.000000027 ;
|
||||
49.558093 -0.2949846 -0.00063993 -0.000002143 ;
|
||||
336.060234 0.4438898 -0.00017321 0.000000300]
|
||||
elseif planet.name == "Jupiter"
|
||||
table = [ 34.351484 3034.9056746 -0.00008501 0.000000004 ;
|
||||
5.202603191 0.0000001913 0 0 ;
|
||||
0.04849485 0.000163244 -0.0000004719 -0.00000000197 ;
|
||||
1.303270 -0.0019872 0.00003318 0.000000092 ;
|
||||
100.464441 0.1766828 0.00090387 -0.000007032 ;
|
||||
14.331309 0.2155525 0.00072252 -0.000004590]
|
||||
elseif planet.name == "Saturn"
|
||||
table = [ 50.077471 1222.1137943 0.00021004 -0.000000019 ;
|
||||
9.554909596 -0.0000021389 0 0 ;
|
||||
0.05550862 -0.000346818 -0.0000006456 0.00000000338 ;
|
||||
2.488878 0.0025515 -0.00004903 0.000000018 ;
|
||||
113.665524 -0.2566649 -0.00018345 0.000000357 ;
|
||||
93.056787 0.5665496 0.00052809 0.000004882]
|
||||
elseif planet.name == "Uranus"
|
||||
table = [ 314.055005 429.8640561 0.00030434 0.000000026 ;
|
||||
19.218446062 -0.0000000372 0.00000000098 0 ;
|
||||
0.04629590 -0.000027337 0.0000000790 0.00000000025 ;
|
||||
0.773196 0.0007744 0.00003749 -0.000000092 ;
|
||||
74.005947 0.5211258 0.00133982 0.000018516 ;
|
||||
173.005159 1.4863784 0.0021450 0.000000433]
|
||||
elseif planet.name == "Neptune"
|
||||
table = [ 304.348665 219.8833092 0.00030926 0.000000018 ;
|
||||
30.110386869 -0.0000001663 0.00000000069 0 ;
|
||||
0.00898809 0.000006408 -0.0000000008 -0.00000000005 ;
|
||||
1.769952 -0.0093082 -0.00000708 0.000000028 ;
|
||||
131.784057 1.1022057 0.00026006 -0.000000636 ;
|
||||
48.123691 1.4262677 0.00037918 -0.000000003]
|
||||
elseif planet.name == "Pluto"
|
||||
table = [ 238.92903833 145.20780515 0 0 ;
|
||||
39.48211675 -0.00031596 0 0 ;
|
||||
0.24882730 0.00005170 0 0 ;
|
||||
17.14001206 0.00004818 0 0 ;
|
||||
110.30393684 -0.01183482 0 0 ;
|
||||
224.06891629 -0.04062942 0 0]
|
||||
else
|
||||
return "No such planet"
|
||||
end
|
||||
poly = [1,century,century^2,century^3]
|
||||
L,a,e,i,Ω,P = table * poly
|
||||
L,i,Ω,P = [L,i,Ω,P] * (π/180)
|
||||
ω = P-Ω
|
||||
M = L-P
|
||||
θ = M + (2e - 0.25e^3 + (5/96)*e^5)*sin(M) +
|
||||
(1.25e^2 - (11/24)*e^4)*sin(2M) + ((13/12)*e^3 - (43/64)*e^5)*sin(3M) +
|
||||
(103/96)*e^4*sin(4M) + (1097/960)*e^5*sin(5M)
|
||||
oe = [a*AU,e,i,Ω,ω,θ]
|
||||
return oe_to_xyz(oe, Sun.μ)
|
||||
|
||||
end
|
||||
|
||||
@@ -49,7 +49,7 @@ This is the opposite of the function below. It takes a vector and any other nece
|
||||
"""
|
||||
function Mission_Guess(x::Vector{Float64}, sc::Sc, mass::Float64, flybys::Vector{Body})
|
||||
# Variable mission params
|
||||
launch_date = unix2datetime(x[1])
|
||||
launch_date = julian2datetime(x[1])
|
||||
launch_v∞ = x[2:4]
|
||||
|
||||
# Try to intelligently determine n
|
||||
@@ -78,7 +78,7 @@ information from the guess though.
|
||||
"""
|
||||
function Base.Vector(g::Mission_Guess)
|
||||
result = Vector{Float64}()
|
||||
push!(result, datetime2unix(g.launch_date))
|
||||
push!(result, datetime2julian(g.launch_date))
|
||||
push!(result, g.launch_v∞...)
|
||||
for phase in g.phases
|
||||
push!(result,phase.v∞_in...)
|
||||
@@ -91,7 +91,7 @@ end
|
||||
|
||||
function lowest_mission_vector(launch_window::Tuple{DateTime,DateTime}, num_phases::Int, n::Int)
|
||||
result = Vector{Float64}()
|
||||
push!(result, datetime2unix(launch_window[1]))
|
||||
push!(result, datetime2julian(launch_window[1]))
|
||||
push!(result, -10*ones(3)...)
|
||||
for i in 1:num_phases
|
||||
push!(result, -10*ones(3)...)
|
||||
@@ -104,7 +104,7 @@ end
|
||||
|
||||
function highest_mission_vector(launch_window::Tuple{DateTime,DateTime}, mission_length::Float64, num_phases::Int, n::Int)
|
||||
result = Vector{Float64}()
|
||||
push!(result, datetime2unix(launch_window[2]))
|
||||
push!(result, datetime2julian(launch_window[2]))
|
||||
push!(result, 10*ones(3)...)
|
||||
for i in 1:num_phases
|
||||
push!(result, 10*ones(3)...)
|
||||
@@ -133,14 +133,14 @@ function Mission(sc::Sc, mass::Float64, date::DateTime, v∞::Vector{Float64}, p
|
||||
force=false)
|
||||
# First do some checks to make sure that it's valid
|
||||
if !force
|
||||
time = utc2et(format(date,"yyyy-mm-ddTHH:MM:SS"))
|
||||
time = datetime2julian(date)
|
||||
current_planet = Earth
|
||||
start = state(current_planet, time, v∞, mass)
|
||||
for phase in phases
|
||||
#Propagate
|
||||
final = prop(phase.thrust_profile, start, sc, phase.tof)[2]
|
||||
final = prop(phase.thrust_profile, start, sc, phase.tof)[end,:]
|
||||
current_planet = phase.planet
|
||||
time += phase.tof
|
||||
time += phase.tof/86400
|
||||
goal = state(current_planet, time, phase.v∞_in)
|
||||
start = state(current_planet, time, phase.v∞_out, final[7])
|
||||
|
||||
@@ -178,7 +178,7 @@ end
|
||||
|
||||
function Mission(x::Vector{Float64}, sc::Sc, mass::Float64, flybys::Vector{Body})
|
||||
# Variable mission params
|
||||
launch_date = unix2datetime(x[1])
|
||||
launch_date = julian2datetime(x[1])
|
||||
launch_v∞ = x[2:4]
|
||||
|
||||
# Try to intelligently determine n
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
function laguerre_conway(state::Vector{<:Real}, time::Float64, primary::Body=Sun)
|
||||
function laguerre_conway(state::AbstractArray, time::Real, primary::Body=Sun)
|
||||
|
||||
μ = primary.μ
|
||||
n = 5 # Choose LaGuerre-Conway "n"
|
||||
|
||||
@@ -59,27 +59,27 @@ end
|
||||
"""
|
||||
A fundamental function to generate a plot for a single orbit path
|
||||
"""
|
||||
function gen_plot(path::Vector{Vector{Float64}};
|
||||
function gen_plot(path::AbstractArray;
|
||||
label::Union{AbstractString, Nothing} = nothing,
|
||||
color::AbstractString = random_color(),
|
||||
markers=true)
|
||||
|
||||
# Plot the orbit
|
||||
if label === nothing
|
||||
path_trace = scatter3d(;x=(path[1]),y=(path[2]),z=(path[3]),
|
||||
path_trace = scatter3d(;x=(path[:,1]),y=(path[:,2]),z=(path[:,3]),
|
||||
mode="lines", showlegend=false, line_color=color, line_width=3)
|
||||
else
|
||||
path_trace = scatter3d(;x=(path[1]),y=(path[2]),z=(path[3]),
|
||||
path_trace = scatter3d(;x=(path[:,1]),y=(path[:,2]),z=(path[:,3]),
|
||||
mode="lines", name=label, line_color=color, line_width=3)
|
||||
end
|
||||
traces = [ path_trace ]
|
||||
|
||||
# Plot the markers
|
||||
if markers
|
||||
push!(traces, scatter3d(;x=([path[1][1]]),y=([path[2][1]]),z=([path[3][1]]),
|
||||
push!(traces, scatter3d(;x=([path[1,1]]),y=([path[1,2]]),z=([path[1,3]]),
|
||||
mode="markers", showlegend=false,
|
||||
marker=attr(color=color, size=3, symbol="circle")))
|
||||
push!(traces, scatter3d(;x=([path[1][end]]),y=([path[2][end]]),z=([path[3][end]]),
|
||||
push!(traces, scatter3d(;x=([path[end,1]]),y=([path[end,2]]),z=([path[end,3]]),
|
||||
mode="markers", showlegend=false,
|
||||
marker=attr(color=color, size=3, symbol="diamond")))
|
||||
end
|
||||
@@ -222,7 +222,7 @@ end
|
||||
"""
|
||||
Generic plotting function for a bunch of paths. Useful for debugging.
|
||||
"""
|
||||
function plot(paths::Vector{Vector{Vector{Float64}}};
|
||||
function plot(paths::Vector{Matrix{Real}};
|
||||
labels::Union{Vector{String},Nothing}=nothing,
|
||||
colors::Union{Vector{String},Nothing}=nothing,
|
||||
markers::Bool=true,
|
||||
@@ -243,7 +243,8 @@ function plot(paths::Vector{Vector{Vector{Float64}}};
|
||||
push!(traces, gen_plot(Sun)[1]...)
|
||||
|
||||
# Determine layout details
|
||||
layout = standard_layout(limit, title)
|
||||
# layout = standard_layout(limit, title)
|
||||
layout = standard_layout(1e9, title)
|
||||
|
||||
# Plot
|
||||
PlotlyJS.plot( PlotlyJS.Plot( traces, layout ) )
|
||||
@@ -253,19 +254,20 @@ end
|
||||
function plot(m::Union{Mission, Mission_Guess}; title::String="Mision Plot")
|
||||
# First plot the earth
|
||||
# Then plot phase plus planet phase
|
||||
time = m.launch_date
|
||||
time = datetime2julian(m.launch_date)
|
||||
mass = m.start_mass
|
||||
current_planet = Earth
|
||||
earth_trace, limit = gen_plot(current_planet, time, year)
|
||||
earth_trace, limit = gen_plot(current_planet, julian2datetime(time), year)
|
||||
start = state(current_planet, time, m.launch_v∞, mass)
|
||||
traces = [ earth_trace... ]
|
||||
|
||||
i = 1
|
||||
for phase in m.phases
|
||||
# First do the path
|
||||
path, final = prop(phase.thrust_profile, start, m.sc, phase.tof, interpolate=true)
|
||||
path = prop(phase.thrust_profile, start, m.sc, phase.tof)
|
||||
final = path[end,:]
|
||||
mass = final[7]
|
||||
time += Second(floor(phase.tof))
|
||||
time += phase.tof/86400
|
||||
current_planet = phase.planet
|
||||
start = state(current_planet, time, phase.v∞_out, mass)
|
||||
path_trace, new_limit = gen_plot(path, label="Phase "*string(i))
|
||||
@@ -273,7 +275,7 @@ function plot(m::Union{Mission, Mission_Guess}; title::String="Mision Plot")
|
||||
limit = max(limit, new_limit)
|
||||
|
||||
# Then the planet
|
||||
planet_trace, new_limit = gen_plot(current_planet, time, -phase.tof)
|
||||
planet_trace, new_limit = gen_plot(current_planet, julian2datetime(time), -phase.tof)
|
||||
push!(traces, planet_trace...)
|
||||
limit = max(limit, new_limit)
|
||||
|
||||
|
||||
@@ -3,83 +3,52 @@ export prop
|
||||
"""
|
||||
Maximum ΔV that a spacecraft can impulse for a given single time step
|
||||
"""
|
||||
function max_ΔV(duty_cycle::Float64,
|
||||
function max_ΔV(duty_cycle::Real,
|
||||
num_thrusters::Int,
|
||||
max_thrust::Float64,
|
||||
tf::Float64,
|
||||
t0::Float64,
|
||||
mass::T) where T <: Real
|
||||
return duty_cycle*num_thrusters*max_thrust*(tf-t0)/mass
|
||||
end
|
||||
|
||||
"""
|
||||
A convenience function for using spacecraft. Note that this function outputs a sc instead of a mass
|
||||
"""
|
||||
function prop_one(ΔV_unit::Vector{<:Real},
|
||||
state::Vector{<:Real},
|
||||
craft::Sc,
|
||||
time::Float64,
|
||||
primary::Body=Sun)
|
||||
|
||||
ΔV = max_ΔV(craft.duty_cycle, craft.num_thrusters, craft.max_thrust, time, 0., state[7]) * ΔV_unit
|
||||
halfway = laguerre_conway(state, time/2, primary) + [zeros(3); ΔV]
|
||||
final = laguerre_conway(halfway, time/2, primary)
|
||||
return [final; state[7] - mfr(craft)*norm(ΔV_unit)*time]
|
||||
|
||||
max_thrust::Real,
|
||||
tf::Real,
|
||||
t0::Real)
|
||||
return duty_cycle*num_thrusters*max_thrust*(tf-t0)
|
||||
end
|
||||
|
||||
"""
|
||||
The propagator function
|
||||
"""
|
||||
function prop(ΔVs::Matrix{T},
|
||||
state::Vector{Float64},
|
||||
function prop(ΔVs::AbstractArray,
|
||||
state::AbstractArray,
|
||||
craft::Sc,
|
||||
time::Float64,
|
||||
primary::Body=Sun;
|
||||
interpolate::Bool=false) where T <: Real
|
||||
time::Real;
|
||||
primary::Body=Sun)
|
||||
|
||||
size(ΔVs)[2] == 3 || throw(ΔVsize_Error())
|
||||
size(ΔVs)[2] == 3 || throw(ΔVsize_Error(size(ΔVs)))
|
||||
n = size(ΔVs)[1]
|
||||
|
||||
states = [ Vector{T}(),Vector{T}(),Vector{T}(),Vector{T}(),Vector{T}(),Vector{T}(),Vector{T}() ]
|
||||
|
||||
for i in 1:7 push!(states[i], state[i]) end
|
||||
output = Array{Real,2}(undef,n,7)
|
||||
current = copy(state)
|
||||
full_thrust = max_ΔV(craft.duty_cycle, craft.num_thrusters, craft.max_thrust, time/n, 0.)
|
||||
|
||||
for i in 1:n
|
||||
if interpolate
|
||||
interpolated_state = copy(state)
|
||||
for j in 1:49
|
||||
interpolated_state = [laguerre_conway(interpolated_state, time/50n, primary); 0.0]
|
||||
for k in 1:7 push!(states[k], interpolated_state[k]) end
|
||||
end
|
||||
halfway = laguerre_conway(current[1:6], time/(2n), primary)
|
||||
if time > 0
|
||||
halfway += [zeros(3); full_thrust * ΔVs[i,:]] / current[7]
|
||||
current[7] -= mfr(craft) * norm(ΔVs[i,:]) * time/n
|
||||
else
|
||||
current[7] -= mfr(craft) * norm(ΔVs[i,:]) * time/n
|
||||
halfway += [zeros(3); full_thrust * ΔVs[i,:]] / current[7]
|
||||
end
|
||||
try
|
||||
state = prop_one(ΔVs[i,:], state, craft, time/n, primary)
|
||||
catch e
|
||||
if isa(e,PropOne_Error)
|
||||
for val in e.ΔV_unit
|
||||
# If this isn't true, then we just let it slide
|
||||
if abs(val) > 1.0001
|
||||
rethrow()
|
||||
end
|
||||
end
|
||||
else
|
||||
rethrow()
|
||||
end
|
||||
end
|
||||
for j in 1:7 push!(states[j], state[j]) end
|
||||
current[1:6] = laguerre_conway(halfway, time/(2n), primary)
|
||||
output[i,:] = current
|
||||
end
|
||||
|
||||
state[7] > craft.dry_mass || throw(Mass_Error(state[7]))
|
||||
current[7] > craft.dry_mass || throw(Mass_Error(current[7]))
|
||||
|
||||
return states, state
|
||||
return output
|
||||
|
||||
end
|
||||
|
||||
"""
|
||||
Convenience function for propagating a state with no thrust
|
||||
"""
|
||||
prop(x::Vector{Float64}, t::Float64, p::Body=Sun) = prop(zeros(1000,3), [x;1.], no_thrust, t, p)[1]
|
||||
prop(x::AbstractArray, t::Real, p::Body=Sun) = prop(zeros(1000,3), x, no_thrust, t, p)
|
||||
|
||||
"""
|
||||
This is solely for the purposes of getting the final state of a mission or guess
|
||||
@@ -91,7 +60,7 @@ function prop(m::Union{Mission, Mission_Guess})
|
||||
|
||||
final = zeros(7)
|
||||
for phase in m.phases
|
||||
final = prop(phase.thrust_profile, start, m.sc, phase.tof)[2]
|
||||
final = prop(phase.thrust_profile, start, m.sc, phase.tof)[end,:]
|
||||
mass = final[7]
|
||||
current_planet = phase.planet
|
||||
time += Second(floor(phase.tof))
|
||||
|
||||
@@ -7,23 +7,23 @@ Spacecraft: bepi
|
||||
num_thrusters: 2
|
||||
duty_cycle: 0.9
|
||||
Launch Mass: 3600.0 kg
|
||||
Launch Date: 2021-10-31T23:59:59.769
|
||||
Launch V∞: [1.0462564431708832, -2.520754077506101, -2.301043507881933] km/s
|
||||
Launch Date: 2021-10-31T22:00:16.400
|
||||
Launch V∞: [1.0097399011270518, -2.6447886914618515, -2.5394649406128433] km/s
|
||||
Phase 1:
|
||||
Planet: Venus
|
||||
V∞_in: [0.4205842845952983, -3.5241183574614556, 4.879873784266574] km/s
|
||||
V∞_out: [2.657685712690303, -4.920354075306563, 2.266369032728228] km/s
|
||||
time of flight: 1.2614399691127092e7 seconds
|
||||
arrival date: 2022-03-26T23:59:58.769
|
||||
thrust profile: [0.08791530712557315 -0.009101317973001748 0.010254083007822207; 0.07287521745776969 -0.011381949725375708 0.051332448819202944; 0.04543116258472458 -0.01531732267940295 0.08273458014460809; 0.011034188560216448 -0.020310595889307323 0.10100599446320643; -0.009607377273254756 -0.02382633371411493 0.1081982710061048; -0.028510355701058584 -0.030611944159923403 0.11101434996597628; -0.039048295910837236 -0.03820244320795566 0.11279184708362161; -0.048252651406879885 -0.04651039104792323 0.11301481830933677; -0.05288674350674192 -0.0561882917884983 0.11293454239992265; -0.05458628096513579 -0.06643801004024381 0.11223764822140121; -0.053564283975236535 -0.07751051107973227 0.11061646758637526; -0.049500823222769094 -0.0891415249668692 0.10769319474620971; -0.04185476746663511 -0.10066361474827486 0.10355236756997019; -0.03087924291992901 -0.1112479139000727 0.09781871133696314; -0.015564164113106642 -0.11996802006040436 0.09064682025194883; 0.001781758545597473 -0.12613079909578606 0.0809801955196938; 0.021345925406049154 -0.12876486287710442 0.06930029766487243; 0.041502826765638504 -0.12763804654948588 0.054677487677216745; 0.06024411885991524 -0.12236183464053872 0.038231302757203295; 0.07560839256024353 -0.114157581119008 0.018886579096999003] %
|
||||
V∞_in: [0.6971321781569763, -3.000415336232889, 5.257930893162622] km/s
|
||||
V∞_out: [3.155471614002537, -4.846243818499916, 1.9261368837603878] km/s
|
||||
time of flight: 1.261440000905646e7 seconds
|
||||
arrival date: 2022-03-26T22:00:16.400
|
||||
thrust profile: [0.034282174989117516 0.030630284530489906 0.0516767016545959; 0.04055472535721235 0.027376197088858283 0.04809039664320572; 0.043660143604191994 0.03047637966598728 0.04358760046457853; 0.04125099543115894 0.03016179866323979 0.04499932191472562; 0.04495441021193453 0.03348083036100891 0.03861183062100992; 0.04710965203705168 0.02635602095857307 0.04054560175736578; 0.05033947480940243 0.03062684297509654 0.032922298467773295; 0.04663650635412875 0.030369216537824293 0.03703971691255565; 0.048565701285880614 0.029118981813448557 0.034508738912923845; 0.05056448644255328 0.028722504694661054 0.031034420379757226; 0.04932798248085456 0.03007397062288681 0.030824783232637425; 0.047996060872376366 0.028952951818463326 0.032857369566278626; 0.04951821298908887 0.028758116977346378 0.027958339954661; 0.0489313400699588 0.03046347487498191 0.027859841906091212; 0.04520420340375004 0.031670198439770064 0.030514442243397236; 0.04566034232248259 0.034381957552538395 0.024900845759794794; 0.04082535412813151 0.03357236769501879 0.03170011587741194; 0.04621217362755022 0.03182636410505487 0.02410773528455805; 0.045645717216652795 0.032921517920520164 0.02079135127615303; 0.042597542211632096 0.03558968396172082 0.021282994074205266; 0.03731044485129105 0.03994289623933655 0.02130495307758324; 0.04247833588674327 0.03457796735712127 0.01899569141913135; 0.04312850336659755 0.03399248745544899 0.013149159955936978; 0.03754604612989521 0.03763011819702751 0.018318693954420588; 0.03535094668642273 0.036858320028499134 0.02199684830247042; 0.028891076662331875 0.04324155785176078 0.014413619206886816; 0.03267849036426984 0.0401634806637448 0.011840587979407397; 0.024706839495172658 0.043042163807245896 0.01826522977160073; 0.028601237657836467 0.041588848578667854 0.014411946517623132; 0.028228090581187873 0.04015749743865513 0.01508529741887872; 0.024783781293558266 0.04189396738290361 0.014616887877185162; 0.024764235231400287 0.0412235929856152 0.014206631004299218; 0.022700981741250053 0.04285522888573239 0.008652897464076466; 0.023149708367887163 0.04204784290805528 0.011482287191821549; 0.030060665695868752 0.03682561335933804 0.01406740384301527; 0.020327198179371554 0.03967929127546447 0.01907556971774192; 0.01948576963473395 0.04150171458022886 0.01440277138047399; 0.014609183554173198 0.04193091541988154 0.0190142349738259; 0.017338241200120032 0.0405327064144073 0.019397828837718817; 0.013519064235294736 0.043194207588669445 0.012618271521276186; 0.01416527483071525 0.042360112796518024 0.018565046588499192; 0.016192504354863486 0.04321790744316709 0.014857969976184007; 0.005926517746692747 0.04385012579593121 0.01848227965737381; 0.007881472501745706 0.045008039792868576 0.01571801630208125; 0.006544092936553959 0.04561895672702495 0.016342515520064185; 0.0018483989093118227 0.046533973409849064 0.014988164886431584; -0.000568247332158013 0.047073416094890685 0.01286929122897256; -0.008004594524198529 0.046599777614930456 0.013010850227684606; -0.00696671229499173 0.048339673337854945 0.010999881717700421; -0.0070218437672999665 0.04911375570173229 0.010996777473604348] %
|
||||
Phase 2:
|
||||
Planet: Mars
|
||||
V∞_in: [3.866657617879469, -3.8561104436565112, -1.1528388074396114] km/s
|
||||
V∞_out: [-0.04156826938628659, 0.04537147320396694, 0.010962101613372877] km/s
|
||||
time of flight: 1.3305600070108933e7 seconds
|
||||
arrival date: 2022-08-27T23:59:58.769
|
||||
thrust profile: [0.12294683695617006 -0.14210501591303906 -0.015953927996763824; 0.1346036754636979 -0.11703322342276389 -0.02118233265872474; 0.14035562458965456 -0.09253436643679969 -0.026037109750586127; 0.14159974389839877 -0.07034252588185486 -0.02965559917950358; 0.13983758574258884 -0.0508280123903436 -0.03226072974284784; 0.13628355001371623 -0.03381714643542805 -0.033706183284138075; 0.13174907912062978 -0.01944710462973476 -0.03378159713957984; 0.12690191547644916 -0.006666552590772735 -0.032314321099804075; 0.12190989012800546 0.005350412631176013 -0.02896415432946389; 0.11640547480173373 0.01766009561198736 -0.024295908236754368; 0.11004779022898785 0.029624240108957346 -0.018629744776725948; 0.10255142565747595 0.041391197147168296 -0.011260773047897207; 0.09257939116538691 0.054055648527399226 -0.0018819573006649628; 0.07862129598678515 0.06762185940978795 0.006827208192964654; 0.06184044671572194 0.07873199678299247 0.015671300335402687; 0.04256729407158805 0.08711502955932304 0.023547740065060118; 0.022644089962366266 0.0922573542104121 0.029300773045221138; 0.0012772594401787602 0.09453861142625342 0.0335188440659034; -0.017213511457067864 0.09403439603239908 0.036105272081528195; -0.03466637624188391 0.0910940423628138 0.03867124120601387] %
|
||||
V∞_in: [3.934071361708631, -4.0556866988998195, -0.9569218994864468] km/s
|
||||
V∞_out: [2.835079207012675, -3.038506396757051, -0.8239067509398897] km/s
|
||||
time of flight: 1.3305600002135515e7 seconds
|
||||
arrival date: 2022-08-27T22:00:16.400
|
||||
thrust profile: [0.07875872819429838 -0.07602928888291517 -0.002461076427925589; 0.08368497242841927 -0.06670986115534407 0.001665869512245407; 0.08577981435177857 -0.05793119355590426 0.011165188393882227; 0.08758545440549516 -0.0339816665457332 0.026794441364176573; 0.08293133779344392 -0.02340157704539268 0.034551607127364624; 0.07757395448326561 -0.006354368804274271 0.03802615353405709; 0.0644275187408338 0.00817115132820835 0.04477293215146323; 0.052643603336670175 0.021208603088669686 0.04641877730052604; 0.0422696791291819 0.03249686419539815 0.04293455453504036; 0.0299947244754212 0.0342146829206795 0.04610828643246764; 0.028375921792895057 0.031929570942726804 0.04880758017415033; 0.021457075341902082 0.03512409953676916 0.047848639128187716; 0.014050820576587325 0.03598753239044044 0.048208234639668036; 0.01239374458074181 0.03519088938079009 0.04991578465780201; 0.005554038390401058 0.03590306275800209 0.04943448284625346; 0.004594710645977571 0.03473960951290201 0.05085953544892566; 0.004962419167461687 0.03677569856463667 0.05029354676804025; 0.0007318114245317572 0.03710676170960615 0.050422609329575686; -0.0008906817624837742 0.03770220933797602 0.05041455076147805; -0.006778334873847526 0.03779829345387088 0.04962125740173904; -0.007046493202932243 0.03568043355312452 0.051960594399799505; -0.008049628911291552 0.03913802154188755 0.05028104660474625; -0.010537903266724359 0.03672325453597655 0.051884804336631986; -0.00818351261490794 0.038741730202093635 0.05210658416215128; -0.010666656787731375 0.03849972475725258 0.05243476797310733; -0.012555727410020852 0.0382137309957785 0.05268364578100002; -0.009820005328087349 0.03916769798664862 0.05359353372069135; -0.012387176669361927 0.03970296584000698 0.05331339060382668; -0.01244834483921497 0.041886262658702045 0.05253893772334037; -0.013444072160084112 0.04262744032016184 0.05253898626998434; -0.012523862311046558 0.04142301768047668 0.05454027471095643; -0.012895225834978194 0.042511978835118515 0.0544877324498131; -0.012679086383971097 0.04485961538708221 0.05361843203762159; -0.01233563279407355 0.04412582031595734 0.05489553351056654; -0.011291838361870397 0.04737557615034447 0.05363956736166156; -0.011230502857283789 0.04704594850205801 0.05467457973688944; -0.008797763456055051 0.04928744387907065 0.05415511568853677; -0.008048802844087589 0.05075747730843418 0.0538825677403911; -0.0056970113123549744 0.05224183281724393 0.05369505177198884; -0.006070834938122434 0.052936925948144475 0.05379731537648658; -0.0024653651357053295 0.05567255160163994 0.05213940324181525; -0.000733453786943943 0.057067189219935754 0.05145199179114529; 0.0012456777227569263 0.059943358064031824 0.04907287600209174; 0.004373513720293685 0.06169575905345249 0.047206183474067936; 0.009873790970193171 0.06486640320654036 0.04255101782330187; 0.013319573203495716 0.06692522008245975 0.03887179390451873; 0.018201455983236366 0.06835502892414509 0.034298233864195185; 0.023662275014910684 0.06904022589813187 0.029150000528514425; 0.02774195908046571 0.07005784655018363 0.02165291283778826; 0.031997497603024734 0.06946489515884077 0.015502921841459603] %
|
||||
|
||||
Mass Used: 121.86921799846004 kg
|
||||
Launch C3: 12.743654889305812 km²/s²
|
||||
||V∞_in||: 5.58118860132149 km/s
|
||||
Mass Used: 61.61570260672124 kg
|
||||
Launch C3: 14.463364075014354 km²/s²
|
||||
||V∞_in||: 5.730725224643533 km/s
|
||||
|
||||
@@ -4,72 +4,37 @@
|
||||
|
||||
println("Testing NLP solver")
|
||||
|
||||
# Test the optimizer for a one-phase mission
|
||||
# The lambert's solver said this should be pretty valid
|
||||
launch_window = DateTime(1992,11,1), DateTime(1992,12,1)
|
||||
latest_arrival = DateTime(1993,6,1)
|
||||
leave, arrive = DateTime(1992,11,19), DateTime(1993,4,1)
|
||||
test_leave = DateTime(1992,11,12)
|
||||
earth_state = state(Earth, leave)
|
||||
venus_state = state(Venus, arrive)
|
||||
v∞_out, v∞_in, tof = Thesis.lamberts(Earth, Venus, leave, arrive)
|
||||
# We can get the thrust profile and tof pretty wrong and still be ok
|
||||
phase = Phase(Venus, 1.1v∞_in, v∞_in, 0.9*tof, 0.1*ones(20,3))
|
||||
guess = Mission_Guess(bepi, 3_600., test_leave, 0.9*v∞_out, [phase])
|
||||
m = solve_mission(guess, launch_window, latest_arrival, 200., 20., verbose=true)
|
||||
@test typeof(m) == Mission
|
||||
|
||||
# Now we can plot the results to check visually
|
||||
p = plot(m, title="NLP Test Solution")
|
||||
savefig(p,"../plots/nlp_test_1_phase.html")
|
||||
store(m, "missions/nlp_1_phase")
|
||||
|
||||
# Now we can look at a slightly more complicated trajectory
|
||||
flybys = [Earth, Venus, Mars]
|
||||
# This will be the only test to verify rather than testing different complexities
|
||||
n = 50
|
||||
flybys = [Earth, Venus, Mars]#, Jupiter]
|
||||
launch_window = DateTime(2021,10,1), DateTime(2021,12,1)
|
||||
latest_arrival = DateTime(2023,1,1)
|
||||
dates = [DateTime(2021,11,1), DateTime(2022,3,27), DateTime(2022,8,28)]
|
||||
latest_arrival = DateTime(2028,1,1)
|
||||
dates = [DateTime(2021,11,1),
|
||||
DateTime(2022,3,27),
|
||||
DateTime(2022,8,28)]
|
||||
# DateTime(2028,3,1)]
|
||||
phases = Vector{Phase}()
|
||||
launch_v∞, _, tof1 = Thesis.lamberts(flybys[1], flybys[2], dates[1], dates[2])
|
||||
for i in 1:length(dates)-2
|
||||
v∞_out1, v∞_in1, tof1 = Thesis.lamberts(flybys[i], flybys[i+1], dates[i], dates[i+1])
|
||||
v∞_out2, v∞_in2, tof2 = Thesis.lamberts(flybys[i+1], flybys[i+2], dates[i+1], dates[i+2])
|
||||
push!(phases, Phase(flybys[i+1], v∞_in1, v∞_out2, tof1, 0.01*ones(20,3)))
|
||||
v∞_in1, tof1 = Thesis.lamberts(flybys[i], flybys[i+1], dates[i], dates[i+1])[2:3]
|
||||
v∞_out2 = Thesis.lamberts(flybys[i+1], flybys[i+2], dates[i+1], dates[i+2])[1]
|
||||
push!(phases, Phase(flybys[i+1], v∞_in1, v∞_out2, tof1, 0.01*ones(50,3)))
|
||||
end
|
||||
v∞_out, v∞_in, tof = Thesis.lamberts(flybys[end-1], flybys[end], dates[end-1], dates[end])
|
||||
push!(phases, Phase(flybys[end], v∞_in, v∞_in, tof, 0.01*ones(20,3)))
|
||||
v∞_in, tof = Thesis.lamberts(flybys[end-1], flybys[end], dates[end-1], dates[end])[2:3]
|
||||
push!(phases, Phase(flybys[end], v∞_in, v∞_in, tof, 0.01*ones(50,3)))
|
||||
guess = Mission_Guess(bepi, 3_600., dates[1], launch_v∞, phases)
|
||||
m = solve_mission(guess, launch_window, latest_arrival, 200., 20., verbose=true)
|
||||
m = solve_mission(guess,
|
||||
launch_window,
|
||||
latest_arrival,
|
||||
200.,
|
||||
20.,
|
||||
verbose=true,
|
||||
print_level=4)
|
||||
@test typeof(m) == Mission
|
||||
p = plot(m, title="NLP Test Solution (2 Phases)")
|
||||
savefig(p,"../plots/nlp_test_2_phase.html")
|
||||
store(m, "missions/nlp_2_phase")
|
||||
|
||||
# Here is the final, most complicated, trajectory to test
|
||||
# Ignoring for now as the initial guess makes the test take too long to converge with mbh settings
|
||||
# flybys = [Earth, Venus, Earth, Mars, Earth, Jupiter]
|
||||
# launch_window = DateTime(2023,1,1), DateTime(2024,1,1)
|
||||
# latest_arrival = DateTime(2031,1,1)
|
||||
# dates = [DateTime(2023,5,23),
|
||||
# DateTime(2023,10,21),
|
||||
# DateTime(2024,8,24),
|
||||
# DateTime(2025,2,13),
|
||||
# DateTime(2026,11,22),
|
||||
# DateTime(2032,1,1)]
|
||||
# phases = Vector{Phase}()
|
||||
# launch_v∞, _, tof1 = Thesis.lamberts(flybys[1], flybys[2], dates[1], dates[2])
|
||||
# for i in 1:length(dates)-2
|
||||
# v∞_out1, v∞_in1, tof1 = Thesis.lamberts(flybys[i], flybys[i+1], dates[i], dates[i+1])
|
||||
# v∞_out2, v∞_in2, tof2 = Thesis.lamberts(flybys[i+1], flybys[i+2], dates[i+1], dates[i+2])
|
||||
# push!(phases, Phase(flybys[i+1], 1.02v∞_in1, 0.98v∞_out2, 1.02tof1, 0.02*ones(20,3)))
|
||||
# end
|
||||
# v∞_out, v∞_in, tof = Thesis.lamberts(flybys[end-1], flybys[end], dates[end-1], dates[end])
|
||||
# push!(phases, Phase(flybys[end], v∞_in, v∞_in, tof, 0.01*ones(20,3)))
|
||||
# guess = Mission_Guess(bepi, 3_600., dates[1], launch_v∞, phases)
|
||||
# m = solve_mission(guess, launch_window, latest_arrival, 200., 20., verbose=true)
|
||||
# @test typeof(m) == Mission
|
||||
# p = plot(m, title="NLP Test Solution (5 Phases)")
|
||||
# savefig(p,"../plots/nlp_test_5_phase.html")
|
||||
# store(m, "missions/nlp_5_phase")
|
||||
if typeof(m) == Mission
|
||||
p = plot(m, title="NLP Test Solution (2 Phases)")
|
||||
savefig(p,"../plots/nlp_test_2_phase.html")
|
||||
store(m, "missions/nlp_2_phase")
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -1,21 +1,27 @@
|
||||
@testset "Propagator" begin
|
||||
|
||||
println("Testing propagator")
|
||||
using PlotlyJS: savefig
|
||||
|
||||
using Thesis: prop_one
|
||||
println("Testing Propagator")
|
||||
|
||||
# Set up
|
||||
start_mass = 10_000.
|
||||
start = gen_orbit(rand(.5year : hour : 2year), start_mass)
|
||||
stepsize = rand(hour : second : 6hour)
|
||||
time = rand(0.2year : second : 0.5year)
|
||||
n = 1_000
|
||||
|
||||
# Test that Laguerre-Conway is the default propagator for spacecrafts
|
||||
state = prop_one([0., 0., 0.], start, no_thrust, stepsize)
|
||||
@test laguerre_conway(start, stepsize) ≈ state[1:6]
|
||||
@test state[7] == start_mass
|
||||
# Test that Propagation works
|
||||
states = prop(zeros(n,3), start, no_thrust, time)
|
||||
@test states[1,:] != states[end,:]
|
||||
|
||||
# Test that mass is reduced properly
|
||||
state = prop_one([1., 0., 0.], start, bepi, stepsize)
|
||||
@test state[7] == start_mass - mfr(bepi)*stepsize
|
||||
|
||||
states = prop(ones(n,3)/√3, start, bepi, time)
|
||||
@test states[end,7] ≈ start_mass - mfr(bepi)*time
|
||||
|
||||
# Test that the propagator works backwards
|
||||
backwards = prop(ones(n,3)/√3, states[end,:], bepi, -time)
|
||||
p = plot([states, backwards])
|
||||
savefig(p,"../plots/prop_back.html")
|
||||
@test backwards[end,:] ≈ start
|
||||
|
||||
end
|
||||
|
||||
@@ -3,7 +3,7 @@ using Random
|
||||
using LinearAlgebra
|
||||
using SPICE
|
||||
using Thesis
|
||||
using Dates: DateTime, Millisecond, Dates, Second, format, datetime2unix, unix2datetime
|
||||
using Dates: DateTime, Millisecond, Dates, Second, format, datetime2julian, julian2datetime
|
||||
|
||||
try
|
||||
furnsh("../../spice_files/naif0012.tls")
|
||||
@@ -14,10 +14,10 @@ catch
|
||||
end
|
||||
|
||||
@testset "All Tests" begin
|
||||
include("plotting.jl")
|
||||
include("laguerre-conway.jl")
|
||||
# include("plotting.jl")
|
||||
# include("laguerre-conway.jl")
|
||||
include("propagator.jl")
|
||||
include("nlp_solver.jl")
|
||||
include("mbh.jl")
|
||||
include("genetic_algorithm.jl")
|
||||
# include("nlp_solver.jl")
|
||||
# include("mbh.jl")
|
||||
# include("genetic_algorithm.jl")
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user