Commit c2a7e1e8 authored by Roque's avatar Roque

Fix coordinates conversion

See merge request nexedi/erp5!1807
parents 98aa5f07 6a6f2bd3
Pipeline #29374 failed with stage
...@@ -93,7 +93,7 @@ var FixedWingDroneAPI = /** @class */ (function () { ...@@ -93,7 +93,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_update = function (context, delta_time) {
var diff, newrot, orientationValue, rotStep, updateSpeed; var diff, newrot, orientationValue, rotStep;
//TODO rotation //TODO rotation
if (context._rotationTarget) { if (context._rotationTarget) {
...@@ -117,18 +117,8 @@ var FixedWingDroneAPI = /** @class */ (function () { ...@@ -117,18 +117,8 @@ var FixedWingDroneAPI = /** @class */ (function () {
} }
this._updateSpeed(context, delta_time); this._updateSpeed(context, delta_time);
this._updateDirection(context, delta_time); this._updatePosition(context, delta_time);
updateSpeed = context._speed * delta_time / 1000;
if (context._direction.x !== 0 ||
context._direction.y !== 0 ||
context._direction.z !== 0) {
context._controlMesh.position.addInPlace(new BABYLON.Vector3(
context._direction.x * updateSpeed,
context._direction.y * updateSpeed,
context._direction.z * updateSpeed
));
}
//TODO rotation //TODO rotation
orientationValue = context._maxOrientation * orientationValue = context._maxOrientation *
(context._speed / context._maxSpeed); (context._speed / context._maxSpeed);
...@@ -181,66 +171,111 @@ var FixedWingDroneAPI = /** @class */ (function () { ...@@ -181,66 +171,111 @@ var FixedWingDroneAPI = /** @class */ (function () {
} }
}; };
FixedWingDroneAPI.prototype._updateDirection = function (drone, delta_time) { FixedWingDroneAPI.prototype._updatePosition = function (drone, delta_time) {
var horizontalCoeff, newX, newY, newZ, tangentYaw; var R = 6371e3,
currentGeoCoordinates = this._mapManager.convertToGeoCoordinates(
drone.position.x,
drone.position.y,
drone.position.z
),
targetCoordinates = this._mapManager.convertToGeoCoordinates(
drone._targetCoordinates.x,
drone._targetCoordinates.y,
drone._targetCoordinates.z
),
bearing = this._computeBearing(
currentGeoCoordinates.x,
currentGeoCoordinates.y,
targetCoordinates.x,
targetCoordinates.y
),
currentCosLat,
currentLatRad,
distance,
distanceCos,
distanceSin,
currentSinLat,
currentLonRad,
groundSpeed,
newCoordinates,
newLatRad,
newLonRad,
newYaw,
newYawRad,
verticalSpeed,
yawToDirection;
if (this._loiter_mode && Math.sqrt( if (this._loiter_mode && Math.sqrt(
Math.pow(drone._targetCoordinates.x - drone.position.x, 2) + Math.pow(drone._targetCoordinates.x - drone.position.x, 2) +
Math.pow(drone._targetCoordinates.y - drone.position.y, 2) Math.pow(drone._targetCoordinates.y - drone.position.y, 2)
) <= this._loiter_radius) { ) <= this._loiter_radius) {
tangentYaw = this._computeBearing( newYaw = bearing - 90;
drone.position.x,
drone.position.y,
drone._targetCoordinates.x,
drone._targetCoordinates.y
) - 90;
// trigonometric circle is east oriented, yaw angle is clockwise
tangentYaw = this._toRad(-tangentYaw + 90);
newX = Math.cos(tangentYaw);
newZ = Math.sin(tangentYaw);
} else { } else {
[newX, newZ] = this._getNewYaw(drone, delta_time); newYaw = this._getNewYaw(drone, bearing, delta_time);
} }
newY = this._getNewAltitude(drone); newYawRad = this._toRad(newYaw);
currentLatRad = this._toRad(currentGeoCoordinates.x);
currentCosLat = Math.cos(currentLatRad);
currentSinLat = Math.sin(currentLatRad);
currentLonRad = this._toRad(currentGeoCoordinates.y);
horizontalCoeff = Math.sqrt( verticalSpeed = this._getVerticalSpeed(drone);
( groundSpeed = Math.sqrt(
Math.pow(drone.getAirSpeed(), 2) - Math.pow(newY, 2) Math.pow(drone.getAirSpeed(), 2) - Math.pow(verticalSpeed, 2)
) / (
Math.pow(newX, 2) + Math.pow(newZ, 2)
)
); );
newX *= horizontalCoeff;
newZ *= horizontalCoeff;
// swap y and z axis so z axis represents altitude
drone.setDirection(newX, newZ, newY);
};
FixedWingDroneAPI.prototype._getNewYaw = function (drone, delta_time) { distance = (groundSpeed * delta_time / 1000) / R;
// swap y and z axis so z axis represents altitude distanceCos = Math.cos(distance);
var bearing = this._computeBearing( distanceSin = Math.sin(distance);
drone.position.x,
drone.position.y,
drone._targetCoordinates.x,
drone._targetCoordinates.y
),
yaw = drone.getYaw(),
yawDiff = this._computeYawDiff(yaw, bearing),
yawUpdate = this.getYawVelocity(drone) * delta_time / 1000;
if (yawUpdate >= Math.abs(yawDiff)) { newLatRad = Math.asin(
yawUpdate = yawDiff; currentSinLat * distanceCos +
} else if (yawDiff < 0) { currentCosLat * distanceSin * Math.cos(newYawRad)
yawUpdate *= -1; );
} newLonRad = currentLonRad + Math.atan2(
yaw += yawUpdate; Math.sin(newYawRad) * distanceSin * currentCosLat,
distanceCos - currentSinLat * Math.sin(newLatRad)
);
// trigonometric circle is east oriented, yaw angle is clockwise newCoordinates = this._mapManager.convertToLocalCoordinates(
yaw = this._toRad(-yaw + 90); this._toDeg(newLatRad),
return [Math.cos(yaw), Math.sin(yaw)]; this._toDeg(newLonRad),
drone.position.z
);
// swap y and z axis so z axis represents altitude
drone._controlMesh.position.addInPlace(new BABYLON.Vector3(
Math.abs(newCoordinates.x - drone.position.x) *
(newCoordinates.x < drone.position.x ? -1 : 1),
verticalSpeed * delta_time / 1000,
Math.abs(newCoordinates.y - drone.position.y) *
(newCoordinates.y < drone.position.y ? -1 : 1)
));
yawToDirection = this._toRad(-newYaw + 90);
drone.setDirection(
groundSpeed * Math.cos(yawToDirection),
groundSpeed * Math.sin(yawToDirection),
verticalSpeed
);
}; };
FixedWingDroneAPI.prototype._getNewAltitude = function (drone) { FixedWingDroneAPI.prototype._getNewYaw =
function (drone, bearing, delta_time) {
// swap y and z axis so z axis represents altitude
var yaw = drone.getYaw(),
yawDiff = this._computeYawDiff(yaw, bearing),
yawUpdate = this.getYawVelocity(drone) * delta_time / 1000;
if (yawUpdate >= Math.abs(yawDiff)) {
yawUpdate = yawDiff;
} else if (yawDiff < 0) {
yawUpdate *= -1;
}
return yaw + yawUpdate;
};
FixedWingDroneAPI.prototype._getVerticalSpeed = function (drone) {
// swap y and z axis so z axis represents altitude // swap y and z axis so z axis represents altitude
var altitudeDiff = drone._targetCoordinates.z - drone.position.z, var altitudeDiff = drone._targetCoordinates.z - drone.position.z,
verticalSpeed; verticalSpeed;
...@@ -356,20 +391,16 @@ var FixedWingDroneAPI = /** @class */ (function () { ...@@ -356,20 +391,16 @@ var FixedWingDroneAPI = /** @class */ (function () {
if (isNaN(lat) || isNaN(lon) || isNaN(z)) { if (isNaN(lat) || isNaN(lon) || isNaN(z)) {
throw new Error('Target coordinates must be numbers'); throw new Error('Target coordinates must be numbers');
} }
var point = this._mapManager.toLocalCoordinates(lat, lon, var processed_coordinates =
this._map_dict.map_size), this._mapManager.convertToLocalCoordinates(lat, lon, z);
position = this._mapManager.normalize(point.x, point.y, this._map_dict); if (processed_coordinates.z > this._map_dict.start_AMSL) {
if (z > this._map_dict.start_AMSL) { processed_coordinates.z -= this._map_dict.start_AMSL;
z -= this._map_dict.start_AMSL;
} }
return { return processed_coordinates;
x: position[0],
y: position[1],
z: z
};
}; };
FixedWingDroneAPI.prototype.getCurrentPosition = function (x, y, z) { FixedWingDroneAPI.prototype.getCurrentPosition = function (x, y, z) {
return this._mapManager.convertToGeoCoordinates(x, y, z, this._map_dict); return this._mapManager.convertToGeoCoordinates(x, y, z);
}; };
FixedWingDroneAPI.prototype.getDroneViewInfo = function (drone) { FixedWingDroneAPI.prototype.getDroneViewInfo = function (drone) {
var context = this, result = { "obstacles": [], "drones": [] }, distance, var context = this, result = { "obstacles": [], "drones": [] }, distance,
...@@ -455,11 +486,18 @@ var FixedWingDroneAPI = /** @class */ (function () { ...@@ -455,11 +486,18 @@ var FixedWingDroneAPI = /** @class */ (function () {
}; };
FixedWingDroneAPI.prototype.getYaw = function (drone) { FixedWingDroneAPI.prototype.getYaw = function (drone) {
var direction = drone.worldDirection; var direction = drone.worldDirection;
return this._computeBearing(0, 0, direction.x, direction.z); return this._toDeg(Math.atan2(direction.x, direction.z));
}; };
FixedWingDroneAPI.prototype._computeBearing = function (x1, z1, x2, z2) { FixedWingDroneAPI.prototype._computeBearing =
return this._toDeg(Math.atan2(x2 - x1, z2 - z1)); function (lat1, lon1, lat2, lon2) {
}; var dLon = this._toRad(lon2 - lon1),
lat1Rad = this._toRad(lat1),
lat2Rad = this._toRad(lat2),
x = Math.cos(lat2Rad) * Math.sin(dLon),
y = Math.cos(lat1Rad) * Math.sin(lat2Rad) -
Math.sin(lat1Rad) * Math.cos(lat2Rad) * Math.cos(dLon);
return this._toDeg(Math.atan2(x, y));
};
FixedWingDroneAPI.prototype._computeYawDiff = function (yaw1, yaw2) { FixedWingDroneAPI.prototype._computeYawDiff = function (yaw1, yaw2) {
var diff = yaw2 - yaw1; var diff = yaw2 - yaw1;
diff += (diff > 180) ? -360 : (diff < -180) ? 360 : 0; diff += (diff > 180) ? -360 : (diff < -180) ? 360 : 0;
......
...@@ -246,7 +246,7 @@ ...@@ -246,7 +246,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>1010.5034.64121.33006</string> </value> <value> <string>1010.22181.14558.58982</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>1690565260.64</float> <float>1691593350.04</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -408,70 +408,15 @@ var DroneManager = /** @class */ (function () { ...@@ -408,70 +408,15 @@ var DroneManager = /** @class */ (function () {
var MapManager = /** @class */ (function () { var MapManager = /** @class */ (function () {
"use strict"; "use strict";
//random geo-point: var EPSILON = 9.9,
var MIN_LAT = 45.64,
MIN_LON = 14.253,
EPSILON = 9.9,
START_Z = 15, START_Z = 15,
R = 6371e3; R = 6371e3;
function calculateMapInfo(map, map_dict) {
var min_lat = map_dict.min_lat || MIN_LAT,
min_lon = map_dict.min_lon || MIN_LON,
offset = map.latLonOffset(min_lat, min_lon, map_dict.map_size),
max_lat = offset[0],
max_lon = offset[1],
starting_point = map_dict.map_size / 2 * -0.75,
local_min = map.toLocalCoordinates(min_lat, min_lon, map_dict.map_size),
local_max = map.toLocalCoordinates(max_lat, max_lon, map_dict.map_size);
map.map_info = {
"depth": map_dict.map_size,
"width": map_dict.map_size,
"map_size": map_dict.map_size,
"min_lat": min_lat,
"min_lon": min_lon,
"max_lat": max_lat,
"max_lon": max_lon,
"min_x": local_min.x,
"min_y": local_min.y,
"max_x": local_max.x,
"max_y": local_max.y,
"height": map_dict.height,
"start_AMSL": map_dict.start_AMSL,
"flag_list": map_dict.flag_list,
"geo_flag_list": [],
"flag_distance_epsilon": map_dict.flag_distance_epsilon || EPSILON,
"obstacle_list": map_dict.obstacle_list,
"geo_obstacle_list": [],
"initial_position": {
"x": 0,
"y": starting_point,
"z": START_Z
}
};
map_dict.flag_list.forEach(function (flag_info, index) {
map.map_info.geo_flag_list.push(map.convertToGeoCoordinates(
flag_info.position.x,
flag_info.position.y,
flag_info.position.z
));
});
map_dict.obstacle_list.forEach(function (obstacle_info, index) {
var geo_obstacle = {};
Object.assign(geo_obstacle, obstacle_info);
geo_obstacle.position = map.convertToGeoCoordinates(
obstacle_info.position.x,
obstacle_info.position.y,
obstacle_info.position.z
);
map.map_info.geo_obstacle_list.push(geo_obstacle);
});
}
//** CONSTRUCTOR //** CONSTRUCTOR
function MapManager(scene) { function MapManager(scene) {
var _this = this, max_sky, skybox, skyboxMat, largeGroundMat, flag_material, var _this = this, max_sky, skybox, skyboxMat, largeGroundMat, flag_material,
largeGroundBottom, width, depth, terrain, max, flag_a, flag_b, mast, flag, largeGroundBottom, width, depth, terrain, max, flag_a, flag_b, mast, flag,
count = 0, new_obstacle; count = 0, new_obstacle;
calculateMapInfo(_this, GAMEPARAMETERS.map); this.setMapInfo(GAMEPARAMETERS.map, GAMEPARAMETERS.initialPosition);
max = _this.map_info.width; max = _this.map_info.width;
if (_this.map_info.depth > max) { if (_this.map_info.depth > max) {
max = _this.map_info.depth; max = _this.map_info.depth;
...@@ -612,22 +557,74 @@ var MapManager = /** @class */ (function () { ...@@ -612,22 +557,74 @@ var MapManager = /** @class */ (function () {
_this._flag_list.push(flag); _this._flag_list.push(flag);
}); });
} }
MapManager.prototype.setMapInfo = function (map_dict, initial_position) {
var max_width = this.latLonDistance([map_dict.min_lat, map_dict.min_lon],
[map_dict.min_lat, map_dict.max_lon]),
max_height = this.latLonDistance([map_dict.min_lat, map_dict.min_lon],
[map_dict.max_lat, map_dict.min_lon]),
map_size = Math.ceil(Math.max(max_width, max_height)),
starting_point = map_size / 2 * -0.75;
console.log("max_width:",max_width);
console.log("max_height:",max_height);
console.log("map_size:",map_size);
this.map_info = {
"depth": map_size,
"height": map_dict.height,
"width": map_size,
"map_size": map_size,
"start_AMSL": map_dict.start_AMSL,
"flag_list": map_dict.flag_list,
"geo_flag_list": [],
"flag_distance_epsilon": map_dict.flag_distance_epsilon || EPSILON,
"obstacle_list": map_dict.obstacle_list,
"geo_obstacle_list": [],
"initial_position": {
"x": 0,
"y": starting_point,
"z": START_Z
}
};
this.map_info.min_x = this.longitudToX(map_dict.min_lon);
this.map_info.min_y = this.latitudeToY(map_dict.min_lat);
this.map_info.max_x = this.longitudToX(map_dict.max_lon);
this.map_info.max_y = this.latitudeToY(map_dict.max_lat);
var map = this;
map_dict.flag_list.forEach(function (flag_info, index) {
map.map_info.geo_flag_list.push(map.convertToGeoCoordinates(
flag_info.position.x,
flag_info.position.y,
flag_info.position.z
));
});
map_dict.obstacle_list.forEach(function (obstacle_info, index) {
var geo_obstacle = {};
Object.assign(geo_obstacle, obstacle_info);
geo_obstacle.position = map.convertToGeoCoordinates(
obstacle_info.position.x,
obstacle_info.position.y,
obstacle_info.position.z
);
map.map_info.geo_obstacle_list.push(geo_obstacle);
});
};
MapManager.prototype.getMapInfo = function () { MapManager.prototype.getMapInfo = function () {
return this.map_info; return this.map_info;
}; };
MapManager.prototype.latLonOffset = function (lat, lon, offset_in_mt) { MapManager.prototype.longitudToX = function (lon) {
return (this.map_info.map_size / 360.0) * (180 + lon);
};
MapManager.prototype.latitudeToY = function (lat) {
return (this.map_info.map_size / 180.0) * (90 - lat);
};
//TODO refactor latLonOffset, should be the reverse of lat-lon distance
//then map_size can be used as parameter (get max lat-lon from map_size)
/*MapManager.prototype.latLonOffset = function (lat, lon, offset_in_mt) {
var R = 6371e3, //Earth radius var R = 6371e3, //Earth radius
lat_offset = offset_in_mt / R, lat_offset = offset_in_mt / R,
lon_offset = offset_in_mt / (R * Math.cos(Math.PI * lat / 180)); lon_offset = offset_in_mt / (R * Math.cos(Math.PI * lat / 180));
return [lat + lat_offset * 180 / Math.PI, return [lat + lat_offset * 180 / Math.PI,
lon + lon_offset * 180 / Math.PI]; lon + lon_offset * 180 / Math.PI];
}; };*/
MapManager.prototype.toLocalCoordinates = function (lat, lon, map_size) {
return {
"x": (map_size / 360.0) * (180 + lon),
"y": (map_size / 180.0) * (90 - lat)
};
};
MapManager.prototype.latLonDistance = function (c1, c2) { MapManager.prototype.latLonDistance = function (c1, c2) {
var q1 = c1[0] * Math.PI / 180, var q1 = c1[0] * Math.PI / 180,
q2 = c2[0] * Math.PI / 180, q2 = c2[0] * Math.PI / 180,
...@@ -639,24 +636,30 @@ var MapManager = /** @class */ (function () { ...@@ -639,24 +636,30 @@ var MapManager = /** @class */ (function () {
c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return R * c; return R * c;
}; };
MapManager.prototype.normalize = function (x, y, map_dict) { MapManager.prototype.convertToLocalCoordinates =
var n_x = (x - map_dict.min_x) / (map_dict.max_x - map_dict.min_x), function (latitude, longitude, altitude) {
n_y = (y - map_dict.min_y) / (map_dict.max_y - map_dict.min_y); var map_info = this.map_info,
return [n_x * 1000 - map_dict.width / 2, x = this.longitudToX(longitude),
n_y * 1000 - map_dict.depth / 2]; y = this.latitudeToY(latitude);
}; return {
x: ((x - map_info.min_x) / (map_info.max_x - map_info.min_x)) *
1000 - map_info.width / 2,
y: ((y - map_info.min_y) / (map_info.max_y - map_info.min_y)) *
1000 - map_info.depth / 2,
z: altitude
};
};
MapManager.prototype.convertToGeoCoordinates = function (x, y, z) { MapManager.prototype.convertToGeoCoordinates = function (x, y, z) {
var map_dict = this.map_info, var lon = x + this.map_info.width / 2,
lon = x + map_dict.width / 2, lat = y + this.map_info.depth / 2;
lat = y + map_dict.depth / 2;
lon = lon / 1000; lon = lon / 1000;
lon = lon * (map_dict.max_x - map_dict.min_x) + lon = lon * (this.map_info.max_x - this.map_info.min_x) +
map_dict.min_x; this.map_info.min_x;
lon = lon / (map_dict.width / 360.0) - 180; lon = lon / (this.map_info.map_size / 360.0) - 180;
lat = lat / 1000; lat = lat / 1000;
lat = lat * (map_dict.max_y - map_dict.min_y) + lat = lat * (this.map_info.max_y - this.map_info.min_y) +
map_dict.min_y; this.map_info.min_y;
lat = 90 - lat / (map_dict.depth / 180.0); lat = 90 - lat / (this.map_info.map_size / 180.0);
return { return {
x: lat, x: lat,
y: lon, y: lon,
...@@ -676,7 +679,7 @@ var GameManager = /** @class */ (function () { ...@@ -676,7 +679,7 @@ var GameManager = /** @class */ (function () {
"use strict"; "use strict";
// *** CONSTRUCTOR *** // *** CONSTRUCTOR ***
function GameManager(canvas, game_parameters_json) { function GameManager(canvas, game_parameters_json) {
var drone, header_list, drone_count; var drone, header_list, drone_count, i;
this._canvas = canvas; this._canvas = canvas;
this._canvas_width = canvas.width; this._canvas_width = canvas.width;
this._canvas_height = canvas.height; this._canvas_height = canvas.height;
...@@ -737,7 +740,7 @@ var GameManager = /** @class */ (function () { ...@@ -737,7 +740,7 @@ var GameManager = /** @class */ (function () {
console.log = function () { console.log = function () {
baseLogFunction.apply(console, arguments); baseLogFunction.apply(console, arguments);
var args = Array.prototype.slice.call(arguments); var args = Array.prototype.slice.call(arguments);
for (var i = 0;i < args.length;i++) { for (i = 0;i < args.length;i++) {
console_log += args[i] + "\n"; console_log += args[i] + "\n";
} }
}; };
......
...@@ -246,7 +246,7 @@ ...@@ -246,7 +246,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>1010.5086.1058.34440</string> </value> <value> <string>1010.22324.3760.41318</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>1690567567.2</float> <float>1691601869.17</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
/* DOCUMENTATION */
.documentation p {
margin: 10px 0;
font-family: monospace;
color: #263238;
line-height: 18px;
}
.documentation pre {
line-height: 18px;
font-family: monospace;
}
.documentation h1 {
margin: 0 0 30px 0;
font-size: 2.3em;
}
.documentation h3 {
margin: 0 0 15px 0;
font-size: 1.6em;
}
.documentation h4 {
margin-top: 20px;
}
.documentation h5 {
font-weight: bold;
}
.documentation h4,
.documentation h5 {
margin: 0;
}
.documentation .line {
width: 100%;
height: 1px;
background-color: lightgrey;
margin: 30px 0;
}
.documentation .item-param-1,
.documentation .item-param-2 {
width: 25%;
display: inline-block;
}
.item-name {
background-color: #F8F8F8;
padding: 8px;
margin: 8px 0;
font-size: 1.2em; }
.item-name span:first-of-type {
font-weight: bold; }
.item-name span:last-of-type {
font-style: italic; }
.line {
width: 100%;
height: 1px;
background-color: lightgrey;
margin: 30px 0; }
\ No newline at end of file
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Web Style" 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_api_page.css</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>ojs_drone_capture_flag_API_page_css</string> </value>
</item>
<item>
<key> <string>language</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>short_title</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Drone Capture Flag API Page CSS</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>1691176318.47</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>1010.15231.63877.58538</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>1691176394.73</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>
<none/>
</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>empty</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>1691176198.41</float>
<string>UTC</string>
</tuple>
</state>
</object>
</value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<html>
<head>
<link rel="stylesheet" type="text/css" href="gadget_erp5_page_drone_capture_flag_api_page.css">
<script src="gadget_erp5_page_drone_capture_flag_api_page.js"></script>
<title>Drone API Documentation</title>
</head>
<body>
<div class="documentation">
<h1>Fixed Wings Drone API</h1>
<h3>API functions</h3>
<h3>Functions called by game on event</h3>
<!-- Start -->
<h4 class="item-name" id="start"><span>onStart</span><span>: void</span></h4>
<p class="item-descr">Function called on game start.</p>
<div>
<h5 class="item-param-1">Example</h5>
</div>
<p class="item-param-1">me.onStart = function() {<br>
&nbsp;&nbsp;//one time execution code<br>
}
</p>
<div class="line"></div>
<!-- Update -->
<h4 class="item-name" id="update"><span>onUpdate</span><span>: void</span></h4>
<p class="item-descr">Function called on game update, 60 times / second. <br></p>
<div>
<h5 class="item-param-1">Param</h5>
<h5 class="item-param-2">Description</h5>
</div>
<div>
<p class="item-param-1">timestamp: Integer</p>
<p class="item-param-2">Timestamp in milliseconds from UNIX epoch</p>
</div>
<h5 class="item-param-1">Example</h5>
<p class="item-example">me.onUpdate = function() {<br>
&nbsp;&nbsp;//code executed 60 times per second<br>
}
</p>
<div class="line"></div>
<!-- Touched -->
<h4 class="item-name" id="touched"><span>onTouched</span><span>: void</span></h4>
<p class="item-descr">Function called when drone is touched by another drone.</p>
<h5 class="item-param-1">Example</h5>
<p class="item-example">me.onTouched = function() {<br>
&nbsp;&nbsp;//code executed when drone is touched<br>
}
</p>
<h5 class="item-param-1">Drones collision</h5>
<p class="item-example">
The collision between 2 drones is determined by a calculation based on each drone direction, exact position and collision angle, and resolves if one drone bumps the other of if both drones are set down.
<br><br>
The simulator engine checks if the drone control masks intersect, and then based on drones directions it calculates the collision angle between them. If the angle is too wide, both drones will fall. If not, the fastest drone will knockdown the slowest one.
<br><br>
The drone mask size is 0.5 x 0.5 (meters)
</p>
<div class="line"></div>
<!-- onDroneViewInfo -->
<h4 class="item-name" id="update"><span>onDroneViewInfo</span><span>: void</span></h4>
<p class="item-descr">Function called when a fired detection process finishes.<br>
(a detection process is started when a drone calls getDroneViewInfo method, see below)<br>
</p>
<div>
<h5 class="item-param-1">Param</h5>
<h5 class="item-param-2">Description</h5>
</div>
<div>
<p class="item-param-1">drone_view: dict</p>
<p class="item-param-2">Result of detection.</p>
</div>
<h5 class="item-param-1">Example</h5>
<p class="item-example">
me.getDroneViewInfo = function (drone_view) {<br>
&nbsp;&nbsp;//code executed when getDroneViewInfo finished<br>
}
</p>
<div class="line"></div>
<!-- GetMsg -->
<h4 class="item-name" id="getMsg"><span>onGetMsg</span><span>: void</span></h4>
<p class="item-descr">Function called when drone receives a message.</p>
<div>
<h5 class="item-param-1">Param</h5>
<h5 class="item-param-2">Description</h5>
</div>
<div>
<p class="item-param-1">msg: String</p>
<p class="item-param-2">Content of the message</p>
</div>
<div>
<h5 class="item-param-1">Example</h5>
</div>
<div>
<p class="item-param-1">me.onGetMsg = function (msg) {<br>
&nbsp;&nbsp;//process the msg
<br> }
</p>
</div>
<div class="line"></div>
<h3>Function that drones can call</h3>
<div class="line"></div>
<!-- sendMsg -->
<h4 class="item-name" id="sendMsg"><span>sendMsg</span><span>: void</span></h4>
<p class="item-descr">Sends a message to another drone (or to all team drones).<p>
<div>
<h5 class="item-param-1">Param</h5>
<h5 class="item-param-2">Description</h5>
</div>
<div>
<p class="item-param-1">msg: String</p>
<p class="item-param-2">The message to send.</p>
</div>
<div>
<p class="item-param-1">id ?: Number</p>
<p class="item-param-2">ID of the recipient. Leave empty to send to all team drones.</p>
</div>
<div>
<h5 class="item-param-1">Example</h5>
</div>
<div>
<p class="item-example">
me.sendMsg("My broadcast message");<br>
me.sendMsg("To my friend 0", 0);
</p>
</div>
<div class="line"></div>
<!-- getCurrentPosition -->
<h4 class="item-name" id="getCurrentPosition"><span>getCurrentPosition</span><span>: dictionary</span></h4>
<p class="item-descr">
Get drone current position geo-coordinates.<br>
{<br>
&nbsp;&nbsp;x: number, //latitude (in degrees)<br>
&nbsp;&nbsp;y: number, //longitude (in degrees)<br>
&nbsp;&nbsp;z: number //altitude (in meters)<br>
}<br>
</p>
<h5 class="item-param-1">Example</h5>
<p class="item-example">
var current_position = me.getCurrentPosition();<br>
console.log(current_position);<br>
</p>
<div class="line"></div>
<!-- getDroneViewInfo -->
<h4 class="item-name" id="getDroneViewInfo"><span>getDroneViewInfo</span><span>: void</span></h4>
<p class="item-descr">
By calling this method, the drone detection process is fired. It will get all the view information within its scope.<br>
Once the detection finishes (2 seconds) the event method onDroneViewInfo will be called.<br>
</p>
<h5 class="item-param-1">Example</h5>
<p class="item-example">
if (!me.ongoing_detection) {<br>
&nbsp;&nbsp;me.ongoing_detection = true;<br>
&nbsp;&nbsp;me.getDroneViewInfo();<br>
&nbsp;&nbsp;me.ongoing_detection = true;<br>
}<br>
</p>
<div class="line"></div>
<!-- setTargetCoordinates -->
<h4 class="item-name" id="setTargetCoordinates"><span>setTargetCoordinates</span><span>: dictionary</span></h4>
<p class="item-descr">
Set a target point expressed in geo coordinates. The drone will move straight to this point.
</p>
<div>
<h5 class="item-param-1">Param</h5>
<h5 class="item-param-2">Description</h5>
</div>
<div>
<p class="item-param-1">X: Float</p>
<p class="item-param-2">X value - latitude (in degrees).</p>
</div>
<div>
<p class="item-param-1">Y: Float</p>
<p class="item-param-2">Y value - longitude (in degrees).</p>
</div>
<div>
<p class="item-param-1">Z: Float</p>
<p class="item-param-2">Z value - altitude (in meters).</p>
</div>
<div>
<h5 class="item-param-1">Example</h5>
</div>
<div>
<p class="item-example">
me.setTargetCoordinates(lat, lon, altitude);<br>
</p>
</div>
<div class="line"></div>
<!-- setSpeed -->
<h4 class="item-name" id="setSpeed"><span>setSpeed</span><span>: void</span></h4>
<p class="item-descr">Set the drone speed in meters/second. The drone will move at the given value.</p>
<div>
<h5 class="item-param-1">Param</h5>
<h5 class="item-param-2">Description</h5>
</div>
<div>
<p class="item-param-1">altitude: Float</p>
<p class="item-param-2">Speed value</p>
</div>
<div>
<h5 class="item-param-1">Example</h5>
</div>
<p class="item-param-1">me.setSpeed(16);<br>
</p>
<div class="line"></div>
<!-- loiter -->
<h4 class="item-name" id="loiter"><span>loiter</span><span>: void</span></h4>
<p class="item-descr">Set the drone to loiter mode, it will loiter around last target coordinates.</p>
<div>
<h5 class="item-param-1">Param</h5>
<h5 class="item-param-2">Description</h5>
</div>
<div>
<p class="item-param-1">altitude: Float</p>
<p class="item-param-2">altitude value</p>
</div>
<div>
<h5 class="item-param-1">Example</h5>
</div>
<p class="item-param-1">me.loiter(100);<br>
</p>
<div class="line"></div>
<!-- exit -->
<h4 class="item-name" id="exit"><span>exit</span><span>: void</span></h4>
<p class="item-descr">Finishes the drone flight.</p>
<div>
<h5 class="item-param-1">Param</h5>
<h5 class="item-param-2">Description</h5>
</div>
<div>
<p class="item-param-1">exit_code: Integer</p>
<p class="item-param-2">Code to indicate exit status.</p>
</div>
<div>
<h5 class="item-param-1">Example</h5>
</div>
<p class="item-param-1">me.exit(0);<br>
</p>
<div class="line"></div>
<!-- triggerParachute -->
<h4 class="item-name" id="triggerParachute"><span>triggerParachute</span><span>: void</span></h4>
<p class="item-descr">Indicates the drone to deploy the parachute to finish the landing.</p>
<div>
<h5 class="item-param-1">Param</h5>
<h5 class="item-param-2">Description</h5>
</div>
<div>
<h5 class="item-param-1">Example</h5>
</div>
<p class="item-param-1">me.doParachute();<br>
</p>
<div class="line"></div>
<!-- landed -->
<h4 class="item-name" id="landed"><span>landed</span><span>: boolean</span></h4>
<p class="item-descr">Indicates if the drone has landed (reached the floor altitude).</p>
<div>
<h5 class="item-param-1">Example</h5>
</div>
<p class="item-example">
if (me.landed()) {<br>
&nbsp;&nbsp;//do something<br>
}<br>
</p>
<div class="line"></div>
<!-- getInitialAltitude -->
<h4 class="item-name" id="getInitialAltitude"><span>getInitialAltitude</span><span>: Float</span></h4>
<p class="item-descr">Get drone startup altitude.</p>
<div>
<h5 class="item-param-1">Example</h5>
</div>
<p class="item-param-1">me.getInitialAltitude();<br>
</p>
<div class="line"></div>
<!-- getYaw -->
<h4 class="item-name" id="getYaw"><span>getYaw</span><span>: Float</span></h4>
<p class="item-descr">Get drone yaw angle (angle between north and the projection of the aircraft longitudinal axis onto the horizontal plane, see https://en.wikipedia.org/wiki/Aircraft_flight_dynamics) in degrees (value is in [-180; 180]).<br>
Yaw angle can be different of heading (angle between north and the horizontal component of the velocity vector, which describes which direction the aircraft is moving relative to cardinal directions) when there is wind.<br>
</p>
<div>
<h5 class="item-param-1">Example</h5>
</div>
<p class="item-param-1">me.getYaw();<br>
</p>
<div class="line"></div>
<!-- getSpeed -->
<h4 class="item-name" id="getSpeed"><span>getSpeed</span><span>: Float</span></h4>
<p class="item-descr">Get drone air speed in meters/second.</p>
<div>
<h5 class="item-param-1">Example</h5>
</div>
<p class="item-param-1">me.getSpeed();<br>
</p>
<div class="line"></div>
<!-- getGroundSpeed -->
<h4 class="item-name" id="getGroundSpeed"><span>getGroundSpeed</span><span>: Float</span></h4>
<p class="item-descr">Get drone ground speed in meters/second.</p>
<div>
<h5 class="item-param-1">Example</h5>
</div>
<p class="item-param-1">me.getGroundSpeed();<br>
</p>
<div class="line"></div>
<!-- getClimbRate -->
<h4 class="item-name" id="getClimbRate"><span>getClimbRate</span><span>: Float</span></h4>
<p class="item-descr">Get drone climb rate in meters/second.</p>
<div>
<h5 class="item-param-1">Example</h5>
</div>
<p class="item-param-1">me.getClimbRate();<br>
</p>
<div class="line"></div>
<!-- getSinkRate -->
<h4 class="item-name" id="getSinkRate"><span>getSinkRate</span><span>: Float</span></h4>
<p class="item-descr">Get drone sink rate in meters/second.</p>
<div>
<h5 class="item-param-1">Example</h5>
</div>
<p class="item-param-1">me.getSinkRate();<br>
</p>
<div class="line"></div>
<h3>Drone properties</h3>
<div class="line"></div>
<!-- id -->
<h4 class="item-name" id="id"><span>id</span><span>: number</span></h4>
<p class="item-descr">Drone unique numeric identifier: from 0 to 9.</p>
<h5 class="item-param-1">Example</h5>
<p class="item-example">
var drone_id = me.id;<br>
</p>
<div class="line"></div>
<!-- drone_dict -->
<h4 class="item-name" id="id"><span>drone_dict</span><span>: dictionary</span></h4>
<p class="item-descr">Access drones information dictionary. It contains one entry per drone:<br>
key-id: value-drone_dict<br>
{<br>
latitude: number, //latitude (in degrees)<br>
longitude: number, //longitude (in degrees)<br>
altitudeAbs: number //altitude (in meters)<br>
}<br>
</p>
<h5 class="item-param-1">Example</h5>
<p class="item-example">
var leader = me.drone_dict[LEADER_ID];<br>
console.log("leader latitude:", leader.latitude);<br>
console.log("leader longitude:", leader.longitude);<br>
console.log("leader absolute altitude:", leader.altitudeAbs);<br>
</p>
<div class="line"></div>
<!--<h3 class="category-name">Drone Physics Schema</h3>
<center><img src="assets/schema.png"></center>
<div class="line"></div>-->
</div>
</body>
</html>
<?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_api_page.html</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>ojs_drone_capture_flag_API_page_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 API 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>1691175735.97</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>1010.22088.20940.23517</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>1691587714.89</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>1691175684.28</float>
<string>UTC</string>
</tuple>
</state>
</object>
</value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
/*global window, rJS*/
/*jslint indent:2, maxlen: 80, nomen: true */
(function (window, rJS) {
"use strict";
rJS(window)
.declareAcquiredMethod('updateHeader', 'updateHeader')
.declareAcquiredMethod('getUrlFor', 'getUrlFor')
.declareMethod('render', function () {
var gadget = this;
return gadget.getUrlFor({'command': 'history_previous'})
.push(function (url) {
return gadget.updateHeader({
page_title: "Drone API Documentation",
selection_url: url
});
});
});
}(window, rJS));
<?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_api_page.js</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>ojs_drone_capture_flag_API_page_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 API 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>1691176000.16</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>1010.15227.26072.45243</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>1691176057.3</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>1691175985.71</float>
<string>UTC</string>
</tuple>
</state>
</object>
</value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -156,11 +156,13 @@ ...@@ -156,11 +156,13 @@
.push(function () { .push(function () {
return RSVP.hash({ return RSVP.hash({
url_list: gadget.getUrlForList([ url_list: gadget.getUrlForList([
{command: 'display', options: {page: "drone_capture_flag_script_page"}} {command: 'display', options: {page: "drone_capture_flag_script_page"}},
{command: 'display', options: {page: "drone_capture_flag_api_page"}}
]), ]),
translation_list: gadget.getTranslationList([ translation_list: gadget.getTranslationList([
'Editable', 'Editable',
'Run Game' 'Run Game',
'API documentation'
]) ])
}); });
}) })
...@@ -168,7 +170,8 @@ ...@@ -168,7 +170,8 @@
var editable_value = [], var editable_value = [],
element_list = [], element_list = [],
icon_and_key_list = [ icon_and_key_list = [
'puzzle-piece', null 'puzzle-piece', null,
'paperclip', null
]; ];
for (i = 0; i < result_dict.url_list.length; i += 1) { for (i = 0; i < result_dict.url_list.length; i += 1) {
......
...@@ -256,7 +256,7 @@ ...@@ -256,7 +256,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1682444688.11</float> <float>1691175603.36</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -6,7 +6,16 @@ ...@@ -6,7 +6,16 @@
//Drone default values - TODO: get them from the drone API //Drone default values - TODO: get them from the drone API
var SIMULATION_SPEED = 10, var SIMULATION_SPEED = 10,
SIMULATION_TIME = 270, SIMULATION_TIME = 270,
MAP_SIZE = 600, //HARDCODED map size: it is defined by min-max lat-lon distance
//this is done by the map manager (latLonDistance)
//but map_size is needed here for map randomization (location of objects)
//TODO refactor: or randomization is moved to map manager (seed as param)
//or randomization is done here but with geo-coordinates (not meters)
MAP_SIZE = 902,
min_lat = 45.6475,
max_lat = 45.65,
min_lon = 14.265,
max_lon = 14.2766,
map_height = 700, map_height = 700,
start_AMSL = 595, start_AMSL = 595,
DEFAULT_SPEED = 16, DEFAULT_SPEED = 16,
...@@ -291,7 +300,7 @@ ...@@ -291,7 +300,7 @@
"hidden": 0, "hidden": 0,
"type": "FloatField" "type": "FloatField"
}, },
"my_map_size": { /*"my_map_size": {
"description": "", "description": "",
"title": "Map size", "title": "Map size",
"default": MAP_SIZE, "default": MAP_SIZE,
...@@ -301,7 +310,7 @@ ...@@ -301,7 +310,7 @@
"key": "map_size", "key": "map_size",
"hidden": 0, "hidden": 0,
"type": "FloatField" "type": "FloatField"
}, },*/
"my_start_AMSL": { "my_start_AMSL": {
"description": "", "description": "",
"title": "Start AMSL", "title": "Start AMSL",
...@@ -380,7 +389,7 @@ ...@@ -380,7 +389,7 @@
group_list: [[ group_list: [[
"left", "left",
[["my_simulation_speed"], ["my_simulation_time"], ["my_number_of_drones"], [["my_simulation_speed"], ["my_simulation_time"], ["my_number_of_drones"],
["my_map_size"], ["my_map_height"],// ["my_flag_weight"], /*["my_map_size"], */["my_map_height"],// ["my_flag_weight"],
["my_start_AMSL"], ["my_map_seed"]] ["my_start_AMSL"], ["my_map_seed"]]
], [ ], [
"right", "right",
...@@ -407,6 +416,7 @@ ...@@ -407,6 +416,7 @@
var gadget = this, i, var gadget = this, i,
fragment = gadget.element.querySelector('.simulator_div'), fragment = gadget.element.querySelector('.simulator_div'),
game_parameters_json, map_json; game_parameters_json, map_json;
options.map_size = MAP_SIZE;
DRONE_LIST = []; DRONE_LIST = [];
fragment = domsugar(gadget.element.querySelector('.simulator_div'), fragment = domsugar(gadget.element.querySelector('.simulator_div'),
[domsugar('div')]).firstElementChild; [domsugar('div')]).firstElementChild;
...@@ -429,8 +439,7 @@ ...@@ -429,8 +439,7 @@
var seed_value = options.map_seed, var seed_value = options.map_seed,
random_seed = new Math.seedrandom(seed_value), i, random_seed = new Math.seedrandom(seed_value), i,
n_enemies = randomIntFromInterval(5, 10, random_seed), n_enemies = randomIntFromInterval(5, 10, random_seed),
n_flags = randomIntFromInterval(Math.floor(DRONE_LIST.length / 2), n_flags = randomIntFromInterval(5, 10, random_seed),
DRONE_LIST.length, random_seed),
n_obstacles = randomIntFromInterval(5, 15, random_seed), n_obstacles = randomIntFromInterval(5, 15, random_seed),
flag_list = [], obstacle_list = [], enemy_list = [], random_position, flag_list = [], obstacle_list = [], enemy_list = [], random_position,
obstacles_types = ["box"/*, "sphere"*/, "cylinder"], type, obstacles_types = ["box"/*, "sphere"*/, "cylinder"], type,
...@@ -511,6 +520,10 @@ ...@@ -511,6 +520,10 @@
"map_size": parseFloat(options.map_size), "map_size": parseFloat(options.map_size),
"height": parseInt(options.map_height, 10), "height": parseInt(options.map_height, 10),
"start_AMSL": parseFloat(options.start_AMSL), "start_AMSL": parseFloat(options.start_AMSL),
"min_lat": parseFloat(min_lat),
"max_lat": parseFloat(max_lat),
"min_lon": parseFloat(min_lon),
"max_lon": parseFloat(max_lon),
"flag_list": [], "flag_list": [],
"obstacle_list" : [], "obstacle_list" : [],
"drones": { "drones": {
......
...@@ -246,7 +246,7 @@ ...@@ -246,7 +246,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>1009.57725.14056.1911</string> </value> <value> <string>1010.22334.20227.40840</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>1689793877.59</float> <float>1691602475.06</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -8,6 +8,9 @@ url_list = [ ...@@ -8,6 +8,9 @@ url_list = [
"gadget_erp5_panel_drone_capture_flag.js", "gadget_erp5_panel_drone_capture_flag.js",
"gadget_erp5_page_drone_capture_flag_fixedwingdrone.js", "gadget_erp5_page_drone_capture_flag_fixedwingdrone.js",
"gadget_erp5_page_drone_capture_flag_enemydrone.js", "gadget_erp5_page_drone_capture_flag_enemydrone.js",
"gadget_erp5_page_drone_capture_flag_api_page.html",
"gadget_erp5_page_drone_capture_flag_api_page.js",
"gadget_erp5_page_drone_capture_flag_api_page.css",
"assets/map/terrain.jpg", "assets/map/terrain.jpg",
"assets/map/map.babylon", "assets/map/map.babylon",
"assets/drone/drone.babylon", "assets/drone/drone.babylon",
......
...@@ -5,7 +5,11 @@ ...@@ -5,7 +5,11 @@
var SIMULATION_SPEED = 10, var SIMULATION_SPEED = 10,
SIMULATION_TIME = 270, SIMULATION_TIME = 270,
MAP_SIZE = 600, MAP_SIZE = 1905,
min_lat = 45.6364,
max_lat = 45.65,
min_lon = 14.2521,
max_lon = 14.2766,
map_height = 700, map_height = 700,
start_AMSL = 595, start_AMSL = 595,
DEFAULT_SPEED = 16, DEFAULT_SPEED = 16,
...@@ -109,6 +113,10 @@ ...@@ -109,6 +113,10 @@
"map_size": parseFloat(MAP_SIZE), "map_size": parseFloat(MAP_SIZE),
"height": parseInt(map_height, 10), "height": parseInt(map_height, 10),
"start_AMSL": parseFloat(start_AMSL), "start_AMSL": parseFloat(start_AMSL),
"min_lat": parseFloat(min_lat),
"max_lat": parseFloat(max_lat),
"min_lon": parseFloat(min_lon),
"max_lon": parseFloat(max_lon),
"flag_list": [{ "flag_list": [{
"position": { "position": {
"x": -27, "x": -27,
......
...@@ -246,7 +246,7 @@ ...@@ -246,7 +246,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>1010.10600.362.51182</string> </value> <value> <string>1010.22211.26359.65484</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>1690983490.56</float> <float>1691595104.74</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