{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Parking Robot with Discrete Dynamics\n", "Richard M. Murray, 20 Jul 2013 (updated 19 Feb 2020)\n", "\n", "## Problem description\n", "This example illustrates the use of TuLiP to synthesize a reactive\n", "controller for system whose dynamics are described by a discrete\n", "transition system.\n", "\n", "We begin by importing the packages and modules that we will need." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Include commands to allow inline display of movies\n", "%matplotlib inline\n", "from IPython.display import HTML\n", "\n", "# Import TuLiP and other Python packages\n", "from tulip import transys, spec, synth\n", "import random" ] }, { "attachments": { "image.png": { "image/png": "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" } }, "cell_type": "markdown", "metadata": {}, "source": [ "### System dynamics\n", "\n", "The system is modeled as a discrete transition system in which the\n", "robot can be located anyplace on a 2x3 grid of cells. Transitions\n", "between adjacent cells are allowed, which we model as a transition\n", "system in this example (it would also be possible to do this via a\n", "formula).\n", "\n", "We label the states using the following picture:\n", "\n", "" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Create a finite transition system\n", "sys = transys.FTS()\n", "\n", "# Define the states of the system\n", "sys.states.add_from(['C0', 'C1', 'C2', 'C3', 'C4', 'C5'])\n", "sys.states.initial.add_from(['C0']) # start in state C0\n", "\n", "# Define the allowable transitions\n", "sys.transitions.add_comb({'C0'}, {'C1', 'C3'})\n", "sys.transitions.add_comb({'C1'}, {'C0', 'C4', 'C2'})\n", "sys.transitions.add_comb({'C2'}, {'C1', 'C5'})\n", "sys.transitions.add_comb({'C3'}, {'C0', 'C4'})\n", "sys.transitions.add_comb({'C4'}, {'C3', 'C1', 'C5'})\n", "sys.transitions.add_comb({'C5'}, {'C4', 'C2'})\n", "\n", "# Add atomic propositions to the states\n", "sys.atomic_propositions.add_from({'home', 'lot'})\n", "sys.states.add('C0', ap={'lot'})\n", "sys.states.add('C5', ap={'home'})\n", "\n", "# Generate a picture of the system\n", "sys.plot();" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Environment variables and specification\n", "\n", "The environment can issue a park signal that the robot must respond\n", "to by moving to the lower left corner of the grid. We assume that\n", "the park signal is turned off infinitely often." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "env_vars = {'park'}\n", "env_init = [] # empty set\n", "env_prog = '!park'\n", "env_safe = set() # empty set (another way)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### System specification\n", "\n", "The system specification is that the robot should repeatedly revisit\n", "the upper right corner of the grid while at the same time responding\n", "to the park signal by visiting the lower left corner. The LTL\n", "specification is given by\n", "\n", " []<> home && [](park -> <>lot)\n", "\n", "Since this specification is not in GR(1) form, we introduce the\n", "variable X0reach that is initialized to True and the specification\n", "`[](park -> <>lot)` becomes\n", "\n", " []((X (X0reach)) <-> (lot | (X0reach && !park)))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "sys_vars = {'X0reach'} # infer the rest from TS\n", "sys_init = {'X0reach'}\n", "sys_prog = {'home'} # []<>home\n", "sys_safe = {'(X (X0reach)) <-> (lot | (X0reach & !park))'}\n", "sys_prog |= {'X0reach'}" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Create the specification\n", "specs = spec.GRSpec(env_vars, sys_vars, env_init, sys_init,\n", " env_safe, sys_safe, env_prog, sys_prog)\n", "specs.qinit = \"\\A \\E\"\n", "print(specs.pretty())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Controller synthesis\n", "\n", "At this point we can synthesize the controller using one of the available\n", "methods." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "ctrl = synth.synthesize(specs, sys=sys)\n", "assert ctrl is not None, 'unrealizable'" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Description of the synthesized controller\n", "ctrl.plot()\n", "print(ctrl)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Simulation\n", "\n", "We can now generate a simulation to visualize the action of the controller.\n", "\n", "Note: this simulation uses the `gridworld` module functionality to generate the animation. This is not idea for this example, but is a good first start." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Create a grid world for visualizing the results\n", "import tulip.gridworld as gw\n", "world = gw.unoccupied((2, 3))\n", "print(world)\n", "\n", "# Create a dictionary between named locations and gridworld location\n", "gridloc = {\n", " 'C3': (0, 0), 'C4': (0, 1), 'C5': (0, 2),\n", " 'C0': (1, 0), 'C1': (1, 1), 'C2': (1, 2)\n", "}" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Simulation\n", "T = 100\n", "\n", "# Pick an environmental signal\n", "# randParkSignal = [random.randint(0, 1) for b in range(1, T + 1)]\n", "randParkSignal = [(0, 0, 0, 0, 0, 0, 0, 1)[b % 8] for b in range(1, T+1)]\n", "\n", "# Run a simulation\n", "time, states = ctrl.run('Sinit', {'park': randParkSignal})\n", "\n", "# Grab the location\n", "loc = [gridloc[loc] for loc in states['loc']]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Animate the motion\n", "anim = gw.animate_paths(world, (loc,))\n", "HTML(anim.to_jshtml())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Things to Try\n", "* Allow the system to start in a different state\n", "* Allow the system to stay in its current cell for multiple steps" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## specs.qinit\n", "\n", "* '\\A \\A': forall env forall sys assume env_init sys_init must be empty\n", "* '\\A \\E': forall env exist sys (usually not Moore) assume env_init and require sys_init\n", "* '\\E \\A': exist sys forall env assume env_init and require sys_init\n", "* '\\E \\E': exist env exist sys require sys_init env_init must be empty" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "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.6" } }, "nbformat": 4, "nbformat_minor": 4 }