optimization_engine 0.7.4

A pure Rust framework for embedded nonconvex optimization. Ideal for robotics!
Documentation
{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Parametric nonconvex optimization\n",
    "\n",
    "Consider the following minimization problem ([reference](https://alphaville.github.io/optimization-engine/docs/example_rosenbrock_py))\n",
    "$$\n",
    "\\begin{align}\n",
    "    \\operatorname*{Minimize}_{\\|u\\|\\leq r}& \\sum_{i=1}^{n_u - 1} b (u_{i+1} - u_{i}^2)^2 + (a-u_i)^2\n",
    "    \\\\\n",
    "    \\text{subject to: }& 1.5 u_1 - u_2 = 0\n",
    "    \\\\\n",
    "    &u_3 - u_4 + 0.1 \\leq 0\n",
    "    \\end{align}\n",
    "$$\n",
    "The parameter vector is $p=(a,b)$. \n",
    "\n",
    "Let us generate a parametric optimiser with $n_u=5$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import opengen as og\n",
    "import casadi.casadi as cs\n",
    "\n",
    "# Build parametric optimizer\n",
    "# ------------------------------------\n",
    "u = cs.SX.sym(\"u\", 5)  # decision variables\n",
    "p = cs.SX.sym(\"p\", 2)  # parameters, p = (a, b)\n",
    "\n",
    "# cost function:\n",
    "phi = og.functions.rosenbrock(u, p)\n",
    "\n",
    "# constraints:\n",
    "c = cs.vertcat(1.5 * u[0] - u[1],\n",
    "               cs.fmax(0.0, u[2] - u[3] + 0.1))\n",
    "\n",
    "# simple bounds on decision variables:\n",
    "bounds = og.constraints.Ball2(None, 1.5)\n",
    "\n",
    "# problem formulation\n",
    "problem = og.builder.Problem(u, p, phi) \\\n",
    "    .with_penalty_constraints(c)        \\\n",
    "    .with_constraints(bounds)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Generate optimizer\n",
    "\n",
    "The following code will generate your parametric optimizer. \n",
    "\n",
    "The auto-generated files will be stored in `optimizers/rosenbrock`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Configure and build\n",
    "# (This might take a while)\n",
    "# ---------------------------------\n",
    "build_config = og.config.BuildConfiguration()      \\\n",
    "    .with_build_directory(\"optimizers\")            \\\n",
    "    .with_build_mode(og.config.BuildConfiguration.DEBUG_MODE)  \\\n",
    "    .with_tcp_interface_config()\n",
    "meta = og.config.OptimizerMeta()                   \\\n",
    "    .with_optimizer_name(\"rosenbrock\")\n",
    "solver_config = og.config.SolverConfiguration()    \\\n",
    "    .with_tolerance(1e-5)                          \\\n",
    "    .with_delta_tolerance(1e-4)                    \\\n",
    "    .with_initial_penalty(1e3)                     \\\n",
    "    .with_penalty_weight_update_factor(5)\n",
    "builder = og.builder.OpEnOptimizerBuilder(problem, meta,\n",
    "                                          build_config, solver_config)\n",
    "builder.build()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Use the auto-generated optimizer\n",
    "\n",
    "You may now use the auto-generated optimizer in Python.\n",
    "\n",
    "\n",
    "<div class=\"alert alert-block alert-info\">\n",
    "<b>Tip:</b> First you need to <em>start</em> the server. Then, you can <em>call</em> it as many times as you like. When you're done, you can <em>kill</em> it.</div>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Start the optimisation server\n",
    "# ----------------------------------\n",
    "mng = og.tcp.OptimizerTcpManager('optimizers/rosenbrock')\n",
    "mng.start()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Call the server\n",
    "# ----------------------------------\n",
    "response = mng.call([1.0, 50.0])\n",
    "if response.is_ok():\n",
    "    # Solver returned a solution\n",
    "    solution_data = response.get()\n",
    "    u_star = solution_data.solution\n",
    "    exit_status = solution_data.exit_status\n",
    "    solver_time = solution_data.solve_time_ms\n",
    "    print(\"u_star = \", u_star)\n",
    "    print(\"solved in = \", solver_time, \"ms\")\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Kill the server\n",
    "# ----------------------------------\n",
    "mng.kill()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div class=\"alert alert-block alert-info\">\n",
    "<b>Tip:</b> The auto-generated TCP server you built above listens for requests at port <code>8333</code>. Since it runs within this docker container, if you want to call it from another application outside this Jupyter notebook you need to forward the port - to do so, run the docker image with <code>-p 8333:8333</code>.</div>"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "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.7.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}