updated drone_analyzer feature: jaggery app

GPrathap 9 years ago
parent 20beb69419
commit 4c41b73e5c

@ -15,7 +15,7 @@
#
#
#[Device-Configurations]
[Device-Configurations]
owner=${DEVICE_OWNER}
deviceId=${DEVICE_ID}
device-name=${DEVICE_NAME}

@ -1,15 +1,6 @@
{{#zone "topCss"}}
<style>
.thumbnail.icon:before {
padding-top: 0;
}
</style>
{{/zone}}
{{#zone "device-thumbnail"}}
<img src="{{@unit.publicUri}}/images/drone-icon.png"/>
{{/zone}}
{{#zone "device-opetations"}}
<div style="background: #11375B; color: #fff; padding: 10px; margin-bottom: 5px">
Operations
@ -18,53 +9,70 @@
{{unit "iot.unit.device.operation" device=device}}
</div>
{{/zone}}
{{#zone "device-detail-properties"}}
<div class="media-body add-padding-left-5x remove-padding-xs tab-content">
<div class="panel-group tab-content">
<div class="media">
<div class="media-left col-xs-12 col-sm-2 col-md-2 col-lg-2">
<ul class="list-group" role="tablist">
<li><a class="list-group-item" href="#policy_compliance" role="tab"
data-toggle="tab" aria-controls="policy_compliance">Policy Compliance</a>
</li>
<li><a class="list-group-item" href="#event_log" role="tab" data-toggle="tab"
aria-controls="event_log">Operations Log</a></li>
</ul>
</div>
<div class="media-body add-padding-left-5x remove-padding-xs tab-content">
<div class="panel-group tab-content">
<div id="deviceDetails" class="panel panel-default tab-pane active" id="device_details" role="tabpanel" aria-labelledby="device_details">
<div class="panel-heading">Device Details</div>
{{unit "iot.unit.device.stats" device=device}}
</div>
<div class="panel panel-default tab-pane active"
id="device_statistics" role="tabpanel" aria-labelledby="device_statistics">
<div class="panel-heading">Device Statistics</div>
{{unit "iot.unit.device.droneanalyzer.statistics" device=device}}
</div>
<div class="panel panel-default tab-pane" id="policy_compliance" role="tabpanel" aria-labelledby="policy_compliance">
<div class="panel-heading">Policy Compliance <span><a href="#" id="refresh-policy"><i class="fw fw-refresh"></i></a></span></div>
<div class="panel-body">
<div id="policy-spinner" class="wr-advance-operations-init hidden">
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<i class="fw fw-settings fw-spin fw-2x"></i>
&nbsp;&nbsp;&nbsp;
Loading Policy Compliance . . .
<br>
<br>
</div>
<div id="policy-list-container">
<div class="panel-body">
Not available yet
<div class="panel panel-default tab-pane" id="policy_compliance" role="tabpanel"
aria-labelledby="policy_compliance">
<div class="panel-heading">Policy Compliance <span><a href="#"
id="refresh-policy"><i
class="fw fw-refresh"></i></a></span></div>
<div class="panel-body">
<div id="policy-spinner" class="wr-advance-operations-init hidden">
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<i class="fw fw-settings fw-spin fw-2x"></i>
&nbsp;&nbsp;&nbsp;
Loading Policy Compliance . . .
<br>
<br>
</div>
<div id="policy-list-container">
<div class="panel-body">
Not available yet
</div>
<br class="c-both"/>
</div>
<br class="c-both" />
</div>
</div>
</div>
<div class="panel panel-default tab-pane" id="event_log" role="tabpanel" aria-labelledby="event_log">
<div class="panel-heading">Operations Log <span><a href="#" id="refresh-operations"><i class="fw fw-refresh"></i></a></span></div>
<div class="panel-body">
<div id="operations-spinner" class="wr-advance-operations-init hidden">
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<i class="fw fw-settings fw-spin fw-2x"></i>
&nbsp;&nbsp;&nbsp;
Loading Operations Log . . .
<br>
<br>
</div>
<div id="operations-log-container">
<div class="panel-body">
Not available yet
<div class="panel panel-default tab-pane" id="event_log" role="tabpanel"
aria-labelledby="event_log">
<div class="panel-heading">Operations Log <span><a href="#"
id="refresh-operations"><i
class="fw fw-refresh"></i></a></span></div>
<div class="panel-body">
<div id="operations-spinner" class="wr-advance-operations-init hidden">
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<i class="fw fw-settings fw-spin fw-2x"></i>
&nbsp;&nbsp;&nbsp;
Loading Operations Log . . .
<br>
<br>
</div>
<div id="operations-log-container">
<div class="panel-body">
Not available yet
</div>
<br class="c-both"/>
</div>
<br class="c-both" />
</div>
</div>
</div>

@ -1,3 +1,20 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
function onRequest(context) {
var log = new Log("device-view.js");
var deviceType = context.uriParams.deviceType;
@ -11,4 +28,4 @@ function onRequest(context) {
return {"device": device};
}
}
}
}

@ -0,0 +1,197 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
(function () {
var deviceId = $(".device-id");
var deviceIdentifier = deviceId.data("deviceid");
var deviceType = deviceId.data("type");
var payload = [deviceIdentifier];
var operationTable;
if (deviceType == "ios") {
var serviceUrl = "/ios/operation/deviceinfo";
} else if (deviceType == "android") {
var serviceUrl = "/mdm-android-agent/operation/device-info";
}
if(serviceUrl){
invokerUtil.post(serviceUrl, payload,
function(message){
console.log(message);
}, function (message) {
console.log(message);
});
}
$(document).ready(function(){
$(".panel-body").removeClass("hidden");
$("#loading-content").remove();
loadOperationBar(deviceType);
loadOperationsLog();
loadApplicationsList();
loadPolicyCompliance();
$("#refresh-policy").click(function () {
$('#policy-spinner').removeClass('hidden');
loadPolicyCompliance();
});
$("#refresh-apps").click(function () {
$('#apps-spinner').removeClass('hidden');
loadApplicationsList();
});
$("#refresh-operations").click(function () {
$('#operations-spinner').removeClass('hidden');
loadOperationsLog(true);
});
});
function loadOperationsLog(update) {
var operationsLog = $("#operations-log");
var deviceListingSrc = operationsLog.attr("src");
var deviceId = operationsLog.data("device-id");
var deviceType = operationsLog.data("device-type");
$.template("operations-log", deviceListingSrc, function (template) {
var serviceURL = "/devicemgt_admin/operations/"+deviceType+"/"+deviceId;
var successCallback = function (data) {
data = JSON.parse(data);
$('#operations-spinner').addClass('hidden');
var viewModel = {};
viewModel.operations = data;
if(data.length > 0){
var content = template(viewModel);
if(!update) {
$("#operations-log-container").html(content);
operationTable = $('#operations-log-table').datatables_extended();
}else{
$('#operations-log-table').dataTable().fnClearTable();
for(var i=0; i < data.length; i++) {
var status;
if(data[i].status == "COMPLETED") {
status = "<span><i class='fw fw-ok icon-success'></i> Completed</span>";
} else if(data[i].status == "PENDING") {
status = "<span><i class='fw fw-warning icon-warning'></i> Pending</span>";
} else if(data[i].status == "ERROR") {
status = "<span><i class='fw fw-error icon-danger'></i> Error</span>";
} else if(data[i].status == "IN_PROGRESS") {
status = "<span><i class='fw fw-ok icon-warning'></i> In Progress</span>";
}
$('#operations-log-table').dataTable().fnAddData([
data[i].code,
status,
data[i].createdTimeStamp
]);
}
}
}
};
invokerUtil.get(serviceURL,
successCallback, function(message){
console.log(message);
});
});
}
function loadApplicationsList() {
var applicationsList = $("#applications-list");
var deviceListingSrc = applicationsList.attr("src");
var deviceId = applicationsList.data("device-id");
var deviceType = applicationsList.data("device-type");
$.template("application-list", deviceListingSrc, function (template) {
var serviceURL = "/devicemgt_admin/operations/"+deviceType+"/"+deviceId+"/apps";
var successCallback = function (data) {
data = JSON.parse(data);
$('#apps-spinner').addClass('hidden');
var viewModel = {};
if(data != null && data.length > 0) {
for (var i = 0; i < data.length; i++) {
data[i].name = data[i].name.replace(/[^\w\s]/gi, ' ');
data[i].name = data[i].name.replace(/[0-9]/g, ' ');
}
}
viewModel.applications = data;
viewModel.deviceType = deviceType;
if(data.length > 0){
var content = template(viewModel);
$("#applications-list-container").html(content);
}
};
invokerUtil.get(serviceURL,
successCallback, function(message){
console.log(message);
});
});
}
function loadPolicyCompliance() {
var policyCompliance = $("#policy-view");
var policySrc = policyCompliance.attr("src");
var deviceId = policyCompliance.data("device-id");
var deviceType = policyCompliance.data("device-type");
var activePolicy = null;
$.template("policy-view", policySrc, function (template) {
var serviceURLPolicy ="/devicemgt_admin/policies/"+deviceType+"/"+deviceId+"/active-policy"
var serviceURLCompliance = "/devicemgt_admin/policies/"+deviceType+"/"+deviceId;
var successCallbackCompliance = function (data) {
var viewModel = {};
viewModel.policy = activePolicy;
viewModel.deviceType = deviceType;
if(data != null && data.complianceFeatures!= null && data.complianceFeatures != undefined && data.complianceFeatures.length > 0) {
viewModel.compliance = "NON-COMPLIANT";
viewModel.complianceFeatures = data.complianceFeatures;
var content = template(viewModel);
$("#policy-list-container").html(content);
} else {
viewModel.compliance = "COMPLIANT";
var content = template(viewModel);
$("#policy-list-container").html(content);
$("#policy-compliance-table").addClass("hidden");
}
};
var successCallbackPolicy = function (data) {
data = JSON.parse(data);
$('#policy-spinner').addClass('hidden');
if(data != null && data.active == true){
activePolicy = data;
invokerUtil.get(serviceURLCompliance,
successCallbackCompliance, function(message){
console.log(message);
});
}
};
invokerUtil.get(serviceURLPolicy,
successCallbackPolicy, function(message){
console.log(message);
});
});
}
}());

@ -0,0 +1,55 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
$(document).ready(function(){
if (document.getElementById('device-location')){
loadMap();
}
});
function loadMap() {
var map;
function initialize() {
var mapOptions = {
zoom: 18
};
var lat = $("#device-location").data("lat");
var long = $("#device-location").data("long");
if(lat != null && lat != undefined && lat != "" && long != null && long != undefined && long != "") {
$("#map-error").hide();
$("#device-location").show();
map = new google.maps.Map(document.getElementById('device-location'),
mapOptions);
var pos = new google.maps.LatLng(lat,
long);
var marker = new google.maps.Marker({
position: pos,
map: map
});
map.setCenter(pos);
}else{
$("#device-location").hide();
$("#map-error").show();
}
}
google.maps.event.addDomListener(window, 'load', initialize);
}

@ -0,0 +1,12 @@
<div class="wr-app-listing">
<div class="wr-applist">
{{#each applications}}
<a style="text-align: center;width: 100px;height: 100px;">
{{#equal platform "android"}}<i class="fw fw-android"></i>{{/equal}}
{{#equal platform "ios"}}<i class="fw fw-apple"></i>{{/equal}}
{{#equal platform "windows"}}<i class="fw fw-windows"></i>{{/equal}}
<span>{{name}}</span>
</a>
{{/each}}
</div>
</div>

@ -0,0 +1,24 @@
<table class="table table-striped table-hover table-bordered display data-table" id="operations-log-table">
<thead>
<tr class="sort-row">
<th>Operation Code</th>
<th>Status</th>
<th>Request created at</th>
</tr>
</thead>
<tbody>
{{#each operations}}
<tr data-type="selectable" data-id="{{id}}">
<td data-display="{{code}}" data-grid-label="Code">{{code}}</td>
<td data-display="{{status}}" data-grid-label="Status">
{{#equal status "COMPLETED"}}<span><i class="fw fw-ok icon-success"></i> Completed</span>{{/equal}}
{{#equal status "PENDING"}}<span><i class="fw fw-warning icon-warning"></i> Pending</span>{{/equal}}
{{#equal status "ERROR"}}<span><i class="fw fw-error icon-danger"></i> Error</span>{{/equal}}
{{#equal status "IN_PROGRESS"}}<span><i class="fw fw-ok icon-warning"></i> In Progress</span>{{/equal}}
</td>
<td data-display="{{createdTimeStamp}}" data-grid-label="Created Timestamp">{{createdTimeStamp}}</td>
</tr>
{{/each}}
<br class="c-both" />
</tbody>
</table>

@ -0,0 +1,79 @@
<div class="wr-list-group wr-sortable policy-list">
<span class="list-group-item" id="{{id}}">
<div class="row">
<div class="col-lg-3 clearfix">
<span class="wr-list-icon">
{{#equal deviceType "android"}}
<i class=" fw fw-android"></i>
{{/equal}}
{{#equal deviceType "ios"}}
<i class=" fw fw-apple"></i>
{{/equal}}
{{#equal deviceType "windows"}}
<i class=" fw fw-windows"></i>
{{/equal}}
</span>
<span class="wr-list-desc">
<h3 class="wr-list-name">{{policy.policyName}}</h3>
<span class="wr-list-username">{{deviceType}}</span>
</span>
</div>
<div class="col-lg-6">
<div class="row no-gutter">
<div class="wr-desc-list-configs col-lg-4">
<div>
<b>Ownership Type : </b> {{policy.ownershipType}}
</div>
</div>
<div class="wr-desc-list-configs col-lg-4">
<div>
<b>Compliance Type :</b> {{policy.compliance}}
</div>
</div>
<div class="wr-desc-list-configs col-lg-4">
<div>
<b>Compliance :</b>
{{#equal compliance "COMPLIANT"}}
<span><i class="fw fw-ok icon-success"></i> Compliant</span>
{{/equal}}
{{#equal compliance "NON-COMPLIANT"}}
<span><i class="fw fw-warning icon-danger"></i> Not Compliant</span>
{{/equal}}
</div>
</div>
</div>
</div>
<div class="col-lg-3">
<span class="list-group-item-actions">
<a href="/mdm/policies/view?id={{policy.id}}" class="cu-btn-inner policy-view-link" data-id="{{id}}">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-view fw-stack-1x"></i>
</span>
View
</a>
</span>
</div>
</div>
</span>
</div>
<table class="table table-striped table-hover table-bordered display data-table" id="policy-compliance-table">
<thead>
<tr class="sort-row">
<th>Feature</th>
<th>Compliance</th>
</tr>
</thead>
<tbody>
{{#each complianceFeatures}}
<tr data-type="selectable">
<td data-display="{{featureCode}}" data-grid-label="Feature Code">{{featureCode}}</td>
<td data-display="{{compliance}}" data-grid-label="Status">
{{#equal compliance true}}<span><i class="fw fw-ok icon-success"></i> Compliant</span>{{/equal}}
{{#equal compliance false}}<span><i class="fw fw-warning icon-danger"></i> Not Compliant</span>{{/equal}}
</td>
</tr>
{{/each}}
<br class="c-both" />
</tbody>
</table>

@ -1,8 +1,6 @@
{
"deviceType": {
"label": "Drone Analyzer",
"category": "iot",
"downloadAgentUri": "DroneAnalyzerServiceUnitManager/manager/device/drone_analyzer/download",
"downloadAgentLinkGenUri" : "DroneAnalyzerServiceUnitManager/manager/device/drone_analyzer/generate_link"
"category": "iot"
}
}

@ -1,7 +1,7 @@
<div class="col-lg-12 margin-top-double">
<h1 class="grey ">Virtual Firealrm</h1>
<h1 class="grey ">Drone Analyzer</h1>
<hr>
<p class="margin-bottom-double light-grey ">Connect your Android device to the WSO2 device cloud.</p>
<p class="margin-bottom-double light-grey ">Connect your drone device to the WSO2 device cloud.</p>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-4 padding-top">
<img src="{{@unit.publicUri}}/images/drone-icon.png" class="img-responsive">
@ -13,14 +13,7 @@
<p class="grey margin-top">Hardware Requirements </p>
<br>
<ul class="list-unstyled">
<li><span class="fw-stack fw-lg margin-right"><i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-right-arrow fw-stack-1x"></i></span> Raspberry Pi (Internet Enabled)</li>
<li><span class="fw-stack fw-lg margin-right"><i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-right-arrow fw-stack-1x"></i></span> DHT11 Temperature Sensor</li>
<li><span class="fw-stack fw-lg margin-right"><i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-right-arrow fw-stack-1x"></i></span> LED</li>
<li><span class="fw-stack fw-lg margin-right"><i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-right-arrow fw-stack-1x"></i></span> Buzzer(3v)</li>
<li class="padding-top-double"><span class="circle">01</span> Set up your IRIS+ Drone as shown in the schematic below.</li>
</ul>
<br>
@ -38,19 +31,21 @@
<div class="controls">
<input class="new-device-name" style="color:#3f3f3f;padding:5px"
type="text"
placeholder="Ex. Lobby_Firealarm"
placeholder="Ex. drone"
name="deviceName" size="60" required>
<br/><br/>
<input type="hidden" class="deviceType" name="deviceType" value="{{@uriParams.deviceType}}"/>
<input type="radio" name="sketchType" value="simple_agent" id="simple_agent" checked> <label for="simple_agent">Simple Agent</label> &nbsp;&nbsp;
<input type="radio" name="sketchType" value="advanced_agent" id="advanced_agent"> <label for="advanced_agent">Advanced Agent</label>
<br/>
<input type="hidden" class="deviceType" name="deviceType"
value="drone_analyzer"/>
<input type="hidden" class="sketchType" name="sketchType"
value="drone_analyzer"/>
</div>
</div>
<div class="buttons" style="padding-bottom: 0px">
<a class="btn btn-operations" onclick="downloadAgent()">Download
<br/>
<div class="buttons">
<a class="btn-operations" onclick="downloadAgent()">Download
Now</a>
&nbsp;&nbsp;
<a href="#" id="download-device-download-link" class="btn btn-operations">
<a href="#" id="download-device-download-link" class="blue-button">
&nbsp;&nbsp;&nbsp;&nbsp;Copy Link&nbsp;&nbsp;&nbsp;&nbsp;
</a>
&nbsp;&nbsp;
@ -151,9 +146,7 @@
<h3 class="uppercase">Prepare</h3><hr>
<p class="grey margin-top">Get your device ready</p>
<ul class="list-unstyled">
<li class="padding-top-double"><span class="circle">01</span> Set up your RaspberryPi device as shown in the schematic below and get the FireAlarm setup.</li>
<li class="padding-top-double"><span class="circle">02</span> Connect a monitor to your RaspberryPi via the HDMI cable to get a UI view of the device.</li>
<li class="padding-top-double"><span class="circle">03</span> Get the RaspberryPi to connect to the internet (via Ethernet or Wifi) and note its IP_ADDRESS</li>
<li class="padding-top-double"><span class="circle">01</span> Set up your IRIS+ Drone as shown in the schematic below.</li>
</ul>
<br>
</div>
@ -173,9 +166,41 @@
<h3 class="uppercase">Connect (Quick Start)</h3><hr>
<p class="grey margin-top">Internet of Things Foundation Quickstart connection</p>
<ul class="list-unstyled">
<li class="padding-top-double"><span class="circle">01</span> <b>Click on the <i>'Create DEB'</i> button above to get the download link for the FireAlarm setup files</b></li>
<li class="padding-top-double"><span class="circle">02</span> <i>(The following commands can be issued by directly typing into the terminal of the device or by an <b>'ssh'<b> login from a remote PC)</i></li>
<li class="padding-top-double"><span class="circle">03</span> <b>Download the FireAlarm setup files using the following command: 'curl -k < url_link_received_from_the_above_step >> Agent.zip'</b><br/><i>This will download a zip file named 'Agent.zip'</i></li>
<li class="padding-top-double"><span class="circle">01</span> <b>Click on the download button above to get the IRIS+ Drone setup files</b></li>
<li class="padding-top-double"><span class="circle">02</span> <b>Connecting to drone</b>
</br>
<div>
<table class="table table-bordered ">
<thead>
<tr>
<th>Connection type</th>
<th>Connection string</th>
</tr>
</thead>
<tbody>
<tr>
<td>Linux computer connected to the drone via USB</td>
<td>/dev/ttyAMA0(also set baud=57600)</td>
</tr>
<tr>
<td>OSX computer connected to the drone via USB</td>
<td>dev/cu.usbmodem1</td>
</tr>
<tr>
<td>Windows computer connected to the drone via USB (in this case on COM14)</td>
<td>com14</td>
</tr>
<tr>
<td>Windows computer connected to the drone using a 3DR Telemetry Radio on COM14</td>
<td>com14(also set baud=57600)</td>
</tr>
</tbody>
</table>
</div>
Ones you have the setup files please run startservice.sh with root privilege.</br>
<b>Note:</b> these connection types may vary from computer to computer. So please provide the correct
connection port
</li>
</ul>
<br/>
</div>
@ -248,18 +273,4 @@
{{#zone "bottomJs"}}
{{js "/js/download.js"}}
{{js "/js/jquery.validate.js"}}
<script type="text/javascript">
$(document).ready(function(){
toggleEnrollment();
});
function toggleEnrollment(){
$(".modalpopup-content").html($("#qr-code-modal").html());
//generateQRCode(".modalpopup-content .qr-code");
//showPopup();
}
</script>
{{/zone}}

@ -0,0 +1,171 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
.box {
margin-top: 10px;
margin-bottom: 10px;
}
.box-inner {
border: 1px solid #DEDEDE;
border-radius: 3px;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
box-shadow: 0 0 10px rgba(189, 189, 189, 0.4);
-webkit-box-shadow: 0 0 10px rgba(189, 189, 189, 0.4);
-moz-box-shadow: 0 0 10px rgba(189, 189, 189, 0.4);
}
.box-header {
border: none;
padding-top: 5px;
border-bottom: 1px solid #DEDEDE;
border-radius: 3px 3px 0 0;
-webkit-border-radius: 3px 3px 0 0;
-moz-border-radius: 3px 3px 0 0;
height: 35px;
min-height: 35px !important;
margin-bottom: 0;
font-weight: bold;
font-size: 16px;
background: -moz-linear-gradient(top, rgba(255, 255, 255, 0) 0%, rgba(0, 0, 0, 0.1) 100%);
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, rgba(255, 255, 255, 0)), color-stop(100%, rgba(0, 0, 0, 0.1)));
background: -webkit-linear-gradient(top, rgba(255, 255, 255, 0) 0%, rgba(0, 0, 0, 0.1) 100%);
background: -o-linear-gradient(top, rgba(255, 255, 255, 0) 0%, rgba(0, 0, 0, 0.1) 100%);
background: -ms-linear-gradient(top, rgba(255, 255, 255, 0) 0%, rgba(0, 0, 0, 0.1) 100%);
background: linear-gradient(to bottom, rgba(255, 255, 255, 0) 0%, rgba(0, 0, 0, 0.1) 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00ffffff', endColorstr='#1a000000', GradientType=0);
}
.box-header h2 {
font-size: 15px;
width: auto;
clear: none;
float: left;
line-height: 25px;
white-space: nowrap;
font-weight: bold;
margin-top: 0;
margin-bottom: 0;
}
.box-header h3 {
font-size: 13px;
width: auto;
clear: none;
float: left;
line-height: 25px;
white-space: nowrap;
}
.box-header h2 > i {
margin-top: 1px;
}
.box-icon {
float: right;
}
.box-icon a {
clear: none;
float: left;
margin: 0 2px;
height: 20px;
width: 5px;
margin-top: 1px;
}
.box-icon a i {
margin-left: -6px;
top: -1px;
}
.box-content {
padding: 10px;
}
.btn-round {
border-radius: 40px;
-webkit-border-radius: 40px;
-moz-border-radius: 40px;
font-size: 12px;
padding-top: 4px;
}
.navbar-brand {
font-family: 'Shojumaru', cursive, Arial, serif;
letter-spacing: 2px;
text-shadow: 1px 1px 5px rgba(0, 0, 0, 0.5);
width: 183px;
font-size: 17px;
}
.navbar-brand img {
float: left;
height: 20px;
width: 20px;
margin-right: 5px;
}
.navbar-brand span {
float: left;
}
.navbar-search {
margin-left: 10px;
margin-top: 7px;
}
.navbar-inner {
padding-top: 5px;
padding-bottom: 5px;
line-height: 30px;
height: 60px;
}
.navbar-inner .btn-group {
margin: 7px 5px 0 5px;
}
.bs-icons li {
list-style: none;
}
.box-content .nav-tabs {
margin-right: -10px;
margin-left: -10px;
}
.box-content.buttons {
min-height: 297px;
}
.sidebar-nav .nav-header {
display: block;
padding: 3px 15px;
font-size: 11px;
font-weight: bold;
line-height: 18px;
color: #999999;
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
text-transform: uppercase;
}
.navbar {
border-radius: 0;
}

@ -0,0 +1,206 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
var camera, scene, renderer;
var cameraControls;
var clock = new THREE.Clock();
var ground = true;
var circle1, plate1;
var object_maker = function () {
var make_object = this;
make_object.fillScene = function () {
scene = new THREE.Scene();
scene.fog = new THREE.Fog(0x808080, 2000, 4000);
var ambientLight = new THREE.AmbientLight(0x222222);
var light = new THREE.DirectionalLight(0xFFFFFF, 1.0);
light.position.set(200, 400, 500);
var light2 = new THREE.DirectionalLight(0xFFFFFF, 1.0);
light2.position.set(-500, 250, -200);
scene.add(ambientLight);
scene.add(light);
scene.add(light2);
if (ground) {
Coordinates.drawGround({size: 10000});
}
var robotBaseMaterial = new THREE.MeshPhongMaterial({color: 0x6E23BB, specular: 0x6E23BB, shininess: 20});
var robotForearmMaterial = new THREE.MeshPhongMaterial({color: 0xF4C154, specular: 0xF4C154, shininess: 100});
circle1 = new THREE.Object3D();
var circleLength = 40;
make_object.addCircles(circle1, circleLength, robotBaseMaterial);
circle1.position.y = circleLength * 2;
scene.add(circle1);
plate1 = new THREE.Object3D();
var plateLength = 40;
make_object.addPlates(plate1, plateLength, robotForearmMaterial);
plate1.position.y = circleLength / 8;
circle1.add(plate1);
},
make_object.addPlates = function (part, plateLength, material) {
var cylinder = new THREE.Mesh(
new THREE.CylinderGeometry(5, 5, 40, 32), material);
cylinder.rotation.x = 90 * Math.PI / 180;
cylinder.position.x = plateLength + 15;
part.add(cylinder);
cylinder = new THREE.Mesh(
new THREE.CylinderGeometry(5, 5, 40, 32), material);
cylinder.rotation.x = 90 * Math.PI / 180;
cylinder.rotation.z = 90 * Math.PI / 180;
cylinder.position.x = plateLength + 15;
part.add(cylinder);
cylinder = new THREE.Mesh(
new THREE.CylinderGeometry(5, 5, 40, 32), material);
cylinder.rotation.x = 90 * Math.PI / 180;
cylinder.position.x = -plateLength - 15;
part.add(cylinder);
cylinder = new THREE.Mesh(
new THREE.CylinderGeometry(5, 5, 40, 32), material);
cylinder.rotation.x = 90 * Math.PI / 180;
cylinder.rotation.z = 90 * Math.PI / 180;
cylinder.position.x = -plateLength - 15;
part.add(cylinder);
cylinder = new THREE.Mesh(
new THREE.CylinderGeometry(5, 5, 40, 32), material);
cylinder.rotation.x = 90 * Math.PI / 180;
cylinder.position.z = -plateLength - 15;
part.add(cylinder);
cylinder = new THREE.Mesh(
new THREE.CylinderGeometry(5, 5, 40, 32), material);
cylinder.rotation.x = 90 * Math.PI / 180;
cylinder.rotation.z = 90 * Math.PI / 180;
cylinder.position.z = -plateLength - 15;
part.add(cylinder);
//
cylinder = new THREE.Mesh(
new THREE.CylinderGeometry(5, 5, 40, 32), material);
cylinder.rotation.x = 90 * Math.PI / 180;
cylinder.position.z = plateLength + 15;
part.add(cylinder);
cylinder = new THREE.Mesh(
new THREE.CylinderGeometry(5, 5, 40, 32), material);
cylinder.rotation.x = 90 * Math.PI / 180;
cylinder.rotation.z = 90 * Math.PI / 180;
cylinder.position.z = plateLength + 15;
part.add(cylinder);
},
make_object.addCircles = function (part, circleLength, material) {
var circle = new THREE.Mesh(
new THREE.TorusGeometry(40, 10, 40, 20, 6.3), material);
circle.position.x = circleLength + 10;
circle.rotation.x = 90 * Math.PI / 180;
part.add(circle);
circle = new THREE.Mesh(
new THREE.TorusGeometry(40, 10, 40, 20, 6.3), material);
circle.position.x = -circleLength - 10;
circle.rotation.x = 90 * Math.PI / 180;
part.add(circle);
circle = new THREE.Mesh(
new THREE.TorusGeometry(40, 10, 40, 20, 6.3), material);
circle.position.z = -circleLength - 10;
circle.rotation.x = 90 * Math.PI / 180;
part.add(circle);
circle = new THREE.Mesh(
new THREE.TorusGeometry(40, 10, 40, 20, 6.3), material);
circle.position.z = circleLength + 10;
circle.rotation.x = 90 * Math.PI / 180;
part.add(circle);
},
make_object.init = function (holder, object_width, object_height) {
var canvasRatio = 1;
renderer = new THREE.WebGLRenderer({antialias: true});
renderer.gammaInput = true;
renderer.gammaOutput = true;
renderer.setSize(object_width, object_height);
renderer.setClearColorHex(0xAAAAAA, 1.0);
$(holder).append(renderer.domElement);
camera = new THREE.PerspectiveCamera(30, canvasRatio, 1, 10000);
camera.position.set(-510, 240, 100);
cameraControls = new THREE.OrbitAndPanControls(camera, renderer.domElement);
cameraControls.target.set(0, 100, 0);
make_object.fillScene();
},
make_object.animate = function () {
window.requestAnimationFrame(make_object.animate);
make_object.render();
},
make_object.render = function () {
var delta = clock.getDelta();
cameraControls.update(delta);
circle1.rotation.z = config_api.effectController.uz;
circle1.rotation.y = config_api.effectController.uy; // yaw
circle1.rotation.x = config_api.effectController.ux; // roll
circle1.position.z = config_api.effectController.fz;
circle1.position.x = config_api.effectController.fx;
renderer.render(scene, camera);
},
make_object.get_heading_attitude_bank = function (data) {
if (data.length < 4) {
return {"heading": data[0], "attitude": data[1], "bank": data[2]};
} else {
var heading = Math.atan2(2 * data[1] * data[3] - 2 * data[0] * data[1], 1 - 2 * data[1] * data[1]
- 2 * data[2] * data[2]);
var bank = Math.atan2(2 * data[0] * data[3] - 2 * data[1] * data[2], 1 - 2 * data[0] * data[0]
- 2 * data[2] * data[2]);
var attitude = Math.asin(2 * data[0] * data[1] + 2 * data[2] * data[3]);
return {
"heading": isNaN(heading) ? 0 : heading,
"bank": isNaN(bank) ? 0 : bank,
"attitude": isNaN(attitude) ? 0 : attitude
};
}
},
make_object.set_heading_attitude_bank = function (data) {
config_api.effectController.uy = data.heading;
config_api.effectController.uz = data.attitude;
config_api.effectController.ux = data.bank;
},
make_object.set_heading = function (holder, heading) {
var r = (180 / Math.PI) * parseFloat(heading);
$(holder).rotate(r);
},
make_object.set_bank = function (holder, bank) {
var r = (180 / Math.PI) * parseFloat(bank);
$(holder).rotate(r);
}
};

@ -0,0 +1,148 @@
/*global THREE, scene*/
var Coordinates = {
drawGrid:function(params) {
params = params || {};
var size = params.size !== undefined ? params.size:100;
var scale = params.scale !== undefined ? params.scale:0.1;
var orientation = params.orientation !== undefined ? params.orientation:"x";
var grid = new THREE.Mesh(
new THREE.PlaneGeometry(size, size, size * scale, size * scale),
new THREE.MeshBasicMaterial({ color: 0x555555, wireframe: true })
);
// Yes, these are poorly labeled! It would be a mess to fix.
// What's really going on here:
// "x" means "rotate 90 degrees around x", etc.
// So "x" really means "show a grid with a normal of Y"
// "y" means "show a grid with a normal of X"
// "z" means (logically enough) "show a grid with a normal of Z"
if (orientation === "x") {
grid.rotation.x = - Math.PI / 2;
} else if (orientation === "y") {
grid.rotation.y = - Math.PI / 2;
} else if (orientation === "z") {
grid.rotation.z = - Math.PI / 2;
}
scene.add(grid);
},
drawGround:function(params) {
params = params || {};
var size = params.size !== undefined ? params.size:100;
var color = params.color !== undefined ? params.color:0xFFFFFF;
var ground = new THREE.Mesh(
new THREE.PlaneGeometry(size, size),
// When we use a ground plane we use directional lights, so illuminating
// just the corners is sufficient.
// Use MeshPhongMaterial if you want to capture per-pixel lighting:
// new THREE.MeshPhongMaterial({ color: color, specular: 0x000000,
new THREE.MeshLambertMaterial({ color: color,
// polygonOffset moves the plane back from the eye a bit, so that the lines on top of
// the grid do not have z-fighting with the grid:
// Factor == 1 moves it back relative to the slope (more on-edge means move back farther)
// Units == 4 is a fixed amount to move back, and 4 is usually a good value
polygonOffset: true, polygonOffsetFactor: 1.0, polygonOffsetUnits: 4.0
}));
ground.rotation.x = - Math.PI / 2;
scene.add(ground);
},
drawAxes:function(params) {
// x = red, y = green, z = blue (RGB = xyz)
params = params || {};
var axisRadius = params.axisRadius !== undefined ? params.axisRadius:0.04;
var axisLength = params.axisLength !== undefined ? params.axisLength:11;
var axisTess = params.axisTess !== undefined ? params.axisTess:48;
var axisOrientation = params.axisOrientation !== undefined ? params.axisOrientation:"x";
var axisMaterial = new THREE.MeshLambertMaterial({ color: 0x000000, side: THREE.DoubleSide });
var axis = new THREE.Mesh(
new THREE.CylinderGeometry(axisRadius, axisRadius, axisLength, axisTess, 1, true),
axisMaterial
);
if (axisOrientation === "x") {
axis.rotation.z = - Math.PI / 2;
axis.position.x = axisLength/2-1;
} else if (axisOrientation === "y") {
axis.position.y = axisLength/2-1;
}
scene.add( axis );
var arrow = new THREE.Mesh(
new THREE.CylinderGeometry(0, 4*axisRadius, 8*axisRadius, axisTess, 1, true),
axisMaterial
);
if (axisOrientation === "x") {
arrow.rotation.z = - Math.PI / 2;
arrow.position.x = axisLength - 1 + axisRadius*4/2;
} else if (axisOrientation === "y") {
arrow.position.y = axisLength - 1 + axisRadius*4/2;
}
scene.add( arrow );
},
drawAllAxes:function(params) {
params = params || {};
var axisRadius = params.axisRadius !== undefined ? params.axisRadius:0.04;
var axisLength = params.axisLength !== undefined ? params.axisLength:11;
var axisTess = params.axisTess !== undefined ? params.axisTess:48;
var axisXMaterial = new THREE.MeshLambertMaterial({ color: 0xFF0000 });
var axisYMaterial = new THREE.MeshLambertMaterial({ color: 0x00FF00 });
var axisZMaterial = new THREE.MeshLambertMaterial({ color: 0x0000FF });
axisXMaterial.side = THREE.DoubleSide;
axisYMaterial.side = THREE.DoubleSide;
axisZMaterial.side = THREE.DoubleSide;
var axisX = new THREE.Mesh(
new THREE.CylinderGeometry(axisRadius, axisRadius, axisLength, axisTess, 1, true),
axisXMaterial
);
var axisY = new THREE.Mesh(
new THREE.CylinderGeometry(axisRadius, axisRadius, axisLength, axisTess, 1, true),
axisYMaterial
);
var axisZ = new THREE.Mesh(
new THREE.CylinderGeometry(axisRadius, axisRadius, axisLength, axisTess, 1, true),
axisZMaterial
);
axisX.rotation.z = - Math.PI / 2;
axisX.position.x = axisLength/2-1;
axisY.position.y = axisLength/2-1;
axisZ.rotation.y = - Math.PI / 2;
axisZ.rotation.z = - Math.PI / 2;
axisZ.position.z = axisLength/2-1;
scene.add( axisX );
scene.add( axisY );
scene.add( axisZ );
var arrowX = new THREE.Mesh(
new THREE.CylinderGeometry(0, 4*axisRadius, 4*axisRadius, axisTess, 1, true),
axisXMaterial
);
var arrowY = new THREE.Mesh(
new THREE.CylinderGeometry(0, 4*axisRadius, 4*axisRadius, axisTess, 1, true),
axisYMaterial
);
var arrowZ = new THREE.Mesh(
new THREE.CylinderGeometry(0, 4*axisRadius, 4*axisRadius, axisTess, 1, true),
axisZMaterial
);
arrowX.rotation.z = - Math.PI / 2;
arrowX.position.x = axisLength - 1 + axisRadius*4/2;
arrowY.position.y = axisLength - 1 + axisRadius*4/2;
arrowZ.rotation.z = - Math.PI / 2;
arrowZ.rotation.y = - Math.PI / 2;
arrowZ.position.z = axisLength - 1 + axisRadius*4/2;
scene.add( arrowX );
scene.add( arrowY );
scene.add( arrowZ );
}
};

@ -0,0 +1,531 @@
/**
* @author qiao / https://github.com/qiao
* @author mrdoob / http://mrdoob.com
* @author alteredq / http://alteredqualia.com/
* @author WestLangley / http://github.com/WestLangley
* @author erich666 / http://erichaines.com
*/
/*global THREE, console */
THREE.OrbitAndPanControls = function ( object, domElement ) {
THREE.EventDispatcher.call( this );
this.enabled = true;
this.object = object;
this.domElement = ( domElement !== undefined ) ? domElement : document;
// API
this.enabled = true;
this.target = new THREE.Vector3();
// center is old, deprecated; use "target" instead
this.center = this.target;
// This option actually enables dollying in and out
this.noZoom = false;
this.zoomSpeed = 1.0;
this.noRotate = false;
this.rotateSpeed = 1.0;
this.noPan = false;
this.autoRotate = false;
this.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60
this.minPolarAngle = 0; // radians
this.maxPolarAngle = Math.PI; // radians
this.minDistance = 0;
this.maxDistance = Infinity;
this.noKeys = false;
this.keys = { LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40 };
// internals
var scope = this;
var EPS = 0.000001;
var rotateStart = new THREE.Vector2();
var rotateEnd = new THREE.Vector2();
var rotateDelta = new THREE.Vector2();
var panStart = new THREE.Vector2();
var panEnd = new THREE.Vector2();
var panDelta = new THREE.Vector2();
var dollyStart = new THREE.Vector2();
var dollyEnd = new THREE.Vector2();
var dollyDelta = new THREE.Vector2();
var phiDelta = 0;
var thetaDelta = 0;
var scale = 1;
var pan = new THREE.Vector3();
var lastPosition = new THREE.Vector3();
var STATE = { NONE : -1, ROTATE : 0, DOLLY : 1, PAN : 2, TOUCH_ROTATE : 3, TOUCH_DOLLY : 4, TOUCH_PAN : 5 };
var state = STATE.NONE;
// events
var changeEvent = { type: 'change' };
this.rotateLeft = function ( angle ) {
if ( angle === undefined ) {
angle = getAutoRotationAngle();
}
thetaDelta -= angle;
};
this.rotateUp = function ( angle ) {
if ( angle === undefined ) {
angle = getAutoRotationAngle();
}
phiDelta -= angle;
};
// pass in distance in world space to move left
this.panLeft = function ( distance ) {
var panOffset = new THREE.Vector3();
var te = this.object.matrix.elements;
// get X column of matrix
panOffset.set( te[0], te[1], te[2] );
panOffset.multiplyScalar(-distance);
pan.add( panOffset );
};
// pass in distance in world space to move up
this.panUp = function ( distance ) {
var panOffset = new THREE.Vector3();
var te = this.object.matrix.elements;
// get Y column of matrix
panOffset.set( te[4], te[5], te[6] );
panOffset.multiplyScalar(distance);
pan.add( panOffset );
};
// main entry point; pass in Vector2 of change desired in pixel space,
// right and down are positive
this.pan = function ( delta ) {
if ( scope.object.fov !== undefined )
{
// perspective
var position = scope.object.position;
var offset = position.clone().sub( scope.target );
var targetDistance = offset.length();
// half of the fov is center to top of screen
targetDistance *= Math.tan( (scope.object.fov/2) * Math.PI / 180.0 );
// we actually don't use screenWidth, since perspective camera is fixed to screen height
scope.panLeft( 2 * delta.x * targetDistance / scope.domElement.height );
scope.panUp( 2 * delta.y * targetDistance / scope.domElement.height );
}
else if ( scope.object.top !== undefined )
{
// orthographic
scope.panLeft( delta.x * (scope.object.right - scope.object.left) / scope.domElement.width );
scope.panUp( delta.y * (scope.object.top - scope.object.bottom) / scope.domElement.height );
}
else
{
// camera neither orthographic or perspective - warn user
console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.' );
}
};
this.dollyIn = function ( dollyScale ) {
if ( dollyScale === undefined ) {
dollyScale = getZoomScale();
}
scale /= dollyScale;
};
this.dollyOut = function ( dollyScale ) {
if ( dollyScale === undefined ) {
dollyScale = getZoomScale();
}
scale *= dollyScale;
};
this.update = function () {
var position = this.object.position;
var offset = position.clone().sub( this.target );
// angle from z-axis around y-axis
var theta = Math.atan2( offset.x, offset.z );
// angle from y-axis
var phi = Math.atan2( Math.sqrt( offset.x * offset.x + offset.z * offset.z ), offset.y );
if ( this.autoRotate ) {
this.rotateLeft( getAutoRotationAngle() );
}
theta += thetaDelta;
phi += phiDelta;
// restrict phi to be between desired limits
phi = Math.max( this.minPolarAngle, Math.min( this.maxPolarAngle, phi ) );
// restrict phi to be betwee EPS and PI-EPS
phi = Math.max( EPS, Math.min( Math.PI - EPS, phi ) );
var radius = offset.length() * scale;
// restrict radius to be between desired limits
radius = Math.max( this.minDistance, Math.min( this.maxDistance, radius ) );
// move target to panned location
this.target.add( pan );
offset.x = radius * Math.sin( phi ) * Math.sin( theta );
offset.y = radius * Math.cos( phi );
offset.z = radius * Math.sin( phi ) * Math.cos( theta );
position.copy( this.target ).add( offset );
this.object.lookAt( this.target );
thetaDelta = 0;
phiDelta = 0;
scale = 1;
pan.set(0,0,0);
if ( lastPosition.distanceTo( this.object.position ) > 0 ) {
this.dispatchEvent( changeEvent );
lastPosition.copy( this.object.position );
}
};
function getAutoRotationAngle() {
return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;
}
function getZoomScale() {
return Math.pow( 0.95, scope.zoomSpeed );
}
function onMouseDown( event ) {
if ( scope.enabled === false ) { return; }
event.preventDefault();
if ( event.button === 0 ) {
if ( scope.noRotate === true ) { return; }
state = STATE.ROTATE;
rotateStart.set( event.clientX, event.clientY );
} else if ( event.button === 1 ) {
if ( scope.noZoom === true ) { return; }
state = STATE.DOLLY;
dollyStart.set( event.clientX, event.clientY );
} else if ( event.button === 2 ) {
if ( scope.noPan === true ) { return; }
state = STATE.PAN;
panStart.set( event.clientX, event.clientY );
}
document.addEventListener( 'mousemove', onMouseMove, false );
document.addEventListener( 'mouseup', onMouseUp, false );
}
function onMouseMove( event ) {
if ( scope.enabled === false ) { return; }
event.preventDefault();
if ( state === STATE.ROTATE ) {
if ( scope.noRotate === true ) { return; }
rotateEnd.set( event.clientX, event.clientY );
rotateDelta.subVectors( rotateEnd, rotateStart );
// rotating across whole screen goes 360 degrees around
scope.rotateLeft( 2 * Math.PI * rotateDelta.x / scope.domElement.width * scope.rotateSpeed );
// rotating up and down along whole screen attempts to go 360, but limited to 180
scope.rotateUp( 2 * Math.PI * rotateDelta.y / scope.domElement.height * scope.rotateSpeed );
rotateStart.copy( rotateEnd );
} else if ( state === STATE.DOLLY ) {
if ( scope.noZoom === true ) { return; }
dollyEnd.set( event.clientX, event.clientY );
dollyDelta.subVectors( dollyEnd, dollyStart );
if ( dollyDelta.y > 0 ) {
scope.dollyIn();
} else {
scope.dollyOut();
}
dollyStart.copy( dollyEnd );
} else if ( state === STATE.PAN ) {
if ( scope.noPan === true ) { return; }
panEnd.set( event.clientX, event.clientY );
panDelta.subVectors( panEnd, panStart );
scope.pan( panDelta );
panStart.copy( panEnd );
}
}
function onMouseUp( /* event */ ) {
if ( scope.enabled === false ) { return; }
document.removeEventListener( 'mousemove', onMouseMove, false );
document.removeEventListener( 'mouseup', onMouseUp, false );
state = STATE.NONE;
}
function onMouseWheel( event ) {
// this is needed when the program is inside an iframe
// to prevent scrolling the whole page
event.preventDefault();
if ( scope.enabled === false ) { return; }
if ( scope.noZoom === true ) { return; }
var delta = 0;
if ( event.wheelDelta ) { // WebKit / Opera / Explorer 9
delta = event.wheelDelta;
} else if ( event.detail ) { // Firefox
delta = - event.detail;
}
if ( delta > 0 ) {
scope.dollyOut();
} else {
scope.dollyIn();
}
}
function onKeyDown( event ) {
if ( scope.enabled === false ) { return; }
if ( scope.noKeys === true ) { return; }
if ( scope.noPan === true ) { return; }
// pan a pixel - I guess for precise positioning?
switch ( event.keyCode ) {
case scope.keys.UP:
scope.pan( new THREE.Vector2( 0, 1 ) );
break;
case scope.keys.BOTTOM:
scope.pan( new THREE.Vector2( 0, -1 ) );
break;
case scope.keys.LEFT:
scope.pan( new THREE.Vector2( 1, 0 ) );
break;
case scope.keys.RIGHT:
scope.pan( new THREE.Vector2( -1, 0 ) );
break;
}
}
function touchstart( event ) {
if ( scope.enabled === false ) { return; }
switch ( event.touches.length ) {
case 1: // one-fingered touch: rotate
if ( scope.noRotate === true ) { return; }
state = STATE.TOUCH_ROTATE;
rotateStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
break;
case 2: // two-fingered touch: dolly
if ( scope.noZoom === true ) { return; }
state = STATE.TOUCH_DOLLY;
var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;
var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;
var distance = Math.sqrt( dx * dx + dy * dy );
dollyStart.set( 0, distance );
break;
case 3: // three-fingered touch: pan
if ( scope.noPan === true ) { return; }
state = STATE.TOUCH_PAN;
panStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
break;
default:
state = STATE.NONE;
}
}
function touchmove( event ) {
if ( scope.enabled === false ) { return; }
event.preventDefault();
event.stopPropagation();
switch ( event.touches.length ) {
case 1: // one-fingered touch: rotate
if ( scope.noRotate === true ) { return; }
if ( state !== STATE.TOUCH_ROTATE ) { return; }
rotateEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
rotateDelta.subVectors( rotateEnd, rotateStart );
// rotating across whole screen goes 360 degrees around
scope.rotateLeft( 2 * Math.PI * rotateDelta.x / scope.domElement.width * scope.rotateSpeed );
// rotating up and down along whole screen attempts to go 360, but limited to 180
scope.rotateUp( 2 * Math.PI * rotateDelta.y / scope.domElement.height * scope.rotateSpeed );
rotateStart.copy( rotateEnd );
break;
case 2: // two-fingered touch: dolly
if ( scope.noZoom === true ) { return; }
if ( state !== STATE.TOUCH_DOLLY ) { return; }
var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;
var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;
var distance = Math.sqrt( dx * dx + dy * dy );
dollyEnd.set( 0, distance );
dollyDelta.subVectors( dollyEnd, dollyStart );
if ( dollyDelta.y > 0 ) {
scope.dollyOut();
} else {
scope.dollyIn();
}
dollyStart.copy( dollyEnd );
break;
case 3: // three-fingered touch: pan
if ( scope.noPan === true ) { return; }
if ( state !== STATE.TOUCH_PAN ) { return; }
panEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
panDelta.subVectors( panEnd, panStart );
scope.pan( panDelta );
panStart.copy( panEnd );
break;
default:
state = STATE.NONE;
}
}
function touchend( /* event */ ) {
if ( scope.enabled === false ) { return; }
state = STATE.NONE;
}
this.domElement.addEventListener( 'contextmenu', function ( event ) { event.preventDefault(); }, false );
this.domElement.addEventListener( 'mousedown', onMouseDown, false );
this.domElement.addEventListener( 'mousewheel', onMouseWheel, false );
this.domElement.addEventListener( 'DOMMouseScroll', onMouseWheel, false ); // firefox
this.domElement.addEventListener( 'keydown', onKeyDown, false );
this.domElement.addEventListener( 'touchstart', touchstart, false );
this.domElement.addEventListener( 'touchend', touchend, false );
this.domElement.addEventListener( 'touchmove', touchmove, false );
};

@ -0,0 +1,50 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
var ajax_handler = function () {
var api = this;
api.response = "v";
api.ajaxRequest = function (url, type, data, dataType, callback) {
var response;
$.ajax({
url: url,
type: type,
dataType: dataType,
success: function (data, success) {
api.response = data;
console.log(" success " + JSON.stringify(success));
console.log(" data " + JSON.stringify(data));
callback(data, success);
},
error: function (jqxhr, textStatus, error) {
var err = textStatus + ', ' + error;
console.log("Request Failed: " + err);
callback(data, error);
api.response = data;
},
data: data
});
return api.response;
};
api.makeJSONObject = function () {
var object = {};
for (var i = 0; i < arguments.length - 1; i = i + 2) {
object[arguments[i]] = arguments[i + 1];
}
return object;
}
};

@ -0,0 +1,101 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
$('.btn-minimize').click(function (e) {
e.preventDefault();
var $target = $(this).parent().parent().next('.box-content');
if ($target.is(':visible')) {
$('i', $(this)).removeClass('glyphicon-chevron-up').addClass('glyphicon-chevron-down');
checkAndDisable($(this).parent().attr('id'));
}
else {
$('i', $(this)).removeClass('glyphicon-chevron-down').addClass('glyphicon-chevron-up');
checkAndEnable($(this).parent().attr('id'));
}
$target.slideToggle();
});
function checkAndEnable(id) {
//console.log("enable: " + id);
if (id === "RealtimePlotting") {
config_api.modules_status.realtimePlotting = true;
}
else if (id === "SensorReadings") {
config_api.modules_status.sensorReadings = true;
} else if (id === "AngleOfRotation_2") {
config_api.modules_status.angleOfRotation_2 = true;
} else if (id === "AngleOfRotation_1") {
config_api.modules_status.angleOfRotation_1 = true;
}
}
function checkAndDisable(id) {
//console.log("disable: " + id);
if (id === "RealtimePlotting") {
config_api.modules_status.realtimePlotting = false;
}
else if (id === "SensorReadings") {
config_api.modules_status.sensorReadings = false;
} else if (id === "AngleOfRotation_2") {
config_api.modules_status.angleOfRotation_2 = false;
} else if (id === "AngleOfRotation_1") {
config_api.modules_status.angleOfRotation_1 = false;
}
}
function isJSON(data) {
try {
return JSON.parse(data);
}
catch (error) {
return null;
}
}
function Queue() {
var a = [], b = '';
this.enqueue = function (b) {
a.push([this.getLength() - 1 <= 0 ? 0 : this.getLength() - 1, b]);
};
this.dequeue = function () {
if (0 != a.length) {
var c = a[b];
2 * ++b >= a.length && (a = a.slice(b), b = 0);
return c
}
};
this.getLength = function () {
return a.length - b;
};
this.isEmpty = function () {
return 0 == a.length;
};
this.peek = function () {
return 0 < a.length ? a[b] : void 0
};
this.getData = function () {
return a;
};
this.make_fixed_size = function (start, end) {
a = a.slice(start, end);
}
}

@ -0,0 +1,60 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
var webSocket_api = function () {
var api = this;
api.wekSocket;
api.message = function (holder) {
return $("#" + holder + "");
},
api.openSocket = function (url, callback) {
if (api.wekSocket !== undefined && api.wekSocket.readyState !== WebSocket.CLOSED) {
console.log("WebSocket is already opened.");
} else {
api.wekSocket = new WebSocket(url);
}
api.wekSocket.onopen = function (event) {
if (event.data === undefined)
return;
api.writeResponse(event.data);
callback(event.data);
};
api.wekSocket.onmessage = function (event) {
api.writeResponse(event.data);
};
api.wekSocket.onclose = function (event) {
api.writeResponse(event.data);
};
},
api.send = function (message) {
api.wekSocket.send(message);
},
api.closeSocket = function () {
api.wekSocket.close();
},
api.writeResponse = function (arg) {
console.log(arg);
}
}

@ -0,0 +1,39 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
//TODO this needs to a private resource
var config_api = function () {
var config_api = this;
var domain = "localhost";
var port = "9793";
var context_controller = "/drone_analyzer/DroneAnalyzerServiceUnitManager/controller/send_command";
config_api.config_3dobject_holder = "#virtualDrone";
config_api.realtime_plotting_update_interval = 30;
config_api.realtime_plotting_totalPoints = 30;
config_api.realtime_plotting_data_window = {};
config_api.effectController = {uy: 70.0, uz: 15.0, ux: 10.0, fx: 2.0, fz: 15.0, Tmax: 1};
config_api.drone_control = "http://" + domain + ":" + port + "/" + context_controller;
config_api.drone_controlType = "POST";
config_api.drone_controlDataType = "json";
config_api.web_socket_endpoint = "ws://localhost:9763/drone_analyzer/datastream/drone_status";
config_api.modules_status = {
"realtimePlotting": false,
"sensorReadings": false,
"angleOfRotation_2": false,
"angleOfRotation_1": false
};
};

@ -0,0 +1,174 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*
*/
var modalPopup = ".wr-modalpopup";
var modalPopupContainer = modalPopup + " .modalpopup-container";
var modalPopupContent = modalPopup + " .modalpopup-content";
var body = "body";
/*
* set popup maximum height function.
*/
function setPopupMaxHeight() {
$(modalPopupContent).css('max-height', ($(body).height() - ($(body).height() / 100 * 30)));
$(modalPopupContainer).css('margin-top', (-($(modalPopupContainer).height() / 2)));
}
/*
* show popup function.
*/
function showPopup() {
$(modalPopup).show();
setPopupMaxHeight();
$('#downloadForm').validate({
rules: {
deviceName: {
minlength: 4,
required: true
}
},
highlight: function (element) {
$(element).closest('.control-group').removeClass('success').addClass('error');
},
success: function (element) {
$(element).closest('.control-group').removeClass('error').addClass('success');
$('label[for=deviceName]').remove();
}
});
var deviceType = "";
$('.deviceType').each(function () {
if (this.value != "") {
deviceType = this.value;
}
});
}
/*
* hide popup function.
*/
function hidePopup() {
$('label[for=deviceName]').remove();
$('.control-group').removeClass('success').removeClass('error');
$(modalPopupContent).html('');
$(modalPopup).hide();
}
/*
* DOM ready functions.
*/
$(document).ready(function () {
attachEvents();
});
function attachEvents() {
/**
* Following click function would execute
* when a user clicks on "Download" link
* on Device Management page in WSO2 DC Console.
*/
$("a.download-link").click(function () {
var sketchType = $(this).data("sketchtype");
var deviceType = $(this).data("devicetype");
var downloadDeviceAPI = "/devicemgt/api/devices/sketch/generate_link";
var payload = {"sketchType": sketchType, "deviceType": deviceType};
$(modalPopupContent).html($('#download-device-modal-content').html());
showPopup();
var deviceName;
$("a#download-device-download-link").click(function () {
$('.new-device-name').each(function () {
if (this.value != "") {
deviceName = this.value;
}
});
$('label[for=deviceName]').remove();
if (deviceName && deviceName.length >= 4) {
payload.deviceName = deviceName;
invokerUtil.post(
downloadDeviceAPI,
payload,
function (data, textStatus, jqxhr) {
doAction(data);
},
function (data) {
doAction(data);
}
);
}else if(deviceName){
$('.controls').append('<label for="deviceName" generated="true" class="error" style="display: inline-block;">Please enter at least 4 characters.</label>');
$('.control-group').removeClass('success').addClass('error');
} else {
$('.controls').append('<label for="deviceName" generated="true" class="error" style="display: inline-block;">This field is required.</label>');
$('.control-group').removeClass('success').addClass('error');
}
});
$("a#download-device-cancel-link").click(function () {
hidePopup();
});
});
}
function downloadAgent() {
$('#downloadForm').submit();
var deviceName;
$('.new-device-name').each(function () {
if (this.value != "") {
deviceName = this.value;
}
});
if (deviceName && deviceName.length >= 4) {
setTimeout(function () {
hidePopup();
}, 1000);
}
}
function doAction(data) {
//if it is saml redirection response
if (data.status == null) {
document.write(data);
}
if (data.status == "200") {
$(modalPopupContent).html($('#download-device-modal-content-links').html());
$("input#download-device-url").val(data.responseText);
$("input#download-device-url").focus(function () {
$(this).select();
});
showPopup();
} else if (data.status == "401") {
$(modalPopupContent).html($('#device-401-content').html());
$("#device-401-link").click(function () {
window.location = "/devicemgt/login";
});
showPopup();
} else if (data == "403") {
$(modalPopupContent).html($('#device-403-content').html());
$("#device-403-link").click(function () {
window.location = "/devicemgt/login";
});
showPopup();
} else {
$(modalPopupContent).html($('#device-unexpected-error-content').html());
$("a#device-unexpected-error-link").click(function () {
hidePopup();
});
}
}

@ -0,0 +1,21 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
var ajax_handler = new ajax_handler();
var config_api = new config_api();
var plotting = new plotting();
var object_maker = new object_maker();

@ -0,0 +1,339 @@
// VERSION: 2.3 LAST UPDATE: 11.07.2013
/*
* Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
*
* Made by Wilq32, wilq32@gmail.com, Wroclaw, Poland, 01.2009
* Website: http://jqueryrotate.com
*/
(function($) {
var supportedCSS,supportedCSSOrigin, styles=document.getElementsByTagName("head")[0].style,toCheck="transformProperty WebkitTransform OTransform msTransform MozTransform".split(" ");
for (var a = 0; a < toCheck.length; a++) if (styles[toCheck[a]] !== undefined) { supportedCSS = toCheck[a]; }
if (supportedCSS) {
supportedCSSOrigin = supportedCSS.replace(/[tT]ransform/,"TransformOrigin");
if (supportedCSSOrigin[0] == "T") supportedCSSOrigin[0] = "t";
}
// Bad eval to preven google closure to remove it from code o_O
eval('IE = "v"=="\v"');
jQuery.fn.extend({
rotate:function(parameters)
{
if (this.length===0||typeof parameters=="undefined") return;
if (typeof parameters=="number") parameters={angle:parameters};
var returned=[];
for (var i=0,i0=this.length;i<i0;i++)
{
var element=this.get(i);
if (!element.Wilq32 || !element.Wilq32.PhotoEffect) {
var paramClone = $.extend(true, {}, parameters);
var newRotObject = new Wilq32.PhotoEffect(element,paramClone)._rootObj;
returned.push($(newRotObject));
}
else {
element.Wilq32.PhotoEffect._handleRotation(parameters);
}
}
return returned;
},
getRotateAngle: function(){
var ret = [];
for (var i=0,i0=this.length;i<i0;i++)
{
var element=this.get(i);
if (element.Wilq32 && element.Wilq32.PhotoEffect) {
ret[i] = element.Wilq32.PhotoEffect._angle;
}
}
return ret;
},
stopRotate: function(){
for (var i=0,i0=this.length;i<i0;i++)
{
var element=this.get(i);
if (element.Wilq32 && element.Wilq32.PhotoEffect) {
clearTimeout(element.Wilq32.PhotoEffect._timer);
}
}
}
});
// Library agnostic interface
Wilq32=window.Wilq32||{};
Wilq32.PhotoEffect=(function(){
if (supportedCSS) {
return function(img,parameters){
img.Wilq32 = {
PhotoEffect: this
};
this._img = this._rootObj = this._eventObj = img;
this._handleRotation(parameters);
}
} else {
return function(img,parameters) {
this._img = img;
this._onLoadDelegate = [parameters];
this._rootObj=document.createElement('span');
this._rootObj.style.display="inline-block";
this._rootObj.Wilq32 =
{
PhotoEffect: this
};
img.parentNode.insertBefore(this._rootObj,img);
if (img.complete) {
this._Loader();
} else {
var self=this;
// TODO: Remove jQuery dependency
jQuery(this._img).bind("load", function(){ self._Loader(); });
}
}
}
})();
Wilq32.PhotoEffect.prototype = {
_setupParameters : function (parameters){
this._parameters = this._parameters || {};
if (typeof this._angle !== "number") { this._angle = 0 ; }
if (typeof parameters.angle==="number") { this._angle = parameters.angle; }
this._parameters.animateTo = (typeof parameters.animateTo === "number") ? (parameters.animateTo) : (this._angle);
this._parameters.step = parameters.step || this._parameters.step || null;
this._parameters.easing = parameters.easing || this._parameters.easing || this._defaultEasing;
this._parameters.duration = 'duration' in parameters ? parameters.duration : parameters.duration || this._parameters.duration || 1000;
this._parameters.callback = parameters.callback || this._parameters.callback || this._emptyFunction;
this._parameters.center = parameters.center || this._parameters.center || ["50%","50%"];
if (typeof this._parameters.center[0] == "string") {
this._rotationCenterX = (parseInt(this._parameters.center[0],10) / 100) * this._imgWidth * this._aspectW;
} else {
this._rotationCenterX = this._parameters.center[0];
}
if (typeof this._parameters.center[1] == "string") {
this._rotationCenterY = (parseInt(this._parameters.center[1],10) / 100) * this._imgHeight * this._aspectH;
} else {
this._rotationCenterY = this._parameters.center[1];
}
if (parameters.bind && parameters.bind != this._parameters.bind) { this._BindEvents(parameters.bind); }
},
_emptyFunction: function(){},
_defaultEasing: function (x, t, b, c, d) { return -c * ((t=t/d-1)*t*t*t - 1) + b },
_handleRotation : function(parameters, dontcheck){
if (!supportedCSS && !this._img.complete && !dontcheck) {
this._onLoadDelegate.push(parameters);
return;
}
this._setupParameters(parameters);
if (this._angle==this._parameters.animateTo) {
this._rotate(this._angle);
}
else {
this._animateStart();
}
},
_BindEvents:function(events){
if (events && this._eventObj)
{
// Unbinding previous Events
if (this._parameters.bind){
var oldEvents = this._parameters.bind;
for (var a in oldEvents) if (oldEvents.hasOwnProperty(a))
// TODO: Remove jQuery dependency
jQuery(this._eventObj).unbind(a,oldEvents[a]);
}
this._parameters.bind = events;
for (var a in events) if (events.hasOwnProperty(a))
// TODO: Remove jQuery dependency
jQuery(this._eventObj).bind(a,events[a]);
}
},
_Loader:(function()
{
if (IE)
return function() {
var width=this._img.width;
var height=this._img.height;
this._imgWidth = width;
this._imgHeight = height;
this._img.parentNode.removeChild(this._img);
this._vimage = this.createVMLNode('image');
this._vimage.src=this._img.src;
this._vimage.style.height=height+"px";
this._vimage.style.width=width+"px";
this._vimage.style.position="absolute"; // FIXES IE PROBLEM - its only rendered if its on absolute position!
this._vimage.style.top = "0px";
this._vimage.style.left = "0px";
this._aspectW = this._aspectH = 1;
/* Group minifying a small 1px precision problem when rotating object */
this._container = this.createVMLNode('group');
this._container.style.width=width;
this._container.style.height=height;
this._container.style.position="absolute";
this._container.style.top="0px";
this._container.style.left="0px";
this._container.setAttribute('coordsize',width-1+','+(height-1)); // This -1, -1 trying to fix ugly problem with small displacement on IE
this._container.appendChild(this._vimage);
this._rootObj.appendChild(this._container);
this._rootObj.style.position="relative"; // FIXES IE PROBLEM
this._rootObj.style.width=width+"px";
this._rootObj.style.height=height+"px";
this._rootObj.setAttribute('id',this._img.getAttribute('id'));
this._rootObj.className=this._img.className;
this._eventObj = this._rootObj;
var parameters;
while (parameters = this._onLoadDelegate.shift()) {
this._handleRotation(parameters, true);
}
}
else return function () {
this._rootObj.setAttribute('id',this._img.getAttribute('id'));
this._rootObj.className=this._img.className;
this._imgWidth=this._img.naturalWidth;
this._imgHeight=this._img.naturalHeight;
var _widthMax=Math.sqrt((this._imgHeight)*(this._imgHeight) + (this._imgWidth) * (this._imgWidth));
this._width = _widthMax * 3;
this._height = _widthMax * 3;
this._aspectW = this._img.offsetWidth/this._img.naturalWidth;
this._aspectH = this._img.offsetHeight/this._img.naturalHeight;
this._img.parentNode.removeChild(this._img);
this._canvas=document.createElement('canvas');
this._canvas.setAttribute('width',this._width);
this._canvas.style.position="relative";
this._canvas.style.left = -this._img.height * this._aspectW + "px";
this._canvas.style.top = -this._img.width * this._aspectH + "px";
this._canvas.Wilq32 = this._rootObj.Wilq32;
this._rootObj.appendChild(this._canvas);
this._rootObj.style.width=this._img.width*this._aspectW+"px";
this._rootObj.style.height=this._img.height*this._aspectH+"px";
this._eventObj = this._canvas;
this._cnv=this._canvas.getContext('2d');
var parameters;
while (parameters = this._onLoadDelegate.shift()) {
this._handleRotation(parameters, true);
}
}
})(),
_animateStart:function()
{
if (this._timer) {
clearTimeout(this._timer);
}
this._animateStartTime = +new Date;
this._animateStartAngle = this._angle;
this._animate();
},
_animate:function()
{
var actualTime = +new Date;
var checkEnd = actualTime - this._animateStartTime > this._parameters.duration;
// TODO: Bug for animatedGif for static rotation ? (to test)
if (checkEnd && !this._parameters.animatedGif)
{
clearTimeout(this._timer);
}
else
{
if (this._canvas||this._vimage||this._img) {
var angle = this._parameters.easing(0, actualTime - this._animateStartTime, this._animateStartAngle, this._parameters.animateTo - this._animateStartAngle, this._parameters.duration);
this._rotate((~~(angle*10))/10);
}
if (this._parameters.step) {
this._parameters.step(this._angle);
}
var self = this;
this._timer = setTimeout(function()
{
self._animate.call(self);
}, 10);
}
// To fix Bug that prevents using recursive function in callback I moved this function to back
if (this._parameters.callback && checkEnd){
this._angle = this._parameters.animateTo;
this._rotate(this._angle);
this._parameters.callback.call(this._rootObj);
}
},
_rotate : (function()
{
var rad = Math.PI/180;
if (IE)
return function(angle)
{
this._angle = angle;
this._container.style.rotation=(angle%360)+"deg";
this._vimage.style.top = -(this._rotationCenterY - this._imgHeight/2) + "px";
this._vimage.style.left = -(this._rotationCenterX - this._imgWidth/2) + "px";
this._container.style.top = this._rotationCenterY - this._imgHeight/2 + "px";
this._container.style.left = this._rotationCenterX - this._imgWidth/2 + "px";
}
else if (supportedCSS)
return function(angle){
this._angle = angle;
this._img.style[supportedCSS]="rotate("+(angle%360)+"deg)";
this._img.style[supportedCSSOrigin]=this._parameters.center.join(" ");
}
else
return function(angle)
{
this._angle = angle;
angle=(angle%360)* rad;
// clear canvas
this._canvas.width = this._width;//+this._widthAdd;
this._canvas.height = this._height;//+this._heightAdd;
// REMEMBER: all drawings are read from backwards.. so first function is translate, then rotate, then translate, translate..
this._cnv.translate(this._imgWidth*this._aspectW,this._imgHeight*this._aspectH); // at least center image on screen
this._cnv.translate(this._rotationCenterX,this._rotationCenterY); // we move image back to its orginal
this._cnv.rotate(angle); // rotate image
this._cnv.translate(-this._rotationCenterX,-this._rotationCenterY); // move image to its center, so we can rotate around its center
this._cnv.scale(this._aspectW,this._aspectH); // SCALE - if needed ;)
this._cnv.drawImage(this._img, 0, 0); // First - we draw image
}
})()
}
if (IE)
{
Wilq32.PhotoEffect.prototype.createVMLNode=(function(){
document.createStyleSheet().addRule(".rvml", "behavior:url(#default#VML)");
try {
!document.namespaces.rvml && document.namespaces.add("rvml", "urn:schemas-microsoft-com:vml");
return function (tagName) {
return document.createElement('<rvml:' + tagName + ' class="rvml">');
};
} catch (e) {
return function (tagName) {
return document.createElement('<' + tagName + ' xmlns="urn:schemas-microsoft.com:vml" class="rvml">');
};
}
})();
}
})(jQuery);

@ -0,0 +1,144 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
object_maker.init(config_api.config_3dobject_holder, $("#objectHolder").width(), $("#objectHolder").width()/2);
object_maker.animate();
var flight_dynamics = new flight_dynamics();
$("#window_size").slider({
range: "min",
value: 37,
min: 10,
max: 300,
slide: function (event, ui) {
$("#window_size_current_value").html($("#window_size").slider("value"));
}
});
$("#window_update").slider({
range: "min",
value: 234,
min: 100,
max: 1000,
slide: function (event, ui) {
$("#window_update_value").html($("#window_update").slider("value"));
}
});
$("#replotting").click(function () {
plotting.finishPlotting(function (status) {
if (status) {
plotting.initPlotting(function (status) {
d3.select("#realtimechart").select("svg").remove();
plotting.realtime_plotting("#realtimechart", "#range_min", "#range_max", "#window_update_value",
600, $("#realtimechart").height(), "#window_size_current_value",
'#plotting_attribute');
});
} else {
$("#realtimechart").html("There is no data to plot");
}
});
});
$('.btn-minimize').click(function (e) {
e.preventDefault();
var $target = $(this).parent().parent().next('.box-content');
if ($target.is(':visible')) {
if ($(this).parent().attr('id') === "RealtimePlotting") {
plotting.forceToRedraw(function (status) {
d3.select("#realtimechart").select("svg").remove();
plotting.realtime_plotting("#realtimechart", "#range_min", "#range_max", "#window_update_value",
600, $("#realtimechart").height(), "#window_size_current_value",
'#plotting_attribute');
});
}
} else {
}
});
$('#connectionOpen').on('click', function () {
$('#connectionOpen').toggleClass('active');
});
$("#xmppConnectionOpen").on('click', function () {
$('#xmppConnectionOpen').toggleClass('active');
if ($('#xmppConnectionOpen').html() === "Start") {
sendMessage();
$('#xmppConnectionOpen').html("Stop");
} else if ($('#xmppConnectionOpen').html() === "Stop") {
closeSocket();
$('#xmppConnectionOpen').html("Start");
$("#connectionOpen").html("Connect to server").removeClass("btn btn-info").addClass("btn btn-primary");
}
});
$('.btn-minimize').parent().parent().next('.box-content').hide();
var webSocket;
config_api.realtime_plotting_data_window["attitude"] = new Queue();
var current_status = {};
function openSocket() {
if (webSocket !== undefined && webSocket.readyState !== WebSocket.CLOSED) {
writeResponse("WebSocket is already opened.");
} else {
webSocket = new WebSocket(config_api.web_socket_endpoint);
}
webSocket.onopen = function (event) {
if (event === undefined) {
writeResponse("WebSocket cant open " + event);
$("#connectionOpen").html("Connect to server").removeClass("btn btn-info").addClass("btn btn-primary");
} else {
if (event["isTrusted"] == true) {
$("#connectionOpen").html("Connected").removeClass("btn btn-primary").addClass("btn btn-info");
}
writeResponse(JSON.stringify(event));
}
};
webSocket.onmessage = function (event) {
var sender_message = event.data;
sender_message = isJSON(sender_message);
if (sender_message != null) {
flight_dynamics.processingMessage(sender_message);
} else {
writeResponse("Message has been corrupted.");
}
};
}
function sendMessage(message) {
webSocket.send(message);
}
function closeSocket() {
webSocket.close();
}
function writeResponse(text) {
console.log(text);
}
window.onbeforeunload = function () {
webSocket.onclose = function () {
};
webSocket.close()
};

@ -0,0 +1,29 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
$("#module_control button").click(function (index) {
console.log("Asking Server to send the " + $(this).attr('id') + " command to Ar Drone");
var url = config_api.drone_control + "?action=" + $(this).attr('id') + "&speed=6&duration=7";
ajax_handler.ajaxRequest(url, config_api.drone_controlType, {action: $(this).attr('id'), speed: 7, duration: 7},
config_api.drone_controlDataType, function (data, status) {
console.log(JSON.stringify(data));
}
);
});

@ -0,0 +1,79 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
var flight_dynamics = function () {
var api = this;
api.processingMessage = function (sender_message) {
JSON.stringify(sender_message);
if (sender_message.quatanium_val != undefined) {
current_status = object_maker.get_heading_attitude_bank(sender_message.quatanium_val);
object_maker.set_heading_attitude_bank(current_status);
$("#imageTop").animate({rotate: '' + (180 / Math.PI) * 2.890456 + 'deg'}, 2);
}
$("#imageTop").delay(2).animate({rotate: '45deg'}, 2);
if (config_api.modules_status.angleOfRotation_2 || config_api.modules_status.angleOfRotation_1) {
console.log(JSON.stringify(current_status));
object_maker.set_bank("#imageTop", current_status.bank);
object_maker.set_heading("#imageBackSecond", current_status.heading);
}
if (config_api.modules_status.realtimePlotting) {
if (current_status[$('#plotting_attribute').val()] != undefined) {
plotting.pushData(current_status[$('#plotting_attribute').val()]);
}
}
if (sender_message.basicParam != undefined) {
if (sender_message.basicParam.velocity != undefined) {
var velocity = sender_message.basicParam.velocity;
if (velocity.length == 3) {
$("#velocityx").html(velocity[0]);
$("#velocityy").html(velocity[1]);
$("#velocityz").html(velocity[2]);
}
} else {
$("#velocityx").html(NaN);
$("#velocityy").html(NaN);
$("#velocityz").html(NaN);
}
if (sender_message.basicParam.global_location != undefined) {
var location = sender_message.basicParam.global_location;
if (location.length == 3) {
$("#locationLog").html(location[0]);
$("#locationAlt").html(location[1]);
$("#locationLat").html(location[2]);
}
} else {
$("#locationLog").html(NaN);
$("#locationAlt").html(NaN);
$("#locationLat").html(NaN);
}
}
if (sender_message.battery_voltage != undefined) {
$("#battery_voltage").html(sender_message.battery_voltage);
} else {
$("#battery_voltage").html(NaN);
}
}
};

@ -0,0 +1,148 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
var plotting = function () {
var api = this;
api.isDone = false;
api.current_value = 0;
api.finishPlotting = function (callBack) {
api.isDone = true;
callBack(true);
},
api.initPlotting = function (callback) {
api.isDone = false;
callback(true);
},
api.forceToRedraw = function (callback) {
api.isDone == true;
callback(true);
},
api.pushData = function (new_value) {
console.log(new_value);
api.current_value = new_value;
},
api.realtime_plotting = function (holder, y_min_hollder, y_max_holder, update_interval_holder, holder_width,
holder_height, window_size_holder, title) {
$(holder).html();
var init_window = function () {
return 0;
}
api.data = d3.range(parseInt($(window_size_holder).html())).map(init_window);
var margin = {top: 20, right: 20, bottom: 20, left: 40},
width = holder_width - margin.left - margin.right,
height = holder_height - margin.top - margin.bottom;
var x = d3.scale.linear()
.domain([1, parseInt($(window_size_holder).html()) - 2])
.range([0, width]);
var y = d3.scale.linear()
.domain([parseInt($(y_min_hollder).val()), parseInt($(y_max_holder).val())])
.range([height, 0]);
var line = d3.svg.line()
.interpolate("basis")
.x(function (d, i) {
return x(i);
})
.y(function (d, i) {
return y(d);
});
var svg = d3.select(holder).append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
svg.append("defs").append("clipPath")
.attr("id", "clip")
.append("rect")
.attr("width", width)
.attr("height", height);
var axis_x = svg.append("g")
.attr("class", "x_axis")
.attr("transform", "translate(0," + y(0) + ")")
.call(d3.svg.axis().scale(x).orient("bottom"));
var axis_y = svg.append("g")
.attr("class", "y_axis")
.call(d3.svg.axis().scale(y).orient("left"));
var path = svg.append("g")
.attr("clip-path", "url(#clip)")
.append("path")
.datum(api.data)
.attr("class", "line")
.attr("d", line);
svg.append("text")
.attr("class", "yaxis_label")
.attr("transform", "rotate(-90)")
.attr("y", 0 - margin.left - 4)
.attr("x", (0 - (height / 2)))
.attr("dy", "1em")
.style("text-anchor", "middle")
.text($(title).val());
svg.append("text")
.attr("class", "xaixs_label")
.attr("transform",
"translate(" + (width / 2) + " ," +
(height + margin.bottom) + ")")
.style("text-anchor", "middle")
.text("Window Size");
svg.append("text")
.attr("class", "title_label")
.attr("x", (width / 2))
.attr("y", 0 - (margin.top / 4))
.attr("text-anchor", "middle")
.style("font-size", "16px")
.style("text-decoration", "underline")
.text($(title).val() + " variation within last " + $(window_size_holder).html() + " frames");
updateAgain();
function updateAgain() {
if (api.isDone)return;
api.data.push(api.current_value);
path
.attr("d", line)
.attr("transform", null)
.transition()
.duration($(update_interval_holder).html())
.ease("linear")
.attr("transform", "translate(" + x(0) + ",0)")
.each("end", updateAgain);
api.data.shift();
}
function rescale() {
y.domain([parseInt($(y_min_hollder).val()), parseInt($(y_max_holder).val())])
svg.select(".title_label")
.text($(title).val() + " variation within last " + $(window_size_holder).html() + " frames");
svg.select(".yaxis_label")
.text($(title).val());
}
function rescale_x() {
x.domain([1, parseInt($(window_size_holder).html()) - 2]).range([0, width])
svg.select(".x_axis").transition().call(axis_x);
}
$("#plotting_attribute").change(function () {
rescale();
});
}
}

@ -0,0 +1,332 @@
{{#zone "topCss"}}
{{css "css/main-app.css" }}
<style type="text/css">
.circle {
background: none repeat scroll 0 0 #191919;
border-radius: 50px;
height: 50px;
padding: 10px;
width: 50px;
color: #fff;
}
.padding-top-double {
padding-top: 20px;
}
.padding-double {
padding: 20px;
}
.grey {
color: #333;
}
hr {
display: block;
height: 1px;
border: 0;
border-top: 1px solid #7f7f7f;
margin: 1em 0;
padding: 0;
opacity: 0.2;
}
.light-grey {
color: #7c7c7c;
}
.uppercase {
text-transform: uppercase;
}
.grey-bg {
background-color: #f6f4f4;
}
path {
stroke: black;
stroke-width: 2;
fill: none;
}
.axis path, .axis line {
fill: none;
stroke: #ccc;
stroke-width: 2;
shape-rendering: crispEdges;
}
</style>
{{/zone}}
<div class=" row">
<div class="box col-md-12">
<div>
<div class="col-md-2 col-sm-2 col-xs-1">
<button class="btn btn-primary" data-dismiss="modal" id="connectionOpen"
onclick="openSocket();">Connect to server</button>
</div>
<div class="col-md-2 col-sm-2 col-xs-1">
<button class="btn btn-primary" data-dismiss="modal" id="xmppConnectionOpen">Start</button>
</div>
<div class="col-md-0.5 col-sm-1 col-xs-2">
<p>Battery Level </p>
</div>
<div class="col-md-4 col-sm-2 col-xs-2">
<div class="progress">
<div class="progress-bar" role="progressbar" aria-valuenow="60" aria-valuemin="0"
aria-valuemax="100" style="width: 0%;">
0%
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="box col-md-12">
<div class="box-inner">
<div class="box-header well">
<h2><i class="glyphicon glyphicon-info-sign"></i> Controller </h2>
<div class="box-icon">
<a href="#" class="btn btn-setting btn-round btn-default"><i
class="glyphicon glyphicon-cog"></i></a>
<a href="#" class="btn btn-minimize btn-round btn-default"><i
class="glyphicon glyphicon-chevron-up" ></i></a>
<a href="#" class="btn btn-close btn-round btn-default"><i
class="glyphicon glyphicon-remove"></i></a>
</div>
</div>
<div class="box-content row" id="module_control">
<div class="col-lg-1 col-md-12 hidden-xs center-text">
<button class="btn btn-default btn-sm" id="takeoff">
<i class="glyphicon glyphicon-play"></i> Takeoff</button>
</div>
<div class="col-lg-1 col-md-12 hidden-xs center-text">
<button class="btn btn-default btn-sm" id="land">
<i class="glyphicon glyphicon-stop"></i> Land</button>
</div>
<div class="col-lg-1 col-md-12 hidden-xs center-text">
<button class="btn btn-default btn-sm" id="up">
<i class="glyphicon glyphicon-arrow-up"></i> Up</button>
</div>
<div class="col-lg-1 col-md-12 hidden-xs center-text">
<button class="btn btn-default btn-sm" id="down">
<i class="glyphicon glyphicon-arrow-down"></i> Down</button>
</div>
<div class="col-lg-1 col-md-12 hidden-xs center-text">
<button class="btn btn-default btn-sm" id="left">
<i class="glyphicon glyphicon-arrow-left"></i> Left</button>
</div>
<div class="col-lg-1 col-md-12 hidden-xs center-text">
<button class="btn btn-default btn-sm" id="right">
<i class="glyphicon glyphicon-arrow-right"></i> Right</button>
</div>
<div class="col-lg-1 col-md-12 hidden-xs center-text">
<button class="btn btn-default btn-sm" id="front">
<i class="glyphicon glyphicon-chevron-up"></i> Front</button>
</div>
<div class="col-lg-1 col-md-12 hidden-xs center-text">
<button class="btn btn-default btn-sm" id="back">
<i class="glyphicon glyphicon-chevron-down"></i> Back</button>
</div>
<div class="col-lg-1 col-md-12 hidden-xs center-text">
<button class="btn btn-default btn-sm" id="clockwise">
<i class="glyphicon glyphicon-resize-vertical"></i> Clockwise</button>
</div>
<div class="col-lg-1 col-md-12 hidden-xs center-text">
<button class="btn btn-default btn-sm" id="counter_clockwise">
<i class="glyphicon glyphicon-resize-horizontal"></i> Conter-clockwise</button>
</div>
<div class="col-lg-2 col-md-12 hidden-xs center-text">
<button class="btn btn-default btn-sm" id="stop">
<i class="glyphicon glyphicon-ban-circle"></i> Stop</button>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="box col-md-12">
<div class="box col-md-4">
<div class="box-inner">
<div class="box-header well" data-original-title="" >
<h2><i class="glyphicon glyphicon-list"></i> Angle of Rotation</h2>
<div class="box-icon" id="AngleOfRotation_1">
<a href="#" class="btn btn-setting btn-round btn-default"><i
class="glyphicon glyphicon-cog"></i></a>
<a href="#" class="btn btn-minimize btn-round btn-default"><i
class="glyphicon glyphicon-chevron-up"></i></a>
<a href="#" class="btn btn-close btn-round btn-default"><i
class="glyphicon glyphicon-remove"></i></a>
</div>
</div>
<div class="box-content" style="position: relative;" id="objectHolder">
<div class="grayscale" border-radius="2" id="virtualDrone" >
</div>
</div>
</div>
</div>
<div class="box col-md-2">
<div class="box-inner" style="max-height: 280px;">
<div class="box-header well" data-original-title="" >
<div class="box-icon" id="AngleOfRotation_2">
<a href="#" class="btn btn-setting btn-round btn-default"><i
class="glyphicon glyphicon-cog"></i></a>
<a href="#" class="btn btn-minimize btn-round btn-default"><i
class="glyphicon glyphicon-chevron-up"></i></a>
<a href="#" class="btn btn-close btn-round btn-default"><i
class="glyphicon glyphicon-remove"></i></a>
</div>
</div>
<div class="box-content" >
<div style="position: relative;">
<img class="grayscale" id="imageTop"
src="{{@unit.publicUri}}/images/drone_position_controller/direction_drone.png"
style="width: 100%;"/>
<img class="grayscale" id="imageBack"
src="{{@unit.publicUri}}/images/drone_position_controller/background_drone.png"
style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);"/>
</div>
</div>
</div>
</div>
<div class="box col-md-2">
<div class="box-inner" style="max-height: 280px;">
<div class="box-header well" data-original-title="" >
<div class="box-icon" id="AngleOfRotation_3">
<a href="#" class="btn btn-setting btn-round btn-default"><i
class="glyphicon glyphicon-cog"></i></a>
<a href="#" class="btn btn-minimize btn-round btn-default"><i
class="glyphicon glyphicon-chevron-up"></i></a>
<a href="#" class="btn btn-close btn-round btn-default"><i
class="glyphicon glyphicon-remove"></i></a>
</div>
</div>
<div class="box-content" >
<div style="position: relative;">
<img id="imageBackSecond"
src="{{@unit.publicUri}}/images/drone_position_controller/pitch_drone.png"
style="width: 100%;"/>
<img id="imageTopSecond"
src="{{@unit.publicUri}}/images/drone_position_controller/background_drone.png"
style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);"/>
</div>
</div>
</div>
</div>
<div class="box col-md-4">
<div class="box-inner">
<div class="box-header well" data-original-title="" >
<h2><i class="glyphicon glyphicon-list"></i>Live Video Stream</h2>
<div class="box-icon" id="LiveVideoStream">
<a href="#" class="btn btn-setting btn-round btn-default"><i
class="glyphicon glyphicon-cog"></i></a>
<a href="#" class="btn btn-minimize btn-round btn-default"><i
class="glyphicon glyphicon-chevron-up"></i></a>
<a href="#" class="btn btn-close btn-round btn-default"><i
class="glyphicon glyphicon-remove"></i></a>
</div>
</div>
<div class="box-content">
<img class="grayscale" src="{{@unit.publicUri}}/images/no_video_preview.gif"
alt="video stream" style="display: block; height:225px; margin: auto;">
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="box col-md-12">
<div class="box col-md-4">
<div class="box-inner">
<div class="box-header well" data-original-title="" >
<h2><i class="glyphicon glyphicon-list"></i>Sensor Readings</h2>
<div class="box-icon" id="SensorReadings">
<a href="#" class="btn btn-setting btn-round btn-default"><i
class="glyphicon glyphicon-cog"></i></a>
<a href="#" class="btn btn-minimize btn-round btn-default"><i
class="glyphicon glyphicon-chevron-up"></i></a>
<a href="#" class="btn btn-close btn-round btn-default"><i
class="glyphicon glyphicon-remove"></i></a>
</div>
</div>
<div class="box-content" id="basicSensoReading">
<div>
<p>Location latitude: <label id="locationLat"></label></br>
longitude: <label id="locationLog"></label></br>
altitudes: <label id="locationAlt"></label></p>
<p> Velocity: x :<label id="velocityx"></label></br>
y : <label id="velocityy"></label></br>
z : <label id="velocityz"></label></p>
<p> Battery Voltage:<label id="battery_voltage"></label></p>
</div>
</div>
</div>
</div>
<div class="box col-md-8">
<div class="box-inner">
<div class="box-header well" data-original-title="" >
<h2><i class="glyphicon glyphicon-list-alt"></i>Realtime Plotting</h2>
<div class="box-icon" id="RealtimePlotting">
<a href="#" class="btn btn-setting btn-round btn-default"><i
class="glyphicon glyphicon-cog"></i></a>
<a href="#" class="btn btn-minimize btn-round btn-default"><i
class="glyphicon glyphicon-chevron-up"></i></a>
<a href="#" class="btn btn-close btn-round btn-default"><i
class="glyphicon glyphicon-remove"></i></a>
</div>
</div>
<div class="box-content">
<div class="row">
<div class="box col-md-4" id="plottingMetadata" style="margin-left: 5%">
<div>
Window size : <label id="window_size_current_value" >30</label>
<div id="window_size" style="width: 100%;" ></div><br>
Update period : <label id="window_update_value" >300</label>
</div>
<div id="window_update" style="width: 100%;"></div></br>
<div style="width:100%;">Y-axis: <label>Min: <input id="range_min" type="text" value="-4" size="3"></label>
<label>Max: <input id="range_max" value="4" type="text" size="3"></label></div>
<div style="width:100%;"><select ng-model='discussionsSelect' class='form-control' id="plotting_attribute">
<option value='heading' selected>Heading</option>
<option value='bank'>Bank</option>
<option value='attitude'>Attitude</option>
</select></div></br>
<div>
<button class="btn btn-primary" id="replotting" >Replot</button>
</div>
</div>
<div class="box col-md-8" id="realtimechart" style="width:20%; height: 250px;"></div>
</div>
</div>
</div>
</div>
</div>
</div>
{{#zone "bottomJs"}}
{{js "/js/d3.min.js" }}
{{js "/js/3dobject_controller/three.min.js" }}
{{js "/js/3dobject_controller/Coordinates.js" }}
{{js "/js/3dobject_controller/OrbitAndPanControls.js" }}
{{js "/js/3dobject_controller/3dObjectControler.js" }}
{{js "/js/jQueryRotate.js" }}
{{js "/js/config/config.js" }}
{{js "/js/common/ajax_handler.js" }}
{{js "/js/modules/realtime_plotting" }}
{{js "/js/initJs" }}
{{js "/js/common/general_handler" }}
{{js "/js/common/websocket_api" }}
{{js "/js/modules/controller.js" }}
{{js "/js/modules/flight_dynamics.js" }}
{{js "/js/mainHandler" }}
{{/zone}}

@ -0,0 +1,42 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
function onRequest (context) {
/*var log = new Log("detail.js");
var deviceType = request.getParameter("type");
var deviceId = request.getParameter("id");
if (deviceType != null && deviceType != undefined && deviceId != null && deviceId != undefined) {
var deviceModule = require("/modules/device.js").deviceModule;
var device = deviceModule.viewDevice(deviceType, deviceId);
if (device) {
var viewModel = {};
var deviceInfo = device.properties.DEVICE_INFO;
if (deviceInfo != undefined && String(deviceInfo.toString()).length > 0) {
deviceInfo = parse(stringify(deviceInfo));
viewModel.system = device.properties.IMEI;
viewModel.machine = "Virtual Firealarm";
viewModel.vendor = device.properties.VENDOR;
}
device.viewModel = viewModel;
}
context.device = device;
return context;
}*/
}
Loading…
Cancel
Save