Commit 37a38939 authored by Léo-Paul Géneau's avatar Léo-Paul Géneau 👾

erp5_officejs_drone_simulator_test: update tests to support multicopter API

parent b9cae114
...@@ -63,6 +63,42 @@ ...@@ -63,6 +63,42 @@
<td>//textarea[@id="log_result_0"]</td> <td>//textarea[@id="log_result_0"]</td>
<td></td> <td></td>
<tr> <tr>
<!-- Change drone type -->
<tr>
<td>click</td>
<td>//div[contains(@data-gadget-url, 'gadget_erp5_page_drone_capture_flag_script_page.html')]//button[text()="Parameters"]</td>
<td></td>
<tr>
<tr>
<td>waitForElementPresent</td>
<td>//label[text()='Drone Type']</td>
<td></td>
<tr>
<tr>
<td>select</td>
<td>//select[@name="drone_type"]</td>
<td>value=Fixed Wings</td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//label[text()='Drone min speed']</td>
<td></td>
<tr>
<tr>
<td>click</td>
<td>//div[contains(@data-gadget-url, 'gadget_erp5_page_drone_capture_flag_script_page.html')]//button[text()="Run"]</td>
<td></td>
<tr>
<tr>
<td>waitForElementPresent</td>
<td>//span[@id="loading"]</td>
<td></td>
<tr>
<tr>
<td>waitForElementPresent</td>
<td>//a[contains(text(), 'Download Simulation LOG')]</td>
<td></td>
<tr>
</tbody></table> </tbody></table>
</body> </body>
</html> </html>
\ No newline at end of file
...@@ -46,7 +46,7 @@ ...@@ -46,7 +46,7 @@
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>testDroneSimulatorFlight</string> </value> <value> <string>testDroneCaptureFlagFixedWingFlight</string> </value>
</item> </item>
<item> <item>
<key> <string>output_encoding</string> </key> <key> <string>output_encoding</string> </key>
......
...@@ -9,19 +9,19 @@ ...@@ -9,19 +9,19 @@
<body> <body>
<table cellpadding="1" cellspacing="1" border="1"> <table cellpadding="1" cellspacing="1" border="1">
<thead> <thead>
<tr><td rowspan="1" colspan="3">Test Drone Capture Flag OJS app (expected failure)</td></tr> <tr><td rowspan="1" colspan="3">Test Fixed Wing Drone Capture Flag OJS app (expected failure)</td></tr>
</thead><tbody> </thead><tbody>
<tal:block metal:use-macro="here/Zuite_CommonTemplate/macros/init" /> <tal:block metal:use-macro="here/Zuite_CommonTemplate/macros/init" />
<!-- Go to site --> <!-- Go to site -->
<tr> <tr>
<td>open</td> <td>open</td>
<td>${base_url}/web_site_module/officejs_drone_capture_flag/app/#/?page=drone_capture_flag_test_page</td> <td>${base_url}/web_site_module/officejs_drone_capture_flag/app/#/?page=drone_capture_flag_fixed_wing_test_page</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
<td>waitForElementPresent</td> <td>waitForElementPresent</td>
<td>//div[contains(@data-gadget-url, 'gadget_erp5_page_drone_capture_flag_test_page.html')]//input[@type="submit" and @name="action_run"]</td> <td>//div[contains(@data-gadget-url, 'gadget_erp5_page_drone_capture_flag_fixed_wing_test_page.html')]//input[@type="submit" and @name="action_run"]</td>
<td></td> <td></td>
<tr> <tr>
<tr> <tr>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ZopePageTemplate" module="Products.PageTemplates.ZopePageTemplate"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="_reconstructor" module="copy_reg"/>
</klass>
<tuple>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
<global name="object" module="__builtin__"/>
<none/>
</tuple>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>text/html</string> </value>
</item>
<item>
<key> <string>expand</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>testDroneCaptureFlagMulticopterFlight</string> </value>
</item>
<item>
<key> <string>output_encoding</string> </key>
<value> <string>utf-8</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <unicode></unicode> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<html xmlns:tal="http://xml.zope.org/namespaces/tal"
xmlns:metal="http://xml.zope.org/namespaces/metal">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Test Drone Capture Flag OJS app (expected failure)</title>
<!-- This test is expected to fail as the drone simulator runs on a web worker canvas, which relies on a very new feature: offscreen canvas
---- This feature is not supported yet by the latest Firefox ESR used in the test nodes -->
</head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr><td rowspan="1" colspan="3">Test Multicopter Drone Capture Flag OJS app (expected failure)</td></tr>
</thead><tbody>
<tal:block metal:use-macro="here/Zuite_CommonTemplate/macros/init" />
<!-- Go to site -->
<tr>
<td>open</td>
<td>${base_url}/web_site_module/officejs_drone_capture_flag/app/#/?page=drone_capture_flag_multicopter_test_page</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//div[contains(@data-gadget-url, 'gadget_erp5_page_drone_capture_flag_multicopter_test_page.html')]//input[@type="submit" and @name="action_run"]</td>
<td></td>
<tr>
<tr>
<td>waitForElementPresent</td>
<td>//span[@id="loading"]</td>
<td></td>
<tr>
<tr>
<td>waitForElementPresent</td>
<td>//div[contains(@data-gadget-url, 'babylonjs.gadget.html')]</td>
<td></td>
<tr>
<tr>
<td>waitForElementPresent</td>
<td>//div[contains(@data-gadget-url, 'babylonjs.gadget.html')]//canvas[contains(@data-engine, 'Babylon.js')]</td>
<td></td>
<tr>
<tr>
<td>waitForElementPresent</td>
<td>//div[contains(text(), 'CONSOLE LOG ENTRIES:')]</td>
<td></td>
<tr>
<tr>
<td>assertElementPresent</td>
<td>//div[contains(text(), 'Initial speed: OK')]</td>
<td></td>
<tr>
<tr>
<td>assertElementPresent</td>
<td>//div[contains(text(), 'Yaw angle: OK')]</td>
<td></td>
<tr>
<tr>
<td>assertElementPresent</td>
<td>//div[contains(text(), 'Timestamp: OK')]</td>
<td></td>
<tr>
<tr>
<td>assertElementPresent</td>
<td>//div[contains(text(), 'Distance: OK')]</td>
<td></td>
<tr>
<tr>
<td>assertElementPresent</td>
<td>//div[contains(text(), 'Latitude: OK')]</td>
<td></td>
<tr>
<tr>
<td>assertElementPresent</td>
<td>//div[contains(text(), 'Longitude: OK')]</td>
<td></td>
<tr>
<tr>
<td>assertElementPresent</td>
<td>//div[contains(text(), 'Altitude: OK')]</td>
<td></td>
<tr>
<tr>
<td>assertElementPresent</td>
<td>//div[contains(text(), 'Timeout: OK')]</td>
<td></td>
<tr>
</tbody></table>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html>
<!--
data-i18n=Others
data-i18n=Tools
-->
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width" />
<title>Drone Simulator Test Page</title>
<link rel="http://www.renderjs.org/rel/interface" href="interface_page.html">
<!-- renderjs -->
<script src="rsvp.js" type="text/javascript"></script>
<script src="renderjs.js" type="text/javascript"></script>
<!-- custom script -->
<script src="jiodev.js" type="text/javascript"></script>
<script src="gadget_global.js" type="text/javascript"></script>
<script src="domsugar.js" type="text/javascript"></script>
<!-- API scripts -->
<script src="gadget_erp5_page_drone_capture_flag_fixedwingdrone.js" type="text/javascript"></script>
<script src="gadget_erp5_page_drone_capture_flag_fixed_wing_test_page.js" type="text/javascript"></script>
</head>
<body>
<form>
<div data-gadget-url="gadget_erp5_form.html"
data-gadget-scope="form_view"
data-gadget-sandbox="public">
</div>
<input name="action_run" class="dialogconfirm" type="submit" value="Run" style="margin-bottom: 20pt;margin-top: 20pt;">
<a data-i18n="Storages"></a> <!-- for zelenium test common macro -->
<div class="simulator_div"></div>
<div data-gadget-url="gadget_erp5_form.html"
data-gadget-scope="form_view_babylonjs"
data-gadget-sandbox="public">
</div>
<div class="test_log"></div>
</form>
</body>
</html>
\ No newline at end of file
...@@ -73,7 +73,7 @@ ...@@ -73,7 +73,7 @@
</item> </item>
<item> <item>
<key> <string>default_reference</string> </key> <key> <string>default_reference</string> </key>
<value> <string>gadget_erp5_page_drone_capture_flag_test_page.html</string> </value> <value> <string>gadget_erp5_page_drone_capture_flag_fixed_wing_test_page.html</string> </value>
</item> </item>
<item> <item>
<key> <string>description</string> </key> <key> <string>description</string> </key>
...@@ -83,7 +83,7 @@ ...@@ -83,7 +83,7 @@
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>test_capture_drone_flight_html</string> </value> <value> <string>test_capture_drone_fixed_wing_flight_html</string> </value>
</item> </item>
<item> <item>
<key> <string>language</string> </key> <key> <string>language</string> </key>
...@@ -103,7 +103,7 @@ ...@@ -103,7 +103,7 @@
</item> </item>
<item> <item>
<key> <string>title</string> </key> <key> <string>title</string> </key>
<value> <string>Drone Capture Flag Test Page</string> </value> <value> <string>Drone Capture Flag Fixed Wing Test Page</string> </value>
</item> </item>
<item> <item>
<key> <string>version</string> </key> <key> <string>version</string> </key>
...@@ -244,7 +244,7 @@ ...@@ -244,7 +244,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>1009.56051.5673.26368</string> </value> <value> <string>1020.30404.9679.22971</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -264,7 +264,7 @@ ...@@ -264,7 +264,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1690898380.88</float> <float>1730823497.17</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
/*jslint indent: 2, maxlen: 100*/ /*jslint indent: 2, maxlen: 100*/
/*global window, rJS, domsugar, document*/ /*global window, rJS, domsugar, document, FixedWingDroneAPI*/
(function (window, rJS, domsugar, document) { (function (window, rJS, domsugar, document, FixedWingDroneAPI) {
"use strict"; "use strict";
var SIMULATION_SPEED = 1, var SIMULATION_SPEED = 1,
...@@ -17,17 +17,7 @@ ...@@ -17,17 +17,7 @@
INIT_LAT = 45.6412, INIT_LAT = 45.6412,
INIT_ALT = 15, INIT_ALT = 15,
DEFAULT_SPEED = 16, DEFAULT_SPEED = 16,
MAX_ACCELERATION = 6,
MAX_DECELERATION = 1,
MIN_SPEED = 12,
MAX_SPEED = 26,
MAX_ROLL = 35,
MIN_PITCH = -20,
MAX_PITCH = 25,
MAX_CLIMB_RATE = 8,
MAX_SINK_RATE = 3,
NUMBER_OF_DRONES = 1, NUMBER_OF_DRONES = 1,
// Non-inputs parameters
DEFAULT_SCRIPT_CONTENT = DEFAULT_SCRIPT_CONTENT =
'function assert(a, b, msg) {\n' + 'function assert(a, b, msg) {\n' +
' if (a === b)\n' + ' if (a === b)\n' +
...@@ -49,14 +39,14 @@ ...@@ -49,14 +39,14 @@
'}\n' + '}\n' +
'\n' + '\n' +
'function compare(coord1, coord2) {\n' + 'function compare(coord1, coord2) {\n' +
' assert(coord1.latitude, coord2.latitude, "Latitude")\n' + ' assert(coord1.latitude, coord2.latitude, "Latitude");\n' +
' assert(coord1.longitude, coord2.longitude, "Longitude")\n' + ' assert(coord1.longitude, coord2.longitude, "Longitude");\n' +
' assert(coord1.altitude, coord2.altitude, "Altitude")\n' + ' assert(coord1.altitude, coord2.altitude, "Altitude");\n' +
'}\n' + '}\n' +
'\n' + '\n' +
'me.onStart = function (timestamp) {\n' + 'me.onStart = function (timestamp) {\n' +
' assert(me.getSpeed(), ' + DEFAULT_SPEED + ', "Initial speed");\n' + ' assert(me.getSpeed(), ' + DEFAULT_SPEED + ', "Initial speed");\n' +
' assert(me.getYaw(), 0, "Yaw angle")\n' + ' assert(me.getYaw(), 0, "Yaw angle");\n' +
' me.initialPosition = me.getCurrentPosition();\n' + ' me.initialPosition = me.getCurrentPosition();\n' +
' me.start_time = timestamp;\n' + ' me.start_time = timestamp;\n' +
' me.setTargetCoordinates(\n' + ' me.setTargetCoordinates(\n' +
...@@ -95,8 +85,9 @@ ...@@ -95,8 +85,9 @@
LOGIC_FILE_LIST = [ LOGIC_FILE_LIST = [
'gadget_erp5_page_drone_capture_flag_logic.js', 'gadget_erp5_page_drone_capture_flag_logic.js',
'gadget_erp5_page_drone_capture_map_utils.js', 'gadget_erp5_page_drone_capture_map_utils.js',
'gadget_erp5_page_drone_capture_flag_fixedwingdrone.js', 'gadget_erp5_page_drone_capture_flag_multicopterdrone.js',
'gadget_erp5_page_drone_capture_flag_enemydrone.js' 'gadget_erp5_page_drone_capture_flag_enemydrone.js',
FixedWingDroneAPI.SCRIPT_NAME
]; ];
rJS(window) rJS(window)
...@@ -118,7 +109,7 @@ ...@@ -118,7 +109,7 @@
fragment = domsugar(gadget.element.querySelector('.simulator_div'), fragment = domsugar(gadget.element.querySelector('.simulator_div'),
[domsugar('div')]).firstElementChild; [domsugar('div')]).firstElementChild;
for (i = 0; i < NUMBER_OF_DRONES; i += 1) { for (i = 0; i < NUMBER_OF_DRONES; i += 1) {
DRONE_LIST[i] = {"id": i, "type": "FixedWingDroneAPI", DRONE_LIST[i] = {"id": i, "type": FixedWingDroneAPI.name,
"script_content": DEFAULT_SCRIPT_CONTENT}; "script_content": DEFAULT_SCRIPT_CONTENT};
} }
map_json = { map_json = {
...@@ -144,16 +135,6 @@ ...@@ -144,16 +135,6 @@
game_parameters_json = { game_parameters_json = {
"debug_test_mode": true, "debug_test_mode": true,
"drone": { "drone": {
"maxAcceleration": MAX_ACCELERATION,
"maxDeceleration": MAX_DECELERATION,
"minSpeed": MIN_SPEED,
"speed": DEFAULT_SPEED,
"maxSpeed": MAX_SPEED,
"maxRoll": MAX_ROLL,
"minPitchAngle": MIN_PITCH,
"maxPitchAngle": MAX_PITCH,
"maxSinkRate": MAX_SINK_RATE,
"maxClimbRate": MAX_CLIMB_RATE,
"onUpdateInterval": ON_UPDATE_INTERVAL, "onUpdateInterval": ON_UPDATE_INTERVAL,
"list": DRONE_LIST "list": DRONE_LIST
}, },
...@@ -170,6 +151,10 @@ ...@@ -170,6 +151,10 @@
"log_drone_flight": LOG, "log_drone_flight": LOG,
"log_interval_time": LOG_TIME "log_interval_time": LOG_TIME
}; };
Object.keys(FixedWingDroneAPI.FORM_VIEW).forEach(function (parameter) {
var field = FixedWingDroneAPI.FORM_VIEW[parameter];
game_parameters_json.drone[field.key] = field.default;
});
return gadget.declareGadget("babylonjs.gadget.html", return gadget.declareGadget("babylonjs.gadget.html",
{element: fragment, scope: 'simulator'}) {element: fragment, scope: 'simulator'})
.push(function () { .push(function () {
...@@ -241,4 +226,4 @@ ...@@ -241,4 +226,4 @@
}); });
}); });
}(window, rJS, domsugar, document)); }(window, rJS, domsugar, document, FixedWingDroneAPI));
\ No newline at end of file \ No newline at end of file
...@@ -75,7 +75,7 @@ ...@@ -75,7 +75,7 @@
</item> </item>
<item> <item>
<key> <string>default_reference</string> </key> <key> <string>default_reference</string> </key>
<value> <string>gadget_erp5_page_drone_capture_flag_test_page.js</string> </value> <value> <string>gadget_erp5_page_drone_capture_flag_fixed_wing_test_page.js</string> </value>
</item> </item>
<item> <item>
<key> <string>description</string> </key> <key> <string>description</string> </key>
...@@ -85,7 +85,7 @@ ...@@ -85,7 +85,7 @@
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>test_capture_drone_flight_js</string> </value> <value> <string>test_capture_drone_fixed_wing_flight_js</string> </value>
</item> </item>
<item> <item>
<key> <string>language</string> </key> <key> <string>language</string> </key>
...@@ -105,7 +105,7 @@ ...@@ -105,7 +105,7 @@
</item> </item>
<item> <item>
<key> <string>title</string> </key> <key> <string>title</string> </key>
<value> <string>Drone Capture Flag Test Page JS</string> </value> <value> <string>Drone Capture Flag Fixed Wing Test Page JS</string> </value>
</item> </item>
<item> <item>
<key> <string>version</string> </key> <key> <string>version</string> </key>
...@@ -246,7 +246,7 @@ ...@@ -246,7 +246,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>1015.64187.34381.50346</string> </value> <value> <string>1020.30719.39240.47462</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -266,7 +266,7 @@ ...@@ -266,7 +266,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1713428877.4</float> <float>1730823482.02</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
<!DOCTYPE html>
<html>
<!--
data-i18n=Others
data-i18n=Tools
-->
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width" />
<title>Drone Simulator Test Page</title>
<link rel="http://www.renderjs.org/rel/interface" href="interface_page.html">
<!-- renderjs -->
<script src="rsvp.js" type="text/javascript"></script>
<script src="renderjs.js" type="text/javascript"></script>
<!-- custom script -->
<script src="jiodev.js" type="text/javascript"></script>
<script src="gadget_global.js" type="text/javascript"></script>
<script src="domsugar.js" type="text/javascript"></script>
<!-- API scripts -->
<script src="gadget_erp5_page_drone_capture_flag_multicopterdrone.js" type="text/javascript"></script>
<script src="gadget_erp5_page_drone_capture_flag_multicopter_test_page.js" type="text/javascript"></script>
</head>
<body>
<form>
<div data-gadget-url="gadget_erp5_form.html"
data-gadget-scope="form_view"
data-gadget-sandbox="public">
</div>
<input name="action_run" class="dialogconfirm" type="submit" value="Run" style="margin-bottom: 20pt;margin-top: 20pt;">
<a data-i18n="Storages"></a> <!-- for zelenium test common macro -->
<div class="simulator_div"></div>
<div data-gadget-url="gadget_erp5_form.html"
data-gadget-scope="form_view_babylonjs"
data-gadget-sandbox="public">
</div>
<div class="test_log"></div>
</form>
</body>
</html>
\ No newline at end of file
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Web Page" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_Access_contents_information_Permission</string> </key>
<value>
<tuple>
<string>Anonymous</string>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Add_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Change_local_roles_Permission</string> </key>
<value>
<tuple>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Modify_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_View_Permission</string> </key>
<value>
<tuple>
<string>Anonymous</string>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>content_md5</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>text/html</string> </value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>gadget_erp5_page_drone_capture_flag_multicopter_test_page.html</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>test_capture_drone_multicopter_flight_html</string> </value>
</item>
<item>
<key> <string>language</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Web Page</string> </value>
</item>
<item>
<key> <string>short_title</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Drone Capture Flag Multicopter Test Page</string> </value>
</item>
<item>
<key> <string>version</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary>
<item>
<key> <string>document_publication_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>edit_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value>
</item>
<item>
<key> <string>processing_status_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAU=</string> </persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>publish_alive</string> </value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <unicode>zope</unicode> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass>
<global name="_reconstructor" module="copy_reg"/>
</klass>
<tuple>
<global name="DateTime" module="DateTime.DateTime"/>
<global name="object" module="__builtin__"/>
<none/>
</tuple>
<state>
<tuple>
<float>1730804860.17</float>
<string>UTC</string>
</tuple>
</state>
</object>
</value>
</item>
<item>
<key> <string>validation_state</string> </key>
<value> <string>published_alive</string> </value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>edit</string> </value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <unicode>zope</unicode> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>1020.30427.43889.21077</string> </value>
</item>
<item>
<key> <string>state</string> </key>
<value> <string>current</string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass>
<global name="_reconstructor" module="copy_reg"/>
</klass>
<tuple>
<global name="DateTime" module="DateTime.DateTime"/>
<global name="object" module="__builtin__"/>
<none/>
</tuple>
<state>
<tuple>
<float>1730823425.6</float>
<string>UTC</string>
</tuple>
</state>
</object>
</value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="5" aka="AAAAAAAAAAU=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>detect_converted_file</string> </value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <unicode>zope</unicode> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>external_processing_state</string> </key>
<value> <string>converted</string> </value>
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>0.0.0.0</string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass>
<global name="_reconstructor" module="copy_reg"/>
</klass>
<tuple>
<global name="DateTime" module="DateTime.DateTime"/>
<global name="object" module="__builtin__"/>
<none/>
</tuple>
<state>
<tuple>
<float>1730804628.76</float>
<string>UTC</string>
</tuple>
</state>
</object>
</value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
/*jslint indent: 2, maxlen: 100*/
/*global window, rJS, domsugar, document, MulticopterDroneAPI*/
(function (window, rJS, domsugar, document, MulticopterDroneAPI) {
"use strict";
var SIMULATION_SPEED = 100,
LOOP_INTERVAL = 1000 / 60,
ON_UPDATE_INTERVAL = LOOP_INTERVAL,
SIMULATION_TIME = 714 * LOOP_INTERVAL / 1000,
MIN_LAT = 45.6364,
MAX_LAT = 45.65,
MIN_LON = 14.2521,
MAX_LON = 14.2766,
map_height = 700,
start_AMSL = 595,
INIT_LON = 14.2658,
INIT_LAT = 45.6412,
INIT_ALT = 0,
DEFAULT_SPEED = 5,
STEP = 2.3992831666911723e-06 / 16,
TAKEOFF_ALTITUDE = 7,
NUMBER_OF_DRONES = 1,
DEFAULT_SCRIPT_CONTENT =
'function assert(a, b, msg) {\n' +
' if (a === b)\n' +
' console.log(msg + ": OK");\n' +
' else\n' +
' console.log(msg + ": FAIL");\n' +
'}\n' +
'\n' +
'function distance(lat1, lon1, lat2, lon2) {\n' +
' var R = 6371e3, // meters\n' +
' la1 = lat1 * Math.PI / 180, // lat, lon in radians\n' +
' la2 = lat2 * Math.PI / 180,\n' +
' lo1 = lon1 * Math.PI / 180,\n' +
' lo2 = lon2 * Math.PI / 180,\n' +
' haversine_phi = Math.pow(Math.sin((la2 - la1) / 2), 2),\n' +
' sin_lon = Math.sin((lo2 - lo1) / 2),\n' +
' h = haversine_phi + Math.cos(la1) * Math.cos(la2) * sin_lon * sin_lon;\n' +
' return 2 * R * Math.asin(Math.sqrt(h));\n' +
'}\n' +
'\n' +
'function compare(coord1, coord2) {\n' +
' assert(coord1.latitude, coord2.latitude, "Latitude");\n' +
' assert(coord1.longitude, coord2.longitude, "Longitude");\n' +
' assert(coord1.altitude, coord2.altitude, "Altitude");\n' +
'}\n' +
'\n' +
'me.onStart = function (timestamp) {\n' +
' assert(me.getSpeed(), 0, "Initial speed");\n' +
' assert(me.getYaw(), 0, "Yaw angle");\n' +
' me.start_time = timestamp;\n' +
' me.takeOff();\n' +
' me.direction_set = false;\n' +
' me.interval_ckecked = false;\n' +
'};\n' +
'\n' +
'me.onUpdate = function (timestamp) {\n' +
' if (!me.interval_ckecked) {\n' +
' var time_interval = timestamp - me.start_time,\n' +
' expected_interval = ' + LOOP_INTERVAL + ';\n' +
' assert(time_interval.toFixed(4), expected_interval.toFixed(4), "Timestamp");\n' +
' assert(Date.now(), timestamp, "Date");\n' +
' me.interval_ckecked = true;\n' +
' }\n' +
' if (!me.isReadyToFly()) {\n' +
' return;\n' +
' } else {\n' +
' if (me.direction_set === false) {\n' +
' me.initialPosition = me.getCurrentPosition();\n' +
' me.initialPosition.altitude = me.initialPosition.altitude.toFixed(2);\n' +
' assert(me.initialPosition.altitude, (' + TAKEOFF_ALTITUDE + ').toFixed(2),\n' +
' "Altitude");\n' +
' me.direction_set = true;\n' +
' return me.setTargetCoordinates(\n' +
' me.initialPosition.latitude + 0.01,\n' +
' me.initialPosition.longitude,\n' +
' me.getAltitudeAbs(),\n' +
' ' + DEFAULT_SPEED + '\n' +
' );\n' +
' }\n' +
' }\n' +
' var current_position = me.getCurrentPosition(),\n' +
' realDistance = distance(\n' +
' me.initialPosition.latitude,\n' +
' me.initialPosition.longitude,\n' +
' me.getCurrentPosition().latitude,\n' +
' me.getCurrentPosition().longitude\n' +
' ).toFixed(8),\n' +
' expectedDistance = (me.getSpeed() * ' + LOOP_INTERVAL + ' / 1000).toFixed(8);\n' +
' assert(realDistance, expectedDistance, "Distance");\n' +
' current_position.latitude = current_position.latitude.toFixed(7);\n' +
' current_position.altitude = current_position.altitude.toFixed(2);\n' +
' compare(current_position, {\n' +
' latitude: (me.initialPosition.latitude + me.getSpeed() *' + STEP + ').toFixed(7),\n' +
' longitude: me.initialPosition.longitude,\n' +
' altitude: me.initialPosition.altitude\n' +
' });\n' +
'};',
DRAW = true,
LOG = true,
LOG_TIME = 1662.7915426540285,
DRONE_LIST = [],
LOGIC_FILE_LIST = [
'gadget_erp5_page_drone_capture_flag_logic.js',
'gadget_erp5_page_drone_capture_map_utils.js',
'gadget_erp5_page_drone_capture_flag_fixedwingdrone.js',
'gadget_erp5_page_drone_capture_flag_enemydrone.js',
MulticopterDroneAPI.SCRIPT_NAME
];
rJS(window)
/////////////////////////////////////////////////////////////////
// Acquired methods
/////////////////////////////////////////////////////////////////
.declareAcquiredMethod("notifySubmitted", "notifySubmitted")
.declareMethod('render', function render() {
var gadget = this;
return gadget.runGame();
})
.declareJob('runGame', function runGame() {
var gadget = this, i,
fragment = gadget.element.querySelector('.simulator_div'),
game_parameters_json, map_json, operator_init_msg;
DRONE_LIST = [];
fragment = domsugar(gadget.element.querySelector('.simulator_div'),
[domsugar('div')]).firstElementChild;
for (i = 0; i < NUMBER_OF_DRONES; i += 1) {
DRONE_LIST[i] = {"id": i, "type": MulticopterDroneAPI.name,
"script_content": DEFAULT_SCRIPT_CONTENT};
}
map_json = {
"height": map_height,
"start_AMSL": start_AMSL,
"min_lat": MIN_LAT,
"max_lat": MAX_LAT,
"min_lon": MIN_LON,
"max_lon": MAX_LON,
"flag_list": [],
"obstacle_list" : [],
"enemy_list" : [],
"initial_position": {
"longitude": INIT_LON,
"latitude": INIT_LAT,
"altitude": INIT_ALT
}
};
operator_init_msg = {
"flag_positions": []
};
/*jslint evil: false*/
game_parameters_json = {
"debug_test_mode": true,
"drone": {
"onUpdateInterval": ON_UPDATE_INTERVAL,
"list": DRONE_LIST
},
"gameTime": SIMULATION_TIME,
"simulation_speed": SIMULATION_SPEED,
"latency": {
"information": 0,
"communication": 0
},
"map": map_json,
"operator_init_msg": operator_init_msg,
"draw_flight_path": DRAW,
"temp_flight_path": true,
"log_drone_flight": LOG,
"log_interval_time": LOG_TIME
};
Object.keys(MulticopterDroneAPI.FORM_VIEW).forEach(function (parameter) {
var field = MulticopterDroneAPI.FORM_VIEW[parameter];
game_parameters_json.drone[field.key] = field.default;
});
return gadget.declareGadget("babylonjs.gadget.html",
{element: fragment, scope: 'simulator'})
.push(function () {
return gadget.getDeclaredGadget('form_view_babylonjs');
})
.push(function (form_gadget) {
return form_gadget.render({
erp5_document: {
"_embedded": {"_view": {
"my_babylonjs": {
"default": "",
"css_class": "",
"required": 0,
"editable": 1,
"key": "babylonjs",
"hidden": 0,
"type": "GadgetField",
"url": "babylonjs.gadget.html",
"sandbox": "public",
"renderjs_extra": '{"autorun": false, ' +
'"logic_file_list": ' + JSON.stringify(LOGIC_FILE_LIST) + ', ' +
'"game_parameters": ' + JSON.stringify(game_parameters_json) +
'}'
}
}},
"_links": {
"type": {
name: ""
}
}
},
form_definition: {
group_list: [[
"bottom",
[["my_babylonjs"]]
]]
}
});
})
.push(function () {
return gadget.getDeclaredGadget('form_view_babylonjs');
})
.push(function (form_gadget) {
return form_gadget.getContent();
})
.push(function (result) {
var div = domsugar('div', { text: "CONSOLE LOG ENTRIES:" }), lines,
l, test_log_node = document.querySelector('.test_log');
document.querySelector('.container').parentNode.appendChild(div);
function appendToTestLog(test_log_node, message) {
var log_node = document.createElement("div"),
textNode = document.createTextNode(message);
log_node.appendChild(textNode);
test_log_node.appendChild(log_node);
}
lines = result.console_log.split('\n');
for (l = 0; l < lines.length; l += 1) {
if (lines[l] !== 'TIMEOUT!') {
appendToTestLog(test_log_node, lines[l]);
} else {
appendToTestLog(test_log_node, 'Timeout: OK');
return;
}
}
appendToTestLog(test_log_node, 'Timeout: FAILED');
}, function (error) {
return gadget.notifySubmitted({message: "Error: " + error.message,
status: 'error'});
});
});
}(window, rJS, domsugar, document, MulticopterDroneAPI));
\ No newline at end of file
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Web Script" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_Access_contents_information_Permission</string> </key>
<value>
<tuple>
<string>Anonymous</string>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Add_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Change_local_roles_Permission</string> </key>
<value>
<tuple>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Modify_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_View_Permission</string> </key>
<value>
<tuple>
<string>Anonymous</string>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>content_md5</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>content_type</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>gadget_erp5_page_drone_capture_flag_multicopter_test_page.js</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>test_capture_drone_multicopter_flight_js</string> </value>
</item>
<item>
<key> <string>language</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Web Script</string> </value>
</item>
<item>
<key> <string>short_title</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Drone Capture Flag Multicopter Test Page JS</string> </value>
</item>
<item>
<key> <string>version</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary>
<item>
<key> <string>document_publication_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>edit_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value>
</item>
<item>
<key> <string>processing_status_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAU=</string> </persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>publish_alive</string> </value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <unicode>zope</unicode> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass>
<global name="_reconstructor" module="copy_reg"/>
</klass>
<tuple>
<global name="DateTime" module="DateTime.DateTime"/>
<global name="object" module="__builtin__"/>
<none/>
</tuple>
<state>
<tuple>
<float>1730805477.59</float>
<string>UTC</string>
</tuple>
</state>
</object>
</value>
</item>
<item>
<key> <string>validation_state</string> </key>
<value> <string>published_alive</string> </value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>edit</string> </value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <unicode>zope</unicode> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>1020.30724.64753.62276</string> </value>
</item>
<item>
<key> <string>state</string> </key>
<value> <string>current</string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass>
<global name="_reconstructor" module="copy_reg"/>
</klass>
<tuple>
<global name="DateTime" module="DateTime.DateTime"/>
<global name="object" module="__builtin__"/>
<none/>
</tuple>
<state>
<tuple>
<float>1730823460.82</float>
<string>UTC</string>
</tuple>
</state>
</object>
</value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="5" aka="AAAAAAAAAAU=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>detect_converted_file</string> </value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <unicode>zope</unicode> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>external_processing_state</string> </key>
<value> <string>converted</string> </value>
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>0.0.0.0</string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass>
<global name="_reconstructor" module="copy_reg"/>
</klass>
<tuple>
<global name="DateTime" module="DateTime.DateTime"/>
<global name="object" module="__builtin__"/>
<none/>
</tuple>
<state>
<tuple>
<float>1730804884.44</float>
<string>UTC</string>
</tuple>
</state>
</object>
</value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -19,9 +19,11 @@ ...@@ -19,9 +19,11 @@
<td>${base_url}/web_site_module/officejs_drone_simulator/</td> <td>${base_url}/web_site_module/officejs_drone_simulator/</td>
<td></td> <td></td>
</tr> </tr>
<!-- error on /Zuite_waitForActivities
<tal:block tal:define="web_site_name python: 'officejs_drone_simulator'"> <tal:block tal:define="web_site_name python: 'officejs_drone_simulator'">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForOfficejsUi/macros/install_offline_and_redirect" /> <tal:block metal:use-macro="here/Zuite_CommonTemplateForOfficejsUi/macros/install_offline_and_redirect" />
</tal:block> </tal:block>
-->
<!-- Check form --> <!-- Check form -->
<tr> <tr>
<td>waitForElementPresent</td> <td>waitForElementPresent</td>
...@@ -68,17 +70,17 @@ ...@@ -68,17 +70,17 @@
<!-- Check simulator gadget and babylon lib --> <!-- Check simulator gadget and babylon lib -->
<tr> <tr>
<td>waitForElementPresent</td> <td>waitForElementPresent</td>
<td>//div[contains(@data-gadget-url, 'gadget_erp5_page_drone_simulator_gadget.html')]</td> <td>//div[contains(@data-gadget-url, 'babylonjs.gadget.html')]</td>
<td></td> <td></td>
<tr> <tr>
<tr> <tr>
<td>waitForElementPresent</td> <td>waitForElementPresent</td>
<td>//div[contains(@data-gadget-url, 'gadget_erp5_page_drone_simulator_gadget.html')]//canvas[contains(@data-engine, 'Babylon.js')]</td> <td>//div[contains(@data-gadget-url, 'babylonjs.gadget.html')]//canvas[contains(@data-engine, 'Babylon.js')]</td>
<td></td> <td></td>
<tr> <tr>
<tr> <tr>
<td>waitForElementPresent</td> <td>waitForElementPresent</td>
<td>//div[@class="container"]//a[contains(text(), 'Download Simulation LOG')]</td> <td>//a[contains(text(), 'Download Simulation LOG')]</td>
<td></td> <td></td>
<tr> <tr>
<tr> <tr>
...@@ -86,6 +88,32 @@ ...@@ -86,6 +88,32 @@
<td>//div[@class="container"]//textarea</td> <td>//div[@class="container"]//textarea</td>
<td></td> <td></td>
<tr> <tr>
<!-- Change drone type -->
<tr>
<td>select</td>
<td>//select[@name="drone_type"]</td>
<td>value=Fixed Wings</td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//label[text()='Drone min speed']</td>
<td></td>
<tr>
<tr>
<td>click</td>
<td>//div[contains(@data-gadget-url, 'gadget_erp5_page_drone_simulator_script_page.html')]//input[@type="submit" and @name="action_run"]</td>
<td></td>
<tr>
<tr>
<td>waitForElementPresent</td>
<td>//span[@id="loading"]</td>
<td></td>
<tr>
<tr>
<td>waitForElementPresent</td>
<td>//a[contains(text(), 'Download Simulation LOG')]</td>
<td></td>
<tr>
<!-- Go to log page --> <!-- Go to log page -->
<tr> <tr>
<td>click</td> <td>click</td>
...@@ -124,14 +152,14 @@ ...@@ -124,14 +152,14 @@
<tr> <tr>
<td>type</td> <td>type</td>
<td>//textarea[@id="log_1"]</td> <td>//textarea[@id="log_1"]</td>
<td>timestamp;;latitude;;longitude;;AMSL (m);;rel altitude (m);;pitch (°);;roll(°);;yaw(°);;air speed (m/s);;throttle(%);;climb rate(m/s) <td>timestamp (ms);latitude (°);longitude (°);AMSL (m);rel altitude (m);yaw (°);ground speed (m/s);climb rate (m/s)
16.666666666666668;45.6412;14.265800000000013;610.328;15</td> 0;45.6412;14.2658;595;0;0;0;0<br />1;45.6403;14.2671;595;0;180;6;0</td>
</tr> </tr>
<tr> <tr>
<td>type</td> <td>type</td>
<td>//textarea[@id="log_2"]</td> <td>//textarea[@id="log_2"]</td>
<td>timestamp;;latitude;;longitude;;AMSL (m);;rel altitude (m);;pitch (°);;roll(°);;yaw(°);;air speed (m/s);;throttle(%);;climb rate(m/s) <td>timestamp (ms);latitude (°);longitude (°);AMSL (m);rel altitude (m);yaw (°);ground speed (m/s);climb rate (m/s)
16.666666666666668;45.6412;14.265800000000013;610.328;15</td> 0;45.6412;14.2658;595;0;0;0;0<br />1;45.6403;14.2671;595;0;180;6;0</td>
</tr> </tr>
<tr> <tr>
<td>click</td> <td>click</td>
...@@ -151,12 +179,12 @@ ...@@ -151,12 +179,12 @@
<!-- Check simulator gadget and babylon lib --> <!-- Check simulator gadget and babylon lib -->
<tr> <tr>
<td>waitForElementPresent</td> <td>waitForElementPresent</td>
<td>//div[contains(@data-gadget-url, 'gadget_erp5_page_drone_simulator_gadget.html')]</td> <td>//div[contains(@data-gadget-url, 'babylonjs.gadget.html')]</td>
<td></td> <td></td>
<tr> <tr>
<tr> <tr>
<td>waitForElementPresent</td> <td>waitForElementPresent</td>
<td>//div[contains(@data-gadget-url, 'gadget_erp5_page_drone_simulator_gadget.html')]//canvas[contains(@data-engine, 'Babylon.js')]</td> <td>//div[contains(@data-gadget-url, 'babylonjs.gadget.html')]//canvas[contains(@data-engine, 'Babylon.js')]</td>
<td></td> <td></td>
<tr> <tr>
</tbody></table> </tbody></table>
......
...@@ -46,7 +46,7 @@ ...@@ -46,7 +46,7 @@
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>testDroneCaptureFlagFlight</string> </value> <value> <string>testDroneSimulatorFixedWingFlight</string> </value>
</item> </item>
<item> <item>
<key> <string>output_encoding</string> </key> <key> <string>output_encoding</string> </key>
......
...@@ -9,14 +9,14 @@ ...@@ -9,14 +9,14 @@
<body> <body>
<table cellpadding="1" cellspacing="1" border="1"> <table cellpadding="1" cellspacing="1" border="1">
<thead> <thead>
<tr><td rowspan="1" colspan="3">Test Drone Simulator OJS app (expected failure)</td></tr> <tr><td rowspan="1" colspan="3">Test Fixed Wing Drone Simulator OJS app (expected failure)</td></tr>
</thead><tbody> </thead><tbody>
<tal:block metal:use-macro="here/Zuite_CommonTemplate/macros/init" /> <tal:block metal:use-macro="here/Zuite_CommonTemplate/macros/init" />
<!-- Go to site --> <!-- Go to site -->
<tr> <tr>
<td>open</td> <td>open</td>
<td>${base_url}/web_site_module/officejs_drone_simulator/app/#/?page=drone_simulator_test_page</td> <td>${base_url}/web_site_module/officejs_drone_simulator/app/#/?page=drone_simulator_fixed_wing_test_page</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
...@@ -26,12 +26,12 @@ ...@@ -26,12 +26,12 @@
<tr> <tr>
<tr> <tr>
<td>waitForElementPresent</td> <td>waitForElementPresent</td>
<td>//div[contains(@data-gadget-url, 'gadget_erp5_page_drone_simulator_test_page.html')]//input[@type="submit" and @name="action_run"]</td> <td>//div[contains(@data-gadget-url, 'gadget_erp5_page_drone_simulator_fixed_wing_test_page.html')]//input[@type="submit" and @name="action_run"]</td>
<td></td> <td></td>
<tr> <tr>
<tr> <tr>
<td>click</td> <td>click</td>
<td>//div[contains(@data-gadget-url, 'gadget_erp5_page_drone_simulator_test_page.html')]//input[@type="submit" and @name="action_run"]</td> <td>//div[contains(@data-gadget-url, 'gadget_erp5_page_drone_simulator_fixed_wing_test_page.html')]//input[@type="submit" and @name="action_run"]</td>
<td></td> <td></td>
<tr> <tr>
<tr> <tr>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ZopePageTemplate" module="Products.PageTemplates.ZopePageTemplate"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="_reconstructor" module="copy_reg"/>
</klass>
<tuple>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
<global name="object" module="__builtin__"/>
<none/>
</tuple>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>text/html</string> </value>
</item>
<item>
<key> <string>expand</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>testDroneSimulatorMulticopterFlight</string> </value>
</item>
<item>
<key> <string>output_encoding</string> </key>
<value> <string>utf-8</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <unicode></unicode> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<html xmlns:tal="http://xml.zope.org/namespaces/tal"
xmlns:metal="http://xml.zope.org/namespaces/metal">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Test Drone Simulator OJS app (expected failure)</title>
<!-- This test is expected to fail as the drone simulator runs on a web worker canvas, which relies on a very new feature: offscreen canvas
---- This feature is not supported yet by the latest Firefox ESR used in the test nodes -->
</head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr><td rowspan="1" colspan="3">Test Multicopter Drone Simulator OJS app (expected failure)</td></tr>
</thead><tbody>
<tal:block metal:use-macro="here/Zuite_CommonTemplate/macros/init" />
<!-- Go to site -->
<tr>
<td>open</td>
<td>${base_url}/web_site_module/officejs_drone_simulator/app/#/?page=drone_simulator_multicopter_test_page</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//div[contains(@data-gadget-url, 'codemirror.gadget.html')]</td>
<td></td>
<tr>
<tr>
<td>waitForElementPresent</td>
<td>//div[contains(@data-gadget-url, 'gadget_erp5_page_drone_simulator_multicopter_test_page.html')]//input[@type="submit" and @name="action_run"]</td>
<td></td>
<tr>
<tr>
<td>click</td>
<td>//div[contains(@data-gadget-url, 'gadget_erp5_page_drone_simulator_multicopter_test_page.html')]//input[@type="submit" and @name="action_run"]</td>
<td></td>
<tr>
<tr>
<td>waitForElementPresent</td>
<td>//span[@id="loading"]</td>
<td></td>
<tr>
<tr>
<td>waitForElementPresent</td>
<td>//div[contains(@data-gadget-url, 'babylonjs.gadget.html')]</td>
<td></td>
<tr>
<tr>
<td>waitForElementPresent</td>
<td>//div[contains(@data-gadget-url, 'babylonjs.gadget.html')]//canvas[contains(@data-engine, 'Babylon.js')]</td>
<td></td>
<tr>
<tr>
<td>waitForElementPresent</td>
<td>//div[contains(text(), 'CONSOLE LOG ENTRIES:')]</td>
<td></td>
<tr>
<tr>
<td>assertElementPresent</td>
<td>//div[contains(text(), 'Initial speed: OK')]</td>
<td></td>
<tr>
<tr>
<td>assertElementPresent</td>
<td>//div[contains(text(), 'Yaw angle: OK')]</td>
<td></td>
<tr>
<tr>
<td>assertElementPresent</td>
<td>//div[contains(text(), 'Timestamp: OK')]</td>
<td></td>
<tr>
<tr>
<td>assertElementPresent</td>
<td>//div[contains(text(), 'Distance: OK')]</td>
<td></td>
<tr>
<tr>
<td>assertElementPresent</td>
<td>//div[contains(text(), 'Latitude: OK')]</td>
<td></td>
<tr>
<tr>
<td>assertElementPresent</td>
<td>//div[contains(text(), 'Longitude: OK')]</td>
<td></td>
<tr>
<tr>
<td>assertElementPresent</td>
<td>//div[contains(text(), 'Altitude: OK')]</td>
<td></td>
<tr>
<tr>
<td>assertElementPresent</td>
<td>//div[contains(text(), 'Timeout: OK')]</td>
<td></td>
<tr>
</tbody></table>
</body>
</html>
\ No newline at end of file
...@@ -19,7 +19,10 @@ ...@@ -19,7 +19,10 @@
<script src="gadget_global.js" type="text/javascript"></script> <script src="gadget_global.js" type="text/javascript"></script>
<script src="domsugar.js" type="text/javascript"></script> <script src="domsugar.js" type="text/javascript"></script>
<script src="gadget_erp5_page_drone_capture_flag_test_page.js" type="text/javascript"></script> <!-- API scripts -->
<script src="gadget_erp5_page_drone_simulator_fixedwingdrone.js" type="text/javascript"></script>
<script src="gadget_erp5_page_drone_simulator_fixed_wing_test_page.js" type="text/javascript"></script>
</head> </head>
<body> <body>
......
...@@ -73,7 +73,7 @@ ...@@ -73,7 +73,7 @@
</item> </item>
<item> <item>
<key> <string>default_reference</string> </key> <key> <string>default_reference</string> </key>
<value> <string>gadget_erp5_page_drone_simulator_test_page.html</string> </value> <value> <string>gadget_erp5_page_drone_simulator_fixed_wing_test_page.html</string> </value>
</item> </item>
<item> <item>
<key> <string>description</string> </key> <key> <string>description</string> </key>
...@@ -83,7 +83,7 @@ ...@@ -83,7 +83,7 @@
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>test_drone_simulator_flight_html</string> </value> <value> <string>test_drone_simulator_fixed_wing_flight_html</string> </value>
</item> </item>
<item> <item>
<key> <string>language</string> </key> <key> <string>language</string> </key>
...@@ -103,7 +103,7 @@ ...@@ -103,7 +103,7 @@
</item> </item>
<item> <item>
<key> <string>title</string> </key> <key> <string>title</string> </key>
<value> <string>Drone Simulator Test Page</string> </value> <value> <string>Drone Simulator Fixed Wing Test Page</string> </value>
</item> </item>
<item> <item>
<key> <string>version</string> </key> <key> <string>version</string> </key>
...@@ -244,7 +244,7 @@ ...@@ -244,7 +244,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>1010.3732.28220.36454</string> </value> <value> <string>1020.14908.61242.50278</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -264,7 +264,7 @@ ...@@ -264,7 +264,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1690898356.42</float> <float>1730738493.75</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
/*jslint indent: 2, maxlen: 100*/ /*jslint indent: 2, maxlen: 100*/
/*global window, rJS, domsugar, document, URLSearchParams, Blob*/ /*global window, rJS, domsugar, document, FixedWingDroneAPI*/
(function (window, rJS, domsugar, document, URLSearchParams, Blob) { (function (window, rJS, domsugar, document, FixedWingDroneAPI) {
"use strict"; "use strict";
var SIMULATION_SPEED = 1, var SIMULATION_SPEED = 1,
...@@ -8,15 +8,6 @@ ...@@ -8,15 +8,6 @@
ON_UPDATE_INTERVAL = LOOP_INTERVAL, ON_UPDATE_INTERVAL = LOOP_INTERVAL,
SIMULATION_TIME = LOOP_INTERVAL / 1000, SIMULATION_TIME = LOOP_INTERVAL / 1000,
DEFAULT_SPEED = 16, DEFAULT_SPEED = 16,
MAX_ACCELERATION = 6,
MAX_DECELERATION = 1,
MIN_SPEED = 12,
MAX_SPEED = 26,
MAX_ROLL = 35,
MIN_PITCH = -20,
MAX_PITCH = 25,
MAX_CLIMB_RATE = 8,
MAX_SINK_RATE = 3,
NUMBER_OF_DRONES = 1, NUMBER_OF_DRONES = 1,
MIN_LAT = 45.6364, MIN_LAT = 45.6364,
MAX_LAT = 45.65, MAX_LAT = 45.65,
...@@ -49,14 +40,14 @@ ...@@ -49,14 +40,14 @@
'}\n' + '}\n' +
'\n' + '\n' +
'function compare(coord1, coord2) {\n' + 'function compare(coord1, coord2) {\n' +
' assert(coord1.latitude, coord2.latitude, "Latitude")\n' + ' assert(coord1.latitude, coord2.latitude, "Latitude");\n' +
' assert(coord1.longitude, coord2.longitude, "Longitude")\n' + ' assert(coord1.longitude, coord2.longitude, "Longitude");\n' +
' assert(coord1.altitude, coord2.altitude, "Altitude")\n' + ' assert(coord1.altitude, coord2.altitude, "Altitude");\n' +
'}\n' + '}\n' +
'\n' + '\n' +
'me.onStart = function (timestamp) {\n' + 'me.onStart = function (timestamp) {\n' +
' assert(me.getSpeed(), ' + DEFAULT_SPEED + ', "Initial speed");\n' + ' assert(me.getSpeed(), ' + DEFAULT_SPEED + ', "Initial speed");\n' +
' assert(me.getYaw(), 0, "Yaw angle")\n' + ' assert(me.getYaw(), 0, "Yaw angle");\n' +
' me.initialPosition = me.getCurrentPosition();\n' + ' me.initialPosition = me.getCurrentPosition();\n' +
' me.start_time = timestamp;\n' + ' me.start_time = timestamp;\n' +
' me.setTargetCoordinates(\n' + ' me.setTargetCoordinates(\n' +
...@@ -94,8 +85,9 @@ ...@@ -94,8 +85,9 @@
DRONE_LIST = [], DRONE_LIST = [],
LOGIC_FILE_LIST = [ LOGIC_FILE_LIST = [
'gadget_erp5_page_drone_simulator_logic.js', 'gadget_erp5_page_drone_simulator_logic.js',
'gadget_erp5_page_drone_simulator_fixedwingdrone.js', 'gadget_erp5_page_drone_simulator_multicopterdrone.js',
'gadget_erp5_page_drone_simulator_dronelogfollower.js' 'gadget_erp5_page_drone_simulator_dronelogfollower.js',
FixedWingDroneAPI.SCRIPT_NAME
]; ];
rJS(window) rJS(window)
...@@ -138,9 +130,12 @@ ...@@ -138,9 +130,12 @@
"key": "script", "key": "script",
"hidden": 0, "hidden": 0,
"type": "GadgetField", "type": "GadgetField",
"renderjs_extra": '{"editor": "codemirror", "maximize": true}', "renderjs_extra": JSON.stringify({
"url": "gadget_editor.html", "language": "en",
"sandbox": "public" "portal_type": "Web Script",
"editor": "codemirror"
}),
"url": "gadget_editor.html"
} }
}}, }},
"_links": { "_links": {
...@@ -167,23 +162,14 @@ ...@@ -167,23 +162,14 @@
fragment = domsugar(gadget.element.querySelector('.simulator_div'), fragment = domsugar(gadget.element.querySelector('.simulator_div'),
[domsugar('div')]).firstElementChild; [domsugar('div')]).firstElementChild;
for (i = 0; i < NUMBER_OF_DRONES; i += 1) { for (i = 0; i < NUMBER_OF_DRONES; i += 1) {
DRONE_LIST[i] = {"id": i, "type": "FixedWingDroneAPI", DRONE_LIST[i] = {"id": i, "type": FixedWingDroneAPI.name,
"script_content": options.script}; "script_content": options.script};
} }
game_parameters_json = { game_parameters_json = {
"debug_test_mode": true, "debug_test_mode": true,
"drone": { "drone": {
"maxAcceleration": MAX_ACCELERATION, "onUpdateInterval": ON_UPDATE_INTERVAL,
"maxDeceleration": MAX_DECELERATION, "list": DRONE_LIST
"minSpeed": MIN_SPEED,
"speed": DEFAULT_SPEED,
"maxSpeed": MAX_SPEED,
"maxRoll": MAX_ROLL,
"minPitchAngle": MIN_PITCH,
"maxPitchAngle": MAX_PITCH,
"maxSinkRate": MAX_SINK_RATE,
"maxClimbRate": MAX_CLIMB_RATE,
"onUpdateInterval": ON_UPDATE_INTERVAL
}, },
"gameTime": SIMULATION_TIME, "gameTime": SIMULATION_TIME,
"simulation_speed": SIMULATION_SPEED, "simulation_speed": SIMULATION_SPEED,
...@@ -207,9 +193,13 @@ ...@@ -207,9 +193,13 @@
"draw_flight_path": DRAW, "draw_flight_path": DRAW,
"temp_flight_path": true, "temp_flight_path": true,
"log_drone_flight": LOG, "log_drone_flight": LOG,
"log_interval_time": LOG_TIME, "log_interval_time": LOG_TIME
"droneList": DRONE_LIST
}; };
Object.keys(FixedWingDroneAPI.FORM_VIEW).forEach(function (parameter) {
var field = FixedWingDroneAPI.FORM_VIEW[parameter];
game_parameters_json.drone[field.key] = field.default;
});
return gadget.declareGadget("babylonjs.gadget.html", return gadget.declareGadget("babylonjs.gadget.html",
{element: fragment, scope: 'simulator'}) {element: fragment, scope: 'simulator'})
.push(function () { .push(function () {
...@@ -259,7 +249,6 @@ ...@@ -259,7 +249,6 @@
var div = domsugar('div', { text: "CONSOLE LOG ENTRIES:" }), var div = domsugar('div', { text: "CONSOLE LOG ENTRIES:" }),
lines = result.console_log.split('\n'), lines = result.console_log.split('\n'),
line_nb, line_nb,
node,
test_log_node = document.querySelector('.test_log');; test_log_node = document.querySelector('.test_log');;
document.querySelector('.container').parentNode.appendChild(div); document.querySelector('.container').parentNode.appendChild(div);
function appendToTestLog(test_log_node, message) { function appendToTestLog(test_log_node, message) {
...@@ -283,4 +272,4 @@ ...@@ -283,4 +272,4 @@
}); });
}); });
}(window, rJS, domsugar, document, URLSearchParams, Blob)); }(window, rJS, domsugar, document, FixedWingDroneAPI));
\ No newline at end of file \ No newline at end of file
...@@ -75,7 +75,7 @@ ...@@ -75,7 +75,7 @@
</item> </item>
<item> <item>
<key> <string>default_reference</string> </key> <key> <string>default_reference</string> </key>
<value> <string>gadget_erp5_page_drone_simulator_test_page.js</string> </value> <value> <string>gadget_erp5_page_drone_simulator_fixed_wing_test_page.js</string> </value>
</item> </item>
<item> <item>
<key> <string>description</string> </key> <key> <string>description</string> </key>
...@@ -85,7 +85,7 @@ ...@@ -85,7 +85,7 @@
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>test_drone_simulator_flight_js</string> </value> <value> <string>test_drone_simulator_fixed_wing_flight_js</string> </value>
</item> </item>
<item> <item>
<key> <string>language</string> </key> <key> <string>language</string> </key>
...@@ -105,7 +105,7 @@ ...@@ -105,7 +105,7 @@
</item> </item>
<item> <item>
<key> <string>title</string> </key> <key> <string>title</string> </key>
<value> <string>Drone Simulator Test Page JS</string> </value> <value> <string>Drone Simulator Fixed Wing Test Page JS</string> </value>
</item> </item>
<item> <item>
<key> <string>version</string> </key> <key> <string>version</string> </key>
...@@ -246,7 +246,7 @@ ...@@ -246,7 +246,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>1015.64176.45813.63488</string> </value> <value> <string>1020.29326.20074.19694</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -266,7 +266,7 @@ ...@@ -266,7 +266,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1713428376.53</float> <float>1730738827.56</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -19,7 +19,10 @@ ...@@ -19,7 +19,10 @@
<script src="gadget_global.js" type="text/javascript"></script> <script src="gadget_global.js" type="text/javascript"></script>
<script src="domsugar.js" type="text/javascript"></script> <script src="domsugar.js" type="text/javascript"></script>
<script src="gadget_erp5_page_drone_simulator_test_page.js" type="text/javascript"></script> <!-- API scripts -->
<script src="gadget_erp5_page_drone_simulator_multicopterdrone.js" type="text/javascript"></script>
<script src="gadget_erp5_page_drone_simulator_multicopter_test_page.js" type="text/javascript"></script>
</head> </head>
<body> <body>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Web Page" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_Access_contents_information_Permission</string> </key>
<value>
<tuple>
<string>Anonymous</string>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Add_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Change_local_roles_Permission</string> </key>
<value>
<tuple>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Modify_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_View_Permission</string> </key>
<value>
<tuple>
<string>Anonymous</string>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>content_md5</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>text/html</string> </value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>gadget_erp5_page_drone_simulator_multicopter_test_page.html</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>test_drone_simulator_multicopter_flight_html</string> </value>
</item>
<item>
<key> <string>language</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Web Page</string> </value>
</item>
<item>
<key> <string>short_title</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Drone Simulator Multicopter Test Page</string> </value>
</item>
<item>
<key> <string>version</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary>
<item>
<key> <string>document_publication_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>edit_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value>
</item>
<item>
<key> <string>processing_status_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAU=</string> </persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>publish_alive</string> </value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <unicode>zope</unicode> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass>
<global name="_reconstructor" module="copy_reg"/>
</klass>
<tuple>
<global name="DateTime" module="DateTime.DateTime"/>
<global name="object" module="__builtin__"/>
<none/>
</tuple>
<state>
<tuple>
<float>1729873773.39</float>
<string>UTC</string>
</tuple>
</state>
</object>
</value>
</item>
<item>
<key> <string>validation_state</string> </key>
<value> <string>published_alive</string> </value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>edit</string> </value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <unicode>zope</unicode> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>1020.14910.8112.57787</string> </value>
</item>
<item>
<key> <string>state</string> </key>
<value> <string>current</string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass>
<global name="_reconstructor" module="copy_reg"/>
</klass>
<tuple>
<global name="DateTime" module="DateTime.DateTime"/>
<global name="object" module="__builtin__"/>
<none/>
</tuple>
<state>
<tuple>
<float>1730736385.01</float>
<string>UTC</string>
</tuple>
</state>
</object>
</value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="5" aka="AAAAAAAAAAU=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>detect_converted_file</string> </value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <unicode>zope</unicode> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>external_processing_state</string> </key>
<value> <string>converted</string> </value>
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>0.0.0.0</string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass>
<global name="_reconstructor" module="copy_reg"/>
</klass>
<tuple>
<global name="DateTime" module="DateTime.DateTime"/>
<global name="object" module="__builtin__"/>
<none/>
</tuple>
<state>
<tuple>
<float>1729873450.92</float>
<string>UTC</string>
</tuple>
</state>
</object>
</value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
/*jslint indent: 2, maxlen: 100*/
/*global window, rJS, domsugar, document, MulticopterDroneAPI*/
(function (window, rJS, domsugar, document, MulticopterDroneAPI) {
"use strict";
var SIMULATION_SPEED = 100,
LOOP_INTERVAL = 1000 / 60,
ON_UPDATE_INTERVAL = LOOP_INTERVAL,
SIMULATION_TIME = 714 * LOOP_INTERVAL / 1000,
DEFAULT_SPEED = 5,
NUMBER_OF_DRONES = 1,
MIN_LAT = 45.6364,
MAX_LAT = 45.65,
MIN_LON = 14.2521,
MAX_LON = 14.2766,
HEIGHT = 100,
start_AMSL = 595,
INIT_LON = 14.2658,
INIT_LAT = 45.6412,
INIT_ALT = 0,
STEP = 2.3992831666911723e-06 / 16,
TAKEOFF_ALTITUDE = 7,
DEFAULT_SCRIPT_CONTENT =
'function assert(a, b, msg) {\n' +
' if (a === b) {\n' +
' console.log(msg + ": OK");\n' +
' } else {\n' +
' console.log(msg + ": FAIL");\n' +
' console.log(a, b);\n' +
' }\n' +
'}\n' +
'\n' +
'function distance(lat1, lon1, lat2, lon2) {\n' +
' var R = 6371e3, // meters\n' +
' la1 = lat1 * Math.PI / 180, // lat, lon in radians\n' +
' la2 = lat2 * Math.PI / 180,\n' +
' lo1 = lon1 * Math.PI / 180,\n' +
' lo2 = lon2 * Math.PI / 180,\n' +
' haversine_phi = Math.pow(Math.sin((la2 - la1) / 2), 2),\n' +
' sin_lon = Math.sin((lo2 - lo1) / 2),\n' +
' h = haversine_phi + Math.cos(la1) * Math.cos(la2) * sin_lon * sin_lon;\n' +
' return 2 * R * Math.asin(Math.sqrt(h));\n' +
'}\n' +
'\n' +
'function compare(coord1, coord2) {\n' +
' assert(coord1.latitude, coord2.latitude, "Latitude");\n' +
' assert(coord1.longitude, coord2.longitude, "Longitude");\n' +
' assert(coord1.altitude, coord2.altitude, "Altitude");\n' +
'}\n' +
'\n' +
'me.onStart = function (timestamp) {\n' +
' assert(me.getSpeed(), 0, "Initial speed");\n' +
' assert(me.getYaw(), 0, "Yaw angle");\n' +
' me.start_time = timestamp;\n' +
' me.takeOff();\n' +
' me.direction_set = false;\n' +
' me.interval_ckecked = false;\n' +
'};\n' +
'\n' +
'me.onUpdate = function (timestamp) {\n' +
' if (!me.interval_ckecked) {\n' +
' var time_interval = timestamp - me.start_time,\n' +
' expected_interval = ' + LOOP_INTERVAL + ';\n' +
' assert(time_interval.toFixed(4), expected_interval.toFixed(4), "Timestamp");\n' +
' assert(Date.now(), timestamp, "Date");\n' +
' me.interval_ckecked = true;\n' +
' }\n' +
' if (!me.isReadyToFly()) {\n' +
' return;\n' +
' } else {\n' +
' if (me.direction_set === false) {\n' +
' me.initialPosition = me.getCurrentPosition();\n' +
' me.initialPosition.altitude = me.initialPosition.altitude.toFixed(2);\n' +
' assert(me.initialPosition.altitude, (' + TAKEOFF_ALTITUDE + ').toFixed(2),\n' +
' "Altitude");\n' +
' me.direction_set = true;\n' +
' return me.setTargetCoordinates(\n' +
' me.initialPosition.latitude + 0.01,\n' +
' me.initialPosition.longitude,\n' +
' me.getAltitudeAbs(),\n' +
' ' + DEFAULT_SPEED + '\n' +
' );\n' +
' }\n' +
' }\n' +
' var current_position = me.getCurrentPosition(),\n' +
' realDistance = distance(\n' +
' me.initialPosition.latitude,\n' +
' me.initialPosition.longitude,\n' +
' me.getCurrentPosition().latitude,\n' +
' me.getCurrentPosition().longitude\n' +
' ).toFixed(8),\n' +
' expectedDistance = (me.getSpeed() * ' + LOOP_INTERVAL + ' / 1000).toFixed(8);\n' +
' assert(realDistance, expectedDistance, "Distance");\n' +
' current_position.latitude = current_position.latitude.toFixed(7);\n' +
' current_position.altitude = current_position.altitude.toFixed(2);\n' +
' compare(current_position, {\n' +
' latitude: (me.initialPosition.latitude + me.getSpeed() *' + STEP + ').toFixed(7),\n' +
' longitude: me.initialPosition.longitude,\n' +
' altitude: me.initialPosition.altitude\n' +
' });\n' +
'};',
DRAW = true,
LOG = true,
LOG_TIME = 1662.7915426540285,
DRONE_LIST = [],
LOGIC_FILE_LIST = [
'gadget_erp5_page_drone_simulator_logic.js',
'gadget_erp5_page_drone_simulator_fixedwingdrone.js',
'gadget_erp5_page_drone_simulator_dronelogfollower.js',
MulticopterDroneAPI.SCRIPT_NAME
];
rJS(window)
/////////////////////////////////////////////////////////////////
// Acquired methods
/////////////////////////////////////////////////////////////////
.declareAcquiredMethod("notifySubmitted", "notifySubmitted")
.allowPublicAcquisition('notifySubmit', function () {
return this.triggerSubmit();
})
.declareMethod("triggerSubmit", function () {
return this.element.querySelector('input[type="submit"]').click();
})
.onEvent('submit', function () {
var gadget = this;
return gadget.getDeclaredGadget('form_view')
.push(function (form_gadget) {
return form_gadget.getContent();
})
.push(function (input) {
gadget.runGame(input);
});
})
.declareMethod('render', function render() {
var gadget = this;
return gadget.getDeclaredGadget('form_view')
.push(function (form_gadget) {
return form_gadget.render({
erp5_document: {
"_embedded": {"_view": {
"my_script": {
"default": DEFAULT_SCRIPT_CONTENT,
"css_class": "",
"required": 1,
"editable": 1,
"key": "script",
"hidden": 0,
"type": "GadgetField",
"renderjs_extra": JSON.stringify({
"language": "en",
"portal_type": "Web Script",
"editor": "codemirror"
}),
"url": "gadget_editor.html"
}
}},
"_links": {
"type": {
name: ""
}
}
},
form_definition: {
group_list: [[
"bottom",
[["my_script"]]
]]
}
});
});
})
.declareJob('runGame', function runGame(options) {
var gadget = this, i,
fragment = gadget.element.querySelector('.simulator_div'),
game_parameters_json;
DRONE_LIST = [];
fragment = domsugar(gadget.element.querySelector('.simulator_div'),
[domsugar('div')]).firstElementChild;
for (i = 0; i < NUMBER_OF_DRONES; i += 1) {
DRONE_LIST[i] = {"id": i, "type": MulticopterDroneAPI.name,
"script_content": options.script};
}
game_parameters_json = {
"debug_test_mode": true,
"drone": {
"onUpdateInterval": ON_UPDATE_INTERVAL,
"list": DRONE_LIST
},
"gameTime": SIMULATION_TIME,
"simulation_speed": SIMULATION_SPEED,
"latency": {
"information": 0,
"communication": 0
},
"map": {
"min_lat": MIN_LAT,
"max_lat": MAX_LAT,
"min_lon": MIN_LON,
"max_lon": MAX_LON,
"height": HEIGHT,
"start_AMSL": start_AMSL
},
"initialPosition": {
"longitude": INIT_LON,
"latitude": INIT_LAT,
"altitude": INIT_ALT
},
"draw_flight_path": DRAW,
"temp_flight_path": true,
"log_drone_flight": LOG,
"log_interval_time": LOG_TIME
};
Object.keys(MulticopterDroneAPI.FORM_VIEW).forEach(function (parameter) {
var field = MulticopterDroneAPI.FORM_VIEW[parameter];
game_parameters_json.drone[field.key] = field.default;
});
return gadget.declareGadget("babylonjs.gadget.html",
{element: fragment, scope: 'simulator'})
.push(function () {
return gadget.getDeclaredGadget('form_view_babylonjs');
})
.push(function (form_gadget) {
return form_gadget.render({
erp5_document: {
"_embedded": {"_view": {
"my_babylonjs": {
"default": "",
"css_class": "",
"required": 0,
"editable": 1,
"key": "babylonjs",
"hidden": 0,
"type": "GadgetField",
"url": "babylonjs.gadget.html",
"sandbox": "public",
"renderjs_extra": '{"autorun": false, ' +
'"logic_file_list": ' + JSON.stringify(LOGIC_FILE_LIST) + ', ' +
'"game_parameters": ' + JSON.stringify(game_parameters_json) +
'}'
}
}},
"_links": {
"type": {
name: ""
}
}
},
form_definition: {
group_list: [[
"bottom",
[["my_babylonjs"]]
]]
}
});
})
.push(function () {
return gadget.getDeclaredGadget('form_view_babylonjs');
})
.push(function (form_gadget) {
return form_gadget.getContent();
})
.push(function (result) {
var div = domsugar('div', { text: "CONSOLE LOG ENTRIES:" }),
lines = result.console_log.split('\n'),
line_nb,
test_log_node = document.querySelector('.test_log');
document.querySelector('.container').parentNode.appendChild(div);
function appendToTestLog(test_log_node, message) {
var log_node = document.createElement("div"),
textNode = document.createTextNode(message);
log_node.appendChild(textNode);
test_log_node.appendChild(log_node);
}
for (line_nb = 0; line_nb < lines.length; line_nb += 1) {
if (lines[line_nb] !== 'TIMEOUT!') {
appendToTestLog(test_log_node, lines[line_nb]);
} else {
appendToTestLog(test_log_node, 'Timeout: OK');
return;
}
}
appendToTestLog(test_log_node, 'Timeout: FAILED');
}, function (error) {
return gadget.notifySubmitted({message: "Error: " + error.message,
status: 'error'});
});
});
}(window, rJS, domsugar, document, MulticopterDroneAPI));
\ No newline at end of file
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Web Script" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_Access_contents_information_Permission</string> </key>
<value>
<tuple>
<string>Anonymous</string>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Add_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Change_local_roles_Permission</string> </key>
<value>
<tuple>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Modify_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_View_Permission</string> </key>
<value>
<tuple>
<string>Anonymous</string>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>content_md5</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>content_type</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>gadget_erp5_page_drone_simulator_multicopter_test_page.js</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>test_drone_simulator_multicopter_flight_js</string> </value>
</item>
<item>
<key> <string>language</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Web Script</string> </value>
</item>
<item>
<key> <string>short_title</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Drone Simulator Multicopter Test Page JS</string> </value>
</item>
<item>
<key> <string>version</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary>
<item>
<key> <string>document_publication_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>edit_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value>
</item>
<item>
<key> <string>processing_status_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAU=</string> </persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>publish_alive</string> </value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <unicode>zope</unicode> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass>
<global name="_reconstructor" module="copy_reg"/>
</klass>
<tuple>
<global name="DateTime" module="DateTime.DateTime"/>
<global name="object" module="__builtin__"/>
<none/>
</tuple>
<state>
<tuple>
<float>1729871328.22</float>
<string>UTC</string>
</tuple>
</state>
</object>
</value>
</item>
<item>
<key> <string>validation_state</string> </key>
<value> <string>published_alive</string> </value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>edit</string> </value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <unicode>zope</unicode> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>1020.29316.53379.55108</string> </value>
</item>
<item>
<key> <string>state</string> </key>
<value> <string>current</string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass>
<global name="_reconstructor" module="copy_reg"/>
</klass>
<tuple>
<global name="DateTime" module="DateTime.DateTime"/>
<global name="object" module="__builtin__"/>
<none/>
</tuple>
<state>
<tuple>
<float>1730738357.0</float>
<string>UTC</string>
</tuple>
</state>
</object>
</value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="5" aka="AAAAAAAAAAU=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>detect_converted_file</string> </value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <unicode>zope</unicode> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>external_processing_state</string> </key>
<value> <string>converted</string> </value>
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>0.0.0.0</string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass>
<global name="_reconstructor" module="copy_reg"/>
</klass>
<tuple>
<global name="DateTime" module="DateTime.DateTime"/>
<global name="object" module="__builtin__"/>
<none/>
</tuple>
<state>
<tuple>
<float>1729871118.19</float>
<string>UTC</string>
</tuple>
</state>
</object>
</value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment