5.6 KiB
Technical Plan
Notes
- Each of these steps will be completed first in Julia, as I can use that to get to a working point really quickly. Then, I'll redo the efforts in Rust inside of docker containers, providing increased robustness and speed. I'll provide expected time for completion after each item in the form (x/y) where x is the number of hours I expect to take to write the Julia code and y is the number of hours I expect to take to write the Rust code.
Stages of Development
- First I need to set up the inner loop. The inner loop is a Sims-Flanagan transcription single-shooting algorithm, optimized using monotonic basin-hopping. a. I've constructed single-shooting algorithms before, and the Sims-Flanagan transcription is just a really simple notation for approximating low-thrust arcs. So first I'll need to set up a very simple Sims-Flanagan single shooter. I don't expect this to take long. I will write a simple single-shooting algorithm that takes in a start and end state (for now... in stage 2b below I'll update this to only need the J200 time (for ephemeris lookup) and the velocity) and solves Kepler's equation to satisfy the continuity condition. For the rust code, this will require some considerable initial setup of the docker containers and such, though. (6/20) b. Next I'll need to set up the monotonic basin-hopping algorithm. I've written similar optimization algorithms in my spacecraft trajectory optimization course, but none that use basin-hopping. However, it's more or less just a genetic algorithm, so it should be simple to set up in a very general way. The function I'm optimizing can be seen as a system of inputs (initial and final states) and outputs (mass used, or some other more complicated measure of optimality), so I can follow many very descriptive accounts online of this type of genetic algorithm. (12/18)
- Then I'll need to set up the outer loop. This will require optimizing over inputs (selection of flybys) by calling the inner loop to optimize each leg and summing these by way of some cost function. These flyby selections will be optimized using the genetic algorithm described in the first Englander paper. a. First I'll set up a very simple version of the outer loop, that doesn't optimize anything. It will take in a selection of flybys and simply call the inner loop for each of the flybys, outputting some cost function. This shouldn't take long, but at this point I'm adding time because the inner loop may take some time to call (8/12). b. There are also some other inputs to this algorithm, that won't change from problem to problem, but will take some effort to calculate. These include initial launch C3, ephemeris, problem constraints, etc. SPICE and basic modeling can be used for most of this, but I should include some time for incorporating SPICE via C-bindings, which should be relatively easy in both Julia and Rust (in fact, a wrapper exists at least in Julia already). As a less high fidelity backup, I've also modeled ephemeris by polynomials before, so I can do that again, if I find incorporating SPICE is taking too long (16/16) c. Next, I'll write the genetic algorithm in a very general way, as before. This is a different GA (a Binary Genetic Algorithm, suited for discrete problems), but the algorithm is described in-depth in the first Englander paper and I also can refer to the source code from the second Englander paper. In the first paper, he mentions that he used Matlab's implementation. It seems Julia also has an implementation, so this should be simple in Julia, but I will include significant extra time in Rust, in case that is more difficult (6/32) d. From there, calling my outer-loop implementation from the GA should be simple. However, I will include extra time for the rust implementation, because I will also have to consider spinning up extra kubernetes instances for each inner and outer loop. (6/32)
- From here, the work is more or less done. There will be some finalizing to do, including setting up the Kubernetes cluster for the Rust implementation. I've not set up a Kubernetes cluster before, but I have set up docker-compose setups for Rust code, so I would anticipate an extra 10 hours being needed for transitioning that. I will also have to provide a sort of wrapper function that parses the inputs and spins up/calls each lower loop of this optimizer. That should be really simple, but I'm including some slop time in this category to account for administrative issues, particularly in setting up the deployment of the cluster (12/32)
Summary
So, in total, that comes out to 66 hours of coding for the initial Julia implementation and then another 162 hours for the re-implementation in Rust using docker + kubernetes and the deployment of the cluster. At a rate of 20 hours/week, which seems reasonable, as I will have my job to account for, but I am finished with classes, that comes out to roughly 3.5 weeks to finish the first implementation and then 8 weeks to finalize. I think, if anything, that's very conservative, particularly on the Rust side, as I've got a decent amount of experience in web-based deployment, so I shouldn't have as much trouble with Kubernetes and Docker as I've outlined. But it's also worth noting that the Julia implementation is probably perfectly proficient for a Master's Thesis. If the Rust work is too much, then I can write the thesis on the Julia implementation.