Commit 2d2050eb authored by Léo-Paul Géneau's avatar Léo-Paul Géneau 👾

erp5_officejs_drone_simulator: fix timeout

See merge request !1903
parents a12d43f0 23c9f1b0
...@@ -56,7 +56,7 @@ var EnemyDroneAPI = /** @class */ (function () { ...@@ -56,7 +56,7 @@ var EnemyDroneAPI = /** @class */ (function () {
/* /*
** Function called on every drone update, right before onUpdate AI script ** Function called on every drone update, right before onUpdate AI script
*/ */
EnemyDroneAPI.prototype.internal_update = function (context, delta_time) { EnemyDroneAPI.prototype.internal_position_update = function (context, delta_time) {
context._speed += context._acceleration * delta_time / 1000; context._speed += context._acceleration * delta_time / 1000;
if (context._speed > context._maxSpeed) { if (context._speed > context._maxSpeed) {
context._speed = context._maxSpeed; context._speed = context._maxSpeed;
...@@ -81,7 +81,7 @@ var EnemyDroneAPI = /** @class */ (function () { ...@@ -81,7 +81,7 @@ var EnemyDroneAPI = /** @class */ (function () {
/* /*
** Function called on every drone update, right after onUpdate AI script ** Function called on every drone update, right after onUpdate AI script
*/ */
EnemyDroneAPI.prototype.internal_post_update = function (drone) { EnemyDroneAPI.prototype.internal_info_update = function (drone) {
var _this = this, drone_position = drone.getCurrentPosition(), drone_info; var _this = this, drone_position = drone.getCurrentPosition(), drone_info;
if (drone_position) { if (drone_position) {
drone_info = { drone_info = {
...@@ -307,6 +307,9 @@ var EnemyDroneAPI = /** @class */ (function () { ...@@ -307,6 +307,9 @@ var EnemyDroneAPI = /** @class */ (function () {
EnemyDroneAPI.prototype.getMaxHeight = function () { EnemyDroneAPI.prototype.getMaxHeight = function () {
return 800; return 800;
}; };
EnemyDroneAPI.prototype.getOnUpdateInterval = function () {
return 0;
};
EnemyDroneAPI.prototype.getFlightParameters = function () { EnemyDroneAPI.prototype.getFlightParameters = function () {
return this._flight_parameters; return this._flight_parameters;
}; };
......
...@@ -246,7 +246,7 @@ ...@@ -246,7 +246,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>1014.60631.26636.59528</string> </value> <value> <string>1015.63148.58654.57634</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>1709288499.16</float> <float>1713426942.44</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -6,6 +6,7 @@ var FixedWingDroneAPI = /** @class */ (function () { ...@@ -6,6 +6,7 @@ var FixedWingDroneAPI = /** @class */ (function () {
"use strict"; "use strict";
var DEFAULT_SPEED = 16, var DEFAULT_SPEED = 16,
PARACHUTE_SPEED = 8,
EARTH_GRAVITY = 9.81, EARTH_GRAVITY = 9.81,
LOITER_LIMIT = 30, LOITER_LIMIT = 30,
MAX_ACCELERATION = 6, MAX_ACCELERATION = 6,
...@@ -48,7 +49,7 @@ var FixedWingDroneAPI = /** @class */ (function () { ...@@ -48,7 +49,7 @@ var FixedWingDroneAPI = /** @class */ (function () {
throw new Error('max acceleration must be superior to 0'); throw new Error('max acceleration must be superior to 0');
} }
drone._minSpeed = this.getMinSpeed(); drone._minSpeed = this.getMinSpeed();
if (drone._minSpeed <= 0) { if (drone._minSpeed < 0) {
throw new Error('min speed must be superior to 0'); throw new Error('min speed must be superior to 0');
} }
drone._maxSpeed = this.getMaxSpeed(); drone._maxSpeed = this.getMaxSpeed();
...@@ -97,9 +98,13 @@ var FixedWingDroneAPI = /** @class */ (function () { ...@@ -97,9 +98,13 @@ var FixedWingDroneAPI = /** @class */ (function () {
/* /*
** Function called on every drone update, right before onUpdate AI script ** Function called on every drone update, right before onUpdate AI script
*/ */
FixedWingDroneAPI.prototype.internal_update = function (context, delta_time) { FixedWingDroneAPI.prototype.internal_position_update = function (context, delta_time) {
if (context.position.z > 0) {
this._updateSpeed(context, delta_time); this._updateSpeed(context, delta_time);
this._updatePosition(context, delta_time); this._updatePosition(context, delta_time);
} else {
context.setDirection(0, 0, 0);
}
context._controlMesh.computeWorldMatrix(true); context._controlMesh.computeWorldMatrix(true);
context._mesh.computeWorldMatrix(true); context._mesh.computeWorldMatrix(true);
...@@ -107,7 +112,7 @@ var FixedWingDroneAPI = /** @class */ (function () { ...@@ -107,7 +112,7 @@ var FixedWingDroneAPI = /** @class */ (function () {
/* /*
** Function called on every drone update, right after onUpdate AI script ** Function called on every drone update, right after onUpdate AI script
*/ */
FixedWingDroneAPI.prototype.internal_post_update = function (drone) { FixedWingDroneAPI.prototype.internal_info_update = function (drone) {
var _this = this, drone_position = drone.getCurrentPosition(), drone_info; var _this = this, drone_position = drone.getCurrentPosition(), drone_info;
/*if (_this._start_altitude > 0) { //TODO move start_altitude here /*if (_this._start_altitude > 0) { //TODO move start_altitude here
_this.reachAltitude(drone); _this.reachAltitude(drone);
...@@ -486,8 +491,8 @@ var FixedWingDroneAPI = /** @class */ (function () { ...@@ -486,8 +491,8 @@ var FixedWingDroneAPI = /** @class */ (function () {
function (altitude_diff, max_climb_rate, speed, max_pitch) { function (altitude_diff, max_climb_rate, speed, max_pitch) {
var maxVerticalSpeed = var maxVerticalSpeed =
Math.min(altitude_diff, Math.min(max_climb_rate, speed)); Math.min(altitude_diff, Math.min(max_climb_rate, speed));
return (this._toDeg(Math.asin(maxVerticalSpeed / speed)) > max_pitch) ? return (this._toDeg(Math.asin(maxVerticalSpeed / speed)) > max_pitch)
speed * Math.sin(this._toRad(max_pitch)) ? speed * Math.sin(this._toRad(max_pitch))
: maxVerticalSpeed; : maxVerticalSpeed;
}; };
FixedWingDroneAPI.prototype._toRad = function (angle) { FixedWingDroneAPI.prototype._toRad = function (angle) {
...@@ -511,11 +516,16 @@ var FixedWingDroneAPI = /** @class */ (function () { ...@@ -511,11 +516,16 @@ var FixedWingDroneAPI = /** @class */ (function () {
}; };
FixedWingDroneAPI.prototype.land = function (drone) { FixedWingDroneAPI.prototype.land = function (drone) {
var drone_pos = drone.getCurrentPosition(); var drone_pos = drone.getCurrentPosition();
drone.setTargetCoordinates( this._flight_parameters.drone.minSpeed = 0;
drone._speed = 0;
drone._acceleration = EARTH_GRAVITY;
this._flight_parameters.drone.maxSinkRate = PARACHUTE_SPEED;
this._flight_parameters.drone.minPitchAngle = -90;
drone._internal_setTargetCoordinates(
drone_pos.latitude, drone_pos.latitude,
drone_pos.longitude, drone_pos.longitude,
0, -PARACHUTE_SPEED,
drone.get3DSpeed() PARACHUTE_SPEED
); );
this._is_ready_to_fly = false; this._is_ready_to_fly = false;
this._is_landing = true; this._is_landing = true;
...@@ -538,6 +548,9 @@ var FixedWingDroneAPI = /** @class */ (function () { ...@@ -538,6 +548,9 @@ var FixedWingDroneAPI = /** @class */ (function () {
FixedWingDroneAPI.prototype.getMaxHeight = function () { FixedWingDroneAPI.prototype.getMaxHeight = function () {
return 800; return 800;
}; };
FixedWingDroneAPI.prototype.getOnUpdateInterval = function () {
return this._flight_parameters.drone.onUpdateInterval;
};
FixedWingDroneAPI.prototype.getFlightParameters = function () { FixedWingDroneAPI.prototype.getFlightParameters = function () {
return this._flight_parameters; return this._flight_parameters;
}; };
......
...@@ -246,7 +246,7 @@ ...@@ -246,7 +246,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>1014.60733.7318.44953</string> </value> <value> <string>1015.64140.4755.42274</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>1709564488.61</float> <float>1713430403.75</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -6,6 +6,56 @@ var GAMEPARAMETERS = {}, TEAM_USER = "user", TEAM_ENEMY = "enemy"; ...@@ -6,6 +6,56 @@ var GAMEPARAMETERS = {}, TEAM_USER = "user", TEAM_ENEMY = "enemy";
//for DEBUG/TEST mode //for DEBUG/TEST mode
var baseLogFunction = console.log, console_log = ""; var baseLogFunction = console.log, console_log = "";
function spawnDrone(spawnDrone_x, spawnDrone_y, spawnDrone_z, spawnDrone_index,
spawnDrone_drone_info, spawnDrone_api, spawnDrone_team,
spawnDrone_scene, spawnDrone_droneList_user,
spawnDrone_droneList_enemy) {
"use strict";
var default_drone_AI = spawnDrone_api.getDroneAI(), spawnDrone_code,
code_eval;
if (default_drone_AI) {
spawnDrone_code = default_drone_AI;
} else {
spawnDrone_code = spawnDrone_drone_info.script_content;
}
if (!spawnDrone_code.includes("me.onStart")) {
spawnDrone_code = "me.onStart = function () { me.exit(); };";
}
code_eval = "let spawnDrone_drone = new DroneManager(spawnDrone_scene, " +
spawnDrone_index + ', spawnDrone_api, spawnDrone_team);' +
"let droneMe = function(NativeDate, me, Math, window, DroneManager," +
" GameManager, FixedWingDroneAPI, EnemyDroneAPI, BABYLON, " +
"GAMEPARAMETERS) {" +
"Date.now = function () {" +
"return me._API._gameManager.getCurrentTime();}; " +
"function Date() {if (!(this instanceof Date)) " +
"{throw new Error('Missing new operator');} " +
"if (arguments.length === 0) {return new NativeDate(Date.now());} " +
"else {return new NativeDate(...arguments);}}";
// Simple desactivation of direct access of all globals
// It is still accessible in reality, but it will me more visible
// if people really access them
if (spawnDrone_x !== null && spawnDrone_y !== null && spawnDrone_z !== null) {
code_eval += "me.setStartingPosition(" + spawnDrone_x + ", "
+ spawnDrone_y + ", " + spawnDrone_z + ");";
}
//base = code_eval;
code_eval +=
spawnDrone_code + "}; droneMe(Date, spawnDrone_drone, Math, {});";
//base +=
// "};spawnDrone_droneList_" + spawnDrone_team + ".push(spawnDrone_drone)";
code_eval +=
"spawnDrone_droneList_" + spawnDrone_team + ".push(spawnDrone_drone)";
/*jslint evil: true*/
eval(code_eval);
/*jslint evil: false*/
/*try {
eval(code_eval);
} catch (error) {
eval(base);
}*/
}
/******************************* DRONE MANAGER ********************************/ /******************************* DRONE MANAGER ********************************/
var DroneManager = /** @class */ (function () { var DroneManager = /** @class */ (function () {
"use strict"; "use strict";
...@@ -27,6 +77,7 @@ var DroneManager = /** @class */ (function () { ...@@ -27,6 +77,7 @@ var DroneManager = /** @class */ (function () {
this._maxClimbRate = 0; this._maxClimbRate = 0;
this._maxCommandFrequency = 0; this._maxCommandFrequency = 0;
this._last_command_timestamp = 0; this._last_command_timestamp = 0;
this._last_onUpdate_timestamp = 0;
this._speed = 0; this._speed = 0;
this._acceleration = 0; this._acceleration = 0;
this._direction = new BABYLON.Vector3(0, 0, 1); // North this._direction = new BABYLON.Vector3(0, 0, 1); // North
...@@ -135,29 +186,39 @@ var DroneManager = /** @class */ (function () { ...@@ -135,29 +186,39 @@ var DroneManager = /** @class */ (function () {
this._canPlay = true; this._canPlay = true;
this._canCommunicate = true; this._canCommunicate = true;
try { try {
return this.onStart(this._API._gameManager._game_duration); return this.onStart(this._API._gameManager._start_time);
} catch (error) { } catch (error) {
console.warn('Drone crashed on start due to error:', error); console.warn('Drone crashed on start due to error:', error);
this._internal_crash(error); this._internal_crash(error);
} }
}; };
DroneManager.prototype._callSetTargetCommand =
function (latitude, longitude, altitude, speed, radius) {
var current_time = this._API._gameManager.getCurrentTime();
if (!this.isReadyToFly()) {
return;
}
if (current_time - this._last_command_timestamp
< 1000 / this._API.getMaxCommandFrequency()) {
this._internal_crash(new Error('Minimum interval between commands is ' +
1000 / this._API.getMaxCommandFrequency() + ' milliseconds'));
}
this._internal_setTargetCoordinates(latitude, longitude, altitude, speed,
radius);
this._last_command_timestamp = current_time;
};
/** /**
* Set a target point to move * Set a target point to move
*/ */
DroneManager.prototype.setTargetCoordinates = DroneManager.prototype.setTargetCoordinates =
function (latitude, longitude, altitude, speed) { function (latitude, longitude, altitude, speed) {
this._internal_setTargetCoordinates(latitude, longitude, altitude, speed); this._callSetTargetCommand(latitude, longitude, altitude, speed);
}; };
DroneManager.prototype._internal_setTargetCoordinates = DroneManager.prototype._internal_setTargetCoordinates =
function (latitude, longitude, altitude, speed, radius) { function (latitude, longitude, altitude, speed, radius) {
if (!this._canPlay || !this.isReadyToFly()) { if (!this._canPlay) {
return; return;
} }
if (this._API._gameManager._game_duration - this._last_command_timestamp
< 1000 / this._API.getMaxCommandFrequency()) {
this._internal_crash(new Error('Minimum interval between commands is ' +
1000 / this._API.getMaxCommandFrequency() + ' milliseconds'));
}
//each drone API process coordinates on its needs //each drone API process coordinates on its needs
//e.g. fixedwing drone converts real geo-coordinates to virtual x-y //e.g. fixedwing drone converts real geo-coordinates to virtual x-y
this._targetCoordinates = this._targetCoordinates =
...@@ -168,7 +229,6 @@ var DroneManager = /** @class */ (function () { ...@@ -168,7 +229,6 @@ var DroneManager = /** @class */ (function () {
speed, speed,
radius radius
); );
this._last_command_timestamp = this._API._gameManager._game_duration;
}; };
DroneManager.prototype.getDroneDict = function () { DroneManager.prototype.getDroneDict = function () {
return this._API._drone_dict_list; return this._API._drone_dict_list;
...@@ -184,15 +244,29 @@ var DroneManager = /** @class */ (function () { ...@@ -184,15 +244,29 @@ var DroneManager = /** @class */ (function () {
return; return;
}; };
DroneManager.prototype.internal_update = function (delta_time) { DroneManager.prototype.internal_update = function (delta_time) {
var context = this, milliseconds; var context = this,
current_time = this._API._gameManager.getCurrentTime(),
onUpdate_interval = this._API.getOnUpdateInterval(),
onUpdate_start;
if (this._controlMesh) { if (this._controlMesh) {
context._API.internal_update(context, delta_time); context._API.internal_position_update(context, delta_time);
if (context._canUpdate) { if (context._canUpdate &&
current_time - this._last_onUpdate_timestamp >= onUpdate_interval) {
context._canUpdate = false; context._canUpdate = false;
return new RSVP.Queue() return new RSVP.Queue()
.push(function () { .push(function () {
milliseconds = Math.floor(context._API._gameManager._game_duration); onUpdate_start = Date.now();
return context.onUpdate(milliseconds); context._last_onUpdate_timestamp = current_time;
context.onUpdate(current_time);
if (onUpdate_interval > 0 &&
Date.now() - onUpdate_start > onUpdate_interval) {
throw new Error('onUpdate execution took ' +
(Date.now() - onUpdate_start) +
' milliseconds but loop interval is only ' +
onUpdate_interval +
' milliseconds');
}
return;
}) })
.push(function () { .push(function () {
context._canUpdate = true; context._canUpdate = true;
...@@ -201,7 +275,7 @@ var DroneManager = /** @class */ (function () { ...@@ -201,7 +275,7 @@ var DroneManager = /** @class */ (function () {
context._internal_crash(error); context._internal_crash(error);
}) })
.push(function () { .push(function () {
context._API.internal_post_update(context); context._API.internal_info_update(context);
}) })
.push(undefined, function (error) { .push(undefined, function (error) {
console.warn('Drone crashed on update due to error:', error); console.warn('Drone crashed on update due to error:', error);
...@@ -305,7 +379,7 @@ var DroneManager = /** @class */ (function () { ...@@ -305,7 +379,7 @@ var DroneManager = /** @class */ (function () {
this._controlMesh.position.z, this._controlMesh.position.z,
this._controlMesh.position.y this._controlMesh.position.y
); );
position.timestamp = this._API._gameManager._game_duration; position.timestamp = this._API._gameManager.getCurrentTime();
//Backward compatibility sanitation //Backward compatibility sanitation
position.x = position.latitude; position.x = position.latitude;
position.y = position.longitude; position.y = position.longitude;
...@@ -319,13 +393,7 @@ var DroneManager = /** @class */ (function () { ...@@ -319,13 +393,7 @@ var DroneManager = /** @class */ (function () {
*/ */
DroneManager.prototype.loiter = DroneManager.prototype.loiter =
function (latitude, longitude, altitude, radius, speed) { function (latitude, longitude, altitude, radius, speed) {
this._internal_setTargetCoordinates( this._callSetTargetCommand(latitude, longitude, altitude, speed, radius);
latitude,
longitude,
altitude,
speed,
radius
);
}; };
DroneManager.prototype.getFlightParameters = function () { DroneManager.prototype.getFlightParameters = function () {
if (this._API.getFlightParameters) { if (this._API.getFlightParameters) {
...@@ -333,6 +401,9 @@ var DroneManager = /** @class */ (function () { ...@@ -333,6 +401,9 @@ var DroneManager = /** @class */ (function () {
} }
return null; return null;
}; };
DroneManager.prototype.getMaxCommandFrequency = function () {
return this._API.getMaxCommandFrequency();
};
DroneManager.prototype.getYaw = function () { DroneManager.prototype.getYaw = function () {
if (this._API.getYaw !== undefined) { if (this._API.getYaw !== undefined) {
return this._API.getYaw(this); return this._API.getYaw(this);
...@@ -358,7 +429,9 @@ var DroneManager = /** @class */ (function () { ...@@ -358,7 +429,9 @@ var DroneManager = /** @class */ (function () {
return this._API.takeOff(); return this._API.takeOff();
}; };
DroneManager.prototype.land = function () { DroneManager.prototype.land = function () {
if (!this.isLanding()) {
return this._API.land(this); return this._API.land(this);
}
}; };
DroneManager.prototype.exit = function () { DroneManager.prototype.exit = function () {
return this._internal_crash(); return this._internal_crash();
...@@ -916,7 +989,6 @@ var GameManager = /** @class */ (function () { ...@@ -916,7 +989,6 @@ var GameManager = /** @class */ (function () {
this._droneList.forEach(function (drone) { this._droneList.forEach(function (drone) {
queue.push(function () { queue.push(function () {
drone._tick += 1;
if (drone.can_play) { if (drone.can_play) {
if (drone.getCurrentPosition().altitude <= 0) { if (drone.getCurrentPosition().altitude <= 0) {
if (!drone.isLanding()) { if (!drone.isLanding()) {
...@@ -976,7 +1048,8 @@ var GameManager = /** @class */ (function () { ...@@ -976,7 +1048,8 @@ var GameManager = /** @class */ (function () {
this._game_duration += delta_time; this._game_duration += delta_time;
var color, drone_position, game_manager = this, geo_coordinates, var color, drone_position, game_manager = this, geo_coordinates,
log_count, map_info, map_manager, material, position_obj, log_count, map_info, map_manager, material, position_obj,
seconds = Math.floor(this._game_duration / 1000), trace_objects; current_time = this.getCurrentTime(),
seconds = Math.floor(current_time / 1000), trace_objects;
if (GAMEPARAMETERS.log_drone_flight || GAMEPARAMETERS.draw_flight_path) { if (GAMEPARAMETERS.log_drone_flight || GAMEPARAMETERS.draw_flight_path) {
this._droneList_user.forEach(function (drone, index) { this._droneList_user.forEach(function (drone, index) {
...@@ -995,7 +1068,7 @@ var GameManager = /** @class */ (function () { ...@@ -995,7 +1068,7 @@ var GameManager = /** @class */ (function () {
drone_position.z drone_position.z
); );
game_manager._flight_log[index].push([ game_manager._flight_log[index].push([
game_manager._game_duration, geo_coordinates.latitude, current_time, geo_coordinates.latitude,
geo_coordinates.longitude, geo_coordinates.longitude,
map_info.start_AMSL + drone_position.z, map_info.start_AMSL + drone_position.z,
drone_position.z, drone.getYaw(), drone.getSpeed(), drone_position.z, drone.getYaw(), drone.getSpeed(),
...@@ -1043,8 +1116,7 @@ var GameManager = /** @class */ (function () { ...@@ -1043,8 +1116,7 @@ var GameManager = /** @class */ (function () {
}; };
GameManager.prototype._timeOut = function () { GameManager.prototype._timeOut = function () {
var seconds = Math.floor(this._game_duration / 1000); return this._totalTime - this._game_duration <= 0;
return this._totalTime - seconds <= 0;
}; };
GameManager.prototype._allDronesFinished = function () { GameManager.prototype._allDronesFinished = function () {
...@@ -1226,20 +1298,19 @@ var GameManager = /** @class */ (function () { ...@@ -1226,20 +1298,19 @@ var GameManager = /** @class */ (function () {
_this.ongoing_update_promise = null; _this.ongoing_update_promise = null;
_this.finish_deferred = RSVP.defer(); _this.finish_deferred = RSVP.defer();
console.log("Simulation started."); console.log("Simulation started.");
this._game_duration = Date.now(); this._start_time = Date.now();
this._totalTime = GAMEPARAMETERS.gameTime + this._game_duration; this._game_duration = 0;
this._totalTime = GAMEPARAMETERS.gameTime * 1000;
return new RSVP.Queue() return new RSVP.Queue()
.push(function () { .push(function () {
promise_list = []; promise_list = [];
_this._droneList_user.forEach(function (drone) { _this._droneList_user.forEach(function (drone) {
drone._tick = 0;
promise_list.push(drone.internal_start()); promise_list.push(drone.internal_start());
}); });
start_msg = GAMEPARAMETERS.operator_init_msg; start_msg = GAMEPARAMETERS.operator_init_msg;
promise_list.push(_this._droneList_user[0].sendMsg(start_msg)); promise_list.push(_this._droneList_user[0].sendMsg(start_msg));
_this._droneList_enemy.forEach(function (drone) { _this._droneList_enemy.forEach(function (drone) {
drone._tick = 0;
promise_list.push(drone.internal_start()); promise_list.push(drone.internal_start());
}); });
return RSVP.all(promise_list); return RSVP.all(promise_list);
...@@ -1310,47 +1381,6 @@ var GameManager = /** @class */ (function () { ...@@ -1310,47 +1381,6 @@ var GameManager = /** @class */ (function () {
} }
return false; return false;
} }
function spawnDrone(x, y, z, index, drone_info, api, team) {
var default_drone_AI = api.getDroneAI(), code, code_eval;
if (default_drone_AI) {
code = default_drone_AI;
} else {
code = drone_info.script_content;
}
if (!code.includes("me.onStart")) {
code = "me.onStart = function () { me.exit(); };";
}
code_eval = "let drone = new DroneManager(ctx._scene, " +
index + ', api, team);' +
"let droneMe = function(NativeDate, me, Math, window, DroneManager," +
" GameManager, FixedWingDroneAPI, EnemyDroneAPI, BABYLON, " +
"GAMEPARAMETERS) {" +
"var start_time = (new Date(2070, 0, 0, 0, 0, 0, 0)).getTime();" +
"Date.now = function () {" +
"return start_time + drone._tick * 1000/60;}; " +
"function Date() {if (!(this instanceof Date)) " +
"{throw new Error('Missing new operator');} " +
"if (arguments.length === 0) {return new NativeDate(Date.now());} " +
"else {return new NativeDate(...arguments);}}";
// Simple desactivation of direct access of all globals
// It is still accessible in reality, but it will me more visible
// if people really access them
if (x !== null && y !== null && z !== null) {
code_eval += "me.setStartingPosition(" + x + ", " + y + ", " + z + ");";
}
//base = code_eval;
code_eval += code + "}; droneMe(Date, drone, Math, {});";
//base += "};ctx._droneList_" + team + ".push(drone)";
code_eval += "ctx._droneList_" + team + ".push(drone)";
/*jslint evil: true*/
eval(code_eval);
/*jslint evil: false*/
/*try {
eval(code_eval);
} catch (error) {
eval(base);
}*/
}
function randomSpherePoint(x0, y0, z0, rx0, ry0, rz0) { function randomSpherePoint(x0, y0, z0, rx0, ry0, rz0) {
var u = Math.random(), v = Math.random(), var u = Math.random(), v = Math.random(),
rx = Math.random() * rx0, ry = Math.random() * ry0, rx = Math.random() * rx0, ry = Math.random() * ry0,
...@@ -1384,11 +1414,16 @@ var GameManager = /** @class */ (function () { ...@@ -1384,11 +1414,16 @@ var GameManager = /** @class */ (function () {
i + id_offset i + id_offset
); );
spawnDrone(position.x, position.y, position.z, i + id_offset, spawnDrone(position.x, position.y, position.z, i + id_offset,
drone_list[i], api, team); drone_list[i], api, team, ctx._scene, ctx._droneList_user,
ctx._droneList_enemy);
} }
} }
}; };
GameManager.prototype.getCurrentTime = function () {
return this._start_time + this._game_duration;
};
return GameManager; return GameManager;
}()); }());
......
...@@ -246,7 +246,7 @@ ...@@ -246,7 +246,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>1014.65026.25145.27272</string> </value> <value> <string>1016.21978.22579.46609</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>1709560433.33</float> <float>1714742387.62</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -381,6 +381,19 @@ ...@@ -381,6 +381,19 @@
<div class="line"></div> <div class="line"></div>
<!-- getMaxCommandFrequency -->
<h4 class="item-name" id="getMaxCommandFrequency"><span>getMaxCommandFrequency</span><span>: void</span></h4>
<p class="item-descr">Get maximum frequency in hertz at which direction commands (setTargetCoordinates and loiter) can be called.</p>
<div>
<h5 class="item-param-1">Example</h5>
</div>
<p class="item-param-1">me.getMaxCommandFrequency();<br>
</p>
<div class="line"></div>
<!-- takeOff --> <!-- takeOff -->
<h4 class="item-name" id="takeOff"><span>takeOff</span><span>: void</span></h4> <h4 class="item-name" id="takeOff"><span>takeOff</span><span>: void</span></h4>
<p class="item-descr">Trigger drone's takeoff (has only effect on multicopters as fixed wings drones need to take off manually).</p> <p class="item-descr">Trigger drone's takeoff (has only effect on multicopters as fixed wings drones need to take off manually).</p>
......
...@@ -244,7 +244,7 @@ ...@@ -244,7 +244,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>1014.65292.62763.3464</string> </value> <value> <string>1015.13928.44848.25668</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>1709564153.67</float> <float>1710867839.5</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -185,6 +185,7 @@ var OperatorAPI = /** @class */ (function () { ...@@ -185,6 +185,7 @@ var OperatorAPI = /** @class */ (function () {
DRAW = true, DRAW = true,
LOG = true, LOG = true,
LOG_TIME = 1662.7915426540285, LOG_TIME = 1662.7915426540285,
ONUPDATE_INTERVAL = 100,
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',
...@@ -566,6 +567,17 @@ var OperatorAPI = /** @class */ (function () { ...@@ -566,6 +567,17 @@ var OperatorAPI = /** @class */ (function () {
"hidden": 0, "hidden": 0,
"type": "IntegerField" "type": "IntegerField"
}, },
"my_onupdate_interval": {
"description": "Minimum interval (in milliseconds) between 2 executions of onUpdate function as well as periodicity to send telemetry to the swarm",
"title": "OnUpdate interval",
"default": gadget.state.onupdate_interval,
"css_class": "",
"required": 1,
"editable": 1,
"key": "onupdate_interval",
"hidden": 0,
"type": "IntegerField"
},
"my_drone_min_speed": { "my_drone_min_speed": {
"description": "", "description": "",
"title": "Drone min speed", "title": "Drone min speed",
...@@ -708,7 +720,7 @@ var OperatorAPI = /** @class */ (function () { ...@@ -708,7 +720,7 @@ var OperatorAPI = /** @class */ (function () {
form_definition: { form_definition: {
group_list: [[ group_list: [[
"left", "left",
[["my_simulation_speed"], ["my_simulation_time"], [["my_simulation_speed"], ["my_simulation_time"], ["my_onupdate_interval"],
["my_number_of_drones"], ["my_map_seed"]] ["my_number_of_drones"], ["my_map_seed"]]
], [ ], [
"right", "right",
...@@ -845,6 +857,7 @@ var OperatorAPI = /** @class */ (function () { ...@@ -845,6 +857,7 @@ var OperatorAPI = /** @class */ (function () {
"maxSinkRate": parseFloat(gadget.state.drone_max_sink_rate), "maxSinkRate": parseFloat(gadget.state.drone_max_sink_rate),
"maxClimbRate": parseFloat(gadget.state.drone_max_climb_rate), "maxClimbRate": parseFloat(gadget.state.drone_max_climb_rate),
"maxCommandFrequency": parseFloat(gadget.state.drone_max_command_frequency), "maxCommandFrequency": parseFloat(gadget.state.drone_max_command_frequency),
"onUpdateInterval": parseInt(gadget.state.onupdate_interval, 10),
"list": drone_list "list": drone_list
}, },
"gameTime": parseInt(gadget.state.simulation_time, 10), "gameTime": parseInt(gadget.state.simulation_time, 10),
...@@ -970,6 +983,7 @@ var OperatorAPI = /** @class */ (function () { ...@@ -970,6 +983,7 @@ var OperatorAPI = /** @class */ (function () {
drone_max_speed: MAX_SPEED, drone_max_speed: MAX_SPEED,
drone_speed: DEFAULT_SPEED, drone_speed: DEFAULT_SPEED,
drone_min_speed: MIN_SPEED, drone_min_speed: MIN_SPEED,
onupdate_interval: ONUPDATE_INTERVAL,
simulation_time: SIMULATION_TIME, simulation_time: SIMULATION_TIME,
simulation_speed: SIMULATION_SPEED, simulation_speed: SIMULATION_SPEED,
operator_init_msg: {}, operator_init_msg: {},
......
...@@ -246,7 +246,7 @@ ...@@ -246,7 +246,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>1014.48194.32365.65399</string> </value> <value> <string>1016.21921.52144.47906</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>1708709921.07</float> <float>1714738877.83</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -3,8 +3,10 @@ ...@@ -3,8 +3,10 @@
(function (window, rJS, domsugar, document) { (function (window, rJS, domsugar, document) {
"use strict"; "use strict";
var SIMULATION_SPEED = 10, var SIMULATION_SPEED = 1,
SIMULATION_TIME = 270, LOOP_INTERVAL = 1000 / 60,
ON_UPDATE_INTERVAL = LOOP_INTERVAL,
SIMULATION_TIME = LOOP_INTERVAL / 1000,
MIN_LAT = 45.6364, MIN_LAT = 45.6364,
MAX_LAT = 45.65, MAX_LAT = 45.65,
MIN_LON = 14.2521, MIN_LON = 14.2521,
...@@ -74,9 +76,10 @@ ...@@ -74,9 +76,10 @@
' me.getCurrentPosition().longitude\n' + ' me.getCurrentPosition().longitude\n' +
' ).toFixed(8),\n' + ' ).toFixed(8),\n' +
' time_interval = timestamp - me.start_time,\n' + ' time_interval = timestamp - me.start_time,\n' +
' expected_interval = 1000 / 60,\n' + ' expected_interval = ' + LOOP_INTERVAL + ',\n' +
' expectedDistance = (me.getSpeed() * expected_interval / 1000).toFixed(8);\n' + ' expectedDistance = (me.getSpeed() * expected_interval / 1000).toFixed(8);\n' +
' assert(time_interval, Math.floor(expected_interval), "Timestamp");\n' + ' assert(time_interval.toFixed(4), expected_interval.toFixed(4), "Timestamp");\n' +
' assert(Date.now(), timestamp, "Date");\n' +
' assert(realDistance, expectedDistance, "Distance");\n' + ' assert(realDistance, expectedDistance, "Distance");\n' +
' current_position.latitude = current_position.latitude.toFixed(7);\n' + ' current_position.latitude = current_position.latitude.toFixed(7);\n' +
' compare(current_position, {\n' + ' compare(current_position, {\n' +
...@@ -84,7 +87,6 @@ ...@@ -84,7 +87,6 @@
' longitude: me.initialPosition.longitude,\n' + ' longitude: me.initialPosition.longitude,\n' +
' altitude: me.initialPosition.altitude\n' + ' altitude: me.initialPosition.altitude\n' +
' });\n' + ' });\n' +
' me.exit(me.land());\n' +
'};', '};',
DRAW = true, DRAW = true,
LOG = true, LOG = true,
...@@ -120,19 +122,19 @@ ...@@ -120,19 +122,19 @@
"script_content": DEFAULT_SCRIPT_CONTENT}; "script_content": DEFAULT_SCRIPT_CONTENT};
} }
map_json = { map_json = {
"height": parseInt(map_height, 10), "height": map_height,
"start_AMSL": parseFloat(start_AMSL), "start_AMSL": start_AMSL,
"min_lat": parseFloat(MIN_LAT), "min_lat": MIN_LAT,
"max_lat": parseFloat(MAX_LAT), "max_lat": MAX_LAT,
"min_lon": parseFloat(MIN_LON), "min_lon": MIN_LON,
"max_lon": parseFloat(MAX_LON), "max_lon": MAX_LON,
"flag_list": [], "flag_list": [],
"obstacle_list" : [], "obstacle_list" : [],
"enemy_list" : [], "enemy_list" : [],
"initial_position": { "initial_position": {
"longitude": parseFloat(INIT_LON), "longitude": INIT_LON,
"latitude": parseFloat(INIT_LAT), "latitude": INIT_LAT,
"altitude": parseFloat(INIT_ALT) "altitude": INIT_ALT
} }
}; };
operator_init_msg = { operator_init_msg = {
...@@ -142,20 +144,21 @@ ...@@ -142,20 +144,21 @@
game_parameters_json = { game_parameters_json = {
"debug_test_mode": true, "debug_test_mode": true,
"drone": { "drone": {
"maxAcceleration": parseInt(MAX_ACCELERATION, 10), "maxAcceleration": MAX_ACCELERATION,
"maxDeceleration": parseInt(MAX_DECELERATION, 10), "maxDeceleration": MAX_DECELERATION,
"minSpeed": parseInt(MIN_SPEED, 10), "minSpeed": MIN_SPEED,
"speed": parseFloat(DEFAULT_SPEED), "speed": DEFAULT_SPEED,
"maxSpeed": parseInt(MAX_SPEED, 10), "maxSpeed": MAX_SPEED,
"maxRoll": parseFloat(MAX_ROLL), "maxRoll": MAX_ROLL,
"minPitchAngle": parseFloat(MIN_PITCH), "minPitchAngle": MIN_PITCH,
"maxPitchAngle": parseFloat(MAX_PITCH), "maxPitchAngle": MAX_PITCH,
"maxSinkRate": parseFloat(MAX_SINK_RATE), "maxSinkRate": MAX_SINK_RATE,
"maxClimbRate": parseFloat(MAX_CLIMB_RATE), "maxClimbRate": MAX_CLIMB_RATE,
"onUpdateInterval": ON_UPDATE_INTERVAL,
"list": DRONE_LIST "list": DRONE_LIST
}, },
"gameTime": parseInt(SIMULATION_TIME, 10), "gameTime": SIMULATION_TIME,
"simulation_speed": parseInt(SIMULATION_SPEED, 10), "simulation_speed": SIMULATION_SPEED,
"latency": { "latency": {
"information": 0, "information": 0,
"communication": 0 "communication": 0
...@@ -214,19 +217,24 @@ ...@@ -214,19 +217,24 @@
}) })
.push(function (result) { .push(function (result) {
var div = domsugar('div', { text: "CONSOLE LOG ENTRIES:" }), lines, var div = domsugar('div', { text: "CONSOLE LOG ENTRIES:" }), lines,
l, node; l, test_log_node = document.querySelector('.test_log');
document.querySelector('.container').parentNode.appendChild(div); document.querySelector('.container').parentNode.appendChild(div);
function createLogNode(message) { function appendToTestLog(test_log_node, message) {
var log_node = document.createElement("div"), var log_node = document.createElement("div"),
textNode = document.createTextNode(message); textNode = document.createTextNode(message);
log_node.appendChild(textNode); log_node.appendChild(textNode);
return log_node; test_log_node.appendChild(log_node);
} }
lines = result.console_log.split('\n'); lines = result.console_log.split('\n');
for (l = 0; l < lines.length; l += 1) { for (l = 0; l < lines.length; l += 1) {
node = createLogNode(lines[l]); if (lines[l] !== 'TIMEOUT!') {
document.querySelector('.test_log').appendChild(node); appendToTestLog(test_log_node, lines[l]);
} else {
appendToTestLog(test_log_node, 'Timeout: OK');
return;
} }
}
appendToTestLog(test_log_node, 'Timeout: FAILED');
}, function (error) { }, function (error) {
return gadget.notifySubmitted({message: "Error: " + error.message, return gadget.notifySubmitted({message: "Error: " + error.message,
status: 'error'}); status: 'error'});
......
...@@ -246,7 +246,7 @@ ...@@ -246,7 +246,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>1014.60680.20078.34286</string> </value> <value> <string>1015.64187.34381.50346</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>1709286290.59</float> <float>1713428877.4</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -80,7 +80,7 @@ var DroneLogAPI = /** @class */ (function () { ...@@ -80,7 +80,7 @@ var DroneLogAPI = /** @class */ (function () {
/* /*
** Function called on every drone update, right before onUpdate AI script ** Function called on every drone update, right before onUpdate AI script
*/ */
DroneLogAPI.prototype.internal_update = function (context, delta_time) { DroneLogAPI.prototype.internal_position_update = function (context, delta_time) {
var updateSpeed; var updateSpeed;
context._speed += context._acceleration * delta_time / 1000; context._speed += context._acceleration * delta_time / 1000;
if (context._speed > context._maxSpeed) { if (context._speed > context._maxSpeed) {
...@@ -104,7 +104,7 @@ var DroneLogAPI = /** @class */ (function () { ...@@ -104,7 +104,7 @@ var DroneLogAPI = /** @class */ (function () {
/* /*
** Function called on every drone update, right after onUpdate AI script ** Function called on every drone update, right after onUpdate AI script
*/ */
DroneLogAPI.prototype.internal_post_update = function (drone) { DroneLogAPI.prototype.internal_info_update = function (drone) {
return; return;
}; };
DroneLogAPI.prototype.internal_setTargetCoordinates = DroneLogAPI.prototype.internal_setTargetCoordinates =
...@@ -213,6 +213,9 @@ var DroneLogAPI = /** @class */ (function () { ...@@ -213,6 +213,9 @@ var DroneLogAPI = /** @class */ (function () {
DroneLogAPI.prototype.getMaxCommandFrequency = function () { DroneLogAPI.prototype.getMaxCommandFrequency = function () {
return Infinity; return Infinity;
}; };
DroneLogAPI.prototype.getOnUpdateInterval = function () {
return 0;
};
return DroneLogAPI; return DroneLogAPI;
}()); }());
\ No newline at end of file
...@@ -246,7 +246,7 @@ ...@@ -246,7 +246,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>1014.60631.26636.59528</string> </value> <value> <string>1015.64101.28159.26163</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>1709288518.39</float> <float>1713425784.77</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -7,6 +7,7 @@ var FixedWingDroneAPI = /** @class */ (function () { ...@@ -7,6 +7,7 @@ var FixedWingDroneAPI = /** @class */ (function () {
// var TAKEOFF_RADIUS = 60, // var TAKEOFF_RADIUS = 60,
var DEFAULT_SPEED = 16, var DEFAULT_SPEED = 16,
PARACHUTE_SPEED = 8,
EARTH_GRAVITY = 9.81, EARTH_GRAVITY = 9.81,
LOITER_LIMIT = 30, LOITER_LIMIT = 30,
MAX_ACCELERATION = 6, MAX_ACCELERATION = 6,
...@@ -52,7 +53,7 @@ var FixedWingDroneAPI = /** @class */ (function () { ...@@ -52,7 +53,7 @@ var FixedWingDroneAPI = /** @class */ (function () {
throw new Error('max acceleration must be superior to 0'); throw new Error('max acceleration must be superior to 0');
} }
drone._minSpeed = this.getMinSpeed(); drone._minSpeed = this.getMinSpeed();
if (drone._minSpeed <= 0) { if (drone._minSpeed < 0) {
throw new Error('min speed must be superior to 0'); throw new Error('min speed must be superior to 0');
} }
drone._maxSpeed = this.getMaxSpeed(); drone._maxSpeed = this.getMaxSpeed();
...@@ -101,7 +102,7 @@ var FixedWingDroneAPI = /** @class */ (function () { ...@@ -101,7 +102,7 @@ var FixedWingDroneAPI = /** @class */ (function () {
/* /*
** Function called on every drone update, right before onUpdate AI script ** Function called on every drone update, right before onUpdate AI script
*/ */
FixedWingDroneAPI.prototype.internal_update = function (context, delta_time) { FixedWingDroneAPI.prototype.internal_position_update = function (context, delta_time) {
this._updateSpeed(context, delta_time); this._updateSpeed(context, delta_time);
this._updatePosition(context, delta_time); this._updatePosition(context, delta_time);
...@@ -111,7 +112,7 @@ var FixedWingDroneAPI = /** @class */ (function () { ...@@ -111,7 +112,7 @@ var FixedWingDroneAPI = /** @class */ (function () {
/* /*
** Function called on every drone update, right after onUpdate AI script ** Function called on every drone update, right after onUpdate AI script
*/ */
FixedWingDroneAPI.prototype.internal_post_update = function (drone) { FixedWingDroneAPI.prototype.internal_info_update = function (drone) {
var _this = this, drone_position = drone.getCurrentPosition(), drone_info; var _this = this, drone_position = drone.getCurrentPosition(), drone_info;
/*if (_this._start_altitude > 0) { //TODO move start_altitude here /*if (_this._start_altitude > 0) { //TODO move start_altitude here
_this.reachAltitude(drone); _this.reachAltitude(drone);
...@@ -373,8 +374,6 @@ var FixedWingDroneAPI = /** @class */ (function () { ...@@ -373,8 +374,6 @@ var FixedWingDroneAPI = /** @class */ (function () {
var processed_coordinates = var processed_coordinates =
this._mapManager.convertToLocalCoordinates(lat, lon, z); this._mapManager.convertToLocalCoordinates(lat, lon, z);
processed_coordinates.z -= this._map_dict.start_AMSL; processed_coordinates.z -= this._map_dict.start_AMSL;
//this._last_altitude_point_reached = -1;
//this.takeoff_path = [];
return processed_coordinates; return processed_coordinates;
}; };
FixedWingDroneAPI.prototype.getCurrentPosition = function (x, y, z) { FixedWingDroneAPI.prototype.getCurrentPosition = function (x, y, z) {
...@@ -470,11 +469,16 @@ var FixedWingDroneAPI = /** @class */ (function () { ...@@ -470,11 +469,16 @@ var FixedWingDroneAPI = /** @class */ (function () {
}; };
FixedWingDroneAPI.prototype.land = function (drone) { FixedWingDroneAPI.prototype.land = function (drone) {
var drone_pos = drone.getCurrentPosition(); var drone_pos = drone.getCurrentPosition();
drone.setTargetCoordinates( this._flight_parameters.drone.minSpeed = 0;
drone._speed = 0;
drone._acceleration = EARTH_GRAVITY;
this._flight_parameters.drone.maxSinkRate = PARACHUTE_SPEED;
this._flight_parameters.drone.minPitchAngle = -90;
drone._internal_setTargetCoordinates(
drone_pos.latitude, drone_pos.latitude,
drone_pos.longitude, drone_pos.longitude,
0, 0,
drone.get3DSpeed() PARACHUTE_SPEED
); );
this._is_ready_to_fly = false; this._is_ready_to_fly = false;
this._is_landing = true; this._is_landing = true;
...@@ -497,6 +501,9 @@ var FixedWingDroneAPI = /** @class */ (function () { ...@@ -497,6 +501,9 @@ var FixedWingDroneAPI = /** @class */ (function () {
FixedWingDroneAPI.prototype.getMaxHeight = function () { FixedWingDroneAPI.prototype.getMaxHeight = function () {
return 800; return 800;
}; };
FixedWingDroneAPI.prototype.getOnUpdateInterval = function () {
return this._flight_parameters.drone.onUpdateInterval;
};
FixedWingDroneAPI.prototype.getFlightParameters = function () { FixedWingDroneAPI.prototype.getFlightParameters = function () {
return this._flight_parameters; return this._flight_parameters;
}; };
......
...@@ -240,7 +240,7 @@ ...@@ -240,7 +240,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>1014.60733.7318.44953</string> </value> <value> <string>1015.64203.48820.61559</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -260,7 +260,7 @@ ...@@ -260,7 +260,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1709562449.93</float> <float>1713429850.09</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -6,6 +6,50 @@ var GAMEPARAMETERS = {}; ...@@ -6,6 +6,50 @@ var GAMEPARAMETERS = {};
//for DEBUG/TEST mode //for DEBUG/TEST mode
var baseLogFunction = console.log, console_log = ""; var baseLogFunction = console.log, console_log = "";
function spawnDrone(spawnDrone_x, spawnDrone_y, spawnDrone_z, spawnDrone_index,
spawnDrone_drone_info, spawnDrone_api, spawnDrone_scene,
spawnDrone_droneList) {
"use strict";
var default_drone_AI = spawnDrone_api.getDroneAI(), spawnDrone_code,
spawnDrone_base, code_eval;
if (default_drone_AI) {
spawnDrone_code = default_drone_AI;
} else {
spawnDrone_code = spawnDrone_drone_info.script_content;
}
code_eval = "let spawnDrone_drone = new DroneManager(spawnDrone_scene, " +
spawnDrone_index + ', spawnDrone_api);' +
"let droneMe = function(NativeDate, me, Math, window, DroneManager," +
" GameManager, DroneLogAPI, FixedWingDroneAPI, BABYLON, " +
"GAMEPARAMETERS) {" +
"Date.now = function () {" +
"return me._API._gameManager.getCurrentTime();}; " +
"function Date() {if (!(this instanceof Date)) " +
"{throw new Error('Missing new operator');} " +
"if (arguments.length === 0) {return new NativeDate(Date.now());} " +
"else {return new NativeDate(...arguments);}}";
// Simple desactivation of direct access of all globals
// It is still accessible in reality, but it will me more visible
// if people really access them
if (spawnDrone_x !== null && spawnDrone_y !== null && spawnDrone_z !== null) {
code_eval += "me.setStartingPosition(" + spawnDrone_x + ", "
+ spawnDrone_y + ", " + spawnDrone_z + ");";
}
spawnDrone_base = code_eval;
code_eval +=
spawnDrone_code + "}; droneMe(Date, spawnDrone_drone, Math, {});";
spawnDrone_base += "};spawnDrone_droneList.push(spawnDrone_drone)";
code_eval += "spawnDrone_droneList.push(spawnDrone_drone)";
/*jslint evil: true*/
try {
eval(code_eval);
} catch (error) {
console.error(error);
eval(spawnDrone_base);
}
/*jslint evil: false*/
}
/******************************* DRONE MANAGER ********************************/ /******************************* DRONE MANAGER ********************************/
var DroneManager = /** @class */ (function () { var DroneManager = /** @class */ (function () {
"use strict"; "use strict";
...@@ -27,6 +71,7 @@ var DroneManager = /** @class */ (function () { ...@@ -27,6 +71,7 @@ var DroneManager = /** @class */ (function () {
this._maxClimbRate = 0; this._maxClimbRate = 0;
this._maxCommandFrequency = 0; this._maxCommandFrequency = 0;
this._last_command_timestamp = 0; this._last_command_timestamp = 0;
this._last_onUpdate_timestamp = 0;
this._speed = 0; this._speed = 0;
this._acceleration = 0; this._acceleration = 0;
this._direction = new BABYLON.Vector3(0, 0, 1); // North this._direction = new BABYLON.Vector3(0, 0, 1); // North
...@@ -124,29 +169,39 @@ var DroneManager = /** @class */ (function () { ...@@ -124,29 +169,39 @@ var DroneManager = /** @class */ (function () {
this._canCommunicate = true; this._canCommunicate = true;
this._targetCoordinates = initial_position; this._targetCoordinates = initial_position;
try { try {
return this.onStart(this._API._gameManager._game_duration); return this.onStart(this._API._gameManager._start_time);
} catch (error) { } catch (error) {
console.warn('Drone crashed on start due to error:', error); console.warn('Drone crashed on start due to error:', error);
this._internal_crash(error); this._internal_crash(error);
} }
}; };
DroneManager.prototype._callSetTargetCommand =
function (latitude, longitude, altitude, speed, radius) {
var current_time = this._API._gameManager.getCurrentTime();
if (!this.isReadyToFly()) {
return;
}
if (current_time - this._last_command_timestamp
< 1000 / this._API.getMaxCommandFrequency()) {
this._internal_crash(new Error('Minimum interval between commands is ' +
1000 / this._API.getMaxCommandFrequency() + ' milliseconds'));
}
this._internal_setTargetCoordinates(latitude, longitude, altitude, speed,
radius);
this._last_command_timestamp = current_time;
};
/** /**
* Set a target point to move * Set a target point to move
*/ */
DroneManager.prototype.setTargetCoordinates = DroneManager.prototype.setTargetCoordinates =
function (latitude, longitude, altitude, speed) { function (latitude, longitude, altitude, speed) {
this._internal_setTargetCoordinates(latitude, longitude, altitude, speed); this._callSetTargetCommand(latitude, longitude, altitude, speed);
}; };
DroneManager.prototype._internal_setTargetCoordinates = DroneManager.prototype._internal_setTargetCoordinates =
function (latitude, longitude, altitude, speed, radius) { function (latitude, longitude, altitude, speed, radius) {
if (!this._canPlay || !this.isReadyToFly()) { if (!this._canPlay) {
return; return;
} }
if (this._API._gameManager._game_duration - this._last_command_timestamp
< 1000 / this._API.getMaxCommandFrequency()) {
this._internal_crash(new Error('Minimum interval between commands is ' +
1000 / this._API.getMaxCommandFrequency() + ' milliseconds'));
}
//convert real geo-coordinates to virtual x-y coordinates //convert real geo-coordinates to virtual x-y coordinates
this._targetCoordinates = this._targetCoordinates =
this._API.processCoordinates(latitude, longitude, altitude); this._API.processCoordinates(latitude, longitude, altitude);
...@@ -156,17 +211,30 @@ var DroneManager = /** @class */ (function () { ...@@ -156,17 +211,30 @@ var DroneManager = /** @class */ (function () {
speed, speed,
radius radius
); );
this._last_command_timestamp = this._API._gameManager._game_duration;
}; };
DroneManager.prototype.internal_update = function (delta_time) { DroneManager.prototype.internal_update = function (delta_time) {
var context = this; var context = this,
current_time = this._API._gameManager.getCurrentTime(),
onUpdate_interval = this._API.getOnUpdateInterval(),
onUpdate_start;
if (this._controlMesh) { if (this._controlMesh) {
context._API.internal_update(context, delta_time); context._API.internal_position_update(context, delta_time);
if (context._canUpdate) { if (context._canUpdate &&
current_time - this._last_onUpdate_timestamp >= onUpdate_interval) {
context._canUpdate = false; context._canUpdate = false;
return new RSVP.Queue() return new RSVP.Queue()
.push(function () { .push(function () {
return context.onUpdate(context._API._gameManager._game_duration); onUpdate_start = Date.now();
context._last_onUpdate_timestamp = current_time;
context.onUpdate(current_time);
if (onUpdate_interval > 0 &&
Date.now() - onUpdate_start > onUpdate_interval) {
throw new Error('onUpdate execution took ' +
(Date.now() - onUpdate_start) +
' milliseconds but loop interval is only ' +
onUpdate_interval +
' milliseconds');
}
}) })
.push(function () { .push(function () {
context._canUpdate = true; context._canUpdate = true;
...@@ -175,7 +243,7 @@ var DroneManager = /** @class */ (function () { ...@@ -175,7 +243,7 @@ var DroneManager = /** @class */ (function () {
context._internal_crash(error); context._internal_crash(error);
}) })
.push(function () { .push(function () {
context._API.internal_post_update(context); context._API.internal_info_update(context);
}) })
.push(undefined, function (error) { .push(undefined, function (error) {
console.warn('Drone crashed on update due to error:', error); console.warn('Drone crashed on update due to error:', error);
...@@ -274,7 +342,7 @@ var DroneManager = /** @class */ (function () { ...@@ -274,7 +342,7 @@ var DroneManager = /** @class */ (function () {
this._controlMesh.position.z, this._controlMesh.position.z,
this._controlMesh.position.y this._controlMesh.position.y
); );
position.timestamp = this._API._gameManager._game_duration; position.timestamp = this._API._gameManager.getCurrentTime();
return position; return position;
} }
return null; return null;
...@@ -284,13 +352,7 @@ var DroneManager = /** @class */ (function () { ...@@ -284,13 +352,7 @@ var DroneManager = /** @class */ (function () {
*/ */
DroneManager.prototype.loiter = DroneManager.prototype.loiter =
function (latitude, longitude, altitude, radius, speed) { function (latitude, longitude, altitude, radius, speed) {
this._internal_setTargetCoordinates( this._callSetTargetCommand(latitude, longitude, altitude, speed, radius);
latitude,
longitude,
altitude,
speed,
radius
);
}; };
DroneManager.prototype.getFlightParameters = function () { DroneManager.prototype.getFlightParameters = function () {
if (this._API.getFlightParameters) { if (this._API.getFlightParameters) {
...@@ -298,6 +360,9 @@ var DroneManager = /** @class */ (function () { ...@@ -298,6 +360,9 @@ var DroneManager = /** @class */ (function () {
} }
return null; return null;
}; };
DroneManager.prototype.getMaxCommandFrequency = function () {
return this._API.getMaxCommandFrequency();
};
DroneManager.prototype.getYaw = function () { DroneManager.prototype.getYaw = function () {
return this._API.getYaw(this); return this._API.getYaw(this);
}; };
...@@ -314,7 +379,9 @@ var DroneManager = /** @class */ (function () { ...@@ -314,7 +379,9 @@ var DroneManager = /** @class */ (function () {
return this._API.takeOff(); return this._API.takeOff();
}; };
DroneManager.prototype.land = function () { DroneManager.prototype.land = function () {
if (!this.isLanding()) {
return this._API.land(this); return this._API.land(this);
}
}; };
DroneManager.prototype.exit = function () { DroneManager.prototype.exit = function () {
return this._internal_crash(); return this._internal_crash();
...@@ -659,7 +726,6 @@ var GameManager = /** @class */ (function () { ...@@ -659,7 +726,6 @@ var GameManager = /** @class */ (function () {
this._droneList.forEach(function (drone) { this._droneList.forEach(function (drone) {
queue.push(function () { queue.push(function () {
drone._tick += 1;
if (drone._API.isCollidable && drone.can_play) { if (drone._API.isCollidable && drone.can_play) {
if (drone.getCurrentPosition().altitude <= 0) { if (drone.getCurrentPosition().altitude <= 0) {
if (!drone.isLanding()) { if (!drone.isLanding()) {
...@@ -698,7 +764,8 @@ var GameManager = /** @class */ (function () { ...@@ -698,7 +764,8 @@ var GameManager = /** @class */ (function () {
this._game_duration += delta_time; this._game_duration += delta_time;
var color, drone_position, game_manager = this, geo_coordinates, var color, drone_position, game_manager = this, geo_coordinates,
log_count, map_info, map_manager, material, position_obj, log_count, map_info, map_manager, material, position_obj,
seconds = Math.floor(this._game_duration / 1000), trace_objects; current_time = this.getCurrentTime(),
seconds = Math.floor(current_time / 1000), trace_objects;
if (GAMEPARAMETERS.log_drone_flight || GAMEPARAMETERS.draw_flight_path) { if (GAMEPARAMETERS.log_drone_flight || GAMEPARAMETERS.draw_flight_path) {
this._droneList.forEach(function (drone, index) { this._droneList.forEach(function (drone, index) {
...@@ -717,7 +784,7 @@ var GameManager = /** @class */ (function () { ...@@ -717,7 +784,7 @@ var GameManager = /** @class */ (function () {
drone_position.z drone_position.z
); );
game_manager._flight_log[index].push([ game_manager._flight_log[index].push([
game_manager._game_duration, geo_coordinates.latitude, current_time, geo_coordinates.latitude,
geo_coordinates.longitude, geo_coordinates.longitude,
map_info.start_AMSL + drone_position.z, map_info.start_AMSL + drone_position.z,
drone_position.z, drone.getYaw(), drone.getSpeed(), drone_position.z, drone.getYaw(), drone.getSpeed(),
...@@ -763,8 +830,7 @@ var GameManager = /** @class */ (function () { ...@@ -763,8 +830,7 @@ var GameManager = /** @class */ (function () {
}; };
GameManager.prototype._timeOut = function () { GameManager.prototype._timeOut = function () {
var seconds = Math.floor(this._game_duration / 1000); return this._totalTime - this._game_duration <= 0;
return this._totalTime - seconds <= 0;
}; };
GameManager.prototype._allDronesFinished = function () { GameManager.prototype._allDronesFinished = function () {
...@@ -903,14 +969,14 @@ var GameManager = /** @class */ (function () { ...@@ -903,14 +969,14 @@ var GameManager = /** @class */ (function () {
_this.ongoing_update_promise = null; _this.ongoing_update_promise = null;
_this.finish_deferred = RSVP.defer(); _this.finish_deferred = RSVP.defer();
console.log("Simulation started."); console.log("Simulation started.");
this._game_duration = Date.now(); this._start_time = Date.now();
this._totalTime = GAMEPARAMETERS.gameTime + this._game_duration; this._game_duration = 0;
this._totalTime = GAMEPARAMETERS.gameTime * 1000;
return new RSVP.Queue() return new RSVP.Queue()
.push(function () { .push(function () {
promise_list = []; promise_list = [];
_this._droneList.forEach(function (drone) { _this._droneList.forEach(function (drone) {
drone._tick = 0;
promise_list.push(drone.internal_start( promise_list.push(drone.internal_start(
_this._mapManager.getMapInfo().initial_position _this._mapManager.getMapInfo().initial_position
)); ));
...@@ -980,44 +1046,6 @@ var GameManager = /** @class */ (function () { ...@@ -980,44 +1046,6 @@ var GameManager = /** @class */ (function () {
} }
return false; return false;
} }
function spawnDrone(x, y, z, index, drone_info, api) {
var default_drone_AI = api.getDroneAI(), code, base, code_eval;
if (default_drone_AI) {
code = default_drone_AI;
} else {
code = drone_info.script_content;
}
code_eval = "let drone = new DroneManager(ctx._scene, " +
index + ', api);' +
"let droneMe = function(NativeDate, me, Math, window, DroneManager," +
" GameManager, DroneLogAPI, FixedWingDroneAPI, BABYLON, " +
"GAMEPARAMETERS) {" +
"var start_time = (new Date(2070, 0, 0, 0, 0, 0, 0)).getTime();" +
"Date.now = function () {" +
"return start_time + drone._tick * 1000/60;}; " +
"function Date() {if (!(this instanceof Date)) " +
"{throw new Error('Missing new operator');} " +
"if (arguments.length === 0) {return new NativeDate(Date.now());} " +
"else {return new NativeDate(...arguments);}}";
// Simple desactivation of direct access of all globals
// It is still accessible in reality, but it will me more visible
// if people really access them
if (x !== null && y !== null && z !== null) {
code_eval += "me.setStartingPosition(" + x + ", " + y + ", " + z + ");";
}
base = code_eval;
code_eval += code + "}; droneMe(Date, drone, Math, {});";
base += "};ctx._droneList.push(drone)";
code_eval += "ctx._droneList.push(drone)";
/*jslint evil: true*/
try {
eval(code_eval);
} catch (error) {
console.error(error);
eval(base);
}
/*jslint evil: false*/
}
function randomSpherePoint(x0, y0, z0, rx0, ry0, rz0) { function randomSpherePoint(x0, y0, z0, rx0, ry0, rz0) {
var u = Math.random(), v = Math.random(), var u = Math.random(), v = Math.random(),
rx = Math.random() * rx0, ry = Math.random() * ry0, rx = Math.random() * rx0, ry = Math.random() * ry0,
...@@ -1045,11 +1073,15 @@ var GameManager = /** @class */ (function () { ...@@ -1045,11 +1073,15 @@ var GameManager = /** @class */ (function () {
i i
); );
spawnDrone(position.x, position.y, position.z, i, spawnDrone(position.x, position.y, position.z, i,
drone_list[i], api); drone_list[i], api, ctx._scene, ctx._droneList);
} }
} }
}; };
GameManager.prototype.getCurrentTime = function () {
return this._start_time + this._game_duration;
};
return GameManager; return GameManager;
}()); }());
......
...@@ -240,7 +240,7 @@ ...@@ -240,7 +240,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>1014.65027.38618.31573</string> </value> <value> <string>1016.21987.28184.16844</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -260,7 +260,7 @@ ...@@ -260,7 +260,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1709560536.57</float> <float>1714742619.34</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -122,11 +122,13 @@ ...@@ -122,11 +122,13 @@
' }\n' + ' }\n' +
' return;\n' + ' return;\n' +
' }\n' + ' }\n' +
' me.exit(0);\n' + ' if (!me.isLanding()) { me.land() };\n' +
' if (me.getCurrentPosition().altitude <= 0) { me.exit(0) };\n' +
'};', '};',
DRAW = true, DRAW = true,
LOG = true, LOG = true,
LOG_TIME = 1662.7915426540285, LOG_TIME = 1662.7915426540285,
ONUPDATE_INTERVAL = 100,
DRONE_LIST = [], DRONE_LIST = [],
WIDTH = 680, WIDTH = 680,
HEIGHT = 340, HEIGHT = 340,
...@@ -191,6 +193,17 @@ ...@@ -191,6 +193,17 @@
"hidden": 0, "hidden": 0,
"type": "IntegerField" "type": "IntegerField"
}, },
"my_onupdate_interval": {
"description": "Minimum interval (in milliseconds) between 2 executions of onUpdate function as well as periodicity to send telemetry to the swarm",
"title": "OnUpdate interval",
"default": ONUPDATE_INTERVAL,
"css_class": "",
"required": 1,
"editable": 1,
"key": "onupdate_interval",
"hidden": 0,
"type": "IntegerField"
},
"my_drone_min_speed": { "my_drone_min_speed": {
"description": "", "description": "",
"title": "Drone min speed", "title": "Drone min speed",
...@@ -444,8 +457,8 @@ ...@@ -444,8 +457,8 @@
form_definition: { form_definition: {
group_list: [[ group_list: [[
"left", "left",
[["my_simulation_speed"], ["my_simulation_time"], ["my_number_of_drones"], [["my_simulation_speed"], ["my_simulation_time"], ["my_onupdate_interval"],
["my_minimum_latitud"], ["my_maximum_latitud"], ["my_number_of_drones"], ["my_minimum_latitud"], ["my_maximum_latitud"],
["my_minimum_longitud"], ["my_maximum_longitud"], ["my_minimum_longitud"], ["my_maximum_longitud"],
["my_init_pos_lat"], ["my_init_pos_lon"], ["my_init_pos_alt"], ["my_init_pos_lat"], ["my_init_pos_lon"], ["my_init_pos_alt"],
["my_map_height"]] ["my_map_height"]]
...@@ -494,7 +507,8 @@ ...@@ -494,7 +507,8 @@
"maxPitchAngle": parseFloat(options.drone_max_pitch), "maxPitchAngle": parseFloat(options.drone_max_pitch),
"maxSinkRate": parseFloat(options.drone_max_sink_rate), "maxSinkRate": parseFloat(options.drone_max_sink_rate),
"maxClimbRate": parseFloat(options.drone_max_climb_rate), "maxClimbRate": parseFloat(options.drone_max_climb_rate),
"maxCommandFrequency": parseFloat(options.drone_max_command_frequency) "maxCommandFrequency": parseFloat(options.drone_max_command_frequency),
"onUpdateInterval": parseInt(options.onupdate_interval, 10)
}, },
"gameTime": parseInt(options.simulation_time, 10), "gameTime": parseInt(options.simulation_time, 10),
"simulation_speed": parseInt(options.simulation_speed, 10), "simulation_speed": parseInt(options.simulation_speed, 10),
......
...@@ -246,7 +246,7 @@ ...@@ -246,7 +246,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>1014.60725.60577.24917</string> </value> <value> <string>1015.64120.46679.6946</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>1709289017.41</float> <float>1713425712.2</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -3,11 +3,10 @@ ...@@ -3,11 +3,10 @@
(function (window, rJS, domsugar, document, URLSearchParams, Blob) { (function (window, rJS, domsugar, document, URLSearchParams, Blob) {
"use strict"; "use strict";
var SIMULATION_SPEED = 10, var SIMULATION_SPEED = 1,
SIMULATION_TIME = 270, LOOP_INTERVAL = 1000 / 60,
MAP_SIZE = 600, ON_UPDATE_INTERVAL = LOOP_INTERVAL,
map_height = 700, SIMULATION_TIME = LOOP_INTERVAL / 1000,
start_AMSL = 595,
DEFAULT_SPEED = 16, DEFAULT_SPEED = 16,
MAX_ACCELERATION = 6, MAX_ACCELERATION = 6,
MAX_DECELERATION = 1, MAX_DECELERATION = 1,
...@@ -19,7 +18,6 @@ ...@@ -19,7 +18,6 @@
MAX_CLIMB_RATE = 8, MAX_CLIMB_RATE = 8,
MAX_SINK_RATE = 3, MAX_SINK_RATE = 3,
NUMBER_OF_DRONES = 1, NUMBER_OF_DRONES = 1,
FLAG_WEIGHT = 5,
MIN_LAT = 45.6364, MIN_LAT = 45.6364,
MAX_LAT = 45.65, MAX_LAT = 45.65,
MIN_LON = 14.2521, MIN_LON = 14.2521,
...@@ -78,9 +76,10 @@ ...@@ -78,9 +76,10 @@
' me.getCurrentPosition().longitude\n' + ' me.getCurrentPosition().longitude\n' +
' ).toFixed(8),\n' + ' ).toFixed(8),\n' +
' time_interval = timestamp - me.start_time,\n' + ' time_interval = timestamp - me.start_time,\n' +
' expected_interval = 1000 / 60,\n' + ' expected_interval = ' + LOOP_INTERVAL + ',\n' +
' expectedDistance = (me.getSpeed() * expected_interval / 1000).toFixed(8);\n' + ' expectedDistance = (me.getSpeed() * expected_interval / 1000).toFixed(8);\n' +
' assert(time_interval.toFixed(4), expected_interval.toFixed(4), "Timestamp");\n' + ' assert(time_interval.toFixed(4), expected_interval.toFixed(4), "Timestamp");\n' +
' assert(Date.now(), timestamp, "Date");\n' +
' assert(realDistance, expectedDistance, "Distance");\n' + ' assert(realDistance, expectedDistance, "Distance");\n' +
' current_position.latitude = current_position.latitude.toFixed(7);\n' + ' current_position.latitude = current_position.latitude.toFixed(7);\n' +
' compare(current_position, {\n' + ' compare(current_position, {\n' +
...@@ -88,7 +87,6 @@ ...@@ -88,7 +87,6 @@
' longitude: me.initialPosition.longitude,\n' + ' longitude: me.initialPosition.longitude,\n' +
' altitude: me.initialPosition.altitude\n' + ' altitude: me.initialPosition.altitude\n' +
' });\n' + ' });\n' +
' me.exit(me.land());\n' +
'};', '};',
DRAW = true, DRAW = true,
LOG = true, LOG = true,
...@@ -175,35 +173,36 @@ ...@@ -175,35 +173,36 @@
game_parameters_json = { game_parameters_json = {
"debug_test_mode": true, "debug_test_mode": true,
"drone": { "drone": {
"maxAcceleration": parseInt(MAX_ACCELERATION, 10), "maxAcceleration": MAX_ACCELERATION,
"maxDeceleration": parseInt(MAX_DECELERATION, 10), "maxDeceleration": MAX_DECELERATION,
"minSpeed": parseInt(MIN_SPEED, 10), "minSpeed": MIN_SPEED,
"speed": parseFloat(DEFAULT_SPEED), "speed": DEFAULT_SPEED,
"maxSpeed": parseInt(MAX_SPEED, 10), "maxSpeed": MAX_SPEED,
"maxRoll": parseFloat(MAX_ROLL), "maxRoll": MAX_ROLL,
"minPitchAngle": parseFloat(MIN_PITCH), "minPitchAngle": MIN_PITCH,
"maxPitchAngle": parseFloat(MAX_PITCH), "maxPitchAngle": MAX_PITCH,
"maxSinkRate": parseFloat(MAX_SINK_RATE), "maxSinkRate": MAX_SINK_RATE,
"maxClimbRate": parseFloat(MAX_CLIMB_RATE) "maxClimbRate": MAX_CLIMB_RATE,
"onUpdateInterval": ON_UPDATE_INTERVAL
}, },
"gameTime": parseInt(SIMULATION_TIME, 10), "gameTime": SIMULATION_TIME,
"simulation_speed": parseInt(SIMULATION_SPEED, 10), "simulation_speed": SIMULATION_SPEED,
"latency": { "latency": {
"information": 0, "information": 0,
"communication": 0 "communication": 0
}, },
"map": { "map": {
"min_lat": parseFloat(MIN_LAT), "min_lat": MIN_LAT,
"max_lat": parseFloat(MAX_LAT), "max_lat": MAX_LAT,
"min_lon": parseFloat(MIN_LON), "min_lon": MIN_LON,
"max_lon": parseFloat(MAX_LON), "max_lon": MAX_LON,
"height": parseInt(HEIGHT), "height": HEIGHT,
"start_AMSL": parseFloat(start_AMSL) "start_AMSL": start_AMSL
}, },
"initialPosition": { "initialPosition": {
"longitude": parseFloat(INIT_LON), "longitude": INIT_LON,
"latitude": parseFloat(INIT_LAT), "latitude": INIT_LAT,
"altitude": parseFloat(INIT_ALT) "altitude": INIT_ALT
}, },
"draw_flight_path": DRAW, "draw_flight_path": DRAW,
"temp_flight_path": true, "temp_flight_path": true,
...@@ -257,19 +256,27 @@ ...@@ -257,19 +256,27 @@
return form_gadget.getContent(); return form_gadget.getContent();
}) })
.push(function (result) { .push(function (result) {
var div = domsugar('div', { text: "CONSOLE LOG ENTRIES:" }); var div = domsugar('div', { text: "CONSOLE LOG ENTRIES:" }),
lines = result.console_log.split('\n'),
line_nb,
node,
test_log_node = document.querySelector('.test_log');;
document.querySelector('.container').parentNode.appendChild(div); document.querySelector('.container').parentNode.appendChild(div);
function createLogNode(message) { function appendToTestLog(test_log_node, message) {
var node = document.createElement("div"); var log_node = document.createElement("div"),
var textNode = document.createTextNode(message); textNode = document.createTextNode(message);
node.appendChild(textNode); log_node.appendChild(textNode);
return node; 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;
} }
var lines = result.console_log.split('\n');
for (var i = 0;i < lines.length;i++) {
var node = createLogNode(lines[i]);
document.querySelector('.test_log').appendChild(node);
} }
appendToTestLog(test_log_node, 'Timeout: FAILED');
}, function (error) { }, function (error) {
return gadget.notifySubmitted({message: "Error: " + error.message, return gadget.notifySubmitted({message: "Error: " + error.message,
status: 'error'}); status: 'error'});
......
...@@ -246,7 +246,7 @@ ...@@ -246,7 +246,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>1014.60681.20667.37171</string> </value> <value> <string>1015.64176.45813.63488</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>1709286436.53</float> <float>1713428376.53</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
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