kopia lustrzana https://github.com/projecthorus/radiosonde_auto_rx
				
				
				
			
		
			
				
	
	
		
			134 wiersze
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Python
		
	
	
			
		
		
	
	
			134 wiersze
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Python
		
	
	
| #!/usr/bin/env python
 | |
| #
 | |
| # Radiosonde Auto RX Tools
 | |
| # Process last_position.txt and determine effective radio horizon
 | |
| #
 | |
| # 2017-05 Mark Jessop <vk5qi@rfhead.net>
 | |
| #
 | |
| 
 | |
| from math import radians, degrees, sin, cos, atan2, sqrt, pi
 | |
| import sys
 | |
| import numpy as np
 | |
| import matplotlib.pyplot as plt
 | |
| 
 | |
| # SET YOUR LOCATION HERE.
 | |
| my_lat = 0.0
 | |
| my_lon = 0.0
 | |
| my_alt = 0.0
 | |
| 
 | |
| # 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
 | |
|     }
 | |
| 
 | |
| if __name__ == '__main__':
 | |
| 	# Read in last_position.txt line by line.
 | |
| 	f = open('last_positions.txt','r')
 | |
| 
 | |
| 	azimuths = []
 | |
| 	elevations = []
 | |
| 	slant_ranges = []
 | |
| 
 | |
| 	for line in f:
 | |
| 		if 'Last Position:' in line:
 | |
| 			try:
 | |
| 				last_lat = float(line.split(',')[0].split(' ')[2])
 | |
| 				last_lon = float(line.split(',')[1])
 | |
| 				last_alt = float(line.split(',')[2].split(' ')[1])
 | |
| 
 | |
| 				pos_data = position_info( (my_lat, my_lon, my_alt), (last_lat, last_lon, last_alt))
 | |
| 
 | |
| 				azimuths.append(pos_data['bearing'])
 | |
| 				elevations.append(pos_data['elevation'])
 | |
| 				slant_ranges.append(pos_data['straight_distance'])
 | |
| 			except:
 | |
| 				pass
 | |
| 
 | |
| 	f.close()
 | |
| 
 | |
| 	# Plot
 | |
| 	plt.scatter(azimuths, elevations)
 | |
| 	plt.xlabel('Bearing (degrees)')
 | |
| 	plt.ylabel('Elevation (degrees)')
 | |
| 	plt.show()
 | |
| 
 | |
| 
 |