<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1918280582300408186</id><updated>2011-12-19T20:56:28.658+01:00</updated><category term='robot bender URJC luz busca light search robotica sistemas'/><title type='text'>Los circuitos de bender</title><subtitle type='html'>Blog para la asignatura de Robótica de la URJC.

Alumnos:
Sara Pato González;
 Alejandro Ladera Chamorro</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://loscircuitosdebender.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1918280582300408186/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://loscircuitosdebender.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>bender</name><uri>http://www.blogger.com/profile/16632063009721296550</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Xz4N5dIgwOE/SaVr6QYKnPI/AAAAAAAAAAM/WB3MtgVVnjs/S220/bender.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>20</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1918280582300408186.post-6334521938565705429</id><published>2010-04-18T16:23:00.003+02:00</published><updated>2010-04-18T16:39:44.741+02:00</updated><title type='text'>Activar/Desactivar el Touchpad</title><content type='html'>No tiene mucho que ver con este blog, pero es algo bastante útil para los portátiles.&lt;br /&gt;&lt;br /&gt;Muchas veces el Touchpad está activado aunque conectemos el ratón, y sólo podemos desactivarlo en la configuración del ratón (si el botón no te funciona, como suele ocurrir) y se queda de forma permanente, lo cual es muy molesto si un día no puedes enchufar el ratón.&lt;br /&gt;Las soluciones que encontré me parecieron demasiado complejas, y esto es lo que he hecho:&lt;br /&gt;&lt;br /&gt;Lo primero es saber desactivar y activar el ratón, en Google sale a la primera:&lt;br /&gt;synclient TouchpadOff=1 (ó 0 para activarlo).&lt;br /&gt;&lt;br /&gt;INSTRUCCIONES:&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Creamos un script&lt;/span&gt; como éste:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;#!/bin/bash&lt;br /&gt;&lt;br /&gt;modo=`synclient -l | grep TouchpadOff | cut -d = -f 2`&lt;br /&gt;let $modo&lt;br /&gt;if [ $modo -eq 1 ]; then&lt;br /&gt;#       echo activar;&lt;br /&gt;   synclient TouchpadOff=0;&lt;br /&gt;else&lt;br /&gt;#       echo desactivar;&lt;br /&gt;   synclient TouchpadOff=1;&lt;br /&gt;fi&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Lo único que hace es cambiar el estado de TouchpaddOff.&lt;br /&gt;&lt;br /&gt;Lo guardamos donde tengamos acceso y &lt;span style="font-weight: bold;"&gt;le damos permisos de ejecución&lt;/span&gt;&lt;br /&gt;&lt;code&gt;chmod u+x nombreFichero&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Después &lt;span style="font-weight: bold;"&gt;creamos un acceso directo&lt;/span&gt; desde el teclado:&lt;br /&gt;Sistemas -&gt; Preferencias -&gt; Combinaciones de Teclas&lt;br /&gt;Le damos a añadir, le ponemos el nombre que queramos, y en Comando escribimos la ruta completa a nuestro script, por ejemplo:&lt;br /&gt;/home/alex/switchTouchpad&lt;br /&gt;&lt;br /&gt;Después hacéis click en la combinación de teclas y elegís la que queráis.&lt;br /&gt;&lt;br /&gt;Aún queda un pequeño problema, accedemos a la configuración del ratón:&lt;br /&gt;Sistemas -&gt; Preferencias -&gt; Ratón&lt;br /&gt;Pestaña Touchpad&lt;br /&gt;Tenemos que &lt;span style="font-weight: bold;"&gt;desactivar&lt;/span&gt; "Desactivar el Touchpad al escribir".&lt;br /&gt;Si no nos desactivará y activará el ratón cuando quiera, y esto no funciona.&lt;br /&gt;&lt;br /&gt;Ahora ya está listo. Cuando no queráis el ratón, pulsáis las teclas seleccionadas.&lt;br /&gt;Y si algún día lo necesitáis, lo único que debéis recordar es la combinación de teclas.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1918280582300408186-6334521938565705429?l=loscircuitosdebender.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://loscircuitosdebender.blogspot.com/feeds/6334521938565705429/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://loscircuitosdebender.blogspot.com/2010/04/activardesactivar-el-touchpad.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1918280582300408186/posts/default/6334521938565705429'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1918280582300408186/posts/default/6334521938565705429'/><link rel='alternate' type='text/html' href='http://loscircuitosdebender.blogspot.com/2010/04/activardesactivar-el-touchpad.html' title='Activar/Desactivar el Touchpad'/><author><name>Alex</name><uri>http://www.blogger.com/profile/16019735758492860502</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1918280582300408186.post-77932978049388582</id><published>2009-09-23T22:17:00.002+02:00</published><updated>2009-09-23T22:20:20.034+02:00</updated><title type='text'>Perdido pendrive</title><content type='html'>Este post es un poco raro.&lt;br /&gt;He perdido el pendrive, y en él estaba escrito mi nombre. Si alguien lo ha encontrado, puede que llegue hasta aquí.&lt;br /&gt;&lt;br /&gt;Le pido por favor que se ponga en contacto conmigo en la dirección alexlad_87@hotmail.com&lt;br /&gt;&lt;br /&gt;Muchas gracias.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1918280582300408186-77932978049388582?l=loscircuitosdebender.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://loscircuitosdebender.blogspot.com/feeds/77932978049388582/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://loscircuitosdebender.blogspot.com/2009/09/perdido-pendrive.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1918280582300408186/posts/default/77932978049388582'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1918280582300408186/posts/default/77932978049388582'/><link rel='alternate' type='text/html' href='http://loscircuitosdebender.blogspot.com/2009/09/perdido-pendrive.html' title='Perdido pendrive'/><author><name>Alex</name><uri>http://www.blogger.com/profile/16019735758492860502</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1918280582300408186.post-2921205536347689113</id><published>2009-06-04T21:05:00.005+02:00</published><updated>2009-06-06T18:07:55.802+02:00</updated><title type='text'>Prueba final en Simulador JDE/Gazebo Alex</title><content type='html'>He sacado un vídeo de la prueba con el Departamental lleno de papeleras.&lt;br /&gt;&lt;br /&gt;Existen dos papeleras en las que el robot falla al llegar a ellas, sin embargo, si quitamos ese factor (las papeleras separadas, corrigiendo la orientación teleoperando) el robot realiza el resto del recorrido, aunque con algún problema a la hora de dar la vuelta (aunque finalmente lo consigue).&lt;br /&gt;&lt;br /&gt;En este vídeo podemos verlo. Se choca con un par de ellas a la vuelta, pero eso es porque al estar grabando la pantalla no funciona como debería. Lo he probado varias veces sin estar grabando y sí funciona.&lt;br /&gt;&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/R8DRBQovZrQ&amp;amp;hl=es&amp;amp;fs=1&amp;amp;"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/R8DRBQovZrQ&amp;amp;hl=es&amp;amp;fs=1&amp;amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Sin embargo me he dado cuenta de un error que tenía:&lt;br /&gt;A la hora de decidir si seguía las indicaciones de seguridad, tenía esto:&lt;br /&gt;if (segD &gt; 10 || segI &gt; 10)&lt;br /&gt;&lt;br /&gt;Sin embargo, me he dado cuenta de que no es lo que necesitaba, es esto:&lt;br /&gt;if (abs(segD - segI) &gt; 10)&lt;br /&gt;&lt;br /&gt;He vuelto a probarlo y ahora consigue pasar bien, hace el recorrido perfectamente.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;object width="445" height="364"&gt;&lt;param name="movie" value="http://www.youtube.com/v/fkgNDrtp364&amp;hl=es&amp;fs=1&amp;color1=0x234900&amp;color2=0x4e9e00&amp;border=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/fkgNDrtp364&amp;hl=es&amp;fs=1&amp;color1=0x234900&amp;color2=0x4e9e00&amp;border=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="445" height="364"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;Mueve un poco la pared, pero no lo hace si no estoy grabando. Se acerca mucho, pero no llega a tocarla.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1918280582300408186-2921205536347689113?l=loscircuitosdebender.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://loscircuitosdebender.blogspot.com/feeds/2921205536347689113/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://loscircuitosdebender.blogspot.com/2009/06/prueba-final-en-simulador-jdegazebo.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1918280582300408186/posts/default/2921205536347689113'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1918280582300408186/posts/default/2921205536347689113'/><link rel='alternate' type='text/html' href='http://loscircuitosdebender.blogspot.com/2009/06/prueba-final-en-simulador-jdegazebo.html' title='Prueba final en Simulador JDE/Gazebo Alex'/><author><name>Alex</name><uri>http://www.blogger.com/profile/16019735758492860502</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1918280582300408186.post-4559584489216914171</id><published>2009-06-02T17:58:00.002+02:00</published><updated>2009-06-02T18:38:00.793+02:00</updated><title type='text'>Simulador JDE/Gazebo Sara</title><content type='html'>Hemos dejado nuestro robot físico, para adentrarnos en el mundo de los robots simulados, con el entorno Gazebo. Disponíamos de un mundo con el diseño del departamental y nuestro robot tenía que navegar por él sin chocarse, ayudados de las imágenes que obtuviéramos por la cámara, nuestro único sensor.&lt;br /&gt;Una vez definido el problema, había que pasar a solucionarlo… Lo primero que hice fue pasarle un filtro de color, para distinguir el suelo del resto del entorno que es lo que le estorbará al robot para navegar. Una vez hecho esto, pensé…bueno y ahora que?? Lo primero que se me ocurrió fue ir comprobando (de abajo hacía arriba, y de izquierda a derecha) los pixeles que pertenecían al suelo, y poner un umbral de pixeles mínimos de suelo que debía haber, y si encontraba ese umbral que el robot se parase (girase…)… Dándole unas vueltas a esto, me di cuenta de que no iba a llegar muy lejos… tenía un problema grande, que pasaba si me encontraba un objeto en medio del pasillo?? Era muy probable que mi robot se estampara con él, porque seguramente la suma de los pixeles a la derecha e izquierda del objeto superasen ese umbral. &lt;br /&gt;Desestimada esta idea, busqué una solución más fácil, cogería una fila de la imagen y la analizaría. Elegí la fila 210, estaba por debajo de la mitad y parecía una distancia razonable para detectar objetos con los que poder chocar (para no hacerlo claro). Y lo que hacía a continuación era bastante sencillo. Simplemente buscaba el hueco más grande de píxeles “pasillo” que hubiese en el array, calculaba el centro y hacía girar al robot mas o menos en función de ese valor medio, es decir, si me daba mas o menos alrededor del centro, el giro iba a ser cero, si me daba un poco por encima (o por debajo) le haría girar un poco y si me daba muy por encima (o muy por debajo) el giro sería mas brusco. Pues bien, esta solución tan sencilla funcionó a la primera, recorría perfectamente el pasillo y con la idea de ir siempre al centro del grupo de píxeles “pasillo” más grande, se centraba solo el robot, por lo que navegaba por el centro del pasillo sin riesgo a rozar alguna pared y que se viniera abajo todo el departamental.&lt;br /&gt;El problema vino cuando nos cambiaron el mundo…y nos añadieron miles de papeleras… en un principio yo pensé bueno, que mas da una que veinte?? Si el robot pasa una bien, tiene que pasar las veinte bien… pero ahí teníamos la “maldita papelera” en una esquina, cosa imprevista que mi robot al hacer un giro tan brusco a la derecha se comía de lleno. Así que le bajé un poco la velocidad angular y le aumenté la velocidad (sí, antes iba aún mas despacio), probé pero seguía comiéndose la papelera, total que había que bajar aún mas esa velocidad de giro, pero ya no me dio tiempo a cambiarla, porque la competición empezaba, así que mi robot se quedó en la papelera del infierno.&lt;br /&gt;&lt;br /&gt;Aquí os dejo el video para que podais verlo.&lt;br /&gt;&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/DHF_mtiN0kg&amp;amp;hl=es&amp;amp;fs=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/DHF_mtiN0kg&amp;amp;hl=es&amp;amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;Y mi código.&lt;br /&gt;&lt;br /&gt;void yourcode_iteration(void)&lt;br /&gt;{&lt;br /&gt;int y, x, i, j;&lt;br /&gt;int r,g,b;&lt;br /&gt;char matriz[SIFNTSC_COLUMNS][SIFNTSC_ROWS];&lt;br /&gt;int mediorow, mediocol;&lt;br /&gt;int maxina = 0;&lt;br /&gt;int maxact = 0;&lt;br /&gt;int beginact = -1;&lt;br /&gt;int beginina = -1;&lt;br /&gt;int comienzaact=-1;&lt;br /&gt;int comienzaina = -1;&lt;br /&gt;int seguidosact = 0;&lt;br /&gt;int seguidosina = 0;&lt;br /&gt;int medio;&lt;br /&gt;int entra = 0;&lt;br /&gt;int entra2 = 0;&lt;br /&gt;v = 350;&lt;br /&gt;for (y = 0; y &lt; SIFNTSC_ROWS; y++)&lt;br /&gt;for (x = 0; x &lt; SIFNTSC_COLUMNS; x++) {&lt;br /&gt;b = (int)(unsigned char)imagenRGB[(y*SIFNTSC_COLUMNS+x)*3];&lt;br /&gt;g = (int)(unsigned char)imagenRGB[(y*SIFNTSC_COLUMNS+x)*3+1];&lt;br /&gt;r = (int)(unsigned char)imagenRGB[(y*SIFNTSC_COLUMNS+x)*3+2];&lt;br /&gt;if (((r &gt; 230) &amp;amp;&amp;amp; (r &lt;= 255)) &amp;amp;&amp;amp; ((g &gt; 230) &amp;amp;&amp;amp; (g &lt;= 255)) &amp;amp;&amp;amp; ((b &gt; 110)  (b &lt; 140))) {&lt;br /&gt;imagenRGB[(y*SIFNTSC_COLUMNS+x)*3] = (unsigned char)255;&lt;br /&gt;imagenRGB[(y*SIFNTSC_COLUMNS+x)*3+1] = (unsigned char)255;&lt;br /&gt;imagenRGB[(y*SIFNTSC_COLUMNS+x)*3+2] = (unsigned char)255;&lt;br /&gt;matriz[x][y] = '.';&lt;br /&gt;}&lt;br /&gt;else {&lt;br /&gt;imagenRGB[(y*SIFNTSC_COLUMNS+x)*3] = (unsigned char)0;&lt;br /&gt;imagenRGB[(y*SIFNTSC_COLUMNS+x)*3+1] = (unsigned char)0;&lt;br /&gt;imagenRGB[(y*SIFNTSC_COLUMNS+x)*3+2] = (unsigned char)0;&lt;br /&gt;matriz[x][y] = '_';&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;j = 210;&lt;br /&gt;for (i = 0; i &lt; SIFNTSC_COLUMNS; i++) {&lt;br /&gt;if (matriz[i][j] == '.') {&lt;br /&gt;if (maxina &lt; seguidosina) {&lt;br /&gt;comienzaina = beginina;&lt;br /&gt;maxina = seguidosina;&lt;br /&gt;}&lt;br /&gt;beginina = -1;&lt;br /&gt;seguidosina = 0;&lt;br /&gt;if (beginact == -1) {&lt;br /&gt;beginact = i;&lt;br /&gt;seguidosact = seguidosact +1;&lt;br /&gt;}&lt;br /&gt;else&lt;br /&gt;seguidosact = seguidosact +1;&lt;br /&gt;}&lt;br /&gt;else {&lt;br /&gt;if (maxact &lt; seguidosact) {&lt;br /&gt;comienzaact = beginact;&lt;br /&gt;maxact = seguidosact;&lt;br /&gt;}&lt;br /&gt;beginact = -1;&lt;br /&gt;seguidosact = 0;&lt;br /&gt;if (beginina == -1) {&lt;br /&gt;beginina = i;&lt;br /&gt;seguidosina = seguidosina +1;&lt;br /&gt;}&lt;br /&gt;else&lt;br /&gt;seguidosina = seguidosina +1;&lt;br /&gt;}&lt;br /&gt;printf("posicion: [%d,%d], %c\n", i,j, matriz[i][j]);&lt;br /&gt;}&lt;br /&gt;if (maxact &lt; seguidosact) {&lt;br /&gt;comienzaact = beginact;&lt;br /&gt;maxact = seguidosact;&lt;br /&gt;}&lt;br /&gt;else if (maxina &lt; seguidosina) {&lt;br /&gt;comienzaina = beginina;&lt;br /&gt;maxina = seguidosina;&lt;br /&gt;}&lt;br /&gt;printf("maxact %d", maxact);&lt;br /&gt;printf("begin %d", comienzaact);&lt;br /&gt;medio = ((comienzaact + maxact) + comienzaact)/2;&lt;br /&gt;printf("medio %d", medio);&lt;br /&gt;if ( medio &gt;= 0 &amp;amp;&amp;amp; medio &lt;= 75){&lt;br /&gt;w = -65;&lt;br /&gt;v=0;&lt;br /&gt;}&lt;br /&gt;else if(medio &gt; 75 &amp;amp;&amp;amp; medio &lt;= 125) {&lt;br /&gt;w = -30;&lt;br /&gt;v=0;&lt;br /&gt;}&lt;br /&gt;else if (medio &gt; 125 &amp;amp;&amp;amp; medio &lt;= 140) {&lt;br /&gt;w = -10;&lt;br /&gt;v=0;&lt;br /&gt;}&lt;br /&gt;else if (medio &gt; 140 &amp;amp;&amp;amp; medio &lt;= 180) {&lt;br /&gt;w = 0;&lt;br /&gt;}&lt;br /&gt;else if (medio &gt; 180 &amp;amp;&amp;amp; medio &lt;= 195) {&lt;br /&gt;w = 10;&lt;br /&gt;v=0;&lt;br /&gt;}&lt;br /&gt;else if (medio &gt; 295 &amp;amp;&amp;amp; medio &lt;= 245) {&lt;br /&gt;w = 30;&lt;br /&gt;v=0;&lt;br /&gt;}&lt;br /&gt;else {//if (medio &gt; 235 &amp;amp;&amp;amp; medio &lt;= 259)&lt;br /&gt;w = 65;&lt;br /&gt;v=0;&lt;br /&gt;}&lt;br /&gt;//_exit(" ");&lt;br /&gt;printf ("salir");&lt;br /&gt;&lt;br /&gt;}&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1918280582300408186-4559584489216914171?l=loscircuitosdebender.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://loscircuitosdebender.blogspot.com/feeds/4559584489216914171/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://loscircuitosdebender.blogspot.com/2009/06/simulador-jdegazebo-sara.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1918280582300408186/posts/default/4559584489216914171'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1918280582300408186/posts/default/4559584489216914171'/><link rel='alternate' type='text/html' href='http://loscircuitosdebender.blogspot.com/2009/06/simulador-jdegazebo-sara.html' title='Simulador JDE/Gazebo Sara'/><author><name>Sad_Princess</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='33' height='26' src='http://4.bp.blogspot.com/-S_b_bSwgvHE/Tu-W2-l3GcI/AAAAAAAAAYI/YMPI2NWMpBU/s220/5369770838_6b5616eb03.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1918280582300408186.post-5100361789700455696</id><published>2009-06-01T19:27:00.005+02:00</published><updated>2009-06-01T20:54:29.143+02:00</updated><title type='text'>Simulador JDE/Gazebo Alex</title><content type='html'>En esta parte dejamos a Bender, que ya está un poco mayor y trabajamos con el simulador JDE y Gazebo, que proporciona varias herramientas de un robot virtual pioneer, como laser, y cámara en un mundo modelado, en este caso del departamental de la universidad.&lt;br /&gt;Las prácticas se programan en este caso en C, en lugar de Java, como estabamos acostumbrados hasta ahora.&lt;br /&gt;Se trata de deambular por este mundo utilizando tan sólo la visión de la cámara. Para ello nos aconsejaron aplicar un filtro a la imágen (que tenemos en una variable como array de char). Por ello lo primero es crear un filtro de color que detecte el amarillo del suelo (255,255,126 en RGB).&lt;br /&gt;En principio es simple, el problema aquí fue un poco los casting necesarios para pasar de char a entero. Básicamente pasamos de char a  unsigned char, y de ahí a int. Al contrario, sólo pasamos a unsigned char.&lt;br /&gt;&lt;br /&gt;Ésta es la función.&lt;br /&gt;&lt;span style="color: rgb(102, 102, 0);"&gt;void filtro (int cr, int cg, int cb, int threshold)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(102, 102, 0);"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(102, 102, 0);"&gt;    int x,y;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(102, 102, 0);"&gt;    int r,g,b,pos;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(102, 102, 0);"&gt;    for (y=0; y &lt;&gt;&lt;br /&gt;&lt;span style="color: rgb(102, 102, 0);"&gt;        for (x=0; x&lt;sifntsc_columns;&gt;&lt;br /&gt;&lt;span style="color: rgb(102, 102, 0);"&gt;        {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(102, 102, 0);"&gt;            pos = (y*SIFNTSC_COLUMNS + x)*3;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(102, 102, 0);"&gt;            b = (int) (unsigned char) imagenRGB [pos];&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(102, 102, 0);"&gt;            g = (int) (unsigned char) imagenRGB [pos+1];&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(102, 102, 0);"&gt;            r = (int) (unsigned char) imagenRGB [pos+2];&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(102, 102, 0);"&gt;            if ((r &gt; (cr-threshold) &amp;amp;&amp;amp; r &lt; (cr+threshold) &amp;amp;&amp;amp;&lt;/span&gt;&lt;/sifntsc_columns;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(102, 102, 0);"&gt;&lt;span style="color: rgb(102, 102, 0);"&gt;&lt;sifntsc_columns;&gt;&lt;span style="color: rgb(102, 102, 0);"&gt; g &gt; (cg-threshold) &amp;amp;&amp;amp; g &lt; (cg+threshold) &amp;amp;&amp;amp; b &lt; (cb+threshold) &amp;amp;&amp;amp; b &gt; (cb-threshold)))&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(102, 102, 0);"&gt;            {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(102, 102, 0);"&gt;                imagenRGB [pos]= (unsigned char) 255;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(102, 102, 0);"&gt;                imagenRGB [pos+1]= (unsigned char) 255;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(102, 102, 0);"&gt;                imagenRGB [pos+2]= (unsigned char) 255;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(102, 102, 0);"&gt;            }&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(102, 102, 0);"&gt;            else&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(102, 102, 0);"&gt;            {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(102, 102, 0);"&gt;                imagenRGB [pos]= (unsigned char) 0;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(102, 102, 0);"&gt;                imagenRGB [pos+1]= (unsigned char) 0;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(102, 102, 0);"&gt;                imagenRGB [pos+2]= (unsigned char) 0;&lt;/span&gt;&lt;/sifntsc_columns;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(102, 102, 0);"&gt;&lt;span style="color: rgb(102, 102, 0);"&gt;&lt;sifntsc_columns;&gt;&lt;br /&gt;&lt;span style="color: rgb(102, 102, 0);"&gt;            }&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(102, 102, 0);"&gt;        }&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(102, 102, 0);"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Threshold es utilizado para indicar el rango que aceptamos por bueno. Por ejemplo, en este caso para detectar el amarillo, escribía:&lt;br /&gt;&lt;span style="color: rgb(102, 102, 0);"&gt;filtro (255,255,126,10);&lt;/span&gt;&lt;br /&gt;Por tanto, si era 246,255,135 detecta el color como amarillo.&lt;br /&gt;&lt;br /&gt;Los resultados se modifican en la misma var&lt;/sifntsc_columns;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(102, 102, 0);"&gt;&lt;span style="color: rgb(102, 102, 0);"&gt;&lt;sifntsc_columns;&gt;iable global, escribiendo blanco (255,255,255) si encuentra amarillo, y negro (0,0,0) en caso contrario.&lt;br /&gt;&lt;br /&gt;Para comprobar que era correcto me hice un "visualizador" chapucero, escribiendo espacios para no negro y puntos para negro (aunque realmente sólo miro un color, después del filtro todos son iguales).&lt;br /&gt;Como obviamente no cabe todo en la pantalla (la resolución de la imágen era de 320x240), tomaba muestras para que encajara en 80x50:&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;for (y = 0; y &lt; x="0;" relx =" x*(SIFNTSC_COLUMNS/80);" rely =" y*(SIFNTSC_ROWS/50);"&gt;&lt;/span&gt;&lt;/sifntsc_columns;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(102, 102, 0);"&gt;&lt;span style="color: rgb(102, 102, 0);"&gt;&lt;sifntsc_columns;&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;A la hora de analizar la imágen, me decidí por parametrizarla, sacar ciertos valores que fuesen determinantes. Estos fueron los que tomé:&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/sifntsc_columns;&gt;&lt;/span&gt;&lt;/span&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_iG_mDAoGbpQ/SiQUaQWZ6fI/AAAAAAAAACg/sE7ySqnvmhM/s1600-h/Parametrizaci%C3%B3n.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 222px; height: 400px;" src="http://1.bp.blogspot.com/_iG_mDAoGbpQ/SiQUaQWZ6fI/AAAAAAAAACg/sE7ySqnvmhM/s400/Parametrizaci%C3%B3n.jpg" alt="" id="BLOGGER_PHOTO_ID_5342417499266345458" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="color: rgb(102, 102, 0);"&gt;&lt;span style="color: rgb(102, 102, 0);"&gt;&lt;sifntsc_columns;&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Mi intención era era utilizar los ángulos de inclinación izquierdo y derecho (alpha y beta). Pero esto incluía multitud de problemas  no sabía si era muy fiable, y al final no lo incluí.&lt;br /&gt;Este es el código:&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(102, 0, 0);"&gt;void analizarImagen (int *h, int *alpha, int *beta, int *latX, int *latY, int *j, int *k, int *segI, int *segD)&lt;br /&gt;{&lt;br /&gt;  int x,y;&lt;br /&gt;  int maxY=0;&lt;br /&gt;  int maxX=0;&lt;br /&gt;  int seguidos=0;&lt;br /&gt;&lt;br /&gt;  //Hallamos el punto más alto&lt;br /&gt;  for (x=0; x&lt;sifntsc_columns; while="" y="SIFNTSC_ROWS-1;"&gt; 0 &amp;amp;&amp;amp; ((int) (unsigned char) imagenRGB[(y*SIFNTSC_COLUMNS + x)*3]) == 255)&lt;br /&gt;          y--;&lt;br /&gt;      if (x==SIFNTSC_ROWS/2)&lt;br /&gt;          *h=SIFNTSC_ROWS-y;&lt;br /&gt;      if (SIFNTSC_ROWS-y &gt; maxY)&lt;br /&gt;      {&lt;br /&gt;          maxY=SIFNTSC_ROWS-y;&lt;br /&gt;          maxX=x;&lt;br /&gt;          seguidos=0;&lt;br /&gt;      }&lt;br /&gt;      else if (SIFNTSC_ROWS-y == maxY)&lt;br /&gt;          seguidos++;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  //Hallamos medida de seguridad izquierda&lt;br /&gt;  y=SIFNTSC_ROWS-1;&lt;br /&gt;  x=0;&lt;br /&gt;  while (x &lt; segi="x;" y="SIFNTSC_ROWS-1;" x="SIFNTSC_COLUMNS-1;"&gt; 0 &amp;amp;&amp;amp; ((int) (unsigned char) imagenRGB[(y*SIFNTSC_COLUMNS + x)*3]) != 255)&lt;br /&gt;      x--;&lt;br /&gt;  *segD=SIFNTSC_COLUMNS-x;&lt;br /&gt;&lt;br /&gt;  //Hallamos desviación izquierda&lt;br /&gt;  y=SIFNTSC_ROWS-maxY+1;&lt;br /&gt;  x=0;&lt;br /&gt;  while (x &lt; latx="x;" y="SIFNTSC_ROWS-maxY+1;" x="SIFNTSC_COLUMNS-1;"&gt; 0 &amp;amp;&amp;amp; ((int) (unsigned char) imagenRGB[(y*SIFNTSC_COLUMNS + x)*3]) != 255)&lt;br /&gt;      x--;&lt;br /&gt;  *latY=SIFNTSC_COLUMNS-x;&lt;br /&gt;&lt;br /&gt;  //Hallamos altura izquierda&lt;br /&gt;  x=0;&lt;br /&gt;  y=SIFNTSC_ROWS-1;&lt;br /&gt;  while (y &gt; 0 &amp;amp;&amp;amp; ((int) (unsigned char) imagenRGB[(y*SIFNTSC_COLUMNS + x)*3]) == 255)&lt;br /&gt;      y--;&lt;br /&gt;  *j=SIFNTSC_ROWS-y;&lt;br /&gt;&lt;br /&gt;  //Hallamos altura derecha&lt;br /&gt;  x=SIFNTSC_COLUMNS-1;&lt;br /&gt;  y=SIFNTSC_ROWS-1;&lt;br /&gt;  while (y &gt; 0 &amp;amp;&amp;amp; ((int) (unsigned char) imagenRGB[(y*SIFNTSC_COLUMNS + x)*3]) == 255)&lt;br /&gt;      y--;&lt;br /&gt;  *k=SIFNTSC_ROWS-y;&lt;br /&gt;}&lt;/sifntsc_columns;&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;En un principio la altura h era el punto máximo, después vi que está idea no era buena y decidí que fuese la medida del punto medio.&lt;br /&gt;Quizá esto fue uno de mis errores, era demasiado variable y tenía altas probabilidades de error y no ser lo que quería, quizá hubiese sido mejor una media de varios puntos por el centro.&lt;br /&gt;Las medidas segI y segD las incluí después y no estaban previstas, y sin embargo han resultado bastante útiles.&lt;br /&gt;Después de esto ya sólo quedaba la lógica del programa, es decir, como utilizar estos datos.&lt;br /&gt;Había considerado varios casos, y luego añadí algunos más.&lt;br /&gt;En la imágen de arriba vemos el caso simple, sólo hay que avanzar.&lt;br /&gt;Lo primero que hacíamos era atender a las variables segI y segD, que pueden indicarnos un choque inminente, lo que hacemos es que la velocidad angular sea proporcional a la diferencia de ambas. De esta fomra girará más o menos rápido según la necesidad.&lt;br /&gt;Esto sirve para tres cosas:&lt;br /&gt;&lt;/span&gt;&lt;/sifntsc_columns;&gt;&lt;/span&gt;&lt;/span&gt;&lt;ol&gt;&lt;li&gt;Choques inminentes&lt;/li&gt;&lt;li&gt;Centrarse en el pasillo&lt;/li&gt;&lt;li&gt;Ayuda en los giros, cuando lleguemos aproximadamente a la mitad del giro una será mucho más grande que la otra, y girará de forma adecuada.&lt;/li&gt;&lt;/ol&gt;Me paso con casi todas las variables y lo comentaré ahora.&lt;br /&gt;Esta lógica de proporcionalidad parece estar bien, pero como vimos en clase y comprobé en la práctica, tiene grandes fallos. Con una proporción simple el robot oscila muchísimo. Implentar un control PID se me hacía algo complicado, porque no tenía una función de como van cambiando las variables. Lo que hicé para evitarlo fue hacer una media entre la diferencia de las variables, y la velocidad angular anterior: (segD-segI +w )/2.&lt;br /&gt;Aquí tuve que probar varias cosas, como aumentar la proporción que dependía de la medida anterior para que acelerara más despacio, por ejemplo (segD-segI + w*2)/3.&lt;br /&gt;En la realidad este equilibrio era un poco precario.&lt;br /&gt;&lt;br /&gt;También tengo que decir que en los giros tube muchísimos problemas, porque en principio no me funcionaba bien, todo ello se debió a que se me olvidó aplicar la media a estas dos variables y se chocaba con la pared interior por eso.&lt;br /&gt;&lt;br /&gt;Si las dos anteriores eran muy parecidas, utilizaba j y k.&lt;br /&gt;Realmente son muy parecidas a las anteriores, pero las sustituye cuando estamos en una situación como la de la imágen superior, en pasillos más estrechos.&lt;br /&gt;Si también son muy parecidas, quiere decir que estamos centrados y andamos rectos.&lt;br /&gt;Entonces utilizamos las variables latX y latY, que nos conducen al centro del pasillo, y si hay obstáculos que hacen que el centro esté desplazado, tienden a este.&lt;br /&gt;Aquí también pudo haber un pequeño problema, ya que sólo se tiene en cuenta si las anteriores son las correctas. Quizá debía haberlas incorporado antes.&lt;br /&gt;&lt;br /&gt;Esto debía ser suficiente para resolver cualquier situación, pero en los giros w se hacía demasiado alta y chocaba con la pared anterior.&lt;br /&gt;Después me di cuenta de que se debía al problema de la media que dije antes, que no me di cuenta de hacerla para segI y segD.&lt;br /&gt;Por eso utilicé un pequeño truco, acercarme a la pared.&lt;br /&gt;En principio, el giro debía comenzar en el momento en que desaparece la pared del lado al que vamos a girar. Lo que hicé fue que en ese momento actuara otro código, que ponía w a cero, y sólo actualizaba v (no lo he dicho antes, pero v es proporcional a la altura h, de forma suave, con la media, como en el resto de medidas y además en ocasiones le restamos w, para que no vaya muy rápido al girar). Este código dejaba de ejecutarse si h era menor que una cierta medida, que estaba puesta entre 40 y 55).&lt;br /&gt;En ese momento se dejaba actuar el código normal.&lt;br /&gt;Como aún así, no solucionaba correctamente el problema (por lo dicho antes), pasé a crear otro fragmento de código especial para el giro.&lt;br /&gt;Al posicionar, poníamos una variable (girando) a 1, de forma que al dejar de ejecutarse, entrara en la parte del código destinada a girar. Giraba de una forma más suave, y aún no estaba terminada cuando me di cuenta del error de la media.&lt;br /&gt;Entonces rápidamente abandoné esta parte, y comprobé que funcionaba correctamente.&lt;br /&gt;&lt;br /&gt;Ahora me encontraba con otro problema, al llegar a la parte donde tenemos dos posibles giros, no sabía que hacer, porque al ir justo por el centro y acercarse, no se decantaba por ningún lado, o giraba bruscamente. Entonces retomé el código de girar, pero sólo entraba cuando teníamos esta situación, entonces simplemente si no había ninguna posibilidad de decantarse, por defecto w pasaba a valer -3, lo suficiente para que se decantara por la derecha.&lt;br /&gt;El código de girar deja de ejecutarse cuando estamos más o menos encaminados.&lt;br /&gt;(La altura es mayor que la diferencia de los lados, y además es mayor de 30).&lt;br /&gt;&lt;br /&gt;No había tenido en cuenta hasta ahora la posibilidad de tener que dar la vuelta. Así que al final cree un código que si detectaba poca velocidad (que implica poca altura) y que la parte superior de la imágen es estrecha, gira a un lado u otro en función de donde esté situada la parte superior.&lt;br /&gt;&lt;br /&gt;También incluí después un limitador de velocidad angular (si sobrepasaba 40, en un sentido u otro, pasaba a ser 40).&lt;br /&gt;&lt;br /&gt;Este es el código de esta parte:&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;analizarImagen (&amp;amp;h,&amp;amp;alpha,&amp;amp;beta,&amp;amp;latX,&amp;amp;latY,&amp;amp;j,&amp;amp;k,&amp;amp;segI,&amp;amp;segD);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;    &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;    if (((abs (h-k) &lt;&gt;55) //Va a girar, se acerca un poco&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;    {&lt;/span&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;        w=0;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;        &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;        v=h*10;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;        printf ("Posicionando");&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;        if ((abs (h-k) &lt;&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;            giro = 0;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;        else&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;            giro = 1;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;    else&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;    {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;        hInicial = -1;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;        if (giro == 0) //Está girando&amp;amp;&amp;amp; (abs (j-k) &gt; 10)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;        {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;            v = h*10;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;            if (j &gt; k)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;            {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;                ladoRelevante= k;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;                w = 30;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;            }&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;            else&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;            {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;                ladoRelevante= j;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;                w = -30;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;            }&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;             &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;            if (h &gt; (2*abs (j-k)))&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;            {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;                //Giros lentos, porque está terminando&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;                w = (latY-latX)/4;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;                if (w == 0)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;                    w = (j-k)/4;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;                if (w == 0) //Si no sabe donde girar, a la derecha&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;                    w = -3;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;            }&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;                 &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;            &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;            //Si ya hemos encotrado el final del pasillo y más o menos estamos posicionados&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;            //dejamos de girar (la altura máxima es mayor que la diferencia de los lados)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;            if (h &gt; abs (j-k) &amp;amp;&amp;amp; (ladoRelevante &lt;&gt; 30)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;                giro=1;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;            printf ("Girando");&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;        }&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;        else&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;        {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;            giro = 1;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;    &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;            if (segD &gt; 10 || segI &gt; 10)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;                w = (segD - segI + w*2)/6;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;            else&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;                if (abs (j-k)&lt;1)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;                    if (abs(latX-latY)&lt;1&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;                        w=0;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;                    else&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;                        w = ((latY-latX) + (j-k))/2; //Media con lo que daría el otro para que no oscile&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;                else&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;                    w = ((j-k)+w*3)/6;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;        &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;            v = (h*20 + v*2)/4 - abs(w); //Para que no oscile&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;        }&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;    if (v &lt;&gt;1 &amp;amp;&amp;amp; segD&gt;1) &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;    {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;        v=0;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;        if (latX &gt; latY)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;            w = -20;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;        else&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;            w = -20;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;    &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;    if (w&gt;40)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;        w=40;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;        &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;    if (w&lt;-40)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;        w=-40;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Finalmente&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; conseguí que el robot fuera más o menos deprisa (unos 1000 en recta, 1200 incluso), y recorriera cualquier parte del mundo que teníamos, girando a izquierda, derecha, y dando la vuelta. En el vídeo podemos verlo. Va unas 5 veces más rápido que la realidad, porque el capturador de la pantalla quería coger imágenes a 10 fps y sólo lo consiguió a 2 fps.&lt;br /&gt;&lt;br /&gt;&lt;object width="445" height="364"&gt;&lt;param name="movie" value="http://www.youtube.com/v/FAKEkdwNwoU&amp;hl=es&amp;fs=1&amp;color1=0xe1600f&amp;color2=0xfebd01&amp;border=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/FAKEkdwNwoU&amp;hl=es&amp;fs=1&amp;color1=0xe1600f&amp;color2=0xfebd01&amp;border=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="445" height="364"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;En la práctica final sólo llegué a la tercera papelera. El problema era que había demasiado hueco detrás de algunas papeleras, y esto no estaba previsto. Con los ángulos quizás hubiera ido mejor, o incluyendo esa posibilidad, o tomando las medidas de una forma distinta.&lt;br /&gt;Si no hubiese sido por esto, habría ido rápido y bien, y el único problema quizá hubiera sido el dar la vuelta, porque estaba abierto.&lt;br /&gt;El giro de la última esquina, con esa papelera tan "bien" puesta, lo probé después y lo pasaba bien, sin llegar a tocarla (aunque por poco).&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1918280582300408186-5100361789700455696?l=loscircuitosdebender.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://loscircuitosdebender.blogspot.com/feeds/5100361789700455696/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://loscircuitosdebender.blogspot.com/2009/06/simulador-jdegazebo-alex.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1918280582300408186/posts/default/5100361789700455696'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1918280582300408186/posts/default/5100361789700455696'/><link rel='alternate' type='text/html' href='http://loscircuitosdebender.blogspot.com/2009/06/simulador-jdegazebo-alex.html' title='Simulador JDE/Gazebo Alex'/><author><name>Alex</name><uri>http://www.blogger.com/profile/16019735758492860502</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_iG_mDAoGbpQ/SiQUaQWZ6fI/AAAAAAAAACg/sE7ySqnvmhM/s72-c/Parametrizaci%C3%B3n.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1918280582300408186.post-258875613163278330</id><published>2009-06-01T00:22:00.004+02:00</published><updated>2009-06-01T19:25:58.331+02:00</updated><title type='text'>Visualización en pantalla</title><content type='html'>Y llegaron las comunicaciones.&lt;br /&gt;Desde hace un tiempo, Bender conseguía comunicarse con el ordenador y traspasaba todos los datos que recogía, así como los que calculaba.&lt;br /&gt;En el robot era muy sencillo implementar la interfaz gráfica. Con la clase LCD no teníamos más que indicar los dos puntos de una recta, y ésta se imprimía en la pantalla, sin tocar nada más.&lt;br /&gt;Con el ordenador la cosa se complica. Es necesario utilizar alguna de las clases que proporciona Java, y éstas no son muy intuitivas.&lt;br /&gt;Pero finalmente conseguimos imprimirlo, creamos la ventana, transmitimos los datos, y dibujamos con el método paint.&lt;br /&gt;Lo que hicimos fue heredar de la clase JFrame, que es algo parecido a una ventana.&lt;br /&gt;Después no tenemos más que sustituir el método paint, e incluir en main una secuencia de instrucciones que crean el nuevo JFrame y lo ejecutan en un Thread aparte.&lt;br /&gt;Aquí surgió un error, ya que para recibir los datos, lo hacíamos en main, justo después de crear el nuevo Thread, y la variable global donde poníamos los datos no quedaba actualizada y no imprimía nada.&lt;br /&gt;Lo que hicimos puede considerarse una pequeña chapucilla, aunque creo que no lo es.&lt;br /&gt;En el método run del nuevo Thread, incluímos todo el código destinado a la comunicación con Bender. Así conseguimos que funcionara.&lt;br /&gt;Antes de esto, como pensaba que podían funcionar en threads distintos, incluí bloque synchronized antes de modificar o leer la variable global donde estaban los datos.&lt;br /&gt;&lt;br /&gt;Sin embargo surgió otra complicación.&lt;br /&gt;El siguiente paso obvio era no tener que lanzar el programa cada vez que queremos imprimir un escaneo, no tiene sentido entonces crear una nueva conexión cada vez. Así que tubimos que modificar el programa de Bender, para que sólo crease un nuevo canal de comunicación si no tenía ninguno antes.&lt;br /&gt;Sin embargo, al lanzar el prama, no se ejecutaba el método paint, o sólo lo hacía una vez al principio.&lt;br /&gt;Esto se debía a que pusimos un bucle infinito en el código de las comunicaciones, para que siempre esté pidiendo nuevos datos. Y el método para repintar la ventana no se ejecuta automáticamente.&lt;br /&gt;En principio pensaba que podía tratarse de que debían ir en Threads distintos (y de hecho sería mejor así) y probé haciendo yield pero no funcionó. Después me di cuenta que en el programa anterior sólo se actualizaba una vez.&lt;br /&gt;Así que utilizamos un método de la ventana, repaint, pero no funcionaba.&lt;br /&gt;Por fin, un poco por probara, ejecutamos el método paint. Él problema de éste método es que hay que pasarle un objeto Graphics, entonces probé con un método que tiene ventana, getGraphics, y por fin funcionó bien.&lt;br /&gt;&lt;br /&gt;Aquí podemos ver dos vídeos, el primero está configurado con una resolución de un grado.&lt;br /&gt;&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/WPPzSa9GPRQ&amp;hl=es&amp;fs=1&amp;color1=0xe1600f&amp;color2=0xfebd01"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/WPPzSa9GPRQ&amp;hl=es&amp;fs=1&amp;color1=0xe1600f&amp;color2=0xfebd01" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;El segundo con cinco grados.&lt;br /&gt;&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/AzibJ80prhE&amp;hl=es&amp;fs=1&amp;color1=0x402061&amp;color2=0x9461ca"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/AzibJ80prhE&amp;hl=es&amp;fs=1&amp;color1=0x402061&amp;color2=0x9461ca" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;¡Y aquí lo podemos ver en acción!&lt;br /&gt;&lt;br /&gt;&lt;object width="445" height="364"&gt;&lt;param name="movie" value="http://www.youtube.com/v/aEO0ONukjJ0&amp;hl=es&amp;fs=1&amp;color1=0x006699&amp;color2=0x54abd6&amp;border=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/aEO0ONukjJ0&amp;hl=es&amp;fs=1&amp;color1=0x006699&amp;color2=0x54abd6&amp;border=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="445" height="364"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;Para las conexiones con el ordenador utilizamos el USB. Está todo preparado para, modificando una variable (blue=true) utilicemos la conexión por Bluetooth, sin embargo no he conseguido que funcione el driver, y por tanto no lo puedo mostrar.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1918280582300408186-258875613163278330?l=loscircuitosdebender.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://loscircuitosdebender.blogspot.com/feeds/258875613163278330/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://loscircuitosdebender.blogspot.com/2009/06/visualizacion-en-pantalla.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1918280582300408186/posts/default/258875613163278330'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1918280582300408186/posts/default/258875613163278330'/><link rel='alternate' type='text/html' href='http://loscircuitosdebender.blogspot.com/2009/06/visualizacion-en-pantalla.html' title='Visualización en pantalla'/><author><name>Alex</name><uri>http://www.blogger.com/profile/16019735758492860502</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1918280582300408186.post-681067790979729976</id><published>2009-05-31T17:14:00.011+02:00</published><updated>2009-05-31T20:46:10.131+02:00</updated><title type='text'>El radar: Última actualización</title><content type='html'>Finalmente conseguimos implementar la función para los pasillos.&lt;br /&gt;&lt;br /&gt;Intentaremos explicarlo brevemente.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_iG_mDAoGbpQ/SiK5vxf0LRI/AAAAAAAAACI/xHf3nenxKUI/s1600-h/Pasillo1.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 260px;" src="http://4.bp.blogspot.com/_iG_mDAoGbpQ/SiK5vxf0LRI/AAAAAAAAACI/xHf3nenxKUI/s400/Pasillo1.jpg" alt="" id="BLOGGER_PHOTO_ID_5342036338406599954" border="0" /&gt;&lt;/a&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_iG_mDAoGbpQ/SiK51tX3pdI/AAAAAAAAACY/jNDdC9ri3SM/s1600-h/Pasillo3.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 307px;" src="http://2.bp.blogspot.com/_iG_mDAoGbpQ/SiK51tX3pdI/AAAAAAAAACY/jNDdC9ri3SM/s400/Pasillo3.jpg" alt="" id="BLOGGER_PHOTO_ID_5342036440378746322" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;El objetivo es no chocarse con nada.&lt;br /&gt;En principio, si en ese rango de 20º (por defecto, aunque puede variar) no tenemos ningún obstáculo, suponíamos que podíamos pasar. Sin embargo, si en ese pasillo, del mismo ancho que el robot y centrado en la dirección que evaluamos, existe algún punto que queda fuera del ángulo, vamos a chocarnos con él.&lt;br /&gt;Esto es algo que puede ocurrir, por ejemplo, cuando intentamos pasar por una "puerta" y estamos demasiado cerca.&lt;br /&gt;Lo que tratamos de hacer ahora es comprobar si tenemos algún punto de estos, y en caso de encontrarlo, éste será el que defina la nota para esa dirección.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_iG_mDAoGbpQ/SiK5y_JCSpI/AAAAAAAAACQ/9ChDqoKeJ4Y/s1600-h/Pasillo2+Formulas.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 82px;" src="http://2.bp.blogspot.com/_iG_mDAoGbpQ/SiK5y_JCSpI/AAAAAAAAACQ/9ChDqoKeJ4Y/s400/Pasillo2+Formulas.jpg" alt="" id="BLOGGER_PHOTO_ID_5342036393608759954" border="0" /&gt;&lt;/a&gt;Lo que necesitamos es conocer la distancia desde la recta de la dirección candidata al cada uno de los puntos que hemos tomado con el sensor.&lt;br /&gt;En el caso esa distancia (d) sea menos que la mitad del ancho del robot, significa que está dentro del pasillo. Lo que hacemos entonces es calcular la distancia que puede recorrer el robot, que es la distancia en la misma dirección theta desde la recta perpendicular al punto (min).&lt;br /&gt;Por tanto exploramos para cada dirección theta, todos los puntos que tenemos y nos quedamos con el mínimo de todos los que entren en el pasillo.&lt;br /&gt;Realmente no probamos todos los puntos, sino los que varían como mucho 90º de la dirección theta (el resto no influyen) y por supuesto de aquellos de los que tenemos datos.&lt;br /&gt;&lt;br /&gt;La función implementada en java es esta:&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;private static int pasillo (int dir, int[] resultado)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;    {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;        minim = 255;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;        //No interesa lo que queda fuera de la recta perpendicular&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;        for (i = Math.max(0, (dir-90)/resol); i &lt;&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;        {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;            //Calculamos la distancia entre el punto y la recta de la dirección&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;            dis =(int)(Math.abs((Math.tan(Math.toRadians(dir)))&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;                    *Math.cos(Math.toRadians(i*resol))&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;                    *resultado[i]&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;                    -Math.sin(Math.toRadians(i*resol))*resultado[i])/&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;            (Math.sqrt(Math.pow((Math.tan(Math.toRadians(dir))),2)+1)));&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;            //Comprobamos si entra en el pasillo&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;            if (dis &lt; (anchoRobot/2))&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;            {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;                //En caso de entrar comprobamos cuanto podemos avanzar sin chocar&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;                if ((i*resol) &lt;&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;                {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;                    if (Math.sin(Math.toRadians((dir+90)-(i*resol)))*resultado[i] &lt;&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;                    {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;                        minim = (int)(Math.sin(Math.toRadians((dir+90)-(i*resol)))*resultado[i]);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;                    }&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;                }&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;                else&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;                {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;                    if (Math.sin(Math.toRadians(90-(dir-i*resol)))*resultado[i] &lt;&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;                    {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;                        minim = (int)(Math.sin(Math.toRadians(90-(dir-i*resol)))*resultado[i]);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;                    }&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;                }&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;            }&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;        }&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;        return minim;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Esta función nos devuelve la mínima distancia que realmente puede recorrer la la dirección theta proporcionada.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Sin embargo como podemos ver, la complejidad para calcular todo esto es muy grande (tiende a O(n^2))  y el problema es que requiere muchos cálculos y memoria, y cuando lo metimos en el ladrillo del NXT no funcionaba, debido a que se quedaba sin memoria.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Poniéndolas como globales conseguíamos que funcionara, pero tardaba unos 35s.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;De hecho hicimos que diera un beep cada vez que terminaba una dirección (hay 37 con resolución a 5º), los 10 primeros iban más o menos rápidos, el resto tardaban cada vez más porque ya se había quedado sin memoria.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Después nos dimos cuenta que quizá no necesitábamos tantas medidas (cada 5º). Y entonces a lo mejor había funcionado.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Probamos la función en el ordenador, con los datos proporcinados por el sensor y traspasados por USB y funciona perfectamente y decide no atravesar puertas pequeñas demasiado cerca.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Aquí tenemos una muestra de que funciona:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;object style="color: rgb(0, 0, 0);" width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/6TolOJNqkYY&amp;amp;hl=es&amp;amp;fs=1&amp;amp;color1=0x5d1719&amp;amp;color2=0xcd311b"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/6TolOJNqkYY&amp;amp;hl=es&amp;amp;fs=1&amp;amp;color1=0x5d1719&amp;amp;color2=0xcd311b" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;En el vídeo, aunque no avanza porque está desactivado, podemos ver como teniendo un buen hueco, no escoge esa dirección porque no cabe.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1918280582300408186-681067790979729976?l=loscircuitosdebender.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://loscircuitosdebender.blogspot.com/feeds/681067790979729976/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://loscircuitosdebender.blogspot.com/2009/05/el-radar-ultima-actualizacion.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1918280582300408186/posts/default/681067790979729976'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1918280582300408186/posts/default/681067790979729976'/><link rel='alternate' type='text/html' href='http://loscircuitosdebender.blogspot.com/2009/05/el-radar-ultima-actualizacion.html' title='El radar: Última actualización'/><author><name>Alex</name><uri>http://www.blogger.com/profile/16019735758492860502</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_iG_mDAoGbpQ/SiK5vxf0LRI/AAAAAAAAACI/xHf3nenxKUI/s72-c/Pasillo1.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1918280582300408186.post-2315436168961541853</id><published>2009-04-22T12:40:00.004+02:00</published><updated>2009-04-25T20:32:06.326+02:00</updated><title type='text'>El radar: Al detalle</title><content type='html'>Vamos a especificar algunos detalles técnicos de la práctica final, y de la parte de navegación que hemos hecho estos días.&lt;br /&gt;&lt;br /&gt;Para mover el sensor de ultrasonidos, estamos utilizando el método rotateTo en lugar de rotate.&lt;br /&gt;En principio los dos métodos son iguales, pero eso sólo ocurriría en un motor ideal. Sin embargo, se pueden producir pequeños errores en el movimiento. Si le decimos que rote 20º, puede girar entre 18º-22º (por poner un ejemplo).&lt;br /&gt;En principio esto nos daría igual, pero lo malo es que estos errores son acumulativos. Hicimos una prueba, y con rotate, si girábamos 180º en tomas de 1º, acababa girando unos 230º, mucho error.&lt;br /&gt;&lt;br /&gt;Sin embargo con rotateTo esto no ocurre porque, a pesar de tener el mismo margen de error, este no es acumulativo. Si giramos a la posición 5º, y luego queremos girar a la posición 10º, da igual si al principio se quedó en 3º, en 5º, en 6º, o en 20º. Irá a la posición 10º, con las mismas posibilidades de error, pero no acumuladas.&lt;br /&gt;&lt;br /&gt;Para la impresión por pantalla utilizamos trigonometría básica, teníamos la hipotenusa, teníamos el ángulo, hallar los dos catetos estaba tirado.&lt;br /&gt;La escala la hicimos utilizando las constantes de LCD.SCREEN_WIDTH/2 y LCD.SCREEN_HEIGHT.&lt;br /&gt;El ancho lo dividimos entre dos porque hemos colocado el robot en medio, y la medida más larga será la mitad. En este caso además, debíamos sumarle LCD.SCREEN_WIDTH, para que los negativos pasaran a ser la parte izquierda y los positivos la parte derecha de la pantalla.&lt;br /&gt;El único problema que tuvimos aquí fue acordarnos de los radianes, hasta que nos dimos cuenta, las medidas se iban dando vueltas por la pantalla.&lt;br /&gt;&lt;br /&gt;El tema de la navegación ya es algo más complicado.&lt;br /&gt;Al principio nos definimos varias constantes, entre ellas la resolución a utilizar, la distancia mínima, y el ángulo base.&lt;br /&gt;&lt;br /&gt;La distancia mínima es una distancia de seguridad, que nos permite un cierto recorrido sin chocar.&lt;br /&gt;El ángulo base, es un ángulo que definimos para dividir el espacio. Estos se solapan, es decir, con una resolución de 5º, y un ángulo base de 20º, el primero va de 0 a 20, el segundo de 5 a 25, etc.&lt;br /&gt;&lt;br /&gt;Después de tomar las medidas, aplicamos un filtro, para eliminar ciertas medidas "extrañas", típicamente una muy alta (en torno a los 255, que también puede indicar un error) entre dos más discretas.&lt;br /&gt;&lt;br /&gt;Seguidamente asignamos una nota a estos espacios en función de si cumplen la distancia mínima y de cuanto puede recorrer el robot. Actualmente utilizamos la media para asignar las notas, funciona bien, aunque nos estamos planteando utilizar el mínimo.&lt;br /&gt;&lt;br /&gt;A partir de ahora trabajamos con estas notas. Detectamos cual es la mejor y buscamos los grupos seguidos más grandes. Esto es, si la nota máxima es de 45, buscamos el conjunto seguido de notas máximas. En este caso, para admitir pequeñas variaciones, aceptamos en el grupo notas un 10% más bajas que la máxima, en este caso, más de 41. Podríamos bajar un poco más, aunque de momento funciona bien, las pruebas dirán. Pero sí es importante para medidas altas, normalmente 255, para admitir desde 220.&lt;br /&gt;Hay que tener en cuenta que hablamos de notas máximas, no de medidas máximas. ¡Siempre notas! De no ser así tendríamos problemas con picos en las medidas.&lt;br /&gt;&lt;br /&gt;Una vez tenemos el inicio del mayor grupo y su tamaño, escogemos como mejor dirección la que esté en medio.&lt;br /&gt;Para saber cuanto podemos andar buscamos la &lt;span style="font-weight: bold;"&gt;medida&lt;/span&gt; mínima en un rango de la mitad del ángulo base a cada lado (con un ángulo de 20º, 10º a cada lado). Estamos pensando en ampliar este márgen para que detecte bien las cosas, pero tendríamos que tener en cuenta que podemos salirnos del rango de medidas que tenemos. Sin embargo estamos esperando a ver los resultados de otra función que tenemos pensada para ver si aplicamos esta subida o no.&lt;br /&gt;&lt;br /&gt;La función tratará de evitar que choquemos si, por ejemplo, cerca de una "puerta" en la que tenemos un espacio de 20º o más en el que no detectamos nada, pero en el hueco no entramos.&lt;br /&gt;¡Iremos dando más detalles!&lt;br /&gt;&lt;br /&gt;También hemos implementado una conexión USB para pasar todos los datos al ordenador. Nos dió problemas en los ordenadores de la universidad y acabamos intentandolo en casa.&lt;br /&gt;También hubo muchos problemas porque no encotraba los drivers, hasta que después de googlear muchísimo y mirar las implementaciones de las comunicaciones, encontramos una entrada en el foro de Introducción a la Robótica de Carlos Agüero en el que explicaba que debíamos copiar el archivo libjlibnxt.so en /usr/lib. En lugar de copiar hicimos un enlace simbólico, y funcionó sin tocar nada más.&lt;br /&gt;&lt;br /&gt;Sin embargo para hacer lo mismo con bluetooth no hemos sido capaces. Hemos mirado muchísima documentación, hemos probado muchas cosas, como hacer lo mismo con libjbluez.so, con los archivos de $NXT_HOME/3rdparty/lib (libbluecove.so y demás, extraidos de bluecove-gpl.jar) utilizar el fichero de configuración para cambiar a bluez, para cambiar a bluecove... nada ha dado resultado (a pesar de que nxjupload y nxjbrowse funciona por bluetooth).&lt;br /&gt;Si no fuera por esto, lo tendríamos funcionando, y además seleccionando la conexión (USB o bluetooth).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1918280582300408186-2315436168961541853?l=loscircuitosdebender.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://loscircuitosdebender.blogspot.com/feeds/2315436168961541853/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://loscircuitosdebender.blogspot.com/2009/04/el-radar-al-detalle.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1918280582300408186/posts/default/2315436168961541853'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1918280582300408186/posts/default/2315436168961541853'/><link rel='alternate' type='text/html' href='http://loscircuitosdebender.blogspot.com/2009/04/el-radar-al-detalle.html' title='El radar: Al detalle'/><author><name>Alex</name><uri>http://www.blogger.com/profile/16019735758492860502</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1918280582300408186.post-3333266884730271864</id><published>2009-04-05T19:34:00.005+02:00</published><updated>2009-04-05T19:53:07.248+02:00</updated><title type='text'>Siguiendo bien las líneas con comportamientos</title><content type='html'>&lt;span style="color: rgb(51, 0, 51);"&gt;Después de andar trasteando un poco y aunque al final conseguimos solucionar la práctica de los comportamientos, se nos quedo una espinita clavada con el maldito "ismoving". Última solución, mirar los fuentes.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 0, 51);"&gt;Hemos revisado el código fuente de Arbitrator, Navigator, Motor y BasicMotor. Resulta que los motores tienen en principio tres (que nos importen) estados, FORWARD, BACKWARD y STOP. Su ismoving significa simplemente que no este ni en FORWARD ni en BACKWARD (puede estar también en estado FLOAT, pero este no le utilizamos, en este caso el motor va suelto, se deja que pare el solo).&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 0, 51);"&gt;Sin embargo, en Motor, añaden la funcionalidad de rotateTo, que luego utiliza Navigator.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 0, 51);"&gt;Para esto añaden una variable booleana _isrotating. Y su ismoving es que no este ni FORWARD ni BACKWARD y que además _isrotating sea falso.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 0, 51);"&gt;El método Stop actualiza el estado del motor a Stop y se supone que siempre que se cambia un estado, _isrotating es puesto a false.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 0, 51);"&gt;El problema es que tienen un Thread corriendo, que se encarga de que si se pasa rotando, de la vuelta, y así indefinidamente, aunque con ciertos límites. Este Thread cambia velocidades, modos (FORWARD, BACKWARD y STOP) y hace un montón de cosas, un poco complicado.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 0, 51);"&gt;Nuestro problema (comprobado y depurado) es que no salía de un bucle porque se quedaba parado (al ejecutarse un supress) y no estaba en la línea negra, sin embargo ismoving seguía devolviendo true. Probamos cambiando el supress de avanzar (que era parar cada motor por separado) por navigator.stop; pero esto tampoco funciona (un rápido vistazo del código muestra que parar cada motor es lo que hace navigator.stop). Lo que dedicimos al final fue no utilizar el método ismoving de motor, sino el metodo isStopped (que pertenece a BasicMotor) del motor que movemos. De esta forma, pasamos del _isrotating, lo que en principio sería peligroso, aunque no tanto, porque para rotar lo hace con FORWARD y BACKWARD.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 0, 51);"&gt;&lt;br /&gt;Y bueno, parece que funciona:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;object height="344" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/Lfe8TwC1IvY&amp;amp;hl=es&amp;amp;fs=1&amp;amp;color1=0x402061&amp;amp;color2=0x9461ca"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/Lfe8TwC1IvY&amp;amp;hl=es&amp;amp;fs=1&amp;amp;color1=0x402061&amp;amp;color2=0x9461ca" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" height="344" width="425"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 0, 51);"&gt;Y por cierto, algo curioso. El método suppress no se ejecuta siempre, sino solo cuando cambiamos a un comportamiento con más prioridad. Si pasamos por ejemplo del comportamiento cero del array, al uno, no se ejecuta ningún supress.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1918280582300408186-3333266884730271864?l=loscircuitosdebender.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://loscircuitosdebender.blogspot.com/feeds/3333266884730271864/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://loscircuitosdebender.blogspot.com/2009/04/siguiendo-bien-las-lineas-con.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1918280582300408186/posts/default/3333266884730271864'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1918280582300408186/posts/default/3333266884730271864'/><link rel='alternate' type='text/html' href='http://loscircuitosdebender.blogspot.com/2009/04/siguiendo-bien-las-lineas-con.html' title='Siguiendo bien las líneas con comportamientos'/><author><name>Alex</name><uri>http://www.blogger.com/profile/16019735758492860502</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1918280582300408186.post-7005991843445243523</id><published>2009-04-03T01:04:00.005+02:00</published><updated>2009-04-03T01:35:11.565+02:00</updated><title type='text'>Práctica final: El radar</title><content type='html'>&lt;span style="color: rgb(0, 0, 153);"&gt;Ahora Bender se está convirtiendo en una temible máquina de guerra (aunque de momento como radar).&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;No queremos dar muchos detalles por el momento, ya que es la práctica final y aún estamos empezando. De momento ya hemos logrado que haga un barrido y lo muestre por pantalla (la clase Radar). Lo más difícil, y a lo que más tiempo hemos dedicado ha sido a montar el sensor (en las 2h de clase lo teníamos programado, excepto por un detalle que ya comentaremos -Mu tonto-), el diseño ha resultado ser extremadamente sencillo y ligero, cumpliendo perfectamente su cometido. Así funciona:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/G0Dic8zrlbY&amp;amp;hl=es&amp;amp;fs=1&amp;amp;color1=0x006699&amp;amp;color2=0x54abd6"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/G0Dic8zrlbY&amp;amp;hl=es&amp;amp;fs=1&amp;amp;color1=0x006699&amp;amp;color2=0x54abd6" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;Y este es el resultado:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_iG_mDAoGbpQ/SdVHouv-NpI/AAAAAAAAAB4/S68J608fGPo/s1600-h/Resultado.JPG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 240px;" src="http://4.bp.blogspot.com/_iG_mDAoGbpQ/SdVHouv-NpI/AAAAAAAAAB4/S68J608fGPo/s320/Resultado.JPG" alt="" id="BLOGGER_PHOTO_ID_5320237299877688978" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;El "agujero" que se ve (entre donde estoy yo, y donde apunta a la puerta, esa especie de linea que se aleja al limite situada casi en el centro) es consecuencia de mi brazo o mi mano sujetando la cámara.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1918280582300408186-7005991843445243523?l=loscircuitosdebender.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://loscircuitosdebender.blogspot.com/feeds/7005991843445243523/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://loscircuitosdebender.blogspot.com/2009/04/practica-final-el-radar.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1918280582300408186/posts/default/7005991843445243523'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1918280582300408186/posts/default/7005991843445243523'/><link rel='alternate' type='text/html' href='http://loscircuitosdebender.blogspot.com/2009/04/practica-final-el-radar.html' title='Práctica final: El radar'/><author><name>Alex</name><uri>http://www.blogger.com/profile/16019735758492860502</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_iG_mDAoGbpQ/SdVHouv-NpI/AAAAAAAAAB4/S68J608fGPo/s72-c/Resultado.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1918280582300408186.post-9149072328165791693</id><published>2009-03-26T00:48:00.008+01:00</published><updated>2009-03-31T22:15:58.120+02:00</updated><title type='text'>Siguiendo lineas</title><content type='html'>&lt;span style="color: rgb(51, 51, 51);"&gt;Esta práctica ha sido con toda seguridad la más difícil hasta ahora.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 51);"&gt;Se trata de seguir una línea negra sobre fondo blanco, hasta ahí bien. El problema es utilizar los comportamientos de leJos.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 51);"&gt;Desde un principio pensamos que lo mejor sería utilizar dos comportamientos:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 51);"&gt;1. Avanzar, siempre takeControl siempre devuelve verdadero. Lo único que hace es poner la velocidad adecuada y avanzar. Al salir detiene los motores.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 51);"&gt;2. Girar, takeControl devuelve verdadero cuando detecta blanco en el sensor. En la clase principal lo hemos calibrado, 0-&gt;negro, 100-&gt;blanco. Como sabemos que varía un poco, le pusimos verdadero siempre que detecta más de 80.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 51);"&gt;Lo que hace es girar 10º a un lado y a otro, 20º después, 30º, 40º, ... de esta forma encontramos el más cercano. Como normalmente estará cerca, no perderemos demasiado tiempo. Al salir detiene los motores.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 51);"&gt;La implementación fue sencilla, pero llegaron los problemas. Aún seguimos sin saber por qué, pero una vez que se metía en un comportamiento, y a pesar de que el arbitro sabía que debía darle el control a otro (eso indicaban los takeControl), nunca cambiaba. De esta forma, como calibramos primero el blanco y luego el negro, simplemente avanzaba como si no hubiera un mañana.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 51);"&gt;Para nuestra desesperación, a pesar de las multiples trazas, lo único que hacía que cambiase el control era poner sleeps después de las ejecuciones. Eso nos daba un plazo (de la misma duración que el sleep) para cambiar. Si se pasaba ese plazo, vuelta a lo de antes.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 51);"&gt;Como último intento, copia&amp;amp;pega&amp;amp;colorea del ejemplo del enunciado. Lo copiamos, funcionaba, y lo retocamos para que se comportase para seguir líneas (copiar&amp;amp;pegar del proyecto anterior) y... sorpresa!! FUNCIONA!! Estuvimos planteándonos colgar los dos códigos y ofrecer una recompensa por encontrar las 7 diferencias, pero si son iguales!!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 51);"&gt;Ahora ya sólo quedaba resolver algún problemilla, y es que de vez en cuando, el robot se paraba al salir de la línea, y sólo continuaba si volvías a meterlo. Unas trazas y pruebas más tarde, descubrimos el problema.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 51);"&gt;Para realizar la acción de girar, se giraba con steer, retornando inmediatamente, y para conseguir parar si encontraba negro, nos metíamos en un bucle con un sleep. El bucle sólo finalizaba al encontrar negro o cuando la rueda dejaba de moverse.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 51);"&gt;El problema era que si se ponía a girar, e inmediatamente encontraba negro, se ejecutaba alguna instrucción de las de parada (en los supress) y detenía las ruedas. Sin embargo, hasta que no termina la acción de girar, no ejecuta la acción de avanzar, y esta nunca termina porque sorprendetemente, ismoving seguía retornando verdadero, y como la luz no cambia, ahí se queda.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 51);"&gt;Tuvimos que rediseñarlo completamente para eliminar estos sleep, y ahora gira de 5º en 5º y comprueba la luz.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/xCJuP1QECEo&amp;amp;hl=es&amp;amp;fs=1"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/xCJuP1QECEo&amp;amp;hl=es&amp;amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/AQd8_Hoa6Ds&amp;amp;hl=es&amp;amp;fs=1"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/AQd8_Hoa6Ds&amp;amp;hl=es&amp;amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;Como no podemos subir archivos, escribo aquí el código utilizado:&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0); font-family: courier new;"&gt;import lejos.nxt.*;&lt;br /&gt;import lejos.subsumption.*;&lt;br /&gt;&lt;br /&gt;public class SeguirLineas&lt;br /&gt;{&lt;br /&gt;    public static void main(String [] args) {&lt;br /&gt;    &lt;br /&gt;        LightSensor LuzP3 = new LightSensor (SensorPort.S3);&lt;br /&gt;     &lt;br /&gt;         LuzP3.setFloodlight(true);&lt;br /&gt;     &lt;br /&gt;         LCD.clear();&lt;br /&gt;         LCD.drawString("Calibrar",3,4);&lt;br /&gt;         LCD.drawString("alto",5,6);&lt;br /&gt;         Button.waitForPress();&lt;br /&gt;         LuzP3.calibrateHigh();&lt;br /&gt;     &lt;br /&gt;         LCD.clear();&lt;br /&gt;         LCD.drawString("Calibrar",3,4);&lt;br /&gt;         LCD.drawString("bajo",5,6);&lt;br /&gt;         Button.waitForPress();&lt;br /&gt;         LuzP3.calibrateLow();&lt;br /&gt;     &lt;br /&gt;     &lt;br /&gt;       Behavior b1 = new Avanza();&lt;br /&gt;       Behavior b2 = new Gira(LuzP3);&lt;br /&gt;       Behavior [] bArray = {b1, b2};&lt;br /&gt;       Arbitrator arby = new Arbitrator(bArray);&lt;br /&gt;       arby.start();&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(102, 0, 0);"&gt;import lejos.subsumption.*;&lt;br /&gt;import lejos.nxt.*;&lt;br /&gt;import lejos.navigation.*;&lt;br /&gt;&lt;br /&gt;public class Gira implements Behavior&lt;br /&gt;{&lt;br /&gt; public LightSensor luz;&lt;br /&gt; private Pilot navigator = new Pilot(5.6f, 11.25f, Motor.A, Motor.C);&lt;br /&gt;&lt;br /&gt; public Uno (LightSensor sensor)&lt;br /&gt; {&lt;br /&gt;     luz=sensor;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public boolean takeControl() {&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 102, 0); font-family: courier new;"&gt;&lt;span style="color: rgb(102, 0, 0);"&gt;        //Consideramos blanco más de un 80% de luz (sobre lo calibrado)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;&lt;span style="color: rgb(102, 0, 0);"&gt;&lt;span style="font-family: courier new;"&gt;        LCD.clear();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;      LCD.drawInt(luz.readValue(), 3, 4);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;      if (luz.readValue()&gt;80)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;          LCD.drawString("true", 3, 6);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;      else&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;          LCD.drawString("false", 3, 6);&lt;/span&gt;&lt;br /&gt;   &lt;br /&gt;&lt;span style="font-family: courier new;"&gt;     return (luz.readValue()&gt;80);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;  }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;  public void suppress() {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;      navigator.stop();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;  }&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;  public void action() {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;      navigator.stop();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;      navigator.setSpeed(180);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;      for (int i=10; i&lt;180&gt;=20; i=i+10)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;      {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;          MoverPeroParar ( 2*i-10);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;          if (luz.readValue()&gt;=20)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;          {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;              MoverPeroParar (-2*i);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;          }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;      }&lt;/span&gt;&lt;br /&gt;   &lt;br /&gt;&lt;span style="font-family: courier new;"&gt;      navigator.stop();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;  }&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;  private void MoverPeroParar (int cantidad)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;  {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;      int contador=0;&lt;/span&gt;&lt;br /&gt;   &lt;br /&gt;&lt;span style="font-family: courier new;"&gt;      if (cantidad&gt;0)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;      {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;          while (luz.readValue()&gt;=20 &amp;amp;&amp;amp; contador&lt;/span&gt;&lt;cantidad) contador="contador+5;" try="" catch="" exception="" else="" while=""&gt;&lt;span style="font-family: courier new;"&gt;=20 &amp;amp;&amp;amp; contador&gt;cantidad)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;          {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;              contador = contador-5;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;              navigator.steer(200,-5,true);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;              try    {Thread.sleep(20);}    catch (Exception e) {}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;          }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;      }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;  }&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;import lejos.subsumption.*;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;import lejos.nxt.*;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;public class Avanza implements Behavior&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;  public boolean takeControl()&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;  {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;     return true;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;  }&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;  public void suppress() {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;     Motor.A.stop();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;     Motor.C.stop();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;  }&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;  public void action() {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;      Motor.A.setSpeed(360);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;      Motor.C.setSpeed(360);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;     Motor.A.forward();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;     Motor.C.forward();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;  }&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/cantidad)&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1918280582300408186-9149072328165791693?l=loscircuitosdebender.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://loscircuitosdebender.blogspot.com/feeds/9149072328165791693/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://loscircuitosdebender.blogspot.com/2009/03/siguiendo-lineas.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1918280582300408186/posts/default/9149072328165791693'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1918280582300408186/posts/default/9149072328165791693'/><link rel='alternate' type='text/html' href='http://loscircuitosdebender.blogspot.com/2009/03/siguiendo-lineas.html' title='Siguiendo lineas'/><author><name>Alex</name><uri>http://www.blogger.com/profile/16019735758492860502</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1918280582300408186.post-3860228437972685368</id><published>2009-03-25T20:20:00.003+01:00</published><updated>2009-03-25T20:33:13.353+01:00</updated><title type='text'>Practica Opcional: Proyectos en la red</title><content type='html'>Hoy hemos estado buscando distintos proyectos en internet sobre el robot Lego. El que más nos ha sorprendido ha sido un robot que era capaz de resolver un cubo de rubik en menos de un minuto!&lt;br /&gt;El creador de este proyecto es Daniele Benedettelli un ingeniero industrial italiano.&lt;br /&gt;Lo más curioso de este robot es que usa muy pocas piezas, algunos datos técnicos que hemos encontrado han sido los siguientes:&lt;br /&gt;- Un servomotor actúa de junta prismática que empuja el lado del cubo&lt;br /&gt;- Un servomotor rota la plataforma giratoria del robot&lt;br /&gt;- Un servomotor tiene una doble función para ayudar el brazo empujador a acomodar el brazo en el soporte y para sujetar el cubo mientras la base inferior rotatoria gira.&lt;br /&gt;- Dos sensores de contacto como detectores de límite de los brazos&lt;br /&gt;- Un sensor de luz para encontrar la posición inicial de la base rotatoria.&lt;br /&gt;&lt;br /&gt;Pero mejor verlo vosotros mismos:&lt;br /&gt;&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/3QOvEG27Gt4&amp;hl=es&amp;fs=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/3QOvEG27Gt4&amp;hl=es&amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1918280582300408186-3860228437972685368?l=loscircuitosdebender.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://loscircuitosdebender.blogspot.com/feeds/3860228437972685368/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://loscircuitosdebender.blogspot.com/2009/03/practica-opcional-proyectos-en-la-red.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1918280582300408186/posts/default/3860228437972685368'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1918280582300408186/posts/default/3860228437972685368'/><link rel='alternate' type='text/html' href='http://loscircuitosdebender.blogspot.com/2009/03/practica-opcional-proyectos-en-la-red.html' title='Practica Opcional: Proyectos en la red'/><author><name>bender</name><uri>http://www.blogger.com/profile/16632063009721296550</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Xz4N5dIgwOE/SaVr6QYKnPI/AAAAAAAAAAM/WB3MtgVVnjs/S220/bender.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1918280582300408186.post-7145313230286239589</id><published>2009-03-25T02:48:00.002+01:00</published><updated>2009-03-25T02:54:50.137+01:00</updated><title type='text'>Esquivando con multihilo</title><content type='html'>&lt;span style="color: rgb(0, 0, 153);"&gt;Esta práctica consiste en usar dos threads distintos para que el robot esquive objetos de una forma simple.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;Tenemos un hilo para cada rueda. La derecha siempre está avanzando, mientras que la izquierda detecta si hay un objeto a menos de 50 cm (30 de Bender) del sensor de ultrasonidos utilizado. En ese caso detiene la rueda durante 200 ms. En caso contrario avanza.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;De esta forma Bender girará a la izquierda siempre que encuentre un objeto a menos de 30 cm.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/FhHzpKR1kBw&amp;hl=es&amp;fs=1&amp;color1=0x006699&amp;color2=0x54abd6"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/FhHzpKR1kBw&amp;hl=es&amp;fs=1&amp;color1=0x006699&amp;color2=0x54abd6" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1918280582300408186-7145313230286239589?l=loscircuitosdebender.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://loscircuitosdebender.blogspot.com/feeds/7145313230286239589/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://loscircuitosdebender.blogspot.com/2009/03/esquivando-con-multihilo.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1918280582300408186/posts/default/7145313230286239589'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1918280582300408186/posts/default/7145313230286239589'/><link rel='alternate' type='text/html' href='http://loscircuitosdebender.blogspot.com/2009/03/esquivando-con-multihilo.html' title='Esquivando con multihilo'/><author><name>Alex</name><uri>http://www.blogger.com/profile/16019735758492860502</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1918280582300408186.post-8873893662136020052</id><published>2009-03-23T19:00:00.007+01:00</published><updated>2009-03-23T19:36:02.833+01:00</updated><title type='text'>Un día en el campo</title><content type='html'>&lt;span style="color: rgb(0, 102, 0);"&gt;Hoy Bender se ha dado una vueltecita por el campo.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_iG_mDAoGbpQ/ScfWBnDisPI/AAAAAAAAABw/zJhTLCwwglA/s1600-h/IMG_5805.JPG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 240px;" src="http://2.bp.blogspot.com/_iG_mDAoGbpQ/ScfWBnDisPI/AAAAAAAAABw/zJhTLCwwglA/s320/IMG_5805.JPG" alt="" id="BLOGGER_PHOTO_ID_5316453208286212338" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;Ha jugado con la fauna de la zona...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_iG_mDAoGbpQ/ScfQ3ggb5iI/AAAAAAAAAAU/G3_B7D1ajWk/s1600-h/IMG_5806.JPG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 240px;" src="http://3.bp.blogspot.com/_iG_mDAoGbpQ/ScfQ3ggb5iI/AAAAAAAAAAU/G3_B7D1ajWk/s320/IMG_5806.JPG" alt="" id="BLOGGER_PHOTO_ID_5316447537171523106" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;y ha comprobado que no es un robot del campo:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/1gxJf96yai8&amp;amp;hl=es&amp;amp;fs=1&amp;amp;color1=0x234900&amp;amp;color2=0x4e9e00"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/1gxJf96yai8&amp;amp;hl=es&amp;amp;fs=1&amp;amp;color1=0x234900&amp;amp;color2=0x4e9e00" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1918280582300408186-8873893662136020052?l=loscircuitosdebender.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://loscircuitosdebender.blogspot.com/feeds/8873893662136020052/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://loscircuitosdebender.blogspot.com/2009/03/un-dia-en-el-campo.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1918280582300408186/posts/default/8873893662136020052'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1918280582300408186/posts/default/8873893662136020052'/><link rel='alternate' type='text/html' href='http://loscircuitosdebender.blogspot.com/2009/03/un-dia-en-el-campo.html' title='Un día en el campo'/><author><name>Alex</name><uri>http://www.blogger.com/profile/16019735758492860502</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_iG_mDAoGbpQ/ScfWBnDisPI/AAAAAAAAABw/zJhTLCwwglA/s72-c/IMG_5805.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1918280582300408186.post-3216519263472701692</id><published>2009-03-23T18:02:00.002+01:00</published><updated>2009-03-23T18:57:37.769+01:00</updated><title type='text'>Recorrido en ocho</title><content type='html'>&lt;span style="color: rgb(204, 102, 0);"&gt;Para esta práctica Bender debía hacer un recorrido en forma de ocho utilizando la clase Pilot.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(204, 102, 0);"&gt;Lo que no nos quedo muy claro es si tenía que recorrer 1 metro en forma de ocho, o sí debía recorrer un metro recto, hacer un lazo, recorrer otro metro, y hacer el otro lazo. Así que lo hicimos de las dos formas, así no hay confusión.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(204, 102, 0);"&gt;Lo más difícil en esta práctica eran los lazos. Empezando por el ocho corto, debía recorrer en los 360º, 50 cm. Sin embargo no tenemos ninguna forma explícita de saber eso. Hicimos una prueba utilizando steer, y con un cálculo un poco a ojo, conseguimos que recorriera 52 cm.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/mtJ5R2U31nA&amp;hl=es&amp;fs=1&amp;color1=0xe1600f&amp;color2=0xfebd01"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/mtJ5R2U31nA&amp;hl=es&amp;fs=1&amp;color1=0xe1600f&amp;color2=0xfebd01" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(204, 102, 0);"&gt;Para el ocho largo era más complicado, porque al recorrer más distancia, debía estar más ajustado. El recorrido sería avanzar 1 metro, girar 270º (tres cuartos), avanzar otro metro, y volver a girar otros 270º en el sentido contrario. Calculamos cuanto debía recorrer en esos 270º-&gt;235.62. Finalmente recorre 239 y acaba prácticamente en el mismo sitio desde el que partió.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/YT8JcHvzdFs&amp;hl=es&amp;fs=1&amp;color1=0xe1600f&amp;color2=0xfebd01"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/YT8JcHvzdFs&amp;hl=es&amp;fs=1&amp;color1=0xe1600f&amp;color2=0xfebd01" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1918280582300408186-3216519263472701692?l=loscircuitosdebender.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://loscircuitosdebender.blogspot.com/feeds/3216519263472701692/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://loscircuitosdebender.blogspot.com/2009/03/recorrido-en-ocho.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1918280582300408186/posts/default/3216519263472701692'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1918280582300408186/posts/default/3216519263472701692'/><link rel='alternate' type='text/html' href='http://loscircuitosdebender.blogspot.com/2009/03/recorrido-en-ocho.html' title='Recorrido en ocho'/><author><name>Alex</name><uri>http://www.blogger.com/profile/16019735758492860502</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1918280582300408186.post-8936316978062206605</id><published>2009-03-12T01:34:00.005+01:00</published><updated>2009-03-12T01:46:02.170+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='robot bender URJC luz busca light search robotica sistemas'/><title type='text'>Buscando "La Luz"</title><content type='html'>&lt;span style="color: rgb(204, 153, 51);"&gt;Bender ha abierto un poco los ojos y ahora es capaz de distinguir la luz y la oscuridad. Tanto le ha gustado este nuevo sentido, que la busca ansiosamente.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(204, 153, 51);"&gt;Comienza a caminar, y si encuentra un salto un poco brusco, y detecta menos luz, dará un paso atrás y se girara hacia cualquier lado una cantidad aleatoria, si en ese nuevo lugar hay aún menos luz que antes, volverá a girar, así hasta que encuentre más luz que en el último giro.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(204, 153, 51);"&gt;Pero eso no es todo. Si después de un rato avanzando nota que pierde demasiada luz, se dará media vuelta por donde ha venido.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 102, 0);"&gt;Observémoslo:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/xneSF44cJqA&amp;hl=en&amp;fs=1&amp;color1=0xe1600f&amp;color2=0xfebd01"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/xneSF44cJqA&amp;hl=en&amp;fs=1&amp;color1=0xe1600f&amp;color2=0xfebd01" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1918280582300408186-8936316978062206605?l=loscircuitosdebender.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://loscircuitosdebender.blogspot.com/feeds/8936316978062206605/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://loscircuitosdebender.blogspot.com/2009/03/buscando-la-luz_12.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1918280582300408186/posts/default/8936316978062206605'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1918280582300408186/posts/default/8936316978062206605'/><link rel='alternate' type='text/html' href='http://loscircuitosdebender.blogspot.com/2009/03/buscando-la-luz_12.html' title='Buscando &quot;La Luz&quot;'/><author><name>bender</name><uri>http://www.blogger.com/profile/16632063009721296550</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Xz4N5dIgwOE/SaVr6QYKnPI/AAAAAAAAAAM/WB3MtgVVnjs/S220/bender.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1918280582300408186.post-1453617478558086119</id><published>2009-03-06T01:34:00.005+01:00</published><updated>2009-03-12T01:45:53.250+01:00</updated><title type='text'>Práctica 2: El rebotador</title><content type='html'>&lt;span style="color: rgb(153, 0, 0);font-size:130%;" &gt;&lt;span style="font-family:trebuchet ms;"&gt;¡BENDER QUIERE SER LIBRE!&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(102, 0, 0);"&gt;Pero antes necesita aprender algunas cosas...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/jaOGWstoQzc&amp;hl=en&amp;fs=1&amp;color1=0x5d1719&amp;color2=0xcd311b"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/jaOGWstoQzc&amp;hl=en&amp;fs=1&amp;color1=0x5d1719&amp;color2=0xcd311b" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(102, 0, 0);"&gt;Caca... por las paredes no se sube&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/b142cAet4Ew&amp;amp;hl=es&amp;amp;fs=1&amp;amp;color1=0x5d1719&amp;amp;color2=0xcd311b"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/b142cAet4Ew&amp;amp;hl=es&amp;amp;fs=1&amp;amp;color1=0x5d1719&amp;amp;color2=0xcd311b" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(102, 0, 0);"&gt;¡Así sí!&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1918280582300408186-1453617478558086119?l=loscircuitosdebender.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://loscircuitosdebender.blogspot.com/feeds/1453617478558086119/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://loscircuitosdebender.blogspot.com/2009/03/practica-2-el-rebotador.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1918280582300408186/posts/default/1453617478558086119'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1918280582300408186/posts/default/1453617478558086119'/><link rel='alternate' type='text/html' href='http://loscircuitosdebender.blogspot.com/2009/03/practica-2-el-rebotador.html' title='Práctica 2: El rebotador'/><author><name>bender</name><uri>http://www.blogger.com/profile/16632063009721296550</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Xz4N5dIgwOE/SaVr6QYKnPI/AAAAAAAAAAM/WB3MtgVVnjs/S220/bender.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1918280582300408186.post-8651132398682804755</id><published>2009-03-06T01:20:00.017+01:00</published><updated>2009-03-06T01:34:09.410+01:00</updated><title type='text'>Práctica 1: Enséñamelo todo</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="color: rgb(0, 0, 102);font-family:verdana;" &gt;Este es Bender algo más funcional, de momento ya se mueve con sus tres motores.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);font-family:verdana;" &gt;Tiene tres opciones, rotar 45º las ruedas hacia adelante, moverse continuamente adelante, o moverse continuamente atrás. El botón escape sale del programa. Para parar sin salir, en este caso hay que rotar.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);font-family:verdana;" &gt;Además Bender nos enseña lo que está haciendo en cada momento mediante mensajes en la pantalla.&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight: bold; font-style: italic; color: rgb(51, 51, 255);"&gt;&lt;/span&gt;&lt;blockquote&gt;&lt;span style="font-weight: bold; font-style: italic; color: rgb(51, 51, 255);"&gt;¡Cuidado que se escapa!&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/FykUbN7DJv0&amp;amp;hl=es&amp;amp;fs=1&amp;amp;color1=0x006699&amp;amp;color2=0x54abd6"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/FykUbN7DJv0&amp;amp;hl=es&amp;amp;fs=1&amp;amp;color1=0x006699&amp;amp;color2=0x54abd6" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1918280582300408186-8651132398682804755?l=loscircuitosdebender.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://loscircuitosdebender.blogspot.com/feeds/8651132398682804755/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://loscircuitosdebender.blogspot.com/2009/03/practica-1-ensenamelo-todo.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1918280582300408186/posts/default/8651132398682804755'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1918280582300408186/posts/default/8651132398682804755'/><link rel='alternate' type='text/html' href='http://loscircuitosdebender.blogspot.com/2009/03/practica-1-ensenamelo-todo.html' title='Práctica 1: Enséñamelo todo'/><author><name>bender</name><uri>http://www.blogger.com/profile/16632063009721296550</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Xz4N5dIgwOE/SaVr6QYKnPI/AAAAAAAAAAM/WB3MtgVVnjs/S220/bender.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1918280582300408186.post-3876487421543143606</id><published>2009-02-26T22:14:00.011+01:00</published><updated>2009-02-26T22:42:31.490+01:00</updated><title type='text'>Primeros pasos de Bender</title><content type='html'>¡Estos son sus primeros pasos! (eso sí, de 45 en 45º por pulsación)&lt;br /&gt;&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/H7sR1l-oSy0&amp;amp;hl=es&amp;amp;fs=1"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/H7sR1l-oSy0&amp;amp;hl=es&amp;amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;Ahora una cuestión peliaguda en el grupo; el muñeco ¿es chico o chica?&lt;br /&gt;Difícil decisión, que se ha resuelto de una forma justa:&lt;br /&gt;&lt;br /&gt;Durante la construcción del robot, es un obrero, se pone el casco y es un machote de los que tiran piropos&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Xz4N5dIgwOE/SacHRpqW-XI/AAAAAAAAAAw/ngi8w2wC0aQ/s1600-h/IMG_5995.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://2.bp.blogspot.com/_Xz4N5dIgwOE/SacHRpqW-XI/AAAAAAAAAAw/ngi8w2wC0aQ/s320/IMG_5995.JPG" alt="" id="BLOGGER_PHOTO_ID_5307218685702109554" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Pero en los días de gala, se quita el casco y se suelta la melena, ¡será una hermosa princesita!&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Xz4N5dIgwOE/SacHj7tuHHI/AAAAAAAAAA4/DDo-jD2X-jA/s1600-h/IMG_5996.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://3.bp.blogspot.com/_Xz4N5dIgwOE/SacHj7tuHHI/AAAAAAAAAA4/DDo-jD2X-jA/s320/IMG_5996.JPG" alt="" id="BLOGGER_PHOTO_ID_5307218999785692274" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1918280582300408186-3876487421543143606?l=loscircuitosdebender.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://loscircuitosdebender.blogspot.com/feeds/3876487421543143606/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://loscircuitosdebender.blogspot.com/2009/02/primeros-pasos-de-bender.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1918280582300408186/posts/default/3876487421543143606'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1918280582300408186/posts/default/3876487421543143606'/><link rel='alternate' type='text/html' href='http://loscircuitosdebender.blogspot.com/2009/02/primeros-pasos-de-bender.html' title='Primeros pasos de Bender'/><author><name>bender</name><uri>http://www.blogger.com/profile/16632063009721296550</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Xz4N5dIgwOE/SaVr6QYKnPI/AAAAAAAAAAM/WB3MtgVVnjs/S220/bender.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_Xz4N5dIgwOE/SacHRpqW-XI/AAAAAAAAAAw/ngi8w2wC0aQ/s72-c/IMG_5995.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1918280582300408186.post-5061822263254046014</id><published>2009-02-25T21:12:00.001+01:00</published><updated>2009-02-26T21:22:05.491+01:00</updated><title type='text'>De momento...</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Xz4N5dIgwOE/SaWmnTBvDRI/AAAAAAAAAAo/WuwjJ_-iZKQ/s1600-h/IMG_5992.JPG"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; cursor: pointer; width: 320px; height: 240px;" src="http://4.bp.blogspot.com/_Xz4N5dIgwOE/SaWmnTBvDRI/AAAAAAAAAAo/WuwjJ_-iZKQ/s320/IMG_5992.JPG" alt="" id="BLOGGER_PHOTO_ID_5306830929978658066" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;...los circuitos de Bender&lt;br /&gt;&lt;br /&gt;Héchale un vistazo a mi perfil, ¡cacho carne!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1918280582300408186-5061822263254046014?l=loscircuitosdebender.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://loscircuitosdebender.blogspot.com/feeds/5061822263254046014/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://loscircuitosdebender.blogspot.com/2009/02/de-momento.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1918280582300408186/posts/default/5061822263254046014'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1918280582300408186/posts/default/5061822263254046014'/><link rel='alternate' type='text/html' href='http://loscircuitosdebender.blogspot.com/2009/02/de-momento.html' title='De momento...'/><author><name>bender</name><uri>http://www.blogger.com/profile/16632063009721296550</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Xz4N5dIgwOE/SaVr6QYKnPI/AAAAAAAAAAM/WB3MtgVVnjs/S220/bender.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_Xz4N5dIgwOE/SaWmnTBvDRI/AAAAAAAAAAo/WuwjJ_-iZKQ/s72-c/IMG_5992.JPG' height='72' width='72'/><thr:total>0</thr:total></entry></feed>
