earth.html 14 KB
Newer Older
1
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2 3

<html>
pixhawk's avatar
pixhawk committed
4
  <head>
5 6
  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
  <!-- <head> -->
7
<!-- QGroundControl -->
pixhawk's avatar
pixhawk committed
8 9
    <title>QGroundControl Google Earth View</title>
    <!-- *** Replace the key below below with your own API key, available at http://code.google.com/apis/maps/signup.html *** -->
10
    <script type="text/javascript" src="https://getfirebug.com/firebug-lite-beta.js"></script>
11 12
    <script type="text/javascript" src="http://www.google.com/jsapi?key=ABQIAAAAwbkbZLyhsmTCWXbTcjbgbRSzHs7K5SvaUdm8ua-Xxy_-2dYwMxQMhnagaawTo7L1FE1-amhuQxIlXw"></script>
    <script type="text/javascript">
13
google.load("earth", "1", { 'language': 'en'});
pixhawk's avatar
pixhawk committed
14 15

var ge = null;
16
var initialized = false;
lm's avatar
lm committed
17
var currAircraft = 0;
18
var followEnabled = false;
19 20 21

var lastLat = 0;
var lastLon = 0;
lm's avatar
lm committed
22
var lastAlt = 0;
23 24 25
var currLat = 47.3769;
var currLon = 8.549444;
var currAlt = 470;
26
var currFollowHeading = 0.0;
27 28 29 30 31 32 33 34

var homeLat = 0;
var homeLon = 0;
var homeAlt = 0;
var homeViewRange = 500;
var homeLocation = null;
var homeGroundLevel = 0;

35
var currViewRange = 50.0;	///<< The current viewing range from this position (in meters)
36 37 38 39
var currTilt = 40.0;		///<< The tilt angle (in degrees)
var currFollowTilt = 40.0;
var currView = null;

40 41 42 43 44
var viewMode = 0;
var lastTilt = 0;
var lastRoll = 0;
var lastHeading = 0;

45 46
var M_PI = 3.14159265;

47 48 49 50 51


var planeOrient;
var planeLoc;

52
var aircraft = [];
53 54
var aircraftLocations = [];
var aircraftLastLocations = [];
55 56 57
var attitudes = [];
var locations = [];
var trails = [];
58 59 60
var trailPlacemarks = [];
var trailsVisible = [];
var trailColors = [];
pixhawk's avatar
pixhawk committed
61 62
var waypoints = [];
//var waypointLines = [];
63
//var trailPlacemarks[id];
64
var lineStyle;
65 66

// Aircraft class
67
var planeColor = '6600ffff';
68

69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
// Enable / disable dragging
var draggingAllowed = true;

// Waypoint interaction flags
var dragInfo = null;

var dragWaypointIndex = "";
var dragWaypointLatitude = 0;
var dragWaypointLongitude = 0;
var dragWaypointAltitude = 0;
var dragWaypointPending = false;

// Waypoint creation flags
var newWaypointLatitude = 0;
var newWaypointLongitude = 0;
var newWaypointAltitude = 0;
var newWaypointPending = false;

function getGlobal(variable)
{
	return variable;
}

function getDraggingAllowed()
{
	return draggingAllowed;
}

function setDraggingAllowed(allowed)
{
	draggingAllowed = allowed;
}

function setNewWaypointPending(pending)
{
	newWaypointPending = pending;
}

function setDragWaypointPending(pending)
{
	dragWaypointPending = pending;
}
111 112 113 114 115 116

function isInitialized()
{
	return initialized;
}

pixhawk's avatar
pixhawk committed
117

118 119
function init()
{
120 121 122
	google.earth.createInstance("map3d", initCallback, failureCallback);
}

pixhawk's avatar
pixhawk committed
123 124 125 126 127
function setFollowEnabled(enable)
{
	followEnabled = enable;
}

128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205
function enableEventListener()
{
// listen for mousedown on the window (look specifically for point placemarks)
google.earth.addEventListener(ge.getWindow(), 'mousedown', function(event)
{
  if (draggingAllowed)
  {
  if (event.getTarget().getType() == 'KmlPlacemark' &&
      event.getTarget().getGeometry().getType() == 'KmlPoint') {
    //event.preventDefault();
    var placemark = event.getTarget();
    
    dragInfo = {
      placemark: event.getTarget(),
      dragged: false
    };
  }
  }
});

// listen for mousemove on the globe
google.earth.addEventListener(ge.getGlobe(), 'mousemove', function(event)
{
  if (draggingAllowed)
  {
  if (dragInfo) {
    event.preventDefault();
    var point = dragInfo.placemark.getGeometry();
    point.setLatitude(event.getLatitude());
    point.setLongitude(event.getLongitude());
    dragInfo.dragged = true;
    dragWaypointIndex = dragInfo.placemark.getDescription();
	dragWaypointLatitude = event.getLatitude();
	dragWaypointLongitude = event.getLongitude();
	dragWaypointAltitude = point.getAltitude();
	dragWaypointPending = true;
  }
  }
});

// listen for mouseup on the window
google.earth.addEventListener(ge.getWindow(), 'mouseup', function(event)
{
  if (draggingAllowed)
  {
  if (dragInfo) {
    if (dragInfo.dragged)
    {
      	// if the placemark was dragged, prevent balloons from popping up
      	event.preventDefault();
      	// Get drag end location
      	dragWaypointIndex = dragInfo.placemark.getDescription();
      	var point = dragInfo.placemark.getGeometry();
      	dragWaypointLatitude = event.getLatitude();
		dragWaypointLongitude = event.getLongitude();
		dragWaypointAltitude = point.getAltitude();
    	dragWaypointPending = true;
    }
    
    dragInfo = null;
  }
  }
});

// Listen for wp creation request on the globe

google.earth.addEventListener(ge.getGlobe(), 'dblclick', function(event){
	if (draggingAllowed)
	{
       event.preventDefault();
       newWaypointLatitude = event.getLatitude();
       newWaypointLongitude = event.getLongitude();
       newWaypointAltitude = ge.getGlobe().getGroundAltitude(newWaypointLatitude, newWaypointLongitude);
       newWaypointPending = true;
    }
}); 
}

206 207


208 209 210 211
function setCurrAircraft(id)
{
	currAircraft = id;
}
212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243

function setGCSHome(lat, lon, alt)
{
	homeLat = lat;
	homeLon = lon;
	homeAlt = alt;
	
	
	
	var placemark = ge.createPlacemark(''); 
	    var icon = ge.createIcon(''); 
	    icon.setHref('http://google-maps-icons.googlecode.com/files/blackH.png'); 
	    var style = ge.createStyle(''); 
	    style.getIconStyle().setIcon(icon); 
	    //style.getIconStyle().setScale(0.5); 
	    placemark.setStyleSelector(style);  

	    // Set the placemark's location.   
	    homeLocation = ge.createPoint(''); 
	    homeLocation.setLatitude(lat); 
	    homeLocation.setLongitude(lon);
	    homeLocation.setAltitude(alt); 
	    placemark.setGeometry(homeLocation);  

	    // Add the placemark to Earth. 
	    ge.getFeatures().appendChild(placemark); 

	    homeGroundLevel = ge.getGlobe().getGroundAltitude(lat,lon);
	    if (homeGroundLevel == 0)
	    {
		    homeGroundLevel = alt;
	    }
pixhawk's avatar
pixhawk committed
244 245
}

pixhawk's avatar
pixhawk committed
246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269
function updateWaypointListLength(id, len)
{
	// Delete any non-needed waypoints
	if (waypoints.length > len)
	{
		for (var i=len; i<waypoints.length; i++)
		{
			var placemark = waypoints.pop();
		    ge.getFeatures().removeChild(placemark);
		}
	}
}

function updateWaypoint(id, index, lat, lon, alt, action)
{
	// Check if waypoint exists
	if (waypoints.length > index)
	{
		// Waypoint exists
		// Set the placemark's location.   
	    var location = ge.createPoint(''); 
	    location.setLatitude(lat); 
	    location.setLongitude(lon);
	    location.setAltitude(alt); 
lm's avatar
lm committed
270
	    waypoints[index].setGeometry(location);
271
	    waypoints[index].setDescription(index+"");
lm's avatar
lm committed
272
	    console.log('WP LOC:' + lat + lon + alt);
pixhawk's avatar
pixhawk committed
273 274 275 276 277 278 279 280 281
	}
	else
	{
		// Waypoint does not exist yet
		var placemark = ge.createPlacemark(''); 
	    var icon = ge.createIcon('');
	    var numberstring = index;
	    if (index < 10) numberstring = '0' + numberstring
	    icon.setHref('http://google-maps-icons.googlecode.com/files/red' + numberstring +'.png'); 
lm's avatar
lm committed
282 283
	    var style = ge.createStyle('');
	    console.log('WP ICON created:' + 'http://google-maps-icons.googlecode.com/files/red' + numberstring +'.png');
pixhawk's avatar
pixhawk committed
284 285
	    style.getIconStyle().setIcon(icon); 
	    //style.getIconStyle().setScale(0.5); 
286 287
	    placemark.setStyleSelector(style);
	    placemark.setDescription(index+"");
pixhawk's avatar
pixhawk committed
288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303

	    // Set the placemark's location.   
	    var location = ge.createPoint(''); 
	    location.setLatitude(lat); 
	    location.setLongitude(lon);
	    location.setAltitude(alt); 
	    placemark.setGeometry(location);  

	    // Add the placemark to Earth. 
	    ge.getFeatures().appendChild(placemark); 
		waypoints[index] = placemark;
	}
	// Add connecting line
	
}

pixhawk's avatar
pixhawk committed
304
function createAircraft(id, type, color)
305
{
306
	      planePlacemark = ge.createPlacemark('');
307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325
          planePlacemark.setName('aircraft');
          planeModel = ge.createModel('');
          ge.getFeatures().appendChild(planePlacemark);
          planeLoc = ge.createLocation('');
          planeModel.setLocation(planeLoc);
          planeLink = ge.createLink('');
          planeOrient = ge.createOrientation(''); 
          planeModel.setOrientation(planeOrient); 

          planeLink.setHref('http://qgroundcontrol.org/_media/users/models/multiplex-twinstar.dae');
          planeModel.setLink(planeLink);
          planeModel.setAltitudeMode (ge.ALTITUDE_ABSOLUTE); 

          planeLoc.setLatitude(currLat);
          planeLoc.setLongitude(currLon);
          planeLoc.setAltitude(currAlt);

          planePlacemark.setGeometry(planeModel);
          
pixhawk's avatar
pixhawk committed
326 327 328
          // Write into global structure
          aircraft[id] = planePlacemark;
          attitudes[id] = planeOrient;
329
          aircraftLocations[id] = planeLoc;
330
		  aircraftLastLocations[id] = ge.createLocation('');
331
          //planeColor = color;
pixhawk's avatar
pixhawk committed
332
          
333 334
          createTrail(id, color);
          console.log(color);
pixhawk's avatar
pixhawk committed
335 336 337 338
}

function createTrail(id, color)
{
339
          trailPlacemarks[id] = ge.createPlacemark('');
340
          // Create the placemark
pixhawk's avatar
pixhawk committed
341 342
// Create the LineString; set it to extend down to the ground
// and set the altitude mode
343 344 345 346
trails[id] = ge.createLineString('');
trailPlacemarks[id].setGeometry(trails[id]);
trails[id].setExtrude(false);
trails[id].setAltitudeMode(ge.ALTITUDE_ABSOLUTE);
pixhawk's avatar
pixhawk committed
347 348 349 350 351

// Add LineString points
//lineString.getCoordinates().pushLatLngAlt(48.754, -121.835, 700);

// Create a style and set width and color of line
352 353
trailPlacemarks[id].setStyleSelector(ge.createStyle(''));
lineStyle = trailPlacemarks[id].getStyleSelector().getLineStyle();
pixhawk's avatar
pixhawk committed
354
lineStyle.setWidth(5);
355 356 357 358
trailColors[id] = color;
lineStyle.getColor().set('00000000');  // aabbggrr format

trailsVisible[id] = false;
pixhawk's avatar
pixhawk committed
359 360

// Add the feature to Earth
361
//ge.getFeatures().appendChild(trailPlacemarks[id]);
362

pixhawk's avatar
pixhawk committed
363 364
}

lm's avatar
lm committed
365
function clearTrail(id)
366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381
{
	trailsVisible[id] = false;
	ge.getFeatures().removeChild(trailPlacemarks[id]);
}

function showTrail(id)
{
	ge.getFeatures().appendChild(trailPlacemarks[id]);
	trailsVisible[id] = true;
}

function setViewRange(dist)
{
	currViewRange = dist;
}

pixhawk's avatar
pixhawk committed
382 383
function addTrailPosition(id, lat, lon, alt)
{
384
	trails[id].setExtrude(false);
385
    trails[id].setAltitudeMode(ge.ALTITUDE_ABSOLUTE);
386

387
    // Add LineString points
388
	trails[id].getCoordinates().pushLatLngAlt(lat, lon, alt);
389

390 391 392 393 394 395
    // Create a style and set width and color of line
    trailPlacemarks[id].setStyleSelector(ge.createStyle(''));
    lineStyle = trailPlacemarks[id].getStyleSelector().getLineStyle();
    lineStyle.setWidth(5);
    lineStyle.getColor().set(trailColors[id]);  // aabbggrr format
    //lineStyle.getColor().set(color);  // aabbggrr format
396

397 398
    // Add the feature to Earth
    if (trailsVisible[id] == true) ge.getFeatures().replaceChild(trailPlacemarks[id], trailPlacemarks[id]);
pixhawk's avatar
pixhawk committed
399 400
}

401 402
function initCallback(object)
{
403 404 405 406
    ge = object;
    ge.getWindow().setVisibility(true);
    ge.getOptions().setStatusBarVisibility(true); 
    ge.getOptions().setScaleLegendVisibility(true);
pixhawk's avatar
pixhawk committed
407 408
    //ge.getOptions().setFlyToSpeed(5.0); 
    ge.getOptions().setFlyToSpeed(ge.SPEED_TELEPORT); 
409
    ge.getNavigationControl().setVisibility(ge.VISIBILITY_AUTO);
pixhawk's avatar
pixhawk committed
410
        
411 412 413 414
    ge.getLayerRoot().enableLayerById(ge.LAYER_TERRAIN, true); 
    ge.getLayerRoot().enableLayerById(ge.LAYER_BUILDINGS, true); 
    ge.getLayerRoot().enableLayerById(ge.LAYER_BORDERS, true); 
    ge.getLayerRoot().enableLayerById(ge.LAYER_TREES, true);
415 416
    
    enableEventListener();
417

418
    initialized = true;
419 420 421 422 423 424
}

function setAircraftPositionAttitude(id, lat, lon, alt, roll, pitch, yaw)
{
	if (id == currAircraft)
	{
lm's avatar
lm committed
425 426 427
		if (lastLat == 0)
		{
			lastLat = currLat;
pixhawk's avatar
pixhawk committed
428
			lastLon = currLon;
lm's avatar
lm committed
429
		}
430 431
		currLat = lat;
		currLon = lon;
432 433 434 435 436 437 438 439 440
		var trueGroundAlt = ge.getGlobe().getGroundAltitude(lat, lon);
		if (trueGroundAlt < alt)
		{
		  currAlt = alt;
	    }
	    else
	    {
	      currAlt = trueGroundAlt+0.1;
	    }
pixhawk's avatar
pixhawk committed
441 442 443 444
		// Interpolate between t-1 and t and set new states
		lastLat = lastLat*0.8+currLat*0.2;
		lastLon = lastLon*0.8+currLon*0.2;
		lastAlt = lastAlt*0.8+currAlt*0.2;
445
		//currFollowHeading = ((yaw/M_PI)+1.0)*360.0;
446
	
447
	
448
	// FIXME Currently invalid conversion from right-handed z-down to z-up frame
449 450
	planeOrient.setRoll(((roll/M_PI))*180.0+180.0);
	planeOrient.setTilt(((pitch/M_PI))*180.0+180.0);
451
	planeOrient.setHeading(((yaw/M_PI))*180.0-90.0);
pixhawk's avatar
pixhawk committed
452
	
453
	currFollowHeading = ((yaw/M_PI))*180.0;
454
    
pixhawk's avatar
pixhawk committed
455 456 457
    planeLoc.setLatitude(lastLat);
    planeLoc.setLongitude(lastLon);
    planeLoc.setAltitude(lastAlt);
458
    planeModel.setLocation(planeLoc);
pixhawk's avatar
pixhawk committed
459 460
    
    if (followEnabled) updateFollowAircraft();
461
    }
pixhawk's avatar
pixhawk committed
462 463
}

464 465 466 467 468 469 470 471 472 473 474 475
function enableDaylight(enabled)
{
	if(enabled)
	{
		ge.getSun().setVisibility(true);
	}
	else
	{
		ge.getSun().setVisibility(false);
	}
}
		
476 477 478 479 480 481 482 483 484
function goHome()
{
	var currView = ge.getView().copyAsLookAt(ge.ALTITUDE_ABSOLUTE);
	currView.setLatitude(homeLat);
	currView.setLongitude(homeLon);
	currView.setAltitude(homeAlt);
	currView.setRange(homeViewRange);
	currView.setTilt(currTilt);
	ge.getView().setAbstractView(currView);
pixhawk's avatar
pixhawk committed
485
}
486 487 488 489 490 491

function setCurrentAircraft(id)
{
	currAircraft = id;
}

492 493
/** @brief Set the current view mode
 *
494
 * @param mode 0: side map view, 1: top/north map view, 2: fixed chase cam, 3: free chase cam
495 496 497
 */
function setViewMode(mode)
{
498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521
	viewMode = mode;
	
	var currView = ge.getView().copyAsLookAt(ge.ALTITUDE_ABSOLUTE);
	
	if (mode == 0)
	{
		currView.setTilt(0);
		currView.setHeading(0);
	}
	if (mode == 1)
	{
		lastTilt = currView.getTilt();
		lastHeading = currView.getHeading();
		var lastLat2 = currView.getLatitude();
		var lastLon2 = currView.getLongitude();
		var lastAlt2 = currView.getAltitude();
		currView.setTilt(0);
		currView.setHeading(0);
		currView.setLatitude(lastLat2);
		currView.setLongitude(lastLon2);
		currView.setAltitude(lastAlt2);
	}
	
	ge.getView().setAbstractView(currView);
522 523
}

524 525 526
function updateFollowAircraft()
{
	currView = ge.getView().copyAsLookAt(ge.ALTITUDE_ABSOLUTE);
527 528 529 530
	currView.setLatitude(lastLat);
	currView.setLongitude(lastLon);
	currView.setAltitude(lastAlt);

531 532
	currView.setRange(currViewRange);
	currView.setTilt(currFollowTilt);
533
	currView.setHeading(currFollowHeading);
534
	
535 536 537 538 539 540 541 542 543
	ge.getView().setAbstractView(currView);
}

function failureCallback(object)
{
}
</script>


pixhawk's avatar
pixhawk committed
544 545 546 547 548 549 550 551 552 553 554 555 556 557
    <style type="text/css">
    html, body {
      margin: 0;
      width: 100%;
      height: 100%;
    }
    </style>
  </head>
  <body onload='init()' id='body'>
    <center>
      <div id='map3d' style='margin: 0; spacing: 0; height: 100%; width: 100%'></div>
    </center>
  </body>
</html>