mirror of
https://github.com/30hours/3lips.git
synced 2024-11-18 12:33:58 +00:00
Start plotting target local
This commit is contained in:
parent
2c7c4358b7
commit
561baf5a35
8 changed files with 116 additions and 80 deletions
|
@ -17,7 +17,8 @@ app = Flask(__name__)
|
|||
# store state data
|
||||
servers = [
|
||||
{"name": "radar4", "url": "radar4.30hours.dev"},
|
||||
{"name": "radar5", "url": "radar5.30hours.dev"}
|
||||
{"name": "radar5", "url": "radar5.30hours.dev"},
|
||||
{"name": "radar6", "url": "radar6.30hours.dev"}
|
||||
]
|
||||
associators = [
|
||||
{"name": "ADSB Associator", "id": "adsb-associator"}
|
||||
|
|
|
@ -16,14 +16,17 @@ function event_radar() {
|
|||
const target = data["detections_localised"][key];
|
||||
const points = target["points"];
|
||||
|
||||
removeEntitiesByType("test");
|
||||
console.log(target);
|
||||
console.log(points);
|
||||
|
||||
removeEntitiesOlderThanAndFade("detection", 60, 0.5);
|
||||
|
||||
for (const point in points) {
|
||||
addPoint(
|
||||
points[point][0],
|
||||
points[point][1],
|
||||
points[point][2],
|
||||
"test",
|
||||
"detection",
|
||||
style_point.color,
|
||||
style_point.pointSize,
|
||||
style_point.type,
|
||||
|
@ -46,7 +49,7 @@ function event_radar() {
|
|||
}
|
||||
|
||||
var style_point = {};
|
||||
style_point.color = 'rgba(128, 0, 0, 1.0)';
|
||||
style_point.pointSize = 10;
|
||||
style_point.type = "test";
|
||||
style_point.color = 'rgba(0, 255, 0, 1.0)';
|
||||
style_point.pointSize = 16;
|
||||
style_point.type = "detection";
|
||||
style_point.timestamp = Date.now();
|
|
@ -281,16 +281,17 @@ function removeEntitiesOlderThanAndFade(entityType, maxAgeSeconds, baseAlpha) {
|
|||
const type = entity.properties["type"].getValue();
|
||||
const timestamp = entity.properties["timestamp"].getValue();
|
||||
if (entity.properties && entity.properties["type"] &&
|
||||
entity.properties["type"].getValue() === entityType &&
|
||||
Date.now()-timestamp > maxAgeSeconds*1000) {
|
||||
entity.properties["type"].getValue() === entityType) {
|
||||
|
||||
if (Date.now()-timestamp > maxAgeSeconds*1000) {
|
||||
viewer.entities.remove(entity);
|
||||
}
|
||||
else {
|
||||
entity.point.color = new Cesium.Color.fromAlpha(
|
||||
entity.point.color.getValue(), baseAlpha*(1-(Date.now()-timestamp)/(maxAgeSeconds*1000)));
|
||||
}
|
||||
else {
|
||||
entity.point.color = new Cesium.Color.fromAlpha(
|
||||
entity.point.color.getValue(), baseAlpha*(1-(Date.now()-timestamp)/(maxAgeSeconds*1000)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function removeEntitiesByType(entityType) {
|
||||
|
|
|
@ -58,7 +58,7 @@ class Message:
|
|||
with conn:
|
||||
|
||||
while True:
|
||||
data = conn.recv(8096)
|
||||
data = conn.recv(30000)
|
||||
if not data:
|
||||
break
|
||||
decoded_data = data.decode()
|
||||
|
@ -82,7 +82,7 @@ class Message:
|
|||
try:
|
||||
client_socket.connect((self.host, self.port))
|
||||
client_socket.sendall(message.encode())
|
||||
reply = client_socket.recv(8096).decode()
|
||||
reply = client_socket.recv(30000).decode()
|
||||
return reply
|
||||
except ConnectionRefusedError:
|
||||
print(f"Connection to {self.host}:{self.port} refused.")
|
||||
|
|
|
@ -44,6 +44,8 @@ class EllipsoidParametric:
|
|||
for target in assoc_detections:
|
||||
|
||||
print(target, flush=True)
|
||||
target_samples = {}
|
||||
target_samples[target] = {}
|
||||
|
||||
for radar in assoc_detections[target]:
|
||||
|
||||
|
@ -73,20 +75,48 @@ class EllipsoidParametric:
|
|||
radar["radar"]
|
||||
)
|
||||
|
||||
print(ellipsoid.yaw, flush=True)
|
||||
print(ellipsoid.pitch, flush=True)
|
||||
samples = self.sample(ellipsoid, radar["delay"], 20)
|
||||
target_samples[target][radar["radar"]] = samples
|
||||
|
||||
self.sample(ellipsoid, radar["delay"], 10000)
|
||||
# find close points
|
||||
radar_keys = list(target_samples[target].keys())
|
||||
samples_intersect = {key: [] for key in radar_keys}
|
||||
threshold = 200
|
||||
for i in range(0, len(target_samples[target])-1):
|
||||
|
||||
print("", flush=True)
|
||||
for j in range(i+1, len(target_samples[target])):
|
||||
|
||||
for point1 in target_samples[target][radar_keys[i]]:
|
||||
|
||||
for point2 in target_samples[target][radar_keys[j]]:
|
||||
|
||||
if Geometry.distance_ecef(point1, point2) < threshold:
|
||||
samples_intersect[radar_keys[i]].append(point1)
|
||||
samples_intersect[radar_keys[j]].append(point2)
|
||||
|
||||
# remove duplicates and convert to LLA
|
||||
output[target] = {}
|
||||
output[target]["points"] = []
|
||||
for key in radar_keys:
|
||||
samples_intersect[key] = [list(t) for t in {tuple(point) for point in samples_intersect[key]}]
|
||||
for i in range(len(samples_intersect[key])):
|
||||
samples_intersect[key][i] = Geometry.ecef2lla(
|
||||
samples_intersect[key][i][0],
|
||||
samples_intersect[key][i][1],
|
||||
samples_intersect[key][i][2])
|
||||
output[target]["points"].append([
|
||||
round(samples_intersect[key][i][0], 3),
|
||||
round(samples_intersect[key][i][1], 3),
|
||||
round(samples_intersect[key][i][2])])
|
||||
|
||||
return output
|
||||
|
||||
def sample(self, ellipsoid, bistatic_range, n):
|
||||
|
||||
"""
|
||||
@brief Generate a set of points for the ellipsoid.
|
||||
@brief Generate a set of ECEF points for the ellipsoid.
|
||||
@details No arc length parametrisation.
|
||||
@details Use ECEF because distance measure is simple over LLA.
|
||||
@param ellipsoid (Ellipsoid): The ellipsoid object to use.
|
||||
@param bistatic_range (float): Bistatic range for ellipsoid.
|
||||
@param n (int): Number of points to generate.
|
||||
|
@ -101,51 +131,39 @@ class EllipsoidParametric:
|
|||
|
||||
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)]
|
||||
# ])
|
||||
R = np.array([
|
||||
[np.cos(theta), -np.sin(theta)*np.cos(phi), np.sin(theta)*np.sin(phi)],
|
||||
[np.sin(theta), np.cos(theta)*np.cos(phi), -np.cos(theta)*np.sin(phi)],
|
||||
[0, np.sin(phi), np.cos(phi)]
|
||||
])
|
||||
|
||||
# rotation matrix normal
|
||||
# theta = ellipsoid.pitch_plane
|
||||
# phi = ellipsoid.yaw_plane
|
||||
# R2 = 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)**2)
|
||||
u_values = np.linspace(0, 2 * np.pi, n)
|
||||
v_values = np.linspace(-np.pi, np.pi, n)
|
||||
v_values = np.linspace(-np.pi/2, np.pi/2, int(n/2))
|
||||
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)
|
||||
x = a * np.cos(u) * np.cos(v)
|
||||
y = b * np.sin(u)
|
||||
z = a * np.cos(u) * np.sin(v)
|
||||
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, np.dot(R, R2)) + ellipsoid.midpoint
|
||||
#r_1 = np.dot(r, R) + ellipsoid.midpoint
|
||||
r_1 = np.dot(r, R)
|
||||
#r_1 = r
|
||||
|
||||
a, b, c = Geometry.ecef2lla(
|
||||
ellipsoid.midpoint[0], ellipsoid.midpoint[1], ellipsoid.midpoint[2])
|
||||
output = []
|
||||
|
||||
for i in range(len(r_1)):
|
||||
x, y, z = Geometry.enu2ecef(r_1[i][0], r_1[i][1], r_1[i][2],
|
||||
a, b, c)
|
||||
r_1[i] = [x, y, z]
|
||||
# points to ECEF
|
||||
x, y, z = Geometry.enu2ecef(
|
||||
r_1[i][0], r_1[i][1], r_1[i][2],
|
||||
ellipsoid.midpoint_lla[0],
|
||||
ellipsoid.midpoint_lla[1],
|
||||
ellipsoid.midpoint_lla[2])
|
||||
# points to LLA
|
||||
[x, y, z] = Geometry.ecef2lla(x, y, z)
|
||||
# only store points above ground
|
||||
if z > 0:
|
||||
# convert back to ECEF for simple distance measurements
|
||||
[x, y, z] = Geometry.lla2ecef(x, y, z)
|
||||
output.append([round(x, 3), round(y, 3), round(z)])
|
||||
|
||||
return r_1.tolist()
|
||||
return output
|
|
@ -182,4 +182,11 @@ class Geometry:
|
|||
u = cos_lat * t + sin_lat * w
|
||||
n = -sin_lat * t + cos_lat * w
|
||||
|
||||
return e, n, u
|
||||
return e, n, u
|
||||
|
||||
def distance_ecef(point1, point2):
|
||||
|
||||
return math.sqrt(
|
||||
(point2[0]-point1[0])**2 +
|
||||
(point2[1]-point1[1])**2 +
|
||||
(point2[2]-point1[2])**2)
|
|
@ -30,11 +30,11 @@ class Ellipsoid:
|
|||
# dependent members
|
||||
self.midpoint = [(f1[0]+f2[0])/2,
|
||||
(f1[1]+f2[1])/2, (f1[2]+f2[2])/2]
|
||||
midpoint_lla = Geometry.ecef2lla(
|
||||
self.midpoint_lla = Geometry.ecef2lla(
|
||||
self.midpoint[0], self.midpoint[1], self.midpoint[2])
|
||||
vector_enu = Geometry.ecef2enu(f1[0], f1[1], f1[2],
|
||||
midpoint_lla[0], midpoint_lla[1], midpoint_lla[2])
|
||||
self.yaw = -math.atan2(vector_enu[1], vector_enu[0])-math.pi/2
|
||||
self.midpoint_lla[0], self.midpoint_lla[1], self.midpoint_lla[2])
|
||||
self.yaw = -math.atan2(vector_enu[1], vector_enu[0])
|
||||
self.pitch = math.atan2(vector_enu[2],
|
||||
math.sqrt(vector_enu[0]**2 + vector_enu[1]**2))
|
||||
self.distance = math.sqrt(
|
||||
|
|
|
@ -85,7 +85,7 @@ async def event():
|
|||
key: radar_dict[key]
|
||||
for key in item["server"]
|
||||
if key in radar_dict
|
||||
}
|
||||
}
|
||||
|
||||
# associator selection
|
||||
if item["associator"] == "adsb-associator":
|
||||
|
@ -105,30 +105,36 @@ async def event():
|
|||
associated_dets = associator.process(item["server"], radar_dict_item)
|
||||
localised_dets = coordreg.process(associated_dets, radar_dict_item)
|
||||
|
||||
if associated_dets:
|
||||
print(associated_dets, flush=True)
|
||||
|
||||
#if localised_dets:
|
||||
print(localised_dets, flush=True)
|
||||
|
||||
# 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'
|
||||
)
|
||||
pointsEcef = ellipsoidParametric.sample(ellipsoid, 6000, 15)
|
||||
pointsLla = []
|
||||
for point in pointsEcef:
|
||||
lat, lon, alt = Geometry.ecef2lla(point[0], point[1], point[2])
|
||||
pointsLla.append([round(lat, 4), round(lon, 4), round(alt)])
|
||||
localised_dets["test"]["points"] = pointsLla
|
||||
# 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'
|
||||
# )
|
||||
# points = ellipsoidParametric.sample(ellipsoid, 2000, 25)
|
||||
# pointsLla = []
|
||||
# for point in points:
|
||||
# lat, lon, alt = Geometry.ecef2lla(point[0], point[1], point[2])
|
||||
# pointsLla.append([round(lat, 3), round(lon, 3), round(alt)])
|
||||
# localised_dets["test"]["points"] = pointsLla
|
||||
|
||||
# output data to API
|
||||
item["detections_associated"] = associated_dets
|
||||
|
@ -199,4 +205,4 @@ message_api_request.set_callback_message_received(callback_message_received)
|
|||
|
||||
if __name__ == "__main__":
|
||||
threading.Thread(target=message_api_request.start_listener).start()
|
||||
asyncio.run(main())
|
||||
asyncio.run(main())
|
||||
|
|
Loading…
Reference in a new issue