{"id":220,"date":"2016-06-27T13:13:23","date_gmt":"2016-06-27T11:13:23","guid":{"rendered":"http:\/\/www.rtbasics.com\/WP_2\/?p=220"},"modified":"2016-06-27T13:13:23","modified_gmt":"2016-06-27T11:13:23","slug":"sensor-de-profundidad-pantilt-2","status":"publish","type":"post","link":"https:\/\/www.rtbasics.com\/WP_2\/archives\/220","title":{"rendered":"Sensor de profundidad. Pan&#038;Tilt 2"},"content":{"rendered":"<body><p><\/p>Estaba yo pensando\u2026 \u00bfC\u00f3mo controlamos esto?\n<p>Para generar el tren de pulsos descrito en el post anterior se puede usar el PWM (Pulse Width Modulation) que suele incorporar como perif\u00e9rico pr\u00e1cticamente cualquier microcontrolador orientado al entorno industrial.<\/p>\n<p>Conozco bien la familia de procesadores ColdFire de Freescale, ahora incorporada a NXP, por haberla usado muchas veces en mi trabajo. Ten\u00eda por casa una <a href=\"http:\/\/www.nxp.com\/products\/software-and-tools\/run-time-software\/nxp-mqx-software-solutions\/mqx-real-time-operating-system-rtos\/coldfire-mcf5441x-tower-system-module:TWR-MCF5441X?fsrch=1&amp;sr=1&amp;pageNum=1\" target=\"_blank\">Tower del MCF54418<\/a>\u00a0y esto me permiti\u00f3 poner en marcha el invento r\u00e1pidamente. Es una l\u00e1stima que estos procesadores, herederos de la arquitectura del 68000 de Motorola se hayan visto desplazados por los ARM.<\/p>\n<p><!--more--><\/p>\n<p>Hace ya tiempo que Freescale empez\u00f3 a comercializar las tarjetas de evaluaci\u00f3n de la familia Tower. Consiste en una serie de tarjetas que montan sus procesadores y que pueden ser instaladas junto con otras que incluyen perif\u00e9ricos formando una torre de tarjetas conectadas a trav\u00e9s de unos buses trazados en las tarjetas laterales. De esta manera, se pueden montar distintos equipos compuestos por una tarjeta de procesador y por una, o varias, tarjetas de perif\u00e9ricos.<\/p>\n<p>Lo verdaderamente interesante de este prototipo es el sistema operativo, MQX. Hace ya tiempo que Freescale, poco despu\u00e9s de la compra de WindRiver por parte de Intel (\u00bfcasualidad?), empez\u00f3 a promover el uso de MQX en sus micros. Lo distribuye en c\u00f3digo fuente y puede ser usado de manera gratuita con sus herramientas de desarrollo para la mayor parte de sus micros. Est\u00e1 orientado al tiempo real y muy bien estructurado, yo dir\u00eda que a la altura de los buenos. Otro d\u00eda hablaremos de MQX.<\/p>\n<p>Explicar los detalles del programa que hice para esta ocasi\u00f3n y de la configuraci\u00f3n del PWM ser\u00eda un poco aburrido y tampoco es el objetivo. El PWM es un dispositivo ingenioso basado en simples contadores y comparadores hardware que puede dar mucho juego. Se basa en la capacidad de cambiar los estados de alguna se\u00f1al de salida o generar alguna interrupci\u00f3n cuando alg\u00fan contador coincide con el valor configurado en alg\u00fan registro. En un controlador potente, como es \u00e9ste, hay varias salidas, varias entradas, varias interrupciones, varios contadores, varios registros, \u2026 y much\u00edsimas posibilidades de configuraci\u00f3n.<\/p>\n<p>El programa que he generado en esta tarjeta me va a servir para probar los servos, es decir, verificar c\u00f3mo funcionan, probar su rango de movimiento, hacer pruebas a distintas velocidades, identificar sus restricciones mec\u00e1nicas o de la plataforma, etc<\/p>\n<p>Para esto, he programado varios comandos que se pueden teclear a trav\u00e9s de una consola desde un ordenador que ejecuta un programa como el HyperTerminal (a\u00fan le soy fiel, igual que a mi m\u00e1quina Windows XP) y se conecta a la tarjeta a trav\u00e9s de una conexi\u00f3n RS232.<\/p>\n<p>Para manipular los servos he montado en la Tower una tarjeta <a href=\"http:\/\/www.nxp.com\/products\/software-and-tools\/hardware-development-tools\/tower-development-boards\/peripheral-modules\/prototyping-with-perfboard-area-tower-system-module:TWR-PROTO\" target=\"_blank\">TWR-PROTO<\/a>. En esta tarjeta he conectado dos salidas asociadas a los PWMs A y B del micro a trav\u00e9s de un buffer para adaptar los niveles de tensi\u00f3n a dos conectores de astas donde conecto los cables de los servos. Las salidas de este micro son de 3,3V y los servos se alimentan a 5V y esperan en la se\u00f1al de control tambi\u00e9n 5V. Adem\u00e1s incluyo unas resistencias en serie de 200 Ohm para proteger las salidas del micro y del buffer.<\/p>\n<p>He usado las se\u00f1ales que salen del micro en los pines A10 (funci\u00f3n alternativa 1 PWM_A0) y C11 (funci\u00f3n alternativa 1 PWM_B0) a trav\u00e9s de los pines del conector principal de la TWR-PROTO A40 y A39 respectivamente. Cada pin de Entrada\/Salida del procesador MCF54418 en encapsulado 256 MAPBGA que monta la tarjeta de evaluaci\u00f3n TWR-MCF5441X permite ser usado para varias funciones: como GPIO o como otras dos funciones alternativas dependientes de cada pin. En este caso hay que configurar el micro para que internamente conecte estos dos pines a las salidas 0 de los PWM A y B respectivamente.<\/p>\n<p>As\u00ed es como ha quedado la tarjeta TWR-PROT y la TOWER completa.<\/p>\n<p><a href=\"https:\/\/i0.wp.com\/www.rtbasics.com\/WP_2\/wp-content\/uploads\/2016\/06\/Tower_proto.jpg\"><img data-recalc-dims=\"1\" decoding=\"async\" class=\"size-medium wp-image-224 alignleft\" src=\"https:\/\/i0.wp.com\/www.rtbasics.com\/WP_2\/wp-content\/uploads\/2016\/06\/Tower_proto.jpg?resize=300%2C169\" alt=\"Tower_proto\" width=\"300\" height=\"169\" loading=\"lazy\" srcset=\"https:\/\/i0.wp.com\/www.rtbasics.com\/WP_2\/wp-content\/uploads\/2016\/06\/Tower_proto.jpg?resize=300%2C169&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.rtbasics.com\/WP_2\/wp-content\/uploads\/2016\/06\/Tower_proto.jpg?resize=768%2C431&amp;ssl=1 768w, https:\/\/i0.wp.com\/www.rtbasics.com\/WP_2\/wp-content\/uploads\/2016\/06\/Tower_proto.jpg?resize=1024%2C575&amp;ssl=1 1024w, https:\/\/i0.wp.com\/www.rtbasics.com\/WP_2\/wp-content\/uploads\/2016\/06\/Tower_proto.jpg?w=1280 1280w, https:\/\/i0.wp.com\/www.rtbasics.com\/WP_2\/wp-content\/uploads\/2016\/06\/Tower_proto.jpg?w=1920 1920w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><a href=\"https:\/\/i0.wp.com\/www.rtbasics.com\/WP_2\/wp-content\/uploads\/2016\/06\/Tower_y_sensor.jpg\"><img data-recalc-dims=\"1\" decoding=\"async\" class=\"size-medium wp-image-223 alignleft\" src=\"https:\/\/i0.wp.com\/www.rtbasics.com\/WP_2\/wp-content\/uploads\/2016\/06\/Tower_y_sensor.jpg?resize=300%2C169\" alt=\"Tower_y_sensor\" width=\"300\" height=\"169\" loading=\"lazy\" srcset=\"https:\/\/i0.wp.com\/www.rtbasics.com\/WP_2\/wp-content\/uploads\/2016\/06\/Tower_y_sensor.jpg?resize=300%2C169&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.rtbasics.com\/WP_2\/wp-content\/uploads\/2016\/06\/Tower_y_sensor.jpg?resize=768%2C431&amp;ssl=1 768w, https:\/\/i0.wp.com\/www.rtbasics.com\/WP_2\/wp-content\/uploads\/2016\/06\/Tower_y_sensor.jpg?resize=1024%2C575&amp;ssl=1 1024w, https:\/\/i0.wp.com\/www.rtbasics.com\/WP_2\/wp-content\/uploads\/2016\/06\/Tower_y_sensor.jpg?w=1280 1280w, https:\/\/i0.wp.com\/www.rtbasics.com\/WP_2\/wp-content\/uploads\/2016\/06\/Tower_y_sensor.jpg?w=1920 1920w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>Acabo de describir el interface entre esta tarjeta, que hace de controlador de la plataforma de pan&amp;tilt, y los servos. Ahora hablar\u00e9 sobre el interface entre el software que controla el sensor de profundidad y este controlador de la plataforma.<\/p>\n<p>Es muy sencillo. Conecto el PC Linux que corre el programa que adquiere las instant\u00e1neas de profundidad con la Tower a trav\u00e9s de un cable serie como si \u00e9ste fuera una consola. El programa antes de tomar la foto posiciona la plataforma componiendo un comando que env\u00eda por el dispositivo \u201c\/dev\/ttyUSB0\u201d tras haber sido convenientemente configurado.<\/p>\n<p>Esta no es la mejor manera, desde luego, de comunicar dos dispositivos pero s\u00ed me permite resolver la comunicaci\u00f3n de una manera r\u00e1pida y dedicar mis esfuerzos y mi tiempo a lo que realmente es el objetivo del experimento. Adem\u00e1s, est\u00e1 por definir una arquitectura para un equipo integrado que realice estas dos funciones que ahora estoy implementando en dos equipos. Hablaremos de esto en el \u00faltimo post de esta serie.<\/p>\n<p>Para manejar la tarjeta he generado varios comandos de consola:<\/p>\n<ul>\n<li><strong>pwminit<\/strong>. Inicializa los PWM y genera la salida de los servos que corresponde a la posici\u00f3n de reposo de la plataforma.<\/li>\n<li><strong>pwmbseta<\/strong> y <strong>pwmsetb<\/strong>. Estos comandos toman como argumento el ancho del pulso en microsegundos y configuran el PWM correspondiente para que genere el pulso del ancho indicado. Estos comandos los he usado desde la consola para tener control completo de los servos y as\u00ed poder verificar el correcto funcionamiento de hardware y software, caracterizar los servos, identificar restricciones mec\u00e1nicas en el movimiento y ajustar l\u00edmites para proteger los servos y la plataforma.<\/li>\n<li><strong>pwmsetpos<\/strong>. Este comando toma dos argumentos en \u201cunidades de ingenier\u00eda\u201d, es decir: grados. Est\u00e1 orientado a ser usado desde la aplicaci\u00f3n, que necesita apuntar el sensor hacia un punto determinado de la escena sin necesidad de conocer el funcionamiento interno del controlador o de los servos. Cada uno de los argumentos puede ser positivo o negativo y especifica, en grados, el giro que debe imprimirse a la plataforma en sus movimientos de pan y tilt respecto a una posici\u00f3n de referencia establecida como el punto 0,0.<\/li>\n<\/ul>\n<p>De esta manera, para hacer el barrido de la escena que queremos escanear, se configuran en la aplicaci\u00f3n las posiciones desde las que se tiene que tomar la foto. El programa posiciona el sensor haciendo uso del comando <strong>pwmsetpos<\/strong>, espera un segundo para evitar vibraciones que puedan afectar a la calidad de la medida, toma una instant\u00e1nea que graba en un fichero como ya he explicado en un post anterior y se posiciona en el siguiente punto. Tras cubrir toda la ruta configurada, tendremos la colecci\u00f3n de ficheros que se usaran para componer la escena completa. La composici\u00f3n de esta escena ser\u00e1 el objetivo del siguiente post.<\/p>\n<p>Para ilustrar el movimiento de la plataforma, he grabado un video en el que se ve el movimiento de los dos servos. Pod\u00e9is descargarlo del siguiente <a href=\"http:\/\/www.rtbasics.com\/Downloads\/pan_tilt_kinect_20140528.mp4\" target=\"_blank\">enlace<\/a>.<\/p>\n<p>Antes de dar el post por acabado, me gustar\u00eda comentar alguna cosilla:<\/p>\n<ul>\n<li>Los movimientos de la plataforma son un poco bruscos. Acostumbrado a ver los movimientos de los robots industriales con una velocidad, suavidad y precisi\u00f3n asombrosas, confieso que me sent\u00ed un poco decepcionado cuando vi que con los servos seleccionados no era f\u00e1cil controlar la velocidad del movimiento por tramos desde el punto inicial hasta el final. Para mejorar esto creo que habr\u00eda que trabajar en dos aspectos:\n<ol>\n<li>Sustituir los servos c\u00e1sicos que yo he usado por servos digitales que admiten, de manera nominal, un tren de pulsos de 300Hz con lo que la resoluci\u00f3n en el tiempo se multiplica por 6.<\/li>\n<li>Si la posici\u00f3n del servo estuviera realimentada con un encoder, se podr\u00eda cerrar un bucle de control e implementar un PID<\/li>\n<\/ol>\n<\/li>\n<\/ul>\n<ul>\n<li>Si el objetivo hubiera sido controlar un servo, o varios, desde un PC, se podr\u00eda haber usado alguno de los controladores por USB que pod\u00e9is encontrar en <a href=\"http:\/\/www.robotshop.com\/eu\/en\/servo-controllers.html\" target=\"_blank\">Robotshop<\/a>. Lo que yo quer\u00eda era tener control directo sobre la se\u00f1al de control de los servos desde un dispositivo \u00e1gil, con latencias m\u00e1ximas predecibles y ajeno a la carga de proceso de otros subsistemas. En el \u00faltimo post de esta serie hablar\u00e9 sobre la arquitectura de un posible producto.<\/li>\n<\/ul>\n<ul>\n<li>Tambi\u00e9n se podr\u00eda haber pensado en ir grabando frames en un movimiento continuo del sensor y luego procesarlos pero, por un lado, no tengo datos sobre la capacidad del sensor de adquirir informaci\u00f3n mientras se mueve y, por otro, tener parado el sensor en una posici\u00f3n conocida facilita el tratamiento de la integraci\u00f3n de una instant\u00e1nea sobre otra, como veremos en el siguiente post.<\/li>\n<\/ul>\n<p><\/p>\n<\/body>","protected":false},"excerpt":{"rendered":"<p>Estaba yo pensando\u2026 \u00bfC\u00f3mo controlamos esto? Para generar el tren de pulsos descrito en el post anterior se puede usar el PWM (Pulse Width Modulation) que suele incorporar como perif\u00e9rico pr\u00e1cticamente cualquier microcontrolador orientado al entorno industrial. Conozco bien la &hellip; <a href=\"https:\/\/www.rtbasics.com\/WP_2\/archives\/220\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[5,21,20],"tags":[23,7,22,26,31],"class_list":["post-220","post","type-post","status-publish","format-standard","hentry","category-broadcasting","category-depth-sensors","category-sensors","tag-asus-xtion","tag-hard","tag-kinect","tag-pantilt","tag-servo"],"jetpack_featured_media_url":"","jetpack_likes_enabled":true,"jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p4vaHY-3y","_links":{"self":[{"href":"https:\/\/www.rtbasics.com\/WP_2\/wp-json\/wp\/v2\/posts\/220","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.rtbasics.com\/WP_2\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.rtbasics.com\/WP_2\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.rtbasics.com\/WP_2\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.rtbasics.com\/WP_2\/wp-json\/wp\/v2\/comments?post=220"}],"version-history":[{"count":5,"href":"https:\/\/www.rtbasics.com\/WP_2\/wp-json\/wp\/v2\/posts\/220\/revisions"}],"predecessor-version":[{"id":228,"href":"https:\/\/www.rtbasics.com\/WP_2\/wp-json\/wp\/v2\/posts\/220\/revisions\/228"}],"wp:attachment":[{"href":"https:\/\/www.rtbasics.com\/WP_2\/wp-json\/wp\/v2\/media?parent=220"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.rtbasics.com\/WP_2\/wp-json\/wp\/v2\/categories?post=220"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.rtbasics.com\/WP_2\/wp-json\/wp\/v2\/tags?post=220"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}