diff --git a/README.md b/README.md index fedce2e..a2e75b4 100644 --- a/README.md +++ b/README.md @@ -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. diff --git a/api/main.py b/api/main.py index 49b7ba6..b4e8336 100644 --- a/api/main.py +++ b/api/main.py @@ -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/') diff --git a/api/map/main.js b/api/map/main.js index ccca705..05fd504 100644 --- a/api/map/main.js +++ b/api/map/main.js @@ -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. diff --git a/api/public/js/index.js b/api/public/js/index.js index de61c3e..1bbce7d 100644 --- a/api/public/js/index.js +++ b/api/public/js/index.js @@ -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; diff --git a/api/templates/index.html b/api/templates/index.html index 41e048e..d457261 100644 --- a/api/templates/index.html +++ b/api/templates/index.html @@ -47,7 +47,7 @@

3lips

-

Coordinate registration for multi-static radar using ellipse intersections. Requires input of blah2 servers, and choice of algorithm for association and coordinate registration. This program exposes an API endpoint to generate geographic coordinates and a Cesium map for display.

+

Target localisation for multi-static radar using ellipse intersections. Requires input of blah2 servers, and choice of algorithm for association and target localisation. This program exposes an API endpoint to generate geographic coordinates and a Cesium map for display.

See github.com/30hours/3lips for more details.

@@ -72,10 +72,10 @@
- - + {% for localisation in localisations %} + {% endfor %}
diff --git a/event/algorithm/localisation/EllipseParametric.py b/event/algorithm/localisation/EllipseParametric.py new file mode 100644 index 0000000..e69de29 diff --git a/event/algorithm/coordreg/EllipsoidParametric.py b/event/algorithm/localisation/EllipsoidParametric.py similarity index 93% rename from event/algorithm/coordreg/EllipsoidParametric.py rename to event/algorithm/localisation/EllipsoidParametric.py index f20e0ca..2eec4ac 100644 --- a/event/algorithm/coordreg/EllipsoidParametric.py +++ b/event/algorithm/localisation/EllipsoidParametric.py @@ -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([ diff --git a/event/algorithm/localisation/SphericalIntersection.py b/event/algorithm/localisation/SphericalIntersection.py new file mode 100644 index 0000000..e69de29 diff --git a/event/event.py b/event/event.py index a7a7c17..d28974a 100644 --- a/event/event.py +++ b/event/event.py @@ -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)