Plot points from radar rx/tx in cesium

This commit is contained in:
30hours 2024-02-12 13:46:19 +00:00
parent aaab58d2ea
commit abce360cca
3 changed files with 180 additions and 27 deletions

View file

@ -133,3 +133,110 @@ var viewer = new Cesium.Viewer("cesiumContainer", {
selectionIndicator: false selectionIndicator: false
}); });
/**
* @brief Adds a point to Cesium viewer with specified parameters.
* @param {number} latitude - The latitude of the point in degrees.
* @param {number} longitude - The longitude of the point in degrees.
* @param {number} altitude - The altitude of the point in meters.
* @param {string} pointName - The name of the point.
* @param {string} pointColor - The color of the point in CSS color string format.
* @param {number} timestamp - The timestamp in UNIX milliseconds indicating when the point was added.
* @returns {Entity} The Cesium Entity representing the added point.
*/
function addPoint(latitude, longitude, altitude, pointName, pointColor, pointSize, type, timestamp) {
// Convert latitude, longitude, altitude to Cartesian coordinates (ECEF)
const position = Cesium.Cartesian3.fromDegrees(longitude, latitude, altitude);
// Create a point entity
const pointEntity = viewer.entities.add({
position,
point: {
color: Cesium.Color.fromCssColorString(pointColor),
pixelSize: pointSize,
},
label: (type === "radar") ? {
text: pointName,
showBackground: true,
backgroundColor: Cesium.Color.BLACK,
font: '14px sans-serif',
pixelOffset: new Cesium.Cartesian2(0, -20),
} : undefined,
properties: {
timestamp,
type,
},
});
return pointEntity;
}
window.addEventListener('load', function () {
// add radar points
const radar_names = new URLSearchParams(
window.location.search).get('url').split('&');
var radar_config_url = radar_names.map(
url => `http://${url}/api/config`);
if (this.window.location.protocol === "https:") {
radar_config_url = radar_config_url.map(
url => url.replace(/^http:/, 'https:'));
}
var style_radar = {};
style_radar.color = 'rgba(0, 0, 0, 1.0)';
style_radar.pointSize = 10;
style_radar.type = "radar";
style_radar.timestamp = Date.now();
radar_config_url.forEach(url => {
console.log(url);
fetch(url)
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
// add radar rx and tx
addPoint(
data.location.rx.latitude,
data.location.rx.longitude,
data.location.rx.altitude,
data.location.rx.name,
style_radar.color,
style_radar.pointSize,
style_radar.type,
style_radar.timestamp
);
addPoint(
data.location.tx.latitude,
data.location.tx.longitude,
data.location.tx.altitude,
data.location.tx.name,
style_radar.color,
style_radar.pointSize,
style_radar.type,
style_radar.timestamp
);
})
.catch(error => {
// Handle errors during fetch
console.error('Error during fetch:', error);
});
});
// get detection data URL
// get truth URL
// call event loop
event_loop();
})
function event_loop() {
//console.log(Date.now());
setTimeout(event_loop, 1000);
}

View file

@ -4,17 +4,19 @@
""" """
import requests import requests
import math
class AdsbAssociator: class AdsbAssociator:
""" """
@class AdsbAssociator @class AdsbAssociator
@brief A class for associating detections of the same target. @brief A class for associating detections of the same target.
@details Girst associate ADS-B truth with each radar detection. @details First associate ADS-B truth with each radar detection.
Then associate over multiple radars. Then associate over multiple radars.
@see blah2 at https://github.com/30hours/blah2. @see blah2 at https://github.com/30hours/blah2.
Uses truth data in delay-Doppler space from an adsb2dd server. Uses truth data in delay-Doppler space from an adsb2dd server.
@see adsb2dd at https://github.com/30hours/adsb2dd. @see adsb2dd at https://github.com/30hours/adsb2dd.
@todo Add adjustable window for associating truth/detections.
""" """
def __init__(self): def __init__(self):
@ -33,6 +35,7 @@ class AdsbAssociator:
""" """
assoc_detections = {} assoc_detections = {}
assoc_detections_radar = []
for radar in radar_list: for radar in radar_list:
@ -50,26 +53,56 @@ class AdsbAssociator:
except requests.exceptions.RequestException as e: except requests.exceptions.RequestException as e:
print(f"Error fetching data from {url}: {e}") print(f"Error fetching data from {url}: {e}")
adsb_detections = None adsb_detections = None
continue
# associate radar and truth # associate radar and truth
print(adsb_detections, flush=True) assoc_detections_radar.append(self.process_1_radar(
radar, radar_data[radar]["detection"], adsb_detections))
# associate detections between radars
print(assoc_detections_radar, flush=True)
#print(radar_list, flush=True) def process_1_radar(self, radar, radar_detections, adsb_detections):
#print(radar_data, flush=True)
def process_1_radar(self, radar_detections, adsb_detections):
""" """
@brief Associate detections between 1 radar/truth pair. @brief Associate detections between 1 radar/truth pair.
@param radar_detections (str): JSON of blah2 radar detections. @details Output 1 detection per truth point.
@param adsb_detections (str): JSON of adsb2dd truth detections. @param radar (str): Name of radar to process.
@return str: JSON of associated detections. @param radar_detections (dict): blah2 radar detections.
@param adsb_detections (dict): adsb2dd truth detections.
@return dict: Associated detections.
""" """
assoc_detections = {}
distance_window = 10
for aircraft in adsb_detections:
if 'delay' in radar_detections:
if 'delay' in adsb_detections[aircraft] and len(radar_detections['delay']) >= 1:
# distance from aircraft to all detections
closest_point, distance = self.closest_point(
adsb_detections[aircraft]['delay'],
adsb_detections[aircraft]['doppler'],
radar_detections['delay'],
radar_detections['doppler']
)
if distance < distance_window:
assoc_detections[aircraft] = {
'radar': radar,
'delay': closest_point[0],
'doppler': closest_point[1]
}
return assoc_detections
def generate_api_url(self, radar, radar_data): def generate_api_url(self, radar, radar_data):
""" """
@ -99,8 +132,23 @@ class AdsbAssociator:
"&tx=" + str(tx_lat) + "," + "&tx=" + str(tx_lat) + "," +
str(tx_lon) + "," + str(tx_lon) + "," +
str(tx_alt) + str(tx_alt) +
"&fc=" + str(fc) + "&fc=" + str(fc/1000000) +
"&server=" + "http://" + str(adsb) "&server=" + "http://" + str(adsb)
) )
return api_query return api_query
def closest_point(self, x1, y1, x_coords, y_coords):
x1, y1 = float(x1), float(y1)
x_coords = [float(x) for x in x_coords]
y_coords = [float(y) for y in y_coords]
distances = [math.sqrt((x - x1)**2 + (y - y1)**2) for x, y in zip(x_coords, y_coords)]
min_distance_index = distances.index(min(distances))
closest_x = x_coords[min_distance_index]
closest_y = y_coords[min_distance_index]
distance = distances[min_distance_index]
return [closest_x, closest_y], distance

View file

@ -76,8 +76,6 @@ async def event():
"config": radar_config[i] "config": radar_config[i]
} }
print(radar_dict, flush=True)
# main processing # main processing
for item in api_event: for item in api_event: