Lo que se ve es:
- Un pack de 8 baterias AA Ni-MH.
- 2 Motores Dynamixel AX-12 (uno de ellos lisiado) alimentándose de 1.
- Un regulador switcheado de voltaje a 5V, alimenándose de 1.
- Un hub USB, alimentandose desde 3.
- Un conversor USB-serial/TTL, conectado a 4.
- Los motores del punto 2. están conectados al bus serial de 5.
- Un Openmoko (NO SE OLVIDEN DE OPENMOKO) está conectado al hub 4.
- El Openmoko está en modo USB host, controlando el conversor 5.
- Se pueden conectar más perifericos USB, p.ej. una placa de I/O USB4Butia.
- El Openmoko está siendo alimentado desde el hub 4., no desde su batería.
- Como el USB del Openmoko es 1.1, el bus Dynamixel está rebajado a 38400bps.
- Más cosas.
El Openmoko tiene instalado Toribio, un entorno de desarrollo de aplicaciones de robótica para plataformas embebidas. Toribio está construido alrededor de Lumen, un despachador para programación concurrente cooperativa para Lua.
A continuación el contenido del archivo tasks/wander.lua, que implementa una caminata aleatoria extremadamente torpe.
1: return {init = function()
2: local sched = require 'sched'
3: local toribio = require 'toribio'
4:
5: local motor_left = toribio.wait_for_device('AX:3')
6: local motor_right = toribio.wait_for_device('AX:12')
7: local setvel_task = sched.sigrun(
8: {emitter='*', events = {'setvel'}},
9: function(_,_,motor, v)
10: if motor=='left' then motor_left.set_speed(v)
11: elseif motor=='right' then motor_right.set_speed(v) end
12: end
13: )
14: sched.run(function()
15: while true do
16: sched.signal('setvel', 'left', math.random(-100,100))
17: sched.sleep(3+math.random(3))
18: end
19: end)
20: sched.run(function()
21: while true do
22: sched.signal('setvel', 'right', math.random(-100,100))
23: sched.sleep(3+math.random(3))
24: end
25: end)
26:
27: end}
En la línea 7 se levanta una tarea que reacciona a señales "setvel", emitidas por cualquiera ("*"). Espera que la señal traiga dos parámetros: un lado ("left" o "right") y un número (la velocidad).
En las líneas 14 y 20 se levantan dos tareas que periódicamente emiten señales "setvel", una para el "right" y otra para el "left".
Juntando todo lo anterior y poniéndolo a funcionar, obtenemos lo siguiente:
Se podrían agregar más tareas que emitan señales, o mas tareas que reaccionen a ellos, etc. Por ejemplo, agreguemos el siguiente código para permitir detener y re-arrancar el robot presionando un botón conectado a una USB4Butia.
1: sched.run(function()
2: local button = toribio.wait_for_device({module='bb-button'})
3: local dynamixelbus = toribio.wait_for_device({module='dynamixel'})
4: local last = 1
5: local torque = true
6: while true do
7: local now = button.getValue()
8: if last==1 and now==0 then
9: torque = not torque
10: setvel_task:set_pause(not torque)
11: dynamixelbus.get_broadcaster().set_torque_enable(torque)
12: end
13: last = now
14: sched.sleep(0.5)
15: end
16: end)
Con el fragmento de código anterior, y conectando una USB4Butia con un botón, logramos el siguiente brillante resultado:
Notable. Por más ejemplos, se puede recurrir al tutorial (no, si acá vamos a leer el manual).
Una de las características de Toribio es que es altamente portable. Exáctamente el mismo código que funcionó en las partes anteriores fue copiado a un Asus WL-520GU con OpenWRT, y funciona:
Faltara menos.
Este trabajo ha sido realizado en el contexto del Grupo de Investigación MINA de la Fing/Udelar, y en particular el Proyecto Butiá.
No hay comentarios.:
Publicar un comentario