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?
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
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.
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;
}
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With