2011-05-17 20 views
7

Actualmente estoy trabajando en un proyecto de simulación de vuelo con MATLAB/Simulink y Google Earth. Lo que quiero hacer es tener MATLAB/Simulink haciendo todos los cálculos y simulaciones y Google Earth para mostrar el resultado en tiempo real.Alimentando datos al complemento de Google Earth desde MATLAB a través de COM

Para conectar los dos programas, estoy utilizando la interfaz COM, mientras que MATLAB/Simulink como COM-Client e Internet Explorer como servidor COM. Antes de eso, he estado usando la API COM de Google Earth en lugar de la API de Google Earth (la de JavaScript). Sin embargo, algunas de las funciones no están disponibles o limitadas) en la API COM (por ejemplo, pitch, roll).

Por lo tanto, estoy recurriendo a Google Earth Plugin. Este es el ejemplo de cómo debería ser la aplicación web.

http://www.hs-augsburg.de/~bizz145/earth/fps/index3.html

utilizando DOM, puedo escribir en la página web. Pero mi problema es cómo puedo actualizar el cambio que hice en el área de entrada. ¿Es posible desencadenar un evento a través de COM (en mi caso onClick o onBlur)? ¿Hay alguna solución mejor en lugar de usar el elemento Form para enviar los datos a Google Earth?

Respuesta

0

¿Por qué no configurar un servidor xml-rpc o json-rpc para matlab y sondearlo desde la página web utilizando solicitudes ajax. El ángulo de la cámara puede actualizarse utilizando la aplicación javascript.

+0

En realidad, ya tengo éxito al interactuar con Google Earth Plugin y Matlab. Utilizo Internet Explorer como anfitrión para el complemento y controlando la cámara al invocar el JavaScript en el documento html. el problema ahora es que la cámara no quiere moverse en línea recta. puede verlo en acción aquí [enlace] (http://www.youtube.com/watch?v=KS77qORjFh8) la cámara tiene un movimiento suave hacia arriba. pero el movimiento hacia delante tiene un movimiento en zig zag. – Wan

+0

para obtener la Latitud y longitud, convierto la distancia desde la simulación a Lat y Lon usando esta fórmula [enlace] (http://www.movable-type.co.uk/scripts/latlong-vincenty-direct.html) – Wan

+0

Esa fórmula no tiene en cuenta la altitud. ¿Qué sucede si intentas usar una altitud estática? Pero estoy pensando que es un pequeño error como lanzar un float a un int. –

1

Sí, es posible enviar un evento 'triggering' a través de COM, pero no es necesario que lo haga. Si aloja el documento html en matlab, simplemente use execScript() para llamar a los métodos que necesita ... p. Ej.

% Open Plugin 
h = actxcontrol('Shell.Explorer', [0 0 800 600]); 
invoke(h,'Navigate2','host.html'); 

// trigger the behavior, rather than dispatching an event... 
// arguments are: latitude, longitude, altitude, altitudeMode, heading, tilt, roll 
h.Document.parentWindow.execScript(['UpdateCamera(34, 23, 10, 0, 90, 0, 0)'], 'JavaScript'); 

UpdateCamera sería un método COM visibles en 'host.html' - algo así como ...

var UpdateCamera = function() { 
    var a = arguments; // the values from matlab 
    var c = ge.getView().copyAsCamera(ge.ALTITUDE_ABSOLUTE); 
    var oldspeed = ge.getOptions().getFlyToSpeed(); 

    ge.getOptions().setFlyToSpeed(ge.SPEED_TELEPORT); 

    // KmlCamera.set 
    // see http://code.google.com/apis/earth/documentation/reference/interface_kml_camera.html#a716205eab6f634b558fcde6be9c58b50 
    c.set(a[0], a[1], a[2], a[3], a[4], a[5], a[6]); 
    ge.getView().setAbstractView(c); 

    ge.getOptions().setFlyToSpeed(oldspeed);          
} 

En relación con el comentario "zig zag movimiento" - el problema es que la mosca velocidad de la animación en el complemento de Google Earth. Para resolver simplemente agregue las siguientes líneas para alojar html.

function initCB(instance) { 
    ge = instance; 

    // Set the FlyTo speed 
    ge.getOptions().setFlyToSpeed(ge.SPEED_TELEPORT); 

    ... 
} 

Además, para suavizar la animación aún más sería óptimo para activar la animación a través de eventos frameend de la API. Ver: http://earth-api-samples.googlecode.com/svn/trunk/examples/event-frameend.html

1

Resolvimos este problema utilizando la solicitud xmlhttp (javascript a continuación). En nuestro caso, no manejamos la visualización de Matlab, pero el problema es el mismo ... ¿cómo se depositan nuevos valores en la visualización de simulación?

Así es como funciona.

  1. Elija un número de puerto (8080 en nuestro caso)
  2. Escribir código para la máquina que alberga el simulador de Matlab que responde a cualquier solicitud entrante en el puerto 8080 con los datos del estado del modelo actual en formato de texto (ser inteligentes y admite múltiples clientes para que pueda conectar varios frontales gráficos GE a la misma fuente de datos).
  3. Incluya javascript en su visualización de GE similar a lo que ve a continuación. El liveURL es algo así como "http://blob.com/liveData:8080"
  4. Cada vez que recibe el evento 'frameend' llame a readUrl().
  5. para suavizar la animación configurar un filtro de primer orden simple en los datos de posición y actitud - es obvio que necesita utilizar el SPEED_TELEPORT

Esta configuración ha funcionado bien para nosotros. La carga de la red es pequeña.

La latencia asociada con la lectura de datos del servidor es de aproximadamente 150 mseg, lo que puede importar si usted es serio acerca de la sim fidelidad. Dado el comportamiento asíncrono de GE en la carga del terreno y la construcción de datos, puede que no satisfaga al serio científico de la simulación en tiempo real. ¡Pero no puede evitar que la comunidad de GE haga todos sus modelos de terreno para usted!

 xmlhttp = new XMLHttpRequest(); 
    var tmpArr = null; 
    var liveUrlOK = false; 

    function readUrl() { 
     xmlhttp.onreadystatechange = postFileReady; 
     xmlhttp.open('GET', liveUrl, false); 
     xmlhttp.send(null); 
    } 

    function postFileReady() {    // function to handle asynchronous call 
     document.getElementById('noData').innerHTML='No data at ' + liveUrl; 
     document.getElementById('dataOK').innerHTML=''; 
     liveUrlOK = false; 

     if (xmlhttp.readyState==4) { 
      if (xmlhttp.status==200) { 
       tmpArr = xmlhttp.responseText.split('\n'); 
       if (tmpArr && parseFloat(tmpArr[0])) { 
       modelLatCmd  = parseFloat(tmpArr[0]) + latBias; 
       modelLngCmd  = parseFloat(tmpArr[1]) + lngBias; 
       modelAltCmd  = parseFloat(tmpArr[2]) + altBias; 
       modelHeadingCmd = parseFloat(tmpArr[3]); 
       modelTiltCmd = -parseFloat(tmpArr[4]); 
       modelRollCmd = -parseFloat(tmpArr[5]); 
       modelVel  = parseFloat(tmpArr[6]); 
       document.getElementById('noData').innerHTML=''; 
       document.getElementById('dataOK').innerHTML=liveUrl; 
       liveUrlOK = true; 
       } 
      } 
     } 
    } 
Cuestiones relacionadas