diff --git a/Code/MainParticleNetworking.ipynb b/Code/MainParticleNetworking.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..32526d000409d8d54858edd667789beb3b774102 --- /dev/null +++ b/Code/MainParticleNetworking.ipynb @@ -0,0 +1,1939 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Using TensorFlow backend.\n" + ] + } + ], + "source": [ + "#imports\n", + "import socket #used for networking\n", + "import numpy as np\n", + "from io import StringIO #needed to convert data to send via socket\n", + "import struct\n", + "\n", + "#drawing tools\n", + "import matplotlib\n", + "from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg\n", + "from matplotlib.figure import Figure\n", + "from matplotlib.axes import Axes\n", + "from matplotlib.cm import Greys\n", + "from tkinter import *\n", + "matplotlib.use('TkAgg')\n", + "\n", + "lastlocalmap = np.full((10,10),-1)\n", + "\n", + "%run RobotGameEnvironment.ipynb\n", + "%run QN_alldirrobot.ipynb" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "#functions for sending and receiving messages\n", + "#each message is prefixed by an int lenght, used to receive the hole lenght of message afterwards\n", + "def send_msg(sock, msg):\n", + " # Prefix each message with a 4-byte length (network byte order)\n", + " msg = struct.pack('>I', len(msg)) + msg\n", + " sock.sendall(msg)\n", + "\n", + "def recv_msg(sock):\n", + " # Read message length and unpack it into an integer\n", + " raw_msglen = recvall(sock, 4)\n", + " if not raw_msglen:\n", + " return None\n", + " msglen = struct.unpack('>I', raw_msglen)[0]\n", + " # Read the message data\n", + " return recvall(sock, msglen)\n", + "\n", + "def recvall(sock, n):\n", + " # Helper function to recv n bytes or return None if EndOfFile is hit\n", + " data = bytearray()\n", + " while len(data) < n:\n", + " packet = sock.recv(n - len(data))\n", + " if not packet:\n", + " return None\n", + " data.extend(packet)\n", + " return data" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "def particleclient(tk,host=socket.gethostname(),port=4223):\n", + " #host = 'AirujoRaspberry'#socket.gethostname() # get local machine name\n", + " #port = 4223 # Make sure it's within the > 1024 $$ <65535 range\n", + " \n", + " #connect networking socket to robot host\n", + " s = socket.socket()\n", + " s.connect((host, port))\n", + " \n", + " #initialize particlefilter:\n", + " parcount = 100\n", + " #global allparticles\n", + " allparticles = []\n", + " for i in range(parcount):\n", + " allparticles.append(particle(0,0,0))\n", + " \n", + " \n", + " \n", + " #movementbuttons\n", + " manb = Button(tk, text=\"Manual Controls\", command=tk.destroy, state=DISABLED)\n", + " manb.grid(row = 8, column = 1,columnspan = 3)\n", + " forb = Button(tk, text=\"Forward\", command=lambda: movemessage(\"forward\",s,allparticles))\n", + " forb.grid(row = 9, column = 2,columnspan = 1)\n", + " backb = Button(tk, text=\"Backward\", command=lambda: movemessage(\"backward\",s,allparticles))\n", + " backb.grid(row = 11, column = 2,columnspan = 1)\n", + " leftb = Button(tk, text=\"Left\", command=lambda: movemessage(\"left\",s,allparticles))\n", + " leftb.grid(row = 10, column = 1,columnspan = 1)\n", + " rightb = Button(tk, text=\"right\", command=lambda: movemessage(\"right\",s,allparticles))\n", + " rightb.grid(row = 10, column = 3,columnspan = 1) \n", + " \n", + " #explore and relocate\n", + " leftb = Button(tk, text=\"Explore\", command=lambda: explore_a_relocate(\"explore\",s,allparticles))\n", + " leftb.grid(row = 13, column = 1,columnspan = 1)\n", + " rightb = Button(tk, text=\"Relocate\", command=lambda: explore_a_relocate(\"relocate\",s,allparticles))\n", + " rightb.grid(row = 13, column = 3,columnspan = 1) \n", + " \n", + " #automatic\n", + " autob = Button(tk, text=\"QN-Choices\", command=lambda: playonTk_withdqn(RobotGame(s,allparticles),statesize=4,loadweights = str(input(\"which weights?\")),tk=tk))\n", + " autob.grid(row = 15, column = 1,columnspan = 2)\n", + " \n", + " disconnb = Button(tk, text=\"Disconnect\", command=lambda: movemessage(\"q\",s,allparticles))\n", + " disconnb.grid(row = 21, column = 9,columnspan = 2)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "def movemessage(message,socket,allparticles,drawing = True):\n", + " global lastlocalmap\n", + " if message == \"reset\":\n", + " send_msg(socket,message.encode('utf-8'))\n", + " donemsg = recv_msg(socket)\n", + " breakcondition,reward = False,0\n", + " elif message != 'q':\n", + " if movement_allowed(lastlocalmap,message):\n", + " wheeldist = 19.5 # distance of the two wheels, needed to calc the orders send to robot\n", + " \n", + " startangle = allparticles[bestparticle].angle\n", + " #print(localmap)\n", + " #transfer action message into wheelchanges\n", + " if message == \"forward\":\n", + " #changescaling = 0.7074\n", + " #speeds for for/backward are chosen so that robot travels 10cm\n", + " #wheelleft = 0.7074\n", + " #wheelright = 0.7074\n", + " \n", + " #change from simple forward drive to driving to cell in front of me - this means also correcting angle\n", + " direction = int(startangle/(np.pi/2)+0.5)\n", + " aimangle = np.pi/2*direction\n", + " if startangle < 0:\n", + " direction = int(startangle/(np.pi/2)-0.5)\n", + " aimangle = np.pi/2*int(startangle/(np.pi/2)-0.5)\n", + " anglechange = aimangle-startangle\n", + " if abs(anglechange) < 0.01: #small angle approx\n", + " if direction%4 == 0:\n", + " distchange = 10/np.cos(startangle)\n", + " elif direction%4 == 1:\n", + " distchange = 10/np.sin(startangle)\n", + " elif direction%4 == 2:\n", + " distchange = -10/np.cos(startangle)\n", + " elif direction%4 == 3:\n", + " distchange = -10/np.sin(startangle)\n", + " elif direction%4 == 0:\n", + " distchange = 10*anglechange/(-np.sin(startangle)+np.sin(startangle+anglechange))\n", + " elif direction%4 == 1:\n", + " distchange = 10*anglechange/(np.cos(startangle)-np.cos(startangle+anglechange))\n", + " elif direction%4 == 2:\n", + " distchange = -10*anglechange/(-np.sin(startangle)+np.sin(startangle+anglechange))\n", + " elif direction%4 == 3:\n", + " distchange = -10*anglechange/(np.cos(startangle)-np.cos(startangle+anglechange))\n", + " #calc wheelright and wheelleft from distance and angle - changes\n", + " wheelright = 2/np.pi*(2*distchange/wheeldist + anglechange)\n", + " wheelleft = wheelright - 4*anglechange/np.pi\n", + " \n", + " elif message == \"backward\":\n", + " #changescaling = 0.7074\n", + " #wheelleft = -0.7074\n", + " #wheelright = -0.7074\n", + " \n", + " \n", + " #change from simple backward drive to driving to cell behind me - this means also correcting angle\n", + " direction = int(startangle/(np.pi/2)+0.5)\n", + " aimangle = np.pi/2*direction\n", + " if startangle < 0:\n", + " direction = int(startangle/(np.pi/2)-0.5)\n", + " aimangle = np.pi/2*int(startangle/(np.pi/2)-0.5)\n", + " anglechange = aimangle-startangle\n", + " if abs(anglechange) < 0.01: #small angle approx\n", + " if direction%4 == 0:\n", + " distchange = -10/np.cos(startangle)\n", + " elif direction%4 == 1:\n", + " distchange = -10/np.sin(startangle)\n", + " elif direction%4 == 2:\n", + " distchange = 10/np.cos(startangle)\n", + " elif direction%4 == 3:\n", + " distchange = 10/np.sin(startangle)\n", + " elif direction%4 == 0:\n", + " distchange = -10*anglechange/(-np.sin(startangle)+np.sin(startangle+anglechange))\n", + " elif direction%4 == 1:\n", + " distchange = -10*anglechange/(np.cos(startangle)-np.cos(startangle+anglechange))\n", + " elif direction%4 == 2:\n", + " distchange = 10*anglechange/(-np.sin(startangle)+np.sin(startangle+anglechange))\n", + " elif direction%4 == 3:\n", + " distchange = 10*anglechange/(np.cos(startangle)-np.cos(startangle+anglechange))\n", + " #calc wheelright and wheelleft from distance and angle - changes\n", + " wheelright = 2/np.pi*(2*distchange/wheeldist + anglechange)\n", + " wheelleft = wheelright - 4*anglechange/np.pi\n", + " \n", + " elif message == \"left\":\n", + " #turn into a 90degree position not by 90degree e.g. if startangle is -10° turn to +90° not +80°\n", + " aimangle = np.pi/2*int((startangle+np.pi/2)/(np.pi/2)+0.5)\n", + " if (startangle+np.pi/2) < 0: #different int casting for negatives\n", + " aimangle = np.pi/2*int((startangle+np.pi/2)/(np.pi/2)-0.5)\n", + " changeangle = aimangle-startangle\n", + " changescaling = (abs(2*changeangle/np.pi))\n", + " \n", + " wheelleft = -1*changescaling\n", + " wheelright = 1*changescaling\n", + " elif message == \"right\":\n", + " #turn into a 90° position not by 90° e.g. if startangle is -10° turn to -90° not -100°\n", + " aimangle = np.pi/2*int((startangle-np.pi/2)/(np.pi/2)+0.5)\n", + " if (startangle-np.pi/2) < 0: #different int casting for negatives\n", + " aimangle = np.pi/2*int((startangle-np.pi/2)/(np.pi/2)-0.5)\n", + " changeangle = aimangle-startangle\n", + " changescaling = (abs(2*changeangle/np.pi))\n", + " \n", + " wheelleft = 1*changescaling\n", + " wheelright = -1*changescaling\n", + " else:\n", + " #moving forward with 0 velocity is equivalent to staying at position\n", + " message = \"Forward\"\n", + " changescaling = 0\n", + " wheelleft = 0\n", + " wheelright = 0 \n", + " \n", + " #compose the message\n", + " message = message + \"#\" + str(wheelleft) + \"#\" + str(wheelright)\n", + " #send message\n", + " send_msg(socket,message.encode('utf-8')) \n", + " #receive message and convert it to a localmap\n", + " nptest = recv_msg(socket)\n", + " localm = np.frombuffer(nptest)\n", + " localdim = int(np.sqrt(len(localm)))\n", + " localmap = localm.reshape((localdim,localdim))\n", + "\n", + "\n", + " #execute the particle filter step and receive a reward\n", + " reward = particle_filter(allparticles,localmap,wheelleft,wheelright)\n", + " if drawing == True: #draw if wanted\n", + " global figglobe\n", + " global axesglobe\n", + " global figlocal\n", + " global axeslocal\n", + " draw_particles(allparticles,figglobe,axesglobe)\n", + " draw_localmap(localmap,figlocal,axeslocal)\n", + " #print(allparticles[0].counter)\n", + " \n", + " #keep track of the previous localmap\n", + " lastlocalmap = localmap\n", + " #all good no need to break\n", + " breakcondition = False\n", + " else:\n", + " breakcondition = True #movement was not allowed break movement loop\n", + " reward = 0 #no reward in this case\n", + " \n", + " else: #message is \"q\", this ends the connection\n", + " send_msg(socket,message.encode('utf-8'))\n", + " socket.close()\n", + " breakcondition = True\n", + " reward = 0\n", + " #calculate the standard deviation of the particle ensemble \n", + " new_uncertainty = calc_uncertainty(allparticles)\n", + " #return if one should stop, the reward und the particle spread\n", + " return breakcondition, reward, new_uncertainty\n", + " \n", + "def explore_a_relocate(choice,socket,allparticles):\n", + " #function creates and loops through the ordelist of explore and relocate\n", + " continues = True\n", + " targetlocation = 'none'\n", + " while continues == True:\n", + " continues = False\n", + " #use explore and retrace functions on bestparticle to obtain orderlist\n", + " if choice == \"explore\":\n", + " orderlist = allparticles[bestparticle].nearest_unobserved()\n", + " else:\n", + " orderlist, targetlocation = allparticles[bestparticle].retrace(aim_for = targetlocation)\n", + " for i in range(len(orderlist)): #loop through orderlist\n", + " breakcondition,rew,new_unc = movemessage(orderlist[i],socket,allparticles)\n", + " if breakcondition == True: #something was wrong -> stop\n", + " break\n", + " if i > 7 and (len(orderlist)-i)>7:\n", + " #to avoid to long exploration/relocate paths consider recalculating your path after some steps\n", + " continues = True\n", + " break\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "#the main tk window\n", + "def tk_main(host=socket.gethostname(),port=4223):\n", + " #set up tk window\n", + " tk = Tk()\n", + " tk.title(\"Pyborg Explo\")\n", + " tk.resizable(0, 0)\n", + " \n", + " #globals for figures\n", + " global figglobe\n", + " global axesglobe\n", + " global figlocal\n", + " global axeslocal\n", + " \n", + " #initialise global and local map figures\n", + " figglobe = Figure(figsize=(6,6))\n", + " axesglobe = Axes(figglobe,[0.,0.,1.,1.])#figglobe.add_subplot(111)\n", + " figglobe.add_axes(axesglobe)\n", + " axesglobe.set_axis_off()\n", + "\n", + " figlocal = Figure(figsize=(1,1))\n", + " axeslocal = Axes(figlocal,[0.,0.,1.,1.])#figglobe.add_subplot(111)\n", + " figlocal.add_axes(axeslocal)\n", + " axeslocal.set_axis_off()\n", + "\n", + " \n", + " #Buttons\n", + " globalmap = FigureCanvasTkAgg(figglobe,master=tk)#Canvas(tk, width=600, height=600, bd=0, bg=\"#222222\")\n", + " globalmap.get_tk_widget().grid(row = 1, column = 4,columnspan = 20, rowspan = 20)\n", + " localmap = FigureCanvasTkAgg(figlocal,master=tk)#Canvas(tk, width=150, height=150, bd=0, bg=\"#222222\")\n", + " localmap.get_tk_widget().grid(row = 1, column = 1,columnspan = 3, rowspan = 3)\n", + "\n", + "\n", + " autob = Button(tk, text=\"Auto Controls\", command=tk.destroy,state=DISABLED)\n", + " autob.grid(row = 14, column = 1,columnspan = 3)\n", + " #connect and quit\n", + " connb = Button(tk, text=\"Connect\", command=lambda: particleclient(tk,host=host,port=port))\n", + " connb.grid(row = 21, column = 7,columnspan = 2)\n", + "\n", + " quitb = Button(tk, text=\"Quit\", command=tk.destroy)\n", + " quitb.grid(row = 21, column = 13,columnspan = 2)\n", + " \n", + " ##text log, currently completely unused, but could be used\n", + " #log = Text(tk, height=37, width=20)\n", + " #log.grid(row = 2, column = 25,columnspan = 3,rowspan=19)\n", + " #log.insert(END,\"lots of text stuff\\n and more\")\n", + "\n", + " #initialize the figures by some test stuff\n", + " test = np.zeros((20,20))\n", + " test[10][10] = 1\n", + " axesglobe.imshow(test, interpolation='nearest',cmap=Greys,origin = 'lower')\n", + " axeslocal.imshow(test, interpolation='nearest',cmap=Greys,origin = 'lower')\n", + "\n", + " #update window\n", + " tk.update()\n", + "\n", + " tk.mainloop()" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "#for learning dont use a tk window, just play the robotgame without any drawing\n", + "def particleclient_learning(host=socket.gethostname(),port = 4223):\n", + " # Make sure the port is within the > 1024 $$ <65535 range\n", + " \n", + " s = socket.socket()\n", + " s.connect((host, port))\n", + " \n", + " #initialize particlefilter:\n", + " parcount = 100\n", + " #global allparticles\n", + " allparticles = []\n", + " for i in range(parcount):\n", + " allparticles.append(particle(0,0,0))\n", + " \n", + " \n", + " \n", + " environment = RobotGame(s,allparticles) #set up environment\n", + " #choose possible loading weight, leave blank for none\n", + " learn_dqn(environment,loadweights = str(input(\"choose loading weights\")))\n", + " \n", + " #after learning end the connection by quit message\n", + " movemessage(\"q\",s,allparticles)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "#particleclient_learning(port=4223) #use this for learning" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "which weights?alldirexplorandmap2_autosave728_weights.h5\n", + "WARNING:tensorflow:From e:\\anaconda\\envs\\neuralnetsnew\\lib\\site-packages\\tensorflow\\python\\framework\\op_def_library.py:263: colocate_with (from tensorflow.python.framework.ops) is deprecated and will be removed in a future version.\n", + "Instructions for updating:\n", + "Colocations handled automatically by placer.\n", + "0\n", + "0.0 0.0 0.0\n", + "action = 0\n", + "0\n", + "9.911177819840916 0.0 0.004883784445923577\n", + "79\n", + "19.94352526084031 1.1121502644512522 0.06936808115203257\n", + "74\n", + "29.710058339539742 -0.4259590305377062 -0.07271519924387745\n", + "72\n", + "40.094225600069144 0.06297259536432875 0.02158450961845771\n", + "67\n", + "49.88562393819386 -1.5589402624719355 -0.06342587336736671\n", + "2\n", + "60.198592710321876 -0.17775033663221507 0.018020529355017238\n", + "60\n", + "69.8198507046842 -1.5140294544937825 -0.04091367336102306\n", + "39\n", + "80.36086821194765 1.1563302666754813 0.0867295635430214\n", + "28\n", + "90.18885467033343 2.4104770392677817 0.01741696656088769\n", + "action = 0\n", + "12\n", + "99.76767804200792 2.7778460594668672 0.022304941499999585\n", + "58\n", + "109.70503224236397 1.5632634815917505 -0.06591184829586501\n", + "47\n", + "120.06891990972005 0.2182399962428434 -0.026924316825692893\n", + "32\n", + "130.01793563474598 -0.5530979132808937 0.024464637071770004\n", + "43\n", + "139.81690764571619 1.601774684523146 0.051522683104123966\n", + "1\n", + "150.3210587379449 -5.745506581424545 -0.15660443195993515\n", + "1\n", + "159.96041168412498 -0.889529759746452 0.009308237139236744\n", + "15\n", + "170.1591327643228 -7.648081063865034 0.07114402125594907\n", + "52\n", + "180.45661162918293 -9.881567799888208 -0.055506238047366936\n", + "action = 0\n", + "4\n", + "189.97332526579834 -9.294035118554325 0.05120082040477762\n", + "0\n", + "199.44109625928684 3.7382512556596375 -0.0027166365327544392\n", + "9\n", + "199.74665748372502 0.27447507025728574 1.5044452838766775\n", + "58\n", + "200.05586364356776 2.522634886483128 1.6506884563467592\n", + "13\n", + "198.83066096968548 12.590747577541519 1.565202978317461\n", + "59\n", + "200.54851061304285 19.41620258959253 1.522508210067771\n", + "70\n", + "198.78715610125292 45.140225571019705 1.6075804730622072\n", + "44\n", + "198.82305982497013 45.938856856475134 1.5497122276777195\n", + "64\n", + "199.20559462702704 43.75470301533377 3.129633807497952\n", + "action = 0\n", + "22\n", + "209.25438861096342 43.72739627356835 3.1482722010060753\n", + "20\n", + "208.12045430824142 42.69351583930252 1.5337148297827528\n", + "12\n", + "215.05859414649802 48.84765671228461 1.5019529260644517\n", + "29\n", + "209.7727106232872 60.83800809954501 1.6331380588464575\n", + "40\n", + "207.68486642777688 72.32853384968381 1.5508748824729248\n", + "81\n", + "210.8017673668802 82.38933018931894 1.526865998553663\n", + "64\n", + "207.44295137691356 92.19407069717093 1.6085051767680676\n", + "20\n", + "207.776060442259 102.3088516206813 1.5613721905794136\n", + "47\n", + "207.63726671971227 112.27756141095112 1.6084303326652085\n", + "64\n", + "212.59433395528032 120.50679946440762 1.4678699599804448\n", + "88\n", + "211.7876457259403 122.38071036089623 3.1706018888565746\n", + "13\n", + "201.84900402063573 122.37906748855104 3.120060332143107\n", + "action = 0\n", + "18\n", + "214.31589091055298 124.34784895688887 3.1528610749069617\n", + "16\n", + "222.1623125230214 122.65233634672342 3.1572826899688913\n", + "40\n", + "231.44434453579115 122.32429743975067 3.1394029591514765\n", + "86\n", + "243.85492548909988 125.17093639547181 3.135033782866813\n", + "41\n", + "252.5534920583102 119.92192254676316 3.1278168318443322\n", + "5\n", + "262.3572168996574 120.35198808795111 3.1389078148401373\n", + "28\n", + "271.25349030713767 120.21228158164692 3.152921979047119\n", + "11\n", + "266.1665596471464 126.95119172502491 4.749556056006697\n", + "action = 0\n", + "48\n", + "273.0548164891724 129.56946797330815 4.6965460326919475\n", + "4\n", + "265.84054079733613 137.01492565992007 6.326109861592985\n", + "56\n", + "267.8838276078444 152.57656533667628 6.361177523378326\n", + "14\n", + "285.0374538317063 137.33911332483015 6.294909232395639\n", + "32\n", + "303.0376970809968 136.98628828384273 6.260589915139397\n", + "46\n", + "312.97924555379666 136.92205341773433 6.293113543861409\n", + "45\n", + "315.41830762393835 136.06158833873084 6.278310613804161\n", + "73\n", + "307.77613796242235 150.80275935904498 7.846458758148231\n", + "73\n", + "308.2027396614792 161.2423514326261 7.843245060176559\n", + "62\n", + "324.3359090819254 144.73120699559541 7.7175725151264025\n", + "16\n", + "307.8251018280425 181.09716478984856 8.011161391917152\n", + "43\n", + "308.4750817951726 189.91181751622264 7.813438455824073\n", + "action = 0\n", + "2\n", + "308.47974259571527 189.91627930420944 6.281073932989173\n", + "23\n", + "318.76780238153015 190.30412776843497 6.252773473852581\n", + "19\n", + "335.8210441384658 174.40605489796917 6.320041666101124\n", + "63\n", + "339.08787047266884 190.60148894064096 6.279285898716943\n", + "86\n", + "353.89838892932914 180.62310917798212 6.317191423319346\n", + "44\n", + "360.852212044647 169.00175365412497 7.91224864774774\n", + "22\n", + "363.0745360066917 175.2297805581003 7.755805267326891\n", + "3\n", + "356.7863192258101 194.26756670589037 7.8498807350031115\n", + "41\n", + "364.5981689580475 193.1755955957687 7.861520572868775\n", + "26\n", + "361.280691450993 196.97064111457183 9.474167356902226\n", + "3\n", + "350.65230751573756 196.99496588958814 9.43733677097492\n", + "4\n", + "350.65576365831635 196.7156452780545 7.897376807265187\n", + "action = 0\n", + "33\n", + "352.42732733921434 186.0107053337771 7.743579720771135\n", + "21\n", + "350.94053164665644 188.22493730797765 7.927867441339858\n", + "18\n", + "351.8884250265079 165.81955840725078 7.81163413996624\n", + "14\n", + "346.47719270099964 164.2164850255336 7.854960040585877\n", + "39\n", + "347.49414178492907 154.1196210162411 7.914918161061716\n", + "28\n", + "343.069911412837 144.75147636530895 7.738847104239099\n", + "29\n", + "348.8001809554718 125.80025867240724 7.845815794452735\n", + "60\n", + "347.9498650031359 116.176063908152 7.815564000281842\n", + "2\n", + "351.2632210318243 107.2535392864595 7.843904184497276\n", + "15\n", + "334.90893691019943 118.69383540196807 7.847342163638474\n", + "61\n", + "349.18620857655947 86.35320203523864 7.820548324214662\n", + "62\n", + "349.0589944122625 76.4250476734505 7.8620421662317215\n", + "9\n", + "347.16245474240543 67.50381882410802 7.845035921090782\n", + "3\n", + "368.68326929207717 79.52966034313715 9.693520532833451\n", + "21\n", + "350.0489564487065 74.759381127565 9.317072456010063\n", + "action = 0\n", + "12\n", + "350.0415003356973 74.75274324610366 10.987595062727705\n", + "47\n", + "337.6817606266434 58.03142823190321 10.822835402501234\n", + "8\n", + "346.15624142508955 57.89962683376396 11.297926495834005\n", + "57\n", + "352.0478881781986 44.690693395110266 10.91771332915288\n", + "9\n", + "353.6716958206779 34.28156707961549 11.030411094621488\n", + "40\n", + "364.7293759483834 28.5027333144132 11.079273607703309\n", + "17\n", + "350.49730259637965 17.457495623819298 10.97167156227136\n", + "8\n", + "351.02930487984315 7.149777176171028 11.027736531052284\n", + "47\n", + "364.29180340557275 -1.7164859780641812 10.974821250842652\n", + "16\n", + "349.1218808639822 -15.298429827521435 10.920494162641528\n", + "47\n", + "366.3814260436043 -21.99567669333684 11.11162673898621\n", + "action = 0\n", + "73\n", + "349.0052294530806 -23.09772824083206 12.525782791627456\n", + "65\n", + "358.6145610097752 -26.689065893457194 12.446612635175587\n", + "45\n", + "368.7653477020137 -23.083814413175762 12.659380378005803\n", + "21\n", + "367.1182831285828 -26.141016770028106 12.43067303160155\n", + "84\n", + "370.9782149199108 -26.71317046980899 12.544875004358165\n", + "55\n", + "413.88896211050337 -14.915183851144658 12.844779582614533\n", + "20\n", + "425.97146656653985 -15.664419354425913 12.523019176391267\n", + "73\n", + "425.9728174557143 -15.663136203225259 14.130174778089781\n", + "58\n", + "426.43077151563404 -5.881583115820854 14.082775488324359\n", + "11\n", + "426.4252505994779 -5.886813457145717 12.568130265038521\n", + "47\n", + "436.390491668124 -5.925251152568489 12.556665133508691\n", + "91\n", + "443.3612621600484 -11.517722497381289 12.49343643805294\n", + "54\n", + "455.8944342064426 -3.642681143477719 12.74143449924903\n", + "79\n", + "442.0054239263514 -10.015247259927738 12.429181056254047\n", + "action = 0\n", + "61\n", + "452.5189303327524 -17.259354009037565 12.545660506320344\n", + "87\n", + "462.50405480482146 -15.93029189931817 12.586901237561946\n", + "92\n", + "471.9720690361428 -8.344349898558221 12.64000769204401\n", + "4\n", + "482.16704308742516 -11.67647240003797 12.470759575436356\n", + "28\n", + "498.4063991347243 -14.629719293003884 12.651058606312299\n", + "87\n", + "523.4990318617137 1.8403242622339557 12.587300245039321\n", + "12\n", + "535.6725605535728 -7.3202913888937005 12.430446064481744\n", + "58\n", + "511.34538156693753 -41.51518339167942 12.541019997381678\n", + "9\n", + "532.3104770361612 -20.479173132378055 12.582827438953734\n", + "action = 0\n", + "90\n", + "545.8823693127542 -6.4142202839372375 12.645142687165055\n", + "78\n", + "535.6835667450651 2.9120904629089486 12.604354953406965\n", + "5\n", + "507.8680470798798 -3.1063610080024624 12.52373026314353\n", + "9\n", + "498.30036488114723 -18.544335173750515 12.561317557556295\n", + "14\n", + "482.45953315098035 -13.66173223888799 12.581571169897188\n", + "2\n", + "472.08766433061913 -10.609125138978786 12.547194895787742\n", + "0\n", + "468.2527340623105 -18.179775504505596 12.571677327931242\n", + "0\n", + "458.53356185926987 -20.02454147129974 12.591672226664478\n", + "5\n", + "442.003266110698 -13.669193457597054 12.592524431528751\n", + "37\n", + "438.6154180115909 -20.751500932210227 12.552778858054156\n", + "0\n", + "428.5468696389851 -20.614643248774353 12.543287159104118\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0\n", + "418.6936527122829 -16.623517595149472 12.485977009899354\n", + "26\n", + "408.3193477274002 -7.32090109784721 12.63387321472742\n", + "63\n", + "398.301235197986 -9.618122780464086 12.614362112769484\n", + "9\n", + "381.7540577400892 -9.279251800239809 12.45035335263992\n", + "1\n", + "378.9449944524157 -10.72696791381951 12.522503568413482\n", + "10\n", + "368.4247957779541 -6.148365225302724 12.618579800834938\n", + "5\n", + "359.29117005366834 -8.145305785838534 12.452271586019636\n", + "6\n", + "348.3195181848875 -6.711465564082841 12.642672726205465\n", + "75\n", + "338.74245127117035 -11.650476816282524 12.453118370060636\n", + "24\n", + "329.63496884124925 -7.057247485334816 12.6138470754606\n", + "99\n", + "318.74832654631876 -10.889518931436331 12.532799848141726\n", + "35\n", + "309.84218584699227 -7.73675861542532 12.619292778490458\n", + "8\n", + "298.63607575392354 -10.160519530722553 12.51744507972984\n", + "36\n", + "289.61551307524604 -12.964410663602145 12.627133383754813\n", + "41\n", + "279.628274093566 -11.129725896161606 12.499915943069206\n", + "6\n", + "269.3170228664717 -11.495275058330751 12.607400091931773\n", + "78\n", + "259.4838322959269 -14.949937964883535 12.606433711162916\n", + "9\n", + "250.11775041254205 -10.593545653962682 12.64487495414686\n", + "7\n", + "240.12063126764153 -6.291356268098424 12.451965536513384\n", + "46\n", + "239.13615713383612 -13.339982232736649 11.030947281561595\n", + "43\n", + "239.43404561293116 -23.529211613295672 11.01845910954142\n", + "12\n", + "240.67287107894057 -28.708945684095056 11.04537775941195\n", + "action = 1\n", + "54\n", + "242.55410684782126 -35.24556153592344 12.640457698079139\n", + "38\n", + "249.9362341024726 -29.602441971646872 12.457580004689136\n", + "51\n", + "259.01975098701854 -31.843426442905226 12.609134139687592\n", + "68\n", + "269.51383055862254 -28.450854648643645 12.480591740573836\n", + "21\n", + "279.5467838401381 -32.99313580779042 12.611203759317755\n", + "1\n", + "290.7120799557352 -29.667155650362027 12.573372297114405\n", + "68\n", + "302.4124669296465 -30.268992586076948 12.623189999592707\n", + "11\n", + "310.4340498918394 -29.83785148922272 12.514126493479168\n", + "15\n", + "320.63998371769145 -30.168256441175494 12.506678472849504\n", + "15\n", + "319.7488334468133 -32.387632492942515 14.13442098067146\n", + "14\n", + "318.6944502701323 -18.054424655672634 14.181532296970781\n", + "action = 0\n", + "13\n", + "319.94477225481995 -22.513398716089235 15.619923117530274\n", + "30\n", + "309.83328845718864 -22.313594249425243 15.756684735588795\n", + "5\n", + "298.72325703624153 -19.04439676612446 15.759636313593594\n", + "95\n", + "289.9056755206201 -21.30883165439042 15.665242437375062\n", + "17\n", + "280.78104602487883 -20.471498530161828 15.599214651410938\n", + "5\n", + "269.49183494579836 -22.65721474986287 15.873587440158417\n", + "12\n", + "260.85951575697317 -20.09502363766931 15.584607736011542\n", + "2\n", + "250.04371023304398 -23.548720162743766 15.766983172855005\n", + "22\n", + "239.6501983827551 -24.694499891500936 15.743997341732475\n", + "48\n", + "229.6961692527617 -24.96617767595303 15.726118351135323\n", + "10\n", + "229.56406892272707 -27.254394387439532 17.212762554190903\n", + "18\n", + "229.71258377315604 -34.905533024153726 17.29556643129022\n", + "44\n", + "231.28089513931366 -44.99079296045104 17.344581397390492\n", + "11\n", + "228.52271527141232 -57.80298415852903 17.19297463383698\n", + "4\n", + "229.62557691201076 -52.78038408893321 18.845430015212003\n", + "action = 0\n", + "4\n", + "231.43440656150057 -48.88049745222215 17.341552022915725\n", + "1\n", + "231.4060874628242 -65.15214856842645 17.28915746676641\n", + "21\n", + "231.32450765922698 -75.16029840750598 17.251979366778418\n", + "3\n", + "231.01097611797618 -74.89473565125428 18.83128673626516\n", + "action = 0\n", + "29\n", + "221.8156446785624 -69.73615931462656 18.895947437532822\n", + "94\n", + "221.11040505892814 -74.71227447560273 17.208713389400806\n", + "18\n", + "225.78710193331233 -93.54415878314452 17.45721271612179\n", + "69\n", + "222.4473835056927 -89.90845834786401 17.16396142110984\n", + "11\n", + "219.70601573818774 -101.0622537709912 17.28468442622778\n", + "50\n", + "217.03417290492462 -109.40797623068468 17.266853185338135\n", + "4\n", + "220.29855379459187 -124.74137706393692 17.32937787060746\n", + "63\n", + "220.5069729157154 -134.8770446501817 17.26941344992893\n", + "30\n", + "220.16438798377078 -144.66523158039163 17.272614253751893\n", + "22\n", + "213.05884396598682 -138.5703954305403 18.710220390572655\n", + "10\n", + "231.7723962150096 -141.3794148217128 19.00567524225214\n", + "action = 0\n", + "13\n", + "212.71112817801267 -138.58719025326977 18.717004539479984\n", + "48\n", + "197.5029236626407 -137.3965507132599 18.820895599432486\n", + "53\n", + "220.99323049485793 -154.0826935463775 17.430965829956854\n", + "15\n", + "195.95407637478627 -146.67503509119632 17.129216423902292\n", + "1\n", + "212.26510712129962 -163.59527617199362 17.390694801554663\n", + "72\n", + "193.71466497469478 -166.51568780615884 17.185916261415148\n", + "2\n", + "213.60862935071137 -183.17446287785458 17.403969267051565\n", + "0\n", + "224.73685238267439 -203.94423925762229 17.258719034149355\n", + "3\n", + "213.52032956177973 -202.99043690617728 17.220026058729164\n", + "6\n", + "202.47642333667326 -211.78220936203502 17.26478726006077\n", + "20\n", + "193.92982373422478 -217.4601105598151 17.304014038629653\n", + "21\n", + "201.75352115403987 -231.61064059858734 17.180829147863616\n", + "53\n", + "194.01066773199076 -227.40578415602553 18.942190671548126\n", + "61\n", + "228.0635294226874 -231.25543852087182 18.89614832663177\n", + "action = 0\n", + "72\n", + "203.49965710933898 -227.81224756151568 17.11999492302911\n", + "55\n", + "222.83441280378983 -243.5177117641669 17.40414574460434\n", + "20\n", + "203.19170076710782 -247.60192358818406 17.20084044086094\n", + "40\n", + "209.49725989657384 -257.7509166671903 17.361968017646202\n", + "64\n", + "209.8815070527998 -257.67316662659874 18.862887468409635\n", + "41\n", + "238.00479254659854 -261.1505895172056 18.884977471910158\n", + "28\n", + "213.5664919474238 -257.97127023563996 17.188741198374252\n", + "71\n", + "237.8298353958365 -270.9284600438619 17.37664644757731\n", + "74\n", + "212.53015246084072 -268.4061270267648 18.74593935999576\n", + "7\n", + "222.55223782420921 -268.58919482420686 18.821633567313288\n", + "78\n", + "238.6497003826949 -269.4338615339689 18.858557387460014\n", + "49\n", + "249.32964904304288 -265.8715796447043 18.972951447790724\n", + "17\n", + "259.42868748317125 -266.0396420591086 18.80618283201271\n", + "action = 0\n", + "31\n", + "252.41498336670585 -268.38743119435884 17.259662359920956\n", + "22\n", + "260.1074478121458 -275.81993267993363 17.306678813735964\n", + "13\n", + "260.0137089011343 -276.68522408632407 15.71620225858014\n", + "24\n", + "242.44489712168854 -277.8657136462833 15.633046834628507\n", + "3\n", + "239.51930733351287 -276.0911246943533 15.750798788315633\n", + "34\n", + "222.5896159249605 -277.73765489571457 15.702524834897009\n", + "14\n", + "238.49747880573014 -280.9515616165711 15.768411532422325\n", + "68\n", + "228.9023198156622 -281.83069798011104 15.752191869764793\n", + "5\n", + "202.9188836210716 -277.082679112674 17.142395926573197\n", + "1\n", + "202.45922285909185 -276.37543903989894 15.680215412938262\n", + "80\n", + "232.47442561665827 -283.1108469845405 15.903113893478084\n", + "77\n", + "192.49144566300254 -276.6047909767303 13.96562923313694\n", + "23\n", + "199.56074018757957 -267.2161262208257 14.153925704485887\n", + "8\n", + "200.71199144935295 -254.33555204217032 14.100965704468562\n", + "36\n", + "200.1707481472364 -243.77102484788355 14.21049086847387\n", + "1\n", + "193.3072394046635 -237.70982077341628 14.072054705773189\n", + "3\n", + "194.16508454198672 -227.9200453839498 14.154188496171534\n", + "46\n", + "193.15763378759846 -216.76541714295493 14.157837128371426\n", + "32\n", + "202.42195419432966 -205.13378789163352 14.032970238681616\n", + "61\n", + "213.1915627748505 -199.33462079598763 14.266929414114978\n", + "1\n", + "204.18383562162228 -185.14232143796474 13.95943528006415\n", + "77\n", + "214.03229895456153 -178.9511876222998 14.268739746686904\n", + "5\n", + "205.58786116500755 -165.30656844590936 14.004273453736138\n", + "17\n", + "196.17214417614449 -156.16112495513215 14.148251433052286\n", + "3\n", + "196.13287054550577 -146.26373205792873 14.134165116046058\n", + "28\n", + "209.10172217876942 -139.53874488370218 14.176870221661744\n", + "38\n", + "208.90235742328434 -129.39372178897725 14.136631213288414\n", + "5\n", + "208.90215771507175 -129.3935223399712 15.710264356339463\n", + "12\n", + "199.16884388685864 -129.91963595849253 15.801568213646695\n", + "27\n", + "194.41545389394815 -124.96981147607907 13.949432719663779\n", + "74\n", + "198.191259271211 -114.45711837941631 14.17555406475015\n", + "0\n", + "198.59810655358672 -109.32488722981503 14.153308183800679\n", + "2\n", + "198.19267079040145 -99.46388666326641 14.16708082059879\n", + "10\n", + "198.19580552767053 -89.79441170803489 14.122342777804063\n", + "68\n", + "196.5347595726375 -73.95934510095917 14.12408596446066\n", + "7\n", + "198.93489108468884 -69.47970775692329 14.15219290793589\n", + "34\n", + "196.83004404240694 -59.70469087894125 14.231210277420338\n", + "6\n", + "196.385044946301 -49.78395065508599 14.133074150961699\n", + "1\n", + "196.4258555314588 -39.812670582666115 14.128575502297739\n", + "0\n", + "201.78204458767289 -38.7225351929523 15.652158202080559\n", + "11\n", + "191.77927704438238 -38.32342785141076 15.684292234312498\n", + "29\n", + "187.3123511869516 -35.172475960338154 14.137002390308652\n", + "63\n", + "191.8717731529215 -28.327658761449552 14.132502305639928\n", + "5\n", + "191.68677787117343 -28.30530107159697 15.735779774714942\n", + "21\n", + "181.8307271551071 -28.306712771725266 15.711068524594346\n", + "action = 0\n", + "action = 0\n", + "action = 0\n", + "action = 0\n", + "action = 0\n", + "action = 1\n", + "20\n", + "191.62262093392553 -28.513934251164496 15.693256175294348\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "89\n", + "195.5546784550435 -25.657566468840873 15.70323473600358\n", + "45\n", + "211.44871060414044 -28.97919686002106 15.706428785606205\n", + "22\n", + "215.66686874824438 -25.84327201747698 15.701400194074129\n", + "18\n", + "221.49371628179236 -28.83246722298514 17.315737527084195\n", + "2\n", + "215.71933974683844 -39.8515625555322 17.28410328671413\n", + "14\n", + "216.34123189373236 -47.52697242449921 17.285672838201886\n", + "44\n", + "216.9512886286976 -58.21794894641573 17.3357575148985\n", + "48\n", + "217.93659941113964 -67.42640176704022 17.238198429947094\n", + "action = 0\n", + "4\n", + "217.93780382792704 -67.42524270207561 15.710831539149721\n", + "1\n", + "207.05274513610675 -68.44097681798905 15.738345959314026\n", + "3\n", + "196.96120714078768 -68.54852829165358 15.698610574720407\n", + "5\n", + "186.9754332712474 -68.6113753528629 15.730160504632542\n", + "3\n", + "186.975159785793 -68.61110808946064 14.138422862123953\n", + "37\n", + "186.43358347650965 -60.29786194140847 14.188124893619124\n", + "52\n", + "186.8552511547929 -48.44180832180174 14.117363111138769\n", + "20\n", + "186.87252782844865 -36.124242223629054 14.145927342707505\n", + "39\n", + "186.786521979947 -26.306924169962794 14.154802554154637\n", + "4\n", + "186.1732560651035 -26.08012091249554 15.717502809803383\n", + "44\n", + "177.0007763176919 -25.88052068378384 15.71483743506594\n", + "86\n", + "176.22056316740492 -26.170132799807778 14.150599366313964\n", + "52\n", + "188.61370845378562 -11.366545331880321 14.021584113148643\n", + "29\n", + "175.74319569506673 -21.461203706726614 15.858039603400162\n", + "42\n", + "179.4077147224832 -9.83170452049844 15.4901276070352\n", + "8\n", + "155.94280655912758 -22.49406376517601 15.900814644049191\n", + "7\n", + "146.01470976229703 -18.501059228576825 15.711920318382894\n", + "59\n", + "135.17734847023212 -25.555288265829684 15.703912055874781\n", + "14\n", + "126.28586172786474 -18.68923223541382 15.703848316374344\n", + "50\n", + "116.21128271204 -19.375814667882153 15.717824219125951\n", + "61\n", + "105.50449136557174 -26.236071214479832 15.700581360355553\n", + "75\n", + "95.1501637845361 -29.81290473710735 15.750563032182104\n", + "24\n", + "86.51157869112195 -19.742985226100473 15.694507865577371\n", + "2\n", + "75.95523554754728 -19.475498995719967 15.710022258950355\n", + "28\n", + "76.40418823982239 -17.94496689314085 17.29411507936588\n", + "28\n", + "76.4127546419326 -27.904423793419202 17.265732226480417\n", + "82\n", + "76.02709184914302 -39.766200543750756 17.27202239482278\n", + "1\n", + "75.30230572586336 -48.978136681210856 17.286631402718655\n", + "40\n", + "75.14736916617095 -66.91522976993423 17.28484616805595\n", + "8\n", + "76.01722471633889 -68.6321393821908 17.2980575034748\n", + "63\n", + "85.33487886434823 -61.33406485149929 17.212775818885238\n", + "95\n", + "80.12607363123422 -91.46442617543923 17.369363979642102\n", + "96\n", + "73.53978274631397 -98.7796368803569 17.150320714370157\n", + "action = 0\n", + "52\n", + "72.96785946388785 -108.6779775845618 17.2917528201657\n", + "8\n", + "72.91664026506201 -118.55377366018332 17.2554254325788\n", + "99\n", + "78.7112707338506 -118.23990298593748 18.96216931995525\n", + "16\n", + "82.91863612355877 -119.02719683050682 18.75896959985064\n", + "4\n", + "82.92277972290891 -119.03172955524774 17.279772866878492\n", + "19\n", + "82.65629621999501 -129.33159248433088 17.255620845546193\n", + "7\n", + "89.5613042063681 -139.12317201270878 18.95573317382652\n", + "52\n", + "92.68260160261258 -129.76364131258376 18.756602025895127\n", + "13\n", + "108.92308053503193 -136.7034833848109 18.950349329661087\n", + "45\n", + "112.8245277512484 -130.56996265976363 18.765439112426446\n", + "0\n", + "128.04172124482392 -142.54459260338928 18.76711208238938\n", + "action = 0\n", + "10\n", + "113.4392156022644 -141.49297867863083 18.879624848392968\n", + "20\n", + "107.83760978081496 -141.18067285410575 18.777373642057206\n", + "1\n", + "93.40364778656827 -130.78564671963048 18.95696318724585\n", + "1\n", + "82.79308459249197 -133.792109632579 18.842790675230162\n", + "74\n", + "77.69001938466141 -142.91288399453418 18.86822333194748\n", + "15\n", + "73.50766125685487 -133.8650418663604 20.42475747387932\n", + "3\n", + "73.93574888845853 -133.65065237720734 20.45038091556736\n", + "18\n", + "73.4657762964419 -113.96227989570075 20.409618336537093\n", + "23\n", + "73.38969888625365 -104.05440595148623 20.446135849987016\n", + "32\n", + "73.7531865360718 -94.03910117088158 20.39480866384957\n", + "33\n", + "73.90024850693499 -83.93694195588746 20.39907895756574\n", + "1\n", + "74.1117398475641 -73.99680442379088 20.390105120662625\n", + "37\n", + "81.49561458459095 -71.33470803824805 20.44869229352783\n", + "11\n", + "77.29833512367203 -53.774633371856694 20.42529244775718\n", + "5\n", + "77.08316328394744 -42.62843144512638 20.400490067711495\n", + "2\n", + "77.42203913739115 -32.212777699843585 20.407305436312633\n", + "51\n", + "78.22135119859642 -23.498728417417425 20.435936002912165\n", + "29\n", + "82.10089589993754 -21.995021077568342 20.388648560635595\n", + "46\n", + "72.2975313317351 -11.867861121584369 22.08739845605154\n", + "11\n", + "68.18960985942005 -13.44453575258543 21.949152252766257\n", + "6\n", + "67.34132310011654 -11.676663399642864 20.386136907748888\n", + "49\n", + "72.76175491718774 -11.42623803161234 20.378791529680512\n", + "56\n", + "65.01172818826237 6.063224064666821 20.483758910554517\n", + "39\n", + "68.54836765271777 16.855519706489794 20.405560647622277\n", + "78\n", + "67.84936919647376 28.339509290979905 20.395241123868217\n", + "8\n", + "67.80156039990091 36.979782392315634 20.450587711753226\n", + "11\n", + "66.17370043982169 47.56394908898122 20.361477050899072\n", + "17\n", + "70.57609071281307 48.852908993673616 20.538833502217976\n", + "48\n", + "79.02968332952562 58.12674879805631 20.24736524142318\n", + "5\n", + "69.30220766391609 78.52906658632847 20.518073326647556\n", + "78\n", + "67.27414117598344 78.18842993011171 20.412600183343173\n", + "15\n", + "65.53072263694816 95.39901795998406 20.421959165191982\n", + "7\n", + "70.01914571990353 108.86590269810549 20.36969878097521\n", + "action = 0\n", + "62\n", + "67.21627069150787 98.36775423354915 18.90525951482646\n", + "5\n", + "77.57811912553791 106.68509003148452 18.827231571715647\n", + "10\n", + "78.54257422139402 108.4171677872705 20.44935845997429\n", + "14\n", + "81.65675878161021 109.5777978292822 20.462875877277458\n", + "69\n", + "78.98808067686954 126.49250831336842 20.30810688257089\n", + "39\n", + "66.59471622774691 127.6774311247094 18.96553124606816\n", + "77\n", + "88.960215632422 128.34537366740005 18.792432758507868\n", + "81\n", + "88.96158915214801 128.34666746222322 20.41848835264269\n", + "13\n", + "75.01105099075636 138.6843183515588 20.487159590256834\n", + "21\n", + "87.82390567838898 134.94381416847176 18.72108763627566\n", + "74\n", + "96.07790876239088 137.16489429930888 18.892816465237377\n", + "66\n", + "112.99988026900624 129.14469733298466 18.838475493411764\n", + "98\n", + "122.98136763921858 129.43613567126863 18.85898265758818\n", + "27\n", + "122.97966604004661 129.43782493858987 17.276024163527598\n", + "69\n", + "116.03660879262914 126.52585935268547 17.25794905404467\n", + "action = 0\n", + "50\n", + "117.43523449892388 134.48915598022444 17.212723354344273\n", + "6\n", + "119.1662603559316 132.74629562735785 15.68779141254251\n", + "19\n", + "109.8175423970183 132.44535019863824 15.722733704966885\n", + "75\n", + "95.96036201647819 135.9668849506219 15.828696093273571\n", + "6\n", + "89.74396066315185 132.75134271542635 15.659336579960364\n", + "19\n", + "76.58310854243099 135.65288355925503 15.720362391924256\n", + "29\n", + "76.57668853817364 135.65916211982693 14.146334925739552\n", + "74\n", + "76.41851139157262 145.86067374599781 14.158582148468073\n", + "10\n", + "81.3246820711547 151.75233711853485 14.052067292605463\n", + "49\n", + "75.8917758193084 165.84489647998106 14.232330302097168\n", + "50\n", + "76.33927672773552 175.54308216193363 14.109206606519578\n", + "38\n", + "76.5394905689393 185.44189973418506 14.124545589694474\n", + "2\n", + "86.51262680546981 194.58451196530413 14.038718757596671\n", + "5\n", + "80.05658442362284 206.94132038289104 14.177868607673544\n", + "12\n", + "78.03196002659647 207.8232672309546 12.612331650259708\n", + "28\n", + "90.10997990402069 206.76888440572722 12.53656666504879\n", + "14\n", + "88.21437459541187 208.12642678937772 14.181774392071599\n", + "42\n", + "98.63188059314652 212.97456071554817 14.001449342108437\n", + "65\n", + "100.0743542510635 223.11598059858022 14.107131752155754\n", + "83\n", + "87.48987373600308 238.52806883663558 14.261156115518375\n", + "action = 0\n", + "8\n", + "86.78890413417355 248.99871622065052 14.129246280786301\n", + "53\n", + "86.14389628845814 259.10879110980767 14.240573702718013\n", + "59\n", + "88.74032314606822 268.8798895017892 13.940323440850896\n", + "8\n", + "93.97029248890993 273.3226208739374 14.14312286819531\n", + "17\n", + "88.30348527468487 279.20893474563064 12.635513867374343\n", + "31\n", + "104.04371172520143 273.1931674263887 12.546177764959086\n", + "88\n", + "104.03859150025588 273.1881642705846 14.136950533189836\n", + "52\n", + "100.02137616795378 287.94731278937326 14.106910966117663\n", + "48\n", + "96.93096776539518 283.7518997903841 12.582849375192028\n", + "75\n", + "106.80955196007234 289.61820876204234 12.633147749533391\n", + "action = 0\n", + "3\n", + "132.8735055247767 282.49160664716237 12.355074411718203\n", + "46\n", + "128.80947698784334 288.9228165812066 12.754911222301255\n", + "44\n", + "135.6080031171879 292.82552802879434 12.561315007298969\n", + "93\n", + "146.61833987151593 290.39462763970795 12.509419830776691\n", + "8\n", + "173.12208716150565 281.49707275593323 12.558146195745472\n", + "48\n", + "175.2801507628043 281.2868820372556 14.091889876182645\n", + "52\n", + "157.22244242083428 300.91751131551126 14.300868861503512\n", + "31\n", + "154.5378133665829 312.3342837355733 14.083959836228333\n", + "11\n", + "156.68283514210165 320.7817365269714 14.157101219282152\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "41\n", + "156.3139603008257 331.4199825471643 14.104208976366833\n", + "action = 0\n", + "14\n", + "154.6819144552786 322.3062487009328 14.09099088441264\n", + "8\n", + "156.1698155251742 321.75582432022657 12.578721720637338\n", + "81\n", + "165.3706226584607 321.9689816174259 12.519597339377746\n", + "54\n", + "176.2348526447492 319.75877862326865 12.56762451855545\n", + "53\n", + "186.37256610519484 321.9104596237409 12.57704369637371\n", + "37\n", + "217.09316806312287 301.0301212038451 12.42092896577203\n", + "26\n", + "196.26555805291989 319.73459987827846 14.26045024208769\n", + "15\n", + "180.3582173492668 347.227398714468 14.273861571813738\n", + "14\n", + "192.96422303594036 343.4441703643497 14.104481512725776\n", + "77\n", + "193.1895654600177 353.68482152824 14.14403185602059\n", + "13\n", + "193.23933131652947 363.6868149887055 14.120782402939216\n", + "2\n", + "193.23267993787212 363.6935794996742 15.70702307658935\n", + "16\n", + "209.69968124735618 350.69066027595954 15.506214331780292\n", + "action = 0\n", + "37\n", + "223.82490917837333 341.5321302932987 15.738017216168394\n", + "22\n", + "216.77699137977643 350.63501814401644 17.30185849522653\n", + "33\n", + "216.8495070571865 340.7516175415652 17.27002390926656\n", + "7\n", + "182.47860002891127 358.5348177067252 17.442496528576896\n", + "5\n", + "183.12922972702438 348.7522928114243 17.234371803951284\n", + "63\n", + "183.53259715485063 349.02458788641565 15.764958997513405\n", + "3\n", + "173.07805468049537 349.0394396350545 15.651744958736256\n", + "13\n", + "173.17530329420322 348.5096636578807 17.320617581662304\n", + "27\n", + "172.83867746768047 338.99774541670007 17.229705686339376\n", + "87\n", + "184.52712486530703 327.4987974673856 15.606404627700494\n", + "11\n", + "164.32486378255157 336.3495595399484 15.888898585966114\n", + "39\n", + "164.48351658002358 328.7338540555916 15.53863353494412\n", + "35\n", + "144.22443591942888 334.42883369130357 15.899375810833927\n", + "5\n", + "148.40029399517098 324.86830222929825 15.639179069216716\n", + "6\n", + "136.8175964558974 330.42596003532145 15.618694878622755\n", + "13\n", + "126.60789423221478 331.6680341659684 15.666416378610936\n", + "4\n", + "124.09620535955489 331.6663538141491 17.286917556780224\n", + "81\n", + "126.46791328365741 321.60746870930745 17.253856540792828\n", + "14\n", + "150.9886399436276 314.05237481345296 15.548534225865446\n", + "98\n", + "116.52111594363235 320.6049632288266 15.836035470002816\n", + "47\n", + "105.18519402281524 321.8375780983428 15.710883329230901\n", + "65\n", + "94.70875238659764 321.21652256548884 15.723054575553444\n", + "70\n", + "84.59265727615083 317.07467153494736 15.760510495001672\n", + "59\n", + "76.9884157040738 317.6404598295125 15.66916262334301\n", + "1\n", + "64.61861318379788 316.63846302211005 15.750329331204208\n", + "3\n", + "57.16428734304854 316.3094463457086 15.720869969005374\n", + "67\n", + "44.86135264481855 316.42542334891925 15.698423838310356\n", + "20\n", + "61.08873687294752 325.58731967423273 15.555617900627063\n", + "30\n", + "25.24744501369133 315.5091420028153 15.836175375875651\n", + "15\n", + "15.319583248633403 320.508414744273 15.731003426209874\n", + "1\n", + "5.370252320040372 320.46501865550727 15.69372319050748\n", + "33\n", + "22.18759140685247 330.3657509724134 15.573756485741699\n", + "45\n", + "-14.23109662507094 316.4029244742542 15.87527427609954\n", + "36\n", + "-22.800241883732493 311.2659872032036 15.776831398606737\n", + "69\n", + "-34.86391679074219 309.2546878589533 15.67760017381799\n", + "23\n", + "-45.300227317557145 309.18393270664 15.69048785977424\n", + "13\n", + "-63.14134122665755 299.41589683129354 15.696757686638785\n", + "action = 0\n", + "85\n", + "-63.292766310469595 310.53849781554453 15.745020186229047\n", + "31\n", + "-74.27407988027635 323.50071682186064 15.557388084222579\n", + "23\n", + "-84.37754839834794 324.36149423519754 15.68897009306186\n", + "32\n", + "-94.1669546123228 323.1749157659219 15.762145742342705\n", + "57\n", + "-104.18024260400891 324.60980957381287 15.681068089051324\n", + "1\n", + "-114.50284573410161 317.45548225601993 15.702974988727005\n", + "17\n", + "-133.11799027901088 297.7124046614033 15.755532448900572\n", + "79\n", + "-133.9852050526833 306.9316908231855 15.803920569818153\n", + "66\n", + "-144.51006119355287 321.10804281758885 15.579651511017893\n", + "action = 0\n", + "88\n", + "-144.57969539454695 313.055264243142 17.339266008013976\n", + "13\n", + "-142.78867355462134 300.2498864552979 17.371595671656856\n", + "2\n", + "-142.68377443780938 300.21256156303764 18.865962180117364\n", + "33\n", + "-132.82370219256694 289.2019284143777 18.86269304670748\n", + "41\n", + "-123.07238197523034 307.1720048243251 18.80992579520172\n", + "29\n", + "-88.90944773944445 331.01487190459954 18.662005638588095\n", + "17\n", + "-103.1398546117735 291.4644395529581 19.091692853140643\n", + "13\n", + "-69.27923209259924 327.87644426224955 18.598595097232828\n", + "10\n", + "-59.2532929934717 326.77374362800066 18.880880962100548\n", + "31\n", + "-49.18421953300573 327.08926097064415 18.87829284184947\n", + "17\n", + "-64.04318017982033 305.7829113201684 19.01870034041244\n", + "13\n", + "-54.283749726309 308.3961031370421 18.86771559224551\n", + "4\n", + "-43.15731659393422 310.1859362695507 18.854212661717817\n", + "50\n", + "-33.74562853833383 301.2621434337125 18.94141366546367\n", + "13\n", + "-23.11331475974864 308.0872236268865 18.77027748641728\n", + "43\n", + "-13.344529390936371 310.93163473619506 18.914142378079347\n", + "25\n", + "-2.8968872077591197 307.99188540786486 18.76232518156022\n", + "49\n", + "6.901584083508663 307.70950396053377 18.90132386579118\n", + "20\n", + "15.68850373757742 305.3998096905365 18.855067724062504\n", + "7\n", + "25.862628651285522 305.3376063565246 18.81391740401611\n", + "44\n", + "36.614164386510744 306.53058364405547 18.792316623481867\n", + "37\n", + "45.81241121927515 305.4927931533674 18.883938164816808\n", + "31\n", + "46.81729352350698 307.71489255127324 17.317703832435665\n", + "2\n", + "45.638644799820824 295.59827943057644 17.233128159724654\n", + "0\n", + "45.702796552182036 289.69074874422625 17.31101791478621\n", + "5\n", + "45.32082788932725 275.50006980897916 17.223812086397196\n", + "24\n", + "48.40321745534343 267.2669293020533 17.386357244525787\n", + "0\n", + "44.90459647592725 255.4538242166233 17.216926033270866\n", + "91\n", + "44.64851490700103 245.35755394192128 17.289964824540323\n", + "47\n", + "44.76257374503488 235.1789082175148 17.28783785302495\n", + "24\n", + "44.78849576352161 228.75899944848152 17.29368985080909\n", + "20\n", + "49.92268935408325 213.84377288871133 17.306168727257987\n", + "62\n", + "52.81600652787779 207.5955745718151 17.340845808184618\n", + "7\n", + "48.11176547335874 193.9601462542535 17.14562078964594\n", + "40\n", + "45.83243036767198 187.13429390887686 17.346498006250616\n", + "42\n", + "43.686158934328894 189.97570841858766 15.642648491461683\n", + "1\n", + "38.544792932063345 183.85470906871387 15.70631203447525\n", + "14\n", + "38.54266293978652 183.85257363362868 17.283506318020684\n", + "23\n", + "39.04095774974857 173.64919609899044 17.29258155794929\n", + "44\n", + "38.3457184447385 172.990057420664 15.718961196557123\n", + "18\n", + "28.482434291740315 173.99840633443253 15.698827601289286\n", + "84\n", + "18.68191998308754 174.66207292526713 15.69180503608471\n", + "67\n", + "11.304277040734622 170.84668392476883 15.83547627544105\n", + "53\n", + "-1.2860265380630906 175.06492043282918 15.586948942359902\n", + "57\n", + "-11.37217746390504 175.9966602337913 15.695995062652258\n", + "68\n", + "-21.092067431171643 175.68398879741636 15.723526052261093\n", + "54\n", + "-31.03639231467835 175.82160034761822 15.722059337113095\n", + "5\n", + "-40.59338724090238 180.5351163265041 15.625035800448451\n", + "41\n", + "-51.19338630250316 175.01206643489076 15.779573094670587\n", + "action = 1\n", + "9\n", + "-42.35839191364086 177.56923196761795 15.643920020179968\n", + "8\n", + "-30.549546843862196 175.64517425710503 15.745896576593529\n", + "74\n", + "-21.479703165370218 178.8393300797397 15.809639392567497\n", + "6\n", + "-12.406993512020598 179.13550600672974 15.61954024798219\n", + "0\n", + "-1.6956489302176045 176.9121137477816 15.69927541185512\n", + "4\n", + "6.784360395763798 178.17418837004618 15.826669143070133\n", + "24\n", + "18.74766723135926 177.71368697217764 15.63894507520364\n", + "9\n", + "27.801881888017213 174.90942813088174 15.613473972917294\n", + "34\n", + "37.16897956053137 177.7794192730749 15.793671886383855\n", + "34\n", + "47.42954305337861 177.91219949881418 15.66946237819967\n", + "5\n", + "59.076416495596824 176.08215839613828 15.730307195841547\n", + "40\n", + "66.89019999231088 179.0946249126177 15.768407723704044\n", + "8\n", + "77.48669334777497 177.83051867959327 15.653434396098103\n", + "38\n", + "86.6885109010823 176.2660385299906 15.77664983314372\n", + "47\n", + "86.89058815450673 179.01021518331228 17.207135678652854\n", + "18\n", + "87.06006445729301 166.2684947711675 17.350357785758586\n", + "75\n", + "88.05624486891259 162.67316431371148 17.25468066030735\n", + "63\n", + "87.62542213240454 146.50491367592502 17.324821857586844\n", + "action = 0\n", + "11\n", + "89.6211025463031 154.32105727278878 15.652209676603043\n", + "73\n", + "75.69955991339337 149.32904383924216 15.728328788409101\n", + "2\n", + "68.13376412626224 150.53657138879666 15.740627279351296\n", + "9\n", + "55.48291047359903 144.57084798133303 15.644496916855966\n", + "33\n", + "47.99628568749829 150.94707583853176 15.704431420392115\n", + "4\n", + "36.84710194797036 147.34738759749467 15.689220211913986\n", + "24\n", + "26.41060262133474 145.53691004294157 15.695890636585188\n", + "16\n", + "16.545611863168844 146.08559095152725 15.705508760442251\n", + "25\n", + "10.018849579341854 147.49400728946625 15.7756994616249\n", + "59\n", + "-3.008592025517398 147.07218509106193 15.666645439088512\n", + "44\n", + "-13.045450633785842 147.22758812201656 15.718735231420904\n", + "57\n", + "-23.09444786661586 147.5865019829934 15.69181871876648\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "39\n", + "-33.39035581104916 146.5737315453392 15.68257374976938\n", + "5\n", + "-40.894740642447786 147.62264884749519 15.683453419249576\n", + "16\n", + "-50.44273141663942 149.44625293359837 15.661859115525345\n", + "8\n", + "-61.224285901525334 151.04910871211675 15.764084796505514\n", + "48\n", + "-69.5953781984026 145.76179507148632 15.818120708198359\n", + "24\n", + "-79.00581521712968 139.62982334474893 15.79899528568263\n", + "27\n", + "-89.15188476913171 139.17476426859193 15.706550436641704\n", + "40\n", + "-100.76997848559084 144.85624014946094 15.5611838497261\n", + "98\n", + "-108.13069694848909 150.25060302258728 15.781985393773535\n", + "41\n", + "-122.35947832907001 156.79331329837635 15.533600646246013\n", + "95\n", + "-129.8658326661233 145.3280124589276 15.895134355223592\n", + "43\n", + "-140.425336688271 156.88404973793976 15.499593730501052\n", + "95\n", + "-150.44663288077714 148.939689553911 15.871681175001486\n", + "9\n", + "-161.52717917700207 176.87877595228622 15.437834087009975\n", + "92\n", + "-171.76468245943528 175.92353117876138 15.863996418928254\n", + "37\n", + "-181.76195859951724 148.15332187562427 15.804160646156411\n", + "action = 0\n", + "27\n", + "-191.74619023954784 147.1014729764051 15.757420635563099\n", + "38\n", + "-201.91969252880872 146.67413515635047 15.742481714653113\n", + "47\n", + "-211.92536308055043 148.86161612545146 15.612994543934263\n", + "41\n", + "-221.2619378507075 147.48516334877922 15.71612138012252\n", + "38\n", + "-231.85793156109747 149.09558674418287 15.697350302572504\n", + "0\n", + "-239.3563175097231 134.02545034669023 15.866842623050163\n", + "95\n", + "-251.76720063026406 149.97073773676186 15.51420288196775\n", + "0\n", + "-256.68195940465404 142.75277566506242 15.723971534047068\n", + "24\n", + "-266.63376979798545 142.2787872776317 15.74699782958938\n", + "action = 0\n", + "6\n", + "-280.8636716201385 138.98083101790593 15.763909917814912\n", + "42\n", + "-289.7128802549409 130.4600153893556 15.721921209731997\n", + "43\n", + "-299.552280367491 130.38858219245947 15.708527030470027\n", + "50\n", + "-310.40946909056004 159.34536566451433 15.549690433461064\n", + "84\n", + "-322.2233012734579 153.48044464676298 15.798911967156188\n", + "53\n", + "-328.49478592565737 126.77676105006867 15.865657416582964\n", + "38\n", + "-340.4023080435501 161.09377344667826 15.545639409728775\n", + "27\n", + "-352.10031975804037 151.66537739923433 15.79661739206934\n", + "70\n", + "-360.68115017217826 162.06047320692065 15.658952807774563\n", + "53\n", + "-370.6466149858196 159.6557962674954 15.681070389869078\n", + "action = 0\n", + "50\n", + "-362.51977317138494 151.72124559188137 15.766304454699311\n", + "91\n", + "-350.47982579697566 159.34275735900465 15.625798776957271\n", + "39\n", + "-342.0181874191574 152.70948778933567 15.783173185330048\n", + "68\n", + "-330.4975644558536 161.63355789898804 15.728965489143002\n", + "51\n", + "-320.5466406130471 161.71136609476838 15.702329190190035\n", + "4\n", + "-312.1382054995258 155.33396330365522 15.787048612495179\n", + "12\n", + "-302.3186836884235 153.06601828029787 15.640081991148232\n", + "37\n", + "-292.2142697122938 151.4710315205292 15.654694328058822\n", + "8\n", + "-282.07966894467836 153.52558658967072 15.80297967501024\n", + "96\n", + "-266.2075107062281 137.60614500429332 15.735758225055891\n", + "79\n", + "-256.60115653866325 138.6356965579955 15.692891215507467\n", + "6\n", + "-251.76056055692928 153.77066134114241 15.669562224960137\n", + "0\n", + "-241.95972122444164 153.356672922034 15.71331305854471\n", + "0\n", + "-232.23697661644383 154.13326168585982 15.704270773357276\n", + "11\n", + "-220.83501071302874 152.52452672837504 15.68999795104942\n", + "37\n", + "-210.91818951883351 152.60321880685092 15.741855828769793\n", + "80\n", + "-201.7827804366221 154.4337300151101 15.714872463153704\n", + "29\n", + "-192.02190453239874 152.517490221744 15.660398061292252\n", + "21\n", + "-181.75891647771067 153.0574084059836 15.74583544137289\n", + "18\n", + "-172.12566432014154 151.9499553956513 15.665730530767988\n", + "42\n", + "-161.93397292457882 148.8100185709739 15.788018486296123\n", + "22\n", + "-151.76015669414787 153.6219466750054 15.686625081993618\n", + "10\n", + "-141.96797961854364 151.67939630856978 15.778468701213853\n", + "74\n", + "-132.3590699731543 147.16129112729118 15.694108289373597\n", + "0\n", + "-122.09377647343604 152.73294181092203 15.686825941240173\n", + "23\n", + "-111.98073810744442 152.78884638962654 15.739445461793878\n", + "5\n", + "-101.83187406157138 152.861565759908 15.691220174849537\n", + "7\n", + "-102.24992736789682 152.4571791641606 17.261197306011788\n", + "9\n", + "-101.3213319685501 138.93235131520737 17.313517668238298\n", + "31\n", + "-101.5354943694793 132.89688278357437 17.30110532239448\n", + "75\n", + "-103.15236477462325 124.18935703269247 17.181507634361413\n", + "25\n", + "-101.07673798534644 113.03963041134433 17.33794564528383\n", + "90\n", + "-100.59910614069156 102.52197529332736 17.331092438556016\n", + "26\n", + "-104.1291686828499 89.6818548481529 17.22292340096911\n", + "7\n", + "-103.08250411980966 79.54741614886886 17.29774884325758\n", + "3\n", + "-104.05832116112002 72.87304938456982 17.205803096630877\n", + "25\n", + "-104.86561315759154 62.735935873682294 17.29944800771372\n", + "2\n", + "-104.65636925863046 52.62331652695447 17.292560909673426\n", + "action = 0\n", + "5\n", + "-102.71784448252173 42.957762595423986 17.25458906562203\n", + "16\n", + "-104.09457358136139 30.3886734920397 17.316349233812044\n", + "94\n", + "-103.58113347019801 22.16349621604067 17.233537244098148\n", + "61\n", + "-103.01968437007261 12.716737850394399 17.362057591204607\n", + "79\n", + "-91.89767742330982 3.1203214123812835 17.362107612968362\n", + "95\n", + "-104.1421146591899 -7.961041774244952 17.198779076588583\n", + "43\n", + "-103.74346880275932 -20.148585780734575 17.316491242006336\n", + "1\n", + "-103.33072043940365 -30.10866917216135 17.270599849678476\n", + "75\n", + "-91.59901012987591 -30.621097339642034 17.346613869908676\n", + "action = 0\n", + "16\n", + "-103.83094130934384 -37.354466009801975 18.765162064788516\n", + "53\n", + "-93.41327639561597 -40.10977899590495 18.90446211273202\n", + "9\n", + "-83.25495183171589 -39.83158828697811 18.87932925538698\n", + "59\n", + "-73.71355202623215 -38.19963697972113 18.800112747229647\n", + "35\n", + "-63.20601829719556 -38.9066871905868 18.95237692026745\n", + "2\n", + "-63.489216789673755 -39.91832295642279 17.230814015781938\n", + "69\n", + "-64.55937146621453 -48.67511778637396 17.208479217088307\n", + "26\n", + "-64.97991218625349 -58.65576001319484 17.289154264649127\n", + "40\n", + "-52.680367643675 -65.47952242241807 17.334876154387374\n", + "90\n", + "-60.38793101558858 -79.28635141391636 17.333521894314188\n", + "13\n", + "-53.88737476642122 -85.70119417408543 17.193988524756644\n", + "action = 0\n", + "39\n", + "-61.86500295343982 -89.5339085633321 15.818526046097496\n", + "13\n", + "-64.25609113407252 -79.5408947009326 15.58140116354133\n", + "29\n", + "-74.95985520824468 -82.6074921796887 15.665832293843081\n", + "75\n", + "-95.03150521741837 -89.33009775390083 15.846680057713984\n", + "10\n", + "-89.76922664989134 -90.58881394991865 17.2826916185525\n", + "1\n", + "-94.69999754322967 -96.23011067241211 17.130095997158435\n", + "18\n", + "-97.60399859019896 -107.34222819908145 17.300944645827244\n", + "3\n", + "-97.6021649255242 -107.34034908879633 15.708465013256836\n", + "35\n", + "-105.6273383396967 -107.8318768619108 15.747509681841388\n", + "10\n", + "-93.64527604850608 -108.68815398299266 17.383140532927733\n", + "1\n", + "-106.18385048377908 -117.61243032819483 17.16620489265439\n", + "22\n", + "-108.07056295139759 -117.44631203705342 15.709008285622144\n", + "12\n", + "-127.3015614410063 -106.9464473372989 15.447084337130708\n", + "47\n", + "-121.18299353217867 -115.88410175127706 17.42906962732604\n", + "90\n", + "-115.9255585309381 -127.57456847668355 17.448621353339085\n", + "86\n", + "-115.9260853756948 -127.57519949088228 15.719589751494134\n", + "35\n", + "-130.50583640090898 -117.5057701172676 15.502094754633953\n", + "3\n", + "-136.14256196923725 -127.03952654142734 15.850183903826329\n", + "32\n", + "-149.89834259863247 -124.99873952376292 15.662717892400403\n", + "36\n", + "-141.378025762343 -131.2376377391608 15.810204280085905\n", + "14\n", + "-150.69810712234505 -132.34896021804656 15.715262969225623\n", + "89\n", + "-150.5138453832691 -134.3270093533676 14.170757306915746\n", + "52\n", + "-167.52654709214724 -107.90920232587077 13.852605533521238\n", + "action = 0\n", + "42\n", + "-149.18864828561595 -131.91425162294098 14.379824843605222\n", + "4\n", + "-149.18732423674314 -131.9152885730088 15.708612753837606\n", + "51\n", + "-172.97333618012345 -128.6443702942755 15.655815295854456\n", + "11\n", + "-190.13673137114418 -111.87730992060611 15.61908614095781\n", + "10\n", + "-179.2785596099693 -132.32906979438425 15.81135442539465\n", + "40\n", + "-188.25007711329891 -138.74221606483715 15.744061815725905\n", + "14\n", + "-219.87399958714443 -109.94698191741938 15.575246111575705\n", + "43\n", + "-229.92150295905998 -112.23011366914601 15.741522633669973\n", + "49\n", + "-239.76479494792196 -112.8531559460775 15.73522091993528\n", + "13\n", + "-228.08026960400807 -141.6790628519968 15.743186459509305\n", + "26\n", + "-256.1257667679497 -84.01887234126106 15.33779584859576\n", + "71\n", + "-269.09619953870657 -103.39528765916089 15.91600897952604\n", + "action = 0\n", + "49\n", + "-276.39878024186294 -82.2595344427933 15.564462887016612\n", + "14\n", + "-286.4633026469543 -81.67686124917738 15.735849981778703\n", + "53\n", + "-290.80210564188405 -148.48591430447715 16.131852969304834\n", + "30\n", + "-309.15305504857776 -106.89641979435497 15.482761848659997\n", + "68\n", + "-297.7818131248435 -150.418695129514 15.820717209347093\n", + "52\n", + "-329.1000953899441 -104.43666105974131 15.550172414060395\n", + "9\n", + "-340.2382708343311 -104.55184547121989 15.666659894653966\n", + "20\n", + "-350.3776066419198 -122.30371157644954 15.865391235933552\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1\n", + "-352.0032216761207 -151.27291888760237 15.718761104605068\n", + "10\n", + "-361.9124452328594 -151.37992122357346 15.71435662294111\n", + "action = 0\n", + "no orders in explore\n", + "45\n", + "-336.85497897826235 -161.49233898967478 15.748742479017979\n", + "action = 0\n", + "no orders in explore\n", + "80\n", + "-343.2575169105909 -143.46617553430332 15.625885641332776\n", + "action = 0\n", + "no orders in explore\n", + "3\n", + "-340.0855740527063 -122.33844655559338 15.734950722340391\n" + ] + } + ], + "source": [ + "tk_main(host=socket.gethostname(),port=4244) #'AirujoRasperry',port=4223) #use this to visualize what was learned (or test something)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "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.6.8" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/Code/Pyborg_Robot_Scripts/ThunderBorg3.py b/Code/Pyborg_Robot_Scripts/ThunderBorg3.py new file mode 100644 index 0000000000000000000000000000000000000000..7fe1c8cac1a53092d214ca3d9d45c32486828102 --- /dev/null +++ b/Code/Pyborg_Robot_Scripts/ThunderBorg3.py @@ -0,0 +1,908 @@ +#!/usr/bin/env python +# coding: latin-1 +""" +This module is designed to communicate with the ThunderBorg + +Use by creating an instance of the class, call the Init function, then command as desired, e.g. +import ThunderBorg +TB = ThunderBorg.ThunderBorg() +TB.Init() +# User code here, use TB to control the board + +Multiple boards can be used when configured with different I²C addresses by creating multiple instances, e.g. +import ThunderBorg +TB1 = ThunderBorg.ThunderBorg() +TB2 = ThunderBorg.ThunderBorg() +TB1.i2cAddress = 0x15 +TB2.i2cAddress = 0x1516 +TB1.Init() +TB2.Init() +# User code here, use TB1 and TB2 to control each board separately + +For explanations of the functions available call the Help function, e.g. +import ThunderBorg +TB = ThunderBorg.ThunderBorg() +TB.Help() +See the website at www.piborg.org/thunderborg for more details +""" + +# Import the libraries we need +import io +import fcntl +import types +import time + +# Constant values +I2C_SLAVE = 0x0703 +PWM_MAX = 255 +I2C_MAX_LEN = 6 +VOLTAGE_PIN_MAX = 36.3 # Maximum voltage from the analog voltage monitoring pin +VOLTAGE_PIN_CORRECTION = 0.0 # Correction value for the analog voltage monitoring pin +BATTERY_MIN_DEFAULT = 7.0 # Default minimum battery monitoring voltage +BATTERY_MAX_DEFAULT = 35.0 # Default maximum battery monitoring voltage + +I2C_ID_THUNDERBORG = 0x15 + +COMMAND_SET_LED1 = 1 # Set the colour of the ThunderBorg LED +COMMAND_GET_LED1 = 2 # Get the colour of the ThunderBorg LED +COMMAND_SET_LED2 = 3 # Set the colour of the ThunderBorg Lid LED +COMMAND_GET_LED2 = 4 # Get the colour of the ThunderBorg Lid LED +COMMAND_SET_LEDS = 5 # Set the colour of both the LEDs +COMMAND_SET_LED_BATT_MON = 6 # Set the colour of both LEDs to show the current battery level +COMMAND_GET_LED_BATT_MON = 7 # Get the state of showing the current battery level via the LEDs +COMMAND_SET_A_FWD = 8 # Set motor A PWM rate in a forwards direction +COMMAND_SET_A_REV = 9 # Set motor A PWM rate in a reverse direction +COMMAND_GET_A = 10 # Get motor A direction and PWM rate +COMMAND_SET_B_FWD = 11 # Set motor B PWM rate in a forwards direction +COMMAND_SET_B_REV = 12 # Set motor B PWM rate in a reverse direction +COMMAND_GET_B = 13 # Get motor B direction and PWM rate +COMMAND_ALL_OFF = 14 # Switch everything off +COMMAND_GET_DRIVE_A_FAULT = 15 # Get the drive fault flag for motor A, indicates faults such as short-circuits and under voltage +COMMAND_GET_DRIVE_B_FAULT = 16 # Get the drive fault flag for motor B, indicates faults such as short-circuits and under voltage +COMMAND_SET_ALL_FWD = 17 # Set all motors PWM rate in a forwards direction +COMMAND_SET_ALL_REV = 18 # Set all motors PWM rate in a reverse direction +COMMAND_SET_FAILSAFE = 19 # Set the failsafe flag, turns the motors off if communication is interrupted +COMMAND_GET_FAILSAFE = 20 # Get the failsafe flag +COMMAND_GET_BATT_VOLT = 21 # Get the battery voltage reading +COMMAND_SET_BATT_LIMITS = 22 # Set the battery monitoring limits +COMMAND_GET_BATT_LIMITS = 23 # Get the battery monitoring limits +COMMAND_WRITE_EXTERNAL_LED = 24 # Write a 32bit pattern out to SK9822 / APA102C +COMMAND_GET_ID = 0x99 # Get the board identifier +COMMAND_SET_I2C_ADD = 0xAA # Set a new I2C address + +COMMAND_VALUE_FWD = 1 # I2C value representing forward +COMMAND_VALUE_REV = 2 # I2C value representing reverse + +COMMAND_VALUE_ON = 1 # I2C value representing on +COMMAND_VALUE_OFF = 0 # I2C value representing off + +COMMAND_ANALOG_MAX = 0x3FF # Maximum value for analog readings + + +def ScanForThunderBorg(busNumber = 1): + """ +ScanForThunderBorg([busNumber]) + +Scans the I²C bus for a ThunderBorg boards and returns a list of all usable addresses +The busNumber if supplied is which I²C bus to scan, 0 for Rev 1 boards, 1 for Rev 2 boards, if not supplied the default is 1 + """ + found = [] + print('Scanning I²C bus #%d' % (busNumber)) + bus = ThunderBorg() + for address in range(0x03, 0x78, 1): + try: + bus.InitBusOnly(busNumber, address) + i2cRecv = bus.RawRead(COMMAND_GET_ID, I2C_MAX_LEN) + if len(i2cRecv) == I2C_MAX_LEN: + if i2cRecv[1] == I2C_ID_THUNDERBORG: + print('Found ThunderBorg at %02X' % (address)) + found.append(address) + else: + pass + else: + pass + except KeyboardInterrupt: + raise + except: + pass + if len(found) == 0: + print('No ThunderBorg boards found, is bus #%d correct (should be 0 for Rev 1, 1 for Rev 2)' % (busNumber)) + elif len(found) == 1: + print('1 ThunderBorg board found') + else: + print('%d ThunderBorg boards found' % (len(found))) + return found + + +def SetNewAddress(newAddress, oldAddress = -1, busNumber = 1): + """ +SetNewAddress(newAddress, [oldAddress], [busNumber]) + +Scans the I²C bus for the first ThunderBorg and sets it to a new I2C address +If oldAddress is supplied it will change the address of the board at that address rather than scanning the bus +The busNumber if supplied is which I²C bus to scan, 0 for Rev 1 boards, 1 for Rev 2 boards, if not supplied the default is 1 +Warning, this new I²C address will still be used after resetting the power on the device + """ + if newAddress < 0x03: + print('Error, I²C addresses below 3 (0x03) are reserved, use an address between 3 (0x03) and 119 (0x77)') + return + elif newAddress > 0x77: + print('Error, I²C addresses above 119 (0x77) are reserved, use an address between 3 (0x03) and 119 (0x77)') + return + if oldAddress < 0x0: + found = ScanForThunderBorg(busNumber) + if len(found) < 1: + print('No ThunderBorg boards found, cannot set a new I²C address!') + return + else: + oldAddress = found[0] + print('Changing I²C address from %02X to %02X (bus #%d)' % (oldAddress, newAddress, busNumber)) + bus = ThunderBorg() + bus.InitBusOnly(busNumber, oldAddress) + try: + i2cRecv = bus.RawRead(COMMAND_GET_ID, I2C_MAX_LEN) + if len(i2cRecv) == I2C_MAX_LEN: + if i2cRecv[1] == I2C_ID_THUNDERBORG: + foundChip = True + print('Found ThunderBorg at %02X' % (oldAddress)) + else: + foundChip = False + print('Found a device at %02X, but it is not a ThunderBorg (ID %02X instead of %02X)' % (oldAddress, i2cRecv[1], I2C_ID_THUNDERBORG)) + else: + foundChip = False + print('Missing ThunderBorg at %02X' % (oldAddress)) + except KeyboardInterrupt: + raise + except: + foundChip = False + print('Missing ThunderBorg at %02X' % (oldAddress)) + if foundChip: + bus.RawWrite(COMMAND_SET_I2C_ADD, [newAddress]) + time.sleep(0.1) + print('Address changed to %02X, attempting to talk with the new address' % (newAddress)) + try: + bus.InitBusOnly(busNumber, newAddress) + i2cRecv = bus.RawRead(COMMAND_GET_ID, I2C_MAX_LEN) + if len(i2cRecv) == I2C_MAX_LEN: + if i2cRecv[1] == I2C_ID_THUNDERBORG: + foundChip = True + print('Found ThunderBorg at %02X' % (newAddress)) + else: + foundChip = False + print('Found a device at %02X, but it is not a ThunderBorg (ID %02X instead of %02X)' % (newAddress, i2cRecv[1], I2C_ID_THUNDERBORG)) + else: + foundChip = False + print('Missing ThunderBorg at %02X' % (newAddress)) + except KeyboardInterrupt: + raise + except: + foundChip = False + print('Missing ThunderBorg at %02X' % (newAddress)) + if foundChip: + print('New I²C address of %02X set successfully' % (newAddress)) + else: + print('Failed to set new I²C address...') + + +# Class used to control ThunderBorg +class ThunderBorg: + """ +This module is designed to communicate with the ThunderBorg + +busNumber I²C bus on which the ThunderBorg is attached (Rev 1 is bus 0, Rev 2 is bus 1) +bus the smbus object used to talk to the I²C bus +i2cAddress The I²C address of the ThunderBorg chip to control +foundChip True if the ThunderBorg chip can be seen, False otherwise +printFunction Function reference to call when printing text, if None "print" is used + """ + + # Shared values used by this class + busNumber = 1 # Check here for Rev 1 vs Rev 2 and select the correct bus + i2cAddress = I2C_ID_THUNDERBORG # I²C address, override for a different address + foundChip = False + printFunction = None + i2cWrite = None + i2cRead = None + + + def RawWrite(self, command, data): + """ +RawWrite(command, data) + +Sends a raw command on the I2C bus to the ThunderBorg +Command codes can be found at the top of ThunderBorg.py, data is a list of 0 or more byte values + +Under most circumstances you should use the appropriate function instead of RawWrite + """ + rawOutput = [command] + rawOutput.extend(data) + rawOutput = bytes(rawOutput) + self.i2cWrite.write(rawOutput) + + + def RawRead(self, command, length, retryCount = 3): + """ +RawRead(command, length, [retryCount]) + +Reads data back from the ThunderBorg after sending a GET command +Command codes can be found at the top of ThunderBorg.py, length is the number of bytes to read back + +The function checks that the first byte read back matches the requested command +If it does not it will retry the request until retryCount is exhausted (default is 3 times) + +Under most circumstances you should use the appropriate function instead of RawRead + """ + while retryCount > 0: + self.RawWrite(command, []) + rawReply = self.i2cRead.read(length) + reply = [] + for singleByte in rawReply: + reply.append(singleByte) + if command == reply[0]: + break + else: + retryCount -= 1 + if retryCount > 0: + return reply + else: + raise IOError('I2C read for command %d failed' % (command)) + + + def InitBusOnly(self, busNumber, address): + """ +InitBusOnly(busNumber, address) + +Prepare the I2C driver for talking to a ThunderBorg on the specified bus and I2C address +This call does not check the board is present or working, under most circumstances use Init() instead + """ + self.busNumber = busNumber + self.i2cAddress = address + self.i2cRead = io.open("/dev/i2c-" + str(self.busNumber), "rb", buffering = 0) + fcntl.ioctl(self.i2cRead, I2C_SLAVE, self.i2cAddress) + self.i2cWrite = io.open("/dev/i2c-" + str(self.busNumber), "wb", buffering = 0) + fcntl.ioctl(self.i2cWrite, I2C_SLAVE, self.i2cAddress) + + + def Print(self, message): + """ +Print(message) + +Wrapper used by the ThunderBorg instance to print(messages, will call printFunction if set, print otherwise) + """ + if self.printFunction == None: + print(message) + else: + self.printFunction(message) + + + def NoPrint(self, message): + """ +NoPrint(message) + +Does nothing, intended for disabling diagnostic printout by using: +TB = ThunderBorg.ThunderBorg() +TB.printFunction = TB.NoPrint + """ + pass + + + def Init(self, tryOtherBus = False): + """ +Init([tryOtherBus]) + +Prepare the I2C driver for talking to the ThunderBorg + +If tryOtherBus is True, this function will attempt to use the other bus if the ThunderBorg devices can not be found on the current busNumber + This is only really useful for early Raspberry Pi models! + """ + self.Print('Loading ThunderBorg on bus %d, address %02X' % (self.busNumber, self.i2cAddress)) + + # Open the bus + self.i2cRead = io.open("/dev/i2c-" + str(self.busNumber), "rb", buffering = 0) + fcntl.ioctl(self.i2cRead, I2C_SLAVE, self.i2cAddress) + self.i2cWrite = io.open("/dev/i2c-" + str(self.busNumber), "wb", buffering = 0) + fcntl.ioctl(self.i2cWrite, I2C_SLAVE, self.i2cAddress) + + # Check for ThunderBorg + try: + i2cRecv = self.RawRead(COMMAND_GET_ID, I2C_MAX_LEN) + if len(i2cRecv) == I2C_MAX_LEN: + if i2cRecv[1] == I2C_ID_THUNDERBORG: + self.foundChip = True + self.Print('Found ThunderBorg at %02X' % (self.i2cAddress)) + else: + self.foundChip = False + self.Print('Found a device at %02X, but it is not a ThunderBorg (ID %02X instead of %02X)' % (self.i2cAddress, i2cRecv[1], I2C_ID_THUNDERBORG)) + else: + self.foundChip = False + self.Print('Missing ThunderBorg at %02X' % (self.i2cAddress)) + except KeyboardInterrupt: + raise + except: + self.foundChip = False + self.Print('Missing ThunderBorg at %02X' % (self.i2cAddress)) + + # See if we are missing chips + if not self.foundChip: + self.Print('ThunderBorg was not found') + if tryOtherBus: + if self.busNumber == 1: + self.busNumber = 0 + else: + self.busNumber = 1 + self.Print('Trying bus %d instead' % (self.busNumber)) + self.Init(False) + else: + self.Print('Are you sure your ThunderBorg is properly attached, the correct address is used, and the I2C drivers are running?') + self.bus = None + else: + self.Print('ThunderBorg loaded on bus %d' % (self.busNumber)) + + + def SetMotor2(self, power): + """ +SetMotor2(power) + +Sets the drive level for motor 2, from +1 to -1. +e.g. +SetMotor2(0) -> motor 2 is stopped +SetMotor2(0.75) -> motor 2 moving forward at 75% power +SetMotor2(-0.5) -> motor 2 moving reverse at 50% power +SetMotor2(1) -> motor 2 moving forward at 100% power + """ + if power < 0: + # Reverse + command = COMMAND_SET_B_REV + pwm = -int(PWM_MAX * power) + if pwm > PWM_MAX: + pwm = PWM_MAX + else: + # Forward / stopped + command = COMMAND_SET_B_FWD + pwm = int(PWM_MAX * power) + if pwm > PWM_MAX: + pwm = PWM_MAX + + try: + self.RawWrite(command, [pwm]) + except KeyboardInterrupt: + raise + except: + self.Print('Failed sending motor 2 drive level!') + + + def GetMotor2(self): + """ +power = GetMotor2() + +Gets the drive level for motor 2, from +1 to -1. +e.g. +0 -> motor 2 is stopped +0.75 -> motor 2 moving forward at 75% power +-0.5 -> motor 2 moving reverse at 50% power +1 -> motor 2 moving forward at 100% power + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_B, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading motor 2 drive level!') + return + + power = float(i2cRecv[2]) / float(PWM_MAX) + + if i2cRecv[1] == COMMAND_VALUE_FWD: + return power + elif i2cRecv[1] == COMMAND_VALUE_REV: + return -power + else: + return + + + def SetMotor1(self, power): + """ +SetMotor1(power) + +Sets the drive level for motor 1, from +1 to -1. +e.g. +SetMotor1(0) -> motor 1 is stopped +SetMotor1(0.75) -> motor 1 moving forward at 75% power +SetMotor1(-0.5) -> motor 1 moving reverse at 50% power +SetMotor1(1) -> motor 1 moving forward at 100% power + """ + if power < 0: + # Reverse + command = COMMAND_SET_A_REV + pwm = -int(PWM_MAX * power) + if pwm > PWM_MAX: + pwm = PWM_MAX + else: + # Forward / stopped + command = COMMAND_SET_A_FWD + pwm = int(PWM_MAX * power) + if pwm > PWM_MAX: + pwm = PWM_MAX + + try: + self.RawWrite(command, [pwm]) + except KeyboardInterrupt: + raise + except: + self.Print('Failed sending motor 1 drive level!') + + + def GetMotor1(self): + """ +power = GetMotor1() + +Gets the drive level for motor 1, from +1 to -1. +e.g. +0 -> motor 1 is stopped +0.75 -> motor 1 moving forward at 75% power +-0.5 -> motor 1 moving reverse at 50% power +1 -> motor 1 moving forward at 100% power + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_A, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading motor 1 drive level!') + return + + power = float(i2cRecv[2]) / float(PWM_MAX) + + if i2cRecv[1] == COMMAND_VALUE_FWD: + return power + elif i2cRecv[1] == COMMAND_VALUE_REV: + return -power + else: + return + + + def SetMotors(self, power): + """ +SetMotors(power) + +Sets the drive level for all motors, from +1 to -1. +e.g. +SetMotors(0) -> all motors are stopped +SetMotors(0.75) -> all motors are moving forward at 75% power +SetMotors(-0.5) -> all motors are moving reverse at 50% power +SetMotors(1) -> all motors are moving forward at 100% power + """ + if power < 0: + # Reverse + command = COMMAND_SET_ALL_REV + pwm = -int(PWM_MAX * power) + if pwm > PWM_MAX: + pwm = PWM_MAX + else: + # Forward / stopped + command = COMMAND_SET_ALL_FWD + pwm = int(PWM_MAX * power) + if pwm > PWM_MAX: + pwm = PWM_MAX + + try: + self.RawWrite(command, [pwm]) + except KeyboardInterrupt: + raise + except: + self.Print('Failed sending all motors drive level!') + + + def MotorsOff(self): + """ +MotorsOff() + +Sets all motors to stopped, useful when ending a program + """ + try: + self.RawWrite(COMMAND_ALL_OFF, [0]) + except KeyboardInterrupt: + raise + except: + self.Print('Failed sending motors off command!') + + + def SetLed1(self, r, g, b): + """ +SetLed1(r, g, b) + +Sets the current colour of the ThunderBorg LED. r, g, b may each be between 0 and 1 +e.g. +SetLed1(0, 0, 0) -> ThunderBorg LED off +SetLed1(1, 1, 1) -> ThunderBorg LED full white +SetLed1(1.0, 0.5, 0.0) -> ThunderBorg LED bright orange +SetLed1(0.2, 0.0, 0.2) -> ThunderBorg LED dull purple + """ + levelR = max(0, min(PWM_MAX, int(r * PWM_MAX))) + levelG = max(0, min(PWM_MAX, int(g * PWM_MAX))) + levelB = max(0, min(PWM_MAX, int(b * PWM_MAX))) + + try: + self.RawWrite(COMMAND_SET_LED1, [levelR, levelG, levelB]) + except KeyboardInterrupt: + raise + except: + self.Print('Failed sending colour for the ThunderBorg LED!') + + + def GetLed1(self): + """ +r, g, b = GetLed1() + +Gets the current colour of the ThunderBorg LED. r, g, b may each be between 0 and 1 +e.g. +0, 0, 0 -> ThunderBorg LED off +1, 1, 1 -> ThunderBorg LED full white +1.0, 0.5, 0.0 -> ThunderBorg LED bright orange +0.2, 0.0, 0.2 -> ThunderBorg LED dull purple + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_LED1, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading ThunderBorg LED colour!') + return + + r = i2cRecv[1] / float(PWM_MAX) + g = i2cRecv[2] / float(PWM_MAX) + b = i2cRecv[3] / float(PWM_MAX) + return r, g, b + + + def SetLed2(self, r, g, b): + """ +SetLed2(r, g, b) + +Sets the current colour of the ThunderBorg Lid LED. r, g, b may each be between 0 and 1 +e.g. +SetLed2(0, 0, 0) -> ThunderBorg Lid LED off +SetLed2(1, 1, 1) -> ThunderBorg Lid LED full white +SetLed2(1.0, 0.5, 0.0) -> ThunderBorg Lid LED bright orange +SetLed2(0.2, 0.0, 0.2) -> ThunderBorg Lid LED dull purple + """ + levelR = max(0, min(PWM_MAX, int(r * PWM_MAX))) + levelG = max(0, min(PWM_MAX, int(g * PWM_MAX))) + levelB = max(0, min(PWM_MAX, int(b * PWM_MAX))) + + try: + self.RawWrite(COMMAND_SET_LED2, [levelR, levelG, levelB]) + except KeyboardInterrupt: + raise + except: + self.Print('Failed sending colour for the ThunderBorg Lid LED!') + + + def GetLed2(self): + """ +r, g, b = GetLed2() + +Gets the current colour of the ThunderBorg Lid LED. r, g, b may each be between 0 and 1 +e.g. +0, 0, 0 -> ThunderBorg Lid LED off +1, 1, 1 -> ThunderBorg Lid LED full white +1.0, 0.5, 0.0 -> ThunderBorg Lid LED bright orange +0.2, 0.0, 0.2 -> ThunderBorg Lid LED dull purple + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_LED2, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading ThunderBorg Lid LED colour!') + return + + r = i2cRecv[1] / float(PWM_MAX) + g = i2cRecv[2] / float(PWM_MAX) + b = i2cRecv[3] / float(PWM_MAX) + return r, g, b + + + def SetLeds(self, r, g, b): + """ +SetLeds(r, g, b) + +Sets the current colour of both LEDs. r, g, b may each be between 0 and 1 +e.g. +SetLeds(0, 0, 0) -> Both LEDs off +SetLeds(1, 1, 1) -> Both LEDs full white +SetLeds(1.0, 0.5, 0.0) -> Both LEDs bright orange +SetLeds(0.2, 0.0, 0.2) -> Both LEDs dull purple + """ + levelR = max(0, min(PWM_MAX, int(r * PWM_MAX))) + levelG = max(0, min(PWM_MAX, int(g * PWM_MAX))) + levelB = max(0, min(PWM_MAX, int(b * PWM_MAX))) + + try: + self.RawWrite(COMMAND_SET_LEDS, [levelR, levelG, levelB]) + except KeyboardInterrupt: + raise + except: + self.Print('Failed sending colour for both LEDs!') + + + def SetLedShowBattery(self, state): + """ +SetLedShowBattery(state) + +Sets the system to enable or disable the LEDs showing the current battery level +If enabled the LED colours will be ignored and will use the current battery reading instead +This sweeps from fully green for maximum voltage (35 V) to fully red for minimum voltage (7 V) + """ + if state: + level = COMMAND_VALUE_ON + else: + level = COMMAND_VALUE_OFF + + try: + self.RawWrite(COMMAND_SET_LED_BATT_MON, [level]) + except KeyboardInterrupt: + raise + except: + self.Print('Failed sending LED battery monitoring state!') + + + def GetLedShowBattery(self): + """ +state = GetLedShowBattery() + +Gets if the system is using the LEDs to show the current battery level, true for enabled, false for disabled +If enabled the LED colours will be ignored and will use the current battery reading instead +This sweeps from fully green for maximum voltage (35 V) to fully red for minimum voltage (7 V) + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_LED_BATT_MON, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading LED battery monitoring state!') + return + + if i2cRecv[1] == COMMAND_VALUE_OFF: + return False + else: + return True + + + def SetCommsFailsafe(self, state): + """ +SetCommsFailsafe(state) + +Sets the system to enable or disable the communications failsafe +The failsafe will turn the motors off unless it is commanded at least once every 1/4 of a second +Set to True to enable this failsafe, set to False to disable this failsafe +The failsafe is disabled at power on + """ + if state: + level = COMMAND_VALUE_ON + else: + level = COMMAND_VALUE_OFF + + try: + self.RawWrite(COMMAND_SET_FAILSAFE, [level]) + except KeyboardInterrupt: + raise + except: + self.Print('Failed sending communications failsafe state!') + + + def GetCommsFailsafe(self): + """ +state = GetCommsFailsafe() + +Read the current system state of the communications failsafe, True for enabled, False for disabled +The failsafe will turn the motors off unless it is commanded at least once every 1/4 of a second + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_FAILSAFE, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading communications failsafe state!') + return + + if i2cRecv[1] == COMMAND_VALUE_OFF: + return False + else: + return True + + + def GetDriveFault1(self): + """ +state = GetDriveFault1() + +Reads the motor drive fault state for motor #1, False for no problems, True for a fault has been detected +Faults may indicate power problems, such as under-voltage (not enough power), and may be cleared by setting a lower drive power +If a fault is persistent, it repeatably occurs when trying to control the board, this may indicate a wiring problem such as: + * The supply is not powerful enough for the motors + The board has a bare minimum requirement of 6V to operate correctly + A recommended minimum supply of 7.2V should be sufficient for smaller motors + * The + and - connections for motor #1 are connected to each other + * Either + or - is connected to ground (GND, also known as 0V or earth) + * Either + or - is connected to the power supply (V+, directly to the battery or power pack) + * One of the motors may be damaged +Faults will self-clear, they do not need to be reset, however some faults require both motors to be moving at less than 100% to clear +The easiest way to check is to put both motors at a low power setting which is high enough for them to rotate easily, such as 30% +Note that the fault state may be true at power up, this is normal and should clear when both motors have been driven +For more details check the website at www.piborg.org/thunderborg and double check the wiring instructions + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_DRIVE_A_FAULT, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading the drive fault state for motor #1!') + return + + if i2cRecv[1] == COMMAND_VALUE_OFF: + return False + else: + return True + + + def GetDriveFault2(self): + """ +state = GetDriveFault2() + +Reads the motor drive fault state for motor #2, False for no problems, True for a fault has been detected +Faults may indicate power problems, such as under-voltage (not enough power), and may be cleared by setting a lower drive power +If a fault is persistent, it repeatably occurs when trying to control the board, this may indicate a wiring problem such as: + * The supply is not powerful enough for the motors + The board has a bare minimum requirement of 6V to operate correctly + A recommended minimum supply of 7.2V should be sufficient for smaller motors + * The + and - connections for motor #2 are connected to each other + * Either + or - is connected to ground (GND, also known as 0V or earth) + * Either + or - is connected to the power supply (V+, directly to the battery or power pack) + * One of the motors may be damaged +Faults will self-clear, they do not need to be reset, however some faults require both motors to be moving at less than 100% to clear +The easiest way to check is to put both motors at a low power setting which is high enough for them to rotate easily, such as 30% +Note that the fault state may be true at power up, this is normal and should clear when both motors have been driven +For more details check the website at www.piborg.org/thunderborg and double check the wiring instructions + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_DRIVE_B_FAULT, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading the drive fault state for motor #2!') + return + + if i2cRecv[1] == COMMAND_VALUE_OFF: + return False + else: + return True + + + def GetBatteryReading(self): + """ +voltage = GetBatteryReading() + +Reads the current battery level from the main input. +Returns the value as a voltage based on the 3.3 V rail as a reference. + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_BATT_VOLT, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading battery level!') + return + + raw = (i2cRecv[1] << 8) + i2cRecv[2] + level = float(raw) / float(COMMAND_ANALOG_MAX) + level *= VOLTAGE_PIN_MAX + return level + VOLTAGE_PIN_CORRECTION + + + def SetBatteryMonitoringLimits(self, minimum, maximum): + """ +SetBatteryMonitoringLimits(minimum, maximum) + +Sets the battery monitoring limits used for setting the LED colour. +The values are between 0 and 36.3 V. +The colours shown range from full red at minimum or below, yellow half way, and full green at maximum or higher. +These values are stored in EEPROM and reloaded when the board is powered. + """ + levelMin = minimum / float(VOLTAGE_PIN_MAX) + levelMax = maximum / float(VOLTAGE_PIN_MAX) + levelMin = max(0, min(0xFF, int(levelMin * 0xFF))) + levelMax = max(0, min(0xFF, int(levelMax * 0xFF))) + + try: + self.RawWrite(COMMAND_SET_BATT_LIMITS, [levelMin, levelMax]) + time.sleep(0.2) # Wait for EEPROM write to complete + except KeyboardInterrupt: + raise + except: + self.Print('Failed sending battery monitoring limits!') + + + def GetBatteryMonitoringLimits(self): + """ +minimum, maximum = GetBatteryMonitoringLimits() + +Reads the current battery monitoring limits used for setting the LED colour. +The values are between 0 and 36.3 V. +The colours shown range from full red at minimum or below, yellow half way, and full green at maximum or higher. + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_BATT_LIMITS, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading battery monitoring limits!') + return + + rawMin = i2cRecv[1] + rawMax = i2cRecv[2] + levelMin = float(rawMin) / float(0xFF) + levelMax = float(rawMax) / float(0xFF) + levelMin *= VOLTAGE_PIN_MAX + levelMax *= VOLTAGE_PIN_MAX + return levelMin, levelMax + + + def WriteExternalLedWord(self, b0, b1, b2, b3): + """ +WriteExternalLedWord(b0, b1, b2, b3) + +Low level serial LED word writing. +Bytes are written MSB first starting from b0 +e.g. +WriteExtermnalLedWord(255, 64, 1, 0) +will write out: +11111111 01000000 00000001 00000000 +to the LEDs. + """ + b0 = max(0, min(PWM_MAX, int(b0))) + b1 = max(0, min(PWM_MAX, int(b1))) + b2 = max(0, min(PWM_MAX, int(b2))) + b3 = max(0, min(PWM_MAX, int(b3))) + + try: + self.RawWrite(COMMAND_WRITE_EXTERNAL_LED, [b0, b1, b2, b3]) + except KeyboardInterrupt: + raise + except: + self.Print('Failed sending word for the external LEDs!') + + + def SetExternalLedColours(self, colours): + """ +SetExternalLedColours([[r, g, b], ..., [r, g, b]]) + +Takes a set of RGB triples to set each LED to. +Each call will set all of the LEDs +e.g. +SetExternalLedColours([[1.0, 1.0, 0.0]]) +will set a single LED to full yellow. +SetExternalLedColours([[1.0, 0.0, 0.0], [0.5, 0.0, 0.0], [0.0, 0.0, 0.0]]) +will set LED 1 to full red, LED 2 to half red, and LED 3 to off. + """ + # Send the start marker + self.WriteExternalLedWord(0, 0, 0, 0) + + # Send each colour in turn + for r, g, b in colours: + self.WriteExternalLedWord(255, 255 * b, 255 * g, 255 * r) + + + def Help(self): + """ +Help() + +Displays the names and descriptions of the various functions and settings provided + """ + funcList = [ThunderBorg.__dict__.get(a) for a in dir(ThunderBorg) if isinstance(ThunderBorg.__dict__.get(a), types.FunctionType)] + funcListSorted = sorted(funcList, key = lambda x: x.func_code.co_firstlineno) + + print(self.__doc__) + print + for func in funcListSorted: + print('=== %s === %s' % (func.func_name, func.func_doc)) + diff --git a/Code/Pyborg_Robot_Scripts/UltraBorg.py b/Code/Pyborg_Robot_Scripts/UltraBorg.py new file mode 100644 index 0000000000000000000000000000000000000000..b259db6f87b04c610eee63571070f7e8c78011db --- /dev/null +++ b/Code/Pyborg_Robot_Scripts/UltraBorg.py @@ -0,0 +1,1840 @@ +#!/usr/bin/env python +# coding: latin-1 +""" +This module is designed to communicate with the UltraBorg + +Use by creating an instance of the class, call the Init function, then command as desired, e.g. +import UltraBorg +UB = UltraBorg.UltraBorg() +UB.Init() +# User code here, use UB to control the board + +Multiple boards can be used when configured with different I²C addresses by creating multiple instances, e.g. +import UltraBorg +UB1 = UltraBorg.UltraBorg() +UB2 = UltraBorg.UltraBorg() +UB1.i2cAddress = 0x44 +UB2.i2cAddress = 0x45 +UB1.Init() +UB2.Init() +# User code here, use UB1 and UB2 to control each board separately + +For explanations of the functions available call the Help function, e.g. +import UltraBorg +UB = UltraBorg.UltraBorg() +UB.Help() +See the website at www.piborg.org/ultraborg for more details +""" + +# Import the libraries we need +import io +import fcntl +import types +import time + +# Constant values +I2C_SLAVE = 0x0703 +I2C_MAX_LEN = 4 +USM_US_TO_MM = 0.171500 +PWM_MIN = 2000 # Should be a 1 ms burst, typical servo minimum +PWM_MAX = 4000 # Should be a 2 ms burst, typical servo maximum +DELAY_AFTER_EEPROM = 0.01 # Time to wait after updating an EEPROM value before reading +PWM_UNSET = 0xFFFF + +I2C_ID_SERVO_USM = 0x36 + +COMMAND_GET_TIME_USM1 = 1 # Get the time measured by ultrasonic #1 in us (0 for no detection) +COMMAND_GET_TIME_USM2 = 2 # Get the time measured by ultrasonic #2 in us (0 for no detection) +COMMAND_GET_TIME_USM3 = 3 # Get the time measured by ultrasonic #3 in us (0 for no detection) +COMMAND_GET_TIME_USM4 = 4 # Get the time measured by ultrasonic #4 in us (0 for no detection) +COMMAND_SET_PWM1 = 5 # Set the PWM duty cycle for drive #1 (16 bit) +COMMAND_GET_PWM1 = 6 # Get the PWM duty cycle for drive #1 (16 bit) +COMMAND_SET_PWM2 = 7 # Set the PWM duty cycle for drive #2 (16 bit) +COMMAND_GET_PWM2 = 8 # Get the PWM duty cycle for drive #2 (16 bit) +COMMAND_SET_PWM3 = 9 # Set the PWM duty cycle for drive #3 (16 bit) +COMMAND_GET_PWM3 = 10 # Get the PWM duty cycle for drive #3 (16 bit) +COMMAND_SET_PWM4 = 11 # Set the PWM duty cycle for drive #4 (16 bit) +COMMAND_GET_PWM4 = 12 # Get the PWM duty cycle for drive #4 (16 bit) +COMMAND_CALIBRATE_PWM1 = 13 # Set the PWM duty cycle for drive #1 (16 bit, ignores limit checks) +COMMAND_CALIBRATE_PWM2 = 14 # Set the PWM duty cycle for drive #2 (16 bit, ignores limit checks) +COMMAND_CALIBRATE_PWM3 = 15 # Set the PWM duty cycle for drive #3 (16 bit, ignores limit checks) +COMMAND_CALIBRATE_PWM4 = 16 # Set the PWM duty cycle for drive #4 (16 bit, ignores limit checks) +COMMAND_GET_PWM_MIN_1 = 17 # Get the minimum allowed PWM duty cycle for drive #1 +COMMAND_GET_PWM_MAX_1 = 18 # Get the maximum allowed PWM duty cycle for drive #1 +COMMAND_GET_PWM_BOOT_1 = 19 # Get the startup PWM duty cycle for drive #1 +COMMAND_GET_PWM_MIN_2 = 20 # Get the minimum allowed PWM duty cycle for drive #2 +COMMAND_GET_PWM_MAX_2 = 21 # Get the maximum allowed PWM duty cycle for drive #2 +COMMAND_GET_PWM_BOOT_2 = 22 # Get the startup PWM duty cycle for drive #2 +COMMAND_GET_PWM_MIN_3 = 23 # Get the minimum allowed PWM duty cycle for drive #3 +COMMAND_GET_PWM_MAX_3 = 24 # Get the maximum allowed PWM duty cycle for drive #3 +COMMAND_GET_PWM_BOOT_3 = 25 # Get the startup PWM duty cycle for drive #3 +COMMAND_GET_PWM_MIN_4 = 26 # Get the minimum allowed PWM duty cycle for drive #4 +COMMAND_GET_PWM_MAX_4 = 27 # Get the maximum allowed PWM duty cycle for drive #4 +COMMAND_GET_PWM_BOOT_4 = 28 # Get the startup PWM duty cycle for drive #4 +COMMAND_SET_PWM_MIN_1 = 29 # Set the minimum allowed PWM duty cycle for drive #1 +COMMAND_SET_PWM_MAX_1 = 30 # Set the maximum allowed PWM duty cycle for drive #1 +COMMAND_SET_PWM_BOOT_1 = 31 # Set the startup PWM duty cycle for drive #1 +COMMAND_SET_PWM_MIN_2 = 32 # Set the minimum allowed PWM duty cycle for drive #2 +COMMAND_SET_PWM_MAX_2 = 33 # Set the maximum allowed PWM duty cycle for drive #2 +COMMAND_SET_PWM_BOOT_2 = 34 # Set the startup PWM duty cycle for drive #2 +COMMAND_SET_PWM_MIN_3 = 35 # Set the minimum allowed PWM duty cycle for drive #3 +COMMAND_SET_PWM_MAX_3 = 36 # Set the maximum allowed PWM duty cycle for drive #3 +COMMAND_SET_PWM_BOOT_3 = 37 # Set the startup PWM duty cycle for drive #3 +COMMAND_SET_PWM_MIN_4 = 38 # Set the minimum allowed PWM duty cycle for drive #4 +COMMAND_SET_PWM_MAX_4 = 39 # Set the maximum allowed PWM duty cycle for drive #4 +COMMAND_SET_PWM_BOOT_4 = 40 # Set the startup PWM duty cycle for drive #4 +COMMAND_GET_FILTER_USM1 = 41 # Get the filtered time measured by ultrasonic #1 in us (0 for no detection) +COMMAND_GET_FILTER_USM2 = 42 # Get the filtered time measured by ultrasonic #2 in us (0 for no detection) +COMMAND_GET_FILTER_USM3 = 43 # Get the filtered time measured by ultrasonic #3 in us (0 for no detection) +COMMAND_GET_FILTER_USM4 = 44 # Get the filtered time measured by ultrasonic #4 in us (0 for no detection) +COMMAND_GET_ID = 0x99 # Get the board identifier +COMMAND_SET_I2C_ADD = 0xAA # Set a new I2C address + +COMMAND_VALUE_FWD = 1 # I2C value representing forward +COMMAND_VALUE_REV = 2 # I2C value representing reverse + +COMMAND_VALUE_ON = 1 # I2C value representing on +COMMAND_VALUE_OFF = 0 # I2C value representing off + + +def ScanForUltraBorg(busNumber = 1): + """ +ScanForUltraBorg([busNumber]) + +Scans the I²C bus for a UltraBorg boards and returns a list of all usable addresses +The busNumber if supplied is which I²C bus to scan, 0 for Rev 1 boards, 1 for Rev 2 boards, if not supplied the default is 1 + """ + found = [] + print 'Scanning I²C bus #%d' % (busNumber) + bus = UltraBorg() + for address in range(0x03, 0x78, 1): + try: + bus.InitBusOnly(busNumber, address) + i2cRecv = bus.RawRead(COMMAND_GET_ID, I2C_MAX_LEN) + if len(i2cRecv) == I2C_MAX_LEN: + if i2cRecv[1] == I2C_ID_SERVO_USM: + print 'Found UltraBorg at %02X' % (address) + found.append(address) + else: + pass + else: + pass + except KeyboardInterrupt: + raise + except: + pass + if len(found) == 0: + print 'No UltraBorg boards found, is bus #%d correct (should be 0 for Rev 1, 1 for Rev 2)' % (busNumber) + elif len(found) == 1: + print '1 UltraBorg board found' + else: + print '%d UltraBorg boards found' % (len(found)) + return found + + +def SetNewAddress(newAddress, oldAddress = -1, busNumber = 1): + """ +SetNewAddress(newAddress, [oldAddress], [busNumber]) + +Scans the I²C bus for the first UltraBorg and sets it to a new I2C address +If oldAddress is supplied it will change the address of the board at that address rather than scanning the bus +The busNumber if supplied is which I²C bus to scan, 0 for Rev 1 boards, 1 for Rev 2 boards, if not supplied the default is 1 +Warning, this new I²C address will still be used after resetting the power on the device + """ + if newAddress < 0x03: + print 'Error, I²C addresses below 3 (0x03) are reserved, use an address between 3 (0x03) and 119 (0x77)' + return + elif newAddress > 0x77: + print 'Error, I²C addresses above 119 (0x77) are reserved, use an address between 3 (0x03) and 119 (0x77)' + return + if oldAddress < 0x0: + found = ScanForUltraBorg(busNumber) + if len(found) < 1: + print 'No UltraBorg boards found, cannot set a new I²C address!' + return + else: + oldAddress = found[0] + print 'Changing I²C address from %02X to %02X (bus #%d)' % (oldAddress, newAddress, busNumber) + bus = UltraBorg() + bus.InitBusOnly(busNumber, oldAddress) + try: + i2cRecv = bus.RawRead(COMMAND_GET_ID, I2C_MAX_LEN) + if len(i2cRecv) == I2C_MAX_LEN: + if i2cRecv[1] == I2C_ID_SERVO_USM: + foundChip = True + print 'Found UltraBorg at %02X' % (oldAddress) + else: + foundChip = False + print 'Found a device at %02X, but it is not a UltraBorg (ID %02X instead of %02X)' % (oldAddress, i2cRecv[1], I2C_ID_SERVO_USM) + else: + foundChip = False + print 'Missing UltraBorg at %02X' % (oldAddress) + except KeyboardInterrupt: + raise + except: + foundChip = False + print 'Missing UltraBorg at %02X' % (oldAddress) + if foundChip: + bus.RawWrite(COMMAND_SET_I2C_ADD, [newAddress]) + time.sleep(0.1) + print 'Address changed to %02X, attempting to talk with the new address' % (newAddress) + try: + bus.InitBusOnly(busNumber, newAddress) + i2cRecv = bus.RawRead(COMMAND_GET_ID, I2C_MAX_LEN) + if len(i2cRecv) == I2C_MAX_LEN: + if i2cRecv[1] == I2C_ID_SERVO_USM: + foundChip = True + print 'Found UltraBorg at %02X' % (newAddress) + else: + foundChip = False + print 'Found a device at %02X, but it is not a UltraBorg (ID %02X instead of %02X)' % (newAddress, i2cRecv[1], I2C_ID_SERVO_USM) + else: + foundChip = False + print 'Missing UltraBorg at %02X' % (newAddress) + except KeyboardInterrupt: + raise + except: + foundChip = False + print 'Missing UltraBorg at %02X' % (newAddress) + if foundChip: + print 'New I²C address of %02X set successfully' % (newAddress) + else: + print 'Failed to set new I²C address...' + + +# Class used to control UltraBorg +class UltraBorg: + """ +This module is designed to communicate with the UltraBorg + +busNumber I²C bus on which the UltraBorg is attached (Rev 1 is bus 0, Rev 2 is bus 1) +bus the smbus object used to talk to the I²C bus +i2cAddress The I²C address of the UltraBorg chip to control +foundChip True if the UltraBorg chip can be seen, False otherwise +printFunction Function reference to call when printing text, if None "print" is used + """ + + # Shared values used by this class + busNumber = 1 # Check here for Rev 1 vs Rev 2 and select the correct bus + i2cAddress = I2C_ID_SERVO_USM # I²C address, override for a different address + foundChip = False + printFunction = None + i2cWrite = None + i2cRead = None + + # Default calibration adjustments to standard values + PWM_MIN_1 = PWM_MIN + PWM_MAX_1 = PWM_MAX + PWM_MIN_2 = PWM_MIN + PWM_MAX_2 = PWM_MAX + PWM_MIN_3 = PWM_MIN + PWM_MAX_3 = PWM_MAX + PWM_MIN_4 = PWM_MIN + PWM_MAX_4 = PWM_MAX + + def RawWrite(self, command, data): + """ +RawWrite(command, data) + +Sends a raw command on the I2C bus to the UltraBorg +Command codes can be found at the top of UltraBorg.py, data is a list of 0 or more byte values + +Under most circumstances you should use the appropriate function instead of RawWrite + """ + rawOutput = chr(command) + for singleByte in data: + rawOutput += chr(singleByte) + self.i2cWrite.write(rawOutput) + + + def RawRead(self, command, length, retryCount = 3): + """ +RawRead(command, length, [retryCount]) + +Reads data back from the UltraBorg after sending a GET command +Command codes can be found at the top of UltraBorg.py, length is the number of bytes to read back + +The function checks that the first byte read back matches the requested command +If it does not it will retry the request until retryCount is exhausted (default is 3 times) + +Under most circumstances you should use the appropriate function instead of RawRead + """ + while retryCount > 0: + self.RawWrite(command, []) + time.sleep(0.000001) + rawReply = self.i2cRead.read(length) + reply = [] + for singleByte in rawReply: + reply.append(ord(singleByte)) + if command == reply[0]: + break + else: + retryCount -= 1 + if retryCount > 0: + return reply + else: + raise IOError('I2C read for command %d failed' % (command)) + + + def InitBusOnly(self, busNumber, address): + """ +InitBusOnly(busNumber, address) + +Prepare the I2C driver for talking to a UltraBorg on the specified bus and I2C address +This call does not check the board is present or working, under most circumstances use Init() instead + """ + self.busNumber = busNumber + self.i2cAddress = address + self.i2cRead = io.open("/dev/i2c-" + str(self.busNumber), "rb", buffering = 0) + fcntl.ioctl(self.i2cRead, I2C_SLAVE, self.i2cAddress) + self.i2cWrite = io.open("/dev/i2c-" + str(self.busNumber), "wb", buffering = 0) + fcntl.ioctl(self.i2cWrite, I2C_SLAVE, self.i2cAddress) + + + def Print(self, message): + """ +Print(message) + +Wrapper used by the UltraBorg instance to print messages, will call printFunction if set, print otherwise + """ + if self.printFunction == None: + print message + else: + self.printFunction(message) + + + def NoPrint(self, message): + """ +NoPrint(message) + +Does nothing, intended for disabling diagnostic printout by using: +UB = UltraBorg.UltraBorg() +UB.printFunction = UB.NoPrint + """ + pass + + + def Init(self, tryOtherBus = False): + """ +Init([tryOtherBus]) + +Prepare the I2C driver for talking to the UltraBorg + +If tryOtherBus is True, this function will attempt to use the other bus if the ThunderBorg devices can not be found on the current busNumber + This is only really useful for early Raspberry Pi models! + """ + self.Print('Loading UltraBorg on bus %d, address %02X' % (self.busNumber, self.i2cAddress)) + + # Open the bus + self.i2cRead = io.open("/dev/i2c-" + str(self.busNumber), "rb", buffering = 0) + fcntl.ioctl(self.i2cRead, I2C_SLAVE, self.i2cAddress) + self.i2cWrite = io.open("/dev/i2c-" + str(self.busNumber), "wb", buffering = 0) + fcntl.ioctl(self.i2cWrite, I2C_SLAVE, self.i2cAddress) + + # Check for UltraBorg + try: + i2cRecv = self.RawRead(COMMAND_GET_ID, I2C_MAX_LEN) + if len(i2cRecv) == I2C_MAX_LEN: + if i2cRecv[1] == I2C_ID_SERVO_USM: + self.foundChip = True + self.Print('Found UltraBorg at %02X' % (self.i2cAddress)) + else: + self.foundChip = False + self.Print('Found a device at %02X, but it is not a UltraBorg (ID %02X instead of %02X)' % (self.i2cAddress, i2cRecv[1], I2C_ID_SERVO_USM)) + else: + self.foundChip = False + self.Print('Missing UltraBorg at %02X' % (self.i2cAddress)) + except KeyboardInterrupt: + raise + except: + self.foundChip = False + self.Print('Missing UltraBorg at %02X' % (self.i2cAddress)) + + # See if we are missing chips + if not self.foundChip: + self.Print('UltraBorg was not found') + if tryOtherBus: + if self.busNumber == 1: + self.busNumber = 0 + else: + self.busNumber = 1 + self.Print('Trying bus %d instead' % (self.busNumber)) + self.Init(False) + else: + self.Print('Are you sure your UltraBorg is properly attached, the correct address is used, and the I2C drivers are running?') + self.bus = None + else: + self.Print('UltraBorg loaded on bus %d' % (self.busNumber)) + + # Read the calibration settings from the UltraBorg + self.PWM_MIN_1 = self.GetWithRetry(self.GetServoMinimum1, 5) + self.PWM_MAX_1 = self.GetWithRetry(self.GetServoMaximum1, 5) + self.PWM_MIN_2 = self.GetWithRetry(self.GetServoMinimum2, 5) + self.PWM_MAX_2 = self.GetWithRetry(self.GetServoMaximum2, 5) + self.PWM_MIN_3 = self.GetWithRetry(self.GetServoMinimum3, 5) + self.PWM_MAX_3 = self.GetWithRetry(self.GetServoMaximum3, 5) + self.PWM_MIN_4 = self.GetWithRetry(self.GetServoMinimum4, 5) + self.PWM_MAX_4 = self.GetWithRetry(self.GetServoMaximum4, 5) + + + def GetWithRetry(self, function, count): + """ +value = GetWithRetry(function, count) + +Attempts to read a value multiple times before giving up +Pass a get function with no parameters +e.g. +distance = GetWithRetry(UB.GetDistance1, 5) +Will try UB.GetDistance1() upto 5 times, returning when it gets a value +Useful for ensuring a read is successful + """ + value = None + for i in range(count): + okay = True + try: + value = function() + except KeyboardInterrupt: + raise + except: + okay = False + if okay: + break + return value + + + def SetWithRetry(self, setFunction, getFunction, value, count): + """ +worked = SetWithRetry(setFunction, getFunction, value, count) + +Attempts to write a value multiple times before giving up +Pass a set function with one parameter, and a get function no parameters +The get function will be used to check if the set worked, if not it will be repeated +e.g. +worked = SetWithRetry(UB.SetServoMinimum1, UB.GetServoMinimum1, 2000, 5) +Will try UB.SetServoMinimum1(2000) upto 5 times, returning when UB.GetServoMinimum1 returns 2000. +Useful for ensuring a write is successful + """ + for i in range(count): + okay = True + try: + setFunction(value) + readValue = getFunction() + except KeyboardInterrupt: + raise + except: + okay = False + if okay: + if readValue == value: + break + else: + okay = False + return okay + + + def GetDistance1(self): + """ +distance = GetDistance1() + +Gets the filtered distance for ultrasonic module #1 in millimeters +Returns 0 for no object detected or no ultrasonic module attached +If you need a faster response try GetRawDistance1 instead (no filtering) +e.g. +0 -> No object in range +25 -> Object 25 mm away +1000 -> Object 1000 mm (1 m) away +3500 -> Object 3500 mm (3.5 m) away + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_FILTER_USM1, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading ultrasonic #1 distance!') + return + + time_us = (i2cRecv[1] << 8) + i2cRecv[2] + if time_us == 65535: + time_us = 0 + return time_us * USM_US_TO_MM + + + def GetDistance2(self): + """ +distance = GetDistance2() + +Gets the filtered distance for ultrasonic module #2 in millimeters +Returns 0 for no object detected or no ultrasonic module attached +If you need a faster response try GetRawDistance2 instead (no filtering) +e.g. +0 -> No object in range +25 -> Object 25 mm away +1000 -> Object 1000 mm (1 m) away +3500 -> Object 3500 mm (3.5 m) away + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_FILTER_USM2, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading ultrasonic #2 distance!') + return + + time_us = (i2cRecv[1] << 8) + i2cRecv[2] + if time_us == 65535: + time_us = 0 + return time_us * USM_US_TO_MM + + + def GetDistance3(self): + """ +distance = GetDistance3() + +Gets the filtered distance for ultrasonic module #3 in millimeters +Returns 0 for no object detected or no ultrasonic module attached +If you need a faster response try GetRawDistance3 instead (no filtering) +e.g. +0 -> No object in range +25 -> Object 25 mm away +1000 -> Object 1000 mm (1 m) away +3500 -> Object 3500 mm (3.5 m) away + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_FILTER_USM3, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading ultrasonic #3 distance!') + return + + time_us = (i2cRecv[1] << 8) + i2cRecv[2] + if time_us == 65535: + time_us = 0 + return time_us * USM_US_TO_MM + + + def GetDistance4(self): + """ +distance = GetDistance4() + +Gets the filtered distance for ultrasonic module #4 in millimeters +Returns 0 for no object detected or no ultrasonic module attached +If you need a faster response try GetRawDistance4 instead (no filtering) +e.g. +0 -> No object in range +25 -> Object 25 mm away +1000 -> Object 1000 mm (1 m) away +3500 -> Object 3500 mm (3.5 m) away + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_FILTER_USM4, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading ultrasonic #4 distance!') + return + + time_us = (i2cRecv[1] << 8) + i2cRecv[2] + if time_us == 65535: + time_us = 0 + return time_us * USM_US_TO_MM + + + + def GetRawDistance1(self): + """ +distance = GetRawDistance1() + +Gets the raw distance for ultrasonic module #1 in millimeters +Returns 0 for no object detected or no ultrasonic module attached +For a filtered (less jumpy) reading use GetDistance1 +e.g. +0 -> No object in range +25 -> Object 25 mm away +1000 -> Object 1000 mm (1 m) away +3500 -> Object 3500 mm (3.5 m) away + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_TIME_USM1, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading ultrasonic #1 distance!') + return + + time_us = (i2cRecv[1] << 8) + i2cRecv[2] + if time_us == 65535: + time_us = 0 + return time_us * USM_US_TO_MM + + + def GetRawDistance2(self): + """ +distance = GetRawDistance2() + +Gets the raw distance for ultrasonic module #2 in millimeters +Returns 0 for no object detected or no ultrasonic module attached +For a filtered (less jumpy) reading use GetDistance2 +e.g. +0 -> No object in range +25 -> Object 25 mm away +1000 -> Object 1000 mm (1 m) away +3500 -> Object 3500 mm (3.5 m) away + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_TIME_USM2, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading ultrasonic #2 distance!') + return + + time_us = (i2cRecv[1] << 8) + i2cRecv[2] + if time_us == 65535: + time_us = 0 + return time_us * USM_US_TO_MM + + + def GetRawDistance3(self): + """ +distance = GetRawDistance3() + +Gets the raw distance for ultrasonic module #3 in millimeters +Returns 0 for no object detected or no ultrasonic module attached +For a filtered (less jumpy) reading use GetDistance3 +e.g. +0 -> No object in range +25 -> Object 25 mm away +1000 -> Object 1000 mm (1 m) away +3500 -> Object 3500 mm (3.5 m) away + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_TIME_USM3, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading ultrasonic #3 distance!') + return + + time_us = (i2cRecv[1] << 8) + i2cRecv[2] + if time_us == 65535: + time_us = 0 + return time_us * USM_US_TO_MM + + + def GetRawDistance4(self): + """ +distance = GetRawDistance4() + +Gets the distance for ultrasonic module #4 in millimeters +Returns 0 for no object detected or no ultrasonic module attached +For a filtered (less jumpy) reading use GetDistance4 +e.g. +0 -> No object in range +25 -> Object 25 mm away +1000 -> Object 1000 mm (1 m) away +3500 -> Object 3500 mm (3.5 m) away + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_TIME_USM4, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading ultrasonic #4 distance!') + return + + time_us = (i2cRecv[1] << 8) + i2cRecv[2] + if time_us == 65535: + time_us = 0 + return time_us * USM_US_TO_MM + + + def GetServoPosition1(self): + """ +position = GetServoPosition1() + +Gets the drive position for servo output #1 +0 is central, -1 is maximum left, +1 is maximum right +e.g. +0 -> Central +0.5 -> 50% to the right +1 -> 100% to the right +-0.75 -> 75% to the left + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_PWM1, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading servo output #1!') + return + + pwmDuty = (i2cRecv[1] << 8) + i2cRecv[2] + powerOut = (float(pwmDuty) - self.PWM_MIN_1) / (self.PWM_MAX_1 - self.PWM_MIN_1) + return (2.0 * powerOut) - 1.0 + + + def GetServoPosition2(self): + """ +position = GetServoPosition2() + +Gets the drive position for servo output #2 +0 is central, -1 is maximum left, +1 is maximum right +e.g. +0 -> Central +0.5 -> 50% to the right +1 -> 100% to the right +-0.75 -> 75% to the left + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_PWM2, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading servo output #2!') + return + + pwmDuty = (i2cRecv[1] << 8) + i2cRecv[2] + powerOut = (float(pwmDuty) - self.PWM_MIN_2) / (self.PWM_MAX_2 - self.PWM_MIN_2) + return (2.0 * powerOut) - 1.0 + + + def GetServoPosition3(self): + """ +position = GetServoPosition3() + +Gets the drive position for servo output #3 +0 is central, -1 is maximum left, +1 is maximum right +e.g. +0 -> Central +0.5 -> 50% to the right +1 -> 100% to the right +-0.75 -> 75% to the left + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_PWM3, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading servo output #3!') + return + + pwmDuty = (i2cRecv[1] << 8) + i2cRecv[2] + powerOut = (float(pwmDuty) - self.PWM_MIN_3) / (self.PWM_MAX_3 - self.PWM_MIN_3) + return (2.0 * powerOut) - 1.0 + + + def GetServoPosition4(self): + """ +position = GetServoPosition4() + +Gets the drive position for servo output #4 +0 is central, -1 is maximum left, +1 is maximum right +e.g. +0 -> Central +0.5 -> 50% to the right +1 -> 100% to the right +-0.75 -> 75% to the left + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_PWM4, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading servo output #4!') + return + + pwmDuty = (i2cRecv[1] << 8) + i2cRecv[2] + powerOut = (float(pwmDuty) - self.PWM_MIN_4) / (self.PWM_MAX_4 - self.PWM_MIN_4) + return (2.0 * powerOut) - 1.0 + + + def SetServoPosition1(self, position): + """ +SetServoPosition1(position) + +Sets the drive position for servo output #1 +0 is central, -1 is maximum left, +1 is maximum right +e.g. +0 -> Central +0.5 -> 50% to the right +1 -> 100% to the right +-0.75 -> 75% to the left + """ + powerOut = (position + 1.0) / 2.0 + pwmDuty = int((powerOut * (self.PWM_MAX_1 - self.PWM_MIN_1)) + self.PWM_MIN_1) + pwmDutyLow = pwmDuty & 0xFF + pwmDutyHigh = (pwmDuty >> 8) & 0xFF + + try: + self.RawWrite(COMMAND_SET_PWM1, [pwmDutyHigh, pwmDutyLow]) + except KeyboardInterrupt: + raise + except: + self.Print('Failed sending servo output #1!') + + + def SetServoPosition2(self, position): + """ +SetServoPosition2(position) + +Sets the drive position for servo output #2 +0 is central, -1 is maximum left, +1 is maximum right +e.g. +0 -> Central +0.5 -> 50% to the right +1 -> 100% to the right +-0.75 -> 75% to the left + """ + powerOut = (position + 1.0) / 2.0 + pwmDuty = int((powerOut * (self.PWM_MAX_2 - self.PWM_MIN_2)) + self.PWM_MIN_2) + pwmDutyLow = pwmDuty & 0xFF + pwmDutyHigh = (pwmDuty >> 8) & 0xFF + + try: + self.RawWrite(COMMAND_SET_PWM2, [pwmDutyHigh, pwmDutyLow]) + except KeyboardInterrupt: + raise + except: + self.Print('Failed sending servo output #2!') + + + def SetServoPosition3(self, position): + """ +SetServoPosition3(position) + +Sets the drive position for servo output #3 +0 is central, -1 is maximum left, +1 is maximum right +e.g. +0 -> Central +0.5 -> 50% to the right +1 -> 100% to the right +-0.75 -> 75% to the left + """ + powerOut = (position + 1.0) / 2.0 + pwmDuty = int((powerOut * (self.PWM_MAX_3 - self.PWM_MIN_3)) + self.PWM_MIN_3) + pwmDutyLow = pwmDuty & 0xFF + pwmDutyHigh = (pwmDuty >> 8) & 0xFF + + try: + self.RawWrite(COMMAND_SET_PWM3, [pwmDutyHigh, pwmDutyLow]) + except KeyboardInterrupt: + raise + except: + self.Print('Failed sending servo output #3!') + + + def SetServoPosition4(self, position): + """ +SetServoPosition4(position) + +Sets the drive position for servo output #4 +0 is central, -1 is maximum left, +1 is maximum right +e.g. +0 -> Central +0.5 -> 50% to the right +1 -> 100% to the right +-0.75 -> 75% to the left + """ + powerOut = (position + 1.0) / 2.0 + pwmDuty = int((powerOut * (self.PWM_MAX_4 - self.PWM_MIN_4)) + self.PWM_MIN_4) + pwmDutyLow = pwmDuty & 0xFF + pwmDutyHigh = (pwmDuty >> 8) & 0xFF + + try: + self.RawWrite(COMMAND_SET_PWM4, [pwmDutyHigh, pwmDutyLow]) + except KeyboardInterrupt: + raise + except: + self.Print('Failed sending servo output #1!') + + + def GetServoMinimum1(self): + """ +pwmLevel = GetServoMinimum1() + +Gets the minimum PWM level for servo output #1 +This corresponds to position -1 +The value is an integer where 2000 represents a 1 ms servo burst +e.g. +2000 -> 1 ms servo burst, typical shortest burst +4000 -> 2 ms servo burst, typical longest burst +3000 -> 1.5 ms servo burst, typical centre +5000 -> 2.5 ms servo burst, higher than typical longest burst + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_PWM_MIN_1, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading servo #1 minimum burst!') + return + + return (i2cRecv[1] << 8) + i2cRecv[2] + + + def GetServoMinimum2(self): + """ +pwmLevel = GetServoMinimum2() + +Gets the minimum PWM level for servo output #2 +This corresponds to position -1 +The value is an integer where 2000 represents a 1 ms servo burst +e.g. +2000 -> 1 ms servo burst, typical shortest burst +4000 -> 2 ms servo burst, typical longest burst +3000 -> 1.5 ms servo burst, typical centre +5000 -> 2.5 ms servo burst, higher than typical longest burst + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_PWM_MIN_2, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading servo #2 minimum burst!') + return + + return (i2cRecv[1] << 8) + i2cRecv[2] + + + def GetServoMinimum3(self): + """ +pwmLevel = GetServoMinimum3() + +Gets the minimum PWM level for servo output #3 +This corresponds to position -1 +The value is an integer where 2000 represents a 1 ms servo burst +e.g. +2000 -> 1 ms servo burst, typical shortest burst +4000 -> 2 ms servo burst, typical longest burst +3000 -> 1.5 ms servo burst, typical centre +5000 -> 2.5 ms servo burst, higher than typical longest burst + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_PWM_MIN_3, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading servo #3 minimum burst!') + return + + return (i2cRecv[1] << 8) + i2cRecv[2] + + + def GetServoMinimum4(self): + """ +pwmLevel = GetServoMinimum4() + +Gets the minimum PWM level for servo output #4 +This corresponds to position -1 +The value is an integer where 2000 represents a 1 ms servo burst +e.g. +2000 -> 1 ms servo burst, typical shortest burst +4000 -> 2 ms servo burst, typical longest burst +3000 -> 1.5 ms servo burst, typical centre +5000 -> 2.5 ms servo burst, higher than typical longest burst + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_PWM_MIN_4, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading servo #4 minimum burst!') + return + + return (i2cRecv[1] << 8) + i2cRecv[2] + + + def GetServoMaximum1(self): + """ +pwmLevel = GetServoMaximum1() + +Gets the maximum PWM level for servo output #1 +This corresponds to position +1 +The value is an integer where 2000 represents a 1 ms servo burst +e.g. +2000 -> 1 ms servo burst, typical shortest burst +4000 -> 2 ms servo burst, typical longest burst +3000 -> 1.5 ms servo burst, typical centre +5000 -> 2.5 ms servo burst, higher than typical longest burst + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_PWM_MAX_1, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading servo #1 maximum burst!') + return + + return (i2cRecv[1] << 8) + i2cRecv[2] + + + def GetServoMaximum2(self): + """ +pwmLevel = GetServoMaximum2() + +Gets the maximum PWM level for servo output #2 +This corresponds to position +1 +The value is an integer where 2000 represents a 1 ms servo burst +e.g. +2000 -> 1 ms servo burst, typical shortest burst +4000 -> 2 ms servo burst, typical longest burst +3000 -> 1.5 ms servo burst, typical centre +5000 -> 2.5 ms servo burst, higher than typical longest burst + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_PWM_MAX_2, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading servo #2 maximum burst!') + return + + return (i2cRecv[1] << 8) + i2cRecv[2] + + + def GetServoMaximum3(self): + """ +pwmLevel = GetServoMaximum3() + +Gets the maximum PWM level for servo output #3 +This corresponds to position +1 +The value is an integer where 2000 represents a 1 ms servo burst +e.g. +2000 -> 1 ms servo burst, typical shortest burst +4000 -> 2 ms servo burst, typical longest burst +3000 -> 1.5 ms servo burst, typical centre +5000 -> 2.5 ms servo burst, higher than typical longest burst + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_PWM_MAX_3, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading servo #3 maximum burst!') + return + + return (i2cRecv[1] << 8) + i2cRecv[2] + + + def GetServoMaximum4(self): + """ +pwmLevel = GetServoMaximum4() + +Gets the maximum PWM level for servo output #4 +This corresponds to position +1 +The value is an integer where 2000 represents a 1 ms servo burst +e.g. +2000 -> 1 ms servo burst, typical shortest burst +4000 -> 2 ms servo burst, typical longest burst +3000 -> 1.5 ms servo burst, typical centre +5000 -> 2.5 ms servo burst, higher than typical longest burst + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_PWM_MAX_4, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading servo #4 maximum burst!') + return + + return (i2cRecv[1] << 8) + i2cRecv[2] + + + def GetServoStartup1(self): + """ +pwmLevel = GetServoStartup1() + +Gets the startup PWM level for servo output #1 +This can be anywhere in the minimum to maximum range +The value is an integer where 2000 represents a 1 ms servo burst +e.g. +2000 -> 1 ms servo burst, typical shortest burst +4000 -> 2 ms servo burst, typical longest burst +3000 -> 1.5 ms servo burst, typical centre +5000 -> 2.5 ms servo burst, higher than typical longest burst + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_PWM_BOOT_1, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading servo #1 startup burst!') + return + + return (i2cRecv[1] << 8) + i2cRecv[2] + + + def GetServoStartup2(self): + """ +pwmLevel = GetServoStartup2() + +Gets the startup PWM level for servo output #2 +This can be anywhere in the minimum to maximum range +The value is an integer where 2000 represents a 1 ms servo burst +e.g. +2000 -> 1 ms servo burst, typical shortest burst +4000 -> 2 ms servo burst, typical longest burst +3000 -> 1.5 ms servo burst, typical centre +5000 -> 2.5 ms servo burst, higher than typical longest burst + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_PWM_BOOT_2, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading servo #2 startup burst!') + return + + return (i2cRecv[1] << 8) + i2cRecv[2] + + + def GetServoStartup3(self): + """ +pwmLevel = GetServoStartup3() + +Gets the startup PWM level for servo output #3 +This can be anywhere in the minimum to maximum range +The value is an integer where 2000 represents a 1 ms servo burst +e.g. +2000 -> 1 ms servo burst, typical shortest burst +4000 -> 2 ms servo burst, typical longest burst +3000 -> 1.5 ms servo burst, typical centre +5000 -> 2.5 ms servo burst, higher than typical longest burst + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_PWM_BOOT_3, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading servo #3 startup burst!') + return + + return (i2cRecv[1] << 8) + i2cRecv[2] + + + def GetServoStartup4(self): + """ +pwmLevel = GetServoStartup4() + +Gets the startup PWM level for servo output #4 +This can be anywhere in the minimum to maximum range +The value is an integer where 2000 represents a 1 ms servo burst +e.g. +2000 -> 1 ms servo burst, typical shortest burst +4000 -> 2 ms servo burst, typical longest burst +3000 -> 1.5 ms servo burst, typical centre, +5000 -> 2.5 ms servo burst, higher than typical longest burst + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_PWM_BOOT_4, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading servo #4 startup burst!') + return + + return (i2cRecv[1] << 8) + i2cRecv[2] + + + def CalibrateServoPosition1(self, pwmLevel): + """ +CalibrateServoPosition1(pwmLevel) + +Sets the raw PWM level for servo output #1 +This value can be set anywhere from 0 for a 0% duty cycle to 65535 for a 100% duty cycle + +Setting values outside the range of the servo for extended periods of time can damage the servo +NO LIMIT CHECKING IS PERFORMED BY THIS COMMAND! +We recommend using the tuning GUI for setting the servo limits for SetServoPosition1 / GetServoPosition1 + +The value is an integer where 2000 represents a 1ms servo burst, approximately 3% duty cycle +e.g. +2000 -> 1 ms servo burst, typical shortest burst, ~3% duty cycle +4000 -> 2 ms servo burst, typical longest burst, ~ 6.1% duty cycle +3000 -> 1.5 ms servo burst, typical centre, ~4.6% duty cycle +5000 -> 2.5 ms servo burst, higher than typical longest burst, ~ 7.6% duty cycle + """ + pwmDutyLow = pwmLevel & 0xFF + pwmDutyHigh = (pwmLevel >> 8) & 0xFF + + try: + self.RawWrite(COMMAND_CALIBRATE_PWM1, [pwmDutyHigh, pwmDutyLow]) + except KeyboardInterrupt: + raise + except: + self.Print('Failed sending calibration servo output #1!') + + + def CalibrateServoPosition2(self, pwmLevel): + """ +CalibrateServoPosition2(pwmLevel) + +Sets the raw PWM level for servo output #2 +This value can be set anywhere from 0 for a 0% duty cycle to 65535 for a 100% duty cycle + +Setting values outside the range of the servo for extended periods of time can damage the servo +NO LIMIT CHECKING IS PERFORMED BY THIS COMMAND! +We recommend using the tuning GUI for setting the servo limits for SetServoPosition2 / GetServoPosition2 + +The value is an integer where 2000 represents a 1ms servo burst, approximately 3% duty cycle +e.g. +2000 -> 1 ms servo burst, typical shortest burst, ~3% duty cycle +4000 -> 2 ms servo burst, typical longest burst, ~ 6.1% duty cycle +3000 -> 1.5 ms servo burst, typical centre, ~4.6% duty cycle +5000 -> 2.5 ms servo burst, higher than typical longest burst, ~ 7.6% duty cycle + """ + pwmDutyLow = pwmLevel & 0xFF + pwmDutyHigh = (pwmLevel >> 8) & 0xFF + + try: + self.RawWrite(COMMAND_CALIBRATE_PWM2, [pwmDutyHigh, pwmDutyLow]) + except KeyboardInterrupt: + raise + except: + self.Print('Failed sending calibration servo output #2!') + + + def CalibrateServoPosition3(self, pwmLevel): + """ +CalibrateServoPosition3(pwmLevel) + +Sets the raw PWM level for servo output #3 +This value can be set anywhere from 0 for a 0% duty cycle to 65535 for a 100% duty cycle + +Setting values outside the range of the servo for extended periods of time can damage the servo +NO LIMIT CHECKING IS PERFORMED BY THIS COMMAND! +We recommend using the tuning GUI for setting the servo limits for SetServoPosition3 / GetServoPosition3 + +The value is an integer where 2000 represents a 1ms servo burst, approximately 3% duty cycle +e.g. +2000 -> 1 ms servo burst, typical shortest burst, ~3% duty cycle +4000 -> 2 ms servo burst, typical longest burst, ~ 6.1% duty cycle +3000 -> 1.5 ms servo burst, typical centre, ~4.6% duty cycle +5000 -> 2.5 ms servo burst, higher than typical longest burst, ~ 7.6% duty cycle + """ + pwmDutyLow = pwmLevel & 0xFF + pwmDutyHigh = (pwmLevel >> 8) & 0xFF + + try: + self.RawWrite(COMMAND_CALIBRATE_PWM3, [pwmDutyHigh, pwmDutyLow]) + except KeyboardInterrupt: + raise + except: + self.Print('Failed sending calibration servo output #3!') + + + def CalibrateServoPosition4(self, pwmLevel): + """ +CalibrateServoPosition4(pwmLevel) + +Sets the raw PWM level for servo output #4 +This value can be set anywhere from 0 for a 0% duty cycle to 65535 for a 100% duty cycle + +Setting values outside the range of the servo for extended periods of time can damage the servo +NO LIMIT CHECKING IS PERFORMED BY THIS COMMAND! +We recommend using the tuning GUI for setting the servo limits for SetServoPosition4 / GetServoPosition4 + +The value is an integer where 2000 represents a 1ms servo burst, approximately 3% duty cycle +e.g. +2000 -> 1 ms servo burst, typical shortest burst, ~3% duty cycle +4000 -> 2 ms servo burst, typical longest burst, ~ 6.1% duty cycle +3000 -> 1.5 ms servo burst, typical centre, ~4.6% duty cycle +5000 -> 2.5 ms servo burst, higher than typical longest burst, ~ 7.6% duty cycle + """ + pwmDutyLow = pwmLevel & 0xFF + pwmDutyHigh = (pwmLevel >> 8) & 0xFF + + try: + self.RawWrite(COMMAND_CALIBRATE_PWM4, [pwmDutyHigh, pwmDutyLow]) + except KeyboardInterrupt: + raise + except: + self.Print('Failed sending calibration servo output #4!') + + + def GetRawServoPosition1(self): + """ +pwmLevel = GetRawServoPosition1() + +Gets the raw PWM level for servo output #1 +This value can be set anywhere from 0 for a 0% duty cycle to 65535 for a 100% duty cycle + +This value requires interpreting into an actual servo position, this is already done by GetServoPosition1 +We recommend using the tuning GUI for setting the servo limits for SetServoPosition1 / GetServoPosition1 + +The value is an integer where 2000 represents a 1ms servo burst, approximately 3% duty cycle +e.g. +2000 -> 1 ms servo burst, typical shortest burst, ~3% duty cycle +4000 -> 2 ms servo burst, typical longest burst, ~ 6.1% duty cycle +3000 -> 1.5 ms servo burst, typical centre, ~4.6% duty cycle +5000 -> 2.5 ms servo burst, higher than typical longest burst, ~ 7.6% duty cycle + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_PWM1, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading raw servo output #1!') + return + + pwmDuty = (i2cRecv[1] << 8) + i2cRecv[2] + return pwmDuty + + + def GetRawServoPosition2(self): + """ +pwmLevel = GetRawServoPosition2() + +Gets the raw PWM level for servo output #2 +This value can be set anywhere from 0 for a 0% duty cycle to 65535 for a 100% duty cycle + +This value requires interpreting into an actual servo position, this is already done by GetServoPosition2 +We recommend using the tuning GUI for setting the servo limits for SetServoPosition2 / GetServoPosition2 + +The value is an integer where 2000 represents a 1ms servo burst, approximately 3% duty cycle +e.g. +2000 -> 1 ms servo burst, typical shortest burst, ~3% duty cycle +4000 -> 2 ms servo burst, typical longest burst, ~ 6.1% duty cycle +3000 -> 1.5 ms servo burst, typical centre, ~4.6% duty cycle +5000 -> 2.5 ms servo burst, higher than typical longest burst, ~ 7.6% duty cycle + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_PWM2, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading raw servo output #2!') + return + + pwmDuty = (i2cRecv[1] << 8) + i2cRecv[2] + return pwmDuty + + + def GetRawServoPosition3(self): + """ +pwmLevel = GetRawServoPosition3() + +Gets the raw PWM level for servo output #3 +This value can be set anywhere from 0 for a 0% duty cycle to 65535 for a 100% duty cycle + +This value requires interpreting into an actual servo position, this is already done by GetServoPosition3 +We recommend using the tuning GUI for setting the servo limits for SetServoPosition3 / GetServoPosition3 + +The value is an integer where 2000 represents a 1ms servo burst, approximately 3% duty cycle +e.g. +2000 -> 1 ms servo burst, typical shortest burst, ~3% duty cycle +4000 -> 2 ms servo burst, typical longest burst, ~ 6.1% duty cycle +3000 -> 1.5 ms servo burst, typical centre, ~4.6% duty cycle +5000 -> 2.5 ms servo burst, higher than typical longest burst, ~ 7.6% duty cycle + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_PWM3, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading raw servo output #3!') + return + + pwmDuty = (i2cRecv[1] << 8) + i2cRecv[2] + return pwmDuty + + + def GetRawServoPosition4(self): + """ +pwmLevel = GetRawServoPosition4() + +Gets the raw PWM level for servo output #4 +This value can be set anywhere from 0 for a 0% duty cycle to 65535 for a 100% duty cycle + +This value requires interpreting into an actual servo position, this is already done by GetServoPosition4 +We recommend using the tuning GUI for setting the servo limits for SetServoPosition4 / GetServoPosition4 + +The value is an integer where 2000 represents a 1ms servo burst, approximately 3% duty cycle +e.g. +2000 -> 1 ms servo burst, typical shortest burst, ~3% duty cycle +4000 -> 2 ms servo burst, typical longest burst, ~ 6.1% duty cycle +3000 -> 1.5 ms servo burst, typical centre, ~4.6% duty cycle +5000 -> 2.5 ms servo burst, higher than typical longest burst, ~ 7.6% duty cycle + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_PWM4, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading raw servo output #4!') + return + + pwmDuty = (i2cRecv[1] << 8) + i2cRecv[2] + return pwmDuty + + + def SetServoMinimum1(self, pwmLevel): + """ +SetServoMinimum1(pwmLevel) + +Sets the minimum PWM level for servo output #1 +This corresponds to position -1 +This value can be set anywhere from 0 for a 0% duty cycle to 65535 for a 100% duty cycle + +Setting values outside the range of the servo for extended periods of time can damage the servo +LIMIT CHECKING IS ALTERED BY THIS COMMAND! +We recommend using the tuning GUI for setting the servo limits for SetServoPosition1 / GetServoPosition1 + +The value is an integer where 2000 represents a 1ms servo burst, approximately 3% duty cycle +e.g. +2000 -> 1 ms servo burst, typical shortest burst, ~3% duty cycle +4000 -> 2 ms servo burst, typical longest burst, ~ 6.1% duty cycle +3000 -> 1.5 ms servo burst, typical centre, ~4.6% duty cycle +5000 -> 2.5 ms servo burst, higher than typical longest burst, ~ 7.6% duty cycle + """ + pwmDutyLow = pwmLevel & 0xFF + pwmDutyHigh = (pwmLevel >> 8) & 0xFF + + try: + self.RawWrite(COMMAND_SET_PWM_MIN_1, [pwmDutyHigh, pwmDutyLow]) + except KeyboardInterrupt: + raise + except: + self.Print('Failed sending servo minimum limit #1!') + time.sleep(DELAY_AFTER_EEPROM) + self.PWM_MIN_1 = self.GetServoMinimum1() + + + def SetServoMinimum2(self, pwmLevel): + """ +SetServoMinimum2(pwmLevel) + +Sets the minimum PWM level for servo output #2 +This corresponds to position -1 +This value can be set anywhere from 0 for a 0% duty cycle to 65535 for a 100% duty cycle + +Setting values outside the range of the servo for extended periods of time can damage the servo +LIMIT CHECKING IS ALTERED BY THIS COMMAND! +We recommend using the tuning GUI for setting the servo limits for SetServoPosition2 / GetServoPosition2 + +The value is an integer where 2000 represents a 1ms servo burst, approximately 3% duty cycle +e.g. +2000 -> 1 ms servo burst, typical shortest burst, ~3% duty cycle +4000 -> 2 ms servo burst, typical longest burst, ~ 6.1% duty cycle +3000 -> 1.5 ms servo burst, typical centre, ~4.6% duty cycle +5000 -> 2.5 ms servo burst, higher than typical longest burst, ~ 7.6% duty cycle + """ + pwmDutyLow = pwmLevel & 0xFF + pwmDutyHigh = (pwmLevel >> 8) & 0xFF + + try: + self.RawWrite(COMMAND_SET_PWM_MIN_2, [pwmDutyHigh, pwmDutyLow]) + except KeyboardInterrupt: + raise + except: + self.Print('Failed sending servo minimum limit #2!') + time.sleep(DELAY_AFTER_EEPROM) + self.PWM_MIN_2 = self.GetServoMinimum2() + + + def SetServoMinimum3(self, pwmLevel): + """ +SetServoMinimum3(pwmLevel) + +Sets the minimum PWM level for servo output #3 +This corresponds to position -1 +This value can be set anywhere from 0 for a 0% duty cycle to 65535 for a 100% duty cycle + +Setting values outside the range of the servo for extended periods of time can damage the servo +LIMIT CHECKING IS ALTERED BY THIS COMMAND! +We recommend using the tuning GUI for setting the servo limits for SetServoPosition3 / GetServoPosition3 + +The value is an integer where 2000 represents a 1ms servo burst, approximately 3% duty cycle +e.g. +2000 -> 1 ms servo burst, typical shortest burst, ~3% duty cycle +4000 -> 2 ms servo burst, typical longest burst, ~ 6.1% duty cycle +3000 -> 1.5 ms servo burst, typical centre, ~4.6% duty cycle +5000 -> 2.5 ms servo burst, higher than typical longest burst, ~ 7.6% duty cycle + """ + pwmDutyLow = pwmLevel & 0xFF + pwmDutyHigh = (pwmLevel >> 8) & 0xFF + + try: + self.RawWrite(COMMAND_SET_PWM_MIN_3, [pwmDutyHigh, pwmDutyLow]) + except KeyboardInterrupt: + raise + except: + self.Print('Failed sending servo minimum limit #3!') + time.sleep(DELAY_AFTER_EEPROM) + self.PWM_MIN_3 = self.GetServoMinimum3() + + + def SetServoMinimum4(self, pwmLevel): + """ +SetServoMinimum4(pwmLevel) + +Sets the minimum PWM level for servo output #4 +This corresponds to position -1 +This value can be set anywhere from 0 for a 0% duty cycle to 65535 for a 100% duty cycle + +Setting values outside the range of the servo for extended periods of time can damage the servo +LIMIT CHECKING IS ALTERED BY THIS COMMAND! +We recommend using the tuning GUI for setting the servo limits for SetServoPosition4 / GetServoPosition4 + +The value is an integer where 2000 represents a 1ms servo burst, approximately 3% duty cycle +e.g. +2000 -> 1 ms servo burst, typical shortest burst, ~3% duty cycle +4000 -> 2 ms servo burst, typical longest burst, ~ 6.1% duty cycle +3000 -> 1.5 ms servo burst, typical centre, ~4.6% duty cycle +5000 -> 2.5 ms servo burst, higher than typical longest burst, ~ 7.6% duty cycle + """ + pwmDutyLow = pwmLevel & 0xFF + pwmDutyHigh = (pwmLevel >> 8) & 0xFF + + try: + self.RawWrite(COMMAND_SET_PWM_MIN_4, [pwmDutyHigh, pwmDutyLow]) + except KeyboardInterrupt: + raise + except: + self.Print('Failed sending servo minimum limit #4!') + time.sleep(DELAY_AFTER_EEPROM) + self.PWM_MIN_4 = self.GetServoMinimum4() + + + def SetServoMaximum1(self, pwmLevel): + """ +SetServoMaximum1(pwmLevel) + +Sets the maximum PWM level for servo output #1 +This corresponds to position +1 +This value can be set anywhere from 0 for a 0% duty cycle to 65535 for a 100% duty cycle + +Setting values outside the range of the servo for extended periods of time can damage the servo +LIMIT CHECKING IS ALTERED BY THIS COMMAND! +We recommend using the tuning GUI for setting the servo limits for SetServoPosition1 / GetServoPosition1 + +The value is an integer where 2000 represents a 1ms servo burst, approximately 3% duty cycle +e.g. +2000 -> 1 ms servo burst, typical shortest burst, ~3% duty cycle +4000 -> 2 ms servo burst, typical longest burst, ~ 6.1% duty cycle +3000 -> 1.5 ms servo burst, typical centre, ~4.6% duty cycle +5000 -> 2.5 ms servo burst, higher than typical longest burst, ~ 7.6% duty cycle + """ + pwmDutyLow = pwmLevel & 0xFF + pwmDutyHigh = (pwmLevel >> 8) & 0xFF + + try: + self.RawWrite(COMMAND_SET_PWM_MAX_1, [pwmDutyHigh, pwmDutyLow]) + except KeyboardInterrupt: + raise + except: + self.Print('Failed sending servo maximum limit #1!') + time.sleep(DELAY_AFTER_EEPROM) + self.PWM_MAX_1 = self.GetServoMaximum1() + + + def SetServoMaximum2(self, pwmLevel): + """ +SetServoMaximum2(pwmLevel) + +Sets the maximum PWM level for servo output #2 +This corresponds to position +1 +This value can be set anywhere from 0 for a 0% duty cycle to 65535 for a 100% duty cycle + +Setting values outside the range of the servo for extended periods of time can damage the servo +LIMIT CHECKING IS ALTERED BY THIS COMMAND! +We recommend using the tuning GUI for setting the servo limits for SetServoPosition2 / GetServoPosition2 + +The value is an integer where 2000 represents a 1ms servo burst, approximately 3% duty cycle +e.g. +2000 -> 1 ms servo burst, typical shortest burst, ~3% duty cycle +4000 -> 2 ms servo burst, typical longest burst, ~ 6.1% duty cycle +3000 -> 1.5 ms servo burst, typical centre, ~4.6% duty cycle +5000 -> 2.5 ms servo burst, higher than typical longest burst, ~ 7.6% duty cycle + """ + pwmDutyLow = pwmLevel & 0xFF + pwmDutyHigh = (pwmLevel >> 8) & 0xFF + + try: + self.RawWrite(COMMAND_SET_PWM_MAX_2, [pwmDutyHigh, pwmDutyLow]) + except KeyboardInterrupt: + raise + except: + self.Print('Failed sending servo maximum limit #2!') + time.sleep(DELAY_AFTER_EEPROM) + self.PWM_MAX_2 = self.GetServoMaximum2() + + + def SetServoMaximum3(self, pwmLevel): + """ +SetServoMaximum3(pwmLevel) + +Sets the maximum PWM level for servo output #3 +This corresponds to position +1 +This value can be set anywhere from 0 for a 0% duty cycle to 65535 for a 100% duty cycle + +Setting values outside the range of the servo for extended periods of time can damage the servo +LIMIT CHECKING IS ALTERED BY THIS COMMAND! +We recommend using the tuning GUI for setting the servo limits for SetServoPosition3 / GetServoPosition3 + +The value is an integer where 2000 represents a 1ms servo burst, approximately 3% duty cycle +e.g. +2000 -> 1 ms servo burst, typical shortest burst, ~3% duty cycle +4000 -> 2 ms servo burst, typical longest burst, ~ 6.1% duty cycle +3000 -> 1.5 ms servo burst, typical centre, ~4.6% duty cycle +5000 -> 2.5 ms servo burst, higher than typical longest burst, ~ 7.6% duty cycle + """ + pwmDutyLow = pwmLevel & 0xFF + pwmDutyHigh = (pwmLevel >> 8) & 0xFF + + try: + self.RawWrite(COMMAND_SET_PWM_MAX_3, [pwmDutyHigh, pwmDutyLow]) + except KeyboardInterrupt: + raise + except: + self.Print('Failed sending servo maximum limit #3!') + time.sleep(DELAY_AFTER_EEPROM) + self.PWM_MAX_3 = self.GetServoMaximum3() + + + def SetServoMaximum4(self, pwmLevel): + """ +SetServoMaximum4(pwmLevel) + +Sets the maximum PWM level for servo output #4 +This corresponds to position +1 +This value can be set anywhere from 0 for a 0% duty cycle to 65535 for a 100% duty cycle + +Setting values outside the range of the servo for extended periods of time can damage the servo +LIMIT CHECKING IS ALTERED BY THIS COMMAND! +We recommend using the tuning GUI for setting the servo limits for SetServoPosition4 / GetServoPosition4 + +The value is an integer where 2000 represents a 1ms servo burst, approximately 3% duty cycle +e.g. +2000 -> 1 ms servo burst, typical shortest burst, ~3% duty cycle +4000 -> 2 ms servo burst, typical longest burst, ~ 6.1% duty cycle +3000 -> 1.5 ms servo burst, typical centre, ~4.6% duty cycle +5000 -> 2.5 ms servo burst, higher than typical longest burst, ~ 7.6% duty cycle + """ + pwmDutyLow = pwmLevel & 0xFF + pwmDutyHigh = (pwmLevel >> 8) & 0xFF + + try: + self.RawWrite(COMMAND_SET_PWM_MAX_4, [pwmDutyHigh, pwmDutyLow]) + except KeyboardInterrupt: + raise + except: + self.Print('Failed sending servo maximum limit #4!') + time.sleep(DELAY_AFTER_EEPROM) + self.PWM_MAX_4 = self.GetServoMaximum4() + + + def SetServoStartup1(self, pwmLevel): + """ +SetServoStartup1(pwmLevel) + +Sets the startup PWM level for servo output #1 +This can be anywhere in the minimum to maximum range + +We recommend using the tuning GUI for setting the servo limits for SetServoPosition1 / GetServoPosition1 +This value is checked against the current servo limits before setting + +The value is an integer where 2000 represents a 1ms servo burst, approximately 3% duty cycle +e.g. +2000 -> 1 ms servo burst, typical shortest burst, ~3% duty cycle +4000 -> 2 ms servo burst, typical longest burst, ~ 6.1% duty cycle +3000 -> 1.5 ms servo burst, typical centre, ~4.6% duty cycle +5000 -> 2.5 ms servo burst, higher than typical longest burst, ~ 7.6% duty cycle + """ + pwmDutyLow = pwmLevel & 0xFF + pwmDutyHigh = (pwmLevel >> 8) & 0xFF + inRange = True + + if self.PWM_MIN_1 < self.PWM_MAX_1: + # Normal direction + if pwmLevel < self.PWM_MIN_1: + inRange = False + elif pwmLevel > self.PWM_MAX_1: + inRange = False + else: + # Inverted direction + if pwmLevel > self.PWM_MIN_1: + inRange = False + elif pwmLevel < self.PWM_MAX_1: + inRange = False + if pwmLevel == PWM_UNSET: + # Force to unset behaviour (central) + inRange = True + + if not inRange: + print 'Servo #1 startup position %d is outside the limits of %d to %d' % (pwmLevel, self.PWM_MIN_1, self.PWM_MAX_1) + return + + try: + self.RawWrite(COMMAND_SET_PWM_BOOT_1, [pwmDutyHigh, pwmDutyLow]) + except KeyboardInterrupt: + raise + except: + self.Print('Failed sending servo startup position #1!') + time.sleep(DELAY_AFTER_EEPROM) + + + def SetServoStartup2(self, pwmLevel): + """ +SetServoStartup2(pwmLevel) + +Sets the startup PWM level for servo output #2 +This can be anywhere in the minimum to maximum range + +We recommend using the tuning GUI for setting the servo limits for SetServoPosition2 / GetServoPosition2 +This value is checked against the current servo limits before setting + +The value is an integer where 2000 represents a 1ms servo burst, approximately 3% duty cycle +e.g. +2000 -> 1 ms servo burst, typical shortest burst, ~3% duty cycle +4000 -> 2 ms servo burst, typical longest burst, ~ 6.1% duty cycle +3000 -> 1.5 ms servo burst, typical centre, ~4.6% duty cycle +5000 -> 2.5 ms servo burst, higher than typical longest burst, ~ 7.6% duty cycle + """ + pwmDutyLow = pwmLevel & 0xFF + pwmDutyHigh = (pwmLevel >> 8) & 0xFF + inRange = True + + if self.PWM_MIN_2 < self.PWM_MAX_2: + # Normal direction + if pwmLevel < self.PWM_MIN_2: + inRange = False + elif pwmLevel > self.PWM_MAX_2: + inRange = False + else: + # Inverted direction + if pwmLevel > self.PWM_MIN_2: + inRange = False + elif pwmLevel < self.PWM_MAX_2: + inRange = False + if pwmLevel == PWM_UNSET: + # Force to unset behaviour (central) + inRange = True + + if not inRange: + print 'Servo #2 startup position %d is outside the limits of %d to %d' % (pwmLevel, self.PWM_MIN_2, self.PWM_MAX_2) + return + + try: + self.RawWrite(COMMAND_SET_PWM_BOOT_2, [pwmDutyHigh, pwmDutyLow]) + except KeyboardInterrupt: + raise + except: + self.Print('Failed sending servo startup position #2!') + time.sleep(DELAY_AFTER_EEPROM) + + + def SetServoStartup3(self, pwmLevel): + """ +SetServoStartup3(pwmLevel) + +Sets the startup PWM level for servo output #3 +This can be anywhere in the minimum to maximum range + +We recommend using the tuning GUI for setting the servo limits for SetServoPosition3 / GetServoPosition3 +This value is checked against the current servo limits before setting + +The value is an integer where 2000 represents a 1ms servo burst, approximately 3% duty cycle +e.g. +2000 -> 1 ms servo burst, typical shortest burst, ~3% duty cycle +4000 -> 2 ms servo burst, typical longest burst, ~ 6.1% duty cycle +3000 -> 1.5 ms servo burst, typical centre, ~4.6% duty cycle +5000 -> 2.5 ms servo burst, higher than typical longest burst, ~ 7.6% duty cycle + """ + pwmDutyLow = pwmLevel & 0xFF + pwmDutyHigh = (pwmLevel >> 8) & 0xFF + inRange = True + + if self.PWM_MIN_3 < self.PWM_MAX_3: + # Normal direction + if pwmLevel < self.PWM_MIN_3: + inRange = False + elif pwmLevel > self.PWM_MAX_3: + inRange = False + else: + # Inverted direction + if pwmLevel > self.PWM_MIN_3: + inRange = False + elif pwmLevel < self.PWM_MAX_3: + inRange = False + if pwmLevel == PWM_UNSET: + # Force to unset behaviour (central) + inRange = True + + if not inRange: + print 'Servo #3 startup position %d is outside the limits of %d to %d' % (pwmLevel, self.PWM_MIN_3, self.PWM_MAX_3) + return + + try: + self.RawWrite(COMMAND_SET_PWM_BOOT_3, [pwmDutyHigh, pwmDutyLow]) + except KeyboardInterrupt: + raise + except: + self.Print('Failed sending servo startup position #3!') + time.sleep(DELAY_AFTER_EEPROM) + + + def SetServoStartup4(self, pwmLevel): + """ +SetServoStartup4(pwmLevel) + +Sets the startup PWM level for servo output #4 +This can be anywhere in the minimum to maximum range + +We recommend using the tuning GUI for setting the servo limits for SetServoPosition4 / GetServoPosition4 +This value is checked against the current servo limits before setting + +The value is an integer where 2000 represents a 1ms servo burst, approximately 3% duty cycle +e.g. +2000 -> 1 ms servo burst, typical shortest burst, ~3% duty cycle +4000 -> 2 ms servo burst, typical longest burst, ~ 6.1% duty cycle +3000 -> 1.5 ms servo burst, typical centre, ~4.6% duty cycle +5000 -> 2.5 ms servo burst, higher than typical longest burst, ~ 7.6% duty cycle + """ + pwmDutyLow = pwmLevel & 0xFF + pwmDutyHigh = (pwmLevel >> 8) & 0xFF + inRange = True + + if self.PWM_MIN_4 < self.PWM_MAX_4: + # Normal direction + if pwmLevel < self.PWM_MIN_4: + inRange = False + elif pwmLevel > self.PWM_MAX_4: + inRange = False + else: + # Inverted direction + if pwmLevel > self.PWM_MIN_4: + inRange = False + elif pwmLevel < self.PWM_MAX_4: + inRange = False + if pwmLevel == PWM_UNSET: + # Force to unset behaviour (central) + inRange = True + + if not inRange: + print 'Servo #4 startup position %d is outside the limits of %d to %d' % (pwmLevel, self.PWM_MIN_4, self.PWM_MAX_4) + return + + try: + self.RawWrite(COMMAND_SET_PWM_BOOT_4, [pwmDutyHigh, pwmDutyLow]) + except KeyboardInterrupt: + raise + except: + self.Print('Failed sending servo startup position #4!') + time.sleep(DELAY_AFTER_EEPROM) + + + def Help(self): + """ +Help() + +Displays the names and descriptions of the various functions and settings provided + """ + funcList = [UltraBorg.__dict__.get(a) for a in dir(UltraBorg) if isinstance(UltraBorg.__dict__.get(a), types.FunctionType)] + funcListSorted = sorted(funcList, key = lambda x: x.func_code.co_firstlineno) + + print self.__doc__ + print + for func in funcListSorted: + print '=== %s === %s' % (func.func_name, func.func_doc) + diff --git a/Code/Pyborg_Robot_Scripts/UltraBorg3.py b/Code/Pyborg_Robot_Scripts/UltraBorg3.py new file mode 100644 index 0000000000000000000000000000000000000000..b77b5c9740025fd39a7751755658461650f2f6a2 --- /dev/null +++ b/Code/Pyborg_Robot_Scripts/UltraBorg3.py @@ -0,0 +1,1840 @@ +#!/usr/bin/env python +# coding: latin-1 +""" +This module is designed to communicate with the UltraBorg + +Use by creating an instance of the class, call the Init function, then command as desired, e.g. +import UltraBorg +UB = UltraBorg.UltraBorg() +UB.Init() +# User code here, use UB to control the board + +Multiple boards can be used when configured with different I²C addresses by creating multiple instances, e.g. +import UltraBorg +UB1 = UltraBorg.UltraBorg() +UB2 = UltraBorg.UltraBorg() +UB1.i2cAddress = 0x44 +UB2.i2cAddress = 0x45 +UB1.Init() +UB2.Init() +# User code here, use UB1 and UB2 to control each board separately + +For explanations of the functions available call the Help function, e.g. +import UltraBorg +UB = UltraBorg.UltraBorg() +UB.Help() +See the website at www.piborg.org/ultraborg for more details +""" + +# Import the libraries we need +import io +import fcntl +import types +import time + +# Constant values +I2C_SLAVE = 0x0703 +I2C_MAX_LEN = 4 +USM_US_TO_MM = 0.171500 +PWM_MIN = 2000 # Should be a 1 ms burst, typical servo minimum +PWM_MAX = 4000 # Should be a 2 ms burst, typical servo maximum +DELAY_AFTER_EEPROM = 0.01 # Time to wait after updating an EEPROM value before reading +PWM_UNSET = 0xFFFF + +I2C_ID_SERVO_USM = 0x36 + +COMMAND_GET_TIME_USM1 = 1 # Get the time measured by ultrasonic #1 in us (0 for no detection) +COMMAND_GET_TIME_USM2 = 2 # Get the time measured by ultrasonic #2 in us (0 for no detection) +COMMAND_GET_TIME_USM3 = 3 # Get the time measured by ultrasonic #3 in us (0 for no detection) +COMMAND_GET_TIME_USM4 = 4 # Get the time measured by ultrasonic #4 in us (0 for no detection) +COMMAND_SET_PWM1 = 5 # Set the PWM duty cycle for drive #1 (16 bit) +COMMAND_GET_PWM1 = 6 # Get the PWM duty cycle for drive #1 (16 bit) +COMMAND_SET_PWM2 = 7 # Set the PWM duty cycle for drive #2 (16 bit) +COMMAND_GET_PWM2 = 8 # Get the PWM duty cycle for drive #2 (16 bit) +COMMAND_SET_PWM3 = 9 # Set the PWM duty cycle for drive #3 (16 bit) +COMMAND_GET_PWM3 = 10 # Get the PWM duty cycle for drive #3 (16 bit) +COMMAND_SET_PWM4 = 11 # Set the PWM duty cycle for drive #4 (16 bit) +COMMAND_GET_PWM4 = 12 # Get the PWM duty cycle for drive #4 (16 bit) +COMMAND_CALIBRATE_PWM1 = 13 # Set the PWM duty cycle for drive #1 (16 bit, ignores limit checks) +COMMAND_CALIBRATE_PWM2 = 14 # Set the PWM duty cycle for drive #2 (16 bit, ignores limit checks) +COMMAND_CALIBRATE_PWM3 = 15 # Set the PWM duty cycle for drive #3 (16 bit, ignores limit checks) +COMMAND_CALIBRATE_PWM4 = 16 # Set the PWM duty cycle for drive #4 (16 bit, ignores limit checks) +COMMAND_GET_PWM_MIN_1 = 17 # Get the minimum allowed PWM duty cycle for drive #1 +COMMAND_GET_PWM_MAX_1 = 18 # Get the maximum allowed PWM duty cycle for drive #1 +COMMAND_GET_PWM_BOOT_1 = 19 # Get the startup PWM duty cycle for drive #1 +COMMAND_GET_PWM_MIN_2 = 20 # Get the minimum allowed PWM duty cycle for drive #2 +COMMAND_GET_PWM_MAX_2 = 21 # Get the maximum allowed PWM duty cycle for drive #2 +COMMAND_GET_PWM_BOOT_2 = 22 # Get the startup PWM duty cycle for drive #2 +COMMAND_GET_PWM_MIN_3 = 23 # Get the minimum allowed PWM duty cycle for drive #3 +COMMAND_GET_PWM_MAX_3 = 24 # Get the maximum allowed PWM duty cycle for drive #3 +COMMAND_GET_PWM_BOOT_3 = 25 # Get the startup PWM duty cycle for drive #3 +COMMAND_GET_PWM_MIN_4 = 26 # Get the minimum allowed PWM duty cycle for drive #4 +COMMAND_GET_PWM_MAX_4 = 27 # Get the maximum allowed PWM duty cycle for drive #4 +COMMAND_GET_PWM_BOOT_4 = 28 # Get the startup PWM duty cycle for drive #4 +COMMAND_SET_PWM_MIN_1 = 29 # Set the minimum allowed PWM duty cycle for drive #1 +COMMAND_SET_PWM_MAX_1 = 30 # Set the maximum allowed PWM duty cycle for drive #1 +COMMAND_SET_PWM_BOOT_1 = 31 # Set the startup PWM duty cycle for drive #1 +COMMAND_SET_PWM_MIN_2 = 32 # Set the minimum allowed PWM duty cycle for drive #2 +COMMAND_SET_PWM_MAX_2 = 33 # Set the maximum allowed PWM duty cycle for drive #2 +COMMAND_SET_PWM_BOOT_2 = 34 # Set the startup PWM duty cycle for drive #2 +COMMAND_SET_PWM_MIN_3 = 35 # Set the minimum allowed PWM duty cycle for drive #3 +COMMAND_SET_PWM_MAX_3 = 36 # Set the maximum allowed PWM duty cycle for drive #3 +COMMAND_SET_PWM_BOOT_3 = 37 # Set the startup PWM duty cycle for drive #3 +COMMAND_SET_PWM_MIN_4 = 38 # Set the minimum allowed PWM duty cycle for drive #4 +COMMAND_SET_PWM_MAX_4 = 39 # Set the maximum allowed PWM duty cycle for drive #4 +COMMAND_SET_PWM_BOOT_4 = 40 # Set the startup PWM duty cycle for drive #4 +COMMAND_GET_FILTER_USM1 = 41 # Get the filtered time measured by ultrasonic #1 in us (0 for no detection) +COMMAND_GET_FILTER_USM2 = 42 # Get the filtered time measured by ultrasonic #2 in us (0 for no detection) +COMMAND_GET_FILTER_USM3 = 43 # Get the filtered time measured by ultrasonic #3 in us (0 for no detection) +COMMAND_GET_FILTER_USM4 = 44 # Get the filtered time measured by ultrasonic #4 in us (0 for no detection) +COMMAND_GET_ID = 0x99 # Get the board identifier +COMMAND_SET_I2C_ADD = 0xAA # Set a new I2C address + +COMMAND_VALUE_FWD = 1 # I2C value representing forward +COMMAND_VALUE_REV = 2 # I2C value representing reverse + +COMMAND_VALUE_ON = 1 # I2C value representing on +COMMAND_VALUE_OFF = 0 # I2C value representing off + + +def ScanForUltraBorg(busNumber = 1): + """ +ScanForUltraBorg([busNumber]) + +Scans the I²C bus for a UltraBorg boards and returns a list of all usable addresses +The busNumber if supplied is which I²C bus to scan, 0 for Rev 1 boards, 1 for Rev 2 boards, if not supplied the default is 1 + """ + found = [] + print('Scanning I²C bus #%d' % (busNumber)) + bus = UltraBorg() + for address in range(0x03, 0x78, 1): + try: + bus.InitBusOnly(busNumber, address) + i2cRecv = bus.RawRead(COMMAND_GET_ID, I2C_MAX_LEN) + if len(i2cRecv) == I2C_MAX_LEN: + if i2cRecv[1] == I2C_ID_SERVO_USM: + print('Found UltraBorg at %02X' % (address)) + found.append(address) + else: + pass + else: + pass + except KeyboardInterrupt: + raise + except: + pass + if len(found) == 0: + print('No UltraBorg boards found, is bus #%d correct (should be 0 for Rev 1, 1 for Rev 2)' % (busNumber)) + elif len(found) == 1: + print('1 UltraBorg board found') + else: + print('%d UltraBorg boards found' % (len(found))) + return found + + +def SetNewAddress(newAddress, oldAddress = -1, busNumber = 1): + """ +SetNewAddress(newAddress, [oldAddress], [busNumber]) + +Scans the I²C bus for the first UltraBorg and sets it to a new I2C address +If oldAddress is supplied it will change the address of the board at that address rather than scanning the bus +The busNumber if supplied is which I²C bus to scan, 0 for Rev 1 boards, 1 for Rev 2 boards, if not supplied the default is 1 +Warning, this new I²C address will still be used after resetting the power on the device + """ + if newAddress < 0x03: + print('Error, I²C addresses below 3 (0x03) are reserved, use an address between 3 (0x03) and 119 (0x77)') + return + elif newAddress > 0x77: + print('Error, I²C addresses above 119 (0x77) are reserved, use an address between 3 (0x03) and 119 (0x77)') + return + if oldAddress < 0x0: + found = ScanForUltraBorg(busNumber) + if len(found) < 1: + print('No UltraBorg boards found, cannot set a new I²C address!') + return + else: + oldAddress = found[0] + print('Changing I²C address from %02X to %02X (bus #%d)' % (oldAddress, newAddress, busNumber)) + bus = UltraBorg() + bus.InitBusOnly(busNumber, oldAddress) + try: + i2cRecv = bus.RawRead(COMMAND_GET_ID, I2C_MAX_LEN) + if len(i2cRecv) == I2C_MAX_LEN: + if i2cRecv[1] == I2C_ID_SERVO_USM: + foundChip = True + print('Found UltraBorg at %02X' % (oldAddress)) + else: + foundChip = False + print('Found a device at %02X, but it is not a UltraBorg (ID %02X instead of %02X)' % (oldAddress, i2cRecv[1], I2C_ID_SERVO_USM)) + else: + foundChip = False + print('Missing UltraBorg at %02X' % (oldAddress)) + except KeyboardInterrupt: + raise + except: + foundChip = False + print('Missing UltraBorg at %02X' % (oldAddress)) + if foundChip: + bus.RawWrite(COMMAND_SET_I2C_ADD, [newAddress]) + time.sleep(0.1) + print('Address changed to %02X, attempting to talk with the new address' % (newAddress)) + try: + bus.InitBusOnly(busNumber, newAddress) + i2cRecv = bus.RawRead(COMMAND_GET_ID, I2C_MAX_LEN) + if len(i2cRecv) == I2C_MAX_LEN: + if i2cRecv[1] == I2C_ID_SERVO_USM: + foundChip = True + print('Found UltraBorg at %02X' % (newAddress)) + else: + foundChip = False + print('Found a device at %02X, but it is not a UltraBorg (ID %02X instead of %02X)' % (newAddress, i2cRecv[1], I2C_ID_SERVO_USM)) + else: + foundChip = False + print('Missing UltraBorg at %02X' % (newAddress)) + except KeyboardInterrupt: + raise + except: + foundChip = False + print('Missing UltraBorg at %02X' % (newAddress)) + if foundChip: + print('New I²C address of %02X set successfully' % (newAddress)) + else: + print('Failed to set new I²C address...') + + +# Class used to control UltraBorg +class UltraBorg: + """ +This module is designed to communicate with the UltraBorg + +busNumber I²C bus on which the UltraBorg is attached (Rev 1 is bus 0, Rev 2 is bus 1) +bus the smbus object used to talk to the I²C bus +i2cAddress The I²C address of the UltraBorg chip to control +foundChip True if the UltraBorg chip can be seen, False otherwise +printFunction Function reference to call when printing text, if None "print" is used + """ + + # Shared values used by this class + busNumber = 1 # Check here for Rev 1 vs Rev 2 and select the correct bus + i2cAddress = I2C_ID_SERVO_USM # I²C address, override for a different address + foundChip = False + printFunction = None + i2cWrite = None + i2cRead = None + + # Default calibration adjustments to standard values + PWM_MIN_1 = PWM_MIN + PWM_MAX_1 = PWM_MAX + PWM_MIN_2 = PWM_MIN + PWM_MAX_2 = PWM_MAX + PWM_MIN_3 = PWM_MIN + PWM_MAX_3 = PWM_MAX + PWM_MIN_4 = PWM_MIN + PWM_MAX_4 = PWM_MAX + + def RawWrite(self, command, data): + """ +RawWrite(command, data) + +Sends a raw command on the I2C bus to the UltraBorg +Command codes can be found at the top of UltraBorg.py, data is a list of 0 or more byte values + +Under most circumstances you should use the appropriate function instead of RawWrite + """ + rawOutput = [command] + rawOutput.extend(data) + rawOutput = bytes(rawOutput) + self.i2cWrite.write(rawOutput) + + + def RawRead(self, command, length, retryCount = 3): + """ +RawRead(command, length, [retryCount]) + +Reads data back from the UltraBorg after sending a GET command +Command codes can be found at the top of UltraBorg.py, length is the number of bytes to read back + +The function checks that the first byte read back matches the requested command +If it does not it will retry the request until retryCount is exhausted (default is 3 times) + +Under most circumstances you should use the appropriate function instead of RawRead + """ + while retryCount > 0: + self.RawWrite(command, []) + time.sleep(0.000001) + rawReply = self.i2cRead.read(length) + reply = [] + for singleByte in rawReply: + reply.append(singleByte) + if command == reply[0]: + break + else: + retryCount -= 1 + if retryCount > 0: + return reply + else: + raise IOError('I2C read for command %d failed' % (command)) + + + def InitBusOnly(self, busNumber, address): + """ +InitBusOnly(busNumber, address) + +Prepare the I2C driver for talking to a UltraBorg on the specified bus and I2C address +This call does not check the board is present or working, under most circumstances use Init() instead + """ + self.busNumber = busNumber + self.i2cAddress = address + self.i2cRead = io.open("/dev/i2c-" + str(self.busNumber), "rb", buffering = 0) + fcntl.ioctl(self.i2cRead, I2C_SLAVE, self.i2cAddress) + self.i2cWrite = io.open("/dev/i2c-" + str(self.busNumber), "wb", buffering = 0) + fcntl.ioctl(self.i2cWrite, I2C_SLAVE, self.i2cAddress) + + + def Print(self, message): + """ +Print(message) + +Wrapper used by the UltraBorg instance to print messages, will call printFunction if set, print otherwise + """ + if self.printFunction == None: + print(message) + else: + self.printFunction(message) + + + def NoPrint(self, message): + """ +NoPrint(message) + +Does nothing, intended for disabling diagnostic printout by using: +UB = UltraBorg.UltraBorg() +UB.printFunction = UB.NoPrint + """ + pass + + + def Init(self, tryOtherBus = False): + """ +Init([tryOtherBus]) + +Prepare the I2C driver for talking to the UltraBorg + +If tryOtherBus is True, this function will attempt to use the other bus if the ThunderBorg devices can not be found on the current busNumber + This is only really useful for early Raspberry Pi models! + """ + self.Print('Loading UltraBorg on bus %d, address %02X' % (self.busNumber, self.i2cAddress)) + + # Open the bus + self.i2cRead = io.open("/dev/i2c-" + str(self.busNumber), "rb", buffering = 0) + fcntl.ioctl(self.i2cRead, I2C_SLAVE, self.i2cAddress) + self.i2cWrite = io.open("/dev/i2c-" + str(self.busNumber), "wb", buffering = 0) + fcntl.ioctl(self.i2cWrite, I2C_SLAVE, self.i2cAddress) + + # Check for UltraBorg + try: + i2cRecv = self.RawRead(COMMAND_GET_ID, I2C_MAX_LEN) + if len(i2cRecv) == I2C_MAX_LEN: + if i2cRecv[1] == I2C_ID_SERVO_USM: + self.foundChip = True + self.Print('Found UltraBorg at %02X' % (self.i2cAddress)) + else: + self.foundChip = False + self.Print('Found a device at %02X, but it is not a UltraBorg (ID %02X instead of %02X)' % (self.i2cAddress, i2cRecv[1], I2C_ID_SERVO_USM)) + else: + self.foundChip = False + self.Print('Missing UltraBorg at %02X' % (self.i2cAddress)) + except KeyboardInterrupt: + raise + except: + self.foundChip = False + self.Print('Missing UltraBorg at %02X' % (self.i2cAddress)) + + # See if we are missing chips + if not self.foundChip: + self.Print('UltraBorg was not found') + if tryOtherBus: + if self.busNumber == 1: + self.busNumber = 0 + else: + self.busNumber = 1 + self.Print('Trying bus %d instead' % (self.busNumber)) + self.Init(False) + else: + self.Print('Are you sure your UltraBorg is properly attached, the correct address is used, and the I2C drivers are running?') + self.bus = None + else: + self.Print('UltraBorg loaded on bus %d' % (self.busNumber)) + + # Read the calibration settings from the UltraBorg + self.PWM_MIN_1 = self.GetWithRetry(self.GetServoMinimum1, 5) + self.PWM_MAX_1 = self.GetWithRetry(self.GetServoMaximum1, 5) + self.PWM_MIN_2 = self.GetWithRetry(self.GetServoMinimum2, 5) + self.PWM_MAX_2 = self.GetWithRetry(self.GetServoMaximum2, 5) + self.PWM_MIN_3 = self.GetWithRetry(self.GetServoMinimum3, 5) + self.PWM_MAX_3 = self.GetWithRetry(self.GetServoMaximum3, 5) + self.PWM_MIN_4 = self.GetWithRetry(self.GetServoMinimum4, 5) + self.PWM_MAX_4 = self.GetWithRetry(self.GetServoMaximum4, 5) + + + def GetWithRetry(self, function, count): + """ +value = GetWithRetry(function, count) + +Attempts to read a value multiple times before giving up +Pass a get function with no parameters +e.g. +distance = GetWithRetry(UB.GetDistance1, 5) +Will try UB.GetDistance1() upto 5 times, returning when it gets a value +Useful for ensuring a read is successful + """ + value = None + for i in range(count): + okay = True + try: + value = function() + except KeyboardInterrupt: + raise + except: + okay = False + if okay: + break + return value + + + def SetWithRetry(self, setFunction, getFunction, value, count): + """ +worked = SetWithRetry(setFunction, getFunction, value, count) + +Attempts to write a value multiple times before giving up +Pass a set function with one parameter, and a get function no parameters +The get function will be used to check if the set worked, if not it will be repeated +e.g. +worked = SetWithRetry(UB.SetServoMinimum1, UB.GetServoMinimum1, 2000, 5) +Will try UB.SetServoMinimum1(2000) upto 5 times, returning when UB.GetServoMinimum1 returns 2000. +Useful for ensuring a write is successful + """ + for i in range(count): + okay = True + try: + setFunction(value) + readValue = getFunction() + except KeyboardInterrupt: + raise + except: + okay = False + if okay: + if readValue == value: + break + else: + okay = False + return okay + + + def GetDistance1(self): + """ +distance = GetDistance1() + +Gets the filtered distance for ultrasonic module #1 in millimeters +Returns 0 for no object detected or no ultrasonic module attached +If you need a faster response try GetRawDistance1 instead (no filtering) +e.g. +0 -> No object in range +25 -> Object 25 mm away +1000 -> Object 1000 mm (1 m) away +3500 -> Object 3500 mm (3.5 m) away + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_FILTER_USM1, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading ultrasonic #1 distance!') + return + + time_us = (i2cRecv[1] << 8) + i2cRecv[2] + if time_us == 65535: + time_us = 0 + return time_us * USM_US_TO_MM + + + def GetDistance2(self): + """ +distance = GetDistance2() + +Gets the filtered distance for ultrasonic module #2 in millimeters +Returns 0 for no object detected or no ultrasonic module attached +If you need a faster response try GetRawDistance2 instead (no filtering) +e.g. +0 -> No object in range +25 -> Object 25 mm away +1000 -> Object 1000 mm (1 m) away +3500 -> Object 3500 mm (3.5 m) away + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_FILTER_USM2, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading ultrasonic #2 distance!') + return + + time_us = (i2cRecv[1] << 8) + i2cRecv[2] + if time_us == 65535: + time_us = 0 + return time_us * USM_US_TO_MM + + + def GetDistance3(self): + """ +distance = GetDistance3() + +Gets the filtered distance for ultrasonic module #3 in millimeters +Returns 0 for no object detected or no ultrasonic module attached +If you need a faster response try GetRawDistance3 instead (no filtering) +e.g. +0 -> No object in range +25 -> Object 25 mm away +1000 -> Object 1000 mm (1 m) away +3500 -> Object 3500 mm (3.5 m) away + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_FILTER_USM3, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading ultrasonic #3 distance!') + return + + time_us = (i2cRecv[1] << 8) + i2cRecv[2] + if time_us == 65535: + time_us = 0 + return time_us * USM_US_TO_MM + + + def GetDistance4(self): + """ +distance = GetDistance4() + +Gets the filtered distance for ultrasonic module #4 in millimeters +Returns 0 for no object detected or no ultrasonic module attached +If you need a faster response try GetRawDistance4 instead (no filtering) +e.g. +0 -> No object in range +25 -> Object 25 mm away +1000 -> Object 1000 mm (1 m) away +3500 -> Object 3500 mm (3.5 m) away + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_FILTER_USM4, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading ultrasonic #4 distance!') + return + + time_us = (i2cRecv[1] << 8) + i2cRecv[2] + if time_us == 65535: + time_us = 0 + return time_us * USM_US_TO_MM + + + + def GetRawDistance1(self): + """ +distance = GetRawDistance1() + +Gets the raw distance for ultrasonic module #1 in millimeters +Returns 0 for no object detected or no ultrasonic module attached +For a filtered (less jumpy) reading use GetDistance1 +e.g. +0 -> No object in range +25 -> Object 25 mm away +1000 -> Object 1000 mm (1 m) away +3500 -> Object 3500 mm (3.5 m) away + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_TIME_USM1, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading ultrasonic #1 distance!') + return + + time_us = (i2cRecv[1] << 8) + i2cRecv[2] + if time_us == 65535: + time_us = 0 + return time_us * USM_US_TO_MM + + + def GetRawDistance2(self): + """ +distance = GetRawDistance2() + +Gets the raw distance for ultrasonic module #2 in millimeters +Returns 0 for no object detected or no ultrasonic module attached +For a filtered (less jumpy) reading use GetDistance2 +e.g. +0 -> No object in range +25 -> Object 25 mm away +1000 -> Object 1000 mm (1 m) away +3500 -> Object 3500 mm (3.5 m) away + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_TIME_USM2, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading ultrasonic #2 distance!') + return + + time_us = (i2cRecv[1] << 8) + i2cRecv[2] + if time_us == 65535: + time_us = 0 + return time_us * USM_US_TO_MM + + + def GetRawDistance3(self): + """ +distance = GetRawDistance3() + +Gets the raw distance for ultrasonic module #3 in millimeters +Returns 0 for no object detected or no ultrasonic module attached +For a filtered (less jumpy) reading use GetDistance3 +e.g. +0 -> No object in range +25 -> Object 25 mm away +1000 -> Object 1000 mm (1 m) away +3500 -> Object 3500 mm (3.5 m) away + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_TIME_USM3, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading ultrasonic #3 distance!') + return + + time_us = (i2cRecv[1] << 8) + i2cRecv[2] + if time_us == 65535: + time_us = 0 + return time_us * USM_US_TO_MM + + + def GetRawDistance4(self): + """ +distance = GetRawDistance4() + +Gets the distance for ultrasonic module #4 in millimeters +Returns 0 for no object detected or no ultrasonic module attached +For a filtered (less jumpy) reading use GetDistance4 +e.g. +0 -> No object in range +25 -> Object 25 mm away +1000 -> Object 1000 mm (1 m) away +3500 -> Object 3500 mm (3.5 m) away + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_TIME_USM4, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading ultrasonic #4 distance!') + return + + time_us = (i2cRecv[1] << 8) + i2cRecv[2] + if time_us == 65535: + time_us = 0 + return time_us * USM_US_TO_MM + + + def GetServoPosition1(self): + """ +position = GetServoPosition1() + +Gets the drive position for servo output #1 +0 is central, -1 is maximum left, +1 is maximum right +e.g. +0 -> Central +0.5 -> 50% to the right +1 -> 100% to the right +-0.75 -> 75% to the left + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_PWM1, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading servo output #1!') + return + + pwmDuty = (i2cRecv[1] << 8) + i2cRecv[2] + powerOut = (float(pwmDuty) - self.PWM_MIN_1) / (self.PWM_MAX_1 - self.PWM_MIN_1) + return (2.0 * powerOut) - 1.0 + + + def GetServoPosition2(self): + """ +position = GetServoPosition2() + +Gets the drive position for servo output #2 +0 is central, -1 is maximum left, +1 is maximum right +e.g. +0 -> Central +0.5 -> 50% to the right +1 -> 100% to the right +-0.75 -> 75% to the left + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_PWM2, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading servo output #2!') + return + + pwmDuty = (i2cRecv[1] << 8) + i2cRecv[2] + powerOut = (float(pwmDuty) - self.PWM_MIN_2) / (self.PWM_MAX_2 - self.PWM_MIN_2) + return (2.0 * powerOut) - 1.0 + + + def GetServoPosition3(self): + """ +position = GetServoPosition3() + +Gets the drive position for servo output #3 +0 is central, -1 is maximum left, +1 is maximum right +e.g. +0 -> Central +0.5 -> 50% to the right +1 -> 100% to the right +-0.75 -> 75% to the left + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_PWM3, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading servo output #3!') + return + + pwmDuty = (i2cRecv[1] << 8) + i2cRecv[2] + powerOut = (float(pwmDuty) - self.PWM_MIN_3) / (self.PWM_MAX_3 - self.PWM_MIN_3) + return (2.0 * powerOut) - 1.0 + + + def GetServoPosition4(self): + """ +position = GetServoPosition4() + +Gets the drive position for servo output #4 +0 is central, -1 is maximum left, +1 is maximum right +e.g. +0 -> Central +0.5 -> 50% to the right +1 -> 100% to the right +-0.75 -> 75% to the left + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_PWM4, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading servo output #4!') + return + + pwmDuty = (i2cRecv[1] << 8) + i2cRecv[2] + powerOut = (float(pwmDuty) - self.PWM_MIN_4) / (self.PWM_MAX_4 - self.PWM_MIN_4) + return (2.0 * powerOut) - 1.0 + + + def SetServoPosition1(self, position): + """ +SetServoPosition1(position) + +Sets the drive position for servo output #1 +0 is central, -1 is maximum left, +1 is maximum right +e.g. +0 -> Central +0.5 -> 50% to the right +1 -> 100% to the right +-0.75 -> 75% to the left + """ + powerOut = (position + 1.0) / 2.0 + pwmDuty = int((powerOut * (self.PWM_MAX_1 - self.PWM_MIN_1)) + self.PWM_MIN_1) + pwmDutyLow = pwmDuty & 0xFF + pwmDutyHigh = (pwmDuty >> 8) & 0xFF + + try: + self.RawWrite(COMMAND_SET_PWM1, [pwmDutyHigh, pwmDutyLow]) + except KeyboardInterrupt: + raise + except: + self.Print('Failed sending servo output #1!') + + + def SetServoPosition2(self, position): + """ +SetServoPosition2(position) + +Sets the drive position for servo output #2 +0 is central, -1 is maximum left, +1 is maximum right +e.g. +0 -> Central +0.5 -> 50% to the right +1 -> 100% to the right +-0.75 -> 75% to the left + """ + powerOut = (position + 1.0) / 2.0 + pwmDuty = int((powerOut * (self.PWM_MAX_2 - self.PWM_MIN_2)) + self.PWM_MIN_2) + pwmDutyLow = pwmDuty & 0xFF + pwmDutyHigh = (pwmDuty >> 8) & 0xFF + + try: + self.RawWrite(COMMAND_SET_PWM2, [pwmDutyHigh, pwmDutyLow]) + except KeyboardInterrupt: + raise + except: + self.Print('Failed sending servo output #2!') + + + def SetServoPosition3(self, position): + """ +SetServoPosition3(position) + +Sets the drive position for servo output #3 +0 is central, -1 is maximum left, +1 is maximum right +e.g. +0 -> Central +0.5 -> 50% to the right +1 -> 100% to the right +-0.75 -> 75% to the left + """ + powerOut = (position + 1.0) / 2.0 + pwmDuty = int((powerOut * (self.PWM_MAX_3 - self.PWM_MIN_3)) + self.PWM_MIN_3) + pwmDutyLow = pwmDuty & 0xFF + pwmDutyHigh = (pwmDuty >> 8) & 0xFF + + try: + self.RawWrite(COMMAND_SET_PWM3, [pwmDutyHigh, pwmDutyLow]) + except KeyboardInterrupt: + raise + except: + self.Print('Failed sending servo output #3!') + + + def SetServoPosition4(self, position): + """ +SetServoPosition4(position) + +Sets the drive position for servo output #4 +0 is central, -1 is maximum left, +1 is maximum right +e.g. +0 -> Central +0.5 -> 50% to the right +1 -> 100% to the right +-0.75 -> 75% to the left + """ + powerOut = (position + 1.0) / 2.0 + pwmDuty = int((powerOut * (self.PWM_MAX_4 - self.PWM_MIN_4)) + self.PWM_MIN_4) + pwmDutyLow = pwmDuty & 0xFF + pwmDutyHigh = (pwmDuty >> 8) & 0xFF + + try: + self.RawWrite(COMMAND_SET_PWM4, [pwmDutyHigh, pwmDutyLow]) + except KeyboardInterrupt: + raise + except: + self.Print('Failed sending servo output #1!') + + + def GetServoMinimum1(self): + """ +pwmLevel = GetServoMinimum1() + +Gets the minimum PWM level for servo output #1 +This corresponds to position -1 +The value is an integer where 2000 represents a 1 ms servo burst +e.g. +2000 -> 1 ms servo burst, typical shortest burst +4000 -> 2 ms servo burst, typical longest burst +3000 -> 1.5 ms servo burst, typical centre +5000 -> 2.5 ms servo burst, higher than typical longest burst + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_PWM_MIN_1, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading servo #1 minimum burst!') + return + + return (i2cRecv[1] << 8) + i2cRecv[2] + + + def GetServoMinimum2(self): + """ +pwmLevel = GetServoMinimum2() + +Gets the minimum PWM level for servo output #2 +This corresponds to position -1 +The value is an integer where 2000 represents a 1 ms servo burst +e.g. +2000 -> 1 ms servo burst, typical shortest burst +4000 -> 2 ms servo burst, typical longest burst +3000 -> 1.5 ms servo burst, typical centre +5000 -> 2.5 ms servo burst, higher than typical longest burst + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_PWM_MIN_2, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading servo #2 minimum burst!') + return + + return (i2cRecv[1] << 8) + i2cRecv[2] + + + def GetServoMinimum3(self): + """ +pwmLevel = GetServoMinimum3() + +Gets the minimum PWM level for servo output #3 +This corresponds to position -1 +The value is an integer where 2000 represents a 1 ms servo burst +e.g. +2000 -> 1 ms servo burst, typical shortest burst +4000 -> 2 ms servo burst, typical longest burst +3000 -> 1.5 ms servo burst, typical centre +5000 -> 2.5 ms servo burst, higher than typical longest burst + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_PWM_MIN_3, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading servo #3 minimum burst!') + return + + return (i2cRecv[1] << 8) + i2cRecv[2] + + + def GetServoMinimum4(self): + """ +pwmLevel = GetServoMinimum4() + +Gets the minimum PWM level for servo output #4 +This corresponds to position -1 +The value is an integer where 2000 represents a 1 ms servo burst +e.g. +2000 -> 1 ms servo burst, typical shortest burst +4000 -> 2 ms servo burst, typical longest burst +3000 -> 1.5 ms servo burst, typical centre +5000 -> 2.5 ms servo burst, higher than typical longest burst + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_PWM_MIN_4, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading servo #4 minimum burst!') + return + + return (i2cRecv[1] << 8) + i2cRecv[2] + + + def GetServoMaximum1(self): + """ +pwmLevel = GetServoMaximum1() + +Gets the maximum PWM level for servo output #1 +This corresponds to position +1 +The value is an integer where 2000 represents a 1 ms servo burst +e.g. +2000 -> 1 ms servo burst, typical shortest burst +4000 -> 2 ms servo burst, typical longest burst +3000 -> 1.5 ms servo burst, typical centre +5000 -> 2.5 ms servo burst, higher than typical longest burst + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_PWM_MAX_1, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading servo #1 maximum burst!') + return + + return (i2cRecv[1] << 8) + i2cRecv[2] + + + def GetServoMaximum2(self): + """ +pwmLevel = GetServoMaximum2() + +Gets the maximum PWM level for servo output #2 +This corresponds to position +1 +The value is an integer where 2000 represents a 1 ms servo burst +e.g. +2000 -> 1 ms servo burst, typical shortest burst +4000 -> 2 ms servo burst, typical longest burst +3000 -> 1.5 ms servo burst, typical centre +5000 -> 2.5 ms servo burst, higher than typical longest burst + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_PWM_MAX_2, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading servo #2 maximum burst!') + return + + return (i2cRecv[1] << 8) + i2cRecv[2] + + + def GetServoMaximum3(self): + """ +pwmLevel = GetServoMaximum3() + +Gets the maximum PWM level for servo output #3 +This corresponds to position +1 +The value is an integer where 2000 represents a 1 ms servo burst +e.g. +2000 -> 1 ms servo burst, typical shortest burst +4000 -> 2 ms servo burst, typical longest burst +3000 -> 1.5 ms servo burst, typical centre +5000 -> 2.5 ms servo burst, higher than typical longest burst + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_PWM_MAX_3, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading servo #3 maximum burst!') + return + + return (i2cRecv[1] << 8) + i2cRecv[2] + + + def GetServoMaximum4(self): + """ +pwmLevel = GetServoMaximum4() + +Gets the maximum PWM level for servo output #4 +This corresponds to position +1 +The value is an integer where 2000 represents a 1 ms servo burst +e.g. +2000 -> 1 ms servo burst, typical shortest burst +4000 -> 2 ms servo burst, typical longest burst +3000 -> 1.5 ms servo burst, typical centre +5000 -> 2.5 ms servo burst, higher than typical longest burst + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_PWM_MAX_4, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading servo #4 maximum burst!') + return + + return (i2cRecv[1] << 8) + i2cRecv[2] + + + def GetServoStartup1(self): + """ +pwmLevel = GetServoStartup1() + +Gets the startup PWM level for servo output #1 +This can be anywhere in the minimum to maximum range +The value is an integer where 2000 represents a 1 ms servo burst +e.g. +2000 -> 1 ms servo burst, typical shortest burst +4000 -> 2 ms servo burst, typical longest burst +3000 -> 1.5 ms servo burst, typical centre +5000 -> 2.5 ms servo burst, higher than typical longest burst + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_PWM_BOOT_1, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading servo #1 startup burst!') + return + + return (i2cRecv[1] << 8) + i2cRecv[2] + + + def GetServoStartup2(self): + """ +pwmLevel = GetServoStartup2() + +Gets the startup PWM level for servo output #2 +This can be anywhere in the minimum to maximum range +The value is an integer where 2000 represents a 1 ms servo burst +e.g. +2000 -> 1 ms servo burst, typical shortest burst +4000 -> 2 ms servo burst, typical longest burst +3000 -> 1.5 ms servo burst, typical centre +5000 -> 2.5 ms servo burst, higher than typical longest burst + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_PWM_BOOT_2, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading servo #2 startup burst!') + return + + return (i2cRecv[1] << 8) + i2cRecv[2] + + + def GetServoStartup3(self): + """ +pwmLevel = GetServoStartup3() + +Gets the startup PWM level for servo output #3 +This can be anywhere in the minimum to maximum range +The value is an integer where 2000 represents a 1 ms servo burst +e.g. +2000 -> 1 ms servo burst, typical shortest burst +4000 -> 2 ms servo burst, typical longest burst +3000 -> 1.5 ms servo burst, typical centre +5000 -> 2.5 ms servo burst, higher than typical longest burst + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_PWM_BOOT_3, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading servo #3 startup burst!') + return + + return (i2cRecv[1] << 8) + i2cRecv[2] + + + def GetServoStartup4(self): + """ +pwmLevel = GetServoStartup4() + +Gets the startup PWM level for servo output #4 +This can be anywhere in the minimum to maximum range +The value is an integer where 2000 represents a 1 ms servo burst +e.g. +2000 -> 1 ms servo burst, typical shortest burst +4000 -> 2 ms servo burst, typical longest burst +3000 -> 1.5 ms servo burst, typical centre, +5000 -> 2.5 ms servo burst, higher than typical longest burst + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_PWM_BOOT_4, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading servo #4 startup burst!') + return + + return (i2cRecv[1] << 8) + i2cRecv[2] + + + def CalibrateServoPosition1(self, pwmLevel): + """ +CalibrateServoPosition1(pwmLevel) + +Sets the raw PWM level for servo output #1 +This value can be set anywhere from 0 for a 0% duty cycle to 65535 for a 100% duty cycle + +Setting values outside the range of the servo for extended periods of time can damage the servo +NO LIMIT CHECKING IS PERFORMED BY THIS COMMAND! +We recommend using the tuning GUI for setting the servo limits for SetServoPosition1 / GetServoPosition1 + +The value is an integer where 2000 represents a 1ms servo burst, approximately 3% duty cycle +e.g. +2000 -> 1 ms servo burst, typical shortest burst, ~3% duty cycle +4000 -> 2 ms servo burst, typical longest burst, ~ 6.1% duty cycle +3000 -> 1.5 ms servo burst, typical centre, ~4.6% duty cycle +5000 -> 2.5 ms servo burst, higher than typical longest burst, ~ 7.6% duty cycle + """ + pwmDutyLow = pwmLevel & 0xFF + pwmDutyHigh = (pwmLevel >> 8) & 0xFF + + try: + self.RawWrite(COMMAND_CALIBRATE_PWM1, [pwmDutyHigh, pwmDutyLow]) + except KeyboardInterrupt: + raise + except: + self.Print('Failed sending calibration servo output #1!') + + + def CalibrateServoPosition2(self, pwmLevel): + """ +CalibrateServoPosition2(pwmLevel) + +Sets the raw PWM level for servo output #2 +This value can be set anywhere from 0 for a 0% duty cycle to 65535 for a 100% duty cycle + +Setting values outside the range of the servo for extended periods of time can damage the servo +NO LIMIT CHECKING IS PERFORMED BY THIS COMMAND! +We recommend using the tuning GUI for setting the servo limits for SetServoPosition2 / GetServoPosition2 + +The value is an integer where 2000 represents a 1ms servo burst, approximately 3% duty cycle +e.g. +2000 -> 1 ms servo burst, typical shortest burst, ~3% duty cycle +4000 -> 2 ms servo burst, typical longest burst, ~ 6.1% duty cycle +3000 -> 1.5 ms servo burst, typical centre, ~4.6% duty cycle +5000 -> 2.5 ms servo burst, higher than typical longest burst, ~ 7.6% duty cycle + """ + pwmDutyLow = pwmLevel & 0xFF + pwmDutyHigh = (pwmLevel >> 8) & 0xFF + + try: + self.RawWrite(COMMAND_CALIBRATE_PWM2, [pwmDutyHigh, pwmDutyLow]) + except KeyboardInterrupt: + raise + except: + self.Print('Failed sending calibration servo output #2!') + + + def CalibrateServoPosition3(self, pwmLevel): + """ +CalibrateServoPosition3(pwmLevel) + +Sets the raw PWM level for servo output #3 +This value can be set anywhere from 0 for a 0% duty cycle to 65535 for a 100% duty cycle + +Setting values outside the range of the servo for extended periods of time can damage the servo +NO LIMIT CHECKING IS PERFORMED BY THIS COMMAND! +We recommend using the tuning GUI for setting the servo limits for SetServoPosition3 / GetServoPosition3 + +The value is an integer where 2000 represents a 1ms servo burst, approximately 3% duty cycle +e.g. +2000 -> 1 ms servo burst, typical shortest burst, ~3% duty cycle +4000 -> 2 ms servo burst, typical longest burst, ~ 6.1% duty cycle +3000 -> 1.5 ms servo burst, typical centre, ~4.6% duty cycle +5000 -> 2.5 ms servo burst, higher than typical longest burst, ~ 7.6% duty cycle + """ + pwmDutyLow = pwmLevel & 0xFF + pwmDutyHigh = (pwmLevel >> 8) & 0xFF + + try: + self.RawWrite(COMMAND_CALIBRATE_PWM3, [pwmDutyHigh, pwmDutyLow]) + except KeyboardInterrupt: + raise + except: + self.Print('Failed sending calibration servo output #3!') + + + def CalibrateServoPosition4(self, pwmLevel): + """ +CalibrateServoPosition4(pwmLevel) + +Sets the raw PWM level for servo output #4 +This value can be set anywhere from 0 for a 0% duty cycle to 65535 for a 100% duty cycle + +Setting values outside the range of the servo for extended periods of time can damage the servo +NO LIMIT CHECKING IS PERFORMED BY THIS COMMAND! +We recommend using the tuning GUI for setting the servo limits for SetServoPosition4 / GetServoPosition4 + +The value is an integer where 2000 represents a 1ms servo burst, approximately 3% duty cycle +e.g. +2000 -> 1 ms servo burst, typical shortest burst, ~3% duty cycle +4000 -> 2 ms servo burst, typical longest burst, ~ 6.1% duty cycle +3000 -> 1.5 ms servo burst, typical centre, ~4.6% duty cycle +5000 -> 2.5 ms servo burst, higher than typical longest burst, ~ 7.6% duty cycle + """ + pwmDutyLow = pwmLevel & 0xFF + pwmDutyHigh = (pwmLevel >> 8) & 0xFF + + try: + self.RawWrite(COMMAND_CALIBRATE_PWM4, [pwmDutyHigh, pwmDutyLow]) + except KeyboardInterrupt: + raise + except: + self.Print('Failed sending calibration servo output #4!') + + + def GetRawServoPosition1(self): + """ +pwmLevel = GetRawServoPosition1() + +Gets the raw PWM level for servo output #1 +This value can be set anywhere from 0 for a 0% duty cycle to 65535 for a 100% duty cycle + +This value requires interpreting into an actual servo position, this is already done by GetServoPosition1 +We recommend using the tuning GUI for setting the servo limits for SetServoPosition1 / GetServoPosition1 + +The value is an integer where 2000 represents a 1ms servo burst, approximately 3% duty cycle +e.g. +2000 -> 1 ms servo burst, typical shortest burst, ~3% duty cycle +4000 -> 2 ms servo burst, typical longest burst, ~ 6.1% duty cycle +3000 -> 1.5 ms servo burst, typical centre, ~4.6% duty cycle +5000 -> 2.5 ms servo burst, higher than typical longest burst, ~ 7.6% duty cycle + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_PWM1, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading raw servo output #1!') + return + + pwmDuty = (i2cRecv[1] << 8) + i2cRecv[2] + return pwmDuty + + + def GetRawServoPosition2(self): + """ +pwmLevel = GetRawServoPosition2() + +Gets the raw PWM level for servo output #2 +This value can be set anywhere from 0 for a 0% duty cycle to 65535 for a 100% duty cycle + +This value requires interpreting into an actual servo position, this is already done by GetServoPosition2 +We recommend using the tuning GUI for setting the servo limits for SetServoPosition2 / GetServoPosition2 + +The value is an integer where 2000 represents a 1ms servo burst, approximately 3% duty cycle +e.g. +2000 -> 1 ms servo burst, typical shortest burst, ~3% duty cycle +4000 -> 2 ms servo burst, typical longest burst, ~ 6.1% duty cycle +3000 -> 1.5 ms servo burst, typical centre, ~4.6% duty cycle +5000 -> 2.5 ms servo burst, higher than typical longest burst, ~ 7.6% duty cycle + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_PWM2, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading raw servo output #2!') + return + + pwmDuty = (i2cRecv[1] << 8) + i2cRecv[2] + return pwmDuty + + + def GetRawServoPosition3(self): + """ +pwmLevel = GetRawServoPosition3() + +Gets the raw PWM level for servo output #3 +This value can be set anywhere from 0 for a 0% duty cycle to 65535 for a 100% duty cycle + +This value requires interpreting into an actual servo position, this is already done by GetServoPosition3 +We recommend using the tuning GUI for setting the servo limits for SetServoPosition3 / GetServoPosition3 + +The value is an integer where 2000 represents a 1ms servo burst, approximately 3% duty cycle +e.g. +2000 -> 1 ms servo burst, typical shortest burst, ~3% duty cycle +4000 -> 2 ms servo burst, typical longest burst, ~ 6.1% duty cycle +3000 -> 1.5 ms servo burst, typical centre, ~4.6% duty cycle +5000 -> 2.5 ms servo burst, higher than typical longest burst, ~ 7.6% duty cycle + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_PWM3, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading raw servo output #3!') + return + + pwmDuty = (i2cRecv[1] << 8) + i2cRecv[2] + return pwmDuty + + + def GetRawServoPosition4(self): + """ +pwmLevel = GetRawServoPosition4() + +Gets the raw PWM level for servo output #4 +This value can be set anywhere from 0 for a 0% duty cycle to 65535 for a 100% duty cycle + +This value requires interpreting into an actual servo position, this is already done by GetServoPosition4 +We recommend using the tuning GUI for setting the servo limits for SetServoPosition4 / GetServoPosition4 + +The value is an integer where 2000 represents a 1ms servo burst, approximately 3% duty cycle +e.g. +2000 -> 1 ms servo burst, typical shortest burst, ~3% duty cycle +4000 -> 2 ms servo burst, typical longest burst, ~ 6.1% duty cycle +3000 -> 1.5 ms servo burst, typical centre, ~4.6% duty cycle +5000 -> 2.5 ms servo burst, higher than typical longest burst, ~ 7.6% duty cycle + """ + try: + i2cRecv = self.RawRead(COMMAND_GET_PWM4, I2C_MAX_LEN) + except KeyboardInterrupt: + raise + except: + self.Print('Failed reading raw servo output #4!') + return + + pwmDuty = (i2cRecv[1] << 8) + i2cRecv[2] + return pwmDuty + + + def SetServoMinimum1(self, pwmLevel): + """ +SetServoMinimum1(pwmLevel) + +Sets the minimum PWM level for servo output #1 +This corresponds to position -1 +This value can be set anywhere from 0 for a 0% duty cycle to 65535 for a 100% duty cycle + +Setting values outside the range of the servo for extended periods of time can damage the servo +LIMIT CHECKING IS ALTERED BY THIS COMMAND! +We recommend using the tuning GUI for setting the servo limits for SetServoPosition1 / GetServoPosition1 + +The value is an integer where 2000 represents a 1ms servo burst, approximately 3% duty cycle +e.g. +2000 -> 1 ms servo burst, typical shortest burst, ~3% duty cycle +4000 -> 2 ms servo burst, typical longest burst, ~ 6.1% duty cycle +3000 -> 1.5 ms servo burst, typical centre, ~4.6% duty cycle +5000 -> 2.5 ms servo burst, higher than typical longest burst, ~ 7.6% duty cycle + """ + pwmDutyLow = pwmLevel & 0xFF + pwmDutyHigh = (pwmLevel >> 8) & 0xFF + + try: + self.RawWrite(COMMAND_SET_PWM_MIN_1, [pwmDutyHigh, pwmDutyLow]) + except KeyboardInterrupt: + raise + except: + self.Print('Failed sending servo minimum limit #1!') + time.sleep(DELAY_AFTER_EEPROM) + self.PWM_MIN_1 = self.GetServoMinimum1() + + + def SetServoMinimum2(self, pwmLevel): + """ +SetServoMinimum2(pwmLevel) + +Sets the minimum PWM level for servo output #2 +This corresponds to position -1 +This value can be set anywhere from 0 for a 0% duty cycle to 65535 for a 100% duty cycle + +Setting values outside the range of the servo for extended periods of time can damage the servo +LIMIT CHECKING IS ALTERED BY THIS COMMAND! +We recommend using the tuning GUI for setting the servo limits for SetServoPosition2 / GetServoPosition2 + +The value is an integer where 2000 represents a 1ms servo burst, approximately 3% duty cycle +e.g. +2000 -> 1 ms servo burst, typical shortest burst, ~3% duty cycle +4000 -> 2 ms servo burst, typical longest burst, ~ 6.1% duty cycle +3000 -> 1.5 ms servo burst, typical centre, ~4.6% duty cycle +5000 -> 2.5 ms servo burst, higher than typical longest burst, ~ 7.6% duty cycle + """ + pwmDutyLow = pwmLevel & 0xFF + pwmDutyHigh = (pwmLevel >> 8) & 0xFF + + try: + self.RawWrite(COMMAND_SET_PWM_MIN_2, [pwmDutyHigh, pwmDutyLow]) + except KeyboardInterrupt: + raise + except: + self.Print('Failed sending servo minimum limit #2!') + time.sleep(DELAY_AFTER_EEPROM) + self.PWM_MIN_2 = self.GetServoMinimum2() + + + def SetServoMinimum3(self, pwmLevel): + """ +SetServoMinimum3(pwmLevel) + +Sets the minimum PWM level for servo output #3 +This corresponds to position -1 +This value can be set anywhere from 0 for a 0% duty cycle to 65535 for a 100% duty cycle + +Setting values outside the range of the servo for extended periods of time can damage the servo +LIMIT CHECKING IS ALTERED BY THIS COMMAND! +We recommend using the tuning GUI for setting the servo limits for SetServoPosition3 / GetServoPosition3 + +The value is an integer where 2000 represents a 1ms servo burst, approximately 3% duty cycle +e.g. +2000 -> 1 ms servo burst, typical shortest burst, ~3% duty cycle +4000 -> 2 ms servo burst, typical longest burst, ~ 6.1% duty cycle +3000 -> 1.5 ms servo burst, typical centre, ~4.6% duty cycle +5000 -> 2.5 ms servo burst, higher than typical longest burst, ~ 7.6% duty cycle + """ + pwmDutyLow = pwmLevel & 0xFF + pwmDutyHigh = (pwmLevel >> 8) & 0xFF + + try: + self.RawWrite(COMMAND_SET_PWM_MIN_3, [pwmDutyHigh, pwmDutyLow]) + except KeyboardInterrupt: + raise + except: + self.Print('Failed sending servo minimum limit #3!') + time.sleep(DELAY_AFTER_EEPROM) + self.PWM_MIN_3 = self.GetServoMinimum3() + + + def SetServoMinimum4(self, pwmLevel): + """ +SetServoMinimum4(pwmLevel) + +Sets the minimum PWM level for servo output #4 +This corresponds to position -1 +This value can be set anywhere from 0 for a 0% duty cycle to 65535 for a 100% duty cycle + +Setting values outside the range of the servo for extended periods of time can damage the servo +LIMIT CHECKING IS ALTERED BY THIS COMMAND! +We recommend using the tuning GUI for setting the servo limits for SetServoPosition4 / GetServoPosition4 + +The value is an integer where 2000 represents a 1ms servo burst, approximately 3% duty cycle +e.g. +2000 -> 1 ms servo burst, typical shortest burst, ~3% duty cycle +4000 -> 2 ms servo burst, typical longest burst, ~ 6.1% duty cycle +3000 -> 1.5 ms servo burst, typical centre, ~4.6% duty cycle +5000 -> 2.5 ms servo burst, higher than typical longest burst, ~ 7.6% duty cycle + """ + pwmDutyLow = pwmLevel & 0xFF + pwmDutyHigh = (pwmLevel >> 8) & 0xFF + + try: + self.RawWrite(COMMAND_SET_PWM_MIN_4, [pwmDutyHigh, pwmDutyLow]) + except KeyboardInterrupt: + raise + except: + self.Print('Failed sending servo minimum limit #4!') + time.sleep(DELAY_AFTER_EEPROM) + self.PWM_MIN_4 = self.GetServoMinimum4() + + + def SetServoMaximum1(self, pwmLevel): + """ +SetServoMaximum1(pwmLevel) + +Sets the maximum PWM level for servo output #1 +This corresponds to position +1 +This value can be set anywhere from 0 for a 0% duty cycle to 65535 for a 100% duty cycle + +Setting values outside the range of the servo for extended periods of time can damage the servo +LIMIT CHECKING IS ALTERED BY THIS COMMAND! +We recommend using the tuning GUI for setting the servo limits for SetServoPosition1 / GetServoPosition1 + +The value is an integer where 2000 represents a 1ms servo burst, approximately 3% duty cycle +e.g. +2000 -> 1 ms servo burst, typical shortest burst, ~3% duty cycle +4000 -> 2 ms servo burst, typical longest burst, ~ 6.1% duty cycle +3000 -> 1.5 ms servo burst, typical centre, ~4.6% duty cycle +5000 -> 2.5 ms servo burst, higher than typical longest burst, ~ 7.6% duty cycle + """ + pwmDutyLow = pwmLevel & 0xFF + pwmDutyHigh = (pwmLevel >> 8) & 0xFF + + try: + self.RawWrite(COMMAND_SET_PWM_MAX_1, [pwmDutyHigh, pwmDutyLow]) + except KeyboardInterrupt: + raise + except: + self.Print('Failed sending servo maximum limit #1!') + time.sleep(DELAY_AFTER_EEPROM) + self.PWM_MAX_1 = self.GetServoMaximum1() + + + def SetServoMaximum2(self, pwmLevel): + """ +SetServoMaximum2(pwmLevel) + +Sets the maximum PWM level for servo output #2 +This corresponds to position +1 +This value can be set anywhere from 0 for a 0% duty cycle to 65535 for a 100% duty cycle + +Setting values outside the range of the servo for extended periods of time can damage the servo +LIMIT CHECKING IS ALTERED BY THIS COMMAND! +We recommend using the tuning GUI for setting the servo limits for SetServoPosition2 / GetServoPosition2 + +The value is an integer where 2000 represents a 1ms servo burst, approximately 3% duty cycle +e.g. +2000 -> 1 ms servo burst, typical shortest burst, ~3% duty cycle +4000 -> 2 ms servo burst, typical longest burst, ~ 6.1% duty cycle +3000 -> 1.5 ms servo burst, typical centre, ~4.6% duty cycle +5000 -> 2.5 ms servo burst, higher than typical longest burst, ~ 7.6% duty cycle + """ + pwmDutyLow = pwmLevel & 0xFF + pwmDutyHigh = (pwmLevel >> 8) & 0xFF + + try: + self.RawWrite(COMMAND_SET_PWM_MAX_2, [pwmDutyHigh, pwmDutyLow]) + except KeyboardInterrupt: + raise + except: + self.Print('Failed sending servo maximum limit #2!') + time.sleep(DELAY_AFTER_EEPROM) + self.PWM_MAX_2 = self.GetServoMaximum2() + + + def SetServoMaximum3(self, pwmLevel): + """ +SetServoMaximum3(pwmLevel) + +Sets the maximum PWM level for servo output #3 +This corresponds to position +1 +This value can be set anywhere from 0 for a 0% duty cycle to 65535 for a 100% duty cycle + +Setting values outside the range of the servo for extended periods of time can damage the servo +LIMIT CHECKING IS ALTERED BY THIS COMMAND! +We recommend using the tuning GUI for setting the servo limits for SetServoPosition3 / GetServoPosition3 + +The value is an integer where 2000 represents a 1ms servo burst, approximately 3% duty cycle +e.g. +2000 -> 1 ms servo burst, typical shortest burst, ~3% duty cycle +4000 -> 2 ms servo burst, typical longest burst, ~ 6.1% duty cycle +3000 -> 1.5 ms servo burst, typical centre, ~4.6% duty cycle +5000 -> 2.5 ms servo burst, higher than typical longest burst, ~ 7.6% duty cycle + """ + pwmDutyLow = pwmLevel & 0xFF + pwmDutyHigh = (pwmLevel >> 8) & 0xFF + + try: + self.RawWrite(COMMAND_SET_PWM_MAX_3, [pwmDutyHigh, pwmDutyLow]) + except KeyboardInterrupt: + raise + except: + self.Print('Failed sending servo maximum limit #3!') + time.sleep(DELAY_AFTER_EEPROM) + self.PWM_MAX_3 = self.GetServoMaximum3() + + + def SetServoMaximum4(self, pwmLevel): + """ +SetServoMaximum4(pwmLevel) + +Sets the maximum PWM level for servo output #4 +This corresponds to position +1 +This value can be set anywhere from 0 for a 0% duty cycle to 65535 for a 100% duty cycle + +Setting values outside the range of the servo for extended periods of time can damage the servo +LIMIT CHECKING IS ALTERED BY THIS COMMAND! +We recommend using the tuning GUI for setting the servo limits for SetServoPosition4 / GetServoPosition4 + +The value is an integer where 2000 represents a 1ms servo burst, approximately 3% duty cycle +e.g. +2000 -> 1 ms servo burst, typical shortest burst, ~3% duty cycle +4000 -> 2 ms servo burst, typical longest burst, ~ 6.1% duty cycle +3000 -> 1.5 ms servo burst, typical centre, ~4.6% duty cycle +5000 -> 2.5 ms servo burst, higher than typical longest burst, ~ 7.6% duty cycle + """ + pwmDutyLow = pwmLevel & 0xFF + pwmDutyHigh = (pwmLevel >> 8) & 0xFF + + try: + self.RawWrite(COMMAND_SET_PWM_MAX_4, [pwmDutyHigh, pwmDutyLow]) + except KeyboardInterrupt: + raise + except: + self.Print('Failed sending servo maximum limit #4!') + time.sleep(DELAY_AFTER_EEPROM) + self.PWM_MAX_4 = self.GetServoMaximum4() + + + def SetServoStartup1(self, pwmLevel): + """ +SetServoStartup1(pwmLevel) + +Sets the startup PWM level for servo output #1 +This can be anywhere in the minimum to maximum range + +We recommend using the tuning GUI for setting the servo limits for SetServoPosition1 / GetServoPosition1 +This value is checked against the current servo limits before setting + +The value is an integer where 2000 represents a 1ms servo burst, approximately 3% duty cycle +e.g. +2000 -> 1 ms servo burst, typical shortest burst, ~3% duty cycle +4000 -> 2 ms servo burst, typical longest burst, ~ 6.1% duty cycle +3000 -> 1.5 ms servo burst, typical centre, ~4.6% duty cycle +5000 -> 2.5 ms servo burst, higher than typical longest burst, ~ 7.6% duty cycle + """ + pwmDutyLow = pwmLevel & 0xFF + pwmDutyHigh = (pwmLevel >> 8) & 0xFF + inRange = True + + if self.PWM_MIN_1 < self.PWM_MAX_1: + # Normal direction + if pwmLevel < self.PWM_MIN_1: + inRange = False + elif pwmLevel > self.PWM_MAX_1: + inRange = False + else: + # Inverted direction + if pwmLevel > self.PWM_MIN_1: + inRange = False + elif pwmLevel < self.PWM_MAX_1: + inRange = False + if pwmLevel == PWM_UNSET: + # Force to unset behaviour (central) + inRange = True + + if not inRange: + print('Servo #1 startup position %d is outside the limits of %d to %d' % (pwmLevel, self.PWM_MIN_1, self.PWM_MAX_1)) + return + + try: + self.RawWrite(COMMAND_SET_PWM_BOOT_1, [pwmDutyHigh, pwmDutyLow]) + except KeyboardInterrupt: + raise + except: + self.Print('Failed sending servo startup position #1!') + time.sleep(DELAY_AFTER_EEPROM) + + + def SetServoStartup2(self, pwmLevel): + """ +SetServoStartup2(pwmLevel) + +Sets the startup PWM level for servo output #2 +This can be anywhere in the minimum to maximum range + +We recommend using the tuning GUI for setting the servo limits for SetServoPosition2 / GetServoPosition2 +This value is checked against the current servo limits before setting + +The value is an integer where 2000 represents a 1ms servo burst, approximately 3% duty cycle +e.g. +2000 -> 1 ms servo burst, typical shortest burst, ~3% duty cycle +4000 -> 2 ms servo burst, typical longest burst, ~ 6.1% duty cycle +3000 -> 1.5 ms servo burst, typical centre, ~4.6% duty cycle +5000 -> 2.5 ms servo burst, higher than typical longest burst, ~ 7.6% duty cycle + """ + pwmDutyLow = pwmLevel & 0xFF + pwmDutyHigh = (pwmLevel >> 8) & 0xFF + inRange = True + + if self.PWM_MIN_2 < self.PWM_MAX_2: + # Normal direction + if pwmLevel < self.PWM_MIN_2: + inRange = False + elif pwmLevel > self.PWM_MAX_2: + inRange = False + else: + # Inverted direction + if pwmLevel > self.PWM_MIN_2: + inRange = False + elif pwmLevel < self.PWM_MAX_2: + inRange = False + if pwmLevel == PWM_UNSET: + # Force to unset behaviour (central) + inRange = True + + if not inRange: + print('Servo #2 startup position %d is outside the limits of %d to %d' % (pwmLevel, self.PWM_MIN_2, self.PWM_MAX_2)) + return + + try: + self.RawWrite(COMMAND_SET_PWM_BOOT_2, [pwmDutyHigh, pwmDutyLow]) + except KeyboardInterrupt: + raise + except: + self.Print('Failed sending servo startup position #2!') + time.sleep(DELAY_AFTER_EEPROM) + + + def SetServoStartup3(self, pwmLevel): + """ +SetServoStartup3(pwmLevel) + +Sets the startup PWM level for servo output #3 +This can be anywhere in the minimum to maximum range + +We recommend using the tuning GUI for setting the servo limits for SetServoPosition3 / GetServoPosition3 +This value is checked against the current servo limits before setting + +The value is an integer where 2000 represents a 1ms servo burst, approximately 3% duty cycle +e.g. +2000 -> 1 ms servo burst, typical shortest burst, ~3% duty cycle +4000 -> 2 ms servo burst, typical longest burst, ~ 6.1% duty cycle +3000 -> 1.5 ms servo burst, typical centre, ~4.6% duty cycle +5000 -> 2.5 ms servo burst, higher than typical longest burst, ~ 7.6% duty cycle + """ + pwmDutyLow = pwmLevel & 0xFF + pwmDutyHigh = (pwmLevel >> 8) & 0xFF + inRange = True + + if self.PWM_MIN_3 < self.PWM_MAX_3: + # Normal direction + if pwmLevel < self.PWM_MIN_3: + inRange = False + elif pwmLevel > self.PWM_MAX_3: + inRange = False + else: + # Inverted direction + if pwmLevel > self.PWM_MIN_3: + inRange = False + elif pwmLevel < self.PWM_MAX_3: + inRange = False + if pwmLevel == PWM_UNSET: + # Force to unset behaviour (central) + inRange = True + + if not inRange: + print('Servo #3 startup position %d is outside the limits of %d to %d' % (pwmLevel, self.PWM_MIN_3, self.PWM_MAX_3)) + return + + try: + self.RawWrite(COMMAND_SET_PWM_BOOT_3, [pwmDutyHigh, pwmDutyLow]) + except KeyboardInterrupt: + raise + except: + self.Print('Failed sending servo startup position #3!') + time.sleep(DELAY_AFTER_EEPROM) + + + def SetServoStartup4(self, pwmLevel): + """ +SetServoStartup4(pwmLevel) + +Sets the startup PWM level for servo output #4 +This can be anywhere in the minimum to maximum range + +We recommend using the tuning GUI for setting the servo limits for SetServoPosition4 / GetServoPosition4 +This value is checked against the current servo limits before setting + +The value is an integer where 2000 represents a 1ms servo burst, approximately 3% duty cycle +e.g. +2000 -> 1 ms servo burst, typical shortest burst, ~3% duty cycle +4000 -> 2 ms servo burst, typical longest burst, ~ 6.1% duty cycle +3000 -> 1.5 ms servo burst, typical centre, ~4.6% duty cycle +5000 -> 2.5 ms servo burst, higher than typical longest burst, ~ 7.6% duty cycle + """ + pwmDutyLow = pwmLevel & 0xFF + pwmDutyHigh = (pwmLevel >> 8) & 0xFF + inRange = True + + if self.PWM_MIN_4 < self.PWM_MAX_4: + # Normal direction + if pwmLevel < self.PWM_MIN_4: + inRange = False + elif pwmLevel > self.PWM_MAX_4: + inRange = False + else: + # Inverted direction + if pwmLevel > self.PWM_MIN_4: + inRange = False + elif pwmLevel < self.PWM_MAX_4: + inRange = False + if pwmLevel == PWM_UNSET: + # Force to unset behaviour (central) + inRange = True + + if not inRange: + print('Servo #4 startup position %d is outside the limits of %d to %d' % (pwmLevel, self.PWM_MIN_4, self.PWM_MAX_4)) + return + + try: + self.RawWrite(COMMAND_SET_PWM_BOOT_4, [pwmDutyHigh, pwmDutyLow]) + except KeyboardInterrupt: + raise + except: + self.Print('Failed sending servo startup position #4!') + time.sleep(DELAY_AFTER_EEPROM) + + + def Help(self): + """ +Help() + +Displays the names and descriptions of the various functions and settings provided + """ + funcList = [UltraBorg.__dict__.get(a) for a in dir(UltraBorg) if isinstance(UltraBorg.__dict__.get(a), types.FunctionType)] + funcListSorted = sorted(funcList, key = lambda x: x.func_code.co_firstlineno) + + print(self.__doc__) + print + for func in funcListSorted: + print('=== %s === %s' % (func.func_name, func.func_doc)) + diff --git a/Code/Pyborg_Robot_Scripts/__pycache__/ThunderBorg3.cpython-35.pyc b/Code/Pyborg_Robot_Scripts/__pycache__/ThunderBorg3.cpython-35.pyc new file mode 100644 index 0000000000000000000000000000000000000000..393d0d5c13ac027bfe04f29974637e1ea8c44db0 Binary files /dev/null and b/Code/Pyborg_Robot_Scripts/__pycache__/ThunderBorg3.cpython-35.pyc differ diff --git a/Code/Pyborg_Robot_Scripts/__pycache__/UltraBorg3.cpython-35.pyc b/Code/Pyborg_Robot_Scripts/__pycache__/UltraBorg3.cpython-35.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0902fb52c0979766fcbc0653f7fce52332f9c102 Binary files /dev/null and b/Code/Pyborg_Robot_Scripts/__pycache__/UltraBorg3.cpython-35.pyc differ diff --git a/Code/Pyborg_Robot_Scripts/__pycache__/localmap.cpython-35.pyc b/Code/Pyborg_Robot_Scripts/__pycache__/localmap.cpython-35.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f67022295c73874bea0118e353807d1a7ec58ea0 Binary files /dev/null and b/Code/Pyborg_Robot_Scripts/__pycache__/localmap.cpython-35.pyc differ diff --git a/Code/Pyborg_Robot_Scripts/__pycache__/movement.cpython-35.pyc b/Code/Pyborg_Robot_Scripts/__pycache__/movement.cpython-35.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f90f616ce9e2341455b215937f7c704e8f453e82 Binary files /dev/null and b/Code/Pyborg_Robot_Scripts/__pycache__/movement.cpython-35.pyc differ diff --git a/Code/Pyborg_Robot_Scripts/__pycache__/networking.cpython-35.pyc b/Code/Pyborg_Robot_Scripts/__pycache__/networking.cpython-35.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4bd5a642c28a565040e940921441cf1182431e17 Binary files /dev/null and b/Code/Pyborg_Robot_Scripts/__pycache__/networking.cpython-35.pyc differ diff --git a/Code/Pyborg_Robot_Scripts/alternative_localmap.py b/Code/Pyborg_Robot_Scripts/alternative_localmap.py new file mode 100644 index 0000000000000000000000000000000000000000..83101f8d35426d573eb3b468914d7a99e462b4f3 --- /dev/null +++ b/Code/Pyborg_Robot_Scripts/alternative_localmap.py @@ -0,0 +1,254 @@ +#!/usr/bin/env python +# coding: latin-1 + +# Import the libraries we need +import UltraBorg3 as UltraBorg +import time +import numpy as np +#from matplotlib import pyplot as plt +import math + +# Settings for servo +servoMin = -1.0 # Smallest servo position to use +servoMax = +1.0 # Largest servo position to use +startupDelay = 0.5 # Delay before making the initial move +stepDelay = 0.1 # Delay between steps +rate = 0.1 #0.05 # Step distance for all servos during initial move +sleeptime = 1 +# In[2]: +#ultrasonic sonsor specifics +opening = (15/2) * (np.pi/180) #half of the full opening angle (in rad) +#the rotating axes of the sensor (which is the center point for the localmap) is not exactly in the sensor +#the below distance between sensor and rotating axes must be added to all distance measures +sensor_rotatedist = 20 +#distance between front and back sensor +backsensordistance = 149 + +#number of total measurements +measnumber = 2*int((servoMax-servoMin)/rate) +overlap = int(opening/(2*np.pi/measnumber)+1) +print(overlap) + +#local map specifications +localdim = 20 #localmapdim +gridsize = 100 #gridsize in mm +localsize = gridsize*localdim #resulting localsize in mm + +# Start the UltraBorg +UB = UltraBorg.UltraBorg() # Create a new UltraBorg object +UB.Init() # Set the board up (checks the board is connected) + +#function moves servo, returns measurements +def get_measures(): + N = measnumber + #list of all measurements + measurements = np.zeros(N) + + # Set our initial servo position + servo1 = -1 + UB.SetServoPosition1(servo1) + UB.SetServoPosition2(servo1) + + # Read ultrasonic values + time.sleep(2.5) + usm1 = UB.GetDistance1() + usm2 = UB.GetDistance2() + print(usm1,usm2) + #print(usm1,usm2) + #add to meas list + measurements[0] = usm1 + measurements[int(N/2)] = usm2 + print(N) + #loop for all servo positions (N/2 due to 2 sensors) + for i in range(1,int(N/2)): + #move serve by rate + servo1 += rate + UB.SetServoPosition1(servo1) + UB.SetServoPosition2(servo1) + + # Read ultrasonic values + time.sleep(sleeptime) + usm1 = UB.GetDistance1() + usm2 = UB.GetDistance2() + #print(usm1,usm2) + + #add to meas list + measurements[0+i] = usm1 + measurements[int(N/2)+i] = usm2 + + measurements += sensor_rotatedist #add rotatedist to all measurements + return measurements + + + +def build_map(meas1,meas2,meas3,meas4): + N = 20 + gridsize = 100 + map = np.zeros((N,N)) + + #calc limits from measurements + rightlimit = min(N,int(N/2+meas1/gridsize)) + uplimit = min(N,int(N/2+meas2/gridsize)) + leftlimit = max(0,int(N/2-meas3/gridsize)) + downlimit = max(0,int(N/2-meas4/gridsize)) + + + #wall corresponding to meas1: + if meas1 < N/2*gridsize: + grid_x = int(N/2+meas1/gridsize) + for i in range(downlimit,uplimit): + map[grid_x,i] = 1-1.5*abs(N/2-i)/N + + #wall corresponding to meas2: + if meas2 < N/2*gridsize: + grid_y = int(N/2+meas2/gridsize) + for i in range(leftlimit,rightlimit): + map[i,grid_y] = 1-1.5*abs(N/2-i)/N + + #wall corresponding to meas3: + if meas3 < N/2*gridsize: + grid_x = int(N/2-meas3/gridsize) + for i in range(downlimit,uplimit): + map[grid_x,i] = 1-1.5*abs(N/2-i)/N + + #wall corresponding to meas4: + if meas4 < N/2*gridsize: + grid_y = int(N/2-meas4/gridsize) + for i in range(leftlimit,rightlimit): + map[i,grid_y] = 1-1.5*abs(N/2-i)/N + + #fill in between with unoccupied + for i in range(leftlimit+1,rightlimit): + for j in range(downlimit+1,uplimit): + map[i,j] = -0.5 + #left and down need extra fills at the edges! + if meas3 >= N/2*gridsize: + for j in range(downlimit+1,uplimit): + map[0,j] = -0.5 + if meas4 >= N/2*gridsize: + map[0,0] = -0.5 + if meas4 >= N/2*gridsize: + for i in range(leftlimit+1,rightlimit): + map[i,0] = -0.5 + + + return map + + +# In[3]: + + +def rotate_to_localmap(old_map,angle): + N = len(old_map) + new_map = np.zeros((N,N)) + for i in range(N): + for j in range(N): + #coordinate of grid_cell in old map + old_x = i+1/2 -N/2 + old_y = j+1/2 -N/2 + #coordinate of grid_cell in new map + new_x = old_x*math.cos(angle) - old_y*math.sin(angle) + new_y = old_x*math.sin(angle) + old_y*math.cos(angle) + #grid of grid_cell in new map + new_i = int(new_x + N/2) + new_j = int(new_y + N/2) + #apply if grid is within bounds + if 0 <= new_i < N and 0<= new_j < N: + new_map[new_i,new_j] = old_map[i,j] + + return new_map + + +# In[4]: + + +def change_measurements(sensordist,angle,meas1,meas2,meas3,meas4): + #measurement shifting for robot with 2 sensors at different positions + #sensors are located along the robots forward heading axis, back sensor is sensordist from front + shiftx = sensordist*math.cos(-angle) + shifty = sensordist*math.sin(-angle) + + if shiftx < 0: + meas1 -= shiftx + else: + meas3 += shiftx + if shifty < 0: + meas2 -= shifty + else: + meas4 += shifty + + return meas1,meas2,meas3,meas4 + + +# In[5]: + + +def find_4measures(measlist): + meascount = len(measlist) + + #first find minimum + minmeas = measlist[0] + minindex = 0 + for i in range(1,meascount): + if measlist[i] < minmeas: + minmeas = measlist[i] + minindex = i + + #determine the 4 measurments + meas1 = measlist[minindex] + meas2 = measlist[int(minindex+meascount/4)%meascount] + meas3 = measlist[int(minindex+meascount/2)%meascount] + meas4 = measlist[int(minindex+3*meascount/4)%meascount] + print(minindex) + #shortest measurement angle (rotation angle for rotate_to_localmap) + #index 0 correspond to -pi/2 and angle increases with higher index + angle = -(np.pi/2 - minindex*2*np.pi/meascount) + + return meas1,meas2,meas3,meas4,angle + + +# In[8]: + + +#test = build_map(5,15,5,15) +#test = rotate_to_localmap(test,np.pi/3) +#plt.imshow(test.T,origin='lower') + + +# In[7]: + + +#meastest = change_measurements(1,7*np.pi/4,10,10,10,10) +#print(meastest) + +def build_localmap(): + #take measurements + measurements = get_measures() + #extract 4 measurements + meas1,meas2,meas3,meas4,angle = find_4measures(measurements) + #convert backmeasures to frontmeasures + meas1,meas2,meas3,meas4 = change_measurements(backsensordistance,angle,meas1,meas2,meas3,meas4) + #build unrotated map where meas1 is in x-direction + intermap = build_map(meas1,meas2,meas3,meas4) + #rotate map so robot is heading in x-direction + new_map = rotate_to_localmap(intermap,angle) + #return it + return new_map + +### In[ ]: +##testmeasures = get_measures() +##meas1,meas2,meas3,meas4,angle = find_4measures(testmeasures) +##print(testmeasures) +##print(meas1,meas2,meas3,meas4,angle) +## +##meas1,meas2,meas3,meas4 = change_measurements(backsensordistance,angle,meas1,meas2,meas3,meas4) +##intermap = build_map(meas1,meas2,meas3,meas4) +###new_map = rotate_to_localmap(intermap,angle) +## +#new_map = build_localmap() +#from matplotlib import pyplot as plt +#plt.imshow(intermap.T,origin='lower') +#plt.show() +#new_map = rotate_to_localmap(intermap,angle) +#plt.imshow(new_map.T,origin='lower',cmap="Greys") +#plt.show() \ No newline at end of file diff --git a/Code/Pyborg_Robot_Scripts/lefigure.png b/Code/Pyborg_Robot_Scripts/lefigure.png new file mode 100644 index 0000000000000000000000000000000000000000..4a5138bf962debe501b19e52759dcf1f25470099 Binary files /dev/null and b/Code/Pyborg_Robot_Scripts/lefigure.png differ diff --git a/Code/Pyborg_Robot_Scripts/localmap.py b/Code/Pyborg_Robot_Scripts/localmap.py new file mode 100644 index 0000000000000000000000000000000000000000..c28a730ba944649bccc5aa37b1e0ce4946648811 --- /dev/null +++ b/Code/Pyborg_Robot_Scripts/localmap.py @@ -0,0 +1,236 @@ +#!/usr/bin/env python +# coding: latin-1 + +# Import the libraries we need +import UltraBorg3 as UltraBorg +import time +import numpy as np +#from matplotlib import pyplot as plt + +# Settings for servo +servoMin = -1.0 # Smallest servo position to use +servoMax = +1.0 # Largest servo position to use +startupDelay = 0.5 # Delay before making the initial move +stepDelay = 0.1 # Delay between steps +rate = 0.1 #0.05 # Step distance for all servos during initial move +sleeptime = 1 + +#ultrasonic sonsor specifics +opening = (15/2) * (np.pi/180) #half of the full opening angle (in rad) +#the rotating axes of the sensor (which is the center point for the localmap) is not exactly in the sensor +#the below distance between sensor and rotating axes must be added to all distance measures +sensor_rotatedist = 20 + +#number of total measurements +measnumber = 2*int((servoMax-servoMin)/rate) +overlap = int(opening/(2*np.pi/measnumber)+1) +print(overlap) + +#local map specifications +localdim = 20 #localmapdim +gridsize = 100 #gridsize in mm +localsize = gridsize*localdim #resulting localsize in mm + +#returns matrix which +#assigns each gridposition to a measurement entry from 0 to measnumber-1 +def assignmap(): + assigner = np.zeros((localdim,localdim)) + assigner = [] + for i in range(localdim): + assignerrow = [] + for j in range(localdim): + assignerrow.append([]) + assigner.append(assignerrow) + #distances is divided into distances for front sensor (0) and for back sensor (1) + #this is necessary since the sensors are not at the same position + distances = [np.zeros((localdim,localdim)),np.zeros((localdim,localdim))] + #first loop for front sensor only + for i in range(localdim): + for j in range(localdim): + #coordinates, origin of the map at localdim/2 + y = j+0.5 -localdim/2 + x = i+0.5 -localdim/2 + #assigning by calculating polar coordinates + #assign angle to correct sensor + #save distance for later use + angle = np.arctan2(y,x) + np.pi/2 #add pi/2 since measurement 0 corresponds to an angle of -pi/2 + if angle < 0: + angle += 2*np.pi + if angle > 2*np.pi: + angle -= 2*np.pi + assign_to = (int(angle*measnumber/(2*np.pi) +0.5))%measnumber + #only measurements below measnumber/2 belong to front sensor + #others to be added in a second loop + if assign_to < measnumber/2: + assigner[i][j].append(assign_to) + #distance grid to map-origin in mm + dist = np.sqrt(x**2+y**2) * gridsize + distances[0][i,j] = dist + + #check all near neigboring sensors in overlap range + for k in [l for l in range(assign_to-overlap,assign_to+overlap) if l!=assign_to]: + k_plus = k % measnumber + #sensor field of view between minus and plus angle, remember 2*np.pi periodicity + minus = 2*np.pi*k_plus/(measnumber)-opening + plus = 2*np.pi*k_plus/(measnumber)+opening + + if k_plus < measnumber/2: #only front sensor + #check if angle between minus and plus (many cases due to periodicity) + if angle > minus: + if angle < plus: + assigner[i][j].append(k_plus) + elif minus < 0: + if angle > minus + 2*np.pi: + assigner[i][j].append(k_plus) + elif plus > 2*np.pi: + assigner[i][j].append(k_plus) + elif plus > 2*np.pi: + if angle < plus - 2*np.pi: + assigner[i][j].append(k_plus) + + #second loop for back sensor only + backsensordistance = 149 #distance between front/back sensor in mm + for i in range(localdim): + for j in range(localdim): + #coordinates, origin of the map at localdim/2 + y = j+0.5 -localdim/2 + x = i+0.5 -localdim/2 + backsensordistance/localsize #add distance between sensors since backsensor is located at x= - backsensordistance + #assigning by calculating polar coordinates + #assign angle to correct sensor + #save distance for later use + angle = np.arctan2(y,x) + np.pi/2 #add pi/2 since measurement 0 corresponds to an angle of -pi/2 + if angle < 0: + angle += 2*np.pi + if angle > 2*np.pi: + angle -= 2*np.pi + assign_to = (int(angle*measnumber/(2*np.pi) +0.5))%measnumber + #only measurements >= measnumber/2 belong to back sensor + if assign_to >= measnumber/2: + assigner[i][j].append(assign_to) + #distance grid to back sensor in mm + dist = np.sqrt(x**2+y**2) * gridsize + distances[1][i,j] = dist + + #check all near neigboring sensors in overlap range + for k in [l for l in range(assign_to-overlap,assign_to+overlap) if l!=assign_to]: + k_plus = k % measnumber + #sensor field of view between minus and plus angle, remember 2*np.pi periodicity + minus = 2*np.pi*k_plus/(measnumber)-opening + plus = 2*np.pi*k_plus/(measnumber)+opening + + if k_plus >= measnumber/2: #only back sensor + #check if angle between minus and plus (many cases due to periodicity) + if angle > minus: + if angle < plus: + assigner[i][j].append(k_plus) + elif minus < 0: + if angle > minus + 2*np.pi: + assigner[i][j].append(k_plus) + elif plus > 2*np.pi: + assigner[i][j].append(k_plus) + elif plus > 2*np.pi: + if angle < plus - 2*np.pi: + assigner[i][j].append(k_plus) + + #print(assigner) + return assigner,distances +#assigner assign gridpos to sensorreading +assigner,distances = assignmap() +print(distances) + +# Start the UltraBorg +UB = UltraBorg.UltraBorg() # Create a new UltraBorg object +UB.Init() # Set the board up (checks the board is connected) + + + + +#function moves servo, returns measurements +def get_measures(): + N = measnumber + #list of all measurements + measurements = np.zeros(N) + + # Set our initial servo position + servo1 = -1 + UB.SetServoPosition1(servo1) + UB.SetServoPosition2(servo1) + + # Read ultrasonic values + time.sleep(sleeptime) + usm1 = UB.GetDistance1() + usm2 = UB.GetDistance2() + print(type(usm1)) + #print(usm1,usm2) + #add to meas list + measurements[0] = usm1 + measurements[int(N/2)] = usm2 + + #loop for all servo positions (N/2 due to 2 sensors) + for i in range(1,int(N/2)): + #move serve by rate + servo1 += rate + UB.SetServoPosition1(servo1) + UB.SetServoPosition2(servo1) + + # Read ultrasonic values + time.sleep(sleeptime) + usm1 = UB.GetDistance1() + usm2 = UB.GetDistance2() + #print(usm1,usm2) + + #add to meas list + measurements[0+i] = usm1 + measurements[int(N/2)+i] = usm2 + + measurements += sensor_rotatedist #add rotatedist to all measurements + return measurements + +def localmap(measurements): + #alpha is range in which cells are considered occupied (should be min gridsize/2) + alpha = gridsize/2 + #occupied cells are adjusted by l_plus, unoccupied by l_minus + l_plus = 1 + l_minus = 0.5 + #cycle through each cell of the map and apply sensor data + map = np.zeros((localdim,localdim)) + + for i in range(localdim): + for j in range(localdim): + #multiple measurement correspond to this cell due to overlap, choose the min value of these + #intial min values + mink = assigner[i][j][0] + minmeas = measurements[mink] + #loop through overlap choose the minimum measurement in the overlap + for k in assigner[i][j]: + #set new min if smaller + if measurements[k] < minmeas: + minmeas = measurements[k] + mink = k + + + #front or back sensor? + if mink < measnumber/2: + sensor = 0 + else: + sensor = 1 + + #check measurements + if distances[sensor][i][j] < measurements[mink] - alpha: + #unoccupied measurement + map[i][j] -= l_minus + elif distances[sensor][i][j] < measurements[mink] + alpha: + #occupied measurement + map[i][j] += l_plus + return map + +#building localmap by getting measures and converting to map +def build_localmap(): + measures = get_measures() + return localmap(measures) + +test = build_localmap() +from matplotlib import pyplot as plt +plt.imshow(test.T, interpolation='nearest',cmap='Greys',origin = 'lower', vmin=-2, vmax=2) +plt.show() + diff --git a/Code/Pyborg_Robot_Scripts/losfiguros.png b/Code/Pyborg_Robot_Scripts/losfiguros.png new file mode 100644 index 0000000000000000000000000000000000000000..52f4332e7365cfdb7ac02096cd37e9648618c9b7 Binary files /dev/null and b/Code/Pyborg_Robot_Scripts/losfiguros.png differ diff --git a/Code/Pyborg_Robot_Scripts/movement.py b/Code/Pyborg_Robot_Scripts/movement.py new file mode 100644 index 0000000000000000000000000000000000000000..76f7e37fdad1c7c4ab6877b0d4143f7db3f9e5e5 --- /dev/null +++ b/Code/Pyborg_Robot_Scripts/movement.py @@ -0,0 +1,52 @@ +import ThunderBorg3 +import time +import sys +import numpy as np + +# Setup the ThunderBorg +global TB +TB = ThunderBorg3.ThunderBorg() # Create a new ThunderBorg object +#TB.i2cAddress = 0x15 # Uncomment and change the value if you have changed the board address +TB.Init() # Set the board up (checks the board is connected) +if not TB.foundChip: + boards = ThunderBorg.ScanForThunderBorg() + if len(boards) == 0: + print ('No ThunderBorg found, check you are attached :)') + else: + print ('No ThunderBorg at address %02X, but we did find boards:') % (TB.i2cAddress) + for board in boards: + print (' %02X (%d)' % (board, board)) + print ('If you need to change the I²C address change the setup line so it is correct, e.g.') + print ('TB.i2cAddress = 0x%02X' % (boards[0])) + sys.exit() + +stepDelay = 1 + +def moving(step0,step1,length=stepDelay): + TB.SetMotor1(step0) # Set the first motor to the first value in the pair + TB.SetMotor2(step1) # Set the second motor to the second value in the pair + #print ('%+.1f %+.1f' % (step0, step1)) + time.sleep(length) # Wait between steps + TB.MotorsOff() # Turn both motors off +#moving(0.65,-0.65) + + +def forward(): + moving(0.62,0.62) + +def backward(): + moving(-0.62,-0.62) + +def left(): + moving(-0.62,0.62) + +def right(): + moving(0.62,-0.62) + +def execute_movement(order): + splitted = order.split('#') + wheelleft = float(splitted[1]) + wheelright = float(splitted[2]) + if wheelleft != 0: + wheelrightcorrection = abs(wheelright/wheelleft) + moving(np.sign(wheelleft)*0.62,np.sign(wheelright)*0.62*wheelrightcorrection,abs(wheelleft)) \ No newline at end of file diff --git a/Code/Pyborg_Robot_Scripts/networking.py b/Code/Pyborg_Robot_Scripts/networking.py new file mode 100644 index 0000000000000000000000000000000000000000..3b598354437fb832be01b2baaba937218828cd21 --- /dev/null +++ b/Code/Pyborg_Robot_Scripts/networking.py @@ -0,0 +1,64 @@ +import socket +import numpy as np +from io import StringIO +import struct + +def send_msg(sock, msg): + # Prefix each message with a 4-byte length (network byte order) + msg = struct.pack('>I', len(msg)) + msg + sock.sendall(msg) + +def recv_msg(sock): + # Read message length and unpack it into an integer + raw_msglen = recvall(sock, 4) + if not raw_msglen: + return None + msglen = struct.unpack('>I', raw_msglen)[0] + # Read the message data + return recvall(sock, msglen) + +def recvall(sock, n): + # Helper function to recv n bytes or return None if EOF is hit + data = bytearray() + while len(data) < n: + packet = sock.recv(n - len(data)) + if not packet: + return None + data.extend(packet) + return data + + +## +##def server(): +## host = socket.gethostname() #get local machine name +## #print(host) +## port = 4223 +## print("hosting on: '" + str(host) + "' \t port: " + str(port)) +## +## s = socket.socket() +## s.bind(('',port)) +## +## s.listen(1) +## client_socket, adress = s.accept() +## print("Connection from: " + str(adress)) +## data='empty' +## while data != 'q': +## data = recv_msg(client_socket).decode('utf-8')#client_socket.recv(1024).decode('utf-8') +## if not data: +## break +## print("From online user: " + data) +## data = data.upper() +## send_msg(client_socket,data.encode('utf-8'))#client_socket.send(data.encode('utf-8')) +## if data == 'NUMPY': +## print("doing the numpy") +## nptest = np.ones((20,20)) +## nptest[0][0] = -0.3 +## send = nptest.tostring() +## send_msg(client_socket,send) +## break +## client_socket.close() +## +## +## +##server() + \ No newline at end of file diff --git a/Code/Pyborg_Robot_Scripts/remote_controlling.py b/Code/Pyborg_Robot_Scripts/remote_controlling.py new file mode 100644 index 0000000000000000000000000000000000000000..e86b23fbc470280276f97b0501c1e388c6ddbabc --- /dev/null +++ b/Code/Pyborg_Robot_Scripts/remote_controlling.py @@ -0,0 +1,55 @@ +import networking as net +import numpy as np +from io import StringIO +import alternative_localmap as localmap +import movement + +def server(): + host = net.socket.gethostname() #get local machine name + #print(host) + port = 4223 + print("hosting on: '" + str(host) + "' \t port: " + str(port)) + + s = net.socket.socket() + s.bind(('',port)) + + s.listen(1) + client_socket, adress = s.accept() + print("Connection from: " + str(adress)) + data='empty' + #until data = q do move/meas loop + while data != 'q': + data = net.recv_msg(client_socket).decode('utf-8')#client_socket.recv(1024).decode('utf-8') + if not data or data == 'q': + break + if data == 'reset': + #reset only necessary for simulated robots + #so do nothing + send = 'done' + net.send_msg(client_socket,send.encode('utf-8')) + else: + print("Executing movement: " + data) + movement.execute_movement(data) + + localm = localmap.build_localmap() + + send_localm = localm.tostring() + net.send_msg(client_socket,send_localm) +## data = data.upper() +## net.send_msg(client_socket,data.encode('utf-8'))#client_socket.send(data.encode('utf-8')) +## if data == 'NUMPY': +## print("doing the numpy") +## nptest = np.ones((20,20)) +## nptest[0][0] = -0.3 +## send = nptest.tostring() +## net.send_msg(client_socket,send) +## break + client_socket.close() + + + +server() + + + + \ No newline at end of file diff --git a/Code/QN_alldirrobot.ipynb b/Code/QN_alldirrobot.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..6398967b3771be30c78c6b6bc05f961eb4e2d423 --- /dev/null +++ b/Code/QN_alldirrobot.ipynb @@ -0,0 +1,286 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Using TensorFlow backend.\n" + ] + } + ], + "source": [ + "#imports\n", + "#use keras for neural net\n", + "import numpy as np\n", + "import random\n", + "from keras import models\n", + "from keras import layers\n", + "from keras.optimizers import Adam\n", + "from keras.optimizers import SGD\n", + "from keras.metrics import mse\n", + "from collections import deque\n", + "import tensorflow as tf\n", + "import os" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "#class of the QNagent (structure can be used for any actionvalue-function-learning using q-learning)\n", + "class QNAgent:\n", + " def __init__(self,statesize = 4):\n", + " self.state_size = statesize #uncertainty, relocate-,explore-counter , bank\n", + " self.output_size = 2 #explore vs relocate\n", + " #memory of past state,action,reward,next state pairs\n", + " #using deque to only store up to 1000 memory and then delete old ones\n", + " self.memory = deque(maxlen=1000) \n", + " self.gamma = 0.6#0.3 # discount factor\n", + " self.eps = 1 # epsilon for use in epsilon greedy strategies (starting at one and lowering)\n", + " self.epsdecay = 0.993 #epsilon decay\n", + " self.epsmin = 0.05 #minimum value of epsilon\n", + " self.learning_rate = 0.001 #learning rate for neural net\n", + " self.model = self._build_model()\n", + " \n", + " \n", + " def _build_model(self):\n", + " #building the neural network and comppiling\n", + " input1 = layers.Input(shape=(self.state_size,)) #input layer\n", + " #three fully connected hidden layers of sizes state_size,2*state_size,state_size\n", + " fully1 = layers.Dense(self.state_size,activation='relu')(input1)\n", + " fully2 = layers.Dense(2*self.state_size,activation='relu')(fully1)\n", + " fully3 = layers.Dense(self.state_size,activation='relu')(fully2)\n", + " #fully connected output layer with linear activation\n", + " out = layers.Dense(self.output_size,activation='linear')(fully3)\n", + " #combine layers to model\n", + " model = models.Model(inputs = input1,outputs=out)\n", + " #using stochastic gradient descent\n", + " sgd = SGD(lr=self.learning_rate, clipnorm=1.)\n", + " \n", + " #combine sgd with mean squared error as loss\n", + " model.compile(optimizer=sgd,loss = 'mse')\n", + " \n", + " return model\n", + " \n", + " \n", + " def remember(self,state,action,reward,next_state,done):\n", + " #add to memory\n", + " self.memory.append((state,action,reward,next_state,done))\n", + " \n", + " def act(self,state):\n", + " #act epsilon greedy - random with prob eps, else greedy\n", + " values = self.model.predict(state)\n", + "\n", + " if np.random.rand() <= self.eps:\n", + " action = random.randrange(self.output_size) #return random action\n", + " else:\n", + " action = np.argmax(values)\n", + " return action #return greedy action\n", + " \n", + " def replay(self,batch_size):\n", + " #replaying from memory to learn\n", + " minibatch = random.sample(self.memory, batch_size) #randomly sample batchsize memories (this decorelates)\n", + " for state, action, reward, next_state, done in minibatch:\n", + " #target is estimate of value function in current cell\n", + " target = reward\n", + " if not done:\n", + " target = reward + self.gamma * np.amax(self.model.predict(next_state)[0])\n", + " #since neural net is predicting for all cells only the value for the next_cell differs in target_f\n", + " target_allact = self.model.predict(state)\n", + " target_allact[0][action] = target\n", + " #fit\n", + " self.model.fit(state,target_allact,epochs = 1,verbose=0)\n", + " #lower epsilon\n", + " if self.eps > self.epsmin:\n", + " self.eps *= self.epsdecay\n", + " \n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "#function autosaves the current weights/model every few episodes\n", + "def autosave(model,episode, episodeplus, saveinterval):\n", + " #plus in case loading an autosave\n", + " episode = episode + episodeplus\n", + " #autosave model in case programm shuts down before finishing\n", + " name1 = \"alldirexplorandmap2_autosave\" + str(episode) + \".h5\"\n", + " name2 = \"alldirexplorandmap2_autosave\" + str(episode) + \"_weights.h5\"\n", + " model.save(name1)\n", + " model.save_weights(name2)\n", + " name1 = \"alldirexplorandmap2_autosave\" + str(episode-saveinterval) + \".h5\"\n", + " name2 = \"alldirexplorandmap2_autosave\" + str(episode-saveinterval) + \"_weights.h5\"\n", + " if os.path.exists(name1): #remove old autosave to avoid cluttering\n", + " os.remove(name1)\n", + " os.remove(name2)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "#environment needs:\n", + "#reset method returning start state\n", + "#step method executing action returning next_state, reward, done\n", + "#maybe render method\n", + "\n", + "#learn algorithm plays the \"game\" and adjusts the neural net\n", + "def learn_dqn(environment,statesize=4,loadweights = \"\"):\n", + " global errorcount #errorcount abort if too high\n", + " episodeplus = 0 #when loading an autosave one could start at a higher episodeocount\n", + " autosaveinterval = 2 #save every x episodes\n", + " \n", + " agent = QNAgent(statesize) #define agent by using QNAgent class\n", + " env = environment #define environment (will be from RobotGameEnvironment.py)\n", + " #iterate the game\n", + " max_episodes = 2000\n", + " if loadweights != \"\":\n", + " agent.model.load_weights(loadweights)\n", + " \n", + " \n", + " for i in range(max_episodes):\n", + " #reset; state always needs to be reshaped for use in neural net\n", + " state = np.reshape(env.reset(),[1,statesize])\n", + " global isdone\n", + " isdone = False\n", + " errorcount = 0\n", + " # iterate through max_actions actions\n", + " max_actions = 60\n", + " for actionnumber in range(max_actions):\n", + "\n", + " # decide epsilon greedy action\n", + " action = agent.act(state)\n", + " print(\"action = \" + str(action))\n", + " \n", + " # execute the action and save/reshape output\n", + " next_state, reward, done = env.step(action)\n", + " next_state = np.reshape(next_state,[1,statesize])\n", + " print(next_state,reward)\n", + " # store in memory\n", + " agent.remember(state, action, reward, next_state, done)\n", + "\n", + " # overwrite old state\n", + " state = next_state\n", + "\n", + " # check if done \n", + " if errorcount > 2:\n", + " break\n", + " if done or isdone:\n", + " #end episode\n", + " break\n", + " print(\"episode: {}/{}\".format(i+1,max_episodes))\n", + " #train agent from memory\n", + " batch_size = min(len(agent.memory)-1,400)\n", + " agent.replay(batch_size)\n", + " if i%autosaveinterval == 0:\n", + " autosave(agent.model,i, episodeplus, autosaveinterval)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "#play a once on neuralnet for testing\n", + "#same as above but with rendering of the environment\n", + "#show in tk\n", + "def playonTk_withdqn(environment,tk,statesize=4,loadweights = \"\"):\n", + " global stop_playonTk\n", + " stop_playonTk = False\n", + " #automatic stopbutton\n", + " autostopb = Button(tk, text=\"Stop\", command=lambda: change_stop_playonTk(True))\n", + " autostopb.grid(row = 15, column = 3,columnspan = 2)\n", + " \n", + " agent = QNAgent(statesize)\n", + " env = environment\n", + " #render the environment!\n", + " env.drawing = True\n", + " \n", + " \n", + " if loadweights != \"\":\n", + " agent.model.load_weights(loadweights)\n", + " agent.eps = 0\n", + " \n", + " #reset; state always needs to be reshaped for use in neural net\n", + " state = np.reshape(env.reset(),[1,statesize])\n", + " global isdone\n", + " isdone = False\n", + " # iterate through max_actions actions\n", + " max_actions = 60\n", + " for actionnumber in range(max_actions):\n", + " tk.update()\n", + " if stop_playonTk == False:\n", + "\n", + " # decide epsilon greedy action\n", + " action = agent.act(state)\n", + " print(\"action = \" + str(action))\n", + "\n", + " # execute the action and save/reshape output\n", + " next_state, reward, done = env.step(action)\n", + " next_state = np.reshape(next_state,[1,statesize])\n", + "\n", + " # store in memory\n", + " agent.remember(state, action, reward, next_state, done)\n", + "\n", + " # overwrite old state\n", + " state = next_state\n", + "\n", + " # check if done\n", + " global errorcount\n", + " if errorcount > 2:\n", + " break\n", + " if done or isdone:\n", + " #end episode\n", + " break\n", + " else:\n", + " break" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "def change_stop_playonTk(value): #function for stop button, ends episode\n", + " global stop_playonTk\n", + " stop_playonTk = value" + ] + } + ], + "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.6.8" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/Code/RobotGameEnvironment.ipynb b/Code/RobotGameEnvironment.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..2423a8d662c1f72136d3fb8172e567345b0f0aa1 --- /dev/null +++ b/Code/RobotGameEnvironment.ipynb @@ -0,0 +1,238 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "#imports\n", + "import numpy as np\n", + "import random\n", + "import socket\n", + "\n", + "%run alldirparticlefilt.ipynb" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "class RobotGame:\n", + " def __init__(self,sock,allparticles, bestparticle = 0, render_choice = False):\n", + " #initialize the game\n", + " uncert = 0\n", + " #environment state and statesize\n", + " self.state = [uncert,0,0,0] #consists of uncertainty, relocate-,explore-counter , bank\n", + " self.statesize = len(self.state)\n", + " \n", + " #socket to communicate with\n", + " self.socket = sock\n", + " #particles\n", + " self.particles = allparticles\n", + " \n", + " self.drawing = render_choice #to draw or not to draw\n", + " \n", + " def reset(self):\n", + " #reset the state to zeros\n", + " self.state = np.zeros(self.statesize) #(uncertainty, relocate-,explore-counter , bank)\n", + " \n", + " #create new particles\n", + " newparticles = []\n", + " for i in range(len(self.particles)):\n", + " newparticles.append(particle(0,0,0))\n", + " self.particles = newparticles\n", + " \n", + " movemessage(\"reset\",self.socket,self.particles,drawing = self.drawing)\n", + " movemessage(\"Stay\",self.socket,self.particles,drawing = self.drawing)\n", + " \n", + " return self.state\n", + " \n", + " #step function for 2 actions: explore/relocate\n", + " def step(self,action):\n", + " #change counters\n", + " if action == 0:#explore\n", + " self.state[2] += 1 #explore-counter\n", + " self.state[1] = 0 #relocate-counter\n", + " if action == 1:#relocate\n", + " self.state[2] = 0 #explore-counter\n", + " self.state[1] += 1 #relocate-counter\n", + " \n", + " full_reward = 0 #initialize reward\n", + " \n", + " continues = True #continues loop is for recalculating the explore/relocate action mid-action\n", + " targetlocation = 'none'\n", + " while continues == True:\n", + " continues = False\n", + " \n", + " if action == 0:#explore\n", + " orders = self.particles[bestparticle].nearest_unobserved()\n", + "\n", + " if action == 1:#relocate\n", + " orders,targetlocation = self.particles[bestparticle].retrace(aim_for = targetlocation)\n", + "\n", + "\n", + " prev_scale_factor = reward_scaling(self.state[0])\n", + "\n", + "\n", + " \n", + " #execute orders via socket\n", + " for i in range(len(orders)):\n", + " breakcondition, immediate_reward, new_uncertainty = movemessage(orders[i],self.socket,self.particles,drawing = self.drawing)\n", + " if breakcondition == True:\n", + " break\n", + "\n", + " scale_factor = reward_scaling(new_uncertainty)\n", + "\n", + " #to account for pose (and map) uncertainty in the robot we are banking part of the reward\n", + " #depending on how the pose spread, this reward can be obtained later if the robots uncertainty lowers\n", + " if new_uncertainty < self.state[0]: #better uncertainty leads to unbanking reward\n", + " unbank = self.state[3]*abs((prev_scale_factor-scale_factor)/(1-prev_scale_factor))\n", + " else:\n", + " unbank = 0\n", + " full_reward += immediate_reward* scale_factor + unbank #add to full reward\n", + " self.state[3] += immediate_reward*(1-scale_factor) - unbank #change banked reward\n", + "\n", + " self.state[0] = new_uncertainty #change old uncertainty to new\n", + " prev_scale_factor = scale_factor #new scale factor becomes old\n", + " if i > 7 and (len(orders)-i)>7:\n", + " #to avoid to long exploration/relocate paths consider recalculating your path after some steps\n", + " continues = True\n", + " break\n", + " \n", + " done = False #done always false for now\n", + " return self.state, full_reward, done\n", + " #return next_state, reward, done" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "#reward scaling\n", + "#was a simple exp(-x) function at the beginning with x being the uncertainty, didnt work well\n", + "#second attempt with exp(-x^2)\n", + "def reward_scaling(uncertainty):\n", + " #mu = 10\n", + " #return np.exp(-uncertainty/mu)\n", + " a = 14\n", + " return np.exp(-uncertainty**2/a**2)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0\n", + "1\n", + "2\n", + "0\n", + "1\n", + "2\n", + "3\n", + "0\n", + "1\n", + "2\n", + "3\n", + "4\n", + "0\n", + "1\n", + "2\n", + "3\n", + "4\n", + "5\n", + "0\n", + "1\n", + "2\n", + "3\n", + "4\n", + "5\n", + "6\n", + "0\n", + "1\n", + "2\n", + "3\n", + "4\n", + "5\n", + "6\n", + "7\n", + "0\n", + "1\n", + "2\n", + "3\n", + "4\n", + "5\n", + "6\n", + "7\n", + "8\n", + "0\n", + "1\n", + "2\n", + "3\n", + "4\n", + "5\n", + "6\n", + "7\n", + "8\n", + "9\n", + "0\n", + "1\n", + "2\n", + "3\n", + "4\n", + "5\n", + "6\n", + "7\n", + "8\n", + "9\n" + ] + } + ], + "source": [] + }, + { + "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.6.8" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/Code/Simulate_Alldirrobot.ipynb b/Code/Simulate_Alldirrobot.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..894c128c19c27e0c486960a5b7658ebe2d0c68db --- /dev/null +++ b/Code/Simulate_Alldirrobot.ipynb @@ -0,0 +1,420 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import math\n", + "import random" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "%run maps.ipynb\n", + "gridsize = 10\n", + "\n", + "\n", + "##building a global map that consists of a long corridor, not used right now\n", + "#realglobalmap = corridor()\n", + "##using a custom made map, also not used\n", + "#realglobalmap = custom_map01()\n", + "#currently using the random map generator to generate an branching corridor map\n", + "realglobalmap = generate_random_map(maxcounter = 20)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "#keeping track of robot position, robot position in cm not mm!\n", + "myxpos = 0\n", + "myypos = 0\n", + "myangle = 0" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "# Settings for servo\n", + "servoMin = -1.0 # Smallest servo position to use\n", + "servoMax = +1.0 # Largest servo position to use\n", + "startupDelay = 0.5 # Delay before making the initial move\n", + "stepDelay = 0.1 # Delay between steps\n", + "rate = 0.05 # Step distance for all servos during initial move\n", + "sleeptime = 0.3\n", + "\n", + "#ultrasonic sonsor specifics\n", + "opening = (15/2) * (np.pi/180) #half of the full opening angle (in rad)\n", + "#number of total measurements\n", + "measnumber = 2*int((servoMax-servoMin)/rate)\n", + "overlap = int(opening/(2*np.pi/measnumber)+1)\n", + "#print(overlap)\n", + " \n", + "#local map specifications\n", + "localdim = 20 #localmapdim\n", + "gridsize = 100 #gridsize in mm\n", + "localsize = gridsize*localdim #resulting localsize in mm\n", + "\n", + "#returns matrix which\n", + "#assigns each gridposition to a measurement entry from 0 to measnumber-1\n", + "def assignmap():\n", + " assigner = []\n", + " for i in range(localdim):\n", + " assignerrow = []\n", + " for j in range(localdim):\n", + " assignerrow.append([])\n", + " assigner.append(assignerrow)\n", + " distances = np.zeros((localdim,localdim))\n", + " for i in range(localdim):\n", + " for j in range(localdim):\n", + " #coordinates, origin of the map at localdim/2\n", + " y = j+0.5 -localdim/2\n", + " x = i+0.5 -localdim/2\n", + " #assigning by calculating polar coordinates\n", + " #assign angle to correct sensor\n", + " #save distance for later use\n", + " angle = np.arctan2(y,x)\n", + " if angle < 0:\n", + " angle += 2*np.pi\n", + " assign_to = (int(angle*measnumber/(2*np.pi) +0.5))%measnumber\n", + " assigner[i][j].append(assign_to)\n", + " #distance grid to map-origin in mm\n", + " dist = np.sqrt(x**2+y**2) * gridsize\n", + " distances[i,j] = dist\n", + " \n", + " #check all near neigboring sensors in overlap range\n", + " for k in [l for l in range(assign_to-overlap,assign_to+overlap) if l!=assign_to]:\n", + " k_plus = k % measnumber\n", + " #sensor field of view between minus and plus angle, remember 2*np.pi periodicity\n", + " minus = 2*np.pi*k_plus/(measnumber)-opening\n", + " plus = 2*np.pi*k_plus/(measnumber)+opening\n", + " if angle > minus:\n", + " if angle < plus:\n", + " assigner[i][j].append(k_plus)\n", + " elif minus < 0:\n", + " if angle > minus + 2*np.pi:\n", + " assigner[i][j].append(k_plus)\n", + " elif plus > 2*np.pi:\n", + " assigner[i][j].append(k_plus)\n", + " elif plus > 2*np.pi:\n", + " if angle < plus - 2*np.pi:\n", + " assigner[i][j].append(k_plus)\n", + " \n", + " #add the two closest cells to the sensor as these might be omitted in the above calculation\n", + " for k in range(measnumber):\n", + " k_angle = 2*np.pi*k/(measnumber)\n", + " to_add1_i = int((1*math.cos(k_angle))/gridsize + localdim/2)\n", + " to_add1_j = int((1*math.sin(k_angle))/gridsize + localdim/2)\n", + " if k not in assigner[to_add1_i][to_add1_j]:\n", + " assigner[to_add1_i][to_add1_j].append(k)\n", + " to_add2_i = int((gridsize*math.cos(k_angle))/gridsize + localdim/2)\n", + " to_add2_j = int((gridsize*math.sin(k_angle))/gridsize + localdim/2)\n", + " if to_add2_i == to_add1_i and to_add1_j == to_add2_j:\n", + " to_add2_i = int((2*gridsize*math.cos(k_angle))/gridsize + localdim/2)\n", + " to_add2_j = int((2*gridsize*math.sin(k_angle))/gridsize + localdim/2)\n", + " if k not in assigner[to_add2_i][to_add2_j]:\n", + " assigner[to_add2_i][to_add2_j].append(k)\n", + " #print(assigner)\n", + " return assigner,distances\n", + "#assigner assign gridpos to sensorreading\n", + "assigner,distances = assignmap()\n", + "#print(measnumber)\n", + "#print(assigner[int(localdim/2)+1][int(localdim/2)])" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "def simulate_measurements():\n", + " error = 1 #standard deviation for gaussian measurement error (in mm)\n", + " \n", + " N = measnumber\n", + " #list of all measurements\n", + " measurements = np.zeros(N) \n", + " #determine correct measurements values\n", + " for i in range(localdim):\n", + " for j in range(localdim):\n", + " local_x = (i+1/2)*gridsize - localdim*gridsize/2\n", + " local_y = (j+1/2)*gridsize - localdim*gridsize/2\n", + " #remember to convert cm position to mm!\n", + " globalmap_x = 10*myxpos + local_x * math.cos(myangle) - local_y * math.sin(myangle)\n", + " globalmap_y = 10*myypos + local_x * math.sin(myangle) + local_y * math.cos(myangle)\n", + " globalgrid = (int(math.floor(globalmap_x/gridsize)),int(math.floor(globalmap_y/gridsize)))\n", + " #print(globalgrid)\n", + " if globalgrid in realglobalmap:\n", + " for sensor in assigner[i][j]:\n", + " if measurements[sensor] == 0 or measurements[sensor] > distances[i][j]:\n", + " measurements[sensor] = distances[i][j]\n", + " #sample gaussian measurements around exact meas\n", + " for k in range(N):\n", + " if measurements[k] == 0:\n", + " measurements[k] = 4000\n", + " else:\n", + " measurements[k] = random.gauss(measurements[k],error)\n", + " \n", + " return measurements\n", + "\n", + "#print(simulate_measurements())" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "def localmap(measurements):\n", + " #print(measurements)\n", + " #alpha is range in which cells are considered occupied (should be min gridsize/2)\n", + " alpha = gridsize/2\n", + " #occupied cells are adjusted by l_plus, unoccupied by l_minus\n", + " l_plus = 1\n", + " l_minus = 0.5\n", + " #cycle through each cell of the map and apply sensor data\n", + " map = np.zeros((localdim,localdim))\n", + " \n", + " for i in range(localdim):\n", + " for j in range(localdim):\n", + " for k in assigner[i][j]:\n", + " if distances[i][j] < measurements[k] - alpha:\n", + " #unoccupied measurement\n", + " map[i][j] -= l_minus\n", + " elif distances[i][j] < measurements[k] + alpha:\n", + " #occupied measurement\n", + " map[i][j] += l_plus\n", + " return map" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "#building localmap by getting measures and converting to map\n", + "def build_localmap():\n", + " measures = simulate_measurements()\n", + " #print(measures)\n", + " map = localmap(measures)\n", + " return map" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "def sample_motion(velocity, angular_velocity):\n", + " global myxpos,myypos,myangle\n", + " #sample motion for a velocity motion model\n", + " #delta_t needs to be normalized to 1!\n", + " #see probabilistic robotics page 124\n", + " \n", + "\n", + " #error parameters\n", + " alpha_1 = 0.0001 #influence of velocity on velocity uncertainty\n", + " alpha_2 = 0.00001 #influence of angular velocity on velocity uncertainty\n", + " alpha_3 = 0.000005 #influence of velocity on angular velocity uncertainty\n", + " alpha_4 = 0.00001 #influence of angular velocity on angular velocity uncertainty\n", + " #an additional angle will be added to account for non circular motion\n", + " alpha_5 = 0.000000001 #influence of velocity on additional angle uncertainty\n", + " alpha_6 = 0.000001 #influence of angular velocity on additional angle uncertainty\n", + "\n", + " #sample with gaussians\n", + " sample_vel = random.gauss(velocity, np.sqrt(alpha_1*velocity**2+alpha_2*angular_velocity**2))\n", + " sample_angvel = random.gauss(angular_velocity, np.sqrt(alpha_3*velocity**2 + alpha_4 * angular_velocity**2))\n", + " sample_addangle = random.gauss(0, np.sqrt(alpha_5*velocity**2+alpha_6*angular_velocity**2))\n", + "\n", + " if angular_velocity != 0 and abs(sample_angvel) >= 0.01:\n", + " #apply motion\n", + " myxpos += -sample_vel/sample_angvel*math.sin(myangle) + sample_vel/sample_angvel*math.sin(myangle+sample_angvel)\n", + " myypos += sample_vel/sample_angvel*math.cos(myangle) - sample_vel/sample_angvel*math.cos(myangle+sample_angvel)\n", + " myangle += sample_angvel+sample_addangle\n", + " else:\n", + " #motion for very small angular velocity, to avoid division by near 0 values\n", + " myxpos += sample_vel*math.cos(myangle)\n", + " myypos += sample_vel*math.sin(myangle)\n", + " myangle += sample_angvel+sample_addangle" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "#moving all particles\n", + "#change is wheel1-,wheel2-voltage time from executed movement\n", + "def move_me(wheelleft,wheelright,delta_t=1):\n", + " wheeldist = 19.5 #distance between left/right wheel in cm\n", + " speed = wheeldist*np.pi/4 #distance a wheel at max voltage 1 rotates in one delta_t\n", + " \n", + " #mean speed:\n", + " mean_speed = delta_t*speed*(wheelright+wheelleft)/2\n", + " #angular velocity\n", + " alpha_speed = (wheelright-wheelleft)*delta_t*speed/wheeldist\n", + " sample_motion(mean_speed, alpha_speed)\n", + " #print(wheelleft,wheelright)\n", + " #print(myxpos,myypos,myangle)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "def execute_movement(order):\n", + " #split the movement order\n", + " splitted = order.split('#')\n", + " wheelleft = float(splitted[1])\n", + " wheelright= float(splitted[2])\n", + " #and execute it using move_me\n", + " move_me(wheelleft,wheelright)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "##checking motion model\n", + "#myxpos,myypos,myangle = 0,0,0\n", + "#execute_movement('forward')\n", + "#print(myxpos,myypos)" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[ 0. 0. 0. 0. 0. 0. 0. 0. 0. -0.5 -0.5 0.\n", + " 0. 0. 0. 0. 0. 0. 0. 0. ]\n", + " [ 0. 0. 0. 0. 0. 0. 0. 0. 0. -0.5 -0.5 0.\n", + " 0. 0. 0. 0. 0. 0. 0. 0. ]\n", + " [ 0. 0. 0. 0. 0. 0. 0. 0. 0. -0.5 -0.5 0.\n", + " 0. 0. 0. 0. 0. 0. 0. 0. ]\n", + " [ 0. 0. 0. 0. 0. 0. 0. 0. 0. -0.5 -0.5 0.\n", + " 0. 0. 0. 0. 0. 0. 0. 0. ]\n", + " [ 0. 0. 0. 0. 0. 0. 0. 0. 0. -0.5 -0.5 0.\n", + " 0. 0. 0. 0. 0. 0. 0. 0. ]\n", + " [ 0. 0. 0. 0. 0. 0. 0. 0. 0. -0.5 -0.5 0.\n", + " 0. 0. 0. 0. 0. 0. 0. 0. ]\n", + " [ 0. 0. 0. 0. 0. 0. 0. 0. 1. 0. 1. 1.\n", + " 0. 0. 0. 0. 0. 0. 0. 0. ]\n", + " [ 0. 0. 0. 0. 0. 0. 0. 3. 3. 4. 3. 3.\n", + " 3. 2. 2. 1. 0. 1. 1. 0. ]\n", + " [ 0. 0. 0. 0. 0. 0. 1. 3. -3.5 -3. -3.5 -3.5\n", + " -1.5 -1.5 0. 0. -1. 0. 0.5 -0.5]\n", + " [ -0.5 -0.5 -0.5 -0.5 -0.5 -0.5 1. 3. -3. -9.5 -10. -3.\n", + " -2. -1.5 -1.5 -1.5 -1.5 -1.5 0. -1. ]\n", + " [ -0.5 -0.5 -0.5 -0.5 -0.5 -0.5 0. 4. -3.5 -10. -10.5 -3.5\n", + " -1.5 -1.5 -2. -1.5 -1.5 -1.5 -1.5 -1.5]\n", + " [ 0. 0. 0. 0. 0. 0. 1. 3. -3.5 -3. -3.5 -3.5\n", + " -1.5 -1.5 -1.5 -2. -1.5 -1.5 -1.5 -1.5]\n", + " [ 0. 0. 0. 0. 0. 0. 0. 3. -1.5 -1.5 -2. -1.5\n", + " -1.5 -1.5 -2. -2. -1.5 -1.5 -1.5 -1.5]\n", + " [ 0. 0. 0. 0. 0. 0. 0. 2. -1.5 -1.5 -1.5 -1.5\n", + " -1.5 -1.5 -2. -1.5 -1.5 -1.5 -1.5 -2. ]\n", + " [ 0. 0. 0. 0. 0. 0. 0. 2. 0. -2. -1.5 -1.5\n", + " -1.5 -1.5 -1.5 -1.5 -1.5 -1.5 -1.5 -1.5]\n", + " [ 0. 0. 0. 0. 0. 0. 0. 1. 0. -1.5 -1.5 -1.5\n", + " -1.5 -1.5 -1.5 -1.5 -1.5 -1.5 -1.5 -1.5]\n", + " [ 0. 0. 0. 0. 0. 0. 0. 0. -1. -1.5 -1.5 -1.5\n", + " -1.5 -1.5 -1.5 -1.5 -1.5 -1.5 -1.5 -1.5]\n", + " [ 0. 0. 0. 0. 0. 0. 0. 1. 0.5 -1.5 -1.5 -2.\n", + " -1.5 -2. -1.5 -1.5 -1.5 -1.5 -1.5 -1.5]\n", + " [ 0. 0. 0. 0. 0. 0. 0. 0. -1. -1.5 -1.5 -1.5\n", + " -2. -1.5 -1.5 -1.5 -1.5 -1.5 -1.5 -1.5]\n", + " [ 0. 0. 0. 0. 0. 0. 0. 1. 0.5 0. -1.5 -1.5\n", + " -1.5 -1.5 -2. -1.5 -2. -2. -1.5 -1.5]]\n" + ] + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAQUAAAD4CAYAAADl7fPiAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjAsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+17YcXAAAPgklEQVR4nO3df4xVZX7H8c8HkBEoqQ6UQYXKZoskdlPphrDdmDZYCyIxy25jW0jT0tYGu65JN2mT0jbRzfafbRpr0rLRnXWJrtll3f5gl2SpQmwT12R/OBJUrFAoYesIzlTd4hpGNuN8+8ecMfcZzoVz77nn/vL9Sib3/HjuOc9hhg/nzH14vo4IAcCMOZ3uAIDuQigASBAKABKEAoAEoQAgMa/THcgzMDAQixYt6nQ3esbk5GThtnPmFP93oJG28+fPL9y2GxS9tqmpqZYfs1GN9KGoc+fOaWJiwnn7ujIUFi1apNtuu63T3egZY2NjhdsuXry4cNuFCxcWbrtixYrCbbvBggULCrWbmJho+TEb1Ugfinr88cfr7uPxAUCCUACQIBQAJAgFAAlCAUCCUACQIBQAJAgFAAlCAUCiK0c0ojFDQ0OF2y5ZsqRw26pG6DWikT40MvKvilGCVRyzE7hTAJAgFAAkCAUACUIBQIJQAJAgFAAkCAUAicuOU7C9R9IdksYj4iPZtickrcmaXCXp/yJibc57T0v6iaT3JE1GxLoW9RtARYoMXnpU0m5JX53ZEBG/M7Ns+wFJ5y7x/lsi4o1mOwigvS4bChHxjO1VeftsW9JvS/r11nYLQKeUHeb8q5LGIuJEnf0h6aDtkPSliBiudyDbOyXtlBqbMBSNTdx6/vz5wm1vuOGGZrpzWVUNXa7quB80ZUNhu6S9l9h/c0Scsb1M0iHbxyLimbyGWWAMS9Lg4CBVb4EOafrTB9vzJP2mpCfqtYmIM9nruKR9ktY3ez4A7VHmI8nfkHQsIkbzdtpeZHvxzLKkTZKOljgfgDa4bCjY3ivpe5LW2B61fVe2a5tmPTrYvtb2gWx1SNKztl+Q9ENJ34mIJ1vXdQBVKPLpw/Y62/8gZ9sZSVuy5VOSbirZPwBtxohGAAlCAUCCUACQIBQAJAgFAAlmc+4DVc3mXJWqhhgzdLk1uFMAkCAUACQIBQAJQgFAglAAkCAUACQIBQAJQgFAglAAkCAUACQY5twHGpnNuRErVqyo5LjobtwpAEgUmaNxj+1x20drtn3O9mu2j2RfW+q8d7Pt47ZP2t7Vyo4DqEaRO4VHJW3O2f5gRKzNvg7M3ml7rqQvSrpd0o2Sttu+sUxnAVTvsqGQFW95q4ljr5d0MiJORcRPJX1D0tYmjgOgjcr8TuFe2y9mjxdX5+y/TtKrNeuj2bZctnfaHrE9cuHChRLdAlBGs6HwkKQPS1or6aykB3LaOGdb3XJwETEcEesiYt3AwECT3QJQVlOhEBFjEfFeRExJ+rLyy8GNSlpZs75C0plmzgegfZoKBdvX1Kx+Svnl4J6TtNr2h2zP13RFqf3NnA9A+1x28FJWNm6DpKW2RyXdL2mD7bWafhw4LenurO21kh6JiC0RMWn7XklPSZoraU9EvFzJVQBomWbLxn2lTtv3y8Zl6wckXfRxJYDuxTDnPvD6668XbtvIzM8LFiwo3JaZlPsHw5wBJAgFAAlCAUCCUACQIBQAJAgFAAlCAUCCUACQIBQAJBjR+AHTyGSs/TxKsehozV77Myh6XXPm1L8f4E4BQIJQAJAgFAAkCAUACUIBQIJQAJAgFAAkmi0b93e2j2V1H/bZvqrOe0/bfikrLTfSyo4DqEazZeMOSfpIRPySpP+S9JeXeP8tWWm5dc11EUA7NVU2LiIORsRktvp9Tdd0ANAHWjHM+Y8kPVFnX0g6aDskfSkihusdxPZOSTslaeHChS3o1gfH+Ph4p7vQt5O89tp1Fe3D1NRU3X2lQsH2X0ualPS1Ok1ujogztpdJOmT7WHbncZEsMIYlaXBwsG55OQDVavrTB9s7JN0h6XcjIvcvcVYHQhExLmmf8svLAegizZaN2yzpLyR9IiLO12mzyPbimWVJm5RfXg5AFynykeReSd+TtMb2qO27JO2WtFjTjwRHbD+ctb3W9kxFqCFJz9p+QdIPJX0nIp6s5CoAtExlZeMi4pSkm0r1DkDbMaIRQIJQAJAgFAAkCAUACUIBQILZnLvU2NhYJcdds2ZN4bbnz+cOQclV1dD048ePV3LcosOBGxnm3C+4UwCQIBQAJAgFAAlCAUCCUACQIBQAJAgFAAlCAUCCUACQIBQAJLpymPOcOXM+kMNLaw0NDRVu++abb1bSh3vuuadw23nziv8oPfLII810p6WK/nx1wwzN7cadAoBEoVCoUzpu0PYh2yey16vrvHdH1uZENgM0gC5W9E7hUV1cOm6XpKcjYrWkp7P1hO1BSfdL+pimp3e/v154AOgOhUIhr3ScpK2SHsuWH5P0yZy33ibpUES8FRE/1nQNytnhAqCLlPmdwlBEnJWk7HVZTpvrJL1asz6abQPQpar+RaNztuVWk7K90/aI7ZF333234m4BqKdMKIzZvkaSste8KqejklbWrK+QdCbvYBExHBHrImLdlVdeWaJbAMooEwr7Jc18mrBD0rdz2jwlaZPtq7NfMG7KtgHoUkU/kswrHfcFSRttn5C0MVuX7XW2H5GkiHhL0t9Iei77+ny2DUCXKjQMrU7pOEm6NaftiKQ/rlnfI2lPU70D0HZdOcwZjc3mvGTJksJtG5mheXJysnDbRjTSh0aGuzcyJLmXhi+Pjo4Wblv0Z2FqaqruPoY5A0gQCgAShAKABKEAIEEoAEgQCgAShAKABKEAIEEoAEgQCgASXTnMeWpqqqeGofaShQsXFm47PDxcyXEbaVvVz0EjQ4eLamS4eSMzcFcxLJxhzgAKIxQAJAgFAAlCAUCCUACQIBQAJAgFAImmQ8H2GttHar7etv3ZWW022D5X0+a+8l0GUKWmBy9FxHFJayXJ9lxJr0nal9P0uxFxR7PnAdBerXp8uFXSf0fEj1p0PAAd0qphztsk7a2z7+O2X9B0Zag/j4iX8xrZ3ilpp9TYMNh+NTQ0VMlxd+26qDh4XY0MxW1kiG9Vli3LK2dazvLly1t+TKmx2bobUfTvTqXDnG3Pl/QJSf+Us/uwpOsj4iZJ/yjpW/WOU1s2bmBgoGy3ADSpFY8Pt0s6HBEXRV9EvB0R72TLByRdYXtpC84JoCKtCIXtqvPoYHu5bWfL67PzFb8nBdB2pX6nYHuhputI3l2z7U8kKSIelnSnpE/bnpQ0IWlbROSWogfQHUqFQkScl7Rk1raHa5Z3S9pd5hwA2osRjQAShAKABKEAIEEoAEgQCgASXTmbMxqzcePGwm0bGV7byFDrqobtVjXcu9O6+bq4UwCQIBQAJAgFAAlCAUCCUACQIBQAJAgFAAlCAUCCUACQIBQAJBjm/AHTyPDaBQsWFG67atWqwm0nJiYKt0X7cacAINGKKd5P234pKws3krPftv/B9knbL9r+aNlzAqhOqx4fbomIN+rsu13S6uzrY5Ieyl4BdKF2PD5slfTVmPZ9SVfZvqYN5wXQhFaEQkg6aPv5rPTbbNdJerVmfTTblrC90/aI7ZELFy60oFsAmtGKx4ebI+KM7WWSDtk+FhHP1Ox3znsuqv0QEcOShiVpcHCQ2hBAh5S+U4iIM9nruKZL0a+f1WRU0sqa9RWaLjYLoAuVCgXbi2wvnlmWtEnS0VnN9kv6/exTiF+RdC4izpY5L4DqlH18GJK0LysXOU/S1yPiyVml4w5I2iLppKTzkv6w5DkBVKhs2bhTkm7K2V5bOi4kfabMeQC0DyMaASQIBQAJQgFAglAAkCAUACQIBQAJQgFAglAAkCAUACQIBQAJQgFAglAAkCAUACQIBQAJQgFAglAAkCAUACQIBQCJpkPB9krb/2H7Fdsv2/7TnDYbbJ/LSsodsX1fue4CqFqZORonJf1ZRBzOZnR+3vahiPjPWe2+GxF3lDgPgDZq+k4hIs5GxOFs+SeSXlFO5ScAvaUlv1OwvUrSL0v6Qc7uj9t+wfa/2f7FSxyDsnFAFyhdNs72z0j6F0mfjYi3Z+0+LOn6iHjH9hZJ39J09emLUDYO6A5lK0RdoelA+FpE/Ovs/RHxdkS8ky0fkHSF7aVlzgmgWmU+fbCkr0h6JSL+vk6b5Vk72V6fne/NZs8JoHplHh9ulvR7kl6yfSTb9leSfl56v0rUnZI+bXtS0oSkbVnFKABdqulQiIhnlV9mvrbNbkm7mz0HgPZjRCOABKEAIEEoAEgQCgAShAKABKEAIEEoAEgQCgAShAKABKEAIEEoAEgQCgAShAKABKEAIEEoAEgQCgAShAKABKEAIFF2NufNto/bPml7V87+AdtPZPt/kNWHANDFyszmPFfSFyXdLulGSdtt3zir2V2SfhwRvyDpQUl/2+z5ALRHmTuF9ZJORsSpiPippG9I2jqrzVZJj2XL/yzp1pkp3wF0pzKhcJ2kV2vWR3VxLcn320TEpKRzkpbkHYyycUB3KBMKef/iz67pUKTN9MaI4YhYFxHrBgYGSnQLQBllQmFU0sqa9RWSztRrY3uepJ+V9FaJcwKoWJlQeE7Satsfsj1f0jZJ+2e12S9pR7Z8p6R/p0IU0N3KVIiatH2vpKckzZW0JyJetv15SSMRsV/TtSYft31S03cI21rRaQDVKVWKPqskfWDWtvtqlt+V9FtlzgGgvdyNd/O2/1fSj2ZtXirpjQ50p2r9el1S/15bP1zX9RHxc3k7ujIU8tgeiYh1ne5Hq/XrdUn9e239el0z+L8PABKEAoBEL4XCcKc7UJF+vS6pf6+tX69LUg/9TgFAe/TSnQKANiAUACR6IhQuN5lLr7J92vZLto/YHul0f8qwvcf2uO2jNdsGbR+yfSJ7vbqTfWxGnev6nO3Xsu/bEdtbOtnHVuv6UCg4mUsvuyUi1vbB596PSto8a9suSU9HxGpJT2frveZRXXxdkvRg9n1bm43s7RtdHwoqNpkLOiwintHF/wO2dpKdxyR9sq2daoE619XXeiEUikzm0qtC0kHbz9ve2enOVGAoIs5KUva6rMP9aaV7bb+YPV703GPRpfRCKBSeqKUH3RwRH9X0o9FnbP9apzuEQh6S9GFJayWdlfRAZ7vTWr0QCkUmc+lJEXEmex2XtE/Tj0r9ZMz2NZKUvY53uD8tERFjEfFeRExJ+rL67PvWC6FQZDKXnmN7ke3FM8uSNkk6eul39ZzaSXZ2SPp2B/vSMjNBl/mU+uz7Vmo+hXaoN5lLh7vVCkOS9mWTW8+T9PWIeLKzXWqe7b2SNkhaantU0v2SviDpm7bvkvQ/6sG5Nepc1wbbazX9GHta0t0d62AFGOYMINELjw8A2ohQAJAgFAAkCAUACUIBQIJQAJAgFAAk/h9pSXs3TPlnwwAAAABJRU5ErkJggg==\n", + "text/plain": [ + "<Figure size 432x288 with 1 Axes>" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "##checking if localmap works\n", + "##remember pyplots imshow is rotated to how the maps are used for us(first index in y dir instead x)\n", + "#myxpos = 50\n", + "#myypos = 50\n", + "#myangle = 0\n", + "\n", + "\n", + "#localmappy = build_localmap()\n", + "#print(localmappy)\n", + "#import matplotlib.pyplot as plt\n", + "#plt.imshow(localmappy, interpolation='nearest', cmap=plt.cm.Greys,origin = 'lower')\n", + "#plt.show()\n", + "#print(localmappy[3][5])" + ] + }, + { + "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.6.8" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/Code/SimulatedRobotHost.ipynb b/Code/SimulatedRobotHost.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..aca9b18dffa57570ade01435a4ce541e249696ba --- /dev/null +++ b/Code/SimulatedRobotHost.ipynb @@ -0,0 +1,171 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import socket\n", + "import numpy as np\n", + "from io import StringIO\n", + "import struct\n", + "%run Simulate_Alldirrobot.ipynb" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "#functions for sending and receiving messages\n", + "#each message is prefixed by an int lenght, used to receive the hole lenght of message afterwards\n", + "def send_msg(sock, msg):\n", + " # Prefix each message with a 4-byte length (network byte order)\n", + " msg = struct.pack('>I', len(msg)) + msg\n", + " sock.sendall(msg)\n", + "\n", + "def recv_msg(sock):\n", + " # Read message length and unpack it into an integer\n", + " raw_msglen = recvall(sock, 4)\n", + " if not raw_msglen:\n", + " return None\n", + " msglen = struct.unpack('>I', raw_msglen)[0]\n", + " # Read the message data\n", + " return recvall(sock, msglen)\n", + "\n", + "def recvall(sock, n):\n", + " # Helper function to recv n bytes or return None if EOF is hit\n", + " data = bytearray()\n", + " while len(data) < n:\n", + " packet = sock.recv(n - len(data))\n", + " if not packet:\n", + " return None\n", + " data.extend(packet)\n", + " return data" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "def server():\n", + " #host with your own name on port\n", + " host = socket.gethostname() #get local machine name\n", + " port = 4244\n", + " print(\"hosting on: '\" + str(host) + \"' \\t port: \" + str(port))\n", + " \n", + " #do the hosting\n", + " s = socket.socket()\n", + " s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)\n", + " s.bind(('',port))\n", + " \n", + " #wait for connection\n", + " s.listen(1)\n", + " client_socket, adress = s.accept()\n", + " print(\"Connection from: \" + str(adress))\n", + " data='empty'\n", + " #until data = q do move/meas loop\n", + " while True:\n", + " data = recv_msg(client_socket).decode('utf-8')#reveive message\n", + " if not data or data == 'q': #received a disconnect message\n", + " print(\"Disconnecting\")\n", + " break\n", + " if data == \"reset\": #reset message\n", + " print(\"Resetting...\")\n", + " #reset positions\n", + " global myxpos\n", + " global myypos\n", + " global myangle\n", + " myxpos = 0\n", + " myypos = 0\n", + " myangle = 0\n", + " #generate a new random map\n", + " global realglobalmap\n", + " realglobalmap = generate_random_map(maxcounter = 20)#custom_map01()\n", + " #send im done resetting \n", + " send = 'done'\n", + " send_msg(client_socket,send.encode('utf-8'))\n", + " else: \n", + " #received a movement message -> execute it\n", + " execute_movement(data)\n", + " #simulate building of a localmap\n", + " localm = build_localmap()\n", + " #send localmap as message\n", + " send_localm = localm.tostring()\n", + " send_msg(client_socket,send_localm)\n", + " #end\n", + " client_socket.close()\n" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "hosting on: 'DESKTOP-P0PR3LK' \t port: 4244\n", + "Connection from: ('192.168.178.20', 61896)\n", + "Resetting...\n" + ] + }, + { + "ename": "AttributeError", + "evalue": "'NoneType' object has no attribute 'decode'", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mAttributeError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m<ipython-input-4-9938d8172090>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mserver\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;31m#start server\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[1;32m<ipython-input-3-933ae119dc87>\u001b[0m in \u001b[0;36mserver\u001b[1;34m()\u001b[0m\n\u001b[0;32m 17\u001b[0m \u001b[1;31m#until data = q do move/meas loop\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 18\u001b[0m \u001b[1;32mwhile\u001b[0m \u001b[1;32mTrue\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 19\u001b[1;33m \u001b[0mdata\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mrecv_msg\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mclient_socket\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mdecode\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m'utf-8'\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;31m#reveive message\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 20\u001b[0m \u001b[1;32mif\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[0mdata\u001b[0m \u001b[1;32mor\u001b[0m \u001b[0mdata\u001b[0m \u001b[1;33m==\u001b[0m \u001b[1;34m'q'\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;31m#received a disconnect message\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 21\u001b[0m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Disconnecting\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mAttributeError\u001b[0m: 'NoneType' object has no attribute 'decode'" + ] + } + ], + "source": [ + "server() #start server" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "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.6.8" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/Code/alldirexplorandmap2_autosave728_weights.h5 b/Code/alldirexplorandmap2_autosave728_weights.h5 new file mode 100644 index 0000000000000000000000000000000000000000..8cf5d62fdaf675d6b6119dcfa453bd1c5c7122ca Binary files /dev/null and b/Code/alldirexplorandmap2_autosave728_weights.h5 differ diff --git a/Code/alldirparticlefilt.ipynb b/Code/alldirparticlefilt.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..98b6343a1652f0354d217e599abde183198bedd3 --- /dev/null +++ b/Code/alldirparticlefilt.ipynb @@ -0,0 +1,837 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "#particle filter for a full vision robot" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "16\n" + ] + } + ], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "#imports\n", + "import numpy as np\n", + "import math\n", + "import copy\n", + "import random\n", + "import time" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "#some global parameters\n", + "gridsize = 10 #size of map grids\n", + "relocatecounter = 0 #how often relocated in a row\n", + "bestparticle = 0 #current particle with highest weight\n", + "errorcount = 0 #how often failed to execute actions (too high = abort)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "#convert a map value into a simple 1 occupied or 0 not occupied\n", + "def mapconvert(value):\n", + " if value > 0:\n", + " return 1\n", + " else:\n", + " return 0" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "class particle:\n", + " def __init__(self,x,y,phi,pmap = {}, counter = 0, priorcells = None):\n", + " #initiate particle by pose and map copy\n", + " self.xpos = x\n", + " self.ypos = y\n", + " self.angle = phi\n", + " self.map = copy.deepcopy(pmap)\n", + " self.weight = 1 #starting weight is 1\n", + " #priorcells are a memory of path; copy it or add start cell\n", + " if priorcells == None:\n", + " self.priorcells = [(int(math.floor(self.xpos/gridsize)),int(math.floor(self.ypos/gridsize)))]\n", + " else:\n", + " self.priorcells = copy.deepcopy(priorcells)\n", + " self.counter = counter #counts motion, only every 10th cell will be added to priorcells\n", + " \n", + " def incorporate_localmap(self,localmap):\n", + " #incorporating given local map into the global map\n", + " \n", + " #extra unoccupied measurement for the cell the robot is currently at\n", + " current_cell = (int(math.floor(self.xpos/gridsize)),int(math.floor(self.ypos/gridsize)))\n", + " if current_cell not in self.map:\n", + " self.map[current_cell] = -1\n", + " else:\n", + " self.map[current_cell] -= 1\n", + " \n", + "\n", + " #loop over localmap\n", + " N = len(localmap)\n", + " for i in range(N):\n", + " for j in range(N):\n", + " #only use localmap entries that are actually measured (!=0)\n", + " if localmap[i][j] != 0:\n", + " #convert local i,j to global\n", + " local_x = (i+1/2)*gridsize - N*gridsize/2\n", + " local_y = (j+1/2)*gridsize - N*gridsize/2\n", + " globalmap_x = self.xpos + local_x * math.cos(self.angle) - local_y * math.sin(self.angle)\n", + " globalmap_y = self.ypos + local_x * math.sin(self.angle) + local_y * math.cos(self.angle)\n", + " globalgrid = (int(math.floor(globalmap_x/gridsize)),int(math.floor(globalmap_y/gridsize)))\n", + " #update global map, if cell never observed before create entry\n", + " if globalgrid in self.map:\n", + " self.map[globalgrid] += localmap[i][j]\n", + " else:\n", + " self.map[globalgrid] = localmap[i][j]\n", + " \n", + " return self.map\n", + " \n", + " def incorporate_localmap_withreward(self,localmap):\n", + " #the same function as before but also calculate a reward by counting newly observed cells\n", + " \n", + " #incorporating given local map into the global map\n", + " new_cells = 0 #count all cells that were observed for the first time as rewards\n", + " \n", + " #extra unoccupied measurement for the cell the robot is currently at\n", + " current_cell = (int(math.floor(self.xpos/gridsize)),int(math.floor(self.ypos/gridsize)))\n", + " if current_cell not in self.map:\n", + " self.map[current_cell] = -1\n", + " new_cells += 1 #newly observed cell = reward\n", + " else:\n", + " self.map[current_cell] -=1\n", + " \n", + " #loop over localmap\n", + " N = len(localmap)\n", + " for i in range(N):\n", + " for j in range(N):\n", + " #only use localmap entries that are actually measured (!=0)\n", + " if localmap[i][j] != 0:\n", + " #convert local i,j to global\n", + " local_x = (i+1/2)*gridsize - N*gridsize/2\n", + " local_y = (j+1/2)*gridsize - N*gridsize/2\n", + " globalmap_x = self.xpos + local_x * math.cos(self.angle) - local_y * math.sin(self.angle)\n", + " globalmap_y = self.ypos + local_x * math.sin(self.angle) + local_y * math.cos(self.angle)\n", + " globalgrid = (int(math.floor(globalmap_x/gridsize)),int(math.floor(globalmap_y/gridsize)))\n", + " #update global map, if cell never observed before create entry\n", + " if globalgrid in self.map:\n", + " self.map[globalgrid] += localmap[i][j]\n", + " else:\n", + " self.map[globalgrid] = localmap[i][j]\n", + " new_cells += 1 #newly observed cell = reward\n", + " \n", + " return new_cells #return number of newly observed cells as reward\n", + " \n", + " def map_weigh(self,localmap):\n", + " #calculate probability of localmap corresponding to global map at particle position \n", + " \n", + " #find overlapping cells calc m_bar\n", + " N = len(localmap)\n", + " overlap = []\n", + " m_bar = 0\n", + " for i in range(N):\n", + " for j in range(N):\n", + " #only use localmap entries that are actually measured (!=0)\n", + " if localmap[i][j] != 0:\n", + " local_x = (i+1/2)*gridsize - N*gridsize/2\n", + " local_y = (j+1/2)*gridsize - N*gridsize/2\n", + " globalmap_x = self.xpos + local_x * math.cos(self.angle) - local_y * math.sin(self.angle)\n", + " globalmap_y = self.ypos + local_x * math.sin(self.angle) + local_y * math.cos(self.angle)\n", + " globalgrid = (int(math.floor(globalmap_x/gridsize)),int(math.floor(globalmap_y/gridsize)))\n", + " if globalgrid in self.map:\n", + " m_bar += mapconvert(self.map[globalgrid]) + mapconvert(localmap[i][j]) \n", + " overlap.append(((i,j),globalgrid))\n", + " #calculate correlation between the two maps (only if there is an overlap)\n", + " if len(overlap) > 0:\n", + " m_bar = m_bar/(2*len(overlap)) \n", + "\n", + " sum_1 = 0\n", + " sum_2 = 0\n", + " sum_3 = 0\n", + " for ((i,j),(k,l)) in overlap:\n", + " sum_1 += (mapconvert(self.map[(k,l)])-m_bar)*(mapconvert(localmap[i][j])-m_bar)\n", + " sum_2 += (mapconvert(self.map[(k,l)])-m_bar)**2\n", + " sum_3 += (mapconvert(localmap[i][j])-m_bar)**2\n", + " correlation = sum_1/math.sqrt(sum_2*sum_3)\n", + " if self.weight != 1: #this is only a safety check, it should not be possible\n", + " print(\"Weight not 1 for some reason\")\n", + " #use max of correlation and 0.01\n", + " #not using max with 0 to avoid edge case of all particles losing their weight\n", + " self.weight *= max(0.01,correlation)\n", + " \n", + " return self.weight\n", + " \n", + " def sample_motion(self, velocity, angular_velocity):\n", + " #if self.counter is high enough add to history of previously visited cells\n", + " #save cell as priorcell every 10 steps\n", + " if self.counter == 10:\n", + " self.priorcells.append((int(math.floor(self.xpos/gridsize)),int(math.floor(self.ypos/gridsize))))\n", + " self.counter = 0\n", + " else:\n", + " self.counter += 1\n", + " \n", + " #sample motion for a velocity motion model\n", + " #delta_t needs to be normalized to 1!\n", + " #see probabilistic robotics page 124\n", + " \n", + " #error parameters\n", + " alpha_1 = 0.0001 #influence of velocity on velocity uncertainty\n", + " alpha_2 = 0.00001 #influence of angular velocity on velocity uncertainty\n", + " alpha_3 = 0.000005 #influence of velocity on angular velocity uncertainty\n", + " alpha_4 = 0.00001 #influence of angular velocity on angular velocity uncertainty\n", + " #an additional angle will be added to account for non circular motion\n", + " alpha_5 = 0.000000001 #influence of velocity on additional angle uncertainty\n", + " alpha_6 = 0.000001 #influence of angular velocity on additional angle uncertainty\n", + "\n", + " #sample with gaussians\n", + " sample_vel = random.gauss(velocity, np.sqrt(alpha_1*velocity**2+alpha_2*angular_velocity**2))\n", + " sample_angvel = random.gauss(angular_velocity, np.sqrt(alpha_3*velocity**2 + alpha_4 * angular_velocity**2))\n", + " sample_addangle = random.gauss(0, np.sqrt(alpha_5*velocity**2+alpha_6*angular_velocity**2))\n", + "\n", + " if abs(sample_angvel) >= 0.01:\n", + " #apply motion\n", + " self.xpos += -sample_vel/sample_angvel*math.sin(self.angle) + sample_vel/sample_angvel*math.sin(self.angle+sample_angvel)\n", + " self.ypos += sample_vel/sample_angvel*math.cos(self.angle) - sample_vel/sample_angvel*math.cos(self.angle+sample_angvel)\n", + " self.angle += sample_angvel+sample_addangle\n", + " else:\n", + " #motion for very small angular velocity, to avoid division by near 0 values\n", + " self.xpos += sample_vel*math.cos(self.angle)\n", + " self.ypos += sample_vel*math.sin(self.angle)\n", + " self.angle += sample_angvel+sample_addangle\n", + " \n", + " \n", + " return self.xpos,self.ypos,self.angle\n", + " \n", + " def nearest_unobserved(self):\n", + " #find nearest unobserved grid cell\n", + " #and return path to it\n", + " #used as an exploration algorithm\n", + " \n", + " #start cell, start path\n", + " selfgrid = (int(math.floor(self.xpos/gridsize)),int(math.floor(self.ypos/gridsize)))\n", + " paths = [[selfgrid]]\n", + " #done_cells are already considered cells to avoid going in circles\n", + " done_cells = [selfgrid]\n", + " \n", + " #search paths in a breadth-first search\n", + " while True:\n", + " #check if path has been observed in map, if yes search neighbours\n", + " if paths[0][-1] in self.map:\n", + " #only search neighbours if mapcell is unoccupied\n", + " if self.map[paths[0][-1]] < 0:\n", + " #to avoid wallhugging paths check for occupied neighbours, if present this path is not desirable\n", + " no_hugging = True\n", + " for (i,j) in [(-1,0),(1,0),(0,-1),(0,1)]:\n", + " next_cell = (paths[0][-1][0]+i,paths[0][-1][1]+j)\n", + " if next_cell in self.map:\n", + " if self.map[next_cell] > 0:\n", + " no_hugging = False\n", + " if no_hugging == True or paths[0][-1] == selfgrid:\n", + " #loop through neighbours\n", + " for (i,j) in [(-1,0),(1,0),(0,-1),(0,1)]:\n", + " next_cell = (paths[0][-1][0]+i,paths[0][-1][1]+j)\n", + " #add new path if next_cell is not in an observed path\n", + " if next_cell not in done_cells:\n", + " new_path = copy.copy(paths[0])\n", + " new_path.append(next_cell)\n", + " paths.append(new_path)\n", + " done_cells.append(next_cell)\n", + " #pop out considered paths\n", + " paths.pop(0)\n", + " else:\n", + " #found path\n", + " target_path = paths[0]\n", + " break\n", + " if len(paths) == 0:\n", + " #there is no path to an unobserved cell (everything is observed or robot is stuck)\n", + " target_path = []\n", + " break\n", + " \n", + " #left,right,forward,backward order list to follow target path \n", + " orders = []\n", + " #looking dir is 0 to 3 standing for right,up,left,down\n", + " looking_dir = int(((self.angle%(2*np.pi)) *2/np.pi)+0.5)%4\n", + " for i in range(1,len(target_path)-1): \n", + " change = (target_path[i][0] - target_path[i-1][0],target_path[i][1] - target_path[i-1][1])\n", + " #translate change into number 0 to 3 that tells you if you need to go right,up,left or down\n", + " ruld_change = int(-change[0] + 1 + change[1]*(change[1]-1))\n", + " if (ruld_change - looking_dir)%4 == 0:\n", + " orders.append(\"forward\")\n", + " else:\n", + " if (ruld_change - looking_dir)%4 == 1:\n", + " orders.append(\"left\")\n", + " orders.append(\"forward\")\n", + " looking_dir += 1\n", + " if (ruld_change - looking_dir)%4 == 2:\n", + " orders.append(\"backward\")\n", + " if (ruld_change - looking_dir)%4 == 3:\n", + " orders.append(\"right\")\n", + " orders.append(\"forward\")\n", + " looking_dir -= 1\n", + " \n", + " global errorcount\n", + " if len(orders) == 0:\n", + " #if there are no orders move backward once to get out of a stuck position\n", + " print(\"no orders in explore\")\n", + " orders.append(\"backward\")\n", + " errorcount += 1 #errorcount, abort if this gets to high\n", + " else:\n", + " errorcount = 0\n", + " return orders\n", + " \n", + " #old idea - doesnt work well, use not recommended\n", + " #def relocate(self, localmap):\n", + " # #relocate algorithm\n", + " # #find best known cell in vicinity\n", + " # #return path to it\n", + " # \n", + " # localsize = len(localmap)\n", + " # N = localsize \n", + " # \n", + " # k=0\n", + " # bestcell = ()\n", + " # bestcellvalue = 0\n", + " # while bestcellvalue == 0:\n", + " # for i in range(localsize):\n", + " # for j in [k,-1-k]:\n", + " # #convert local i,j to global\n", + " # #print(gridsize)\n", + " # local_x = (i+1/2)*gridsize - N*gridsize*0.5\n", + " # local_y = (j+1/2)*gridsize - N*gridsize*0.5\n", + " # globalmap_x = self.xpos + local_x * math.cos(self.angle) - local_y * math.sin(self.angle)\n", + " # globalmap_y = self.ypos + local_x * math.sin(self.angle) + local_y * math.cos(self.angle)\n", + " # globalgrid = (int(math.floor(globalmap_x/gridsize)),int(math.floor(globalmap_y/gridsize)))\n", + " # \n", + " # #update global map, if cell never observed before create entry\n", + " # if globalgrid in self.map and localmap[i][j] < 0:\n", + " # if self.map[globalgrid] < bestcellvalue:\n", + " # bestcell = (i,j)\n", + " # bestcellvalue = self.map[globalgrid] \n", + " # for i in [k,-1-k]:\n", + " # for j in range(localsize):\n", + " # #convert local i,j to global\n", + " # local_x = (i+1/2)*gridsize - N*gridsize/2\n", + " # local_y = (j+1/2)*gridsize - N*gridsize/2\n", + " # globalmap_x = self.xpos + local_x * math.cos(self.angle) - local_y * math.sin(self.angle)\n", + " # globalmap_y = self.ypos + local_x * math.sin(self.angle) + local_y * math.cos(self.angle)\n", + " # globalgrid = (int(math.floor(globalmap_x/gridsize)),int(math.floor(globalmap_y/gridsize)))\n", + " # \n", + " # #update global map, if cell never observed before create entry\n", + " # if globalgrid in self.map and localmap[i][j] < 0:\n", + " # if self.map[globalgrid] < bestcellvalue:\n", + " # bestcell = (i,j)\n", + " # bestcellvalue = self.map[globalgrid]\n", + " # print(bestcell,bestcellvalue)\n", + " # #building a movement cost map from bestcell to find path \n", + " # costmap = np.full((localsize,localsize),100)\n", + " # costmap[bestcell] = 0\n", + " # done = [bestcell]\n", + " # to_do = [bestcell]\n", + " # while len(to_do) > 0:\n", + " # for (i,j) in [(-1,0),(1,0),(0,1),(0,-1)]:\n", + " # if 0 <= to_do[0][0]+i < localsize and 0 <= to_do[0][1]+j < localsize:\n", + " # if (to_do[0][0]+i,to_do[0][1]+j) not in done:\n", + " # if localmap[(to_do[0][0]+i,to_do[0][1]+j)] < 0:\n", + " # costmap[to_do[0][0]+i,to_do[0][1]+j] = costmap[to_do[0][0],to_do[0][1]] + 1\n", + " # to_do.append((to_do[0][0]+i,to_do[0][1]+j))\n", + " # done.append((to_do[0][0]+i,to_do[0][1]+j))\n", + " # to_do.pop(0)\n", + " # print(costmap) \n", + " # \n", + " # #follow costmap to goal\n", + " # orders = []\n", + " # currentcell = (int(localsize/2),int(localsize/2))\n", + " # lookingdir = 0\n", + " # foundgoal = False\n", + " # \n", + " # waylist = [(1,0),(0,1),(-1,0),(0,-1)]\n", + " # while foundgoal == False:\n", + " # bestway = (currentcell[0]+waylist[lookingdir][0],currentcell[1]+waylist[lookingdir][1])\n", + " # bestwayvalue = costmap[bestway]\n", + " # movedir = lookingdir\n", + " # for i in range(len(waylist)):\n", + " # new_cell = (currentcell[0]+waylist[i][0],currentcell[1]+waylist[i][1])\n", + " # if costmap[new_cell] < bestwayvalue:\n", + " # bestway = new_cell\n", + " # bestwayvalue = costmap[new_cell]\n", + " # movedir = i\n", + " # currentcell = bestway\n", + " # if (movedir - lookingdir)%4 == 0:\n", + " # orders.append(\"forward\")\n", + " # else:\n", + " # if (movedir - lookingdir)%4 == 1:\n", + " # orders.append(\"left\")\n", + " # orders.append(\"forward\")\n", + " # lookingdir += 1\n", + " # if (movedir - lookingdir)%4 == 2:\n", + " # orders.append(\"backward\")\n", + " # if (movedir - lookingdir)%4 == 3:\n", + " # orders.append(\"right\")\n", + " # orders.append(\"forward\")\n", + " # lookingdir -= 1\n", + " # #print(bestwayvalue)\n", + " # if bestwayvalue == 0:\n", + " # foundgoal = True\n", + " # elif bestwayvalue == 100:\n", + " # print(\"No possible way\")\n", + " # foundgoal = True\n", + " # return orders\n", + " \n", + " def retrace(self,aim_for = 'none'):\n", + " #retrace algorithm\n", + " #find path to a cell seome time ago from the saved path of the particle\n", + " #standard is going to a cell 3*10= 30 steps earlier\n", + " #changes if cell not reachable or multiple relocates in a wor\n", + " global errorcount\n", + " global relocatecounter\n", + " relocatecorrection = 0 # correction of relocate counter if we dont take the full 3 relocate steps\n", + " given_aim_for = False #the cell to aim for may be given, in this case go there\n", + " #aim_for is a cell some steps earlier\n", + " if aim_for != 'none': #aimfor is given no need to find it\n", + " relocatecorrection = 3\n", + " given_aim_for = True\n", + " else:\n", + " #no aim for given, choose cell (2*relocatecounter+1)*3 earlier\n", + " if len(self.priorcells) > (2*relocatecounter+1)*3:\n", + " aim_for = self.priorcells[int(-(2*relocatecounter+1)*3 + 0.5)]\n", + " aim_for_index = int(-(2*relocatecounter+1)*3 + 0.5)\n", + " #not enough members in priorcell, go to first member\n", + " elif len(self.priorcells) > 0:\n", + " aim_for = self.priorcells[0]\n", + " aim_for_index = 0\n", + " #no members in priorcells, relocate does not make sense here\n", + " else:\n", + " return [\"Do_nothing\"], aim_for\n", + " \n", + " #starting cell and looking direction\n", + " start_cell = (int(math.floor(self.xpos/gridsize)),int(math.floor(self.ypos/gridsize)))\n", + " startlooking_dir = int(((self.angle%(2*np.pi)) *2/np.pi)+0.5)%4 #looking dir is 0 to 3 standing for right,up,left,down\n", + " \n", + " #find a path from currentcell to aim_for\n", + " #start cell, start path\n", + " selfgrid = start_cell\n", + " paths = [[selfgrid]]\n", + " #done_cells are already considered cells to avoid going in circles\n", + " done_cells = [selfgrid]\n", + " #translate lookingdir into change of coordinates resulting in forwardchange\n", + " waylist = [(1,0),(0,1),(-1,0),(0,-1)]\n", + " forwardchange = waylist[startlooking_dir]\n", + " #search paths in a breadth-first search\n", + " while True:\n", + " #check if path has been observed in map, if yes search neighbours\n", + " if paths[0][-1] in self.map:\n", + " if paths[0][-1] == aim_for:\n", + " #finished search if path is found\n", + " target_path = paths[0]\n", + " break\n", + " \n", + " #only search neighbours if mapcell is unoccupied\n", + " if self.map[paths[0][-1]] < 0:\n", + " #to avoid wallhugging paths check for occupied neighbours, if present this path is not desirable\n", + " no_hugging = True\n", + " for (i,j) in [(-1,0),(1,0),(0,-1),(0,1)]:\n", + " next_cell = (paths[0][-1][0]+i,paths[0][-1][1]+j)\n", + " if next_cell in self.map:\n", + " if self.map[next_cell] > 0:\n", + " no_hugging = False\n", + " if no_hugging == True or paths[0][-1] == selfgrid:\n", + " #loop through neighbours\n", + " #give priority to moving forward, to not find paths with more turns than necessary\n", + " if len(paths[0]) > 2:\n", + " forwardchange = (paths[0][-1][0] - paths[0][-2][0],paths[0][-1][1] - paths[0][-2][1])\n", + " ij_list = copy.deepcopy(waylist)\n", + " ij_list.remove(forwardchange)\n", + " ij_list.insert(0,forwardchange)\n", + " for (i,j) in ij_list:\n", + " next_cell = (paths[0][-1][0]+i,paths[0][-1][1]+j)\n", + " #add new path if next_cell is not in an observed path\n", + " if next_cell not in done_cells:\n", + " new_path = copy.copy(paths[0])\n", + " new_path.append(next_cell)\n", + " paths.append(new_path)\n", + " done_cells.append(next_cell)\n", + " #pop out considered paths\n", + " paths.pop(0)\n", + " else:\n", + " #cell is not in map - pop out path \n", + " #unless we arrived at an aim_for which is not in map (debugging - shouldn't happen often)\n", + " if paths[0][-1] == aim_for:\n", + " #finished search if path is found\n", + " target_path = paths[0]\n", + " break\n", + " else:\n", + " paths.pop(0)\n", + " if len(paths) == 0:\n", + " #there is no path to aim_for\n", + " #move backward to get out of a stuck position\n", + " target_path = None\n", + " if aim_for == selfgrid:\n", + " return [\"backward\"], aim_for\n", + " if given_aim_for == True:\n", + " #couldn't find a path to given aim_for\n", + " print(\"Couldn't correct path in mid of relocating\")\n", + " return [\"Do_nothing\"], aim_for\n", + " \n", + " #if one can not find a path try a shorter one before giving up\n", + " if aim_for_index > 6*relocatecounter:\n", + " #restart search with different aim_for\n", + " aim_for_index -= 1\n", + " aim_for = self.priorcells[aim_for_index]\n", + " selfgrid = start_cell\n", + " paths = [[selfgrid]]\n", + " done_cells = [selfgrid]\n", + " forwardchange = waylist[startlooking_dir]\n", + " \n", + " relocatecorrection += 1\n", + " else:\n", + " print(\"No path found in retrace!\")\n", + " target_path = []\n", + " break\n", + " \n", + " \n", + " #left,right,forward,backward order list to follow target path \n", + " orders = []\n", + " #looking dir is 0 to 3 standing for right,up,left,down\n", + " looking_dir = int(((self.angle%(2*np.pi)) *2/np.pi)+0.5)%4\n", + " for i in range(1,len(target_path)-1): \n", + " change = (target_path[i][0] - target_path[i-1][0],target_path[i][1] - target_path[i-1][1])\n", + " #translate change into number 0 to 3 that tells you if you need to go right,up,left or down\n", + " ruld_change = int(-change[0] + 1 + change[1]*(change[1]-1))\n", + " if (ruld_change - looking_dir)%4 == 0:\n", + " orders.append(\"forward\")\n", + " else:\n", + " if (ruld_change - looking_dir)%4 == 1:\n", + " orders.append(\"left\")\n", + " orders.append(\"forward\")\n", + " looking_dir += 1\n", + " if (ruld_change - looking_dir)%4 == 2:\n", + " orders.append(\"backward\")\n", + " if (ruld_change - looking_dir)%4 == 3:\n", + " orders.append(\"right\")\n", + " orders.append(\"forward\")\n", + " looking_dir -= 1\n", + " \n", + " if len(orders) == 0:\n", + " errorcount += 1\n", + " #if there are no orders move backward once to get out of a stuck position\n", + " orders.append(\"backward\")\n", + " else:\n", + " errorcount = 0\n", + " relocatecounter += 1-1/3*relocatecorrection\n", + " \n", + " return orders, aim_for" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Particle Filter functions\n", + "- Propagation\n", + "- Weighing\n", + "- Resampling" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "#moving all particles\n", + "#change is wheel1-,wheel2-voltage time from executed movement\n", + "def move_particles(allparticles,wheelleft,wheelright,delta_t=1):\n", + " wheeldist = 19.5 #distance between left/right wheel in cm\n", + " speed = wheeldist*np.pi/4 #distance a wheel at voltage 1 rotates in one delta_t (speed is set so that turns are 90 degree)\n", + " \n", + " #mean speed:\n", + " mean_speed = delta_t*speed*(wheelright+wheelleft)/2\n", + " #angular velocity\n", + " alpha_speed = (wheelright-wheelleft)*delta_t*speed/wheeldist\n", + " #apply motions to all particles\n", + " for i in range(len(allparticles)):\n", + " allparticles[i].sample_motion(mean_speed, alpha_speed)\n", + "\n", + "#using localmap on particle by first weighing it and than incorporating it\n", + "def weigh_and_map_particles(allparticles,localmap):\n", + " #start by weighing and mapping the bestparticle\n", + " #remember reward here\n", + " global bestparticle\n", + " allparticles[bestparticle].map_weigh(localmap)\n", + " reward = allparticles[bestparticle].incorporate_localmap_withreward(localmap)\n", + " \n", + " #weigh all other particles and uptade their map\n", + " for i in [x for x in range(len(allparticles)) if x!=bestparticle]:\n", + " allparticles[i].map_weigh(localmap)\n", + " allparticles[i].incorporate_localmap(localmap)\n", + " \n", + " #lowering reward since only using new_cells leads to very high rewards\n", + " reward /= 10\n", + " return reward\n", + "\n", + "#resampling particles in accordance to their weights\n", + "def resampling(allparticles):\n", + " new_particles = []\n", + " #normalizing weight \n", + " normweight = 0\n", + " for i in range(len(allparticles)):\n", + " normweight += allparticles[i].weight\n", + " if normweight == 0:\n", + " #normweight is 0, this mean all particles have weight 0\n", + " global isdone\n", + " isdone = True\n", + " rewardchange = -10\n", + " print(\"lost confidence in position - abort\")\n", + " #if this happens often you migh consider adding some new random particles in an attempt to fix it\n", + " return rewardchange\n", + " \n", + " #the resample algorithm\n", + " global bestparticle\n", + " maxweight = 0\n", + " rand = 0\n", + " for i in range(len(allparticles)):\n", + " #draw random between 0,1\n", + " rand = random.random()\n", + " j = 0\n", + " sum_weights = allparticles[0].weight/normweight\n", + " #choose particle to draw\n", + " while rand>sum_weights:\n", + " j += 1\n", + " sum_weights += allparticles[j].weight/normweight\n", + " #add particle and check if is better then current best particle\n", + " new_particles.append(particle(allparticles[j].xpos,allparticles[j].ypos,allparticles[j].angle,allparticles[j].map,allparticles[j].counter,allparticles[j].priorcells))\n", + " if allparticles[j].weight > maxweight:\n", + " bestparticle = i\n", + " maxweight = allparticles[j].weight\n", + " #update the old particles to new ones\n", + " for i in range(len(allparticles)):\n", + " allparticles[i] = new_particles[i]\n", + " #returning a rewardchange, usually 0\n", + " return 0\n", + "\n", + "#calculating uncertainty\n", + "def calc_uncertainty(allparticles):\n", + " #simply calculating the standarddeviation\n", + " #in this case the uncertainty of x,y,phi is simply added together\n", + " #one might consider tracking them individually since phi uncertainty will be largly ignored this way\n", + " average = [0,0,0] #calc average first\n", + " for i in range(len(allparticles)):\n", + " average[0] += allparticles[i].xpos\n", + " average[1] += allparticles[i].ypos\n", + " average[2] += allparticles[i].angle\n", + " average = [x/len(allparticles) for x in average] \n", + " \n", + " variance = [0,0,0] #now calc variance\n", + " for i in range(len(allparticles)):\n", + " variance[0] += (allparticles[i].xpos-average[0])**2\n", + " variance[1] += (allparticles[i].ypos-average[1])**2\n", + " variance[2] += (allparticles[i].angle-average[2])**2\n", + " variance = [x/len(allparticles) for x in variance] \n", + " #transform variance to standard deviation and add all together\n", + " total_std_dev = np.sqrt(variance[0]) + np.sqrt(variance[1]) + np.sqrt(variance[2]) \n", + " \n", + " return total_std_dev\n", + " \n", + "#one particle filter step:\n", + "def particle_filter(allparticles,localmap,wheelleft,wheelright,delta_t=1):\n", + " #propagate\n", + " move_particles(allparticles,wheelleft,wheelright,delta_t)\n", + " #incorporate and map\n", + " reward = weigh_and_map_particles(allparticles,localmap)\n", + "\n", + " \n", + " #resample\n", + " rewchange = resampling(allparticles)\n", + " return reward+rewchange\n", + "\n", + "#plotting globalmap and particles\n", + "def draw_particles(allparticles,figure,axes):\n", + " axes.clear()\n", + " xposes = []\n", + " yposes = []\n", + " for i in range(len(allparticles)):\n", + " xposes.append(allparticles[i].xpos/gridsize)\n", + " yposes.append(allparticles[i].ypos/gridsize)\n", + " #plot particles \n", + " axes.plot(xposes,yposes,'.')\n", + " #plot 'best' map\n", + " globaldim = 150\n", + " globalmap = np.zeros((globaldim,globaldim)) #init map\n", + " globalorigin = -75 #lower left origin of map\n", + " #extract part of the bestparticles globalmap from dictionary\n", + " for i in range(globalorigin,globaldim+globalorigin):\n", + " for j in range(globalorigin,globaldim+globalorigin):\n", + " if (i,j) in allparticles[bestparticle].map:\n", + " globalmap[i-globalorigin][j-globalorigin] = allparticles[bestparticle].map[(i,j)]\n", + " #do the imshow and print bestparticles position \n", + " axes.imshow(globalmap.T, interpolation='nearest', cmap=Greys,origin = 'lower',extent = [globalorigin,globaldim+globalorigin,globalorigin,globaldim+globalorigin], vmin=-3, vmax=3)\n", + " print(bestparticle)\n", + " print(allparticles[bestparticle].xpos,allparticles[bestparticle].ypos,allparticles[bestparticle].angle)\n", + " \n", + " figure.canvas.draw()\n", + " figure.canvas.flush_events()\n", + " #time.sleep(0.1)\n", + " \n", + " \n", + "#plotting localmap\n", + "def draw_localmap(localmap,figure,axes):\n", + " #a simple imshow of the localmap on the figure\n", + " axes.clear()\n", + " axes.imshow(localmap.T, interpolation='nearest',cmap=Greys,origin = 'lower', vmin=-3, vmax=3)\n", + " figure.canvas.draw()\n", + " figure.canvas.flush_events()\n", + " time.sleep(0.1)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "#this check if a particle is allowed to move in a direction\n", + "def movement_allowed(localmap,movementorder):\n", + " L = len(localmap) #needed to find center of localmap where robot resides\n", + " #check that cells before or behind robot are unoccupied to allow movement\n", + " if movementorder == \"forward\":\n", + " if localmap[int(L/2)][int(L/2)] < 0 and localmap[int(L/2)][int(L/2)-1] < 0 and localmap[int(L/2)+1][int(L/2)] < 0 and localmap[int(L/2)+1][int(L/2)-1] < 0:\n", + " return True #movement allowed\n", + " elif movementorder == \"backward\":\n", + " if localmap[int(L/2)-1][int(L/2)] < 0 and localmap[int(L/2)-1][int(L/2)-1] < 0 and localmap[int(L/2)-2][int(L/2)] < 0 and localmap[int(L/2)-2][int(L/2)-1] < 0:\n", + " return True #movement allowed\n", + " else:\n", + " return True #robot wants to turn, always allowed\n", + " return False #movement not allowed, there is an obstacle in the way" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "False True\n" + ] + } + ], + "source": [] + }, + { + "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.6.8" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/Code/alldirparticlefilt.py b/Code/alldirparticlefilt.py new file mode 100644 index 0000000000000000000000000000000000000000..be75817018dd56254ec2d9e123346397157202f4 --- /dev/null +++ b/Code/alldirparticlefilt.py @@ -0,0 +1,243 @@ +#!/usr/bin/env python +# coding: utf-8 + +# In[ ]: + + +#new particle filter for full vision robot + + +# In[ ]: + + + + + +# In[14]: + + +import numpy as np +import math +import copy +import random + + +# In[15]: + + +gridsize = 10 + + +# In[26]: + + +class particle: + def __init__(self,x,y,phi,pmap = {}): + self.xpos = x + self.ypos = y + self.angle = phi + self.map = copy.deepcopy(pmap) + self.weight = 1 + + def incorporate_localmap(self,localmap): + #incorporating given local map into the global map + + #loop over localmap + N = len(localmap) + for i in range(N): + for j in range(N): + #only use localmap entries that are actually measured (!=0) + if localmap[i][j] != 0: + #convert local i,j to global + local_x = (i+1/2)*gridsize - N*gridsize/2 + local_y = (j+1/2)*gridsize - N*gridsize/2 + globalmap_x = self.xpos + local_x * math.cos(self.angle) - local_y * math.sin(self.angle) + globalmap_y = self.ypos + local_x * math.sin(self.angle) + local_y * math.cos(self.angle) + globalgrid = (int(math.floor(globalmap_x/gridsize)),int(math.floor(globalmap_y/gridsize))) + #update global map, if cell never observed before create entry + if globalgrid in self.map: + self.map[globalgrid] += localmap[i][j] + else: + self.map[globalgrid] = localmap[i][j] + + def map_weigh(self,localmap): + #calculate probability of localmap corresponding to global map at particle position + + #find overlapping cells calc m_bar + N = len(localmap) + overlap = [] + m_bar = 0 + for i in range(N): + for j in range(N): + local_x = (i+1/2)*gridsize - N*gridsize/2 + local_y = (j+1/2)*gridsize - N*gridsize/2 + globalmap_x = self.xpos + local_x * math.cos(self.angle) - local_y * math.sin(self.angle) + globalmap_y = self.ypos + local_x * math.sin(self.angle) + local_y * math.cos(self.angle) + globalgrid = (int(math.floor(globalmap_x/gridsize)),int(math.floor(globalmap_y/gridsize))) + if globalgrid in self.map: + m_bar += self.map[globalgrid] + localmap[i][j] + overlap.append(((i,j),globalgrid)) + #calculate correlation between the two maps (only if there is an overlap) + if len(overlap) > 0: + m_bar = m_bar/(2*len(overlap)) + + sum_1 = 0 + sum_2 = 0 + sum_3 = 0 + for ((i,j),(k,l)) in overlap: + sum_1 += (self.map[(k,l)]-m_bar)*(localmap[i][j]-m_bar) + sum_2 += (self.map[(k,l)]-m_bar)**2 + sum_3 += (localmap[i][j]-m_bar)**2 + correlation = sum_1/math.sqrt(sum_2*sum_3) + self.weight *= max(0,correlation) + + def sample_motion(self, velocity, angular_velocity): + #sample motion for a velocity motion model + #delta_t needs to be normalized to 1! + #see probabilistic robotics page 124 + + #mean values for displacement + delta_rot1 = math.atan2(new_mean[1]-self.ypos,new_mean[0]-self.xpos) - self.angle + delta_trans = np.sqrt(((self.xpos-new_mean[0])**2)+((self.ypos-new_mean[1])**2)) + if delta_trans == 0: + delta_rot1 = 0 + delta_rot2 = new_mean[2] - self.angle - delta_rot1 + if delta_rot2 > PI: + delta_rot2 -= 2*PI + #error parameters + alpha_1 = 0.0001 #influence of velocity on velocity uncertainty + alpha_2 = 0.0001 #influence of angular velocity on velocity uncertainty + alpha_3 = 0.0001 #influence of velocity on angular velocity uncertainty + alpha_4 = 0.0001 #influence of angular velocity on angular velocity uncertainty + #an additional angle will be added to account for non circular motion + alpha_5 = 0.000001 #influence of velocity on additional angle uncertainty + alpha_6 = 0.000001 #influence of angular velocity on additional angle uncertainty + + #sample with gaussians + sample_vel = random.gauss(velocity=locity, np.sqrt(alpha_1*velocity**2+alpha_2*angular_velocity**2)) + sample_angvel = random.gauss(angular_velocity, np.sqrt(alpha_3*velocity**2 + alpha_4 * angular_velocity**2)) + sample_addangle = random.gauss(0, np.sqrt(alpha_5*velocity**2+alpha_6*angular_velocity**2)) + + if angular_velocity != 0 and abs(sample_angvel) >= 0.01: + #apply motion + self.xpos += -sample_vel/sample_angvel*math.sin(self.angle) + sample_vel/sample_angvel*math.sin(self.angle*sample_angvel) + self.ypos += sample_vel/sample_angvel*math.cos(self.angle) - sample_vel/sample_angvel*math.cos(self.angle*sample_angvel) + self.angle += sample_angvel+sample_addangle + else: + #motion for very small angular velocity, to avoid division by near 0 values + self.xpos += sample_vel*math.cos(self.angle) + self.ypos += sample_vel*math.sin(self.angle) + self.angle += sample_angvel+sample_addangle + + +# In[ ]: + + + + + +# ### Particle Filter functions +# - Propagation +# - Weighing +# - Resampling + +# In[ ]: + + +#moving all particles +#change is wheel1-,wheel2-voltage time from executed movement +def move_particles(allparticles,wheelleft,wheelright,delta_t=1): + wheeldist = 18 #distance between left/right wheel in cm + speed = 10 #distance a wheel at max voltage 1 rotates in one delta_t + + #mean speed: + mean_speed = delta_t*speed*(wheelright+wheelleft)/2 + #angular velocity + alpha_speed = (wheelright-wheelleft)*delta_t*speed/wheeldist + for i in range(len(allparticles)): + allparticles[i].sample_motion(mean_speed, alpha_speed) + +#using localmap on particle by first weighing it and than incorporating it +def weigh_and_map_particles(allparticles,localmap): + for i in range(len(allparticles)): + allparticles[i].map_weigh(localmap) + allparticles[i].incorporate_localmap(localmap) + +#resampling particles in accordance to their weights +def resampling(allparticles): + new_particles = [] + #normalizing weight + normweight = 0 + for i in range(len(allparticles)): + normweight += allparticles[i] + + rand = 0 + for i in range(len(allparticles)): + #draw random between 0,1 + rand = random.random() + j = 0 + sum_weights = allparticles[0].weight/normweight + while rand>sum_weights: + j += 1 + sum_weights += allparticles[j].weight/normweight + new_particles.append(particle(allparticles[j].xpos,allparticles[j].ypos,allparticles[j].angle,allparticles[j].map))) + + + return new_particles + +#one particle filter step: +def particle_filter(allparticles,localmap,wheelleft,wheelright,delta_t=1): + #propagate + move_particles(allparticles,wheelleft,wheelright,delta_t) + #incorporate and map + weigh_and_map_particles(allparticles,localmap) + #esampled + newparticles = resampling(allparticles) + return newparticles + + +# In[ ]: + + + + + +# In[27]: + + +#a = particle(0,0,0) +#localmap = np.ones((10,10)) + + +# In[28]: + + +#a.incorporate_localmap(localmap) +#print(a.map) + + +# In[7]: + + +#a = [] +#a.append([(0,0),(1,1)]) +# +#a.append([(0,0),(1,2)]) +# +#a.append([(0,0),(4,1)]) +#print(a) +#for ((i,j),(k,l)) in a: +# print(i,j,k,l) + + +# In[3]: + + + + + +# In[ ]: + + + + diff --git a/Code/maps.ipynb b/Code/maps.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..a498826aba46fc840f64ab17a41e9d8d80670167 --- /dev/null +++ b/Code/maps.ipynb @@ -0,0 +1,551 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "def box():\n", + " #a simple quadratic box\n", + " realglobalmap = {}\n", + " for i in range(1,39):\n", + " realglobalmap[(2,i)] = 1\n", + " realglobalmap[(1,i)] = 1\n", + " realglobalmap[(40-3,i)] = 1\n", + " realglobalmap[(40-2,i)] = 1\n", + " realglobalmap[(i,2)] = 1\n", + " realglobalmap[(i,1)] = 1\n", + " realglobalmap[(i,40-3)] = 1\n", + " realglobalmap[(i,40-2)] = 1\n", + " \n", + " return realglobalmap" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Using matplotlib backend: Qt5Agg\n" + ] + } + ], + "source": [ + "def corridor():\n", + " #long corridor map\n", + " realglobalmap = {}\n", + " for j in range(-40,40):\n", + " realglobalmap[(j,7)] = 1\n", + " realglobalmap[(j,-7)] = 1\n", + " for k in range(-7,7):\n", + " realglobalmap[(-40,k)] = 1\n", + " realglobalmap[(40,k)] = 1\n", + " return realglobalmap" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def custom_map01():\n", + " #some custom map\n", + " realglobalmap = {}\n", + " for i in range(-7,50):\n", + " realglobalmap[(-7,i)] = 1\n", + " realglobalmap[(49,i)] = 1\n", + " realglobalmap[(i,-7)] = 1\n", + " realglobalmap[(i,49)] = 1\n", + " for k in range(-7,36):\n", + " realglobalmap[(k,7)] = 1\n", + " for k in range(20,36):\n", + " realglobalmap[(20,k)] = 1\n", + " for k in range(10,36):\n", + " realglobalmap[(k,35)] = 1\n", + " realglobalmap[(k,20)] = 1\n", + " return realglobalmap" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Random Map Generator\n", + "using several map blocks (size 15x15) to build a random map\n", + "\n", + "used blocks are:\n", + "* straight\n", + "* curves\n", + "* 4way intersection\n", + "* 3way intersection\n", + "* dead end" + ] + }, + { + "cell_type": "code", + "execution_count": 85, + "metadata": {}, + "outputs": [], + "source": [ + "blocksize = 15 #size of a block must be uneven! to ensure a center attachment grid" + ] + }, + { + "cell_type": "code", + "execution_count": 135, + "metadata": {}, + "outputs": [], + "source": [ + "#function attaches a blocksize block to the globalmap given attachment_grid, direction\n", + "#negative directions (such as left and down) are mirrored so that this cases do not need to be considered when building the blocks\n", + "def attach_block(attachment_grid, direction, globalmap, block, block_attachments):\n", + " if direction == 0: #attach to the right (positive x-dir)\n", + " for i in range(blocksize):\n", + " for j in range(blocksize):\n", + " if block[i][j] == 1: #globalmap shall only store walls i.e. ones\n", + " globalmap[(i+attachment_grid[0],j+attachment_grid[1]-int(blocksize/2))] = block[i][j]\n", + " #converting block attachments\n", + " for k in range(len(block_attachments)):\n", + " block_attachments[k][0] = (block_attachments[k][0][0]+attachment_grid[0],block_attachments[k][0][1]+attachment_grid[1]-int(blocksize/2))\n", + " elif direction == 2: #attach to the left (negative x-dir), this also mirrors x-axis\n", + " for i in range(blocksize):\n", + " for j in range(blocksize): \n", + " if block[i][j] == 1: #globalmap shall only store walls i.e. ones\n", + " globalmap[(-i+attachment_grid[0],j+attachment_grid[1]-int(blocksize/2))] = block[i][j]\n", + " #converting block attachments\n", + " for k in range(len(block_attachments)):\n", + " block_attachments[k][0] = (-block_attachments[k][0][0]+attachment_grid[0],block_attachments[k][0][1]+attachment_grid[1]-int(blocksize/2))\n", + " #convert attachments to the right to left ones due to mirroring\n", + " if block_attachments[k][1] == 0:\n", + " block_attachments[k][1] = 2\n", + " elif direction == 1: #attach to above (positive y-dir)\n", + " for i in range(blocksize):\n", + " for j in range(blocksize):\n", + " if block[i][j] == 1: #globalmap shall only store walls i.e. ones\n", + " globalmap[(i+attachment_grid[0]-int(blocksize/2),j+attachment_grid[1])] = block[i][j]\n", + " #converting block attachments\n", + " for k in range(len(block_attachments)):\n", + " block_attachments[k][0] = (block_attachments[k][0][0]+attachment_grid[0]-int(blocksize/2),block_attachments[k][0][1]+attachment_grid[1])\n", + " \n", + " elif direction == 3: #attach to below (negative y-dir), this also mirrors y-axis\n", + " for i in range(blocksize):\n", + " for j in range(blocksize):\n", + " if block[i][j] == 1: #globalmap shall only store walls i.e. ones\n", + " globalmap[(i+attachment_grid[0]-int(blocksize/2),-j+attachment_grid[1])] = block[i][j]\n", + " #converting block attachments\n", + " for k in range(len(block_attachments)):\n", + " block_attachments[k][0] = (block_attachments[k][0][0]+attachment_grid[0]-int(blocksize/2),-block_attachments[k][0][1]+attachment_grid[1])\n", + " #convert attachments to the top to bottom ones due to mirroring\n", + " if block_attachments[k][1] == 1:\n", + " block_attachments[k][1] = 3" + ] + }, + { + "cell_type": "code", + "execution_count": 87, + "metadata": {}, + "outputs": [], + "source": [ + "#returns a 15x15 map block consisting of a straight corridor in direction right,up,left,down = 0,1,2,3\n", + "def straight_block(attachment_grid, direction, globalmap):\n", + " #define block\n", + " block = np.ones([blocksize,blocksize])\n", + " block_attachments = [] #block attachments are the places where new blocks may be added later\n", + " #corridor direction left to right and vice versa \n", + " if direction == 0 or direction == 2:\n", + " for i in range(blocksize):\n", + " for j in range(int(blocksize/2-3),int(blocksize/2+4)):\n", + " block[i][j] = 0\n", + " #add block attachments\n", + " #you only need attachment on the right since attach_block mirrors\n", + " block_attachments.append([(blocksize,int(blocksize/2)),0])\n", + " #corridor direction up to down and vice versa \n", + " else:\n", + " for j in range(blocksize):\n", + " for i in range(int(blocksize/2-3),int(blocksize/2+4)):\n", + " block[i][j] = 0\n", + " #add block attachments\n", + " #you only need attachment on the top since attach_block mirrors\n", + " block_attachments.append([(int(blocksize/2),blocksize),1])\n", + " #attach block to map\n", + " attach_block(attachment_grid, direction, globalmap, block, block_attachments)\n", + " #return new attachment positions\n", + " return block_attachments" + ] + }, + { + "cell_type": "code", + "execution_count": 88, + "metadata": {}, + "outputs": [], + "source": [ + "#a curve\n", + "def curved_block(attachment_grid, startdirection, enddirection, globalmap):\n", + " #check if this even is a curve and not a straight corridor\n", + " if (startdirection-enddirection)%2 == 0:\n", + " print(\"Error in Map generating - this is not a curve\")\n", + " return\n", + " \n", + " block = np.ones([blocksize,blocksize]) #define block\n", + " block_attachments = [] #block attachments are the places where new blocks may be added later\n", + " \n", + " #starting left or right uses the same block since attach_block() is also mirroring based on attachdirection\n", + " if startdirection == 0 or startdirection == 2:\n", + " for i in range(int(blocksize/2)+4): #corridor until middle of cell\n", + " for j in range(int(blocksize/2)-3,int(blocksize/2)+4):\n", + " block[i][j] = 0\n", + " \n", + " if enddirection == 1: #second corridor going up\n", + " for j in range(int(blocksize/2)-3,blocksize):\n", + " for i in range(int(blocksize/2)-3,int(blocksize/2)+4):\n", + " block[i][j] = 0 \n", + " block_attachments.append([(int(blocksize/2),15),enddirection]) #attachment on the top\n", + " if enddirection == 3: #second corridor going down\n", + " for j in range(int(blocksize/2)+4):\n", + " for i in range(int(blocksize/2)-3,int(blocksize/2)+4):\n", + " block[i][j] = 0\n", + " block_attachments.append([(int(blocksize/2),-1),enddirection]) #attachment on the bottom\n", + " #starting up or down uses the same block since attach_block() is also mirroring based on attachdirection\n", + " elif startdirection == 1 or startdirection == 3:\n", + " for j in range(int(blocksize/2)+4): #corridor until middle of cell\n", + " for i in range(int(blocksize/2)-3,int(blocksize/2)+4):\n", + " block[i][j] = 0\n", + " if enddirection == 2: #second corridor going left\n", + " for i in range(int(blocksize/2)+4):\n", + " for j in range(int(blocksize/2)-3,int(blocksize/2)+4):\n", + " block[i][j] = 0 \n", + " block_attachments.append([(-1,int(blocksize/2)),enddirection]) #attachment on the left\n", + " if enddirection == 0: #second corridor going right\n", + " for i in range(int(blocksize/2)-3,blocksize):\n", + " for j in range(int(blocksize/2)-3,int(blocksize/2)+4):\n", + " block[i][j] = 0 \n", + " block_attachments.append([(blocksize,int(blocksize/2)),enddirection]) #attachment on the right\n", + " \n", + " attach_block(attachment_grid, startdirection, globalmap, block, block_attachments)\n", + " #return new attachment positions\n", + " return block_attachments" + ] + }, + { + "cell_type": "code", + "execution_count": 89, + "metadata": {}, + "outputs": [], + "source": [ + "# a simple 4way intersection open in all directions\n", + "def intersection_4way(attachment_grid, direction, globalmap):\n", + " block = np.ones([blocksize,blocksize]) #define block\n", + " block_attachments = [] #block attachments are the places where new blocks may be added later\n", + " \n", + " #for simplicities sake we are simply overlapping two corridors from left to right and top to bottom\n", + " for i in range(blocksize):\n", + " for j in range(int(blocksize/2-3),int(blocksize/2+4)):\n", + " block[i][j] = 0\n", + " \n", + " for j in range(blocksize):\n", + " for i in range(int(blocksize/2-3),int(blocksize/2+4)):\n", + " block[i][j] = 0\n", + " \n", + " if direction == 1 or direction == 3: #starting in top or bottom\n", + " block_attachments.append([(-1,int(blocksize/2)),2]) #left\n", + " block_attachments.append([(blocksize,int(blocksize/2)),0]) #right\n", + " block_attachments.append([(int(blocksize/2),blocksize),1]) #top this is automatically mirrored to bottom in case of direction == 2\n", + " elif direction == 0 or direction == 2: #starting in right or left\n", + " block_attachments.append([(blocksize,int(blocksize/2)),0]) #right automatically mirrored to left if direction == 2\n", + " block_attachments.append([(int(blocksize/2),blocksize),1]) #top\n", + " block_attachments.append([(int(blocksize/2),-1),3]) #bottom\n", + " \n", + " attach_block(attachment_grid, direction, globalmap, block, block_attachments)\n", + " return block_attachments" + ] + }, + { + "cell_type": "code", + "execution_count": 90, + "metadata": {}, + "outputs": [], + "source": [ + "#a 3way intersection open in all but one directions\n", + "#in contrast to the curve this becomes more complex due to mirroring\n", + "def intersection_3way(attachment_grid, direction, omitted_direction,globalmap):\n", + " #you can't omit the direction you are starting at\n", + " if omitted_direction == (direction-2)%4 or omitted_direction == (direction+2)%4:\n", + " print(\"Error in Map generating - 3way intersection is trying to omit starting direction\")\n", + " return\n", + " \n", + " block = np.ones([blocksize,blocksize]) #define block\n", + " block_attachments = [] #block attachments are the places where new blocks may be added later\n", + " if direction == 0 or direction == 2: #start right/left\n", + " if omitted_direction == 1 or omitted_direction == 3: #omit up/down\n", + " #left-right corridor\n", + " for i in range(blocksize):\n", + " for j in range(int(blocksize/2-3),int(blocksize/2+4)):\n", + " block[i][j] = 0\n", + " block_attachments.append([(blocksize,int(blocksize/2)),0]) #attachment right, will be mirrored if direction==2\n", + " \n", + " if omitted_direction == 1: #omit up\n", + " #half corridor to bottom\n", + " for j in range(int(blocksize/2)+4):\n", + " for i in range(int(blocksize/2)-3,int(blocksize/2)+4):\n", + " block[i][j] = 0\n", + " block_attachments.append([(int(blocksize/2),-1),3]) #attachment on the bottom\n", + " if omitted_direction == 3: #omit down\n", + " #half corridor to top\n", + " for j in range(int(blocksize/2)-3,blocksize):\n", + " for i in range(int(blocksize/2)-3,int(blocksize/2)+4):\n", + " block[i][j] = 0 \n", + " block_attachments.append([(int(blocksize/2),15),1]) #attachment on the top\n", + " \n", + " else: #you only need to consider corridor to right omitting right, other case is mirrored\n", + " #full corridor top-bottom\n", + " for j in range(blocksize):\n", + " for i in range(int(blocksize/2-3),int(blocksize/2+4)):\n", + " block[i][j] = 0\n", + " block_attachments.append([(int(blocksize/2),blocksize),1]) #attachment top\n", + " block_attachments.append([(int(blocksize/2),-1),3]) #attachment bottom\n", + " \n", + " #half corridor from the left\n", + " for i in range(int(blocksize/2)+4): #corridor until middle of cell\n", + " for j in range(int(blocksize/2)-3,int(blocksize/2)+4):\n", + " block[i][j] = 0\n", + " if direction == 1 or direction == 3: #start top/bottom\n", + " if omitted_direction == 0 or omitted_direction == 2: #omit right/left\n", + " #full corridor top-bottom\n", + " for j in range(blocksize):\n", + " for i in range(int(blocksize/2-3),int(blocksize/2+4)):\n", + " block[i][j] = 0\n", + " block_attachments.append([(int(blocksize/2),blocksize),1]) #attachment top, mirrored in case direction==3\n", + " \n", + " if omitted_direction == 0: #omit right\n", + " #half corridor to the left\n", + " for i in range(int(blocksize/2)+4):\n", + " for j in range(int(blocksize/2)-3,int(blocksize/2)+4):\n", + " block[i][j] = 0 \n", + " block_attachments.append([(-1,int(blocksize/2)),2]) #attachment on the left\n", + " if omitted_direction == 2: #omit left\n", + " #half corridor to the right\n", + " for i in range(int(blocksize/2)-3,blocksize):\n", + " for j in range(int(blocksize/2)-3,int(blocksize/2)+4):\n", + " block[i][j] = 0 \n", + " block_attachments.append([(blocksize,int(blocksize/2)),0]) #attachment on the right\n", + " \n", + " else: #you only need to consider corridor to top omitting top, other case is mirrored\n", + " #full corridor left-right\n", + " for i in range(blocksize):\n", + " for j in range(int(blocksize/2-3),int(blocksize/2+4)):\n", + " block[i][j] = 0\n", + " block_attachments.append([(-1,int(blocksize/2)),2]) #attachment left\n", + " block_attachments.append([(blocksize,int(blocksize/2)),0]) #attachment right\n", + " #half corridor from the bottom\n", + " for j in range(int(blocksize/2)+4): #corridor until middle of cell\n", + " for i in range(int(blocksize/2)-3,int(blocksize/2)+4):\n", + " block[i][j] = 0\n", + " \n", + " attach_block(attachment_grid, direction, globalmap, block, block_attachments)\n", + " return block_attachments" + ] + }, + { + "cell_type": "code", + "execution_count": 145, + "metadata": {}, + "outputs": [], + "source": [ + "#completely occupied block, a solid dead end\n", + "def dead_end(attachment_grid, direction, globalmap):\n", + " block = np.ones([blocksize,blocksize])\n", + " block_attachments = []\n", + " attach_block(attachment_grid, direction, globalmap, block, block_attachments)\n", + " \n", + " return block_attachments" + ] + }, + { + "cell_type": "code", + "execution_count": 146, + "metadata": {}, + "outputs": [], + "source": [ + "def generate_random_map(maxcounter = 20):\n", + " realmap = {}\n", + " attachments = [[(0,0),0],[(-1,0),2]]\n", + " \n", + " counter = 0\n", + " more = True\n", + " while more == True:\n", + " counter += 1\n", + " \n", + " blockchoice = random.randint(0,3) #random decision what block to add\n", + " #print(blockchoice)\n", + " if blockchoice == 0: #straight corridor\n", + " new_attachments = straight_block(attachments[0][0],attachments[0][1],realmap)\n", + " if blockchoice == 1: #curve\n", + " curvechange = 2*random.randint(0,1) + 1 #choose curve dir\n", + " new_attachments = curved_block(attachments[0][0],attachments[0][1],(attachments[0][1]+curvechange)%4,realmap)\n", + " if blockchoice == 2: #4way intersection\n", + " new_attachments = intersection_4way(attachments[0][0],attachments[0][1],realmap)\n", + " if blockchoice == 3: #3way intersection\n", + " omit = ((random.randint(3,5)) + attachments[0][1])%4 #choose omitted dir\n", + " new_attachments = intersection_3way(attachments[0][0],attachments[0][1],omit,realmap)\n", + " #print(new_attachments)\n", + " attachments.pop(0)\n", + " #print(attachments)\n", + " #add new attachments to attachments\n", + " for k in range(len(new_attachments)):\n", + " #for each new attachment check if the corresponding counter attachment already exists\n", + " #if yes - you have completed a loop remove the counter from attachments, don't add new attachment\n", + " #if no - check if there is a wall at the attachment position, if not you can add the new attachment\n", + " if new_attachments[k][1] == 0:\n", + " if [(new_attachments[k][0][0]-1,new_attachments[k][0][1]),2] not in attachments: #counter attachment?\n", + " if (new_attachments[k][0][0],new_attachments[k][0][1]) not in realmap: #wall in map?\n", + " attachments.append(new_attachments[k])\n", + " else:\n", + " attachments.remove([(new_attachments[k][0][0]-1,new_attachments[k][0][1]),2]) #remove counter \n", + " if new_attachments[k][1] == 1:\n", + " if [(new_attachments[k][0][0],new_attachments[k][0][1]-1),3] not in attachments: #counter attachment?\n", + " if (new_attachments[k][0][0],new_attachments[k][0][1]) not in realmap: #wall in map?\n", + " attachments.append(new_attachments[k])\n", + " else:\n", + " attachments.remove([(new_attachments[k][0][0],new_attachments[k][0][1]-1),3]) #remove counter \n", + " if new_attachments[k][1] == 2:\n", + " if [(new_attachments[k][0][0]+1,new_attachments[k][0][1]),0] not in attachments: #counter attachment?\n", + " if (new_attachments[k][0][0],new_attachments[k][0][1]) not in realmap: #wall in map?\n", + " attachments.append(new_attachments[k])\n", + " else:\n", + " attachments.remove([(new_attachments[k][0][0]+1,new_attachments[k][0][1]),0]) #remove counter \n", + " if new_attachments[k][1] == 3:\n", + " if [(new_attachments[k][0][0],new_attachments[k][0][1]+1),1] not in attachments: #counter attachment?\n", + " if (new_attachments[k][0][0],new_attachments[k][0][1]) not in realmap: #wall in map?\n", + " attachments.append(new_attachments[k])\n", + " else:\n", + " attachments.remove([(new_attachments[k][0][0],new_attachments[k][0][1]+1),1]) #remove counter \n", + " \n", + " #check the attachments, some may now be blocked off, if so remove \n", + " to_pop = []\n", + " for k in range(len(attachments)):\n", + " if (attachments[k][0][0],attachments[k][0][1]) in realmap: #check if attachment path is blocked\n", + " to_pop.append(k)\n", + " for k in range(len(to_pop)):\n", + " attachments.pop(to_pop[k])\n", + " \n", + " if len(attachments) == 0 or counter >= maxcounter:\n", + " more = False\n", + " #fill open end with dead ends\n", + " for i in range(len(attachments)):\n", + " new_attachments = dead_end(attachments[i][0],attachments[i][1],realmap)\n", + " \n", + " return realmap" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "import random\n", + "realglobalmap = generate_random_map(maxcounter = 20)\n", + "#print()\n", + "#print(realglobalmap)\n", + "L = 100\n", + "test = np.zeros([L,L])\n", + "for i in range(L):\n", + " for j in range(L):\n", + " if (i-int(L/2),j-int(L/2)) in realglobalmap:\n", + " test[i][j] = realglobalmap[(i-int(L/2),j-int(L/2))]\n", + "from matplotlib import pyplot as plt\n", + "plt.imshow(test.T,origin = 'lower',extent=[-int(L/2),int(L/2),-int(L/2),int(L/2)])" + ] + }, + { + "cell_type": "code", + "execution_count": 138, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{(0, -7): 1.0, (0, -6): 1.0, (0, -5): 1.0, (0, -4): 1.0, (0, 4): 1.0, (0, 5): 1.0, (0, 6): 1.0, (0, 7): 1.0, (1, -7): 1.0, (1, -6): 1.0, (1, -5): 1.0, (1, -4): 1.0, (1, 4): 1.0, (1, 5): 1.0, (1, 6): 1.0, (1, 7): 1.0, (2, -7): 1.0, (2, -6): 1.0, (2, -5): 1.0, (2, -4): 1.0, (2, 4): 1.0, (2, 5): 1.0, (2, 6): 1.0, (2, 7): 1.0, (3, -7): 1.0, (3, -6): 1.0, (3, -5): 1.0, (3, -4): 1.0, (3, 4): 1.0, (3, 5): 1.0, (3, 6): 1.0, (3, 7): 1.0, (4, -7): 1.0, (4, -6): 1.0, (4, -5): 1.0, (4, -4): 1.0, (4, 4): 1.0, (4, 5): 1.0, (4, 6): 1.0, (4, 7): 1.0, (5, -7): 1.0, (5, -6): 1.0, (5, -5): 1.0, (5, -4): 1.0, (5, 4): 1.0, (5, 5): 1.0, (5, 6): 1.0, (5, 7): 1.0, (6, -7): 1.0, (6, -6): 1.0, (6, -5): 1.0, (6, -4): 1.0, (6, 4): 1.0, (6, 5): 1.0, (6, 6): 1.0, (6, 7): 1.0, (7, -7): 1.0, (7, -6): 1.0, (7, -5): 1.0, (7, -4): 1.0, (7, 4): 1.0, (7, 5): 1.0, (7, 6): 1.0, (7, 7): 1.0, (8, -7): 1.0, (8, -6): 1.0, (8, -5): 1.0, (8, -4): 1.0, (8, 4): 1.0, (8, 5): 1.0, (8, 6): 1.0, (8, 7): 1.0, (9, -7): 1.0, (9, -6): 1.0, (9, -5): 1.0, (9, -4): 1.0, (9, 4): 1.0, (9, 5): 1.0, (9, 6): 1.0, (9, 7): 1.0, (10, -7): 1.0, (10, -6): 1.0, (10, -5): 1.0, (10, -4): 1.0, (10, 4): 1.0, (10, 5): 1.0, (10, 6): 1.0, (10, 7): 1.0, (11, -7): 1.0, (11, -6): 1.0, (11, -5): 1.0, (11, -4): 1.0, (11, 4): 1.0, (11, 5): 1.0, (11, 6): 1.0, (11, 7): 1.0, (12, -7): 1.0, (12, -6): 1.0, (12, -5): 1.0, (12, -4): 1.0, (12, 4): 1.0, (12, 5): 1.0, (12, 6): 1.0, (12, 7): 1.0, (13, -7): 1.0, (13, -6): 1.0, (13, -5): 1.0, (13, -4): 1.0, (13, 4): 1.0, (13, 5): 1.0, (13, 6): 1.0, (13, 7): 1.0, (14, -7): 1.0, (14, -6): 1.0, (14, -5): 1.0, (14, -4): 1.0, (14, 4): 1.0, (14, 5): 1.0, (14, 6): 1.0, (14, 7): 1.0, (15, -7): 1.0, (15, -6): 1.0, (15, -5): 1.0, (15, -4): 1.0, (15, 4): 1.0, (15, 5): 1.0, (15, 6): 1.0, (15, 7): 1.0, (16, -7): 1.0, (16, -6): 1.0, (16, -5): 1.0, (16, -4): 1.0, (16, 4): 1.0, (16, 5): 1.0, (16, 6): 1.0, (16, 7): 1.0, (17, -7): 1.0, (17, -6): 1.0, (17, -5): 1.0, (17, -4): 1.0, (17, 4): 1.0, (17, 5): 1.0, (17, 6): 1.0, (17, 7): 1.0, (18, -7): 1.0, (18, -6): 1.0, (18, -5): 1.0, (18, -4): 1.0, (18, 4): 1.0, (18, 5): 1.0, (18, 6): 1.0, (18, 7): 1.0, (19, -7): 1.0, (19, -6): 1.0, (19, -5): 1.0, (19, -4): 1.0, (20, -7): 1.0, (20, -6): 1.0, (20, -5): 1.0, (20, -4): 1.0, (21, -7): 1.0, (21, -6): 1.0, (21, -5): 1.0, (21, -4): 1.0, (22, -7): 1.0, (22, -6): 1.0, (22, -5): 1.0, (22, -4): 1.0, (23, -7): 1.0, (23, -6): 1.0, (23, -5): 1.0, (23, -4): 1.0, (24, -7): 1.0, (24, -6): 1.0, (24, -5): 1.0, (24, -4): 1.0, (25, -7): 1.0, (25, -6): 1.0, (25, -5): 1.0, (25, -4): 1.0, (26, -7): 1.0, (26, -6): 1.0, (26, -5): 1.0, (26, -4): 1.0, (26, -3): 1.0, (26, -2): 1.0, (26, -1): 1.0, (26, 0): 1.0, (26, 1): 1.0, (26, 2): 1.0, (26, 3): 1.0, (26, 4): 1.0, (26, 5): 1.0, (26, 6): 1.0, (26, 7): 1.0, (27, -7): 1.0, (27, -6): 1.0, (27, -5): 1.0, (27, -4): 1.0, (27, -3): 1.0, (27, -2): 1.0, (27, -1): 1.0, (27, 0): 1.0, (27, 1): 1.0, (27, 2): 1.0, (27, 3): 1.0, (27, 4): 1.0, (27, 5): 1.0, (27, 6): 1.0, (27, 7): 1.0, (28, -7): 1.0, (28, -6): 1.0, (28, -5): 1.0, (28, -4): 1.0, (28, -3): 1.0, (28, -2): 1.0, (28, -1): 1.0, (28, 0): 1.0, (28, 1): 1.0, (28, 2): 1.0, (28, 3): 1.0, (28, 4): 1.0, (28, 5): 1.0, (28, 6): 1.0, (28, 7): 1.0, (29, -7): 1.0, (29, -6): 1.0, (29, -5): 1.0, (29, -4): 1.0, (29, -3): 1.0, (29, -2): 1.0, (29, -1): 1.0, (29, 0): 1.0, (29, 1): 1.0, (29, 2): 1.0, (29, 3): 1.0, (29, 4): 1.0, (29, 5): 1.0, (29, 6): 1.0, (29, 7): 1.0, (15, 8): 1.0, (15, 9): 1.0, (15, 10): 1.0, (15, 11): 1.0, (15, 19): 1.0, (15, 20): 1.0, (15, 21): 1.0, (15, 22): 1.0, (16, 8): 1.0, (16, 9): 1.0, (16, 10): 1.0, (16, 11): 1.0, (16, 19): 1.0, (16, 20): 1.0, (16, 21): 1.0, (16, 22): 1.0, (17, 8): 1.0, (17, 9): 1.0, (17, 10): 1.0, (17, 11): 1.0, (17, 19): 1.0, (17, 20): 1.0, (17, 21): 1.0, (17, 22): 1.0, (18, 8): 1.0, (18, 9): 1.0, (18, 10): 1.0, (18, 11): 1.0, (18, 19): 1.0, (18, 20): 1.0, (18, 21): 1.0, (18, 22): 1.0, (19, 19): 1.0, (19, 20): 1.0, (19, 21): 1.0, (19, 22): 1.0, (20, 19): 1.0, (20, 20): 1.0, (20, 21): 1.0, (20, 22): 1.0, (21, 19): 1.0, (21, 20): 1.0, (21, 21): 1.0, (21, 22): 1.0, (22, 19): 1.0, (22, 20): 1.0, (22, 21): 1.0, (22, 22): 1.0, (23, 19): 1.0, (23, 20): 1.0, (23, 21): 1.0, (23, 22): 1.0, (24, 19): 1.0, (24, 20): 1.0, (24, 21): 1.0, (24, 22): 1.0, (25, 19): 1.0, (25, 20): 1.0, (25, 21): 1.0, (25, 22): 1.0, (26, 8): 1.0, (26, 9): 1.0, (26, 10): 1.0, (26, 11): 1.0, (26, 12): 1.0, (26, 13): 1.0, (26, 14): 1.0, (26, 15): 1.0, (26, 16): 1.0, (26, 17): 1.0, (26, 18): 1.0, (26, 19): 1.0, (26, 20): 1.0, (26, 21): 1.0, (26, 22): 1.0, (27, 8): 1.0, (27, 9): 1.0, (27, 10): 1.0, (27, 11): 1.0, (27, 12): 1.0, (27, 13): 1.0, (27, 14): 1.0, (27, 15): 1.0, (27, 16): 1.0, (27, 17): 1.0, (27, 18): 1.0, (27, 19): 1.0, (27, 20): 1.0, (27, 21): 1.0, (27, 22): 1.0, (28, 8): 1.0, (28, 9): 1.0, (28, 10): 1.0, (28, 11): 1.0, (28, 12): 1.0, (28, 13): 1.0, (28, 14): 1.0, (28, 15): 1.0, (28, 16): 1.0, (28, 17): 1.0, (28, 18): 1.0, (28, 19): 1.0, (28, 20): 1.0, (28, 21): 1.0, (28, 22): 1.0, (29, 8): 1.0, (29, 9): 1.0, (29, 10): 1.0, (29, 11): 1.0, (29, 12): 1.0, (29, 13): 1.0, (29, 14): 1.0, (29, 15): 1.0, (29, 16): 1.0, (29, 17): 1.0, (29, 18): 1.0, (29, 19): 1.0, (29, 20): 1.0, (29, 21): 1.0, (29, 22): 1.0, (14, 8): 1.0, (14, 9): 1.0, (14, 10): 1.0, (14, 11): 1.0, (14, 19): 1.0, (14, 20): 1.0, (14, 21): 1.0, (14, 22): 1.0, (13, 8): 1.0, (13, 9): 1.0, (13, 10): 1.0, (13, 11): 1.0, (13, 19): 1.0, (13, 20): 1.0, (13, 21): 1.0, (13, 22): 1.0, (12, 8): 1.0, (12, 9): 1.0, (12, 10): 1.0, (12, 11): 1.0, (12, 19): 1.0, (12, 20): 1.0, (12, 21): 1.0, (12, 22): 1.0, (11, 8): 1.0, (11, 9): 1.0, (11, 10): 1.0, (11, 11): 1.0, (11, 19): 1.0, (11, 20): 1.0, (11, 21): 1.0, (11, 22): 1.0, (10, 8): 1.0, (10, 9): 1.0, (10, 10): 1.0, (10, 11): 1.0, (9, 8): 1.0, (9, 9): 1.0, (9, 10): 1.0, (9, 11): 1.0, (8, 8): 1.0, (8, 9): 1.0, (8, 10): 1.0, (8, 11): 1.0, (7, 8): 1.0, (7, 9): 1.0, (7, 10): 1.0, (7, 11): 1.0, (6, 8): 1.0, (6, 9): 1.0, (6, 10): 1.0, (6, 11): 1.0, (5, 8): 1.0, (5, 9): 1.0, (5, 10): 1.0, (5, 11): 1.0, (4, 8): 1.0, (4, 9): 1.0, (4, 10): 1.0, (4, 11): 1.0, (3, 8): 1.0, (3, 9): 1.0, (3, 10): 1.0, (3, 11): 1.0, (3, 12): 1.0, (3, 13): 1.0, (3, 14): 1.0, (3, 15): 1.0, (3, 16): 1.0, (3, 17): 1.0, (3, 18): 1.0, (3, 19): 1.0, (3, 20): 1.0, (3, 21): 1.0, (3, 22): 1.0, (2, 8): 1.0, (2, 9): 1.0, (2, 10): 1.0, (2, 11): 1.0, (2, 12): 1.0, (2, 13): 1.0, (2, 14): 1.0, (2, 15): 1.0, (2, 16): 1.0, (2, 17): 1.0, (2, 18): 1.0, (2, 19): 1.0, (2, 20): 1.0, (2, 21): 1.0, (2, 22): 1.0, (1, 8): 1.0, (1, 9): 1.0, (1, 10): 1.0, (1, 11): 1.0, (1, 12): 1.0, (1, 13): 1.0, (1, 14): 1.0, (1, 15): 1.0, (1, 16): 1.0, (1, 17): 1.0, (1, 18): 1.0, (1, 19): 1.0, (1, 20): 1.0, (1, 21): 1.0, (1, 22): 1.0, (0, 8): 1.0, (0, 9): 1.0, (0, 10): 1.0, (0, 11): 1.0, (0, 12): 1.0, (0, 13): 1.0, (0, 14): 1.0, (0, 15): 1.0, (0, 16): 1.0, (0, 17): 1.0, (0, 18): 1.0, (0, 19): 1.0, (0, 20): 1.0, (0, 21): 1.0, (0, 22): 1.0, (0, 23): 1.0, (0, 24): 1.0, (0, 25): 1.0, (0, 26): 1.0, (0, 34): 1.0, (0, 35): 1.0, (0, 36): 1.0, (0, 37): 1.0, (1, 23): 1.0, (1, 24): 1.0, (1, 25): 1.0, (1, 26): 1.0, (1, 34): 1.0, (1, 35): 1.0, (1, 36): 1.0, (1, 37): 1.0, (2, 23): 1.0, (2, 24): 1.0, (2, 25): 1.0, (2, 26): 1.0, (2, 34): 1.0, (2, 35): 1.0, (2, 36): 1.0, (2, 37): 1.0, (3, 23): 1.0, (3, 24): 1.0, (3, 25): 1.0, (3, 26): 1.0, (3, 34): 1.0, (3, 35): 1.0, (3, 36): 1.0, (3, 37): 1.0, (11, 23): 1.0, (11, 24): 1.0, (11, 25): 1.0, (11, 26): 1.0, (11, 34): 1.0, (11, 35): 1.0, (11, 36): 1.0, (11, 37): 1.0, (12, 23): 1.0, (12, 24): 1.0, (12, 25): 1.0, (12, 26): 1.0, (12, 34): 1.0, (12, 35): 1.0, (12, 36): 1.0, (12, 37): 1.0, (13, 23): 1.0, (13, 24): 1.0, (13, 25): 1.0, (13, 26): 1.0, (13, 34): 1.0, (13, 35): 1.0, (13, 36): 1.0, (13, 37): 1.0, (14, 23): 1.0, (14, 24): 1.0, (14, 25): 1.0, (14, 26): 1.0, (14, 34): 1.0, (14, 35): 1.0, (14, 36): 1.0, (14, 37): 1.0, (15, 23): 1.0, (15, 24): 1.0, (15, 25): 1.0, (15, 26): 1.0, (15, 34): 1.0, (15, 35): 1.0, (15, 36): 1.0, (15, 37): 1.0, (16, 23): 1.0, (16, 24): 1.0, (16, 25): 1.0, (16, 26): 1.0, (16, 34): 1.0, (16, 35): 1.0, (16, 36): 1.0, (16, 37): 1.0, (17, 23): 1.0, (17, 24): 1.0, (17, 25): 1.0, (17, 26): 1.0, (17, 34): 1.0, (17, 35): 1.0, (17, 36): 1.0, (17, 37): 1.0, (18, 23): 1.0, (18, 24): 1.0, (18, 25): 1.0, (18, 26): 1.0, (18, 34): 1.0, (18, 35): 1.0, (18, 36): 1.0, (18, 37): 1.0, (26, 23): 1.0, (26, 24): 1.0, (26, 25): 1.0, (26, 26): 1.0, (26, 27): 1.0, (26, 28): 1.0, (26, 29): 1.0, (26, 30): 1.0, (26, 31): 1.0, (26, 32): 1.0, (26, 33): 1.0, (26, 34): 1.0, (26, 35): 1.0, (26, 36): 1.0, (26, 37): 1.0, (27, 23): 1.0, (27, 24): 1.0, (27, 25): 1.0, (27, 26): 1.0, (27, 27): 1.0, (27, 28): 1.0, (27, 29): 1.0, (27, 30): 1.0, (27, 31): 1.0, (27, 32): 1.0, (27, 33): 1.0, (27, 34): 1.0, (27, 35): 1.0, (27, 36): 1.0, (27, 37): 1.0, (28, 23): 1.0, (28, 24): 1.0, (28, 25): 1.0, (28, 26): 1.0, (28, 27): 1.0, (28, 28): 1.0, (28, 29): 1.0, (28, 30): 1.0, (28, 31): 1.0, (28, 32): 1.0, (28, 33): 1.0, (28, 34): 1.0, (28, 35): 1.0, (28, 36): 1.0, (28, 37): 1.0, (29, 23): 1.0, (29, 24): 1.0, (29, 25): 1.0, (29, 26): 1.0, (29, 27): 1.0, (29, 28): 1.0, (29, 29): 1.0, (29, 30): 1.0, (29, 31): 1.0, (29, 32): 1.0, (29, 33): 1.0, (29, 34): 1.0, (29, 35): 1.0, (29, 36): 1.0, (29, 37): 1.0}\n" + ] + }, + { + "data": { + "text/plain": [ + "<matplotlib.image.AxesImage at 0x2359151e5c0>" + ] + }, + "execution_count": 138, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAQoAAAD8CAYAAACPd+p5AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjAsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+17YcXAAANZUlEQVR4nO3df+hd9X3H8edrMYktVjSd2pgIppAV09FpF5zDMUTtTK0YOxRSyghUCBsOLB20ccKgsELdoO0f2+hCleWPrupsJcF1y6JVymDVpvXHjJlLtGyGBEOpUssgNfreH/dk/S79Jh/zvefec7/6fMCXe35/3n5vfN3POfdzvidVhSSdyq8MXYCk2WdQSGoyKCQ1GRSSmgwKSU0GhaSm3oIiyZIkTyZ5qJtfk+TxJPuT3JdkWV9tSZquPnsUtwP75szfBXy5qtYCrwC39tiWpCnqJSiSrAY+Bnytmw9wNfBAt8l24KY+2pI0fWf0dJyvAJ8F3tPNvxd4taqOdfMHgVXz7ZhkC7AFYAlLfvPdnN1TSZLm8xqv/LiqzjudfcYOiiQ3AEeq6gdJrjq+eJ5N5x0rXlXbgG0AZ2dF/VauGbckSafwcD3wX6e7Tx89iiuBG5NcD5wJnM2oh3FOkjO6XsVq4FAPbUkawNjXKKrqjqpaXVUXA5uA71TVJ4FHgZu7zTYDO8ZtS9IwJjmO4nPAZ5IcYHTN4u4JtiVpgvq6mAlAVT0GPNZNvwhc3ufxJQ3DkZmSmnrtUWjydh16akH7XXfhpT1XMr+F1jeOafy3jfPfNa3f/STZo5DUZFBIajIoJDUZFJKaDApJTQaFpCaDQlKTQSGpyaCQ1GRQSGoyKCQ1GRSSmgwKSU0GhaQmbzNfZGb9luVZr08LY49CUpNBIanJoJDUZFBIajIoJDUZFJKaDApJTQaFpCaDQlKTQSGpaeygSHJmkieSPJ1kb5LPd8vXJHk8yf4k9yVZNn65kobQR4/iKHB1Vf0GcCmwIckVwF3Al6tqLfAKcGsPbUkawNhBUSM/62aXdj8FXA080C3fDtw0bluShtHLNYokS5I8BRwBdgMvAK9W1bFuk4PAqj7akjR9vQRFVb1RVZcCq4HLgUvm22y+fZNsSbInyZ7XOdpHOZJ61uu3HlX1KvAYcAVwTpLjf+9iNXDoJPtsq6r1VbV+Kcv7LEdST/r41uO8JOd00+8CrgX2AY8CN3ebbQZ2jNuWpGH08ReuVgLbkyxhFDz3V9VDSZ4D7k3y58CTwN09tCVpAGMHRVU9A1w2z/IXGV2vkLTIOTJTUpNBIanJoJDUZFBIajIoJDX5AKBFZtehpxa037QezLPQ+sbhQ4cmzx6FpCaDQlKTQSGpyaCQ1GRQSGoyKCQ1GRSSmgwKSU0GhaQmg0JSk0EhqcmgkNRkUEhqMigkNXmbuRa9IW5tf6exRyGpyaCQ1GRQSGoyKCQ1GRSSmgwKSU0GhaSmsYMiyUVJHk2yL8neJLd3y1ck2Z1kf/d67vjlShpCHz2KY8CfVNUlwBXAbUnWAVuBR6pqLfBINy9pERo7KKrqcFX9sJt+DdgHrAI2Atu7zbYDN43blqRh9HqNIsnFwGXA48AFVXUYRmECnH+SfbYk2ZNkz+sc7bMcST3pLSiSnAV8E/h0Vf30re5XVduqan1VrV/K8r7KkdSjXoIiyVJGIfH1qvpWt/jlJCu79SuBI320JWn6xr57NEmAu4F9VfWlOat2ApuBL3avO8ZtS7Pv7frA4Hf6Hap93GZ+JfAHwL8nOf7b/FNGAXF/kluB/wZu6aEtSQMYOyiq6l+BnGT1NeMeX9LwHJkpqcmgkNRkUEhqMigkNRkUkpoMCklNBoWkJoNCUpNBIanJoJDUZFBIajIoJDUZFJKaDApJTQaFpCaDQlKTQSGpyaCQ1GRQSGoyKCQ1GRSSmgwKSU0GhaSmPh4ApEXg7fykq7fr08lmiT0KSU0GhaQmg0JSUy9BkeSeJEeSPDtn2Yoku5Ps717P7aMtSdPXV4/i74ANJyzbCjxSVWuBR7p5SYtQL0FRVd8FfnLC4o3A9m56O3BTH21Jmr5JXqO4oKoOA3Sv58+3UZItSfYk2fM6RydYjqSFGvxiZlVtq6r1VbV+KcuHLkfSPCYZFC8nWQnQvR6ZYFuSJmiSQbET2NxNbwZ2TLAtSRPU19ej3wD+DfhAkoNJbgW+CHwkyX7gI928pEWol3s9quoTJ1l1TR/HlzSswS9mSpp9BoWkJoNCUpNBIanJoJDUZFBIajIoJDUZFJKaDApJTQaFpCaDQlKTQSGpyaCQ1GRQSGoyKCQ1GRSSmnxI8SLjA3k1BHsUkpoMCklNBoWkJoNCUpNBIanJoJDUZFBIajIoJDUZFJKaDApJTRMPiiQbkjyf5ECSrZNuT1L/JhoUSZYAfw18FFgHfCLJukm2Kal/k+5RXA4cqKoXq+rnwL3Axgm3Kalnkw6KVcBLc+YPdsv+T5ItSfYk2fM6RydcjqSFmHRQZJ5l9f9mqrZV1fqqWr+U5RMuR9JCTDooDgIXzZlfDRyacJuSejbpoPg+sDbJmiTLgE3Azgm3KalnE/0LV1V1LMkfA7uAJcA9VbV3km1K6t/E/xReVX0b+Pak25E0OY7MlNRkUEhqMigkNRkUkpoMCklNPgBokdl16KmhS9A7kD0KSU0GhaQmg0JSk0EhqcmgkNRkUEhqMigkNRkUkpoMCklNBoWkJoNCUpNBIanJoJDUZFBIavI280XmugsvHboEvQPZo5DUZFBIajIoJDUZFJKaDApJTQaFpKaxgiLJLUn2JnkzyfoT1t2R5ECS55NcN16ZkoY07jiKZ4HfB/527sIk64BNwAeBC4GHk/xaVb0xZnuSBjBWj6Kq9lXV8/Os2gjcW1VHq+pHwAHg8nHakjScSV2jWAW8NGf+YLdM0iLUPPVI8jDwvnlW3VlVO0622zzL6iTH3wJsATiTd7fKkTSAZlBU1bULOO5B4KI586uBQyc5/jZgG8DZWTFvmEga1qROPXYCm5IsT7IGWAs8MaG2JE3YuF+PfjzJQeC3gX9MsgugqvYC9wPPAf8M3OY3HtLiNdbXo1X1IPDgSdZ9AfjCOMeXNBscmSmpyaCQ1GRQSGoyKCQ1GRSSmgwKSU0GhaQmg0JSk0EhqcmgkNRkUEhqMigkNRkUkpoMCklNBoWkJoNCUpNBIanJoJDUZFBIajIoJDUZFJKaDApJTQaFpCaDQlKTQSGpyaCQ1GRQSGoyKCQ1jfs0879M8h9JnknyYJJz5qy7I8mBJM8nuW78UiUNZdwexW7g16vqQ8B/AncAJFkHbAI+CGwA/ibJkjHbkjSQsYKiqv6lqo51s98DVnfTG4F7q+poVf0IOABcPk5bkoZzRo/H+hRwXze9ilFwHHewW/ZLkmwBtnSzRx+uB57tsaZx/Srw46GLOMGs1WQ9pzZr9QB84HR3aAZFkoeB982z6s6q2tFtcydwDPj68d3m2b7mO35VbQO2dcfZU1Xr30LdUzFr9cDs1WQ9pzZr9cCoptPdpxkUVXVto9HNwA3ANVV1PAwOAhfN2Ww1cOh0i5M0G8b91mMD8Dngxqr6nzmrdgKbkixPsgZYCzwxTluShjPuNYq/ApYDu5MAfK+q/rCq9ia5H3iO0SnJbVX1xls43rYx6+nbrNUDs1eT9ZzarNUDC6gpvzhbkKT5OTJTUpNBIalpJoJi1oaCJ7klyd4kbyZZf8K6QYamJ9nQtXkgydZptXtCDfckOZLk2TnLViTZnWR/93ruFOu5KMmjSfZ179ftQ9aU5MwkTyR5uqvn893yNUke7+q5L8myadQzp64lSZ5M8tCC66mqwX+A3wPO6KbvAu7qptcBTzO6YLoGeAFYMoV6LmE0KOUxYP2c5UPVs6Rr6/3Asq6GdQO8T78LfBh4ds6yvwC2dtNbj793U6pnJfDhbvo9jG4jWDdUTYzGD53VTS8FHgeuAO4HNnXLvwr80ZTft88Afw881M2fdj0z0aOoGRsKXlX7qur5eVYNNTT9cuBAVb1YVT8H7u1qmaqq+i7wkxMWbwS2d9PbgZumWM/hqvphN/0asI/RCOBBaqqRn3WzS7ufAq4GHph2PQBJVgMfA77WzWch9cxEUJzgU8A/ddOrgJfmrDvpUPApGaqeWfs9zHVBVR2G0f+4wPlDFJHkYuAyRp/ig9XUdfOfAo4wumnyBeDVOR+E037vvgJ8Fnizm3/vQurp816PU5r0UPBJ1DPfbpOqp2GodheFJGcB3wQ+XVU/7cb0DKJG44Uu7a6zPcjoNPaXNptGLUluAI5U1Q+SXHV88ULqmVpQ1IwNBW/VcxJDDU2f5SHxLydZWVWHk6xk9Ek6NUmWMgqJr1fVt2ahJoCqejXJY4yuUZyT5IzuU3ya792VwI1JrgfOBM5m1MM47Xpm4tRjEQ0FH6qe7wNru6vVyxj9rY+dU2j3rdgJbO6mNwMn6431rjvfvhvYV1VfGrqmJOcd/8YuybuAaxldN3kUuHna9VTVHVW1uqouZvRv5jtV9ckF1TPNq6+nuCp7gNE5+FPdz1fnrLuT0Xne88BHp1TPxxl9ih8FXgZ2DVlP1+71jK7qv8Do9GiI9+kbwGHg9e73cyujc95HgP3d64op1vM7jLrNz8z5t3P9UDUBHwKe7Op5Fvizbvn7GX2gHAD+AVg+wHt3Fb/41uO063EIt6SmmTj1kDTbDApJTQaFpCaDQlKTQSGpyaCQ1GRQSGr6X8tWam9q8gRfAAAAAElFTkSuQmCC\n", + "text/plain": [ + "<Figure size 432x288 with 1 Axes>" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [] + }, + { + "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.6.8" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/latex_and_figures/figs/ch_apply/Implementationex_manual1.PNG b/latex_and_figures/figs/ch_apply/Implementationex_manual1.PNG new file mode 100644 index 0000000000000000000000000000000000000000..2f5d0fdbc2e1ed4de1e43d26a6acc31735716e84 Binary files /dev/null and b/latex_and_figures/figs/ch_apply/Implementationex_manual1.PNG differ diff --git a/latex_and_figures/figs/ch_apply/Implementationex_manual2.PNG b/latex_and_figures/figs/ch_apply/Implementationex_manual2.PNG new file mode 100644 index 0000000000000000000000000000000000000000..10f2490088fa0b937aee64808996be04f1a1759f Binary files /dev/null and b/latex_and_figures/figs/ch_apply/Implementationex_manual2.PNG differ diff --git a/latex_and_figures/figs/ch_apply/Implementationex_only_endpicture.PNG b/latex_and_figures/figs/ch_apply/Implementationex_only_endpicture.PNG new file mode 100644 index 0000000000000000000000000000000000000000..6c38cb3feb383bbc2fdea2e6dc483c2d5b93a25b Binary files /dev/null and b/latex_and_figures/figs/ch_apply/Implementationex_only_endpicture.PNG differ diff --git a/latex_and_figures/figs/ch_apply/Implementationex_only_endpicture_closeup.PNG b/latex_and_figures/figs/ch_apply/Implementationex_only_endpicture_closeup.PNG new file mode 100644 index 0000000000000000000000000000000000000000..bef2519ce2348be23b47f04a3ddef4b8ee39d962 Binary files /dev/null and b/latex_and_figures/figs/ch_apply/Implementationex_only_endpicture_closeup.PNG differ diff --git a/latex_and_figures/figs/ch_apply/Implementationex_only_endpicture_closeup2.PNG b/latex_and_figures/figs/ch_apply/Implementationex_only_endpicture_closeup2.PNG new file mode 100644 index 0000000000000000000000000000000000000000..42a0147ec031d10d974cc2a1653e758a4a6fd049 Binary files /dev/null and b/latex_and_figures/figs/ch_apply/Implementationex_only_endpicture_closeup2.PNG differ diff --git a/latex_and_figures/figs/ch_apply/Implementationex_only_exploreproblem.PNG b/latex_and_figures/figs/ch_apply/Implementationex_only_exploreproblem.PNG new file mode 100644 index 0000000000000000000000000000000000000000..20ba9fbe1ec58c0ddbf4798289253da146bcd475 Binary files /dev/null and b/latex_and_figures/figs/ch_apply/Implementationex_only_exploreproblem.PNG differ diff --git a/latex_and_figures/figs/ch_apply/Implementationex_only_exploreproblem_closeup.PNG b/latex_and_figures/figs/ch_apply/Implementationex_only_exploreproblem_closeup.PNG new file mode 100644 index 0000000000000000000000000000000000000000..68a2d30ad995c01a03cefad9678558d896d6585d Binary files /dev/null and b/latex_and_figures/figs/ch_apply/Implementationex_only_exploreproblem_closeup.PNG differ diff --git a/latex_and_figures/figs/ch_apply/Implementationex_only_relocatesolution.PNG b/latex_and_figures/figs/ch_apply/Implementationex_only_relocatesolution.PNG new file mode 100644 index 0000000000000000000000000000000000000000..51f3e8ad98ded61f450c7a3dd70f8044bfec27a4 Binary files /dev/null and b/latex_and_figures/figs/ch_apply/Implementationex_only_relocatesolution.PNG differ diff --git a/latex_and_figures/figs/ch_apply/Implementationex_only_relocatesolution_closeup.PNG b/latex_and_figures/figs/ch_apply/Implementationex_only_relocatesolution_closeup.PNG new file mode 100644 index 0000000000000000000000000000000000000000..11d8a1f6295dba323ff0afc63c0107b05cc8cec9 Binary files /dev/null and b/latex_and_figures/figs/ch_apply/Implementationex_only_relocatesolution_closeup.PNG differ diff --git a/latex_and_figures/figs/ch_apply/explore_linear1.PNG b/latex_and_figures/figs/ch_apply/explore_linear1.PNG new file mode 100644 index 0000000000000000000000000000000000000000..f8c76c478d657d59dfabb68e0a623350e00ea4bc Binary files /dev/null and b/latex_and_figures/figs/ch_apply/explore_linear1.PNG differ diff --git a/latex_and_figures/figs/ch_apply/explore_linear2.PNG b/latex_and_figures/figs/ch_apply/explore_linear2.PNG new file mode 100644 index 0000000000000000000000000000000000000000..53b7ecefa145581f9134f2058429a8041a56d5eb Binary files /dev/null and b/latex_and_figures/figs/ch_apply/explore_linear2.PNG differ diff --git a/latex_and_figures/figs/ch_apply/explore_linear3.PNG b/latex_and_figures/figs/ch_apply/explore_linear3.PNG new file mode 100644 index 0000000000000000000000000000000000000000..051d1e5eb90b675df59e6b2bee3af229cf77f04f Binary files /dev/null and b/latex_and_figures/figs/ch_apply/explore_linear3.PNG differ diff --git a/latex_and_figures/figs/ch_apply/explore_linear4.PNG b/latex_and_figures/figs/ch_apply/explore_linear4.PNG new file mode 100644 index 0000000000000000000000000000000000000000..71f29a14445b8dce8f3bafb733a5477496daab32 Binary files /dev/null and b/latex_and_figures/figs/ch_apply/explore_linear4.PNG differ diff --git a/latex_and_figures/figs/ch_apply/explore_linear5.PNG b/latex_and_figures/figs/ch_apply/explore_linear5.PNG new file mode 100644 index 0000000000000000000000000000000000000000..efea8ea92ed75ac6e66042e397a46ee9f3925d1d Binary files /dev/null and b/latex_and_figures/figs/ch_apply/explore_linear5.PNG differ diff --git a/latex_and_figures/figs/ch_apply/explore_linear6.PNG b/latex_and_figures/figs/ch_apply/explore_linear6.PNG new file mode 100644 index 0000000000000000000000000000000000000000..6ab216598e687c6fd39dcd35bde2ea69e44c6c2d Binary files /dev/null and b/latex_and_figures/figs/ch_apply/explore_linear6.PNG differ diff --git a/latex_and_figures/figs/ch_apply/explore_linear_part1.PNG b/latex_and_figures/figs/ch_apply/explore_linear_part1.PNG new file mode 100644 index 0000000000000000000000000000000000000000..f3dbedba347e17bf5625ddac2f0b0de304d93be6 Binary files /dev/null and b/latex_and_figures/figs/ch_apply/explore_linear_part1.PNG differ diff --git a/latex_and_figures/figs/ch_apply/explore_linear_part2.PNG b/latex_and_figures/figs/ch_apply/explore_linear_part2.PNG new file mode 100644 index 0000000000000000000000000000000000000000..75a8de65516e5c2ca69022a885c81cd14e360868 Binary files /dev/null and b/latex_and_figures/figs/ch_apply/explore_linear_part2.PNG differ diff --git a/latex_and_figures/figs/ch_apply/explore_linear_part3.PNG b/latex_and_figures/figs/ch_apply/explore_linear_part3.PNG new file mode 100644 index 0000000000000000000000000000000000000000..0a2b2f31ca6441c460a5270642157b3ee968fc07 Binary files /dev/null and b/latex_and_figures/figs/ch_apply/explore_linear_part3.PNG differ diff --git a/latex_and_figures/figs/ch_apply/explore_linear_part4.PNG b/latex_and_figures/figs/ch_apply/explore_linear_part4.PNG new file mode 100644 index 0000000000000000000000000000000000000000..e710108f8fca33e6111d22c2d0656b617d4ee1df Binary files /dev/null and b/latex_and_figures/figs/ch_apply/explore_linear_part4.PNG differ diff --git a/latex_and_figures/figs/ch_apply/explore_linear_part5.PNG b/latex_and_figures/figs/ch_apply/explore_linear_part5.PNG new file mode 100644 index 0000000000000000000000000000000000000000..fdf2841ff8c6f9ae4305842794be1197425cc6b7 Binary files /dev/null and b/latex_and_figures/figs/ch_apply/explore_linear_part5.PNG differ diff --git a/latex_and_figures/figs/ch_apply/explore_linear_part6.PNG b/latex_and_figures/figs/ch_apply/explore_linear_part6.PNG new file mode 100644 index 0000000000000000000000000000000000000000..5594ddea876925851c7279917ff7b3f7dd1b1be4 Binary files /dev/null and b/latex_and_figures/figs/ch_apply/explore_linear_part6.PNG differ diff --git a/latex_and_figures/figs/ch_apply/explore_linear_part7.PNG b/latex_and_figures/figs/ch_apply/explore_linear_part7.PNG new file mode 100644 index 0000000000000000000000000000000000000000..64114950452b2c420af3d73579a28123fe47f511 Binary files /dev/null and b/latex_and_figures/figs/ch_apply/explore_linear_part7.PNG differ diff --git a/latex_and_figures/figs/ch_apply/explore_linear_part8.PNG b/latex_and_figures/figs/ch_apply/explore_linear_part8.PNG new file mode 100644 index 0000000000000000000000000000000000000000..a2d335b5cd1b9c17a7308b6be1b2163aeb769bb0 Binary files /dev/null and b/latex_and_figures/figs/ch_apply/explore_linear_part8.PNG differ diff --git a/latex_and_figures/figs/ch_apply/explore_linear_part9.PNG b/latex_and_figures/figs/ch_apply/explore_linear_part9.PNG new file mode 100644 index 0000000000000000000000000000000000000000..cf7a7448520480c6c410972f4be7eed27659f7da Binary files /dev/null and b/latex_and_figures/figs/ch_apply/explore_linear_part9.PNG differ diff --git a/latex_and_figures/figs/ch_apply/explore_neuralnet1.PNG b/latex_and_figures/figs/ch_apply/explore_neuralnet1.PNG new file mode 100644 index 0000000000000000000000000000000000000000..122c1fe2cff07adad1746055e375affdcf793559 Binary files /dev/null and b/latex_and_figures/figs/ch_apply/explore_neuralnet1.PNG differ diff --git a/latex_and_figures/figs/ch_apply/explore_neuralnet2.PNG b/latex_and_figures/figs/ch_apply/explore_neuralnet2.PNG new file mode 100644 index 0000000000000000000000000000000000000000..240298f7bdba717e1532c2b85aa8bc054b51cebf Binary files /dev/null and b/latex_and_figures/figs/ch_apply/explore_neuralnet2.PNG differ diff --git a/latex_and_figures/figs/ch_apply/explore_neuralnet3.PNG b/latex_and_figures/figs/ch_apply/explore_neuralnet3.PNG new file mode 100644 index 0000000000000000000000000000000000000000..db0b0a377d93b68a0d5949e20e3d51b7a2b980da Binary files /dev/null and b/latex_and_figures/figs/ch_apply/explore_neuralnet3.PNG differ diff --git a/latex_and_figures/figs/ch_apply/explore_neuralnet4.PNG b/latex_and_figures/figs/ch_apply/explore_neuralnet4.PNG new file mode 100644 index 0000000000000000000000000000000000000000..7229d0bda06804549cfc0c3e7d0ffd2ed25d594e Binary files /dev/null and b/latex_and_figures/figs/ch_apply/explore_neuralnet4.PNG differ diff --git a/latex_and_figures/figs/ch_apply/explore_neuralnet5.PNG b/latex_and_figures/figs/ch_apply/explore_neuralnet5.PNG new file mode 100644 index 0000000000000000000000000000000000000000..2b41adf243e9a4d9426c6126e18db27e54782d01 Binary files /dev/null and b/latex_and_figures/figs/ch_apply/explore_neuralnet5.PNG differ diff --git a/latex_and_figures/figs/ch_apply/explore_neuralnet_beginning.PNG b/latex_and_figures/figs/ch_apply/explore_neuralnet_beginning.PNG new file mode 100644 index 0000000000000000000000000000000000000000..f5853323b96042c9162fffa91c1f1537371f3148 Binary files /dev/null and b/latex_and_figures/figs/ch_apply/explore_neuralnet_beginning.PNG differ diff --git a/latex_and_figures/figs/ch_apply/explore_neuralnet_part1.PNG b/latex_and_figures/figs/ch_apply/explore_neuralnet_part1.PNG new file mode 100644 index 0000000000000000000000000000000000000000..37051c481cce39878470b80c9e78eca83c2bb2d9 Binary files /dev/null and b/latex_and_figures/figs/ch_apply/explore_neuralnet_part1.PNG differ diff --git a/latex_and_figures/figs/ch_apply/explore_neuralnet_part2.PNG b/latex_and_figures/figs/ch_apply/explore_neuralnet_part2.PNG new file mode 100644 index 0000000000000000000000000000000000000000..a5d9bf64c99fab1f5a4b8528b1a525591fce3c5e Binary files /dev/null and b/latex_and_figures/figs/ch_apply/explore_neuralnet_part2.PNG differ diff --git a/latex_and_figures/figs/ch_apply/explore_neuralnet_part3.PNG b/latex_and_figures/figs/ch_apply/explore_neuralnet_part3.PNG new file mode 100644 index 0000000000000000000000000000000000000000..c18d8756ee5b105a4e2fdc1eb6ca8f46b31b90eb Binary files /dev/null and b/latex_and_figures/figs/ch_apply/explore_neuralnet_part3.PNG differ diff --git a/latex_and_figures/figs/ch_apply/explore_neuralnet_part4.PNG b/latex_and_figures/figs/ch_apply/explore_neuralnet_part4.PNG new file mode 100644 index 0000000000000000000000000000000000000000..3c6077467378e192be38eef7d4d7a4f5a1f0262a Binary files /dev/null and b/latex_and_figures/figs/ch_apply/explore_neuralnet_part4.PNG differ diff --git a/latex_and_figures/figs/ch_apply/explore_neuralnet_part5.PNG b/latex_and_figures/figs/ch_apply/explore_neuralnet_part5.PNG new file mode 100644 index 0000000000000000000000000000000000000000..4fd11b270b5cc663d27535672dc199a579247a2a Binary files /dev/null and b/latex_and_figures/figs/ch_apply/explore_neuralnet_part5.PNG differ diff --git a/latex_and_figures/figs/ch_apply/explore_neuralnet_part6.PNG b/latex_and_figures/figs/ch_apply/explore_neuralnet_part6.PNG new file mode 100644 index 0000000000000000000000000000000000000000..f1b9682f755f8a5e6a3f29e32466edc611b3b628 Binary files /dev/null and b/latex_and_figures/figs/ch_apply/explore_neuralnet_part6.PNG differ diff --git a/latex_and_figures/figs/ch_apply/explore_neuralnet_part7.PNG b/latex_and_figures/figs/ch_apply/explore_neuralnet_part7.PNG new file mode 100644 index 0000000000000000000000000000000000000000..25c34cb781eb37fb188ffcbf2f7bdf1152f0d5dc Binary files /dev/null and b/latex_and_figures/figs/ch_apply/explore_neuralnet_part7.PNG differ diff --git a/latex_and_figures/figs/ch_apply/map1.png b/latex_and_figures/figs/ch_apply/map1.png new file mode 100644 index 0000000000000000000000000000000000000000..20e070c1d45bbef55c1ab83a15d848a6b9e1a5e1 Binary files /dev/null and b/latex_and_figures/figs/ch_apply/map1.png differ diff --git a/latex_and_figures/figs/ch_apply/map10.png b/latex_and_figures/figs/ch_apply/map10.png new file mode 100644 index 0000000000000000000000000000000000000000..b3753fab0b09cc420835911dffdc7bd0b241b15a Binary files /dev/null and b/latex_and_figures/figs/ch_apply/map10.png differ diff --git a/latex_and_figures/figs/ch_apply/map11.png b/latex_and_figures/figs/ch_apply/map11.png new file mode 100644 index 0000000000000000000000000000000000000000..dc45dffe8a5728359f7e28271c0e7e4a8512177e Binary files /dev/null and b/latex_and_figures/figs/ch_apply/map11.png differ diff --git a/latex_and_figures/figs/ch_apply/map2.png b/latex_and_figures/figs/ch_apply/map2.png new file mode 100644 index 0000000000000000000000000000000000000000..dea0f8988018f8d0c67ce4cddf45d8987b4b0fe3 Binary files /dev/null and b/latex_and_figures/figs/ch_apply/map2.png differ diff --git a/latex_and_figures/figs/ch_apply/map3.png b/latex_and_figures/figs/ch_apply/map3.png new file mode 100644 index 0000000000000000000000000000000000000000..b318497555404c07be9cea3cb5021e5eee96cda1 Binary files /dev/null and b/latex_and_figures/figs/ch_apply/map3.png differ diff --git a/latex_and_figures/figs/ch_apply/map4.png b/latex_and_figures/figs/ch_apply/map4.png new file mode 100644 index 0000000000000000000000000000000000000000..052a7524e390bd92f93a7d6f6a7fcea9dcc45857 Binary files /dev/null and b/latex_and_figures/figs/ch_apply/map4.png differ diff --git a/latex_and_figures/figs/ch_apply/map5.png b/latex_and_figures/figs/ch_apply/map5.png new file mode 100644 index 0000000000000000000000000000000000000000..5c77e72f4d08f5b0c62c2b740e6694722a14ad6b Binary files /dev/null and b/latex_and_figures/figs/ch_apply/map5.png differ diff --git a/latex_and_figures/figs/ch_apply/map6.png b/latex_and_figures/figs/ch_apply/map6.png new file mode 100644 index 0000000000000000000000000000000000000000..ba301c0771a14a14a3ae1c14161ba448b40a06da Binary files /dev/null and b/latex_and_figures/figs/ch_apply/map6.png differ diff --git a/latex_and_figures/figs/ch_apply/map7.png b/latex_and_figures/figs/ch_apply/map7.png new file mode 100644 index 0000000000000000000000000000000000000000..068e7b66ec375e6dd6f622391b20519fa1daa5ea Binary files /dev/null and b/latex_and_figures/figs/ch_apply/map7.png differ diff --git a/latex_and_figures/figs/ch_apply/map8.png b/latex_and_figures/figs/ch_apply/map8.png new file mode 100644 index 0000000000000000000000000000000000000000..dfdb05e74bfc243aab1122b973474551da8d52ac Binary files /dev/null and b/latex_and_figures/figs/ch_apply/map8.png differ diff --git a/latex_and_figures/figs/ch_apply/map9.png b/latex_and_figures/figs/ch_apply/map9.png new file mode 100644 index 0000000000000000000000000000000000000000..2b639c46724316ecb972c51b2ae6566ba10e64bc Binary files /dev/null and b/latex_and_figures/figs/ch_apply/map9.png differ diff --git a/latex_and_figures/figs/ch_filters/bayes_ex_lightbulb.png b/latex_and_figures/figs/ch_filters/bayes_ex_lightbulb.png new file mode 100644 index 0000000000000000000000000000000000000000..3a2aa02282f2f55df01bba1113b3be16219e7bd9 Binary files /dev/null and b/latex_and_figures/figs/ch_filters/bayes_ex_lightbulb.png differ diff --git a/latex_and_figures/figs/ch_filters/example_histogramm_filter.png b/latex_and_figures/figs/ch_filters/example_histogramm_filter.png new file mode 100644 index 0000000000000000000000000000000000000000..fea48bae40a6ed5e546e73f377c7da7f67311051 Binary files /dev/null and b/latex_and_figures/figs/ch_filters/example_histogramm_filter.png differ diff --git a/latex_and_figures/figs/ch_filters/example_kalman_filter.png b/latex_and_figures/figs/ch_filters/example_kalman_filter.png new file mode 100644 index 0000000000000000000000000000000000000000..4497d7f7832c3ee415068caea4d0f88eee2392d0 Binary files /dev/null and b/latex_and_figures/figs/ch_filters/example_kalman_filter.png differ diff --git a/latex_and_figures/figs/ch_filters/example_particlefitler_20parts.png b/latex_and_figures/figs/ch_filters/example_particlefitler_20parts.png new file mode 100644 index 0000000000000000000000000000000000000000..a10b32332d2b054ffe65e2f31ad5bd4933722a6f Binary files /dev/null and b/latex_and_figures/figs/ch_filters/example_particlefitler_20parts.png differ diff --git a/latex_and_figures/figs/ch_filters/example_particlefitler_20parts.svg b/latex_and_figures/figs/ch_filters/example_particlefitler_20parts.svg new file mode 100644 index 0000000000000000000000000000000000000000..3607463f3d56489ff3396100af5261b90c992702 --- /dev/null +++ b/latex_and_figures/figs/ch_filters/example_particlefitler_20parts.svg @@ -0,0 +1,1427 @@ +<?xml version="1.0" encoding="utf-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Created with matplotlib (https://matplotlib.org/) --> +<svg height="358.56pt" version="1.1" viewBox="0 0 720 358.56" width="720pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <defs> + <style type="text/css"> +*{stroke-linecap:butt;stroke-linejoin:round;white-space:pre;} + </style> + </defs> + <g id="figure_1"> + <g id="patch_1"> + <path d="M 0 358.56 +L 720 358.56 +L 720 0 +L 0 0 +z +" style="fill:#ffffff;"/> + </g> + <g id="axes_1"> + <g id="patch_2"> + <path d="M 16.2 149.898 +L 342.36 149.898 +L 342.36 35.73648 +L 16.2 35.73648 +z +" style="fill:#ffffff;"/> + </g> + <g id="matplotlib.axis_1"> + <g id="xtick_1"> + <g id="line2d_1"> + <defs> + <path d="M 0 0 +L 0 3.5 +" id="m4e2dfcffa2" style="stroke:#000000;stroke-width:0.8;"/> + </defs> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="41.289231" xlink:href="#m4e2dfcffa2" y="149.898"/> + </g> + </g> + <g id="text_1"> + <!-- −2 --> + <defs> + <path d="M 10.59375 35.5 +L 73.1875 35.5 +L 73.1875 27.203125 +L 10.59375 27.203125 +z +" id="DejaVuSans-8722"/> + <path d="M 19.1875 8.296875 +L 53.609375 8.296875 +L 53.609375 0 +L 7.328125 0 +L 7.328125 8.296875 +Q 12.9375 14.109375 22.625 23.890625 +Q 32.328125 33.6875 34.8125 36.53125 +Q 39.546875 41.84375 41.421875 45.53125 +Q 43.3125 49.21875 43.3125 52.78125 +Q 43.3125 58.59375 39.234375 62.25 +Q 35.15625 65.921875 28.609375 65.921875 +Q 23.96875 65.921875 18.8125 64.3125 +Q 13.671875 62.703125 7.8125 59.421875 +L 7.8125 69.390625 +Q 13.765625 71.78125 18.9375 73 +Q 24.125 74.21875 28.421875 74.21875 +Q 39.75 74.21875 46.484375 68.546875 +Q 53.21875 62.890625 53.21875 53.421875 +Q 53.21875 48.921875 51.53125 44.890625 +Q 49.859375 40.875 45.40625 35.40625 +Q 44.1875 33.984375 37.640625 27.21875 +Q 31.109375 20.453125 19.1875 8.296875 +z +" id="DejaVuSans-50"/> + </defs> + <g transform="translate(30.23259 168.295656)scale(0.15 -0.15)"> + <use xlink:href="#DejaVuSans-8722"/> + <use x="83.789062" xlink:href="#DejaVuSans-50"/> + </g> + </g> + </g> + <g id="xtick_2"> + <g id="line2d_2"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="91.467692" xlink:href="#m4e2dfcffa2" y="149.898"/> + </g> + </g> + <g id="text_2"> + <!-- 0 --> + <defs> + <path d="M 31.78125 66.40625 +Q 24.171875 66.40625 20.328125 58.90625 +Q 16.5 51.421875 16.5 36.375 +Q 16.5 21.390625 20.328125 13.890625 +Q 24.171875 6.390625 31.78125 6.390625 +Q 39.453125 6.390625 43.28125 13.890625 +Q 47.125 21.390625 47.125 36.375 +Q 47.125 51.421875 43.28125 58.90625 +Q 39.453125 66.40625 31.78125 66.40625 +z +M 31.78125 74.21875 +Q 44.046875 74.21875 50.515625 64.515625 +Q 56.984375 54.828125 56.984375 36.375 +Q 56.984375 17.96875 50.515625 8.265625 +Q 44.046875 -1.421875 31.78125 -1.421875 +Q 19.53125 -1.421875 13.0625 8.265625 +Q 6.59375 17.96875 6.59375 36.375 +Q 6.59375 54.828125 13.0625 64.515625 +Q 19.53125 74.21875 31.78125 74.21875 +z +" id="DejaVuSans-48"/> + </defs> + <g transform="translate(86.695817 168.295656)scale(0.15 -0.15)"> + <use xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="xtick_3"> + <g id="line2d_3"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="141.646154" xlink:href="#m4e2dfcffa2" y="149.898"/> + </g> + </g> + <g id="text_3"> + <!-- 2 --> + <g transform="translate(136.874279 168.295656)scale(0.15 -0.15)"> + <use xlink:href="#DejaVuSans-50"/> + </g> + </g> + </g> + <g id="xtick_4"> + <g id="line2d_4"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="191.824615" xlink:href="#m4e2dfcffa2" y="149.898"/> + </g> + </g> + <g id="text_4"> + <!-- 4 --> + <defs> + <path d="M 37.796875 64.3125 +L 12.890625 25.390625 +L 37.796875 25.390625 +z +M 35.203125 72.90625 +L 47.609375 72.90625 +L 47.609375 25.390625 +L 58.015625 25.390625 +L 58.015625 17.1875 +L 47.609375 17.1875 +L 47.609375 0 +L 37.796875 0 +L 37.796875 17.1875 +L 4.890625 17.1875 +L 4.890625 26.703125 +z +" id="DejaVuSans-52"/> + </defs> + <g transform="translate(187.05274 168.295656)scale(0.15 -0.15)"> + <use xlink:href="#DejaVuSans-52"/> + </g> + </g> + </g> + <g id="xtick_5"> + <g id="line2d_5"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="242.003077" xlink:href="#m4e2dfcffa2" y="149.898"/> + </g> + </g> + <g id="text_5"> + <!-- 6 --> + <defs> + <path d="M 33.015625 40.375 +Q 26.375 40.375 22.484375 35.828125 +Q 18.609375 31.296875 18.609375 23.390625 +Q 18.609375 15.53125 22.484375 10.953125 +Q 26.375 6.390625 33.015625 6.390625 +Q 39.65625 6.390625 43.53125 10.953125 +Q 47.40625 15.53125 47.40625 23.390625 +Q 47.40625 31.296875 43.53125 35.828125 +Q 39.65625 40.375 33.015625 40.375 +z +M 52.59375 71.296875 +L 52.59375 62.3125 +Q 48.875 64.0625 45.09375 64.984375 +Q 41.3125 65.921875 37.59375 65.921875 +Q 27.828125 65.921875 22.671875 59.328125 +Q 17.53125 52.734375 16.796875 39.40625 +Q 19.671875 43.65625 24.015625 45.921875 +Q 28.375 48.1875 33.59375 48.1875 +Q 44.578125 48.1875 50.953125 41.515625 +Q 57.328125 34.859375 57.328125 23.390625 +Q 57.328125 12.15625 50.6875 5.359375 +Q 44.046875 -1.421875 33.015625 -1.421875 +Q 20.359375 -1.421875 13.671875 8.265625 +Q 6.984375 17.96875 6.984375 36.375 +Q 6.984375 53.65625 15.1875 63.9375 +Q 23.390625 74.21875 37.203125 74.21875 +Q 40.921875 74.21875 44.703125 73.484375 +Q 48.484375 72.75 52.59375 71.296875 +z +" id="DejaVuSans-54"/> + </defs> + <g transform="translate(237.231202 168.295656)scale(0.15 -0.15)"> + <use xlink:href="#DejaVuSans-54"/> + </g> + </g> + </g> + <g id="xtick_6"> + <g id="line2d_6"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="292.181538" xlink:href="#m4e2dfcffa2" y="149.898"/> + </g> + </g> + <g id="text_6"> + <!-- 8 --> + <defs> + <path d="M 31.78125 34.625 +Q 24.75 34.625 20.71875 30.859375 +Q 16.703125 27.09375 16.703125 20.515625 +Q 16.703125 13.921875 20.71875 10.15625 +Q 24.75 6.390625 31.78125 6.390625 +Q 38.8125 6.390625 42.859375 10.171875 +Q 46.921875 13.96875 46.921875 20.515625 +Q 46.921875 27.09375 42.890625 30.859375 +Q 38.875 34.625 31.78125 34.625 +z +M 21.921875 38.8125 +Q 15.578125 40.375 12.03125 44.71875 +Q 8.5 49.078125 8.5 55.328125 +Q 8.5 64.0625 14.71875 69.140625 +Q 20.953125 74.21875 31.78125 74.21875 +Q 42.671875 74.21875 48.875 69.140625 +Q 55.078125 64.0625 55.078125 55.328125 +Q 55.078125 49.078125 51.53125 44.71875 +Q 48 40.375 41.703125 38.8125 +Q 48.828125 37.15625 52.796875 32.3125 +Q 56.78125 27.484375 56.78125 20.515625 +Q 56.78125 9.90625 50.3125 4.234375 +Q 43.84375 -1.421875 31.78125 -1.421875 +Q 19.734375 -1.421875 13.25 4.234375 +Q 6.78125 9.90625 6.78125 20.515625 +Q 6.78125 27.484375 10.78125 32.3125 +Q 14.796875 37.15625 21.921875 38.8125 +z +M 18.3125 54.390625 +Q 18.3125 48.734375 21.84375 45.5625 +Q 25.390625 42.390625 31.78125 42.390625 +Q 38.140625 42.390625 41.71875 45.5625 +Q 45.3125 48.734375 45.3125 54.390625 +Q 45.3125 60.0625 41.71875 63.234375 +Q 38.140625 66.40625 31.78125 66.40625 +Q 25.390625 66.40625 21.84375 63.234375 +Q 18.3125 60.0625 18.3125 54.390625 +z +" id="DejaVuSans-56"/> + </defs> + <g transform="translate(287.409663 168.295656)scale(0.15 -0.15)"> + <use xlink:href="#DejaVuSans-56"/> + </g> + </g> + </g> + <g id="xtick_7"> + <g id="line2d_7"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="342.36" xlink:href="#m4e2dfcffa2" y="149.898"/> + </g> + </g> + <g id="text_7"> + <!-- 10 --> + <defs> + <path d="M 12.40625 8.296875 +L 28.515625 8.296875 +L 28.515625 63.921875 +L 10.984375 60.40625 +L 10.984375 69.390625 +L 28.421875 72.90625 +L 38.28125 72.90625 +L 38.28125 8.296875 +L 54.390625 8.296875 +L 54.390625 0 +L 12.40625 0 +z +" id="DejaVuSans-49"/> + </defs> + <g transform="translate(332.81625 168.295656)scale(0.15 -0.15)"> + <use xlink:href="#DejaVuSans-49"/> + <use x="63.623047" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + </g> + <g id="EventCollection_1"> + <path clip-path="url(#pfc40d23fab)" d="M 51.423724 35.73648 +L 51.423724 149.898 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + <path clip-path="url(#pfc40d23fab)" d="M 56.507399 35.73648 +L 56.507399 149.898 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + <path clip-path="url(#pfc40d23fab)" d="M 65.910797 35.73648 +L 65.910797 149.898 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + <path clip-path="url(#pfc40d23fab)" d="M 72.416691 35.73648 +L 72.416691 149.898 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + <path clip-path="url(#pfc40d23fab)" d="M 77.644685 35.73648 +L 77.644685 149.898 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + <path clip-path="url(#pfc40d23fab)" d="M 80.684025 35.73648 +L 80.684025 149.898 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + <path clip-path="url(#pfc40d23fab)" d="M 81.079005 35.73648 +L 81.079005 149.898 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + <path clip-path="url(#pfc40d23fab)" d="M 82.984046 35.73648 +L 82.984046 149.898 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + <path clip-path="url(#pfc40d23fab)" d="M 85.719875 35.73648 +L 85.719875 149.898 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + <path clip-path="url(#pfc40d23fab)" d="M 86.738931 35.73648 +L 86.738931 149.898 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + <path clip-path="url(#pfc40d23fab)" d="M 88.775106 35.73648 +L 88.775106 149.898 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + <path clip-path="url(#pfc40d23fab)" d="M 89.315383 35.73648 +L 89.315383 149.898 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + <path clip-path="url(#pfc40d23fab)" d="M 89.865913 35.73648 +L 89.865913 149.898 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + <path clip-path="url(#pfc40d23fab)" d="M 95.506701 35.73648 +L 95.506701 149.898 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + <path clip-path="url(#pfc40d23fab)" d="M 101.308138 35.73648 +L 101.308138 149.898 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + <path clip-path="url(#pfc40d23fab)" d="M 108.846531 35.73648 +L 108.846531 149.898 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + <path clip-path="url(#pfc40d23fab)" d="M 109.950139 35.73648 +L 109.950139 149.898 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + <path clip-path="url(#pfc40d23fab)" d="M 127.588562 35.73648 +L 127.588562 149.898 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + <path clip-path="url(#pfc40d23fab)" d="M 129.438932 35.73648 +L 129.438932 149.898 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + <path clip-path="url(#pfc40d23fab)" d="M 131.036643 35.73648 +L 131.036643 149.898 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + </g> + <g id="patch_3"> + <path d="M 16.2 149.898 +L 342.36 149.898 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/> + </g> + <g id="text_8"> + <!-- starting particles --> + <defs> + <path d="M 44.28125 53.078125 +L 44.28125 44.578125 +Q 40.484375 46.53125 36.375 47.5 +Q 32.28125 48.484375 27.875 48.484375 +Q 21.1875 48.484375 17.84375 46.4375 +Q 14.5 44.390625 14.5 40.28125 +Q 14.5 37.15625 16.890625 35.375 +Q 19.28125 33.59375 26.515625 31.984375 +L 29.59375 31.296875 +Q 39.15625 29.25 43.1875 25.515625 +Q 47.21875 21.78125 47.21875 15.09375 +Q 47.21875 7.46875 41.1875 3.015625 +Q 35.15625 -1.421875 24.609375 -1.421875 +Q 20.21875 -1.421875 15.453125 -0.5625 +Q 10.6875 0.296875 5.421875 2 +L 5.421875 11.28125 +Q 10.40625 8.6875 15.234375 7.390625 +Q 20.0625 6.109375 24.8125 6.109375 +Q 31.15625 6.109375 34.5625 8.28125 +Q 37.984375 10.453125 37.984375 14.40625 +Q 37.984375 18.0625 35.515625 20.015625 +Q 33.0625 21.96875 24.703125 23.78125 +L 21.578125 24.515625 +Q 13.234375 26.265625 9.515625 29.90625 +Q 5.8125 33.546875 5.8125 39.890625 +Q 5.8125 47.609375 11.28125 51.796875 +Q 16.75 56 26.8125 56 +Q 31.78125 56 36.171875 55.265625 +Q 40.578125 54.546875 44.28125 53.078125 +z +" id="DejaVuSans-115"/> + <path d="M 18.3125 70.21875 +L 18.3125 54.6875 +L 36.8125 54.6875 +L 36.8125 47.703125 +L 18.3125 47.703125 +L 18.3125 18.015625 +Q 18.3125 11.328125 20.140625 9.421875 +Q 21.96875 7.515625 27.59375 7.515625 +L 36.8125 7.515625 +L 36.8125 0 +L 27.59375 0 +Q 17.1875 0 13.234375 3.875 +Q 9.28125 7.765625 9.28125 18.015625 +L 9.28125 47.703125 +L 2.6875 47.703125 +L 2.6875 54.6875 +L 9.28125 54.6875 +L 9.28125 70.21875 +z +" id="DejaVuSans-116"/> + <path d="M 34.28125 27.484375 +Q 23.390625 27.484375 19.1875 25 +Q 14.984375 22.515625 14.984375 16.5 +Q 14.984375 11.71875 18.140625 8.90625 +Q 21.296875 6.109375 26.703125 6.109375 +Q 34.1875 6.109375 38.703125 11.40625 +Q 43.21875 16.703125 43.21875 25.484375 +L 43.21875 27.484375 +z +M 52.203125 31.203125 +L 52.203125 0 +L 43.21875 0 +L 43.21875 8.296875 +Q 40.140625 3.328125 35.546875 0.953125 +Q 30.953125 -1.421875 24.3125 -1.421875 +Q 15.921875 -1.421875 10.953125 3.296875 +Q 6 8.015625 6 15.921875 +Q 6 25.140625 12.171875 29.828125 +Q 18.359375 34.515625 30.609375 34.515625 +L 43.21875 34.515625 +L 43.21875 35.40625 +Q 43.21875 41.609375 39.140625 45 +Q 35.0625 48.390625 27.6875 48.390625 +Q 23 48.390625 18.546875 47.265625 +Q 14.109375 46.140625 10.015625 43.890625 +L 10.015625 52.203125 +Q 14.9375 54.109375 19.578125 55.046875 +Q 24.21875 56 28.609375 56 +Q 40.484375 56 46.34375 49.84375 +Q 52.203125 43.703125 52.203125 31.203125 +z +" id="DejaVuSans-97"/> + <path d="M 41.109375 46.296875 +Q 39.59375 47.171875 37.8125 47.578125 +Q 36.03125 48 33.890625 48 +Q 26.265625 48 22.1875 43.046875 +Q 18.109375 38.09375 18.109375 28.8125 +L 18.109375 0 +L 9.078125 0 +L 9.078125 54.6875 +L 18.109375 54.6875 +L 18.109375 46.1875 +Q 20.953125 51.171875 25.484375 53.578125 +Q 30.03125 56 36.53125 56 +Q 37.453125 56 38.578125 55.875 +Q 39.703125 55.765625 41.0625 55.515625 +z +" id="DejaVuSans-114"/> + <path d="M 9.421875 54.6875 +L 18.40625 54.6875 +L 18.40625 0 +L 9.421875 0 +z +M 9.421875 75.984375 +L 18.40625 75.984375 +L 18.40625 64.59375 +L 9.421875 64.59375 +z +" id="DejaVuSans-105"/> + <path d="M 54.890625 33.015625 +L 54.890625 0 +L 45.90625 0 +L 45.90625 32.71875 +Q 45.90625 40.484375 42.875 44.328125 +Q 39.84375 48.1875 33.796875 48.1875 +Q 26.515625 48.1875 22.3125 43.546875 +Q 18.109375 38.921875 18.109375 30.90625 +L 18.109375 0 +L 9.078125 0 +L 9.078125 54.6875 +L 18.109375 54.6875 +L 18.109375 46.1875 +Q 21.34375 51.125 25.703125 53.5625 +Q 30.078125 56 35.796875 56 +Q 45.21875 56 50.046875 50.171875 +Q 54.890625 44.34375 54.890625 33.015625 +z +" id="DejaVuSans-110"/> + <path d="M 45.40625 27.984375 +Q 45.40625 37.75 41.375 43.109375 +Q 37.359375 48.484375 30.078125 48.484375 +Q 22.859375 48.484375 18.828125 43.109375 +Q 14.796875 37.75 14.796875 27.984375 +Q 14.796875 18.265625 18.828125 12.890625 +Q 22.859375 7.515625 30.078125 7.515625 +Q 37.359375 7.515625 41.375 12.890625 +Q 45.40625 18.265625 45.40625 27.984375 +z +M 54.390625 6.78125 +Q 54.390625 -7.171875 48.1875 -13.984375 +Q 42 -20.796875 29.203125 -20.796875 +Q 24.46875 -20.796875 20.265625 -20.09375 +Q 16.0625 -19.390625 12.109375 -17.921875 +L 12.109375 -9.1875 +Q 16.0625 -11.328125 19.921875 -12.34375 +Q 23.78125 -13.375 27.78125 -13.375 +Q 36.625 -13.375 41.015625 -8.765625 +Q 45.40625 -4.15625 45.40625 5.171875 +L 45.40625 9.625 +Q 42.625 4.78125 38.28125 2.390625 +Q 33.9375 0 27.875 0 +Q 17.828125 0 11.671875 7.65625 +Q 5.515625 15.328125 5.515625 27.984375 +Q 5.515625 40.671875 11.671875 48.328125 +Q 17.828125 56 27.875 56 +Q 33.9375 56 38.28125 53.609375 +Q 42.625 51.21875 45.40625 46.390625 +L 45.40625 54.6875 +L 54.390625 54.6875 +z +" id="DejaVuSans-103"/> + <path id="DejaVuSans-32"/> + <path d="M 18.109375 8.203125 +L 18.109375 -20.796875 +L 9.078125 -20.796875 +L 9.078125 54.6875 +L 18.109375 54.6875 +L 18.109375 46.390625 +Q 20.953125 51.265625 25.265625 53.625 +Q 29.59375 56 35.59375 56 +Q 45.5625 56 51.78125 48.09375 +Q 58.015625 40.1875 58.015625 27.296875 +Q 58.015625 14.40625 51.78125 6.484375 +Q 45.5625 -1.421875 35.59375 -1.421875 +Q 29.59375 -1.421875 25.265625 0.953125 +Q 20.953125 3.328125 18.109375 8.203125 +z +M 48.6875 27.296875 +Q 48.6875 37.203125 44.609375 42.84375 +Q 40.53125 48.484375 33.40625 48.484375 +Q 26.265625 48.484375 22.1875 42.84375 +Q 18.109375 37.203125 18.109375 27.296875 +Q 18.109375 17.390625 22.1875 11.75 +Q 26.265625 6.109375 33.40625 6.109375 +Q 40.53125 6.109375 44.609375 11.75 +Q 48.6875 17.390625 48.6875 27.296875 +z +" id="DejaVuSans-112"/> + <path d="M 48.78125 52.59375 +L 48.78125 44.1875 +Q 44.96875 46.296875 41.140625 47.34375 +Q 37.3125 48.390625 33.40625 48.390625 +Q 24.65625 48.390625 19.8125 42.84375 +Q 14.984375 37.3125 14.984375 27.296875 +Q 14.984375 17.28125 19.8125 11.734375 +Q 24.65625 6.203125 33.40625 6.203125 +Q 37.3125 6.203125 41.140625 7.25 +Q 44.96875 8.296875 48.78125 10.40625 +L 48.78125 2.09375 +Q 45.015625 0.34375 40.984375 -0.53125 +Q 36.96875 -1.421875 32.421875 -1.421875 +Q 20.0625 -1.421875 12.78125 6.34375 +Q 5.515625 14.109375 5.515625 27.296875 +Q 5.515625 40.671875 12.859375 48.328125 +Q 20.21875 56 33.015625 56 +Q 37.15625 56 41.109375 55.140625 +Q 45.0625 54.296875 48.78125 52.59375 +z +" id="DejaVuSans-99"/> + <path d="M 9.421875 75.984375 +L 18.40625 75.984375 +L 18.40625 0 +L 9.421875 0 +z +" id="DejaVuSans-108"/> + <path d="M 56.203125 29.59375 +L 56.203125 25.203125 +L 14.890625 25.203125 +Q 15.484375 15.921875 20.484375 11.0625 +Q 25.484375 6.203125 34.421875 6.203125 +Q 39.59375 6.203125 44.453125 7.46875 +Q 49.3125 8.734375 54.109375 11.28125 +L 54.109375 2.78125 +Q 49.265625 0.734375 44.1875 -0.34375 +Q 39.109375 -1.421875 33.890625 -1.421875 +Q 20.796875 -1.421875 13.15625 6.1875 +Q 5.515625 13.8125 5.515625 26.8125 +Q 5.515625 40.234375 12.765625 48.109375 +Q 20.015625 56 32.328125 56 +Q 43.359375 56 49.78125 48.890625 +Q 56.203125 41.796875 56.203125 29.59375 +z +M 47.21875 32.234375 +Q 47.125 39.59375 43.09375 43.984375 +Q 39.0625 48.390625 32.421875 48.390625 +Q 24.90625 48.390625 20.390625 44.140625 +Q 15.875 39.890625 15.1875 32.171875 +z +" id="DejaVuSans-101"/> + </defs> + <g transform="translate(102.909375 29.73648)scale(0.18 -0.18)"> + <use xlink:href="#DejaVuSans-115"/> + <use x="52.099609" xlink:href="#DejaVuSans-116"/> + <use x="91.308594" xlink:href="#DejaVuSans-97"/> + <use x="152.587891" xlink:href="#DejaVuSans-114"/> + <use x="193.701172" xlink:href="#DejaVuSans-116"/> + <use x="232.910156" xlink:href="#DejaVuSans-105"/> + <use x="260.693359" xlink:href="#DejaVuSans-110"/> + <use x="324.072266" xlink:href="#DejaVuSans-103"/> + <use x="387.548828" xlink:href="#DejaVuSans-32"/> + <use x="419.335938" xlink:href="#DejaVuSans-112"/> + <use x="482.8125" xlink:href="#DejaVuSans-97"/> + <use x="544.091797" xlink:href="#DejaVuSans-114"/> + <use x="585.205078" xlink:href="#DejaVuSans-116"/> + <use x="624.414062" xlink:href="#DejaVuSans-105"/> + <use x="652.197266" xlink:href="#DejaVuSans-99"/> + <use x="707.177734" xlink:href="#DejaVuSans-108"/> + <use x="734.960938" xlink:href="#DejaVuSans-101"/> + <use x="796.484375" xlink:href="#DejaVuSans-115"/> + </g> + </g> + </g> + <g id="axes_2"> + <g id="patch_4"> + <path d="M 368.1 149.898 +L 694.26 149.898 +L 694.26 35.73648 +L 368.1 35.73648 +z +" style="fill:#ffffff;"/> + </g> + <g id="matplotlib.axis_2"> + <g id="xtick_8"> + <g id="line2d_8"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="393.189231" xlink:href="#m4e2dfcffa2" y="149.898"/> + </g> + </g> + <g id="text_9"> + <!-- −2 --> + <g transform="translate(382.13259 168.295656)scale(0.15 -0.15)"> + <use xlink:href="#DejaVuSans-8722"/> + <use x="83.789062" xlink:href="#DejaVuSans-50"/> + </g> + </g> + </g> + <g id="xtick_9"> + <g id="line2d_9"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="443.367692" xlink:href="#m4e2dfcffa2" y="149.898"/> + </g> + </g> + <g id="text_10"> + <!-- 0 --> + <g transform="translate(438.595817 168.295656)scale(0.15 -0.15)"> + <use xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="xtick_10"> + <g id="line2d_10"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="493.546154" xlink:href="#m4e2dfcffa2" y="149.898"/> + </g> + </g> + <g id="text_11"> + <!-- 2 --> + <g transform="translate(488.774279 168.295656)scale(0.15 -0.15)"> + <use xlink:href="#DejaVuSans-50"/> + </g> + </g> + </g> + <g id="xtick_11"> + <g id="line2d_11"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="543.724615" xlink:href="#m4e2dfcffa2" y="149.898"/> + </g> + </g> + <g id="text_12"> + <!-- 4 --> + <g transform="translate(538.95274 168.295656)scale(0.15 -0.15)"> + <use xlink:href="#DejaVuSans-52"/> + </g> + </g> + </g> + <g id="xtick_12"> + <g id="line2d_12"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="593.903077" xlink:href="#m4e2dfcffa2" y="149.898"/> + </g> + </g> + <g id="text_13"> + <!-- 6 --> + <g transform="translate(589.131202 168.295656)scale(0.15 -0.15)"> + <use xlink:href="#DejaVuSans-54"/> + </g> + </g> + </g> + <g id="xtick_13"> + <g id="line2d_13"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="644.081538" xlink:href="#m4e2dfcffa2" y="149.898"/> + </g> + </g> + <g id="text_14"> + <!-- 8 --> + <g transform="translate(639.309663 168.295656)scale(0.15 -0.15)"> + <use xlink:href="#DejaVuSans-56"/> + </g> + </g> + </g> + <g id="xtick_14"> + <g id="line2d_14"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="694.26" xlink:href="#m4e2dfcffa2" y="149.898"/> + </g> + </g> + <g id="text_15"> + <!-- 10 --> + <g transform="translate(684.71625 168.295656)scale(0.15 -0.15)"> + <use xlink:href="#DejaVuSans-49"/> + <use x="63.623047" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + </g> + <g id="EventCollection_2"> + <path clip-path="url(#pa6df66d423)" d="M 516.631132 35.73648 +L 516.631132 149.898 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + <path clip-path="url(#pa6df66d423)" d="M 517.372587 35.73648 +L 517.372587 149.898 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + <path clip-path="url(#pa6df66d423)" d="M 517.531053 35.73648 +L 517.531053 149.898 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + <path clip-path="url(#pa6df66d423)" d="M 533.177351 35.73648 +L 533.177351 149.898 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + <path clip-path="url(#pa6df66d423)" d="M 535.672438 35.73648 +L 535.672438 149.898 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + <path clip-path="url(#pa6df66d423)" d="M 544.448295 35.73648 +L 544.448295 149.898 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + <path clip-path="url(#pa6df66d423)" d="M 549.582087 35.73648 +L 549.582087 149.898 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + <path clip-path="url(#pa6df66d423)" d="M 553.110418 35.73648 +L 553.110418 149.898 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + <path clip-path="url(#pa6df66d423)" d="M 553.926091 35.73648 +L 553.926091 149.898 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + <path clip-path="url(#pa6df66d423)" d="M 558.751751 35.73648 +L 558.751751 149.898 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + <path clip-path="url(#pa6df66d423)" d="M 565.670017 35.73648 +L 565.670017 149.898 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + <path clip-path="url(#pa6df66d423)" d="M 571.620525 35.73648 +L 571.620525 149.898 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + <path clip-path="url(#pa6df66d423)" d="M 573.793428 35.73648 +L 573.793428 149.898 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + <path clip-path="url(#pa6df66d423)" d="M 577.170198 35.73648 +L 577.170198 149.898 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + <path clip-path="url(#pa6df66d423)" d="M 578.713501 35.73648 +L 578.713501 149.898 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + <path clip-path="url(#pa6df66d423)" d="M 586.109327 35.73648 +L 586.109327 149.898 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + <path clip-path="url(#pa6df66d423)" d="M 592.606393 35.73648 +L 592.606393 149.898 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + <path clip-path="url(#pa6df66d423)" d="M 597.973771 35.73648 +L 597.973771 149.898 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + <path clip-path="url(#pa6df66d423)" d="M 604.470674 35.73648 +L 604.470674 149.898 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + <path clip-path="url(#pa6df66d423)" d="M 629.171116 35.73648 +L 629.171116 149.898 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + </g> + <g id="patch_5"> + <path d="M 368.1 149.898 +L 694.26 149.898 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/> + </g> + <g id="text_16"> + <!-- moved particles --> + <defs> + <path d="M 52 44.1875 +Q 55.375 50.25 60.0625 53.125 +Q 64.75 56 71.09375 56 +Q 79.640625 56 84.28125 50.015625 +Q 88.921875 44.046875 88.921875 33.015625 +L 88.921875 0 +L 79.890625 0 +L 79.890625 32.71875 +Q 79.890625 40.578125 77.09375 44.375 +Q 74.3125 48.1875 68.609375 48.1875 +Q 61.625 48.1875 57.5625 43.546875 +Q 53.515625 38.921875 53.515625 30.90625 +L 53.515625 0 +L 44.484375 0 +L 44.484375 32.71875 +Q 44.484375 40.625 41.703125 44.40625 +Q 38.921875 48.1875 33.109375 48.1875 +Q 26.21875 48.1875 22.15625 43.53125 +Q 18.109375 38.875 18.109375 30.90625 +L 18.109375 0 +L 9.078125 0 +L 9.078125 54.6875 +L 18.109375 54.6875 +L 18.109375 46.1875 +Q 21.1875 51.21875 25.484375 53.609375 +Q 29.78125 56 35.6875 56 +Q 41.65625 56 45.828125 52.96875 +Q 50 49.953125 52 44.1875 +z +" id="DejaVuSans-109"/> + <path d="M 30.609375 48.390625 +Q 23.390625 48.390625 19.1875 42.75 +Q 14.984375 37.109375 14.984375 27.296875 +Q 14.984375 17.484375 19.15625 11.84375 +Q 23.34375 6.203125 30.609375 6.203125 +Q 37.796875 6.203125 41.984375 11.859375 +Q 46.1875 17.53125 46.1875 27.296875 +Q 46.1875 37.015625 41.984375 42.703125 +Q 37.796875 48.390625 30.609375 48.390625 +z +M 30.609375 56 +Q 42.328125 56 49.015625 48.375 +Q 55.71875 40.765625 55.71875 27.296875 +Q 55.71875 13.875 49.015625 6.21875 +Q 42.328125 -1.421875 30.609375 -1.421875 +Q 18.84375 -1.421875 12.171875 6.21875 +Q 5.515625 13.875 5.515625 27.296875 +Q 5.515625 40.765625 12.171875 48.375 +Q 18.84375 56 30.609375 56 +z +" id="DejaVuSans-111"/> + <path d="M 2.984375 54.6875 +L 12.5 54.6875 +L 29.59375 8.796875 +L 46.6875 54.6875 +L 56.203125 54.6875 +L 35.6875 0 +L 23.484375 0 +z +" id="DejaVuSans-118"/> + <path d="M 45.40625 46.390625 +L 45.40625 75.984375 +L 54.390625 75.984375 +L 54.390625 0 +L 45.40625 0 +L 45.40625 8.203125 +Q 42.578125 3.328125 38.25 0.953125 +Q 33.9375 -1.421875 27.875 -1.421875 +Q 17.96875 -1.421875 11.734375 6.484375 +Q 5.515625 14.40625 5.515625 27.296875 +Q 5.515625 40.1875 11.734375 48.09375 +Q 17.96875 56 27.875 56 +Q 33.9375 56 38.25 53.625 +Q 42.578125 51.265625 45.40625 46.390625 +z +M 14.796875 27.296875 +Q 14.796875 17.390625 18.875 11.75 +Q 22.953125 6.109375 30.078125 6.109375 +Q 37.203125 6.109375 41.296875 11.75 +Q 45.40625 17.390625 45.40625 27.296875 +Q 45.40625 37.203125 41.296875 42.84375 +Q 37.203125 48.484375 30.078125 48.484375 +Q 22.953125 48.484375 18.875 42.84375 +Q 14.796875 37.203125 14.796875 27.296875 +z +" id="DejaVuSans-100"/> + </defs> + <g transform="translate(458.835469 29.73648)scale(0.18 -0.18)"> + <use xlink:href="#DejaVuSans-109"/> + <use x="97.412109" xlink:href="#DejaVuSans-111"/> + <use x="158.59375" xlink:href="#DejaVuSans-118"/> + <use x="217.773438" xlink:href="#DejaVuSans-101"/> + <use x="279.296875" xlink:href="#DejaVuSans-100"/> + <use x="342.773438" xlink:href="#DejaVuSans-32"/> + <use x="374.560547" xlink:href="#DejaVuSans-112"/> + <use x="438.037109" xlink:href="#DejaVuSans-97"/> + <use x="499.316406" xlink:href="#DejaVuSans-114"/> + <use x="540.429688" xlink:href="#DejaVuSans-116"/> + <use x="579.638672" xlink:href="#DejaVuSans-105"/> + <use x="607.421875" xlink:href="#DejaVuSans-99"/> + <use x="662.402344" xlink:href="#DejaVuSans-108"/> + <use x="690.185547" xlink:href="#DejaVuSans-101"/> + <use x="751.708984" xlink:href="#DejaVuSans-115"/> + </g> + </g> + </g> + <g id="axes_3"> + <g id="patch_6"> + <path d="M 16.2 321.1104 +L 342.36 321.1104 +L 342.36 206.94888 +L 16.2 206.94888 +z +" style="fill:#ffffff;"/> + </g> + <g id="matplotlib.axis_3"> + <g id="xtick_15"> + <g id="line2d_15"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="41.289231" xlink:href="#m4e2dfcffa2" y="321.1104"/> + </g> + </g> + <g id="text_17"> + <!-- −2 --> + <g transform="translate(30.23259 339.508056)scale(0.15 -0.15)"> + <use xlink:href="#DejaVuSans-8722"/> + <use x="83.789062" xlink:href="#DejaVuSans-50"/> + </g> + </g> + </g> + <g id="xtick_16"> + <g id="line2d_16"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="91.467692" xlink:href="#m4e2dfcffa2" y="321.1104"/> + </g> + </g> + <g id="text_18"> + <!-- 0 --> + <g transform="translate(86.695817 339.508056)scale(0.15 -0.15)"> + <use xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="xtick_17"> + <g id="line2d_17"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="141.646154" xlink:href="#m4e2dfcffa2" y="321.1104"/> + </g> + </g> + <g id="text_19"> + <!-- 2 --> + <g transform="translate(136.874279 339.508056)scale(0.15 -0.15)"> + <use xlink:href="#DejaVuSans-50"/> + </g> + </g> + </g> + <g id="xtick_18"> + <g id="line2d_18"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="191.824615" xlink:href="#m4e2dfcffa2" y="321.1104"/> + </g> + </g> + <g id="text_20"> + <!-- 4 --> + <g transform="translate(187.05274 339.508056)scale(0.15 -0.15)"> + <use xlink:href="#DejaVuSans-52"/> + </g> + </g> + </g> + <g id="xtick_19"> + <g id="line2d_19"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="242.003077" xlink:href="#m4e2dfcffa2" y="321.1104"/> + </g> + </g> + <g id="text_21"> + <!-- 6 --> + <g transform="translate(237.231202 339.508056)scale(0.15 -0.15)"> + <use xlink:href="#DejaVuSans-54"/> + </g> + </g> + </g> + <g id="xtick_20"> + <g id="line2d_20"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="292.181538" xlink:href="#m4e2dfcffa2" y="321.1104"/> + </g> + </g> + <g id="text_22"> + <!-- 8 --> + <g transform="translate(287.409663 339.508056)scale(0.15 -0.15)"> + <use xlink:href="#DejaVuSans-56"/> + </g> + </g> + </g> + <g id="xtick_21"> + <g id="line2d_21"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="342.36" xlink:href="#m4e2dfcffa2" y="321.1104"/> + </g> + </g> + <g id="text_23"> + <!-- 10 --> + <g transform="translate(332.81625 339.508056)scale(0.15 -0.15)"> + <use xlink:href="#DejaVuSans-49"/> + <use x="63.623047" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + </g> + <g id="EventCollection_3"> + <path clip-path="url(#p8b647610fc)" d="M 206.851751 214.211839 +L 206.851751 313.847441 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + </g> + <g id="EventCollection_4"> + <path clip-path="url(#p8b647610fc)" d="M 165.631053 263.597937 +L 165.631053 264.461343 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + </g> + <g id="EventCollection_5"> + <path clip-path="url(#p8b647610fc)" d="M 192.548295 231.440532 +L 192.548295 296.618748 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + </g> + <g id="EventCollection_6"> + <path clip-path="url(#p8b647610fc)" d="M 226.813501 253.778237 +L 226.813501 274.281043 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + </g> + <g id="EventCollection_7"> + <path clip-path="url(#p8b647610fc)" d="M 181.277351 254.695135 +L 181.277351 273.364145 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + </g> + <g id="EventCollection_8"> + <path clip-path="url(#p8b647610fc)" d="M 183.772438 250.831664 +L 183.772438 277.227616 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + </g> + <g id="EventCollection_9"> + <path clip-path="url(#p8b647610fc)" d="M 225.270198 251.3505 +L 225.270198 276.70878 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + </g> + <g id="EventCollection_10"> + <path clip-path="url(#p8b647610fc)" d="M 234.209327 261.029061 +L 234.209327 267.030219 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + </g> + <g id="EventCollection_11"> + <path clip-path="url(#p8b647610fc)" d="M 252.570674 263.998023 +L 252.570674 264.061257 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + </g> + <g id="EventCollection_12"> + <path clip-path="url(#p8b647610fc)" d="M 221.893428 244.881236 +L 221.893428 283.178044 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + </g> + <g id="EventCollection_13"> + <path clip-path="url(#p8b647610fc)" d="M 202.026091 214.105262 +L 202.026091 313.954018 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + </g> + <g id="EventCollection_14"> + <path clip-path="url(#p8b647610fc)" d="M 219.720525 240.002378 +L 219.720525 288.056902 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + </g> + <g id="EventCollection_15"> + <path clip-path="url(#p8b647610fc)" d="M 197.682087 219.955535 +L 197.682087 308.103745 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + </g> + <g id="EventCollection_16"> + <path clip-path="url(#p8b647610fc)" d="M 213.770017 225.663998 +L 213.770017 302.395282 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + </g> + <g id="EventCollection_17"> + <path clip-path="url(#p8b647610fc)" d="M 246.073771 263.827377 +L 246.073771 264.231903 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + </g> + <g id="EventCollection_18"> + <path clip-path="url(#p8b647610fc)" d="M 240.706393 263.26419 +L 240.706393 264.79509 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + </g> + <g id="EventCollection_19"> + <path clip-path="url(#p8b647610fc)" d="M 277.271116 264.029638 +L 277.271116 264.029642 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + </g> + <g id="EventCollection_20"> + <path clip-path="url(#p8b647610fc)" d="M 201.210418 214.812081 +L 201.210418 313.247199 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + </g> + <g id="EventCollection_21"> + <path clip-path="url(#p8b647610fc)" d="M 165.472587 263.614486 +L 165.472587 264.444794 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + </g> + <g id="EventCollection_22"> + <path clip-path="url(#p8b647610fc)" d="M 164.731132 263.684608 +L 164.731132 264.374672 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + </g> + <g id="LineCollection_1"> + <path clip-path="url(#p8b647610fc)" d="M 204.369231 359.56 +L 204.369231 92.617067 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + </g> + <g id="patch_7"> + <path d="M 16.2 321.1104 +L 342.36 321.1104 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/> + </g> + <g id="text_24"> + <!-- weighted particles --> + <defs> + <path d="M 4.203125 54.6875 +L 13.1875 54.6875 +L 24.421875 12.015625 +L 35.59375 54.6875 +L 46.1875 54.6875 +L 57.421875 12.015625 +L 68.609375 54.6875 +L 77.59375 54.6875 +L 63.28125 0 +L 52.6875 0 +L 40.921875 44.828125 +L 29.109375 0 +L 18.5 0 +z +" id="DejaVuSans-119"/> + <path d="M 54.890625 33.015625 +L 54.890625 0 +L 45.90625 0 +L 45.90625 32.71875 +Q 45.90625 40.484375 42.875 44.328125 +Q 39.84375 48.1875 33.796875 48.1875 +Q 26.515625 48.1875 22.3125 43.546875 +Q 18.109375 38.921875 18.109375 30.90625 +L 18.109375 0 +L 9.078125 0 +L 9.078125 75.984375 +L 18.109375 75.984375 +L 18.109375 46.1875 +Q 21.34375 51.125 25.703125 53.5625 +Q 30.078125 56 35.796875 56 +Q 45.21875 56 50.046875 50.171875 +Q 54.890625 44.34375 54.890625 33.015625 +z +" id="DejaVuSans-104"/> + </defs> + <g transform="translate(96.191719 200.94888)scale(0.18 -0.18)"> + <use xlink:href="#DejaVuSans-119"/> + <use x="81.787109" xlink:href="#DejaVuSans-101"/> + <use x="143.310547" xlink:href="#DejaVuSans-105"/> + <use x="171.09375" xlink:href="#DejaVuSans-103"/> + <use x="234.570312" xlink:href="#DejaVuSans-104"/> + <use x="297.949219" xlink:href="#DejaVuSans-116"/> + <use x="337.158203" xlink:href="#DejaVuSans-101"/> + <use x="398.681641" xlink:href="#DejaVuSans-100"/> + <use x="462.158203" xlink:href="#DejaVuSans-32"/> + <use x="493.945312" xlink:href="#DejaVuSans-112"/> + <use x="557.421875" xlink:href="#DejaVuSans-97"/> + <use x="618.701172" xlink:href="#DejaVuSans-114"/> + <use x="659.814453" xlink:href="#DejaVuSans-116"/> + <use x="699.023438" xlink:href="#DejaVuSans-105"/> + <use x="726.806641" xlink:href="#DejaVuSans-99"/> + <use x="781.787109" xlink:href="#DejaVuSans-108"/> + <use x="809.570312" xlink:href="#DejaVuSans-101"/> + <use x="871.09375" xlink:href="#DejaVuSans-115"/> + </g> + </g> + </g> + <g id="axes_4"> + <g id="patch_8"> + <path d="M 368.1 321.1104 +L 694.26 321.1104 +L 694.26 206.94888 +L 368.1 206.94888 +z +" style="fill:#ffffff;"/> + </g> + <g id="matplotlib.axis_4"> + <g id="xtick_22"> + <g id="line2d_22"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="393.189231" xlink:href="#m4e2dfcffa2" y="321.1104"/> + </g> + </g> + <g id="text_25"> + <!-- −2 --> + <g transform="translate(382.13259 339.508056)scale(0.15 -0.15)"> + <use xlink:href="#DejaVuSans-8722"/> + <use x="83.789062" xlink:href="#DejaVuSans-50"/> + </g> + </g> + </g> + <g id="xtick_23"> + <g id="line2d_23"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="443.367692" xlink:href="#m4e2dfcffa2" y="321.1104"/> + </g> + </g> + <g id="text_26"> + <!-- 0 --> + <g transform="translate(438.595817 339.508056)scale(0.15 -0.15)"> + <use xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="xtick_24"> + <g id="line2d_24"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="493.546154" xlink:href="#m4e2dfcffa2" y="321.1104"/> + </g> + </g> + <g id="text_27"> + <!-- 2 --> + <g transform="translate(488.774279 339.508056)scale(0.15 -0.15)"> + <use xlink:href="#DejaVuSans-50"/> + </g> + </g> + </g> + <g id="xtick_25"> + <g id="line2d_25"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="543.724615" xlink:href="#m4e2dfcffa2" y="321.1104"/> + </g> + </g> + <g id="text_28"> + <!-- 4 --> + <g transform="translate(538.95274 339.508056)scale(0.15 -0.15)"> + <use xlink:href="#DejaVuSans-52"/> + </g> + </g> + </g> + <g id="xtick_26"> + <g id="line2d_26"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="593.903077" xlink:href="#m4e2dfcffa2" y="321.1104"/> + </g> + </g> + <g id="text_29"> + <!-- 6 --> + <g transform="translate(589.131202 339.508056)scale(0.15 -0.15)"> + <use xlink:href="#DejaVuSans-54"/> + </g> + </g> + </g> + <g id="xtick_27"> + <g id="line2d_27"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="644.081538" xlink:href="#m4e2dfcffa2" y="321.1104"/> + </g> + </g> + <g id="text_30"> + <!-- 8 --> + <g transform="translate(639.309663 339.508056)scale(0.15 -0.15)"> + <use xlink:href="#DejaVuSans-56"/> + </g> + </g> + </g> + <g id="xtick_28"> + <g id="line2d_28"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="694.26" xlink:href="#m4e2dfcffa2" y="321.1104"/> + </g> + </g> + <g id="text_31"> + <!-- 10 --> + <g transform="translate(684.71625 339.508056)scale(0.15 -0.15)"> + <use xlink:href="#DejaVuSans-49"/> + <use x="63.623047" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + </g> + <g id="EventCollection_23"> + <path clip-path="url(#p743c85a154)" d="M 553.926091 283.627368 +L 553.926091 320.539592 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + </g> + <g id="EventCollection_24"> + <path clip-path="url(#p743c85a154)" d="M 553.926091 245.573528 +L 553.926091 282.485752 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + </g> + <g id="EventCollection_25"> + <path clip-path="url(#p743c85a154)" d="M 553.926091 207.519688 +L 553.926091 244.431912 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + </g> + <g id="EventCollection_26"> + <path clip-path="url(#p743c85a154)" d="M 565.670017 283.627368 +L 565.670017 320.539592 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + </g> + <g id="EventCollection_27"> + <path clip-path="url(#p743c85a154)" d="M 565.670017 245.573528 +L 565.670017 282.485752 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + </g> + <g id="EventCollection_28"> + <path clip-path="url(#p743c85a154)" d="M 565.670017 207.519688 +L 565.670017 244.431912 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + </g> + <g id="EventCollection_29"> + <path clip-path="url(#p743c85a154)" d="M 571.620525 283.627368 +L 571.620525 320.539592 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + </g> + <g id="EventCollection_30"> + <path clip-path="url(#p743c85a154)" d="M 571.620525 245.573528 +L 571.620525 282.485752 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + </g> + <g id="EventCollection_31"> + <path clip-path="url(#p743c85a154)" d="M 571.620525 207.519688 +L 571.620525 244.431912 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + </g> + <g id="EventCollection_32"> + <path clip-path="url(#p743c85a154)" d="M 544.448295 283.627368 +L 544.448295 320.539592 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + </g> + <g id="EventCollection_33"> + <path clip-path="url(#p743c85a154)" d="M 544.448295 245.573528 +L 544.448295 282.485752 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + </g> + <g id="EventCollection_34"> + <path clip-path="url(#p743c85a154)" d="M 553.110418 283.627368 +L 553.110418 320.539592 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + </g> + <g id="EventCollection_35"> + <path clip-path="url(#p743c85a154)" d="M 553.110418 245.573528 +L 553.110418 282.485752 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + </g> + <g id="EventCollection_36"> + <path clip-path="url(#p743c85a154)" d="M 535.672438 283.627368 +L 535.672438 320.539592 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + </g> + <g id="EventCollection_37"> + <path clip-path="url(#p743c85a154)" d="M 535.672438 245.573528 +L 535.672438 282.485752 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + </g> + <g id="EventCollection_38"> + <path clip-path="url(#p743c85a154)" d="M 549.582087 283.627368 +L 549.582087 320.539592 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + </g> + <g id="EventCollection_39"> + <path clip-path="url(#p743c85a154)" d="M 549.582087 245.573528 +L 549.582087 282.485752 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + </g> + <g id="EventCollection_40"> + <path clip-path="url(#p743c85a154)" d="M 558.751751 283.627368 +L 558.751751 320.539592 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + </g> + <g id="EventCollection_41"> + <path clip-path="url(#p743c85a154)" d="M 578.713501 283.627368 +L 578.713501 320.539592 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + </g> + <g id="EventCollection_42"> + <path clip-path="url(#p743c85a154)" d="M 592.606393 283.627368 +L 592.606393 320.539592 +" style="fill:none;stroke:#1f77b4;stroke-width:1.5;"/> + </g> + <g id="patch_9"> + <path d="M 368.1 321.1104 +L 694.26 321.1104 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/> + </g> + <g id="text_32"> + <!-- resampled particles --> + <g transform="translate(442.016719 200.94888)scale(0.18 -0.18)"> + <use xlink:href="#DejaVuSans-114"/> + <use x="41.082031" xlink:href="#DejaVuSans-101"/> + <use x="102.605469" xlink:href="#DejaVuSans-115"/> + <use x="154.705078" xlink:href="#DejaVuSans-97"/> + <use x="215.984375" xlink:href="#DejaVuSans-109"/> + <use x="313.396484" xlink:href="#DejaVuSans-112"/> + <use x="376.873047" xlink:href="#DejaVuSans-108"/> + <use x="404.65625" xlink:href="#DejaVuSans-101"/> + <use x="466.179688" xlink:href="#DejaVuSans-100"/> + <use x="529.65625" xlink:href="#DejaVuSans-32"/> + <use x="561.443359" xlink:href="#DejaVuSans-112"/> + <use x="624.919922" xlink:href="#DejaVuSans-97"/> + <use x="686.199219" xlink:href="#DejaVuSans-114"/> + <use x="727.3125" xlink:href="#DejaVuSans-116"/> + <use x="766.521484" xlink:href="#DejaVuSans-105"/> + <use x="794.304688" xlink:href="#DejaVuSans-99"/> + <use x="849.285156" xlink:href="#DejaVuSans-108"/> + <use x="877.068359" xlink:href="#DejaVuSans-101"/> + <use x="938.591797" xlink:href="#DejaVuSans-115"/> + </g> + </g> + </g> + </g> + <defs> + <clipPath id="pfc40d23fab"> + <rect height="114.16152" width="326.16" x="16.2" y="35.73648"/> + </clipPath> + <clipPath id="pa6df66d423"> + <rect height="114.16152" width="326.16" x="368.1" y="35.73648"/> + </clipPath> + <clipPath id="p8b647610fc"> + <rect height="114.16152" width="326.16" x="16.2" y="206.94888"/> + </clipPath> + <clipPath id="p743c85a154"> + <rect height="114.16152" width="326.16" x="368.1" y="206.94888"/> + </clipPath> + </defs> +</svg> diff --git a/latex_and_figures/figs/ch_filters/prob_sampling_1000samples.png b/latex_and_figures/figs/ch_filters/prob_sampling_1000samples.png new file mode 100644 index 0000000000000000000000000000000000000000..6899bfc0ede5d028c179280950cb57682db11c65 Binary files /dev/null and b/latex_and_figures/figs/ch_filters/prob_sampling_1000samples.png differ diff --git a/latex_and_figures/figs/ch_filters/prob_sampling_1000samples.svg b/latex_and_figures/figs/ch_filters/prob_sampling_1000samples.svg new file mode 100644 index 0000000000000000000000000000000000000000..c95df5dfc3be3da35b562d41a6018adc7c233980 --- /dev/null +++ b/latex_and_figures/figs/ch_filters/prob_sampling_1000samples.svg @@ -0,0 +1,3965 @@ +<?xml version="1.0" encoding="utf-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Created with matplotlib (https://matplotlib.org/) --> +<svg height="358.56pt" version="1.1" viewBox="0 0 936 358.56" width="936pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <defs> + <style type="text/css"> +*{stroke-linecap:butt;stroke-linejoin:round;white-space:pre;} + </style> + </defs> + <g id="figure_1"> + <g id="patch_1"> + <path d="M 0 358.56 +L 936 358.56 +L 936 0 +L 0 0 +z +" style="fill:#ffffff;"/> + </g> + <g id="axes_1"> + <g id="patch_2"> + <path d="M 83.63 296.32992 +L 448.02 296.32992 +L 448.02 18.28656 +L 83.63 18.28656 +z +" style="fill:#ffffff;"/> + </g> + <g id="matplotlib.axis_1"> + <g id="xtick_1"> + <g id="line2d_1"> + <defs> + <path d="M 0 0 +L 0 3.5 +" id="m304933a64d" style="stroke:#000000;stroke-width:0.8;"/> + </defs> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="83.63" xlink:href="#m304933a64d" y="296.32992"/> + </g> + </g> + <g id="text_1"> + <!-- −40 --> + <defs> + <path d="M 10.59375 35.5 +L 73.1875 35.5 +L 73.1875 27.203125 +L 10.59375 27.203125 +z +" id="DejaVuSans-8722"/> + <path d="M 37.796875 64.3125 +L 12.890625 25.390625 +L 37.796875 25.390625 +z +M 35.203125 72.90625 +L 47.609375 72.90625 +L 47.609375 25.390625 +L 58.015625 25.390625 +L 58.015625 17.1875 +L 47.609375 17.1875 +L 47.609375 0 +L 37.796875 0 +L 37.796875 17.1875 +L 4.890625 17.1875 +L 4.890625 26.703125 +z +" id="DejaVuSans-52"/> + <path d="M 31.78125 66.40625 +Q 24.171875 66.40625 20.328125 58.90625 +Q 16.5 51.421875 16.5 36.375 +Q 16.5 21.390625 20.328125 13.890625 +Q 24.171875 6.390625 31.78125 6.390625 +Q 39.453125 6.390625 43.28125 13.890625 +Q 47.125 21.390625 47.125 36.375 +Q 47.125 51.421875 43.28125 58.90625 +Q 39.453125 66.40625 31.78125 66.40625 +z +M 31.78125 74.21875 +Q 44.046875 74.21875 50.515625 64.515625 +Q 56.984375 54.828125 56.984375 36.375 +Q 56.984375 17.96875 50.515625 8.265625 +Q 44.046875 -1.421875 31.78125 -1.421875 +Q 19.53125 -1.421875 13.0625 8.265625 +Q 6.59375 17.96875 6.59375 36.375 +Q 6.59375 54.828125 13.0625 64.515625 +Q 19.53125 74.21875 31.78125 74.21875 +z +" id="DejaVuSans-48"/> + </defs> + <g transform="translate(65.691016 316.247264)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-8722"/> + <use x="83.789062" xlink:href="#DejaVuSans-52"/> + <use x="147.412109" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="xtick_2"> + <g id="line2d_2"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="174.7275" xlink:href="#m304933a64d" y="296.32992"/> + </g> + </g> + <g id="text_2"> + <!-- −20 --> + <defs> + <path d="M 19.1875 8.296875 +L 53.609375 8.296875 +L 53.609375 0 +L 7.328125 0 +L 7.328125 8.296875 +Q 12.9375 14.109375 22.625 23.890625 +Q 32.328125 33.6875 34.8125 36.53125 +Q 39.546875 41.84375 41.421875 45.53125 +Q 43.3125 49.21875 43.3125 52.78125 +Q 43.3125 58.59375 39.234375 62.25 +Q 35.15625 65.921875 28.609375 65.921875 +Q 23.96875 65.921875 18.8125 64.3125 +Q 13.671875 62.703125 7.8125 59.421875 +L 7.8125 69.390625 +Q 13.765625 71.78125 18.9375 73 +Q 24.125 74.21875 28.421875 74.21875 +Q 39.75 74.21875 46.484375 68.546875 +Q 53.21875 62.890625 53.21875 53.421875 +Q 53.21875 48.921875 51.53125 44.890625 +Q 49.859375 40.875 45.40625 35.40625 +Q 44.1875 33.984375 37.640625 27.21875 +Q 31.109375 20.453125 19.1875 8.296875 +z +" id="DejaVuSans-50"/> + </defs> + <g transform="translate(156.788516 316.247264)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-8722"/> + <use x="83.789062" xlink:href="#DejaVuSans-50"/> + <use x="147.412109" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="xtick_3"> + <g id="line2d_3"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="265.825" xlink:href="#m304933a64d" y="296.32992"/> + </g> + </g> + <g id="text_3"> + <!-- 0 --> + <g transform="translate(260.416875 316.247264)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="xtick_4"> + <g id="line2d_4"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="356.9225" xlink:href="#m304933a64d" y="296.32992"/> + </g> + </g> + <g id="text_4"> + <!-- 20 --> + <g transform="translate(346.10625 316.247264)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-50"/> + <use x="63.623047" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="xtick_5"> + <g id="line2d_5"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="448.02" xlink:href="#m304933a64d" y="296.32992"/> + </g> + </g> + <g id="text_5"> + <!-- 40 --> + <g transform="translate(437.20375 316.247264)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-52"/> + <use x="63.623047" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="text_6"> + <!-- x --> + <defs> + <path d="M 54.890625 54.6875 +L 35.109375 28.078125 +L 55.90625 0 +L 45.3125 0 +L 29.390625 21.484375 +L 13.484375 0 +L 2.875 0 +L 24.125 28.609375 +L 4.6875 54.6875 +L 15.28125 54.6875 +L 29.78125 35.203125 +L 44.28125 54.6875 +z +" id="DejaVuSans-120"/> + </defs> + <g transform="translate(260.794063 336.700076)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-120"/> + </g> + </g> + </g> + <g id="matplotlib.axis_2"> + <g id="ytick_1"> + <g id="line2d_6"> + <defs> + <path d="M 0 0 +L -3.5 0 +" id="md18a56d055" style="stroke:#000000;stroke-width:0.8;"/> + </defs> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="83.63" xlink:href="#md18a56d055" y="296.32992"/> + </g> + </g> + <g id="text_7"> + <!-- 0.00 --> + <defs> + <path d="M 10.6875 12.40625 +L 21 12.40625 +L 21 0 +L 10.6875 0 +z +" id="DejaVuSans-46"/> + </defs> + <g transform="translate(38.778438 302.788592)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-48"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-48"/> + <use x="159.033203" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="ytick_2"> + <g id="line2d_7"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="83.63" xlink:href="#md18a56d055" y="240.721248"/> + </g> + </g> + <g id="text_8"> + <!-- 0.01 --> + <defs> + <path d="M 12.40625 8.296875 +L 28.515625 8.296875 +L 28.515625 63.921875 +L 10.984375 60.40625 +L 10.984375 69.390625 +L 28.421875 72.90625 +L 38.28125 72.90625 +L 38.28125 8.296875 +L 54.390625 8.296875 +L 54.390625 0 +L 12.40625 0 +z +" id="DejaVuSans-49"/> + </defs> + <g transform="translate(38.778438 247.17992)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-48"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-48"/> + <use x="159.033203" xlink:href="#DejaVuSans-49"/> + </g> + </g> + </g> + <g id="ytick_3"> + <g id="line2d_8"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="83.63" xlink:href="#md18a56d055" y="185.112576"/> + </g> + </g> + <g id="text_9"> + <!-- 0.02 --> + <g transform="translate(38.778438 191.571248)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-48"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-48"/> + <use x="159.033203" xlink:href="#DejaVuSans-50"/> + </g> + </g> + </g> + <g id="ytick_4"> + <g id="line2d_9"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="83.63" xlink:href="#md18a56d055" y="129.503904"/> + </g> + </g> + <g id="text_10"> + <!-- 0.03 --> + <defs> + <path d="M 40.578125 39.3125 +Q 47.65625 37.796875 51.625 33 +Q 55.609375 28.21875 55.609375 21.1875 +Q 55.609375 10.40625 48.1875 4.484375 +Q 40.765625 -1.421875 27.09375 -1.421875 +Q 22.515625 -1.421875 17.65625 -0.515625 +Q 12.796875 0.390625 7.625 2.203125 +L 7.625 11.71875 +Q 11.71875 9.328125 16.59375 8.109375 +Q 21.484375 6.890625 26.8125 6.890625 +Q 36.078125 6.890625 40.9375 10.546875 +Q 45.796875 14.203125 45.796875 21.1875 +Q 45.796875 27.640625 41.28125 31.265625 +Q 36.765625 34.90625 28.71875 34.90625 +L 20.21875 34.90625 +L 20.21875 43.015625 +L 29.109375 43.015625 +Q 36.375 43.015625 40.234375 45.921875 +Q 44.09375 48.828125 44.09375 54.296875 +Q 44.09375 59.90625 40.109375 62.90625 +Q 36.140625 65.921875 28.71875 65.921875 +Q 24.65625 65.921875 20.015625 65.03125 +Q 15.375 64.15625 9.8125 62.3125 +L 9.8125 71.09375 +Q 15.4375 72.65625 20.34375 73.4375 +Q 25.25 74.21875 29.59375 74.21875 +Q 40.828125 74.21875 47.359375 69.109375 +Q 53.90625 64.015625 53.90625 55.328125 +Q 53.90625 49.265625 50.4375 45.09375 +Q 46.96875 40.921875 40.578125 39.3125 +z +" id="DejaVuSans-51"/> + </defs> + <g transform="translate(38.778438 135.962576)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-48"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-48"/> + <use x="159.033203" xlink:href="#DejaVuSans-51"/> + </g> + </g> + </g> + <g id="ytick_5"> + <g id="line2d_10"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="83.63" xlink:href="#md18a56d055" y="73.895232"/> + </g> + </g> + <g id="text_11"> + <!-- 0.04 --> + <g transform="translate(38.778438 80.353904)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-48"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-48"/> + <use x="159.033203" xlink:href="#DejaVuSans-52"/> + </g> + </g> + </g> + <g id="text_12"> + <!-- p(x) --> + <defs> + <path d="M 18.109375 8.203125 +L 18.109375 -20.796875 +L 9.078125 -20.796875 +L 9.078125 54.6875 +L 18.109375 54.6875 +L 18.109375 46.390625 +Q 20.953125 51.265625 25.265625 53.625 +Q 29.59375 56 35.59375 56 +Q 45.5625 56 51.78125 48.09375 +Q 58.015625 40.1875 58.015625 27.296875 +Q 58.015625 14.40625 51.78125 6.484375 +Q 45.5625 -1.421875 35.59375 -1.421875 +Q 29.59375 -1.421875 25.265625 0.953125 +Q 20.953125 3.328125 18.109375 8.203125 +z +M 48.6875 27.296875 +Q 48.6875 37.203125 44.609375 42.84375 +Q 40.53125 48.484375 33.40625 48.484375 +Q 26.265625 48.484375 22.1875 42.84375 +Q 18.109375 37.203125 18.109375 27.296875 +Q 18.109375 17.390625 22.1875 11.75 +Q 26.265625 6.109375 33.40625 6.109375 +Q 40.53125 6.109375 44.609375 11.75 +Q 48.6875 17.390625 48.6875 27.296875 +z +" id="DejaVuSans-112"/> + <path d="M 31 75.875 +Q 24.46875 64.65625 21.28125 53.65625 +Q 18.109375 42.671875 18.109375 31.390625 +Q 18.109375 20.125 21.3125 9.0625 +Q 24.515625 -2 31 -13.1875 +L 23.1875 -13.1875 +Q 15.875 -1.703125 12.234375 9.375 +Q 8.59375 20.453125 8.59375 31.390625 +Q 8.59375 42.28125 12.203125 53.3125 +Q 15.828125 64.359375 23.1875 75.875 +z +" id="DejaVuSans-40"/> + <path d="M 8.015625 75.875 +L 15.828125 75.875 +Q 23.140625 64.359375 26.78125 53.3125 +Q 30.421875 42.28125 30.421875 31.390625 +Q 30.421875 20.453125 26.78125 9.375 +Q 23.140625 -1.703125 15.828125 -13.1875 +L 8.015625 -13.1875 +Q 14.5 -2 17.703125 9.0625 +Q 20.90625 20.125 20.90625 31.390625 +Q 20.90625 42.671875 17.703125 53.65625 +Q 14.5 64.65625 8.015625 75.875 +z +" id="DejaVuSans-41"/> + </defs> + <g transform="translate(31.242969 174.368006)rotate(-90)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-112"/> + <use x="63.476562" xlink:href="#DejaVuSans-40"/> + <use x="102.490234" xlink:href="#DejaVuSans-120"/> + <use x="161.669922" xlink:href="#DejaVuSans-41"/> + </g> + </g> + </g> + <g id="EventCollection_1"> + <path clip-path="url(#pdb6ddb23b2)" d="M 138.976805 240.721248 +L 138.976805 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 139.175747 240.721248 +L 139.175747 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 139.522563 240.721248 +L 139.522563 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 144.721672 240.721248 +L 144.721672 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 160.428023 240.721248 +L 160.428023 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 161.192128 240.721248 +L 161.192128 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 162.619278 240.721248 +L 162.619278 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 164.519545 240.721248 +L 164.519545 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 165.973615 240.721248 +L 165.973615 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 166.438592 240.721248 +L 166.438592 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 168.180859 240.721248 +L 168.180859 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 168.210883 240.721248 +L 168.210883 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 169.155071 240.721248 +L 169.155071 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 169.395613 240.721248 +L 169.395613 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 170.125367 240.721248 +L 170.125367 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 171.87493 240.721248 +L 171.87493 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 172.438278 240.721248 +L 172.438278 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 177.308109 240.721248 +L 177.308109 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 179.252502 240.721248 +L 179.252502 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 180.554541 240.721248 +L 180.554541 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 181.003024 240.721248 +L 181.003024 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 181.20526 240.721248 +L 181.20526 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 182.441484 240.721248 +L 182.441484 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 183.246099 240.721248 +L 183.246099 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 185.029371 240.721248 +L 185.029371 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 185.653645 240.721248 +L 185.653645 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 186.269085 240.721248 +L 186.269085 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 186.454455 240.721248 +L 186.454455 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 188.246341 240.721248 +L 188.246341 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 188.301094 240.721248 +L 188.301094 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 189.133774 240.721248 +L 189.133774 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 189.680282 240.721248 +L 189.680282 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 189.753823 240.721248 +L 189.753823 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 190.129446 240.721248 +L 190.129446 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 190.265808 240.721248 +L 190.265808 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 190.300152 240.721248 +L 190.300152 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 191.760472 240.721248 +L 191.760472 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 192.359779 240.721248 +L 192.359779 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 192.373795 240.721248 +L 192.373795 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 192.854964 240.721248 +L 192.854964 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 192.943089 240.721248 +L 192.943089 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 193.038098 240.721248 +L 193.038098 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 193.499249 240.721248 +L 193.499249 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 194.009071 240.721248 +L 194.009071 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 194.098852 240.721248 +L 194.098852 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 195.30648 240.721248 +L 195.30648 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 195.54544 240.721248 +L 195.54544 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 196.699966 240.721248 +L 196.699966 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 196.837697 240.721248 +L 196.837697 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 197.003466 240.721248 +L 197.003466 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 197.354831 240.721248 +L 197.354831 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 197.36198 240.721248 +L 197.36198 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 197.412038 240.721248 +L 197.412038 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 197.45975 240.721248 +L 197.45975 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 197.528881 240.721248 +L 197.528881 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 197.734145 240.721248 +L 197.734145 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 198.002197 240.721248 +L 198.002197 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 198.295595 240.721248 +L 198.295595 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 198.608317 240.721248 +L 198.608317 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 198.751673 240.721248 +L 198.751673 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 199.37771 240.721248 +L 199.37771 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 200.320726 240.721248 +L 200.320726 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 200.792255 240.721248 +L 200.792255 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 201.250397 240.721248 +L 201.250397 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 202.441993 240.721248 +L 202.441993 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 202.463527 240.721248 +L 202.463527 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 202.505371 240.721248 +L 202.505371 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 202.571726 240.721248 +L 202.571726 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 202.731274 240.721248 +L 202.731274 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 203.594808 240.721248 +L 203.594808 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 203.700093 240.721248 +L 203.700093 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 204.128617 240.721248 +L 204.128617 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 204.233302 240.721248 +L 204.233302 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 204.325671 240.721248 +L 204.325671 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 204.606264 240.721248 +L 204.606264 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 204.70278 240.721248 +L 204.70278 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 204.999096 240.721248 +L 204.999096 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 205.073482 240.721248 +L 205.073482 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 205.12979 240.721248 +L 205.12979 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 205.208659 240.721248 +L 205.208659 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 205.770345 240.721248 +L 205.770345 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 205.86922 240.721248 +L 205.86922 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 206.110121 240.721248 +L 206.110121 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 206.263969 240.721248 +L 206.263969 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 206.44719 240.721248 +L 206.44719 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 206.481837 240.721248 +L 206.481837 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 206.772545 240.721248 +L 206.772545 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 206.924701 240.721248 +L 206.924701 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 207.143949 240.721248 +L 207.143949 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 207.391472 240.721248 +L 207.391472 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 207.634792 240.721248 +L 207.634792 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 207.887066 240.721248 +L 207.887066 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 208.202774 240.721248 +L 208.202774 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 208.565113 240.721248 +L 208.565113 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 208.593809 240.721248 +L 208.593809 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 208.711098 240.721248 +L 208.711098 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 208.785001 240.721248 +L 208.785001 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 208.929731 240.721248 +L 208.929731 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 208.934868 240.721248 +L 208.934868 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 208.981886 240.721248 +L 208.981886 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 209.378613 240.721248 +L 209.378613 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 209.447298 240.721248 +L 209.447298 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 209.590581 240.721248 +L 209.590581 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 209.943026 240.721248 +L 209.943026 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 210.077126 240.721248 +L 210.077126 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 210.277343 240.721248 +L 210.277343 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 210.674796 240.721248 +L 210.674796 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 210.679739 240.721248 +L 210.679739 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 210.767152 240.721248 +L 210.767152 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 211.008394 240.721248 +L 211.008394 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 211.840635 240.721248 +L 211.840635 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 211.857726 240.721248 +L 211.857726 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 212.122995 240.721248 +L 212.122995 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 212.150329 240.721248 +L 212.150329 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 212.273894 240.721248 +L 212.273894 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 212.366235 240.721248 +L 212.366235 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 212.487697 240.721248 +L 212.487697 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 212.765234 240.721248 +L 212.765234 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 212.914703 240.721248 +L 212.914703 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 212.917784 240.721248 +L 212.917784 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 212.967537 240.721248 +L 212.967537 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 212.992277 240.721248 +L 212.992277 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 213.207079 240.721248 +L 213.207079 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 213.242047 240.721248 +L 213.242047 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 213.53451 240.721248 +L 213.53451 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 213.966364 240.721248 +L 213.966364 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 214.172413 240.721248 +L 214.172413 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 214.265291 240.721248 +L 214.265291 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 214.354884 240.721248 +L 214.354884 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 214.991191 240.721248 +L 214.991191 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 215.18221 240.721248 +L 215.18221 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 215.32583 240.721248 +L 215.32583 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 215.37643 240.721248 +L 215.37643 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 215.386324 240.721248 +L 215.386324 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 215.447789 240.721248 +L 215.447789 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 215.622119 240.721248 +L 215.622119 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 215.869437 240.721248 +L 215.869437 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 216.068863 240.721248 +L 216.068863 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 216.312275 240.721248 +L 216.312275 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 216.545271 240.721248 +L 216.545271 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 216.579446 240.721248 +L 216.579446 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 217.358784 240.721248 +L 217.358784 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 217.421241 240.721248 +L 217.421241 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 217.570776 240.721248 +L 217.570776 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 217.732332 240.721248 +L 217.732332 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 218.03794 240.721248 +L 218.03794 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 218.749442 240.721248 +L 218.749442 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 218.879941 240.721248 +L 218.879941 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 218.900628 240.721248 +L 218.900628 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 219.137263 240.721248 +L 219.137263 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 219.291454 240.721248 +L 219.291454 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 219.3307 240.721248 +L 219.3307 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 219.363682 240.721248 +L 219.363682 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 219.57269 240.721248 +L 219.57269 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 219.787092 240.721248 +L 219.787092 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 219.887596 240.721248 +L 219.887596 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 219.978328 240.721248 +L 219.978328 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 220.357459 240.721248 +L 220.357459 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 220.43136 240.721248 +L 220.43136 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 220.491793 240.721248 +L 220.491793 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 220.54803 240.721248 +L 220.54803 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 220.908205 240.721248 +L 220.908205 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 220.964326 240.721248 +L 220.964326 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 221.123899 240.721248 +L 221.123899 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 221.471822 240.721248 +L 221.471822 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 221.489121 240.721248 +L 221.489121 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 221.880538 240.721248 +L 221.880538 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 222.118927 240.721248 +L 222.118927 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 222.238438 240.721248 +L 222.238438 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 222.361458 240.721248 +L 222.361458 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 222.72939 240.721248 +L 222.72939 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 222.885667 240.721248 +L 222.885667 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 223.013728 240.721248 +L 223.013728 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 223.01711 240.721248 +L 223.01711 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 223.030979 240.721248 +L 223.030979 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 223.143524 240.721248 +L 223.143524 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 223.166363 240.721248 +L 223.166363 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 223.213065 240.721248 +L 223.213065 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 223.536151 240.721248 +L 223.536151 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 223.6201 240.721248 +L 223.6201 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 223.893631 240.721248 +L 223.893631 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 224.022012 240.721248 +L 224.022012 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 224.250759 240.721248 +L 224.250759 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 224.282593 240.721248 +L 224.282593 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 225.142052 240.721248 +L 225.142052 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 225.181243 240.721248 +L 225.181243 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 225.467397 240.721248 +L 225.467397 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 225.892924 240.721248 +L 225.892924 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 226.028457 240.721248 +L 226.028457 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 226.030726 240.721248 +L 226.030726 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 226.143137 240.721248 +L 226.143137 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 226.22514 240.721248 +L 226.22514 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 226.420777 240.721248 +L 226.420777 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 226.782077 240.721248 +L 226.782077 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 226.789506 240.721248 +L 226.789506 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 226.902959 240.721248 +L 226.902959 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 227.377385 240.721248 +L 227.377385 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 227.638061 240.721248 +L 227.638061 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 227.723536 240.721248 +L 227.723536 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 228.05906 240.721248 +L 228.05906 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 228.305054 240.721248 +L 228.305054 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 228.504783 240.721248 +L 228.504783 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 228.628747 240.721248 +L 228.628747 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 228.715953 240.721248 +L 228.715953 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 228.884032 240.721248 +L 228.884032 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 229.203884 240.721248 +L 229.203884 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 229.324713 240.721248 +L 229.324713 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 229.531283 240.721248 +L 229.531283 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 229.620869 240.721248 +L 229.620869 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 229.862332 240.721248 +L 229.862332 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 230.032216 240.721248 +L 230.032216 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 230.069258 240.721248 +L 230.069258 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 230.244248 240.721248 +L 230.244248 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 230.340885 240.721248 +L 230.340885 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 230.523511 240.721248 +L 230.523511 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 230.713797 240.721248 +L 230.713797 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 230.724355 240.721248 +L 230.724355 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 230.860451 240.721248 +L 230.860451 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 230.930822 240.721248 +L 230.930822 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 231.085388 240.721248 +L 231.085388 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 231.165617 240.721248 +L 231.165617 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 231.269404 240.721248 +L 231.269404 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 231.278695 240.721248 +L 231.278695 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 231.478144 240.721248 +L 231.478144 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 231.894223 240.721248 +L 231.894223 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 231.901179 240.721248 +L 231.901179 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 231.928117 240.721248 +L 231.928117 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 232.301651 240.721248 +L 232.301651 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 232.387401 240.721248 +L 232.387401 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 232.845213 240.721248 +L 232.845213 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 232.864169 240.721248 +L 232.864169 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 232.995485 240.721248 +L 232.995485 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 233.026241 240.721248 +L 233.026241 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 233.071684 240.721248 +L 233.071684 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 233.24929 240.721248 +L 233.24929 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 233.408347 240.721248 +L 233.408347 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 233.941673 240.721248 +L 233.941673 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 234.022303 240.721248 +L 234.022303 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 234.113734 240.721248 +L 234.113734 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 234.190608 240.721248 +L 234.190608 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 234.418534 240.721248 +L 234.418534 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 234.462577 240.721248 +L 234.462577 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 234.827284 240.721248 +L 234.827284 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 234.885838 240.721248 +L 234.885838 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 235.10314 240.721248 +L 235.10314 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 235.117588 240.721248 +L 235.117588 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 235.148483 240.721248 +L 235.148483 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 235.228144 240.721248 +L 235.228144 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 235.318328 240.721248 +L 235.318328 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 235.428341 240.721248 +L 235.428341 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 235.563697 240.721248 +L 235.563697 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 235.75197 240.721248 +L 235.75197 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 236.012703 240.721248 +L 236.012703 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 236.157817 240.721248 +L 236.157817 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 236.258621 240.721248 +L 236.258621 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 236.461816 240.721248 +L 236.461816 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 236.529808 240.721248 +L 236.529808 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 236.609393 240.721248 +L 236.609393 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 237.392436 240.721248 +L 237.392436 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 237.400267 240.721248 +L 237.400267 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 237.500753 240.721248 +L 237.500753 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 237.545893 240.721248 +L 237.545893 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 237.887644 240.721248 +L 237.887644 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 238.011024 240.721248 +L 238.011024 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 238.160079 240.721248 +L 238.160079 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 238.293162 240.721248 +L 238.293162 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 238.49907 240.721248 +L 238.49907 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 238.502811 240.721248 +L 238.502811 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 238.616679 240.721248 +L 238.616679 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 238.653733 240.721248 +L 238.653733 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 238.670586 240.721248 +L 238.670586 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 238.749082 240.721248 +L 238.749082 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 239.06843 240.721248 +L 239.06843 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 239.17753 240.721248 +L 239.17753 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 239.19362 240.721248 +L 239.19362 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 239.3287 240.721248 +L 239.3287 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 239.37319 240.721248 +L 239.37319 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 239.466454 240.721248 +L 239.466454 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 239.704895 240.721248 +L 239.704895 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 239.949153 240.721248 +L 239.949153 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 240.053867 240.721248 +L 240.053867 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 240.118356 240.721248 +L 240.118356 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 240.121785 240.721248 +L 240.121785 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 240.245261 240.721248 +L 240.245261 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 241.085257 240.721248 +L 241.085257 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 241.187711 240.721248 +L 241.187711 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 241.191844 240.721248 +L 241.191844 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 241.251723 240.721248 +L 241.251723 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 241.548778 240.721248 +L 241.548778 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 241.670389 240.721248 +L 241.670389 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 241.706103 240.721248 +L 241.706103 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 241.743342 240.721248 +L 241.743342 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 241.831596 240.721248 +L 241.831596 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 242.067038 240.721248 +L 242.067038 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 242.335213 240.721248 +L 242.335213 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 242.448627 240.721248 +L 242.448627 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 242.503865 240.721248 +L 242.503865 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 242.771783 240.721248 +L 242.771783 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 242.820787 240.721248 +L 242.820787 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 242.886538 240.721248 +L 242.886538 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 242.947642 240.721248 +L 242.947642 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 243.011942 240.721248 +L 243.011942 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 243.027027 240.721248 +L 243.027027 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 243.101367 240.721248 +L 243.101367 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 243.210224 240.721248 +L 243.210224 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 243.23432 240.721248 +L 243.23432 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 243.273397 240.721248 +L 243.273397 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 243.574361 240.721248 +L 243.574361 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 243.581966 240.721248 +L 243.581966 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 243.614835 240.721248 +L 243.614835 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 243.933856 240.721248 +L 243.933856 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 243.940202 240.721248 +L 243.940202 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 244.089567 240.721248 +L 244.089567 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 244.409142 240.721248 +L 244.409142 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 244.646752 240.721248 +L 244.646752 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 244.715895 240.721248 +L 244.715895 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 244.721231 240.721248 +L 244.721231 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 244.953744 240.721248 +L 244.953744 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 245.100382 240.721248 +L 245.100382 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 245.117826 240.721248 +L 245.117826 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 245.7359 240.721248 +L 245.7359 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 245.768423 240.721248 +L 245.768423 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 245.768976 240.721248 +L 245.768976 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 245.860795 240.721248 +L 245.860795 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 246.050814 240.721248 +L 246.050814 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 246.334394 240.721248 +L 246.334394 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 246.351663 240.721248 +L 246.351663 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 246.417807 240.721248 +L 246.417807 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 246.458427 240.721248 +L 246.458427 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 246.576641 240.721248 +L 246.576641 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 246.66639 240.721248 +L 246.66639 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 246.694168 240.721248 +L 246.694168 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 246.774251 240.721248 +L 246.774251 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 246.821263 240.721248 +L 246.821263 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 246.879403 240.721248 +L 246.879403 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 246.915987 240.721248 +L 246.915987 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 246.988332 240.721248 +L 246.988332 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 247.011911 240.721248 +L 247.011911 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 247.03184 240.721248 +L 247.03184 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 247.189385 240.721248 +L 247.189385 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 247.243738 240.721248 +L 247.243738 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 247.348352 240.721248 +L 247.348352 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 247.442572 240.721248 +L 247.442572 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 247.485175 240.721248 +L 247.485175 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 247.502451 240.721248 +L 247.502451 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 247.575172 240.721248 +L 247.575172 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 247.727138 240.721248 +L 247.727138 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 247.871617 240.721248 +L 247.871617 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 248.10293 240.721248 +L 248.10293 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 248.146897 240.721248 +L 248.146897 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 248.199735 240.721248 +L 248.199735 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 248.277031 240.721248 +L 248.277031 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 248.379651 240.721248 +L 248.379651 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 248.610556 240.721248 +L 248.610556 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 249.077683 240.721248 +L 249.077683 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 249.144754 240.721248 +L 249.144754 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 249.196669 240.721248 +L 249.196669 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 249.384841 240.721248 +L 249.384841 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 249.414003 240.721248 +L 249.414003 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 249.569256 240.721248 +L 249.569256 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 249.609147 240.721248 +L 249.609147 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 249.676599 240.721248 +L 249.676599 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 249.685851 240.721248 +L 249.685851 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 249.818079 240.721248 +L 249.818079 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 249.824808 240.721248 +L 249.824808 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 249.858466 240.721248 +L 249.858466 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 249.982329 240.721248 +L 249.982329 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 250.172335 240.721248 +L 250.172335 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 250.180993 240.721248 +L 250.180993 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 250.487028 240.721248 +L 250.487028 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 250.614878 240.721248 +L 250.614878 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 250.618629 240.721248 +L 250.618629 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 250.745796 240.721248 +L 250.745796 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 250.910854 240.721248 +L 250.910854 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 250.926583 240.721248 +L 250.926583 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 250.982138 240.721248 +L 250.982138 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 251.072404 240.721248 +L 251.072404 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 251.124231 240.721248 +L 251.124231 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 251.15669 240.721248 +L 251.15669 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 251.220279 240.721248 +L 251.220279 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 251.241617 240.721248 +L 251.241617 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 251.292931 240.721248 +L 251.292931 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 251.494869 240.721248 +L 251.494869 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 251.631539 240.721248 +L 251.631539 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 251.711742 240.721248 +L 251.711742 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 251.788763 240.721248 +L 251.788763 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 251.81541 240.721248 +L 251.81541 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 251.968161 240.721248 +L 251.968161 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 252.164037 240.721248 +L 252.164037 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 252.216844 240.721248 +L 252.216844 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 252.45023 240.721248 +L 252.45023 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 252.720026 240.721248 +L 252.720026 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 252.918781 240.721248 +L 252.918781 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 252.958549 240.721248 +L 252.958549 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 253.269237 240.721248 +L 253.269237 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 253.392152 240.721248 +L 253.392152 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 253.413268 240.721248 +L 253.413268 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 253.815037 240.721248 +L 253.815037 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 253.842112 240.721248 +L 253.842112 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 253.880338 240.721248 +L 253.880338 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 253.901485 240.721248 +L 253.901485 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 253.932096 240.721248 +L 253.932096 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 254.106996 240.721248 +L 254.106996 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 254.184964 240.721248 +L 254.184964 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 254.251787 240.721248 +L 254.251787 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 254.440116 240.721248 +L 254.440116 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 254.637966 240.721248 +L 254.637966 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 254.739263 240.721248 +L 254.739263 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 254.859869 240.721248 +L 254.859869 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 255.066693 240.721248 +L 255.066693 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 255.784644 240.721248 +L 255.784644 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 255.97418 240.721248 +L 255.97418 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 256.152227 240.721248 +L 256.152227 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 256.379159 240.721248 +L 256.379159 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 256.57042 240.721248 +L 256.57042 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 256.634812 240.721248 +L 256.634812 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 256.762025 240.721248 +L 256.762025 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 256.809498 240.721248 +L 256.809498 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 256.843891 240.721248 +L 256.843891 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 256.858997 240.721248 +L 256.858997 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 256.99305 240.721248 +L 256.99305 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 257.019174 240.721248 +L 257.019174 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 257.098397 240.721248 +L 257.098397 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 257.102953 240.721248 +L 257.102953 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 257.201496 240.721248 +L 257.201496 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 257.411957 240.721248 +L 257.411957 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 257.413191 240.721248 +L 257.413191 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 257.605469 240.721248 +L 257.605469 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 257.820813 240.721248 +L 257.820813 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 257.852153 240.721248 +L 257.852153 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 257.902776 240.721248 +L 257.902776 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 257.927698 240.721248 +L 257.927698 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 258.225253 240.721248 +L 258.225253 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 258.332507 240.721248 +L 258.332507 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 258.393006 240.721248 +L 258.393006 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 258.546234 240.721248 +L 258.546234 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 258.593412 240.721248 +L 258.593412 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 258.622405 240.721248 +L 258.622405 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 258.849421 240.721248 +L 258.849421 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 258.878171 240.721248 +L 258.878171 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 259.075154 240.721248 +L 259.075154 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 259.142617 240.721248 +L 259.142617 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 259.169033 240.721248 +L 259.169033 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 259.343975 240.721248 +L 259.343975 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 260.027569 240.721248 +L 260.027569 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 260.163081 240.721248 +L 260.163081 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 260.307082 240.721248 +L 260.307082 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 260.321161 240.721248 +L 260.321161 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 260.380631 240.721248 +L 260.380631 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 260.600682 240.721248 +L 260.600682 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 260.612145 240.721248 +L 260.612145 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 260.627166 240.721248 +L 260.627166 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 260.633682 240.721248 +L 260.633682 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 260.661611 240.721248 +L 260.661611 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 260.758607 240.721248 +L 260.758607 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 260.872232 240.721248 +L 260.872232 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 260.879597 240.721248 +L 260.879597 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 260.938405 240.721248 +L 260.938405 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 260.996009 240.721248 +L 260.996009 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 260.999063 240.721248 +L 260.999063 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 261.048158 240.721248 +L 261.048158 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 261.16745 240.721248 +L 261.16745 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 261.258015 240.721248 +L 261.258015 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 261.281104 240.721248 +L 261.281104 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 261.423262 240.721248 +L 261.423262 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 261.482418 240.721248 +L 261.482418 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 261.626862 240.721248 +L 261.626862 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 261.679034 240.721248 +L 261.679034 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 261.781905 240.721248 +L 261.781905 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 262.140268 240.721248 +L 262.140268 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 262.187505 240.721248 +L 262.187505 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 262.246447 240.721248 +L 262.246447 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 262.301182 240.721248 +L 262.301182 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 262.629009 240.721248 +L 262.629009 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 262.634367 240.721248 +L 262.634367 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 262.668045 240.721248 +L 262.668045 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 262.678291 240.721248 +L 262.678291 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 262.678698 240.721248 +L 262.678698 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 262.707559 240.721248 +L 262.707559 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 262.785181 240.721248 +L 262.785181 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 262.83458 240.721248 +L 262.83458 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 262.965304 240.721248 +L 262.965304 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 262.974172 240.721248 +L 262.974172 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 262.984503 240.721248 +L 262.984503 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 263.094165 240.721248 +L 263.094165 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 263.119761 240.721248 +L 263.119761 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 263.340544 240.721248 +L 263.340544 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 263.39971 240.721248 +L 263.39971 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 263.443723 240.721248 +L 263.443723 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 263.834846 240.721248 +L 263.834846 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 263.876789 240.721248 +L 263.876789 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 263.957611 240.721248 +L 263.957611 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 264.066603 240.721248 +L 264.066603 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 264.254831 240.721248 +L 264.254831 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 264.468002 240.721248 +L 264.468002 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 264.608516 240.721248 +L 264.608516 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 264.863666 240.721248 +L 264.863666 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 264.96106 240.721248 +L 264.96106 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 265.231702 240.721248 +L 265.231702 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 265.392034 240.721248 +L 265.392034 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 265.504178 240.721248 +L 265.504178 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 265.504881 240.721248 +L 265.504881 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 265.57643 240.721248 +L 265.57643 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 265.57816 240.721248 +L 265.57816 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 265.59339 240.721248 +L 265.59339 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 265.621256 240.721248 +L 265.621256 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 265.803579 240.721248 +L 265.803579 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 265.956884 240.721248 +L 265.956884 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 266.101742 240.721248 +L 266.101742 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 266.143971 240.721248 +L 266.143971 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 266.235999 240.721248 +L 266.235999 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 266.28327 240.721248 +L 266.28327 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 266.403892 240.721248 +L 266.403892 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 266.41747 240.721248 +L 266.41747 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 266.457286 240.721248 +L 266.457286 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 266.524364 240.721248 +L 266.524364 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 266.676883 240.721248 +L 266.676883 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 266.750223 240.721248 +L 266.750223 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 266.850189 240.721248 +L 266.850189 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 267.103507 240.721248 +L 267.103507 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 267.113081 240.721248 +L 267.113081 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 267.251107 240.721248 +L 267.251107 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 267.536706 240.721248 +L 267.536706 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 267.538188 240.721248 +L 267.538188 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 267.590634 240.721248 +L 267.590634 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 267.630583 240.721248 +L 267.630583 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 267.678872 240.721248 +L 267.678872 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 267.812097 240.721248 +L 267.812097 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 267.884049 240.721248 +L 267.884049 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 268.391393 240.721248 +L 268.391393 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 268.707906 240.721248 +L 268.707906 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 268.717585 240.721248 +L 268.717585 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 268.751862 240.721248 +L 268.751862 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 269.079057 240.721248 +L 269.079057 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 269.175779 240.721248 +L 269.175779 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 269.456157 240.721248 +L 269.456157 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 269.859737 240.721248 +L 269.859737 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 270.137544 240.721248 +L 270.137544 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 270.281653 240.721248 +L 270.281653 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 270.312124 240.721248 +L 270.312124 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 270.314611 240.721248 +L 270.314611 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 270.440497 240.721248 +L 270.440497 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 270.458908 240.721248 +L 270.458908 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 270.496069 240.721248 +L 270.496069 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 270.687233 240.721248 +L 270.687233 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 270.716449 240.721248 +L 270.716449 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 270.982097 240.721248 +L 270.982097 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 271.071473 240.721248 +L 271.071473 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 271.220403 240.721248 +L 271.220403 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 271.315821 240.721248 +L 271.315821 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 271.483831 240.721248 +L 271.483831 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 271.582862 240.721248 +L 271.582862 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 271.729044 240.721248 +L 271.729044 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 272.125744 240.721248 +L 272.125744 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 272.32695 240.721248 +L 272.32695 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 272.327048 240.721248 +L 272.327048 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 272.530864 240.721248 +L 272.530864 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 272.648233 240.721248 +L 272.648233 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 272.675375 240.721248 +L 272.675375 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 272.890719 240.721248 +L 272.890719 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 272.899793 240.721248 +L 272.899793 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 273.02189 240.721248 +L 273.02189 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 273.156259 240.721248 +L 273.156259 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 273.37356 240.721248 +L 273.37356 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 273.444367 240.721248 +L 273.444367 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 273.741517 240.721248 +L 273.741517 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 273.774893 240.721248 +L 273.774893 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 273.813708 240.721248 +L 273.813708 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 273.838158 240.721248 +L 273.838158 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 273.933392 240.721248 +L 273.933392 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 274.007638 240.721248 +L 274.007638 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 274.076416 240.721248 +L 274.076416 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 274.093114 240.721248 +L 274.093114 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 274.097861 240.721248 +L 274.097861 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 274.141976 240.721248 +L 274.141976 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 274.321716 240.721248 +L 274.321716 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 274.350071 240.721248 +L 274.350071 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 274.68344 240.721248 +L 274.68344 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 274.912898 240.721248 +L 274.912898 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 275.023578 240.721248 +L 275.023578 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 275.125722 240.721248 +L 275.125722 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 275.593998 240.721248 +L 275.593998 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 275.658939 240.721248 +L 275.658939 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 275.683213 240.721248 +L 275.683213 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 275.736007 240.721248 +L 275.736007 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 275.790212 240.721248 +L 275.790212 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 275.970768 240.721248 +L 275.970768 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 275.974921 240.721248 +L 275.974921 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 276.197604 240.721248 +L 276.197604 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 276.571021 240.721248 +L 276.571021 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 276.58788 240.721248 +L 276.58788 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 276.593749 240.721248 +L 276.593749 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 276.655091 240.721248 +L 276.655091 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 276.724959 240.721248 +L 276.724959 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 276.768137 240.721248 +L 276.768137 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 276.776249 240.721248 +L 276.776249 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 276.882994 240.721248 +L 276.882994 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 277.044731 240.721248 +L 277.044731 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 277.300481 240.721248 +L 277.300481 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 277.322663 240.721248 +L 277.322663 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 277.367773 240.721248 +L 277.367773 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 277.76589 240.721248 +L 277.76589 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 277.797567 240.721248 +L 277.797567 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 277.851004 240.721248 +L 277.851004 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 278.00381 240.721248 +L 278.00381 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 278.065452 240.721248 +L 278.065452 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 278.404581 240.721248 +L 278.404581 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 278.536071 240.721248 +L 278.536071 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 278.698868 240.721248 +L 278.698868 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 278.787562 240.721248 +L 278.787562 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 278.8719 240.721248 +L 278.8719 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 278.968039 240.721248 +L 278.968039 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 279.017583 240.721248 +L 279.017583 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 279.044638 240.721248 +L 279.044638 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 279.148061 240.721248 +L 279.148061 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 279.179589 240.721248 +L 279.179589 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 279.330116 240.721248 +L 279.330116 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 279.334478 240.721248 +L 279.334478 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 279.715508 240.721248 +L 279.715508 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 280.051198 240.721248 +L 280.051198 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 280.068413 240.721248 +L 280.068413 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 280.152134 240.721248 +L 280.152134 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 280.178729 240.721248 +L 280.178729 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 280.453539 240.721248 +L 280.453539 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 280.46202 240.721248 +L 280.46202 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 280.586055 240.721248 +L 280.586055 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 280.631725 240.721248 +L 280.631725 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 280.904069 240.721248 +L 280.904069 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 281.002929 240.721248 +L 281.002929 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 281.01203 240.721248 +L 281.01203 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 281.073055 240.721248 +L 281.073055 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 281.192623 240.721248 +L 281.192623 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 281.24915 240.721248 +L 281.24915 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 281.27691 240.721248 +L 281.27691 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 281.528543 240.721248 +L 281.528543 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 281.59063 240.721248 +L 281.59063 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 281.673419 240.721248 +L 281.673419 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 281.716167 240.721248 +L 281.716167 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 282.049746 240.721248 +L 282.049746 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 282.463929 240.721248 +L 282.463929 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 282.466392 240.721248 +L 282.466392 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 282.520229 240.721248 +L 282.520229 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 282.552592 240.721248 +L 282.552592 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 282.59363 240.721248 +L 282.59363 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 282.895548 240.721248 +L 282.895548 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 282.920147 240.721248 +L 282.920147 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 283.282621 240.721248 +L 283.282621 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 283.314473 240.721248 +L 283.314473 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 283.323871 240.721248 +L 283.323871 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 283.352537 240.721248 +L 283.352537 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 283.353884 240.721248 +L 283.353884 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 283.434553 240.721248 +L 283.434553 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 283.583888 240.721248 +L 283.583888 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 283.810662 240.721248 +L 283.810662 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 283.822536 240.721248 +L 283.822536 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 283.824884 240.721248 +L 283.824884 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 284.044531 240.721248 +L 284.044531 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 284.071787 240.721248 +L 284.071787 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 284.206849 240.721248 +L 284.206849 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 284.252488 240.721248 +L 284.252488 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 284.299273 240.721248 +L 284.299273 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 284.432762 240.721248 +L 284.432762 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 284.504009 240.721248 +L 284.504009 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 284.690169 240.721248 +L 284.690169 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 284.820447 240.721248 +L 284.820447 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 284.824612 240.721248 +L 284.824612 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 285.036279 240.721248 +L 285.036279 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 285.046127 240.721248 +L 285.046127 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 285.161297 240.721248 +L 285.161297 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 285.225341 240.721248 +L 285.225341 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 285.225436 240.721248 +L 285.225436 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 285.390928 240.721248 +L 285.390928 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 285.401029 240.721248 +L 285.401029 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 285.443584 240.721248 +L 285.443584 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 285.475221 240.721248 +L 285.475221 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 285.734822 240.721248 +L 285.734822 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 285.777819 240.721248 +L 285.777819 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 285.859941 240.721248 +L 285.859941 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 286.09556 240.721248 +L 286.09556 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 286.543455 240.721248 +L 286.543455 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 286.598288 240.721248 +L 286.598288 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 286.905762 240.721248 +L 286.905762 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 286.932164 240.721248 +L 286.932164 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 287.269596 240.721248 +L 287.269596 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 287.402862 240.721248 +L 287.402862 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 287.468366 240.721248 +L 287.468366 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 287.475585 240.721248 +L 287.475585 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 287.636549 240.721248 +L 287.636549 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 287.660768 240.721248 +L 287.660768 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 287.856901 240.721248 +L 287.856901 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 287.893189 240.721248 +L 287.893189 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 288.117544 240.721248 +L 288.117544 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 288.333303 240.721248 +L 288.333303 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 288.38093 240.721248 +L 288.38093 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 288.480861 240.721248 +L 288.480861 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 288.60313 240.721248 +L 288.60313 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 288.859713 240.721248 +L 288.859713 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 289.031629 240.721248 +L 289.031629 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 289.086755 240.721248 +L 289.086755 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 289.434085 240.721248 +L 289.434085 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 289.465279 240.721248 +L 289.465279 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 289.48771 240.721248 +L 289.48771 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 289.801667 240.721248 +L 289.801667 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 289.871225 240.721248 +L 289.871225 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 289.964131 240.721248 +L 289.964131 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 290.013714 240.721248 +L 290.013714 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 290.066703 240.721248 +L 290.066703 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 290.172927 240.721248 +L 290.172927 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 290.187348 240.721248 +L 290.187348 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 290.43608 240.721248 +L 290.43608 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 290.533547 240.721248 +L 290.533547 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 290.697245 240.721248 +L 290.697245 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 291.086662 240.721248 +L 291.086662 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 291.191807 240.721248 +L 291.191807 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 291.498404 240.721248 +L 291.498404 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 291.530973 240.721248 +L 291.530973 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 291.536222 240.721248 +L 291.536222 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 291.827625 240.721248 +L 291.827625 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 291.937602 240.721248 +L 291.937602 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 292.081001 240.721248 +L 292.081001 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 292.112995 240.721248 +L 292.112995 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 292.11386 240.721248 +L 292.11386 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 292.128845 240.721248 +L 292.128845 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 292.415766 240.721248 +L 292.415766 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 292.535719 240.721248 +L 292.535719 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 292.664858 240.721248 +L 292.664858 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 292.789081 240.721248 +L 292.789081 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 292.790115 240.721248 +L 292.790115 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 292.836549 240.721248 +L 292.836549 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 292.98598 240.721248 +L 292.98598 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 293.016519 240.721248 +L 293.016519 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 293.085757 240.721248 +L 293.085757 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 293.135752 240.721248 +L 293.135752 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 293.164511 240.721248 +L 293.164511 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 293.168459 240.721248 +L 293.168459 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 293.251463 240.721248 +L 293.251463 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 293.403053 240.721248 +L 293.403053 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 293.492056 240.721248 +L 293.492056 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 293.681956 240.721248 +L 293.681956 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 294.009967 240.721248 +L 294.009967 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 294.107842 240.721248 +L 294.107842 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 294.149378 240.721248 +L 294.149378 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 294.581603 240.721248 +L 294.581603 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 294.75548 240.721248 +L 294.75548 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 295.110317 240.721248 +L 295.110317 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 295.164428 240.721248 +L 295.164428 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 295.208587 240.721248 +L 295.208587 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 295.242895 240.721248 +L 295.242895 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 295.625532 240.721248 +L 295.625532 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 295.782814 240.721248 +L 295.782814 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 295.828561 240.721248 +L 295.828561 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 295.901723 240.721248 +L 295.901723 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 295.922577 240.721248 +L 295.922577 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 296.004702 240.721248 +L 296.004702 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 296.08307 240.721248 +L 296.08307 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 296.085023 240.721248 +L 296.085023 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 296.140533 240.721248 +L 296.140533 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 296.326231 240.721248 +L 296.326231 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 296.398438 240.721248 +L 296.398438 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 296.41816 240.721248 +L 296.41816 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 296.43633 240.721248 +L 296.43633 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 297.027032 240.721248 +L 297.027032 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 297.13026 240.721248 +L 297.13026 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 297.455876 240.721248 +L 297.455876 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 297.60613 240.721248 +L 297.60613 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 298.272074 240.721248 +L 298.272074 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 298.299913 240.721248 +L 298.299913 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 298.821308 240.721248 +L 298.821308 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 298.852502 240.721248 +L 298.852502 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 298.887483 240.721248 +L 298.887483 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 298.946681 240.721248 +L 298.946681 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 299.02934 240.721248 +L 299.02934 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 299.114676 240.721248 +L 299.114676 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 299.229027 240.721248 +L 299.229027 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 299.318859 240.721248 +L 299.318859 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 299.407058 240.721248 +L 299.407058 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 299.663142 240.721248 +L 299.663142 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 300.186447 240.721248 +L 300.186447 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 300.700024 240.721248 +L 300.700024 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 300.717061 240.721248 +L 300.717061 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 300.743882 240.721248 +L 300.743882 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 301.024132 240.721248 +L 301.024132 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 301.160576 240.721248 +L 301.160576 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 301.250807 240.721248 +L 301.250807 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 301.30038 240.721248 +L 301.30038 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 301.369256 240.721248 +L 301.369256 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 301.977409 240.721248 +L 301.977409 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 302.042601 240.721248 +L 302.042601 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 302.208982 240.721248 +L 302.208982 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 302.628791 240.721248 +L 302.628791 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 302.757584 240.721248 +L 302.757584 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 302.842749 240.721248 +L 302.842749 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 302.95006 240.721248 +L 302.95006 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 302.995259 240.721248 +L 302.995259 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 302.999601 240.721248 +L 302.999601 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 303.162271 240.721248 +L 303.162271 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 303.255999 240.721248 +L 303.255999 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 303.31081 240.721248 +L 303.31081 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 303.361806 240.721248 +L 303.361806 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 303.443163 240.721248 +L 303.443163 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 303.504529 240.721248 +L 303.504529 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 303.595151 240.721248 +L 303.595151 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 303.64866 240.721248 +L 303.64866 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 303.664811 240.721248 +L 303.664811 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 303.753383 240.721248 +L 303.753383 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 303.777932 240.721248 +L 303.777932 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 303.993271 240.721248 +L 303.993271 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 304.18423 240.721248 +L 304.18423 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 304.192516 240.721248 +L 304.192516 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 304.372734 240.721248 +L 304.372734 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 304.44156 240.721248 +L 304.44156 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 304.574438 240.721248 +L 304.574438 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 304.829304 240.721248 +L 304.829304 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 304.863072 240.721248 +L 304.863072 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 304.936017 240.721248 +L 304.936017 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 305.249566 240.721248 +L 305.249566 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 305.277735 240.721248 +L 305.277735 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 305.544761 240.721248 +L 305.544761 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 305.755937 240.721248 +L 305.755937 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 306.118895 240.721248 +L 306.118895 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 306.125821 240.721248 +L 306.125821 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 306.81775 240.721248 +L 306.81775 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 306.829257 240.721248 +L 306.829257 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 307.191541 240.721248 +L 307.191541 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 307.591347 240.721248 +L 307.591347 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 307.664477 240.721248 +L 307.664477 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 307.768974 240.721248 +L 307.768974 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 308.014152 240.721248 +L 308.014152 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 308.144123 240.721248 +L 308.144123 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 308.26903 240.721248 +L 308.26903 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 308.284721 240.721248 +L 308.284721 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 308.385311 240.721248 +L 308.385311 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 308.463503 240.721248 +L 308.463503 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 308.886682 240.721248 +L 308.886682 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 309.27066 240.721248 +L 309.27066 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 309.38518 240.721248 +L 309.38518 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 309.443207 240.721248 +L 309.443207 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 309.493425 240.721248 +L 309.493425 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 310.122837 240.721248 +L 310.122837 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 310.374436 240.721248 +L 310.374436 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 310.379409 240.721248 +L 310.379409 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 310.973021 240.721248 +L 310.973021 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 310.980288 240.721248 +L 310.980288 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 311.059778 240.721248 +L 311.059778 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 311.273658 240.721248 +L 311.273658 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 311.346329 240.721248 +L 311.346329 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 311.347648 240.721248 +L 311.347648 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 311.427412 240.721248 +L 311.427412 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 311.446381 240.721248 +L 311.446381 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 311.525034 240.721248 +L 311.525034 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 312.069082 240.721248 +L 312.069082 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 312.218372 240.721248 +L 312.218372 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 312.456491 240.721248 +L 312.456491 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 312.51931 240.721248 +L 312.51931 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 312.72645 240.721248 +L 312.72645 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 312.843778 240.721248 +L 312.843778 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 312.862883 240.721248 +L 312.862883 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 312.94284 240.721248 +L 312.94284 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 312.995863 240.721248 +L 312.995863 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 313.468582 240.721248 +L 313.468582 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 313.897122 240.721248 +L 313.897122 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 313.936697 240.721248 +L 313.936697 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 313.952205 240.721248 +L 313.952205 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 314.887326 240.721248 +L 314.887326 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 314.924023 240.721248 +L 314.924023 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 314.988605 240.721248 +L 314.988605 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 315.250759 240.721248 +L 315.250759 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 315.283115 240.721248 +L 315.283115 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 315.388032 240.721248 +L 315.388032 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 315.914427 240.721248 +L 315.914427 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 315.946327 240.721248 +L 315.946327 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 316.215463 240.721248 +L 316.215463 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 316.256586 240.721248 +L 316.256586 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 316.789285 240.721248 +L 316.789285 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 316.981105 240.721248 +L 316.981105 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 317.004115 240.721248 +L 317.004115 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 317.056055 240.721248 +L 317.056055 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 317.17196 240.721248 +L 317.17196 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 317.821789 240.721248 +L 317.821789 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 318.607559 240.721248 +L 318.607559 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 318.980943 240.721248 +L 318.980943 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 319.36696 240.721248 +L 319.36696 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 319.746698 240.721248 +L 319.746698 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 320.004636 240.721248 +L 320.004636 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 320.273147 240.721248 +L 320.273147 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 320.45045 240.721248 +L 320.45045 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 320.529221 240.721248 +L 320.529221 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 320.563472 240.721248 +L 320.563472 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 320.712861 240.721248 +L 320.712861 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 320.908587 240.721248 +L 320.908587 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 320.93034 240.721248 +L 320.93034 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 321.135529 240.721248 +L 321.135529 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 321.155652 240.721248 +L 321.155652 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 321.716878 240.721248 +L 321.716878 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 321.943043 240.721248 +L 321.943043 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 322.115143 240.721248 +L 322.115143 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 322.935207 240.721248 +L 322.935207 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 323.136375 240.721248 +L 323.136375 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 323.217286 240.721248 +L 323.217286 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 323.282071 240.721248 +L 323.282071 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 323.656458 240.721248 +L 323.656458 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 323.780671 240.721248 +L 323.780671 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 323.790223 240.721248 +L 323.790223 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 323.998974 240.721248 +L 323.998974 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 324.346643 240.721248 +L 324.346643 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 324.70897 240.721248 +L 324.70897 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 324.7983 240.721248 +L 324.7983 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 324.82786 240.721248 +L 324.82786 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 325.569154 240.721248 +L 325.569154 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 325.611765 240.721248 +L 325.611765 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 325.985793 240.721248 +L 325.985793 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 326.021551 240.721248 +L 326.021551 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 326.151424 240.721248 +L 326.151424 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 326.939964 240.721248 +L 326.939964 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 327.129302 240.721248 +L 327.129302 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 327.159314 240.721248 +L 327.159314 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 327.243414 240.721248 +L 327.243414 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 327.351606 240.721248 +L 327.351606 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 327.826045 240.721248 +L 327.826045 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 327.904783 240.721248 +L 327.904783 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 328.258894 240.721248 +L 328.258894 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 329.185387 240.721248 +L 329.185387 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 329.697358 240.721248 +L 329.697358 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 329.795733 240.721248 +L 329.795733 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 330.646477 240.721248 +L 330.646477 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 330.934803 240.721248 +L 330.934803 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 331.425418 240.721248 +L 331.425418 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 331.801925 240.721248 +L 331.801925 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 331.852104 240.721248 +L 331.852104 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 331.97438 240.721248 +L 331.97438 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 332.205137 240.721248 +L 332.205137 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 332.401758 240.721248 +L 332.401758 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 332.565706 240.721248 +L 332.565706 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 333.557696 240.721248 +L 333.557696 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 333.974026 240.721248 +L 333.974026 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 334.107661 240.721248 +L 334.107661 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 334.424534 240.721248 +L 334.424534 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 334.513237 240.721248 +L 334.513237 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 334.513294 240.721248 +L 334.513294 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 334.947893 240.721248 +L 334.947893 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 335.288724 240.721248 +L 335.288724 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 335.804059 240.721248 +L 335.804059 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 337.172238 240.721248 +L 337.172238 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 337.482493 240.721248 +L 337.482493 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 337.589488 240.721248 +L 337.589488 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 337.701891 240.721248 +L 337.701891 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 338.642885 240.721248 +L 338.642885 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 339.137425 240.721248 +L 339.137425 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 339.209964 240.721248 +L 339.209964 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 339.266542 240.721248 +L 339.266542 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 340.382622 240.721248 +L 340.382622 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 340.751967 240.721248 +L 340.751967 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 341.097863 240.721248 +L 341.097863 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 341.579847 240.721248 +L 341.579847 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 341.768417 240.721248 +L 341.768417 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 342.026374 240.721248 +L 342.026374 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 342.291032 240.721248 +L 342.291032 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 342.348491 240.721248 +L 342.348491 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 342.964908 240.721248 +L 342.964908 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 342.988332 240.721248 +L 342.988332 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 343.07868 240.721248 +L 343.07868 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 343.284911 240.721248 +L 343.284911 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 343.474806 240.721248 +L 343.474806 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 344.701521 240.721248 +L 344.701521 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 344.829272 240.721248 +L 344.829272 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 344.895957 240.721248 +L 344.895957 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 346.22933 240.721248 +L 346.22933 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 346.453806 240.721248 +L 346.453806 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 347.206733 240.721248 +L 347.206733 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 347.433784 240.721248 +L 347.433784 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 347.831535 240.721248 +L 347.831535 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 347.912514 240.721248 +L 347.912514 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 348.645026 240.721248 +L 348.645026 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 349.432402 240.721248 +L 349.432402 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 350.16736 240.721248 +L 350.16736 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 350.200416 240.721248 +L 350.200416 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 350.565958 240.721248 +L 350.565958 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 350.681759 240.721248 +L 350.681759 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 350.773122 240.721248 +L 350.773122 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 350.935651 240.721248 +L 350.935651 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 353.136997 240.721248 +L 353.136997 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 353.275525 240.721248 +L 353.275525 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 353.836366 240.721248 +L 353.836366 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 354.559884 240.721248 +L 354.559884 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 358.012902 240.721248 +L 358.012902 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 359.175509 240.721248 +L 359.175509 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 360.043865 240.721248 +L 360.043865 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 361.320424 240.721248 +L 361.320424 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 362.020807 240.721248 +L 362.020807 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 364.291695 240.721248 +L 364.291695 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 367.066613 240.721248 +L 367.066613 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 367.675503 240.721248 +L 367.675503 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 367.791325 240.721248 +L 367.791325 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 371.269482 240.721248 +L 371.269482 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 373.516635 240.721248 +L 373.516635 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 374.253555 240.721248 +L 374.253555 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 374.395078 240.721248 +L 374.395078 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 379.387304 240.721248 +L 379.387304 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 384.980811 240.721248 +L 384.980811 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#pdb6ddb23b2)" d="M 420.173905 240.721248 +L 420.173905 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + </g> + <g id="line2d_11"> + <path clip-path="url(#pdb6ddb23b2)" d="M 38.08125 296.329093 +L 88.352446 296.217855 +L 102.062772 295.983869 +L 111.202989 295.632128 +L 118.819837 295.116005 +L 124.913315 294.477182 +L 129.483424 293.81553 +L 134.053533 292.951768 +L 138.623641 291.83674 +L 143.19375 290.413537 +L 146.240489 289.261933 +L 149.287228 287.923869 +L 152.333967 286.377121 +L 155.380707 284.598374 +L 158.427446 282.563464 +L 161.474185 280.247702 +L 164.520924 277.62626 +L 167.567663 274.674625 +L 170.614402 271.36912 +L 173.661141 267.687497 +L 176.70788 263.609575 +L 179.75462 259.117932 +L 182.801359 254.198632 +L 185.848098 248.841964 +L 188.894837 243.043189 +L 191.941576 236.803254 +L 194.988315 230.129476 +L 198.035054 223.036141 +L 202.605163 211.659236 +L 207.175272 199.49612 +L 211.74538 186.695015 +L 219.362228 164.472987 +L 228.502446 137.746751 +L 233.072554 125.022533 +L 236.119293 116.983308 +L 239.166033 109.405031 +L 242.212772 102.37627 +L 245.259511 95.981624 +L 248.30625 90.300037 +L 251.352989 85.403175 +L 252.876359 83.269051 +L 254.399728 81.353932 +L 255.923098 79.664086 +L 257.446467 78.205079 +L 258.969837 76.981737 +L 260.493207 75.998126 +L 262.016576 75.257524 +L 263.539946 74.762406 +L 265.063315 74.514432 +L 266.586685 74.514432 +L 268.110054 74.762406 +L 269.633424 75.257524 +L 271.156793 75.998126 +L 272.680163 76.981737 +L 274.203533 78.205079 +L 275.726902 79.664086 +L 277.250272 81.353932 +L 278.773641 83.269051 +L 280.297011 85.403175 +L 281.82038 87.749362 +L 284.86712 93.04703 +L 287.913859 99.094597 +L 290.960598 105.81656 +L 294.007337 113.130942 +L 297.054076 120.950946 +L 301.624185 133.431874 +L 307.717663 150.996313 +L 321.427989 191.022088 +L 325.998098 203.629552 +L 330.568207 215.545019 +L 335.138315 226.634073 +L 338.185054 233.519873 +L 341.231793 239.978066 +L 344.278533 245.997922 +L 347.325272 251.57539 +L 350.372011 256.712454 +L 353.41875 261.41643 +L 356.465489 265.699235 +L 359.512228 269.576641 +L 362.558967 273.067538 +L 365.605707 276.193223 +L 368.652446 278.976737 +L 371.699185 281.442243 +L 374.745924 283.614474 +L 377.792663 285.518241 +L 380.839402 287.178015 +L 383.886141 288.617569 +L 386.93288 289.859702 +L 389.97962 290.926012 +L 394.549728 292.239687 +L 399.119837 293.265021 +L 403.689946 294.05633 +L 409.783424 294.826873 +L 415.876902 295.353896 +L 423.49375 295.775115 +L 432.633967 296.058448 +L 446.344293 296.243759 +L 472.241576 296.32222 +L 493.56875 296.329093 +L 493.56875 296.329093 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-width:1.5;"/> + </g> + <g id="patch_3"> + <path d="M 83.63 296.32992 +L 83.63 18.28656 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/> + </g> + <g id="patch_4"> + <path d="M 448.02 296.32992 +L 448.02 18.28656 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/> + </g> + <g id="patch_5"> + <path d="M 83.63 296.32992 +L 448.02 296.32992 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/> + </g> + <g id="patch_6"> + <path d="M 83.63 18.28656 +L 448.02 18.28656 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/> + </g> + </g> + <g id="axes_2"> + <g id="patch_7"> + <path d="M 542.45 296.32992 +L 906.84 296.32992 +L 906.84 18.28656 +L 542.45 18.28656 +z +" style="fill:#ffffff;"/> + </g> + <g id="patch_8"> + <path clip-path="url(#p876c80fe4f)" d="M 542.45 296.32992 +L 566.742667 296.32992 +L 566.742667 296.32992 +L 542.45 296.32992 +z +" style="fill:#d3d3d3;"/> + </g> + <g id="patch_9"> + <path clip-path="url(#p876c80fe4f)" d="M 566.742667 296.32992 +L 591.035333 296.32992 +L 591.035333 296.32992 +L 566.742667 296.32992 +z +" style="fill:#d3d3d3;"/> + </g> + <g id="patch_10"> + <path clip-path="url(#p876c80fe4f)" d="M 591.035333 296.32992 +L 615.328 296.32992 +L 615.328 292.15927 +L 591.035333 292.15927 +z +" style="fill:#d3d3d3;"/> + </g> + <g id="patch_11"> + <path clip-path="url(#p876c80fe4f)" d="M 615.328 296.32992 +L 639.620667 296.32992 +L 639.620667 279.647318 +L 615.328 279.647318 +z +" style="fill:#d3d3d3;"/> + </g> + <g id="patch_12"> + <path clip-path="url(#p876c80fe4f)" d="M 639.620667 296.32992 +L 663.913333 296.32992 +L 663.913333 235.855489 +L 639.620667 235.855489 +z +" style="fill:#d3d3d3;"/> + </g> + <g id="patch_13"> + <path clip-path="url(#p876c80fe4f)" d="M 663.913333 296.32992 +L 688.206 296.32992 +L 688.206 161.826445 +L 663.913333 161.826445 +z +" style="fill:#d3d3d3;"/> + </g> + <g id="patch_14"> + <path clip-path="url(#p876c80fe4f)" d="M 688.206 296.32992 +L 712.498667 296.32992 +L 712.498667 98.224026 +L 688.206 98.224026 +z +" style="fill:#d3d3d3;"/> + </g> + <g id="patch_15"> + <path clip-path="url(#p876c80fe4f)" d="M 712.498667 296.32992 +L 736.791333 296.32992 +L 736.791333 80.498762 +L 712.498667 80.498762 +z +" style="fill:#d3d3d3;"/> + </g> + <g id="patch_16"> + <path clip-path="url(#p876c80fe4f)" d="M 736.791333 296.32992 +L 761.084 296.32992 +L 761.084 103.437339 +L 736.791333 103.437339 +z +" style="fill:#d3d3d3;"/> + </g> + <g id="patch_17"> + <path clip-path="url(#p876c80fe4f)" d="M 761.084 296.32992 +L 785.376667 296.32992 +L 785.376667 167.039758 +L 761.084 167.039758 +z +" style="fill:#d3d3d3;"/> + </g> + <g id="patch_18"> + <path clip-path="url(#p876c80fe4f)" d="M 785.376667 296.32992 +L 809.669333 296.32992 +L 809.669333 227.514188 +L 785.376667 227.514188 +z +" style="fill:#d3d3d3;"/> + </g> + <g id="patch_19"> + <path clip-path="url(#p876c80fe4f)" d="M 809.669333 296.32992 +L 833.962 296.32992 +L 833.962 277.561993 +L 809.669333 277.561993 +z +" style="fill:#d3d3d3;"/> + </g> + <g id="patch_20"> + <path clip-path="url(#p876c80fe4f)" d="M 833.962 296.32992 +L 858.254667 296.32992 +L 858.254667 294.244595 +L 833.962 294.244595 +z +" style="fill:#d3d3d3;"/> + </g> + <g id="patch_21"> + <path clip-path="url(#p876c80fe4f)" d="M 858.254667 296.32992 +L 882.547333 296.32992 +L 882.547333 295.287257 +L 858.254667 295.287257 +z +" style="fill:#d3d3d3;"/> + </g> + <g id="patch_22"> + <path clip-path="url(#p876c80fe4f)" d="M 882.547333 296.32992 +L 906.84 296.32992 +L 906.84 296.32992 +L 882.547333 296.32992 +z +" style="fill:#d3d3d3;"/> + </g> + <g id="matplotlib.axis_3"> + <g id="xtick_6"> + <g id="line2d_12"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="542.45" xlink:href="#m304933a64d" y="296.32992"/> + </g> + </g> + <g id="text_13"> + <!-- −40 --> + <g transform="translate(524.511016 316.247264)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-8722"/> + <use x="83.789062" xlink:href="#DejaVuSans-52"/> + <use x="147.412109" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="xtick_7"> + <g id="line2d_13"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="633.5475" xlink:href="#m304933a64d" y="296.32992"/> + </g> + </g> + <g id="text_14"> + <!-- −20 --> + <g transform="translate(615.608516 316.247264)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-8722"/> + <use x="83.789062" xlink:href="#DejaVuSans-50"/> + <use x="147.412109" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="xtick_8"> + <g id="line2d_14"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="724.645" xlink:href="#m304933a64d" y="296.32992"/> + </g> + </g> + <g id="text_15"> + <!-- 0 --> + <g transform="translate(719.236875 316.247264)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="xtick_9"> + <g id="line2d_15"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="815.7425" xlink:href="#m304933a64d" y="296.32992"/> + </g> + </g> + <g id="text_16"> + <!-- 20 --> + <g transform="translate(804.92625 316.247264)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-50"/> + <use x="63.623047" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="xtick_10"> + <g id="line2d_16"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="906.84" xlink:href="#m304933a64d" y="296.32992"/> + </g> + </g> + <g id="text_17"> + <!-- 40 --> + <g transform="translate(896.02375 316.247264)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-52"/> + <use x="63.623047" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="text_18"> + <!-- x --> + <g transform="translate(719.614063 336.700076)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-120"/> + </g> + </g> + </g> + <g id="matplotlib.axis_4"> + <g id="ytick_6"> + <g id="line2d_17"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="542.45" xlink:href="#md18a56d055" y="296.32992"/> + </g> + </g> + <g id="text_19"> + <!-- 0.00 --> + <g transform="translate(497.598438 302.788592)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-48"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-48"/> + <use x="159.033203" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="ytick_7"> + <g id="line2d_18"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="542.45" xlink:href="#md18a56d055" y="240.721248"/> + </g> + </g> + <g id="text_20"> + <!-- 0.01 --> + <g transform="translate(497.598438 247.17992)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-48"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-48"/> + <use x="159.033203" xlink:href="#DejaVuSans-49"/> + </g> + </g> + </g> + <g id="ytick_8"> + <g id="line2d_19"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="542.45" xlink:href="#md18a56d055" y="185.112576"/> + </g> + </g> + <g id="text_21"> + <!-- 0.02 --> + <g transform="translate(497.598438 191.571248)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-48"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-48"/> + <use x="159.033203" xlink:href="#DejaVuSans-50"/> + </g> + </g> + </g> + <g id="ytick_9"> + <g id="line2d_20"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="542.45" xlink:href="#md18a56d055" y="129.503904"/> + </g> + </g> + <g id="text_22"> + <!-- 0.03 --> + <g transform="translate(497.598438 135.962576)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-48"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-48"/> + <use x="159.033203" xlink:href="#DejaVuSans-51"/> + </g> + </g> + </g> + <g id="ytick_10"> + <g id="line2d_21"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="542.45" xlink:href="#md18a56d055" y="73.895232"/> + </g> + </g> + <g id="text_23"> + <!-- 0.04 --> + <g transform="translate(497.598438 80.353904)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-48"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-48"/> + <use x="159.033203" xlink:href="#DejaVuSans-52"/> + </g> + </g> + </g> + <g id="text_24"> + <!-- p(x) --> + <g transform="translate(490.062969 174.368006)rotate(-90)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-112"/> + <use x="63.476562" xlink:href="#DejaVuSans-40"/> + <use x="102.490234" xlink:href="#DejaVuSans-120"/> + <use x="161.669922" xlink:href="#DejaVuSans-41"/> + </g> + </g> + </g> + <g id="line2d_22"> + <path clip-path="url(#p876c80fe4f)" d="M 496.90125 296.329093 +L 547.172446 296.217855 +L 560.882772 295.983869 +L 570.022989 295.632128 +L 577.639837 295.116005 +L 583.733315 294.477182 +L 588.303424 293.81553 +L 592.873533 292.951768 +L 597.443641 291.83674 +L 602.01375 290.413537 +L 605.060489 289.261933 +L 608.107228 287.923869 +L 611.153967 286.377121 +L 614.200707 284.598374 +L 617.247446 282.563464 +L 620.294185 280.247702 +L 623.340924 277.62626 +L 626.387663 274.674625 +L 629.434402 271.36912 +L 632.481141 267.687497 +L 635.52788 263.609575 +L 638.57462 259.117932 +L 641.621359 254.198632 +L 644.668098 248.841964 +L 647.714837 243.043189 +L 650.761576 236.803254 +L 653.808315 230.129476 +L 656.855054 223.036141 +L 661.425163 211.659236 +L 665.995272 199.49612 +L 670.56538 186.695015 +L 678.182228 164.472987 +L 687.322446 137.746751 +L 691.892554 125.022533 +L 694.939293 116.983308 +L 697.986033 109.405031 +L 701.032772 102.37627 +L 704.079511 95.981624 +L 707.12625 90.300037 +L 710.172989 85.403175 +L 711.696359 83.269051 +L 713.219728 81.353932 +L 714.743098 79.664086 +L 716.266467 78.205079 +L 717.789837 76.981737 +L 719.313207 75.998126 +L 720.836576 75.257524 +L 722.359946 74.762406 +L 723.883315 74.514432 +L 725.406685 74.514432 +L 726.930054 74.762406 +L 728.453424 75.257524 +L 729.976793 75.998126 +L 731.500163 76.981737 +L 733.023533 78.205079 +L 734.546902 79.664086 +L 736.070272 81.353932 +L 737.593641 83.269051 +L 739.117011 85.403175 +L 740.64038 87.749362 +L 743.68712 93.04703 +L 746.733859 99.094597 +L 749.780598 105.81656 +L 752.827337 113.130942 +L 755.874076 120.950946 +L 760.444185 133.431874 +L 766.537663 150.996313 +L 780.247989 191.022088 +L 784.818098 203.629552 +L 789.388207 215.545019 +L 793.958315 226.634073 +L 797.005054 233.519873 +L 800.051793 239.978066 +L 803.098533 245.997922 +L 806.145272 251.57539 +L 809.192011 256.712454 +L 812.23875 261.41643 +L 815.285489 265.699235 +L 818.332228 269.576641 +L 821.378967 273.067538 +L 824.425707 276.193223 +L 827.472446 278.976737 +L 830.519185 281.442243 +L 833.565924 283.614474 +L 836.612663 285.518241 +L 839.659402 287.178015 +L 842.706141 288.617569 +L 845.75288 289.859702 +L 848.79962 290.926012 +L 853.369728 292.239687 +L 857.939837 293.265021 +L 862.509946 294.05633 +L 868.603424 294.826873 +L 874.696902 295.353896 +L 882.31375 295.775115 +L 891.453967 296.058448 +L 905.164293 296.243759 +L 931.061576 296.32222 +L 937 296.325686 +L 937 296.325686 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-width:1.5;"/> + </g> + <g id="patch_23"> + <path d="M 542.45 296.32992 +L 542.45 18.28656 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/> + </g> + <g id="patch_24"> + <path d="M 906.84 296.32992 +L 906.84 18.28656 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/> + </g> + <g id="patch_25"> + <path d="M 542.45 296.32992 +L 906.84 296.32992 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/> + </g> + <g id="patch_26"> + <path d="M 542.45 18.28656 +L 906.84 18.28656 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/> + </g> + </g> + </g> + <defs> + <clipPath id="pdb6ddb23b2"> + <rect height="278.04336" width="364.39" x="83.63" y="18.28656"/> + </clipPath> + <clipPath id="p876c80fe4f"> + <rect height="278.04336" width="364.39" x="542.45" y="18.28656"/> + </clipPath> + </defs> +</svg> diff --git a/latex_and_figures/figs/ch_filters/prob_sampling_100samples.png b/latex_and_figures/figs/ch_filters/prob_sampling_100samples.png new file mode 100644 index 0000000000000000000000000000000000000000..66042360501f54a7d2f6fe55bb607da75c31f73e Binary files /dev/null and b/latex_and_figures/figs/ch_filters/prob_sampling_100samples.png differ diff --git a/latex_and_figures/figs/ch_filters/prob_sampling_100samples.svg b/latex_and_figures/figs/ch_filters/prob_sampling_100samples.svg new file mode 100644 index 0000000000000000000000000000000000000000..b89f0ed4ec3cc988fa7f8cc110f10b8dba2a20fc --- /dev/null +++ b/latex_and_figures/figs/ch_filters/prob_sampling_100samples.svg @@ -0,0 +1,1265 @@ +<?xml version="1.0" encoding="utf-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Created with matplotlib (https://matplotlib.org/) --> +<svg height="358.56pt" version="1.1" viewBox="0 0 936 358.56" width="936pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <defs> + <style type="text/css"> +*{stroke-linecap:butt;stroke-linejoin:round;white-space:pre;} + </style> + </defs> + <g id="figure_1"> + <g id="patch_1"> + <path d="M 0 358.56 +L 936 358.56 +L 936 0 +L 0 0 +z +" style="fill:#ffffff;"/> + </g> + <g id="axes_1"> + <g id="patch_2"> + <path d="M 83.63 296.32992 +L 448.02 296.32992 +L 448.02 18.28656 +L 83.63 18.28656 +z +" style="fill:#ffffff;"/> + </g> + <g id="matplotlib.axis_1"> + <g id="xtick_1"> + <g id="line2d_1"> + <defs> + <path d="M 0 0 +L 0 3.5 +" id="me8766ee2c7" style="stroke:#000000;stroke-width:0.8;"/> + </defs> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="83.63" xlink:href="#me8766ee2c7" y="296.32992"/> + </g> + </g> + <g id="text_1"> + <!-- −40 --> + <defs> + <path d="M 10.59375 35.5 +L 73.1875 35.5 +L 73.1875 27.203125 +L 10.59375 27.203125 +z +" id="DejaVuSans-8722"/> + <path d="M 37.796875 64.3125 +L 12.890625 25.390625 +L 37.796875 25.390625 +z +M 35.203125 72.90625 +L 47.609375 72.90625 +L 47.609375 25.390625 +L 58.015625 25.390625 +L 58.015625 17.1875 +L 47.609375 17.1875 +L 47.609375 0 +L 37.796875 0 +L 37.796875 17.1875 +L 4.890625 17.1875 +L 4.890625 26.703125 +z +" id="DejaVuSans-52"/> + <path d="M 31.78125 66.40625 +Q 24.171875 66.40625 20.328125 58.90625 +Q 16.5 51.421875 16.5 36.375 +Q 16.5 21.390625 20.328125 13.890625 +Q 24.171875 6.390625 31.78125 6.390625 +Q 39.453125 6.390625 43.28125 13.890625 +Q 47.125 21.390625 47.125 36.375 +Q 47.125 51.421875 43.28125 58.90625 +Q 39.453125 66.40625 31.78125 66.40625 +z +M 31.78125 74.21875 +Q 44.046875 74.21875 50.515625 64.515625 +Q 56.984375 54.828125 56.984375 36.375 +Q 56.984375 17.96875 50.515625 8.265625 +Q 44.046875 -1.421875 31.78125 -1.421875 +Q 19.53125 -1.421875 13.0625 8.265625 +Q 6.59375 17.96875 6.59375 36.375 +Q 6.59375 54.828125 13.0625 64.515625 +Q 19.53125 74.21875 31.78125 74.21875 +z +" id="DejaVuSans-48"/> + </defs> + <g transform="translate(65.691016 316.247264)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-8722"/> + <use x="83.789062" xlink:href="#DejaVuSans-52"/> + <use x="147.412109" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="xtick_2"> + <g id="line2d_2"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="174.7275" xlink:href="#me8766ee2c7" y="296.32992"/> + </g> + </g> + <g id="text_2"> + <!-- −20 --> + <defs> + <path d="M 19.1875 8.296875 +L 53.609375 8.296875 +L 53.609375 0 +L 7.328125 0 +L 7.328125 8.296875 +Q 12.9375 14.109375 22.625 23.890625 +Q 32.328125 33.6875 34.8125 36.53125 +Q 39.546875 41.84375 41.421875 45.53125 +Q 43.3125 49.21875 43.3125 52.78125 +Q 43.3125 58.59375 39.234375 62.25 +Q 35.15625 65.921875 28.609375 65.921875 +Q 23.96875 65.921875 18.8125 64.3125 +Q 13.671875 62.703125 7.8125 59.421875 +L 7.8125 69.390625 +Q 13.765625 71.78125 18.9375 73 +Q 24.125 74.21875 28.421875 74.21875 +Q 39.75 74.21875 46.484375 68.546875 +Q 53.21875 62.890625 53.21875 53.421875 +Q 53.21875 48.921875 51.53125 44.890625 +Q 49.859375 40.875 45.40625 35.40625 +Q 44.1875 33.984375 37.640625 27.21875 +Q 31.109375 20.453125 19.1875 8.296875 +z +" id="DejaVuSans-50"/> + </defs> + <g transform="translate(156.788516 316.247264)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-8722"/> + <use x="83.789062" xlink:href="#DejaVuSans-50"/> + <use x="147.412109" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="xtick_3"> + <g id="line2d_3"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="265.825" xlink:href="#me8766ee2c7" y="296.32992"/> + </g> + </g> + <g id="text_3"> + <!-- 0 --> + <g transform="translate(260.416875 316.247264)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="xtick_4"> + <g id="line2d_4"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="356.9225" xlink:href="#me8766ee2c7" y="296.32992"/> + </g> + </g> + <g id="text_4"> + <!-- 20 --> + <g transform="translate(346.10625 316.247264)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-50"/> + <use x="63.623047" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="xtick_5"> + <g id="line2d_5"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="448.02" xlink:href="#me8766ee2c7" y="296.32992"/> + </g> + </g> + <g id="text_5"> + <!-- 40 --> + <g transform="translate(437.20375 316.247264)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-52"/> + <use x="63.623047" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="text_6"> + <!-- x --> + <defs> + <path d="M 54.890625 54.6875 +L 35.109375 28.078125 +L 55.90625 0 +L 45.3125 0 +L 29.390625 21.484375 +L 13.484375 0 +L 2.875 0 +L 24.125 28.609375 +L 4.6875 54.6875 +L 15.28125 54.6875 +L 29.78125 35.203125 +L 44.28125 54.6875 +z +" id="DejaVuSans-120"/> + </defs> + <g transform="translate(260.794063 336.700076)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-120"/> + </g> + </g> + </g> + <g id="matplotlib.axis_2"> + <g id="ytick_1"> + <g id="line2d_6"> + <defs> + <path d="M 0 0 +L -3.5 0 +" id="mabde5d4b91" style="stroke:#000000;stroke-width:0.8;"/> + </defs> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="83.63" xlink:href="#mabde5d4b91" y="296.32992"/> + </g> + </g> + <g id="text_7"> + <!-- 0.00 --> + <defs> + <path d="M 10.6875 12.40625 +L 21 12.40625 +L 21 0 +L 10.6875 0 +z +" id="DejaVuSans-46"/> + </defs> + <g transform="translate(38.778438 302.788592)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-48"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-48"/> + <use x="159.033203" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="ytick_2"> + <g id="line2d_7"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="83.63" xlink:href="#mabde5d4b91" y="240.721248"/> + </g> + </g> + <g id="text_8"> + <!-- 0.01 --> + <defs> + <path d="M 12.40625 8.296875 +L 28.515625 8.296875 +L 28.515625 63.921875 +L 10.984375 60.40625 +L 10.984375 69.390625 +L 28.421875 72.90625 +L 38.28125 72.90625 +L 38.28125 8.296875 +L 54.390625 8.296875 +L 54.390625 0 +L 12.40625 0 +z +" id="DejaVuSans-49"/> + </defs> + <g transform="translate(38.778438 247.17992)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-48"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-48"/> + <use x="159.033203" xlink:href="#DejaVuSans-49"/> + </g> + </g> + </g> + <g id="ytick_3"> + <g id="line2d_8"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="83.63" xlink:href="#mabde5d4b91" y="185.112576"/> + </g> + </g> + <g id="text_9"> + <!-- 0.02 --> + <g transform="translate(38.778438 191.571248)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-48"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-48"/> + <use x="159.033203" xlink:href="#DejaVuSans-50"/> + </g> + </g> + </g> + <g id="ytick_4"> + <g id="line2d_9"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="83.63" xlink:href="#mabde5d4b91" y="129.503904"/> + </g> + </g> + <g id="text_10"> + <!-- 0.03 --> + <defs> + <path d="M 40.578125 39.3125 +Q 47.65625 37.796875 51.625 33 +Q 55.609375 28.21875 55.609375 21.1875 +Q 55.609375 10.40625 48.1875 4.484375 +Q 40.765625 -1.421875 27.09375 -1.421875 +Q 22.515625 -1.421875 17.65625 -0.515625 +Q 12.796875 0.390625 7.625 2.203125 +L 7.625 11.71875 +Q 11.71875 9.328125 16.59375 8.109375 +Q 21.484375 6.890625 26.8125 6.890625 +Q 36.078125 6.890625 40.9375 10.546875 +Q 45.796875 14.203125 45.796875 21.1875 +Q 45.796875 27.640625 41.28125 31.265625 +Q 36.765625 34.90625 28.71875 34.90625 +L 20.21875 34.90625 +L 20.21875 43.015625 +L 29.109375 43.015625 +Q 36.375 43.015625 40.234375 45.921875 +Q 44.09375 48.828125 44.09375 54.296875 +Q 44.09375 59.90625 40.109375 62.90625 +Q 36.140625 65.921875 28.71875 65.921875 +Q 24.65625 65.921875 20.015625 65.03125 +Q 15.375 64.15625 9.8125 62.3125 +L 9.8125 71.09375 +Q 15.4375 72.65625 20.34375 73.4375 +Q 25.25 74.21875 29.59375 74.21875 +Q 40.828125 74.21875 47.359375 69.109375 +Q 53.90625 64.015625 53.90625 55.328125 +Q 53.90625 49.265625 50.4375 45.09375 +Q 46.96875 40.921875 40.578125 39.3125 +z +" id="DejaVuSans-51"/> + </defs> + <g transform="translate(38.778438 135.962576)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-48"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-48"/> + <use x="159.033203" xlink:href="#DejaVuSans-51"/> + </g> + </g> + </g> + <g id="ytick_5"> + <g id="line2d_10"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="83.63" xlink:href="#mabde5d4b91" y="73.895232"/> + </g> + </g> + <g id="text_11"> + <!-- 0.04 --> + <g transform="translate(38.778438 80.353904)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-48"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-48"/> + <use x="159.033203" xlink:href="#DejaVuSans-52"/> + </g> + </g> + </g> + <g id="text_12"> + <!-- p(x) --> + <defs> + <path d="M 18.109375 8.203125 +L 18.109375 -20.796875 +L 9.078125 -20.796875 +L 9.078125 54.6875 +L 18.109375 54.6875 +L 18.109375 46.390625 +Q 20.953125 51.265625 25.265625 53.625 +Q 29.59375 56 35.59375 56 +Q 45.5625 56 51.78125 48.09375 +Q 58.015625 40.1875 58.015625 27.296875 +Q 58.015625 14.40625 51.78125 6.484375 +Q 45.5625 -1.421875 35.59375 -1.421875 +Q 29.59375 -1.421875 25.265625 0.953125 +Q 20.953125 3.328125 18.109375 8.203125 +z +M 48.6875 27.296875 +Q 48.6875 37.203125 44.609375 42.84375 +Q 40.53125 48.484375 33.40625 48.484375 +Q 26.265625 48.484375 22.1875 42.84375 +Q 18.109375 37.203125 18.109375 27.296875 +Q 18.109375 17.390625 22.1875 11.75 +Q 26.265625 6.109375 33.40625 6.109375 +Q 40.53125 6.109375 44.609375 11.75 +Q 48.6875 17.390625 48.6875 27.296875 +z +" id="DejaVuSans-112"/> + <path d="M 31 75.875 +Q 24.46875 64.65625 21.28125 53.65625 +Q 18.109375 42.671875 18.109375 31.390625 +Q 18.109375 20.125 21.3125 9.0625 +Q 24.515625 -2 31 -13.1875 +L 23.1875 -13.1875 +Q 15.875 -1.703125 12.234375 9.375 +Q 8.59375 20.453125 8.59375 31.390625 +Q 8.59375 42.28125 12.203125 53.3125 +Q 15.828125 64.359375 23.1875 75.875 +z +" id="DejaVuSans-40"/> + <path d="M 8.015625 75.875 +L 15.828125 75.875 +Q 23.140625 64.359375 26.78125 53.3125 +Q 30.421875 42.28125 30.421875 31.390625 +Q 30.421875 20.453125 26.78125 9.375 +Q 23.140625 -1.703125 15.828125 -13.1875 +L 8.015625 -13.1875 +Q 14.5 -2 17.703125 9.0625 +Q 20.90625 20.125 20.90625 31.390625 +Q 20.90625 42.671875 17.703125 53.65625 +Q 14.5 64.65625 8.015625 75.875 +z +" id="DejaVuSans-41"/> + </defs> + <g transform="translate(31.242969 174.368006)rotate(-90)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-112"/> + <use x="63.476562" xlink:href="#DejaVuSans-40"/> + <use x="102.490234" xlink:href="#DejaVuSans-120"/> + <use x="161.669922" xlink:href="#DejaVuSans-41"/> + </g> + </g> + </g> + <g id="EventCollection_1"> + <path clip-path="url(#p138968d73d)" d="M 146.415713 240.721248 +L 146.415713 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 169.516689 240.721248 +L 169.516689 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 175.057496 240.721248 +L 175.057496 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 185.464299 240.721248 +L 185.464299 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 186.405889 240.721248 +L 186.405889 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 187.917051 240.721248 +L 187.917051 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 190.361833 240.721248 +L 190.361833 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 204.209573 240.721248 +L 204.209573 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 207.128558 240.721248 +L 207.128558 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 207.918432 240.721248 +L 207.918432 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 211.936467 240.721248 +L 211.936467 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 214.55705 240.721248 +L 214.55705 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 214.935402 240.721248 +L 214.935402 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 216.713738 240.721248 +L 216.713738 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 220.700002 240.721248 +L 220.700002 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 221.413525 240.721248 +L 221.413525 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 222.421607 240.721248 +L 222.421607 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 225.438741 240.721248 +L 225.438741 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 227.140368 240.721248 +L 227.140368 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 229.748012 240.721248 +L 229.748012 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 230.6506 240.721248 +L 230.6506 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 230.905488 240.721248 +L 230.905488 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 231.362102 240.721248 +L 231.362102 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 231.607989 240.721248 +L 231.607989 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 231.965856 240.721248 +L 231.965856 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 233.91739 240.721248 +L 233.91739 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 235.488233 240.721248 +L 235.488233 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 237.190719 240.721248 +L 237.190719 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 238.41122 240.721248 +L 238.41122 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 242.440523 240.721248 +L 242.440523 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 243.171056 240.721248 +L 243.171056 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 245.298013 240.721248 +L 245.298013 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 245.945428 240.721248 +L 245.945428 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 246.245659 240.721248 +L 246.245659 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 247.096759 240.721248 +L 247.096759 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 250.335016 240.721248 +L 250.335016 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 251.716038 240.721248 +L 251.716038 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 251.821266 240.721248 +L 251.821266 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 252.535797 240.721248 +L 252.535797 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 254.064369 240.721248 +L 254.064369 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 254.085396 240.721248 +L 254.085396 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 254.837048 240.721248 +L 254.837048 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 255.920946 240.721248 +L 255.920946 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 258.229309 240.721248 +L 258.229309 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 259.218057 240.721248 +L 259.218057 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 259.641116 240.721248 +L 259.641116 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 261.002043 240.721248 +L 261.002043 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 261.622611 240.721248 +L 261.622611 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 262.326507 240.721248 +L 262.326507 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 262.705342 240.721248 +L 262.705342 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 263.260957 240.721248 +L 263.260957 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 263.754842 240.721248 +L 263.754842 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 264.813311 240.721248 +L 264.813311 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 266.322612 240.721248 +L 266.322612 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 266.964529 240.721248 +L 266.964529 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 268.082144 240.721248 +L 268.082144 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 269.666515 240.721248 +L 269.666515 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 272.388045 240.721248 +L 272.388045 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 272.948186 240.721248 +L 272.948186 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 276.433461 240.721248 +L 276.433461 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 276.966884 240.721248 +L 276.966884 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 281.263998 240.721248 +L 281.263998 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 281.356 240.721248 +L 281.356 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 281.672738 240.721248 +L 281.672738 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 282.190704 240.721248 +L 282.190704 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 283.818396 240.721248 +L 283.818396 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 284.918333 240.721248 +L 284.918333 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 285.256965 240.721248 +L 285.256965 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 285.99082 240.721248 +L 285.99082 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 286.342131 240.721248 +L 286.342131 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 286.710166 240.721248 +L 286.710166 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 286.980799 240.721248 +L 286.980799 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 287.248067 240.721248 +L 287.248067 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 288.513437 240.721248 +L 288.513437 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 289.672583 240.721248 +L 289.672583 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 293.187325 240.721248 +L 293.187325 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 293.992034 240.721248 +L 293.992034 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 295.541876 240.721248 +L 295.541876 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 297.314361 240.721248 +L 297.314361 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 301.314144 240.721248 +L 301.314144 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 301.613109 240.721248 +L 301.613109 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 301.613142 240.721248 +L 301.613142 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 306.690648 240.721248 +L 306.690648 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 307.359862 240.721248 +L 307.359862 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 310.801183 240.721248 +L 310.801183 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 311.096815 240.721248 +L 311.096815 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 311.418595 240.721248 +L 311.418595 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 311.592503 240.721248 +L 311.592503 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 311.854813 240.721248 +L 311.854813 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 312.089277 240.721248 +L 312.089277 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 313.898221 240.721248 +L 313.898221 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 314.457795 240.721248 +L 314.457795 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 315.802167 240.721248 +L 315.802167 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 315.805093 240.721248 +L 315.805093 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 321.945118 240.721248 +L 321.945118 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 326.949315 240.721248 +L 326.949315 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 346.289657 240.721248 +L 346.289657 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 350.145814 240.721248 +L 350.145814 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 355.945729 240.721248 +L 355.945729 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p138968d73d)" d="M 366.607783 240.721248 +L 366.607783 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + </g> + <g id="line2d_11"> + <path clip-path="url(#p138968d73d)" d="M 38.08125 296.329093 +L 88.352446 296.217855 +L 102.062772 295.983869 +L 111.202989 295.632128 +L 118.819837 295.116005 +L 124.913315 294.477182 +L 129.483424 293.81553 +L 134.053533 292.951768 +L 138.623641 291.83674 +L 143.19375 290.413537 +L 146.240489 289.261933 +L 149.287228 287.923869 +L 152.333967 286.377121 +L 155.380707 284.598374 +L 158.427446 282.563464 +L 161.474185 280.247702 +L 164.520924 277.62626 +L 167.567663 274.674625 +L 170.614402 271.36912 +L 173.661141 267.687497 +L 176.70788 263.609575 +L 179.75462 259.117932 +L 182.801359 254.198632 +L 185.848098 248.841964 +L 188.894837 243.043189 +L 191.941576 236.803254 +L 194.988315 230.129476 +L 198.035054 223.036141 +L 202.605163 211.659236 +L 207.175272 199.49612 +L 211.74538 186.695015 +L 219.362228 164.472987 +L 228.502446 137.746751 +L 233.072554 125.022533 +L 236.119293 116.983308 +L 239.166033 109.405031 +L 242.212772 102.37627 +L 245.259511 95.981624 +L 248.30625 90.300037 +L 251.352989 85.403175 +L 252.876359 83.269051 +L 254.399728 81.353932 +L 255.923098 79.664086 +L 257.446467 78.205079 +L 258.969837 76.981737 +L 260.493207 75.998126 +L 262.016576 75.257524 +L 263.539946 74.762406 +L 265.063315 74.514432 +L 266.586685 74.514432 +L 268.110054 74.762406 +L 269.633424 75.257524 +L 271.156793 75.998126 +L 272.680163 76.981737 +L 274.203533 78.205079 +L 275.726902 79.664086 +L 277.250272 81.353932 +L 278.773641 83.269051 +L 280.297011 85.403175 +L 281.82038 87.749362 +L 284.86712 93.04703 +L 287.913859 99.094597 +L 290.960598 105.81656 +L 294.007337 113.130942 +L 297.054076 120.950946 +L 301.624185 133.431874 +L 307.717663 150.996313 +L 321.427989 191.022088 +L 325.998098 203.629552 +L 330.568207 215.545019 +L 335.138315 226.634073 +L 338.185054 233.519873 +L 341.231793 239.978066 +L 344.278533 245.997922 +L 347.325272 251.57539 +L 350.372011 256.712454 +L 353.41875 261.41643 +L 356.465489 265.699235 +L 359.512228 269.576641 +L 362.558967 273.067538 +L 365.605707 276.193223 +L 368.652446 278.976737 +L 371.699185 281.442243 +L 374.745924 283.614474 +L 377.792663 285.518241 +L 380.839402 287.178015 +L 383.886141 288.617569 +L 386.93288 289.859702 +L 389.97962 290.926012 +L 394.549728 292.239687 +L 399.119837 293.265021 +L 403.689946 294.05633 +L 409.783424 294.826873 +L 415.876902 295.353896 +L 423.49375 295.775115 +L 432.633967 296.058448 +L 446.344293 296.243759 +L 472.241576 296.32222 +L 493.56875 296.329093 +L 493.56875 296.329093 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-width:1.5;"/> + </g> + <g id="patch_3"> + <path d="M 83.63 296.32992 +L 83.63 18.28656 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/> + </g> + <g id="patch_4"> + <path d="M 448.02 296.32992 +L 448.02 18.28656 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/> + </g> + <g id="patch_5"> + <path d="M 83.63 296.32992 +L 448.02 296.32992 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/> + </g> + <g id="patch_6"> + <path d="M 83.63 18.28656 +L 448.02 18.28656 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/> + </g> + </g> + <g id="axes_2"> + <g id="patch_7"> + <path d="M 542.45 296.32992 +L 906.84 296.32992 +L 906.84 18.28656 +L 542.45 18.28656 +z +" style="fill:#ffffff;"/> + </g> + <g id="patch_8"> + <path clip-path="url(#p73155e6d43)" d="M 542.45 296.32992 +L 566.742667 296.32992 +L 566.742667 296.32992 +L 542.45 296.32992 +z +" style="fill:#d3d3d3;"/> + </g> + <g id="patch_9"> + <path clip-path="url(#p73155e6d43)" d="M 566.742667 296.32992 +L 591.035333 296.32992 +L 591.035333 296.32992 +L 566.742667 296.32992 +z +" style="fill:#d3d3d3;"/> + </g> + <g id="patch_10"> + <path clip-path="url(#p73155e6d43)" d="M 591.035333 296.32992 +L 615.328 296.32992 +L 615.328 285.903294 +L 591.035333 285.903294 +z +" style="fill:#d3d3d3;"/> + </g> + <g id="patch_11"> + <path clip-path="url(#p73155e6d43)" d="M 615.328 296.32992 +L 639.620667 296.32992 +L 639.620667 275.476668 +L 615.328 275.476668 +z +" style="fill:#d3d3d3;"/> + </g> + <g id="patch_12"> + <path clip-path="url(#p73155e6d43)" d="M 639.620667 296.32992 +L 663.913333 296.32992 +L 663.913333 244.19679 +L 639.620667 244.19679 +z +" style="fill:#d3d3d3;"/> + </g> + <g id="patch_13"> + <path clip-path="url(#p73155e6d43)" d="M 663.913333 296.32992 +L 688.206 296.32992 +L 688.206 181.637034 +L 663.913333 181.637034 +z +" style="fill:#d3d3d3;"/> + </g> + <g id="patch_14"> + <path clip-path="url(#p73155e6d43)" d="M 688.206 296.32992 +L 712.498667 296.32992 +L 712.498667 87.7974 +L 688.206 87.7974 +z +" style="fill:#d3d3d3;"/> + </g> + <g id="patch_15"> + <path clip-path="url(#p73155e6d43)" d="M 712.498667 296.32992 +L 736.791333 296.32992 +L 736.791333 66.944148 +L 712.498667 66.944148 +z +" style="fill:#d3d3d3;"/> + </g> + <g id="patch_16"> + <path clip-path="url(#p73155e6d43)" d="M 736.791333 296.32992 +L 761.084 296.32992 +L 761.084 77.370774 +L 736.791333 77.370774 +z +" style="fill:#d3d3d3;"/> + </g> + <g id="patch_17"> + <path clip-path="url(#p73155e6d43)" d="M 761.084 296.32992 +L 785.376667 296.32992 +L 785.376667 160.783782 +L 761.084 160.783782 +z +" style="fill:#d3d3d3;"/> + </g> + <g id="patch_18"> + <path clip-path="url(#p73155e6d43)" d="M 785.376667 296.32992 +L 809.669333 296.32992 +L 809.669333 265.050042 +L 785.376667 265.050042 +z +" style="fill:#d3d3d3;"/> + </g> + <g id="patch_19"> + <path clip-path="url(#p73155e6d43)" d="M 809.669333 296.32992 +L 833.962 296.32992 +L 833.962 275.476668 +L 809.669333 275.476668 +z +" style="fill:#d3d3d3;"/> + </g> + <g id="patch_20"> + <path clip-path="url(#p73155e6d43)" d="M 833.962 296.32992 +L 858.254667 296.32992 +L 858.254667 296.32992 +L 833.962 296.32992 +z +" style="fill:#d3d3d3;"/> + </g> + <g id="patch_21"> + <path clip-path="url(#p73155e6d43)" d="M 858.254667 296.32992 +L 882.547333 296.32992 +L 882.547333 296.32992 +L 858.254667 296.32992 +z +" style="fill:#d3d3d3;"/> + </g> + <g id="patch_22"> + <path clip-path="url(#p73155e6d43)" d="M 882.547333 296.32992 +L 906.84 296.32992 +L 906.84 296.32992 +L 882.547333 296.32992 +z +" style="fill:#d3d3d3;"/> + </g> + <g id="matplotlib.axis_3"> + <g id="xtick_6"> + <g id="line2d_12"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="542.45" xlink:href="#me8766ee2c7" y="296.32992"/> + </g> + </g> + <g id="text_13"> + <!-- −40 --> + <g transform="translate(524.511016 316.247264)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-8722"/> + <use x="83.789062" xlink:href="#DejaVuSans-52"/> + <use x="147.412109" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="xtick_7"> + <g id="line2d_13"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="633.5475" xlink:href="#me8766ee2c7" y="296.32992"/> + </g> + </g> + <g id="text_14"> + <!-- −20 --> + <g transform="translate(615.608516 316.247264)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-8722"/> + <use x="83.789062" xlink:href="#DejaVuSans-50"/> + <use x="147.412109" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="xtick_8"> + <g id="line2d_14"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="724.645" xlink:href="#me8766ee2c7" y="296.32992"/> + </g> + </g> + <g id="text_15"> + <!-- 0 --> + <g transform="translate(719.236875 316.247264)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="xtick_9"> + <g id="line2d_15"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="815.7425" xlink:href="#me8766ee2c7" y="296.32992"/> + </g> + </g> + <g id="text_16"> + <!-- 20 --> + <g transform="translate(804.92625 316.247264)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-50"/> + <use x="63.623047" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="xtick_10"> + <g id="line2d_16"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="906.84" xlink:href="#me8766ee2c7" y="296.32992"/> + </g> + </g> + <g id="text_17"> + <!-- 40 --> + <g transform="translate(896.02375 316.247264)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-52"/> + <use x="63.623047" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="text_18"> + <!-- x --> + <g transform="translate(719.614063 336.700076)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-120"/> + </g> + </g> + </g> + <g id="matplotlib.axis_4"> + <g id="ytick_6"> + <g id="line2d_17"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="542.45" xlink:href="#mabde5d4b91" y="296.32992"/> + </g> + </g> + <g id="text_19"> + <!-- 0.00 --> + <g transform="translate(497.598438 302.788592)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-48"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-48"/> + <use x="159.033203" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="ytick_7"> + <g id="line2d_18"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="542.45" xlink:href="#mabde5d4b91" y="240.721248"/> + </g> + </g> + <g id="text_20"> + <!-- 0.01 --> + <g transform="translate(497.598438 247.17992)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-48"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-48"/> + <use x="159.033203" xlink:href="#DejaVuSans-49"/> + </g> + </g> + </g> + <g id="ytick_8"> + <g id="line2d_19"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="542.45" xlink:href="#mabde5d4b91" y="185.112576"/> + </g> + </g> + <g id="text_21"> + <!-- 0.02 --> + <g transform="translate(497.598438 191.571248)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-48"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-48"/> + <use x="159.033203" xlink:href="#DejaVuSans-50"/> + </g> + </g> + </g> + <g id="ytick_9"> + <g id="line2d_20"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="542.45" xlink:href="#mabde5d4b91" y="129.503904"/> + </g> + </g> + <g id="text_22"> + <!-- 0.03 --> + <g transform="translate(497.598438 135.962576)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-48"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-48"/> + <use x="159.033203" xlink:href="#DejaVuSans-51"/> + </g> + </g> + </g> + <g id="ytick_10"> + <g id="line2d_21"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="542.45" xlink:href="#mabde5d4b91" y="73.895232"/> + </g> + </g> + <g id="text_23"> + <!-- 0.04 --> + <g transform="translate(497.598438 80.353904)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-48"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-48"/> + <use x="159.033203" xlink:href="#DejaVuSans-52"/> + </g> + </g> + </g> + <g id="text_24"> + <!-- p(x) --> + <g transform="translate(490.062969 174.368006)rotate(-90)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-112"/> + <use x="63.476562" xlink:href="#DejaVuSans-40"/> + <use x="102.490234" xlink:href="#DejaVuSans-120"/> + <use x="161.669922" xlink:href="#DejaVuSans-41"/> + </g> + </g> + </g> + <g id="line2d_22"> + <path clip-path="url(#p73155e6d43)" d="M 496.90125 296.329093 +L 547.172446 296.217855 +L 560.882772 295.983869 +L 570.022989 295.632128 +L 577.639837 295.116005 +L 583.733315 294.477182 +L 588.303424 293.81553 +L 592.873533 292.951768 +L 597.443641 291.83674 +L 602.01375 290.413537 +L 605.060489 289.261933 +L 608.107228 287.923869 +L 611.153967 286.377121 +L 614.200707 284.598374 +L 617.247446 282.563464 +L 620.294185 280.247702 +L 623.340924 277.62626 +L 626.387663 274.674625 +L 629.434402 271.36912 +L 632.481141 267.687497 +L 635.52788 263.609575 +L 638.57462 259.117932 +L 641.621359 254.198632 +L 644.668098 248.841964 +L 647.714837 243.043189 +L 650.761576 236.803254 +L 653.808315 230.129476 +L 656.855054 223.036141 +L 661.425163 211.659236 +L 665.995272 199.49612 +L 670.56538 186.695015 +L 678.182228 164.472987 +L 687.322446 137.746751 +L 691.892554 125.022533 +L 694.939293 116.983308 +L 697.986033 109.405031 +L 701.032772 102.37627 +L 704.079511 95.981624 +L 707.12625 90.300037 +L 710.172989 85.403175 +L 711.696359 83.269051 +L 713.219728 81.353932 +L 714.743098 79.664086 +L 716.266467 78.205079 +L 717.789837 76.981737 +L 719.313207 75.998126 +L 720.836576 75.257524 +L 722.359946 74.762406 +L 723.883315 74.514432 +L 725.406685 74.514432 +L 726.930054 74.762406 +L 728.453424 75.257524 +L 729.976793 75.998126 +L 731.500163 76.981737 +L 733.023533 78.205079 +L 734.546902 79.664086 +L 736.070272 81.353932 +L 737.593641 83.269051 +L 739.117011 85.403175 +L 740.64038 87.749362 +L 743.68712 93.04703 +L 746.733859 99.094597 +L 749.780598 105.81656 +L 752.827337 113.130942 +L 755.874076 120.950946 +L 760.444185 133.431874 +L 766.537663 150.996313 +L 780.247989 191.022088 +L 784.818098 203.629552 +L 789.388207 215.545019 +L 793.958315 226.634073 +L 797.005054 233.519873 +L 800.051793 239.978066 +L 803.098533 245.997922 +L 806.145272 251.57539 +L 809.192011 256.712454 +L 812.23875 261.41643 +L 815.285489 265.699235 +L 818.332228 269.576641 +L 821.378967 273.067538 +L 824.425707 276.193223 +L 827.472446 278.976737 +L 830.519185 281.442243 +L 833.565924 283.614474 +L 836.612663 285.518241 +L 839.659402 287.178015 +L 842.706141 288.617569 +L 845.75288 289.859702 +L 848.79962 290.926012 +L 853.369728 292.239687 +L 857.939837 293.265021 +L 862.509946 294.05633 +L 868.603424 294.826873 +L 874.696902 295.353896 +L 882.31375 295.775115 +L 891.453967 296.058448 +L 905.164293 296.243759 +L 931.061576 296.32222 +L 937 296.325686 +L 937 296.325686 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-width:1.5;"/> + </g> + <g id="patch_23"> + <path d="M 542.45 296.32992 +L 542.45 18.28656 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/> + </g> + <g id="patch_24"> + <path d="M 906.84 296.32992 +L 906.84 18.28656 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/> + </g> + <g id="patch_25"> + <path d="M 542.45 296.32992 +L 906.84 296.32992 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/> + </g> + <g id="patch_26"> + <path d="M 542.45 18.28656 +L 906.84 18.28656 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/> + </g> + </g> + </g> + <defs> + <clipPath id="p138968d73d"> + <rect height="278.04336" width="364.39" x="83.63" y="18.28656"/> + </clipPath> + <clipPath id="p73155e6d43"> + <rect height="278.04336" width="364.39" x="542.45" y="18.28656"/> + </clipPath> + </defs> +</svg> diff --git a/latex_and_figures/figs/ch_filters/prob_sampling_25samples.png b/latex_and_figures/figs/ch_filters/prob_sampling_25samples.png new file mode 100644 index 0000000000000000000000000000000000000000..9ea4ca2f34d231cc9adbb9746bdd6f523fb71022 Binary files /dev/null and b/latex_and_figures/figs/ch_filters/prob_sampling_25samples.png differ diff --git a/latex_and_figures/figs/ch_filters/prob_sampling_25samples.svg b/latex_and_figures/figs/ch_filters/prob_sampling_25samples.svg new file mode 100644 index 0000000000000000000000000000000000000000..acf19cc9f02305b8b94d2682f2a3cd54aa05761f --- /dev/null +++ b/latex_and_figures/figs/ch_filters/prob_sampling_25samples.svg @@ -0,0 +1,1040 @@ +<?xml version="1.0" encoding="utf-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Created with matplotlib (https://matplotlib.org/) --> +<svg height="358.56pt" version="1.1" viewBox="0 0 936 358.56" width="936pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <defs> + <style type="text/css"> +*{stroke-linecap:butt;stroke-linejoin:round;white-space:pre;} + </style> + </defs> + <g id="figure_1"> + <g id="patch_1"> + <path d="M 0 358.56 +L 936 358.56 +L 936 0 +L 0 0 +z +" style="fill:#ffffff;"/> + </g> + <g id="axes_1"> + <g id="patch_2"> + <path d="M 83.63 296.32992 +L 448.02 296.32992 +L 448.02 18.28656 +L 83.63 18.28656 +z +" style="fill:#ffffff;"/> + </g> + <g id="matplotlib.axis_1"> + <g id="xtick_1"> + <g id="line2d_1"> + <defs> + <path d="M 0 0 +L 0 3.5 +" id="mfc208fee9a" style="stroke:#000000;stroke-width:0.8;"/> + </defs> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="83.63" xlink:href="#mfc208fee9a" y="296.32992"/> + </g> + </g> + <g id="text_1"> + <!-- −40 --> + <defs> + <path d="M 10.59375 35.5 +L 73.1875 35.5 +L 73.1875 27.203125 +L 10.59375 27.203125 +z +" id="DejaVuSans-8722"/> + <path d="M 37.796875 64.3125 +L 12.890625 25.390625 +L 37.796875 25.390625 +z +M 35.203125 72.90625 +L 47.609375 72.90625 +L 47.609375 25.390625 +L 58.015625 25.390625 +L 58.015625 17.1875 +L 47.609375 17.1875 +L 47.609375 0 +L 37.796875 0 +L 37.796875 17.1875 +L 4.890625 17.1875 +L 4.890625 26.703125 +z +" id="DejaVuSans-52"/> + <path d="M 31.78125 66.40625 +Q 24.171875 66.40625 20.328125 58.90625 +Q 16.5 51.421875 16.5 36.375 +Q 16.5 21.390625 20.328125 13.890625 +Q 24.171875 6.390625 31.78125 6.390625 +Q 39.453125 6.390625 43.28125 13.890625 +Q 47.125 21.390625 47.125 36.375 +Q 47.125 51.421875 43.28125 58.90625 +Q 39.453125 66.40625 31.78125 66.40625 +z +M 31.78125 74.21875 +Q 44.046875 74.21875 50.515625 64.515625 +Q 56.984375 54.828125 56.984375 36.375 +Q 56.984375 17.96875 50.515625 8.265625 +Q 44.046875 -1.421875 31.78125 -1.421875 +Q 19.53125 -1.421875 13.0625 8.265625 +Q 6.59375 17.96875 6.59375 36.375 +Q 6.59375 54.828125 13.0625 64.515625 +Q 19.53125 74.21875 31.78125 74.21875 +z +" id="DejaVuSans-48"/> + </defs> + <g transform="translate(65.691016 316.247264)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-8722"/> + <use x="83.789062" xlink:href="#DejaVuSans-52"/> + <use x="147.412109" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="xtick_2"> + <g id="line2d_2"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="174.7275" xlink:href="#mfc208fee9a" y="296.32992"/> + </g> + </g> + <g id="text_2"> + <!-- −20 --> + <defs> + <path d="M 19.1875 8.296875 +L 53.609375 8.296875 +L 53.609375 0 +L 7.328125 0 +L 7.328125 8.296875 +Q 12.9375 14.109375 22.625 23.890625 +Q 32.328125 33.6875 34.8125 36.53125 +Q 39.546875 41.84375 41.421875 45.53125 +Q 43.3125 49.21875 43.3125 52.78125 +Q 43.3125 58.59375 39.234375 62.25 +Q 35.15625 65.921875 28.609375 65.921875 +Q 23.96875 65.921875 18.8125 64.3125 +Q 13.671875 62.703125 7.8125 59.421875 +L 7.8125 69.390625 +Q 13.765625 71.78125 18.9375 73 +Q 24.125 74.21875 28.421875 74.21875 +Q 39.75 74.21875 46.484375 68.546875 +Q 53.21875 62.890625 53.21875 53.421875 +Q 53.21875 48.921875 51.53125 44.890625 +Q 49.859375 40.875 45.40625 35.40625 +Q 44.1875 33.984375 37.640625 27.21875 +Q 31.109375 20.453125 19.1875 8.296875 +z +" id="DejaVuSans-50"/> + </defs> + <g transform="translate(156.788516 316.247264)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-8722"/> + <use x="83.789062" xlink:href="#DejaVuSans-50"/> + <use x="147.412109" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="xtick_3"> + <g id="line2d_3"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="265.825" xlink:href="#mfc208fee9a" y="296.32992"/> + </g> + </g> + <g id="text_3"> + <!-- 0 --> + <g transform="translate(260.416875 316.247264)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="xtick_4"> + <g id="line2d_4"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="356.9225" xlink:href="#mfc208fee9a" y="296.32992"/> + </g> + </g> + <g id="text_4"> + <!-- 20 --> + <g transform="translate(346.10625 316.247264)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-50"/> + <use x="63.623047" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="xtick_5"> + <g id="line2d_5"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="448.02" xlink:href="#mfc208fee9a" y="296.32992"/> + </g> + </g> + <g id="text_5"> + <!-- 40 --> + <g transform="translate(437.20375 316.247264)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-52"/> + <use x="63.623047" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="text_6"> + <!-- x --> + <defs> + <path d="M 54.890625 54.6875 +L 35.109375 28.078125 +L 55.90625 0 +L 45.3125 0 +L 29.390625 21.484375 +L 13.484375 0 +L 2.875 0 +L 24.125 28.609375 +L 4.6875 54.6875 +L 15.28125 54.6875 +L 29.78125 35.203125 +L 44.28125 54.6875 +z +" id="DejaVuSans-120"/> + </defs> + <g transform="translate(260.794063 336.700076)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-120"/> + </g> + </g> + </g> + <g id="matplotlib.axis_2"> + <g id="ytick_1"> + <g id="line2d_6"> + <defs> + <path d="M 0 0 +L -3.5 0 +" id="mada51459be" style="stroke:#000000;stroke-width:0.8;"/> + </defs> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="83.63" xlink:href="#mada51459be" y="296.32992"/> + </g> + </g> + <g id="text_7"> + <!-- 0.00 --> + <defs> + <path d="M 10.6875 12.40625 +L 21 12.40625 +L 21 0 +L 10.6875 0 +z +" id="DejaVuSans-46"/> + </defs> + <g transform="translate(38.778438 302.788592)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-48"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-48"/> + <use x="159.033203" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="ytick_2"> + <g id="line2d_7"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="83.63" xlink:href="#mada51459be" y="240.721248"/> + </g> + </g> + <g id="text_8"> + <!-- 0.01 --> + <defs> + <path d="M 12.40625 8.296875 +L 28.515625 8.296875 +L 28.515625 63.921875 +L 10.984375 60.40625 +L 10.984375 69.390625 +L 28.421875 72.90625 +L 38.28125 72.90625 +L 38.28125 8.296875 +L 54.390625 8.296875 +L 54.390625 0 +L 12.40625 0 +z +" id="DejaVuSans-49"/> + </defs> + <g transform="translate(38.778438 247.17992)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-48"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-48"/> + <use x="159.033203" xlink:href="#DejaVuSans-49"/> + </g> + </g> + </g> + <g id="ytick_3"> + <g id="line2d_8"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="83.63" xlink:href="#mada51459be" y="185.112576"/> + </g> + </g> + <g id="text_9"> + <!-- 0.02 --> + <g transform="translate(38.778438 191.571248)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-48"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-48"/> + <use x="159.033203" xlink:href="#DejaVuSans-50"/> + </g> + </g> + </g> + <g id="ytick_4"> + <g id="line2d_9"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="83.63" xlink:href="#mada51459be" y="129.503904"/> + </g> + </g> + <g id="text_10"> + <!-- 0.03 --> + <defs> + <path d="M 40.578125 39.3125 +Q 47.65625 37.796875 51.625 33 +Q 55.609375 28.21875 55.609375 21.1875 +Q 55.609375 10.40625 48.1875 4.484375 +Q 40.765625 -1.421875 27.09375 -1.421875 +Q 22.515625 -1.421875 17.65625 -0.515625 +Q 12.796875 0.390625 7.625 2.203125 +L 7.625 11.71875 +Q 11.71875 9.328125 16.59375 8.109375 +Q 21.484375 6.890625 26.8125 6.890625 +Q 36.078125 6.890625 40.9375 10.546875 +Q 45.796875 14.203125 45.796875 21.1875 +Q 45.796875 27.640625 41.28125 31.265625 +Q 36.765625 34.90625 28.71875 34.90625 +L 20.21875 34.90625 +L 20.21875 43.015625 +L 29.109375 43.015625 +Q 36.375 43.015625 40.234375 45.921875 +Q 44.09375 48.828125 44.09375 54.296875 +Q 44.09375 59.90625 40.109375 62.90625 +Q 36.140625 65.921875 28.71875 65.921875 +Q 24.65625 65.921875 20.015625 65.03125 +Q 15.375 64.15625 9.8125 62.3125 +L 9.8125 71.09375 +Q 15.4375 72.65625 20.34375 73.4375 +Q 25.25 74.21875 29.59375 74.21875 +Q 40.828125 74.21875 47.359375 69.109375 +Q 53.90625 64.015625 53.90625 55.328125 +Q 53.90625 49.265625 50.4375 45.09375 +Q 46.96875 40.921875 40.578125 39.3125 +z +" id="DejaVuSans-51"/> + </defs> + <g transform="translate(38.778438 135.962576)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-48"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-48"/> + <use x="159.033203" xlink:href="#DejaVuSans-51"/> + </g> + </g> + </g> + <g id="ytick_5"> + <g id="line2d_10"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="83.63" xlink:href="#mada51459be" y="73.895232"/> + </g> + </g> + <g id="text_11"> + <!-- 0.04 --> + <g transform="translate(38.778438 80.353904)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-48"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-48"/> + <use x="159.033203" xlink:href="#DejaVuSans-52"/> + </g> + </g> + </g> + <g id="text_12"> + <!-- p(x) --> + <defs> + <path d="M 18.109375 8.203125 +L 18.109375 -20.796875 +L 9.078125 -20.796875 +L 9.078125 54.6875 +L 18.109375 54.6875 +L 18.109375 46.390625 +Q 20.953125 51.265625 25.265625 53.625 +Q 29.59375 56 35.59375 56 +Q 45.5625 56 51.78125 48.09375 +Q 58.015625 40.1875 58.015625 27.296875 +Q 58.015625 14.40625 51.78125 6.484375 +Q 45.5625 -1.421875 35.59375 -1.421875 +Q 29.59375 -1.421875 25.265625 0.953125 +Q 20.953125 3.328125 18.109375 8.203125 +z +M 48.6875 27.296875 +Q 48.6875 37.203125 44.609375 42.84375 +Q 40.53125 48.484375 33.40625 48.484375 +Q 26.265625 48.484375 22.1875 42.84375 +Q 18.109375 37.203125 18.109375 27.296875 +Q 18.109375 17.390625 22.1875 11.75 +Q 26.265625 6.109375 33.40625 6.109375 +Q 40.53125 6.109375 44.609375 11.75 +Q 48.6875 17.390625 48.6875 27.296875 +z +" id="DejaVuSans-112"/> + <path d="M 31 75.875 +Q 24.46875 64.65625 21.28125 53.65625 +Q 18.109375 42.671875 18.109375 31.390625 +Q 18.109375 20.125 21.3125 9.0625 +Q 24.515625 -2 31 -13.1875 +L 23.1875 -13.1875 +Q 15.875 -1.703125 12.234375 9.375 +Q 8.59375 20.453125 8.59375 31.390625 +Q 8.59375 42.28125 12.203125 53.3125 +Q 15.828125 64.359375 23.1875 75.875 +z +" id="DejaVuSans-40"/> + <path d="M 8.015625 75.875 +L 15.828125 75.875 +Q 23.140625 64.359375 26.78125 53.3125 +Q 30.421875 42.28125 30.421875 31.390625 +Q 30.421875 20.453125 26.78125 9.375 +Q 23.140625 -1.703125 15.828125 -13.1875 +L 8.015625 -13.1875 +Q 14.5 -2 17.703125 9.0625 +Q 20.90625 20.125 20.90625 31.390625 +Q 20.90625 42.671875 17.703125 53.65625 +Q 14.5 64.65625 8.015625 75.875 +z +" id="DejaVuSans-41"/> + </defs> + <g transform="translate(31.242969 174.368006)rotate(-90)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-112"/> + <use x="63.476562" xlink:href="#DejaVuSans-40"/> + <use x="102.490234" xlink:href="#DejaVuSans-120"/> + <use x="161.669922" xlink:href="#DejaVuSans-41"/> + </g> + </g> + </g> + <g id="EventCollection_1"> + <path clip-path="url(#p2102571907)" d="M 186.415461 240.721248 +L 186.415461 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p2102571907)" d="M 213.694952 240.721248 +L 213.694952 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p2102571907)" d="M 216.528764 240.721248 +L 216.528764 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p2102571907)" d="M 222.166526 240.721248 +L 222.166526 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p2102571907)" d="M 228.297285 240.721248 +L 228.297285 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p2102571907)" d="M 229.907991 240.721248 +L 229.907991 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p2102571907)" d="M 235.334979 240.721248 +L 235.334979 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p2102571907)" d="M 237.809831 240.721248 +L 237.809831 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p2102571907)" d="M 241.912433 240.721248 +L 241.912433 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p2102571907)" d="M 243.833824 240.721248 +L 243.833824 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p2102571907)" d="M 249.986725 240.721248 +L 249.986725 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p2102571907)" d="M 264.672122 240.721248 +L 264.672122 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p2102571907)" d="M 268.335925 240.721248 +L 268.335925 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p2102571907)" d="M 272.817115 240.721248 +L 272.817115 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p2102571907)" d="M 274.403568 240.721248 +L 274.403568 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p2102571907)" d="M 275.904974 240.721248 +L 275.904974 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p2102571907)" d="M 280.766967 240.721248 +L 280.766967 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p2102571907)" d="M 294.121012 240.721248 +L 294.121012 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p2102571907)" d="M 298.202651 240.721248 +L 298.202651 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p2102571907)" d="M 298.674773 240.721248 +L 298.674773 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p2102571907)" d="M 312.235851 240.721248 +L 312.235851 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p2102571907)" d="M 315.134695 240.721248 +L 315.134695 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p2102571907)" d="M 316.485924 240.721248 +L 316.485924 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p2102571907)" d="M 317.888928 240.721248 +L 317.888928 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + <path clip-path="url(#p2102571907)" d="M 320.396614 240.721248 +L 320.396614 296.32992 +" style="fill:none;stroke:#808080;stroke-width:1.5;"/> + </g> + <g id="line2d_11"> + <path clip-path="url(#p2102571907)" d="M 38.08125 296.329093 +L 88.352446 296.217855 +L 102.062772 295.983869 +L 111.202989 295.632128 +L 118.819837 295.116005 +L 124.913315 294.477182 +L 129.483424 293.81553 +L 134.053533 292.951768 +L 138.623641 291.83674 +L 143.19375 290.413537 +L 146.240489 289.261933 +L 149.287228 287.923869 +L 152.333967 286.377121 +L 155.380707 284.598374 +L 158.427446 282.563464 +L 161.474185 280.247702 +L 164.520924 277.62626 +L 167.567663 274.674625 +L 170.614402 271.36912 +L 173.661141 267.687497 +L 176.70788 263.609575 +L 179.75462 259.117932 +L 182.801359 254.198632 +L 185.848098 248.841964 +L 188.894837 243.043189 +L 191.941576 236.803254 +L 194.988315 230.129476 +L 198.035054 223.036141 +L 202.605163 211.659236 +L 207.175272 199.49612 +L 211.74538 186.695015 +L 219.362228 164.472987 +L 228.502446 137.746751 +L 233.072554 125.022533 +L 236.119293 116.983308 +L 239.166033 109.405031 +L 242.212772 102.37627 +L 245.259511 95.981624 +L 248.30625 90.300037 +L 251.352989 85.403175 +L 252.876359 83.269051 +L 254.399728 81.353932 +L 255.923098 79.664086 +L 257.446467 78.205079 +L 258.969837 76.981737 +L 260.493207 75.998126 +L 262.016576 75.257524 +L 263.539946 74.762406 +L 265.063315 74.514432 +L 266.586685 74.514432 +L 268.110054 74.762406 +L 269.633424 75.257524 +L 271.156793 75.998126 +L 272.680163 76.981737 +L 274.203533 78.205079 +L 275.726902 79.664086 +L 277.250272 81.353932 +L 278.773641 83.269051 +L 280.297011 85.403175 +L 281.82038 87.749362 +L 284.86712 93.04703 +L 287.913859 99.094597 +L 290.960598 105.81656 +L 294.007337 113.130942 +L 297.054076 120.950946 +L 301.624185 133.431874 +L 307.717663 150.996313 +L 321.427989 191.022088 +L 325.998098 203.629552 +L 330.568207 215.545019 +L 335.138315 226.634073 +L 338.185054 233.519873 +L 341.231793 239.978066 +L 344.278533 245.997922 +L 347.325272 251.57539 +L 350.372011 256.712454 +L 353.41875 261.41643 +L 356.465489 265.699235 +L 359.512228 269.576641 +L 362.558967 273.067538 +L 365.605707 276.193223 +L 368.652446 278.976737 +L 371.699185 281.442243 +L 374.745924 283.614474 +L 377.792663 285.518241 +L 380.839402 287.178015 +L 383.886141 288.617569 +L 386.93288 289.859702 +L 389.97962 290.926012 +L 394.549728 292.239687 +L 399.119837 293.265021 +L 403.689946 294.05633 +L 409.783424 294.826873 +L 415.876902 295.353896 +L 423.49375 295.775115 +L 432.633967 296.058448 +L 446.344293 296.243759 +L 472.241576 296.32222 +L 493.56875 296.329093 +L 493.56875 296.329093 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-width:1.5;"/> + </g> + <g id="patch_3"> + <path d="M 83.63 296.32992 +L 83.63 18.28656 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/> + </g> + <g id="patch_4"> + <path d="M 448.02 296.32992 +L 448.02 18.28656 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/> + </g> + <g id="patch_5"> + <path d="M 83.63 296.32992 +L 448.02 296.32992 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/> + </g> + <g id="patch_6"> + <path d="M 83.63 18.28656 +L 448.02 18.28656 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/> + </g> + </g> + <g id="axes_2"> + <g id="patch_7"> + <path d="M 542.45 296.32992 +L 906.84 296.32992 +L 906.84 18.28656 +L 542.45 18.28656 +z +" style="fill:#ffffff;"/> + </g> + <g id="patch_8"> + <path clip-path="url(#pbcc2859865)" d="M 542.45 296.32992 +L 566.742667 296.32992 +L 566.742667 296.32992 +L 542.45 296.32992 +z +" style="fill:#d3d3d3;"/> + </g> + <g id="patch_9"> + <path clip-path="url(#pbcc2859865)" d="M 566.742667 296.32992 +L 591.035333 296.32992 +L 591.035333 296.32992 +L 566.742667 296.32992 +z +" style="fill:#d3d3d3;"/> + </g> + <g id="patch_10"> + <path clip-path="url(#pbcc2859865)" d="M 591.035333 296.32992 +L 615.328 296.32992 +L 615.328 296.32992 +L 591.035333 296.32992 +z +" style="fill:#d3d3d3;"/> + </g> + <g id="patch_11"> + <path clip-path="url(#pbcc2859865)" d="M 615.328 296.32992 +L 639.620667 296.32992 +L 639.620667 296.32992 +L 615.328 296.32992 +z +" style="fill:#d3d3d3;"/> + </g> + <g id="patch_12"> + <path clip-path="url(#pbcc2859865)" d="M 639.620667 296.32992 +L 663.913333 296.32992 +L 663.913333 254.623416 +L 639.620667 254.623416 +z +" style="fill:#d3d3d3;"/> + </g> + <g id="patch_13"> + <path clip-path="url(#pbcc2859865)" d="M 663.913333 296.32992 +L 688.206 296.32992 +L 688.206 129.503904 +L 663.913333 129.503904 +z +" style="fill:#d3d3d3;"/> + </g> + <g id="patch_14"> + <path clip-path="url(#pbcc2859865)" d="M 688.206 296.32992 +L 712.498667 296.32992 +L 712.498667 46.090896 +L 688.206 46.090896 +z +" style="fill:#d3d3d3;"/> + </g> + <g id="patch_15"> + <path clip-path="url(#pbcc2859865)" d="M 712.498667 296.32992 +L 736.791333 296.32992 +L 736.791333 87.7974 +L 712.498667 87.7974 +z +" style="fill:#d3d3d3;"/> + </g> + <g id="patch_16"> + <path clip-path="url(#pbcc2859865)" d="M 736.791333 296.32992 +L 761.084 296.32992 +L 761.084 129.503904 +L 736.791333 129.503904 +z +" style="fill:#d3d3d3;"/> + </g> + <g id="patch_17"> + <path clip-path="url(#pbcc2859865)" d="M 761.084 296.32992 +L 785.376667 296.32992 +L 785.376667 87.7974 +L 761.084 87.7974 +z +" style="fill:#d3d3d3;"/> + </g> + <g id="patch_18"> + <path clip-path="url(#pbcc2859865)" d="M 785.376667 296.32992 +L 809.669333 296.32992 +L 809.669333 296.32992 +L 785.376667 296.32992 +z +" style="fill:#d3d3d3;"/> + </g> + <g id="patch_19"> + <path clip-path="url(#pbcc2859865)" d="M 809.669333 296.32992 +L 833.962 296.32992 +L 833.962 296.32992 +L 809.669333 296.32992 +z +" style="fill:#d3d3d3;"/> + </g> + <g id="patch_20"> + <path clip-path="url(#pbcc2859865)" d="M 833.962 296.32992 +L 858.254667 296.32992 +L 858.254667 296.32992 +L 833.962 296.32992 +z +" style="fill:#d3d3d3;"/> + </g> + <g id="patch_21"> + <path clip-path="url(#pbcc2859865)" d="M 858.254667 296.32992 +L 882.547333 296.32992 +L 882.547333 296.32992 +L 858.254667 296.32992 +z +" style="fill:#d3d3d3;"/> + </g> + <g id="patch_22"> + <path clip-path="url(#pbcc2859865)" d="M 882.547333 296.32992 +L 906.84 296.32992 +L 906.84 296.32992 +L 882.547333 296.32992 +z +" style="fill:#d3d3d3;"/> + </g> + <g id="matplotlib.axis_3"> + <g id="xtick_6"> + <g id="line2d_12"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="542.45" xlink:href="#mfc208fee9a" y="296.32992"/> + </g> + </g> + <g id="text_13"> + <!-- −40 --> + <g transform="translate(524.511016 316.247264)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-8722"/> + <use x="83.789062" xlink:href="#DejaVuSans-52"/> + <use x="147.412109" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="xtick_7"> + <g id="line2d_13"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="633.5475" xlink:href="#mfc208fee9a" y="296.32992"/> + </g> + </g> + <g id="text_14"> + <!-- −20 --> + <g transform="translate(615.608516 316.247264)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-8722"/> + <use x="83.789062" xlink:href="#DejaVuSans-50"/> + <use x="147.412109" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="xtick_8"> + <g id="line2d_14"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="724.645" xlink:href="#mfc208fee9a" y="296.32992"/> + </g> + </g> + <g id="text_15"> + <!-- 0 --> + <g transform="translate(719.236875 316.247264)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="xtick_9"> + <g id="line2d_15"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="815.7425" xlink:href="#mfc208fee9a" y="296.32992"/> + </g> + </g> + <g id="text_16"> + <!-- 20 --> + <g transform="translate(804.92625 316.247264)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-50"/> + <use x="63.623047" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="xtick_10"> + <g id="line2d_16"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="906.84" xlink:href="#mfc208fee9a" y="296.32992"/> + </g> + </g> + <g id="text_17"> + <!-- 40 --> + <g transform="translate(896.02375 316.247264)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-52"/> + <use x="63.623047" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="text_18"> + <!-- x --> + <g transform="translate(719.614063 336.700076)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-120"/> + </g> + </g> + </g> + <g id="matplotlib.axis_4"> + <g id="ytick_6"> + <g id="line2d_17"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="542.45" xlink:href="#mada51459be" y="296.32992"/> + </g> + </g> + <g id="text_19"> + <!-- 0.00 --> + <g transform="translate(497.598438 302.788592)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-48"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-48"/> + <use x="159.033203" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="ytick_7"> + <g id="line2d_18"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="542.45" xlink:href="#mada51459be" y="240.721248"/> + </g> + </g> + <g id="text_20"> + <!-- 0.01 --> + <g transform="translate(497.598438 247.17992)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-48"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-48"/> + <use x="159.033203" xlink:href="#DejaVuSans-49"/> + </g> + </g> + </g> + <g id="ytick_8"> + <g id="line2d_19"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="542.45" xlink:href="#mada51459be" y="185.112576"/> + </g> + </g> + <g id="text_21"> + <!-- 0.02 --> + <g transform="translate(497.598438 191.571248)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-48"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-48"/> + <use x="159.033203" xlink:href="#DejaVuSans-50"/> + </g> + </g> + </g> + <g id="ytick_9"> + <g id="line2d_20"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="542.45" xlink:href="#mada51459be" y="129.503904"/> + </g> + </g> + <g id="text_22"> + <!-- 0.03 --> + <g transform="translate(497.598438 135.962576)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-48"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-48"/> + <use x="159.033203" xlink:href="#DejaVuSans-51"/> + </g> + </g> + </g> + <g id="ytick_10"> + <g id="line2d_21"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="542.45" xlink:href="#mada51459be" y="73.895232"/> + </g> + </g> + <g id="text_23"> + <!-- 0.04 --> + <g transform="translate(497.598438 80.353904)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-48"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-48"/> + <use x="159.033203" xlink:href="#DejaVuSans-52"/> + </g> + </g> + </g> + <g id="text_24"> + <!-- p(x) --> + <g transform="translate(490.062969 174.368006)rotate(-90)scale(0.17 -0.17)"> + <use xlink:href="#DejaVuSans-112"/> + <use x="63.476562" xlink:href="#DejaVuSans-40"/> + <use x="102.490234" xlink:href="#DejaVuSans-120"/> + <use x="161.669922" xlink:href="#DejaVuSans-41"/> + </g> + </g> + </g> + <g id="line2d_22"> + <path clip-path="url(#pbcc2859865)" d="M 496.90125 296.329093 +L 547.172446 296.217855 +L 560.882772 295.983869 +L 570.022989 295.632128 +L 577.639837 295.116005 +L 583.733315 294.477182 +L 588.303424 293.81553 +L 592.873533 292.951768 +L 597.443641 291.83674 +L 602.01375 290.413537 +L 605.060489 289.261933 +L 608.107228 287.923869 +L 611.153967 286.377121 +L 614.200707 284.598374 +L 617.247446 282.563464 +L 620.294185 280.247702 +L 623.340924 277.62626 +L 626.387663 274.674625 +L 629.434402 271.36912 +L 632.481141 267.687497 +L 635.52788 263.609575 +L 638.57462 259.117932 +L 641.621359 254.198632 +L 644.668098 248.841964 +L 647.714837 243.043189 +L 650.761576 236.803254 +L 653.808315 230.129476 +L 656.855054 223.036141 +L 661.425163 211.659236 +L 665.995272 199.49612 +L 670.56538 186.695015 +L 678.182228 164.472987 +L 687.322446 137.746751 +L 691.892554 125.022533 +L 694.939293 116.983308 +L 697.986033 109.405031 +L 701.032772 102.37627 +L 704.079511 95.981624 +L 707.12625 90.300037 +L 710.172989 85.403175 +L 711.696359 83.269051 +L 713.219728 81.353932 +L 714.743098 79.664086 +L 716.266467 78.205079 +L 717.789837 76.981737 +L 719.313207 75.998126 +L 720.836576 75.257524 +L 722.359946 74.762406 +L 723.883315 74.514432 +L 725.406685 74.514432 +L 726.930054 74.762406 +L 728.453424 75.257524 +L 729.976793 75.998126 +L 731.500163 76.981737 +L 733.023533 78.205079 +L 734.546902 79.664086 +L 736.070272 81.353932 +L 737.593641 83.269051 +L 739.117011 85.403175 +L 740.64038 87.749362 +L 743.68712 93.04703 +L 746.733859 99.094597 +L 749.780598 105.81656 +L 752.827337 113.130942 +L 755.874076 120.950946 +L 760.444185 133.431874 +L 766.537663 150.996313 +L 780.247989 191.022088 +L 784.818098 203.629552 +L 789.388207 215.545019 +L 793.958315 226.634073 +L 797.005054 233.519873 +L 800.051793 239.978066 +L 803.098533 245.997922 +L 806.145272 251.57539 +L 809.192011 256.712454 +L 812.23875 261.41643 +L 815.285489 265.699235 +L 818.332228 269.576641 +L 821.378967 273.067538 +L 824.425707 276.193223 +L 827.472446 278.976737 +L 830.519185 281.442243 +L 833.565924 283.614474 +L 836.612663 285.518241 +L 839.659402 287.178015 +L 842.706141 288.617569 +L 845.75288 289.859702 +L 848.79962 290.926012 +L 853.369728 292.239687 +L 857.939837 293.265021 +L 862.509946 294.05633 +L 868.603424 294.826873 +L 874.696902 295.353896 +L 882.31375 295.775115 +L 891.453967 296.058448 +L 905.164293 296.243759 +L 931.061576 296.32222 +L 937 296.325686 +L 937 296.325686 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-width:1.5;"/> + </g> + <g id="patch_23"> + <path d="M 542.45 296.32992 +L 542.45 18.28656 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/> + </g> + <g id="patch_24"> + <path d="M 906.84 296.32992 +L 906.84 18.28656 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/> + </g> + <g id="patch_25"> + <path d="M 542.45 296.32992 +L 906.84 296.32992 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/> + </g> + <g id="patch_26"> + <path d="M 542.45 18.28656 +L 906.84 18.28656 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/> + </g> + </g> + </g> + <defs> + <clipPath id="p2102571907"> + <rect height="278.04336" width="364.39" x="83.63" y="18.28656"/> + </clipPath> + <clipPath id="pbcc2859865"> + <rect height="278.04336" width="364.39" x="542.45" y="18.28656"/> + </clipPath> + </defs> +</svg> diff --git a/latex_and_figures/figs/ch_reinlearning/neuralnet_basic.png b/latex_and_figures/figs/ch_reinlearning/neuralnet_basic.png new file mode 100644 index 0000000000000000000000000000000000000000..ac75478c796725513386ad8f988c2283bdf9e2c2 Binary files /dev/null and b/latex_and_figures/figs/ch_reinlearning/neuralnet_basic.png differ diff --git a/latex_and_figures/figs/ch_results/acc_rew_hists.png b/latex_and_figures/figs/ch_results/acc_rew_hists.png new file mode 100644 index 0000000000000000000000000000000000000000..940f658916437db8fd02839716f63eda1f366338 Binary files /dev/null and b/latex_and_figures/figs/ch_results/acc_rew_hists.png differ diff --git a/latex_and_figures/figs/ch_results/explore_linear1_z.png b/latex_and_figures/figs/ch_results/explore_linear1_z.png new file mode 100644 index 0000000000000000000000000000000000000000..538434085e15000ba4685f4fc7eee7658182b92b Binary files /dev/null and b/latex_and_figures/figs/ch_results/explore_linear1_z.png differ diff --git a/latex_and_figures/figs/ch_results/explore_linear2_z.png b/latex_and_figures/figs/ch_results/explore_linear2_z.png new file mode 100644 index 0000000000000000000000000000000000000000..e84cc4268b378c02d34267a2bab28d5e619df19c Binary files /dev/null and b/latex_and_figures/figs/ch_results/explore_linear2_z.png differ diff --git a/latex_and_figures/figs/ch_results/explore_linear4_z.png b/latex_and_figures/figs/ch_results/explore_linear4_z.png new file mode 100644 index 0000000000000000000000000000000000000000..d248c727dcbd20ed3a1d0a1bb68ae520a052188d Binary files /dev/null and b/latex_and_figures/figs/ch_results/explore_linear4_z.png differ diff --git a/latex_and_figures/figs/ch_results/explore_linear6_z.png b/latex_and_figures/figs/ch_results/explore_linear6_z.png new file mode 100644 index 0000000000000000000000000000000000000000..104851cf0b157ec9e3c6b458056e2f688ddbeb36 Binary files /dev/null and b/latex_and_figures/figs/ch_results/explore_linear6_z.png differ diff --git a/latex_and_figures/figs/ch_results/explore_linear_part1.png b/latex_and_figures/figs/ch_results/explore_linear_part1.png new file mode 100644 index 0000000000000000000000000000000000000000..50de256f6b3a98c0d8c27e37553bd93eaaf7c4c8 Binary files /dev/null and b/latex_and_figures/figs/ch_results/explore_linear_part1.png differ diff --git a/latex_and_figures/figs/ch_results/explore_linear_part2.png b/latex_and_figures/figs/ch_results/explore_linear_part2.png new file mode 100644 index 0000000000000000000000000000000000000000..20e974db9f1280a951f45ec1ae5e07f4564ad4fd Binary files /dev/null and b/latex_and_figures/figs/ch_results/explore_linear_part2.png differ diff --git a/latex_and_figures/figs/ch_results/explore_linear_part3.png b/latex_and_figures/figs/ch_results/explore_linear_part3.png new file mode 100644 index 0000000000000000000000000000000000000000..a87b2af56f4fb871c069c0d98f92f44763349bf1 Binary files /dev/null and b/latex_and_figures/figs/ch_results/explore_linear_part3.png differ diff --git a/latex_and_figures/figs/ch_results/explore_linear_part4.png b/latex_and_figures/figs/ch_results/explore_linear_part4.png new file mode 100644 index 0000000000000000000000000000000000000000..58667adea476610ce12d98988b4a2bcf2fb9e949 Binary files /dev/null and b/latex_and_figures/figs/ch_results/explore_linear_part4.png differ diff --git a/latex_and_figures/figs/ch_results/explore_linear_part5.png b/latex_and_figures/figs/ch_results/explore_linear_part5.png new file mode 100644 index 0000000000000000000000000000000000000000..e38be16f34ccd2f50237e167ebcea51ba630ae93 Binary files /dev/null and b/latex_and_figures/figs/ch_results/explore_linear_part5.png differ diff --git a/latex_and_figures/figs/ch_results/explore_linear_part6.png b/latex_and_figures/figs/ch_results/explore_linear_part6.png new file mode 100644 index 0000000000000000000000000000000000000000..864d8cab34d1e1d0b500f1b46b275891abd95f94 Binary files /dev/null and b/latex_and_figures/figs/ch_results/explore_linear_part6.png differ diff --git a/latex_and_figures/figs/ch_results/explore_linear_part7.png b/latex_and_figures/figs/ch_results/explore_linear_part7.png new file mode 100644 index 0000000000000000000000000000000000000000..d8200dc9aac4618b78f1805b0c0365699007fad5 Binary files /dev/null and b/latex_and_figures/figs/ch_results/explore_linear_part7.png differ diff --git a/latex_and_figures/figs/ch_results/explore_linear_part8.png b/latex_and_figures/figs/ch_results/explore_linear_part8.png new file mode 100644 index 0000000000000000000000000000000000000000..6cd29012fb316bb00878b99ca050657339c71d2a Binary files /dev/null and b/latex_and_figures/figs/ch_results/explore_linear_part8.png differ diff --git a/latex_and_figures/figs/ch_results/explore_linear_part9.png b/latex_and_figures/figs/ch_results/explore_linear_part9.png new file mode 100644 index 0000000000000000000000000000000000000000..f0028907e50ea9ab9f9b9294e282f72775a5b6ff Binary files /dev/null and b/latex_and_figures/figs/ch_results/explore_linear_part9.png differ diff --git a/latex_and_figures/figs/ch_results/explore_neural_part1_z.png b/latex_and_figures/figs/ch_results/explore_neural_part1_z.png new file mode 100644 index 0000000000000000000000000000000000000000..c3ec547c45c052f133c2895c0c8944b8f36a096a Binary files /dev/null and b/latex_and_figures/figs/ch_results/explore_neural_part1_z.png differ diff --git a/latex_and_figures/figs/ch_results/explore_neural_part2_z.png b/latex_and_figures/figs/ch_results/explore_neural_part2_z.png new file mode 100644 index 0000000000000000000000000000000000000000..b89f5eccc00256827a7262d958aa58cdc49eef32 Binary files /dev/null and b/latex_and_figures/figs/ch_results/explore_neural_part2_z.png differ diff --git a/latex_and_figures/figs/ch_results/explore_neural_part3_z.png b/latex_and_figures/figs/ch_results/explore_neural_part3_z.png new file mode 100644 index 0000000000000000000000000000000000000000..da93fde7dcd8d573f58bb019111c42983fcddb65 Binary files /dev/null and b/latex_and_figures/figs/ch_results/explore_neural_part3_z.png differ diff --git a/latex_and_figures/figs/ch_results/explore_neural_part4_z.png b/latex_and_figures/figs/ch_results/explore_neural_part4_z.png new file mode 100644 index 0000000000000000000000000000000000000000..0f23c202cc64db6f4aefaa6f6ade431616c3d4e2 Binary files /dev/null and b/latex_and_figures/figs/ch_results/explore_neural_part4_z.png differ diff --git a/latex_and_figures/figs/ch_results/explore_neural_part5_z.png b/latex_and_figures/figs/ch_results/explore_neural_part5_z.png new file mode 100644 index 0000000000000000000000000000000000000000..97499aa4d2bf8d61041b88ca25db6d36f7bfede0 Binary files /dev/null and b/latex_and_figures/figs/ch_results/explore_neural_part5_z.png differ diff --git a/latex_and_figures/figs/ch_results/explore_neural_part6_z.png b/latex_and_figures/figs/ch_results/explore_neural_part6_z.png new file mode 100644 index 0000000000000000000000000000000000000000..fb3e930516918d110b7899eb396f583cb7d7e6d9 Binary files /dev/null and b/latex_and_figures/figs/ch_results/explore_neural_part6_z.png differ diff --git a/latex_and_figures/figs/ch_results/explore_neural_part7_z.png b/latex_and_figures/figs/ch_results/explore_neural_part7_z.png new file mode 100644 index 0000000000000000000000000000000000000000..711ede24c470013cf1a02bae13421defc50c63f0 Binary files /dev/null and b/latex_and_figures/figs/ch_results/explore_neural_part7_z.png differ diff --git a/latex_and_figures/figs/ch_results/explore_neuralnet1_z.png b/latex_and_figures/figs/ch_results/explore_neuralnet1_z.png new file mode 100644 index 0000000000000000000000000000000000000000..f48940d0c2600011b9fc4af1934a3f399885f9b8 Binary files /dev/null and b/latex_and_figures/figs/ch_results/explore_neuralnet1_z.png differ diff --git a/latex_and_figures/figs/ch_results/explore_neuralnet2_z.png b/latex_and_figures/figs/ch_results/explore_neuralnet2_z.png new file mode 100644 index 0000000000000000000000000000000000000000..d6847198b49597af3db3178fdf33e6e5b21266a3 Binary files /dev/null and b/latex_and_figures/figs/ch_results/explore_neuralnet2_z.png differ diff --git a/latex_and_figures/figs/ch_results/explore_neuralnet3_z.png b/latex_and_figures/figs/ch_results/explore_neuralnet3_z.png new file mode 100644 index 0000000000000000000000000000000000000000..11f627f08412831daf1906a6878fce29aadf1479 Binary files /dev/null and b/latex_and_figures/figs/ch_results/explore_neuralnet3_z.png differ diff --git a/latex_and_figures/figs/ch_results/explore_neuralnet4_z.png b/latex_and_figures/figs/ch_results/explore_neuralnet4_z.png new file mode 100644 index 0000000000000000000000000000000000000000..acc8b555ff5e8f1ba6b8a2166f30b6edf45441c8 Binary files /dev/null and b/latex_and_figures/figs/ch_results/explore_neuralnet4_z.png differ diff --git a/latex_and_figures/figs/ch_results/imme_rew_hists.png b/latex_and_figures/figs/ch_results/imme_rew_hists.png new file mode 100644 index 0000000000000000000000000000000000000000..ee5c55ceb0051a327bec57b803e2fe51737b0396 Binary files /dev/null and b/latex_and_figures/figs/ch_results/imme_rew_hists.png differ diff --git a/latex_and_figures/figs/ch_robotmodel/featuremapping.png b/latex_and_figures/figs/ch_robotmodel/featuremapping.png new file mode 100644 index 0000000000000000000000000000000000000000..6019d61be712356ef7aeca0738df3d5f7edfb26e Binary files /dev/null and b/latex_and_figures/figs/ch_robotmodel/featuremapping.png differ diff --git a/latex_and_figures/figs/ch_robotmodel/gridmapping.png b/latex_and_figures/figs/ch_robotmodel/gridmapping.png new file mode 100644 index 0000000000000000000000000000000000000000..31546ddc7b0d9e6bb5f1d7cdde936c7cbc8c061e Binary files /dev/null and b/latex_and_figures/figs/ch_robotmodel/gridmapping.png differ diff --git a/latex_and_figures/figs/ch_robotmodel/locationbasedmeasure.png b/latex_and_figures/figs/ch_robotmodel/locationbasedmeasure.png new file mode 100644 index 0000000000000000000000000000000000000000..93cc5b8ba9ec3fd8dc15c52993501562d4062d2a Binary files /dev/null and b/latex_and_figures/figs/ch_robotmodel/locationbasedmeasure.png differ diff --git a/latex_and_figures/figs/ch_robotmodel/measurement_model_features.png b/latex_and_figures/figs/ch_robotmodel/measurement_model_features.png new file mode 100644 index 0000000000000000000000000000000000000000..942cd2e40b952a9db5e9de961ddacc36369d34b8 Binary files /dev/null and b/latex_and_figures/figs/ch_robotmodel/measurement_model_features.png differ diff --git a/latex_and_figures/figs/ch_robotmodel/measurement_model_mapmatching.png b/latex_and_figures/figs/ch_robotmodel/measurement_model_mapmatching.png new file mode 100644 index 0000000000000000000000000000000000000000..a7b96519b7c329215650aac6bd8f06d1dec31fe5 Binary files /dev/null and b/latex_and_figures/figs/ch_robotmodel/measurement_model_mapmatching.png differ diff --git a/latex_and_figures/figs/ch_robotmodel/measurement_model_mapmatching.svg b/latex_and_figures/figs/ch_robotmodel/measurement_model_mapmatching.svg new file mode 100644 index 0000000000000000000000000000000000000000..b23803c408a3ea22876394b097ab3dc50ef88dc7 --- /dev/null +++ b/latex_and_figures/figs/ch_robotmodel/measurement_model_mapmatching.svg @@ -0,0 +1,1696 @@ +<?xml version="1.0" encoding="utf-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Created with matplotlib (https://matplotlib.org/) --> +<svg height="358.56pt" version="1.1" viewBox="0 0 720 358.56" width="720pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <defs> + <style type="text/css"> +*{stroke-linecap:butt;stroke-linejoin:round;white-space:pre;} + </style> + </defs> + <g id="figure_1"> + <g id="patch_1"> + <path d="M 0 358.56 +L 720 358.56 +L 720 0 +L 0 0 +z +" style="fill:#ffffff;"/> + </g> + <g id="axes_1"> + <g id="patch_2"> + <path d="M 90 307.890982 +L 343.636364 307.890982 +L 343.636364 54.254618 +L 90 54.254618 +z +" style="fill:#ffffff;"/> + </g> + <g clip-path="url(#p07d1048ee6)"> + <image height="254.16" id="image8121bb489c" transform="scale(1 -1)translate(0 -254.16)" width="254.16" x="90" xlink:href="data:image/png;base64, +iVBORw0KGgoAAAANSUhEUgAAAWEAAAFhCAYAAACh/xvXAAAABHNCSVQICAgIfAhkiAAABPFJREFUeJzt3TEOgzAQAME44v9fvnzBBbBJmKmRfNXqGuw1M/MCIPGuBwB4MhEGCIkwQEiEAUIiDBASYYCQCAOERBggdOx8tNa6eg6Av7PzL5xNGCAkwgAhEQYIiTBASIQBQiIMEBJhgJAIA4REGCAkwgAhEQYIiTBASIQBQiIMEBJhgJAIA4S2LnU/w87lxgDf4q7HLGzCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCx10HrbXuOgrgZ9iEAUIiDBASYYCQCAOERBggJMIAIREGCIkwQEiEAUIiDBASYYCQCAOERBggJMIAIREGCIkwQGjrUveZuXoOgEeyCQOERBggJMIAIREGCIkwQEiEAUIiDBASYYDQB+OID8aIwF82AAAAAElFTkSuQmCC" y="-53.730982"/> + </g> + <g id="matplotlib.axis_1"> + <g id="xtick_1"> + <g id="line2d_1"> + <defs> + <path d="M 0 0 +L 0 3.5 +" id="mf144b052cc" style="stroke:#000000;stroke-width:0.8;"/> + </defs> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="93.170455" xlink:href="#mf144b052cc" y="307.890982"/> + </g> + </g> + <g id="text_1"> + <!-- 0 --> + <defs> + <path d="M 31.78125 66.40625 +Q 24.171875 66.40625 20.328125 58.90625 +Q 16.5 51.421875 16.5 36.375 +Q 16.5 21.390625 20.328125 13.890625 +Q 24.171875 6.390625 31.78125 6.390625 +Q 39.453125 6.390625 43.28125 13.890625 +Q 47.125 21.390625 47.125 36.375 +Q 47.125 51.421875 43.28125 58.90625 +Q 39.453125 66.40625 31.78125 66.40625 +z +M 31.78125 74.21875 +Q 44.046875 74.21875 50.515625 64.515625 +Q 56.984375 54.828125 56.984375 36.375 +Q 56.984375 17.96875 50.515625 8.265625 +Q 44.046875 -1.421875 31.78125 -1.421875 +Q 19.53125 -1.421875 13.0625 8.265625 +Q 6.59375 17.96875 6.59375 36.375 +Q 6.59375 54.828125 13.0625 64.515625 +Q 19.53125 74.21875 31.78125 74.21875 +z +" id="DejaVuSans-48"/> + </defs> + <g transform="translate(89.03483 324.768951)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="xtick_2"> + <g id="line2d_2"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="156.579545" xlink:href="#mf144b052cc" y="307.890982"/> + </g> + </g> + <g id="text_2"> + <!-- 10 --> + <defs> + <path d="M 12.40625 8.296875 +L 28.515625 8.296875 +L 28.515625 63.921875 +L 10.984375 60.40625 +L 10.984375 69.390625 +L 28.421875 72.90625 +L 38.28125 72.90625 +L 38.28125 8.296875 +L 54.390625 8.296875 +L 54.390625 0 +L 12.40625 0 +z +" id="DejaVuSans-49"/> + </defs> + <g transform="translate(148.308295 324.768951)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-49"/> + <use x="63.623047" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="xtick_3"> + <g id="line2d_3"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="219.988636" xlink:href="#mf144b052cc" y="307.890982"/> + </g> + </g> + <g id="text_3"> + <!-- 20 --> + <defs> + <path d="M 19.1875 8.296875 +L 53.609375 8.296875 +L 53.609375 0 +L 7.328125 0 +L 7.328125 8.296875 +Q 12.9375 14.109375 22.625 23.890625 +Q 32.328125 33.6875 34.8125 36.53125 +Q 39.546875 41.84375 41.421875 45.53125 +Q 43.3125 49.21875 43.3125 52.78125 +Q 43.3125 58.59375 39.234375 62.25 +Q 35.15625 65.921875 28.609375 65.921875 +Q 23.96875 65.921875 18.8125 64.3125 +Q 13.671875 62.703125 7.8125 59.421875 +L 7.8125 69.390625 +Q 13.765625 71.78125 18.9375 73 +Q 24.125 74.21875 28.421875 74.21875 +Q 39.75 74.21875 46.484375 68.546875 +Q 53.21875 62.890625 53.21875 53.421875 +Q 53.21875 48.921875 51.53125 44.890625 +Q 49.859375 40.875 45.40625 35.40625 +Q 44.1875 33.984375 37.640625 27.21875 +Q 31.109375 20.453125 19.1875 8.296875 +z +" id="DejaVuSans-50"/> + </defs> + <g transform="translate(211.717386 324.768951)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-50"/> + <use x="63.623047" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="xtick_4"> + <g id="line2d_4"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="283.397727" xlink:href="#mf144b052cc" y="307.890982"/> + </g> + </g> + <g id="text_4"> + <!-- 30 --> + <defs> + <path d="M 40.578125 39.3125 +Q 47.65625 37.796875 51.625 33 +Q 55.609375 28.21875 55.609375 21.1875 +Q 55.609375 10.40625 48.1875 4.484375 +Q 40.765625 -1.421875 27.09375 -1.421875 +Q 22.515625 -1.421875 17.65625 -0.515625 +Q 12.796875 0.390625 7.625 2.203125 +L 7.625 11.71875 +Q 11.71875 9.328125 16.59375 8.109375 +Q 21.484375 6.890625 26.8125 6.890625 +Q 36.078125 6.890625 40.9375 10.546875 +Q 45.796875 14.203125 45.796875 21.1875 +Q 45.796875 27.640625 41.28125 31.265625 +Q 36.765625 34.90625 28.71875 34.90625 +L 20.21875 34.90625 +L 20.21875 43.015625 +L 29.109375 43.015625 +Q 36.375 43.015625 40.234375 45.921875 +Q 44.09375 48.828125 44.09375 54.296875 +Q 44.09375 59.90625 40.109375 62.90625 +Q 36.140625 65.921875 28.71875 65.921875 +Q 24.65625 65.921875 20.015625 65.03125 +Q 15.375 64.15625 9.8125 62.3125 +L 9.8125 71.09375 +Q 15.4375 72.65625 20.34375 73.4375 +Q 25.25 74.21875 29.59375 74.21875 +Q 40.828125 74.21875 47.359375 69.109375 +Q 53.90625 64.015625 53.90625 55.328125 +Q 53.90625 49.265625 50.4375 45.09375 +Q 46.96875 40.921875 40.578125 39.3125 +z +" id="DejaVuSans-51"/> + </defs> + <g transform="translate(275.126477 324.768951)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-51"/> + <use x="63.623047" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="text_5"> + <!-- x --> + <defs> + <path d="M 54.890625 54.6875 +L 35.109375 28.078125 +L 55.90625 0 +L 45.3125 0 +L 29.390625 21.484375 +L 13.484375 0 +L 2.875 0 +L 24.125 28.609375 +L 4.6875 54.6875 +L 15.28125 54.6875 +L 29.78125 35.203125 +L 44.28125 54.6875 +z +" id="DejaVuSans-120"/> + </defs> + <g transform="translate(212.970994 341.350513)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-120"/> + </g> + </g> + </g> + <g id="matplotlib.axis_2"> + <g id="ytick_1"> + <g id="line2d_5"> + <defs> + <path d="M 0 0 +L -3.5 0 +" id="md113a83665" style="stroke:#000000;stroke-width:0.8;"/> + </defs> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="90" xlink:href="#md113a83665" y="304.720527"/> + </g> + </g> + <g id="text_6"> + <!-- 0 --> + <g transform="translate(74.72875 309.659512)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="ytick_2"> + <g id="line2d_6"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="90" xlink:href="#md113a83665" y="273.015982"/> + </g> + </g> + <g id="text_7"> + <!-- 5 --> + <defs> + <path d="M 10.796875 72.90625 +L 49.515625 72.90625 +L 49.515625 64.59375 +L 19.828125 64.59375 +L 19.828125 46.734375 +Q 21.96875 47.46875 24.109375 47.828125 +Q 26.265625 48.1875 28.421875 48.1875 +Q 40.625 48.1875 47.75 41.5 +Q 54.890625 34.8125 54.890625 23.390625 +Q 54.890625 11.625 47.5625 5.09375 +Q 40.234375 -1.421875 26.90625 -1.421875 +Q 22.3125 -1.421875 17.546875 -0.640625 +Q 12.796875 0.140625 7.71875 1.703125 +L 7.71875 11.625 +Q 12.109375 9.234375 16.796875 8.0625 +Q 21.484375 6.890625 26.703125 6.890625 +Q 35.15625 6.890625 40.078125 11.328125 +Q 45.015625 15.765625 45.015625 23.390625 +Q 45.015625 31 40.078125 35.4375 +Q 35.15625 39.890625 26.703125 39.890625 +Q 22.75 39.890625 18.8125 39.015625 +Q 14.890625 38.140625 10.796875 36.28125 +z +" id="DejaVuSans-53"/> + </defs> + <g transform="translate(74.72875 277.954966)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-53"/> + </g> + </g> + </g> + <g id="ytick_3"> + <g id="line2d_7"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="90" xlink:href="#md113a83665" y="241.311436"/> + </g> + </g> + <g id="text_8"> + <!-- 10 --> + <g transform="translate(66.4575 246.250421)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-49"/> + <use x="63.623047" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="ytick_4"> + <g id="line2d_8"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="90" xlink:href="#md113a83665" y="209.606891"/> + </g> + </g> + <g id="text_9"> + <!-- 15 --> + <g transform="translate(66.4575 214.545875)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-49"/> + <use x="63.623047" xlink:href="#DejaVuSans-53"/> + </g> + </g> + </g> + <g id="ytick_5"> + <g id="line2d_9"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="90" xlink:href="#md113a83665" y="177.902345"/> + </g> + </g> + <g id="text_10"> + <!-- 20 --> + <g transform="translate(66.4575 182.84133)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-50"/> + <use x="63.623047" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="ytick_6"> + <g id="line2d_10"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="90" xlink:href="#md113a83665" y="146.1978"/> + </g> + </g> + <g id="text_11"> + <!-- 25 --> + <g transform="translate(66.4575 151.136784)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-50"/> + <use x="63.623047" xlink:href="#DejaVuSans-53"/> + </g> + </g> + </g> + <g id="ytick_7"> + <g id="line2d_11"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="90" xlink:href="#md113a83665" y="114.493255"/> + </g> + </g> + <g id="text_12"> + <!-- 30 --> + <g transform="translate(66.4575 119.432239)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-51"/> + <use x="63.623047" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="ytick_8"> + <g id="line2d_12"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="90" xlink:href="#md113a83665" y="82.788709"/> + </g> + </g> + <g id="text_13"> + <!-- 35 --> + <g transform="translate(66.4575 87.727693)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-51"/> + <use x="63.623047" xlink:href="#DejaVuSans-53"/> + </g> + </g> + </g> + <g id="text_14"> + <!-- y --> + <defs> + <path d="M 32.171875 -5.078125 +Q 28.375 -14.84375 24.75 -17.8125 +Q 21.140625 -20.796875 15.09375 -20.796875 +L 7.90625 -20.796875 +L 7.90625 -13.28125 +L 13.1875 -13.28125 +Q 16.890625 -13.28125 18.9375 -11.515625 +Q 21 -9.765625 23.484375 -3.21875 +L 25.09375 0.875 +L 2.984375 54.6875 +L 12.5 54.6875 +L 29.59375 11.921875 +L 46.6875 54.6875 +L 56.203125 54.6875 +z +" id="DejaVuSans-121"/> + </defs> + <g transform="translate(59.753906 184.919988)rotate(-90)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-121"/> + </g> + </g> + </g> + <g id="line2d_13"> + <defs> + <path d="M 0 1.5 +C 0.397805 1.5 0.77937 1.341951 1.06066 1.06066 +C 1.341951 0.77937 1.5 0.397805 1.5 0 +C 1.5 -0.397805 1.341951 -0.77937 1.06066 -1.06066 +C 0.77937 -1.341951 0.397805 -1.5 0 -1.5 +C -0.397805 -1.5 -0.77937 -1.341951 -1.06066 -1.06066 +C -1.341951 -0.77937 -1.5 -0.397805 -1.5 0 +C -1.5 0.397805 -1.341951 0.77937 -1.06066 1.06066 +C -0.77937 1.341951 -0.397805 1.5 0 1.5 +z +" id="m58866a935f" style="stroke:#1f77b4;"/> + </defs> + <g clip-path="url(#p07d1048ee6)"> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="129.534988" xlink:href="#m58866a935f" y="228.886952"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="117.062328" xlink:href="#m58866a935f" y="248.689741"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="138.601553" xlink:href="#m58866a935f" y="224.54572"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="183.930101" xlink:href="#m58866a935f" y="235.378975"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="141.570892" xlink:href="#m58866a935f" y="283.67248"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="176.338416" xlink:href="#m58866a935f" y="181.628129"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="124.899769" xlink:href="#m58866a935f" y="235.831554"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="178.13675" xlink:href="#m58866a935f" y="246.851055"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="115.153619" xlink:href="#m58866a935f" y="267.463182"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="175.485441" xlink:href="#m58866a935f" y="247.608617"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="136.485723" xlink:href="#m58866a935f" y="221.973033"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="150.601707" xlink:href="#m58866a935f" y="263.738153"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="158.08432" xlink:href="#m58866a935f" y="264.37759"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="155.278157" xlink:href="#m58866a935f" y="243.971014"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="185.979078" xlink:href="#m58866a935f" y="245.833445"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="152.16842" xlink:href="#m58866a935f" y="262.39495"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="146.312249" xlink:href="#m58866a935f" y="213.332884"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="182.440429" xlink:href="#m58866a935f" y="281.411139"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="132.751675" xlink:href="#m58866a935f" y="252.202373"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="128.96588" xlink:href="#m58866a935f" y="256.939057"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="228.550948" xlink:href="#m58866a935f" y="281.014619"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="191.128054" xlink:href="#m58866a935f" y="221.415675"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="155.793932" xlink:href="#m58866a935f" y="263.619666"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="181.045228" xlink:href="#m58866a935f" y="258.56063"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="157.111976" xlink:href="#m58866a935f" y="246.438526"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="128.531418" xlink:href="#m58866a935f" y="268.491056"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="123.408337" xlink:href="#m58866a935f" y="244.186829"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="129.868782" xlink:href="#m58866a935f" y="265.357199"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="135.672512" xlink:href="#m58866a935f" y="257.175531"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="156.234143" xlink:href="#m58866a935f" y="240.242967"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="134.196427" xlink:href="#m58866a935f" y="222.743133"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="155.178986" xlink:href="#m58866a935f" y="260.937064"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="141.934001" xlink:href="#m58866a935f" y="248.570374"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="135.272137" xlink:href="#m58866a935f" y="270.69575"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="141.172847" xlink:href="#m58866a935f" y="194.571538"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="152.362159" xlink:href="#m58866a935f" y="248.789481"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="175.799789" xlink:href="#m58866a935f" y="235.907348"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="115.663831" xlink:href="#m58866a935f" y="273.979315"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="158.100219" xlink:href="#m58866a935f" y="216.421262"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="200.286378" xlink:href="#m58866a935f" y="257.878905"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="114.81991" xlink:href="#m58866a935f" y="239.663518"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="126.602474" xlink:href="#m58866a935f" y="252.990828"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="130.726987" xlink:href="#m58866a935f" y="254.68485"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="113.378939" xlink:href="#m58866a935f" y="238.693646"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="213.816573" xlink:href="#m58866a935f" y="272.055437"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="151.240541" xlink:href="#m58866a935f" y="263.85165"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="193.59759" xlink:href="#m58866a935f" y="230.841434"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="232.762851" xlink:href="#m58866a935f" y="247.396636"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="112.998283" xlink:href="#m58866a935f" y="269.520854"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="137.777908" xlink:href="#m58866a935f" y="239.939587"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="141.084068" xlink:href="#m58866a935f" y="253.698811"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="157.855524" xlink:href="#m58866a935f" y="268.073097"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="145.45742" xlink:href="#m58866a935f" y="264.59701"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="126.712755" xlink:href="#m58866a935f" y="244.425841"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="217.250816" xlink:href="#m58866a935f" y="274.909716"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="177.535537" xlink:href="#m58866a935f" y="271.843339"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="135.026501" xlink:href="#m58866a935f" y="207.025007"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="126.1649" xlink:href="#m58866a935f" y="281.420068"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="174.365839" xlink:href="#m58866a935f" y="216.241904"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="118.057286" xlink:href="#m58866a935f" y="259.573967"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="153.8033" xlink:href="#m58866a935f" y="261.058071"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="189.275404" xlink:href="#m58866a935f" y="267.694528"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="132.237785" xlink:href="#m58866a935f" y="273.247376"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="135.488602" xlink:href="#m58866a935f" y="237.271041"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="135.21111" xlink:href="#m58866a935f" y="225.119125"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="161.367569" xlink:href="#m58866a935f" y="235.958087"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="161.551539" xlink:href="#m58866a935f" y="264.603688"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="135.651016" xlink:href="#m58866a935f" y="272.630731"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="124.376265" xlink:href="#m58866a935f" y="230.881519"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="117.600189" xlink:href="#m58866a935f" y="268.177906"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="155.503996" xlink:href="#m58866a935f" y="218.742307"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="144.893903" xlink:href="#m58866a935f" y="275.983184"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="170.000811" xlink:href="#m58866a935f" y="274.334262"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="203.301991" xlink:href="#m58866a935f" y="245.258711"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="128.399378" xlink:href="#m58866a935f" y="238.85146"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="146.666343" xlink:href="#m58866a935f" y="235.479264"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="136.727747" xlink:href="#m58866a935f" y="242.436603"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="145.881445" xlink:href="#m58866a935f" y="238.316789"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="181.178415" xlink:href="#m58866a935f" y="189.887576"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="124.049463" xlink:href="#m58866a935f" y="264.718441"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="166.205857" xlink:href="#m58866a935f" y="272.115312"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="164.697188" xlink:href="#m58866a935f" y="266.633492"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="159.407105" xlink:href="#m58866a935f" y="273.602854"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="156.329457" xlink:href="#m58866a935f" y="273.526313"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="162.401748" xlink:href="#m58866a935f" y="260.697743"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="202.264872" xlink:href="#m58866a935f" y="269.816975"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="126.833095" xlink:href="#m58866a935f" y="192.310009"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="181.904702" xlink:href="#m58866a935f" y="268.229651"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="136.533793" xlink:href="#m58866a935f" y="186.543903"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="139.986883" xlink:href="#m58866a935f" y="255.842124"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="170.16783" xlink:href="#m58866a935f" y="252.64448"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="190.282199" xlink:href="#m58866a935f" y="251.165013"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="181.394429" xlink:href="#m58866a935f" y="218.449409"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="146.25753" xlink:href="#m58866a935f" y="267.431126"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="152.927912" xlink:href="#m58866a935f" y="239.831361"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="121.296142" xlink:href="#m58866a935f" y="257.406894"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="129.404697" xlink:href="#m58866a935f" y="250.648014"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="156.273382" xlink:href="#m58866a935f" y="276.128092"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="126.11389" xlink:href="#m58866a935f" y="228.576672"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="122.355059" xlink:href="#m58866a935f" y="281.29743"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="150.227946" xlink:href="#m58866a935f" y="226.854792"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="138.457093" xlink:href="#m58866a935f" y="274.984899"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="166.307894" xlink:href="#m58866a935f" y="269.381692"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="136.643737" xlink:href="#m58866a935f" y="237.347719"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="173.396227" xlink:href="#m58866a935f" y="274.113666"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="145.686634" xlink:href="#m58866a935f" y="248.503395"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="113.150398" xlink:href="#m58866a935f" y="195.40919"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="125.396573" xlink:href="#m58866a935f" y="255.078013"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="148.091544" xlink:href="#m58866a935f" y="258.844281"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="115.842697" xlink:href="#m58866a935f" y="260.638971"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="166.175794" xlink:href="#m58866a935f" y="245.046433"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="131.161971" xlink:href="#m58866a935f" y="249.899054"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="163.853649" xlink:href="#m58866a935f" y="262.437812"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="118.313275" xlink:href="#m58866a935f" y="285.388577"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="134.73266" xlink:href="#m58866a935f" y="251.961919"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="119.483891" xlink:href="#m58866a935f" y="272.996403"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="185.614227" xlink:href="#m58866a935f" y="254.938025"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="201.863631" xlink:href="#m58866a935f" y="245.576871"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="125.156011" xlink:href="#m58866a935f" y="282.054992"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="133.653614" xlink:href="#m58866a935f" y="261.562655"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="151.312047" xlink:href="#m58866a935f" y="280.13681"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="147.426176" xlink:href="#m58866a935f" y="248.150375"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="124.773195" xlink:href="#m58866a935f" y="248.805359"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="122.8583" xlink:href="#m58866a935f" y="263.239159"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="134.333763" xlink:href="#m58866a935f" y="225.923819"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="187.121402" xlink:href="#m58866a935f" y="237.21152"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="112.399609" xlink:href="#m58866a935f" y="277.117001"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="154.238833" xlink:href="#m58866a935f" y="248.136257"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="146.538829" xlink:href="#m58866a935f" y="272.859525"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="135.93611" xlink:href="#m58866a935f" y="282.270444"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="140.680542" xlink:href="#m58866a935f" y="278.252741"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="145.592467" xlink:href="#m58866a935f" y="232.573999"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="202.310431" xlink:href="#m58866a935f" y="283.257141"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="159.881665" xlink:href="#m58866a935f" y="246.28662"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="128.336828" xlink:href="#m58866a935f" y="275.848764"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="204.438673" xlink:href="#m58866a935f" y="232.22582"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="173.191969" xlink:href="#m58866a935f" y="268.500802"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="136.800231" xlink:href="#m58866a935f" y="277.264747"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="149.106071" xlink:href="#m58866a935f" y="215.966912"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="145.525404" xlink:href="#m58866a935f" y="239.578198"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="168.151404" xlink:href="#m58866a935f" y="270.243276"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="123.255872" xlink:href="#m58866a935f" y="209.899706"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="124.212778" xlink:href="#m58866a935f" y="224.718685"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="176.210918" xlink:href="#m58866a935f" y="285.575625"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="158.097494" xlink:href="#m58866a935f" y="277.242265"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="121.247863" xlink:href="#m58866a935f" y="237.421043"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="151.829429" xlink:href="#m58866a935f" y="248.388513"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="188.417331" xlink:href="#m58866a935f" y="278.427956"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="184.917446" xlink:href="#m58866a935f" y="223.378579"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="119.705742" xlink:href="#m58866a935f" y="278.656899"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="134.451095" xlink:href="#m58866a935f" y="253.044493"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="165.965907" xlink:href="#m58866a935f" y="278.289951"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="174.287831" xlink:href="#m58866a935f" y="197.742018"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="136.756517" xlink:href="#m58866a935f" y="239.038963"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="147.562751" xlink:href="#m58866a935f" y="259.962433"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="181.80986" xlink:href="#m58866a935f" y="255.665223"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="116.01759" xlink:href="#m58866a935f" y="235.128086"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="157.426976" xlink:href="#m58866a935f" y="247.292189"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="177.125621" xlink:href="#m58866a935f" y="283.130241"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="166.46929" xlink:href="#m58866a935f" y="226.948416"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="142.771639" xlink:href="#m58866a935f" y="278.265998"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="159.197967" xlink:href="#m58866a935f" y="260.795913"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="191.03305" xlink:href="#m58866a935f" y="252.885885"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="127.714554" xlink:href="#m58866a935f" y="266.534387"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="159.412364" xlink:href="#m58866a935f" y="256.617712"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="226.260328" xlink:href="#m58866a935f" y="234.547019"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="168.187181" xlink:href="#m58866a935f" y="272.512773"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="152.432224" xlink:href="#m58866a935f" y="280.715235"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="147.104219" xlink:href="#m58866a935f" y="258.047126"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="146.148153" xlink:href="#m58866a935f" y="237.050138"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="181.538267" xlink:href="#m58866a935f" y="274.641405"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="120.487634" xlink:href="#m58866a935f" y="274.036813"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="163.545871" xlink:href="#m58866a935f" y="280.027081"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="159.450649" xlink:href="#m58866a935f" y="251.023861"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="149.831296" xlink:href="#m58866a935f" y="250.301572"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="146.604945" xlink:href="#m58866a935f" y="241.484723"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="153.802891" xlink:href="#m58866a935f" y="255.513637"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="140.117942" xlink:href="#m58866a935f" y="273.829092"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="163.47498" xlink:href="#m58866a935f" y="259.507016"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="117.460652" xlink:href="#m58866a935f" y="228.296827"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="190.619326" xlink:href="#m58866a935f" y="240.544808"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="151.309412" xlink:href="#m58866a935f" y="259.039838"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="165.633437" xlink:href="#m58866a935f" y="202.738822"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="122.79794" xlink:href="#m58866a935f" y="243.441607"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="195.388551" xlink:href="#m58866a935f" y="255.315383"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="144.673443" xlink:href="#m58866a935f" y="268.40364"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="180.689408" xlink:href="#m58866a935f" y="241.936601"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="156.424402" xlink:href="#m58866a935f" y="222.053656"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="151.606939" xlink:href="#m58866a935f" y="258.885418"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="145.135261" xlink:href="#m58866a935f" y="239.561828"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="120.945304" xlink:href="#m58866a935f" y="265.435237"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="161.336226" xlink:href="#m58866a935f" y="264.716255"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="116.211666" xlink:href="#m58866a935f" y="213.124729"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="145.761912" xlink:href="#m58866a935f" y="219.106589"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="156.518037" xlink:href="#m58866a935f" y="264.241934"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="123.164806" xlink:href="#m58866a935f" y="270.545706"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="161.791516" xlink:href="#m58866a935f" y="263.837911"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="162.889738" xlink:href="#m58866a935f" y="217.30143"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="162.145478" xlink:href="#m58866a935f" y="208.624517"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="129.5145" xlink:href="#m58866a935f" y="278.607098"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="160.936754" xlink:href="#m58866a935f" y="235.48377"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="115.771572" xlink:href="#m58866a935f" y="242.080935"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="128.0135" xlink:href="#m58866a935f" y="268.006684"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="118.634797" xlink:href="#m58866a935f" y="267.328914"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="157.487421" xlink:href="#m58866a935f" y="264.353067"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="155.63883" xlink:href="#m58866a935f" y="237.215616"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="122.104617" xlink:href="#m58866a935f" y="271.767744"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="137.59411" xlink:href="#m58866a935f" y="270.461764"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="147.254879" xlink:href="#m58866a935f" y="240.930723"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="128.79606" xlink:href="#m58866a935f" y="268.69636"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="173.034979" xlink:href="#m58866a935f" y="238.932386"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="191.954365" xlink:href="#m58866a935f" y="243.547052"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="150.060039" xlink:href="#m58866a935f" y="251.999889"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="164.737859" xlink:href="#m58866a935f" y="253.005565"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="118.672664" xlink:href="#m58866a935f" y="270.075682"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="124.188278" xlink:href="#m58866a935f" y="262.705706"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="123.5163" xlink:href="#m58866a935f" y="243.43987"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="170.055097" xlink:href="#m58866a935f" y="284.245921"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="183.989501" xlink:href="#m58866a935f" y="274.888143"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="144.550289" xlink:href="#m58866a935f" y="236.649796"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="122.102031" xlink:href="#m58866a935f" y="253.42903"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="156.117803" xlink:href="#m58866a935f" y="236.889353"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="136.873857" xlink:href="#m58866a935f" y="278.095874"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="195.893912" xlink:href="#m58866a935f" y="250.09364"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="169.507681" xlink:href="#m58866a935f" y="239.994481"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="172.52514" xlink:href="#m58866a935f" y="254.758515"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="126.072145" xlink:href="#m58866a935f" y="252.703981"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="127.745653" xlink:href="#m58866a935f" y="257.855713"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="158.661227" xlink:href="#m58866a935f" y="272.099579"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="114.088839" xlink:href="#m58866a935f" y="245.441622"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="131.920244" xlink:href="#m58866a935f" y="267.043994"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="133.922635" xlink:href="#m58866a935f" y="265.973307"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="117.778926" xlink:href="#m58866a935f" y="266.803378"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="115.265534" xlink:href="#m58866a935f" y="236.951137"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="127.871769" xlink:href="#m58866a935f" y="185.830262"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="164.223152" xlink:href="#m58866a935f" y="281.224386"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="180.767408" xlink:href="#m58866a935f" y="269.161077"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="154.186224" xlink:href="#m58866a935f" y="258.723819"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="123.046739" xlink:href="#m58866a935f" y="261.043681"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="137.273184" xlink:href="#m58866a935f" y="247.037093"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="114.730832" xlink:href="#m58866a935f" y="279.669533"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="152.773511" xlink:href="#m58866a935f" y="248.190614"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="127.785248" xlink:href="#m58866a935f" y="249.789734"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="142.721808" xlink:href="#m58866a935f" y="199.629544"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="121.700618" xlink:href="#m58866a935f" y="200.650255"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="113.731218" xlink:href="#m58866a935f" y="206.792424"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="140.932011" xlink:href="#m58866a935f" y="250.811631"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="155.654596" xlink:href="#m58866a935f" y="237.345054"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="146.818352" xlink:href="#m58866a935f" y="234.231937"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="157.573414" xlink:href="#m58866a935f" y="204.734294"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="119.869785" xlink:href="#m58866a935f" y="268.5218"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="161.533202" xlink:href="#m58866a935f" y="257.093406"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="119.49129" xlink:href="#m58866a935f" y="243.383747"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="173.05199" xlink:href="#m58866a935f" y="247.891165"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="175.714623" xlink:href="#m58866a935f" y="266.219632"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="134.160243" xlink:href="#m58866a935f" y="239.56514"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="126.85014" xlink:href="#m58866a935f" y="262.945122"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="112.84011" xlink:href="#m58866a935f" y="285.092701"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="204.199536" xlink:href="#m58866a935f" y="262.922004"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="154.894504" xlink:href="#m58866a935f" y="274.720425"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="125.841903" xlink:href="#m58866a935f" y="256.583598"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="120.291397" xlink:href="#m58866a935f" y="233.402831"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="171.695576" xlink:href="#m58866a935f" y="231.805713"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="116.109997" xlink:href="#m58866a935f" y="254.019296"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="112.960902" xlink:href="#m58866a935f" y="244.90673"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="139.914041" xlink:href="#m58866a935f" y="241.854933"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="138.63605" xlink:href="#m58866a935f" y="198.455129"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="148.691859" xlink:href="#m58866a935f" y="275.422362"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="167.544478" xlink:href="#m58866a935f" y="251.79409"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="129.795232" xlink:href="#m58866a935f" y="204.037904"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="160.427278" xlink:href="#m58866a935f" y="275.096066"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="117.367666" xlink:href="#m58866a935f" y="237.564702"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="115.252808" xlink:href="#m58866a935f" y="224.853171"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="127.763107" xlink:href="#m58866a935f" y="278.410354"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="157.182611" xlink:href="#m58866a935f" y="273.820278"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="153.195471" xlink:href="#m58866a935f" y="281.202098"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="113.231532" xlink:href="#m58866a935f" y="229.179429"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="127.194714" xlink:href="#m58866a935f" y="236.9063"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="140.610944" xlink:href="#m58866a935f" y="195.489733"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="222.815652" xlink:href="#m58866a935f" y="220.806839"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="152.956244" xlink:href="#m58866a935f" y="245.618171"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="151.307446" xlink:href="#m58866a935f" y="280.011389"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="186.417759" xlink:href="#m58866a935f" y="251.067507"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="219.880493" xlink:href="#m58866a935f" y="245.21439"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="142.784569" xlink:href="#m58866a935f" y="254.168582"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="166.051467" xlink:href="#m58866a935f" y="281.127037"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="137.472981" xlink:href="#m58866a935f" y="240.901221"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="133.326745" xlink:href="#m58866a935f" y="219.719136"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="155.53025" xlink:href="#m58866a935f" y="207.354018"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="193.880127" xlink:href="#m58866a935f" y="264.305231"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="127.8667" xlink:href="#m58866a935f" y="199.174046"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="126.857245" xlink:href="#m58866a935f" y="240.048508"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="143.995907" xlink:href="#m58866a935f" y="220.526495"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="118.633962" xlink:href="#m58866a935f" y="243.190971"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="121.322268" xlink:href="#m58866a935f" y="246.286424"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="131.642258" xlink:href="#m58866a935f" y="267.33715"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="116.059297" xlink:href="#m58866a935f" y="259.404918"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="129.619326" xlink:href="#m58866a935f" y="213.905367"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="132.722119" xlink:href="#m58866a935f" y="273.922528"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="138.041242" xlink:href="#m58866a935f" y="284.151076"/> + </g> + </g> + <g id="patch_3"> + <path d="M 90 307.890982 +L 90 54.254618 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/> + </g> + <g id="patch_4"> + <path d="M 343.636364 307.890982 +L 343.636364 54.254618 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/> + </g> + <g id="patch_5"> + <path d="M 90 307.890982 +L 343.636364 307.890982 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/> + </g> + <g id="patch_6"> + <path d="M 90 54.254618 +L 343.636364 54.254618 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/> + </g> + <g id="text_15"> + <!-- Initial set of particles --> + <defs> + <path d="M 9.8125 72.90625 +L 19.671875 72.90625 +L 19.671875 0 +L 9.8125 0 +z +" id="DejaVuSans-73"/> + <path d="M 54.890625 33.015625 +L 54.890625 0 +L 45.90625 0 +L 45.90625 32.71875 +Q 45.90625 40.484375 42.875 44.328125 +Q 39.84375 48.1875 33.796875 48.1875 +Q 26.515625 48.1875 22.3125 43.546875 +Q 18.109375 38.921875 18.109375 30.90625 +L 18.109375 0 +L 9.078125 0 +L 9.078125 54.6875 +L 18.109375 54.6875 +L 18.109375 46.1875 +Q 21.34375 51.125 25.703125 53.5625 +Q 30.078125 56 35.796875 56 +Q 45.21875 56 50.046875 50.171875 +Q 54.890625 44.34375 54.890625 33.015625 +z +" id="DejaVuSans-110"/> + <path d="M 9.421875 54.6875 +L 18.40625 54.6875 +L 18.40625 0 +L 9.421875 0 +z +M 9.421875 75.984375 +L 18.40625 75.984375 +L 18.40625 64.59375 +L 9.421875 64.59375 +z +" id="DejaVuSans-105"/> + <path d="M 18.3125 70.21875 +L 18.3125 54.6875 +L 36.8125 54.6875 +L 36.8125 47.703125 +L 18.3125 47.703125 +L 18.3125 18.015625 +Q 18.3125 11.328125 20.140625 9.421875 +Q 21.96875 7.515625 27.59375 7.515625 +L 36.8125 7.515625 +L 36.8125 0 +L 27.59375 0 +Q 17.1875 0 13.234375 3.875 +Q 9.28125 7.765625 9.28125 18.015625 +L 9.28125 47.703125 +L 2.6875 47.703125 +L 2.6875 54.6875 +L 9.28125 54.6875 +L 9.28125 70.21875 +z +" id="DejaVuSans-116"/> + <path d="M 34.28125 27.484375 +Q 23.390625 27.484375 19.1875 25 +Q 14.984375 22.515625 14.984375 16.5 +Q 14.984375 11.71875 18.140625 8.90625 +Q 21.296875 6.109375 26.703125 6.109375 +Q 34.1875 6.109375 38.703125 11.40625 +Q 43.21875 16.703125 43.21875 25.484375 +L 43.21875 27.484375 +z +M 52.203125 31.203125 +L 52.203125 0 +L 43.21875 0 +L 43.21875 8.296875 +Q 40.140625 3.328125 35.546875 0.953125 +Q 30.953125 -1.421875 24.3125 -1.421875 +Q 15.921875 -1.421875 10.953125 3.296875 +Q 6 8.015625 6 15.921875 +Q 6 25.140625 12.171875 29.828125 +Q 18.359375 34.515625 30.609375 34.515625 +L 43.21875 34.515625 +L 43.21875 35.40625 +Q 43.21875 41.609375 39.140625 45 +Q 35.0625 48.390625 27.6875 48.390625 +Q 23 48.390625 18.546875 47.265625 +Q 14.109375 46.140625 10.015625 43.890625 +L 10.015625 52.203125 +Q 14.9375 54.109375 19.578125 55.046875 +Q 24.21875 56 28.609375 56 +Q 40.484375 56 46.34375 49.84375 +Q 52.203125 43.703125 52.203125 31.203125 +z +" id="DejaVuSans-97"/> + <path d="M 9.421875 75.984375 +L 18.40625 75.984375 +L 18.40625 0 +L 9.421875 0 +z +" id="DejaVuSans-108"/> + <path id="DejaVuSans-32"/> + <path d="M 44.28125 53.078125 +L 44.28125 44.578125 +Q 40.484375 46.53125 36.375 47.5 +Q 32.28125 48.484375 27.875 48.484375 +Q 21.1875 48.484375 17.84375 46.4375 +Q 14.5 44.390625 14.5 40.28125 +Q 14.5 37.15625 16.890625 35.375 +Q 19.28125 33.59375 26.515625 31.984375 +L 29.59375 31.296875 +Q 39.15625 29.25 43.1875 25.515625 +Q 47.21875 21.78125 47.21875 15.09375 +Q 47.21875 7.46875 41.1875 3.015625 +Q 35.15625 -1.421875 24.609375 -1.421875 +Q 20.21875 -1.421875 15.453125 -0.5625 +Q 10.6875 0.296875 5.421875 2 +L 5.421875 11.28125 +Q 10.40625 8.6875 15.234375 7.390625 +Q 20.0625 6.109375 24.8125 6.109375 +Q 31.15625 6.109375 34.5625 8.28125 +Q 37.984375 10.453125 37.984375 14.40625 +Q 37.984375 18.0625 35.515625 20.015625 +Q 33.0625 21.96875 24.703125 23.78125 +L 21.578125 24.515625 +Q 13.234375 26.265625 9.515625 29.90625 +Q 5.8125 33.546875 5.8125 39.890625 +Q 5.8125 47.609375 11.28125 51.796875 +Q 16.75 56 26.8125 56 +Q 31.78125 56 36.171875 55.265625 +Q 40.578125 54.546875 44.28125 53.078125 +z +" id="DejaVuSans-115"/> + <path d="M 56.203125 29.59375 +L 56.203125 25.203125 +L 14.890625 25.203125 +Q 15.484375 15.921875 20.484375 11.0625 +Q 25.484375 6.203125 34.421875 6.203125 +Q 39.59375 6.203125 44.453125 7.46875 +Q 49.3125 8.734375 54.109375 11.28125 +L 54.109375 2.78125 +Q 49.265625 0.734375 44.1875 -0.34375 +Q 39.109375 -1.421875 33.890625 -1.421875 +Q 20.796875 -1.421875 13.15625 6.1875 +Q 5.515625 13.8125 5.515625 26.8125 +Q 5.515625 40.234375 12.765625 48.109375 +Q 20.015625 56 32.328125 56 +Q 43.359375 56 49.78125 48.890625 +Q 56.203125 41.796875 56.203125 29.59375 +z +M 47.21875 32.234375 +Q 47.125 39.59375 43.09375 43.984375 +Q 39.0625 48.390625 32.421875 48.390625 +Q 24.90625 48.390625 20.390625 44.140625 +Q 15.875 39.890625 15.1875 32.171875 +z +" id="DejaVuSans-101"/> + <path d="M 30.609375 48.390625 +Q 23.390625 48.390625 19.1875 42.75 +Q 14.984375 37.109375 14.984375 27.296875 +Q 14.984375 17.484375 19.15625 11.84375 +Q 23.34375 6.203125 30.609375 6.203125 +Q 37.796875 6.203125 41.984375 11.859375 +Q 46.1875 17.53125 46.1875 27.296875 +Q 46.1875 37.015625 41.984375 42.703125 +Q 37.796875 48.390625 30.609375 48.390625 +z +M 30.609375 56 +Q 42.328125 56 49.015625 48.375 +Q 55.71875 40.765625 55.71875 27.296875 +Q 55.71875 13.875 49.015625 6.21875 +Q 42.328125 -1.421875 30.609375 -1.421875 +Q 18.84375 -1.421875 12.171875 6.21875 +Q 5.515625 13.875 5.515625 27.296875 +Q 5.515625 40.765625 12.171875 48.375 +Q 18.84375 56 30.609375 56 +z +" id="DejaVuSans-111"/> + <path d="M 37.109375 75.984375 +L 37.109375 68.5 +L 28.515625 68.5 +Q 23.6875 68.5 21.796875 66.546875 +Q 19.921875 64.59375 19.921875 59.515625 +L 19.921875 54.6875 +L 34.71875 54.6875 +L 34.71875 47.703125 +L 19.921875 47.703125 +L 19.921875 0 +L 10.890625 0 +L 10.890625 47.703125 +L 2.296875 47.703125 +L 2.296875 54.6875 +L 10.890625 54.6875 +L 10.890625 58.5 +Q 10.890625 67.625 15.140625 71.796875 +Q 19.390625 75.984375 28.609375 75.984375 +z +" id="DejaVuSans-102"/> + <path d="M 18.109375 8.203125 +L 18.109375 -20.796875 +L 9.078125 -20.796875 +L 9.078125 54.6875 +L 18.109375 54.6875 +L 18.109375 46.390625 +Q 20.953125 51.265625 25.265625 53.625 +Q 29.59375 56 35.59375 56 +Q 45.5625 56 51.78125 48.09375 +Q 58.015625 40.1875 58.015625 27.296875 +Q 58.015625 14.40625 51.78125 6.484375 +Q 45.5625 -1.421875 35.59375 -1.421875 +Q 29.59375 -1.421875 25.265625 0.953125 +Q 20.953125 3.328125 18.109375 8.203125 +z +M 48.6875 27.296875 +Q 48.6875 37.203125 44.609375 42.84375 +Q 40.53125 48.484375 33.40625 48.484375 +Q 26.265625 48.484375 22.1875 42.84375 +Q 18.109375 37.203125 18.109375 27.296875 +Q 18.109375 17.390625 22.1875 11.75 +Q 26.265625 6.109375 33.40625 6.109375 +Q 40.53125 6.109375 44.609375 11.75 +Q 48.6875 17.390625 48.6875 27.296875 +z +" id="DejaVuSans-112"/> + <path d="M 41.109375 46.296875 +Q 39.59375 47.171875 37.8125 47.578125 +Q 36.03125 48 33.890625 48 +Q 26.265625 48 22.1875 43.046875 +Q 18.109375 38.09375 18.109375 28.8125 +L 18.109375 0 +L 9.078125 0 +L 9.078125 54.6875 +L 18.109375 54.6875 +L 18.109375 46.1875 +Q 20.953125 51.171875 25.484375 53.578125 +Q 30.03125 56 36.53125 56 +Q 37.453125 56 38.578125 55.875 +Q 39.703125 55.765625 41.0625 55.515625 +z +" id="DejaVuSans-114"/> + <path d="M 48.78125 52.59375 +L 48.78125 44.1875 +Q 44.96875 46.296875 41.140625 47.34375 +Q 37.3125 48.390625 33.40625 48.390625 +Q 24.65625 48.390625 19.8125 42.84375 +Q 14.984375 37.3125 14.984375 27.296875 +Q 14.984375 17.28125 19.8125 11.734375 +Q 24.65625 6.203125 33.40625 6.203125 +Q 37.3125 6.203125 41.140625 7.25 +Q 44.96875 8.296875 48.78125 10.40625 +L 48.78125 2.09375 +Q 45.015625 0.34375 40.984375 -0.53125 +Q 36.96875 -1.421875 32.421875 -1.421875 +Q 20.0625 -1.421875 12.78125 6.34375 +Q 5.515625 14.109375 5.515625 27.296875 +Q 5.515625 40.671875 12.859375 48.328125 +Q 20.21875 56 33.015625 56 +Q 37.15625 56 41.109375 55.140625 +Q 45.0625 54.296875 48.78125 52.59375 +z +" id="DejaVuSans-99"/> + </defs> + <g transform="translate(134.877963 48.254618)scale(0.156 -0.156)"> + <use xlink:href="#DejaVuSans-73"/> + <use x="29.492188" xlink:href="#DejaVuSans-110"/> + <use x="92.871094" xlink:href="#DejaVuSans-105"/> + <use x="120.654297" xlink:href="#DejaVuSans-116"/> + <use x="159.863281" xlink:href="#DejaVuSans-105"/> + <use x="187.646484" xlink:href="#DejaVuSans-97"/> + <use x="248.925781" xlink:href="#DejaVuSans-108"/> + <use x="276.708984" xlink:href="#DejaVuSans-32"/> + <use x="308.496094" xlink:href="#DejaVuSans-115"/> + <use x="360.595703" xlink:href="#DejaVuSans-101"/> + <use x="422.119141" xlink:href="#DejaVuSans-116"/> + <use x="461.328125" xlink:href="#DejaVuSans-32"/> + <use x="493.115234" xlink:href="#DejaVuSans-111"/> + <use x="554.296875" xlink:href="#DejaVuSans-102"/> + <use x="589.501953" xlink:href="#DejaVuSans-32"/> + <use x="621.289062" xlink:href="#DejaVuSans-112"/> + <use x="684.765625" xlink:href="#DejaVuSans-97"/> + <use x="746.044922" xlink:href="#DejaVuSans-114"/> + <use x="787.158203" xlink:href="#DejaVuSans-116"/> + <use x="826.367188" xlink:href="#DejaVuSans-105"/> + <use x="854.150391" xlink:href="#DejaVuSans-99"/> + <use x="909.130859" xlink:href="#DejaVuSans-108"/> + <use x="936.914062" xlink:href="#DejaVuSans-101"/> + <use x="998.4375" xlink:href="#DejaVuSans-115"/> + </g> + </g> + </g> + <g id="axes_2"> + <g id="patch_7"> + <path d="M 394.363636 307.890982 +L 648 307.890982 +L 648 54.254618 +L 394.363636 54.254618 +z +" style="fill:#ffffff;"/> + </g> + <g clip-path="url(#p3584c99251)"> + <image height="254.16" id="image20c86ac86d" transform="scale(1 -1)translate(0 -254.16)" width="254.16" x="394.363636" xlink:href="data:image/png;base64, +iVBORw0KGgoAAAANSUhEUgAAAWEAAAFhCAYAAACh/xvXAAAABHNCSVQICAgIfAhkiAAABPFJREFUeJzt3TEOgzAQAME44v9fvnzBBbBJmKmRfNXqGuw1M/MCIPGuBwB4MhEGCIkwQEiEAUIiDBASYYCQCAOERBggdOx8tNa6eg6Av7PzL5xNGCAkwgAhEQYIiTBASIQBQiIMEBJhgJAIA4REGCAkwgAhEQYIiTBASIQBQiIMEBJhgJAIA4S2LnU/w87lxgDf4q7HLGzCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCIgwQEmGAkAgDhEQYICTCACERBgiJMEBIhAFCx10HrbXuOgrgZ9iEAUIiDBASYYCQCAOERBggJMIAIREGCIkwQEiEAUIiDBASYYCQCAOERBggJMIAIREGCIkwQGjrUveZuXoOgEeyCQOERBggJMIAIREGCIkwQEiEAUIiDBASYYDQB+OID8aIwF82AAAAAElFTkSuQmCC" y="-53.730982"/> + </g> + <g id="matplotlib.axis_3"> + <g id="xtick_5"> + <g id="line2d_14"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="397.534091" xlink:href="#mf144b052cc" y="307.890982"/> + </g> + </g> + <g id="text_16"> + <!-- 0 --> + <g transform="translate(393.398466 324.768951)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="xtick_6"> + <g id="line2d_15"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="460.943182" xlink:href="#mf144b052cc" y="307.890982"/> + </g> + </g> + <g id="text_17"> + <!-- 10 --> + <g transform="translate(452.671932 324.768951)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-49"/> + <use x="63.623047" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="xtick_7"> + <g id="line2d_16"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="524.352273" xlink:href="#mf144b052cc" y="307.890982"/> + </g> + </g> + <g id="text_18"> + <!-- 20 --> + <g transform="translate(516.081023 324.768951)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-50"/> + <use x="63.623047" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="xtick_8"> + <g id="line2d_17"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="587.761364" xlink:href="#mf144b052cc" y="307.890982"/> + </g> + </g> + <g id="text_19"> + <!-- 30 --> + <g transform="translate(579.490114 324.768951)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-51"/> + <use x="63.623047" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="text_20"> + <!-- x --> + <g transform="translate(517.334631 341.350513)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-120"/> + </g> + </g> + </g> + <g id="matplotlib.axis_4"> + <g id="ytick_9"> + <g id="line2d_18"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="394.363636" xlink:href="#md113a83665" y="304.720527"/> + </g> + </g> + <g id="text_21"> + <!-- 0 --> + <g transform="translate(379.092386 309.659512)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="ytick_10"> + <g id="line2d_19"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="394.363636" xlink:href="#md113a83665" y="273.015982"/> + </g> + </g> + <g id="text_22"> + <!-- 5 --> + <g transform="translate(379.092386 277.954966)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-53"/> + </g> + </g> + </g> + <g id="ytick_11"> + <g id="line2d_20"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="394.363636" xlink:href="#md113a83665" y="241.311436"/> + </g> + </g> + <g id="text_23"> + <!-- 10 --> + <g transform="translate(370.821136 246.250421)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-49"/> + <use x="63.623047" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="ytick_12"> + <g id="line2d_21"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="394.363636" xlink:href="#md113a83665" y="209.606891"/> + </g> + </g> + <g id="text_24"> + <!-- 15 --> + <g transform="translate(370.821136 214.545875)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-49"/> + <use x="63.623047" xlink:href="#DejaVuSans-53"/> + </g> + </g> + </g> + <g id="ytick_13"> + <g id="line2d_22"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="394.363636" xlink:href="#md113a83665" y="177.902345"/> + </g> + </g> + <g id="text_25"> + <!-- 20 --> + <g transform="translate(370.821136 182.84133)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-50"/> + <use x="63.623047" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="ytick_14"> + <g id="line2d_23"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="394.363636" xlink:href="#md113a83665" y="146.1978"/> + </g> + </g> + <g id="text_26"> + <!-- 25 --> + <g transform="translate(370.821136 151.136784)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-50"/> + <use x="63.623047" xlink:href="#DejaVuSans-53"/> + </g> + </g> + </g> + <g id="ytick_15"> + <g id="line2d_24"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="394.363636" xlink:href="#md113a83665" y="114.493255"/> + </g> + </g> + <g id="text_27"> + <!-- 30 --> + <g transform="translate(370.821136 119.432239)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-51"/> + <use x="63.623047" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="ytick_16"> + <g id="line2d_25"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="394.363636" xlink:href="#md113a83665" y="82.788709"/> + </g> + </g> + <g id="text_28"> + <!-- 35 --> + <g transform="translate(370.821136 87.727693)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-51"/> + <use x="63.623047" xlink:href="#DejaVuSans-53"/> + </g> + </g> + </g> + <g id="text_29"> + <!-- y --> + <g transform="translate(364.117543 184.919988)rotate(-90)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-121"/> + </g> + </g> + </g> + <g id="line2d_26"> + <g clip-path="url(#p3584c99251)"> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="429.519647" xlink:href="#m58866a935f" y="282.054992"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="441.163867" xlink:href="#m58866a935f" y="277.264747"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="431.213777" xlink:href="#m58866a935f" y="262.945122"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="431.558351" xlink:href="#m58866a935f" y="236.9063"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="463.024863" xlink:href="#m58866a935f" y="272.099579"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="463.770742" xlink:href="#m58866a935f" y="273.602854"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="432.763014" xlink:href="#m58866a935f" y="238.85146"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="460.693094" xlink:href="#m58866a935f" y="273.526313"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="450.902466" xlink:href="#m58866a935f" y="272.859525"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="455.671082" xlink:href="#m58866a935f" y="280.011389"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="420.206333" xlink:href="#m58866a935f" y="260.638971"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="425.659778" xlink:href="#m58866a935f" y="257.406894"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="432.230336" xlink:href="#m58866a935f" y="199.174046"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="425.685905" xlink:href="#m58866a935f" y="246.286424"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="450.902466" xlink:href="#m58866a935f" y="272.859525"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="420.422933" xlink:href="#m58866a935f" y="259.404918"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="439.635773" xlink:href="#m58866a935f" y="270.69575"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="424.851271" xlink:href="#m58866a935f" y="274.036813"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="423.854926" xlink:href="#m58866a935f" y="243.383747"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="461.851058" xlink:href="#m58866a935f" y="264.353067"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="428.576414" xlink:href="#m58866a935f" y="224.718685"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="431.220881" xlink:href="#m58866a935f" y="240.048508"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="422.998433" xlink:href="#m58866a935f" y="267.328914"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="426.718695" xlink:href="#m58866a935f" y="281.29743"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="425.659778" xlink:href="#m58866a935f" y="257.406894"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="419.517255" xlink:href="#m58866a935f" y="267.463182"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="441.957746" xlink:href="#m58866a935f" y="270.461764"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="432.763014" xlink:href="#m58866a935f" y="238.85146"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="486.804066" xlink:href="#m58866a935f" y="281.411139"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="423.854926" xlink:href="#m58866a935f" y="243.383747"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="470.569494" xlink:href="#m58866a935f" y="272.115312"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="485.901903" xlink:href="#m58866a935f" y="274.641405"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="426.064254" xlink:href="#m58866a935f" y="200.650255"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="428.739901" xlink:href="#m58866a935f" y="230.881519"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="427.161577" xlink:href="#m58866a935f" y="243.441607"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="424.851271" xlink:href="#m58866a935f" y="274.036813"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="449.25754" xlink:href="#m58866a935f" y="275.983184"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="463.024863" xlink:href="#m58866a935f" y="272.099579"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="430.966111" xlink:href="#m58866a935f" y="252.990828"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="432.235405" xlink:href="#m58866a935f" y="185.830262"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="419.094468" xlink:href="#m58866a935f" y="279.669533"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="427.161577" xlink:href="#m58866a935f" y="243.441607"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="423.854926" xlink:href="#m58866a935f" y="243.383747"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="440.014653" xlink:href="#m58866a935f" y="272.630731"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="421.731302" xlink:href="#m58866a935f" y="237.564702"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="486.804066" xlink:href="#m58866a935f" y="281.411139"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="434.158868" xlink:href="#m58866a935f" y="204.037904"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="427.410375" xlink:href="#m58866a935f" y="261.043681"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="425.611499" xlink:href="#m58866a935f" y="237.421043"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="480.574554" xlink:href="#m58866a935f" y="285.575625"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="455.675684" xlink:href="#m58866a935f" y="280.13681"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="442.82073" xlink:href="#m58866a935f" y="274.984899"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="429.136831" xlink:href="#m58866a935f" y="248.805359"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="420.027467" xlink:href="#m58866a935f" y="273.979315"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="457.559107" xlink:href="#m58866a935f" y="281.202098"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="481.899173" xlink:href="#m58866a935f" y="271.843339"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="432.230336" xlink:href="#m58866a935f" y="199.174046"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="427.221937" xlink:href="#m58866a935f" y="263.239159"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="420.135209" xlink:href="#m58866a935f" y="242.080935"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="444.481578" xlink:href="#m58866a935f" y="273.829092"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="427.528442" xlink:href="#m58866a935f" y="270.545706"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="470.415103" xlink:href="#m58866a935f" y="281.127037"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="445.044178" xlink:href="#m58866a935f" y="278.252741"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="419.094468" xlink:href="#m58866a935f" y="279.669533"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="430.528537" xlink:href="#m58866a935f" y="281.420068"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="427.410375" xlink:href="#m58866a935f" y="261.043681"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="431.076391" xlink:href="#m58866a935f" y="244.425841"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="470.569494" xlink:href="#m58866a935f" y="272.115312"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="428.739901" xlink:href="#m58866a935f" y="230.881519"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="532.914584" xlink:href="#m58866a935f" y="281.014619"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="425.611499" xlink:href="#m58866a935f" y="237.421043"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="424.851271" xlink:href="#m58866a935f" y="274.036813"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="442.82073" xlink:href="#m58866a935f" y="274.984899"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="459.25814" xlink:href="#m58866a935f" y="274.720425"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="424.851271" xlink:href="#m58866a935f" y="274.036813"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="422.676911" xlink:href="#m58866a935f" y="285.388577"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="420.473633" xlink:href="#m58866a935f" y="254.019296"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="420.473633" xlink:href="#m58866a935f" y="254.019296"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="432.07819" xlink:href="#m58866a935f" y="266.534387"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="485.901903" xlink:href="#m58866a935f" y="274.641405"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="432.126743" xlink:href="#m58866a935f" y="278.410354"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="492.780968" xlink:href="#m58866a935f" y="278.427956"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="430.966111" xlink:href="#m58866a935f" y="252.990828"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="464.790914" xlink:href="#m58866a935f" y="275.096066"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="426.064254" xlink:href="#m58866a935f" y="200.650255"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="432.07819" xlink:href="#m58866a935f" y="266.534387"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="432.235405" xlink:href="#m58866a935f" y="185.830262"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="427.221937" xlink:href="#m58866a935f" y="263.239159"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="422.420922" xlink:href="#m58866a935f" y="259.573967"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="422.676911" xlink:href="#m58866a935f" y="285.388577"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="432.07819" xlink:href="#m58866a935f" y="266.534387"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="466.155152" xlink:href="#m58866a935f" y="263.837911"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="431.076391" xlink:href="#m58866a935f" y="244.425841"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="430.966111" xlink:href="#m58866a935f" y="252.990828"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="420.027467" xlink:href="#m58866a935f" y="273.979315"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="428.739901" xlink:href="#m58866a935f" y="230.881519"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="428.413099" xlink:href="#m58866a935f" y="264.718441"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="431.076391" xlink:href="#m58866a935f" y="244.425841"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="416.763245" xlink:href="#m58866a935f" y="277.117001"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="486.804066" xlink:href="#m58866a935f" y="281.411139"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="423.854926" xlink:href="#m58866a935f" y="243.383747"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="486.804066" xlink:href="#m58866a935f" y="281.411139"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="424.851271" xlink:href="#m58866a935f" y="274.036813"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="430.528537" xlink:href="#m58866a935f" y="281.420068"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="455.675684" xlink:href="#m58866a935f" y="280.13681"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="420.135209" xlink:href="#m58866a935f" y="242.080935"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="492.780968" xlink:href="#m58866a935f" y="278.427956"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="488.353138" xlink:href="#m58866a935f" y="274.888143"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="427.161577" xlink:href="#m58866a935f" y="243.441607"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="423.0363" xlink:href="#m58866a935f" y="270.075682"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="432.377137" xlink:href="#m58866a935f" y="268.006684"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="423.0363" xlink:href="#m58866a935f" y="270.075682"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="455.671082" xlink:href="#m58866a935f" y="280.011389"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="430.528537" xlink:href="#m58866a935f" y="281.420068"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="424.851271" xlink:href="#m58866a935f" y="274.036813"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="436.283881" xlink:href="#m58866a935f" y="267.043994"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="420.381226" xlink:href="#m58866a935f" y="235.128086"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="429.263406" xlink:href="#m58866a935f" y="235.831554"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="421.731302" xlink:href="#m58866a935f" y="237.564702"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="427.771974" xlink:href="#m58866a935f" y="244.186829"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="429.263406" xlink:href="#m58866a935f" y="235.831554"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="424.655033" xlink:href="#m58866a935f" y="233.402831"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="420.575302" xlink:href="#m58866a935f" y="213.124729"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="421.824288" xlink:href="#m58866a935f" y="228.296827"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="468.586788" xlink:href="#m58866a935f" y="281.224386"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="425.685905" xlink:href="#m58866a935f" y="246.286424"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="518.180209" xlink:href="#m58866a935f" y="272.055437"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="425.685905" xlink:href="#m58866a935f" y="246.286424"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="430.20554" xlink:href="#m58866a935f" y="256.583598"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="429.519647" xlink:href="#m58866a935f" y="282.054992"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="431.220881" xlink:href="#m58866a935f" y="240.048508"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="422.676911" xlink:href="#m58866a935f" y="285.388577"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="416.763245" xlink:href="#m58866a935f" y="277.117001"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="521.614453" xlink:href="#m58866a935f" y="274.909716"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="421.963826" xlink:href="#m58866a935f" y="268.177906"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="429.136831" xlink:href="#m58866a935f" y="248.805359"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="440.014653" xlink:href="#m58866a935f" y="272.630731"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="426.468253" xlink:href="#m58866a935f" y="271.767744"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="432.07819" xlink:href="#m58866a935f" y="266.534387"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="424.851271" xlink:href="#m58866a935f" y="274.036813"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="426.468253" xlink:href="#m58866a935f" y="271.767744"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="420.381226" xlink:href="#m58866a935f" y="235.128086"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="436.005894" xlink:href="#m58866a935f" y="267.33715"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="420.473633" xlink:href="#m58866a935f" y="254.019296"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="441.957746" xlink:href="#m58866a935f" y="270.461764"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="437.085756" xlink:href="#m58866a935f" y="273.922528"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="429.519647" xlink:href="#m58866a935f" y="282.054992"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="432.377137" xlink:href="#m58866a935f" y="268.006684"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="432.700465" xlink:href="#m58866a935f" y="275.848764"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="427.528442" xlink:href="#m58866a935f" y="270.545706"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="420.422933" xlink:href="#m58866a935f" y="259.404918"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="433.878136" xlink:href="#m58866a935f" y="278.607098"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="430.528537" xlink:href="#m58866a935f" y="281.420068"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="492.780968" xlink:href="#m58866a935f" y="278.427956"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="432.700465" xlink:href="#m58866a935f" y="275.848764"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="439.635773" xlink:href="#m58866a935f" y="270.69575"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="432.700465" xlink:href="#m58866a935f" y="275.848764"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="424.655033" xlink:href="#m58866a935f" y="233.402831"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="464.790914" xlink:href="#m58866a935f" y="275.096066"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="430.966111" xlink:href="#m58866a935f" y="252.990828"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="433.878136" xlink:href="#m58866a935f" y="278.607098"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="506.674068" xlink:href="#m58866a935f" y="283.257141"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="518.180209" xlink:href="#m58866a935f" y="272.055437"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="463.024863" xlink:href="#m58866a935f" y="272.099579"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="427.528442" xlink:href="#m58866a935f" y="270.545706"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="421.731302" xlink:href="#m58866a935f" y="237.564702"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="420.381226" xlink:href="#m58866a935f" y="235.128086"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="472.550817" xlink:href="#m58866a935f" y="272.512773"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="425.659778" xlink:href="#m58866a935f" y="257.406894"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="419.517255" xlink:href="#m58866a935f" y="267.463182"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="432.700465" xlink:href="#m58866a935f" y="275.848764"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="432.126743" xlink:href="#m58866a935f" y="278.410354"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="427.161577" xlink:href="#m58866a935f" y="243.441607"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="420.381226" xlink:href="#m58866a935f" y="235.128086"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="427.410375" xlink:href="#m58866a935f" y="261.043681"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="431.196731" xlink:href="#m58866a935f" y="192.310009"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="521.614453" xlink:href="#m58866a935f" y="274.909716"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="463.770742" xlink:href="#m58866a935f" y="273.602854"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="431.220881" xlink:href="#m58866a935f" y="240.048508"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="433.898624" xlink:href="#m58866a935f" y="228.886952"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="432.700465" xlink:href="#m58866a935f" y="275.848764"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="426.468253" xlink:href="#m58866a935f" y="271.767744"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="421.425964" xlink:href="#m58866a935f" y="248.689741"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="427.410375" xlink:href="#m58866a935f" y="261.043681"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="425.659778" xlink:href="#m58866a935f" y="257.406894"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="420.381226" xlink:href="#m58866a935f" y="235.128086"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="427.410375" xlink:href="#m58866a935f" y="261.043681"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="420.206333" xlink:href="#m58866a935f" y="260.638971"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="422.142562" xlink:href="#m58866a935f" y="266.803378"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="472.51504" xlink:href="#m58866a935f" y="270.243276"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="474.364447" xlink:href="#m58866a935f" y="274.334262"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="423.854926" xlink:href="#m58866a935f" y="243.383747"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="444.481578" xlink:href="#m58866a935f" y="273.829092"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="436.601421" xlink:href="#m58866a935f" y="273.247376"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="429.519647" xlink:href="#m58866a935f" y="282.054992"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="437.115311" xlink:href="#m58866a935f" y="252.202373"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="470.569494" xlink:href="#m58866a935f" y="272.115312"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="430.528537" xlink:href="#m58866a935f" y="281.420068"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="427.221937" xlink:href="#m58866a935f" y="263.239159"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="466.155152" xlink:href="#m58866a935f" y="263.837911"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="419.094468" xlink:href="#m58866a935f" y="279.669533"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="423.0363" xlink:href="#m58866a935f" y="270.075682"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="427.528442" xlink:href="#m58866a935f" y="270.545706"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="488.353138" xlink:href="#m58866a935f" y="274.888143"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="432.230336" xlink:href="#m58866a935f" y="199.174046"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="417.742575" xlink:href="#m58866a935f" y="238.693646"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="420.206333" xlink:href="#m58866a935f" y="260.638971"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="432.07819" xlink:href="#m58866a935f" y="266.534387"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="424.655033" xlink:href="#m58866a935f" y="233.402831"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="445.044178" xlink:href="#m58866a935f" y="278.252741"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="432.148885" xlink:href="#m58866a935f" y="249.789734"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="421.824288" xlink:href="#m58866a935f" y="228.296827"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="433.768334" xlink:href="#m58866a935f" y="250.648014"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="416.763245" xlink:href="#m58866a935f" y="277.117001"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="441.957746" xlink:href="#m58866a935f" y="270.461764"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="428.739901" xlink:href="#m58866a935f" y="230.881519"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="433.159697" xlink:href="#m58866a935f" y="268.69636"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="459.25814" xlink:href="#m58866a935f" y="274.720425"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="464.790914" xlink:href="#m58866a935f" y="275.096066"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="432.377137" xlink:href="#m58866a935f" y="268.006684"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="428.576414" xlink:href="#m58866a935f" y="224.718685"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="470.415103" xlink:href="#m58866a935f" y="281.127037"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="433.159697" xlink:href="#m58866a935f" y="268.69636"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="442.82073" xlink:href="#m58866a935f" y="274.984899"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="423.0363" xlink:href="#m58866a935f" y="270.075682"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="425.611499" xlink:href="#m58866a935f" y="237.421043"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="416.763245" xlink:href="#m58866a935f" y="277.117001"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="463.770742" xlink:href="#m58866a935f" y="273.602854"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="420.575302" xlink:href="#m58866a935f" y="213.124729"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="418.452476" xlink:href="#m58866a935f" y="245.441622"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="428.739901" xlink:href="#m58866a935f" y="230.881519"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="422.998433" xlink:href="#m58866a935f" y="267.328914"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="429.519647" xlink:href="#m58866a935f" y="282.054992"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="420.381226" xlink:href="#m58866a935f" y="235.128086"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="432.126743" xlink:href="#m58866a935f" y="278.410354"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="429.76021" xlink:href="#m58866a935f" y="255.078013"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="480.574554" xlink:href="#m58866a935f" y="285.575625"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="464.790914" xlink:href="#m58866a935f" y="275.096066"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="427.619509" xlink:href="#m58866a935f" y="209.899706"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="474.364447" xlink:href="#m58866a935f" y="274.334262"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="441.163867" xlink:href="#m58866a935f" y="277.264747"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="521.614453" xlink:href="#m58866a935f" y="274.909716"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="485.901903" xlink:href="#m58866a935f" y="274.641405"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="426.064254" xlink:href="#m58866a935f" y="200.650255"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="488.353138" xlink:href="#m58866a935f" y="274.888143"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="462.21916" xlink:href="#m58866a935f" y="268.073097"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="462.461131" xlink:href="#m58866a935f" y="277.242265"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="431.220881" xlink:href="#m58866a935f" y="240.048508"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="485.901903" xlink:href="#m58866a935f" y="274.641405"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="472.550817" xlink:href="#m58866a935f" y="272.512773"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="429.76021" xlink:href="#m58866a935f" y="255.078013"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="481.489257" xlink:href="#m58866a935f" y="283.130241"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="431.196731" xlink:href="#m58866a935f" y="192.310009"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="460.693094" xlink:href="#m58866a935f" y="273.526313"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="425.611499" xlink:href="#m58866a935f" y="237.421043"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="421.824288" xlink:href="#m58866a935f" y="228.296827"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="429.136831" xlink:href="#m58866a935f" y="248.805359"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="420.575302" xlink:href="#m58866a935f" y="213.124729"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="447.135275" xlink:href="#m58866a935f" y="278.265998"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="461.851058" xlink:href="#m58866a935f" y="264.353067"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="470.415103" xlink:href="#m58866a935f" y="281.127037"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="472.550817" xlink:href="#m58866a935f" y="272.512773"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="492.780968" xlink:href="#m58866a935f" y="278.427956"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="481.899173" xlink:href="#m58866a935f" y="271.843339"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="423.0363" xlink:href="#m58866a935f" y="270.075682"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="433.159697" xlink:href="#m58866a935f" y="268.69636"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="455.671082" xlink:href="#m58866a935f" y="280.011389"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="432.148885" xlink:href="#m58866a935f" y="249.789734"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="421.824288" xlink:href="#m58866a935f" y="228.296827"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="426.468253" xlink:href="#m58866a935f" y="271.767744"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="432.377137" xlink:href="#m58866a935f" y="268.006684"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="431.558351" xlink:href="#m58866a935f" y="236.9063"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="472.51504" xlink:href="#m58866a935f" y="270.243276"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="447.135275" xlink:href="#m58866a935f" y="278.265998"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="430.435782" xlink:href="#m58866a935f" y="252.703981"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="438.01725" xlink:href="#m58866a935f" y="261.562655"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="428.551915" xlink:href="#m58866a935f" y="262.705706"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="474.364447" xlink:href="#m58866a935f" y="274.334262"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="444.481578" xlink:href="#m58866a935f" y="273.829092"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="470.329544" xlink:href="#m58866a935f" y="278.289951"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="430.435782" xlink:href="#m58866a935f" y="252.703981"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="428.576414" xlink:href="#m58866a935f" y="224.718685"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="442.404878" xlink:href="#m58866a935f" y="284.151076"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="421.425964" xlink:href="#m58866a935f" y="248.689741"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="423.854926" xlink:href="#m58866a935f" y="243.383747"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="459.25814" xlink:href="#m58866a935f" y="274.720425"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="429.76021" xlink:href="#m58866a935f" y="255.078013"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="431.220881" xlink:href="#m58866a935f" y="240.048508"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="437.115311" xlink:href="#m58866a935f" y="252.202373"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="422.676911" xlink:href="#m58866a935f" y="285.388577"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="445.044178" xlink:href="#m58866a935f" y="278.252741"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="432.377137" xlink:href="#m58866a935f" y="268.006684"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="470.415103" xlink:href="#m58866a935f" y="281.127037"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="466.155152" xlink:href="#m58866a935f" y="263.837911"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="442.404878" xlink:href="#m58866a935f" y="284.151076"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="420.381226" xlink:href="#m58866a935f" y="235.128086"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="422.998433" xlink:href="#m58866a935f" y="267.328914"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="438.286271" xlink:href="#m58866a935f" y="265.973307"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="440.299746" xlink:href="#m58866a935f" y="282.270444"/> + <use style="fill:#1f77b4;stroke:#1f77b4;" x="426.465668" xlink:href="#m58866a935f" y="253.42903"/> + </g> + </g> + <g id="patch_8"> + <path d="M 394.363636 307.890982 +L 394.363636 54.254618 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/> + </g> + <g id="patch_9"> + <path d="M 648 307.890982 +L 648 54.254618 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/> + </g> + <g id="patch_10"> + <path d="M 394.363636 307.890982 +L 648 307.890982 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/> + </g> + <g id="patch_11"> + <path d="M 394.363636 54.254618 +L 648 54.254618 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/> + </g> + <g id="text_30"> + <!-- Resampled particles --> + <defs> + <path d="M 44.390625 34.1875 +Q 47.5625 33.109375 50.5625 29.59375 +Q 53.5625 26.078125 56.59375 19.921875 +L 66.609375 0 +L 56 0 +L 46.6875 18.703125 +Q 43.0625 26.03125 39.671875 28.421875 +Q 36.28125 30.8125 30.421875 30.8125 +L 19.671875 30.8125 +L 19.671875 0 +L 9.8125 0 +L 9.8125 72.90625 +L 32.078125 72.90625 +Q 44.578125 72.90625 50.734375 67.671875 +Q 56.890625 62.453125 56.890625 51.90625 +Q 56.890625 45.015625 53.6875 40.46875 +Q 50.484375 35.9375 44.390625 34.1875 +z +M 19.671875 64.796875 +L 19.671875 38.921875 +L 32.078125 38.921875 +Q 39.203125 38.921875 42.84375 42.21875 +Q 46.484375 45.515625 46.484375 51.90625 +Q 46.484375 58.296875 42.84375 61.546875 +Q 39.203125 64.796875 32.078125 64.796875 +z +" id="DejaVuSans-82"/> + <path d="M 52 44.1875 +Q 55.375 50.25 60.0625 53.125 +Q 64.75 56 71.09375 56 +Q 79.640625 56 84.28125 50.015625 +Q 88.921875 44.046875 88.921875 33.015625 +L 88.921875 0 +L 79.890625 0 +L 79.890625 32.71875 +Q 79.890625 40.578125 77.09375 44.375 +Q 74.3125 48.1875 68.609375 48.1875 +Q 61.625 48.1875 57.5625 43.546875 +Q 53.515625 38.921875 53.515625 30.90625 +L 53.515625 0 +L 44.484375 0 +L 44.484375 32.71875 +Q 44.484375 40.625 41.703125 44.40625 +Q 38.921875 48.1875 33.109375 48.1875 +Q 26.21875 48.1875 22.15625 43.53125 +Q 18.109375 38.875 18.109375 30.90625 +L 18.109375 0 +L 9.078125 0 +L 9.078125 54.6875 +L 18.109375 54.6875 +L 18.109375 46.1875 +Q 21.1875 51.21875 25.484375 53.609375 +Q 29.78125 56 35.6875 56 +Q 41.65625 56 45.828125 52.96875 +Q 50 49.953125 52 44.1875 +z +" id="DejaVuSans-109"/> + <path d="M 45.40625 46.390625 +L 45.40625 75.984375 +L 54.390625 75.984375 +L 54.390625 0 +L 45.40625 0 +L 45.40625 8.203125 +Q 42.578125 3.328125 38.25 0.953125 +Q 33.9375 -1.421875 27.875 -1.421875 +Q 17.96875 -1.421875 11.734375 6.484375 +Q 5.515625 14.40625 5.515625 27.296875 +Q 5.515625 40.1875 11.734375 48.09375 +Q 17.96875 56 27.875 56 +Q 33.9375 56 38.25 53.625 +Q 42.578125 51.265625 45.40625 46.390625 +z +M 14.796875 27.296875 +Q 14.796875 17.390625 18.875 11.75 +Q 22.953125 6.109375 30.078125 6.109375 +Q 37.203125 6.109375 41.296875 11.75 +Q 45.40625 17.390625 45.40625 27.296875 +Q 45.40625 37.203125 41.296875 42.84375 +Q 37.203125 48.484375 30.078125 48.484375 +Q 22.953125 48.484375 18.875 42.84375 +Q 14.796875 37.203125 14.796875 27.296875 +z +" id="DejaVuSans-100"/> + </defs> + <g transform="translate(441.696162 48.254618)scale(0.156 -0.156)"> + <use xlink:href="#DejaVuSans-82"/> + <use x="69.419922" xlink:href="#DejaVuSans-101"/> + <use x="130.943359" xlink:href="#DejaVuSans-115"/> + <use x="183.042969" xlink:href="#DejaVuSans-97"/> + <use x="244.322266" xlink:href="#DejaVuSans-109"/> + <use x="341.734375" xlink:href="#DejaVuSans-112"/> + <use x="405.210938" xlink:href="#DejaVuSans-108"/> + <use x="432.994141" xlink:href="#DejaVuSans-101"/> + <use x="494.517578" xlink:href="#DejaVuSans-100"/> + <use x="557.994141" xlink:href="#DejaVuSans-32"/> + <use x="589.78125" xlink:href="#DejaVuSans-112"/> + <use x="653.257812" xlink:href="#DejaVuSans-97"/> + <use x="714.537109" xlink:href="#DejaVuSans-114"/> + <use x="755.650391" xlink:href="#DejaVuSans-116"/> + <use x="794.859375" xlink:href="#DejaVuSans-105"/> + <use x="822.642578" xlink:href="#DejaVuSans-99"/> + <use x="877.623047" xlink:href="#DejaVuSans-108"/> + <use x="905.40625" xlink:href="#DejaVuSans-101"/> + <use x="966.929688" xlink:href="#DejaVuSans-115"/> + </g> + </g> + </g> + <g id="axes_3"> + <g id="patch_12"> + <path d="M 540.045455 162.209164 +L 641.5 162.209164 +L 641.5 60.754618 +L 540.045455 60.754618 +z +" style="fill:#ffffff;"/> + </g> + <g clip-path="url(#p21eebb9627)"> + <image height="101.52" id="image0bf04e735e" transform="scale(1 -1)translate(0 -101.52)" width="101.52" x="540.045455" xlink:href="data:image/png;base64, +iVBORw0KGgoAAAANSUhEUgAAAI0AAACNCAYAAACKXvmlAAAABHNCSVQICAgIfAhkiAAAAfhJREFUeJzt3VFOwkAUQFExrhbW024XV2DNHSk4wzm/pg0xNy95DJTLtm33Dwg+X/0CmI9oyERDJhoy0ZCJhkw0ZKIhEw2ZaMhEQyYaMtGQiYZMNGSiIRMNmWjIREMmGjLRkImGTDRkoiETDZloyERDJhoy0ZCJhkw0ZKIhEw2ZaMhEQyYaMtGQiYZMNGSiIRMN2derX8DZbrfbj3/btm3out8c3XcFJg2ZaMhEQyYaMtGQiYbsssKPhP1lPV7BGW8dHN3TpCETDZloyERDJhoy0ZBNc8o9ujre7/O8o7Dv+9B11+t16Lqj/+nRPU0aMtGQiYZMNGSiIRMN2TQr9zsYXZ2ffU+Thkw0ZKIhEw2ZaMhEQ7b8B8tnOuWehUlDJhoy0ZCJhkw0ZKIhEw3ZNB+NePcv+f8nJg2ZaMhEQyYaMtGQiYZsmpX7rEfS05k0ZKIhEw2ZaMhEQyYaMtGQiYZMNGSiIRMNmWjIREM2zSn3qKNHx5/xPLp3YNKQiYZMNGSiIRMNmWjIREMmGjLRkImGTDRkoiETDdkSp9xH3/N2kv14Jg2ZaMhEQyYaMtGQiYZsiZX76PFpfnXu8UwaMtGQiYZMNGSiIRMN2RIrt1Pu5zJpyERDJhoy0ZCJhkw0ZEus3KOn3Fb1MSYNmWjIREMmGjLRkImG7BsAVD4WJX2WoQAAAABJRU5ErkJggg==" y="-60.689164"/> + </g> + <g id="matplotlib.axis_5"> + <g id="text_31"> + <!-- local map --> + <g transform="translate(559.119759 176.087132)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-108"/> + <use x="27.783203" xlink:href="#DejaVuSans-111"/> + <use x="88.964844" xlink:href="#DejaVuSans-99"/> + <use x="143.945312" xlink:href="#DejaVuSans-97"/> + <use x="205.224609" xlink:href="#DejaVuSans-108"/> + <use x="233.007812" xlink:href="#DejaVuSans-32"/> + <use x="264.794922" xlink:href="#DejaVuSans-109"/> + <use x="362.207031" xlink:href="#DejaVuSans-97"/> + <use x="423.486328" xlink:href="#DejaVuSans-112"/> + </g> + </g> + </g> + <g id="matplotlib.axis_6"/> + <g id="patch_13"> + <path d="M 540.045455 162.209164 +L 540.045455 60.754618 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/> + </g> + <g id="patch_14"> + <path d="M 641.5 162.209164 +L 641.5 60.754618 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/> + </g> + <g id="patch_15"> + <path d="M 540.045455 162.209164 +L 641.5 162.209164 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/> + </g> + <g id="patch_16"> + <path d="M 540.045455 60.754618 +L 641.5 60.754618 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/> + </g> + </g> + </g> + <defs> + <clipPath id="p07d1048ee6"> + <rect height="253.636364" width="253.636364" x="90" y="54.254618"/> + </clipPath> + <clipPath id="p3584c99251"> + <rect height="253.636364" width="253.636364" x="394.363636" y="54.254618"/> + </clipPath> + <clipPath id="p21eebb9627"> + <rect height="101.454545" width="101.454545" x="540.045455" y="60.754618"/> + </clipPath> + </defs> +</svg> diff --git a/latex_and_figures/figs/ch_robotmodel/measurementprob.png b/latex_and_figures/figs/ch_robotmodel/measurementprob.png new file mode 100644 index 0000000000000000000000000000000000000000..c4b2ea74ad7e2a8a16f489834101d5931c04ce0a Binary files /dev/null and b/latex_and_figures/figs/ch_robotmodel/measurementprob.png differ diff --git a/latex_and_figures/figs/ch_robotmodel/motion_model.png b/latex_and_figures/figs/ch_robotmodel/motion_model.png new file mode 100644 index 0000000000000000000000000000000000000000..bc5242790d59ee856de6d94888cdea2ec89d6ab3 Binary files /dev/null and b/latex_and_figures/figs/ch_robotmodel/motion_model.png differ diff --git a/latex_and_figures/figs/ch_robotmodel/motion_model.svg b/latex_and_figures/figs/ch_robotmodel/motion_model.svg new file mode 100644 index 0000000000000000000000000000000000000000..c6bc6d00b3b285227bd1ffcc920066e263b04a7f --- /dev/null +++ b/latex_and_figures/figs/ch_robotmodel/motion_model.svg @@ -0,0 +1,2298 @@ +<?xml version="1.0" encoding="utf-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Created with matplotlib (https://matplotlib.org/) --> +<svg height="718.56pt" version="1.1" viewBox="0 0 720 718.56" width="720pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <defs> + <style type="text/css"> +*{stroke-linecap:butt;stroke-linejoin:round;white-space:pre;} + </style> + </defs> + <g id="figure_1"> + <g id="patch_1"> + <path d="M 0 718.56 +L 720 718.56 +L 720 0 +L 0 0 +z +" style="fill:#ffffff;"/> + </g> + <g id="axes_1"> + <g id="patch_2"> + <path d="M 77.495251 315.42788 +L 344.755659 315.42788 +L 344.755659 48.167472 +L 77.495251 48.167472 +z +" style="fill:#ffffff;"/> + </g> + <g id="patch_3"> + <path clip-path="url(#p7ed90a7c9b)" d="M 110.902802 282.020329 +C 144.483368 282.020329 177.531681 273.581709 207.0014 257.482328 +C 236.47112 241.382947 261.428053 218.133157 279.571711 189.876084 +" style="fill:none;stroke:#000000;stroke-linejoin:miter;stroke-width:0.5;"/> + </g> + <g id="patch_4"> + <path clip-path="url(#p7ed90a7c9b)" d="M 140.969597 282.020329 +L 130.947332 285.361084 +L 130.947332 282.053737 +L 90.858271 282.053737 +L 90.858271 281.986921 +L 130.947332 281.986921 +L 130.947332 278.679574 +z +" style="fill:#0000ff;opacity:0.5;stroke:#0000ff;stroke-linejoin:miter;"/> + </g> + <g id="patch_5"> + <path clip-path="url(#p7ed90a7c9b)" d="M 295.81687 164.575748 +L 293.212965 174.814211 +L 290.429928 173.027243 +L 268.769716 206.761025 +L 268.713493 206.724925 +L 290.373705 172.991143 +L 287.590668 171.204175 +z +" style="fill:#0000ff;opacity:0.5;stroke:#0000ff;stroke-linejoin:miter;"/> + </g> + <g id="matplotlib.axis_1"> + <g id="xtick_1"> + <g id="line2d_1"> + <defs> + <path d="M 0 0 +L 0 3.5 +" id="m49a95e4598" style="stroke:#000000;stroke-width:0.8;"/> + </defs> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="110.902802" xlink:href="#m49a95e4598" y="315.42788"/> + </g> + </g> + <g id="text_1"> + <!-- 0 --> + <defs> + <path d="M 31.78125 66.40625 +Q 24.171875 66.40625 20.328125 58.90625 +Q 16.5 51.421875 16.5 36.375 +Q 16.5 21.390625 20.328125 13.890625 +Q 24.171875 6.390625 31.78125 6.390625 +Q 39.453125 6.390625 43.28125 13.890625 +Q 47.125 21.390625 47.125 36.375 +Q 47.125 51.421875 43.28125 58.90625 +Q 39.453125 66.40625 31.78125 66.40625 +z +M 31.78125 74.21875 +Q 44.046875 74.21875 50.515625 64.515625 +Q 56.984375 54.828125 56.984375 36.375 +Q 56.984375 17.96875 50.515625 8.265625 +Q 44.046875 -1.421875 31.78125 -1.421875 +Q 19.53125 -1.421875 13.0625 8.265625 +Q 6.59375 17.96875 6.59375 36.375 +Q 6.59375 54.828125 13.0625 64.515625 +Q 19.53125 74.21875 31.78125 74.21875 +z +" id="DejaVuSans-48"/> + </defs> + <g transform="translate(106.767177 332.305849)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="xtick_2"> + <g id="line2d_2"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="177.717904" xlink:href="#m49a95e4598" y="315.42788"/> + </g> + </g> + <g id="text_2"> + <!-- 1 --> + <defs> + <path d="M 12.40625 8.296875 +L 28.515625 8.296875 +L 28.515625 63.921875 +L 10.984375 60.40625 +L 10.984375 69.390625 +L 28.421875 72.90625 +L 38.28125 72.90625 +L 38.28125 8.296875 +L 54.390625 8.296875 +L 54.390625 0 +L 12.40625 0 +z +" id="DejaVuSans-49"/> + </defs> + <g transform="translate(173.582279 332.305849)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-49"/> + </g> + </g> + </g> + <g id="xtick_3"> + <g id="line2d_3"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="244.533006" xlink:href="#m49a95e4598" y="315.42788"/> + </g> + </g> + <g id="text_3"> + <!-- 2 --> + <defs> + <path d="M 19.1875 8.296875 +L 53.609375 8.296875 +L 53.609375 0 +L 7.328125 0 +L 7.328125 8.296875 +Q 12.9375 14.109375 22.625 23.890625 +Q 32.328125 33.6875 34.8125 36.53125 +Q 39.546875 41.84375 41.421875 45.53125 +Q 43.3125 49.21875 43.3125 52.78125 +Q 43.3125 58.59375 39.234375 62.25 +Q 35.15625 65.921875 28.609375 65.921875 +Q 23.96875 65.921875 18.8125 64.3125 +Q 13.671875 62.703125 7.8125 59.421875 +L 7.8125 69.390625 +Q 13.765625 71.78125 18.9375 73 +Q 24.125 74.21875 28.421875 74.21875 +Q 39.75 74.21875 46.484375 68.546875 +Q 53.21875 62.890625 53.21875 53.421875 +Q 53.21875 48.921875 51.53125 44.890625 +Q 49.859375 40.875 45.40625 35.40625 +Q 44.1875 33.984375 37.640625 27.21875 +Q 31.109375 20.453125 19.1875 8.296875 +z +" id="DejaVuSans-50"/> + </defs> + <g transform="translate(240.397381 332.305849)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-50"/> + </g> + </g> + </g> + <g id="xtick_4"> + <g id="line2d_4"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="311.348108" xlink:href="#m49a95e4598" y="315.42788"/> + </g> + </g> + <g id="text_4"> + <!-- 3 --> + <defs> + <path d="M 40.578125 39.3125 +Q 47.65625 37.796875 51.625 33 +Q 55.609375 28.21875 55.609375 21.1875 +Q 55.609375 10.40625 48.1875 4.484375 +Q 40.765625 -1.421875 27.09375 -1.421875 +Q 22.515625 -1.421875 17.65625 -0.515625 +Q 12.796875 0.390625 7.625 2.203125 +L 7.625 11.71875 +Q 11.71875 9.328125 16.59375 8.109375 +Q 21.484375 6.890625 26.8125 6.890625 +Q 36.078125 6.890625 40.9375 10.546875 +Q 45.796875 14.203125 45.796875 21.1875 +Q 45.796875 27.640625 41.28125 31.265625 +Q 36.765625 34.90625 28.71875 34.90625 +L 20.21875 34.90625 +L 20.21875 43.015625 +L 29.109375 43.015625 +Q 36.375 43.015625 40.234375 45.921875 +Q 44.09375 48.828125 44.09375 54.296875 +Q 44.09375 59.90625 40.109375 62.90625 +Q 36.140625 65.921875 28.71875 65.921875 +Q 24.65625 65.921875 20.015625 65.03125 +Q 15.375 64.15625 9.8125 62.3125 +L 9.8125 71.09375 +Q 15.4375 72.65625 20.34375 73.4375 +Q 25.25 74.21875 29.59375 74.21875 +Q 40.828125 74.21875 47.359375 69.109375 +Q 53.90625 64.015625 53.90625 55.328125 +Q 53.90625 49.265625 50.4375 45.09375 +Q 46.96875 40.921875 40.578125 39.3125 +z +" id="DejaVuSans-51"/> + </defs> + <g transform="translate(307.212483 332.305849)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-51"/> + </g> + </g> + </g> + <g id="text_5"> + <!-- x --> + <defs> + <path d="M 54.890625 54.6875 +L 35.109375 28.078125 +L 55.90625 0 +L 45.3125 0 +L 29.390625 21.484375 +L 13.484375 0 +L 2.875 0 +L 24.125 28.609375 +L 4.6875 54.6875 +L 15.28125 54.6875 +L 29.78125 35.203125 +L 44.28125 54.6875 +z +" id="DejaVuSans-120"/> + </defs> + <g transform="translate(207.278267 348.887411)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-120"/> + </g> + </g> + </g> + <g id="matplotlib.axis_2"> + <g id="ytick_1"> + <g id="line2d_5"> + <defs> + <path d="M 0 0 +L -3.5 0 +" id="m392a87831e" style="stroke:#000000;stroke-width:0.8;"/> + </defs> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="77.495251" xlink:href="#m392a87831e" y="315.42788"/> + </g> + </g> + <g id="text_6"> + <!-- −0.5 --> + <defs> + <path d="M 10.59375 35.5 +L 73.1875 35.5 +L 73.1875 27.203125 +L 10.59375 27.203125 +z +" id="DejaVuSans-8722"/> + <path d="M 10.6875 12.40625 +L 21 12.40625 +L 21 0 +L 10.6875 0 +z +" id="DejaVuSans-46"/> + <path d="M 10.796875 72.90625 +L 49.515625 72.90625 +L 49.515625 64.59375 +L 19.828125 64.59375 +L 19.828125 46.734375 +Q 21.96875 47.46875 24.109375 47.828125 +Q 26.265625 48.1875 28.421875 48.1875 +Q 40.625 48.1875 47.75 41.5 +Q 54.890625 34.8125 54.890625 23.390625 +Q 54.890625 11.625 47.5625 5.09375 +Q 40.234375 -1.421875 26.90625 -1.421875 +Q 22.3125 -1.421875 17.546875 -0.640625 +Q 12.796875 0.140625 7.71875 1.703125 +L 7.71875 11.625 +Q 12.109375 9.234375 16.796875 8.0625 +Q 21.484375 6.890625 26.703125 6.890625 +Q 35.15625 6.890625 40.078125 11.328125 +Q 45.015625 15.765625 45.015625 23.390625 +Q 45.015625 31 40.078125 35.4375 +Q 35.15625 39.890625 26.703125 39.890625 +Q 22.75 39.890625 18.8125 39.015625 +Q 14.890625 38.140625 10.796875 36.28125 +z +" id="DejaVuSans-53"/> + </defs> + <g transform="translate(38.927594 320.366864)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-8722"/> + <use x="83.789062" xlink:href="#DejaVuSans-48"/> + <use x="147.412109" xlink:href="#DejaVuSans-46"/> + <use x="179.199219" xlink:href="#DejaVuSans-53"/> + </g> + </g> + </g> + <g id="ytick_2"> + <g id="line2d_6"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="77.495251" xlink:href="#m392a87831e" y="282.020329"/> + </g> + </g> + <g id="text_7"> + <!-- 0.0 --> + <g transform="translate(49.821188 286.959313)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-48"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="ytick_3"> + <g id="line2d_7"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="77.495251" xlink:href="#m392a87831e" y="248.612778"/> + </g> + </g> + <g id="text_8"> + <!-- 0.5 --> + <g transform="translate(49.821188 253.551762)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-48"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-53"/> + </g> + </g> + </g> + <g id="ytick_4"> + <g id="line2d_8"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="77.495251" xlink:href="#m392a87831e" y="215.205227"/> + </g> + </g> + <g id="text_9"> + <!-- 1.0 --> + <g transform="translate(49.821188 220.144211)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-49"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="ytick_5"> + <g id="line2d_9"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="77.495251" xlink:href="#m392a87831e" y="181.797676"/> + </g> + </g> + <g id="text_10"> + <!-- 1.5 --> + <g transform="translate(49.821188 186.73666)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-49"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-53"/> + </g> + </g> + </g> + <g id="ytick_6"> + <g id="line2d_10"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="77.495251" xlink:href="#m392a87831e" y="148.390125"/> + </g> + </g> + <g id="text_11"> + <!-- 2.0 --> + <g transform="translate(49.821188 153.329109)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-50"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="ytick_7"> + <g id="line2d_11"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="77.495251" xlink:href="#m392a87831e" y="114.982574"/> + </g> + </g> + <g id="text_12"> + <!-- 2.5 --> + <g transform="translate(49.821188 119.921558)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-50"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-53"/> + </g> + </g> + </g> + <g id="ytick_8"> + <g id="line2d_12"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="77.495251" xlink:href="#m392a87831e" y="81.575023"/> + </g> + </g> + <g id="text_13"> + <!-- 3.0 --> + <g transform="translate(49.821188 86.514007)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-51"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="ytick_9"> + <g id="line2d_13"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="77.495251" xlink:href="#m392a87831e" y="48.167472"/> + </g> + </g> + <g id="text_14"> + <!-- 3.5 --> + <g transform="translate(49.821188 53.106456)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-51"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-53"/> + </g> + </g> + </g> + <g id="text_15"> + <!-- y --> + <defs> + <path d="M 32.171875 -5.078125 +Q 28.375 -14.84375 24.75 -17.8125 +Q 21.140625 -20.796875 15.09375 -20.796875 +L 7.90625 -20.796875 +L 7.90625 -13.28125 +L 13.1875 -13.28125 +Q 16.890625 -13.28125 18.9375 -11.515625 +Q 21 -9.765625 23.484375 -3.21875 +L 25.09375 0.875 +L 2.984375 54.6875 +L 12.5 54.6875 +L 29.59375 11.921875 +L 46.6875 54.6875 +L 56.203125 54.6875 +z +" id="DejaVuSans-121"/> + </defs> + <g transform="translate(32.224001 185.644864)rotate(-90)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-121"/> + </g> + </g> + </g> + <g id="line2d_14"> + <defs> + <path d="M 0 1.5 +C 0.397805 1.5 0.77937 1.341951 1.06066 1.06066 +C 1.341951 0.77937 1.5 0.397805 1.5 0 +C 1.5 -0.397805 1.341951 -0.77937 1.06066 -1.06066 +C 0.77937 -1.341951 0.397805 -1.5 0 -1.5 +C -0.397805 -1.5 -0.77937 -1.341951 -1.06066 -1.06066 +C -1.341951 -0.77937 -1.5 -0.397805 -1.5 0 +C -1.5 0.397805 -1.341951 0.77937 -1.06066 1.06066 +C -0.77937 1.341951 -0.397805 1.5 0 1.5 +z +" id="m5fb0882079" style="stroke:#000000;"/> + </defs> + <g clip-path="url(#p7ed90a7c9b)"> + <use style="stroke:#000000;" x="263.332642" xlink:href="#m5fb0882079" y="200.400053"/> + <use style="stroke:#000000;" x="260.82767" xlink:href="#m5fb0882079" y="204.303886"/> + <use style="stroke:#000000;" x="299.275809" xlink:href="#m5fb0882079" y="179.599353"/> + <use style="stroke:#000000;" x="298.173634" xlink:href="#m5fb0882079" y="181.983535"/> + <use style="stroke:#000000;" x="288.082926" xlink:href="#m5fb0882079" y="187.50727"/> + <use style="stroke:#000000;" x="295.047771" xlink:href="#m5fb0882079" y="181.230246"/> + <use style="stroke:#000000;" x="281.972266" xlink:href="#m5fb0882079" y="188.484505"/> + <use style="stroke:#000000;" x="298.893063" xlink:href="#m5fb0882079" y="179.919553"/> + <use style="stroke:#000000;" x="275.442253" xlink:href="#m5fb0882079" y="191.837368"/> + <use style="stroke:#000000;" x="270.604898" xlink:href="#m5fb0882079" y="195.801206"/> + <use style="stroke:#000000;" x="265.103257" xlink:href="#m5fb0882079" y="195.506589"/> + <use style="stroke:#000000;" x="263.949768" xlink:href="#m5fb0882079" y="198.364607"/> + <use style="stroke:#000000;" x="269.2562" xlink:href="#m5fb0882079" y="195.373116"/> + <use style="stroke:#000000;" x="236.262751" xlink:href="#m5fb0882079" y="214.029364"/> + <use style="stroke:#000000;" x="287.448546" xlink:href="#m5fb0882079" y="188.969577"/> + <use style="stroke:#000000;" x="290.82332" xlink:href="#m5fb0882079" y="184.243334"/> + <use style="stroke:#000000;" x="281.587989" xlink:href="#m5fb0882079" y="187.409294"/> + <use style="stroke:#000000;" x="283.508406" xlink:href="#m5fb0882079" y="187.430423"/> + <use style="stroke:#000000;" x="290.113022" xlink:href="#m5fb0882079" y="181.76521"/> + <use style="stroke:#000000;" x="260.100978" xlink:href="#m5fb0882079" y="201.296309"/> + <use style="stroke:#000000;" x="267.379299" xlink:href="#m5fb0882079" y="196.792944"/> + <use style="stroke:#000000;" x="314.620006" xlink:href="#m5fb0882079" y="170.234453"/> + <use style="stroke:#000000;" x="272.58209" xlink:href="#m5fb0882079" y="195.703638"/> + <use style="stroke:#000000;" x="250.014909" xlink:href="#m5fb0882079" y="206.517656"/> + <use style="stroke:#000000;" x="260.918892" xlink:href="#m5fb0882079" y="200.601501"/> + <use style="stroke:#000000;" x="291.232491" xlink:href="#m5fb0882079" y="181.685617"/> + <use style="stroke:#000000;" x="299.190438" xlink:href="#m5fb0882079" y="176.924219"/> + <use style="stroke:#000000;" x="320.926277" xlink:href="#m5fb0882079" y="164.99204"/> + <use style="stroke:#000000;" x="254.565162" xlink:href="#m5fb0882079" y="202.426093"/> + <use style="stroke:#000000;" x="285.663336" xlink:href="#m5fb0882079" y="188.972721"/> + <use style="stroke:#000000;" x="276.713666" xlink:href="#m5fb0882079" y="189.641418"/> + <use style="stroke:#000000;" x="268.929932" xlink:href="#m5fb0882079" y="195.365847"/> + <use style="stroke:#000000;" x="283.143593" xlink:href="#m5fb0882079" y="188.252768"/> + <use style="stroke:#000000;" x="266.387365" xlink:href="#m5fb0882079" y="198.444591"/> + <use style="stroke:#000000;" x="314.42473" xlink:href="#m5fb0882079" y="171.979495"/> + <use style="stroke:#000000;" x="263.135801" xlink:href="#m5fb0882079" y="196.658094"/> + <use style="stroke:#000000;" x="275.458583" xlink:href="#m5fb0882079" y="192.900547"/> + <use style="stroke:#000000;" x="270.393723" xlink:href="#m5fb0882079" y="194.667639"/> + <use style="stroke:#000000;" x="291.81429" xlink:href="#m5fb0882079" y="183.452208"/> + <use style="stroke:#000000;" x="276.253715" xlink:href="#m5fb0882079" y="189.195613"/> + <use style="stroke:#000000;" x="259.949782" xlink:href="#m5fb0882079" y="199.369659"/> + <use style="stroke:#000000;" x="270.291705" xlink:href="#m5fb0882079" y="196.252067"/> + <use style="stroke:#000000;" x="264.640556" xlink:href="#m5fb0882079" y="198.902778"/> + <use style="stroke:#000000;" x="262.476223" xlink:href="#m5fb0882079" y="197.16084"/> + <use style="stroke:#000000;" x="254.755943" xlink:href="#m5fb0882079" y="204.70142"/> + <use style="stroke:#000000;" x="267.478505" xlink:href="#m5fb0882079" y="199.045155"/> + <use style="stroke:#000000;" x="249.800175" xlink:href="#m5fb0882079" y="206.968934"/> + <use style="stroke:#000000;" x="264.466427" xlink:href="#m5fb0882079" y="196.596021"/> + <use style="stroke:#000000;" x="303.449663" xlink:href="#m5fb0882079" y="175.984688"/> + <use style="stroke:#000000;" x="315.821449" xlink:href="#m5fb0882079" y="167.562599"/> + <use style="stroke:#000000;" x="283.093551" xlink:href="#m5fb0882079" y="189.530219"/> + <use style="stroke:#000000;" x="263.35151" xlink:href="#m5fb0882079" y="198.498367"/> + <use style="stroke:#000000;" x="310.019387" xlink:href="#m5fb0882079" y="174.056827"/> + <use style="stroke:#000000;" x="308.639126" xlink:href="#m5fb0882079" y="175.481781"/> + <use style="stroke:#000000;" x="270.121241" xlink:href="#m5fb0882079" y="194.478173"/> + <use style="stroke:#000000;" x="297.379415" xlink:href="#m5fb0882079" y="179.243871"/> + <use style="stroke:#000000;" x="308.951582" xlink:href="#m5fb0882079" y="171.110538"/> + <use style="stroke:#000000;" x="256.470777" xlink:href="#m5fb0882079" y="201.061015"/> + <use style="stroke:#000000;" x="273.056763" xlink:href="#m5fb0882079" y="194.057183"/> + <use style="stroke:#000000;" x="277.863709" xlink:href="#m5fb0882079" y="191.816294"/> + <use style="stroke:#000000;" x="291.518161" xlink:href="#m5fb0882079" y="185.836215"/> + <use style="stroke:#000000;" x="271.543462" xlink:href="#m5fb0882079" y="192.617003"/> + <use style="stroke:#000000;" x="286.166343" xlink:href="#m5fb0882079" y="187.611259"/> + <use style="stroke:#000000;" x="300.901757" xlink:href="#m5fb0882079" y="179.163243"/> + <use style="stroke:#000000;" x="252.072733" xlink:href="#m5fb0882079" y="204.167976"/> + <use style="stroke:#000000;" x="289.422146" xlink:href="#m5fb0882079" y="184.496827"/> + <use style="stroke:#000000;" x="290.082893" xlink:href="#m5fb0882079" y="184.242745"/> + <use style="stroke:#000000;" x="288.423167" xlink:href="#m5fb0882079" y="182.506694"/> + <use style="stroke:#000000;" x="293.680624" xlink:href="#m5fb0882079" y="182.244007"/> + <use style="stroke:#000000;" x="275.672894" xlink:href="#m5fb0882079" y="192.506361"/> + <use style="stroke:#000000;" x="277.667694" xlink:href="#m5fb0882079" y="191.84356"/> + <use style="stroke:#000000;" x="306.698683" xlink:href="#m5fb0882079" y="175.462545"/> + <use style="stroke:#000000;" x="285.900663" xlink:href="#m5fb0882079" y="185.977158"/> + <use style="stroke:#000000;" x="297.384552" xlink:href="#m5fb0882079" y="177.98962"/> + <use style="stroke:#000000;" x="288.116153" xlink:href="#m5fb0882079" y="185.981784"/> + <use style="stroke:#000000;" x="297.808958" xlink:href="#m5fb0882079" y="178.051298"/> + <use style="stroke:#000000;" x="263.738202" xlink:href="#m5fb0882079" y="200.150181"/> + <use style="stroke:#000000;" x="308.165673" xlink:href="#m5fb0882079" y="173.613182"/> + <use style="stroke:#000000;" x="311.65274" xlink:href="#m5fb0882079" y="171.395772"/> + <use style="stroke:#000000;" x="302.726532" xlink:href="#m5fb0882079" y="179.682127"/> + <use style="stroke:#000000;" x="314.950693" xlink:href="#m5fb0882079" y="168.35498"/> + <use style="stroke:#000000;" x="256.295825" xlink:href="#m5fb0882079" y="203.739289"/> + <use style="stroke:#000000;" x="278.414294" xlink:href="#m5fb0882079" y="191.223489"/> + <use style="stroke:#000000;" x="295.09776" xlink:href="#m5fb0882079" y="181.541654"/> + <use style="stroke:#000000;" x="242.175477" xlink:href="#m5fb0882079" y="209.379794"/> + <use style="stroke:#000000;" x="284.119798" xlink:href="#m5fb0882079" y="187.604641"/> + <use style="stroke:#000000;" x="244.172428" xlink:href="#m5fb0882079" y="209.492429"/> + <use style="stroke:#000000;" x="272.446588" xlink:href="#m5fb0882079" y="191.405298"/> + <use style="stroke:#000000;" x="281.93718" xlink:href="#m5fb0882079" y="188.160742"/> + <use style="stroke:#000000;" x="277.590891" xlink:href="#m5fb0882079" y="191.951883"/> + <use style="stroke:#000000;" x="284.760277" xlink:href="#m5fb0882079" y="188.260481"/> + <use style="stroke:#000000;" x="276.775214" xlink:href="#m5fb0882079" y="193.70099"/> + <use style="stroke:#000000;" x="306.676805" xlink:href="#m5fb0882079" y="175.132512"/> + <use style="stroke:#000000;" x="243.82821" xlink:href="#m5fb0882079" y="209.13043"/> + <use style="stroke:#000000;" x="236.96652" xlink:href="#m5fb0882079" y="210.62552"/> + <use style="stroke:#000000;" x="296.262391" xlink:href="#m5fb0882079" y="180.404229"/> + <use style="stroke:#000000;" x="287.69384" xlink:href="#m5fb0882079" y="185.977571"/> + <use style="stroke:#000000;" x="309.830939" xlink:href="#m5fb0882079" y="172.013475"/> + <use style="stroke:#000000;" x="300.630588" xlink:href="#m5fb0882079" y="175.798659"/> + <use style="stroke:#000000;" x="297.353114" xlink:href="#m5fb0882079" y="181.696534"/> + </g> + </g> + <g id="patch_6"> + <path d="M 77.495251 315.42788 +L 77.495251 48.167472 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/> + </g> + <g id="patch_7"> + <path d="M 344.755659 315.42788 +L 344.755659 48.167472 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/> + </g> + <g id="patch_8"> + <path d="M 77.495251 315.42788 +L 344.755659 315.42788 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/> + </g> + <g id="patch_9"> + <path d="M 77.495251 48.167472 +L 344.755659 48.167472 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/> + </g> + <g id="text_16"> + <!-- Velocity Motion Model --> + <defs> + <path d="M 28.609375 0 +L 0.78125 72.90625 +L 11.078125 72.90625 +L 34.1875 11.53125 +L 57.328125 72.90625 +L 67.578125 72.90625 +L 39.796875 0 +z +" id="DejaVuSans-86"/> + <path d="M 56.203125 29.59375 +L 56.203125 25.203125 +L 14.890625 25.203125 +Q 15.484375 15.921875 20.484375 11.0625 +Q 25.484375 6.203125 34.421875 6.203125 +Q 39.59375 6.203125 44.453125 7.46875 +Q 49.3125 8.734375 54.109375 11.28125 +L 54.109375 2.78125 +Q 49.265625 0.734375 44.1875 -0.34375 +Q 39.109375 -1.421875 33.890625 -1.421875 +Q 20.796875 -1.421875 13.15625 6.1875 +Q 5.515625 13.8125 5.515625 26.8125 +Q 5.515625 40.234375 12.765625 48.109375 +Q 20.015625 56 32.328125 56 +Q 43.359375 56 49.78125 48.890625 +Q 56.203125 41.796875 56.203125 29.59375 +z +M 47.21875 32.234375 +Q 47.125 39.59375 43.09375 43.984375 +Q 39.0625 48.390625 32.421875 48.390625 +Q 24.90625 48.390625 20.390625 44.140625 +Q 15.875 39.890625 15.1875 32.171875 +z +" id="DejaVuSans-101"/> + <path d="M 9.421875 75.984375 +L 18.40625 75.984375 +L 18.40625 0 +L 9.421875 0 +z +" id="DejaVuSans-108"/> + <path d="M 30.609375 48.390625 +Q 23.390625 48.390625 19.1875 42.75 +Q 14.984375 37.109375 14.984375 27.296875 +Q 14.984375 17.484375 19.15625 11.84375 +Q 23.34375 6.203125 30.609375 6.203125 +Q 37.796875 6.203125 41.984375 11.859375 +Q 46.1875 17.53125 46.1875 27.296875 +Q 46.1875 37.015625 41.984375 42.703125 +Q 37.796875 48.390625 30.609375 48.390625 +z +M 30.609375 56 +Q 42.328125 56 49.015625 48.375 +Q 55.71875 40.765625 55.71875 27.296875 +Q 55.71875 13.875 49.015625 6.21875 +Q 42.328125 -1.421875 30.609375 -1.421875 +Q 18.84375 -1.421875 12.171875 6.21875 +Q 5.515625 13.875 5.515625 27.296875 +Q 5.515625 40.765625 12.171875 48.375 +Q 18.84375 56 30.609375 56 +z +" id="DejaVuSans-111"/> + <path d="M 48.78125 52.59375 +L 48.78125 44.1875 +Q 44.96875 46.296875 41.140625 47.34375 +Q 37.3125 48.390625 33.40625 48.390625 +Q 24.65625 48.390625 19.8125 42.84375 +Q 14.984375 37.3125 14.984375 27.296875 +Q 14.984375 17.28125 19.8125 11.734375 +Q 24.65625 6.203125 33.40625 6.203125 +Q 37.3125 6.203125 41.140625 7.25 +Q 44.96875 8.296875 48.78125 10.40625 +L 48.78125 2.09375 +Q 45.015625 0.34375 40.984375 -0.53125 +Q 36.96875 -1.421875 32.421875 -1.421875 +Q 20.0625 -1.421875 12.78125 6.34375 +Q 5.515625 14.109375 5.515625 27.296875 +Q 5.515625 40.671875 12.859375 48.328125 +Q 20.21875 56 33.015625 56 +Q 37.15625 56 41.109375 55.140625 +Q 45.0625 54.296875 48.78125 52.59375 +z +" id="DejaVuSans-99"/> + <path d="M 9.421875 54.6875 +L 18.40625 54.6875 +L 18.40625 0 +L 9.421875 0 +z +M 9.421875 75.984375 +L 18.40625 75.984375 +L 18.40625 64.59375 +L 9.421875 64.59375 +z +" id="DejaVuSans-105"/> + <path d="M 18.3125 70.21875 +L 18.3125 54.6875 +L 36.8125 54.6875 +L 36.8125 47.703125 +L 18.3125 47.703125 +L 18.3125 18.015625 +Q 18.3125 11.328125 20.140625 9.421875 +Q 21.96875 7.515625 27.59375 7.515625 +L 36.8125 7.515625 +L 36.8125 0 +L 27.59375 0 +Q 17.1875 0 13.234375 3.875 +Q 9.28125 7.765625 9.28125 18.015625 +L 9.28125 47.703125 +L 2.6875 47.703125 +L 2.6875 54.6875 +L 9.28125 54.6875 +L 9.28125 70.21875 +z +" id="DejaVuSans-116"/> + <path id="DejaVuSans-32"/> + <path d="M 9.8125 72.90625 +L 24.515625 72.90625 +L 43.109375 23.296875 +L 61.8125 72.90625 +L 76.515625 72.90625 +L 76.515625 0 +L 66.890625 0 +L 66.890625 64.015625 +L 48.09375 14.015625 +L 38.1875 14.015625 +L 19.390625 64.015625 +L 19.390625 0 +L 9.8125 0 +z +" id="DejaVuSans-77"/> + <path d="M 54.890625 33.015625 +L 54.890625 0 +L 45.90625 0 +L 45.90625 32.71875 +Q 45.90625 40.484375 42.875 44.328125 +Q 39.84375 48.1875 33.796875 48.1875 +Q 26.515625 48.1875 22.3125 43.546875 +Q 18.109375 38.921875 18.109375 30.90625 +L 18.109375 0 +L 9.078125 0 +L 9.078125 54.6875 +L 18.109375 54.6875 +L 18.109375 46.1875 +Q 21.34375 51.125 25.703125 53.5625 +Q 30.078125 56 35.796875 56 +Q 45.21875 56 50.046875 50.171875 +Q 54.890625 44.34375 54.890625 33.015625 +z +" id="DejaVuSans-110"/> + <path d="M 45.40625 46.390625 +L 45.40625 75.984375 +L 54.390625 75.984375 +L 54.390625 0 +L 45.40625 0 +L 45.40625 8.203125 +Q 42.578125 3.328125 38.25 0.953125 +Q 33.9375 -1.421875 27.875 -1.421875 +Q 17.96875 -1.421875 11.734375 6.484375 +Q 5.515625 14.40625 5.515625 27.296875 +Q 5.515625 40.1875 11.734375 48.09375 +Q 17.96875 56 27.875 56 +Q 33.9375 56 38.25 53.625 +Q 42.578125 51.265625 45.40625 46.390625 +z +M 14.796875 27.296875 +Q 14.796875 17.390625 18.875 11.75 +Q 22.953125 6.109375 30.078125 6.109375 +Q 37.203125 6.109375 41.296875 11.75 +Q 45.40625 17.390625 45.40625 27.296875 +Q 45.40625 37.203125 41.296875 42.84375 +Q 37.203125 48.484375 30.078125 48.484375 +Q 22.953125 48.484375 18.875 42.84375 +Q 14.796875 37.203125 14.796875 27.296875 +z +" id="DejaVuSans-100"/> + </defs> + <g transform="translate(125.107298 24.698885)scale(0.156 -0.156)"> + <use xlink:href="#DejaVuSans-86"/> + <use x="68.298828" xlink:href="#DejaVuSans-101"/> + <use x="129.822266" xlink:href="#DejaVuSans-108"/> + <use x="157.605469" xlink:href="#DejaVuSans-111"/> + <use x="218.787109" xlink:href="#DejaVuSans-99"/> + <use x="273.767578" xlink:href="#DejaVuSans-105"/> + <use x="301.550781" xlink:href="#DejaVuSans-116"/> + <use x="340.759766" xlink:href="#DejaVuSans-121"/> + <use x="399.939453" xlink:href="#DejaVuSans-32"/> + <use x="431.726562" xlink:href="#DejaVuSans-77"/> + <use x="518.005859" xlink:href="#DejaVuSans-111"/> + <use x="579.1875" xlink:href="#DejaVuSans-116"/> + <use x="618.396484" xlink:href="#DejaVuSans-105"/> + <use x="646.179688" xlink:href="#DejaVuSans-111"/> + <use x="707.361328" xlink:href="#DejaVuSans-110"/> + <use x="770.740234" xlink:href="#DejaVuSans-32"/> + <use x="802.527344" xlink:href="#DejaVuSans-77"/> + <use x="888.806641" xlink:href="#DejaVuSans-111"/> + <use x="949.988281" xlink:href="#DejaVuSans-100"/> + <use x="1013.464844" xlink:href="#DejaVuSans-101"/> + <use x="1074.988281" xlink:href="#DejaVuSans-108"/> + </g> + <!-- high translatory uncertainty --> + <defs> + <path d="M 54.890625 33.015625 +L 54.890625 0 +L 45.90625 0 +L 45.90625 32.71875 +Q 45.90625 40.484375 42.875 44.328125 +Q 39.84375 48.1875 33.796875 48.1875 +Q 26.515625 48.1875 22.3125 43.546875 +Q 18.109375 38.921875 18.109375 30.90625 +L 18.109375 0 +L 9.078125 0 +L 9.078125 75.984375 +L 18.109375 75.984375 +L 18.109375 46.1875 +Q 21.34375 51.125 25.703125 53.5625 +Q 30.078125 56 35.796875 56 +Q 45.21875 56 50.046875 50.171875 +Q 54.890625 44.34375 54.890625 33.015625 +z +" id="DejaVuSans-104"/> + <path d="M 45.40625 27.984375 +Q 45.40625 37.75 41.375 43.109375 +Q 37.359375 48.484375 30.078125 48.484375 +Q 22.859375 48.484375 18.828125 43.109375 +Q 14.796875 37.75 14.796875 27.984375 +Q 14.796875 18.265625 18.828125 12.890625 +Q 22.859375 7.515625 30.078125 7.515625 +Q 37.359375 7.515625 41.375 12.890625 +Q 45.40625 18.265625 45.40625 27.984375 +z +M 54.390625 6.78125 +Q 54.390625 -7.171875 48.1875 -13.984375 +Q 42 -20.796875 29.203125 -20.796875 +Q 24.46875 -20.796875 20.265625 -20.09375 +Q 16.0625 -19.390625 12.109375 -17.921875 +L 12.109375 -9.1875 +Q 16.0625 -11.328125 19.921875 -12.34375 +Q 23.78125 -13.375 27.78125 -13.375 +Q 36.625 -13.375 41.015625 -8.765625 +Q 45.40625 -4.15625 45.40625 5.171875 +L 45.40625 9.625 +Q 42.625 4.78125 38.28125 2.390625 +Q 33.9375 0 27.875 0 +Q 17.828125 0 11.671875 7.65625 +Q 5.515625 15.328125 5.515625 27.984375 +Q 5.515625 40.671875 11.671875 48.328125 +Q 17.828125 56 27.875 56 +Q 33.9375 56 38.28125 53.609375 +Q 42.625 51.21875 45.40625 46.390625 +L 45.40625 54.6875 +L 54.390625 54.6875 +z +" id="DejaVuSans-103"/> + <path d="M 41.109375 46.296875 +Q 39.59375 47.171875 37.8125 47.578125 +Q 36.03125 48 33.890625 48 +Q 26.265625 48 22.1875 43.046875 +Q 18.109375 38.09375 18.109375 28.8125 +L 18.109375 0 +L 9.078125 0 +L 9.078125 54.6875 +L 18.109375 54.6875 +L 18.109375 46.1875 +Q 20.953125 51.171875 25.484375 53.578125 +Q 30.03125 56 36.53125 56 +Q 37.453125 56 38.578125 55.875 +Q 39.703125 55.765625 41.0625 55.515625 +z +" id="DejaVuSans-114"/> + <path d="M 34.28125 27.484375 +Q 23.390625 27.484375 19.1875 25 +Q 14.984375 22.515625 14.984375 16.5 +Q 14.984375 11.71875 18.140625 8.90625 +Q 21.296875 6.109375 26.703125 6.109375 +Q 34.1875 6.109375 38.703125 11.40625 +Q 43.21875 16.703125 43.21875 25.484375 +L 43.21875 27.484375 +z +M 52.203125 31.203125 +L 52.203125 0 +L 43.21875 0 +L 43.21875 8.296875 +Q 40.140625 3.328125 35.546875 0.953125 +Q 30.953125 -1.421875 24.3125 -1.421875 +Q 15.921875 -1.421875 10.953125 3.296875 +Q 6 8.015625 6 15.921875 +Q 6 25.140625 12.171875 29.828125 +Q 18.359375 34.515625 30.609375 34.515625 +L 43.21875 34.515625 +L 43.21875 35.40625 +Q 43.21875 41.609375 39.140625 45 +Q 35.0625 48.390625 27.6875 48.390625 +Q 23 48.390625 18.546875 47.265625 +Q 14.109375 46.140625 10.015625 43.890625 +L 10.015625 52.203125 +Q 14.9375 54.109375 19.578125 55.046875 +Q 24.21875 56 28.609375 56 +Q 40.484375 56 46.34375 49.84375 +Q 52.203125 43.703125 52.203125 31.203125 +z +" id="DejaVuSans-97"/> + <path d="M 44.28125 53.078125 +L 44.28125 44.578125 +Q 40.484375 46.53125 36.375 47.5 +Q 32.28125 48.484375 27.875 48.484375 +Q 21.1875 48.484375 17.84375 46.4375 +Q 14.5 44.390625 14.5 40.28125 +Q 14.5 37.15625 16.890625 35.375 +Q 19.28125 33.59375 26.515625 31.984375 +L 29.59375 31.296875 +Q 39.15625 29.25 43.1875 25.515625 +Q 47.21875 21.78125 47.21875 15.09375 +Q 47.21875 7.46875 41.1875 3.015625 +Q 35.15625 -1.421875 24.609375 -1.421875 +Q 20.21875 -1.421875 15.453125 -0.5625 +Q 10.6875 0.296875 5.421875 2 +L 5.421875 11.28125 +Q 10.40625 8.6875 15.234375 7.390625 +Q 20.0625 6.109375 24.8125 6.109375 +Q 31.15625 6.109375 34.5625 8.28125 +Q 37.984375 10.453125 37.984375 14.40625 +Q 37.984375 18.0625 35.515625 20.015625 +Q 33.0625 21.96875 24.703125 23.78125 +L 21.578125 24.515625 +Q 13.234375 26.265625 9.515625 29.90625 +Q 5.8125 33.546875 5.8125 39.890625 +Q 5.8125 47.609375 11.28125 51.796875 +Q 16.75 56 26.8125 56 +Q 31.78125 56 36.171875 55.265625 +Q 40.578125 54.546875 44.28125 53.078125 +z +" id="DejaVuSans-115"/> + <path d="M 8.5 21.578125 +L 8.5 54.6875 +L 17.484375 54.6875 +L 17.484375 21.921875 +Q 17.484375 14.15625 20.5 10.265625 +Q 23.53125 6.390625 29.59375 6.390625 +Q 36.859375 6.390625 41.078125 11.03125 +Q 45.3125 15.671875 45.3125 23.6875 +L 45.3125 54.6875 +L 54.296875 54.6875 +L 54.296875 0 +L 45.3125 0 +L 45.3125 8.40625 +Q 42.046875 3.421875 37.71875 1 +Q 33.40625 -1.421875 27.6875 -1.421875 +Q 18.265625 -1.421875 13.375 4.4375 +Q 8.5 10.296875 8.5 21.578125 +z +M 31.109375 56 +z +" id="DejaVuSans-117"/> + </defs> + <g transform="translate(99.228361 42.167472)scale(0.156 -0.156)"> + <use xlink:href="#DejaVuSans-32"/> + <use x="31.787109" xlink:href="#DejaVuSans-104"/> + <use x="95.166016" xlink:href="#DejaVuSans-105"/> + <use x="122.949219" xlink:href="#DejaVuSans-103"/> + <use x="186.425781" xlink:href="#DejaVuSans-104"/> + <use x="249.804688" xlink:href="#DejaVuSans-32"/> + <use x="281.591797" xlink:href="#DejaVuSans-116"/> + <use x="320.800781" xlink:href="#DejaVuSans-114"/> + <use x="361.914062" xlink:href="#DejaVuSans-97"/> + <use x="423.193359" xlink:href="#DejaVuSans-110"/> + <use x="486.572266" xlink:href="#DejaVuSans-115"/> + <use x="538.671875" xlink:href="#DejaVuSans-108"/> + <use x="566.455078" xlink:href="#DejaVuSans-97"/> + <use x="627.734375" xlink:href="#DejaVuSans-116"/> + <use x="666.943359" xlink:href="#DejaVuSans-111"/> + <use x="728.125" xlink:href="#DejaVuSans-114"/> + <use x="769.238281" xlink:href="#DejaVuSans-121"/> + <use x="828.417969" xlink:href="#DejaVuSans-32"/> + <use x="860.205078" xlink:href="#DejaVuSans-117"/> + <use x="923.583984" xlink:href="#DejaVuSans-110"/> + <use x="986.962891" xlink:href="#DejaVuSans-99"/> + <use x="1041.943359" xlink:href="#DejaVuSans-101"/> + <use x="1103.466797" xlink:href="#DejaVuSans-114"/> + <use x="1144.580078" xlink:href="#DejaVuSans-116"/> + <use x="1183.789062" xlink:href="#DejaVuSans-97"/> + <use x="1245.068359" xlink:href="#DejaVuSans-105"/> + <use x="1272.851562" xlink:href="#DejaVuSans-110"/> + <use x="1336.230469" xlink:href="#DejaVuSans-116"/> + <use x="1375.439453" xlink:href="#DejaVuSans-121"/> + </g> + </g> + </g> + <g id="axes_2"> + <g id="patch_10"> + <path d="M 430.06616 315.42788 +L 697.326568 315.42788 +L 697.326568 48.167472 +L 430.06616 48.167472 +z +" style="fill:#ffffff;"/> + </g> + <g id="patch_11"> + <path clip-path="url(#p9ff03703d7)" d="M 463.473711 282.020329 +C 497.054277 282.020329 530.10259 273.581709 559.572309 257.482328 +C 589.042029 241.382947 613.998962 218.133157 632.14262 189.876084 +" style="fill:none;stroke:#000000;stroke-linejoin:miter;stroke-width:0.5;"/> + </g> + <g id="patch_12"> + <path clip-path="url(#p9ff03703d7)" d="M 493.540507 282.020329 +L 483.518241 285.361084 +L 483.518241 282.053737 +L 443.42918 282.053737 +L 443.42918 281.986921 +L 483.518241 281.986921 +L 483.518241 278.679574 +z +" style="fill:#0000ff;opacity:0.5;stroke:#0000ff;stroke-linejoin:miter;"/> + </g> + <g id="patch_13"> + <path clip-path="url(#p9ff03703d7)" d="M 648.387779 164.575748 +L 645.783874 174.814211 +L 643.000837 173.027243 +L 621.340625 206.761025 +L 621.284402 206.724925 +L 642.944614 172.991143 +L 640.161577 171.204175 +z +" style="fill:#0000ff;opacity:0.5;stroke:#0000ff;stroke-linejoin:miter;"/> + </g> + <g id="matplotlib.axis_3"> + <g id="xtick_5"> + <g id="line2d_15"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="463.473711" xlink:href="#m49a95e4598" y="315.42788"/> + </g> + </g> + <g id="text_17"> + <!-- 0 --> + <g transform="translate(459.338086 332.305849)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="xtick_6"> + <g id="line2d_16"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="530.288813" xlink:href="#m49a95e4598" y="315.42788"/> + </g> + </g> + <g id="text_18"> + <!-- 1 --> + <g transform="translate(526.153188 332.305849)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-49"/> + </g> + </g> + </g> + <g id="xtick_7"> + <g id="line2d_17"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="597.103915" xlink:href="#m49a95e4598" y="315.42788"/> + </g> + </g> + <g id="text_19"> + <!-- 2 --> + <g transform="translate(592.96829 332.305849)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-50"/> + </g> + </g> + </g> + <g id="xtick_8"> + <g id="line2d_18"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="663.919017" xlink:href="#m49a95e4598" y="315.42788"/> + </g> + </g> + <g id="text_20"> + <!-- 3 --> + <g transform="translate(659.783392 332.305849)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-51"/> + </g> + </g> + </g> + <g id="text_21"> + <!-- x --> + <g transform="translate(559.849176 348.887411)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-120"/> + </g> + </g> + </g> + <g id="matplotlib.axis_4"> + <g id="ytick_10"> + <g id="line2d_19"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="430.06616" xlink:href="#m392a87831e" y="315.42788"/> + </g> + </g> + <g id="text_22"> + <!-- −0.5 --> + <g transform="translate(391.498503 320.366864)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-8722"/> + <use x="83.789062" xlink:href="#DejaVuSans-48"/> + <use x="147.412109" xlink:href="#DejaVuSans-46"/> + <use x="179.199219" xlink:href="#DejaVuSans-53"/> + </g> + </g> + </g> + <g id="ytick_11"> + <g id="line2d_20"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="430.06616" xlink:href="#m392a87831e" y="282.020329"/> + </g> + </g> + <g id="text_23"> + <!-- 0.0 --> + <g transform="translate(402.392097 286.959313)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-48"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="ytick_12"> + <g id="line2d_21"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="430.06616" xlink:href="#m392a87831e" y="248.612778"/> + </g> + </g> + <g id="text_24"> + <!-- 0.5 --> + <g transform="translate(402.392097 253.551762)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-48"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-53"/> + </g> + </g> + </g> + <g id="ytick_13"> + <g id="line2d_22"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="430.06616" xlink:href="#m392a87831e" y="215.205227"/> + </g> + </g> + <g id="text_25"> + <!-- 1.0 --> + <g transform="translate(402.392097 220.144211)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-49"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="ytick_14"> + <g id="line2d_23"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="430.06616" xlink:href="#m392a87831e" y="181.797676"/> + </g> + </g> + <g id="text_26"> + <!-- 1.5 --> + <g transform="translate(402.392097 186.73666)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-49"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-53"/> + </g> + </g> + </g> + <g id="ytick_15"> + <g id="line2d_24"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="430.06616" xlink:href="#m392a87831e" y="148.390125"/> + </g> + </g> + <g id="text_27"> + <!-- 2.0 --> + <g transform="translate(402.392097 153.329109)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-50"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="ytick_16"> + <g id="line2d_25"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="430.06616" xlink:href="#m392a87831e" y="114.982574"/> + </g> + </g> + <g id="text_28"> + <!-- 2.5 --> + <g transform="translate(402.392097 119.921558)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-50"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-53"/> + </g> + </g> + </g> + <g id="ytick_17"> + <g id="line2d_26"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="430.06616" xlink:href="#m392a87831e" y="81.575023"/> + </g> + </g> + <g id="text_29"> + <!-- 3.0 --> + <g transform="translate(402.392097 86.514007)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-51"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="ytick_18"> + <g id="line2d_27"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="430.06616" xlink:href="#m392a87831e" y="48.167472"/> + </g> + </g> + <g id="text_30"> + <!-- 3.5 --> + <g transform="translate(402.392097 53.106456)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-51"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-53"/> + </g> + </g> + </g> + <g id="text_31"> + <!-- y --> + <g transform="translate(384.79491 185.644864)rotate(-90)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-121"/> + </g> + </g> + </g> + <g id="line2d_28"> + <g clip-path="url(#p9ff03703d7)"> + <use style="stroke:#000000;" x="629.030741" xlink:href="#m5fb0882079" y="185.660888"/> + <use style="stroke:#000000;" x="624.847067" xlink:href="#m5fb0882079" y="182.670281"/> + <use style="stroke:#000000;" x="632.393521" xlink:href="#m5fb0882079" y="189.872562"/> + <use style="stroke:#000000;" x="653.388779" xlink:href="#m5fb0882079" y="228.862198"/> + <use style="stroke:#000000;" x="601.950497" xlink:href="#m5fb0882079" y="165.090947"/> + <use style="stroke:#000000;" x="612.524769" xlink:href="#m5fb0882079" y="170.571651"/> + <use style="stroke:#000000;" x="641.966938" xlink:href="#m5fb0882079" y="205.559013"/> + <use style="stroke:#000000;" x="598.394336" xlink:href="#m5fb0882079" y="158.94352"/> + <use style="stroke:#000000;" x="622.393973" xlink:href="#m5fb0882079" y="179.284415"/> + <use style="stroke:#000000;" x="634.372954" xlink:href="#m5fb0882079" y="190.847716"/> + <use style="stroke:#000000;" x="644.148224" xlink:href="#m5fb0882079" y="209.274504"/> + <use style="stroke:#000000;" x="605.580757" xlink:href="#m5fb0882079" y="162.320209"/> + <use style="stroke:#000000;" x="578.71609" xlink:href="#m5fb0882079" y="148.899556"/> + <use style="stroke:#000000;" x="636.969596" xlink:href="#m5fb0882079" y="194.792035"/> + <use style="stroke:#000000;" x="632.98781" xlink:href="#m5fb0882079" y="187.798065"/> + <use style="stroke:#000000;" x="640.320483" xlink:href="#m5fb0882079" y="201.696101"/> + <use style="stroke:#000000;" x="621.002063" xlink:href="#m5fb0882079" y="181.910516"/> + <use style="stroke:#000000;" x="632.359747" xlink:href="#m5fb0882079" y="190.726809"/> + <use style="stroke:#000000;" x="643.847019" xlink:href="#m5fb0882079" y="211.305033"/> + <use style="stroke:#000000;" x="625.417116" xlink:href="#m5fb0882079" y="177.384101"/> + <use style="stroke:#000000;" x="626.343064" xlink:href="#m5fb0882079" y="185.11167"/> + <use style="stroke:#000000;" x="629.010881" xlink:href="#m5fb0882079" y="182.082554"/> + <use style="stroke:#000000;" x="615.245199" xlink:href="#m5fb0882079" y="169.575291"/> + <use style="stroke:#000000;" x="634.085588" xlink:href="#m5fb0882079" y="188.92479"/> + <use style="stroke:#000000;" x="638.721602" xlink:href="#m5fb0882079" y="208.245357"/> + <use style="stroke:#000000;" x="654.849574" xlink:href="#m5fb0882079" y="223.368443"/> + <use style="stroke:#000000;" x="652.748841" xlink:href="#m5fb0882079" y="228.727768"/> + <use style="stroke:#000000;" x="645.030619" xlink:href="#m5fb0882079" y="209.836596"/> + <use style="stroke:#000000;" x="632.325585" xlink:href="#m5fb0882079" y="189.565755"/> + <use style="stroke:#000000;" x="625.420151" xlink:href="#m5fb0882079" y="179.953241"/> + <use style="stroke:#000000;" x="618.866493" xlink:href="#m5fb0882079" y="175.277955"/> + <use style="stroke:#000000;" x="635.086476" xlink:href="#m5fb0882079" y="192.427563"/> + <use style="stroke:#000000;" x="603.529722" xlink:href="#m5fb0882079" y="160.448251"/> + <use style="stroke:#000000;" x="618.333543" xlink:href="#m5fb0882079" y="168.29314"/> + <use style="stroke:#000000;" x="649.343178" xlink:href="#m5fb0882079" y="215.410269"/> + <use style="stroke:#000000;" x="607.850938" xlink:href="#m5fb0882079" y="164.321464"/> + <use style="stroke:#000000;" x="651.857418" xlink:href="#m5fb0882079" y="213.145318"/> + <use style="stroke:#000000;" x="634.555057" xlink:href="#m5fb0882079" y="187.044629"/> + <use style="stroke:#000000;" x="604.338884" xlink:href="#m5fb0882079" y="160.737131"/> + <use style="stroke:#000000;" x="632.072839" xlink:href="#m5fb0882079" y="190.068173"/> + <use style="stroke:#000000;" x="655.266086" xlink:href="#m5fb0882079" y="217.981396"/> + <use style="stroke:#000000;" x="592.857049" xlink:href="#m5fb0882079" y="160.07653"/> + <use style="stroke:#000000;" x="602.475666" xlink:href="#m5fb0882079" y="158.719561"/> + <use style="stroke:#000000;" x="605.75564" xlink:href="#m5fb0882079" y="160.147056"/> + <use style="stroke:#000000;" x="578.789033" xlink:href="#m5fb0882079" y="146.503606"/> + <use style="stroke:#000000;" x="623.96947" xlink:href="#m5fb0882079" y="179.173006"/> + <use style="stroke:#000000;" x="623.428774" xlink:href="#m5fb0882079" y="182.043557"/> + <use style="stroke:#000000;" x="635.055208" xlink:href="#m5fb0882079" y="191.157266"/> + <use style="stroke:#000000;" x="637.657609" xlink:href="#m5fb0882079" y="203.941625"/> + <use style="stroke:#000000;" x="662.608085" xlink:href="#m5fb0882079" y="247.437361"/> + <use style="stroke:#000000;" x="608.640515" xlink:href="#m5fb0882079" y="169.922093"/> + <use style="stroke:#000000;" x="636.224662" xlink:href="#m5fb0882079" y="189.836508"/> + <use style="stroke:#000000;" x="617.027178" xlink:href="#m5fb0882079" y="170.525001"/> + <use style="stroke:#000000;" x="622.577434" xlink:href="#m5fb0882079" y="179.504746"/> + <use style="stroke:#000000;" x="635.84942" xlink:href="#m5fb0882079" y="197.080576"/> + <use style="stroke:#000000;" x="612.337356" xlink:href="#m5fb0882079" y="165.281239"/> + <use style="stroke:#000000;" x="645.732547" xlink:href="#m5fb0882079" y="206.947154"/> + <use style="stroke:#000000;" x="642.347705" xlink:href="#m5fb0882079" y="204.562639"/> + <use style="stroke:#000000;" x="608.335946" xlink:href="#m5fb0882079" y="172.304327"/> + <use style="stroke:#000000;" x="631.933797" xlink:href="#m5fb0882079" y="184.606034"/> + <use style="stroke:#000000;" x="625.231368" xlink:href="#m5fb0882079" y="182.199142"/> + <use style="stroke:#000000;" x="635.410305" xlink:href="#m5fb0882079" y="198.377906"/> + <use style="stroke:#000000;" x="638.193548" xlink:href="#m5fb0882079" y="191.8106"/> + <use style="stroke:#000000;" x="610.281595" xlink:href="#m5fb0882079" y="170.614975"/> + <use style="stroke:#000000;" x="599.31017" xlink:href="#m5fb0882079" y="160.652547"/> + <use style="stroke:#000000;" x="633.736297" xlink:href="#m5fb0882079" y="189.906638"/> + <use style="stroke:#000000;" x="639.747506" xlink:href="#m5fb0882079" y="201.524233"/> + <use style="stroke:#000000;" x="595.50475" xlink:href="#m5fb0882079" y="155.524583"/> + <use style="stroke:#000000;" x="569.476454" xlink:href="#m5fb0882079" y="144.605819"/> + <use style="stroke:#000000;" x="654.540111" xlink:href="#m5fb0882079" y="227.43694"/> + <use style="stroke:#000000;" x="638.128929" xlink:href="#m5fb0882079" y="192.023"/> + <use style="stroke:#000000;" x="622.902365" xlink:href="#m5fb0882079" y="177.397671"/> + <use style="stroke:#000000;" x="649.089975" xlink:href="#m5fb0882079" y="227.858164"/> + <use style="stroke:#000000;" x="650.367747" xlink:href="#m5fb0882079" y="217.649146"/> + <use style="stroke:#000000;" x="607.126425" xlink:href="#m5fb0882079" y="162.634476"/> + <use style="stroke:#000000;" x="642.906785" xlink:href="#m5fb0882079" y="205.138498"/> + <use style="stroke:#000000;" x="618.334524" xlink:href="#m5fb0882079" y="176.768072"/> + <use style="stroke:#000000;" x="619.796019" xlink:href="#m5fb0882079" y="172.295116"/> + <use style="stroke:#000000;" x="605.002474" xlink:href="#m5fb0882079" y="165.81829"/> + <use style="stroke:#000000;" x="633.19646" xlink:href="#m5fb0882079" y="193.988051"/> + <use style="stroke:#000000;" x="636.294957" xlink:href="#m5fb0882079" y="194.679132"/> + <use style="stroke:#000000;" x="621.158455" xlink:href="#m5fb0882079" y="176.7583"/> + <use style="stroke:#000000;" x="642.749413" xlink:href="#m5fb0882079" y="209.862014"/> + <use style="stroke:#000000;" x="624.53528" xlink:href="#m5fb0882079" y="178.833512"/> + <use style="stroke:#000000;" x="645.83925" xlink:href="#m5fb0882079" y="211.921739"/> + <use style="stroke:#000000;" x="634.84222" xlink:href="#m5fb0882079" y="195.931075"/> + <use style="stroke:#000000;" x="618.791074" xlink:href="#m5fb0882079" y="181.494495"/> + <use style="stroke:#000000;" x="618.099554" xlink:href="#m5fb0882079" y="174.494536"/> + <use style="stroke:#000000;" x="643.115926" xlink:href="#m5fb0882079" y="202.954329"/> + <use style="stroke:#000000;" x="657.319539" xlink:href="#m5fb0882079" y="231.513664"/> + <use style="stroke:#000000;" x="654.026249" xlink:href="#m5fb0882079" y="224.375269"/> + <use style="stroke:#000000;" x="647.598511" xlink:href="#m5fb0882079" y="207.050055"/> + <use style="stroke:#000000;" x="631.66444" xlink:href="#m5fb0882079" y="186.830376"/> + <use style="stroke:#000000;" x="630.804931" xlink:href="#m5fb0882079" y="182.103052"/> + <use style="stroke:#000000;" x="645.22075" xlink:href="#m5fb0882079" y="205.381863"/> + <use style="stroke:#000000;" x="628.826394" xlink:href="#m5fb0882079" y="181.424142"/> + <use style="stroke:#000000;" x="592.573826" xlink:href="#m5fb0882079" y="159.758404"/> + <use style="stroke:#000000;" x="655.084747" xlink:href="#m5fb0882079" y="250.319203"/> + <use style="stroke:#000000;" x="594.539045" xlink:href="#m5fb0882079" y="156.350295"/> + <use style="stroke:#000000;" x="643.647761" xlink:href="#m5fb0882079" y="207.094047"/> + </g> + </g> + <g id="patch_14"> + <path d="M 430.06616 315.42788 +L 430.06616 48.167472 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/> + </g> + <g id="patch_15"> + <path d="M 697.326568 315.42788 +L 697.326568 48.167472 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/> + </g> + <g id="patch_16"> + <path d="M 430.06616 315.42788 +L 697.326568 315.42788 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/> + </g> + <g id="patch_17"> + <path d="M 430.06616 48.167472 +L 697.326568 48.167472 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/> + </g> + <g id="text_32"> + <!-- Velocity Motion Model --> + <g transform="translate(477.678207 24.698885)scale(0.156 -0.156)"> + <use xlink:href="#DejaVuSans-86"/> + <use x="68.298828" xlink:href="#DejaVuSans-101"/> + <use x="129.822266" xlink:href="#DejaVuSans-108"/> + <use x="157.605469" xlink:href="#DejaVuSans-111"/> + <use x="218.787109" xlink:href="#DejaVuSans-99"/> + <use x="273.767578" xlink:href="#DejaVuSans-105"/> + <use x="301.550781" xlink:href="#DejaVuSans-116"/> + <use x="340.759766" xlink:href="#DejaVuSans-121"/> + <use x="399.939453" xlink:href="#DejaVuSans-32"/> + <use x="431.726562" xlink:href="#DejaVuSans-77"/> + <use x="518.005859" xlink:href="#DejaVuSans-111"/> + <use x="579.1875" xlink:href="#DejaVuSans-116"/> + <use x="618.396484" xlink:href="#DejaVuSans-105"/> + <use x="646.179688" xlink:href="#DejaVuSans-111"/> + <use x="707.361328" xlink:href="#DejaVuSans-110"/> + <use x="770.740234" xlink:href="#DejaVuSans-32"/> + <use x="802.527344" xlink:href="#DejaVuSans-77"/> + <use x="888.806641" xlink:href="#DejaVuSans-111"/> + <use x="949.988281" xlink:href="#DejaVuSans-100"/> + <use x="1013.464844" xlink:href="#DejaVuSans-101"/> + <use x="1074.988281" xlink:href="#DejaVuSans-108"/> + </g> + <!-- high rotatory uncertainty --> + <g transform="translate(462.98252 42.167472)scale(0.156 -0.156)"> + <use xlink:href="#DejaVuSans-32"/> + <use x="31.787109" xlink:href="#DejaVuSans-104"/> + <use x="95.166016" xlink:href="#DejaVuSans-105"/> + <use x="122.949219" xlink:href="#DejaVuSans-103"/> + <use x="186.425781" xlink:href="#DejaVuSans-104"/> + <use x="249.804688" xlink:href="#DejaVuSans-32"/> + <use x="281.591797" xlink:href="#DejaVuSans-114"/> + <use x="322.673828" xlink:href="#DejaVuSans-111"/> + <use x="383.855469" xlink:href="#DejaVuSans-116"/> + <use x="423.064453" xlink:href="#DejaVuSans-97"/> + <use x="484.34375" xlink:href="#DejaVuSans-116"/> + <use x="523.552734" xlink:href="#DejaVuSans-111"/> + <use x="584.734375" xlink:href="#DejaVuSans-114"/> + <use x="625.847656" xlink:href="#DejaVuSans-121"/> + <use x="685.027344" xlink:href="#DejaVuSans-32"/> + <use x="716.814453" xlink:href="#DejaVuSans-117"/> + <use x="780.193359" xlink:href="#DejaVuSans-110"/> + <use x="843.572266" xlink:href="#DejaVuSans-99"/> + <use x="898.552734" xlink:href="#DejaVuSans-101"/> + <use x="960.076172" xlink:href="#DejaVuSans-114"/> + <use x="1001.189453" xlink:href="#DejaVuSans-116"/> + <use x="1040.398438" xlink:href="#DejaVuSans-97"/> + <use x="1101.677734" xlink:href="#DejaVuSans-105"/> + <use x="1129.460938" xlink:href="#DejaVuSans-110"/> + <use x="1192.839844" xlink:href="#DejaVuSans-116"/> + <use x="1232.048828" xlink:href="#DejaVuSans-121"/> + </g> + </g> + </g> + <g id="axes_3"> + <g id="patch_18"> + <path d="M 77.495251 667.70192 +L 344.755659 667.70192 +L 344.755659 400.441512 +L 77.495251 400.441512 +z +" style="fill:#ffffff;"/> + </g> + <g id="patch_19"> + <path clip-path="url(#p0f820d4006)" d="M 140.969597 634.294369 +L 130.947332 637.635124 +L 130.947332 634.327777 +L 90.858271 634.327777 +L 90.858271 634.260961 +L 130.947332 634.260961 +L 130.947332 630.953614 +z +" style="fill:#0000ff;opacity:0.5;stroke:#0000ff;stroke-linejoin:miter;"/> + </g> + <g id="patch_20"> + <path clip-path="url(#p0f820d4006)" d="M 295.81687 516.849788 +L 293.212965 527.088251 +L 290.429928 525.301283 +L 268.769716 559.035065 +L 268.713493 558.998965 +L 290.373705 525.265183 +L 287.590668 523.478215 +z +" style="fill:#0000ff;opacity:0.5;stroke:#0000ff;stroke-linejoin:miter;"/> + </g> + <g id="matplotlib.axis_5"> + <g id="xtick_9"> + <g id="line2d_29"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="110.902802" xlink:href="#m49a95e4598" y="667.70192"/> + </g> + </g> + <g id="text_33"> + <!-- 0 --> + <g transform="translate(106.767177 684.579889)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="xtick_10"> + <g id="line2d_30"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="177.717904" xlink:href="#m49a95e4598" y="667.70192"/> + </g> + </g> + <g id="text_34"> + <!-- 1 --> + <g transform="translate(173.582279 684.579889)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-49"/> + </g> + </g> + </g> + <g id="xtick_11"> + <g id="line2d_31"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="244.533006" xlink:href="#m49a95e4598" y="667.70192"/> + </g> + </g> + <g id="text_35"> + <!-- 2 --> + <g transform="translate(240.397381 684.579889)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-50"/> + </g> + </g> + </g> + <g id="xtick_12"> + <g id="line2d_32"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="311.348108" xlink:href="#m49a95e4598" y="667.70192"/> + </g> + </g> + <g id="text_36"> + <!-- 3 --> + <g transform="translate(307.212483 684.579889)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-51"/> + </g> + </g> + </g> + <g id="text_37"> + <!-- x --> + <g transform="translate(207.278267 701.161451)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-120"/> + </g> + </g> + </g> + <g id="matplotlib.axis_6"> + <g id="ytick_19"> + <g id="line2d_33"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="77.495251" xlink:href="#m392a87831e" y="667.70192"/> + </g> + </g> + <g id="text_38"> + <!-- −0.5 --> + <g transform="translate(38.927594 672.640904)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-8722"/> + <use x="83.789062" xlink:href="#DejaVuSans-48"/> + <use x="147.412109" xlink:href="#DejaVuSans-46"/> + <use x="179.199219" xlink:href="#DejaVuSans-53"/> + </g> + </g> + </g> + <g id="ytick_20"> + <g id="line2d_34"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="77.495251" xlink:href="#m392a87831e" y="634.294369"/> + </g> + </g> + <g id="text_39"> + <!-- 0.0 --> + <g transform="translate(49.821188 639.233353)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-48"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="ytick_21"> + <g id="line2d_35"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="77.495251" xlink:href="#m392a87831e" y="600.886818"/> + </g> + </g> + <g id="text_40"> + <!-- 0.5 --> + <g transform="translate(49.821188 605.825802)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-48"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-53"/> + </g> + </g> + </g> + <g id="ytick_22"> + <g id="line2d_36"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="77.495251" xlink:href="#m392a87831e" y="567.479267"/> + </g> + </g> + <g id="text_41"> + <!-- 1.0 --> + <g transform="translate(49.821188 572.418251)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-49"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="ytick_23"> + <g id="line2d_37"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="77.495251" xlink:href="#m392a87831e" y="534.071716"/> + </g> + </g> + <g id="text_42"> + <!-- 1.5 --> + <g transform="translate(49.821188 539.0107)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-49"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-53"/> + </g> + </g> + </g> + <g id="ytick_24"> + <g id="line2d_38"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="77.495251" xlink:href="#m392a87831e" y="500.664165"/> + </g> + </g> + <g id="text_43"> + <!-- 2.0 --> + <g transform="translate(49.821188 505.603149)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-50"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="ytick_25"> + <g id="line2d_39"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="77.495251" xlink:href="#m392a87831e" y="467.256614"/> + </g> + </g> + <g id="text_44"> + <!-- 2.5 --> + <g transform="translate(49.821188 472.195598)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-50"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-53"/> + </g> + </g> + </g> + <g id="ytick_26"> + <g id="line2d_40"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="77.495251" xlink:href="#m392a87831e" y="433.849063"/> + </g> + </g> + <g id="text_45"> + <!-- 3.0 --> + <g transform="translate(49.821188 438.788047)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-51"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="ytick_27"> + <g id="line2d_41"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="77.495251" xlink:href="#m392a87831e" y="400.441512"/> + </g> + </g> + <g id="text_46"> + <!-- 3.5 --> + <g transform="translate(49.821188 405.380496)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-51"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-53"/> + </g> + </g> + </g> + <g id="text_47"> + <!-- y --> + <g transform="translate(32.224001 537.918903)rotate(-90)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-121"/> + </g> + </g> + </g> + <g id="line2d_42"> + <g clip-path="url(#p0f820d4006)"> + <use style="stroke:#000000;" x="275.572817" xlink:href="#m5fb0882079" y="544.753077"/> + <use style="stroke:#000000;" x="255.290466" xlink:href="#m5fb0882079" y="555.393795"/> + <use style="stroke:#000000;" x="275.643348" xlink:href="#m5fb0882079" y="545.416789"/> + <use style="stroke:#000000;" x="277.831393" xlink:href="#m5fb0882079" y="543.502902"/> + <use style="stroke:#000000;" x="266.545036" xlink:href="#m5fb0882079" y="548.470106"/> + <use style="stroke:#000000;" x="268.452623" xlink:href="#m5fb0882079" y="548.159373"/> + <use style="stroke:#000000;" x="275.482614" xlink:href="#m5fb0882079" y="545.440035"/> + <use style="stroke:#000000;" x="285.462948" xlink:href="#m5fb0882079" y="538.358619"/> + <use style="stroke:#000000;" x="284.460384" xlink:href="#m5fb0882079" y="541.040958"/> + <use style="stroke:#000000;" x="281.245532" xlink:href="#m5fb0882079" y="538.957962"/> + <use style="stroke:#000000;" x="285.524591" xlink:href="#m5fb0882079" y="542.559594"/> + <use style="stroke:#000000;" x="286.829742" xlink:href="#m5fb0882079" y="533.573222"/> + <use style="stroke:#000000;" x="288.168687" xlink:href="#m5fb0882079" y="538.717515"/> + <use style="stroke:#000000;" x="314.199482" xlink:href="#m5fb0882079" y="518.951662"/> + <use style="stroke:#000000;" x="271.640884" xlink:href="#m5fb0882079" y="547.072049"/> + <use style="stroke:#000000;" x="273.204168" xlink:href="#m5fb0882079" y="541.104365"/> + <use style="stroke:#000000;" x="259.619777" xlink:href="#m5fb0882079" y="554.842328"/> + <use style="stroke:#000000;" x="286.075459" xlink:href="#m5fb0882079" y="540.636523"/> + <use style="stroke:#000000;" x="291.138077" xlink:href="#m5fb0882079" y="536.798887"/> + <use style="stroke:#000000;" x="258.373889" xlink:href="#m5fb0882079" y="552.828125"/> + <use style="stroke:#000000;" x="283.871471" xlink:href="#m5fb0882079" y="536.102362"/> + <use style="stroke:#000000;" x="275.342133" xlink:href="#m5fb0882079" y="542.536225"/> + <use style="stroke:#000000;" x="295.101386" xlink:href="#m5fb0882079" y="530.650613"/> + <use style="stroke:#000000;" x="280.928763" xlink:href="#m5fb0882079" y="539.593836"/> + <use style="stroke:#000000;" x="265.499518" xlink:href="#m5fb0882079" y="552.050175"/> + <use style="stroke:#000000;" x="297.224381" xlink:href="#m5fb0882079" y="531.503301"/> + <use style="stroke:#000000;" x="265.448702" xlink:href="#m5fb0882079" y="546.560992"/> + <use style="stroke:#000000;" x="286.777125" xlink:href="#m5fb0882079" y="537.499925"/> + <use style="stroke:#000000;" x="313.070162" xlink:href="#m5fb0882079" y="519.983089"/> + <use style="stroke:#000000;" x="321.100569" xlink:href="#m5fb0882079" y="525.910639"/> + <use style="stroke:#000000;" x="259.262035" xlink:href="#m5fb0882079" y="552.117968"/> + <use style="stroke:#000000;" x="299.010294" xlink:href="#m5fb0882079" y="529.842101"/> + <use style="stroke:#000000;" x="301.816657" xlink:href="#m5fb0882079" y="531.895144"/> + <use style="stroke:#000000;" x="261.609044" xlink:href="#m5fb0882079" y="549.321168"/> + <use style="stroke:#000000;" x="263.077028" xlink:href="#m5fb0882079" y="552.774142"/> + <use style="stroke:#000000;" x="287.778546" xlink:href="#m5fb0882079" y="543.621385"/> + <use style="stroke:#000000;" x="286.234351" xlink:href="#m5fb0882079" y="542.882539"/> + <use style="stroke:#000000;" x="301.518446" xlink:href="#m5fb0882079" y="527.843132"/> + <use style="stroke:#000000;" x="289.389967" xlink:href="#m5fb0882079" y="535.736939"/> + <use style="stroke:#000000;" x="279.369013" xlink:href="#m5fb0882079" y="540.326454"/> + <use style="stroke:#000000;" x="271.516718" xlink:href="#m5fb0882079" y="544.7425"/> + <use style="stroke:#000000;" x="244.660051" xlink:href="#m5fb0882079" y="562.624522"/> + <use style="stroke:#000000;" x="282.614859" xlink:href="#m5fb0882079" y="542.888504"/> + <use style="stroke:#000000;" x="269.927236" xlink:href="#m5fb0882079" y="550.422094"/> + <use style="stroke:#000000;" x="281.807478" xlink:href="#m5fb0882079" y="539.545462"/> + <use style="stroke:#000000;" x="282.888168" xlink:href="#m5fb0882079" y="541.443807"/> + <use style="stroke:#000000;" x="257.109296" xlink:href="#m5fb0882079" y="556.512996"/> + <use style="stroke:#000000;" x="264.541083" xlink:href="#m5fb0882079" y="552.253303"/> + <use style="stroke:#000000;" x="281.214682" xlink:href="#m5fb0882079" y="543.236112"/> + <use style="stroke:#000000;" x="287.059695" xlink:href="#m5fb0882079" y="536.050621"/> + <use style="stroke:#000000;" x="288.364246" xlink:href="#m5fb0882079" y="535.418793"/> + <use style="stroke:#000000;" x="228.59219" xlink:href="#m5fb0882079" y="568.358201"/> + <use style="stroke:#000000;" x="292.383704" xlink:href="#m5fb0882079" y="535.011482"/> + <use style="stroke:#000000;" x="260.182333" xlink:href="#m5fb0882079" y="554.995737"/> + <use style="stroke:#000000;" x="272.129032" xlink:href="#m5fb0882079" y="547.553019"/> + <use style="stroke:#000000;" x="285.289762" xlink:href="#m5fb0882079" y="540.300686"/> + <use style="stroke:#000000;" x="258.597419" xlink:href="#m5fb0882079" y="554.4327"/> + <use style="stroke:#000000;" x="284.555717" xlink:href="#m5fb0882079" y="542.2908"/> + <use style="stroke:#000000;" x="276.086229" xlink:href="#m5fb0882079" y="543.98409"/> + <use style="stroke:#000000;" x="270.447533" xlink:href="#m5fb0882079" y="554.071967"/> + <use style="stroke:#000000;" x="293.150298" xlink:href="#m5fb0882079" y="538.188441"/> + <use style="stroke:#000000;" x="251.205957" xlink:href="#m5fb0882079" y="559.522319"/> + <use style="stroke:#000000;" x="257.881343" xlink:href="#m5fb0882079" y="551.941588"/> + <use style="stroke:#000000;" x="279.28501" xlink:href="#m5fb0882079" y="540.512118"/> + <use style="stroke:#000000;" x="301.994436" xlink:href="#m5fb0882079" y="533.299224"/> + <use style="stroke:#000000;" x="263.898567" xlink:href="#m5fb0882079" y="551.249934"/> + <use style="stroke:#000000;" x="283.753031" xlink:href="#m5fb0882079" y="544.659604"/> + <use style="stroke:#000000;" x="293.722482" xlink:href="#m5fb0882079" y="536.579389"/> + <use style="stroke:#000000;" x="301.025214" xlink:href="#m5fb0882079" y="531.758241"/> + <use style="stroke:#000000;" x="285.335453" xlink:href="#m5fb0882079" y="540.616013"/> + <use style="stroke:#000000;" x="268.34383" xlink:href="#m5fb0882079" y="550.01081"/> + <use style="stroke:#000000;" x="258.395189" xlink:href="#m5fb0882079" y="554.495113"/> + <use style="stroke:#000000;" x="263.820612" xlink:href="#m5fb0882079" y="550.262671"/> + <use style="stroke:#000000;" x="263.582394" xlink:href="#m5fb0882079" y="546.637261"/> + <use style="stroke:#000000;" x="251.795015" xlink:href="#m5fb0882079" y="554.540229"/> + <use style="stroke:#000000;" x="314.313542" xlink:href="#m5fb0882079" y="524.996669"/> + <use style="stroke:#000000;" x="275.532691" xlink:href="#m5fb0882079" y="544.329427"/> + <use style="stroke:#000000;" x="288.667793" xlink:href="#m5fb0882079" y="537.318849"/> + <use style="stroke:#000000;" x="284.857977" xlink:href="#m5fb0882079" y="536.933681"/> + <use style="stroke:#000000;" x="268.070142" xlink:href="#m5fb0882079" y="545.818328"/> + <use style="stroke:#000000;" x="292.648291" xlink:href="#m5fb0882079" y="533.808382"/> + <use style="stroke:#000000;" x="275.259338" xlink:href="#m5fb0882079" y="544.51336"/> + <use style="stroke:#000000;" x="276.697443" xlink:href="#m5fb0882079" y="543.068411"/> + <use style="stroke:#000000;" x="285.627875" xlink:href="#m5fb0882079" y="536.098647"/> + <use style="stroke:#000000;" x="307.648622" xlink:href="#m5fb0882079" y="527.246075"/> + <use style="stroke:#000000;" x="251.054227" xlink:href="#m5fb0882079" y="559.645521"/> + <use style="stroke:#000000;" x="264.755893" xlink:href="#m5fb0882079" y="545.617092"/> + <use style="stroke:#000000;" x="300.45505" xlink:href="#m5fb0882079" y="532.886181"/> + <use style="stroke:#000000;" x="286.385277" xlink:href="#m5fb0882079" y="537.13753"/> + <use style="stroke:#000000;" x="285.655064" xlink:href="#m5fb0882079" y="540.140661"/> + <use style="stroke:#000000;" x="244.99313" xlink:href="#m5fb0882079" y="564.213131"/> + <use style="stroke:#000000;" x="273.697975" xlink:href="#m5fb0882079" y="548.107593"/> + <use style="stroke:#000000;" x="301.118374" xlink:href="#m5fb0882079" y="529.068831"/> + <use style="stroke:#000000;" x="274.428136" xlink:href="#m5fb0882079" y="545.822916"/> + <use style="stroke:#000000;" x="276.039288" xlink:href="#m5fb0882079" y="546.774016"/> + <use style="stroke:#000000;" x="302.077185" xlink:href="#m5fb0882079" y="526.22012"/> + <use style="stroke:#000000;" x="285.041601" xlink:href="#m5fb0882079" y="541.514864"/> + <use style="stroke:#000000;" x="310.61888" xlink:href="#m5fb0882079" y="524.294235"/> + <use style="stroke:#000000;" x="284.004936" xlink:href="#m5fb0882079" y="545.339223"/> + <use style="stroke:#000000;" x="289.236452" xlink:href="#m5fb0882079" y="539.964964"/> + </g> + </g> + <g id="line2d_43"> + <path clip-path="url(#p0f820d4006)" d="M 110.902802 634.294369 +L 279.571711 542.150124 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-width:0.5;"/> + </g> + <g id="patch_21"> + <path d="M 77.495251 667.70192 +L 77.495251 400.441512 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/> + </g> + <g id="patch_22"> + <path d="M 344.755659 667.70192 +L 344.755659 400.441512 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/> + </g> + <g id="patch_23"> + <path d="M 77.495251 667.70192 +L 344.755659 667.70192 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/> + </g> + <g id="patch_24"> + <path d="M 77.495251 400.441512 +L 344.755659 400.441512 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/> + </g> + <g id="text_48"> + <!-- Odometry Motion Model --> + <defs> + <path d="M 39.40625 66.21875 +Q 28.65625 66.21875 22.328125 58.203125 +Q 16.015625 50.203125 16.015625 36.375 +Q 16.015625 22.609375 22.328125 14.59375 +Q 28.65625 6.59375 39.40625 6.59375 +Q 50.140625 6.59375 56.421875 14.59375 +Q 62.703125 22.609375 62.703125 36.375 +Q 62.703125 50.203125 56.421875 58.203125 +Q 50.140625 66.21875 39.40625 66.21875 +z +M 39.40625 74.21875 +Q 54.734375 74.21875 63.90625 63.9375 +Q 73.09375 53.65625 73.09375 36.375 +Q 73.09375 19.140625 63.90625 8.859375 +Q 54.734375 -1.421875 39.40625 -1.421875 +Q 24.03125 -1.421875 14.8125 8.828125 +Q 5.609375 19.09375 5.609375 36.375 +Q 5.609375 53.65625 14.8125 63.9375 +Q 24.03125 74.21875 39.40625 74.21875 +z +" id="DejaVuSans-79"/> + <path d="M 52 44.1875 +Q 55.375 50.25 60.0625 53.125 +Q 64.75 56 71.09375 56 +Q 79.640625 56 84.28125 50.015625 +Q 88.921875 44.046875 88.921875 33.015625 +L 88.921875 0 +L 79.890625 0 +L 79.890625 32.71875 +Q 79.890625 40.578125 77.09375 44.375 +Q 74.3125 48.1875 68.609375 48.1875 +Q 61.625 48.1875 57.5625 43.546875 +Q 53.515625 38.921875 53.515625 30.90625 +L 53.515625 0 +L 44.484375 0 +L 44.484375 32.71875 +Q 44.484375 40.625 41.703125 44.40625 +Q 38.921875 48.1875 33.109375 48.1875 +Q 26.21875 48.1875 22.15625 43.53125 +Q 18.109375 38.875 18.109375 30.90625 +L 18.109375 0 +L 9.078125 0 +L 9.078125 54.6875 +L 18.109375 54.6875 +L 18.109375 46.1875 +Q 21.1875 51.21875 25.484375 53.609375 +Q 29.78125 56 35.6875 56 +Q 41.65625 56 45.828125 52.96875 +Q 50 49.953125 52 44.1875 +z +" id="DejaVuSans-109"/> + </defs> + <g transform="translate(117.161048 376.972924)scale(0.156 -0.156)"> + <use xlink:href="#DejaVuSans-79"/> + <use x="78.710938" xlink:href="#DejaVuSans-100"/> + <use x="142.1875" xlink:href="#DejaVuSans-111"/> + <use x="203.369141" xlink:href="#DejaVuSans-109"/> + <use x="300.78125" xlink:href="#DejaVuSans-101"/> + <use x="362.304688" xlink:href="#DejaVuSans-116"/> + <use x="401.513672" xlink:href="#DejaVuSans-114"/> + <use x="442.626953" xlink:href="#DejaVuSans-121"/> + <use x="501.806641" xlink:href="#DejaVuSans-32"/> + <use x="533.59375" xlink:href="#DejaVuSans-77"/> + <use x="619.873047" xlink:href="#DejaVuSans-111"/> + <use x="681.054688" xlink:href="#DejaVuSans-116"/> + <use x="720.263672" xlink:href="#DejaVuSans-105"/> + <use x="748.046875" xlink:href="#DejaVuSans-111"/> + <use x="809.228516" xlink:href="#DejaVuSans-110"/> + <use x="872.607422" xlink:href="#DejaVuSans-32"/> + <use x="904.394531" xlink:href="#DejaVuSans-77"/> + <use x="990.673828" xlink:href="#DejaVuSans-111"/> + <use x="1051.855469" xlink:href="#DejaVuSans-100"/> + <use x="1115.332031" xlink:href="#DejaVuSans-101"/> + <use x="1176.855469" xlink:href="#DejaVuSans-108"/> + </g> + <!-- high translatory uncertainty --> + <g transform="translate(99.228361 394.441512)scale(0.156 -0.156)"> + <use xlink:href="#DejaVuSans-32"/> + <use x="31.787109" xlink:href="#DejaVuSans-104"/> + <use x="95.166016" xlink:href="#DejaVuSans-105"/> + <use x="122.949219" xlink:href="#DejaVuSans-103"/> + <use x="186.425781" xlink:href="#DejaVuSans-104"/> + <use x="249.804688" xlink:href="#DejaVuSans-32"/> + <use x="281.591797" xlink:href="#DejaVuSans-116"/> + <use x="320.800781" xlink:href="#DejaVuSans-114"/> + <use x="361.914062" xlink:href="#DejaVuSans-97"/> + <use x="423.193359" xlink:href="#DejaVuSans-110"/> + <use x="486.572266" xlink:href="#DejaVuSans-115"/> + <use x="538.671875" xlink:href="#DejaVuSans-108"/> + <use x="566.455078" xlink:href="#DejaVuSans-97"/> + <use x="627.734375" xlink:href="#DejaVuSans-116"/> + <use x="666.943359" xlink:href="#DejaVuSans-111"/> + <use x="728.125" xlink:href="#DejaVuSans-114"/> + <use x="769.238281" xlink:href="#DejaVuSans-121"/> + <use x="828.417969" xlink:href="#DejaVuSans-32"/> + <use x="860.205078" xlink:href="#DejaVuSans-117"/> + <use x="923.583984" xlink:href="#DejaVuSans-110"/> + <use x="986.962891" xlink:href="#DejaVuSans-99"/> + <use x="1041.943359" xlink:href="#DejaVuSans-101"/> + <use x="1103.466797" xlink:href="#DejaVuSans-114"/> + <use x="1144.580078" xlink:href="#DejaVuSans-116"/> + <use x="1183.789062" xlink:href="#DejaVuSans-97"/> + <use x="1245.068359" xlink:href="#DejaVuSans-105"/> + <use x="1272.851562" xlink:href="#DejaVuSans-110"/> + <use x="1336.230469" xlink:href="#DejaVuSans-116"/> + <use x="1375.439453" xlink:href="#DejaVuSans-121"/> + </g> + </g> + </g> + <g id="axes_4"> + <g id="patch_25"> + <path d="M 430.06616 667.70192 +L 697.326568 667.70192 +L 697.326568 400.441512 +L 430.06616 400.441512 +z +" style="fill:#ffffff;"/> + </g> + <g id="patch_26"> + <path clip-path="url(#pab0c3ad644)" d="M 493.540507 634.294369 +L 483.518241 637.635124 +L 483.518241 634.327777 +L 443.42918 634.327777 +L 443.42918 634.260961 +L 483.518241 634.260961 +L 483.518241 630.953614 +z +" style="fill:#0000ff;opacity:0.5;stroke:#0000ff;stroke-linejoin:miter;"/> + </g> + <g id="patch_27"> + <path clip-path="url(#pab0c3ad644)" d="M 648.387779 516.849788 +L 645.783874 527.088251 +L 643.000837 525.301283 +L 621.340625 559.035065 +L 621.284402 558.998965 +L 642.944614 525.265183 +L 640.161577 523.478215 +z +" style="fill:#0000ff;opacity:0.5;stroke:#0000ff;stroke-linejoin:miter;"/> + </g> + <g id="matplotlib.axis_7"> + <g id="xtick_13"> + <g id="line2d_44"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="463.473711" xlink:href="#m49a95e4598" y="667.70192"/> + </g> + </g> + <g id="text_49"> + <!-- 0 --> + <g transform="translate(459.338086 684.579889)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="xtick_14"> + <g id="line2d_45"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="530.288813" xlink:href="#m49a95e4598" y="667.70192"/> + </g> + </g> + <g id="text_50"> + <!-- 1 --> + <g transform="translate(526.153188 684.579889)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-49"/> + </g> + </g> + </g> + <g id="xtick_15"> + <g id="line2d_46"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="597.103915" xlink:href="#m49a95e4598" y="667.70192"/> + </g> + </g> + <g id="text_51"> + <!-- 2 --> + <g transform="translate(592.96829 684.579889)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-50"/> + </g> + </g> + </g> + <g id="xtick_16"> + <g id="line2d_47"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="663.919017" xlink:href="#m49a95e4598" y="667.70192"/> + </g> + </g> + <g id="text_52"> + <!-- 3 --> + <g transform="translate(659.783392 684.579889)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-51"/> + </g> + </g> + </g> + <g id="text_53"> + <!-- x --> + <g transform="translate(559.849176 701.161451)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-120"/> + </g> + </g> + </g> + <g id="matplotlib.axis_8"> + <g id="ytick_28"> + <g id="line2d_48"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="430.06616" xlink:href="#m392a87831e" y="667.70192"/> + </g> + </g> + <g id="text_54"> + <!-- −0.5 --> + <g transform="translate(391.498503 672.640904)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-8722"/> + <use x="83.789062" xlink:href="#DejaVuSans-48"/> + <use x="147.412109" xlink:href="#DejaVuSans-46"/> + <use x="179.199219" xlink:href="#DejaVuSans-53"/> + </g> + </g> + </g> + <g id="ytick_29"> + <g id="line2d_49"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="430.06616" xlink:href="#m392a87831e" y="634.294369"/> + </g> + </g> + <g id="text_55"> + <!-- 0.0 --> + <g transform="translate(402.392097 639.233353)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-48"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="ytick_30"> + <g id="line2d_50"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="430.06616" xlink:href="#m392a87831e" y="600.886818"/> + </g> + </g> + <g id="text_56"> + <!-- 0.5 --> + <g transform="translate(402.392097 605.825802)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-48"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-53"/> + </g> + </g> + </g> + <g id="ytick_31"> + <g id="line2d_51"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="430.06616" xlink:href="#m392a87831e" y="567.479267"/> + </g> + </g> + <g id="text_57"> + <!-- 1.0 --> + <g transform="translate(402.392097 572.418251)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-49"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="ytick_32"> + <g id="line2d_52"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="430.06616" xlink:href="#m392a87831e" y="534.071716"/> + </g> + </g> + <g id="text_58"> + <!-- 1.5 --> + <g transform="translate(402.392097 539.0107)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-49"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-53"/> + </g> + </g> + </g> + <g id="ytick_33"> + <g id="line2d_53"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="430.06616" xlink:href="#m392a87831e" y="500.664165"/> + </g> + </g> + <g id="text_59"> + <!-- 2.0 --> + <g transform="translate(402.392097 505.603149)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-50"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="ytick_34"> + <g id="line2d_54"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="430.06616" xlink:href="#m392a87831e" y="467.256614"/> + </g> + </g> + <g id="text_60"> + <!-- 2.5 --> + <g transform="translate(402.392097 472.195598)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-50"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-53"/> + </g> + </g> + </g> + <g id="ytick_35"> + <g id="line2d_55"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="430.06616" xlink:href="#m392a87831e" y="433.849063"/> + </g> + </g> + <g id="text_61"> + <!-- 3.0 --> + <g transform="translate(402.392097 438.788047)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-51"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-48"/> + </g> + </g> + </g> + <g id="ytick_36"> + <g id="line2d_56"> + <g> + <use style="stroke:#000000;stroke-width:0.8;" x="430.06616" xlink:href="#m392a87831e" y="400.441512"/> + </g> + </g> + <g id="text_62"> + <!-- 3.5 --> + <g transform="translate(402.392097 405.380496)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-51"/> + <use x="63.623047" xlink:href="#DejaVuSans-46"/> + <use x="95.410156" xlink:href="#DejaVuSans-53"/> + </g> + </g> + </g> + <g id="text_63"> + <!-- y --> + <g transform="translate(384.79491 537.918903)rotate(-90)scale(0.13 -0.13)"> + <use xlink:href="#DejaVuSans-121"/> + </g> + </g> + </g> + <g id="line2d_57"> + <g clip-path="url(#pab0c3ad644)"> + <use style="stroke:#000000;" x="637.197834" xlink:href="#m5fb0882079" y="552.724718"/> + <use style="stroke:#000000;" x="624.239224" xlink:href="#m5fb0882079" y="527.823504"/> + <use style="stroke:#000000;" x="631.983901" xlink:href="#m5fb0882079" y="538.860704"/> + <use style="stroke:#000000;" x="628.011798" xlink:href="#m5fb0882079" y="534.562182"/> + <use style="stroke:#000000;" x="623.365141" xlink:href="#m5fb0882079" y="536.342315"/> + <use style="stroke:#000000;" x="629.97094" xlink:href="#m5fb0882079" y="541.866578"/> + <use style="stroke:#000000;" x="612.408224" xlink:href="#m5fb0882079" y="508.769603"/> + <use style="stroke:#000000;" x="641.640148" xlink:href="#m5fb0882079" y="560.611183"/> + <use style="stroke:#000000;" x="646.644518" xlink:href="#m5fb0882079" y="572.774894"/> + <use style="stroke:#000000;" x="639.674884" xlink:href="#m5fb0882079" y="563.318231"/> + <use style="stroke:#000000;" x="636.437031" xlink:href="#m5fb0882079" y="548.755098"/> + <use style="stroke:#000000;" x="628.672653" xlink:href="#m5fb0882079" y="534.381944"/> + <use style="stroke:#000000;" x="641.741136" xlink:href="#m5fb0882079" y="562.814251"/> + <use style="stroke:#000000;" x="634.817815" xlink:href="#m5fb0882079" y="546.795488"/> + <use style="stroke:#000000;" x="621.98077" xlink:href="#m5fb0882079" y="523.414998"/> + <use style="stroke:#000000;" x="613.698272" xlink:href="#m5fb0882079" y="515.497316"/> + <use style="stroke:#000000;" x="618.745899" xlink:href="#m5fb0882079" y="519.257361"/> + <use style="stroke:#000000;" x="601.030608" xlink:href="#m5fb0882079" y="500.570507"/> + <use style="stroke:#000000;" x="634.652275" xlink:href="#m5fb0882079" y="546.695946"/> + <use style="stroke:#000000;" x="630.997862" xlink:href="#m5fb0882079" y="542.032832"/> + <use style="stroke:#000000;" x="613.775932" xlink:href="#m5fb0882079" y="513.56535"/> + <use style="stroke:#000000;" x="628.189456" xlink:href="#m5fb0882079" y="539.380891"/> + <use style="stroke:#000000;" x="637.299926" xlink:href="#m5fb0882079" y="562.109719"/> + <use style="stroke:#000000;" x="640.143427" xlink:href="#m5fb0882079" y="554.379549"/> + <use style="stroke:#000000;" x="608.830598" xlink:href="#m5fb0882079" y="506.451424"/> + <use style="stroke:#000000;" x="627.550643" xlink:href="#m5fb0882079" y="537.508224"/> + <use style="stroke:#000000;" x="640.85292" xlink:href="#m5fb0882079" y="561.80408"/> + <use style="stroke:#000000;" x="603.005769" xlink:href="#m5fb0882079" y="500.078296"/> + <use style="stroke:#000000;" x="630.27367" xlink:href="#m5fb0882079" y="543.548504"/> + <use style="stroke:#000000;" x="634.025621" xlink:href="#m5fb0882079" y="540.944531"/> + <use style="stroke:#000000;" x="617.644344" xlink:href="#m5fb0882079" y="523.120667"/> + <use style="stroke:#000000;" x="630.820312" xlink:href="#m5fb0882079" y="542.70736"/> + <use style="stroke:#000000;" x="629.098902" xlink:href="#m5fb0882079" y="533.123944"/> + <use style="stroke:#000000;" x="640.001772" xlink:href="#m5fb0882079" y="546.711432"/> + <use style="stroke:#000000;" x="622.916356" xlink:href="#m5fb0882079" y="526.959345"/> + <use style="stroke:#000000;" x="627.040548" xlink:href="#m5fb0882079" y="537.353806"/> + <use style="stroke:#000000;" x="610.971515" xlink:href="#m5fb0882079" y="511.069989"/> + <use style="stroke:#000000;" x="611.250801" xlink:href="#m5fb0882079" y="509.096122"/> + <use style="stroke:#000000;" x="609.679324" xlink:href="#m5fb0882079" y="506.748472"/> + <use style="stroke:#000000;" x="622.113672" xlink:href="#m5fb0882079" y="524.040426"/> + <use style="stroke:#000000;" x="630.132824" xlink:href="#m5fb0882079" y="538.998833"/> + <use style="stroke:#000000;" x="620.219869" xlink:href="#m5fb0882079" y="527.022866"/> + <use style="stroke:#000000;" x="637.244505" xlink:href="#m5fb0882079" y="543.911106"/> + <use style="stroke:#000000;" x="635.75135" xlink:href="#m5fb0882079" y="550.29334"/> + <use style="stroke:#000000;" x="641.621263" xlink:href="#m5fb0882079" y="572.213774"/> + <use style="stroke:#000000;" x="627.798543" xlink:href="#m5fb0882079" y="532.895285"/> + <use style="stroke:#000000;" x="638.436229" xlink:href="#m5fb0882079" y="547.308553"/> + <use style="stroke:#000000;" x="644.628543" xlink:href="#m5fb0882079" y="568.686659"/> + <use style="stroke:#000000;" x="622.976861" xlink:href="#m5fb0882079" y="532.662413"/> + <use style="stroke:#000000;" x="635.593103" xlink:href="#m5fb0882079" y="548.709922"/> + <use style="stroke:#000000;" x="615.559639" xlink:href="#m5fb0882079" y="519.109201"/> + <use style="stroke:#000000;" x="628.950436" xlink:href="#m5fb0882079" y="539.731039"/> + <use style="stroke:#000000;" x="641.844211" xlink:href="#m5fb0882079" y="564.521163"/> + <use style="stroke:#000000;" x="642.899271" xlink:href="#m5fb0882079" y="564.422142"/> + <use style="stroke:#000000;" x="637.453393" xlink:href="#m5fb0882079" y="556.48229"/> + <use style="stroke:#000000;" x="632.32175" xlink:href="#m5fb0882079" y="540.887759"/> + <use style="stroke:#000000;" x="631.193485" xlink:href="#m5fb0882079" y="537.694997"/> + <use style="stroke:#000000;" x="614.954589" xlink:href="#m5fb0882079" y="524.702536"/> + <use style="stroke:#000000;" x="643.439996" xlink:href="#m5fb0882079" y="563.451186"/> + <use style="stroke:#000000;" x="615.318466" xlink:href="#m5fb0882079" y="514.521252"/> + <use style="stroke:#000000;" x="650.752422" xlink:href="#m5fb0882079" y="583.367074"/> + <use style="stroke:#000000;" x="620.449624" xlink:href="#m5fb0882079" y="524.369182"/> + <use style="stroke:#000000;" x="633.082172" xlink:href="#m5fb0882079" y="544.527999"/> + <use style="stroke:#000000;" x="623.026029" xlink:href="#m5fb0882079" y="528.516259"/> + <use style="stroke:#000000;" x="637.036291" xlink:href="#m5fb0882079" y="552.807681"/> + <use style="stroke:#000000;" x="632.456173" xlink:href="#m5fb0882079" y="540.210748"/> + <use style="stroke:#000000;" x="620.038536" xlink:href="#m5fb0882079" y="524.585663"/> + <use style="stroke:#000000;" x="637.524504" xlink:href="#m5fb0882079" y="548.303595"/> + <use style="stroke:#000000;" x="636.296425" xlink:href="#m5fb0882079" y="545.048551"/> + <use style="stroke:#000000;" x="627.217161" xlink:href="#m5fb0882079" y="529.023982"/> + <use style="stroke:#000000;" x="626.964159" xlink:href="#m5fb0882079" y="529.073747"/> + <use style="stroke:#000000;" x="646.367987" xlink:href="#m5fb0882079" y="575.529751"/> + <use style="stroke:#000000;" x="643.820362" xlink:href="#m5fb0882079" y="562.359522"/> + <use style="stroke:#000000;" x="623.095492" xlink:href="#m5fb0882079" y="533.033861"/> + <use style="stroke:#000000;" x="603.268848" xlink:href="#m5fb0882079" y="502.04617"/> + <use style="stroke:#000000;" x="630.590562" xlink:href="#m5fb0882079" y="538.677113"/> + <use style="stroke:#000000;" x="642.586423" xlink:href="#m5fb0882079" y="556.918131"/> + <use style="stroke:#000000;" x="630.017363" xlink:href="#m5fb0882079" y="542.463209"/> + <use style="stroke:#000000;" x="635.644365" xlink:href="#m5fb0882079" y="553.795694"/> + <use style="stroke:#000000;" x="636.301119" xlink:href="#m5fb0882079" y="543.400916"/> + <use style="stroke:#000000;" x="630.043627" xlink:href="#m5fb0882079" y="536.871335"/> + <use style="stroke:#000000;" x="644.419725" xlink:href="#m5fb0882079" y="557.814692"/> + <use style="stroke:#000000;" x="611.534266" xlink:href="#m5fb0882079" y="511.522129"/> + <use style="stroke:#000000;" x="615.005946" xlink:href="#m5fb0882079" y="514.231466"/> + <use style="stroke:#000000;" x="636.500919" xlink:href="#m5fb0882079" y="549.185733"/> + <use style="stroke:#000000;" x="631.396284" xlink:href="#m5fb0882079" y="538.566661"/> + <use style="stroke:#000000;" x="636.48075" xlink:href="#m5fb0882079" y="541.90916"/> + <use style="stroke:#000000;" x="642.742011" xlink:href="#m5fb0882079" y="560.357532"/> + <use style="stroke:#000000;" x="640.428411" xlink:href="#m5fb0882079" y="558.172411"/> + <use style="stroke:#000000;" x="632.176978" xlink:href="#m5fb0882079" y="541.248343"/> + <use style="stroke:#000000;" x="642.804023" xlink:href="#m5fb0882079" y="569.630161"/> + <use style="stroke:#000000;" x="643.986426" xlink:href="#m5fb0882079" y="565.098747"/> + <use style="stroke:#000000;" x="636.927348" xlink:href="#m5fb0882079" y="552.317685"/> + <use style="stroke:#000000;" x="632.130736" xlink:href="#m5fb0882079" y="541.125857"/> + <use style="stroke:#000000;" x="626.124885" xlink:href="#m5fb0882079" y="532.780199"/> + <use style="stroke:#000000;" x="589.041684" xlink:href="#m5fb0882079" y="487.446853"/> + <use style="stroke:#000000;" x="642.605596" xlink:href="#m5fb0882079" y="563.259351"/> + <use style="stroke:#000000;" x="647.018975" xlink:href="#m5fb0882079" y="581.469391"/> + <use style="stroke:#000000;" x="632.075243" xlink:href="#m5fb0882079" y="545.194799"/> + <use style="stroke:#000000;" x="629.274596" xlink:href="#m5fb0882079" y="536.388993"/> + </g> + </g> + <g id="line2d_58"> + <path clip-path="url(#pab0c3ad644)" d="M 463.473711 634.294369 +L 632.14262 542.150124 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-width:0.5;"/> + </g> + <g id="patch_28"> + <path d="M 430.06616 667.70192 +L 430.06616 400.441512 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/> + </g> + <g id="patch_29"> + <path d="M 697.326568 667.70192 +L 697.326568 400.441512 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/> + </g> + <g id="patch_30"> + <path d="M 430.06616 667.70192 +L 697.326568 667.70192 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/> + </g> + <g id="patch_31"> + <path d="M 430.06616 400.441512 +L 697.326568 400.441512 +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/> + </g> + <g id="text_64"> + <!-- Odometry Motion Model --> + <g transform="translate(469.731957 376.972924)scale(0.156 -0.156)"> + <use xlink:href="#DejaVuSans-79"/> + <use x="78.710938" xlink:href="#DejaVuSans-100"/> + <use x="142.1875" xlink:href="#DejaVuSans-111"/> + <use x="203.369141" xlink:href="#DejaVuSans-109"/> + <use x="300.78125" xlink:href="#DejaVuSans-101"/> + <use x="362.304688" xlink:href="#DejaVuSans-116"/> + <use x="401.513672" xlink:href="#DejaVuSans-114"/> + <use x="442.626953" xlink:href="#DejaVuSans-121"/> + <use x="501.806641" xlink:href="#DejaVuSans-32"/> + <use x="533.59375" xlink:href="#DejaVuSans-77"/> + <use x="619.873047" xlink:href="#DejaVuSans-111"/> + <use x="681.054688" xlink:href="#DejaVuSans-116"/> + <use x="720.263672" xlink:href="#DejaVuSans-105"/> + <use x="748.046875" xlink:href="#DejaVuSans-111"/> + <use x="809.228516" xlink:href="#DejaVuSans-110"/> + <use x="872.607422" xlink:href="#DejaVuSans-32"/> + <use x="904.394531" xlink:href="#DejaVuSans-77"/> + <use x="990.673828" xlink:href="#DejaVuSans-111"/> + <use x="1051.855469" xlink:href="#DejaVuSans-100"/> + <use x="1115.332031" xlink:href="#DejaVuSans-101"/> + <use x="1176.855469" xlink:href="#DejaVuSans-108"/> + </g> + <!-- high rotatory uncertainty --> + <g transform="translate(462.98252 394.441512)scale(0.156 -0.156)"> + <use xlink:href="#DejaVuSans-32"/> + <use x="31.787109" xlink:href="#DejaVuSans-104"/> + <use x="95.166016" xlink:href="#DejaVuSans-105"/> + <use x="122.949219" xlink:href="#DejaVuSans-103"/> + <use x="186.425781" xlink:href="#DejaVuSans-104"/> + <use x="249.804688" xlink:href="#DejaVuSans-32"/> + <use x="281.591797" xlink:href="#DejaVuSans-114"/> + <use x="322.673828" xlink:href="#DejaVuSans-111"/> + <use x="383.855469" xlink:href="#DejaVuSans-116"/> + <use x="423.064453" xlink:href="#DejaVuSans-97"/> + <use x="484.34375" xlink:href="#DejaVuSans-116"/> + <use x="523.552734" xlink:href="#DejaVuSans-111"/> + <use x="584.734375" xlink:href="#DejaVuSans-114"/> + <use x="625.847656" xlink:href="#DejaVuSans-121"/> + <use x="685.027344" xlink:href="#DejaVuSans-32"/> + <use x="716.814453" xlink:href="#DejaVuSans-117"/> + <use x="780.193359" xlink:href="#DejaVuSans-110"/> + <use x="843.572266" xlink:href="#DejaVuSans-99"/> + <use x="898.552734" xlink:href="#DejaVuSans-101"/> + <use x="960.076172" xlink:href="#DejaVuSans-114"/> + <use x="1001.189453" xlink:href="#DejaVuSans-116"/> + <use x="1040.398438" xlink:href="#DejaVuSans-97"/> + <use x="1101.677734" xlink:href="#DejaVuSans-105"/> + <use x="1129.460938" xlink:href="#DejaVuSans-110"/> + <use x="1192.839844" xlink:href="#DejaVuSans-116"/> + <use x="1232.048828" xlink:href="#DejaVuSans-121"/> + </g> + </g> + </g> + </g> + <defs> + <clipPath id="p7ed90a7c9b"> + <rect height="267.260408" width="267.260408" x="77.495251" y="48.167472"/> + </clipPath> + <clipPath id="p9ff03703d7"> + <rect height="267.260408" width="267.260408" x="430.06616" y="48.167472"/> + </clipPath> + <clipPath id="p0f820d4006"> + <rect height="267.260408" width="267.260408" x="77.495251" y="400.441512"/> + </clipPath> + <clipPath id="pab0c3ad644"> + <rect height="267.260408" width="267.260408" x="430.06616" y="400.441512"/> + </clipPath> + </defs> +</svg> diff --git a/latex_and_figures/figs/ch_robotmodel/odo_motion_model_geo.ggb b/latex_and_figures/figs/ch_robotmodel/odo_motion_model_geo.ggb new file mode 100644 index 0000000000000000000000000000000000000000..3738da4afd4188582237a40c4e1a989bc8d8193f Binary files /dev/null and b/latex_and_figures/figs/ch_robotmodel/odo_motion_model_geo.ggb differ diff --git a/latex_and_figures/figs/ch_robotmodel/odo_motion_model_geo.png b/latex_and_figures/figs/ch_robotmodel/odo_motion_model_geo.png new file mode 100644 index 0000000000000000000000000000000000000000..8e085bfa57eb356be052e1a903b5721473748ecf Binary files /dev/null and b/latex_and_figures/figs/ch_robotmodel/odo_motion_model_geo.png differ diff --git a/latex_and_figures/figs/ch_robotmodel/odo_motion_model_geo.txt b/latex_and_figures/figs/ch_robotmodel/odo_motion_model_geo.txt new file mode 100644 index 0000000000000000000000000000000000000000..eff1b2bc3ca7d3906f784c93fbd78a156b33d611 --- /dev/null +++ b/latex_and_figures/figs/ch_robotmodel/odo_motion_model_geo.txt @@ -0,0 +1,33 @@ +\documentclass[10pt]{article} +\usepackage{pgfplots} +\pgfplotsset{compat=1.15} +\usepackage{mathrsfs} +\usetikzlibrary{arrows} +\pagestyle{empty} +\begin{document} +\definecolor{qqwuqq}{rgb}{0,0.39215686274509803,0} +\definecolor{qqqqff}{rgb}{0,0,1} +\definecolor{ududff}{rgb}{0.30196078431372547,0.30196078431372547,1} +\definecolor{cqcqcq}{rgb}{0.7529411764705882,0.7529411764705882,0.7529411764705882} +\begin{tikzpicture}[line cap=round,line join=round,>=triangle 45,x=1cm,y=1cm] +\draw [color=cqcqcq,, xstep=0.5cm,ystep=0.5cm] (-4.8658753823317715,-2.733563528320184) grid (6.943997768851088,6.090517765227268); +\clip(-4.8658753823317715,-2.733563528320184) rectangle (6.943997768851088,6.090517765227268); +\draw [shift={(-2.779834710743806,-0.9641322314049579)},line width=2pt,color=qqwuqq,fill=qqwuqq,fill opacity=0.10000000149011612] (0,0) -- (-5.974323286480479:0.6664713967936151) arc (-5.974323286480479:34.9527630758816:0.6664713967936151) -- cycle; +\draw [shift={(3.6995041322313993,3.564793388429755)},line width=2pt,color=qqwuqq,fill=qqwuqq,fill opacity=0.10000000149011612] (0,0) -- (34.9527630758816:0.6664713967936151) arc (34.9527630758816:92.04540848888722:0.6664713967936151) -- cycle; +\draw [->,line width=2pt] (-2.779834710743806,-0.9641322314049579) -- (3.6995041322313993,3.564793388429755); +\draw [->,line width=2pt,color=qqqqff] (-2.779834710743806,-0.9641322314049579) -- (-1.3583471074380211,-1.1128925619834666); +\draw [->,line width=2pt,color=qqqqff] (3.6995041322313993,3.564793388429755) -- (3.6499173553718953,4.953223140495877); +\draw [line width=0.8pt,domain=-4.8658753823317715:6.943997768851088] plot(\x,{(--6.34272522368694--4.5289256198347125*\x)/6.4793388429752055}); +\draw [shift={(-2.779834710743806,-0.9641322314049579)},->,line width=2pt,color=qqwuqq] (-5.974323286480479:0.6664713967936151) arc (-5.974323286480479:34.9527630758816:0.6664713967936151); +\draw [shift={(3.6995041322313993,3.564793388429755)},->,line width=2pt,color=qqwuqq] (34.9527630758816:0.6664713967936151) arc (34.9527630758816:92.04540848888722:0.6664713967936151); +\begin{scriptsize} +\draw [fill=ududff] (-2.779834710743806,-0.9641322314049579) circle (2.5pt); +\draw[color=ududff] (-2.953102473534096,-0.8841054022179045) node {(x,y)}; +\draw [fill=ududff] (3.6995041322313993,3.564793388429755) circle (2.5pt); +\draw[color=ududff] (3.94487648327982,3.4879469607482045) node {(x',y')}; +\draw[color=black] (0.7591432066063398,1.3285796351368946) node {$$\delta$_{trans}$}; +\draw[color=qqwuqq] (-1.983386591199386,-0.7574758368271177) node {$$\delta$_{rot1}$}; +\draw[color=qqwuqq] (4.174809115173617,4.2543890670608615) node {$$\delta$_{rot2}$}; +\end{scriptsize} +\end{tikzpicture} +\end{document} \ No newline at end of file diff --git a/latex_and_figures/figs/ch_robotmodel/vel_motion_model_geo.ggb b/latex_and_figures/figs/ch_robotmodel/vel_motion_model_geo.ggb new file mode 100644 index 0000000000000000000000000000000000000000..ff249e62aa923d7f72a8412c40964e068dfced4e Binary files /dev/null and b/latex_and_figures/figs/ch_robotmodel/vel_motion_model_geo.ggb differ diff --git a/latex_and_figures/figs/ch_robotmodel/vel_motion_model_geo.txt b/latex_and_figures/figs/ch_robotmodel/vel_motion_model_geo.txt new file mode 100644 index 0000000000000000000000000000000000000000..5af10579c06baac1c1f8befeda142bd4e2b5e3df --- /dev/null +++ b/latex_and_figures/figs/ch_robotmodel/vel_motion_model_geo.txt @@ -0,0 +1,38 @@ +\documentclass[10pt]{article} +\usepackage{pgfplots} +\pgfplotsset{compat=1.15} +\usepackage{mathrsfs} +\usetikzlibrary{arrows} +\pagestyle{empty} +\newcommand{\degre}{\ensuremath{^\circ}} +\begin{document} +\definecolor{qqqqff}{rgb}{0,0,1} +\definecolor{qqwuqq}{rgb}{0,0.39215686274509803,0} +\definecolor{ududff}{rgb}{0.30196078431372547,0.30196078431372547,1} +\begin{tikzpicture}[line cap=round,line join=round,>=triangle 45,x=1cm,y=1cm] +\clip(-6.433807693467152,-6.137003967258573) rectangle (9.996539691798784,4.201674152451818); +\draw [shift={(-3.42,-2.6)},line width=2pt,color=qqwuqq,fill=qqwuqq,fill opacity=0.10000000149011612] (0,0) -- (11.639688715129786:0.965229285035205) arc (11.639688715129786:77.53937446355862:0.965229285035205) -- cycle; +\draw [shift={(2.1465917602996245,-2.6)},line width=2pt,color=qqwuqq,fill=qqwuqq,fill opacity=0.10000000149011612] (0,0) -- (0:1.0724769833724501) arc (0:101.63968871512975:1.0724769833724501) -- cycle; +\draw[line width=2pt,color=qqwuqq,fill=qqwuqq,fill opacity=0.10000000149011612] (1.6971717858387136,-1.5459009429920252) -- (1.743072728830739,-1.7687291571533115) -- (1.9659009429920251,-1.7228282141612863) -- (1.92,-1.5) -- cycle; +\draw [shift={(-3.42,-2.6)},line width=2pt,color=qqwuqq,fill=qqwuqq,fill opacity=0.10000000149011612] (0,0) -- (0:1.0724769833724501) arc (0:11.639688715129784:1.0724769833724501) -- cycle; +\draw[line width=2pt,color=qqwuqq,fill=qqwuqq,fill opacity=0.10000000149011612] (1.92,-2.3724932757172548) -- (1.6924932757172544,-2.3724932757172548) -- (1.6924932757172544,-2.6) -- (1.92,-2.6) -- cycle; +\draw [shift={(-3.42,-2.6)},line width=2pt] (0,0) -- plot[domain=0.2031508919862431:1.3533173843259099,variable=\t]({1*5.452118854170367*cos(\t r)+0*5.452118854170367*sin(\t r)},{0*5.452118854170367*cos(\t r)+1*5.452118854170367*sin(\t r)}) -- cycle ; +\draw [line width=0.8pt,domain=-6.433807693467152:9.996539691798784] plot(\x,{(--8.6028-5.34*\x)/1.1}); +\draw [->,line width=2pt,color=qqqqff] (1.92,-1.5) -- (1.3686678149473854,1.1764671528917834); +\draw [line width=0.8pt,domain=-6.433807693467152:9.996539691798784] plot(\x,{(-2.6-0*\x)/1}); +\draw [line width=0.8pt] (1.92,-6.137003967258573) -- (1.92,4.201674152451818); +\draw (-0.4064870469139822,-1.6754997164291923) node[anchor=north west] {r}; +\begin{scriptsize} +\draw [fill=ududff] (-3.42,-2.6) circle (2.5pt); +\draw[color=ududff] (-3.2968125171027354,-2.587105152295772) node {$(x_c,y_c)$}; +\draw [fill=ududff] (1.92,-1.5) circle (2.5pt); +\draw[color=ududff] (2.2586182567665567,-1.2304217683296266) node {(x,y)}; +\draw [fill=ududff] (-2.24,2.74) circle (2.5pt); +\draw[color=ududff] (-1.7846199705475807,3.016587085825264) node {(x',y')}; +\draw[color=qqwuqq] (-2.2886841527326323,-2.0884033550275842) node {$\omega$$\Delta$t}; +\draw[color=qqqqff] (1.7652788444152294,0.04582584188358553) node {v}; +\draw[color=qqwuqq] (2.660797125531225,-2.2278253628660023) node {$\theta$}; +\draw[color=qqwuqq] (-1.6237484230417132,-2.377972140538145) node {90\textrm{\degre}- $\theta$}; +\end{scriptsize} +\end{tikzpicture} +\end{document} \ No newline at end of file diff --git a/latex_and_figures/figs/robotimg/RobotCorridorExploration_end.jpg b/latex_and_figures/figs/robotimg/RobotCorridorExploration_end.jpg new file mode 100644 index 0000000000000000000000000000000000000000..22750c8633da2f2a496aadc650fdc9ec520f5d50 Binary files /dev/null and b/latex_and_figures/figs/robotimg/RobotCorridorExploration_end.jpg differ diff --git a/latex_and_figures/figs/robotimg/arduinobordandpower.jpg b/latex_and_figures/figs/robotimg/arduinobordandpower.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1ed06253120c948369ad9bdbbbbc413549c3ff6f Binary files /dev/null and b/latex_and_figures/figs/robotimg/arduinobordandpower.jpg differ diff --git a/latex_and_figures/figs/robotimg/bad_localmap_robot.png b/latex_and_figures/figs/robotimg/bad_localmap_robot.png new file mode 100644 index 0000000000000000000000000000000000000000..e97853fb73faff6cb7828bd427cfe5831c0f57ed Binary files /dev/null and b/latex_and_figures/figs/robotimg/bad_localmap_robot.png differ diff --git a/latex_and_figures/figs/robotimg/bad_localmap_robot2.png b/latex_and_figures/figs/robotimg/bad_localmap_robot2.png new file mode 100644 index 0000000000000000000000000000000000000000..ec7980b17fdea0645a9a89db6354d5446084cf29 Binary files /dev/null and b/latex_and_figures/figs/robotimg/bad_localmap_robot2.png differ diff --git a/latex_and_figures/figs/robotimg/completerobot.jpg b/latex_and_figures/figs/robotimg/completerobot.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f6d49e5cfd27c9ae92e10e85c9cc9980ab2efb8f Binary files /dev/null and b/latex_and_figures/figs/robotimg/completerobot.jpg differ diff --git a/latex_and_figures/figs/robotimg/losfiguros.png b/latex_and_figures/figs/robotimg/losfiguros.png new file mode 100644 index 0000000000000000000000000000000000000000..8e36b5cd8f9df2535a8eb80a7bd9f1b3bbc67948 Binary files /dev/null and b/latex_and_figures/figs/robotimg/losfiguros.png differ diff --git a/latex_and_figures/figs/robotimg/robotmotor.jpg b/latex_and_figures/figs/robotimg/robotmotor.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6aadbd64464556f791d98d0e173eb687bc45df5e Binary files /dev/null and b/latex_and_figures/figs/robotimg/robotmotor.jpg differ diff --git a/latex_and_figures/figs/robotimg/robotmotordark.jpg b/latex_and_figures/figs/robotimg/robotmotordark.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c340e3c83055b6cbd1ff715a21ac41a69414db32 Binary files /dev/null and b/latex_and_figures/figs/robotimg/robotmotordark.jpg differ diff --git a/latex_and_figures/figs/robotimg/steppermotors.jpg b/latex_and_figures/figs/robotimg/steppermotors.jpg new file mode 100644 index 0000000000000000000000000000000000000000..5f22271a5141653ebbb40607e104663c80e9f0d3 Binary files /dev/null and b/latex_and_figures/figs/robotimg/steppermotors.jpg differ