kopia lustrzana https://github.com/projecthorus/radiosonde_auto_rx
				
				
				
			
		
			
				
	
	
		
			180 wiersze
		
	
	
		
			5.8 KiB
		
	
	
	
		
			Python
		
	
	
			
		
		
	
	
			180 wiersze
		
	
	
		
			5.8 KiB
		
	
	
	
		
			Python
		
	
	
#!/usr/bin/env python
 | 
						|
#
 | 
						|
# Receiver Statistics Calculator
 | 
						|
#
 | 
						|
# 2018-04 Mark Jessop <vk5qi@rfhead.net>
 | 
						|
#
 | 
						|
# Usage:
 | 
						|
# python receiver_stats.py --lat=yourlat --lon=yourlon --alt=youralt ../log/
 | 
						|
# lat and lon are in decimal degrees.
 | 
						|
#
 | 
						|
import argparse
 | 
						|
import glob
 | 
						|
import numpy as np
 | 
						|
import sys
 | 
						|
from math import radians, degrees, sin, cos, atan2, sqrt, pi
 | 
						|
 | 
						|
 | 
						|
# Earthmaths code by Daniel Richman (thanks!)
 | 
						|
# Copyright 2012 (C) Daniel Richman; GNU GPL 3
 | 
						|
def position_info(listener, balloon):
 | 
						|
    """
 | 
						|
    Calculate and return information from 2 (lat, lon, alt) tuples
 | 
						|
 | 
						|
    Returns a dict with:
 | 
						|
 | 
						|
     - angle at centre
 | 
						|
     - great circle distance
 | 
						|
     - distance in a straight line
 | 
						|
     - bearing (azimuth or initial course)
 | 
						|
     - elevation (altitude)
 | 
						|
 | 
						|
    Input and output latitudes, longitudes, angles, bearings and elevations are
 | 
						|
    in degrees, and input altitudes and output distances are in meters.
 | 
						|
    """
 | 
						|
 | 
						|
    # Earth:
 | 
						|
    #radius = 6371000.0
 | 
						|
    radius = 6364963.0 # Optimized for Australia :-)
 | 
						|
 | 
						|
    (lat1, lon1, alt1) = listener
 | 
						|
    (lat2, lon2, alt2) = balloon
 | 
						|
 | 
						|
    lat1 = radians(lat1)
 | 
						|
    lat2 = radians(lat2)
 | 
						|
    lon1 = radians(lon1)
 | 
						|
    lon2 = radians(lon2)
 | 
						|
 | 
						|
    # Calculate the bearing, the angle at the centre, and the great circle
 | 
						|
    # distance using Vincenty's_formulae with f = 0 (a sphere). See
 | 
						|
    # http://en.wikipedia.org/wiki/Great_circle_distance#Formulas and
 | 
						|
    # http://en.wikipedia.org/wiki/Great-circle_navigation and
 | 
						|
    # http://en.wikipedia.org/wiki/Vincenty%27s_formulae
 | 
						|
    d_lon = lon2 - lon1
 | 
						|
    sa = cos(lat2) * sin(d_lon)
 | 
						|
    sb = (cos(lat1) * sin(lat2)) - (sin(lat1) * cos(lat2) * cos(d_lon))
 | 
						|
    bearing = atan2(sa, sb)
 | 
						|
    aa = sqrt((sa ** 2) + (sb ** 2))
 | 
						|
    ab = (sin(lat1) * sin(lat2)) + (cos(lat1) * cos(lat2) * cos(d_lon))
 | 
						|
    angle_at_centre = atan2(aa, ab)
 | 
						|
    great_circle_distance = angle_at_centre * radius
 | 
						|
 | 
						|
    # Armed with the angle at the centre, calculating the remaining items
 | 
						|
    # is a simple 2D triangley circley problem:
 | 
						|
 | 
						|
    # Use the triangle with sides (r + alt1), (r + alt2), distance in a
 | 
						|
    # straight line. The angle between (r + alt1) and (r + alt2) is the
 | 
						|
    # angle at the centre. The angle between distance in a straight line and
 | 
						|
    # (r + alt1) is the elevation plus pi/2.
 | 
						|
 | 
						|
    # Use sum of angle in a triangle to express the third angle in terms
 | 
						|
    # of the other two. Use sine rule on sides (r + alt1) and (r + alt2),
 | 
						|
    # expand with compound angle formulae and solve for tan elevation by
 | 
						|
    # dividing both sides by cos elevation
 | 
						|
    ta = radius + alt1
 | 
						|
    tb = radius + alt2
 | 
						|
    ea = (cos(angle_at_centre) * tb) - ta
 | 
						|
    eb = sin(angle_at_centre) * tb
 | 
						|
    elevation = atan2(ea, eb)
 | 
						|
 | 
						|
    # Use cosine rule to find unknown side.
 | 
						|
    distance = sqrt((ta ** 2) + (tb ** 2) - 2 * tb * ta * cos(angle_at_centre))
 | 
						|
 | 
						|
    # Give a bearing in range 0 <= b < 2pi
 | 
						|
    if bearing < 0:
 | 
						|
        bearing += 2 * pi
 | 
						|
 | 
						|
    return {
 | 
						|
        "listener": listener, "balloon": balloon,
 | 
						|
        "listener_radians": (lat1, lon1, alt1),
 | 
						|
        "balloon_radians": (lat2, lon2, alt2),
 | 
						|
        "angle_at_centre": degrees(angle_at_centre),
 | 
						|
        "angle_at_centre_radians": angle_at_centre,
 | 
						|
        "bearing": degrees(bearing),
 | 
						|
        "bearing_radians": bearing,
 | 
						|
        "great_circle_distance": great_circle_distance,
 | 
						|
        "straight_distance": distance,
 | 
						|
        "elevation": degrees(elevation),
 | 
						|
        "elevation_radians": elevation
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
 | 
						|
def read_last_position(filename):
 | 
						|
    ''' Read in a a sonde log file, and return the last lat/lon/alt '''
 | 
						|
 | 
						|
    _last = None
 | 
						|
    _f = open(filename, 'r')
 | 
						|
    for line in _f:
 | 
						|
        _last = line
 | 
						|
    
 | 
						|
    return _last.split(',')
 | 
						|
 | 
						|
 | 
						|
if __name__ == '__main__':
 | 
						|
 | 
						|
    parser = argparse.ArgumentParser()
 | 
						|
    parser.add_argument("--lat", default=-34.0, type=float, help="Receiver Latitude")
 | 
						|
    parser.add_argument("--lon", default=138.0, type=float, help="Receiver Longitude")
 | 
						|
    parser.add_argument("--alt", default=0.0, type=float, help="Receiver Altitude")
 | 
						|
    parser.add_argument("folder", default="../log/", help="Folder containing log files.")
 | 
						|
    args = parser.parse_args()
 | 
						|
 | 
						|
 | 
						|
    _file_list = glob.glob(args.folder + "*_sonde.log")
 | 
						|
    #print(_file_list)
 | 
						|
 | 
						|
 | 
						|
    statistics = {
 | 
						|
        'furthest': {'range':0},
 | 
						|
        'lowest': {'elev':90}
 | 
						|
        }
 | 
						|
 | 
						|
 | 
						|
    for _file in _file_list:
 | 
						|
        try:
 | 
						|
            _last_entry = read_last_position(_file)
 | 
						|
        except Exception as e:
 | 
						|
            print("Error processing file %s: " % _file + str(e))
 | 
						|
            continue
 | 
						|
 | 
						|
        _last_pos = (float(_last_entry[3]),float(_last_entry[4]),float(_last_entry[5]))
 | 
						|
 | 
						|
        _stats = position_info((args.lat, args.lon, args.alt), _last_pos)
 | 
						|
 | 
						|
        _range = _stats['straight_distance']/1000.0
 | 
						|
        _elev = _stats['elevation']
 | 
						|
 | 
						|
        if _range > statistics['furthest']['range']:
 | 
						|
            # Update the furthest distance
 | 
						|
            statistics['furthest']['range'] = _range
 | 
						|
            statistics['furthest']['elev'] = _stats['elevation']
 | 
						|
            statistics['furthest']['bearing'] = _stats['bearing']
 | 
						|
            statistics['furthest']['telem'] = _last_entry
 | 
						|
 | 
						|
        if (_elev < statistics['lowest']['elev']) and (_range > 20) :
 | 
						|
            statistics['lowest']['range'] = _range
 | 
						|
            statistics['lowest']['elev'] = _stats['elevation']
 | 
						|
            statistics['lowest']['bearing'] = _stats['bearing']
 | 
						|
            statistics['lowest']['telem'] = _last_entry
 | 
						|
 | 
						|
    print("Longest Distance: %.1f km" % statistics['furthest']['range'])
 | 
						|
    print("    Detail: %.1f deg elev, %.1f deg bearing" % (
 | 
						|
        statistics['furthest']['elev'],
 | 
						|
        statistics['furthest']['bearing']))
 | 
						|
    print("    Last Telemetry: %s" % str(",".join(statistics['furthest']['telem'])))
 | 
						|
    
 | 
						|
 | 
						|
    print("Lowest Elevation: %.1f degrees" % statistics['lowest']['elev'])
 | 
						|
    print("    Detail: %.1f km range, %.1f deg bearing" % (
 | 
						|
        statistics['lowest']['range'],
 | 
						|
        statistics['lowest']['bearing']))
 | 
						|
    print("    Last Telemetry: %s" % str(",".join(statistics['lowest']['telem'])))
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 |