Javier Santos Paniego
César Pérez Fernández

miércoles, 24 de febrero de 2010

Práctica2

Seguimos intentando mejorar en nuestros avances con HansF10, pero es inevitable echar mano de aquel mítico concursante de gran hermano, para describir lo que sentimos: "¿Quién me pone la mano encima para que no levante cabeza?".

1. Obteniendo información...

El programa en esencia debía mostrar la información obtenida mediante los distintos sensores conectados a Hans (ultrasonidos e Infrarojos).
El resultado fue el esperado, o incluso mejor ya que hicimos que el programa se actualizase en tiempo real.

El código correspondiente es el que sigue:

import lejos.nxt.*;
public class GetHansInfo {

static String NombreRobot="HansF10";
static UltrasonicSensor US=new UltrasonicSensor(SensorPort.S1);
static LightSensor LS=new LightSensor(SensorPort.S2);

public static void main(String[] args)throws Exception {
while(!Button.ESCAPE.isPressed()){
LCD.clear();
LCD.drawString(NombreRobot, 0, 0);
LCD.drawString("US: " + US.getDistance() + " cm.",0,1);
LCD.drawString("Luz: " + LS.readValue() + " % ("+ LS.readNormalizedValue() + ")",0,2);
LCD.drawString("Bat: " + Battery.getVoltageMilliVolt() + " mV",0,3);
LCD.drawString("Mem: " + (int)(Runtime.getRuntime().freeMemory()),0,4);
Thread.sleep(1000);
}
}
}


2. Control del robot por sonido.





En este ejercicio se nos pedía un programa que hiciese que el robot, atendiendo a una palmada o sonido brusco, avanzase o se detuviera.

En un principio pensamos abordar el problema captando una medida, y en caso de de ser superior a X dB, activar o no el avance del robot. Sin embargo no teníamos en cuenta el ruido ambiente. Si no tenemos en cuenta que el ruido ambiente puede estar cerca del umbral de los X dB que nosotros marcamos deliberadamente, el robot puede comportarse de manera errática.

Así pues decidimos que lo mejor era tomar una medida, esperar una fracción de tiempo, y volver a medir, y si la diferencia entre ambas era muy grande es porque se había producido un ruido brusco.

Aplicando estos criterios obtuvimos el siguiente comportamiento:




El código que implementamos fue el siguiente:

import lejos.nxt.*;
import lejos.robotics.navigation.TachoPilot;
public class ClapControl {

static TachoPilot tp=new TachoPilot(5.6f, 11.0f, Motor.C, Motor.B);
static SoundSensor SS=new SoundSensor(SensorPort.S3);
static boolean moviendose=false;
static final int SONIDO_MAX=30;

public static void main(String[] args)throws Exception {
int sonido1;
int sonido2;
while (!Button.ESCAPE.isPressed()) {
sonido1= SS.readValue();
Thread.sleep(50);
sonido2=SS.readValue();
LCD.drawInt(Math.abs(sonido2-sonido1),2,2);
if (Math.abs(sonido2-sonido1)>=SONIDO_MAX){
if (!moviendose){
tp.forward();
}else{
tp.stop();
}
moviendose=!moviendose;
}
}

}
}


3. Bump & Go! usando sensores de contacto



La práctica de Bump&Go! implementada consiste en poner el robot a avanzar en una dirección, y en cuanto detecte un obstaculo(esta vez mediante sensores de contacto) retrocede, rota un número arbitrario de ángulos y repite los mismos pasos. El ejercicio ha sido sencillo, siendo lo más tedioso tener que demostrar nuestro avanzado control sobre las matemáticas (¡¿?!) al tener que controlar que los giros no fuesen mayores de 180 º, y en caso de serlo usar el ángulo complementario. Lo que conseguimos fue esto:







Código:


import lejos.nxt.*;
import lejos.robotics.navigation.*;

public class BumpAndGo {
static TachoPilot tp = new TachoPilot(5.6f,12f,Motor.C,Motor.B);
static TouchSensor touch1=new TouchSensor(SensorPort.S1);
static TouchSensor touch2=new TouchSensor(SensorPort.S2);

public static void main(String[] args) throws Exception{
int giro;
while(!Button.ESCAPE.isPressed()){
tp.forward();
while(!touch1.isPressed() && !touch2.isPressed()){}
tp.travel(-15);
giro=(int)(Math.random()*360);
if (giro>180){
giro-=360;
}
tp.rotate(giro);
}
}

}



4. Bump & Go! usando sensores de ultrasonido

El comportamiento a sequir debía ser el mismo que el del ejercicio anterior, solo que esta vez usando ultrasonidos. Una vez que la distancia obtenida fuese inferior a X cm, el robot debía retroceder, elegir otra dirección y repetir el proceso.




Código:


import lejos.nxt.Button;
import lejos.nxt.Motor;
import lejos.nxt.SensorPort;
import lejos.nxt.UltrasonicSensor;
import lejos.robotics.navigation.TachoPilot;

public class SAvoidObstacle {


static TachoPilot tp = new TachoPilot(5.6f,11f,Motor.C,Motor.B);
static UltrasonicSensor us = new UltrasonicSensor(SensorPort.S1);

public static void main(String[] args) throws InterruptedException {
int distancia;
int giro;
while(!Button.ESCAPE.isPressed()){
tp.forward();
do{
distancia = us.getDistance();
}while(distancia > 30);
tp.travel(-15);
giro=(int)(Math.random()*360);
if (giro>180){
giro-=360;
}
tp.rotate(giro);

}

}
}




5. Comportamiento sigue-pared para salir de un laberinto




Este ejercicio es el que más problemas nos dio, de hecho, no conseguimos terminarlo. En primer lugar nos costaba que el robot hiciese correctamente el giro de una esquina de 90º. Mediante el método rotate, en cuanto conseguía llegar a los 45º, perdía el contacto con la pared y no se "decidía" si debía girar en sentido horario o antihorario para encontrar de nuevo la pared. Probamos más tarde llamando a "steer(100, giro *5);", es decir, girando, no sobre sí mismo sino sobre la rueda interior, y haciendo un giro de 5º, donde la variable "giro" que puede valer 1 o -1 indica la dirección. El resultado obtenido fue que el robot despues de hacer steer se quedaba parado. Finalmente por falta de tiempo acabamos deshechando la idea de completar este ejercicio. Código con el cual trabajamos:



import lejos.nxt.Button;

import lejos.nxt.LCD;

import lejos.nxt.Motor;

import lejos.nxt.SensorPort;

import lejos.nxt.UltrasonicSensor;
import lejos.robotics.navigation.TachoPilot;

public class SiguePared {


static TachoPilot tp = new TachoPilot(5.6f,11f,Motor.C,Motor.B);

static UltrasonicSensor us = new UltrasonicSensor(SensorPort.S1);

final static int DIFERENCIA_MAX=4;

static int distanciaNormal;
static int distanciaActual;

private static void MostrarInfo() throws Exception{
LCD.clear();
LCD.drawString("Normal=" + distanciaNormal, 2, 2);
LCD.drawString("Actual=" + distanciaActual, 2, 4);
Thread.sleep(30);
}

public static void main(String[] args) throws Exception {
int giro=0;
us.ping();
Thread.sleep(30);
distanciaNormal=us.getDistance();
distanciaActual=distanciaNormal;
us.continuous();
while(!Button.ESCAPE.isPressed()){
tp.forward();
while((Math.abs((distanciaActual=us.getDistance())-distanciaNormal))
distanciaNormal){
giro=-1;
}else{
giro=1;
}
do{
MostrarInfo();
tp.steer(100,giro*5);
}while((Math.abs((distanciaActual=us.getDistance())-distanciaNormal))menor diferencia_max);
MostrarInfo();
}
}
}


6. Calibrado del ultrasonido


En este ejercicio se nos pedía determinar el margen de error y limitaciones del sensor de ultrasonidos.

Apartado 1

Distancia real maxima = 23 distancia real minima = 215

Apartado 2

Para ayudarnos en la tarea hemos usado este pequeño programa :


import lejos.nxt.Button;

import lejos.nxt.LCD;

import lejos.nxt.Motor;

import lejos.nxt.SensorPort;

import lejos.nxt.UltrasonicSensor;

import lejos.robotics.navigation.TachoPilot;

public class PruebaRotando {

private static TachoPilot tp = new TachoPilot(5.6f,12f,Motor.C,Motor.B);

private static UltrasonicSensor us = new UltrasonicSensor(SensorPort.S1);

public static void main(String[] args) throws InterruptedException {

int i,boton,suma,sentido;

sentido = 1;

suma = 0;

boton = 0;

while (!(boton==1)){

boton = Button.waitForPress();

if (boton == 8){

sentido = -1;

}

if (boton == 2){

tp.rotate(sentido*10);

LCD.drawInt(us.getDistance(), 2, 2);

suma += 10*sentido;

LCD.drawInt(suma, 3, 3);

}

else if (boton == 4){

for(i=1;i<=9;i++){

tp.rotate(sentido*1);

LCD.drawInt(us.getDistance(), 2, 2);

suma += 1*sentido;

LCD.drawInt(suma, 3, 3);

Thread.sleep(1000);

}

}

LCD.drawInt(suma, 3, 3);

}

}

}


Estos son los resultados obtenidos:


Grados positivos

10

20

30

40

50

60

70

80

90

medida ultrasonidos

40

40

40

41

255

255

255

255

255

Grados positivos

41

42

43

44

45

46

47

48

49

medida ultrasonidos

41

41

40

41

40

41

40

41

255



Grados negativos

-10

-20

-30

-40

-50

-60

-70

-80

-90

medida ultrasonidos

40

40

41

41

255

255

255

255

255

Grados negativos

-41

-42

-43

-44

-45

-46

-47

-48

-49

medida ultrasonidos

41

40

41

41

40

40

255

255

255

Por tanto el máximo valor negativo para los que los valores son validos es -46 grados, y el positivo 48 grados.


Apartado 3

Medida real

20

30

40

50

60

70

80

90

100

Medida US

22

31

40

50

61

71

81

89

101

La media de los errores entre la medida real y la del ultrasonido es 0,66.


Apartado 4


Real Ultrasonido (10 observaciones)


40

40

40

40

40

40

40

40

40

40

40

50

50

50

50

50

50

50

50

50

50

50

60

61

60

60

60

61

61

60

60

60

60

70

71

71

71

71

71

71

71

71

71

71

80

81

82

81

82

81

81

82

81

81

82

90

90

91

91

91

90

91

91

91

91

91

100

100

101

101

101

100

100

101

101

101

101

110

111

113

112

113

111

112

113

113

112

113

120

120

120

121

120

120

121

120

120

121

120


En vista de los resultados obtenidos no tenemos ninguna evidencia que indique que la distancia influya en el error de medicion del sensor de ultrasonidos.





Eso es todo, amigos...


No hay comentarios: