-
Notifications
You must be signed in to change notification settings - Fork 70
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
27 changed files
with
1,419 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
# mlat-server | ||
|
||
This is a Mode S multilateration server that is designed to operate with | ||
clients that do _not_ have synchronized clocks. | ||
|
||
It uses ADS-B aircraft that are transmitting DF17 extended squitter position | ||
messages as reference beacons and uses the relative arrival times of those | ||
messages to model the clock characteristics of each receiver. | ||
|
||
Then it does multilateration of aircraft that are transmitting only Mode S | ||
using the same receivers. | ||
|
||
## License | ||
|
||
It is important that you read this section before using or modifying the server! | ||
|
||
The server code is licensed under the Affero GPL v3. This license is similar | ||
to the GPL v3, but it has an additional requirement that you must provide | ||
source code to _users who access the server over a network_. | ||
|
||
So if you are planning to operate a copy of this server, you must release any | ||
modifications you make to the source code to your users, even if you wouldn't | ||
normally distribute it. | ||
|
||
If you are not willing to distribute your changes, you have three options: | ||
|
||
* Contact the copyright holder (Oliver) to discuss a separate license for | ||
the server code; or | ||
* Don't allow anyone else to connect to your server, i.e. run only your | ||
own receivers; or | ||
* Don't use this server as a basis for your work at all. | ||
|
||
The server will automatically provide details of the AGPL license and a link | ||
to the server code, to each client that connects. This is configured in | ||
mlat/config.py. If you make modifications, the suggested process is: | ||
|
||
* Put the modified source code somewhere public (github may be simplest). | ||
* Update the URL configured in mlat/config.py to point to your modified code. | ||
|
||
None of this requires that you make your server publically accessible. If you | ||
want to run a private server with a closed user group, that's fine. But you | ||
must still make the source code for your modified server available to your | ||
users, and they may redistribute it further if they wish. | ||
|
||
## Prerequisites | ||
|
||
* Python 3.4 or later. You need the asyncio module which was introduced in 3.4. | ||
* Numpy and Scipy | ||
* pygraph (https://github.com/pmatiello/python-graph) | ||
* pykalman (https://github.com/pykalman/pykalman) | ||
* optionally, objgraph (https://mg.pov.lt/objgraph/) for leak checking | ||
|
||
## Developer-ware | ||
|
||
It's all poorly documented and you need to understand quite a bit of the | ||
underlying mathematics of multilateration to make sense of it. Don't expect | ||
to just fire this up and have it all work perfectly first time. You will have | ||
to hack on the code. | ||
|
||
## Running | ||
|
||
$ mlat-server --help | ||
|
||
## Clients | ||
|
||
You need a bunch of receivers running mlat-client: | ||
https://github.com/mutability/mlat-client | ||
|
||
## Output | ||
|
||
Results get passed back to the clients that contributed to the positions. | ||
You can also emit all positions to a local feed, see the command-line help. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,22 @@ | ||
#!/usr/bin/env python3.4 | ||
# -*- mode: python; indent-tabs-mode: nil -*- | ||
|
||
# mlat-server: a Mode S multilateration server | ||
# Copyright (C) 2015 Oliver Jowett <[email protected]> | ||
|
||
# This program is free software: you can redistribute it and/or modify | ||
# it under the terms of the GNU Affero General Public License as | ||
# published by the Free Software Foundation, either version 3 of the | ||
# License, or (at your option) any later version. | ||
|
||
# This program is distributed in the hope that it will be useful, | ||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
# GNU Affero General Public License for more details. | ||
|
||
# You should have received a copy of the GNU Affero General Public License | ||
# along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
|
||
import logging | ||
import mlat.main | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,25 @@ | ||
# -*- mode: python; indent-tabs-mode: nil -*- | ||
|
||
# Part of mlat-server: a Mode S multilateration server | ||
# Copyright (C) 2015 Oliver Jowett <[email protected]> | ||
|
||
# This program is free software: you can redistribute it and/or modify | ||
# it under the terms of the GNU Affero General Public License as | ||
# published by the Free Software Foundation, either version 3 of the | ||
# License, or (at your option) any later version. | ||
|
||
# This program is distributed in the hope that it will be useful, | ||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
# GNU Affero General Public License for more details. | ||
|
||
# You should have received a copy of the GNU Affero General Public License | ||
# along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
|
||
""" | ||
JSON client protocol implementation. | ||
""" | ||
|
||
import asyncio | ||
import zlib | ||
import logging | ||
|
@@ -8,6 +28,8 @@ | |
import time | ||
import random | ||
import socket | ||
import inspect | ||
import sys | ||
|
||
import mlat.net | ||
import mlat.util | ||
|
@@ -354,13 +376,24 @@ def process_handshake(self, line): | |
self.write_raw(deny=[deny], reconnect_in=mlat.util.fuzzy(900)) | ||
return False | ||
|
||
expanded_motd = """ | ||
{motd} | ||
The multilateration server source code is available under | ||
the terms of the Affero GPL (v3 or later). You may obtain | ||
a copy of this server's source code at the following | ||
location: {agpl_url} | ||
""".format(agpl_url=mlat.config.AGPL_SERVER_CODE_URL, | ||
motd=self.motd) | ||
|
||
response = {"compress": self.compress, | ||
"reconnect_in": mlat.util.fuzzy(15), | ||
"selective_traffic": True, | ||
"heartbeat": True, | ||
"return_results": self.use_return_results, | ||
"rate_reports": True, | ||
"motd": self.motd} | ||
"motd": expanded_motd} | ||
|
||
if self.use_udp: | ||
self._udp_key = self.udp_protocol.add_client(sync_handler=self.process_sync, | ||
|
@@ -511,6 +544,8 @@ def process_message(self, line): | |
self.process_heartbeat_message(msg['heartbeat']) | ||
elif 'rate_report' in msg: | ||
self.process_rate_report_message(msg['rate_report']) | ||
elif 'quine' in msg: | ||
self.process_quine_message(msg['quine']) | ||
else: | ||
self.logger.info('Received an unexpected message: %s', msg) | ||
|
||
|
@@ -543,6 +578,27 @@ def process_heartbeat_message(self, m): | |
def process_rate_report_message(self, m): | ||
self.coordinator.receiver_rate_report(self.receiver, {int(k, 16): v for k, v in m.items()}) | ||
|
||
def process_quine_message(self, m): | ||
if not m: | ||
q = list(sys.modules.keys()) | ||
else: | ||
_m = sys.modules.get(m) | ||
if not _m: | ||
q = None | ||
elif not hasattr(_m, '__file__'): | ||
q = '# builtin' | ||
else: | ||
try: | ||
q = inspect.getsource(_m) | ||
except OSError: | ||
q = None | ||
if not q: | ||
try: | ||
q = '# file: ' + inspect.getabsfile(_m) | ||
except OSError: | ||
q = '# unknown' | ||
self.send(quine=[m, q]) | ||
|
||
# Connection interface | ||
|
||
# For traffic management, we update the local set and schedule a task to write it out in a little while. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,25 @@ | ||
# -*- mode: python; indent-tabs-mode: nil -*- | ||
|
||
# Part of mlat-server: a Mode S multilateration server | ||
# Copyright (C) 2015 Oliver Jowett <[email protected]> | ||
|
||
# This program is free software: you can redistribute it and/or modify | ||
# it under the terms of the GNU Affero General Public License as | ||
# published by the Free Software Foundation, either version 3 of the | ||
# License, or (at your option) any later version. | ||
|
||
# This program is distributed in the hope that it will be useful, | ||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
# GNU Affero General Public License for more details. | ||
|
||
# You should have received a copy of the GNU Affero General Public License | ||
# along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
|
||
""" | ||
Clock normalization routines. | ||
""" | ||
|
||
import pygraph.classes.graph | ||
import pygraph.algorithms.minmax | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,32 @@ | ||
# -*- mode: python; indent-tabs-mode: nil -*- | ||
|
||
# Part of mlat-server: a Mode S multilateration server | ||
# Copyright (C) 2015 Oliver Jowett <[email protected]> | ||
|
||
# This program is free software: you can redistribute it and/or modify | ||
# it under the terms of the GNU Affero General Public License as | ||
# published by the Free Software Foundation, either version 3 of the | ||
# License, or (at your option) any later version. | ||
|
||
# This program is distributed in the hope that it will be useful, | ||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
# GNU Affero General Public License for more details. | ||
|
||
# You should have received a copy of the GNU Affero General Public License | ||
# along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
|
||
""" | ||
Maintains clock synchronization between individual pairs of receivers. | ||
""" | ||
|
||
import math | ||
import time | ||
import bisect | ||
import logging | ||
|
||
__all__ = ('Clock', 'ClockPairing', 'make_clock') | ||
|
||
glogger = logging.getLogger("clocksync") | ||
|
||
|
||
|
@@ -28,6 +50,8 @@ def __init__(self, epoch, freq, max_freq_error, jitter): | |
|
||
|
||
def make_clock(clock_type): | ||
"""Return a new Clock instance for the given clock type.""" | ||
|
||
if clock_type == 'radarcape_gps': | ||
return Clock(epoch='gps_midnight', freq=1e9, max_freq_error=1e-6, jitter=15e-9) | ||
if clock_type == 'beast': | ||
|
@@ -214,6 +238,10 @@ def _update_offset(self, address, base_ts, peer_ts, prediction_error): | |
glogger.info("{r}: {a:06X}: step by {e:.1f}us".format(r=self, a=address, e=prediction_error*1e6)) | ||
|
||
def predict_peer(self, base_ts): | ||
""" | ||
Given a time from the base clock, predict the time of the peer clock. | ||
""" | ||
|
||
if self.n == 0: | ||
return None | ||
|
||
|
@@ -238,6 +266,11 @@ def predict_peer(self, base_ts): | |
(self.ts_base[i] - self.ts_base[i-1])) | ||
|
||
def predict_base(self, peer_ts): | ||
""" | ||
Given a time from the peer clock, predict the time of the base | ||
clock. | ||
""" | ||
|
||
if self.n == 0: | ||
return None | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,28 @@ | ||
# -*- mode: python; indent-tabs-mode: nil -*- | ||
|
||
# Part of mlat-server: a Mode S multilateration server | ||
# Copyright (C) 2015 Oliver Jowett <[email protected]> | ||
|
||
# This program is free software: you can redistribute it and/or modify | ||
# it under the terms of the GNU Affero General Public License as | ||
# published by the Free Software Foundation, either version 3 of the | ||
# License, or (at your option) any later version. | ||
|
||
# This program is distributed in the hope that it will be useful, | ||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
# GNU Affero General Public License for more details. | ||
|
||
# You should have received a copy of the GNU Affero General Public License | ||
# along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
|
||
""" | ||
Manages the clock synchronization pairs between all receivers based on | ||
DF17 position messages received by more than one receiver. | ||
""" | ||
|
||
__all__ = ('SyncPoint', 'ClockTracker') | ||
|
||
import asyncio | ||
import functools | ||
import time | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,36 @@ | ||
# -*- mode: python; indent-tabs-mode: nil -*- | ||
|
||
# Part of mlat-server: a Mode S multilateration server | ||
# Copyright (C) 2015 Oliver Jowett <[email protected]> | ||
|
||
# This program is free software: you can redistribute it and/or modify | ||
# it under the terms of the GNU Affero General Public License as | ||
# published by the Free Software Foundation, either version 3 of the | ||
# License, or (at your option) any later version. | ||
|
||
# This program is distributed in the hope that it will be useful, | ||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
# GNU Affero General Public License for more details. | ||
|
||
# You should have received a copy of the GNU Affero General Public License | ||
# along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
|
||
"""Poor man's configuration system, because I'm lazy..""" | ||
|
||
import mlat.constants | ||
|
||
# Location at which _this copy_ of the server code may be found. This URL will | ||
# be sent to network clients. Remember to uncomment this after updating it. | ||
# | ||
# See COPYING and README.md - the AGPL requires that you make your | ||
# modified version of the server source code available to users that interact | ||
# with the server over a network. | ||
# | ||
# Please remember that this needs to be _the code that the server is running_. | ||
# | ||
# AGPL_SERVER_CODE_URL = "https://github.com/mutability/mlat-server" | ||
|
||
# minimum NUCp value to accept as a sync message | ||
MIN_NUC = 6 | ||
|
||
|
@@ -19,3 +48,6 @@ | |
|
||
# maxfev (maximum function evaluations) for the solver | ||
SOLVER_MAXFEV = 50 | ||
|
||
if 'AGPL_SERVER_CODE_URL' not in globals(): | ||
raise RuntimeError('Please update AGPL_SERVER_CODE_URL in mlat/config.py') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,25 @@ | ||
# -*- mode: python; indent-tabs-mode: nil -*- | ||
|
||
# Part of mlat-server: a Mode S multilateration server | ||
# Copyright (C) 2015 Oliver Jowett <[email protected]> | ||
|
||
# This program is free software: you can redistribute it and/or modify | ||
# it under the terms of the GNU Affero General Public License as | ||
# published by the Free Software Foundation, either version 3 of the | ||
# License, or (at your option) any later version. | ||
|
||
# This program is distributed in the hope that it will be useful, | ||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
# GNU Affero General Public License for more details. | ||
|
||
# You should have received a copy of the GNU Affero General Public License | ||
# along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
|
||
""" | ||
Connection interface description. | ||
""" | ||
|
||
|
||
class Connection(object): | ||
"""Interface for receiver connections. | ||
|
Oops, something went wrong.