LoRaWAN-Signal-Mapping/client_src/js/Worker/AIWrapper.mjs

85 lines
1.8 KiB
JavaScript

"use strict";
import path from 'path';
import {
loadLayersModel as tf_loadLayersModel,
tensor as tf_tensor
} from '@tensorflow/tfjs';
import { normalise } from '../../common/Math.mjs';
import Config from '../ClientConfig.mjs';
class AIWrapper {
constructor() {
this.setup_complete = false;
this.map_bounds = null;
this.index = null;
this.gateways = new Map();
}
async setup({ bounds, index }) {
this.map_bounds = bounds;
this.index = index;
for(let gateway of this.index.index) {
this.gateways.set(
gateway.id,
await tf_loadLayersModel(`${window.location.href}/${path.dirname(Config.ai_index_file)}/${gateway.id}/model.json`)
);
}
this.setup_complete = true;
}
predict_row(lat) {
if(!setup_complete)
throw new Error("Error: Can't do predictions until the setup is complete.");
let results = [],
stats = {
rssi_min: Infinity,
rssi_max: -Infinity
};
for(let lng = this.map_bounds.west; lng < this.map_bounds.east; lng += Config.step.lng) {
let max_predicted_rssi = -Infinity;
for(let [, ai] of this.gateways) {
let next_prediction = this.predict_value(lat, lng)
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 };
}
predict_value(latitude, longitude) {
return ai.predict(
tf_tensor([ latitude, longitude ], [1, 2])
).arraySync()[0][0];
}
}
export default AIWrapper;