Skip to content

Commit

Permalink
Polyline rework (#3854)
Browse files Browse the repository at this point in the history
* added better rng

* forgot adding

* rework on polyline

* remove wrong files...

* remove wrong files...

* reverting unnecessory change...

* minor fix

* get the CI pass

* fix test

* minor fix
  • Loading branch information
kanemasa1987 authored and elicwhite committed Aug 19, 2016
1 parent a58d437 commit b60cefd
Show file tree
Hide file tree
Showing 12 changed files with 106 additions and 39 deletions.
1 change: 1 addition & 0 deletions configs/config.json.map.example
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@
"update_map": true,
"mode": "priority",
"map_path": "raw_data",
"walker": "StepWalker",
"catch": {
"==========Legendaries==========": 0,
"Aerodactyl": 1000,
Expand Down
2 changes: 1 addition & 1 deletion pokemongo_bot/cell_workers/follow_cluster.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from pokemongo_bot.step_walker import StepWalker
from pokemongo_bot.walkers.step_walker import StepWalker
from pokemongo_bot.cell_workers.utils import distance
from pokemongo_bot.cell_workers.utils import find_biggest_cluster
from pokemongo_bot.base_task import BaseTask
Expand Down
2 changes: 1 addition & 1 deletion pokemongo_bot/cell_workers/follow_path.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from pokemongo_bot.base_task import BaseTask
from pokemongo_bot.cell_workers.utils import distance, i2f, format_dist
from pokemongo_bot.human_behaviour import sleep
from pokemongo_bot.step_walker import StepWalker
from pokemongo_bot.walkers.step_walker import StepWalker
from pgoapi.utilities import f2i


Expand Down
2 changes: 1 addition & 1 deletion pokemongo_bot/cell_workers/follow_spiral.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import math

from pokemongo_bot.cell_workers.utils import distance, format_dist
from pokemongo_bot.step_walker import StepWalker
from pokemongo_bot.walkers.step_walker import StepWalker
from pokemongo_bot.base_task import BaseTask

class FollowSpiral(BaseTask):
Expand Down
2 changes: 1 addition & 1 deletion pokemongo_bot/cell_workers/move_to_fort.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from pokemongo_bot import inventory
from pokemongo_bot.constants import Constants
from pokemongo_bot.step_walker import StepWalker
from pokemongo_bot.walkers.step_walker import StepWalker
from pokemongo_bot.worker_result import WorkerResult
from pokemongo_bot.base_task import BaseTask
from utils import distance, format_dist, fort_details
Expand Down
11 changes: 6 additions & 5 deletions pokemongo_bot/cell_workers/move_to_map_pokemon.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
from pokemongo_bot import inventory
from pokemongo_bot.base_dir import _base_dir
from pokemongo_bot.cell_workers.utils import distance, format_dist, format_time
from pokemongo_bot.step_walker import StepWalker
from pokemongo_bot.walkers.walker_factory import walker_factory
from pokemongo_bot.worker_result import WorkerResult
from pokemongo_bot.base_task import BaseTask
from pokemongo_bot.cell_workers.pokemon_catch_worker import PokemonCatchWorker
Expand Down Expand Up @@ -90,10 +90,10 @@ def initialize(self):
self.caught = []
self.min_ball = self.config.get('min_ball', 1)
self.map_path = self.config.get('map_path', 'raw_data')
self.walker = self.config.get('walker', 'StepWalker')
self.snipe_high_prio_only = self.config.get('snipe_high_prio_only', False)
self.snipe_high_prio_threshold = self.config.get('snipe_high_prio_threshold', 400)


data_file = os.path.join(_base_dir, 'map-caught-{}.json'.format(self.bot.config.username))
if os.path.isfile(data_file):
self.caught = json.load(
Expand Down Expand Up @@ -365,7 +365,7 @@ def _move_to(self, pokemon):
pokemon: Pokemon to move to.
Returns:
StepWalker
Walker
"""
now = int(time.time())
self.emit_event(
Expand All @@ -374,8 +374,9 @@ def _move_to(self, pokemon):
'{disappears_in})'),
data=self._pokemon_event_data(pokemon)
)
return StepWalker(
return walker_factory(self.walker,
self.bot,
pokemon['latitude'],
pokemon['longitude']
pokemon['longitude'],
**{'parent': MoveToMapPokemon}
)
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import unittest
from mock import MagicMock, patch

from pokemongo_bot.step_walker import StepWalker
from pokemongo_bot.walkers.step_walker import StepWalker
from pokemongo_bot.cell_workers.utils import float_equal

NORMALIZED_LAT_LNG_DISTANCE_STEP = 6.3593e-6

class TestStepWalker(unittest.TestCase):
def setUp(self):
self.patcherSleep = patch('pokemongo_bot.step_walker.sleep')
self.patcherRandomLat = patch('pokemongo_bot.step_walker.random_lat_long_delta', return_value=0)
self.patcherSleep = patch('pokemongo_bot.walkers.step_walker.sleep')
self.patcherRandomLat = patch('pokemongo_bot.walkers.step_walker.random_lat_long_delta', return_value=0)
self.patcherSleep.start()
self.patcherRandomLat.start()

Expand Down
2 changes: 0 additions & 2 deletions pokemongo_bot/walkers/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +0,0 @@
from polyline_generator import Polyline
from polyline_walker import PolylineWalker
49 changes: 46 additions & 3 deletions pokemongo_bot/walkers/polyline_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,48 @@
import polyline
import requests

class PolylineObjectHandler:
'''
Does this need to be a class?
More like a namespace...
'''
_cache = {}
_kill_these = set()

class Polyline(object):
@staticmethod
def cached_polyline(bot, origin, destination, speed, parent_cls):
'''
Google API has limits, so we can't generate new Polyline at every tick...
'''
for key in list(PolylineObjectHandler._kill_these):
PolylineObjectHandler._cache.pop(key)
PolylineObjectHandler._kill_these.remove(key)

key = parent_cls
if key not in PolylineObjectHandler._cache:
polyline = Polyline(origin, destination, speed)
polyline.key = key
polyline.destination = destination

PolylineObjectHandler._cache[key] = polyline
elif key in PolylineObjectHandler._cache and PolylineObjectHandler._cache[key].destination != destination:
# The case bot changes mind to catch Mew instead of following Doduo...
# Merge with upper code? Without comment, it would be quite puzzling...
polyline = Polyline(origin, destination, speed)
polyline.key = key
polyline.destination = destination

PolylineObjectHandler._cache[key] = polyline
else:
polyline = PolylineObjectHandler._cache[key]
return polyline

@staticmethod
def delete_cache(polyline):
PolylineObjectHandler._cache.pop(polyline.key)


class Polyline(object):
def __init__(self, origin, destination, speed):
self.DISTANCE_API_URL='https://maps.googleapis.com/maps/api/directions/json?mode=walking'
self.origin = origin
Expand All @@ -18,12 +57,16 @@ def __init__(self, origin, destination, speed):
'{},{}'.format(*self.destination))
self.request_responce = requests.get(self.URL).json()
try:
# Polyline walker starts teleporting after reaching api query limit.
# throw error here atm, catch it at factory and return StepWalker
# TODO Check what is happening...
self.polyline_points = [x['polyline']['points'] for x in
self.request_responce['routes'][0]['legs'][0]['steps']]
self.request_responce['routes'][0]['legs'][0]['steps']]
except IndexError:
self.polyline_points = self.request_responce['routes']
self.speed = float(speed)
raise # catch at factory atm...
self.points = [self.origin] + self.get_points(self.polyline_points) + [self.destination]
self.speed = float(speed)
self.lat, self.long = self.points[0][0], self.points[0][1]
self.polyline = self.combine_polylines(self.points)
self._timestamp = time.time()
Expand Down
49 changes: 29 additions & 20 deletions pokemongo_bot/walkers/polyline_walker.py
Original file line number Diff line number Diff line change
@@ -1,31 +1,40 @@
# -*- coding: utf-8 -*-

from pokemongo_bot.human_behaviour import sleep
from pokemongo_bot.step_walker import StepWalker
from polyline_generator import Polyline

from pokemongo_bot.walkers.step_walker import StepWalker
from polyline_generator import PolylineObjectHandler
from pokemongo_bot.cell_workers.utils import distance
from pokemongo_bot.constants import Constants

class PolylineWalker(StepWalker):
'''
Heavy multi-botting can cause issue, since the directions API has limits.
'''

def __init__(self, bot, speed, dest_lat, dest_lng):
def __init__(self, bot, speed, dest_lat, dest_lng, parent):
super(PolylineWalker, self).__init__(bot, speed, dest_lat, dest_lng)
self.polyline_walker = Polyline((self.api._position_lat, self.api._position_lng),
(self.destLat, self.destLng), self.speed)
self.bot.event_manager.emit(
'polyline_request',
sender=self,
level='info',
formatted="{url}",
data={'url': self.polyline_walker.URL}
self.polyline_walker = PolylineObjectHandler.cached_polyline(bot, (self.api._position_lat, self.api._position_lng),
(self.destLat, self.destLng), self.speed, parent)
self.dist = distance(
self.bot.position[0],
self.bot.position[1],
dest_lat,
dest_lng
)

def step(self):
cLat, cLng = self.api._position_lat, self.api._position_lng
while (cLat, cLng) != self.polyline_walker.get_pos()[0]:
self.polyline_walker.unpause()
sleep(1)
self.polyline_walker.pause()
cLat, cLng = self.polyline_walker.get_pos()[0]
self.api.set_position(round(cLat, 5), round(cLng, 5), 0)
self.bot.heartbeat()
return True

if self.dist < 10: # 10m, add config? set it at constants?
PolylineObjectHandler.delete_cache(self.polyline_walker)
return True

self.polyline_walker.unpause()
sleep(1)
self.polyline_walker.pause()
cLat, cLng = self.polyline_walker.get_pos()[0]
_, _, alt = self.api.get_position()
self.api.set_position(cLat, cLng, alt)
self.bot.heartbeat()
return False

Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from math import sqrt

from random import random
from cell_workers.utils import distance
from human_behaviour import random_lat_long_delta, sleep
from pokemongo_bot.cell_workers.utils import distance
from pokemongo_bot.human_behaviour import random_lat_long_delta, sleep


class StepWalker(object):
Expand Down
15 changes: 15 additions & 0 deletions pokemongo_bot/walkers/walker_factory.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from pokemongo_bot.walkers.polyline_walker import PolylineWalker
from pokemongo_bot.walkers.step_walker import StepWalker

def walker_factory(name, bot, speed, dest_lat, dest_lng, *args, **kwargs):
'''
Charlie and the Walker Factory
'''
if 'StepWalker' == name:
ret = StepWalker(bot, speed, dest_lat, dest_lng)
elif 'PolylineWalker' == name:
try:
ret = PolylineWalker(bot, speed, dest_lat, dest_lng, *args, **kwargs)
except:
ret = StepWalker(bot, speed, dest_lat, dest_lng)
return ret

0 comments on commit b60cefd

Please sign in to comment.