earth.html 15.1 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
var currTilt = 40.0;		///<< The tilt angle (in degrees)
var currFollowTilt = 40.0;
var currView = null;
39
var distanceMode = 0;
40

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

46 47
var M_PI = 3.14159265;

48 49 50 51 52


var planeOrient;
var planeLoc;

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

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

70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
// 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;

88 89
var homePlacemark = null;

90 91 92 93 94 95 96 97 98 99
function getGlobal(variable)
{
	return variable;
}

function getDraggingAllowed()
{
	return draggingAllowed;
}

100 101 102 103 104
function setDistanceMode(mode)
{
	distanceMode = mode;
}

105 106
function setDraggingAllowed(allowed)
{
107
	draggingAllowed = allowed;
108 109 110 111 112 113 114 115 116 117 118
}

function setNewWaypointPending(pending)
{
	newWaypointPending = pending;
}

function setDragWaypointPending(pending)
{
	dragWaypointPending = pending;
}
119 120 121 122 123 124

function isInitialized()
{
	return initialized;
}

pixhawk's avatar
pixhawk committed
125

126 127
function init()
{
128 129 130
	google.earth.createInstance("map3d", initCallback, failureCallback);
}

pixhawk's avatar
pixhawk committed
131 132 133 134 135
function setFollowEnabled(enable)
{
	followEnabled = enable;
}

136 137 138 139 140 141 142 143
function enableEventListener()
{
// listen for mousedown on the window (look specifically for point placemarks)
google.earth.addEventListener(ge.getWindow(), 'mousedown', function(event)
{
  if (event.getTarget().getType() == 'KmlPlacemark' &&
      event.getTarget().getGeometry().getType() == 'KmlPoint') {
    var placemark = event.getTarget();
144 145 146
    event.preventDefault();
      if (draggingAllowed)
  {
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 206 207 208 209 210 211 212
    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;
    }
}); 
}

213 214


215 216 217 218
function setCurrAircraft(id)
{
	currAircraft = id;
}
219 220 221 222 223 224 225 226

function setGCSHome(lat, lon, alt)
{
	homeLat = lat;
	homeLon = lon;
	homeAlt = alt;
	
	
227 228
	if (homePlacemark == null)
	{
229 230 231 232 233 234
	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); 
235 236
	    placemark.setStyleSelector(style);
	    placemark.setDescription('HOME');
237 238 239 240 241 242 243 244 245

	    // 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. 
246 247 248 249 250 251 252 253 254 255 256 257 258
	    ge.getFeatures().appendChild(placemark);
	    
	    homePlacemark = placemark;
	    }
	    else
	    {
	    	var location = ge.createPoint(''); 
	    location.setLatitude(lat); 
	    location.setLongitude(lon);
	    location.setAltitude(alt); 
	    homePlacemark.setGeometry(location);
	    homePlacemark.setDescription('HOME');
	    }
259 260 261 262 263 264

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

pixhawk's avatar
pixhawk committed
267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290
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
291
	    waypoints[index].setGeometry(location);
292
	    waypoints[index].setDescription(index+"");
lm's avatar
lm committed
293
	    console.log('WP LOC:' + lat + lon + alt);
pixhawk's avatar
pixhawk committed
294 295 296 297 298 299 300 301 302
	}
	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
303 304
	    var style = ge.createStyle('');
	    console.log('WP ICON created:' + 'http://google-maps-icons.googlecode.com/files/red' + numberstring +'.png');
pixhawk's avatar
pixhawk committed
305 306
	    style.getIconStyle().setIcon(icon); 
	    //style.getIconStyle().setScale(0.5); 
307 308
	    placemark.setStyleSelector(style);
	    placemark.setDescription(index+"");
pixhawk's avatar
pixhawk committed
309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324

	    // 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
325
function createAircraft(id, type, color)
326
{
327
	      planePlacemark = ge.createPlacemark('');
328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346
          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
347 348 349
          // Write into global structure
          aircraft[id] = planePlacemark;
          attitudes[id] = planeOrient;
350
          aircraftLocations[id] = planeLoc;
351
		  aircraftLastLocations[id] = ge.createLocation('');
352
          //planeColor = color;
pixhawk's avatar
pixhawk committed
353
          
354 355
          createTrail(id, color);
          console.log(color);
pixhawk's avatar
pixhawk committed
356 357 358 359
}

function createTrail(id, color)
{
360
          trailPlacemarks[id] = ge.createPlacemark('');
361
          // Create the placemark
pixhawk's avatar
pixhawk committed
362 363
// Create the LineString; set it to extend down to the ground
// and set the altitude mode
364 365 366 367
trails[id] = ge.createLineString('');
trailPlacemarks[id].setGeometry(trails[id]);
trails[id].setExtrude(false);
trails[id].setAltitudeMode(ge.ALTITUDE_ABSOLUTE);
pixhawk's avatar
pixhawk committed
368 369 370 371 372

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

// Create a style and set width and color of line
373 374
trailPlacemarks[id].setStyleSelector(ge.createStyle(''));
lineStyle = trailPlacemarks[id].getStyleSelector().getLineStyle();
pixhawk's avatar
pixhawk committed
375
lineStyle.setWidth(5);
376 377 378 379
trailColors[id] = color;
lineStyle.getColor().set('00000000');  // aabbggrr format

trailsVisible[id] = false;
pixhawk's avatar
pixhawk committed
380 381

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

pixhawk's avatar
pixhawk committed
384 385
}

lm's avatar
lm committed
386
function clearTrail(id)
387 388 389 390 391 392 393 394 395 396 397 398
{
	ge.getFeatures().removeChild(trailPlacemarks[id]);
	trailPlacemarks[id] = null;
	var isVisible = trailsVisible[id];
	createTrail(id, trailColors[id]);
	if (isVisible)
	{
		showTrail(id);
	}
}

function hideTrail(id)
399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414
{
	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
415 416
function addTrailPosition(id, lat, lon, alt)
{
417
	trails[id].setExtrude(false);
418
    trails[id].setAltitudeMode(ge.ALTITUDE_ABSOLUTE);
419

420
    // Add LineString points
421
	trails[id].getCoordinates().pushLatLngAlt(lat, lon, alt);
422

423 424 425 426 427 428
    // 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
429

430 431
    // Add the feature to Earth
    if (trailsVisible[id] == true) ge.getFeatures().replaceChild(trailPlacemarks[id], trailPlacemarks[id]);
pixhawk's avatar
pixhawk committed
432 433
}

434 435
function initCallback(object)
{
436 437 438 439
    ge = object;
    ge.getWindow().setVisibility(true);
    ge.getOptions().setStatusBarVisibility(true); 
    ge.getOptions().setScaleLegendVisibility(true);
pixhawk's avatar
pixhawk committed
440 441
    //ge.getOptions().setFlyToSpeed(5.0); 
    ge.getOptions().setFlyToSpeed(ge.SPEED_TELEPORT); 
442
    ge.getNavigationControl().setVisibility(ge.VISIBILITY_AUTO);
pixhawk's avatar
pixhawk committed
443
        
444 445 446 447
    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);
448 449
    
    enableEventListener();
450

451
    initialized = true;
452 453 454 455 456 457
}

function setAircraftPositionAttitude(id, lat, lon, alt, roll, pitch, yaw)
{
	if (id == currAircraft)
	{
lm's avatar
lm committed
458 459 460
		if (lastLat == 0)
		{
			lastLat = currLat;
pixhawk's avatar
pixhawk committed
461
			lastLon = currLon;
lm's avatar
lm committed
462
		}
463 464
		currLat = lat;
		currLon = lon;
465 466 467 468 469 470 471 472 473
		var trueGroundAlt = ge.getGlobe().getGroundAltitude(lat, lon);
		if (trueGroundAlt < alt)
		{
		  currAlt = alt;
	    }
	    else
	    {
	      currAlt = trueGroundAlt+0.1;
	    }
pixhawk's avatar
pixhawk committed
474 475 476 477
		// 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;
478
		//currFollowHeading = ((yaw/M_PI)+1.0)*360.0;
479
	
480
	
481
	// FIXME Currently invalid conversion from right-handed z-down to z-up frame
482 483
	planeOrient.setRoll(((roll/M_PI))*180.0+180.0);
	planeOrient.setTilt(((pitch/M_PI))*180.0+180.0);
484
	planeOrient.setHeading(((yaw/M_PI))*180.0-90.0);
pixhawk's avatar
pixhawk committed
485
	
486
	currFollowHeading = ((yaw/M_PI))*180.0;
487
    
pixhawk's avatar
pixhawk committed
488 489 490
    planeLoc.setLatitude(lastLat);
    planeLoc.setLongitude(lastLon);
    planeLoc.setAltitude(lastAlt);
491
    planeModel.setLocation(planeLoc);
pixhawk's avatar
pixhawk committed
492 493
    
    if (followEnabled) updateFollowAircraft();
494
    }
pixhawk's avatar
pixhawk committed
495 496
}

497 498 499 500 501 502 503 504 505 506 507
function enableDaylight(enabled)
{
	if(enabled)
	{
		ge.getSun().setVisibility(true);
	}
	else
	{
		ge.getSun().setVisibility(false);
	}
}
508 509 510 511 512

function enableAtmosphere(enabled)
{
	ge.getOptions().setAtmosphereVisibility(enabled);
}
513
		
514 515 516 517 518 519 520 521 522
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
523
}
524 525 526 527 528 529

function setCurrentAircraft(id)
{
	currAircraft = id;
}

530 531
/** @brief Set the current view mode
 *
532
 * @param mode 0: side map view, 1: top/north map view, 2: fixed chase cam, 3: free chase cam
533 534 535
 */
function setViewMode(mode)
{
536
	var currView = ge.getView().copyAsLookAt(ge.ALTITUDE_RELATIVE_TO_GROUND);
537 538 539
	
	if (mode == 0)
	{
540 541
		currView.setTilt(lastTilt);
		currView.setHeading(lastHeading);
542
	}
543
	if (mode == 1 && viewMode != mode)
544 545 546
	{
		lastTilt = currView.getTilt();
		lastHeading = currView.getHeading();
547 548 549
		//var lastLat2 = currView.getLatitude();
		//var lastLon2 = currView.getLongitude();
		//var lastAlt2 = currView.getAltitude();
550 551
		currView.setTilt(0);
		currView.setHeading(0);
552 553 554
		//currView.setLatitude(lastLat2);
		//currView.setLongitude(lastLon2);
		//currView.setAltitude(lastAlt2);
555 556
	}
	
557 558
	viewMode = mode;
	
559
	ge.getView().setAbstractView(currView);
560 561
}

562 563 564
function updateFollowAircraft()
{
	currView = ge.getView().copyAsLookAt(ge.ALTITUDE_ABSOLUTE);
565 566
	currView.setLatitude(lastLat);
	currView.setLongitude(lastLon);
567 568 569 570 571 572 573 574
	
	if (distanceMode == 1)
	{
		var groundAltitude = ge.getGlobe().getGroundAltitude(lastLat, lastLon);
		currView.setAltitude(groundAltitude);
	}
	
	if (distanceMode == 0) currView.setAltitude(lastAlt);
575

576
	currView.setRange(currViewRange);
577 578 579 580 581 582
	
	if (viewMode != 3) // VIEW_MODE_CHASE_FREE
	{
		currView.setTilt(currFollowTilt);
		currView.setHeading(currFollowHeading);
	}
583
	
584 585 586 587 588 589 590 591 592
	ge.getView().setAbstractView(currView);
}

function failureCallback(object)
{
}
</script>


pixhawk's avatar
pixhawk committed
593 594 595 596 597 598 599 600 601 602 603 604 605 606
    <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>