Commit 36b5ce60 authored by Roque's avatar Roque

erp5_officejs_drone_capture_flag: new map randomization strategy

- grid of blocks
- set of block templates
- randomization conditions
- new terrarin texture
- refine enemy drone collision
- more aggressive enemies
parent 26d6772a
...@@ -6,10 +6,11 @@ var EnemyDroneAPI = /** @class */ (function () { ...@@ -6,10 +6,11 @@ var EnemyDroneAPI = /** @class */ (function () {
"use strict"; "use strict";
var DEFAULT_ACCELERATION = 1, var DEFAULT_ACCELERATION = 1,
VIEW_SCOPE = 50, VIEW_SCOPE = 25,
DEFAULT_SPEED = 16.5, DEFAULT_SPEED = 16.5,
MIN_SPEED = 12, MIN_SPEED = 12,
MAX_SPEED = 26; MAX_SPEED = 26,
COLLISION_SECTOR = 10;
//** CONSTRUCTOR //** CONSTRUCTOR
function EnemyDroneAPI(gameManager, drone_info, flight_parameters, id) { function EnemyDroneAPI(gameManager, drone_info, flight_parameters, id) {
...@@ -21,6 +22,7 @@ var EnemyDroneAPI = /** @class */ (function () { ...@@ -21,6 +22,7 @@ var EnemyDroneAPI = /** @class */ (function () {
this._drone_info = drone_info; this._drone_info = drone_info;
this._drone_dict_list = []; this._drone_dict_list = [];
this._acceleration = DEFAULT_ACCELERATION; this._acceleration = DEFAULT_ACCELERATION;
this._collision_sector = COLLISION_SECTOR;
} }
/* /*
** Function called on start phase of the drone, just before onStart AI script ** Function called on start phase of the drone, just before onStart AI script
...@@ -189,15 +191,16 @@ var EnemyDroneAPI = /** @class */ (function () { ...@@ -189,15 +191,16 @@ var EnemyDroneAPI = /** @class */ (function () {
EnemyDroneAPI.prototype.getDroneViewInfo = function (drone) { EnemyDroneAPI.prototype.getDroneViewInfo = function (drone) {
var context = this, result = [], distance, var context = this, result = [], distance,
drone_position = drone.position, other_position; drone_position = drone.position, other_position;
function calculateDistance(a, b) { function calculateDistance(a, b, _3D) {
return Math.sqrt(Math.pow((a.x - b.x), 2) + Math.pow((a.y - b.y), 2) + var z = (_3D ? Math.pow((a.z - b.z), 2) : 0);
Math.pow((a.z - b.z), 2)); return Math.sqrt(Math.pow((a.x - b.x), 2) + Math.pow((a.y - b.y), 2) + z);
} }
context._gameManager._droneList_user.forEach(function (other) { context._gameManager._droneList_user.forEach(function (other) {
if (other.can_play) { if (other.can_play) {
other_position = other.position; other_position = other.position;
distance = calculateDistance(drone_position, other_position); distance = calculateDistance(drone_position, other_position);
if (distance <= VIEW_SCOPE) { //the higher the drone, the easier to detect
if (distance / (other_position.z * 0.05) <= VIEW_SCOPE) {
result.push({ result.push({
position: other_position, position: other_position,
direction: other.direction, direction: other.direction,
...@@ -213,8 +216,7 @@ var EnemyDroneAPI = /** @class */ (function () { ...@@ -213,8 +216,7 @@ var EnemyDroneAPI = /** @class */ (function () {
}; };
EnemyDroneAPI.prototype.getDroneAI = function () { EnemyDroneAPI.prototype.getDroneAI = function () {
//interception math based on https://www.codeproject.com/Articles/990452/Interception-of-Two-Moving-Objects-in-D-Space //interception math based on https://www.codeproject.com/Articles/990452/Interception-of-Two-Moving-Objects-in-D-Space
return 'var BASE_DISTANCE = 300;\n' + return 'function calculateInterception(hunter_position, prey_position, hunter_speed, prey_speed, prey_velocity_vector) {\n' +
'function calculateInterception(hunter_position, prey_position, hunter_speed, prey_speed, prey_velocity_vector) {\n' +
' var vector_from_drone, distance_to_prey, distance_to_prey_vector, a, b, c, t1, t2, interception_time, interception_point;\n' + ' var vector_from_drone, distance_to_prey, distance_to_prey_vector, a, b, c, t1, t2, interception_time, interception_point;\n' +
' function dot(a, b) {\n' + ' function dot(a, b) {\n' +
' return a.map((x, i) => a[i] * b[i]).reduce((m, n) => m + n);\n' + ' return a.map((x, i) => a[i] * b[i]).reduce((m, n) => m + n);\n' +
...@@ -242,7 +244,6 @@ var EnemyDroneAPI = /** @class */ (function () { ...@@ -242,7 +244,6 @@ var EnemyDroneAPI = /** @class */ (function () {
'}\n' + '}\n' +
'\n' + '\n' +
'me.onStart = function () {\n' + 'me.onStart = function () {\n' +
' me.base = me.position;\n' +
' me.setDirection(0,0,0);\n' + ' me.setDirection(0,0,0);\n' +
' return;\n' + ' return;\n' +
'\n' + '\n' +
...@@ -251,20 +252,6 @@ var EnemyDroneAPI = /** @class */ (function () { ...@@ -251,20 +252,6 @@ var EnemyDroneAPI = /** @class */ (function () {
'me.onUpdate = function (timestamp) {\n' + 'me.onUpdate = function (timestamp) {\n' +
' me.current_position = me.position;\n' + ' me.current_position = me.position;\n' +
' var drone_position, drone_velocity_vector, interception_point, drone_view,\n' + ' var drone_position, drone_velocity_vector, interception_point, drone_view,\n' +
' dist = distance(\n' +
' me.current_position,\n' +
' me.base\n' +
' );\n' +
// return to base point if drone is too far
' if (dist >= BASE_DISTANCE) {\n' +
' me.chasing = false;\n' +
' me.setTargetCoordinates(\n' +
' me.base.x,\n' +
' me.base.y,\n' +
' me.base.z\n' +
' );\n' +
' return;\n' +
' }\n' +
' drone_view = me.getDroneViewInfo();\n' + ' drone_view = me.getDroneViewInfo();\n' +
' if (drone_view.length) {\n' + ' if (drone_view.length) {\n' +
' drone_position = drone_view[0].position;\n' + ' drone_position = drone_view[0].position;\n' +
...@@ -273,13 +260,8 @@ var EnemyDroneAPI = /** @class */ (function () { ...@@ -273,13 +260,8 @@ var EnemyDroneAPI = /** @class */ (function () {
' if (!interception_point) {\n' + ' if (!interception_point) {\n' +
' return;\n' + ' return;\n' +
' }\n' + ' }\n' +
' me.chasing = true;\n' +
' me.setTargetCoordinates(interception_point[0], interception_point[1], interception_point[2]);\n' + ' me.setTargetCoordinates(interception_point[0], interception_point[1], interception_point[2]);\n' +
' }\n' + ' }\n' +
// return to base point if drone is too far
' if (!me.chasing && dist <= 10) {\n' +
' me.setDirection(0,0,0);\n' +
' }\n' +
'};'; '};';
}; };
EnemyDroneAPI.prototype.getMinSpeed = function () { EnemyDroneAPI.prototype.getMinSpeed = function () {
...@@ -330,5 +312,8 @@ var EnemyDroneAPI = /** @class */ (function () { ...@@ -330,5 +312,8 @@ var EnemyDroneAPI = /** @class */ (function () {
EnemyDroneAPI.prototype.getFlightParameters = function () { EnemyDroneAPI.prototype.getFlightParameters = function () {
return this._flight_parameters; return this._flight_parameters;
}; };
EnemyDroneAPI.prototype.getCollisionSector = function () {
return this._collision_sector;
};
return EnemyDroneAPI; return EnemyDroneAPI;
}()); }());
...@@ -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.37360.49772.3874</string> </value> <value> <string>1011.20054.25134.60962</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>1688571911.82</float> <float>1695397984.38</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -422,11 +422,11 @@ var FixedWingDroneAPI = /** @class */ (function () { ...@@ -422,11 +422,11 @@ var FixedWingDroneAPI = /** @class */ (function () {
distance = calculateDistance(drone_position, other_position, context); distance = calculateDistance(drone_position, other_position, context);
if (distance <= VIEW_SCOPE) { if (distance <= VIEW_SCOPE) {
result.drones.push({ result.drones.push({
position: drone.getCurrentPosition(), position: other.getCurrentPosition(),
direction: drone.direction, direction: other.direction,
rotation: drone.rotation, rotation: other.rotation,
speed: drone.speed, speed: other.speed,
team: drone.team team: other.team
}); });
} }
} }
......
...@@ -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.45437.13560.55142</string> </value> <value> <string>1011.5610.25987.56473</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>1694531183.74</float> <float>1695395371.67</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -290,6 +290,9 @@ var DroneManager = /** @class */ (function () { ...@@ -290,6 +290,9 @@ var DroneManager = /** @class */ (function () {
DroneManager.prototype.getInitialAltitude = function () { DroneManager.prototype.getInitialAltitude = function () {
return this._API.getInitialAltitude(); return this._API.getInitialAltitude();
}; };
DroneManager.prototype.getCollisionSector = function () {
return this._API.getCollisionSector();
};
DroneManager.prototype.getAltitudeAbs = function () { DroneManager.prototype.getAltitudeAbs = function () {
if (this._controlMesh) { if (this._controlMesh) {
var altitude = this._controlMesh.position.y; var altitude = this._controlMesh.position.y;
...@@ -601,7 +604,6 @@ var MapManager = /** @class */ (function () { ...@@ -601,7 +604,6 @@ var MapManager = /** @class */ (function () {
flag = BABYLON.Mesh.MergeMeshes([flag_a, flag_b, mast]); flag = BABYLON.Mesh.MergeMeshes([flag_a, flag_b, mast]);
flag.id = index; flag.id = index;
flag.location = flag_info.position; flag.location = flag_info.position;
//flag.drone_collider_list = [];
flag.weight = flag_info.weight; flag.weight = flag_info.weight;
flag.score = flag_info.score; flag.score = flag_info.score;
flag.id = index; flag.id = index;
...@@ -611,14 +613,6 @@ var MapManager = /** @class */ (function () { ...@@ -611,14 +613,6 @@ var MapManager = /** @class */ (function () {
MapManager.prototype.getMapInfo = function () { MapManager.prototype.getMapInfo = function () {
return this.map_info; return this.map_info;
}; };
//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) {
lat_offset = offset_in_mt / R,
lon_offset = offset_in_mt / (R * Math.cos(Math.PI * lat / 180));
return [lat + lat_offset * 180 / Math.PI,
lon + lon_offset * 180 / Math.PI];
};*/
MapManager.prototype.latLonDistance = function (c1, c2) { MapManager.prototype.latLonDistance = function (c1, c2) {
return this.mapUtils.latLonDistance(c1, c2); return this.mapUtils.latLonDistance(c1, c2);
}; };
...@@ -834,44 +828,42 @@ var GameManager = /** @class */ (function () { ...@@ -834,44 +828,42 @@ var GameManager = /** @class */ (function () {
flag.weight -= 1; flag.weight -= 1;
drone.score += flag.score; // move score to a global place? GM, MM? drone.score += flag.score; // move score to a global place? GM, MM?
} }
/*if (!flag.drone_collider_list.includes(drone.id)) {
//console.log("flag " + flag.id + " hit by drone " + drone.id);
drone._internal_crash(new Error('Drone ' + drone.id +
' touched a flag.'));
if (flag.drone_collider_list.length === 0) {
drone.score++;
flag.drone_collider_list.push(drone.id);
}
}*/
} }
} }
}; };
GameManager.prototype._checkCollision = function (drone, other) { GameManager.prototype._checkCollision = function (drone, other) {
if (drone.colliderMesh && other.colliderMesh && if (drone.team == TEAM_ENEMY && other.team == TEAM_ENEMY) return;
drone.colliderMesh.intersectsMesh(other.colliderMesh, false)) { function distance(a, b) {
var angle = Math.acos(BABYLON.Vector3.Dot(drone.worldDirection, return Math.sqrt(Math.pow((a.x - b.x), 2) + Math.pow((a.y - b.y), 2) +
other.worldDirection) / Math.pow((a.z - b.z), 2));
(drone.worldDirection.length() * }
other.worldDirection.length())); if (drone.team != other.team) {
//TODO is this parameter set? keep it or make 2 drones die when intersect? var enemy, prey;
if (angle < GAMEPARAMETERS.drone.collisionSector) { if (drone.team == TEAM_ENEMY) {
if (drone.speed > other.speed) { enemy = drone;
other._internal_crash(new Error('Drone ' + drone.id + prey = other;
' bump drone ' + other.id + '.')); } else if (other.team == TEAM_ENEMY) {
} enemy = other;
else { prey = drone;
drone._internal_crash(new Error('Drone ' + other.id +
' bumped drone ' + drone.id + '.'));
}
} }
else { if (drone.position && other.position) {
drone._internal_crash(new Error('Drone ' + drone.id + if (distance(drone.position, other.position) <
' touched drone ' + other.id + '.')); enemy.getCollisionSector()) {
other._internal_crash(new Error('Drone ' + drone.id + drone._internal_crash(new Error('enemy drone ' + enemy.id +
' touched drone ' + other.id + '.')); ' bumped drone ' + prey.id + '.'));
other._internal_crash(new Error('enemy drone ' + enemy.id +
' bumped drone ' + prey.id + '.'));
}
} }
} }
if (drone.colliderMesh && other.colliderMesh &&
drone.colliderMesh.intersectsMesh(other.colliderMesh, false)) {
drone._internal_crash(new Error('drone ' + drone.id +
' touched drone ' + other.id + '.'));
other._internal_crash(new Error('drone ' + drone.id +
' touched drone ' + other.id + '.'));
}
}; };
GameManager.prototype._update = function (delta_time, fullscreen) { GameManager.prototype._update = function (delta_time, fullscreen) {
...@@ -1040,19 +1032,6 @@ var GameManager = /** @class */ (function () { ...@@ -1040,19 +1032,6 @@ var GameManager = /** @class */ (function () {
return finish; return finish;
}; };
//game ends due to timeout or all drones stopped/crashed
/*GameManager.prototype._allFlagsCaptured = function () {
var finish = true;
this._mapManager._flag_list.forEach(function (flag) {
//do not use flag weight for now, just 1 hit is enough
if (flag.drone_collider_list.length === 0) {
//if (flag.drone_collider_list.length < flag.weight) {
finish = false;
}
});
return finish;
};*/
GameManager.prototype._calculateUserScore = function () { GameManager.prototype._calculateUserScore = function () {
var score = 0; var score = 0;
this._droneList_user.forEach(function (drone) { this._droneList_user.forEach(function (drone) {
......
...@@ -246,7 +246,7 @@ ...@@ -246,7 +246,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>1011.9946.55286.52770</string> </value> <value> <string>1011.18882.27011.1501</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>1694792090.7</float> <float>1695327797.6</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -89,102 +89,247 @@ var MapUtils = /** @class */ (function () { ...@@ -89,102 +89,247 @@ var MapUtils = /** @class */ (function () {
/* /*
** Randomizes all map elements: starting point, enemies, flags, obstacles ** Randomizes all map elements: starting point, enemies, flags, obstacles
*/ */
MapUtils.prototype.randomize = function (seed) { MapUtils.prototype.randomizeByBlockTemplates = function (seed) {
//TODO randomize start_ASML, map height, depth and width? function normalize(x, min, max) {
var _this = this, randomized_map = {}; return min + (max - min) * x / 100;
function randomIntFromInterval(min, max, random_seed) {
return Math.floor(random_seed.quick() * (max - min + 1) + min);
}
function randomPosition(random_seed, map_size) {
var sign_x = random_seed.quick() < 0.5 ? -1 : 1,
sign_y = random_seed.quick() < 0.5 ? -1 : 1,
pos_x = sign_x * random_seed.quick() * map_size / 2,
pos_y = sign_y * random_seed.quick() * map_size / 2;
return [pos_x, pos_y];
} }
var random_seed = new Math.seedrandom(seed), i, function fillTemplate(template, min_x, min_y, max_x, max_y) {
n_enemies = randomIntFromInterval(5, 10, random_seed), function fillFlagList(list, min_x, min_y, max_x, max_y) {
n_flags = randomIntFromInterval(5, 10, random_seed), //TODO change range var i, el, result_list = [];
n_obstacles = randomIntFromInterval(5, 15, random_seed), for (i = 0; i < list.length; i += 1) {
flag_list = [], obstacle_list = [], enemy_list = [], random_position, el = {"position":
obstacles_types = ["box", "cylinder"], type, {"x": 0, "y": 0, "z": 0},
obstacle_limit = [_this.map_param.map_size / 6, _this.map_param.map_size / 100, "score": list[i].score,
_this.map_param.map_size / 6, 30], "weight": list[i].weight};
geo_flag_info, geo_obstacle, geo_enemy, coordinates; el.position.x = normalize(list[i].position.x, min_x, max_x);
//enemies el.position.y = normalize(list[i].position.y, min_y, max_y);
for (i = 0; i < n_enemies; i += 1) { //TODO normalize z to map height?
random_position = randomPosition(random_seed, _this.map_param.map_size); el.position.z = list[i].position.z;
enemy_list.push({ result_list.push(el);
"type": "EnemyDroneAPI", }
"position": { return result_list;
"x": random_position[0], }
"y": random_position[1], function fillEnemyList(list, min_x, min_y, max_x, max_y) {
"z": 15 //TODO random z? yes var i, el, result_list = [];
for (i = 0; i < list.length; i += 1) {
el = {"position":
{"x": 0, "y": 0, "z": 0},
"type": list[i].type};
el.position.x = normalize(list[i].position.x, min_x, max_x);
el.position.y = normalize(list[i].position.y, min_y, max_y);
//TODO normalize z to map height?
el.position.z = list[i].position.z;
result_list.push(el);
}
return result_list;
}
function fillObstacleList(list, min_x, min_y, max_x, max_y) {
var i, el, result_list = [];
for (i = 0; i < list.length; i += 1) {
el = {"position":
{"x": 0, "y": 0, "z": 0},
"scale":
{"x": 0, "y": 0, "z": 0},
"type": list[i].type};
if (list[i].rotation) {
el.rotation = {"x": list[i].rotation.x, "y": list[i].rotation.y,
"z": list[i].rotation.z};
}
el.position.x = normalize(list[i].position.x, min_x, max_x);
el.position.y = normalize(list[i].position.y, min_y, max_y);
//TODO normalize z to map height?
el.position.z = list[i].position.z;
el.scale.x = normalize(list[i].scale.x, 0, Math.abs(max_x - min_x));
el.scale.y = normalize(list[i].scale.y, 0, Math.abs(max_x - min_x));
//TODO normalize z to map height?
el.scale.z = list[i].scale.z;
result_list.push(el);
} }
}); return result_list;
}
return {
"flag_list": fillFlagList(template.flag_list, min_x, min_y, max_x, max_y),
"obstacle_list": fillObstacleList(template.obstacle_list, min_x, min_y, max_x, max_y),
"enemy_list": fillEnemyList(template.enemy_list, min_x, min_y, max_x, max_y)
};
} }
//flags // 4x4 grid
for (i = 0; i < n_flags; i += 1) { var GRID = 4, i, j, map_size = this.map_info.map_size, initial_block,
//avoid flags near the limits x1, y1, x2, y2, block_result, index, block_size = map_size / GRID,
random_position = randomPosition(random_seed, _this.map_param.map_size * 0.75); result_map,
flag_list.push({ BLOCK_TEMPLATE_LIST = [{
"position": { "flag_list": [{"position":
"x": random_position[0], {"x": 50, "y": 50, "z": 10},
"y": random_position[1], "score": 1, "weight": 1}],
"z": 10 "obstacle_list": [{"type": "box",
}, "position": {"x": 50, "y": 70, "z": 20},
"score": randomIntFromInterval(1, 5, random_seed), "scale": {"x": 80, "y": 4, "z": 40},
"weight": randomIntFromInterval(1, 5, random_seed) "rotation": {"x": 0, "y": 0, "z": 0}}],
}); "enemy_list": [{"type": "EnemyDroneAPI",
"position": {"x": 50, "y": 30, "z": 10}}
]
}, {
"flag_list": [],
"obstacle_list": [{"type": "box",
"position": {"x": 20, "y": 65, "z": 20},
"scale": {"x": 4, "y": 70, "z": 40},
"rotation": {"x": 0, "y": 0, "z": 0}},
{"type": "box",
"position": {"x": 50, "y": 35, "z": 20},
"scale": {"x": 4, "y": 70, "z": 40},
"rotation": {"x": 0, "y": 0, "z": 0}},
{"type": "box",
"position": {"x": 80, "y": 65, "z": 20},
"scale": {"x": 4, "y": 70, "z": 40},
"rotation": {"x": 0, "y": 0, "z": 0}}],
"enemy_list": []
}, {
"flag_list": [],
"obstacle_list": [{"type": "mountain",
"position": {"x": 50, "y": 50, "z": 200},
"scale": {"x": 80, "y": 80,
"z": 400} //this.map_info.height?
}],
"enemy_list": []
}, {
"flag_list": [],
"obstacle_list": [],
"enemy_list": [{"type": "EnemyDroneAPI",
"position": {"x": 20, "y": 20, "z": 10}},
{"type": "EnemyDroneAPI",
"position": {"x": 20, "y": 80, "z": 10}},
{"type": "EnemyDroneAPI",
"position": {"x": 80, "y": 20, "z": 10}},
{"type": "EnemyDroneAPI",
"position": {"x": 80, "y": 80, "z": 10}}]
}, {
"flag_list": [{"position":
{"x": 50, "y": 50, "z": 10},
"score": 1, "weight": 1}],
"obstacle_list": [],
"enemy_list": []
}, {
"flag_list": [{"position":
{"x": 50, "y": 50, "z": 10},
"score": 1, "weight": 1}],
"obstacle_list": [],
"enemy_list": [{"type": "EnemyDroneAPI",
"position": {"x": 50, "y": 20, "z": 10}},
{"type": "EnemyDroneAPI",
"position": {"x": 50, "y": 80, "z": 10}}]
}, {
"flag_list": [{"position":
{"x": 50, "y": 50, "z": 10},
"score": 1, "weight": 1}],
"obstacle_list": [{"type": "box",
"position": {"x": 50, "y": 10, "z": 25},
"scale": {"x": 80, "y": 2, "z": 50},
"rotation": {"x": 0, "y": 0, "z": 0}},
{"type": "box",
"position": {"x": 10, "y": 50, "z": 25},
"scale": {"x": 2, "y": 80, "z": 50},
"rotation": {"x": 0, "y": 0, "z": 0}},
{"type": "box",
"position": {"x": 50, "y": 90, "z": 25},
"scale": {"x": 80, "y": 2, "z": 50},
"rotation": {"x": 0, "y": 0, "z": 0}},
{"type": "box",
"position": {"x": 90, "y": 50, "z": 25},
"scale": {"x": 2, "y": 80, "z": 50},
"rotation": {"x": 0, "y": 0, "z": 0}}],
"enemy_list": []
}, {
"flag_list": [],
"obstacle_list": [],
"enemy_list": []
}];
function getInitialBlock(GRID) {
var x, y;
do {
x = Math.floor(seed.quick() * GRID);
y = Math.floor(seed.quick() * GRID);
//ensure intial block is in the edge of map
} while (x !== 0 && x !== GRID-1 && y !== 0 && y !== GRID-1);
return {x: x, y: y};
} }
function checkDistance(position, position_list) { initial_block = getInitialBlock(GRID);
function distance(a, b) { function checkConditions(json_map, GRID) {
return Math.sqrt((a.x - b.x) ** 2 + (a.y - b.y) ** 2); if (!json_map) return false;
// set ~20% of the blocks with flags
if (json_map.flag_list.length !== Math.round(GRID * GRID * 0.2)) return false;
// limit n_mountains
if (json_map.obstacle_list.length > 3) {
var i, n_mountains = 0;
for (i = 0; i < json_map.obstacle_list.length; i += 1) {
if (json_map.obstacle_list[i].type === "mountain") {
n_mountains += 1;
if (n_mountains > 3) {
return false;
}
json_map.obstacle_list[i].type = "box";
}
}
} }
var el; var f;
for (el = 0; el < position_list.length; el += 1) { // at least one flag in the oposite side of drones initial position
if (distance(position, position_list[el].position) < _this.map_param.map_size / 6) { for (f = 0; f < json_map.flag_list.length; f += 1) {
if ((json_map.flag_list[f].position.x * json_map.initial_position.x) < 0 ||
(json_map.flag_list[f].position.y * json_map.initial_position.y) < 0) {
return true; return true;
} }
} }
return false; return false;
} }
//obstacles do {
for (i = 0; i < n_obstacles; i += 1) { result_map = {
random_position = randomPosition(random_seed, _this.map_param.map_size); "flag_list": [],
if (checkDistance({ 'x': random_position[0], "obstacle_list": [],
'y': random_position[1]}, flag_list)) { "enemy_list": []
i -= 1; };
} else { for (i = 0; i < GRID; i += 1) {
type = randomIntFromInterval(0, 2, random_seed); for (j = 0; j < GRID; j += 1) {
obstacle_list.push({ index = Math.floor(seed.quick() * BLOCK_TEMPLATE_LIST.length);
"type": obstacles_types[type], x1 = block_size * i - map_size / 2;
"position": { y1 = block_size * j - map_size / 2;
"x": random_position[0], x2 = block_size * i + block_size - map_size / 2;
"y": random_position[1], y2 = block_size * j + block_size - map_size / 2;
"z": 15 //TODO random z? if (initial_block.x === i && initial_block.y === j) {
}, result_map.initial_position = {x: normalize(50, x1, x2),
"scale": { y: normalize(50, y1, y2),
"x": randomIntFromInterval(20, obstacle_limit[type], random_seed), z: 15 };
"y": randomIntFromInterval(20, obstacle_limit[type], random_seed), } else {
"z": randomIntFromInterval(5, obstacle_limit[3], random_seed) block_result = fillTemplate(BLOCK_TEMPLATE_LIST[index], x1, y1, x2, y2);
}, result_map.flag_list = result_map.flag_list.concat(block_result.flag_list);
"rotation": { result_map.obstacle_list = result_map.obstacle_list.concat(block_result.obstacle_list);
"x": 0, result_map.enemy_list = result_map.enemy_list.concat(block_result.enemy_list);
"y": 0,
"z": 0
} }
}); }
} }
} } while (!checkConditions(result_map, GRID));
return result_map;
};
/*
** Generates a random map json
*/
MapUtils.prototype.randomize = function (seed) {
//TODO randomize start_ASML, map height, depth and width?
var _this = this, flag_list, obstacle_list, enemy_list,
geo_flag_info, geo_obstacle, geo_enemy, coordinates,
random_seed = new Math.seedrandom(seed),
randomized_map = _this.randomizeByBlockTemplates(random_seed);
obstacle_list = randomized_map.obstacle_list;
enemy_list = randomized_map.enemy_list;
flag_list = randomized_map.flag_list;
_this.map_param.obstacle_list = []; _this.map_param.obstacle_list = [];
_this.map_param.enemy_list = []; _this.map_param.enemy_list = [];
_this.map_param.flag_list = []; _this.map_param.flag_list = [];
//TODO make it random //convert all map elements positions to geo coordinates
_this.map_info.initial_position = _this.convertToGeoCoordinates( _this.map_info.initial_position = _this.convertToGeoCoordinates(
0, _this.map_param.map_size / 2 * -0.75, 15 randomized_map.initial_position.x,
randomized_map.initial_position.y,
randomized_map.initial_position.z
); );
//convert all map elements positions to geo coordinates
Object.assign(_this.map_info, _this.map_param); Object.assign(_this.map_info, _this.map_param);
flag_list.forEach(function (flag_info, index) { flag_list.forEach(function (flag_info, index) {
coordinates = _this.convertToGeoCoordinates( coordinates = _this.convertToGeoCoordinates(
......
...@@ -242,7 +242,7 @@ ...@@ -242,7 +242,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>1011.8487.12042.61832</string> </value> <value> <string>1011.18883.7641.45704</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -262,7 +262,7 @@ ...@@ -262,7 +262,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1694782467.44</float> <float>1695327563.61</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -39,7 +39,7 @@ var OperatorAPI = /** @class */ (function () { ...@@ -39,7 +39,7 @@ var OperatorAPI = /** @class */ (function () {
//seed //seed
//url_sp = new URLSearchParams(window.location.hash), //url_sp = new URLSearchParams(window.location.hash),
//url_seed = url_sp.get("seed"), //url_seed = url_sp.get("seed"),
SEED = '6!',//url_seed ? url_seed : '6!', SEED = '123',//'6!',
MAP = { MAP = {
"height": MAP_HEIGHT, "height": MAP_HEIGHT,
"start_AMSL": START_AMSL, "start_AMSL": START_AMSL,
...@@ -61,7 +61,8 @@ var OperatorAPI = /** @class */ (function () { ...@@ -61,7 +61,8 @@ var OperatorAPI = /** @class */ (function () {
"rotation": {"x": 0, "y": 0, "z": 0}}], "rotation": {"x": 0, "y": 0, "z": 0}}],
"enemy_list": [{"type": "EnemyDroneAPI", "enemy_list": [{"type": "EnemyDroneAPI",
"position": {"x": 45.6455531, "position": {"x": 45.6455531,
"y": 14.270231599999988, "z": 15}}], "y": 14.270747186236491,
"z": 15}}],
"initial_position": {"x": 45.642813275, "y": 14.270231599999988, "z": 15} "initial_position": {"x": 45.642813275, "y": 14.270231599999988, "z": 15}
}, },
DEFAULT_SPEED = 16, DEFAULT_SPEED = 16,
...@@ -76,7 +77,7 @@ var OperatorAPI = /** @class */ (function () { ...@@ -76,7 +77,7 @@ var OperatorAPI = /** @class */ (function () {
MAX_SINK_RATE = 3, MAX_SINK_RATE = 3,
NUMBER_OF_DRONES = 5, NUMBER_OF_DRONES = 5,
// Non-inputs parameters // Non-inputs parameters
EPSILON = 15, EPSILON = "15",
DEFAULT_OPERATOR_SCRIPT = 'var map = operator.getMapJSON();\n' + DEFAULT_OPERATOR_SCRIPT = 'var map = operator.getMapJSON();\n' +
'operator.sendMsg({flag_positions: map.flag_list});\n', 'operator.sendMsg({flag_positions: map.flag_list});\n',
DEFAULT_SCRIPT_CONTENT = DEFAULT_SCRIPT_CONTENT =
......
...@@ -246,7 +246,7 @@ ...@@ -246,7 +246,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>1011.10069.44691.10922</string> </value> <value> <string>1011.18818.32686.32580</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>1694798760.01</float> <float>1695397751.99</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