package org.sunspotworld.demo; import com.sun.spot.peripheral.Spot; import com.sun.spot.peripheral.radio.IRadioPolicyManager; import com.sun.spot.io.j2me.radiostream.*; import com.sun.spot.io.j2me.radiogram.*; import com.sun.spot.util.IEEEAddress; import javax.swing.*; import java.awt.*; import java.lang.Math; import java.io.*; import javax.microedition.io.*; /** * Aplicacion anfitriona Sun SPOT, encargada de la inicialización de la aplicacion * y además del comportamiento de la interfaz gráfica * * @author Mauricio Diaz, Daniel Zuleta * */ public class SunSpotHostApplication { //Variables usadas private double[] data; private double incX; private double incY; private double incZ; private double auxincZ; private int coordXi; private int coordYi; private double coordXd; private double coordYd; private int traslacionX; private int deltaZ; private double velZ, distZ; private int traslacionY; private double accX; private double accY; private double accZ; private int nLineas; private int coordenadas [][]; private int contador; /** * Metodo principal de la clase anfitriona, encargado de inicializar las variables * y de inicializar la escucha de paquetes a traves de la estacion base */ public void run() { data = new double[8]; //arreglo que recibirá el datagrama incX = 0; incY = 0; incZ = 0; coordXi = 0; coordYi = 0; coordXd = 0; coordYd = 0; traslacionX = 450; traslacionY = 350; accX = 0; accY = 0; accZ = 0; nLineas = 1; contador = 0; //Arreglo utilizado para guardar las coordenadas de la espada //para poder dejar una "estela" coordenadas = new int[2][nLineas]; //Inicialización del arreglo de coordenadas for(int i=0;i corresponde al frame usado para poner nuestro JPanel JFrame frame = new JFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //drawPanel -> es una instancia de JPanel que va en el frame //para poder dibujar cada vez nuestra espada MyDrawPanel drawPanel = new MyDrawPanel(); frame.setBounds(75,25,900,700); frame.getContentPane().add(drawPanel); frame.setVisible(true); //Ahora hacer siempre: while(true){ try { dg.reset(); dgConnection.receive(dg); data[0]=dg.readInt(); //opcionSW1 data[1]=dg.readDouble(); // inclinacion x data[2]=dg.readDouble(); // inclinacion y data[3]=dg.readDouble(); // inclinacion z data[4]=dg.readDouble(); // aceleracion x data[5]=dg.readDouble(); // aceleracion y data[6]=dg.readDouble(); // aceleracion z data[7]=dg.readInt(); //opcion SW2 incX = data[1]; incY = data[2]; auxincZ = incZ; incZ = data[3]; accX = data[4]; accY = data[5]; accZ = data[6]; if(data[0]==0){ System.out.println("accX: "+accX); } if(data[0]==1){ System.out.println("accY: "+accY); } if(data[0]==2){ System.out.println("accZ: "+accZ); } //Solo dibujar si la espada esta en "posicion correcta" if(incY>=-90 && incY<=30) drawPanel.repaint(); } catch (IOException e) { System.out.println("Nothing received"); } } } /** * Main de la aplicacion anfitriona, donde se instancia esta misma y se * hecha a andar en forma normal. * * @param args cualquier argumento de la linea de comandos */ public static void main(String[] args) throws Exception { SunSpotHostApplication app = new SunSpotHostApplication(); app.run(); System.exit(0); } //clase interna que permite la manipulación de la interfaz gráfica: /** * Clase interna, auxiliar, utilizada con el fin de implementar el metodo * para redibujar una y otra vez el JPanel, de manera de que la espada * muestre la ilusión de movimiento a través de la pantalla. * */ class MyDrawPanel extends JPanel{ public void paintComponent (Graphics g){ if(data[7]==1){ deltaZ = calculoDeltaZ(); if(((traslacionX + deltaZ) >= 30) && ((traslacionX + deltaZ) <= 870)) traslacionX = traslacionX + deltaZ; else { distZ = 0; velZ = 0; } } //Trasladamos el origen(0,0) al punto indicado por traslacionX y traslacionY g.translate(traslacionX,traslacionY); //Pintamos el Fondo de color blanco g.setColor(Color.white); g.fillRect(-900,-700,1800,1400); //DIbujamos lineas orientadoras de color azul g.setColor(Color.blue); g.drawLine(-100,0,-50,0); //izquierda del centro g.drawLine(50,0,100,0); //derecha del centro g.drawLine(0,-100,0,-50); //arriba del centro g.drawLine(0,0,0,50); //abajo del centro if(data[7]==0){ //Llevar la inclinación en el eje Z del SPOT a coordenadas plano XY transfCoord(incZ); //Forma de transformar desde grados hasta un factor que le da el //tamaño a la espada de manera de tener la sensacion de profundidad coordXi = (int) ((1-(Math.abs(incX)/90))*coordXd); coordYi = (int) ((1-(Math.abs(incX)/90))*coordYd); //Varias implementaciones para encontrar el "tamaño" de la espada en //vez de usar la que esta arriba //Forma de transformar desde radianes en incX // coordXi = (int) (Math.cos(incX)*coordXd); // coordYi = (int) (Math.cos(incX)*coordYd); //Forma de Mostrar solo la inclinación izquierda/derecha // coordXi = (int) coordXd; // coordYi = (int) coordYd; } //Ingresamos la linea actual al registro de las coordenadas //anteriores para dibujar la "estela" de la espada coordenadas[0][contador] = coordXi; coordenadas[1][contador] = coordYi; //Dibujamos la recta que será controlada por el Sun SPOT // g.setColor(Color.red); crearLineas(g,coordenadas,nLineas); } } /** * Metodo que encuentra el cambio en la traslacion que debe sufrir la * espada segun lo que indiquen los datos de la aceleracion. * * @return el cambio sufrido por la posicion de la espada en el eje X de la pantalla. */ private int calculoDeltaZ(){ //cada vez que calculamos el valor del delta, este se resetea. int delta = 0; //si la variacion del angulo en z con respecto a la ultima medicion es //mayor que en valor absoluto que 0.05 entonces hacemos el calculo if((incZ - auxincZ) <= 0.05 && (incZ - auxincZ) >= -0.05){ //eliminar mediciones seleccionando solo las que nos sirven y descartando //las que son cosideradas "basura" if(incZ <= 0.1 && incZ >= -0.1){ if(accZ >= 0.015 || accZ <= -0.015) velZ = velZ + 1*accZ; } else if(accZ >= 0.01 || accZ <= -0.01) velZ = velZ + 5*accZ; if(velZ <= 5 && accZ <= 0.05 && accZ >= -0.05) velZ = 0; if(velZ >= -5 && accZ <= 0.05 && accZ >= -0.05) velZ = 0; // System.out.println("velZ: " + velZ); distZ = distZ + 3*velZ; // System.out.println("distZ: " + distZ); if(distZ >= 0) while(distZ >= 1){ delta = delta +1; distZ = distZ -1; } else while(distZ <= -1){ delta = delta -1; distZ = distZ +1; } // System.out.println("distZ" + distZ); // System.out.println("delta: " + delta); } return delta; } /** * Pequeño metodo utilizado para para llevar la inclinacion en el eje Z * entregada por el Sun Spot de rango libre hasta coordenadas cartesianas. * * @param inclinacionZ la inclinacion entregada por el Sun Spot de rango libre. */ private void transfCoord (double inclinacionZ){ coordYd = 300 * Math.cos(inclinacionZ); coordXd = 300 * Math.sin(inclinacionZ); } //Funcion utilizada para crear las lineas en pantalla, formando la ilusión //de una espada con estela /** * Metodo que crea lineas en una determinada grafica de un JPanel, estas * lineas simulan la forma de una espada muy basica de manera de traspasar * los datos entregados por el Sun Spot hasta una interfaz grafica. * * @param g graficas en las que se quiere dibujar. * @param coords coordenadas de las "n" lineas que se quieren dibujar. * @param n numero de lineas a dibujar. */ private void crearLineas (Graphics g,int coords[][], int n){ int [] x=new int[3]; int [] y=new int[3]; x[0]=-10; x[2]=10; y[0]=0; y[2]=0; for(int i=0;i