Diferencia entre revisiones de «Tutorial:ODE y robots modulares:Módulo»
(→Función Module_new()) |
(→Función Module_render()) |
||
Línea 162: | Línea 162: | ||
=== Función Module_render() === | === Función Module_render() === | ||
+ | Esta es la función encargada de '''dibujar el módulo'''. Es muy sencilla ya que el módulo sólo tiene dos geometrías. Es similar a los ejemplos anteriores: Primero se establece la textura y luego se dibuja la geometría del cuerpo izquierdo con un color y la del derecho con otro: | ||
+ | |||
+ | dsSetTexture (DS_WOOD); | ||
+ | dsSetColor (0.9,0,0); | ||
+ | drawGeom(mod->geom_left); | ||
+ | dsSetColor (1,0,0); | ||
+ | drawGeom (mod->geom_right); | ||
+ | |||
=== Simulación del servo === | === Simulación del servo === | ||
Revisión del 10:46 8 ene 2009
Contenido
Simulación de un módulo
|
|
|
Introducción
El siguiente paso para empezar a simular robots modulares es saber cómo implementar un servo. Construiremos un módulo constituido por dos cuerpos unidos mediante un servo. En la simulación de ejemplo, el usuario podrá establecer las posiciones de -90, 90 y 0 grados para este servo y verá cómo varían las posiciones relativas de los dos cuerpos.
Objetivo
- Aprender a simular un servo y construir nuestro primer módulo
Código
Programa principal | |
Creación y dibujo del módulo | |
Definición de las constantes. | |
Definición de los prototipos de modulo.cpp y las estructuras de datos. |
Compilación
Todos los ejemplos de este tutorial compilan tecleando "make". Sin embargo se describe a continuación cómo se compila directamente usando el GCC:
g++ -Iinclude -c -o servo_ex/servo.o servo_ex/servo.cpp g++ -Iinclude -c -o servo_ex/module.o servo_ex/module.cpp g++ -o servo servo_ex/servo.o servo_ex/module.o libdrawstuff.a -lm -lode -lX11 -lm -lGL -lGLU
Ejecución
Para probar el ejemplo, teclear:
./servo
Además de los mensajes impresos en pantalla por la drawstuff, aparecerá el siguiente menú:
Keys for moving the servo: 1: Set the servo angle to 90 degrees 2: Set the servo angle to 0 degrees 3: Set the servo angle to -90 degrees q: Quit
Por medio de las teclas '1', '2' y '3' el usuario puede establecer la posición del servo a 90, 0 y -90 grados respectivamente.
Capturas de pantalla
Visualización del módulo en las tres posiciones:
Vídeo
video.mpg |
Modelo de módulo
El módulo está formado por dos cuerpos, que denominaremos izquierdo y derecho. Tienen diferente masa y longitud, pero la altura y anchura son las mismas. Ambos cuerpos tienen como geometría un hexaedro, como se muestra en la figura 1.
- Cuerpo izquierdo:
- Masa: MASS0
- Dimensiones: W x L0 x H
- Cuerpo derecho:
- Masa: MASS1
- Dimensiones: W x L1 x H
La estructura de datos para representar el módulo está definida en el fichero module.h:
struct MyModule { dJointID joint; dReal servo_ref_pos; dBodyID body_left; dGeomID geom_left; dBodyID body_right; dGeomID geom_right; };
Además de los dos cuerpos y sus correspondientes geometrías, la estructura tiene el identificador de la articulación y la posición angular en la que situar el servo: servo_ref_pos.
Los dos hexaedros que forman los cuerpos unidos por una articulación rotan alrededor del eje z que pasa por el punto de anclaje de la articulación, situado en las coordenadas (0,L0,0) con respecto al origen de coordenadas.
Al rotar, los dos hexaedros entran en colisión. Sin embargo, como vimos en el [del capítulo 2], si dos objetos están conectados mediante una articulación, las colisiones no se tienen en cuenta. Por ello, los dos hexaedros pueden rotar y penetrarán el uno en el otro.
Funcionamiento del servo
Figura 2: Respuesta del servo al escalón |
Figura 3: Velocidad del servo al aplicar un escalón |
Para la implementación del servo se han seguido las recomendaciones indicadas en el manual del ODE. Se ha utilizado un controlador de tipo proporcional que viene dado por la ecuación: <math> w\left(t\right)=K_{p}\left[\varphi\left(t\right)-p\right]</math>, donde:
|
|
|
|
En la figura 2 se muestra la respuesta al escalón. En el instante t=200 se establece como posición de referencia p=90 grados. el servo se encuentra en la posición de 0 grados. La posición del servo empieza a aumentar. Según se acerca a la posición de referencia su velocidad va disminuyendo hasta llegar a 0. En la figura 3 se muestra la velocidad angular para ese mismo ejemplo. La velocidad máxima está limitada por la que tiene el servo (WMAX) por lo que hay saturación. A partir de un instante, esta velocidad comienza a disminuir hasta llegar a 0.
Explicación del código
Función Module_new()
Esta es la función que se encarga de crear el módulo entero. Primero se crea el cuerpo izquierdo y se establece la posición de su centro de masas. Tomando como referencia el origen indicado anteriormente, se debe situar en las coordenadas (0,-L0/2,H/2):
mod->body_left = dBodyCreate(world); dBodySetPosition(mod->body_left, 0.0, -L0/2, H/2);
Luego se le asigna la masa (MASS0) y se establecen las dimensiones del hexaedro que delimita el cuerpo, que es uno de dimensiones W x L0 x H:
dMassSetBoxTotal (&m, MASS0, W, L0, H); dBodySetMass (mod->body_left,&m);
Ahora se crea la geometría, que es un hexaedro de las mismas dimensiones anteriores y se asigna al cuerpo izquierdo:
mod->geom_left = dCreateBox (space, W, L0, H); dGeomSetBody (mod->geom_left,mod->body_left);
Lo siguiente es crear el cuerpo derecho. El proceso es el mismo pero ahora su centro de masas se encuentra en la posición (0,-L0-L1/2, H/2), sus dimensiones son (W,L1,H) y su masas MASS1:
mod->body_right = dBodyCreate(world); dBodySetPosition(mod->body_right, 0.0, -L0-L1/2, H/2); dMassSetBoxTotal (&m, MASS1, W, L1,H); dBodySetMass (mod->body_right,&m); mod->geom_right = dCreateBox (space, W, L1, H); dGeomSetBody (mod->geom_right,mod->body_right);
Por último se crea la articulación. Se sitúa en el punto (0,-L0,H/2), se asigna el eje z como eje de rotación (0,0,1) y se establece su fuerza máxima, dada por la constante TORQUE y una velocidad angular inicial de 0:
mod->joint=dJointCreateHinge (world, 0); dJointAttach (mod->joint,mod->body_left,mod->body_right); dJointSetHingeAnchor (mod->joint, 0, -L0, H/2); dJointSetHingeAxis (mod->joint, 0,0,1); dJointSetHingeParam(mod->joint, dParamFMax, TORQUE); dJointSetHingeParam(mod->joint, dParamVel, 0.0);
Función Module_render()
Esta es la función encargada de dibujar el módulo. Es muy sencilla ya que el módulo sólo tiene dos geometrías. Es similar a los ejemplos anteriores: Primero se establece la textura y luego se dibuja la geometría del cuerpo izquierdo con un color y la del derecho con otro:
dsSetTexture (DS_WOOD); dsSetColor (0.9,0,0); drawGeom(mod->geom_left); dsSetColor (1,0,0); drawGeom (mod->geom_right);
Simulación del servo
Función Main
Enlaces
|
|
|