Seems like a lot changed...

This commit is contained in:
Connor
2022-02-19 12:30:54 -07:00
parent 5d5c79c909
commit 329a2990c5
16 changed files with 532 additions and 273 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 103 KiB

After

Width:  |  Height:  |  Size: 111 KiB

View File

@@ -7,7 +7,7 @@
viewBox="0 0 279.4 215.9" viewBox="0 0 279.4 215.9"
version="1.1" version="1.1"
id="svg5" 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" sodipodi:docname="mbh.svg"
inkscape:export-filename="/home/connor/projects/thesis/LaTeX/flowcharts/mbh.png" inkscape:export-filename="/home/connor/projects/thesis/LaTeX/flowcharts/mbh.png"
inkscape:export-xdpi="150" inkscape:export-xdpi="150"
@@ -27,15 +27,18 @@
inkscape:document-units="mm" inkscape:document-units="mm"
showgrid="true" showgrid="true"
units="in" units="in"
inkscape:zoom="1.1148803" inkscape:zoom="0.78833942"
inkscape:cx="548.48938" inkscape:cx="525.15451"
inkscape:cy="287.02633" inkscape:cy="378.64401"
inkscape:window-width="1916" inkscape:window-width="1912"
inkscape:window-height="1045" inkscape:window-height="1040"
inkscape:window-x="1920" inkscape:window-x="1920"
inkscape:window-y="31" inkscape:window-y="32"
inkscape:window-maximized="1" 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 <inkscape:grid
type="xygrid" type="xygrid"
id="grid9" id="grid9"
@@ -270,6 +273,32 @@
width="113.38583" width="113.38583"
height="18.897638" height="18.897638"
id="rect242401-5-7" /> 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> </defs>
<g <g
inkscape:label="Layer 1" inkscape:label="Layer 1"
@@ -299,17 +328,17 @@
inkscape:export-ydpi="150"><tspan inkscape:export-ydpi="150"><tspan
x="51.237262" x="51.237262"
y="35.095099" y="35.095099"
id="tspan295134">Generate Random </tspan><tspan id="tspan10729">Generate Random </tspan><tspan
x="53.253338" x="53.253338"
y="38.622885" y="38.622885"
id="tspan295136">Mission Guess</tspan></text> id="tspan10731">Mission Guess</tspan></text>
<rect <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" id="rect33-3"
width="25" width="25"
height="15" height="15"
x="97.5" x="97.5"
y="32.5" y="42.5"
rx="1" rx="1"
ry="1" ry="1"
inkscape:export-filename="/home/connor/projects/thesis/LaTeX/flowcharts/mbh.png" inkscape:export-filename="/home/connor/projects/thesis/LaTeX/flowcharts/mbh.png"
@@ -326,8 +355,33 @@
inkscape:export-xdpi="150" inkscape:export-xdpi="150"
inkscape:export-ydpi="150"><tspan inkscape:export-ydpi="150"><tspan
x="98.748283" x="98.748283"
y="35.095099" y="45.095099"
id="tspan295138">Correct the Guess</tspan></text> 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 <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-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
id="rect33-3-1" id="rect33-3-1"
@@ -352,7 +406,7 @@
inkscape:export-ydpi="150"><tspan inkscape:export-ydpi="150"><tspan
x="201.24829" x="201.24829"
y="99.141974" y="99.141974"
id="tspan295140">Correct the Guess</tspan></text> id="tspan10737">Correct the Guess</tspan></text>
<rect <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-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
id="rect33-3-2" id="rect33-3-2"
@@ -377,10 +431,10 @@
inkscape:export-ydpi="150"><tspan inkscape:export-ydpi="150"><tspan
x="227.35348" x="227.35348"
y="35.095099" y="35.095099"
id="tspan295142">Store as Current </tspan><tspan id="tspan10739">Store as Current </tspan><tspan
x="227.66698" x="227.66698"
y="38.622885" y="38.622885"
id="tspan295144">Best, Set Drill=0</tspan></text> id="tspan10741">Best, Set Drill=0</tspan></text>
<rect <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-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
id="rect33-3-2-9" id="rect33-3-2-9"
@@ -405,10 +459,10 @@
inkscape:export-ydpi="150"><tspan inkscape:export-ydpi="150"><tspan
x="202.34314" x="202.34314"
y="67.118536" y="67.118536"
id="tspan295146">Perturb the Best </tspan><tspan id="tspan10743">Perturb the Best </tspan><tspan
x="202.27079" x="202.27079"
y="70.646322" y="70.646322"
id="tspan295148">Guess (in Basin)</tspan></text> id="tspan10745">Guess (in Basin)</tspan></text>
<circle <circle
style="fill:#3771c8;stroke:#1d195c;stroke-width:0.5;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" style="fill:#3771c8;stroke:#1d195c;stroke-width:0.5;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
id="path49453" id="path49453"
@@ -476,12 +530,12 @@
inkscape:export-ydpi="150"><tspan inkscape:export-ydpi="150"><tspan
x="37.12022" x="37.12022"
y="52.132153" y="52.132153"
id="tspan295150">Hit Search<tspan id="tspan10747">Hit Search<tspan
y="52.132153" y="52.132153"
id="tspan295152"> </tspan></tspan><tspan id="tspan10749"> </tspan></tspan><tspan
x="37.12022" x="37.12022"
y="55.659938" y="55.659938"
id="tspan295154">Limit?</tspan></text> id="tspan10751">Limit?</tspan></text>
<circle <circle
style="fill:#3771c8;stroke:#1d195c;stroke-width:0.5;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" style="fill:#3771c8;stroke:#1d195c;stroke-width:0.5;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
id="path49453-9-7" id="path49453-9-7"
@@ -503,12 +557,12 @@
inkscape:export-ydpi="150"><tspan inkscape:export-ydpi="150"><tspan
x="107.7821" x="107.7821"
y="78.232147" y="78.232147"
id="tspan295156">Hit Drill<tspan id="tspan10753">Hit Drill<tspan
y="78.232147" y="78.232147"
id="tspan295158"> </tspan></tspan><tspan id="tspan10755"> </tspan></tspan><tspan
x="107.7821" x="107.7821"
y="81.759936" y="81.759936"
id="tspan295160">Limit?</tspan></text> id="tspan10757">Limit?</tspan></text>
<circle <circle
style="fill:#3771c8;stroke:#1d195c;stroke-width:0.5;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" style="fill:#3771c8;stroke:#1d195c;stroke-width:0.5;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
id="path49453-5" id="path49453-5"
@@ -530,22 +584,22 @@
inkscape:export-ydpi="150"><tspan inkscape:export-ydpi="150"><tspan
x="141.6602" x="141.6602"
y="25.945316" y="25.945316"
id="tspan295162">Better<tspan id="tspan10759">Better<tspan
y="25.945316" y="25.945316"
id="tspan295164"> </tspan></tspan><tspan id="tspan10761"> </tspan></tspan><tspan
x="141.6602" x="141.6602"
y="29.473104" y="29.473104"
id="tspan295166">than<tspan id="tspan10763">than<tspan
y="29.473104" y="29.473104"
id="tspan295168"> </tspan></tspan><tspan id="tspan10765"> </tspan></tspan><tspan
x="141.6602" x="141.6602"
y="33.000892" y="33.000892"
id="tspan295170">current<tspan id="tspan10767">current<tspan
y="33.000892" y="33.000892"
id="tspan295172"> </tspan></tspan><tspan id="tspan10769"> </tspan></tspan><tspan
x="141.6602" x="141.6602"
y="36.528678" y="36.528678"
id="tspan295174">best?</tspan></text> id="tspan10771">best?</tspan></text>
<circle <circle
style="fill:#3771c8;stroke:#1d195c;stroke-width:0.5;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" style="fill:#3771c8;stroke:#1d195c;stroke-width:0.5;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
id="path49453-5-9" id="path49453-5-9"
@@ -567,22 +621,22 @@
inkscape:export-ydpi="150"><tspan inkscape:export-ydpi="150"><tspan
x="141.6602" x="141.6602"
y="25.945316" y="25.945316"
id="tspan295176">Better<tspan id="tspan10773">Better<tspan
y="25.945316" y="25.945316"
id="tspan295178"> </tspan></tspan><tspan id="tspan10775"> </tspan></tspan><tspan
x="141.6602" x="141.6602"
y="29.473104" y="29.473104"
id="tspan295180">than<tspan id="tspan10777">than<tspan
y="29.473104" y="29.473104"
id="tspan295182"> </tspan></tspan><tspan id="tspan10779"> </tspan></tspan><tspan
x="141.6602" x="141.6602"
y="33.000892" y="33.000892"
id="tspan295184">current<tspan id="tspan10781">current<tspan
y="33.000892" y="33.000892"
id="tspan295186"> </tspan></tspan><tspan id="tspan10783"> </tspan></tspan><tspan
x="141.6602" x="141.6602"
y="36.528678" y="36.528678"
id="tspan295188">best?</tspan></text> id="tspan10785">best?</tspan></text>
<path <path
sodipodi:type="star" sodipodi:type="star"
style="fill:#cc00ff;stroke:#460e4f;stroke-opacity:1;stroke-width:1.8897638;stroke-miterlimit:4;stroke-dasharray:none" 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 inkscape:export-ydpi="150"><tspan
x="-9.077858" x="-9.077858"
y="179.51565" y="179.51565"
id="tspan295190">Output </tspan><tspan id="tspan10787">Output </tspan><tspan
x="-2.361691" x="-2.361691"
y="192.84903" y="192.84903"
id="tspan295192">Best </tspan><tspan id="tspan10789">Best </tspan><tspan
x="-10.317445" x="-10.317445"
y="206.1824" y="206.1824"
id="tspan295194">Mission</tspan></text> id="tspan10791">Mission</tspan></text>
<text <text
xml:space="preserve" xml:space="preserve"
transform="scale(0.26458333)" transform="scale(0.26458333)"
id="text150108" 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)" /> style="line-height:1.25;font-family:sans-serif;font-size:10.66666667px;text-align:center;white-space:pre;shape-inside:url(#rect150110)" />
<path <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" 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 75,39.999999 c 22.5,0 22.5,0 22.5,0" d="M 78.75,29.999999 96.25,30"
id="path183790" id="path183790"
inkscape:export-filename="/home/connor/projects/thesis/LaTeX/flowcharts/mbh.png" inkscape:export-filename="/home/connor/projects/thesis/LaTeX/flowcharts/mbh.png"
inkscape:export-xdpi="150" inkscape:export-xdpi="150"
inkscape:export-ydpi="150" /> inkscape:export-ydpi="150"
sodipodi:nodetypes="cc" />
<path <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" 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 122.5,39.999999 c 22.5,0 22.5,0 22.5,0" 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" id="path183792"
inkscape:export-filename="/home/connor/projects/thesis/LaTeX/flowcharts/mbh.png" inkscape:export-filename="/home/connor/projects/thesis/LaTeX/flowcharts/mbh.png"
inkscape:export-xdpi="150" inkscape:export-xdpi="150"
inkscape:export-ydpi="150" /> inkscape:export-ydpi="150"
sodipodi:nodetypes="cc" />
<path <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)" 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" d="M 153.75,48.75 V 67.5 H 71.249999"
@@ -649,12 +713,13 @@
inkscape:export-xdpi="150" inkscape:export-xdpi="150"
inkscape:export-ydpi="150" /> inkscape:export-ydpi="150" />
<path <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)" 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 c 0,-14.999999 0,-14.999999 0,-14.999999" d="M 62.499999,62.499999 62.5,48.75"
id="path184104" id="path184104"
inkscape:export-filename="/home/connor/projects/thesis/LaTeX/flowcharts/mbh.png" inkscape:export-filename="/home/connor/projects/thesis/LaTeX/flowcharts/mbh.png"
inkscape:export-xdpi="150" inkscape:export-xdpi="150"
inkscape:export-ydpi="150" /> inkscape:export-ydpi="150"
sodipodi:nodetypes="cc" />
<path <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)" 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" 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 inkscape:export-ydpi="150"><tspan
x="635.915" x="635.915"
y="141.72073" y="141.72073"
id="tspan295196">True</tspan></text> id="tspan10793">True</tspan></text>
<text <text
xml:space="preserve" xml:space="preserve"
transform="matrix(0.26458333,0,0,0.26458333,-12.955747,15.101026)" transform="matrix(0.26458333,0,0,0.26458333,-12.955747,15.101026)"
@@ -760,7 +825,7 @@
inkscape:export-ydpi="150"><tspan inkscape:export-ydpi="150"><tspan
x="633.8551" x="633.8551"
y="141.72073" y="141.72073"
id="tspan295198">False</tspan></text> id="tspan10795">False</tspan></text>
<text <text
xml:space="preserve" xml:space="preserve"
transform="matrix(0.26458333,0,0,0.26458333,26.891584,14.845951)" transform="matrix(0.26458333,0,0,0.26458333,26.891584,14.845951)"
@@ -771,7 +836,7 @@
inkscape:export-ydpi="150"><tspan inkscape:export-ydpi="150"><tspan
x="633.8551" x="633.8551"
y="141.72073" y="141.72073"
id="tspan295200">False</tspan></text> id="tspan10797">False</tspan></text>
<text <text
xml:space="preserve" xml:space="preserve"
transform="matrix(0.26458333,0,0,0.26458333,-32.656732,64.804214)" transform="matrix(0.26458333,0,0,0.26458333,-32.656732,64.804214)"
@@ -782,7 +847,7 @@
inkscape:export-ydpi="150"><tspan inkscape:export-ydpi="150"><tspan
x="633.8551" x="633.8551"
y="141.72073" y="141.72073"
id="tspan295202">False</tspan></text> id="tspan10799">False</tspan></text>
<text <text
xml:space="preserve" xml:space="preserve"
transform="matrix(0.26458333,0,0,0.26458333,-34.796459,97.987154)" transform="matrix(0.26458333,0,0,0.26458333,-34.796459,97.987154)"
@@ -793,7 +858,7 @@
inkscape:export-ydpi="150"><tspan inkscape:export-ydpi="150"><tspan
x="633.8551" x="633.8551"
y="141.72073" y="141.72073"
id="tspan295204">False</tspan></text> id="tspan10801">False</tspan></text>
<text <text
xml:space="preserve" xml:space="preserve"
transform="matrix(0.26458333,0,0,0.26458333,-56.727236,55.251175)" transform="matrix(0.26458333,0,0,0.26458333,-56.727236,55.251175)"
@@ -804,7 +869,7 @@
inkscape:export-ydpi="150"><tspan inkscape:export-ydpi="150"><tspan
x="633.8551" x="633.8551"
y="141.72073" y="141.72073"
id="tspan295206">False</tspan></text> id="tspan10803">False</tspan></text>
<text <text
xml:space="preserve" xml:space="preserve"
transform="matrix(0.26458333,0,0,0.26458333,-104.48989,22.217343)" transform="matrix(0.26458333,0,0,0.26458333,-104.48989,22.217343)"
@@ -815,7 +880,7 @@
inkscape:export-ydpi="150"><tspan inkscape:export-ydpi="150"><tspan
x="633.8551" x="633.8551"
y="141.72073" y="141.72073"
id="tspan295208">False</tspan></text> id="tspan10805">False</tspan></text>
<text <text
xml:space="preserve" xml:space="preserve"
transform="matrix(0.26458333,0,0,0.26458333,40.720808,1.6305782)" transform="matrix(0.26458333,0,0,0.26458333,40.720808,1.6305782)"
@@ -826,7 +891,7 @@
inkscape:export-ydpi="150"><tspan inkscape:export-ydpi="150"><tspan
x="635.915" x="635.915"
y="141.72073" y="141.72073"
id="tspan295210">True</tspan></text> id="tspan10807">True</tspan></text>
<text <text
xml:space="preserve" xml:space="preserve"
transform="matrix(0.26458333,0,0,0.26458333,-13.87236,82.629073)" transform="matrix(0.26458333,0,0,0.26458333,-13.87236,82.629073)"
@@ -837,7 +902,7 @@
inkscape:export-ydpi="150"><tspan inkscape:export-ydpi="150"><tspan
x="635.915" x="635.915"
y="141.72073" y="141.72073"
id="tspan295212">True</tspan></text> id="tspan10809">True</tspan></text>
<text <text
xml:space="preserve" xml:space="preserve"
transform="matrix(0.26458333,0,0,0.26458333,-1.9337214,98.008192)" transform="matrix(0.26458333,0,0,0.26458333,-1.9337214,98.008192)"
@@ -848,7 +913,7 @@
inkscape:export-ydpi="150"><tspan inkscape:export-ydpi="150"><tspan
x="635.915" x="635.915"
y="141.72073" y="141.72073"
id="tspan295214">True</tspan></text> id="tspan10811">True</tspan></text>
<text <text
xml:space="preserve" xml:space="preserve"
transform="matrix(0.26458333,0,0,0.26458333,-74.958276,64.67963)" transform="matrix(0.26458333,0,0,0.26458333,-74.958276,64.67963)"
@@ -859,7 +924,7 @@
inkscape:export-ydpi="150"><tspan inkscape:export-ydpi="150"><tspan
x="635.915" x="635.915"
y="141.72073" y="141.72073"
id="tspan295216">True</tspan></text> id="tspan10813">True</tspan></text>
<text <text
xml:space="preserve" xml:space="preserve"
transform="matrix(0.26458333,0,0,0.26458333,-104.68725,49.492044)" transform="matrix(0.26458333,0,0,0.26458333,-104.68725,49.492044)"
@@ -870,7 +935,7 @@
inkscape:export-ydpi="150"><tspan inkscape:export-ydpi="150"><tspan
x="635.915" x="635.915"
y="141.72073" y="141.72073"
id="tspan295218">True</tspan></text> id="tspan10815">True</tspan></text>
<text <text
xml:space="preserve" xml:space="preserve"
transform="matrix(0.26458333,0,0,0.26458333,1.5394599,3.6362688)" transform="matrix(0.26458333,0,0,0.26458333,1.5394599,3.6362688)"
@@ -881,7 +946,29 @@
inkscape:export-ydpi="150"><tspan inkscape:export-ydpi="150"><tspan
x="391.15289" x="391.15289"
y="236.20901" 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 <text
xml:space="preserve" xml:space="preserve"
transform="matrix(0.26458333,0,0,0.26458333,22.069121,44.757718)" transform="matrix(0.26458333,0,0,0.26458333,22.069121,44.757718)"
@@ -892,7 +979,7 @@
inkscape:export-ydpi="150"><tspan inkscape:export-ydpi="150"><tspan
x="398.73104" x="398.73104"
y="236.20901" y="236.20901"
id="tspan295222">Drill += 1</tspan></text> id="tspan10823">Drill += 1</tspan></text>
<text <text
xml:space="preserve" xml:space="preserve"
transform="matrix(0.26458333,0,0,0.26458333,22.933651,79.18148)" transform="matrix(0.26458333,0,0,0.26458333,22.933651,79.18148)"
@@ -903,7 +990,7 @@
inkscape:export-ydpi="150"><tspan inkscape:export-ydpi="150"><tspan
x="398.73104" x="398.73104"
y="236.20901" y="236.20901"
id="tspan295224">Drill += 1</tspan></text> id="tspan10825">Drill += 1</tspan></text>
<path <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)" 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" 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-filename="/home/connor/projects/thesis/LaTeX/flowcharts/mbh.png"
inkscape:export-xdpi="150" inkscape:export-xdpi="150"
inkscape:export-ydpi="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> </g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 42 KiB

View File

@@ -12,8 +12,8 @@
\degree{Master of Science}{M.S., Aerospace Engineering} \degree{Master of Science}{M.S., Aerospace Engineering}
\dept{Department of}{Aerospace Engineering} \dept{Department of}{Aerospace Engineering}
\advisor{Prof.}{Natasha Bosanac} \advisor{Prof.}{Natasha Bosanac}
\reader{TBD: Kathryn Davis} \reader{Kathryn Davis}
\readerThree{TBD: Daniel Scheeres} \readerThree{Daniel Scheeres}
\abstract{ \OnePageChapter \abstract{ \OnePageChapter
There are a variety of approaches to finding and optimizing low-thrust trajectories in 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 Englander in his Hybrid Optimal Control Problem paper, but does not allow for missions
with multiple targets, simplifying the optimization. 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 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 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. in order to achieve maximum precision.
\section{Outer Loop Implementation} \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} Now we have the tools in place for, given a potential ''mission guess`` in the
The primary reason for including this section is to discuss the error handling. 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 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 used and go into quite a bit of detail. Englander's paper on the MBH algorithm specifically
should be a good guide. Mention validation. 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 Talk a bit about why this work is valuable. Missions that could have benefited, missions that
this enables, etc. 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 Recommend future work, obviously. There are a \emph{ton} of opportunities for improvement
including parallelization, cluster computing, etc. including parallelization, cluster computing, etc.

View File

@@ -99,6 +99,12 @@ git-tree-sha1 = "bdc0937269321858ab2a4f288486cb258b9a0af7"
uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
version = "1.3.0" version = "1.3.0"
[[CodeTracking]]
deps = ["InteractiveUtils", "UUIDs"]
git-tree-sha1 = "9aa8a5ebb6b5bf469a7e0e2b5202cf6f8c291104"
uuid = "da1fd8a2-8d9e-5ec2-8556-3022fb5608a2"
version = "1.0.6"
[[CodecBzip2]] [[CodecBzip2]]
deps = ["Bzip2_jll", "Libdl", "TranscodingStreams"] deps = ["Bzip2_jll", "Libdl", "TranscodingStreams"]
git-tree-sha1 = "2e62a725210ce3c3c2e1a3080190e7ca491f18d7" git-tree-sha1 = "2e62a725210ce3c3c2e1a3080190e7ca491f18d7"
@@ -329,6 +335,12 @@ git-tree-sha1 = "2f49f7f86762a0fbbeef84912265a1ae61c4ef80"
uuid = "7d188eb4-7ad8-530c-ae41-71a32a6d4692" uuid = "7d188eb4-7ad8-530c-ae41-71a32a6d4692"
version = "0.3.4" 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]] [[Kaleido_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "2ef87eeaa28713cb010f9fb0be288b6c1a4ecd53" git-tree-sha1 = "2ef87eeaa28713cb010f9fb0be288b6c1a4ecd53"
@@ -390,6 +402,12 @@ version = "0.3.0"
[[Logging]] [[Logging]]
uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" 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]] [[METIS_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "2dc1a9fc87e57e32b1fc186db78811157b30c118" git-tree-sha1 = "2dc1a9fc87e57e32b1fc186db78811157b30c118"
@@ -559,6 +577,12 @@ git-tree-sha1 = "63ee24ea0689157a1113dbdab10c6cb011d519c4"
uuid = "37e2e3b7-166d-5795-8a7a-e32c996b4267" uuid = "37e2e3b7-166d-5795-8a7a-e32c996b4267"
version = "1.9.0" 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]] [[SHA]]
uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce"

View File

@@ -12,6 +12,7 @@ LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
PlotlyBase = "a03496cd-edff-5a9b-9e67-9cda94a718b5" PlotlyBase = "a03496cd-edff-5a9b-9e67-9cda94a718b5"
PlotlyJS = "f0f68f2c-4968-5e81-91da-67840de0976a" PlotlyJS = "f0f68f2c-4968-5e81-91da-67840de0976a"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
Revise = "295af30f-e4ad-537b-8983-00126c2a3abe"
SNOW = "105f6ee8-0889-46b1-9d4b-65e03cbc8f13" SNOW = "105f6ee8-0889-46b1-9d4b-65e03cbc8f13"
SPICE = "5bab7191-041a-5c2e-a744-024b9c3a5062" SPICE = "5bab7191-041a-5c2e-a744-024b9c3a5062"
SymbolServer = "cf896787-08d5-524d-9de7-132aaa0cb996" SymbolServer = "cf896787-08d5-524d-9de7-132aaa0cb996"

View File

@@ -7,7 +7,7 @@ module Thesis
using PlotlyJS using PlotlyJS
using Distributed using Distributed
using SPICE using SPICE
using Dates: DateTime, Millisecond, Dates, Second, format, datetime2unix, unix2datetime using Dates: DateTime, Millisecond, Dates, Second, format, datetime2julian, julian2datetime
try try
furnsh("../../spice_files/naif0012.tls") furnsh("../../spice_files/naif0012.tls")

View File

@@ -2,30 +2,27 @@ using SNOW
export solve_mission 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) function constraint_bounds(guess::Mission_Guess)
low_constraint = Vector{Float64}() low_constraint = Vector{Float64}()
high_constraint = Vector{Float64}() high_constraint = Vector{Float64}()
for phase in guess.phases 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!(low_constraint, (-1 * state_constraint)... )
push!(high_constraint, state_constraint... ) push!(high_constraint, state_constraint... )
if phase != guess.phases[end] if phase != guess.phases[end]
push!(low_constraint, -0.005*v∞_scale, 100.) # Constraints on the v∞ and turning angle
push!(high_constraint, 0.005*v∞_scale, 1e7) push!(low_constraint, -0.05, 100.)
push!(high_constraint, 0.05, 1e7)
else else
# Constraints on mass
push!(low_constraint, 0.) push!(low_constraint, 0.)
push!(high_constraint, guess.start_mass - guess.sc.dry_mass) push!(high_constraint, guess.start_mass - guess.sc.dry_mass)
end end
end end
# Constraints on C3 and V∞
push!(low_constraint, 0., 0.) push!(low_constraint, 0., 0.)
push!(high_constraint, 1e3, 1e3) push!(high_constraint, 1e3, 1e3)
@@ -57,8 +54,8 @@ function solve_mission( guess::Mission_Guess,
# Establish initial conditions # Establish initial conditions
v∞_out = x[2:4] v∞_out = x[2:4]
current_planet = Earth current_planet = Earth
launch_date = unix2datetime(x[1]) launch_date = julian2datetime(x[1])
time = utc2et(format(launch_date,"yyyy-mm-ddTHH:MM:SS")) time = Dates.datetime2julian(launch_date)
start = state(current_planet, time, v∞_out, guess.start_mass) start = state(current_planet, time, v∞_out, guess.start_mass)
final = zeros(7) final = zeros(7)
@@ -80,16 +77,16 @@ function solve_mission( guess::Mission_Guess,
thrusts = reshape(phase_params[8:end], (n,3)) thrusts = reshape(phase_params[8:end], (n,3))
# Propagate # Propagate
final = prop(thrusts, start, guess.sc, tof)[2] final = prop(thrusts, start, guess.sc, tof)[end,:]
current_planet = flyby current_planet = flyby
time += tof time += tof/86400
goal = state(current_planet, time, v∞_in)[1:6] goal = state(current_planet, time, v∞_in)[1:6]
start = state(current_planet, time, v∞_out, final[7]) start = state(current_planet, time, v∞_out, final[7])
# Do Checks # 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] 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) ) ) δ = 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 g[8+8i] = (current_planet.μ/(v∞_in v∞_in)) * ( 1/sin(δ/2) - 1 ) - current_planet.r
else else
@@ -100,7 +97,7 @@ function solve_mission( guess::Mission_Guess,
i += 1 i += 1
end end
return 1.0 return -final[end]
catch e catch e
@@ -114,7 +111,7 @@ function solve_mission( guess::Mission_Guess,
end end
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) lower_x = lowest_mission_vector(launch_window, length(guess.phases), n)
upper_x = highest_mission_vector(launch_window, max_time, 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 num_constraints = 8*(length(guess.phases)-1) + 9
@@ -123,7 +120,7 @@ function solve_mission( guess::Mission_Guess,
"acceptable_constr_viol_tol" => 100tol, "acceptable_constr_viol_tol" => 100tol,
"bound_relax_factor" => 0., "bound_relax_factor" => 0.,
"max_iter" => 100_000, "max_iter" => 100_000,
"max_cpu_time" => 5. * length(guess.phases), "max_cpu_time" => 10. * length(guess.phases),
"print_level" => print_level) "print_level" => print_level)
options = Options(solver=IPOPT(ipopt_options), derivatives=ForwardFD()) options = Options(solver=IPOPT(ipopt_options), derivatives=ForwardFD())

View File

@@ -1,22 +1,106 @@
export state, period export state, period
struct Body struct Body
μ::Float64 μ::Real
r::Float64 # radius r::Real # radius
color::String color::String
id::Int # SPICE id id::Int # SPICE id
a::Float64 # semi-major axis a::Real # semi-major axis
line_color::AbstractString line_color::AbstractString
name::AbstractString name::AbstractString
end end
period(b::Body) = 2π * (b.a^3 / Sun.μ) 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 function state(p::Body, t::DateTime, add_v∞::AbstractVector=[0., 0., 0.], add_mass::Float64=1e10)
time = utc2et(format(t,"yyyy-mm-ddTHH:MM:SS")) time = Dates.datetime2julian(t)
[ spkssb(p.id, time, "ECLIPJ2000"); 0.0 ] + [ zeros(3); add_v∞; add_mass ] [ basic_ephemeris(p,time); 0.0 ] + [ zeros(3); add_v∞; add_mass ]
end end
function state(p::Body, t::S, add_v∞::Vector{T}=[0., 0., 0.], add_mass::Float64=1e10) where {T,S <: Real} function state(p::Body, t::Real, add_v∞::AbstractVector=[0., 0., 0.], add_mass::Real=1e10)
[ spkssb(p.id, t, "ECLIPJ2000"); 0.0 ] + [ zeros(3); add_v∞; add_mass ] [ 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 end

View File

@@ -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}) function Mission_Guess(x::Vector{Float64}, sc::Sc, mass::Float64, flybys::Vector{Body})
# Variable mission params # Variable mission params
launch_date = unix2datetime(x[1]) launch_date = julian2datetime(x[1])
launch_v∞ = x[2:4] launch_v∞ = x[2:4]
# Try to intelligently determine n # Try to intelligently determine n
@@ -78,7 +78,7 @@ information from the guess though.
""" """
function Base.Vector(g::Mission_Guess) function Base.Vector(g::Mission_Guess)
result = Vector{Float64}() result = Vector{Float64}()
push!(result, datetime2unix(g.launch_date)) push!(result, datetime2julian(g.launch_date))
push!(result, g.launch_v∞...) push!(result, g.launch_v∞...)
for phase in g.phases for phase in g.phases
push!(result,phase.v∞_in...) push!(result,phase.v∞_in...)
@@ -91,7 +91,7 @@ end
function lowest_mission_vector(launch_window::Tuple{DateTime,DateTime}, num_phases::Int, n::Int) function lowest_mission_vector(launch_window::Tuple{DateTime,DateTime}, num_phases::Int, n::Int)
result = Vector{Float64}() result = Vector{Float64}()
push!(result, datetime2unix(launch_window[1])) push!(result, datetime2julian(launch_window[1]))
push!(result, -10*ones(3)...) push!(result, -10*ones(3)...)
for i in 1:num_phases for i in 1:num_phases
push!(result, -10*ones(3)...) 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) function highest_mission_vector(launch_window::Tuple{DateTime,DateTime}, mission_length::Float64, num_phases::Int, n::Int)
result = Vector{Float64}() result = Vector{Float64}()
push!(result, datetime2unix(launch_window[2])) push!(result, datetime2julian(launch_window[2]))
push!(result, 10*ones(3)...) push!(result, 10*ones(3)...)
for i in 1:num_phases for i in 1:num_phases
push!(result, 10*ones(3)...) push!(result, 10*ones(3)...)
@@ -133,14 +133,14 @@ function Mission(sc::Sc, mass::Float64, date::DateTime, v∞::Vector{Float64}, p
force=false) force=false)
# First do some checks to make sure that it's valid # First do some checks to make sure that it's valid
if !force if !force
time = utc2et(format(date,"yyyy-mm-ddTHH:MM:SS")) time = datetime2julian(date)
current_planet = Earth current_planet = Earth
start = state(current_planet, time, v∞, mass) start = state(current_planet, time, v∞, mass)
for phase in phases for phase in phases
#Propagate #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 current_planet = phase.planet
time += phase.tof time += phase.tof/86400
goal = state(current_planet, time, phase.v∞_in) goal = state(current_planet, time, phase.v∞_in)
start = state(current_planet, time, phase.v∞_out, final[7]) 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}) function Mission(x::Vector{Float64}, sc::Sc, mass::Float64, flybys::Vector{Body})
# Variable mission params # Variable mission params
launch_date = unix2datetime(x[1]) launch_date = julian2datetime(x[1])
launch_v∞ = x[2:4] launch_v∞ = x[2:4]
# Try to intelligently determine n # Try to intelligently determine n

View File

@@ -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.μ μ = primary.μ
n = 5 # Choose LaGuerre-Conway "n" n = 5 # Choose LaGuerre-Conway "n"

View File

@@ -59,27 +59,27 @@ end
""" """
A fundamental function to generate a plot for a single orbit path 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, label::Union{AbstractString, Nothing} = nothing,
color::AbstractString = random_color(), color::AbstractString = random_color(),
markers=true) markers=true)
# Plot the orbit # Plot the orbit
if label === nothing 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) mode="lines", showlegend=false, line_color=color, line_width=3)
else 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) mode="lines", name=label, line_color=color, line_width=3)
end end
traces = [ path_trace ] traces = [ path_trace ]
# Plot the markers # Plot the markers
if 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, mode="markers", showlegend=false,
marker=attr(color=color, size=3, symbol="circle"))) 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, mode="markers", showlegend=false,
marker=attr(color=color, size=3, symbol="diamond"))) marker=attr(color=color, size=3, symbol="diamond")))
end end
@@ -222,7 +222,7 @@ end
""" """
Generic plotting function for a bunch of paths. Useful for debugging. 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, labels::Union{Vector{String},Nothing}=nothing,
colors::Union{Vector{String},Nothing}=nothing, colors::Union{Vector{String},Nothing}=nothing,
markers::Bool=true, markers::Bool=true,
@@ -243,7 +243,8 @@ function plot(paths::Vector{Vector{Vector{Float64}}};
push!(traces, gen_plot(Sun)[1]...) push!(traces, gen_plot(Sun)[1]...)
# Determine layout details # Determine layout details
layout = standard_layout(limit, title) # layout = standard_layout(limit, title)
layout = standard_layout(1e9, title)
# Plot # Plot
PlotlyJS.plot( PlotlyJS.Plot( traces, layout ) ) PlotlyJS.plot( PlotlyJS.Plot( traces, layout ) )
@@ -253,19 +254,20 @@ end
function plot(m::Union{Mission, Mission_Guess}; title::String="Mision Plot") function plot(m::Union{Mission, Mission_Guess}; title::String="Mision Plot")
# First plot the earth # First plot the earth
# Then plot phase plus planet phase # Then plot phase plus planet phase
time = m.launch_date time = datetime2julian(m.launch_date)
mass = m.start_mass mass = m.start_mass
current_planet = Earth 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) start = state(current_planet, time, m.launch_v∞, mass)
traces = [ earth_trace... ] traces = [ earth_trace... ]
i = 1 i = 1
for phase in m.phases for phase in m.phases
# First do the path # 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] mass = final[7]
time += Second(floor(phase.tof)) time += phase.tof/86400
current_planet = phase.planet current_planet = phase.planet
start = state(current_planet, time, phase.v∞_out, mass) start = state(current_planet, time, phase.v∞_out, mass)
path_trace, new_limit = gen_plot(path, label="Phase "*string(i)) 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) limit = max(limit, new_limit)
# Then the planet # 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...) push!(traces, planet_trace...)
limit = max(limit, new_limit) limit = max(limit, new_limit)

View File

@@ -3,83 +3,52 @@ export prop
""" """
Maximum ΔV that a spacecraft can impulse for a given single time step 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, num_thrusters::Int,
max_thrust::Float64, max_thrust::Real,
tf::Float64, tf::Real,
t0::Float64, t0::Real)
mass::T) where T <: Real return duty_cycle*num_thrusters*max_thrust*(tf-t0)
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]
end end
""" """
The propagator function The propagator function
""" """
function prop(ΔVs::Matrix{T}, function prop(ΔVs::AbstractArray,
state::Vector{Float64}, state::AbstractArray,
craft::Sc, craft::Sc,
time::Float64, time::Real;
primary::Body=Sun; primary::Body=Sun)
interpolate::Bool=false) where T <: Real
size(ΔVs)[2] == 3 || throw(ΔVsize_Error()) size(ΔVs)[2] == 3 || throw(ΔVsize_Error(size(ΔVs)))
n = size(ΔVs)[1] n = size(ΔVs)[1]
output = Array{Real,2}(undef,n,7)
states = [ Vector{T}(),Vector{T}(),Vector{T}(),Vector{T}(),Vector{T}(),Vector{T}(),Vector{T}() ] current = copy(state)
full_thrust = max_ΔV(craft.duty_cycle, craft.num_thrusters, craft.max_thrust, time/n, 0.)
for i in 1:7 push!(states[i], state[i]) end
for i in 1:n for i in 1:n
if interpolate halfway = laguerre_conway(current[1:6], time/(2n), primary)
interpolated_state = copy(state) if time > 0
for j in 1:49 halfway += [zeros(3); full_thrust * ΔVs[i,:]] / current[7]
interpolated_state = [laguerre_conway(interpolated_state, time/50n, primary); 0.0] current[7] -= mfr(craft) * norm(ΔVs[i,:]) * time/n
for k in 1:7 push!(states[k], interpolated_state[k]) end
end
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 else
rethrow() current[7] -= mfr(craft) * norm(ΔVs[i,:]) * time/n
halfway += [zeros(3); full_thrust * ΔVs[i,:]] / current[7]
end end
end current[1:6] = laguerre_conway(halfway, time/(2n), primary)
for j in 1:7 push!(states[j], state[j]) end output[i,:] = current
end 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 end
""" """
Convenience function for propagating a state with no thrust 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 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) final = zeros(7)
for phase in m.phases 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] mass = final[7]
current_planet = phase.planet current_planet = phase.planet
time += Second(floor(phase.tof)) time += Second(floor(phase.tof))

View File

@@ -7,23 +7,23 @@ Spacecraft: bepi
num_thrusters: 2 num_thrusters: 2
duty_cycle: 0.9 duty_cycle: 0.9
Launch Mass: 3600.0 kg Launch Mass: 3600.0 kg
Launch Date: 2021-10-31T23:59:59.769 Launch Date: 2021-10-31T22:00:16.400
Launch V∞: [1.0462564431708832, -2.520754077506101, -2.301043507881933] km/s Launch V∞: [1.0097399011270518, -2.6447886914618515, -2.5394649406128433] km/s
Phase 1: Phase 1:
Planet: Venus Planet: Venus
V∞_in: [0.4205842845952983, -3.5241183574614556, 4.879873784266574] km/s V∞_in: [0.6971321781569763, -3.000415336232889, 5.257930893162622] km/s
V∞_out: [2.657685712690303, -4.920354075306563, 2.266369032728228] km/s V∞_out: [3.155471614002537, -4.846243818499916, 1.9261368837603878] km/s
time of flight: 1.2614399691127092e7 seconds time of flight: 1.261440000905646e7 seconds
arrival date: 2022-03-26T23:59:58.769 arrival date: 2022-03-26T22:00:16.400
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] % 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: Phase 2:
Planet: Mars Planet: Mars
V∞_in: [3.866657617879469, -3.8561104436565112, -1.1528388074396114] km/s V∞_in: [3.934071361708631, -4.0556866988998195, -0.9569218994864468] km/s
V∞_out: [-0.04156826938628659, 0.04537147320396694, 0.010962101613372877] km/s V∞_out: [2.835079207012675, -3.038506396757051, -0.8239067509398897] km/s
time of flight: 1.3305600070108933e7 seconds time of flight: 1.3305600002135515e7 seconds
arrival date: 2022-08-27T23:59:58.769 arrival date: 2022-08-27T22:00:16.400
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] % 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 Mass Used: 61.61570260672124 kg
Launch C3: 12.743654889305812 km²/s² Launch C3: 14.463364075014354 km²/s²
||V∞_in||: 5.58118860132149 km/s ||V∞_in||: 5.730725224643533 km/s

View File

@@ -4,72 +4,37 @@
println("Testing NLP solver") println("Testing NLP solver")
# Test the optimizer for a one-phase mission # This will be the only test to verify rather than testing different complexities
# The lambert's solver said this should be pretty valid n = 50
launch_window = DateTime(1992,11,1), DateTime(1992,12,1) flybys = [Earth, Venus, Mars]#, Jupiter]
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]
launch_window = DateTime(2021,10,1), DateTime(2021,12,1) launch_window = DateTime(2021,10,1), DateTime(2021,12,1)
latest_arrival = DateTime(2023,1,1) latest_arrival = DateTime(2028,1,1)
dates = [DateTime(2021,11,1), DateTime(2022,3,27), DateTime(2022,8,28)] dates = [DateTime(2021,11,1),
DateTime(2022,3,27),
DateTime(2022,8,28)]
# DateTime(2028,3,1)]
phases = Vector{Phase}() phases = Vector{Phase}()
launch_v∞, _, tof1 = Thesis.lamberts(flybys[1], flybys[2], dates[1], dates[2]) launch_v∞, _, tof1 = Thesis.lamberts(flybys[1], flybys[2], dates[1], dates[2])
for i in 1:length(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∞_in1, tof1 = Thesis.lamberts(flybys[i], flybys[i+1], dates[i], dates[i+1])[2:3]
v∞_out2, v∞_in2, tof2 = Thesis.lamberts(flybys[i+1], flybys[i+2], dates[i+1], dates[i+2]) 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(20,3))) push!(phases, Phase(flybys[i+1], v∞_in1, v∞_out2, tof1, 0.01*ones(50,3)))
end end
v∞_out, v∞_in, tof = Thesis.lamberts(flybys[end-1], flybys[end], dates[end-1], dates[end]) 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(20,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) 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 @test typeof(m) == Mission
if typeof(m) == Mission
p = plot(m, title="NLP Test Solution (2 Phases)") p = plot(m, title="NLP Test Solution (2 Phases)")
savefig(p,"../plots/nlp_test_2_phase.html") savefig(p,"../plots/nlp_test_2_phase.html")
store(m, "missions/nlp_2_phase") store(m, "missions/nlp_2_phase")
end
# 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")
end end

View File

@@ -1,21 +1,27 @@
@testset "Propagator" begin @testset "Propagator" begin
println("Testing propagator") using PlotlyJS: savefig
using Thesis: prop_one println("Testing Propagator")
# Set up # Set up
start_mass = 10_000. start_mass = 10_000.
start = gen_orbit(rand(.5year : hour : 2year), start_mass) 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 # Test that Propagation works
state = prop_one([0., 0., 0.], start, no_thrust, stepsize) states = prop(zeros(n,3), start, no_thrust, time)
@test laguerre_conway(start, stepsize) state[1:6] @test states[1,:] != states[end,:]
@test state[7] == start_mass
# Test that mass is reduced properly # Test that mass is reduced properly
state = prop_one([1., 0., 0.], start, bepi, stepsize) states = prop(ones(n,3)/3, start, bepi, time)
@test state[7] == start_mass - mfr(bepi)*stepsize @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 end

View File

@@ -3,7 +3,7 @@ using Random
using LinearAlgebra using LinearAlgebra
using SPICE using SPICE
using Thesis using Thesis
using Dates: DateTime, Millisecond, Dates, Second, format, datetime2unix, unix2datetime using Dates: DateTime, Millisecond, Dates, Second, format, datetime2julian, julian2datetime
try try
furnsh("../../spice_files/naif0012.tls") furnsh("../../spice_files/naif0012.tls")
@@ -14,10 +14,10 @@ catch
end end
@testset "All Tests" begin @testset "All Tests" begin
include("plotting.jl") # include("plotting.jl")
include("laguerre-conway.jl") # include("laguerre-conway.jl")
include("propagator.jl") include("propagator.jl")
include("nlp_solver.jl") # include("nlp_solver.jl")
include("mbh.jl") # include("mbh.jl")
include("genetic_algorithm.jl") # include("genetic_algorithm.jl")
end end