{"id":8725,"date":"2024-05-08T18:56:10","date_gmt":"2024-05-08T16:56:10","guid":{"rendered":"https:\/\/blogs.etsii.urjc.es\/dseytr\/?p=8725"},"modified":"2024-05-08T18:56:11","modified_gmt":"2024-05-08T16:56:11","slug":"terrenator-cortacesped-inteligente","status":"publish","type":"post","link":"https:\/\/blogs.etsii.urjc.es\/dseytr\/terrenator-cortacesped-inteligente\/","title":{"rendered":"TERRENATOR &#8211; Cortac\u00e9sped Inteligente"},"content":{"rendered":"\n<p class=\"has-text-align-center\"><img loading=\"lazy\" decoding=\"async\" width=\"329\" height=\"586\" src=\"https:\/\/lh7-us.googleusercontent.com\/7xLmNuOL2Jqj6zuCQVIgbcnZ2mw1Actg3JEfo7Pbj93tIkjdhnRCRhJquTKhL_bWdJ2-v3URDIztftSN-I9yPlto7BuFuYfTJyqk92xolARu0rx9PI9MQwGpxVvA-2SUYwSPTT-W9OpADMQ0dWE-I8s\"><\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Grupo 18<\/h1>\n\n\n\n<p>Integrantes:<br><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Fiorella Victoria Hern\u00e1ndez Mej\u00eda<\/li>\n\n\n\n<li>Frantzes Elzaurdia<\/li>\n\n\n\n<li>Rub\u00e9n Gonz\u00e1lez de Pablo<\/li>\n\n\n\n<li>Vicente Gonz\u00e1lez P\u00e9rez<\/li>\n<\/ul>\n\n\n\n<h1 class=\"wp-block-heading\">Introducci\u00f3n<\/h1>\n\n\n\n<p>La motivaci\u00f3n del proyecto surge debido a que nos dimos cuenta de que conoc\u00edamos a alguna persona con una finca como segunda residencia donde pasaba tiempo ocasionalmente. El problema reside en que normalmente estas parcelas tienen zonas donde crece la hierba y hay que cortarla con cierta frecuencia, lo cual es un esfuerzo considerable haciendo uso de un cortac\u00e9sped normal.<\/p>\n\n\n\n<p>Para solucionar este problema decidimos dise\u00f1ar un cortac\u00e9sped radiocontrol que pueda dirigirse con un mando y a su vez que tambi\u00e9n funcione de forma aut\u00f3noma.<\/p>\n\n\n\n<p>Inicialmente, consideramos que podr\u00eda contar con dos modos de operar: un modo teledirigido con un mando de radiocontrol, y modo \u201cRoomba\u201d que recortar\u00eda autom\u00e1ticamente el terreno contando con un parachoques para cambiar su rumbo. Sin embargo, no nos convenci\u00f3 este \u00faltimo modo y concluimos que no resultaba pr\u00e1ctico en el contexto que queremos desplegar nuestro producto. Es por ello que decidimos descartarlo en favor de un modo que utilice un GPS y 4 coordenadas de v\u00e9rtices para recorrer una extensi\u00f3n de tierra. Mantuvimos el parachoques de la idea anterior para que la desbrozadora al chocar con un obst\u00e1culo grande, sea capaz de ir marcha atr\u00e1s y cambiar su orientaci\u00f3n para esquivar el obst\u00e1culo y seguir recortando siguiendo un algoritmo para asegurar que no quede ning\u00fan metro cuadrado sin recortar; sin embargo, finalmente por numerosos contratiempos, qued\u00f3 a medias la implementaci\u00f3n del parachoques.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Implementaci\u00f3n<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">Reparto de tareas<\/h2>\n\n\n\n<p>Aunque intentamos repartir las tareas de manera que trabaj\u00e1ramos todos igual en cada uno de los aspectos del proyecto, finalmente como hemos tenido problemas con el hardware, Rub\u00e9n y Fiorella se han encargado m\u00e1s de ese aspecto que Vicente y Frantzes, los cuales han incidido m\u00e1s en el desarrollo del software.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Dise\u00f1o del producto<\/h2>\n\n\n\n<p>Para calcular las dimensiones del chasis se decidi\u00f3 que lo mejor era hacer un dise\u00f1o 3D de la estructura. De esta manera pod\u00edamos ver de qu\u00e9 tama\u00f1o hay que cortar y soldar la estructura de acero para que cumpla nuestros requisitos.<\/p>\n\n\n\n<p class=\"has-text-align-center\"><\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"768\" height=\"1024\" src=\"https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2024\/05\/WhatsApp-Image-2024-05-08-at-18.22.25-2-768x1024.jpeg\" alt=\"\" class=\"wp-image-8824\" style=\"width:308px;height:auto\" srcset=\"https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2024\/05\/WhatsApp-Image-2024-05-08-at-18.22.25-2-768x1024.jpeg 768w, https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2024\/05\/WhatsApp-Image-2024-05-08-at-18.22.25-2-225x300.jpeg 225w, https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2024\/05\/WhatsApp-Image-2024-05-08-at-18.22.25-2-1152x1536.jpeg 1152w, https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2024\/05\/WhatsApp-Image-2024-05-08-at-18.22.25-2-1536x2048.jpeg 1536w, https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2024\/05\/WhatsApp-Image-2024-05-08-at-18.22.25-2.jpeg 1920w\" sizes=\"auto, (max-width: 768px) 100vw, 768px\" \/><figcaption class=\"wp-element-caption\"><strong>Figura 1<\/strong><br>Rub\u00e9n pintando el chasis de acero<\/figcaption><\/figure>\n<\/div>\n\n\n<p>En tema de hardware el robot tiene varios componentes principales:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Tenemos los 4 m\u00f3dulos controladores de motores. Cada rueda tiene un motor independiente controlado de manera independiente. Estos m\u00f3dulos est\u00e1n compuestos de dos partes. Un grupo de rel\u00e9s que controla la direcci\u00f3n de giro de los motores invirtiendo las conexiones, y otro m\u00f3dulo que controla la velocidad del motor haciendo uso de dos mosfet.&nbsp;<\/li>\n\n\n\n<li>Para la parte de la cuchilla tenemos el motor de 250w y otra controladora m\u00e1s potente para poder regular la velocidad y el arranque del motor.&nbsp;<\/li>\n\n\n\n<li>La alimentaci\u00f3n est\u00e1 compuesta de dos bater\u00edas Lipo de 12v 4Ah que forman en conjunto un sistema de 24v.&nbsp;<\/li>\n\n\n\n<li>Todo el sistema est\u00e1 controlado por un Arduino Mega.&nbsp;<\/li>\n\n\n\n<li>Para el control y comunicaci\u00f3n tenemos dos m\u00f3dulos de radio. Un receptor para un mando de RC y una antena de radio telemetr\u00eda de 915mhz que nos permite comunicaci\u00f3n bidireccional entre el Arduino y el ordenador.&nbsp;<\/li>\n\n\n\n<li>Por \u00faltimo para el modo aut\u00f3nomo tenemos un GPS para saber en tiempo real la ubicaci\u00f3n del robot.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Proceso de montaje y de desarrollo de software<\/h2>\n\n\n\n<p>Una vez que montamos todo, probamos que cortara con \u00e9xito, y as\u00ed fue. Escribimos el c\u00f3digo del modo RC y al probarlo dimos con un problema grave: nuestros controladores de motor se quemaron.&nbsp;<\/p>\n\n\n\n<p>El modo RC permite ir hacia delante, atr\u00e1s, girar de golpe y girar a la vez que est\u00e1 acelerando hacia delante o hacia atr\u00e1s. La velocidad de los motores no es constante, se puede controlar usando los <em>joysticks<\/em> del mando RC. Para recortar se gira de la rueda correspondiente que sirve de <em>toggle<\/em>.<\/p>\n\n\n\n<p class=\"has-text-align-center\"><\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"720\" height=\"898\" src=\"https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2024\/05\/WhatsApp-Image-2024-05-08-at-18.22.25-1.jpeg\" alt=\"\" class=\"wp-image-8823\" style=\"width:271px;height:auto\" srcset=\"https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2024\/05\/WhatsApp-Image-2024-05-08-at-18.22.25-1.jpeg 720w, https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2024\/05\/WhatsApp-Image-2024-05-08-at-18.22.25-1-241x300.jpeg 241w\" sizes=\"auto, (max-width: 720px) 100vw, 720px\" \/><figcaption class=\"wp-element-caption\"><strong>Figura 2<\/strong><br>Mando RC<\/figcaption><\/figure>\n<\/div>\n\n\n<p>Implementamos la comunicaci\u00f3n bidireccional entre el Arduino y el PC creando nuestro propio protocolo usando caracteres para que el PC fuera capaz de enviarle al Arduino de manera codificada c\u00f3mo debe moverse para recorrer la superficie del cuadril\u00e1tero. A la vez, el Arduino env\u00eda al ordenador constantemente su ubicaci\u00f3n actual.<\/p>\n\n\n\n<p>El funcionamiento es el siguiente:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Con el mando se cambia el modo de operaciones a \u201cmodo PC\u201d.&nbsp;<\/li>\n\n\n\n<li>Una vez establecida la comunicaci\u00f3n entre ambos dispositivos, el PC comprueba la orientaci\u00f3n y la ubicaci\u00f3n actual del Arduino y le manda una orden de moverse siguiendo el algoritmo para recorrer la superficie entera.<\/li>\n\n\n\n<li>El Arduino recibe la orden y sigue movi\u00e9ndose en dicha direcci\u00f3n hasta recibir una nueva orden que puede ser cambiar la direcci\u00f3n, girando en forma de \u201cu\u201d o detenerse porque ya ha terminado de recortar.<\/li>\n<\/ol>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"457\" src=\"https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2024\/05\/Captura-de-pantalla-2024-05-08-182906-1024x457.png\" alt=\"\" class=\"wp-image-8825\" srcset=\"https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2024\/05\/Captura-de-pantalla-2024-05-08-182906-1024x457.png 1024w, https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2024\/05\/Captura-de-pantalla-2024-05-08-182906-300x134.png 300w, https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2024\/05\/Captura-de-pantalla-2024-05-08-182906-768x342.png 768w, https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2024\/05\/Captura-de-pantalla-2024-05-08-182906.png 1294w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\"><br><strong>Figura 3<\/strong><br>Diagrama de actividad del funcionamiento del software Arduino<br><\/figcaption><\/figure>\n<\/div>\n\n\n<p>Por otro lado hemos a\u00f1adido funcionalidades para evitar accidentes.&nbsp;<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Si se desconecta el mando la m\u00e1quina se detiene.<\/li>\n\n\n\n<li>Si queda poca bater\u00eda, contamos con un zumbador que emite pitidos para notificarlo.<\/li>\n\n\n\n<li>En cualquier momento durante la ejecuci\u00f3n del modo de recorte autom\u00e1tico se puede cambiar al modo manual usando el mando gracias a las interrupciones.<\/li>\n<\/ul>\n\n\n\n<p>Poniendo el enfoque en la parte de software del ordenador, desarrollamos una app de escritorio simple utilizando Unity para poder utilizar la API de Google Maps para pinchar sobre el mapa y obtener de una manera intuitiva las coordenadas de los v\u00e9rtices de nuestra superficie a cortar. Utilizar un ordenador nos proporciona la gran ventaja de no estar limitado por el procesador del Arduino, pudiendo ejecutar algoritmos m\u00e1s complejos y manteniendo un canal bidireccional de comunicaci\u00f3n en tiempo real. Aprovechamos tambi\u00e9n para utilizar una antena que se enchufa al puerto USB con un alcance de hasta 2 km, posibilitando el recorte de terrenos m\u00e1s grandes.<\/p>\n\n\n\n<p>Hab\u00edamos considerado desarrollar una aplicaci\u00f3n m\u00f3vil que utilizara <em>bluetooth <\/em>para enviar inicialmente las coordenadas de los v\u00e9rtices de un rect\u00e1ngulo y que ya se encargara el Arduino de recorrerlo por s\u00ed solo; no obstante, esto limitar\u00eda mucho las posibilidades del software, ya que adem\u00e1s de depender de las limitaciones del hardware, una vez que arranca y se desconecta&nbsp; el <em>bluetooth <\/em>por su rango muy limitado, no tendr\u00edamos manera de conocer qu\u00e9 est\u00e1 sucediendo a partir de ese instante. En cualquier caso, no descartamos la posibilidad de incorporar esta funcionalidad para una versi\u00f3n del producto orientada a recortar patios y parcelas peque\u00f1as.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"779\" height=\"414\" src=\"https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2024\/05\/Captura-de-pantalla-2024-05-08-183617.png\" alt=\"\" class=\"wp-image-8826\" srcset=\"https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2024\/05\/Captura-de-pantalla-2024-05-08-183617.png 779w, https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2024\/05\/Captura-de-pantalla-2024-05-08-183617-300x159.png 300w, https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2024\/05\/Captura-de-pantalla-2024-05-08-183617-768x408.png 768w\" sizes=\"auto, (max-width: 779px) 100vw, 779px\" \/><figcaption class=\"wp-element-caption\"><strong>Figura 4<\/strong><br>Software PC desarrollado con Unity<\/figcaption><\/figure>\n<\/div>\n\n\n<h1 class=\"wp-block-heading\">Costes materiales<\/h1>\n\n\n\n<p>Finalmente, el coste total de los materiales ha sido de 517,74 euros aproximadamente, contando el precio de los componentes que pose\u00edamos de antemano, y que no tuvimos que comprar. En la Figura 5 pueden encontrar cada uno de los materiales utilizados con su respectivo precio.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"570\" height=\"745\" src=\"https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2024\/05\/Captura-de-pantalla-2024-05-08-184147.png\" alt=\"\" class=\"wp-image-8827\" srcset=\"https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2024\/05\/Captura-de-pantalla-2024-05-08-184147.png 570w, https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2024\/05\/Captura-de-pantalla-2024-05-08-184147-230x300.png 230w\" sizes=\"auto, (max-width: 570px) 100vw, 570px\" \/><figcaption class=\"wp-element-caption\"><strong>Figura 5<\/strong><br>Tabla de gastos de hardware<br><\/figcaption><\/figure>\n<\/div>\n\n\n<h1 class=\"wp-block-heading\">Dificultades encontradas<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">Hardware<\/h2>\n\n\n\n<p>El principal problema que encontramos fue en el sistema de propulsi\u00f3n. Los motores elegidos originalmente no ten\u00edan suficiente fuerza para mover el robot a trav\u00e9s de la hierba alta. Por eso compramos unos motores con 6 veces m\u00e1s potencia, pero eso acarre\u00f3 otro problema. Estos nuevos motores ten\u00edan un consumo demasiado elevado para los controladores originales, los L298N, lo que hizo explotar varios de ellos. La soluci\u00f3n la encontramos en otros reguladores de velocidad m\u00e1s potentes, de hasta 80w de consumo y uno grupos de rel\u00e9s para poder invertir la direcci\u00f3n de giro. Para llegar hasta esta soluci\u00f3n hubo que hacer ingenier\u00eda inversa.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"575\" height=\"1024\" src=\"https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2024\/05\/WhatsApp-Image-2024-05-08-at-18.29.40-575x1024.jpeg\" alt=\"\" class=\"wp-image-8828\" style=\"width:238px;height:auto\" srcset=\"https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2024\/05\/WhatsApp-Image-2024-05-08-at-18.29.40-575x1024.jpeg 575w, https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2024\/05\/WhatsApp-Image-2024-05-08-at-18.29.40-169x300.jpeg 169w, https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2024\/05\/WhatsApp-Image-2024-05-08-at-18.29.40-768x1367.jpeg 768w, https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2024\/05\/WhatsApp-Image-2024-05-08-at-18.29.40-863x1536.jpeg 863w, https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2024\/05\/WhatsApp-Image-2024-05-08-at-18.29.40.jpeg 899w\" sizes=\"auto, (max-width: 575px) 100vw, 575px\" \/><figcaption class=\"wp-element-caption\"><strong>Figura 6<\/strong><br>L298N quemado<br><\/figcaption><\/figure>\n<\/div>\n\n\n<p>Por otro lado, las ruedas no ten\u00edan suficiente agarre, por lo que en ocasiones se quedaba el robot atascado en terreno complicado o no giraba correctamente. Hemos reemplazado dos de ellas por unas creadas con impresora 3D, pero aunque hemos notado una peque\u00f1a mejora, no es muy significativa.<br>Compramos un m\u00f3dulo GPS que pens\u00e1bamos que contaba con una br\u00fajula para conocer la orientaci\u00f3n del cortac\u00e9sped, sin embargo al no tenerla, hemos tenido que tirar de software, aproximando la orientaci\u00f3n utilizando las coordenadas que obtenemos mientras se mueve.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"768\" height=\"1024\" src=\"https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2024\/05\/WhatsApp-Image-2024-05-08-at-18.22.25-3-768x1024.jpeg\" alt=\"\" class=\"wp-image-8832\" style=\"width:370px;height:auto\" srcset=\"https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2024\/05\/WhatsApp-Image-2024-05-08-at-18.22.25-3-768x1024.jpeg 768w, https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2024\/05\/WhatsApp-Image-2024-05-08-at-18.22.25-3-225x300.jpeg 225w, https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2024\/05\/WhatsApp-Image-2024-05-08-at-18.22.25-3-1152x1536.jpeg 1152w, https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2024\/05\/WhatsApp-Image-2024-05-08-at-18.22.25-3.jpeg 1200w\" sizes=\"auto, (max-width: 768px) 100vw, 768px\" \/><figcaption class=\"wp-element-caption\"><strong>Figura <\/strong>7<br>Hardware<\/figcaption><\/figure>\n<\/div>\n\n\n<h2 class=\"wp-block-heading\">Software<\/h2>\n\n\n\n<p>Tuvimos dificultades con la documentaci\u00f3n de las funciones exclusivas del Arduino y el proceso de establecer la comunicaci\u00f3n entre este y el PC. Tambi\u00e9n con el funcionamiento de los nuevos controladores de los motores que no est\u00e1n dise\u00f1ados para Arduino, as\u00ed como el m\u00f3dulo de GPS.&nbsp;<\/p>\n\n\n\n<p>En cuanto a la comunicaci\u00f3n, llev\u00f3 varias horas lograr establecerla entre el Arduino y el ordenador usando la antena, principalmente porque no nos dimos cuenta de aumentar los baudios.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"768\" height=\"1024\" src=\"https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2024\/05\/WhatsApp-Image-2024-05-08-at-18.22.25-3-1-768x1024.jpeg\" alt=\"\" class=\"wp-image-8833\" style=\"width:350px;height:auto\" srcset=\"https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2024\/05\/WhatsApp-Image-2024-05-08-at-18.22.25-3-1-768x1024.jpeg 768w, https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2024\/05\/WhatsApp-Image-2024-05-08-at-18.22.25-3-1-225x300.jpeg 225w, https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2024\/05\/WhatsApp-Image-2024-05-08-at-18.22.25-3-1-1152x1536.jpeg 1152w, https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2024\/05\/WhatsApp-Image-2024-05-08-at-18.22.25-3-1.jpeg 1200w\" sizes=\"auto, (max-width: 768px) 100vw, 768px\" \/><figcaption class=\"wp-element-caption\"><strong>Figura <\/strong>8<br>Antenas de telemetr\u00eda<\/figcaption><\/figure>\n<\/div>\n\n\n<p>En general el desarrollo del software fue lento debido a que en varias ocasiones ten\u00edamos que esperar a que el que tuviera el hardware lo probara, y como hemos tenido numerosos problemas con el hardware, sumando el tiempo de los env\u00edos de los componentes sustituidos, etc., hab\u00eda periodos de d\u00edas en los que no pod\u00edamos avanzar. En este aspecto podr\u00edamos habernos organizado mejor para evitar estos cuellos de botella.<\/p>\n\n\n\n<p><span id=\"docs-internal-guid-c13ac08c-7fff-2496-7c41-12414b1f9ee9\"><\/span><\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Posibles mejoras<\/h1>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Como hab\u00edamos mencionado previamente, se podr\u00eda a\u00f1adir un m\u00f3dulo <em>bluetooth<\/em> u otro tipo de conectividad, ya que se podr\u00eda reutilizar casi todo el software incluyendo la del Unity generando un APK y quedar\u00eda implementar el proceso de <em>pairing <\/em>y de recorrido simplificado en el Arduino, sin necesidad de utilizar una antena con ese rango. Este ser\u00eda un caso de uso diferente, ya que no es tan vers\u00e1til. Tambi\u00e9n se podr\u00eda considerar crear una aplicaci\u00f3n web.<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Ser capaz de indicar de antemano en el mapa la ubicaci\u00f3n de obst\u00e1culos para evitarlos sin tener el cortac\u00e9sped que chocarse contra ellos y hacer un recorrido \u00f3ptimo usando alg\u00fan algoritmo m\u00e1s complejo como backtracking.<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Acabar la implementaci\u00f3n del parachoques.<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Tener una bater\u00eda recargable de mucha m\u00e1s capacidad para que el robot tenga una autonom\u00eda muy supe<\/li>\n<\/ul>\n\n\n\n<p><span id=\"docs-internal-guid-c13ac08c-7fff-2496-7c41-12414b1f9ee9\"><\/span><\/p>\n\n\n\n<p><span id=\"docs-internal-guid-c13ac08c-7fff-2496-7c41-12414b1f9ee9\"><span style=\"font-size: 16pt;font-family: Arial, sans-serif;background-color: transparent;font-weight: 400;vertical-align: baseline\">C\u00f3digo Arduino<\/span><\/span><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;SoftwareSerial.h&gt;\n#include &lt;TinyGPS.h&gt;\n#include &lt;math.h&gt;\n\nconst int CHNUM = 5; \/\/ n\u00famero de canales de la emisora\nint chval&#091;CHNUM]; \/\/ valores de los canales\nconst int PWM_ADVANCE_PIN = 5;\nconst int PWM_ROTATE_PIN = 3;\nconst int PWM_BLADE_PIN = 4;\nconst int PWM_MODE_SWITCH_PIN = 6;\nconst int PWM_BUZZER_ON = 7;\n\nconst int VOLTAGE_PIN = A0;\n\nconst int BUZZER_PIN = 27;\nconst int BLADE_ENABLE_PIN = 28;\n\nconst int MIN_VOLTAGE_LIMIT = 4.2;\n\nconst int CHANGE_DIR_DELAY = 200;\n\nconst int THRESHOLD_FORWARD_MIN = 1500;\nconst int THRESHOLD_FORWARD_MAX = 1900;\nconst int THRESHOLD_BACKWARD_MIN = 1020;\nconst int THRESHOLD_BACKWARD_MAX = 1450;\nconst int THRESHOLD_TURN_LEFT_MIN = 1225;\nconst int THRESHOLD_TURN_LEFT_MAX = 1425;\nconst int THRESHOLD_TURN_RIGHT_MIN = 1475; \nconst int THRESHOLD_TURN_RIGHT_MAX = 1700; \nconst int THRESHOLD_BLADE_MIN = 1040; \nconst int THRESHOLD_BLADE_MAX = 1900; \n\nconst int RELE_FL_MOTOR_PIN = 22;\nconst int RELE_FR_MOTOR_PIN = 23;\nconst int RELE_BL_MOTOR_PIN = 24;\nconst int RELE_BR_MOTOR_PIN = 25;\n\nconst int PWM_FL_PIN = 13;\nconst int PWM_FR_PIN = 12;\nconst int PWM_BL_PIN = 11;\nconst int PWM_BR_PIN = 10;\n\nconst int PWM_BLADE_SPEED_PIN = 9;\n\nbool batteryCharged = true;\nbool bladeMotorSpinning = false;\nvolatile bool rcMode;\n\nbool l_motor_forward = false;\nbool r_motor_forward = false;\nbool l_motor_backward = false;\nbool r_motor_backward = false;  \n\nTinyGPS gps;\n\nvoid setup() {\n  pinMode(VOLTAGE_PIN, INPUT);\n  pinMode(BUZZER_PIN, OUTPUT);\n\n  pinMode(RELE_FL_MOTOR_PIN, OUTPUT);\n  pinMode(RELE_FR_MOTOR_PIN, OUTPUT);\n  pinMode(RELE_BL_MOTOR_PIN, OUTPUT);\n  pinMode(RELE_BR_MOTOR_PIN, OUTPUT);\n  pinMode(BLADE_ENABLE_PIN, OUTPUT);\n  digitalWrite(BLADE_ENABLE_PIN, LOW);\n  pinMode(PWM_BLADE_SPEED_PIN, OUTPUT);\n\n  pinMode(PWM_FL_PIN, OUTPUT);\n  pinMode(PWM_FR_PIN, OUTPUT);\n  pinMode(PWM_BL_PIN, OUTPUT);\n  pinMode(PWM_BR_PIN, OUTPUT);\n\n  Serial.begin(9600);\n  Serial1.begin(57600); \/\/ Antena\n  Serial3.begin(9600); \/\/ GPS communication initialization\n  \/\/PWM INPUTs\n  pinMode(PWM_ADVANCE_PIN, INPUT);\n  pinMode(PWM_ROTATE_PIN, INPUT);\n  pinMode(PWM_BLADE_PIN, INPUT);\n  pinMode(PWM_MODE_SWITCH_PIN, INPUT);\n  pinMode(PWM_BUZZER_ON, INPUT);\n\n  startTone();\n\n  attachInterrupt(digitalPinToInterrupt(PWM_MODE_SWITCH_PIN), changeMode, CHANGE);\n}\n\nvoid startTone(){\n  soundBuzzer(HIGH);\n  delay(500);\n  soundBuzzer(LOW);\n  delay(300);\n\n  soundBuzzer(HIGH);\n  delay(300);\n  soundBuzzer(LOW);\n  delay(300);\n\n  soundBuzzer(HIGH);\n  delay(300);\n  soundBuzzer(LOW);\n}\n\nvoid lowBatteryTone(){\n  soundBuzzer(HIGH);\n  delay(800);\n  soundBuzzer(LOW);\n  delay(300);\n\n  soundBuzzer(HIGH);\n  delay(800);\n  soundBuzzer(LOW);\n  delay(300);\n}\n\n\n\nvoid RCmodeTone(){\n  soundBuzzer(HIGH);\n  delay(200);\n  soundBuzzer(LOW);\n}\n\nvoid automaticModeTone(){\n  soundBuzzer(HIGH);\n  delay(200);\n  soundBuzzer(LOW);\n  delay(300);\n  soundBuzzer(HIGH);\n  delay(200);\n  soundBuzzer(LOW);\n}\n\nvoid changeMode(){\n  rcMode = !rcMode;\n}\n\nvoid soundBuzzer(bool value){\n  digitalWrite(BUZZER_PIN, value);\n}\n\nvoid checkVoltage(){\n  int readValue = analogRead(VOLTAGE_PIN);\n  float voltage = readValue * 5.0\/1023;\n \n  if (voltage &lt; MIN_VOLTAGE_LIMIT){\n\tstopWheels();\n\tlowBatteryTone ();\n\tbatteryCharged = false;\n  } else{\n\tbatteryCharged = true;\n  }\n}\n\nint to255Range(int value){\n  return max(0, min(255, value));\n}\n\n\n\nfloat mapToRange(float value) {\n  float r =  (float)map(value, 0, 255, 0, 1000) \/ 1000.0;\n  return max(0, min(255, r));\n}\n\nvoid stopWheels() {\n  analogWrite(PWM_FL_PIN, 0);\n  analogWrite(PWM_FR_PIN, 0);\n  analogWrite(PWM_BL_PIN, 0);\n  analogWrite(PWM_BR_PIN, 0);\n  delay(CHANGE_DIR_DELAY);\n  digitalWrite(RELE_FR_MOTOR_PIN, HIGH);\n  digitalWrite(RELE_FL_MOTOR_PIN, HIGH);\n  digitalWrite(RELE_BL_MOTOR_PIN, HIGH);\n  digitalWrite(RELE_BR_MOTOR_PIN, HIGH);\n  l_motor_forward = true;\n  r_motor_forward = true;\n  l_motor_backward = false;\n  r_motor_backward = false;\n}\n\/\/ Receives as parameters the forward movement speed, and then two values between 1 and 2 used to decrease the speed of the wheels on one side to make it turn\nvoid accelerateWheels(int forwardSpeed, float turningLeftRate, float turningRightRate) {\n  int leftWheelsSpeed = round(forwardSpeed - 255 * (1 - turningLeftRate));\n  int rightWheelsSpeed = round(forwardSpeed - 255 * (1 - turningRightRate));\n    moveMotors(HIGH, HIGH, leftWheelsSpeed, rightWheelsSpeed);\n}\n\/\/ Receives as parameters the backward movement speed, and then two values between 1 and 2 used to decrease the speed of the wheels on one side to make it turn\nvoid reverseWheels(int backwardSpeed, float turningLeftRate, float turningRightRate) {\n  int leftWheelsSpeed = round(backwardSpeed - 255 * (1 - turningLeftRate));\n  int rightWheelsSpeed = round(backwardSpeed - 255 * (1 - turningRightRate));\n    moveMotors(LOW, LOW, leftWheelsSpeed, rightWheelsSpeed);\n}\n\nvoid turnLeft(int leftSpeed) {\n  moveMotors(LOW, HIGH, leftSpeed, leftSpeed);\n}\n\nvoid turnRight(int rightSpeed) {\n  moveMotors(HIGH, LOW, rightSpeed, rightSpeed);\n}\n\nvoid moveMotors(bool left, bool right, int analogL, int analogR) {\n  Serial.println(\"R: \" + String(analogR) + \" L: \" + String(analogL));\n  if (left &amp;&amp; l_motor_forward) {\n\tanalogWrite(PWM_FL_PIN, analogL);\n\tanalogWrite(PWM_BL_PIN, analogL);\n  } else if (!left &amp;&amp; l_motor_backward) {\n\tanalogWrite(PWM_FL_PIN, analogL);\n\tanalogWrite(PWM_BL_PIN, analogL);\n  } else {\n\tanalogWrite(PWM_FL_PIN,0);\n\tanalogWrite(PWM_BL_PIN,0);\n\tdelay(CHANGE_DIR_DELAY);\n\tdigitalWrite(RELE_FL_MOTOR_PIN, left);\n\tdigitalWrite(RELE_BL_MOTOR_PIN, left);\n\tdelay(CHANGE_DIR_DELAY);\n\tanalogWrite(PWM_FL_PIN, analogL);\n\tanalogWrite(PWM_BL_PIN, analogL);\n\n\tl_motor_forward = left;\n\tl_motor_backward = !left;\n  }\n  if (right &amp;&amp; r_motor_forward) {\n\tanalogWrite(PWM_FR_PIN, analogR);\n\tanalogWrite(PWM_BR_PIN, analogR);\n  } else if (!right &amp;&amp; r_motor_backward) {\n\tanalogWrite(PWM_FR_PIN, analogR);\n\tanalogWrite(PWM_BR_PIN, analogR);\n  } else {\n\tanalogWrite(PWM_FR_PIN,0);\n\tanalogWrite(PWM_BR_PIN,0);\n\tdelay(CHANGE_DIR_DELAY);\n\tdigitalWrite(RELE_FR_MOTOR_PIN, right);\n\tdigitalWrite(RELE_BR_MOTOR_PIN, right);\n\tdelay(CHANGE_DIR_DELAY);\n\tanalogWrite(PWM_FR_PIN, analogR);\n\tanalogWrite(PWM_BR_PIN, analogR);\n    \n\tr_motor_forward = right;\n\tr_motor_backward = !right;\n  }\n}\n\nbool isTurning(int leftSpeed, int rightSpeed) {\n  return leftSpeed &gt; 0 || rightSpeed &gt; 0;\n}\n\nbool isAccelerating(int forwardSpeed, int backwardSpeed) {\n  return forwardSpeed &gt; 0 || backwardSpeed &gt; 0;\n}\n\nvoid toggleBladeMotor(int pwmValue){\n  int bladeSpeed = map(pwmValue, THRESHOLD_BLADE_MIN+100, THRESHOLD_BLADE_MAX, 0, 255);\n  bladeSpeed = to255Range(bladeSpeed);\n  if(pwmValue&lt;THRESHOLD_BLADE_MIN+100){\n\tanalogWrite(PWM_BLADE_SPEED_PIN, 0);\n\tdigitalWrite(BLADE_ENABLE_PIN, LOW);\n  }else{\n\tanalogWrite(PWM_BLADE_SPEED_PIN, bladeSpeed);\n\tdigitalWrite(BLADE_ENABLE_PIN, HIGH);\n  }\n}\n\nString getCoordinates(){\n  bool newData = false;\n\tfor (unsigned long start = millis(); millis() - start &lt; 1000;) {\n  \twhile (Serial3.available())\n  \t{\n    \tchar c = Serial3.read();\n    \tif (gps.encode(c)) \/\/ Did a new valid sentence come in?\n      \tnewData = true;\n  \t}\n\t}\n \n  if (newData)\n  {\n\tString coordinates = \"\";\n\tfloat flat, flon, course;\n\tunsigned long age;\n\tgps.f_get_position(&amp;flat, &amp;flon, &amp;age);\n\tcourse = gps.f_course();\n\tSerial.print(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flat, 6);\n\tSerial.print(flon == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flon, 6);\n\tSerial.print(course == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : course, 6);\n\t\/\/ Warning, if the data received is corrupt the value will be reassigned to 0.0\n\tif ((flat != 0.0) &amp;&amp; (flon != 0.0))\n  \tcoordinates = \"G:\" + String(flat) + \" \" + String(flon) + \" \" + String(gps.cardinal(course));\n\treturn coordinates;\n  }\n\n  unsigned long chars;\n  unsigned short sentences, failed;\n  gps.stats(&amp;chars, &amp;sentences, &amp;failed);\n  Serial1.print(\" CHARS=\");\n  Serial1.print(chars);\n  Serial1.print(\" SENTENCES=\");\n  Serial1.print(sentences);\n  Serial1.print(\" CSUM ERR=\");\n  Serial1.println(failed);\n  if (chars == 0)\n\tSerial1.println(\"** No characters received from GPS: check wiring **\");\n  return \"\";\n}\n\nvoid pcMode(){\n  Serial.println(\"PC\");\n  \/*\n  Serial recieves messages from PC. Serial1 sends GPS coordinates to PC.\n\n  READING PROTOCOL:\n\tMovement:\n\tS =&gt; Stop\n\tF =&gt; Forward\n\tB =&gt; Backward\n\tR =&gt; Turn Right\n\tL =&gt; Turn Left\n\tC =&gt; Toggle Cutting Motor\n\n\tCompleted route:\n\tZ =&gt; Stop, empty Serial buffer and exit pcMode\n  *\/\n\n  char incomingChar = 'X';\n\n  const int PC_MODE_SPEED =  125;\n  getCoordinates();\n  \/\/ Turn on blade\n  toggleBladeMotor(1500);\n\n  while (incomingChar != 'Z' &amp;&amp; !rcMode){\n    \n\tif(pulseIn(PWM_MODE_SWITCH_PIN, HIGH) &gt; 1500){\n  \treturn;\n\t}\n\tincomingChar = Serial1.read();\n\t\/\/ Check if data has been received\n    \n\t\/\/ Switch statement to handle different commands\n\tswitch (incomingChar) {\n    \tcase 'S':\n        \tstopWheels();\n        \tbreak;\n    \tcase 'F':\n        \taccelerateWheels(PC_MODE_SPEED, 1, 1);\n        \tbreak;\n    \tcase 'B':\n        \treverseWheels(PC_MODE_SPEED, 1, 1);\n        \tbreak;\n    \tcase 'R':\n        \tturnRight(PC_MODE_SPEED);\n        \tbreak;\n    \tcase 'L':\n        \tturnLeft(PC_MODE_SPEED);\n        \tbreak;\n    \tcase 'C':\n        \ttoggleBladeMotor(1500);\/\/hacer esto regulable\n        \tbreak;\n    \tdefault:\n        \tSerial.println(\"No movement char detected\");\n        \tbreak;\n\t}\n\n\tString coordinates = getCoordinates();\n\t\/\/ Checks if buffer isn't full and sends coordinates and if a collision has been detected\n\tif (Serial1.availableForWrite() &amp;&amp; !rcMode){\n  \tSerial1.println(\"Sending coordinates: \");\n \t \n  \tSerial1.println(coordinates);\n\t}\n  }\n\n  stopWheels();\n\n  \/\/ Turn off blade\n  toggleBladeMotor(1500);\n\n  Serial.flush();\n}\n\nvoid readRCInput() {\n  Serial.println(\"RC\");\n  \/\/ Read channels\n  chval&#091;0] = pulseIn(PWM_ADVANCE_PIN, HIGH);\n  chval&#091;1] = pulseIn(PWM_ROTATE_PIN, HIGH);\n  chval&#091;2] = pulseIn(PWM_BLADE_PIN, HIGH);\n  chval&#091;3] = pulseIn(PWM_BUZZER_ON, HIGH);\n  while(chval&#091;0]&lt;500){\n\tdelay(200);\n\tchval&#091;0] = pulseIn(PWM_ADVANCE_PIN, HIGH);\n  }\n \n  int forwardSpeed = map(chval&#091;0], THRESHOLD_FORWARD_MIN, THRESHOLD_FORWARD_MAX, 0, 255);\n  int backwardSpeed = map(chval&#091;0], THRESHOLD_BACKWARD_MAX, THRESHOLD_BACKWARD_MIN, 0, 255);\n  int leftSpeed = map(chval&#091;1], THRESHOLD_TURN_LEFT_MAX, THRESHOLD_TURN_LEFT_MIN, 0, 255);\n  int rightSpeed = map(chval&#091;1], THRESHOLD_TURN_RIGHT_MIN, THRESHOLD_TURN_RIGHT_MAX, 0, 255);\n \n  forwardSpeed = to255Range(forwardSpeed);\n  backwardSpeed = to255Range(backwardSpeed);\n  leftSpeed = to255Range(leftSpeed);\n  rightSpeed = to255Range(rightSpeed);\n\n  toggleBladeMotor(chval&#091;2]);\n \n  if(chval&#091;3]&gt;1000){\n\tSerial.println(\"buffer\");\n\tsoundBuzzer(HIGH);\n  }else{\n\tsoundBuzzer(LOW);\n  }\n  \n  if (isAccelerating(forwardSpeed,backwardSpeed) &amp;&amp; !isTurning(leftSpeed,rightSpeed)) {\n\t\/\/ Not turning\n\t\/\/ Get if its moving forward or backward\n\tif (forwardSpeed &gt; 0){\n  \taccelerateWheels(forwardSpeed, 1, 1);\n\t} else {\n  \treverseWheels(backwardSpeed, 1, 1);\n\t}\n  } else if (!isAccelerating(forwardSpeed,backwardSpeed) &amp;&amp; isTurning(leftSpeed,rightSpeed)) {\n\t\/\/ Not turning\n\t\/\/ Get if its moving forward or backward\n\tif (rightSpeed &gt; 0){\n  \tturnRight(rightSpeed);\n\t} else {\n  \tturnLeft(leftSpeed);\n\t}\n  } else if(rightSpeed &gt; 10 || leftSpeed &gt; 10){\n\t\/\/ Is accelerating and turning at the same time\n\t\/\/ To make it turn and move forward at the same time, we decelerate the wheels on the side where it intends to turn.\n\tif (forwardSpeed &gt; 0) {\n  \tSerial.println(\"rotate\");\n    \tif (rightSpeed &gt; 0){\n    \taccelerateWheels(forwardSpeed, 1, mapToRange(rightSpeed));\n  \t} else {\n    \taccelerateWheels(forwardSpeed, mapToRange(leftSpeed), 1);\n  \t}\n\t} else {\n    \tif (rightSpeed &gt; 0){\n    \treverseWheels(backwardSpeed, 1, mapToRange(rightSpeed));\n  \t} else {\n    \treverseWheels(backwardSpeed, mapToRange(leftSpeed), 1);\n  \t}\n\t}\n  }else {\n  stopWheels();\n  }\n}\n\nvoid loop() {\n  interrupts();\n  checkVoltage();\n  if (batteryCharged){\n\tint changeModeValue= pulseIn(PWM_MODE_SWITCH_PIN, HIGH);\n\tif(changeModeValue &gt; 1500){\n  \tif(!rcMode){\n    \tRCmodeTone();\n  \t}\n  \trcMode = true;\n  \treadRCInput();\n\n\t}else if(changeModeValue&gt;200){\n  \tif(rcMode){\n    \tautomaticModeTone();\n  \t}\n  \trcMode=false;\n  \tpcMode();\n\t}\n  }\n}\n\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">C\u00f3digo C# (Aplicaci\u00f3n en Unity)<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>using System.Collections;\nusing System.Collections.Generic;\nusing UnityEngine;\nusing System.IO.Ports;\n\npublic class ArduinoPcComunication : MonoBehaviour\n{\n\n\tSerialPort portToArduino = new SerialPort(\"COM6\", 57600);\n\tpublic bool comunication;\n\tpublic RobotMovement robot;\n\t\/\/ Start is called before the first frame update\n\tvoid Start()\n\t{\n    \tDebug.Log(\"hola\");\n   \t \n    \tforeach (string str in SerialPort.GetPortNames())\n    \t{\n        \tDebug.Log(string.Format(\"Port : {0}\", str));\n    \t}\n    \tportToArduino.Open();\n\t}\n\tvoid OnDisable()\n\t{\n    \tDebug.Log(\"disable\");\n    \tportToArduino.Close();\n\n\t}\n\t\/\/ Update is called once per frame\n\tvoid Update()\n\t{\n    \tif (comunication &amp;&amp; portToArduino.IsOpen)\n    \t{\n        \tstring data = readSerial();\n        \tif (data.StartsWith(\"G:\"))\n        \t{\n            \tdata.Replace(\"G:\", \"\");\n            \tstring&#091;] parts = data.Split(\" \");\n            \tVector2 point = new Vector2(float.Parse(parts&#091;0]), float.Parse(parts&#091;1]));\n        \t}\n        \telse\n        \t{\n            \tDebug.Log(data);\n        \t}\n    \t}\n  \t \n\t}\n\tstring readSerial()\n\t{\n    \tif (portToArduino.IsOpen)\n    \t{\n        \treturn portToArduino.ReadLine();\n    \t}\n    \treturn \"\";\n\t}\n\tpublic void writeSerial(string data)\n\t{\n    \tif (portToArduino.IsOpen &amp;&amp; comunication)\n    \t{\n        \tportToArduino.WriteLine(data);\n    \t}\n\t}\n}\n\n\n\/\/MIT License\n\/\/Copyright (c) 2023 DA LAB (https:\/\/www.youtube.com\/@DA-LAB)\n\/\/Permission is hereby granted, free of charge, to any person obtaining a copy\n\/\/of this software and associated documentation files (the \"Software\"), to deal\n\/\/in the Software without restriction, including without limitation the rights\n\/\/to use, copy, modify, merge, publish, distribute, sublicense, and\/or sell\n\/\/copies of the Software, and to permit persons to whom the Software is\n\/\/furnished to do so, subject to the following conditions:\n\/\/The above copyright notice and this permission notice shall be included in all\n\/\/copies or substantial portions of the Software.\n\/\/THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\/\/IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\/\/FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\/\/AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\/\/LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\/\/OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n\/\/SOFTWARE.\n\nusing System.Collections;\nusing System.Collections.Generic;\nusing UnityEngine;\nusing UnityEngine.UI;\nusing UnityEngine.Networking;\nusing System;\n\npublic class Map : MonoBehaviour\n{\n\tprivate string apiKey = \"tu clave de maps\";\n\tpublic float lat = 40.336643f;\n\tpublic float lon = -3.876557f;\n\tpublic int zoom = 20;\n\tpublic enum resolution { low = 1, high = 2 };\n\tpublic resolution mapResolution = resolution.low;\n\tpublic enum type { roadmap, satellite, gybrid, terrain };\n\tpublic type mapType = type.roadmap;\n\tpublic Material mapMaterial;\n\tprivate string url = \"\";\n\tpublic int mapWidth = 640;\n\tpublic int mapHeight = 640;\n\tprivate bool mapIsLoading = false; \/\/not used. Can be used to know that the map is loading\n\n\tprivate string apiKeyLast;\n\tprivate float latLast = 40.336643f;\n\tprivate float lonLast = -3.876557f;\n\tprivate int zoomLast = 12;\n\tprivate resolution mapResolutionLast = resolution.low;\n\tprivate type mapTypeLast = type.roadmap;\n\tprivate bool updateMap = true;\n\n\tpublic float latCoordsPerUnit = 3.5e-05f;\n\tpublic float lonCoordsPerUnit = 5.3e-05f;\n\n\n\t\/\/ Start is called before the first frame update\n\tvoid Start()\n\t{\n    \tStartCoroutine(GetGoogleMap());\n  \t \n\t}\n\n\t\/\/ Update is called once per frame\n\tvoid Update()\n\t{\n    \tif (updateMap &amp;&amp; (apiKeyLast != apiKey || !Mathf.Approximately(latLast, lat) || !Mathf.Approximately(lonLast, lon) || zoomLast != zoom || mapResolutionLast != mapResolution || mapTypeLast != mapType))\n    \t{\n        \tStartCoroutine(GetGoogleMap());\n        \tupdateMap = false;\n    \t}\n\t}\n\tpublic Vector2 getCoordOfPoint(Vector2 mapPosition)\n\t{\n   \t \n    \tfloat precisionLat = latCoordsPerUnit \/ zoom;\n    \tfloat precisionLon = lonCoordsPerUnit \/ zoom;\n    \tfloat pointLon = lonLast - lonCoordsPerUnit * mapPosition.x;\n    \tfloat pointLat = latLast - latCoordsPerUnit * mapPosition.y;\n    \tDebug.Log(pointLat.ToString().Replace(\",\", \".\") + \", \" + pointLon.ToString().Replace(\",\", \".\"));\n    \treturn new Vector2(pointLat, pointLon);\n   \t \n\t}\n\tpublic Vector2 getPointOfCoords(Vector2 coords)\n\t{\n   \t \n    \tfloat precisionLat = latCoordsPerUnit \/ zoom;\n    \tfloat precisionLon = lonCoordsPerUnit \/ zoom;\n    \tfloat pointLon = (coords.x - lonLast) \/ lonCoordsPerUnit;\n    \tfloat pointLat =  (coords.y - latLast) \/ latCoordsPerUnit;\n    \tDebug.Log(pointLat.ToString().Replace(\",\", \".\") + \", \" + pointLon.ToString().Replace(\",\", \".\"));\n    \treturn new Vector2(pointLat, pointLon);\n\n\t}\n\n\n\tIEnumerator GetGoogleMap()\n\t{\n    \turl = \"https:\/\/maps.googleapis.com\/maps\/api\/staticmap?center=\" + lat + \",\" + lon + \"&amp;zoom=\" + zoom + \"&amp;size=\" + mapWidth + \"x\" + mapHeight + \"&amp;scale=\" + mapResolution + \"&amp;maptype=\" + mapType + \"&amp;key=\" + apiKey;\n    \tmapIsLoading = true;\n    \tUnityWebRequest www = UnityWebRequestTexture.GetTexture(url);\n    \tyield return www.SendWebRequest();\n    \tif (www.result != UnityWebRequest.Result.Success)\n    \t{\n        \tDebug.Log(\"WWW ERROR: \" + www.error);\n    \t}\n    \telse\n    \t{\n        \tmapIsLoading = false;\n        \tmapMaterial.mainTexture = ((DownloadHandlerTexture)www.downloadHandler).texture;\n\n        \tapiKeyLast = apiKey;\n        \tlatLast = lat;\n        \tlonLast = lon;\n        \tzoomLast = zoom;\n        \tmapResolutionLast = mapResolution;\n        \tmapTypeLast = mapType;\n        \tupdateMap = true;\n    \t}\n\t}\n\n}\n\n\nusing System.Collections;\nusing System.Collections.Generic;\nusing UnityEngine;\n\npublic class SelectPoints : MonoBehaviour\n{\n\tprivate Camera camera;\n\tpublic Map map;\n\tpublic Area area;\n\tpublic GameObject prefabPoint;\n\tpublic RobotMovement robot;\n\t\/\/ Start is called before the first frame update\n\tvoid Start()\n\t{\n    \tcamera = Camera.main;\n\t}\n\n\t\/\/ Update is called once per frame\n\tvoid Update()\n\t{\n    \tif (Input.GetKeyDown(KeyCode.Mouse0))\n    \t{\n        \tselectPointInMap();\n    \t}\n\t}\n\tvoid selectPointInMap()\n\t{\n    \tRaycastHit hit;\n    \tRay ray = camera.ScreenPointToRay(Input.mousePosition);\n\n    \tif (Physics.Raycast(ray, out hit))\n    \t{\n        \tTransform objectHit = hit.transform;\n        \tVector2 point = new Vector2(hit.point.x, hit.point.z);\n        \tVector2 p = map.getCoordOfPoint(point);\n        \tmap.getPointOfCoords(p);\n        \tGameObject.Instantiate(prefabPoint, hit.point, Quaternion.identity, this.transform);\n        \tarea.points.Add(p);\n    \t}\n    \tif(area.points.Count &gt;= 4)\n    \t{\n        \trobot.startMovement();\n    \t}\n\t}\n}\n\n\nusing System.Collections;\nusing System.Collections.Generic;\nusing UnityEngine;\n\npublic class Area : MonoBehaviour\n{\n\tpublic List&lt;Vector2&gt; points;\n\tpublic bool isInArea(Vector2 point)\n\t{\n    \tPolygonCollider2D collider = gameObject.AddComponent&lt;PolygonCollider2D&gt;();\n\n    \tcollider.points = points.ToArray();\n\n    \tbool pointInside = collider.OverlapPoint(point);\n    \tDestroy(collider);\n\n    \treturn pointInside;\n\t}\n    \n}\n\n\n\n\nusing System.Collections;\nusing System.Collections.Generic;\nusing UnityEngine;\n\npublic class RobotMovement : MonoBehaviour\n{\n\tpublic Area area;\n\tpublic ArduinoPcComunication comunication;\n\tprivate bool rotating;\n\tprivate bool moveEnabled = false;\n\tpublic void startMovement()\n\t{\n    \tmoveEnabled = true;\n\t}\n\tvoid actualCoords(Vector2 coords)\n\t{\n    \tif (!moveEnabled)\n    \t{\n        \treturn;\n    \t}\n    \tVector3 worldPos = new Vector3(coords.x, 0, coords.y);\n    \tthis.transform.position = worldPos;\n    \tif (area.isInArea(coords) &amp;&amp; !rotating)\n    \t{\n        \tcomunication.writeSerial(\"F\");\n    \t}\n    \telse\n    \t{\n        \tStartCoroutine(rotateAndContinue());\n    \t}\n\t}\n\tIEnumerator rotateAndContinue()\n\t{\n    \trotating = true;\n    \tcomunication.writeSerial(\"R\");\n    \tyield return new WaitForSeconds(2f);\n    \trotating = false;\n    \tcomunication.writeSerial(\"F\");\n\t}\n}\n\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Grupo 18 Integrantes: Introducci\u00f3n La motivaci\u00f3n del proyecto surge debido a que nos dimos cuenta de que conoc\u00edamos a alguna persona con una finca como segunda residencia donde pasaba tiempo ocasionalmente. El problema reside&#46;&#46;&#46;<\/p>\n","protected":false},"author":216,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"image","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-8725","post","type-post","status-publish","format-image","hentry","category-proyectos","post_format-post-format-image"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.6 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>TERRENATOR - Cortac\u00e9sped Inteligente - Proyectos con Arduino.<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/blogs.etsii.urjc.es\/dseytr\/terrenator-cortacesped-inteligente\/\" \/>\n<meta property=\"og:locale\" content=\"es_ES\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"TERRENATOR - Cortac\u00e9sped Inteligente - Proyectos con Arduino.\" \/>\n<meta property=\"og:description\" content=\"Grupo 18 Integrantes: Introducci\u00f3n La motivaci\u00f3n del proyecto surge debido a que nos dimos cuenta de que conoc\u00edamos a alguna persona con una finca como segunda residencia donde pasaba tiempo ocasionalmente. El problema reside&#046;&#046;&#046;\" \/>\n<meta property=\"og:url\" content=\"https:\/\/blogs.etsii.urjc.es\/dseytr\/terrenator-cortacesped-inteligente\/\" \/>\n<meta property=\"og:site_name\" content=\"Proyectos con Arduino.\" \/>\n<meta property=\"article:published_time\" content=\"2024-05-08T16:56:10+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-05-08T16:56:11+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/lh7-us.googleusercontent.com\/7xLmNuOL2Jqj6zuCQVIgbcnZ2mw1Actg3JEfo7Pbj93tIkjdhnRCRhJquTKhL_bWdJ2-v3URDIztftSN-I9yPlto7BuFuYfTJyqk92xolARu0rx9PI9MQwGpxVvA-2SUYwSPTT-W9OpADMQ0dWE-I8s\" \/>\n<meta name=\"author\" content=\"dsemo2324g18\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Escrito por\" \/>\n\t<meta name=\"twitter:data1\" content=\"dsemo2324g18\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tiempo de lectura\" \/>\n\t<meta name=\"twitter:data2\" content=\"20 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/terrenator-cortacesped-inteligente\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/terrenator-cortacesped-inteligente\\\/\"},\"author\":{\"name\":\"dsemo2324g18\",\"@id\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/#\\\/schema\\\/person\\\/46c0a2a7cb761ec21f565bc18e8cb412\"},\"headline\":\"TERRENATOR &#8211; Cortac\u00e9sped Inteligente\",\"datePublished\":\"2024-05-08T16:56:10+00:00\",\"dateModified\":\"2024-05-08T16:56:11+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/terrenator-cortacesped-inteligente\\\/\"},\"wordCount\":1724,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/terrenator-cortacesped-inteligente\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/lh7-us.googleusercontent.com\\\/7xLmNuOL2Jqj6zuCQVIgbcnZ2mw1Actg3JEfo7Pbj93tIkjdhnRCRhJquTKhL_bWdJ2-v3URDIztftSN-I9yPlto7BuFuYfTJyqk92xolARu0rx9PI9MQwGpxVvA-2SUYwSPTT-W9OpADMQ0dWE-I8s\",\"articleSection\":[\"Proyectos\"],\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/terrenator-cortacesped-inteligente\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/terrenator-cortacesped-inteligente\\\/\",\"url\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/terrenator-cortacesped-inteligente\\\/\",\"name\":\"TERRENATOR - Cortac\u00e9sped Inteligente - Proyectos con Arduino.\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/terrenator-cortacesped-inteligente\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/terrenator-cortacesped-inteligente\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/lh7-us.googleusercontent.com\\\/7xLmNuOL2Jqj6zuCQVIgbcnZ2mw1Actg3JEfo7Pbj93tIkjdhnRCRhJquTKhL_bWdJ2-v3URDIztftSN-I9yPlto7BuFuYfTJyqk92xolARu0rx9PI9MQwGpxVvA-2SUYwSPTT-W9OpADMQ0dWE-I8s\",\"datePublished\":\"2024-05-08T16:56:10+00:00\",\"dateModified\":\"2024-05-08T16:56:11+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/terrenator-cortacesped-inteligente\\\/#breadcrumb\"},\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/terrenator-cortacesped-inteligente\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/terrenator-cortacesped-inteligente\\\/#primaryimage\",\"url\":\"https:\\\/\\\/lh7-us.googleusercontent.com\\\/7xLmNuOL2Jqj6zuCQVIgbcnZ2mw1Actg3JEfo7Pbj93tIkjdhnRCRhJquTKhL_bWdJ2-v3URDIztftSN-I9yPlto7BuFuYfTJyqk92xolARu0rx9PI9MQwGpxVvA-2SUYwSPTT-W9OpADMQ0dWE-I8s\",\"contentUrl\":\"https:\\\/\\\/lh7-us.googleusercontent.com\\\/7xLmNuOL2Jqj6zuCQVIgbcnZ2mw1Actg3JEfo7Pbj93tIkjdhnRCRhJquTKhL_bWdJ2-v3URDIztftSN-I9yPlto7BuFuYfTJyqk92xolARu0rx9PI9MQwGpxVvA-2SUYwSPTT-W9OpADMQ0dWE-I8s\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/terrenator-cortacesped-inteligente\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Portada\",\"item\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"TERRENATOR &#8211; Cortac\u00e9sped Inteligente\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/#website\",\"url\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/\",\"name\":\"Proyectos con Arduino.\",\"description\":\"Blog de proyectos de Arduino de alumnos de la URJC\",\"publisher\":{\"@id\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"es\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/#organization\",\"name\":\"Universidad Rey Juan Carlos\",\"url\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/wp-content\\\/uploads\\\/sites\\\/8\\\/2022\\\/05\\\/logourjc-1.jpg\",\"contentUrl\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/wp-content\\\/uploads\\\/sites\\\/8\\\/2022\\\/05\\\/logourjc-1.jpg\",\"width\":745,\"height\":288,\"caption\":\"Universidad Rey Juan Carlos\"},\"image\":{\"@id\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/#\\\/schema\\\/person\\\/46c0a2a7cb761ec21f565bc18e8cb412\",\"name\":\"dsemo2324g18\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/7f15e8480b1a8fcd9855d1f7ef51efe3db813a18b97131557c94527404ca3831?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/7f15e8480b1a8fcd9855d1f7ef51efe3db813a18b97131557c94527404ca3831?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/7f15e8480b1a8fcd9855d1f7ef51efe3db813a18b97131557c94527404ca3831?s=96&d=mm&r=g\",\"caption\":\"dsemo2324g18\"},\"url\":\"https:\\\/\\\/blogs.etsii.urjc.es\\\/dseytr\\\/author\\\/dsemo2324g18\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"TERRENATOR - Cortac\u00e9sped Inteligente - Proyectos con Arduino.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/blogs.etsii.urjc.es\/dseytr\/terrenator-cortacesped-inteligente\/","og_locale":"es_ES","og_type":"article","og_title":"TERRENATOR - Cortac\u00e9sped Inteligente - Proyectos con Arduino.","og_description":"Grupo 18 Integrantes: Introducci\u00f3n La motivaci\u00f3n del proyecto surge debido a que nos dimos cuenta de que conoc\u00edamos a alguna persona con una finca como segunda residencia donde pasaba tiempo ocasionalmente. El problema reside&#46;&#46;&#46;","og_url":"https:\/\/blogs.etsii.urjc.es\/dseytr\/terrenator-cortacesped-inteligente\/","og_site_name":"Proyectos con Arduino.","article_published_time":"2024-05-08T16:56:10+00:00","article_modified_time":"2024-05-08T16:56:11+00:00","og_image":[{"url":"https:\/\/lh7-us.googleusercontent.com\/7xLmNuOL2Jqj6zuCQVIgbcnZ2mw1Actg3JEfo7Pbj93tIkjdhnRCRhJquTKhL_bWdJ2-v3URDIztftSN-I9yPlto7BuFuYfTJyqk92xolARu0rx9PI9MQwGpxVvA-2SUYwSPTT-W9OpADMQ0dWE-I8s","type":"","width":"","height":""}],"author":"dsemo2324g18","twitter_card":"summary_large_image","twitter_misc":{"Escrito por":"dsemo2324g18","Tiempo de lectura":"20 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/blogs.etsii.urjc.es\/dseytr\/terrenator-cortacesped-inteligente\/#article","isPartOf":{"@id":"https:\/\/blogs.etsii.urjc.es\/dseytr\/terrenator-cortacesped-inteligente\/"},"author":{"name":"dsemo2324g18","@id":"https:\/\/blogs.etsii.urjc.es\/dseytr\/#\/schema\/person\/46c0a2a7cb761ec21f565bc18e8cb412"},"headline":"TERRENATOR &#8211; Cortac\u00e9sped Inteligente","datePublished":"2024-05-08T16:56:10+00:00","dateModified":"2024-05-08T16:56:11+00:00","mainEntityOfPage":{"@id":"https:\/\/blogs.etsii.urjc.es\/dseytr\/terrenator-cortacesped-inteligente\/"},"wordCount":1724,"commentCount":0,"publisher":{"@id":"https:\/\/blogs.etsii.urjc.es\/dseytr\/#organization"},"image":{"@id":"https:\/\/blogs.etsii.urjc.es\/dseytr\/terrenator-cortacesped-inteligente\/#primaryimage"},"thumbnailUrl":"https:\/\/lh7-us.googleusercontent.com\/7xLmNuOL2Jqj6zuCQVIgbcnZ2mw1Actg3JEfo7Pbj93tIkjdhnRCRhJquTKhL_bWdJ2-v3URDIztftSN-I9yPlto7BuFuYfTJyqk92xolARu0rx9PI9MQwGpxVvA-2SUYwSPTT-W9OpADMQ0dWE-I8s","articleSection":["Proyectos"],"inLanguage":"es","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/blogs.etsii.urjc.es\/dseytr\/terrenator-cortacesped-inteligente\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/blogs.etsii.urjc.es\/dseytr\/terrenator-cortacesped-inteligente\/","url":"https:\/\/blogs.etsii.urjc.es\/dseytr\/terrenator-cortacesped-inteligente\/","name":"TERRENATOR - Cortac\u00e9sped Inteligente - Proyectos con Arduino.","isPartOf":{"@id":"https:\/\/blogs.etsii.urjc.es\/dseytr\/#website"},"primaryImageOfPage":{"@id":"https:\/\/blogs.etsii.urjc.es\/dseytr\/terrenator-cortacesped-inteligente\/#primaryimage"},"image":{"@id":"https:\/\/blogs.etsii.urjc.es\/dseytr\/terrenator-cortacesped-inteligente\/#primaryimage"},"thumbnailUrl":"https:\/\/lh7-us.googleusercontent.com\/7xLmNuOL2Jqj6zuCQVIgbcnZ2mw1Actg3JEfo7Pbj93tIkjdhnRCRhJquTKhL_bWdJ2-v3URDIztftSN-I9yPlto7BuFuYfTJyqk92xolARu0rx9PI9MQwGpxVvA-2SUYwSPTT-W9OpADMQ0dWE-I8s","datePublished":"2024-05-08T16:56:10+00:00","dateModified":"2024-05-08T16:56:11+00:00","breadcrumb":{"@id":"https:\/\/blogs.etsii.urjc.es\/dseytr\/terrenator-cortacesped-inteligente\/#breadcrumb"},"inLanguage":"es","potentialAction":[{"@type":"ReadAction","target":["https:\/\/blogs.etsii.urjc.es\/dseytr\/terrenator-cortacesped-inteligente\/"]}]},{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/blogs.etsii.urjc.es\/dseytr\/terrenator-cortacesped-inteligente\/#primaryimage","url":"https:\/\/lh7-us.googleusercontent.com\/7xLmNuOL2Jqj6zuCQVIgbcnZ2mw1Actg3JEfo7Pbj93tIkjdhnRCRhJquTKhL_bWdJ2-v3URDIztftSN-I9yPlto7BuFuYfTJyqk92xolARu0rx9PI9MQwGpxVvA-2SUYwSPTT-W9OpADMQ0dWE-I8s","contentUrl":"https:\/\/lh7-us.googleusercontent.com\/7xLmNuOL2Jqj6zuCQVIgbcnZ2mw1Actg3JEfo7Pbj93tIkjdhnRCRhJquTKhL_bWdJ2-v3URDIztftSN-I9yPlto7BuFuYfTJyqk92xolARu0rx9PI9MQwGpxVvA-2SUYwSPTT-W9OpADMQ0dWE-I8s"},{"@type":"BreadcrumbList","@id":"https:\/\/blogs.etsii.urjc.es\/dseytr\/terrenator-cortacesped-inteligente\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Portada","item":"https:\/\/blogs.etsii.urjc.es\/dseytr\/"},{"@type":"ListItem","position":2,"name":"TERRENATOR &#8211; Cortac\u00e9sped Inteligente"}]},{"@type":"WebSite","@id":"https:\/\/blogs.etsii.urjc.es\/dseytr\/#website","url":"https:\/\/blogs.etsii.urjc.es\/dseytr\/","name":"Proyectos con Arduino.","description":"Blog de proyectos de Arduino de alumnos de la URJC","publisher":{"@id":"https:\/\/blogs.etsii.urjc.es\/dseytr\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/blogs.etsii.urjc.es\/dseytr\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"es"},{"@type":"Organization","@id":"https:\/\/blogs.etsii.urjc.es\/dseytr\/#organization","name":"Universidad Rey Juan Carlos","url":"https:\/\/blogs.etsii.urjc.es\/dseytr\/","logo":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/blogs.etsii.urjc.es\/dseytr\/#\/schema\/logo\/image\/","url":"https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2022\/05\/logourjc-1.jpg","contentUrl":"https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-content\/uploads\/sites\/8\/2022\/05\/logourjc-1.jpg","width":745,"height":288,"caption":"Universidad Rey Juan Carlos"},"image":{"@id":"https:\/\/blogs.etsii.urjc.es\/dseytr\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/blogs.etsii.urjc.es\/dseytr\/#\/schema\/person\/46c0a2a7cb761ec21f565bc18e8cb412","name":"dsemo2324g18","image":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/secure.gravatar.com\/avatar\/7f15e8480b1a8fcd9855d1f7ef51efe3db813a18b97131557c94527404ca3831?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/7f15e8480b1a8fcd9855d1f7ef51efe3db813a18b97131557c94527404ca3831?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/7f15e8480b1a8fcd9855d1f7ef51efe3db813a18b97131557c94527404ca3831?s=96&d=mm&r=g","caption":"dsemo2324g18"},"url":"https:\/\/blogs.etsii.urjc.es\/dseytr\/author\/dsemo2324g18\/"}]}},"_links":{"self":[{"href":"https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-json\/wp\/v2\/posts\/8725","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-json\/wp\/v2\/users\/216"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-json\/wp\/v2\/comments?post=8725"}],"version-history":[{"count":6,"href":"https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-json\/wp\/v2\/posts\/8725\/revisions"}],"predecessor-version":[{"id":8839,"href":"https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-json\/wp\/v2\/posts\/8725\/revisions\/8839"}],"wp:attachment":[{"href":"https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-json\/wp\/v2\/media?parent=8725"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-json\/wp\/v2\/categories?post=8725"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.etsii.urjc.es\/dseytr\/wp-json\/wp\/v2\/tags?post=8725"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}