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 # 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 ## Features
- Provides a JSON API for geolocation of targets given [blah2](http://github.com/30hours/blah2) radar nodes. - 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. - 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 ## 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. - 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: The system architecture is as follows:
@ -40,7 +44,6 @@ The system architecture is as follows:
## Future Work ## Future Work
- Implement an association algorithm that is not reliant on ADS-B truth. - 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. - 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. - 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", "id": "ellipsoid-parametric"},
# {"name": "Ellipsoid Parametric (Arc Length)", "id": "ellipsoid-parametric-arc"} # {"name": "Ellipsoid Parametric (Arc Length)", "id": "ellipsoid-parametric-arc"}
# ] # ]
coordregs = [ localisations = [
{"name": "Ellipsoid Parametric", "id": "ellipsoid-parametric"} {"name": "Ellipsoid Parametric", "id": "ellipsoid-parametric"}
] ]
@ -49,7 +49,7 @@ message_api_request = Message('event', 6969)
@app.route("/") @app.route("/")
def index(): def index():
return render_template("index.html", servers=servers, \ 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 # serve static files from the /app/public folder
@app.route('/public/<path:file>') @app.route('/public/<path:file>')

View file

@ -130,9 +130,17 @@ var viewer = new Cesium.Viewer("cesiumContainer", {
terrainProviderViewModels: terrainProviders, terrainProviderViewModels: terrainProviders,
geocoder: false, geocoder: false,
shouldAnimate: true, shouldAnimate: true,
animation: false,
timeline: false,
selectionIndicator: 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. * @brief Adds a point to Cesium viewer with specified parameters.
* @param {number} latitude - The latitude of the point in degrees. * @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 // Get the form values
var servers = document.querySelectorAll('.toggle-button.active'); var servers = document.querySelectorAll('.toggle-button.active');
var associator = document.querySelector('[name="associator"]').value; 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; var adsb = document.querySelector('[name="adsb"]').value;
// Construct the URL with the form values // Construct the URL with the form values
var apiUrl = '?server=' + Array.from(servers).map(server => server.value).join('&server='); 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 // Redirect to the constructed URL
window.location.href = mapUrl; window.location.href = mapUrl;

View file

@ -47,7 +47,7 @@
<div class="col-md-6"> <div class="col-md-6">
<div class="jumbotron"> <div class="jumbotron">
<h1 class="display-4 text-center">3lips</h1> <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> <p class="lead">See <a href="https://github.com/30hours/3lips" target="_blank">github.com/30hours/3lips</a> for more details.</p>
</div> </div>
<div class="calculator-form"> <div class="calculator-form">
@ -72,10 +72,10 @@
</div> </div>
<div class="mb-3"> <div class="mb-3">
<label class="form-label fw-bold">Coordinate Registration:</label> <label class="form-label fw-bold">Target Localisation:</label>
<select class="form-select" name="coordreg"> <select class="form-select" name="localisation">
{% for coordreg in coordregs %} {% for localisation in localisations %}
<option value="{{ coordreg.id }}">{{ coordreg.name }}</option> <option value="{{ localisation.id }}">{{ localisation.name }}</option>
{% endfor %} {% endfor %}
</select> </select>
</div> </div>

View file

@ -24,15 +24,17 @@ class EllipsoidParametric:
""" """
self.ellipsoids = [] self.ellipsoids = []
self.nSamples = 150
self.threshold = 800
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 target localisation 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.
@param assoc_detections (dict): JSON of blah2 radar detections. @param assoc_detections (dict): JSON of blah2 radar detections.
@param radar_data (dict): JSON of adsb2dd truth detections. @param radar_data (dict): JSON of adsb2dd truth detections.
@return str: JSON of associated detections. @return dict: Dict of associated detections.
""" """
output = {} output = {}
@ -75,13 +77,12 @@ class EllipsoidParametric:
radar["radar"] 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 target_samples[target][radar["radar"]] = samples
# find close points - ellipsoid 1 = master # find close points - ellipsoid 1 = master
radar_keys = list(target_samples[target].keys()) radar_keys = list(target_samples[target].keys())
samples_intersect = [] samples_intersect = []
threshold = 500
# loop points in master ellipsoid # loop points in master ellipsoid
for point1 in target_samples[target][radar_keys[0]]: for point1 in target_samples[target][radar_keys[0]]:
@ -89,7 +90,7 @@ class EllipsoidParametric:
# loop over each other list # loop over each other list
for i in range(1, len(radar_keys)): for i in range(1, len(radar_keys)):
# loop points in other list # 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]]): for point2 in target_samples[target][radar_keys[i]]):
valid_point = False valid_point = False
break break
@ -124,11 +125,6 @@ class EllipsoidParametric:
""" """
# rotation matrix # 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 phi = ellipsoid.pitch
theta = ellipsoid.yaw theta = ellipsoid.yaw
R = np.array([ R = np.array([

View file

@ -14,7 +14,7 @@ import json
import hashlib import hashlib
from algorithm.associator.AdsbAssociator import AdsbAssociator from algorithm.associator.AdsbAssociator import AdsbAssociator
from algorithm.coordreg.EllipsoidParametric import EllipsoidParametric from algorithm.localisation.EllipsoidParametric import EllipsoidParametric
from common.Message import Message from common.Message import Message
from data.Ellipsoid import Ellipsoid from data.Ellipsoid import Ellipsoid
@ -94,11 +94,11 @@ async def event():
print("Error: Associator invalid.") print("Error: Associator invalid.")
return return
# coord reg selection # localisation selection
if item["coordreg"] == "ellipsoid-parametric": if item["localisation"] == "ellipsoid-parametric":
coordreg = ellipsoidParametric localisation = ellipsoidParametric
else: else:
print("Error: Coord reg invalid.") print("Error: Localisation invalid.")
return return
# processing # processing
@ -108,7 +108,7 @@ 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
} }
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: if associated_dets:
print(associated_dets, flush=True) print(associated_dets, flush=True)