kopia lustrzana https://github.com/projecthorus/chasemapper
Add stationary listener option
rodzic
13194ebf0f
commit
f1b1a1d80d
|
@ -57,7 +57,7 @@ Edit this file with your preferred text editor. The configuration file is fairly
|
|||
* At least one telemetry 'profile', which defines where payload and (optionally) car position telemetry data is sourced from.
|
||||
* A default latitude and longitude for the map to centre on.
|
||||
|
||||
The example configuration file includes profiles suitable for receiving data from radiosonde_auto_rx, and from OziMux messages.
|
||||
The example configuration file includes profiles suitable for receiving data from radiosonde_auto_rx, and from [Horus-GUI](https://github.com/projecthorus/horus-gui).
|
||||
|
||||
Once configured, you can start-up the horusmapper server with:
|
||||
```
|
||||
|
|
|
@ -5,3 +5,7 @@
|
|||
# Copyright (C) 2018 Mark Jessop <vk5qi@rfhead.net>
|
||||
# Released under GNU GPL v3 or later
|
||||
#
|
||||
|
||||
# Now using Semantic Versioning (https://semver.org/) MAJOR.MINOR.PATCH
|
||||
|
||||
__version__ = "1.0.1"
|
|
@ -20,6 +20,7 @@ default_config = {
|
|||
# Start location for the map (until either a chase car position, or balloon position is available.)
|
||||
"default_lat": -34.9,
|
||||
"default_lon": 138.6,
|
||||
"default_alt": 0,
|
||||
"payload_max_age": 180,
|
||||
"thunderforest_api_key": "none",
|
||||
# Predictor settings
|
||||
|
@ -64,8 +65,8 @@ def parse_config_file(filename):
|
|||
# Map Defaults
|
||||
chase_config["flask_host"] = config.get("map", "flask_host")
|
||||
chase_config["flask_port"] = config.getint("map", "flask_port")
|
||||
chase_config["default_lat"] = config.get("map", "default_lat")
|
||||
chase_config["default_lon"] = config.get("map", "default_lon")
|
||||
chase_config["default_lat"] = config.getfloat("map", "default_lat")
|
||||
chase_config["default_lon"] = config.getfloat("map", "default_lon")
|
||||
chase_config["payload_max_age"] = config.getint("map", "payload_max_age")
|
||||
chase_config["thunderforest_api_key"] = config.get("map", "thunderforest_api_key")
|
||||
|
||||
|
@ -156,6 +157,12 @@ def parse_config_file(filename):
|
|||
logging.info("Missing Chase Car Speedo Setting, using default (disabled)")
|
||||
chase_config["chase_car_speed"] = False
|
||||
|
||||
try:
|
||||
chase_config["default_alt"] = config.getfloat("map", "default_alt")
|
||||
except:
|
||||
logging.info("Missing default_alt setting, using default (0m)")
|
||||
chase_config["default_alt"] = 0
|
||||
|
||||
# Telemetry Source Profiles
|
||||
|
||||
_profile_count = config.getint("profile_selection", "profile_count")
|
||||
|
|
|
@ -32,6 +32,7 @@ telemetry_source_port = 55673
|
|||
# horus_udp - Read Horus UDP Broadcast 'Car GPS' messages
|
||||
# serial - Read GPS positions from a serial-connected GPS receiver.
|
||||
# gpsd - Poll GPSD for positions.
|
||||
# station - Stationary position (set in the [map] section below)
|
||||
car_source_type = gpsd
|
||||
# Car position source port (UDP) - only used if horus_udp is selected, but still needs to be provided.
|
||||
car_source_port = 12345
|
||||
|
@ -74,15 +75,18 @@ gps_port = /dev/ttyUSB0
|
|||
gps_baud = 9600
|
||||
|
||||
|
||||
# Map Defaults
|
||||
# Map Settings
|
||||
[map]
|
||||
# Host/port to host webserver on
|
||||
flask_host = 0.0.0.0
|
||||
flask_port = 5001
|
||||
|
||||
# Default map centre
|
||||
# Default Map Centre & Stationary Position
|
||||
# If the profile's car_source_type is set to station, the following position will be indicated on the map
|
||||
# as a stationary receiver.
|
||||
default_lat = -34.9
|
||||
default_lon = 138.6
|
||||
default_alt = 0.0
|
||||
|
||||
# How long to keep payload data (minutes)
|
||||
payload_max_age = 180
|
||||
|
@ -191,7 +195,8 @@ range_ring_color = red
|
|||
range_ring_custom_color = #FF0000
|
||||
|
||||
#
|
||||
# Chase Car Speedometer
|
||||
# Chase Car Speedometer
|
||||
# If enabled display the chase car speed at the bottom left of the display.
|
||||
#
|
||||
[speedo]
|
||||
chase_car_speed = True
|
||||
|
|
|
@ -18,6 +18,7 @@ from threading import Thread
|
|||
from datetime import datetime, timedelta
|
||||
from dateutil.parser import parse
|
||||
|
||||
from chasemapper import __version__ as CHASEMAPPER_VERSION
|
||||
from chasemapper.config import *
|
||||
from chasemapper.earthmaths import *
|
||||
from chasemapper.geometry import *
|
||||
|
@ -789,7 +790,7 @@ def udp_listener_car_callback(data):
|
|||
# Handle when GPSD and/or other GPS data sources return a n/a for altitude.
|
||||
try:
|
||||
_alt = float(data["altitude"])
|
||||
except ValueError:
|
||||
except:
|
||||
_alt = 0.0
|
||||
|
||||
_comment = "CAR"
|
||||
|
@ -896,7 +897,7 @@ def start_listeners(profile):
|
|||
'name' (str): Profile name
|
||||
'telemetry_source_type' (str): Data source type (ozimux or horus_udp)
|
||||
'telemetry_source_port' (int): Data source port
|
||||
'car_source_type' (str): Car Position source type (none, horus_udp or gpsd)
|
||||
'car_source_type' (str): Car Position source type (none, horus_udp, gpsd, or station)
|
||||
'car_source_port' (int): Car Position source port
|
||||
"""
|
||||
global data_listeners
|
||||
|
@ -994,6 +995,9 @@ def start_listeners(profile):
|
|||
)
|
||||
data_listeners.append(_serial_gps)
|
||||
|
||||
elif profile["car_source_type"] == "station":
|
||||
logging.info("Using Stationary receiver position.")
|
||||
|
||||
else:
|
||||
# No Car position.
|
||||
logging.info("No car position data source.")
|
||||
|
@ -1014,6 +1018,16 @@ def profile_change(data):
|
|||
# Update all clients with the new profile selection
|
||||
flask_emit_event("server_settings_update", chasemapper_config)
|
||||
|
||||
@socketio.on("device_position", namespace="/chasemapper")
|
||||
def device_position_update(data):
|
||||
""" Accept a device position update from a client and process it as if it was a chase car position """
|
||||
try:
|
||||
udp_listener_car_callback(data)
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
|
||||
|
||||
class WebHandler(logging.Handler):
|
||||
""" Logging Handler for sending log messages via Socket.IO to a Web Client """
|
||||
|
@ -1093,6 +1107,9 @@ if __name__ == "__main__":
|
|||
logging.critical("Could not read configuration data. Exiting")
|
||||
sys.exit(1)
|
||||
|
||||
# Add in Chasemapper version information.
|
||||
chasemapper_config['version'] = CHASEMAPPER_VERSION
|
||||
|
||||
# Copy out the predictor settings to another dictionary.
|
||||
pred_settings = {
|
||||
"pred_binary": chasemapper_config["pred_binary"],
|
||||
|
|
|
@ -124,13 +124,21 @@ function updateSummaryDisplay(){
|
|||
_summary_update.vel_v = _latest_telem.vel_v.toFixed(1) + " m/s";
|
||||
|
||||
|
||||
// Work out if we have data to calculate look-angles from.
|
||||
if (chase_car_position.latest_data.length == 3){
|
||||
// We have a chase car position! Calculate relative position.
|
||||
var _bal = {lat:_latest_telem.position[0], lon:_latest_telem.position[1], alt:_latest_telem.position[2]};
|
||||
// Chase car position available - use that.
|
||||
var _car = {lat:chase_car_position.latest_data[0], lon:chase_car_position.latest_data[1], alt:chase_car_position.latest_data[2]};
|
||||
} else if (home_marker !== "NONE") {
|
||||
// Home marker is on the map - use the home marker position
|
||||
var _car = {lat:chase_config.default_lat, lon:chase_config.default_lon, alt:chase_config.default_alt};
|
||||
} else {
|
||||
// Otherwise, nothing we can use
|
||||
var _car = null;
|
||||
}
|
||||
|
||||
if(_car !== null){
|
||||
var _bal = {lat:_latest_telem.position[0], lon:_latest_telem.position[1], alt:_latest_telem.position[2]};
|
||||
var _look_angles = calculate_lookangles(_car, _bal);
|
||||
|
||||
_summary_update.elevation = _look_angles.elevation.toFixed(0) + "°";
|
||||
_summary_update.azimuth = _look_angles.azimuth.toFixed(0) + "°";
|
||||
_summary_update.range = (_look_angles.range/1000).toFixed(1) + "km";
|
||||
|
@ -168,11 +176,21 @@ function updateSummaryDisplayImperial(){
|
|||
_summary_update.vel_v = (_latest_telem.vel_v*3.28084*60).toFixed(0) + " ft/min";
|
||||
|
||||
|
||||
// Work out if we have data to calculate look-angles from.
|
||||
if (chase_car_position.latest_data.length == 3){
|
||||
// Chase car position available - use that.
|
||||
var _car = {lat:chase_car_position.latest_data[0], lon:chase_car_position.latest_data[1], alt:chase_car_position.latest_data[2]};
|
||||
} else if (home_marker !== "NONE") {
|
||||
// Home marker is on the map - use the home marker position
|
||||
var _car = {lat:chase_config.default_lat, lon:chase_config.default_lon, alt:chase_config.default_alt};
|
||||
} else {
|
||||
// Otherwise, nothing we can use
|
||||
var _car = null;
|
||||
}
|
||||
|
||||
if(_car !== null){
|
||||
// We have a chase car position! Calculate relative position.
|
||||
var _bal = {lat:_latest_telem.position[0], lon:_latest_telem.position[1], alt:_latest_telem.position[2]};
|
||||
var _car = {lat:chase_car_position.latest_data[0], lon:chase_car_position.latest_data[1], alt:chase_car_position.latest_data[2]};
|
||||
|
||||
var _look_angles = calculate_lookangles(_car, _bal);
|
||||
|
||||
_summary_update.elevation = _look_angles.elevation.toFixed(0) + "°";
|
||||
|
|
|
@ -109,3 +109,39 @@ function updateRangeRings(){
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
function reconfigureCarMarker(profile_name){
|
||||
// Remove chase-car marker if it exists, and is not used.
|
||||
if( (chase_config.profiles[profile_name].car_source_type === "none") || (chase_config.profiles[profile_name].car_source_type === "station")){
|
||||
if (chase_car_position.marker !== "NONE"){
|
||||
chase_car_position.marker.remove();
|
||||
chase_car_position.path.remove();
|
||||
}
|
||||
}
|
||||
|
||||
if (chase_config.profiles[profile_name].car_source_type === "station") {
|
||||
// If we are using a stationary profile, add the station icon to the map.
|
||||
// Add our station location marker.
|
||||
home_marker = L.marker([chase_config.default_lat, chase_config.default_lon, chase_config.default_alt],
|
||||
{title: 'Receiver Location', icon: homeIcon}
|
||||
).addTo(map);
|
||||
}
|
||||
|
||||
// If we are switching to a profile with a live car position source, remove the home station Icon
|
||||
if ((chase_config.profiles[profile_name].car_source_type === "serial") || (chase_config.profiles[profile_name].car_source_type === "gpsd") || (chase_config.profiles[profile_name].car_source_type === "horus_udp")){
|
||||
if(home_marker !== "NONE"){
|
||||
home_marker.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var devicePositionCallback = function(position){
|
||||
// Pass a Device position update onto the back-end for processing and re-distribution.
|
||||
var device_pos = {time:position.timestamp, latitude:position.coords.latitude, longitude:position.coords.longitude, altitude:position.coords.altitude};
|
||||
socket.emit('device_position', device_pos);
|
||||
}
|
||||
|
||||
var devicePositionError = function(error){
|
||||
console.log(error.message);
|
||||
}
|
|
@ -66,8 +66,6 @@ function serverSettingsUpdate(data){
|
|||
$('#bearingCustomColor').val(chase_config.bearing_custom_color);
|
||||
$('#bearingMaximumAge').val((chase_config.max_bearing_age/60.0).toFixed(0));
|
||||
|
||||
|
||||
|
||||
// Clear and populate the profile selection.
|
||||
$('#profileSelect').children('option:not(:first)').remove();
|
||||
|
||||
|
@ -78,6 +76,9 @@ function serverSettingsUpdate(data){
|
|||
.text(key));
|
||||
});
|
||||
$("#profileSelect").val(chase_config.selected_profile);
|
||||
|
||||
// Update version
|
||||
$('#chasemapper_version').html(chase_config.version);
|
||||
}
|
||||
|
||||
function clientSettingsUpdate(){
|
||||
|
|
|
@ -66,6 +66,14 @@ var carIconFlip = L.icon({
|
|||
iconAnchor: [27,12] // Revisit this
|
||||
});
|
||||
|
||||
// Home Icon.
|
||||
var homeIcon = L.icon({
|
||||
iconUrl: '/static/img/antenna-green.png',
|
||||
iconSize: [26, 34],
|
||||
iconAnchor: [13, 34]
|
||||
});
|
||||
|
||||
|
||||
// Habitat (or APRS?) sourced chase car icons.
|
||||
var car_colour_values = ['red', 'green', 'yellow'];
|
||||
var car_colour_idx = 0;
|
||||
|
|
|
@ -72,6 +72,9 @@
|
|||
// marker: Leaflet marker
|
||||
var chase_car_position = {latest_data: [], heading:0, marker: 'NONE', path: 'NONE'};
|
||||
|
||||
// Home position marker
|
||||
var home_marker = 'NONE';
|
||||
|
||||
// Data Age variables - these are updated regularly to indicate
|
||||
// if we haven't received data in a while.
|
||||
var payload_data_age = 0.0;
|
||||
|
@ -191,8 +194,11 @@
|
|||
$("#profileSelect").change(function(){
|
||||
// On a profile selection change, emit a message to the client.
|
||||
socket.emit('profile_change', this.value);
|
||||
});
|
||||
|
||||
// Remove chase car if switching to a profile which does not have live position updates.
|
||||
_profile = this.value;
|
||||
reconfigureCarMarker(this.value);
|
||||
});
|
||||
|
||||
// Handle arrival of new log data.
|
||||
socket.on('log_event', function(msg) {
|
||||
|
@ -251,24 +257,20 @@
|
|||
// Add measurement control.
|
||||
|
||||
if (chase_config['unitselection'] == "imperial") {
|
||||
|
||||
|
||||
L.control.polylineMeasure({
|
||||
position: 'topleft',
|
||||
unit: 'landmiles',
|
||||
showClearControl: true,
|
||||
}).addTo(map);
|
||||
|
||||
L.control.polylineMeasure({
|
||||
position: 'topleft',
|
||||
unit: 'landmiles',
|
||||
showClearControl: true,
|
||||
}).addTo(map);
|
||||
}
|
||||
|
||||
|
||||
if (chase_config['unitselection'] == "metric") {
|
||||
L.control.polylineMeasure({
|
||||
position: 'topleft',
|
||||
unit: 'metres',
|
||||
showClearControl: true,
|
||||
}).addTo(map);
|
||||
|
||||
L.control.polylineMeasure({
|
||||
position: 'topleft',
|
||||
unit: 'metres',
|
||||
showClearControl: true,
|
||||
}).addTo(map);
|
||||
}
|
||||
|
||||
|
||||
|
@ -462,6 +464,9 @@
|
|||
// Initialise bearings
|
||||
initialiseBearings();
|
||||
|
||||
// Initial setup of station marker, if using a profile which uses it.
|
||||
reconfigureCarMarker(chase_config.selected_profile);
|
||||
|
||||
|
||||
// Telemetry event handler.
|
||||
// We will get one of these mesages with every new balloon position
|
||||
|
@ -613,6 +618,16 @@
|
|||
}, habitat_update_rate);
|
||||
|
||||
|
||||
// window.setInterval(function(){
|
||||
// if(document.getElementById('useDevicePosition').checked){
|
||||
// if(navigator.geolocation){
|
||||
// car_bad_age = 20.0;
|
||||
// navigator.geolocation.getCurrentPosition(devicePositionCallback,devicePositionError,{enableHighAccuracy:true});
|
||||
// }
|
||||
// }
|
||||
// }, 5000);
|
||||
|
||||
|
||||
window.setInterval(function(){
|
||||
if(Object.keys(bearing_store).length > 0){
|
||||
$.ajax({
|
||||
|
@ -673,6 +688,10 @@
|
|||
<!-- Tab panes -->
|
||||
<div class="sidebar-content">
|
||||
<div class="sidebar-pane" id="home">
|
||||
<div class="paramRow">
|
||||
<b>Chasemapper Version: </b> <div id="chasemapper_version" class="paramEntry">Unknown</div></br>
|
||||
</div>
|
||||
</br>
|
||||
<h1 class="sidebar-header">
|
||||
Log Messages
|
||||
<span class="sidebar-close"><i class="fa fa-caret-left"></i></span>
|
||||
|
@ -742,6 +761,13 @@
|
|||
<span class="sidebar-close"><i class="fa fa-caret-left"></i></span>
|
||||
</h1>
|
||||
|
||||
<!--
|
||||
<h3>Car Position Source</h3>
|
||||
<div class="paramRow">
|
||||
<b>Use Device Position:</b> <input type="checkbox" class="paramSelector" id="useDevicePosition">
|
||||
</div>
|
||||
-->
|
||||
|
||||
<h3>Habitat Chase Car</h3>
|
||||
<div class="paramRow">
|
||||
<b>Show Nearby Chase-Cars:</b> <input type="checkbox" class="paramSelector" id="showOtherCars" onclick="show_habitat_vehicles();">
|
||||
|
|
Ładowanie…
Reference in New Issue