Butialo
Butialo es un entorno fácil de usar que permite programar a Butiá en el lenguaje Lua. Lua es un lenguaje de scripting imperativo simple pero que a la vez permite crear programas sofisticados. Es un lenguaje dinámico, con manejo de memoria automático y es extremadamente rápido. Butialo es un IDE derivado de Pippy (el entorno para Python provisto con las XO), que simplifica la creación de programas para Butiá autodetectando la presencia de componentes Butiá conectados y ofreciendo snippets de código para accederlos.
Instalación
La actividad puede descargarse desde el repositorio de actividades de Sugar
Ejemplo simple
Avanzar mientras no haya un obstaculo.
Motores.setvel2mtr( 1, 500, 1, 500 )
while true do
local dist = Dist.getDistancia()
if dist<700 then
Motores.setvel2mtr( 1, 0, 1, 0 )
repeat
wait(1)
dist = Dist.getDistancia()
until dist > 700
Motores.setvel2mtr( 1, 500, 1, 500 )
end
end
También se puede programar con eventos. Un programa equivalente al anterior puede ser el siguiente:
local function adelante()
Motores.setvel2mtr( 1, 500, 1, 500 )
end
local function esperar()
Motores.setvel2mtr( 1, 0, 1, 0 )
wait( 1 )
end
events.add( Dist.getDistancia, '<', 700, esperar )
events.add( Dist.getDistancia, '>', 700, adelante )
events.go()
Ejemplo simple (otro)
Butiá con estabilidad dinámica. Se toma un Butiá, se le retiran las ruedas locas y se coloca un sensor de distancia IR apuntando al piso. Con el botón se activa y desactiva el comportamiento.
local d --lecturas de distancia
local eq --posicion de equilibrio de d
local v --velocidad calculada
while true do
print ("Presione el botón para comenzar")
repeat until Boton.getBoton()==1
eq = Dist.getDistancia()
print("Arrancando", eq)
wait(1)
repeat
d = Dist.getDistancia()
v = 100+5*math.abs(d-eq)
if v > 1024 then v = 1024 end
if d < eq then
Motores.setvel2mtr(1, v, 1, v)
else
Motores.setvel2mtr(0, v, 0, v)
end
until Boton.getBoton()==1
print("Fin")
Motores.setvel2mtr(1, 0, 1, 0)
wait(1)
end
Eventos
Butialo puede ser programado usando eventos. Un evento permite asociar una función a una condición: si la condición se cumple, la función se ejecuta. Se pueden registrar varios eventos, y estos se pueden agregar y eliminar en cualquier momento. Los eventos se ejecutan de forma bloqueante: cuando un evento se dispara, la función asociada se ejecuta hasta terminar y no puede ser interrumpida por otro evento. Es más, mientras un evento se está ejecutando, no se evalúan las condiciones de los otros eventos.
Para registrar un evento, se usa la función events.add
events.add(func, op, reference, callback [, hysteresis [, name]])
Los parametros func, op y referencia especifican la condición que dispara el evento. func: la función que al ser evaluada devuelve el valor que queremos vigilar. op: operador, '>', '<', '<=', '>=', '==', '~=' referencia: valor de refencia con el que se comparará func() callback: la función que se va invocar cuando se dispara el evento, o sea cuando se cumple que func() op referencia. Cuandose invoca callback, se le pasa como parámetro el valor de func() que disparó el evento.
hysteresis: un parámetro opcional, útil cuando se usan operadores de desigualdad. name: parametro opcional, el nombre del evento. Util para identificar el evento si en otro momento se lo quiere desactivar.
La función events.add devuelve el nombre asignado al evento (coincide con el parámetro name s fue provisto, sino se genera un nombre automáticamente). Esta función puede invocarse tanto desde el programa principal como desde una función callback.
Un evento puede desactivarse usando la función events.remove. Tal como events.add, se puede invocar en cualquier momento.
events.remove( name )
name: el nombre del evento que se quiere desactivar
Para empezar a procesar eventos se usa la llamada events.go
events.go()
Luego de invocada, el sistema queda bloqueado procesando eventos, invocando los callback según corresponda. Esto seguirá así hasta que se invoque la función events.stop
events.stop()
Esta función solo puede ser invocada en una función de callback para detener el procesamiento de eventos. Luego de invocada y terminada la función de callback responsable, el programa continuará ejecutándose en la línea siguiente al events.go.
Como ejemplo, el siguiente programa imprime "tick" cada 2 segundos, hasta que se presiona un botón y el programa finaliza.
local last = 0 --hora de la ultima vez que se imprimio tick
local function get_elapsed()
return util.get_time() - last
end
local function tick_callback ( v )
last = util.get_time()
print("tick", v)
end
local function stop_callback()
events.stop()
end
events.add( get_elapsed, ">=", 2, tick_callback)
events.add( Boton.get_boton, "==", 1, stop_callback )
events.go()