GPS mapping - SergeGit/rc-tank-platform GitHub Wiki
Link
https://github.com/darthmonkey2004/pitank/blob/main/host/mapper.py
Code
import pyproj
from pitank.host.browser import *
import gmplot
import requests
import keyring
from random import randint
from testgps import *
class target():
def __init__(self, _id, lat=None, lon=None, name=None):
self.id = _id
self.lat = lat
self.lon = lon
self.coords = self.lat, self.lon
self.name = name
self.heading = None
self.distance = -1
class mapper():
def __init__(self, origin=(), zoom=20, origin_name='You Are Here!'):
self.gps = gps()
if origin == ():
print("Getting current location...")
self.origin = None
while self.origin is None:
ret, data = self.gps.poll()
if ret:
self.origin = data['lat'], data['lon']
break
else:
self.origin = origin
self.zoom = zoom
self.origin_name = origin_name
self.api_key = self.get_api_key()
self.origin_color = 'green'
self.target_color = 'red'
self.map = self.new_map(origin=self.origin)
self.targets = {}
def add_target(self, coords, name=None):
_id = len(list(self.targets.keys()))
t_lat, t_lon = coords
if name is None:
name = f"target_{_id}"
t = target(_id=_id, lat=t_lat, lon=t_lon, name=name)
t.heading, t.distance = self.get_telemetry(t.coords, self.origin)
print("heading, distance:", t.heading, t.distance)
self.targets[_id] = t
return self.targets
def get_current_pos(self):
origin = None
attempts = 0
while origin is None:
ret, data = self.gps.poll()
if ret:
origin = data['lat'], data['lon']
break
else:
attempts += 1
if attempts >= 20:
print("Retries exceeded! Must not have a good fix...")
origin = (None, None)
break
self.origin = origin
return self.origin
def update(self):
self.origin = self.get_current_pos()
targets = list(self.targets.values())
for t in targets:
try:
t.heading, t.distance = self.get_telemetry(t.coords, self.origin)
except Exception as e:
print(f"Failed to update target ({t.id}, {e})! Removing...")
self.targets = self.remove_target(t.id)
return self.targets
def remove_target(self, _id):
try:
del self.targets[_id]
return True
except Exception as e:
print(f"Unable to remove target with id {_id}: {e}")
return False
def set_api_key(self):
try:
self.api_key = input("enter api key: ")
keyring.set_password('API_KEY', 'MAPS', self.api_key)
return True, self.api_key
except Exception as e:
print("Couldn't set api key:", e)
return False
def get_api_key(self):
try:
self.api_key = keyring.get_password('API_KEY', 'MAPS')
except Exception as e:
print("Key isn't set! Setting...", e)
ret = self.set_api_key()
if ret:
self.api_key = ret
else:
self.api_key = None
return self.api_key
def get_telemetry(self, next_target, src_coords=None):
if src_coords is not None:
self.origin = src_coords
self.next_target = next_target
src_lat, src_lon = self.origin
t_lat, t_lon = self.next_target
g = pyproj.Geod(ellps='WGS84')
self.next_target_heading, _, self.next_target_distance = g.inv(src_lon, src_lat, t_lon, t_lat)
return self.next_target_heading, self.next_target_distance
def new_map(self, origin=None):
if origin is not None:
self.origin = origin
lat, lon = self.origin
self.map = gmplot.GoogleMapPlotter(lat, lon, self.zoom, apikey=self.api_key)
self.map.marker(lat, lon, color=self.origin_color)
return self.map
def create_targets_list(self, targets):
target_lats = []
target_lons = []
for target in targets:
lat, lon = target
target_lats.append(lat)
target_lons.append(lon)
return target_lats, target_lons
def plot_targets(self, targets=[], coords=None, gmap=None):
self.targets = targets
if gmap is not None:
self.map = gmap
if coords is not None:
self.origin = coords
color = 'red'
pos = 0
for target in self.targets:
pos += 1
if self.origin is not None:
heading, distance = get_telemetry(self.origin, target)
name = f"target_{pos}:heading={heading}, distance={distance}"
else:
name = f"target_{pos}"
#self.map.scatter(lats, lons, color='#3B0B39', size=40, marker=False)
self.map.marker(target[0], target[1], color=color, title=name)
return self.map
def draw_fence(self, pois=[], gmap=None, coords=None):
if gmap is not None:
self.map = gmap
color = 'blue'
rois = zip(*pois)
self.map.polygon(*rois, color=color, edge_width=10)
return self.map
def open(filepath='map.html'):
self.filepath = filepath
self.map.draw(self.filepath)
if __name__ == "__main__":
#right = lon + step
#left = lon - step
#down = lat - step
#up = lat + step
step = 1
lon = 0
lat = 0
coords = lat, lon
targets = []
t_lat = -1
t_lon = lon
targets.append((t_lat, t_lon))
for i in range(0, 8):
t_lat = t_lat - step
#t_lon = t_lon + step
targets.append((t_lat, t_lon))
m = new_map(coords[0], coords[1])
m = plot_targets(targets=targets, coords=coords, gmap=m)
m.draw('map.html')