You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Conception/drake-master/tutorials/licensed_solvers_deepnote.i...

198 lines
5.7 KiB

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Enabling licensed solvers on Deepnote\n",
"For instructions on how to run these tutorial notebooks, please see the [index](./index.ipynb).\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import os\n",
"assert \"DEEPNOTE_PROJECT_ID\" in os.environ, \"This tutorial is meant to be run on Deepnote\""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Drake's MathematicalProgram interface supports some commercial solvers that require users to provide a license file in order to activate them. This tutorial provides an example of how this can be accomplished on Deepnote; attempting to simplify the workflow but also minimize the chances of you accidentally sharing your license file.\n",
"\n",
"You can **duplicate this notebook**, and upload your license file, and run the code to make sure the activation works."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Mosek\n",
"\n",
"* If you don't have one, obtain a Mosek license. If you have academic status, then you can obtain a [free personal academic license](https://www.mosek.com/products/academic-licenses/).\n",
"* This cell will prompt you to upload the `mosek.lic` file from your local machine.\n",
"\n",
"**Please be careful to avoid publicly sharing your license file!**\n",
"\n",
"We upload the file to `/tmp/mosek.lic` in order to help prevent accidental sharing of your license file. It will be cleared at the end of each session.\n",
"\n",
"Note: If you share an active session with a collaborator with your license uploaded, they could potentially copy the file out of `/tmp` and obtain your license. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import os\n",
"import os.path\n",
"\n",
"import ipywidgets as widgets # Our use requires ipywidgets >= 7.5.0\n",
"from IPython.display import display\n",
"\n",
"if \"MOSEKLM_LICENSE_FILE\" not in os.environ:\n",
" # If a mosek.lic file has already been uploaded, then simply use it here.\n",
" if os.path.exists('/tmp/mosek.lic'):\n",
" os.environ[\"MOSEKLM_LICENSE_FILE\"] = \"/tmp/mosek.lic\"\n",
" else:\n",
" uploader = widgets.FileUpload(accept='.lic', multiple=False)\n",
" display(uploader)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"if \"MOSEKLM_LICENSE_FILE\" not in os.environ:\n",
" assert len(uploader.value.values()) > 0, \"Please upload a license file using the Upload widget above.\"\n",
" with open('/tmp/mosek.lic', 'wb') as output_file:\n",
" output_file.write(list(uploader.value.values())[-1]['content']) \n",
" os.environ[\"MOSEKLM_LICENSE_FILE\"] = \"/tmp/mosek.lic\""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can confirm that Drake believes Mosek should now be available:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from pydrake.solvers import MosekSolver\n",
"\n",
"print(MosekSolver().enabled())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now let's solve a trivial semidefinite program. \n",
"\n",
"$$\\begin{aligned} \\min_S \\quad & \\text{Trace}(S) \\\\ \\text{subject to} \\quad & S_{1,0} = 1, \\\\ & S \\succeq 0. \\end{aligned}$$\n",
"\n",
"The known optimal solution is $ S = \\begin{bmatrix} 1 & 1 \\\\ 1 & 1\\end{bmatrix}.$"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from pydrake.solvers import MathematicalProgram, MosekSolver\n",
"\n",
"prog = MathematicalProgram()\n",
"S = prog.NewSymmetricContinuousVariables(2, \"S\")\n",
"\n",
"# S ≽ 0.\n",
"prog.AddPositiveSemidefiniteConstraint(S)\n",
"\n",
"# S(1, 0) = 1\n",
"prog.AddBoundingBoxConstraint(1, 1, S[1, 0])\n",
"\n",
"# min Trace(S)\n",
"prog.AddLinearCost(S[0,0] + S[1,1])\n",
"\n",
"mosek = MosekSolver()\n",
"result = mosek.Solve(prog)\n",
"assert result.is_success()\n",
"\n",
"print(result.GetSolution(S))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Gurobi\n",
"\n",
"Gurobi is not yet available in the binary releases of Drake. We hope to enable it in the future: https://github.com/RobotLocomotion/drake/issues/10804"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Clean up\n",
"\n",
"For good measure, let's delete any temporary license files now."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"if os.path.exists('/tmp/mosek.lic'):\n",
" os.remove('/tmp/mosek.lic')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"interpreter": {
"hash": "b0fa6594d8f4cbf19f97940f81e996739fb7646882a419484c72d19e05852a7e"
},
"kernelspec": {
"display_name": "Python 3.9.12 64-bit",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.12"
},
"orig_nbformat": 2
},
"nbformat": 4,
"nbformat_minor": 2
}