-
Notifications
You must be signed in to change notification settings - Fork 2
bender_head
Contenido
[TOC]
En esta documentación se describe el sistema de control implementado para los actuadores de la cabeza de Bender, de acuerdo a lo implementado hasta el 29 de Julio de 2016. Para seguir un tutorial de manejo básico del sistema ir a la sección Tutorial.
La descripción comienza desde las capas de mayor nivel de abstracción hasta las de menor nivel, llegando finalmente al hardware. Éste último esta basado en Arduino.
Abajo se puede ver un esquema básico del sistema.
El controlador ROS es la capa de mayor nivel y esta implementada en el nodo ''expressions_controller'' escrito en python. Los tópicos suscritos a y publicados por este nodo son los siguientes:
-
Suscritos:
- expression_command. Recibe un mensaje de tipo bender_msgs/ExpressionCommand para establecer las emociones de Bender. El mensaje tiene un parámetro, ``expression'' de tipo \textit{string} para indicar el nombre de la emoción. Los valores que puede tomar este parámetro se describen mas abajo.
-
Publicados:
- expression_state. Publica un mensaje de tipo bender_msgs/ExpressionCommand que indica la emoción actual de Bender.
Los mensajes publicados en el tópico expression_command deben ser emociones que estén definidas mediante la interfaz ''facial_expressions'' (interfaz no ROS), la cual se describe en la sección ''Interfaz de programación de emociones''. Las emociones disponibles al momento de redactar este documento son, default, surprised, angry, happy, veryHappy y sad.
Es importante mencionar que este nodo hereda el uso del dispositivo USB-Dynamixel para la comunicación. Por defecto se encuentra definido en el puerto ''/dev/ttyUSB0'', de usar otro debe cambiarse al final del script ''ros_facial_expressions.py'' (linea 91).
El nodo ROS ''expressions_controller'' usa la clase FacialExpressions escrita en python (esta interfaz no usa ROS), para ejecutar las emociones. Esta clase provee métodos que tienen una correspondencia directa con las emociones que se pueden usar en el nodo ROS.
La clase FacialExpressions define emociones a partir de emociones de los ojos y gestos faciales definidos en las clases EyeEmotion y FacialGestures respectivamente.
La clase EyeEmotion define métodos que representan las distintas emociones de los ojos definiendo los colores que deben tener los LEDs. Para esto usa el método ''set_eye_colors(eye, rgb_colors)'' de la clase HeadHWController. Para programar nuevas _emociones de los ojos basta con agregarlas como métodos en esta clase, usando el método ''set_eye_colors'', no es necesario conocer la implementación de la clase HeadHWController, sin embargo si lo desea puede ver su documentación en la sección Interfaz PC-Hardware.
El método ''set_eye_colors(eye, rgb_colors)'' recibe el parámetro ''eye'' de tipo string que puede ser left o right, dependiendo de si se esta definiendo los colores de los LEDs del ojo izquierdo o derecho; y el parámetro rgb_colors que debe ser una lista de 16 colores (cada ojo posee 16 LEDs[^1]).
Los colores están definidos en el módulo ''colores_rgb'' y corresponden a listas de 3 valores enteros, representando los canales R, G y B del color (ej. red = [1,0,0]). Se pueden definir más colores agregándolos en dicho módulo. Cada componente puede tomar valores entre 0 y 3, es decir hay 64 colores[^2].
[^1]: Para ver la numeración de los LEDs ver sección Hardware. [^2]: Los colores efectivos son menos, debido a que las diferencias en los tonos es escasa.
La clase FacialGestures define métodos que representan los distintos gestos definiendo distintos estados de las orejas, cejas y boca de Bender. Para esto usa los métodos de la clase ServosHW que reciben porcentajes para mover los actuadores (servos), y son representativos del órgano que representan (left_ear, mouth, etc.). Sus parámetros son:
- lifting_percentage: Válido para métodos left_ear, right_ear, left_eyebrow, right_eyebrow.
- opening_percentage: Válido para el método mouth.
- Ambos deben ser un número entre 0 y 100.
Para programar nuevos gestos basta con agregarlas como métodos en esta clase usando los métodos mencionados, no es necesario conocer la implementación de la clase ServosHW.
En resumen, para programar nuevas emociones debe definir las emociones de los ojos en la clase EyeEmotion, los gestos faciales en la clase FacialGestures, y usarlos para definir una emoción completa en la clase FacialExpressions. Finalmente debe agregar las emociones en el nodo ROS ros_facial_expressions en el método process_command que recibe el mensaje publicado en el tópico expression_command.
El nodo ''head_hw_controller'' descrito en la sección anterior usa los métodos definidos en la clase ''HeadHWController'' que implementa la comunicación de bajo nivel con el hardware. Para ésto provee los siguientes métodos:
Método | Descripción |
---|---|
ping(): | Permite ver si hay comunicación entre el PC y el hardware. |
get_state(state_variable): | Lee y retorna el valor en memoria del Arduino de la variable state_variable. Las variables disponibles son SERVO_SELECT_STATE , SERVO_POS_STATE , LED_SELECT_STATE y LED_COLOR_STATE (que están en las direcciones de memoria 6,7,8 y 9 respectivamente) |
select_command(num): | Selecciona un servo para mover. Para esto envía al Arduino el número num que le indica qué servo se moverá. |
pos_command(pos): | Indica al Arduino la posición a la que se moverá el servo seleccionado con select_command(num). |
moveServoTo(servo_i, pos): | Los métodos anteriores sólo cambian valores en memoria del Arduino, pero no realizan el movimiento del servo. Para ello se implementa este método que envía al Arduino el comando para que realice el movimiento del servo seleccionado a la posición seleccionada usando los métodos anteriores. |
swapServo(servo_i): | Realiza un swap del servo servo_i, un número entre 0 y 4. |
parallelSwapServos(): | Realiza un swap de todos los servos. |
changeLedColor(numLed, rgb_color): | Envía al Arduino los comandos para cambiar al color rgb_color el LED numLed. El parámetro rgb_color debe ser una lista de tres valores enteros entre 0 y 3 (ej. [1,0,0] sería rojo, [0,1,0] sería verde, etc.). |
set_eye_colors(eye, rgb_colors): | Cambia los colores de los LEDs asociados al ojo derecho u ojo izquierdo dependiendo de si el parámetro eye es el string left o right . Deben especificarse 16 tríos de componentes RGB, debido a que cada ojo posee 16 LEDs (ej. [[1,0,0],[0,1,1],...]) |
Ésta interfaz hace uso de la clase DynamixelIO del paquete dynamixel_driver para el manejo de más bajo nivel de los motores y LEDs mediante el protocolo Dynamixel. La comunicación con el hardware se hace mediante el dispositivo USB-Dynamixel que se encuentra definido en el puerto ''/dev/ttyUSB0'' por defecto.
Esta clase permite un mayor nivel de abstracción para manejar los servos. Permite actuar los órganos (servos) por un porcentaje, sin la necesidad de conocer las restricciones físicas de los servos. Usa los métodos definidos en la clase HeadHWController.
Las limitaciones físicas de los servos según el montaje descrito en <incluir sección> son los siguientes:
Nombre Actuador | Limitación | Comentario |
---|---|---|
oreja der | Entre 0 y 130° | Oreja arriba en 0° |
oreja izq | Entre 50 y 180° | Oreja arriba en 180° |
ceja der | Entre 40 y 140° | |
ceja izq | Entre 40 y 140° | |
boca | Entre 110 y 140° | Boca cerrada en 110° |
No es necesario modificar los métodos de la clase HeadHWController o ServosHW para programar nuevas emociones. Sin embargo podría ser necesario en caso de modificación del montaje de los actuadores, o programar métodos de propósito específico, en estos casos asegúrese de ser consistente con las restricciones físicas de los actuadores y las especificaciones del hardware.
El driver para los servos y LEDs esta programado en Arduino y hace uso de las librerias SerialDXL.h[^3] y Adafruit_NeoPixel.h[^4], además de librería estándar proporcionadas por Arduino.
[^3]: Desarrollada por Rodrigo Muñoz, para más detalles ver https://github.com/rorromr/serial_dxl [^4]: Librería proporcionada por Adafruit para los LEDs NeoPixel, disponible en https://github.com/adafruit/Adafruit_NeoPixel
La librería SerialDXL.h permite el uso del protocolo de comunicación Dynamixel[^5] para el manejo de dispositivos, en éste caso servos y LEDs. De esta forma el Arduino se identifica como un dispositivo Dynamixel, su id por defecto es 0.
[^5]: Ver documentación en http://support.robotis.com/en/product/dxl_main.htm
El funcionamiento del driver se basa en actualizar cuatro variables mapeadas en la memoria del Arduino, SERVO_SELECT_COMMAND
, SERVO_POS_COMMAND
, LED_SELECT_COMMAND
y LED_COLOR_COMMAND
, las cuales determinan el comportamiento de los servos y los LEDs.
Las variables SERVO_SELECT_COMMAND
y LED_SELECT_COMMAND
se usan tanto para seleccionar un número específico de servo o LED, actualizando variables internas, y también como comandos de confirmación y funciones predefinas de los dispositivos. Esto se muestra en el esquema de abajo:
El código esta disponible en el repositorio bender_embedded.
El sistema de comunicación esta implementado mediante el estándar RS-485, el cual corresponde a un sistema de bus diferencial. Esto significa que la información es transmitida usando dos señales complementarias.
Una de las ventajas de este sistema es que es mas robusto al ruido electromagnético comparado con la transmisión de una sola señal. Más detalles de este sistema aquí.
Los programas de control (ROS controller) se manejan en el computador del torso de Bender, dicho computador se comunica con el hardware implementado mediante el dispositivo USB-Dynamixel que tiene Bender, y que es también usado para el control de los motores de los brazos. Se usa la salida RS-485 del dispositivo para conectarse al BUS disponible en el Shield de comunicación y conexiones. En el esquema de abajo se puede ver la topología del sistema.
INSERTAR esquema
Este Shield que va montado en el Arduino es una placa que maneja el envío y transmisión de datos mediante el Differential Bus Transceiver SN75176A (Datasheet del dispositivo aquí), y facilita las conexiones de los servos y la placa de LEDs al Arduino.
Abajo se puede ver una foto del Shield. Todos los conectores están rotulados en la placa.
INSERTAR FOTO
La placa de los LEDs va montada detrás de la mascara de Bender, permite la comunicación entre los rings NeoPixels (Son distribuidos por Adafruit, ver descripción aquí) y el Arduino, la alimentación de los LEDs, y sirve de base para conectar los rings, los cuales son fácilmente desmontables de la placa.
En la foto abajo se puede ver la placa con las referencias asignadas a cada LED para su manejo de acuerdo a lo descrito en la sección 2.1 Interfaz Mediante ROS. Todas Las conexiones se encuentran rotuladas en la placa.
INSERTAR FOTO
En esta sección se describe como usar la interfaz ROS para efectuar emociones mediante el hardware en la cabeza de Bender.
Para poder usar la interfaz, los siguientes requisitos de hardware deben cumplirse:
- Todos los servos deben estar conectados al shield de comunicaciones y conexiones montado en el Arduino.
- Los servos y LEDs deben estar alimentados por 5V, y el Arduino por una fuente entre 6V y 12V, a través de los conectores respectivos del shield (una buena práctica es conectar primero los actuadores, luego los dispositivos de control).
- El shield provee una entrada de alimentación única para los servos y los LEDs, debe asegurarse que la fuente de alimentación sea capaz de suministrar por lo menos 1A de corriente.
- El computador desde el cual se ejecute la interfaz (típicamente el del torso) debe estar conectado al shield mediante la salida RS-485 del dispositivo USBDynamixel.
- Debe asegurarse que el puerto en que está montado el dispositivo USBDynamixel coincida con el definido en la interfaz (por defecto es /dev/ttyUSB0).
- Las orejas de Bender deben estar montadas como se describe en la sección <agregar sección>, de lo contrario podrían chocar y dañarse.
Nota: Al conectar la alimentación a la placa, se establecerá una configuración por defecto para los motores y LEDs (emoción default).
Todo el software necesario se encuentra en el package bender_head en el computador del torso de Bender, específicamente en el directorio ~/bender_head/src/bender_head_arduino/software_interface/
en la rama feat-head_arduino
. Asegúrese de que puede ver estas dependencias mediante roscd bender_head/src/bender_head_arduino/software_interface/
.
Si pudo ver las dependencias, asegúrese de que el sistema puede ver el mensaje que usa la interfaz, puede hacerlo con rosmsg show ExpressionCommand
, debe ver el package y contenido del mensaje. Además debe asegurarse de que se ha generado el código fuente del mensaje en el directorio bender_head/src/bender_head_arduino/bender_head_arduino/msg
.
Si se cumplen todos los requerimientos anteriores, puede comenzar a efectuar emociones siguiendo los siguientes pasos:
- Ejecutar el nodo /expressions_controller. Ejecute el comando
rosrun bender_head ros_facial_expressions
. - Publicar emociones en el tópico /expression_command. Ejecute el comando
rostopic pub -1 ros_facial_expressions/expression_command bender_msgs/ExpressionCommand "'surprised'"
. Puede consultar las emociones disponibles mediante el servicio . - Si realizó todo lo anterior deberá ver a Bender sorprendido. También puede ver la emoción actual de Bender en el tópico /expression_state, mediante el comando `rostopic echo ros_facial_expressions/expression_state.
- Si desea terminar la ejecución de emociones, sólo termine el nodo y desconecte la alimentación de la placa (una buena práctica es desconectar primero los dispositivos de control, luego los actuadores). Opcionalmente si sólo desea apagar los LEDs, publique la emoción apagado.