mirror of
https://github.com/30hours/3lips.git
synced 2024-11-08 12:25:42 +00:00
Input handling and general cleanup
This commit is contained in:
parent
2ac180714e
commit
ad19fe9754
11 changed files with 129 additions and 38 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1 +1,2 @@
|
||||||
**/__pycache__/
|
**/__pycache__/
|
||||||
|
save/
|
||||||
|
|
|
@ -13,4 +13,4 @@ EXPOSE 5000
|
||||||
ENV FLASK_APP=api.py
|
ENV FLASK_APP=api.py
|
||||||
|
|
||||||
# run Gunicorn instead of the default Flask development server
|
# run Gunicorn instead of the default Flask development server
|
||||||
CMD ["gunicorn", "--bind", "0.0.0.0:5000", "--timeout", "60", "main:app"]
|
CMD ["gunicorn", "--bind", "0.0.0.0:5000", "--timeout", "60", "api:app"]
|
||||||
|
|
|
@ -9,21 +9,32 @@ import os
|
||||||
import requests
|
import requests
|
||||||
import time
|
import time
|
||||||
import asyncio
|
import asyncio
|
||||||
|
import yaml
|
||||||
|
|
||||||
from common.Message import Message
|
from common.Message import Message
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
|
|
||||||
|
# init config file
|
||||||
|
try:
|
||||||
|
with open('config/config.yml', 'r') as file:
|
||||||
|
config = yaml.safe_load(file)
|
||||||
|
radar_data = config['radar']
|
||||||
|
except FileNotFoundError:
|
||||||
|
print("Error: Configuration file not found.")
|
||||||
|
except yaml.YAMLError as e:
|
||||||
|
print("Error reading YAML configuration:", e)
|
||||||
|
|
||||||
# store state data
|
# store state data
|
||||||
servers = [
|
servers = []
|
||||||
{"name": "radar4", "url": "radar4.30hours.dev"},
|
for radar in radar_data:
|
||||||
{"name": "radar5", "url": "radar5.30hours.dev"},
|
if radar['name'] and radar['url']:
|
||||||
{"name": "radar6", "url": "radar6.30hours.dev"}
|
servers.append({'name': radar['name'], 'url': radar['url']})
|
||||||
]
|
|
||||||
associators = [
|
associators = [
|
||||||
{"name": "ADSB Associator", "id": "adsb-associator"}
|
{"name": "ADSB Associator", "id": "adsb-associator"}
|
||||||
]
|
]
|
||||||
# todo: ellipse conic int (analytic), SX, arc length
|
|
||||||
localisations = [
|
localisations = [
|
||||||
{"name": "Ellipse Parametric (Mean)", "id": "ellipse-parametric-mean"},
|
{"name": "Ellipse Parametric (Mean)", "id": "ellipse-parametric-mean"},
|
||||||
{"name": "Ellipse Parametric (Min)", "id": "ellipse-parametric-min"},
|
{"name": "Ellipse Parametric (Min)", "id": "ellipse-parametric-min"},
|
||||||
|
@ -31,11 +42,19 @@ localisations = [
|
||||||
{"name": "Ellipsoid Parametric (Min)", "id": "ellipsoid-parametric-min"},
|
{"name": "Ellipsoid Parametric (Min)", "id": "ellipsoid-parametric-min"},
|
||||||
{"name": "Spherical Intersection", "id": "spherical-intersection"}
|
{"name": "Spherical Intersection", "id": "spherical-intersection"}
|
||||||
]
|
]
|
||||||
|
|
||||||
adsbs = [
|
adsbs = [
|
||||||
{"name": "adsb.30hours.dev", "url": "adsb.30hours.dev"},
|
{"name": "adsb.30hours.dev", "url": "adsb.30hours.dev"},
|
||||||
{"name": "None", "url": ""}
|
{"name": "None", "url": ""}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# store valid ids
|
||||||
|
valid = {}
|
||||||
|
valid['servers'] = [item['url'] for item in servers]
|
||||||
|
valid['associators'] = [item['id'] for item in associators]
|
||||||
|
valid['localisations'] = [item['id'] for item in localisations]
|
||||||
|
valid['adsbs'] = [item['url'] for item in adsbs]
|
||||||
|
|
||||||
# message received callback
|
# message received callback
|
||||||
async def callback_message_received(msg):
|
async def callback_message_received(msg):
|
||||||
print(f"Callback: Received message in main.py: {msg}", flush=True)
|
print(f"Callback: Received message in main.py: {msg}", flush=True)
|
||||||
|
@ -58,6 +77,20 @@ def serve_static(file):
|
||||||
@app.route("/api")
|
@app.route("/api")
|
||||||
def api():
|
def api():
|
||||||
api = request.query_string.decode('utf-8')
|
api = request.query_string.decode('utf-8')
|
||||||
|
# input protection
|
||||||
|
servers_api = request.args.getlist('server')
|
||||||
|
associators_api = request.args.getlist('associator')
|
||||||
|
localisations_api = request.args.getlist('localisation')
|
||||||
|
adsbs_api = request.args.getlist('adsb')
|
||||||
|
if not all(item in valid['servers'] for item in servers_api):
|
||||||
|
return 'Invalid server'
|
||||||
|
if not all(item in valid['associators'] for item in associators_api):
|
||||||
|
return 'Invalid associator'
|
||||||
|
if not all(item in valid['localisations'] for item in localisations_api):
|
||||||
|
return 'Invalid localisation'
|
||||||
|
if not all(item in valid['adsbs'] for item in adsbs_api):
|
||||||
|
return 'Invalid ADSB']
|
||||||
|
# send to event handler
|
||||||
try:
|
try:
|
||||||
reply_chunks = message_api_request.send_message(api)
|
reply_chunks = message_api_request.send_message(api)
|
||||||
reply = ''.join(reply_chunks)
|
reply = ''.join(reply_chunks)
|
|
@ -179,6 +179,27 @@ if (cesiumCredit) {
|
||||||
return pointEntity;
|
return pointEntity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function is_localhost(ip) {
|
||||||
|
|
||||||
|
if (ip === 'localhost') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ip = ip.replace(/^https?:\/\//, "");
|
||||||
|
|
||||||
|
const localRanges = ['127.0.0.1', '192.168.0.0/16', '10.0.0.0/8', '172.16.0.0/12'];
|
||||||
|
|
||||||
|
const ipToInt = ip => ip.split('.').reduce((acc, octet) => (acc << 8) + +octet, 0) >>> 0;
|
||||||
|
|
||||||
|
return localRanges.some(range => {
|
||||||
|
const [rangeStart, rangeSize = 32] = range.split('/');
|
||||||
|
const start = ipToInt(rangeStart);
|
||||||
|
const end = (start | (1 << (32 - +rangeSize))) >>> 0;
|
||||||
|
return ipToInt(ip) >= start && ipToInt(ip) <= end;
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// global vars
|
// global vars
|
||||||
var adsb_url;
|
var adsb_url;
|
||||||
var adsbEntities = {};
|
var adsbEntities = {};
|
||||||
|
@ -193,13 +214,14 @@ window.addEventListener('load', function () {
|
||||||
// add radar points
|
// add radar points
|
||||||
const radar_names = new URLSearchParams(
|
const radar_names = new URLSearchParams(
|
||||||
window.location.search).getAll('server');
|
window.location.search).getAll('server');
|
||||||
console.log(radar_names);
|
|
||||||
var radar_config_url = radar_names.map(
|
var radar_config_url = radar_names.map(
|
||||||
url => `http://${url}/api/config`);
|
url => `http://${url}/api/config`);
|
||||||
if (this.window.location.protocol === "https:") {
|
radar_config_url.forEach(function(url) {
|
||||||
|
if (!is_localhost(url)) {
|
||||||
radar_config_url = radar_config_url.map(
|
radar_config_url = radar_config_url.map(
|
||||||
url => url.replace(/^http:/, 'https:'));
|
url => url.replace(/^http:/, 'https:'));
|
||||||
}
|
}
|
||||||
|
});
|
||||||
var style_radar = {};
|
var style_radar = {};
|
||||||
style_radar.color = 'rgba(0, 0, 0, 1.0)';
|
style_radar.color = 'rgba(0, 0, 0, 1.0)';
|
||||||
style_radar.pointSize = 10;
|
style_radar.pointSize = 10;
|
||||||
|
@ -241,19 +263,16 @@ window.addEventListener('load', function () {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
// Handle errors during fetch
|
|
||||||
console.error('Error during fetch:', error);
|
console.error('Error during fetch:', error);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// get detection data URL
|
|
||||||
|
|
||||||
// get truth URL
|
// get truth URL
|
||||||
adsb_url = new URLSearchParams(
|
adsb_url = new URLSearchParams(
|
||||||
window.location.search).get('adsb').split('&');
|
window.location.search).get('adsb').split('&');
|
||||||
adsb_url = adsb_url.map(
|
adsb_url = adsb_url.map(
|
||||||
url => `http://${url}/data/aircraft.json`);
|
url => `http://${url}/data/aircraft.json`);
|
||||||
if (this.window.location.protocol === "https:") {
|
if (!is_localhost(adsb_url[0])) {
|
||||||
adsb_url = adsb_url.map(
|
adsb_url = adsb_url.map(
|
||||||
url => url.replace(/^http:/, 'https:'));
|
url => url.replace(/^http:/, 'https:'));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
Flask==3.0.1
|
Flask==3.0.1
|
||||||
gunicorn==21.2.0
|
gunicorn==21.2.0
|
||||||
requests==2.31.0
|
requests==2.31.0
|
||||||
|
PyYAML==6.0.1
|
26
config/config.yml
Normal file
26
config/config.yml
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
radar:
|
||||||
|
- name: radar4
|
||||||
|
url: radar4.30hours.dev
|
||||||
|
- name: radar5
|
||||||
|
url: radar5.30hours.dev
|
||||||
|
- name: radar6
|
||||||
|
url: radar6.30hours.dev
|
||||||
|
|
||||||
|
associate:
|
||||||
|
adsb:
|
||||||
|
tar1090: 'adsb.30hours.dev'
|
||||||
|
tDelete: 5
|
||||||
|
|
||||||
|
localisation:
|
||||||
|
ellipse:
|
||||||
|
nSamples: 100
|
||||||
|
threshold: 500
|
||||||
|
nDisplay: 50
|
||||||
|
ellipsoid:
|
||||||
|
nSamples: 60
|
||||||
|
threshold: 500
|
||||||
|
nDisplay: 50
|
||||||
|
|
||||||
|
3lips:
|
||||||
|
save: true
|
||||||
|
tDelete: 60
|
|
@ -16,6 +16,7 @@ services:
|
||||||
networks:
|
networks:
|
||||||
- 3lips
|
- 3lips
|
||||||
volumes:
|
volumes:
|
||||||
|
- ./config:/app/config
|
||||||
- ./common:/app/common
|
- ./common:/app/common
|
||||||
container_name: 3lips-api
|
container_name: 3lips-api
|
||||||
|
|
||||||
|
@ -28,6 +29,7 @@ services:
|
||||||
networks:
|
networks:
|
||||||
- 3lips
|
- 3lips
|
||||||
volumes:
|
volumes:
|
||||||
|
- ./config:/app/config
|
||||||
- ./common:/app/common
|
- ./common:/app/common
|
||||||
- ./test:/app/test
|
- ./test:/app/test
|
||||||
- ./save:/app/save
|
- ./save:/app/save
|
||||||
|
|
|
@ -49,15 +49,11 @@ class EllipseParametric:
|
||||||
|
|
||||||
for target in assoc_detections:
|
for target in assoc_detections:
|
||||||
|
|
||||||
print(target, flush=True)
|
|
||||||
target_samples = {}
|
target_samples = {}
|
||||||
target_samples[target] = {}
|
target_samples[target] = {}
|
||||||
|
|
||||||
for radar in assoc_detections[target]:
|
for radar in assoc_detections[target]:
|
||||||
|
|
||||||
print(radar["radar"], flush=True)
|
|
||||||
print(radar["delay"], flush=True)
|
|
||||||
|
|
||||||
# create ellipsoid for radar
|
# create ellipsoid for radar
|
||||||
ellipsoid = next((
|
ellipsoid = next((
|
||||||
item for item in self.ellipsoids
|
item for item in self.ellipsoids
|
||||||
|
|
|
@ -46,15 +46,11 @@ class EllipsoidParametric:
|
||||||
|
|
||||||
for target in assoc_detections:
|
for target in assoc_detections:
|
||||||
|
|
||||||
print(target, flush=True)
|
|
||||||
target_samples = {}
|
target_samples = {}
|
||||||
target_samples[target] = {}
|
target_samples[target] = {}
|
||||||
|
|
||||||
for radar in assoc_detections[target]:
|
for radar in assoc_detections[target]:
|
||||||
|
|
||||||
print(radar["radar"], flush=True)
|
|
||||||
print(radar["delay"], flush=True)
|
|
||||||
|
|
||||||
# create ellipsoid for radar
|
# create ellipsoid for radar
|
||||||
ellipsoid = next((
|
ellipsoid = next((
|
||||||
item for item in self.ellipsoids
|
item for item in self.ellipsoids
|
||||||
|
@ -142,9 +138,6 @@ class EllipsoidParametric:
|
||||||
output[target] = {}
|
output[target] = {}
|
||||||
output[target]["points"] = []
|
output[target]["points"] = []
|
||||||
|
|
||||||
print('test', flush=True)
|
|
||||||
print(samples_intersect, flush=True)
|
|
||||||
|
|
||||||
for i in range(len(samples_intersect)):
|
for i in range(len(samples_intersect)):
|
||||||
samples_intersect[i] = Geometry.ecef2lla(
|
samples_intersect[i] = Geometry.ecef2lla(
|
||||||
samples_intersect[i][0],
|
samples_intersect[i][0],
|
||||||
|
|
|
@ -13,6 +13,7 @@ import copy
|
||||||
import json
|
import json
|
||||||
import hashlib
|
import hashlib
|
||||||
import os
|
import os
|
||||||
|
import yaml
|
||||||
|
|
||||||
from algorithm.associator.AdsbAssociator import AdsbAssociator
|
from algorithm.associator.AdsbAssociator import AdsbAssociator
|
||||||
from algorithm.localisation.EllipseParametric import EllipseParametric
|
from algorithm.localisation.EllipseParametric import EllipseParametric
|
||||||
|
@ -23,19 +24,36 @@ from common.Message import Message
|
||||||
from data.Ellipsoid import Ellipsoid
|
from data.Ellipsoid import Ellipsoid
|
||||||
from algorithm.geometry.Geometry import Geometry
|
from algorithm.geometry.Geometry import Geometry
|
||||||
|
|
||||||
|
# init config file
|
||||||
|
try:
|
||||||
|
with open('config/config.yml', 'r') as file:
|
||||||
|
config = yaml.safe_load(file)
|
||||||
|
nSamplesEllipse = config['localisation']['ellipse']['nSamples']
|
||||||
|
thresholdEllipse = config['localisation']['ellipse']['threshold']
|
||||||
|
nDisplayEllipse = config['localisation']['ellipse']['nDisplay']
|
||||||
|
nSamplesEllipsoid = config['localisation']['ellipsoid']['nSamples']
|
||||||
|
thresholdEllipsoid = config['localisation']['ellipsoid']['threshold']
|
||||||
|
nDisplayEllipsoid = config['localisation']['ellipsoid']['nDisplay']
|
||||||
|
tDeleteAdsb = config['associate']['adsb']['tDelete']
|
||||||
|
save = config['3lips']['save']
|
||||||
|
tDelete = config['3lips']['tDelete']
|
||||||
|
except FileNotFoundError:
|
||||||
|
print("Error: Configuration file not found.")
|
||||||
|
except yaml.YAMLError as e:
|
||||||
|
print("Error reading YAML configuration:", e)
|
||||||
|
|
||||||
# init event loop
|
# init event loop
|
||||||
api = []
|
api = []
|
||||||
|
|
||||||
# init config
|
# init config
|
||||||
tDelete = 60
|
tDelete = tDelete
|
||||||
adsbAssociator = AdsbAssociator()
|
adsbAssociator = AdsbAssociator()
|
||||||
ellipseParametricMean = EllipseParametric("mean", 150, 500)
|
ellipseParametricMean = EllipseParametric("mean", nSamplesEllipse, thresholdEllipse)
|
||||||
ellipseParametricMin = EllipseParametric("min", 150, 500)
|
ellipseParametricMin = EllipseParametric("min", nSamplesEllipse, thresholdEllipse)
|
||||||
ellipsoidParametricMean = EllipsoidParametric("mean", 60, 800)
|
ellipsoidParametricMean = EllipsoidParametric("mean", nSamplesEllipsoid, thresholdEllipsoid)
|
||||||
ellipsoidParametricMin = EllipsoidParametric("min", 60, 800)
|
ellipsoidParametricMin = EllipsoidParametric("min", nSamplesEllipsoid, thresholdEllipsoid)
|
||||||
sphericalIntersection = SphericalIntersection()
|
sphericalIntersection = SphericalIntersection()
|
||||||
adsbTruth = AdsbTruth(5)
|
adsbTruth = AdsbTruth(tDeleteAdsb)
|
||||||
save = True
|
|
||||||
saveFile = '/app/save/' + str(int(time.time())) + '.ndjson'
|
saveFile = '/app/save/' + str(int(time.time())) + '.ndjson'
|
||||||
|
|
||||||
async def event():
|
async def event():
|
||||||
|
@ -139,6 +157,9 @@ async def event():
|
||||||
for key, value in associated_dets.items()
|
for key, value in associated_dets.items()
|
||||||
if isinstance(value, list) and len(value) >= 3
|
if isinstance(value, list) and len(value) >= 3
|
||||||
}
|
}
|
||||||
|
if associated_dets_3_radars:
|
||||||
|
print('Detections from 3 or more radars availble.')
|
||||||
|
print(associated_dets_3_radars)
|
||||||
associated_dets_2_radars = {
|
associated_dets_2_radars = {
|
||||||
key: value
|
key: value
|
||||||
for key, value in associated_dets.items()
|
for key, value in associated_dets.items()
|
||||||
|
@ -176,7 +197,7 @@ async def event():
|
||||||
[x_rx, y_rx, z_rx],
|
[x_rx, y_rx, z_rx],
|
||||||
radar["radar"]
|
radar["radar"]
|
||||||
)
|
)
|
||||||
points = localisation.sample(ellipsoid, radar["delay"]*1000, 50)
|
points = localisation.sample(ellipsoid, radar["delay"]*1000, nDisplayEllipse)
|
||||||
for i in range(len(points)):
|
for i in range(len(points)):
|
||||||
lat, lon, alt = Geometry.ecef2lla(points[i][0], points[i][1], points[i][2])
|
lat, lon, alt = Geometry.ecef2lla(points[i][0], points[i][1], points[i][2])
|
||||||
if item["localisation"] == "ellipsoid-parametric-mean" or \
|
if item["localisation"] == "ellipsoid-parametric-mean" or \
|
||||||
|
@ -239,8 +260,6 @@ def short_hash(input_string, length=10):
|
||||||
# message received callback
|
# message received callback
|
||||||
async def callback_message_received(msg):
|
async def callback_message_received(msg):
|
||||||
|
|
||||||
#print(f"Callback: Received message in event.py: {msg}", flush=True)
|
|
||||||
|
|
||||||
timestamp = int(time.time()*1000)
|
timestamp = int(time.time()*1000)
|
||||||
|
|
||||||
# update timestamp if API entry exists
|
# update timestamp if API entry exists
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
numpy==1.26.4
|
numpy==1.26.4
|
||||||
requests==2.31.0
|
requests==2.31.0
|
||||||
|
PyYAML==6.0.1
|
Loading…
Reference in a new issue