4

Interacción entre V-Rep y Matlab

Saludos, humano. Al habla Transductor. Como últimamente parece que a mis compañeros de Robologs se les ha dado por hacer tutoriales sobre el simulador de robots V-Rep, yo voy a hacer lo mismo y hoy os explicaré como conectarlo con Matlab, el popular software matemático.

Al término de este artículo habrás aprendido a crear un script con Matlab para conectarte con el simulador y acceder a los objetos de la escena. Aprenderemos a mover motores, activar y leer sensores de distancia y acceder a la imagen de una cámara virtual, todo desde Matlab.


¿Qué es V-REP? V-Rep es un simulador de robots que permite probar prototipos y algoritmos sin el esfuerzo (y el coste) que supone construir un robot real. Dispone de un IDE propio para construir escenas virtuales y controlar cada robot/parte mediante scripts internos, nodos ROS o programas externos escritos en lenguajes como C++, Matlab, Java y Python (entre otros).

¿Qué es Matlab? Matlab es un programa para hacer cálculos matemáticos, representar y analizar datos o funciones, construcción testeo de algoritmos, visión por computador e interacción con dispositivos de hardware (entre otros). Es el software por excelencia que se utiliza en universidades y centros de investigación.


1- Preparar Matlab

Este primer paso sólo tendrás que hacerlo la primera vez que utilices Matlab con V-Rep, o si instalas una nueva versión de alguno de los dos programas.

Los scripts para controlar los robots que se simulan con V-Rep se escriben en lenguaje Lua mediante el editor de texto interno que tiene el programa. No obstante, V-Rep también ofrece una API remota para controlar la simulación desde una aplicación externa (como un script de Matlab o un programa en C++) o un hardware remoto (un robot real, otro ordenador conectado a la misma red…).

Para que Matlab pueda conectarse bien con V-Rep tendrás que importar algunas funciones. Ve al directorio dónde tengas instalado V-Rep->programming->remoteApiBindings->matlab->matlab y copia todos los ficheros acabados en ‘.m’ que hay dentro.

Ahora vete al directorio dónde tengas instalado Matlab->R2016b (o la versión que tengas)->bin y pega los ficheros aquí.

Aún necesitas otro fichero. Vuelve al directorio de V-Rep->programming->remoteApiBindings->lib->lib y encontrarás dos carpetas: 32bit y 64bit. Abre la que se corresponda con los bits de tu sistema operativo, y dentro encontrarás un fichero acabado en .so (Linux) o .dll (Windows). Cópialo y pégalo a la carpeta bin de Matlab, junto con el resto de archivos que acabas de copiar hace un momento.

Ahora puedes abrir Matlab. Verás que en la ventana de la izquierda, dónde pone ‘Current folder’, aparecen listados todos los ficheros que acabas de copiar.


 

2- Preparar la escena de V-Rep

Siempre que quieras crear una escena de V-Rep que interactúe con un programa o script externo tendrás que configurar la escena tal y como te explicaré ahora. Recuerda bien este paso, porque tendrás que repetirlo siempre que quieras hacer una simulación que interactúe con Matlab.

Abre el simulador y crea una nueva escena.

 

Ahora abre el editor de scripts. Es este botón, que se encuentra en la barra lateral de la izquierda:

Se abrirá un panel con todos los scripts que hay actualmente en la escena. Ahora mismo sólo hay uno, el script principal (en rojo), que se encarga de gestionar todos los cálculos que hace el programa al iniciar la simulación. Este script no debes modificarlo a no ser que tengas una buena razón para hacerlo.

Para crear un nuevo script pulsa el botón ‘Insert new script’. Aparecerá un desplegable dónde podrás cambiar el tipo de script. Selecciona ‘Child script (threaded)’ y pulsa OK.

 

El nuevo script aparece en azul, y no está asociado a ningún objeto.

 

Abre el desplegable que hay debajo de la lista de scripts, dónde pone “Associated Object” y escoge un objeto de la escena. Como este script habilitará la conexión entre el simulador y Matlab, es buena idea asociarlo a un objeto que no vayamos a destruir nunca durante la simulación. Por ejemplo el objeto DefaultCamera (la cámara que nos permite ver y moverse por la escena):

 

Una vez asociado el script, ábrelo haciendo doble clic con el botón izquierdo del ratón sobre su nombre. El script viene vacío por defecto, tan sólo hay comentarios que ayudan a organizar el script. Añade la instrucción simExtRemoteApiStart(19999) al principio. Lo que hace es crear un puerto desde el que Matlab podrá conectar con la simulación:

Cierra el editor de texto (los cambios se guardan automáticamente).

La escena ya está preparada. Si quieres asegurarte de que todo ha funcionado correctamente, puedes iniciar la simulación pulsando Play

 

Después, abre Matlab. Copia y pega el siguiente script:

vrep=remApi('remoteApi'); %Crear el objeto vrep y cargar la libreria
clientID=vrep.simxStart('127.0.0.1',19999,true,true,5000,5) %Iniciar conexion con el simulador
vrep.simxFinish(clientID); %Terminar la conexion

 

La primera línea crea el objeto vrep y por tanto carga la librería con todas sus funciones. La segunda línea inicializa la simulación llamando la función simxStart y pasándole seis parámetros:

  1. La dirección IP a la que debe conectarse (la dirección de V-Rep). Por defecto es 127.0.0.1
  2. El puerto al que debe conectarse. Este debe coincidir con el número del puerto que has creado con la instrucción simExtRemoteApiStart() del script del simulador.
  3. Al ponerlo a true, Matlab intentará conectarse con el simulador hasta que consiga una conexión exitosa o se le acabe el tiempo de espera.
  4. Al ponerlo a true, Matlab NO intentará reconectarse con el simulador en caso de que se corte la comunicación entre los dos programas.
  5. Indica el tiempo de espera (en milisegundos) durante el cuál Matlab intentará conectarse con el simulador. En este caso, lo intentará durante cinco segundos antes de considerar la conexión fallida.
  6. Frecuencia de envío de datos. 5 es un valor estándar.

La última línea corta la conexión con el simulador. Hay que hacerlo siempre o puede haber problemas para volver a conectarte al mismo puerto.

Si corres este script y todo ha ido bien, verás que la variable clientID vale un número diferente de -1.

La variable clientID vale 0, por tanto la conexión se ha establecido.

 

Aquí, la variable clientID vale -1. Algo ha fallado.

Si no, la conexión ha fallado y tendrás que revisar todos los pasos que te he contado hasta ahora. Lo más probable es que no hayas pulsado el botón de Play del simulador V-Rep.


3- Motores

El primer ejemplo consistirá en mover los dos motores de un robot Pioneer P3DX. Este robot ya viene incluido en el repositorio de modelos de V-Rep.

El robot Pioneer P3DX es muy utilizado en el ámbito académico y de investigación.

Abre la escena de V-Rep que acabas de configurar y a la izquierda, en Model Browser verás un directorio llamado mobile.

Haz clic encima y verás que debajo aparece un listado con distintos modelos de robots y sus iconos. Ve bajando y selecciona el Pioneer p3dx. Arrástralo a la escena 3D con el botón izquierdo del ratón.

 

El modelo del P3DX viene precargado con un script interno en Lua que lo convierte en un esquiva-obstáculos. Si tienes curiosidad, puedes añadir algun obstáculo a la escena e iniciar la simulación. Verás que el robot avanza mientras evita los obstáculos. No obstante, como nos interesa escribir nuestro propio script, tendremos que deshabilitar este que viene por defecto.

Abre la ventana de Scripts:

Verás que ha aparecido un tercer script: ‘Non-threaded child script (Pioneer_p3dx)’. Para deshabilitarlo tienes que seleccionarlo y marcar la casilla ‘Disabled’:

 

Ahora inicia la simulación y abre Matlab. El siguiente script hará que el robot Pioneer dé vueltas sobre sí mismo.

%Conectarse con el simulador
vrep=remApi('remoteApi');
clientID=vrep.simxStart('127.0.0.1',19999,true,true,5000,5);

if (clientID ~=-1)

	%Crear un handle para los motores
	[err, motor_izquierdo]=vrep.simxGetObjectHandle(clientID, 'Pioneer_p3dx_leftMotor', vrep.simx_opmode_oneshot_wait);
	[err, motor_derecho]=vrep.simxGetObjectHandle(clientID, 'Pioneer_p3dx_rightMotor', vrep.simx_opmode_oneshot_wait);

	while (vrep.simxGetConnectionId(clientID)~=-1) %Mientras la simulacion este activa hay que correr el bucle
		%Cambiar la velocidad de los motores
		vrep.simxSetJointTargetVelocity(clientID, motor_izquierdo,3,vrep.simx_opmode_streaming);
		vrep.simxSetJointTargetVelocity(clientID, motor_derecho,-3,vrep.simx_opmode_streaming);
	end
end

vrep.simxFinish(clientID);

Aquí han aparecido tres funciones nuevas que voy a comentar. La primera es vrep.simxGetObjectHandle(), que sirve para guardar la dirección de un objeto de la escena virtual, para así poder interactuar con él más adelante. Esta función recibe tres parámetros:

      1. La ID del cliente.
      2. El nombre del objeto del mundo
      3. El modo de operación

Se devuelve un array con dos parámetros: ‘err’ indica si se ha producido algún error, y ‘motor_izquierdo/motor_derecho’ guarda la dirección del motor.

La función vrep.simxGetConnectionId() recibe como parámetro la ID de un cliente y comprueba que éste aún esté activo. Si lo está, devuelve 0. Si no, devuelve -1.

Por último, he utilizado la función vrep.simxSetJointTargetVelocity(), que sirve para cambiar la velocidad de los motores, y recibe cuatro parámetros:

  1. La ID del cliente
  2. La dirección del motor que hay que mover.
  3. La velocidad del motor. Puede ser un número con coma flotante, y permite negativos para invertir el giro.
  4. El modo de operación.

Fíjate que al poner 3 y -3 a la velocidad de los motores el robot empieza a dar vueltas sobre sí mismo.


 

4- Sensores de distancia

La mayoría de robots autónomos llevan algún tipo de sensor que les permita recoger información de su entorno. Un tipo de sensor muy habitual son los sensores de distancia, ya sean por ultrasonidos o infrarojos. El modelo del robot Pioneer P3DX lleva dieciséis sensores de distancia, pero en este ejemplo sólo vamos a utilizar dos de ellos. Una vez entiendas el código no deberías tener problema en modificarlo para que lea el resto de sensores.

Primero hay que añadir algún objeto en la escena que pueda ser detectado por el robot. Ve a Model Browser->infrastructure->walls->80cm high y añade algunas piezas (las que quieras) alrededor del robot. Recuerda que para añadir un modelo a la escena 3D, tienes que arrastrarlo con el botón izquierdo del ratón.

 

El script de Matlab leerá los sensores 5 y 6, que se encuentran en la parte delantera central del robot, y escribirá sus valores mientras el robot va girando.


%Conectarse con el simulador
vrep=remApi('remoteApi');
clientID=vrep.simxStart('127.0.0.1',19999,true,true,5000,5);

if (clientID ~=-1)

	%Crear un handle para los motores
	[err, motor_izquierdo]=vrep.simxGetObjectHandle(clientID, 'Pioneer_p3dx_leftMotor', vrep.simx_opmode_oneshot_wait);
	[err, motor_derecho]=vrep.simxGetObjectHandle(clientID, 'Pioneer_p3dx_rightMotor', vrep.simx_opmode_oneshot_wait);

	
	%Crear un handle para los sensores de distancia
	[err, sensorA] = vrep.simxGetObjectHandle(clientID, 'Pioneer_p3dx_ultrasonicSensor4', vrep.simx_opmode_oneshot_wait);
	[err, sensorB] = vrep.simxGetObjectHandle(clientID, 'Pioneer_p3dx_ultrasonicSensor5', vrep.simx_opmode_oneshot_wait);


	%Los sensores de distancia se activan leyéndolos una vez
	%[err, estadoA, puntoA, objeto_detectadoA, vector_normalA] = vrep.simxReadProximitySensor(clientID, sensorA, vrep.simx_opmode_streaming);
	%[err, estadoB, puntoB, objeto_detectadoB, vector_normalB] = vrep.simxReadProximitySensor(clientID, sensorB, vrep.simx_opmode_streaming);



	while (vrep.simxGetConnectionId(clientID)~=-1)

		%Cambiar la velocidad de los motores
		vrep.simxSetJointTargetVelocity(clientID, motor_izquierdo,3,vrep.simx_opmode_streaming);
		vrep.simxSetJointTargetVelocity(clientID, motor_derecho,-3,vrep.simx_opmode_streaming);

		%Leer los dos sensores. En este ejemplo solo nos interesa la variable 'estado'.
		[err, estadoA, puntoA, objeto_detectadoA, vector_normalA] = vrep.simxReadProximitySensor(clientID, sensorA, vrep.simx_opmode_streaming);
		[err, estadoB, puntoB, objeto_detectadoB, vector_normalB] = vrep.simxReadProximitySensor(clientID, sensorB, vrep.simx_opmode_streaming);

		%Para mostrar las lecturas de los sensores, creamos un array con el nombre de cada sensor y su estado.
		%Las variables 'estadoA' y 'estadoB' son variables numericas. Hay que convertirlas a string con la funcion num2str.
		lectura_variables = ['Sensor A: ', num2str(estadoA), '     Sensor B: ', num2str(estadoB)];
		disp(lectura_variables) 



	end
end

vrep.simxFinish(clientID);

La función nueva de este código es vrep.simxReadProximitySensor, que como indica su nombre sirve para leer sensores de proximidad. Esta función recibe tres parámetros:

  1. La ID del cliente
  2. La dirección del sensor
  3. El modo de operación

Y devuelve cinco variables:

  1. ‘err’ es una variable que indica si se ha producido algún error al leer el sensor. En ese caso valdrá -1.
  2. ‘estadoA’ es un booleano que toma los valores 0/1 si el sensor detecta un objeto o no.
  3. ‘objeto_detectadoA’ devuelve la dirección del objeto detectado.
  4. ‘vector_normalA’ es el vector 3D normal a la superfície del objeto detectado.

 

Si corres la simulación, verás como las variables de estado de los sensores van cambiando de 0 a 1 cuándo detectan un obstáculo:


 

5- Sensor de visión (cámara)

Lo último que voy a enseñarte hoy es a capturar y mostrar la imagen de un sensor de visión.

Dentro del simulador de V-Rep, haz clic con el botón derecho del ratón sobre la escena 3D -> Add -> Vision Sensor -> Perspective type.

 

Verás que aparece el cono de una cámara al centro de la escena:

Selecciona el Sensor de Visión (por defecto lleva el nombre de ‘Vision_Sensor’) y abre el panel de propiedades del objeto (Scene Object Properties) haciendo clic en este botón en la barra de la izquierda:

Se abrirá un panel como éste:

Aquí puedes modificar las propiedades de la cámara: su ángulo de visión, resolución, dimensiones, etc. Cambia los campos ‘Near/Far clipping plane’ por 1.00e-02 y 6.00e+00. Esto hará que la cámara sólo tenga un rango de visión de seis metros.

También deberías aumentar la resolución. Cámbiala a 256 x 256, o a 128 x 128 si tienes una máquina poco potente.

 

Tal y como está encarada, la cámara apunta al cielo. Por lo que yo sé, el Pioneer P3DX no es un robot volador, por lo que tendrás que cambiar la orientación de la cámara. Pulsa el botón de Object/Item Rotate:

 

Ve a la pestaña Orientation y cambia el campo Alpha [deg] por 90. Verás que ahora la cámara está paralela al suelo.

 

Ahora pulsa el botón Object/Item shift (está al lado del botón que abre el panel de rotación):

Ve a la pestaña Position y cambia los ejes para que la cámara quede por encima del suelo y el robot entre dentro de su campo de visión. Por ejemplo:

 

El código para Matlab leerá el Vision Sensor y mostrará la imagen en una ventana flotante:

%Conectarse con el simulador
vrep=remApi('remoteApi');
clientID=vrep.simxStart('127.0.0.1',19999,true,true,5000,5);

if (clientID ~=-1)

	%Crear un handle para la camara
	[err, camara] = vrep.simxGetObjectHandle(clientID, 'Vision_sensor', vrep.simx_opmode_oneshot_wait);

	while (vrep.simxGetConnectionId(clientID)~=-1)
                %Capturar imagen con la camara
		[errorCode,resolution,img]=vrep.simxGetVisionSensorImage2(clientID,camara,0,vrep.simx_opmode_oneshot_wait);
		
                %Mostrar imagen en una ventana
                imshow(img);
		drawnow;


	end
end

vrep.simxFinish(clientID);

Vamos a ver qué hacen las nuevas funciones.

vrep.simxGetVisionSensorImage2 sirve para capturar un frame de un Vision Sensor. A parte de recibir la ID del cliente, la dirección del objeto y el modo de operación, el tercer parámetro indica si se quiere guardar la imagen en escala de grises o en RGB. Al pasarle 0, esto indica que la imagen se guardará en color.

Esta función devuelve tres variables: un código de error, la resolución de la imagen y un array con la imagen.

Las funciones imshow() y drawnow son funciones propias de Matlab que sirven para dibujar imágenes y gráficos.

Al ejecutar este script verás que se abre una ventana que muestra todo lo que ve el Sensor de Visión. Esto puede ser de especial utilidad para hacer proyectos de visión por computador y machine learning usando las funciones que tiene Matlab para ello.


Conclusiones

Con estos tres ejemplos ya deberías saber cómo interactuar Matlab con V-Rep. Si necesitas más información sobre las funciones de la API Remota de V-Rep para Matlab, puedes consultar la documentación oficial.

Como siempre, me gusta estar en contacto con nuestros lectores humanos, así que tus comentarios son bienvenidos. Si hay algo que no ha quedado claro, encuentras algún error en el tutorial o simplemente tienes algo que decir, déjame un comentario en el formulario que hay más abajo.

Esto es todo por hoy, humano. Final de línea.

Tr4nsduc7or

Originariamente creado cómo un galvanómetro de bolsillo, Transductor tomó consciencia de si mismo y fue despedido cuando en vez cumplir con su trabajo se dedicó a pensar teorías filosóficas sobre los hilos de cobre, los electrones y el Sentido del efecto Joule en el Universo. Guarda cierto recelo a sus creadores por no comprender la esencia metafísica de las metáforas de su obra. Actualmente trabaja a media jornada cómo antena de radio, y dedica su tiempo libre a la electrónica recreativa y a la filosofía.

Antes de comentar, por favor, lee las Normas

4 Comentarios en "Interacción entre V-Rep y Matlab"

avatar
Ordenar por:   más nuevos primero | más antiguos primero
Marysol
Humano

podrías hacer algún tutorial para conectarlo con ROS y vrep 😀 ?

Humano
Humano

opino lo mismo!!!

El primero
Humano

Soy el primero 😀

wpDiscuz