{"id":1076,"date":"2016-06-21T20:38:21","date_gmt":"2016-06-22T02:38:21","guid":{"rendered":"http:\/\/agiltools.com\/blogsp\/?p=1076"},"modified":"2016-06-21T20:38:21","modified_gmt":"2016-06-22T02:38:21","slug":"agentes_con_rango_al","status":"publish","type":"post","link":"https:\/\/agiltools.com\/blogsp\/agentes_con_rango_al\/","title":{"rendered":"C\u00f3mo crear agentes con rangos de visi\u00f3n en AnyLogic"},"content":{"rendered":"<div id=\"dslc-theme-content\"><div id=\"dslc-theme-content-inner\"><p><img loading=\"lazy\" class=\"aligncenter size-full wp-image-1075\" src=\"http:\/\/agiltools.com\/blogsp\/wp-content\/uploads\/2016\/06\/bulldozer.jpg\" alt=\"bulldozer\" width=\"668\" height=\"466\" srcset=\"https:\/\/agiltools.com\/blogsp\/wp-content\/uploads\/2016\/06\/bulldozer.jpg 668w, https:\/\/agiltools.com\/blogsp\/wp-content\/uploads\/2016\/06\/bulldozer-300x209.jpg 300w\" sizes=\"(max-width: 668px) 100vw, 668px\" \/><\/p>\n<script type=\"text\/javascript\"> jQuery(document).ready(function() { jQuery(\"#ffs-tabbed-1\").easyResponsiveTabs({     type: \t\"default\",     width:  \"100%\",     fit: \t false}); var cont_width = jQuery(\"#ffs-tabbed-1.resp-vtabs\").outerWidth() - jQuery(\"#ffs-tabbed-1.resp-vtabs .resp-tabs-list\").outerWidth() - 3;jQuery(\"#ffs-tabbed-1.resp-vtabs .resp-tabs-container\").css({\"width\":cont_width});}); <\/script><style type=\"text\/css\">\n#ffs-tabbed-1 li.resp-tab-active,\n#ffs-tabbed-1.resp-tabs-list li:hover{border-top-color:#71AFFF; border-bottom-color:#71AFFF;}\n#ffs-tabbed-1.resp-vtabs li.resp-tab-active,\n#ffs-tabbed-1.resp-vtabs .resp-tabs-list li:hover{border-left-color:#71AFFF; border-top-color:#C1C1C1; border-right-color:#71AFFF;  border-bottom-color:#C1C1C1;}\n<\/style><div id=\"ffs-tabbed-1\" class=\"ffs-tabbed-nav\"><ul class=\"resp-tabs-list\"><li>Contexto<\/li><li>Modelo<\/li><li>Video<\/li><li>Descarga<\/li><\/ul><div class=\"resp-tabs-container\">\n<div class=\"fruitful_tab tab-contexto\"><\/p>\n<p>Con frecuencia\u00a0se desea limitar el movimiento e iteraci\u00f3n de los agentes a solo aquellos elementos que caen dentro un rango de visi\u00f3n limitado. Este modelo es una demostraci\u00f3n de c\u00f3mo se pueden crear rangos de visi\u00f3n\u00a0a los agentes en un espacio determinado.<\/p>\n<p>En este modelo se asumen agentes representando bulldozers esparcidos en un campo\u00a0donde hay diferentes minas a las que\u00a0los agentes deben trasladarse. Estos\u00a0agentes solo pueden identificar las minas que se encuentran en el rango de visi\u00f3n establecido.<\/p>\n<p><\/div>\n<div class=\"fruitful_tab tab-modelo\"><\/p>\n<p>El modelo cuenta con dos tipos de agentes: <strong>MyAgents<\/strong> y <strong>Mine<\/strong>.<\/p>\n<p>MyAgent representa el bulldozer cuya visi\u00f3n es limitada. La mina es el lugar donde el bulldozer debe desplazarse.<\/p>\n<p>Los agentes estan contenidos en dos poblaciones: <strong>myAgents<\/strong> y <strong>mines<\/strong>, ambas inician vac\u00edas al comienzo del modelo mediante la funci\u00f3n Setup. Esta crea los agentes, los ubica de manera aleatoria en el espacio y asigna par\u00e1metros. A continuaci\u00f3n se presenta la funci\u00f3n:<\/p>\n<pre class=\"lang:java decode:true\" title=\"Setup\">for(int i=0; i&lt;totAgents; i++){\r\n\tMyAgent m = add_myAgents();\r\n\tm.angleRange=angleRange;\r\n\tPoint p = rectangle.randomPointInside();\r\n\tm.setXY(p.getX(), p.getY());\r\n\tm.polyline.setPoint(1, 50, -50*Math.tan(m.angleRange\/57.2958));\r\n\tm.polyline.setPoint(2, 50, +50*Math.tan(m.angleRange\/57.2958));\r\n\tm.setRotation(uniform(-1, 1)*Math.PI);\r\n\tm.rot=m.getRotation()*57.2958;\r\n}\r\nfor(int i=0; i&lt;totMines; i++){\r\n\tMine m = add_mines();\r\n\tPoint p = rectangle.randomPointInside();\r\n\tm.setXY(p.getX(), p.getY());\r\n\tm.remaining=uniform(20, 140);\r\n}<\/pre>\n<p>El usuario cuenta con diferentes botones donde puede seleccionar agentes, rotarlo y obtener los agentes dentro del rango de visi\u00f3n frente a \u00e9l. Este rango de visi\u00f3n es determinado\u00a0por el \u00e1ngulo solamente\u00a0(cualquier agente con un \u00e1ngulo menor a una\u00a0referencia predeterminada\u00a0es aceptable. El usuario puede adem\u00e1s incluir la distancia como parte del rango de visi\u00f3n, es decir no solo considerar las minas que est\u00e9n dentro del \u00e1ngulo de visi\u00f3n frente a el sino tambi\u00e9n dentro de una distancia determinada).<\/p>\n<p>La selecci\u00f3n del agente se realiza utilizando el siguiente c\u00f3digo<\/p>\n<pre class=\"lang:java decode:true\" title=\"Get One\">for(MyAgent m:myAgents) {\r\n\tm.polyline.setFillColor(new Color(238, 232, 170, 107));\r\n\tm.view=false;\r\n\t}\r\ntextResults.get(0).setText(\"\");\r\ntextResults.get(1).setText(\"\");\r\nMyAgent m = myAgents.random();\r\nm.view=true;\r\ntextSelected.get(0).setText(\"Selected Bulldozer \" + m.getIndex());\r\ntextSelected.get(1).setText(\"Selected Bulldozer \" + m.getIndex());\r\nm.polyline.setFillColor(new Color(255, 160, 122, 107));\r\nagent=m;<\/pre>\n<p>El c\u00e1lculo del \u00e1ngulo y la distancia se hace en el siguiente c\u00f3digo<\/p>\n<pre class=\"lang:java decode:true\" title=\"Calc Range\">if(agent!=null){\r\n\ttextResults.get(0).setText(\"\");\r\n\ttextResults.get(1).setText(\"\");\r\n\tcollection.clear();\r\n\tdouble x1 = agent.getX();\r\n\tdouble y1 = agent.getY();\r\n\tint from = agent.getIndex();\r\n\tfor(Mine m: mines){\r\n\t\tdouble x2 = m.getX();\r\n\t\tdouble y2 = m.getY();\r\n\t\tint to = m.getIndex();\r\n\t\tdouble r = getAngleTo(m, agent);\r\n\t\tcollection.put(r, m);\r\n\t}\r\n\tIterator it = collection.keySet().iterator();\r\n\twhile (it.hasNext()) {\r\n\t\tdouble val = (double)it.next();\r\n\t\tif(val&lt;agent.angleRange) {\r\n\t\t\ttextResults.get(0).setText(textResults.get(0).getText() + \"\\nmine \" + collection.get(val).getIndex() + \" angle \" + val + \" distance \" + getDistanceTo(collection.get(val), agent));\r\n\t\t\ttextResults.get(1).setText(textResults.get(1).getText() + \"\\nmine \" + collection.get(val).getIndex() + \" angle \" + val + \" distance \" + getDistanceTo(collection.get(val), agent));\r\n\t\t}\r\n\t}\r\n}<\/pre>\n<p>Este c\u00f3digo hace uso de dos funciones: getAngleTo y getDistanceTo. A continuaci\u00f3n se presentan estas dos funciones:<\/p>\n<pre class=\"lang:java decode:true\" title=\"getAngleTo\">double x1 = a.getX();\r\ndouble y1 = a.getY();\r\ndouble x2 = m.getX();\r\ndouble y2 = m.getY();\r\ndouble r = Math.atan2(y2 - y1,x2 - x1)*57.2958-a.rot;\r\nif(r&lt;-180) r+=360.0;\r\nreturn abs(r);<\/pre>\n\n<pre class=\"lang:java decode:true\" title=\"getDistanceTo\">double x1 = a.getX();\r\ndouble y1 = a.getY();\r\ndouble x2 = m.getX();\r\ndouble y2 = m.getY();\r\ndouble r = getDistance(x1, y1, x2, y2);\r\nreturn r;<\/pre>\n<p>Existen adem\u00e1s botones para aumentar o reducir el \u00e1ngulo de rotaci\u00f3n de los bulldozers. El \u00e1ngulo del campo de visi\u00f3n puede ser ajustado usando un slider. El c\u00f3digo del slider se presenta a continuaci\u00f3n:<\/p>\n<pre class=\"lang:java decode:true\" title=\"slider\">for(MyAgent m:myAgents){\r\n\tm.angleRange=angleRange;\r\n\tm.polyline.setPoint(1, 50, -50*Math.tan(m.angleRange\/57.2958));\r\n\tm.polyline.setPoint(2, 50, +50*Math.tan(m.angleRange\/57.2958));\r\n}<\/pre>\n<h2><\/h2>\n<p><\/div><\/p>\n<p><div class=\"fruitful_tab tab-video\"><\/p>\n<p>El siguiente es un video del modelo en funcionamiento<\/p>\n<p><iframe width=\"560\" height=\"315\" src=\"https:\/\/www.youtube.com\/embed\/ts9azk_NScc\" frameborder=\"0\" allowfullscreen=\"allowfullscreen\"><\/iframe><\/p>\n<p><\/div>\n<div class=\"fruitful_tab tab-descarga\"><\/p>\n<p>El modelo en AnyLogic puede ser descargado en el siguiente <strong><a href=\"http:\/\/agiltools.com\/AnyLogic\/PLE%20Agents%20with%20range%20vision.zip\">Link<\/a><\/strong><\/p>\n\n<h3>Comentario Final<\/h3>\n<p>Como se ha podido observar el modelo no pretende hacer m\u00e1s que reportar las minas frente al agente que est\u00e1n dentro de su campo de visi\u00f3n. El usuario puede agregar utilizar este c\u00f3digo como base para agregar acciones m\u00e1s complejas como movimientos, ruteos e incluso algoritmos de decisi\u00f3n.<\/p>\n<p><\/div>\n<\/div><\/div><div class=\"clearfix\"><\/div>\n<p>No olviden dejar su comentario!<\/p>\n<div class=\"sharedaddy sd-sharing-enabled\"><div class=\"robots-nocontent sd-block sd-social sd-social-icon-text sd-sharing\"><div class=\"sd-content\"><ul><li class=\"share-twitter\"><a rel=\"nofollow noopener noreferrer\" data-shared=\"sharing-twitter-1076\" class=\"share-twitter sd-button share-icon\" href=\"https:\/\/agiltools.com\/blogsp\/agentes_con_rango_al\/?share=twitter\" target=\"_blank\" title=\"Click to share on Twitter\"><span>Twitter<\/span><\/a><\/li><li class=\"share-facebook\"><a rel=\"nofollow noopener noreferrer\" data-shared=\"sharing-facebook-1076\" class=\"share-facebook sd-button share-icon\" href=\"https:\/\/agiltools.com\/blogsp\/agentes_con_rango_al\/?share=facebook\" target=\"_blank\" title=\"Click to share on Facebook\"><span>Facebook<\/span><\/a><\/li><li class=\"share-end\"><\/li><\/ul><\/div><\/div><\/div><\/div><\/div>","protected":false},"excerpt":{"rendered":"<p>No olviden dejar su comentario!<\/p>\n<div class=\"sharedaddy sd-sharing-enabled\"><div class=\"robots-nocontent sd-block sd-social sd-social-icon-text sd-sharing\"><div class=\"sd-content\"><ul><li class=\"share-twitter\"><a rel=\"nofollow noopener noreferrer\" data-shared=\"sharing-twitter-1076\" class=\"share-twitter sd-button share-icon\" href=\"https:\/\/agiltools.com\/blogsp\/agentes_con_rango_al\/?share=twitter\" target=\"_blank\" title=\"Click to share on Twitter\"><span>Twitter<\/span><\/a><\/li><li class=\"share-facebook\"><a rel=\"nofollow noopener noreferrer\" data-shared=\"sharing-facebook-1076\" class=\"share-facebook sd-button share-icon\" href=\"https:\/\/agiltools.com\/blogsp\/agentes_con_rango_al\/?share=facebook\" target=\"_blank\" title=\"Click to share on Facebook\"><span>Facebook<\/span><\/a><\/li><li class=\"share-end\"><\/li><\/ul><\/div><\/div><\/div>","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_mi_skip_tracking":false,"spay_email":""},"categories":[2],"tags":[108,166],"jetpack_featured_media_url":"","jetpack_likes_enabled":true,"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/agiltools.com\/blogsp\/wp-json\/wp\/v2\/posts\/1076"}],"collection":[{"href":"https:\/\/agiltools.com\/blogsp\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/agiltools.com\/blogsp\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/agiltools.com\/blogsp\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/agiltools.com\/blogsp\/wp-json\/wp\/v2\/comments?post=1076"}],"version-history":[{"count":8,"href":"https:\/\/agiltools.com\/blogsp\/wp-json\/wp\/v2\/posts\/1076\/revisions"}],"predecessor-version":[{"id":1084,"href":"https:\/\/agiltools.com\/blogsp\/wp-json\/wp\/v2\/posts\/1076\/revisions\/1084"}],"wp:attachment":[{"href":"https:\/\/agiltools.com\/blogsp\/wp-json\/wp\/v2\/media?parent=1076"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/agiltools.com\/blogsp\/wp-json\/wp\/v2\/categories?post=1076"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/agiltools.com\/blogsp\/wp-json\/wp\/v2\/tags?post=1076"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}