Archivo de la categoría: Software

Este puede ser el Apple II de los brazos de robot impulsados ​​por IA

Un nuevo brazo robótico de bajo costo que se puede controlar con un casco de realidad virtual facilitará la experimentación con inteligencia artificial y robótica.

Los robots en las fábricas de hoy son potentes y precisos, pero tan tontos como una tostadora. Un nuevo brazo robot, desarrollado por un equipo de investigadores de UC Berkeley, está destinado a cambiar eso al proporcionar una plataforma barata y potente para la experimentación de la Inteligencia Artificial. El equipo compara su creación con la Apple II, la computadora personal que atrajo a los aficionados y hackers en los años 70 y 80, iniciando una revolución tecnológica.

Los robots y la inteligencia artificial han evolucionado en paralelo como áreas de investigación durante décadas. En los últimos años, sin embargo, la IA ha avanzado rápidamente cuando se aplica a problemas abstractos como etiquetar imágenes o jugar videojuegos. Pero mientras que los robots industriales pueden hacer las cosas con mucha precisión, requieren una programación minuciosa y no pueden adaptarse a los cambios más pequeños. Han surgido robots más baratos y seguros, pero la mayoría no están diseñados específicamente para ser controlados con software de IA.

“Los robots son cada vez más capaces de aprender nuevas tareas, ya sea a través de prueba y error, o mediante una demostración experta”, dice Stephen McKinley, un postdoctorado en UC Berkeley que estuvo involucrado en el desarrollo del robot. “Sin una plataforma de bajo costo ─un dispositivo tipo Apple II─ la experimentación, la prueba y el error y la investigación productiva continuarán avanzando lentamente. Existe un potencial para que la investigación se acelere en gran medida al hacer que más robots sean más accesibles «.

El nuevo brazo, conocido como Blue, cuesta alrededor de $ 5.000, y puede controlarse a través de un casco de realidad virtual, una técnica que está resultando útil para entrenar algoritmos de IA que controlan robots.


Blue es capaz de transportar cargas relativamente pesadas, pero también es extremadamente «manejable», lo que significa que obedecerá cuando se lo empuje o jale. Esto hace que sea seguro para que las personas trabajen a su lado y permite que se le muestre físicamente cómo hacer algo. El sistema proporciona software de bajo nivel para controlar el robot y para el sistema de realidad Virtual, y está diseñado para ser compatible con cualquier computadora que ejecute el software de Inteligencia Artificial.



El proyecto proviene del laboratorio de Pieter Abbeel, un profesor de la UC Berkeley que ha sido pionero en la aplicación de la inteligencia artificial a la robótica. Las prácticas informáticas para el proyecto han sido licenciadas por UC Berkeley por una nueva compañía llamada Berkeley Open Arms, que desarrollará y venderá el hardware.

Sigue siendo extremadamente difícil traducir el aprendizaje automático de un entorno virtual al mundo real. A pesar de esto, los investigadores académicos han avanzado en la aplicación del aprendizaje automático al hardware del robot, lo que ha llevado a demostraciones espectaculares y algunas empresas comerciales.

Algunas compañías astutas han tomado nota de la tendencia. Nvidia, un fabricante de chips que ha impulsado el auge de la IA al hacer microprocesadores y software para el aprendizaje profundo, lanzó recientemente un laboratorio dedicado a explorar las aplicaciones de la IA a los robots.

El CEO de Nvidia, Jensen Huang, describe al robot de Berkeley como «muy emocionante».

Huang señala que si bien comprar un robot industrial puede costar alrededor de $ 50.000, puede costar muchas veces eso reprogramarlo para una nueva serie de tareas diferentes. «Está al revés», dice. Espera grandes avances en robótica en los próximos años gracias a los avances en el aprendizaje automático y la simulación de realidad virtual: «Los robots y la IA son ahora lo mismo».



Piernas robóticas que se basan en la evolución animal para aprender a caminar

Investigadores de la Universidad de Carolina del Sur (USC) han construido un robot que puede aprender solo a caminar. Inspirados por la forma de aprender de los humanos, y de los animales que han evolucionado para aprender esta habilidad a los pocos minutos de nacer, se espera que la investigación abra nuevas posibilidades en los campos de las prótesis dinámicas y los robots que aprenden sobre la marcha en entornos desconocidos.

La nueva extremidad robótica conectada a una máquina de cuatro patas (Crédito: Matthew Lin)

«Hoy en día, para que un robot esté listo para interactuar con el mundo se necesita el equivalente de meses o años de entrenamiento, pero queremos lograr el rápido aprendizaje y las adaptaciones que se ven en la naturaleza», dice Francisco J. Valero-Cuevas, un profesor de Ingeniería Biomédica.

En pos de este objetivo, Valero-Cuevas y sus colegas desarrollaron una pierna robótica accionada por tendones de tipo animal y controlada por algoritmos de Inteliencia Artificial bio-inspirados. Esto permite que el robot desarrolle la habilidad de caminar de manera similar a los humanos, por medio de lo que se conoce en los círculos de robótica como Motor Babbling (“babbling” es el balbuceo de los bebés que están probando su capacidad de hablar), que implica realizar movimientos exploratorios repetidos.

«Estos movimientos aleatorios de la pierna permiten al robot construir un mapa interno de su extremidad y sus interacciones con el medio ambiente», dice el estudiante de doctorado de ingeniería de la USC, Ali Marjaninejad, autor del estudio.

Los investigadores han desarrollado una extremidad robótica accionada por tendones de tipo animal y controlada por algoritmos de inteligencia artificial específicos.

Al aprender sobre su estructura y entorno, el miembro robótico puede desarrollar su propio andar personalizado y aprender una nueva tarea de caminar después de solo cinco minutos de pruebas puramente descoordinadas. A tal punto que puede recuperarse si tropieza al querer dar su próximo paso con seguridad en el suelo, aunque no esté programado para hacerlo. Los investigadores creen que este es el primer robot capaz de tal hazaña, y están entusiasmados con las posibilidades que abre el avance.
Como explican, los robots pueden programarse para realizar ciertas tareas en ciertos escenarios, pero no se pueden preparar para toda posibilidad. Este tipo de robots, por otro lado, que son capaces de desarrollar sus propios movimientos personalizados en respuesta a su entorno, podrán asumir una gama más amplia de tareas.

«Si se deja que estos robots aprendan de la experiencia relevante, finalmente encontrarán una solución que, una vez lograda, se utilizará y adaptará según sea necesario», dice Marjaninejad. «La solución puede no ser perfecta, pero se adoptará si es lo suficientemente buena para la situación. No todos necesitamos o deseamos, o podemos gastar tiempo y esfuerzo en ganar una medalla olímpica».





Las prótesis sensibles son un área en la que este tipo de tecnología podría tener un impacto, ya que ayuda a las personas con discapacidades, al permitirles extremidades más intuitivas, naturales y que se mejoran a sí mismas. La exploración espacial es otra, donde los robots podrían colocarse en planetas o lunas lejanos y usar sus capacidades de aprendizaje para ajustar su modo de andar y navegar por terreno desconocido.

«La capacidad de una especie para aprender y adaptar sus movimientos a medida que cambian sus cuerpos y ambientes ha sido, desde el principio, un poderoso impulsor de la evolución», dice Brian Cohn, también estudiante de doctorado y autor del estudio. «Nuestro trabajo constituye un paso hacia la capacitación de los robots para aprender y adaptarse de cada experiencia, tal como lo hacen los animales».

Artículos relacionados:
Creando robots que pueden ir a donde nosotros vamos
Walbi, el bípedo que aprende a caminar
Un guepardo robótico capaz de dar volteretas hacia atrás
Una prótesis que restaura la sensación de dónde está tu mano
Logran que los robots rastreen objetos en movimiento con una precisión sin precedentes
Un robot que procura moverse tan bien como una hormiga
Dando sentido del tacto a los robots
¿Por qué está resultando difícil construir robots para convivir y trabajar con nosotros en la vida real?

La investigación fue publicada en la revista Nature Machine Intelligence.
Fuente: Universidad del sur de California



Entendiendo ASCII en el desarrollo de lenguaje de máquina integrado

Este artículo, que sirve como preparación para una discusión de cadenas (strings) en lenguaje C, presenta el concepto de caracteres ASCII y explica dos beneficios de las técnicas de codificación basadas en ASCII.


Un microprocesador o microcontrolador es una colección compleja de circuitos que manipulan voltajes lógicos altos y voltajes lógicos bajos. Para mayor comodidad, nos referimos a estos voltajes como unos y ceros, y diseñamos los procesadores de manera que estos unos y ceros puedan manipularse en conjunto y tratarse como números binarios.

La mayoría de la gente se volvería loca o se quedaría dormida si se vieran obligados a observar el flujo interminable de números binarios dentro y fuera de un microprocesador. La tecnología computacional ha transformado la existencia humana porque estos números binarios se pueden usar para representar cosas que a las personas realmente les importan: música, fotografías o, en el caso del ASCII, letras y dígitos.

Entendiendo el ASCII

ASCII significa Código Estándar Americano para el Intercambio de Información (American Standard Code for Information Interchange = ASCII). En este código, un número binario significa exactamente un caracter, donde «caracter» se refiere a una letra mayúscula, una letra minúscula, un dígito, un signo de puntuación, o varias otras cosas que se pueden encontrar en un teclado. La siguiente tabla le brinda la «traducción» entre los números (aquí, escrita en notación decimal en lugar de binaria) y los caracteres ASCII correspondientes al alfabeto en mayúsculas y minúsculas.

(Nota: Quede claro que cuando en EEUU dicen “americano” se refieren a algo que se aplica solamente a ellos, no a toda América. Quedaba afuera, en principio, toda letra que no se usa en el inglés actual, letras con acentos, diéresis, circunflejo, tildes, y otras diferenciaciones fonéticas en otros idiomas, y por eso se creó la tabla de ASCII extendido, que está incluida más abajo).


Es esencial comprender que su microcontrolador no sabe nada acerca de las letras del inglés u otra lengua (y menos aún de los caracteres acentuados de diferentes maneras o especiales en cada idioma), los signos de puntuación o los dígitos. Su microcontrolador es una máquina muy pequeña, diseñada para procesar números binarios, y cualquier carácter que esté presente en su lenguaje de máquina (firmware) es simplemente su interpretación de los números binarios.

Se puede producir una seria confusión debido a la impresión errónea de que sus variables, o elementos de matriz, contienen realmente caracteres ASCII de una forma u otra. El desarrollo de firmware se vuelve más claro, más ágil y más flexible cuando uno se da cuenta de que los caracteres en realidad son números binarios, y se pueden almacenar, transferir y manipular como números binarios; no se convierten en caracteres ASCII hasta que esté todo listo para interpretarlos como caracteres ASCII.

ASCII Extendido

Beneficios y contras del ASCII

El ASCII es necesario para la programación humana. Hay muchas aplicaciones integradas que pueden beneficiarse del uso de caracteres ASCII, y creo que es una buena idea adquirir el hábito de reconocer situaciones en las que se puede incorporar caracteres ASCII en su código.




Un estándar ampliamente utilizado

Un beneficio innegable de ASCII es la estandarización. Los entornos de desarrollo integrado, los programas de terminal y los paquetes de software computacional comprenden el ASCII y, por lo tanto, los caracteres ASCII son una forma conveniente y efectiva de transferir y mostrar información.

En este ejemplo, una aplicación muestra una representación binaria basada en datos de un sensor:

Transferencia de datos confiable

Un beneficio más sutil, pero quizás igual de importante, es el hecho de que el ASCII proporciona un medio para representar información utilizando un conjunto restringido de números binarios. Cualquier valor numérico puede representarse mediante una secuencia de los dígitos ASCII del 0 al 9 (junto con el punto decimal ASCII si es necesario). Estos caracteres ASCII corresponden a un subconjunto muy pequeño de los 256 valores ofrecidos por un número binario de 8 bits. Pero ¿por qué esto importa?

Imagine que tiene una aplicación en la que un microcontrolador debe transferir mediciones impredecibles y altamente variables de sensores de 8 bits a una PC. Si se transfieren los datos como números binarios ordinarios, un byte individual puede contener un número cualquiera del 0 al 255. Esto nos deja sin una forma conveniente y sencilla de organizar datos o incorporar comandos en el flujo de datos, porque para transferir las mediciones en bruto solo son necesarios todos los números binarios posibles. El PC (y menos nosotros) no puede distinguir entre los datos de medición numéricos y otros tipos de información.

Si se transfieren los datos de medición utilizando caracteres ASCII en lugar de números binarios ordinarios, entran en juego los beneficios de un conjunto restringido. Solo se necesitan diez valores binarios (correspondientes a los dígitos ASCII del 0 al 9) para representar los datos numéricos, y varios otros valores binarios pueden reservarse para una funcionalidad especial, porque nunca aparecerán en los datos de medición.

Aquí, los dígitos ASCII se utilizan para transferir una lectura de temperatura. El final de cada lectura se identifica con un retorno de carro (abreviado CR = Carrier Return); el valor binario correspondiente a CR nunca aparecerá en los datos de medición.

Reducción de la eficiencia

El precio que se paga por esta estandarización y transferencia de datos mejorada es que se usa con menos eficiencia la memoria, el ancho de banda del procesador y el ancho de banda de la comunicación.

El ASCII es un sistema basado en bytes. Cada carácter requiere ocho bits, incluyendo, por ejemplo, el dígito «1», que en circunstancias binarias normales puede representarse mediante un número de 1 bit en lugar de un número de 8 bits.

En la experiencia de un programador actual, esto rara vez es un problema serio; los microcontroladores modernos tienen recursos de procesamiento y memoria que exceden con creces los requisitos de muchas aplicaciones. Sin embargo, si realmente se necesita maximizar el rendimiento o minimizar el uso de la memoria, es posible que debamos renunciar a la conveniencia de usar ASCII.

De ASCII a cadenas de caracteres

Este artículo no es solo una descripción general de ASCII sino también una introducción a la forma en que se maneja una representación basada en caracteres en el lenguaje de programación C. Nos referimos a este tipo de representación como una cadena (string), que es una secuencia o «encadenamienro» de caracteres ASCII.

Veremos más en detalle las cadenas en un próximo artículo.



Comprendiendo Variables al programar en C

Este es un análisis de la naturaleza y el uso de las variables en lenguaje C en el contexto de las aplicaciones para microcontroladores

Muchos de nosotros escuchamos la palabra «variable» en las clases de matemáticas mucho antes de saber mucho, si es que sabemos algo, acerca de la programación de computadoras. Una variable matemática es una cantidad cuyo valor no se conoce o no se limita a un número. Este uso es similar, aunque no idéntico, al concepto de una variable C.

Dos diferencias importantes: primero, en matemáticas, usualmente usamos una letra como x o y para representar una variable, mientras que en C usamos frecuentemente una palabra o frase descriptiva como contadorPulsos, velocidadMedia o cantidadVueltas. En segundo lugar, hay situaciones en las que usamos una variable de C para identificar una cantidad conocida y que no se pretende que cambie del valor original.

Variables en hardware

Las variables son convenientes e intuitivas para los programadores. Para el hardware computacional, por otro lado, no tienen un significado real. Los microprocesadores almacenan datos en registros y ubicaciones de memoria. Esta diferencia fundamental entre las personas que escriben el idioma de máquina y las máquinas que ejecutan este programa se supera mediante lenguajes de alto nivel como C, que maneja varios detalles asociados con la traducción entre variables basadas en texto y la realidad física de un procesador.

Los diseñadores de sistemas integrados trabajan a menudo con procesadores de 8 bits. En estos dispositivos, por lo general, el tamaño fundamental de los datos es un byte. La memoria se organiza de acuerdo con los bytes, el tamaño de los registros es de un byte y la CPU está diseñada para procesar datos de 8 bits. Esta es una limitación bastante incómoda porque hay muchas situaciones en las que el valor de una variable excederá el valor máximo de un número de 8 bits.

Finalmente, todas las variables C cuidadosamente definidas y con un nombre ilustrativo terminan como bits en la memoria (o registros)

El lenguaje C no limita el tamaño de una variable a 8 bits, incluso cuando está trabajando con un procesador de 8 bits. Esto significa que una variable en el programa en lenguaje de máquina que ejecuta el microprocesador puede corresponder a múltiples registros o ubicaciones de memoria en el hardware. «Manualmente» administrar variables de múltiples bytes (es decir, a través del lenguaje ensamblador) no parece muy deseable, pero a los compiladores no les importa en absoluto, y hacen el trabajo muy bien.

Definiendo variables

El primer paso para usar una variable es definir esa variable. Los componentes esenciales de una definición de variable son el tipo y el nombre.

Hay muchos tipos de variables; La lista completa, así como los detalles de la implementación del hardware, variarán según el compilador que esté utilizando. Aquí hay unos ejemplos:

char : un valor con signo de un byte
int : un valor con signo de dos o cuatro bytes
long : un valor con signo de cuatro bytes
float : un valor de cuatro bytes que puede tener números después del punto decimal; en otras palabras, no está limitado a enteros
bit : el valor de la variable puede ser cero o uno

Esta es una representación visual de cómo una serie de bits se interpreta de manera diferente en función de si una variable se considera con signo (utilizando la notación de complemento a dos) o sin signo:

El siguiente código muestra definiciones de variables que consisten solo en un tipo básico y un nombre (la forma más técnica de referirse al nombre es «identificador»):

Inicializando variables

En muchos casos, es una buena idea darle un valor inicial a una variable. Esto facilita la depuración y es esencial si la variable se utilizará antes de que le fije un valor conocido. Puede inicializar una variable en la definición, o en otra parte de su código, pero incluir el valor inicial en la definición es una buena manera de mantener el código organizado y desarrollar el hábito de inicializar siempre que sea necesario.

Aquí hay ejemplos de definiciones de variables que incluyen una inicialización:

Definiciones de variables delicadas

Hay varias otras palabras que se pueden incluir en una definición de variable. Estos se utilizan para especificar con mayor precisión la naturaleza de la variable o para dar instrucciones al compilador sobre cómo implementar la variable en el hardware.

Las siguientes palabras clave podrían ser útiles en sus proyectos de programa para microcontroladores:

■ unsigned : como habrá adivinado, esto le dice al compilador que interprete la variable como un valor sin signo en lugar de un valor con signo. Uno defino le mayoría de sus variables como sin signo, porque rara vez se necesitan números negativos.

■ const : el calificador de tipo const indica al compilador que el valor de una variable no debe cambiar. Como dice al principio del artículo, a veces el valor de una «variable» C no es variable. Si usted comete un error en su código e intenta modificar el valor de una variable const, el compilador generará un error.

■ volatile : los compiladores sofisticados no solo toman su código original y lo traducen directamente al lenguaje de máquina. También intentan hacer que el código funcione de manera más eficiente, y este proceso se conoce como «optimización». En general, la optimización es algo bueno. Sin embargo, de vez en cuando, puede arruinar el día, porque el compilador se optimiza solo en función del código y no puede tener en cuenta los eventos de hardware que interactúan con el código. Cuando una variable tiene el calificador de tipo volátil, el compilador sabe que debe tener cuidado con las optimizaciones relacionadas con esa variable.

Una interrupción puede hacer que el valor de una variable se modifique de una manera que el compilador no espera, y esto puede llevar a una optimización problemática

■ tipos de memoria, como xdata , idata y code : estas palabras obligan al compilador a ubicar una variable en una parte específica de la memoria del microprocesador. El tipo que aloja en la memoria de programa es particularmente útil: los recursos de RAM en un microcontrolador a menudo son mucho más limitados que la memoria de programa no volátil, y el tipo de memoria de código le permite utilizar memoria de programa adicional para almacenar datos que se usan en su programa pero nunca se modifican.

Aquí hay unos ejemplos:

Uso de las variables

No hay mucho que decir acerca de cómo usar sus variables después de que se hayan definido. En realidad, con respecto a la variable en sí, la definición es la mayor parte del trabajo. Después de eso, usted simplemente incorpora el identificador de la variable en operaciones matemáticas, bucles, llamadas a funciones, etc. Un buen compilador no solo manejará los detalles de la implementación del hardware, sino que también buscará formas de optimizar el código con respecto a la velocidad de ejecución o el tamaño del programa.

Quizás el error más común relacionado con el uso variable es un desbordamiento. Esto se refiere a una situación en la que el valor asignado a una variable está fuera del rango numérico asociado con el tipo de datos de la variable.

Se debe pensar en todos los escenarios posibles relacionados con una variable determinada y luego elegir el tipo de datos en consecuencia.

Resumen

La funcionalidad de la variable básica proporcionada por el lenguaje C es intuitiva y directa, pero hay algunos detalles que pueden ayudarlo a hacer que una aplicación integrada sea más confiable y eficiente. Si tiene alguna duda relacionada con las variables de C, no dude en preguntar en nuestro grupo en Facebook Robots Didácticos.




Arduino: alojar datos en la memoria de programa con PROGMEM

Almacene los datos en la memoria FLASH (memoria de programa) en lugar de RAM (a veces nombrada como SRAM, del inglés STATIC RAM = RAM estática).

Los distintos tipos de memoria disponibles en una placa Arduino son:

FLASH: Esta memoria almacena el código del programa.

RAM: Esta memoria almacena los datos del programa y es volátil. Cuando se apaga Arduino se pierden los datos.

EEPROM: Esta memoria almacena datos que son persistentes. Esta memoria puede ser utilizada para guardar configuración o cualquier otro dato que podamos utilizar si se apaga y enciende Arduino.

La palabra clave PROGMEM es un modificador de variable. Se debe usar solo con los tipos de datos definidos en la biblioteca pgmspace.h.

PROGMEM le dice al compilador «ponga esta información en la memoria flash», en lugar de en la RAM, donde iría normalmente.

PROGMEM es parte de la biblioteca pgmspace.h. Ésta se incluye automáticamente en las versiones modernas del IDE. Sin embargo, si estuviese utilizando una versión IDE por debajo de 1.0 (2011), primero deberá incluir la biblioteca en la parte superior de su programa, con esta declaración:

Sintaxis

tipoDato – algún tipo de variable
nombreVariable – el nombre de su matriz de datos

Tenga en cuenta que debido a que la indicación PROGMEM es un modificador de variable, no existe una regla estricta sobre dónde debe ir, por lo que el compilador acepta diversas posiciones, que también pueden ser sinónimos. Sin embargo, las pruebas han indicado que, en varias versiones de Arduino, PROGMEM puede funcionar en una ubicación y no en otra.

Los siguientes ejemplos se han probado y funcionan con los IDE actuales. Las versiones anteriores del IDE pueden funcionar mejor si la palabra PROGMEM se incluye después del nombre de la variable.

Tenga en cuenta que dado que PROGMEM se podría usar con una sola variable, pero en realidad solo vale la pena si tiene un bloque de datos más grande para almacenar, que por lo general es más fácil de poner en una matriz (o en otra estructura de datos C++, algo que queda más allá de la presente discusión).

Usar PROGMEM es un procedimiento de dos pasos. Después de tener los datos que están en la memoria Flash, se requieren métodos especiales (funciones), también definidos en la biblioteca pgmspace.h, para volcar los datos de la memoria de programa a la RAM, de modo de que podamos trabajar con ellos.

Código de ejemplo

Las siguientes secciones de código ilustran cómo leer y escribir unsigned char (bytes) e int (2 bytes) en PROGMEM.

Matrices de cadenas de caracteres

A menudo es conveniente configurar una serie de cadenas de caracteres cuando se trabaja con grandes cantidades de texto, como por ejemplo en un proyecto con una pantalla LCD.

Debido a que las cadenas en sí son matrices, en realidad este es un ejemplo de una matriz bidimensional.

Estas tienden a ser grandes estructuras, por lo que por lo general es deseable colocarlas en la memoria del programa.

El siguiente código ilustra la idea.

Notas y advertencias

Tenga en cuenta que las variables deben estar definidas globalmente, o definidas con la palabra clave static, para poder trabajar con PROGMEM.

El siguiente código NO funcionará cuando esté dentro de una función:

El siguiente código funcionará, incluso si está definido localmente dentro de una función:

La macro F()

Cuando se utiliza una instrucción como:

La cadena a imprimir normalmente se guarda en la memoria RAM. Si su programa imprime muchas cosas en el Monitor Serie, puede acabar llenando la RAM. Si tiene espacio libre en la memoria FLASH, puede indicar fácilmente que la cadena debe guardarse en FLASH, usando la sintaxis: