{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "from CBD.Core import CBD\n",
    "from CBD.lib.std import *\n",
    "\n",
    "class Train(CBD):\n",
    "    def __init__(self, name, dt):\n",
    "        super().__init__(name, [\"a\", \"v0\", \"x0\"], [\"v\", \"x\"])\n",
    "        \n",
    "        self.addBlock(ConstantBlock(\"dt\", dt))\n",
    "        self.addBlock(IntegratorBlock(\"vI\"))\n",
    "        self.addBlock(IntegratorBlock(\"xI\"))\n",
    "        self.addConnection(\"a\", \"vI\")\n",
    "        self.addConnection(\"vI\", \"xI\")\n",
    "        self.addConnection(\"xI\", \"x\")\n",
    "        self.addConnection(\"vI\", \"v\")\n",
    "        self.addConnection(\"dt\", \"xI\", input_port_name=\"delta_t\")\n",
    "        self.addConnection(\"dt\", \"vI\", input_port_name=\"delta_t\")\n",
    "        self.addConnection(\"v0\", \"vI\", input_port_name=\"IC\")\n",
    "        self.addConnection(\"x0\", \"xI\", input_port_name=\"IC\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pypdevs.DEVS import AtomicDEVS, CoupledDEVS\n",
    "from pypdevs.infinity import INFINITY\n",
    "\n",
    "class Compute(AtomicDEVS):\n",
    "    def __init__(self, name):\n",
    "        super().__init__(name)\n",
    "        \n",
    "        self.state = {\n",
    "            \"speeding\": True,\n",
    "            \"braking\": False,\n",
    "            \"acceleration\": 10,\n",
    "            \"output_requested\": True\n",
    "        }\n",
    "        \n",
    "        self.crossing = self.addInPort(\"crossing\")\n",
    "        self.acc = self.addOutPort(\"acc\")\n",
    "        \n",
    "    def extTransition(self, inputs):\n",
    "        crossing = inputs[self.crossing]\n",
    "        if \"v\" in crossing and not self.state[\"braking\"]:\n",
    "            self.speed[\"speeding\"] = not self.speed[\"speeding\"]\n",
    "            if self.speed[\"speeding\"]:\n",
    "                a = 10\n",
    "            else:\n",
    "                a = -5\n",
    "        if \"brake\" in crossing:\n",
    "            a = -5\n",
    "            self.state[\"braking\"] = True\n",
    "        if \"station\" in crossing:\n",
    "            a = 0\n",
    "        self.state[\"acceleration\"] = a\n",
    "        self.state[\"output_requested\"] = True\n",
    "        return self.state\n",
    "    \n",
    "    def outputFnc(self):\n",
    "        return {\n",
    "            self.acc: self.state[\"acceleration\"]\n",
    "        }\n",
    "    \n",
    "    def intTransition(self):\n",
    "        self.state[\"output_requested\"] = False\n",
    "        return self.state\n",
    "    \n",
    "    def timeAdvance(self):\n",
    "        if self.state[\"output_requested\"]:\n",
    "            return 0.0\n",
    "        return INFINITY\n",
    "        \n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from CBD.converters.cbddevs import CBDRunner, CrossingDetection\n",
    "\n",
    "class TrainSystem(CoupledDEVS):\n",
    "    def __init__(self, name):\n",
    "        super().__init__(name)\n",
    "        \n",
    "        self.driver = self.addSubModel(Compute(\"Driver\"))\n",
    "        self.train = self.addSubModel(CBDRunner(\"train\", Train(\"train\", 0.1), {\"a\": 10, \"v0\": 0, \"x0\": 0}))\n",
    "        \n",
    "        "
   ]
  }
 ],
 "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.8.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
