Diferencia entre revisiones de «PyBot»
m (→Usando Pybot localmente) |
(→Agrego HELP) |
||
(No se muestran 4 ediciones intermedias de 2 usuarios) | |||
Línea 1: | Línea 1: | ||
Butiá puede utilizarse de muchas formas, como un servicio consumible mediante la red como es el caso de pybot server o utilizando directamente la biblioteca usb4butia. | Butiá puede utilizarse de muchas formas, como un servicio consumible mediante la red como es el caso de pybot server o utilizando directamente la biblioteca usb4butia. | ||
+ | |||
+ | El código puede ser obtenido clonando el repositorio: | ||
+ | |||
+ | git clone git://git.code.sf.net/p/butia/code | ||
+ | |||
+ | ''(Al día de hoy 10/11/13 la carpeta pesa 98MB es un poco pesada)''<br> | ||
+ | El código se encuentra en "/lugar/de/clonado/turtlebots/pybot" | ||
+ | |||
+ | |||
+ | ==Diseño== | ||
+ | Pybot consta de distintos módulos que se encargan de una parte específca: | ||
+ | |||
+ | baseboard.py funciones inerentes a la placa USB4Butia | ||
+ | com_chotox.py simula la conexión con una placa y todas las funciones | ||
+ | com_usb.py implementa la comunicación usb | ||
+ | device.py abstracción de un dispositivo (botón, motores) conectado a la placa | ||
+ | drivers/ | ||
+ | hotplug/ drivers de módulos abiertos automáticamente por la placa | ||
+ | button.py driver del sensor botón | ||
+ | light.py driver del sensor de luz | ||
+ | ----- | ||
+ | motores.py driver del módulo de motores | ||
+ | butia.py driver del módulo butiá | ||
+ | ----- | ||
+ | functions.py funciones comunes entre el cliente y la usb4butia | ||
+ | pybot_client.py aplicación cliente | ||
+ | pybot_server.py aplicación servidor | ||
+ | server_functions.py lista de funciones del servidor | ||
+ | usb/ librería PyUsb | ||
+ | usb4butia.py módulo principal (core) que implementa las funciones | ||
==Usando Pybot localmente== | ==Usando Pybot localmente== | ||
Línea 57: | Línea 87: | ||
version = robot.getFirmwareVersion() | version = robot.getFirmwareVersion() | ||
+ | |||
+ | ==Usando Pybot server via Telnet== | ||
+ | |||
+ | Cuando se levanta el servidor, se abre un socket en el puerto 2009. | ||
+ | Esto permite conectarnos via red local a un Butiá y poder controlarlo. | ||
+ | Para eso podemos levantar un Telnet así: | ||
+ | |||
+ | telnet localhost 2009 | ||
+ | |||
+ | Ponemos "localhost" porque en nuestro caso estamos corriendo en la misma computadora, | ||
+ | de lo contrario, pondríamos la dirección IP. | ||
+ | |||
+ | ===Comandos del Server=== | ||
+ | |||
+ | Para poder acceder al robot contamos con algunos comandos. | ||
+ | La forma de saber los comandos presentes es mediante otro comando "HELP": | ||
+ | |||
+ | HELP | ||
+ | BUTIA_COUNT, CALL, CLIENTS, CLOSE, DESCRIBE, HELP, LIST, LISTI, OPEN, QUIT, REFRESH | ||
+ | |||
+ | Si queremos saber qué hace cada comando (solo en la versión 23 de PyBot) podemos hacer: | ||
+ | |||
+ | HELP clients | ||
+ | Get a list of current clients in PyBot server | ||
+ | |||
+ | Los comandos y su descripción: | ||
+ | |||
+ | BUTIA_COUNT: Get the number of boards connected | ||
+ | CALL: Call a function of certain module | ||
+ | CLIENTS: Get a list of current clients in PyBot server | ||
+ | CLOSE: Close an 'openable' module such as motors, butia.. | ||
+ | DESCRIBE: Get the list of functions and parameters of a module | ||
+ | HELP: Return a list of commands or the use of specific one | ||
+ | LIST: Get a list of open modules in a board | ||
+ | LISTI: Get a list of instanciables modules of the board | ||
+ | OPEN: Open an 'openable' module such as motors, butia.. | ||
+ | QUIT: Close PyBot server | ||
+ | REFRESH: Search for new devices | ||
+ | |||
+ | Otro comando útil es el "DESCRIBE": este comando permite describir un módulo (por ejemplo, un botón, un motor) y decirnos sus funciones y argumentos. Por ejemplo, en el caso de "grey" (sensor de grises): | ||
+ | |||
+ | DESCRIBE grey | ||
+ | {'getVersion': [], 'getValue': []} | ||
+ | |||
+ | Ésto nos dice que el sensor de grises (grey) cuenta con 2 funciones: "getVersion" y "getValue". | ||
+ | Para usar el comando, teniendo un sensor conectado en el puerto 2, por ejemplo, haríamos un "CALL": | ||
+ | |||
+ | CALL grey:2 getValue | ||
+ | 25789 | ||
+ | |||
+ | Eso nos devuelve el valor del sensor de grises conectado en el puerto 2 de la placa Butiá. | ||
==Funciones USB4Butiá - Pybot Client== | ==Funciones USB4Butiá - Pybot Client== |
Revisión actual del 09:44 7 dic 2013
Butiá puede utilizarse de muchas formas, como un servicio consumible mediante la red como es el caso de pybot server o utilizando directamente la biblioteca usb4butia.
El código puede ser obtenido clonando el repositorio:
git clone git://git.code.sf.net/p/butia/code
(Al día de hoy 10/11/13 la carpeta pesa 98MB es un poco pesada)
El código se encuentra en "/lugar/de/clonado/turtlebots/pybot"
Contenido
Diseño
Pybot consta de distintos módulos que se encargan de una parte específca:
baseboard.py funciones inerentes a la placa USB4Butia com_chotox.py simula la conexión con una placa y todas las funciones com_usb.py implementa la comunicación usb device.py abstracción de un dispositivo (botón, motores) conectado a la placa drivers/ hotplug/ drivers de módulos abiertos automáticamente por la placa button.py driver del sensor botón light.py driver del sensor de luz ----- motores.py driver del módulo de motores butia.py driver del módulo butiá ----- functions.py funciones comunes entre el cliente y la usb4butia pybot_client.py aplicación cliente pybot_server.py aplicación servidor server_functions.py lista de funciones del servidor usb/ librería PyUsb usb4butia.py módulo principal (core) que implementa las funciones
Usando Pybot localmente
Cuando se va a ejecutar Pybot y quién lo usa en la misma máquina, no es recomendable tener una arquitectura cliente-servidor. Para ese caso se dispone de una alternativa: usar directamente el módulo usb4butia dentro de Pybot.
Si no estamos en la carpeta donde está la librería PyBot podemos usar este truco para poder importar Pybot sin problemas desde cualquier lado:
import sys sys.path.insert(0, '/home/olpc/Activities/TurtleBots.activity/plugins/butia')
Esa es la ruta por defecto cuando el .XO se instala en Sugar, puede variar en otras computadoras. El paquete .deb instala TurtleBots en '/usr/share/sugar/activities' por lo que la ruta debe ser:
sys.path.insert(0, '/usr/share/sugar/activities/TurtleBots.activity/plugins/butia')
Importando el módulo:
from pybot import usb4butia
Instanciando la clase:
robot = usb4butia.USB4Butia()
A partir de este momento tenemos las mismas llamadas que en pybot_client. Por ejemplo, para obtener la versión del Firmware:
version = robot.getFirmwareVersion()
El módulo USB4Butia nos provee algunas propiedades "privadas" que pueden resultar útiles:
robot._bb # Lista de placas detectadas robot._drivers_loaded # Diccionario de drivers robot._debug # Bandera de debug, por defecto es False robot._get_all_drivers() # Función para cargar los drivers robot._get_driver() # Función para obtener un driver específico robot._hotplug # Lista de módulos hotplug robot._modules # Lista de módulos robot._openables # Lista de módoulos "openables"
Usando Pybot server
Levantamos el servidor desde una consola (debemos estar dentro de la carpeta pybot):
python pybot_server.py DEBUG
En este caso con la bandera de DEBUG para ver la salida del lado del servidor.
Luego nos encargamos del cliente:
from pybot impoty pybot_client
Instanciamos el cliente:
robot = pybot_client.robot()
A partir de ahora tenemos las mismas funciones que en la versión local, por ejemplo:
version = robot.getFirmwareVersion()
Usando Pybot server via Telnet
Cuando se levanta el servidor, se abre un socket en el puerto 2009. Esto permite conectarnos via red local a un Butiá y poder controlarlo. Para eso podemos levantar un Telnet así:
telnet localhost 2009
Ponemos "localhost" porque en nuestro caso estamos corriendo en la misma computadora, de lo contrario, pondríamos la dirección IP.
Comandos del Server
Para poder acceder al robot contamos con algunos comandos. La forma de saber los comandos presentes es mediante otro comando "HELP":
HELP BUTIA_COUNT, CALL, CLIENTS, CLOSE, DESCRIBE, HELP, LIST, LISTI, OPEN, QUIT, REFRESH
Si queremos saber qué hace cada comando (solo en la versión 23 de PyBot) podemos hacer:
HELP clients Get a list of current clients in PyBot server
Los comandos y su descripción:
BUTIA_COUNT: Get the number of boards connected CALL: Call a function of certain module CLIENTS: Get a list of current clients in PyBot server CLOSE: Close an 'openable' module such as motors, butia.. DESCRIBE: Get the list of functions and parameters of a module HELP: Return a list of commands or the use of specific one LIST: Get a list of open modules in a board LISTI: Get a list of instanciables modules of the board OPEN: Open an 'openable' module such as motors, butia.. QUIT: Close PyBot server REFRESH: Search for new devices
Otro comando útil es el "DESCRIBE": este comando permite describir un módulo (por ejemplo, un botón, un motor) y decirnos sus funciones y argumentos. Por ejemplo, en el caso de "grey" (sensor de grises):
DESCRIBE grey {'getVersion': [], 'getValue': []}
Ésto nos dice que el sensor de grises (grey) cuenta con 2 funciones: "getVersion" y "getValue". Para usar el comando, teniendo un sensor conectado en el puerto 2, por ejemplo, haríamos un "CALL":
CALL grey:2 getValue 25789
Eso nos devuelve el valor del sensor de grises conectado en el puerto 2 de la placa Butiá.
Funciones USB4Butiá - Pybot Client
Funciones útiles:
robot.close() # cierra todas las placas instanciadas robot.find_butias() # busca placas conectadas y las instancia robot.getBatteryCharge() # devuelve el nivel de carga de la batería (si no hay motores-> -1) robot.getFirmwareVersion() # devuelve la versión del firmware dentro del PIC robot.getVersion() # devuelve la versión del módulo butiá (arduino: 20, usb4butia:22) robot.getButiaCount() # devuelve la cantidad de placas conectadas robot.getModulesList() # devuelve la lista de dispositivos conectados (en todas las placas) robot.isPresent(device) # chequea si un dispositivo en particular está conectado robot.loopBack(data) # envía una string 'data' a la placa y devuelve lo mismo robot.reconnect() # no hace nada en usb4butia / en el cliente hace un reconnect del socket robot.refresh() # actualiza la lista de placas conectadas robot.callModule(modulename, board_number, number, function, params) #llamada a un módulo
Sensores
robot.getButton(port) # obtiene el valor del sensor botón conectado en el puerto port robot.getDistance(port) # obtiene el valor del sensor de distancia conectado en el puerto port robot.getGray(port) # obtiene el valor del sensor de grises conectado en el puerto port robot.getLight(port) # obtiene el valor del sensor de luz conectado en el puerto port robot.getResistance(port) # obtiene el valor del sensor de resistencia conectado en el puerto port robot.getTemperature(port) # obtiene el valor del sensor temperatura conectado en el puerto port robot.getVoltage(port) # obtiene el valor del sensor volyaje conectado en el puerto port robot.setLed(port, on) # si on es 1, prende el LED, si es 0, apaga el LED conectado en el puerto port
Hack pins
robot.modeHack(pin, mode) # establece el modo del pin: si mode es 0 es entrada y 1 salida robot.setHack(pin, value) # establece el valor del pin: pin en GND si es 0 y en +5v si es 1 robot.getHack(pin) # lee el valor del pin: pin
Motores
robot.set2MotorSpeed(leftSense, leftSpeed, rightSense, rightSpeed) #sense is 0 or 1, speed is between 0 and 1023 robot.setMotorSpeed(idMotor, sense, speed) #idMotor 0 for left motor, 1 for right
Drivers en PyBot
Los drivers de PyBot son escritos en python. Dentro de la carpeta /drivers se encuentran todos aquellos que no son PNP (plug and play). Los módulos que son abiertos automáticamente por la placa, por ejemplo cuando uno conecta un sensor de grises,
van dentro de /drivers/hotplug.
Cada función en el driver se define como una función Python utilizando el "def" y recibe como primer parámetro el dispositivo ("dev") con el cual se va a comunicar.
Este es el ejemplo del driver del sensor de grises, el cuál tiene dos funciones: getVersion y getValue
Esta es una captura parcial del código del driver de los hack points (hackp):
Como se puede observar, la función "setMode" recibe como primer argumento el "dev" y luego el resto de los parámetros: el número de "pin" y el "value" que es el modo. Se guarda en "msg" la lista con el "código de operación" SET_MODE y se le agregan los otros parámetros.
msg = [SET_MODE, pin, value]
Esto se le envía al módulo con la función "send":
dev.send(msg)
Luego se leen 2 bytes: el primero, como en todas las funciones es el mismo "código de operación" que fue enviado y el segundo es en este caso, el código de error (si es -1, hubo un error).
raw = dev.read(2)
Y solo se retorna el segundo byte que es el el importante:
return raw[1]