Lots and generating points for ellipsoid

This commit is contained in:
30hours 2024-02-25 13:08:26 +00:00
parent 7b7758e3ec
commit 7621c04949
8 changed files with 186 additions and 45 deletions

View file

@ -1,4 +1,26 @@
function event_radar() { function event_radar() {
setTimeout(event_radar, 1000); radar_url = window.location.origin + '/api' + window.location.search;
console.log(radar_url);
fetch(radar_url)
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
// Update aircraft points based on new data
console.log("test");
})
.catch(error => {
// Handle errors during fetch
console.error('Error during fetch:', error);
})
.finally(() => {
// Schedule the next fetch after a delay (e.g., 5 seconds)
setTimeout(event_radar, 1000);
});
} }

View file

@ -1,15 +0,0 @@
<!-- templates/map.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Map Page</title>
</head>
<body>
<h1>Map Page</h1>
<!-- Your map-related content goes here -->
</body>
</html>

View file

@ -58,7 +58,7 @@ class Message:
with conn: with conn:
while True: while True:
data = conn.recv(1024) data = conn.recv(65000)
if not data: if not data:
break break
decoded_data = data.decode() decoded_data = data.decode()
@ -82,7 +82,7 @@ class Message:
try: try:
client_socket.connect((self.host, self.port)) client_socket.connect((self.host, self.port))
client_socket.sendall(message.encode()) client_socket.sendall(message.encode())
reply = client_socket.recv(1024).decode() reply = client_socket.recv(65000).decode()
return reply return reply
except ConnectionRefusedError: except ConnectionRefusedError:
print(f"Connection to {self.host}:{self.port} refused.") print(f"Connection to {self.host}:{self.port} refused.")

View file

@ -39,7 +39,10 @@ class AdsbAssociator:
for radar in radar_list: for radar in radar_list:
if radar_data[radar]["config"] is not None: valid_config = radar_data[radar]["config"] is not None
valid_detection = radar_data[radar]["detection"] is not None
if valid_config and valid_detection:
# get URL for adsb2truth # get URL for adsb2truth
url = self.generate_api_url(radar, radar_data[radar]) url = self.generate_api_url(radar, radar_data[radar])
@ -127,10 +130,7 @@ class AdsbAssociator:
tx_alt = radar_data['config']['location']['tx']['altitude'] tx_alt = radar_data['config']['location']['tx']['altitude']
fc = radar_data['config']['capture']['fc'] fc = radar_data['config']['capture']['fc']
if (radar == "radar5.30hours.dev"): adsb = radar_data['config']['truth']['adsb']['tar1090']
adsb = radar_data['config']['truth']['adsb']['ip']
else:
adsb = radar_data['config']['truth']['adsb']['tar1090']
api_url = "http://adsb2dd.30hours.dev/api/dd" api_url = "http://adsb2dd.30hours.dev/api/dd"

View file

@ -4,6 +4,8 @@
""" """
from data.Ellipsoid import Ellipsoid from data.Ellipsoid import Ellipsoid
from algorithm.geometry.Geometry import Geometry
import numpy as np
class EllipsoidParametric: class EllipsoidParametric:
@ -20,18 +22,96 @@ class EllipsoidParametric:
@brief Constructor for the EllipsoidParametric class. @brief Constructor for the EllipsoidParametric class.
""" """
self.ellipsoids = []
def process(self, assoc_detections, radar_data): def process(self, assoc_detections, radar_data):
""" """
@brief Perform coord registration using the ellipsoid parametric method. @brief Perform coord registration using the ellipsoid parametric method.
@details Generate a (non arc-length) parametric ellipsoid for each node. @details Generate a (non arc-length) parametric ellipsoid for each node.
Find @param assoc_detections (dict): JSON of blah2 radar detections.
@param radar_detections (str): JSON of blah2 radar detections. @param radar_data (dict): JSON of adsb2dd truth detections.
@param adsb_detections (str): JSON of adsb2dd truth detections.
@return str: JSON of associated detections. @return str: JSON of associated detections.
""" """
output = {} output = {}
# return if no detections
if not assoc_detections:
return output
for target in assoc_detections:
print(target, flush=True)
for radar in assoc_detections[target]:
print(radar["radar"], flush=True)
print(radar["delay"], flush=True)
# create ellipsoid for radar
ellipsoid = next((
item for item in self.ellipsoids
if item.name == radar["radar"]), None)
if ellipsoid is None:
config = radar_data[radar["radar"]]["config"]
x_tx, y_tx, z_tx = Geometry.lla2ecef(
config['location']['tx']['latitude'],
config['location']['tx']['longitude'],
config['location']['tx']['altitude']
)
x_rx, y_rx, z_rx = Geometry.lla2ecef(
config['location']['rx']['latitude'],
config['location']['rx']['longitude'],
config['location']['rx']['altitude']
)
ellipsoid = Ellipsoid(
[x_tx, y_tx, z_tx],
[x_rx, y_rx, z_rx],
radar["radar"]
)
print(ellipsoid.yaw, flush=True)
print(ellipsoid.pitch, flush=True)
self.sample(ellipsoid, radar["delay"], 10000)
print("", flush=True)
return output return output
def sample(self, ellipsoid, bistatic_range, n):
"""
@brief Generate a set of points for the ellipsoid.
@details No arc length parametrisation.
@param ellipsoid (Ellipsoid): The ellipsoid object to use.
@param bistatic_range (float): Bistatic range for ellipsoid.
@param n (int): Number of points to generate.
@return list: Samples with size [n, 3].
"""
# rotation matrix
phi = ellipsoid.pitch
theta = ellipsoid.yaw
R = np.array([
[np.cos(phi)*np.cos(theta), -np.sin(phi)*np.cos(theta), np.sin(theta)],
[np.sin(phi), np.cos(phi), 0],
[-np.cos(phi)*np.sin(theta), np.sin(phi)*np.sin(theta), np.cos(theta)]
])
# compute samples vectorised
a = (bistatic_range-ellipsoid.distance)/2
b = np.sqrt(a**2 - (ellipsoid.distance/2))
u_values = np.linspace(0, 2 * np.pi, n)
v_values = np.linspace(-np.pi/2, np.pi/2, n)
u, v = np.meshgrid(u_values, v_values, indexing='ij')
x = a * np.cos(u)
y = b * np.sin(u) * np.cos(v)
z = b * np.sin(u) * np.sin(v)
r = np.stack([x, y, z], axis=-1).reshape(-1, 3)
r_1 = np.dot(r, R) + ellipsoid.midpoint
return r_1.tolist()

View file

@ -0,0 +1,42 @@
"""
@file Geometry.py
@author 30hours
"""
import math
import numpy as np
class Geometry:
"""
@class Geometry
@brief A class to store geometric functions.
"""
def __init__(self, f1, f2, name):
"""
@brief Constructor for the Ellipsoid class.
"""
def lla2ecef(latitude, longitude, altitude):
# WGS84 constants
a = 6378137.0 # semi-major axis in meters
f = 1 / 298.257223563 # flattening
# Convert latitude and longitude to radians
lat_rad = math.radians(latitude)
lon_rad = math.radians(longitude)
# Calculate the auxiliary values
cos_lat = math.cos(lat_rad)
sin_lat = math.sin(lat_rad)
N = a / math.sqrt(1 - f * (2 - f) * sin_lat**2)
# Calculate ECEF coordinates
ecef_x = (N + altitude) * cos_lat * math.cos(lon_rad)
ecef_y = (N + altitude) * cos_lat * math.sin(lon_rad)
ecef_z = (N * (1 - f) + altitude) * sin_lat
return ecef_x, ecef_y, ecef_z

View file

@ -11,19 +11,22 @@ class Ellipsoid:
@class Ellipsoid @class Ellipsoid
@brief A class to store ellipsoid parameters for bistatic radar. @brief A class to store ellipsoid parameters for bistatic radar.
@details Stores foci, midpoint, pitch, yaw and distance. @details Stores foci, midpoint, pitch, yaw and distance.
Able to generate samples through public functions.
""" """
def __init__(self, f1, f2, name): def __init__(self, f1, f2, name):
""" """
@brief Constructor for the Ellipsoid class. @brief Constructor for the Ellipsoid class.
@param f1 (list): [x, y, z] of foci 1 in ECEF.
@param f2 (list): [x, y, z] of foci 2 in ECEF.
@param name (str): Name to associate with shape.
""" """
self.f1 = f1 self.f1 = f1
self.f2 = f2 self.f2 = f2
self.name = name self.name = name
# dependent members
self.midpoint = [(f1[0]+f2[0])/2, self.midpoint = [(f1[0]+f2[0])/2,
(f1[1]+f2[1])/2, (f1[2]+f2[2])/2] (f1[1]+f2[1])/2, (f1[2]+f2[2])/2]
vector = (f2[0]-f1[0], f2[1]-f1[1], f2[2]-f1[2]) vector = (f2[0]-f1[0], f2[1]-f1[1], f2[2]-f1[2])
@ -34,19 +37,3 @@ class Ellipsoid:
(f2[0] - f1[0])**2 + (f2[0] - f1[0])**2 +
(f2[1] - f1[1])**2 + (f2[1] - f1[1])**2 +
(f2[2] - f1[2])**2) (f2[2] - f1[2])**2)
def process(self, bistatic_range):
"""
@brief Perform coord registration using the ellipsoid parametric method.
@details Generate a (non arc-length) parametric ellipsoid for each node.
Find
@param radar_detections (str): JSON of blah2 radar detections.
@param adsb_detections (str): JSON of adsb2dd truth detections.
@return str: JSON of associated detections.
"""
output = {}
return output

View file

@ -17,6 +17,9 @@ from algorithm.associator.AdsbAssociator import AdsbAssociator
from algorithm.coordreg.EllipsoidParametric import EllipsoidParametric from algorithm.coordreg.EllipsoidParametric import EllipsoidParametric
from common.Message import Message from common.Message import Message
from data.Ellipsoid import Ellipsoid
from algorithm.geometry.Geometry import Geometry
# init event loop # init event loop
api = [] api = []
@ -101,7 +104,27 @@ async def event():
# processing # processing
associated_dets = associator.process(item["server"], radar_dict_item) associated_dets = associator.process(item["server"], radar_dict_item)
localised_dets = coordreg.process(associated_dets, radar_dict_item) localised_dets = coordreg.process(associated_dets, radar_dict_item)
# tmp test
localised_dets = {}
localised_dets["test"] = {}
x_tx, y_tx, z_tx = Geometry.lla2ecef(
radar_dict_item['radar4.30hours.dev']["config"]['location']['tx']['latitude'],
radar_dict_item['radar4.30hours.dev']["config"]['location']['tx']['longitude'],
radar_dict_item['radar4.30hours.dev']["config"]['location']['tx']['altitude']
)
x_rx, y_rx, z_rx = Geometry.lla2ecef(
radar_dict_item['radar4.30hours.dev']["config"]['location']['rx']['latitude'],
radar_dict_item['radar4.30hours.dev']["config"]['location']['rx']['longitude'],
radar_dict_item['radar4.30hours.dev']["config"]['location']['rx']['altitude']
)
ellipsoid = Ellipsoid(
[x_tx, y_tx, z_tx],
[x_rx, y_rx, z_rx],
'radar4.30hours.dev'
)
localised_dets["test"]["points"] = ellipsoidParametric.sample(ellipsoid, 10000, 5)
# output data to API # output data to API
item["detections_associated"] = associated_dets item["detections_associated"] = associated_dets
item["detections_localised"] = localised_dets item["detections_localised"] = localised_dets
@ -154,6 +177,8 @@ async def callback_message_received(msg):
else: else:
api[-1][key] = value api[-1][key] = value
api[-1]["timestamp"] = timestamp api[-1]["timestamp"] = timestamp
if not isinstance(api[-1]["server"], list):
api[-1]["server"] = [api[-1]["server"]]
# json dump # json dump
output = json.dumps(api) output = json.dumps(api)