NXT Sonar 3D en RobotC

Gráfica_El objetivo de este experimento es lograr una representación de la visión que obtiene el robot mediante un movimiento del NXT sonar 3D, en dos ejes. Para ello se ha situado al sensor ultrasónico en una plataforma capaz de moverse con dos grados de libertad y se han realizado lecturas medidas en varias posiciones. 

NXT sonar 3D: hyperboloide - electricBricksDado que la posición del robot que sostiene el sensor es fija y sólo se trabaja con movimientos de ángulo horizontal y vertical del mismo, si tomamos las lecturas del robot enfrentado a una pared y las representamos deberíamos obtener una figura similar a una de las hojas de un hiperboloide de dos hojas. Como el alcance del sensor es limitado, esta figura será truncada por el alcance del sensor. Existirán además otras distorsiones derivadas de la dependencia que tiene la medida de la distancia con ángulo con el que la superficie se enfrenta al sensor.

Desafortunadamente la teoría anterior no se traduce tan fácilmente en resultados acordes. El motivo es que la distancia devuelta por el sensor ultrasónico se basa en el principio del tiempo de vuelo, pero las ondas de sonido emitidas por el sonar no siempre rebotan en la superficie más cercana y vuelven directamente. La dirección de reflexión dependerá de varios factores, como las características de la superficie sobre la que se refleja el sonido y el ángulo de incidencia entre el haz de sonido y la superficie. Si el ángulo entre el haz y la superficie es muy bajo y la superficie es lisa, es probable que el haz no vuelva al emisor sino que siga otro camino alejándose (es lo que se denomina reflexión especular), por lo que si vuelve en algún momento al emisor, la distancia que interpretará el sonar no será la distancia correcta existente entre el sonar y la superficie, sino mayor. En el peor de los casos el haz se perderá y no tendremos ninguna lectura de distancia. Este problema puede desaparecer si la superficie con la que se encuentra es rugosa porque al llegar el haz a la misma se producen reflexiones irregulares y en este contexto es más probable que alguno de esos haces dispersos sea devuelto directamente al emisor, proporcionando una lectura correcta.

Vista la limitación anterior, una forma de obtener medidas estadísticamente más correctas sería alterar el medio en el que opera el robot y cubrirlo con una capa rugosa. Podríamos emplear para ello papel de lija, por ejemplo, forrando las superficies sobre las esperamos que incida el haz ultrasónico. Esto puede ser factible en un entorno conocido y controlado o con fines educativos, como cuando hacemos experimentos dentro de un laberinto, pero en un entorno “real” será prácticamente imposible, como por ejemplo si tratamos de medir el fondo marino.

Como la sugerencia de alterar el entorno no es posible en la práctica, nos vemos forzados a solucionar el problema de dos modos posibles, bien incrementando el hardware y trabajando con un array de sensores desfasados que realizan medidas sobre un mismo objeto, o bien complicando el programa que interpreta los datos recibidos: la idea en este segundo caso sería realizar un procesado posterior sobre las medidas que el robot fuera tomando y, almacenando dichas medidas, aceptar como válidas aquellas que fuesen variando de forma paulatina. Esta técnica puede ser combinada con ciertas acciones, como forzando al robot a tomar medidas sobre un mismo punto desde diferentes ángulos en zonas con discontinuidades o incongruencias [1]. Por ejemplo: si nos acercamos hacia una supuesta pared, las medidas recibidas deberán ir reduciéndose y, si no es así, podríamos tomar las medidas como incorrectas o revisar la suposición de la existencia de dicha pared.

Otra forma posible de elevar la garantía de las medidas en un proceso de localización del robot es combinando las lecturas del sonar con las de un segundo dispositivo, como por ejemplo un sistema de visión.

NXT sonar 3D - electricBricks

La siguiente es una vista típica de un sonar en dos dimensiones en la que el robot estaría situado en el triángulo rojo. Nos fijamos en que muchas de las dimensiones crecen en líneas que siguen la dirección de un radio que partiría del robot.

NXT sonar 3D : vista de sonar 2D
En el diagrama anterior podemos ver varias zonas en las que se producen saltos bruscos de medidas de distancia, como el señalado con la flecha azul: es bastante sensato pensar que la discontinuidad en la medida entre la parte superior de la zona señalada por el extremo de la línea azul y la parte inferior de la misma sea debida a una reflexión especular. Para confirmar la medida de esa zona podría ser necesario desplazar el robot a una posición como la señalada por el triángulo verde y volver a tomar la medida desde un angulo diferente.

Para el siguiente programa, implementado en robotC, se debe tener en cuenta que el motor A es el encargado de realizar el barrido horizontal, mientras que el motor B es el que proporciona la elevación. En cada barrido horizontal se realizan tantas lecturas como indique el parámetro nr_h_readings, mientras que el parámetro nr_v_readings indica el número de barridos horizontales realizar. Si int nr_v_readings = 1 transformamos el radar 3D en un radar 2D.

Cada una de las lecturas del sensor ultrasónico, situado en el puerto 1 según el programa, se almacena en una línea del fichero de texto testfile.dat. Para que la representación mediante gnuplot sea correcta, en cada una de las líneas del fichero mencionado se incluyen, junto al valor de la lectura de distancia del sensor, las coordenadas de ángulo y elevación.

El siguiente es el inicio del fichero con unas lecturas a modo de ejemplo:

1.0 1.0 39.0
2.0 1.0 39.0
3.0 1.0 39.0
4.0 1.0 39.0
5.0 1.0 38.0

 NXT Sonar 3D: programación en RobotC

#pragma config(Sensor, S4, sonarSensor, sensorSONAR)
//*!!Code automatically generated by 'ROBOTC' configuration wizard!!*//
//
// www.electricbricks.com
//

const string sFileName = "testfile.dat";
TFileIOResult nIoResult;
TFileHandle hFileHandle;
int nFileSize = 40000;
string sString;

task main() {
int distance_in_cm;
int increment_h = 2; // step increment for angle and elevation
int increment_v = 2; // step increment for angle and elevation
int nr_h_readings = 40; // number of horizontal readings
int nr_v_readings = 25; // number of horizontal lines

nMotorEncoder[motorA] = 0; // Reset Motor A Encoder
nMotorEncoder[motorB] = 0; // Reset Motor B Encoder

Delete(sFileName, nIoResult);
OpenWrite(hFileHandle, nIoResult, sFileName, nFileSize);

for (int angle = 0; angle <= nr_h_readings*increment_h; angle = angle + increment_h) {
for (int elevation = 0; elevation <= nr_v_readings*increment_v; elevation = elevation + increment_v) {
while (nMotorEncoder[motorA] < elevation) {
motor[motorA] = 20;
}
motor[motorA] = 0; // Motor A is sincinc
wait1Msec(50);
distance_in_cm = SensorValue[sonarSensor];
nxtDisplayCenteredTextLine(4, "Distancia: %d", distance_in_cm);
wait1Msec(50);
sString = "" + angle + ".0 " + elevation + ".0 " + distance_in_cm + ".0n";
WriteText(hFileHandle, nIoResult, sString);
}

while (nMotorEncoder[motorB] < angle){
motor[motorB] = 20;
}
motor[motorB] = 0;

//return motor A:
while (nMotorEncoder[motorA] > 0) {
motor[motorA] = -10;
}
motor[motorA] = 0;

}
//return motor B:
while (nMotorEncoder[motorB] > 0) {
motor[motorB] = -10;
}
motor[motorB] = 0;

Close(hFileHandle, nIoResult);
}

 

Los datos se graban en un fichero que, finalizada la ejecución del programa, debe ser enviado posteriormente al PC para su representación gráfica. La aplicación que hemos empleado para representar los datos leídos es gnuplot y el programa encargado de ello es el siguiente:

#
# Representación de las lecturas del lector ultrasónico
#
# www.electricbricks.com
#
set title "Lecturas del sensor ultrasónico"
unset hidden3d
set ticslevel 2.0
set view 38,45
set autoscale
set parametric
set style data lines
set key box
set dgrid3d 30,30,100
set xlabel "www.electricBricks.com"
splot "testfile.dat"
pause -1 "Hit return to continue (1)"
reset

Os ponemos un vídeo del proceso de escaneo, acelerado 3x. El robot de la parte inferior es el que realiza el escaneo del modelo TETRIX que tiene enfrente.

Y un vídeo que muestra los resultados del escáner en gnuplot. La depresión que vemos en el gráfico representa la zona en la que se está encontrando al robot Tetrix. La parte plana superior se corresponde a las medidas devueltas con valor 255, valor que devuelve el sensor cuando la distancia está fuera de rango, por lo que esas zonas medidas hay que descartarlas o interpretarlas como fuera de rango.

Nota: Dado que todos los datos se toman desde el mismo punto, lo ideal sería representar la gráfica en coordenadas esféricas y filtrando las mediciones erróneas de 255, pero por simplicidad se ha realizado una representación cartesiana, cuyos valores habría que corregir. Como una primera representación aproximada puede ser suficiente, puesto que no es ése el objetivo de este artículo.

Información adicional:

  • A Method of Ultrasonic Sensor Data Integration for Floorplan Recognition, Joong Hyup Ko, et al.

Comments are closed.