Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Feeding Data to Google Earth Plugin from MATLAB via COM

I am currently working on a flight simulation project with MATLAB/Simulink and Google Earth. What I want to do, is to have MATLAB/Simulink doing all the calculations and simulations and Google Earth to display the result in real time.

To interface the two programmes, I am using COM interface, whereas MATLAB/Simulink as COM-Client and Internet Explorer as COM-server. Before that, I've been using Google Earth COM API instead of Google Earth API (the javascript one). But, some of the functions are not available or limited) in COM API (e.g: pitch, roll).

Therefore, I am resorting to Google Earth Plugin. Here is the example, how the web application should look like.

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

Using DOM, I can write to the webpage. But my problem is, how can I refresh the change that I made in the input area. Is event triggering possible via COM (in my case onClick or onBlur)? Is there any better solution instead of using the Form element to feed the data to Google Earth?

like image 839
Wan Avatar asked May 17 '11 22:05

Wan


2 Answers

Yes dispatching an event 'triggering' is possible via COM, but you don't need to do that. If you are hosting the html document in matlab simply use execScript() to call the methods you require...e.g.

% 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 would be a COM visible method in 'host.html' - something like...

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);                                     
}

With regard to the "zig zag motion" comment - the issue is the fly to speed of the animation in the Google Earth Plugin. To resolve simply add the following lines to you host html.

function initCB(instance) {
  ge = instance;

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

  ...
}

Also, to smooth the animation even further it would be optimal to trigger the animation via the api's frameend event. See: http://earth-api-samples.googlecode.com/svn/trunk/examples/event-frameend.html

like image 149
Fraser Avatar answered Nov 18 '22 18:11

Fraser


We solved this problem using xmlhttp request (javascript below). In our case we weren't driving the visualization from Matlab but the problem is the same... how do you deposit new values into your simulation visualization.

Here's how it works.

  1. Choose a port number (8080 in our case)
  2. Write code for the machine hosting the Matlab sim that responds to any incoming request on port 8080 with your current model state data in text format (be clever and support multiple clients so you can attach multiple GE graphic front ends to the same data source.)
  3. Include javascript in your GE visualization similar to what you see below. The liveURL is something like "http://blob.com/liveData:8080"
  4. Every time you get the 'frameend' event call readUrl().
  5. To smooth out the animation set up a simple first order filter on the position and attitude data - obviously you need to be using the SPEED_TELEPORT

This setup has worked out well for us. The network load is tiny.

The latency associated with reading data off the server is about 150 msec which may matter to you if you are serious about sim fidelity. Given the asynchronous behavior of GE in loading terrain and building data it may not satisfy the serious real-time simulation scientist. But you can't beat having the GE community do all your terrain modeling for you!

     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;
              }
           }
        }
     }
like image 1
GEsim Avatar answered Nov 18 '22 18:11

GEsim