2019-07-25 15:44:26 +00:00
|
|
|
"use strict";
|
|
|
|
|
|
|
|
import path from 'path';
|
|
|
|
|
|
|
|
import {
|
|
|
|
loadLayersModel as tf_loadLayersModel,
|
2019-07-25 17:56:59 +00:00
|
|
|
tensor as tf_tensor,
|
|
|
|
setBackend as tf_setBackend
|
2019-07-25 15:44:26 +00:00
|
|
|
} from '@tensorflow/tfjs';
|
|
|
|
|
2019-07-25 17:56:59 +00:00
|
|
|
import { normalise } from '../../../common/Math.mjs';
|
2019-07-25 15:44:26 +00:00
|
|
|
|
|
|
|
class AIWrapper {
|
|
|
|
constructor() {
|
|
|
|
this.setup_complete = false;
|
|
|
|
|
|
|
|
this.map_bounds = null;
|
|
|
|
this.index = null;
|
2019-07-25 17:56:59 +00:00
|
|
|
this.Config = null;
|
2019-07-25 15:44:26 +00:00
|
|
|
|
|
|
|
this.gateways = new Map();
|
|
|
|
}
|
|
|
|
|
2019-07-25 17:56:59 +00:00
|
|
|
async setup({ bounds, index, Config }) {
|
2019-07-25 15:44:26 +00:00
|
|
|
this.map_bounds = bounds;
|
|
|
|
this.index = index;
|
2019-07-25 17:56:59 +00:00
|
|
|
this.Config = Config;
|
|
|
|
|
|
|
|
console.log("Loading models");
|
|
|
|
|
|
|
|
// WebGL isn't available inside WebWorkers yet :-(
|
|
|
|
tf_setBackend("cpu");
|
2019-07-25 15:44:26 +00:00
|
|
|
|
|
|
|
for(let gateway of this.index.index) {
|
|
|
|
this.gateways.set(
|
|
|
|
gateway.id,
|
2019-07-25 17:56:59 +00:00
|
|
|
await tf_loadLayersModel(`${path.dirname(self.location.href)}/${path.dirname(this.Config.ai_index_file)}/${gateway.id}/model.json`)
|
2019-07-25 15:44:26 +00:00
|
|
|
);
|
|
|
|
}
|
2019-07-25 17:56:59 +00:00
|
|
|
console.log("Model setup complete.");
|
2019-07-25 15:44:26 +00:00
|
|
|
this.setup_complete = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
predict_row(lat) {
|
2019-07-25 17:56:59 +00:00
|
|
|
if(!this.setup_complete)
|
2019-07-25 15:44:26 +00:00
|
|
|
throw new Error("Error: Can't do predictions until the setup is complete.");
|
|
|
|
|
2019-07-25 17:56:59 +00:00
|
|
|
let result = [],
|
2019-07-25 15:44:26 +00:00
|
|
|
stats = {
|
|
|
|
rssi_min: Infinity,
|
|
|
|
rssi_max: -Infinity
|
|
|
|
};
|
|
|
|
|
2019-07-25 17:56:59 +00:00
|
|
|
for(let lng = this.map_bounds.west; lng < this.map_bounds.east; lng += this.Config.step.lng) {
|
2019-07-25 15:44:26 +00:00
|
|
|
let max_predicted_rssi = -Infinity;
|
|
|
|
|
|
|
|
for(let [, ai] of this.gateways) {
|
2019-07-25 17:56:59 +00:00
|
|
|
let next_prediction = ai.predict(
|
|
|
|
tf_tensor([ lat, lng ], [1, 2])
|
|
|
|
).arraySync()[0][0];
|
2019-07-25 15:44:26 +00:00
|
|
|
max_predicted_rssi = Math.max(
|
|
|
|
max_predicted_rssi,
|
|
|
|
next_prediction
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
max_predicted_rssi = normalise(max_predicted_rssi,
|
|
|
|
{ min: 0, max: 1 },
|
|
|
|
{
|
|
|
|
min: this.index.properties.rssi_min,
|
|
|
|
max: this.index.properties.rssi_max
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
if(max_predicted_rssi > stats.rssi_max)
|
|
|
|
stats.rssi_max = max_predicted_rssi;
|
|
|
|
if(max_predicted_rssi < stats.rssi_min)
|
|
|
|
stats.rssi_min = max_predicted_rssi;
|
|
|
|
|
|
|
|
result.push(max_predicted_rssi);
|
|
|
|
}
|
|
|
|
|
|
|
|
return { result, stats };
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export default AIWrapper;
|