A bunch of UI and formatting changes

This commit is contained in:
30hours 2024-03-05 11:51:07 +00:00
parent ddd73a0d23
commit 88c99ed45e
9 changed files with 37 additions and 30 deletions

View file

@ -1,12 +1,12 @@
# 3lips
Coordinate registration for multi-static radar using ellipse intersections. Not a dating app.
Target localisation for multi-static radar using ellipse intersections. Not a dating app.
## Features
- Provides a JSON API for geolocation of targets given [blah2](http://github.com/30hours/blah2) radar nodes.
- Uses a [CesiumJS](http://github.com/CesiumGS/cesium) web front-end to visualise data.
- Ability to compare a number of algorithms for coordinate registration.
- Ability to compare a number of algorithms for target localisation.
## Usage
@ -27,9 +27,13 @@ The association uses the following algorithm:
- ADS-B associator will associate the highest SNR target within some delay and Doppler boundary around the truth.
The coordinate registration uses 1 of the following algorithms:
The target localisation uses 1 of the following algorithms:
-
- **Ellipse parametric** samples an ellipse (2D) at 0 altitude. Find intersections between 3 or more ellipses such that the distance to each point is under some threshold.
- **Ellipsoid parametric** samples an ellipsoid (3D). Find intersections between 3 or more ellipsoids such that the distance to each point is under some threshold.
- **Spherical intersection** a closed form solution which applies when a common receiver or transmitter are used. As described in [Two Methods for Target Localization in Multistatic Passive Radar](https://ieeexplore.ieee.org/document/6129656).
The system architecture is as follows:
@ -40,7 +44,6 @@ The system architecture is as follows:
## Future Work
- Implement an association algorithm that is not reliant on ADS-B truth.
- Add a variety of methods for solving the ellipse/ellipsoid intersection.
- Choose to use detection or track data from each radar.
- Long term plots to show metrics such as 2D location accuracy to ADS-B, number of aircraft tracked, etc.

View file

@ -30,7 +30,7 @@ associators = [
# {"name": "Ellipsoid Parametric", "id": "ellipsoid-parametric"},
# {"name": "Ellipsoid Parametric (Arc Length)", "id": "ellipsoid-parametric-arc"}
# ]
coordregs = [
localisations = [
{"name": "Ellipsoid Parametric", "id": "ellipsoid-parametric"}
]
@ -49,7 +49,7 @@ message_api_request = Message('event', 6969)
@app.route("/")
def index():
return render_template("index.html", servers=servers, \
associators=associators, coordregs=coordregs, adsbs=adsbs)
associators=associators, localisations=localisations, adsbs=adsbs)
# serve static files from the /app/public folder
@app.route('/public/<path:file>')

View file

@ -130,9 +130,17 @@ var viewer = new Cesium.Viewer("cesiumContainer", {
terrainProviderViewModels: terrainProviders,
geocoder: false,
shouldAnimate: true,
animation: false,
timeline: false,
selectionIndicator: false
});
// keep data attribution, remove CesiumIon logo
var cesiumCredit = document.querySelector('.cesium-credit-logoContainer');
if (cesiumCredit) {
cesiumCredit.style.display = 'none';
}
/**
* @brief Adds a point to Cesium viewer with specified parameters.
* @param {number} latitude - The latitude of the point in degrees.

View file

@ -41,12 +41,12 @@ document.getElementById('buttonMap').addEventListener('click', function() {
// Get the form values
var servers = document.querySelectorAll('.toggle-button.active');
var associator = document.querySelector('[name="associator"]').value;
var coordreg = document.querySelector('[name="coordreg"]').value;
var localisation = document.querySelector('[name="localisation"]').value;
var adsb = document.querySelector('[name="adsb"]').value;
// Construct the URL with the form values
var apiUrl = '?server=' + Array.from(servers).map(server => server.value).join('&server=');
var mapUrl = '/map/index.html' + apiUrl + '&associator=' + associator + '&coordreg=' + coordreg + '&adsb=' + adsb;
var mapUrl = '/map/index.html' + apiUrl + '&associator=' + associator + '&localisation=' + localisation + '&adsb=' + adsb;
// Redirect to the constructed URL
window.location.href = mapUrl;

View file

@ -47,7 +47,7 @@
<div class="col-md-6">
<div class="jumbotron">
<h1 class="display-4 text-center">3lips</h1>
<p class="lead">Coordinate registration for multi-static radar using ellipse intersections. Requires input of <a href="https://github.com/30hours/blah2" target="_blank">blah2</a> servers, and choice of algorithm for association and coordinate registration. This program exposes an API endpoint to generate geographic coordinates and a <a href="https://github.com/CesiumGS/cesium" target="_blank">Cesium</a> map for display.</p>
<p class="lead">Target localisation for multi-static radar using ellipse intersections. Requires input of <a href="https://github.com/30hours/blah2" target="_blank">blah2</a> servers, and choice of algorithm for association and target localisation. This program exposes an API endpoint to generate geographic coordinates and a <a href="https://github.com/CesiumGS/cesium" target="_blank">Cesium</a> map for display.</p>
<p class="lead">See <a href="https://github.com/30hours/3lips" target="_blank">github.com/30hours/3lips</a> for more details.</p>
</div>
<div class="calculator-form">
@ -72,10 +72,10 @@
</div>
<div class="mb-3">
<label class="form-label fw-bold">Coordinate Registration:</label>
<select class="form-select" name="coordreg">
{% for coordreg in coordregs %}
<option value="{{ coordreg.id }}">{{ coordreg.name }}</option>
<label class="form-label fw-bold">Target Localisation:</label>
<select class="form-select" name="localisation">
{% for localisation in localisations %}
<option value="{{ localisation.id }}">{{ localisation.name }}</option>
{% endfor %}
</select>
</div>

View file

@ -24,15 +24,17 @@ class EllipsoidParametric:
"""
self.ellipsoids = []
self.nSamples = 150
self.threshold = 800
def process(self, assoc_detections, radar_data):
"""
@brief Perform coord registration using the ellipsoid parametric method.
@brief Perform target localisation using the ellipsoid parametric method.
@details Generate a (non arc-length) parametric ellipsoid for each node.
@param assoc_detections (dict): JSON of blah2 radar detections.
@param radar_data (dict): JSON of adsb2dd truth detections.
@return str: JSON of associated detections.
@return dict: Dict of associated detections.
"""
output = {}
@ -75,13 +77,12 @@ class EllipsoidParametric:
radar["radar"]
)
samples = self.sample(ellipsoid, radar["delay"]*1000, 120)
samples = self.sample(ellipsoid, radar["delay"]*1000, self.nSamples)
target_samples[target][radar["radar"]] = samples
# find close points - ellipsoid 1 = master
radar_keys = list(target_samples[target].keys())
samples_intersect = []
threshold = 500
# loop points in master ellipsoid
for point1 in target_samples[target][radar_keys[0]]:
@ -89,7 +90,7 @@ class EllipsoidParametric:
# loop over each other list
for i in range(1, len(radar_keys)):
# loop points in other list
if not any(Geometry.distance_ecef(point1, point2) < threshold
if not any(Geometry.distance_ecef(point1, point2) < self.threshold
for point2 in target_samples[target][radar_keys[i]]):
valid_point = False
break
@ -124,11 +125,6 @@ class EllipsoidParametric:
"""
# rotation matrix
phi = np.pi/2 - ellipsoid.pitch
theta = ellipsoid.yaw + np.pi/2
phi = np.deg2rad(3.834)
theta = -np.deg2rad(-77+90)
phi = ellipsoid.pitch
theta = ellipsoid.yaw
R = np.array([

View file

@ -14,7 +14,7 @@ import json
import hashlib
from algorithm.associator.AdsbAssociator import AdsbAssociator
from algorithm.coordreg.EllipsoidParametric import EllipsoidParametric
from algorithm.localisation.EllipsoidParametric import EllipsoidParametric
from common.Message import Message
from data.Ellipsoid import Ellipsoid
@ -94,11 +94,11 @@ async def event():
print("Error: Associator invalid.")
return
# coord reg selection
if item["coordreg"] == "ellipsoid-parametric":
coordreg = ellipsoidParametric
# localisation selection
if item["localisation"] == "ellipsoid-parametric":
localisation = ellipsoidParametric
else:
print("Error: Coord reg invalid.")
print("Error: Localisation invalid.")
return
# processing
@ -108,7 +108,7 @@ async def event():
for key, value in associated_dets.items()
if isinstance(value, list) and len(value) >= 3
}
localised_dets = coordreg.process(associated_dets_3_radars, radar_dict_item)
localised_dets = localisation.process(associated_dets_3_radars, radar_dict_item)
if associated_dets:
print(associated_dets, flush=True)