├── .devcontainer ├── devcontainer.json └── startup.sh ├── .gitignore ├── LICENSE ├── README.md ├── ksp_landing.py ├── media ├── badge.png └── hello_world.png ├── notebooks ├── DCP_analysis.ipynb ├── DCP_analysis_solution.ipynb ├── DPP.ipynb ├── DPP_solution.ipynb ├── solving_the_problem.ipynb └── solving_the_problem_solution.ipynb ├── requirements.txt ├── setup.cfg ├── slides ├── advanced.pdf ├── conclusion.pdf ├── cvxpy_intro.pdf ├── intro.pdf ├── landing_problem.pdf └── mission.pdf └── src └── optimization.py /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | // For format details, see https://aka.ms/devcontainer.json. For config options, see the 2 | // README at: https://github.com/devcontainers/templates/tree/main/src/python 3 | { 4 | "name": "Python 3", 5 | "image": "mcr.microsoft.com/devcontainers/python:1-3.10-bookworm", 6 | "onCreateCommand": ".devcontainer/startup.sh", 7 | "customizations": { 8 | "vscode": { 9 | "extensions": [ 10 | "ms-toolsai.jupyter" 11 | ] 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /.devcontainer/startup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | pip install -e . -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | .idea 6 | 7 | # C extensions 8 | *.so 9 | 10 | # Distribution / packaging 11 | .Python 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | wheels/ 24 | share/python-wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .nox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | *.py,cover 51 | .hypothesis/ 52 | .pytest_cache/ 53 | cover/ 54 | 55 | # Translations 56 | *.mo 57 | *.pot 58 | 59 | # Django stuff: 60 | *.log 61 | local_settings.py 62 | db.sqlite3 63 | db.sqlite3-journal 64 | 65 | # Flask stuff: 66 | instance/ 67 | .webassets-cache 68 | 69 | # Scrapy stuff: 70 | .scrapy 71 | 72 | # Sphinx documentation 73 | docs/_build/ 74 | 75 | # PyBuilder 76 | .pybuilder/ 77 | target/ 78 | 79 | # Jupyter Notebook 80 | .ipynb_checkpoints 81 | 82 | # IPython 83 | profile_default/ 84 | ipython_config.py 85 | 86 | # pyenv 87 | # For a library or package, you might want to ignore these files since the code is 88 | # intended to run in multiple environments; otherwise, check them in: 89 | # .python-version 90 | 91 | # pipenv 92 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 93 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 94 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 95 | # install all needed dependencies. 96 | #Pipfile.lock 97 | 98 | # poetry 99 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 100 | # This is especially recommended for binary packages to ensure reproducibility, and is more 101 | # commonly ignored for libraries. 102 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 103 | #poetry.lock 104 | 105 | # pdm 106 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. 107 | #pdm.lock 108 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it 109 | # in version control. 110 | # https://pdm.fming.dev/#use-with-ide 111 | .pdm.toml 112 | 113 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm 114 | __pypackages__/ 115 | 116 | # Celery stuff 117 | celerybeat-schedule 118 | celerybeat.pid 119 | 120 | # SageMath parsed files 121 | *.sage.py 122 | 123 | # Environments 124 | .env 125 | .venv 126 | env/ 127 | venv/ 128 | ENV/ 129 | env.bak/ 130 | venv.bak/ 131 | 132 | # Spyder project settings 133 | .spyderproject 134 | .spyproject 135 | 136 | # Rope project settings 137 | .ropeproject 138 | 139 | # mkdocs documentation 140 | /site 141 | 142 | # mypy 143 | .mypy_cache/ 144 | .dmypy.json 145 | dmypy.json 146 | 147 | # Pyre type checker 148 | .pyre/ 149 | 150 | # pytype static type analyzer 151 | .pytype/ 152 | 153 | # Cython debug symbols 154 | cython_debug/ 155 | 156 | # PyCharm 157 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can 158 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 159 | # and can be added to the global gitignore or merged into this file. For a more nuclear 160 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 161 | #.idea/ 162 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright 2023, The CVXPY authors 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Controlling Self-Landing Rockets Using CVXPY 2 | 3 | This repository contains the installation instructions for a tutorial at SciPy 2023 in Austin, TX. The tutorial will be held on July 10, 2023. 4 | We will provide additional materials here before the tutorial. 5 | 6 | We're excited to see you there and hope you enjoy the tutorial! 7 | The CVXPY Team 8 | 9 |

10 | “Badge” 11 |

12 | 13 | 14 | ## Installation 15 | To follow along with the tutorial, you will need to install the following packages, ideally in a fresh virtual environment: 16 | ``` 17 | cvxpy 18 | scipy 19 | matplotlib 20 | ``` 21 | CVXPY currently supports Python 3.7-3.11. We are using Python 3.8 for this tutorial, but any of these versions should work. 22 | 23 |
24 | Verify installation 25 | 26 | To verify your installation, run the following commands in a Python interpreter: 27 | ```py 28 | import cvxpy as cp 29 | import matplotlib.pyplot as plt 30 | import numpy as np 31 | 32 | # Minimize sum of coordinates subject to the unit circle constraint. 33 | x = cp.Variable(2) 34 | constraints = [cp.norm(x, 2) <= 1] 35 | obj = cp.Minimize(cp.sum(x)) 36 | prob = cp.Problem(obj, constraints) 37 | prob.solve() 38 | print("status:", prob.status) 39 | print("optimal value", prob.value) 40 | print("optimal var", x.value) 41 | 42 | # Plot the solution. 43 | fig, ax = plt.subplots(figsize=(4, 4)) 44 | circ = plt.Circle((0, 0), radius=1, edgecolor='b', facecolor='None') 45 | ax.add_patch(circ) 46 | plt.arrow(0, 0, -np.sqrt(.5) + .1, -np.sqrt(.5) + .1, head_width=0.05, head_length=0.1) 47 | plt.scatter(x.value[0], x.value[1]) 48 | plt.show() 49 | ``` 50 | This should produce the following output: 51 | 52 |

53 | “Hello 54 |

55 |
56 | 57 | ### Binder and Codespace 58 | You can also run the notebooks on binder or in a codespace 59 | [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/cvxpy/cvxkerb/HEAD) 60 | [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/cvxgrp/cvxmarkowitz) 61 | 62 | ### Optional: KSP 63 | If you have the Kerbal Space Program installed, you can optionally install kRPC. 64 | This will allow you to run the code in the `ksp_landing.py` file (will be provided during the tutorial), which uses CVXPY to control a rocket in KSP. 65 | To use kRPC, you need the client as well as the server. 66 | The client can be installed via pip 67 | ``` 68 | pip install krpc==0.5.3 69 | ``` 70 | 71 | For the server, you can choose from the installation options provided in the [kRPC documentation](https://krpc.github.io/krpc/getting-started.html). 72 | In our case, we downloaded the prebuilt binaries from the [GitHub release](https://github.com/krpc/krpc/releases/tag/v0.5.2) and extracted them to the KSP `GameData` directory. 73 | Note: Use the exact linked release for `v.0.5.2` (even though the pip install is `0.5.3`), as the `0.5.3` release does not contain the server build. 74 | We are using KSP 1.12.5 for this tutorial. 75 | 76 | ## Tutorial outline 77 | ### [Introduction](https://github.com/cvxpy/cvxkerb/blob/main/slides/intro.pdf) [30 min] 78 | 79 | - Explanation of the tutorial's purpose and goals 80 | - Explanation of the importance of self-landing rockets 81 | - A brief overview of CVXPY 82 | 83 | ### [Getting started with CVXPY](https://github.com/cvxpy/cvxkerb/blob/main/slides/cvxpy_intro.pdf) [30 min] 84 | 85 | - A single rule for composing convex functions 86 | - The working principles of CVXPY 87 | - Creating a simple optimization problems 88 | 89 | ### [Formulating the rocket landing problem](https://github.com/cvxpy/cvxkerb/blob/main/slides/landing_problem.pdf) [60 min] 90 | 91 | - Identifying the problem's parameters 92 | - Developing the objective function and constraints 93 | - Specifying the optimization problem in CVXPY 94 | 95 | ### [Solving the problem](https://github.com/cvxpy/cvxkerb/blob/main/notebooks/solving_the_problem_solution.ipynb) [15 min] 96 | 97 | - Using CVXPY to solve the optimization problem 98 | - Interpreting the results 99 | 100 | ### [The mission](https://github.com/cvxpy/cvxkerb/blob/main/slides/mission.pdf) [60 min] 101 | 102 | - Introduction to the Kerbal Space Program and kRPC 103 | - Using CVXPY to control a rocket in KSP 104 | - Launch the rocket and land back on the launchpad 105 | 106 | ### [Advanced features of CVXPY](https://github.com/cvxpy/cvxkerb/blob/main/slides/advanced.pdf) [30 min] 107 | 108 | - Performance improvements via parameters (DPP) 109 | - Using CVXPYgen for implementations in embedded systems 110 | - Fastest descent via quasiconvex optimization (DQCP) 111 | 112 | ### [Conclusion](https://github.com/cvxpy/cvxkerb/blob/main/slides/conclusion.pdf) [15 min] 113 | 114 | - Recap of the tutorial's content and the importance of convex optimization and CVXPY in solving real-world problems 115 | -------------------------------------------------------------------------------- /ksp_landing.py: -------------------------------------------------------------------------------- 1 | import time 2 | 3 | import cvxpy as cp 4 | import krpc 5 | import numpy as np 6 | from krpc.services.spacecenter import ReferenceFrame, Vessel 7 | from scipy.spatial.transform import Rotation as R 8 | 9 | from src.optimization import optimize_fuel 10 | 11 | landing_platform = np.array([159780.5, -1018.1, -578410.4]) 12 | origin = np.array([-0.0021359772614235606, -0.004701372718752435, 0.152749662369653]) 13 | 14 | 15 | def run() -> None: 16 | """ 17 | The main function containing the MPC loop 18 | """ 19 | 20 | conn = krpc.connect(name="Landing") 21 | vessel = conn.space_center.active_vessel 22 | print(f"the vessel's name is: {vessel.name}") 23 | 24 | ref_frame = get_reference_frame(conn, vessel) 25 | 26 | position = conn.add_stream(vessel.position, ref_frame) 27 | velocity = conn.add_stream(vessel.velocity, ref_frame) 28 | 29 | relative_frame = ref_frame.create_relative( 30 | ref_frame, rotation=R.from_euler("yz", [-90, -90], degrees=True).as_quat() 31 | ) 32 | vessel.auto_pilot.reference_frame = relative_frame 33 | vessel.auto_pilot.target_pitch_and_heading(60, 0) 34 | 35 | launch_rocket(vessel) 36 | 37 | while True: 38 | 39 | time.sleep(0.1) 40 | 41 | p = np.array(position()) 42 | v = np.array(velocity()) 43 | max_thrust = vessel.max_thrust 44 | 45 | if vessel.situation.name == "landed": 46 | vessel.control.throttle = 0 47 | break 48 | 49 | # Update the glide angle 50 | alpha = np.arctan(p[2] * 1.05 / np.linalg.norm(p[:2])) 51 | 52 | try: 53 | P, F, _, _ = optimize_fuel( 54 | origin, 55 | 9.81, 56 | vessel.mass, 57 | p, 58 | v, 59 | 100, 60 | 1, 61 | max_thrust, 62 | alpha, 63 | 1, 64 | ) 65 | except (cp.SolverError, AssertionError) as e: 66 | print(e) 67 | if v[2] > 0: 68 | vessel.control.throttle = 0 69 | continue 70 | 71 | if F is None: 72 | print("no solution found") 73 | vessel.control.throttle = 0 74 | continue 75 | else: 76 | target_F = F[0] 77 | thrust_level = np.linalg.norm(target_F) / max_thrust 78 | 79 | direction = target_F / np.linalg.norm(target_F) 80 | xy_len = np.linalg.norm(direction[[0, 1]]) 81 | 82 | # pitch between -90 and 90 83 | target_pitch = np.arctan2(direction[2], xy_len) * 180 / np.pi 84 | 85 | # heading between 0 and 360 86 | target_heading = (np.arctan2(direction[1], direction[0]) * 180 / np.pi) % 360 87 | 88 | vessel.auto_pilot.target_pitch_and_heading(target_pitch, target_heading) 89 | vessel.auto_pilot.engage() 90 | 91 | if thrust_level < 0.01: 92 | thrust_level = 0 93 | vessel.control.throttle = thrust_level 94 | 95 | conn.drawing.clear() 96 | draw_trajectory(conn, P, ref_frame) 97 | draw_F(conn, target_F, ref_frame, vessel.reference_frame) 98 | draw_autopilot_direction( 99 | conn, vessel.auto_pilot.target_direction, relative_frame, vessel.reference_frame 100 | ) 101 | 102 | print("thrust: ", round(thrust_level, 2)) 103 | 104 | conn.close() 105 | 106 | 107 | def draw_trajectory(conn: krpc.Client, P: np.ndarray, ref_frame: ReferenceFrame) -> None: 108 | """ 109 | Draw the next 10 points of the trajectory 110 | """ 111 | for i in range(1, P.shape[0]): 112 | p = P[i] 113 | p0 = P[i - 1] 114 | conn.drawing.add_line(p0, p, ref_frame) 115 | if i > 10: 116 | break 117 | 118 | 119 | def draw_F( 120 | conn: krpc.Client, 121 | target_F: np.ndarray, 122 | ref_frame: ReferenceFrame, 123 | vessel_ref_frame: ReferenceFrame, 124 | ) -> None: 125 | """ 126 | Draw the target force vector in blue 127 | """ 128 | transformed_F = conn.space_center.transform_direction(target_F, ref_frame, vessel_ref_frame) 129 | line = conn.drawing.add_line([0, 0, 0], transformed_F, vessel_ref_frame) 130 | line.color = (0, 0, 1) 131 | 132 | 133 | def draw_autopilot_direction( 134 | conn: krpc.Client, 135 | direction: np.ndarray, 136 | ref_frame: ReferenceFrame, 137 | vessel_ref_frame: ReferenceFrame, 138 | ) -> None: 139 | """ 140 | Draw the autopilot direction in red 141 | """ 142 | transformed_direction = conn.space_center.transform_direction( 143 | direction, ref_frame, vessel_ref_frame 144 | ) 145 | line = conn.drawing.add_line([0, 0, 0], np.array(transformed_direction) * 100, vessel_ref_frame) 146 | line.color = (1, 0, 0) 147 | 148 | 149 | def draw_coordinate_system(conn: krpc.Client, ref_frame: ReferenceFrame) -> None: 150 | """ 151 | Draw the coordinate system of the reference frame 152 | """ 153 | line = conn.drawing.add_line([0, 0, 0], [10, 0, 0], ref_frame) 154 | line.color = (1, 0, 0) 155 | line = conn.drawing.add_line([0, 0, 0], [0, 10, 0], ref_frame) 156 | line.color = (0, 1, 0) 157 | line = conn.drawing.add_line([0, 0, 0], [0, 0, 10], ref_frame) 158 | line.color = (0, 0, 1) 159 | 160 | 161 | def launch_rocket(vessel: Vessel) -> None: 162 | """ 163 | Launch the rocket on a hard-coded trajectory 164 | """ 165 | vessel.auto_pilot.engage() 166 | vessel.control.throttle = 1 167 | vessel.control.activate_next_stage() 168 | time.sleep(2) 169 | vessel.auto_pilot.target_pitch_and_heading(60, 180) 170 | time.sleep(6) 171 | vessel.control.throttle = 0 172 | 173 | 174 | def get_reference_frame(conn: krpc.Client, vessel: Vessel) -> ReferenceFrame: 175 | """ 176 | Get the reference frame of the landing platform 177 | """ 178 | 179 | z = landing_platform 180 | z = z / np.linalg.norm(z) 181 | x = np.array([1, 0, 0]) 182 | y = np.cross(z, x) 183 | y = y / np.linalg.norm(y) 184 | x = np.cross(y, z) 185 | x = x / np.linalg.norm(x) 186 | q = R.from_matrix(np.array([x, y, z]).T).as_quat() 187 | ref_frame = conn.space_center.ReferenceFrame.create_relative( 188 | vessel.orbit.body.reference_frame, position=landing_platform, rotation=q 189 | ) 190 | return ref_frame 191 | 192 | 193 | if __name__ == "__main__": 194 | run() 195 | -------------------------------------------------------------------------------- /media/badge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvxpy/cvxkerb/2878078698a876d7c2b1f7cf9491d7c251a8a519/media/badge.png -------------------------------------------------------------------------------- /media/hello_world.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvxpy/cvxkerb/2878078698a876d7c2b1f7cf9491d7c251a8a519/media/hello_world.png -------------------------------------------------------------------------------- /notebooks/DCP_analysis.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "attachments": {}, 5 | "cell_type": "markdown", 6 | "metadata": {}, 7 | "source": [ 8 | "# Hello, world!\n", 9 | "\n", 10 | "Solve the following optimization problem using CVXPY:\n", 11 | "\n", 12 | "\\begin{array}{ll} \\mbox{minimize} & |x| - 2\\sqrt{y}\\\\\n", 13 | "\\mbox{subject to} & 2 \\geq e^x \\\\\n", 14 | "& x + y = 5,\n", 15 | "\\end{array}\n", 16 | "\n", 17 | "where $x,y \\in \\mathbf{R}$ are variables.\n", 18 | "\n", 19 | "Find the optimal values of $x$ and $y$." 20 | ] 21 | }, 22 | { 23 | "cell_type": "code", 24 | "execution_count": null, 25 | "metadata": { 26 | "collapsed": true 27 | }, 28 | "outputs": [], 29 | "source": [ 30 | "import cvxpy as cp\n", 31 | "\n", 32 | "# Define our variables.\n", 33 | "x = cp.Variable()\n", 34 | "y = cp.Variable()\n", 35 | "\n", 36 | "# NOTE: Form expressions using NumPy syntax.\n", 37 | "# For example, |x| = cp.abs(x)\n", 38 | "\n", 39 | "# TODO: Form the objective.\n", 40 | "objective = ...\n", 41 | "\n", 42 | "# TODO: Form the constraints list.\n", 43 | "constraints = [...]\n", 44 | "\n", 45 | "prob = cp.Problem(objective, constraints)\n", 46 | "opt_val = prob.solve()\n", 47 | "\n", 48 | "print(\"Optimal value:\", opt_val)\n", 49 | "print(\"Optimal x:\", x.value)\n", 50 | "print(\"Optimal y:\", y.value)" 51 | ] 52 | }, 53 | { 54 | "attachments": {}, 55 | "cell_type": "markdown", 56 | "metadata": {}, 57 | "source": [ 58 | "# DCP analysis" 59 | ] 60 | }, 61 | { 62 | "attachments": {}, 63 | "cell_type": "markdown", 64 | "metadata": {}, 65 | "source": [ 66 | "### Problem 1\n", 67 | "\n", 68 | "Write the function \n", 69 | "$$\n", 70 | " f(x) = \\sum_{i=1}^n e^{(a_i^Tx+b_i)_+}\n", 71 | "$$\n", 72 | "in CVXPY and show that it is convex." 73 | ] 74 | }, 75 | { 76 | "cell_type": "code", 77 | "execution_count": null, 78 | "metadata": { 79 | "is_executing": true 80 | }, 81 | "outputs": [], 82 | "source": [ 83 | "# Problem 1 code.\n", 84 | "import cvxpy as cp\n", 85 | "import numpy as np\n", 86 | "\n", 87 | "n = 2\n", 88 | "m = 5\n", 89 | "np.random.seed()\n", 90 | "x = cp.Variable(m)\n", 91 | "a_1 = np.random.randn(m)\n", 92 | "b_1 = np.random.rand()\n", 93 | "a_2 = np.random.randn(m)\n", 94 | "b_2 = np.random.rand()\n", 95 | "\n", 96 | "# TODO define f and show that it is convex.\n", 97 | "f = ...\n", 98 | "assert f.is_convex()" 99 | ] 100 | }, 101 | { 102 | "attachments": {}, 103 | "cell_type": "markdown", 104 | "metadata": {}, 105 | "source": [ 106 | "### Problem 2\n", 107 | "\n", 108 | "Now write the function\n", 109 | "$$\n", 110 | "g(x) = \\sqrt{x^2 + 1}\n", 111 | "$$\n", 112 | "in a way that CVXPY recognizes as convex." 113 | ] 114 | }, 115 | { 116 | "cell_type": "code", 117 | "execution_count": null, 118 | "metadata": { 119 | "is_executing": true 120 | }, 121 | "outputs": [], 122 | "source": [ 123 | "# Problem 2 code.\n", 124 | "import cvxpy as cp\n", 125 | "\n", 126 | "x = cp.Variable()\n", 127 | "\n", 128 | "# TODO define g in a way that CVXPY recognizes as convex.\n", 129 | "g = ...\n", 130 | "assert g.is_convex()" 131 | ] 132 | } 133 | ], 134 | "metadata": { 135 | "kernelspec": { 136 | "display_name": "Python 3", 137 | "language": "python", 138 | "name": "python3" 139 | }, 140 | "language_info": { 141 | "codemirror_mode": { 142 | "name": "ipython", 143 | "version": 3 144 | }, 145 | "file_extension": ".py", 146 | "mimetype": "text/x-python", 147 | "name": "python", 148 | "nbconvert_exporter": "python", 149 | "pygments_lexer": "ipython3", 150 | "version": "3.7.0" 151 | } 152 | }, 153 | "nbformat": 4, 154 | "nbformat_minor": 1 155 | } 156 | -------------------------------------------------------------------------------- /notebooks/DCP_analysis_solution.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "attachments": {}, 5 | "cell_type": "markdown", 6 | "metadata": {}, 7 | "source": [ 8 | "# Hello, world!\n", 9 | "\n", 10 | "Solve the following optimization problem using CVXPY:\n", 11 | "\n", 12 | "\\begin{array}{ll} \\mbox{minimize} & |x| - 2\\sqrt{y}\\\\\n", 13 | "\\mbox{subject to} & 2 \\geq e^x \\\\\n", 14 | "& x + y = 5,\n", 15 | "\\end{array}\n", 16 | "\n", 17 | "where $x,y \\in \\mathbf{R}$ are variables.\n", 18 | "\n", 19 | "Find the optimal values of $x$ and $y$." 20 | ] 21 | }, 22 | { 23 | "cell_type": "code", 24 | "execution_count": 1, 25 | "metadata": { 26 | "collapsed": true, 27 | "ExecuteTime": { 28 | "end_time": "2023-07-14T16:39:28.339633263Z", 29 | "start_time": "2023-07-14T16:39:27.979947146Z" 30 | } 31 | }, 32 | "outputs": [ 33 | { 34 | "name": "stdout", 35 | "output_type": "stream", 36 | "text": [ 37 | "Optimal value: -4.472135941007283\n", 38 | "Optimal x: 9.668438494259135e-09\n", 39 | "Optimal y: 4.9999999903315615\n" 40 | ] 41 | } 42 | ], 43 | "source": [ 44 | "import cvxpy as cp\n", 45 | "\n", 46 | "# Define our variables.\n", 47 | "x = cp.Variable()\n", 48 | "y = cp.Variable()\n", 49 | "\n", 50 | "# NOTE: Form expressions using NumPy syntax.\n", 51 | "# For example, |x| = cp.abs(x)\n", 52 | "\n", 53 | "# TODO: Form the objective.\n", 54 | "objective = cp.abs(x) - 2 * cp.sqrt(y)\n", 55 | "\n", 56 | "# TODO: Form the constraints list.\n", 57 | "constraints = [2 >= cp.exp(x), x + y == 5]\n", 58 | "\n", 59 | "prob = cp.Problem(cp.Minimize(objective), constraints)\n", 60 | "opt_val = prob.solve()\n", 61 | "\n", 62 | "print(\"Optimal value:\", opt_val)\n", 63 | "print(\"Optimal x:\", x.value)\n", 64 | "print(\"Optimal y:\", y.value)" 65 | ] 66 | }, 67 | { 68 | "attachments": {}, 69 | "cell_type": "markdown", 70 | "metadata": {}, 71 | "source": [ 72 | "# DCP analysis" 73 | ] 74 | }, 75 | { 76 | "attachments": {}, 77 | "cell_type": "markdown", 78 | "metadata": {}, 79 | "source": [ 80 | "### Problem 1\n", 81 | "\n", 82 | "Write the function \n", 83 | "$$\n", 84 | " f(x) = \\sum_{i=1}^n e^{(a_i^Tx+b_i)_+}\n", 85 | "$$\n", 86 | "in CVXPY and show that it is convex." 87 | ] 88 | }, 89 | { 90 | "cell_type": "code", 91 | "execution_count": 2, 92 | "metadata": { 93 | "ExecuteTime": { 94 | "end_time": "2023-07-14T16:39:28.348927173Z", 95 | "start_time": "2023-07-14T16:39:28.340852893Z" 96 | } 97 | }, 98 | "outputs": [], 99 | "source": [ 100 | "# Problem 1 code.\n", 101 | "import cvxpy as cp\n", 102 | "import numpy as np\n", 103 | "\n", 104 | "n = 2\n", 105 | "m = 5\n", 106 | "np.random.seed()\n", 107 | "x = cp.Variable(m)\n", 108 | "a_1 = np.random.randn(m)\n", 109 | "b_1 = np.random.rand()\n", 110 | "a_2 = np.random.randn(m)\n", 111 | "b_2 = np.random.rand()\n", 112 | "\n", 113 | "# TODO define f and show that it is convex.\n", 114 | "f = cp.exp(cp.pos(a_1 @ x + b_1)) + cp.exp(cp.pos(a_2 @ x + b_2))\n", 115 | "assert f.is_convex()" 116 | ] 117 | }, 118 | { 119 | "attachments": {}, 120 | "cell_type": "markdown", 121 | "metadata": {}, 122 | "source": [ 123 | "### Problem 2\n", 124 | "\n", 125 | "Now write the function\n", 126 | "$$\n", 127 | "g(x) = \\sqrt{x^2 + 1}\n", 128 | "$$\n", 129 | "in a way that CVXPY recognizes as convex." 130 | ] 131 | }, 132 | { 133 | "cell_type": "code", 134 | "execution_count": 3, 135 | "metadata": { 136 | "ExecuteTime": { 137 | "end_time": "2023-07-14T16:39:28.354448684Z", 138 | "start_time": "2023-07-14T16:39:28.351486055Z" 139 | } 140 | }, 141 | "outputs": [], 142 | "source": [ 143 | "# Problem 2 code.\n", 144 | "import cvxpy as cp\n", 145 | "\n", 146 | "x = cp.Variable()\n", 147 | "\n", 148 | "# TODO define g in a way that CVXPY recognizes as convex.\n", 149 | "# Note that 1^2 = 1, so we can use the norm2 function.\n", 150 | "g = cp.norm2(cp.hstack([x, 1]))\n", 151 | "assert g.is_convex()" 152 | ] 153 | } 154 | ], 155 | "metadata": { 156 | "kernelspec": { 157 | "display_name": "Python 3", 158 | "language": "python", 159 | "name": "python3" 160 | }, 161 | "language_info": { 162 | "codemirror_mode": { 163 | "name": "ipython", 164 | "version": 3 165 | }, 166 | "file_extension": ".py", 167 | "mimetype": "text/x-python", 168 | "name": "python", 169 | "nbconvert_exporter": "python", 170 | "pygments_lexer": "ipython3", 171 | "version": "3.7.0" 172 | } 173 | }, 174 | "nbformat": 4, 175 | "nbformat_minor": 1 176 | } 177 | -------------------------------------------------------------------------------- /notebooks/DPP.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": { 7 | "tags": [] 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "import time\n", 12 | "\n", 13 | "import cvxpy as cp\n", 14 | "import matplotlib.pyplot as plt\n", 15 | "import numpy as np" 16 | ] 17 | }, 18 | { 19 | "cell_type": "markdown", 20 | "metadata": {}, 21 | "source": [ 22 | "# Test data" 23 | ] 24 | }, 25 | { 26 | "cell_type": "code", 27 | "execution_count": null, 28 | "metadata": { 29 | "collapsed": false, 30 | "jupyter": { 31 | "outputs_hidden": false 32 | } 33 | }, 34 | "outputs": [], 35 | "source": [ 36 | "h = 1 # discretization step in s\n", 37 | "g = 0.1 # gravity in m/s^2\n", 38 | "m = 10.0 # mass in kg\n", 39 | "F_max = 10.0 # maximum thrust in Newton\n", 40 | "p_target = np.array([0, 0, 0]) # target position in m\n", 41 | "alpha = np.pi / 8 # glide angle in rad\n", 42 | "gamma = 1.0 # fuel consumption coefficient\n", 43 | "K = 35 # number of discretization steps" 44 | ] 45 | }, 46 | { 47 | "cell_type": "markdown", 48 | "metadata": {}, 49 | "source": [ 50 | "# Formulate the optimization problem" 51 | ] 52 | }, 53 | { 54 | "cell_type": "code", 55 | "execution_count": null, 56 | "metadata": { 57 | "collapsed": false, 58 | "jupyter": { 59 | "outputs_hidden": false 60 | } 61 | }, 62 | "outputs": [], 63 | "source": [ 64 | "def optimize_fuel(\n", 65 | " p_target: np.ndarray,\n", 66 | " g: float,\n", 67 | " m: float,\n", 68 | " K: int,\n", 69 | " h: float,\n", 70 | " F_max: float,\n", 71 | " alpha: float,\n", 72 | " gamma: float,\n", 73 | ") -> cp.Problem:\n", 74 | " \"\"\"\n", 75 | "\n", 76 | " Minimize fuel consumption for a rocket to land on a target\n", 77 | "\n", 78 | " :param p_target: landing target in m\n", 79 | " :param g: gravitational acceleration in m/s^2\n", 80 | " :param m: mass in kg\n", 81 | " :param K: Number of discretization steps\n", 82 | " :param h: discretization step in s\n", 83 | " :param F_max: maximum thrust of engine in kg*m/s^2 (Newton)\n", 84 | " :param alpha: Glide path angle in radian\n", 85 | " :param gamma: converts fuel consumption to liters of fuel consumption\n", 86 | " :return: parametrized problem\n", 87 | " \"\"\"\n", 88 | "\n", 89 | " P_min = p_target[2]\n", 90 | " p0 = ...\n", 91 | " v0 = ...\n", 92 | "\n", 93 | " # Variables\n", 94 | " V = cp.Variable((K + 1, 3)) # velocity\n", 95 | " P = cp.Variable((K + 1, 3)) # position\n", 96 | " F = cp.Variable((K, 3)) # thrust\n", 97 | "\n", 98 | " # Constraints\n", 99 | " # Match initial position and initial velocity\n", 100 | " constraints = [\n", 101 | " V[0] == v0,\n", 102 | " P[0] == p0,\n", 103 | " ]\n", 104 | "\n", 105 | " # Keep height above P_min\n", 106 | " constraints += [P[:, 2] >= P_min]\n", 107 | "\n", 108 | " # Match final position and 0 velocity\n", 109 | " constraints += [\n", 110 | " V[K] == [0, 0, 0],\n", 111 | " P[K] == p_target,\n", 112 | " ]\n", 113 | "\n", 114 | " # Physics dynamics for velocity\n", 115 | " constraints += [V[1:, :2] == V[:-1, :2] + h * (F[:, :2] / m)]\n", 116 | " constraints += [V[1:, 2] == V[:-1, 2] + h * (F[:, 2] / m - g)]\n", 117 | "\n", 118 | " # Physics dynamics for position\n", 119 | " constraints += [P[1:] == P[:-1] + (h / 2) * (V[:-1] + V[1:])]\n", 120 | "\n", 121 | " # Glide path constraint\n", 122 | " constraints += [P[:, 2] >= np.tan(alpha) * cp.norm(P[:, :2], axis=1)]\n", 123 | "\n", 124 | " # Maximum thrust constraint\n", 125 | " constraints += [cp.norm(F, 2, axis=1) <= F_max]\n", 126 | "\n", 127 | " fuel_consumption = gamma * cp.sum(cp.norm(F, axis=1))\n", 128 | "\n", 129 | " problem = cp.Problem(cp.Minimize(fuel_consumption), constraints)\n", 130 | " return problem, p0, v0" 131 | ] 132 | }, 133 | { 134 | "cell_type": "markdown", 135 | "metadata": {}, 136 | "source": [ 137 | "# Solve the problem many times" 138 | ] 139 | }, 140 | { 141 | "cell_type": "code", 142 | "execution_count": null, 143 | "metadata": { 144 | "collapsed": false, 145 | "jupyter": { 146 | "outputs_hidden": false 147 | } 148 | }, 149 | "outputs": [], 150 | "source": [ 151 | "parametrized_problem, p0, v0 = optimize_fuel(p_target, g, m, K, h, F_max, alpha, gamma)\n", 152 | "\n", 153 | "times = []\n", 154 | "for i in range(100):\n", 155 | " start = time.time()\n", 156 | " p0.value = np.array([50, 50, 100]) + np.random.random(3)\n", 157 | " v0.value = np.array([-10, 0, -10]) + np.random.random(3)\n", 158 | " parametrized_problem.solve()\n", 159 | " times.append(time.time() - start)" 160 | ] 161 | }, 162 | { 163 | "cell_type": "code", 164 | "execution_count": null, 165 | "outputs": [], 166 | "source": [ 167 | "plt.plot(times)" 168 | ], 169 | "metadata": { 170 | "collapsed": false 171 | } 172 | } 173 | ], 174 | "metadata": { 175 | "kernelspec": { 176 | "display_name": "Python 3 (ipykernel)", 177 | "language": "python", 178 | "name": "python3" 179 | }, 180 | "language_info": { 181 | "codemirror_mode": { 182 | "name": "ipython", 183 | "version": 3 184 | }, 185 | "file_extension": ".py", 186 | "mimetype": "text/x-python", 187 | "name": "python", 188 | "nbconvert_exporter": "python", 189 | "pygments_lexer": "ipython3", 190 | "version": "3.8.12" 191 | } 192 | }, 193 | "nbformat": 4, 194 | "nbformat_minor": 4 195 | } 196 | -------------------------------------------------------------------------------- /notebooks/DPP_solution.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "tags": [], 8 | "ExecuteTime": { 9 | "end_time": "2023-07-14T16:40:58.587916464Z", 10 | "start_time": "2023-07-14T16:40:57.984118339Z" 11 | } 12 | }, 13 | "outputs": [], 14 | "source": [ 15 | "import time\n", 16 | "\n", 17 | "import cvxpy as cp\n", 18 | "import matplotlib.pyplot as plt\n", 19 | "import numpy as np" 20 | ] 21 | }, 22 | { 23 | "cell_type": "markdown", 24 | "metadata": {}, 25 | "source": [ 26 | "# Test data" 27 | ] 28 | }, 29 | { 30 | "cell_type": "code", 31 | "execution_count": 2, 32 | "metadata": { 33 | "collapsed": false, 34 | "jupyter": { 35 | "outputs_hidden": false 36 | }, 37 | "ExecuteTime": { 38 | "end_time": "2023-07-14T16:40:58.594356138Z", 39 | "start_time": "2023-07-14T16:40:58.592532762Z" 40 | } 41 | }, 42 | "outputs": [], 43 | "source": [ 44 | "h = 1 # discretization step in s\n", 45 | "g = 0.1 # gravity in m/s^2\n", 46 | "m = 10.0 # mass in kg\n", 47 | "F_max = 10.0 # maximum thrust in Newton\n", 48 | "p_target = np.array([0, 0, 0]) # target position in m\n", 49 | "alpha = np.pi / 8 # glide angle in rad\n", 50 | "gamma = 1.0 # fuel consumption coefficient\n", 51 | "K = 35 # number of discretization steps" 52 | ] 53 | }, 54 | { 55 | "cell_type": "markdown", 56 | "metadata": {}, 57 | "source": [ 58 | "# Formulate the optimization problem" 59 | ] 60 | }, 61 | { 62 | "cell_type": "code", 63 | "execution_count": 3, 64 | "metadata": { 65 | "collapsed": false, 66 | "jupyter": { 67 | "outputs_hidden": false 68 | }, 69 | "ExecuteTime": { 70 | "end_time": "2023-07-14T16:40:58.604535561Z", 71 | "start_time": "2023-07-14T16:40:58.602270794Z" 72 | } 73 | }, 74 | "outputs": [], 75 | "source": [ 76 | "def optimize_fuel(\n", 77 | " p_target: np.ndarray,\n", 78 | " g: float,\n", 79 | " m: float,\n", 80 | " K: int,\n", 81 | " h: float,\n", 82 | " F_max: float,\n", 83 | " alpha: float,\n", 84 | " gamma: float,\n", 85 | ") -> cp.Problem:\n", 86 | " \"\"\"\n", 87 | "\n", 88 | " Minimize fuel consumption for a rocket to land on a target\n", 89 | "\n", 90 | " :param p_target: landing target in m\n", 91 | " :param g: gravitational acceleration in m/s^2\n", 92 | " :param m: mass in kg\n", 93 | " :param K: Number of discretization steps\n", 94 | " :param h: discretization step in s\n", 95 | " :param F_max: maximum thrust of engine in kg*m/s^2 (Newton)\n", 96 | " :param alpha: Glide path angle in radian\n", 97 | " :param gamma: converts fuel consumption to liters of fuel consumption\n", 98 | " :return: parametrized problem\n", 99 | " \"\"\"\n", 100 | "\n", 101 | " P_min = p_target[2]\n", 102 | "\n", 103 | " # Parameters are symbolic constants, i.e., we can set the values later\n", 104 | " p0 = cp.Parameter(3)\n", 105 | " v0 = cp.Parameter(3)\n", 106 | "\n", 107 | " # Variables\n", 108 | " V = cp.Variable((K + 1, 3)) # velocity\n", 109 | " P = cp.Variable((K + 1, 3)) # position\n", 110 | " F = cp.Variable((K, 3)) # thrust\n", 111 | "\n", 112 | " # Constraints\n", 113 | " # Match initial position and initial velocity\n", 114 | " constraints = [\n", 115 | " V[0] == v0,\n", 116 | " P[0] == p0,\n", 117 | " ]\n", 118 | "\n", 119 | " # Keep height above P_min\n", 120 | " constraints += [P[:, 2] >= P_min]\n", 121 | "\n", 122 | " # Match final position and 0 velocity\n", 123 | " constraints += [\n", 124 | " V[K] == [0, 0, 0],\n", 125 | " P[K] == p_target,\n", 126 | " ]\n", 127 | "\n", 128 | " # Physics dynamics for velocity\n", 129 | " constraints += [V[1:, :2] == V[:-1, :2] + h * (F[:, :2] / m)]\n", 130 | " constraints += [V[1:, 2] == V[:-1, 2] + h * (F[:, 2] / m - g)]\n", 131 | "\n", 132 | " # Physics dynamics for position\n", 133 | " constraints += [P[1:] == P[:-1] + (h / 2) * (V[:-1] + V[1:])]\n", 134 | "\n", 135 | " # Glide path constraint\n", 136 | " constraints += [P[:, 2] >= np.tan(alpha) * cp.norm(P[:, :2], axis=1)]\n", 137 | "\n", 138 | " # Maximum thrust constraint\n", 139 | " constraints += [cp.norm(F, 2, axis=1) <= F_max]\n", 140 | "\n", 141 | " fuel_consumption = gamma * cp.sum(cp.norm(F, axis=1))\n", 142 | "\n", 143 | " problem = cp.Problem(cp.Minimize(fuel_consumption), constraints)\n", 144 | " return problem, p0, v0" 145 | ] 146 | }, 147 | { 148 | "cell_type": "markdown", 149 | "metadata": {}, 150 | "source": [ 151 | "# Solve the problem many times\n", 152 | "\n", 153 | "We solve the problem many times and observe a large speedup after the first solve when using a parametrized problem.\n", 154 | "This is because the canonicalization map is only computed once and cached for subsequent solves." 155 | ] 156 | }, 157 | { 158 | "cell_type": "code", 159 | "execution_count": 4, 160 | "metadata": { 161 | "collapsed": false, 162 | "jupyter": { 163 | "outputs_hidden": false 164 | }, 165 | "ExecuteTime": { 166 | "end_time": "2023-07-14T16:40:59.912652153Z", 167 | "start_time": "2023-07-14T16:40:58.622356464Z" 168 | } 169 | }, 170 | "outputs": [], 171 | "source": [ 172 | "parametrized_problem, p0, v0 = optimize_fuel(p_target, g, m, K, h, F_max, alpha, gamma)\n", 173 | "\n", 174 | "times = []\n", 175 | "for i in range(100):\n", 176 | " start = time.time()\n", 177 | " p0.value = np.array([50, 50, 100]) + np.random.random(3)\n", 178 | " v0.value = np.array([-10, 0, -10]) + np.random.random(3)\n", 179 | " parametrized_problem.solve()\n", 180 | " times.append(time.time() - start)" 181 | ] 182 | }, 183 | { 184 | "cell_type": "code", 185 | "execution_count": 5, 186 | "outputs": [ 187 | { 188 | "data": { 189 | "text/plain": "[]" 190 | }, 191 | "execution_count": 5, 192 | "metadata": {}, 193 | "output_type": "execute_result" 194 | }, 195 | { 196 | "data": { 197 | "text/plain": "
", 198 | "image/png": "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" 199 | }, 200 | "metadata": {}, 201 | "output_type": "display_data" 202 | } 203 | ], 204 | "source": [ 205 | "plt.plot(times)" 206 | ], 207 | "metadata": { 208 | "collapsed": false, 209 | "ExecuteTime": { 210 | "end_time": "2023-07-14T16:41:00.077788248Z", 211 | "start_time": "2023-07-14T16:40:59.915353116Z" 212 | } 213 | } 214 | } 215 | ], 216 | "metadata": { 217 | "kernelspec": { 218 | "display_name": "Python 3 (ipykernel)", 219 | "language": "python", 220 | "name": "python3" 221 | }, 222 | "language_info": { 223 | "codemirror_mode": { 224 | "name": "ipython", 225 | "version": 3 226 | }, 227 | "file_extension": ".py", 228 | "mimetype": "text/x-python", 229 | "name": "python", 230 | "nbconvert_exporter": "python", 231 | "pygments_lexer": "ipython3", 232 | "version": "3.8.12" 233 | } 234 | }, 235 | "nbformat": 4, 236 | "nbformat_minor": 4 237 | } 238 | -------------------------------------------------------------------------------- /notebooks/solving_the_problem.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": { 7 | "tags": [] 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "from typing import Tuple\n", 12 | "\n", 13 | "import cvxpy as cp\n", 14 | "import matplotlib.pyplot as plt\n", 15 | "import numpy as np\n", 16 | "from matplotlib import cm" 17 | ] 18 | }, 19 | { 20 | "cell_type": "markdown", 21 | "metadata": {}, 22 | "source": [ 23 | "# Test data" 24 | ] 25 | }, 26 | { 27 | "cell_type": "code", 28 | "execution_count": null, 29 | "metadata": { 30 | "collapsed": false, 31 | "jupyter": { 32 | "outputs_hidden": false 33 | } 34 | }, 35 | "outputs": [], 36 | "source": [ 37 | "h = 1 # discretization step in s\n", 38 | "g = 0.1 # gravity in m/s^2\n", 39 | "m = 10.0 # mass in kg\n", 40 | "F_max = 10.0 # maximum thrust in Newton\n", 41 | "p0 = np.array([50, 50, 100]) # initial position in m\n", 42 | "v0 = np.array([-10, 0, -10]) # initial velocity in m/s\n", 43 | "p_target = np.array([0, 0, 0]) # target position in m\n", 44 | "alpha = np.pi / 8 # glide angle in rad\n", 45 | "gamma = 1.0 # fuel consumption coefficient\n", 46 | "K = 35 # number of discretization steps" 47 | ] 48 | }, 49 | { 50 | "cell_type": "markdown", 51 | "metadata": {}, 52 | "source": [ 53 | "# Formulate the optimization problem" 54 | ] 55 | }, 56 | { 57 | "cell_type": "code", 58 | "execution_count": null, 59 | "metadata": { 60 | "collapsed": false, 61 | "jupyter": { 62 | "outputs_hidden": false 63 | } 64 | }, 65 | "outputs": [], 66 | "source": [ 67 | "def optimize_fuel(\n", 68 | " p_target: np.ndarray,\n", 69 | " g: float,\n", 70 | " m: float,\n", 71 | " p0: np.ndarray,\n", 72 | " v0: np.ndarray,\n", 73 | " K: int,\n", 74 | " h: float,\n", 75 | " F_max: float,\n", 76 | " alpha: float,\n", 77 | " gamma: float,\n", 78 | " **kwargs: dict,\n", 79 | ") -> Tuple[np.ndarray, np.ndarray]:\n", 80 | " \"\"\"\n", 81 | "\n", 82 | " Minimize fuel consumption for a rocket to land on a target\n", 83 | "\n", 84 | " :param p_target: landing target in m\n", 85 | " :param g: gravitational acceleration in m/s^2\n", 86 | " :param m: mass in kg\n", 87 | " :param p0: position in m\n", 88 | " :param v0: velocity in m/s\n", 89 | " :param K: Number of discretization steps\n", 90 | " :param h: discretization step in s\n", 91 | " :param F_max: maximum thrust of engine in kg*m/s^2 (Newton)\n", 92 | " :param alpha: Glide path angle in radian\n", 93 | " :param gamma: converts fuel consumption to liters of fuel consumption\n", 94 | " :return: position and thrust over time\n", 95 | " \"\"\"\n", 96 | "\n", 97 | " P_min = p_target[2]\n", 98 | "\n", 99 | " # Variables\n", 100 | " V = cp.Variable((K + 1, 3)) # velocity\n", 101 | " P = cp.Variable((K + 1, 3)) # position\n", 102 | " F = cp.Variable((K, 3)) # thrust\n", 103 | "\n", 104 | " # Constraints\n", 105 | " # Match initial position and initial velocity\n", 106 | " constraints = [...]\n", 107 | "\n", 108 | " # Keep height above P_min\n", 109 | " constraints += [...]\n", 110 | "\n", 111 | " # Match final position and 0 velocity\n", 112 | " constraints += [...]\n", 113 | "\n", 114 | " # Physics dynamics for velocity\n", 115 | " constraints += [...]\n", 116 | "\n", 117 | " # Physics dynamics for position\n", 118 | " constraints += [...]\n", 119 | "\n", 120 | " # Glide path constraint\n", 121 | " # constraints += [...] # Added later\n", 122 | "\n", 123 | " # Maximum thrust constraint\n", 124 | " constraints += [...]\n", 125 | "\n", 126 | " fuel_consumption = ...\n", 127 | "\n", 128 | " problem = cp.Problem(cp.Minimize(fuel_consumption), constraints)\n", 129 | " problem.solve(**kwargs)\n", 130 | " return P.value, F.value, V.value" 131 | ] 132 | }, 133 | { 134 | "cell_type": "markdown", 135 | "metadata": {}, 136 | "source": [ 137 | "# Solve the problem" 138 | ] 139 | }, 140 | { 141 | "cell_type": "code", 142 | "execution_count": null, 143 | "metadata": { 144 | "collapsed": false, 145 | "jupyter": { 146 | "outputs_hidden": false 147 | } 148 | }, 149 | "outputs": [], 150 | "source": [ 151 | "P_star, F_star, V_star = optimize_fuel(\n", 152 | " p_target, g, m, p0, v0, K, h, F_max, alpha, gamma\n", 153 | ")" 154 | ] 155 | }, 156 | { 157 | "cell_type": "markdown", 158 | "metadata": {}, 159 | "source": [ 160 | "# Plot the trajectory" 161 | ] 162 | }, 163 | { 164 | "cell_type": "code", 165 | "execution_count": null, 166 | "outputs": [], 167 | "source": [ 168 | "fig = plt.figure()\n", 169 | "ax = fig.add_subplot(projection=\"3d\")\n", 170 | "X = np.linspace(P_star[:, 0].min() - 10, P_star[:, 0].max() + 10, num=30)\n", 171 | "Y = np.linspace(P_star[:, 1].min() - 10, P_star[:, 1].max() + 10, num=30)\n", 172 | "X, Y = np.meshgrid(X, Y)\n", 173 | "Z = np.tan(alpha) * np.sqrt(X**2 + Y**2)\n", 174 | "ax.plot_surface(\n", 175 | " X,\n", 176 | " Y,\n", 177 | " Z,\n", 178 | " rstride=1,\n", 179 | " cstride=1,\n", 180 | " cmap=cm.autumn,\n", 181 | " linewidth=0.1,\n", 182 | " alpha=0.7,\n", 183 | " edgecolors=\"k\",\n", 184 | ")\n", 185 | "ax = plt.gca()\n", 186 | "ax.view_init(azim=180)\n", 187 | "ax.plot(xs=P_star[:, 0], ys=P_star[:, 1], zs=P_star[:, 2], c=\"b\", lw=2, zorder=5)\n", 188 | "\n", 189 | "ax.quiver(\n", 190 | " P_star[:-1, 0],\n", 191 | " P_star[:-1, 1],\n", 192 | " P_star[:-1, 2],\n", 193 | " F_star[:, 0],\n", 194 | " F_star[:, 1],\n", 195 | " F_star[:, 2],\n", 196 | " zorder=5,\n", 197 | " color=\"black\",\n", 198 | " length=2,\n", 199 | ")\n", 200 | "\n", 201 | "ax.set_xlabel(\"x\")\n", 202 | "ax.set_ylabel(\"y\")\n", 203 | "ax.set_zlabel(\"z\")\n", 204 | "plt.show()" 205 | ], 206 | "metadata": { 207 | "collapsed": false 208 | } 209 | }, 210 | { 211 | "cell_type": "markdown", 212 | "source": [ 213 | "# Plot the Position, Velocity and Thrust over time" 214 | ], 215 | "metadata": { 216 | "collapsed": false 217 | } 218 | }, 219 | { 220 | "cell_type": "code", 221 | "execution_count": null, 222 | "outputs": [], 223 | "source": [ 224 | "fig, ax = plt.subplots(3, 1, sharex=True)\n", 225 | "\n", 226 | "ax[0].plot(P_star[:, 0], label=\"x\")\n", 227 | "ax[0].plot(P_star[:, 1], label=\"y\")\n", 228 | "ax[0].plot(P_star[:, 2], label=\"z\")\n", 229 | "ax[0].set_ylabel(\"Position\")\n", 230 | "ax[0].legend()\n", 231 | "\n", 232 | "ax[1].plot(F_star[:, 0], label=\"x\")\n", 233 | "ax[1].plot(F_star[:, 1], label=\"y\")\n", 234 | "ax[1].plot(F_star[:, 2], label=\"z\")\n", 235 | "ax[1].set_ylabel(\"Thrust\")\n", 236 | "ax[1].legend()\n", 237 | "\n", 238 | "ax[2].plot(V_star[:, 0], label=\"x\")\n", 239 | "ax[2].plot(V_star[:, 1], label=\"y\")\n", 240 | "ax[2].plot(V_star[:, 2], label=\"z\")\n", 241 | "ax[2].set_ylabel(\"Velocity\")\n", 242 | "ax[2].legend()\n", 243 | "\n", 244 | "plt.show()" 245 | ], 246 | "metadata": { 247 | "collapsed": false 248 | } 249 | } 250 | ], 251 | "metadata": { 252 | "kernelspec": { 253 | "display_name": "Python 3 (ipykernel)", 254 | "language": "python", 255 | "name": "python3" 256 | }, 257 | "language_info": { 258 | "codemirror_mode": { 259 | "name": "ipython", 260 | "version": 3 261 | }, 262 | "file_extension": ".py", 263 | "mimetype": "text/x-python", 264 | "name": "python", 265 | "nbconvert_exporter": "python", 266 | "pygments_lexer": "ipython3", 267 | "version": "3.8.12" 268 | } 269 | }, 270 | "nbformat": 4, 271 | "nbformat_minor": 4 272 | } 273 | -------------------------------------------------------------------------------- /notebooks/solving_the_problem_solution.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "tags": [], 8 | "ExecuteTime": { 9 | "end_time": "2023-07-14T16:49:59.320251095Z", 10 | "start_time": "2023-07-14T16:49:58.720565453Z" 11 | } 12 | }, 13 | "outputs": [], 14 | "source": [ 15 | "from typing import Tuple\n", 16 | "\n", 17 | "import cvxpy as cp\n", 18 | "import matplotlib.pyplot as plt\n", 19 | "import numpy as np\n", 20 | "from matplotlib import cm" 21 | ] 22 | }, 23 | { 24 | "cell_type": "markdown", 25 | "metadata": {}, 26 | "source": [ 27 | "# Test data" 28 | ] 29 | }, 30 | { 31 | "cell_type": "code", 32 | "execution_count": 2, 33 | "metadata": { 34 | "collapsed": false, 35 | "jupyter": { 36 | "outputs_hidden": false 37 | }, 38 | "ExecuteTime": { 39 | "end_time": "2023-07-14T16:49:59.325549494Z", 40 | "start_time": "2023-07-14T16:49:59.323646017Z" 41 | } 42 | }, 43 | "outputs": [], 44 | "source": [ 45 | "h = 1 # discretization step in s\n", 46 | "g = 0.1 # gravity in m/s^2\n", 47 | "m = 10.0 # mass in kg\n", 48 | "F_max = 10.0 # maximum thrust in Newton\n", 49 | "p0 = np.array([50, 50, 100]) # initial position in m\n", 50 | "v0 = np.array([-10, 0, -10]) # initial velocity in m/s\n", 51 | "p_target = np.array([0, 0, 0]) # target position in m\n", 52 | "alpha = np.pi / 8 # glide angle in rad\n", 53 | "gamma = 1.0 # fuel consumption coefficient\n", 54 | "K = 35 # number of discretization steps" 55 | ] 56 | }, 57 | { 58 | "cell_type": "markdown", 59 | "metadata": {}, 60 | "source": [ 61 | "# Formulate the optimization problem" 62 | ] 63 | }, 64 | { 65 | "cell_type": "code", 66 | "execution_count": 3, 67 | "metadata": { 68 | "collapsed": false, 69 | "jupyter": { 70 | "outputs_hidden": false 71 | }, 72 | "ExecuteTime": { 73 | "end_time": "2023-07-14T16:49:59.336801931Z", 74 | "start_time": "2023-07-14T16:49:59.335294050Z" 75 | } 76 | }, 77 | "outputs": [], 78 | "source": [ 79 | "def optimize_fuel(\n", 80 | " p_target: np.ndarray,\n", 81 | " g: float,\n", 82 | " m: float,\n", 83 | " p0: np.ndarray,\n", 84 | " v0: np.ndarray,\n", 85 | " K: int,\n", 86 | " h: float,\n", 87 | " F_max: float,\n", 88 | " alpha: float,\n", 89 | " gamma: float,\n", 90 | " **kwargs: dict,\n", 91 | ") -> Tuple[np.ndarray, np.ndarray]:\n", 92 | " \"\"\"\n", 93 | "\n", 94 | " Minimize fuel consumption for a rocket to land on a target\n", 95 | "\n", 96 | " :param p_target: landing target in m\n", 97 | " :param g: gravitational acceleration in m/s^2\n", 98 | " :param m: mass in kg\n", 99 | " :param p0: position in m\n", 100 | " :param v0: velocity in m/s\n", 101 | " :param K: Number of discretization steps\n", 102 | " :param h: discretization step in s\n", 103 | " :param F_max: maximum thrust of engine in kg*m/s^2 (Newton)\n", 104 | " :param alpha: Glide path angle in radian\n", 105 | " :param gamma: converts fuel consumption to liters of fuel consumption\n", 106 | " :return: position and thrust over time\n", 107 | " \"\"\"\n", 108 | "\n", 109 | " P_min = p_target[2]\n", 110 | "\n", 111 | " # Variables\n", 112 | " V = cp.Variable((K + 1, 3)) # velocity\n", 113 | " P = cp.Variable((K + 1, 3)) # position\n", 114 | " F = cp.Variable((K, 3)) # thrust\n", 115 | "\n", 116 | " # Constraints\n", 117 | " # Match initial position and initial velocity\n", 118 | " constraints = [\n", 119 | " V[0] == v0,\n", 120 | " P[0] == p0,\n", 121 | " ]\n", 122 | "\n", 123 | " # Keep height above P_min\n", 124 | " constraints += [P[:, 2] >= P_min]\n", 125 | "\n", 126 | " # Match final position and 0 velocity\n", 127 | " constraints += [\n", 128 | " V[K] == [0, 0, 0],\n", 129 | " P[K] == p_target,\n", 130 | " ]\n", 131 | "\n", 132 | " # Physics dynamics for velocity\n", 133 | " constraints += [V[1:, :2] == V[:-1, :2] + h * (F[:, :2] / m)]\n", 134 | " constraints += [V[1:, 2] == V[:-1, 2] + h * (F[:, 2] / m - g)]\n", 135 | "\n", 136 | " # Physics dynamics for position\n", 137 | " constraints += [P[1:] == P[:-1] + (h / 2) * (V[:-1] + V[1:])]\n", 138 | "\n", 139 | " # Glide path constraint\n", 140 | " constraints += [P[:, 2] >= np.tan(alpha) * cp.norm(P[:, :2], axis=1)]\n", 141 | "\n", 142 | " # Maximum thrust constraint\n", 143 | " constraints += [cp.norm(F, 2, axis=1) <= F_max]\n", 144 | "\n", 145 | " fuel_consumption = gamma * cp.sum(cp.norm(F, axis=1))\n", 146 | "\n", 147 | " problem = cp.Problem(cp.Minimize(fuel_consumption), constraints)\n", 148 | " problem.solve(**kwargs)\n", 149 | " return P.value, F.value, V.value" 150 | ] 151 | }, 152 | { 153 | "cell_type": "markdown", 154 | "metadata": {}, 155 | "source": [ 156 | "# Solve the problem" 157 | ] 158 | }, 159 | { 160 | "cell_type": "code", 161 | "execution_count": 4, 162 | "metadata": { 163 | "collapsed": false, 164 | "jupyter": { 165 | "outputs_hidden": false 166 | }, 167 | "ExecuteTime": { 168 | "end_time": "2023-07-14T16:49:59.386486113Z", 169 | "start_time": "2023-07-14T16:49:59.357429547Z" 170 | } 171 | }, 172 | "outputs": [], 173 | "source": [ 174 | "P_star, F_star, V_star = optimize_fuel(\n", 175 | " p_target, g, m, p0, v0, K, h, F_max, alpha, gamma\n", 176 | ")" 177 | ] 178 | }, 179 | { 180 | "cell_type": "markdown", 181 | "metadata": {}, 182 | "source": [ 183 | "# Plot the trajectory" 184 | ] 185 | }, 186 | { 187 | "cell_type": "code", 188 | "execution_count": 5, 189 | "outputs": [ 190 | { 191 | "data": { 192 | "text/plain": "
", 193 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYUAAAGFCAYAAAASI+9IAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAAEAAElEQVR4nOz9d5Sk2V3nCX/u48JmRnpX3pvu6qrurvatVgt5NEgIIRDmrIAFMbAML8M5DCwLOxwBwzIzzBFodwWIRUhIMCAJGQQSSC3R8u3Uprqry2aWy0pTacPHY+59/3jieSIiMyKrKm2Z53tOnoyIx9z7mHu/9+eFUkoRIUKECBEiANpGdyBChAgRItw4iEghQoQIESKEiEghQoQIESKEiEghQoQIESKEiEghQoQIESKEiEghQoQIESKEiEghQoQIESKEiEghQoQIESKEiEghQoQIESKEiEghQoQIESKEiEghQoQIESKEiEghQoQIESKEiEghQoQIESKEiEghQoQIESKEiEghQoQIESKEiEghQoQIESKEiEghQoQIESKEiEghQoQIESKEiEghQoQIESKEiEghQoQIESKEiEghQoQIESKEiEghQoQIESKEiEghQoQIESKEiEghQoQIESKEiEghQoQIESKEiEghQoQIESKEiEghQoQIESKEiEghQoQIESKEiEghQoQIESKEiEghQoQIESKEiEghQoQIESKEiEghQoQIESKEiEghQoQIESKEiEghQoQIESKEiEghQoQIESKEiEghQoQIESKEiEghQoQIESKEiEghQoQIESKEiEghQoQIESKEiEghQoQIESKEiEghwjXj7NmzvPzyyxvdjQgRIqwhhFJKbXQnItwc2L9/PydPnmTv3r2cPHlyo7sTIUKENUAkKUS4Jrz66qshEbS3t29wbyJEiLBWiEghwjXhp3/6p8PPv//7v7+BPYkQIcJaIlIfRbgqnnjiCd7whjcAYJomxWIRwzA2uFcRIkRYC0SSQoQl4Xkev/RLvxR+f+Mb3xgRQoQItzAiUoiwJD7ykY9w4sSJ8PuP/diPbWBvIkSIsNaI1EcRWiKXy7Fnzx4mJiYAEEIwOTlJT0/PBvcsQoQIa4VIUojQEn/wB38QEgLA/fffHxFChAi3OCJSiNAUjuPw93//9w2//bt/9+82qDcRIkRYL0SkEKEpTNPkYx/7WMNvb3vb2zaoNxEiRFgvRG4kEVriIx/5CAD9/f0kEgmOHDmysR2KECHCmiMyNEdoitnZWTZt2kSpVOIb3/gGDz74YOSKGiHCbYBolEdoio9+9KOUSiUOHTrEI488ghBio7sUIUKEdUBECqsIpVT4dzNDSsn/+//+vwD8wi/8AlLKDe5RhAgrh6Zp0eLmGhCRwipCSolt28sihbGxMTRNo7+/fw161hwjIyN0dXWRyWQafv/KV77C6dOnaW9v513veheVSmXV2jx+/Di7d+/GsqxVO+dSKJfLjIyMcODAgXVpD2Bubo65uTm2b9++bm2Oj48DMDAwsG5tnjt3jo6ODjo6OtatzRMnTrB9+3bi8fh1HRcsbFKpVEQMV0FECmsATbt+p65sNoumaQwODq5Bj5pjamqKZDJJZ2dnw+8f/vCHAfiJn/iJVc+IOjY2xo4dO5Z1j5YDKSVjY2Pccccd69Ie+EQ0NTXFzp07163N+fl5hBAMDQ2tW5tXrlwhHo+v27MEGB0dZevWrdfdppQS13WRUqLr+hr17tZARAqrDNd1EUIsazXiui6e561Br5pDCLGozYsXL/LP//zPAPzsz/7smvRnPa/T8zyUUut6X4O21rPNYLJb7zZh/a9zOc/T87zw2AhLI/I+WkV4nsezzz4bivI3Iz7+8Y/zqU99ikOHDvG7v/u7G92dCBFWDZlMhkceeQTTNDe6Kzc0IlJYRXieR7FYBLhuSWFkZIRisbiuao4XXniBnp4eNm/eDEClUmH//v1MTU3x8Y9/nHe84x2r3uaTTz7JPffcQ1tb26qfuxkKhQJPPfUU3/d937cu7QFcvnyZsbEx7r333nVr89VXX8WyLHbt2rVubX73u99l9+7d65b6xPM8/u3f/o3HHnvsuif2mZkZXn75ZV7/+tcTi8XWqIe3BiL10SpCCIFhGMtSHwUv+XquYnRdR9O0sM1PfepTTE1NsWnTJn7wB39wTeIShBDour5u1xk8j/W+r+t5jbD+9zWAaZrr1mawfrUs67rfzVQqheM466rqulkRpbm4QSCEWHfXz4Vt/tmf/RkA/+v/+r+uWaDaent+3C6eJkqpdb/W9W4zeFeXY9g2TRMhBPl8frW7dcshIoUbBJqmrTspaJoWrr5efPFFvvvd72IYBj/zMz+zZm0KIdbd2He7aEjXmxSklOvqebQSUhBCoGlaWGc8QmtEpHCDYCNIoV5SCKSEd77znWvq674RpLDe2Ijru10khZWQkK7rkQfSNSAihRsEGykpzM3N8T//5/8E4Od//udb7j89Pb3iNtebFDZKfXSrT9CwMZLCStrbiDF2MyIihVXESgZlsIpZTwSSwl//9V9TLBa58847eeSRR5ruOzIywqZNm+jp6eHFF19cUZvRSm31cTtIJysJPFNKhXEcETEsjYgUbhBslKTgeV6oOvr5n//5loP8p37qpwDI5/MrjtS91W0Kt8MEDf4kvd6ksNz2gvsTqY+ujogU1gDLeek2yqbw1FNPcebMGdrb2/mxH/uxpvudPXuWp556CoDBwcEVxRhE6qO1wUbZFG429VEkKVwdESncINgoUvi7v/s7AH7yJ3+SdDrddL9f+7VfCz8HEsNK2oywNljPextkA76ZDM1BWpdIUlgaESmsMpY7SDaCFCYmJvj6178OwPve976m+7zwwgthLiSAd7/73StqM7IprA3We4IOnuHNJCkopcLEeBFaIyKFVcRKBuVGkMKnPvUppJQ8/vjj7N+/v+k+v/VbvxV+7urqWnEK6o1SH61nm7eDTSF4V28mQ3NwjwqFwir37NZCRAo3CNabFCqVCp/+9KeB1m6oTz75JF/5ylfC729729tWPAncLpLCrW5TuBklBfDTnpRKpVXq0a2JiBRWGStVH63XhPmZz3yG6elpent7+YEf+IFF25VS/PZv/3bDb29605tW3O5GkUIkKax+e7D+ksJySSFQHZmmSalUui0WJstFlBDvBkHwsq/H4D5zRvBHf/RV4G7e/vb7muY5+sd//Eeefvrp8LsQYlUyjUaSwtpgve/pSlJOrKTNlbQnpSQej1OpVDbEW+tmQSQprDJWIikA66JC+tmfdTh27KPA93jjG9/edJ/HHnuMhx9+OPx+9OhRuru7V6X928Eldb1xu0gKK2lPSollWZTL5dtiYbJcRKRwg2A9SSEeT4SfF5biDJBOpzl//nz4/fWvf/2qtH27SArrjY0wNN8saTUCI7OUklgsFkoKEZojUh/dIFhPUmhE88Hxr//6r4yOjtLd3c23vvWt6y6U3gobtXK/1W0KsP5xCuupOoKVeR+BX6QnFosxNTUVBbAtgYgUbhAEhXnW42Wtn7NatfeXf/mXAPzET/wE27dvX7W2o4jmtUEkKVzb8YlEIpIU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" 194 | }, 195 | "metadata": {}, 196 | "output_type": "display_data" 197 | } 198 | ], 199 | "source": [ 200 | "fig = plt.figure()\n", 201 | "ax = fig.add_subplot(projection=\"3d\")\n", 202 | "X = np.linspace(P_star[:, 0].min() - 10, P_star[:, 0].max() + 10, num=30)\n", 203 | "Y = np.linspace(P_star[:, 1].min() - 10, P_star[:, 1].max() + 10, num=30)\n", 204 | "X, Y = np.meshgrid(X, Y)\n", 205 | "Z = np.tan(alpha) * np.sqrt(X**2 + Y**2)\n", 206 | "ax.plot_surface(\n", 207 | " X,\n", 208 | " Y,\n", 209 | " Z,\n", 210 | " rstride=1,\n", 211 | " cstride=1,\n", 212 | " cmap=cm.autumn,\n", 213 | " linewidth=0.1,\n", 214 | " alpha=0.7,\n", 215 | " edgecolors=\"k\",\n", 216 | ")\n", 217 | "ax = plt.gca()\n", 218 | "ax.view_init(azim=180)\n", 219 | "ax.plot(xs=P_star[:, 0], ys=P_star[:, 1], zs=P_star[:, 2], c=\"b\", lw=2, zorder=5)\n", 220 | "\n", 221 | "ax.quiver(\n", 222 | " P_star[:-1, 0],\n", 223 | " P_star[:-1, 1],\n", 224 | " P_star[:-1, 2],\n", 225 | " F_star[:, 0],\n", 226 | " F_star[:, 1],\n", 227 | " F_star[:, 2],\n", 228 | " zorder=5,\n", 229 | " color=\"black\",\n", 230 | " length=2,\n", 231 | ")\n", 232 | "\n", 233 | "ax.set_xlabel(\"x\")\n", 234 | "ax.set_ylabel(\"y\")\n", 235 | "ax.set_zlabel(\"z\")\n", 236 | "plt.show()" 237 | ], 238 | "metadata": { 239 | "collapsed": false, 240 | "ExecuteTime": { 241 | "end_time": "2023-07-14T16:49:59.617040034Z", 242 | "start_time": "2023-07-14T16:49:59.391690572Z" 243 | } 244 | } 245 | }, 246 | { 247 | "cell_type": "markdown", 248 | "source": [ 249 | "# Plot the Position, Velocity and Thrust over time" 250 | ], 251 | "metadata": { 252 | "collapsed": false 253 | } 254 | }, 255 | { 256 | "cell_type": "code", 257 | "execution_count": 6, 258 | "outputs": [ 259 | { 260 | "data": { 261 | "text/plain": "
", 262 | "image/png": "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" 263 | }, 264 | "metadata": {}, 265 | "output_type": "display_data" 266 | } 267 | ], 268 | "source": [ 269 | "fig, ax = plt.subplots(3, 1, sharex=True)\n", 270 | "\n", 271 | "ax[0].plot(P_star[:, 0], label=\"x\")\n", 272 | "ax[0].plot(P_star[:, 1], label=\"y\")\n", 273 | "ax[0].plot(P_star[:, 2], label=\"z\")\n", 274 | "ax[0].set_ylabel(\"Position\")\n", 275 | "ax[0].legend()\n", 276 | "\n", 277 | "ax[1].plot(F_star[:, 0], label=\"x\")\n", 278 | "ax[1].plot(F_star[:, 1], label=\"y\")\n", 279 | "ax[1].plot(F_star[:, 2], label=\"z\")\n", 280 | "ax[1].set_ylabel(\"Thrust\")\n", 281 | "ax[1].legend()\n", 282 | "\n", 283 | "ax[2].plot(V_star[:, 0], label=\"x\")\n", 284 | "ax[2].plot(V_star[:, 1], label=\"y\")\n", 285 | "ax[2].plot(V_star[:, 2], label=\"z\")\n", 286 | "ax[2].set_ylabel(\"Velocity\")\n", 287 | "ax[2].legend()\n", 288 | "\n", 289 | "plt.show()" 290 | ], 291 | "metadata": { 292 | "collapsed": false, 293 | "ExecuteTime": { 294 | "end_time": "2023-07-14T16:50:00.053273772Z", 295 | "start_time": "2023-07-14T16:49:59.622973527Z" 296 | } 297 | } 298 | } 299 | ], 300 | "metadata": { 301 | "kernelspec": { 302 | "display_name": "Python 3 (ipykernel)", 303 | "language": "python", 304 | "name": "python3" 305 | }, 306 | "language_info": { 307 | "codemirror_mode": { 308 | "name": "ipython", 309 | "version": 3 310 | }, 311 | "file_extension": ".py", 312 | "mimetype": "text/x-python", 313 | "name": "python", 314 | "nbconvert_exporter": "python", 315 | "pygments_lexer": "ipython3", 316 | "version": "3.8.12" 317 | } 318 | }, 319 | "nbformat": 4, 320 | "nbformat_minor": 4 321 | } 322 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | cvxpy >= 1.3 2 | scipy 3 | matplotlib -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [metadata] 2 | name = cvxkerb 3 | version = 0.1.0 4 | author = Philipp Schiele, Steven Diamond, Eric Luxenberg, Stephen Boyd 5 | author_email = philipp.schiele@stat.uni-muenchen.de, diamond@cs.stanford.edu, ericlux@stanford.edu, boyd@stanford.edu 6 | url = https://github.com/cvxpy/cvxkerb 7 | description = Controlling Self-Landing Rockets Using CVXPY 8 | long_description = file: README.md 9 | long_description_content_type = text/markdown 10 | license = Apache License, Version 2.0 11 | 12 | [options] 13 | packages = find: 14 | install_requires = 15 | cvxpy >= 1.3 16 | scipy 17 | matplotlib 18 | zip_safe = True 19 | include_package_data = True 20 | 21 | [options.package_data] 22 | * = README.md 23 | -------------------------------------------------------------------------------- /slides/advanced.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvxpy/cvxkerb/2878078698a876d7c2b1f7cf9491d7c251a8a519/slides/advanced.pdf -------------------------------------------------------------------------------- /slides/conclusion.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvxpy/cvxkerb/2878078698a876d7c2b1f7cf9491d7c251a8a519/slides/conclusion.pdf -------------------------------------------------------------------------------- /slides/cvxpy_intro.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvxpy/cvxkerb/2878078698a876d7c2b1f7cf9491d7c251a8a519/slides/cvxpy_intro.pdf -------------------------------------------------------------------------------- /slides/intro.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvxpy/cvxkerb/2878078698a876d7c2b1f7cf9491d7c251a8a519/slides/intro.pdf -------------------------------------------------------------------------------- /slides/landing_problem.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvxpy/cvxkerb/2878078698a876d7c2b1f7cf9491d7c251a8a519/slides/landing_problem.pdf -------------------------------------------------------------------------------- /slides/mission.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvxpy/cvxkerb/2878078698a876d7c2b1f7cf9491d7c251a8a519/slides/mission.pdf -------------------------------------------------------------------------------- /src/optimization.py: -------------------------------------------------------------------------------- 1 | from typing import Tuple 2 | 3 | import cvxpy as cp 4 | import numpy as np 5 | 6 | 7 | def optimize_fuel( 8 | p_target: np.ndarray, 9 | g: float, 10 | m: float, 11 | p0: np.ndarray, 12 | v0: np.ndarray, 13 | K: int, 14 | h: float, 15 | F_max: float, 16 | alpha: float, 17 | gamma: float, 18 | **kwargs: dict, 19 | ) -> Tuple[np.ndarray, np.ndarray, float, cp.Problem]: 20 | """ 21 | 22 | Minimize fuel consumption for a rocket to land on a target 23 | 24 | :param p_target: landing target in m 25 | :param g: gravitational acceleration in m/s^2 26 | :param m: mass in kg 27 | :param p0: position in m 28 | :param v0: velocity in m/s 29 | :param K: Number of discretization steps 30 | :param h: discretization step in s 31 | :param F_max: maximum thrust of engine in kg*m/s^2 (Newton) 32 | :param alpha: Glide path angle in radian 33 | :param gamma: converts fuel consumption to liters of fuel consumption 34 | :return: position, thrust, fuel consumption, problem 35 | """ 36 | 37 | P_min = p_target[2] 38 | 39 | # Variables 40 | V = cp.Variable((K + 1, 3)) # velocity 41 | P = cp.Variable((K + 1, 3)) # position 42 | F = cp.Variable((K, 3)) # thrust 43 | 44 | # Constraints 45 | # Match initial position and initial velocity 46 | constraints = [ 47 | V[0] == v0, 48 | P[0] == p0, 49 | P[:, 2] >= P_min, 50 | # P[:, 2] <= P_max, 51 | F[:, 2] >= 0, 52 | V[:, 2] <= 0, 53 | ] 54 | 55 | # Match final position and 0 velocity 56 | constraints += [ 57 | V[K] == [0, 0, 0], 58 | P[K] == p_target, 59 | ] 60 | 61 | # Physics dynamics for velocity 62 | constraints += [V[1:, :2] == V[:-1, :2] + h * (F[:, :2] / m)] 63 | constraints += [V[1:, 2] == V[:-1, 2] + h * (F[:, 2] / m - g)] 64 | 65 | # Physics dynamics for position 66 | constraints += [P[1:] == P[:-1] + (h / 2) * (V[:-1] + V[1:])] 67 | 68 | # Maximum thrust constraint 69 | constraints += [cp.norm(F, 2, axis=1) <= F_max] 70 | 71 | fuel_consumption = gamma * cp.sum(cp.norm(F, axis=1)) 72 | 73 | # Regularization 74 | height_regularization = cp.sum(cp.abs(P[:, 2] - P_min)) 75 | xy_regularization = cp.sum(cp.abs(P[:, :2] - p_target[:2].reshape((1, -1)))) 76 | glide_violation = cp.pos(np.tan(alpha) * cp.norm(P[:, :2], axis=1) - P[:, 2]) 77 | glide_violation = cp.sum(glide_violation) 78 | gamma_height = 1 79 | gamma_xy = 1 80 | gamma_glide = 1000 81 | reg = ( 82 | gamma_height * height_regularization 83 | + gamma_xy * xy_regularization 84 | + gamma_glide * glide_violation 85 | ) 86 | 87 | problem = cp.Problem(cp.Minimize(fuel_consumption + reg), constraints) 88 | problem.solve(**kwargs) 89 | return P.value, F.value, fuel_consumption.value, problem 90 | --------------------------------------------------------------------------------