def test_path(): config = create_core_test_config() path_finder = DirectPathFinder(config) path = path_finder.path(51.5043872, -0.0741802, 51.5060435, -0.073983) assert len(path) == 1 lat, lng = path[0] assert lat == 51.5060435 assert lng == -0.073983
def test_path(self): # pylint: disable=no-self-use bot = create_mock_bot(None) stepper = bot.stepper path_finder = DirectPathFinder(stepper) path = path_finder.path(51.5043872, -0.0741802, 51.5060435, -0.073983) assert len(path) == 1 lat, lng = path[0] assert lat == 51.5060435 assert lng == -0.073983
def test_init(): logger = Mock() logger.log = Mock(return_value=None) config_namespace = create_core_test_config() api_wrapper = create_mock_api_wrapper(config_namespace) event_manager = EventManager() player_service = Player(api_wrapper, event_manager, logger) pokemon_service = PokemonService(api_wrapper) mapper = Mapper(config_namespace, api_wrapper, Mock(), logger) path_finder = DirectPathFinder(config_namespace) stepper = Stepper(config_namespace, api_wrapper, path_finder, logger) navigator = FortNavigator(config_namespace, api_wrapper) bot = PokemonGoBot(config_namespace, api_wrapper, player_service, pokemon_service, event_manager, mapper, stepper, navigator, logger) assert len(bot.pokemon_list) == 151 assert len(bot.item_list) == 30 assert bot.position == (0, 0, 0) assert bot.config is config_namespace assert bot.api_wrapper is api_wrapper assert bot.player_service is player_service assert bot.pokemon_service is pokemon_service assert bot.event_manager is event_manager assert bot.mapper is mapper assert bot.stepper is stepper assert bot.navigator is navigator assert bot.logger is logger
def test_start(): config = create_core_test_config({"movement": { "walk_speed": 4.16, }}) api_wrapper = create_mock_api_wrapper(config) path_finder = DirectPathFinder(config) logger = Mock() logger.log = Mock(return_value=None) stepper = Stepper(config, api_wrapper, path_finder, logger) stepper.start(51.5044524, -0.0752479, 10) assert stepper.origin_lat == 51.5044524 assert stepper.origin_lng == -0.0752479 assert stepper.origin_alt == 10 assert stepper.current_lat == 51.5044524 assert stepper.current_lng == -0.0752479 assert stepper.current_alt == 10 pgo = api_wrapper.get_api() lat, lng, alt = pgo.get_position() assert lat == 51.5044524 assert lng == -0.0752479 assert alt == 10
def test_init_path_finder_direct(): config = create_core_test_config({"movement": { "walk_speed": 4.16, }}) api_wrapper = create_mock_api_wrapper(config) path_finder = DirectPathFinder(config) logger = Mock() logger.log = Mock(return_value=None) stepper = Stepper(config, api_wrapper, path_finder, logger) assert isinstance(stepper.path_finder, DirectPathFinder)
def __init__(self, bot): # type: (PokemonGoBot) -> None self.bot = bot self.api_wrapper = bot.api_wrapper self.config = bot.config self.speed = 4.16 if self.config["movement"]["walk_speed"] <= 0 else self.config["movement"]["walk_speed"] self.path_finder = None self.origin_lat = self.bot.position[0] self.origin_lng = self.bot.position[1] self.origin_alt = self.bot.position[2] self.current_lat = self.origin_lat self.current_lng = self.origin_lng self.current_alt = self.origin_alt if self.config["movement"]["path_finder"] == 'google': self.path_finder = GooglePathFinder(self) # pylint: disable=redefined-variable-type elif self.config["movement"]["path_finder"] == 'direct': self.path_finder = DirectPathFinder(self) # pylint: disable=redefined-variable-type
def test_step(): config = create_core_test_config({ "movement": { "walk_speed": 5, "path_finder": "direct", "distance_unit": "m" } }) api_wrapper = create_mock_api_wrapper(config) path_finder = DirectPathFinder(config) logger = Mock() logger.log = Mock(return_value=None) stepper = Stepper(config, api_wrapper, path_finder, logger) stepper.start(51.50451, -0.07607, 10) destination = Destination(51.506000, -0.075049, 11, name="Test Destination", exact_location=False) steps = [(51.504778, -0.075838, 10), (51.505092, -0.075650, 11), (51.505436, -0.075446, 11)] destination.set_steps(steps) pgo = api_wrapper.get_api() # This route is being walked: http://www.darrinward.com/lat-long/?id=2163411 # pre-calculated distance is 17.8 meters pointer = 0 for _ in stepper.step(destination): target_lat, target_lng, target_alt = steps[pointer] assert stepper.current_lat == target_lat assert stepper.current_lng == target_lng assert stepper.current_alt == target_alt bot_lat, bot_lng, bot_alt = pgo.get_position() assert bot_lat == target_lat assert bot_lng == target_lng assert bot_alt == target_alt pointer += 1 assert pointer == 3 bot_lat, bot_lng, bot_alt = pgo.get_position() assert bot_lat == 51.505436 assert bot_lng == -0.075446 assert bot_alt == 11 assert stepper.current_lat == 51.505436 assert stepper.current_lng == -0.075446 assert stepper.current_alt == 11
def __init__(self, bot): # type: (PokemonGoBot) -> None self.bot = bot self.api_wrapper = bot.api_wrapper self.config = bot.config self.speed = self.config.walk if self.config.walk > 0 else 4.16 self.path_finder = None self.pos = 1 self.step_limit = self.config.max_steps self.step_limit_squared = self.step_limit**2 self.origin_lat = self.bot.position[0] self.origin_lng = self.bot.position[1] self.origin_alt = self.bot.position[2] self.current_lat = self.origin_lat self.current_lng = self.origin_lng self.current_alt = self.origin_alt if self.config.path_finder == 'google': self.path_finder = GooglePathFinder(self) # pylint: disable=redefined-variable-type elif self.config.path_finder == 'direct': self.path_finder = DirectPathFinder(self) # pylint: disable=redefined-variable-type
def __init__(self, bot): # type: (PokemonGoBot) -> None self.bot = bot self.api_wrapper = bot.api_wrapper self.config = bot.config self.speed = self.config.walk if self.config.walk > 0 else 4.16 self.path_finder = None self.pos = 1 self.step_limit = self.config.max_steps self.step_limit_squared = self.step_limit ** 2 self.origin_lat = self.bot.position[0] self.origin_lng = self.bot.position[1] self.origin_alt = self.bot.position[2] self.current_lat = self.origin_lat self.current_lng = self.origin_lng self.current_alt = self.origin_alt if self.config.path_finder == 'google': self.path_finder = GooglePathFinder(self) # pylint: disable=redefined-variable-type elif self.config.path_finder == 'direct': self.path_finder = DirectPathFinder(self) # pylint: disable=redefined-variable-type
def _create_generic_bot(config): logger = Mock() logger.log = Mock() config_namespace = create_core_test_config(config) api_wrapper = create_mock_api_wrapper(config_namespace) event_manager = Mock() player_service = Player(api_wrapper, event_manager, logger) pokemon_service = PokemonService(api_wrapper) mapper = Mapper(config_namespace, api_wrapper, Mock(), logger) path_finder = DirectPathFinder(config_namespace) stepper = Stepper(config_namespace, api_wrapper, path_finder, logger) navigator = FortNavigator(config_namespace, api_wrapper) return PokemonGoBot(config_namespace, api_wrapper, player_service, pokemon_service, event_manager, mapper, stepper, navigator, logger)
def create_mock_bot(user_config=None): config_namespace = create_core_test_config(user_config) event_manager = EventManager() logger = Logger(event_manager) api_wrapper = create_mock_api_wrapper(config_namespace) player_service = Player(api_wrapper, event_manager, logger) pokemon_service = Pokemon(api_wrapper) mapper = Mapper(config_namespace, api_wrapper, Mock(), logger) path_finder = DirectPathFinder(config_namespace) stepper = Stepper(config_namespace, api_wrapper, path_finder, logger) navigator = FortNavigator(config_namespace, api_wrapper) bot = PokemonGoBot(config_namespace, api_wrapper, player_service, pokemon_service, event_manager, mapper, stepper, navigator, logger) return bot
def test_step_already_near_fort(): calls = [] config = create_core_test_config({ "movement": { "walk_speed": 5, "path_finder": "direct", "distance_unit": "m" } }) api_wrapper = create_mock_api_wrapper(config) path_finder = DirectPathFinder(config) destination = Destination(51.50436, -0.07616, 11, name="Test Destination", exact_location=False) steps = [(51.50442, -0.07612, 10), (51.50448, -0.07609, 11), (51.50436, -0.07616, 11)] destination.set_steps(steps) logger = Mock() logger.log = Mock(return_value=None) stepper = Stepper(config, api_wrapper, path_finder, logger) stepper.start(51.50451, -0.07607, 10) pgo = api_wrapper.get_api() # This route is being walked: http://www.darrinward.com/lat-long/?id=2163408 calls.append(call("walking_started", coords=(51.50436, -0.07616, 11))) pointer = 0 for _ in stepper.step(destination): pointer += 1 assert pointer == 0 bot_lat, bot_lng, bot_alt = pgo.get_position() assert bot_lat == 51.50451 assert bot_lng == -0.07607 assert bot_alt == 10 assert stepper.current_lat == 51.50451 assert stepper.current_lng == -0.07607 assert stepper.current_alt == 10
def test_get_route_between(): config = create_core_test_config({"movement": { "walk_speed": 5, }}) api_wrapper = create_mock_api_wrapper(config) path_finder = DirectPathFinder(config) logger = Mock() logger.log = Mock(return_value=None) stepper = Stepper(config, api_wrapper, path_finder, logger) stepper.start(51.5044524, -0.0752479, 10) # pre-calculated distance is 205.5 meters # expected steps is 205.5 / (0.6 * 5) = 68.5 (which rounds to 69) steps = stepper.get_route_between(51.5044524, -0.0752479, 51.5062939, -0.0750065, 10) assert len(steps) == 69 for step in steps: assert len(step) == 3
def test_snap_to_over_distance(): config = create_core_test_config({"movement": { "walk_speed": 5, }}) api_wrapper = create_mock_api_wrapper(config) path_finder = DirectPathFinder(config) logger = Mock() logger.log = Mock(return_value=None) stepper = Stepper(config, api_wrapper, path_finder, logger) stepper.start(51.50451, -0.07607, 10) # pre-calculated distance is 17.8 meters stepper.snap_to(51.50436, -0.07616, 11) pgo = api_wrapper.get_api() lat, lng, alt = pgo.get_position() assert stepper.current_lat == 51.50451 assert stepper.current_lng == -0.07607 assert stepper.current_alt == 10 assert lat == 51.50451 assert lng == -0.07607 assert alt == 10
class Stepper(object): AVERAGE_STRIDE_LENGTH_IN_METRES = 0.60 def __init__(self, bot): # type: (PokemonGoBot) -> None self.bot = bot self.api_wrapper = bot.api_wrapper self.config = bot.config self.speed = self.config.walk if self.config.walk > 0 else 4.16 self.path_finder = None self.pos = 1 self.step_limit = self.config.max_steps self.step_limit_squared = self.step_limit ** 2 self.origin_lat = self.bot.position[0] self.origin_lng = self.bot.position[1] self.origin_alt = self.bot.position[2] self.current_lat = self.origin_lat self.current_lng = self.origin_lng self.current_alt = self.origin_alt if self.config.path_finder == 'google': self.path_finder = GooglePathFinder(self) # pylint: disable=redefined-variable-type elif self.config.path_finder == 'direct': self.path_finder = DirectPathFinder(self) # pylint: disable=redefined-variable-type def start(self): # type: () -> None position = (self.origin_lat, self.origin_lng, self.origin_alt) self.api_wrapper.set_position(*position) def step(self, destination): # type: (Destination) -> None self.bot.fire("walking_started", coords=(destination.target_lat, destination.target_lng, destination.target_alt)) dist = distance(self.current_lat, self.current_lng, destination.target_lat, destination.target_lng) if destination.name: logger.log("Walking towards {} ({} away, eta {})".format(destination.name, format_dist(dist, self.config.distance_unit), format_time(len(destination.steps))), prefix="Navigation") for step in destination.steps: self._step_to(*step) yield step if destination.name: logger.log("Arrived at {} ({} away)".format(destination.name, format_dist(dist, self.config.distance_unit)), prefix="Navigation") self.bot.fire("walking_finished", coords=(destination.target_lat, destination.target_lng, destination.target_alt)) def get_route_between(self, from_lat, from_lng, to_lat, to_lng, alt): # type: (float, float, float) -> List[(float, float, float)] route_steps = list() # ask the path finder how to get there path_points = self.path_finder.path(from_lat, from_lng, to_lat, to_lng) for path_point in path_points: path_to_lat, path_to_lng = path_point path_steps = self._get_steps_between(from_lat, from_lng, path_to_lat, path_to_lng, alt) route_steps += path_steps # shift the path along from_lat = path_to_lat from_lng = path_to_lng return route_steps def _get_steps_between(self, from_lat, from_lng, to_lat, to_lng, alt): # type: (float, float, float) -> List[(float,float,float)] dist = distance(from_lat, from_lng, to_lat, to_lng) steps = (dist / (self.AVERAGE_STRIDE_LENGTH_IN_METRES * self.speed)) step_locations = list() if steps != 0: d_lat = (to_lat - from_lat) / steps d_long = (to_lng - from_lng) / steps total_steps = int(ceil(steps)) for _ in range(total_steps): from_lat += d_lat from_lng += d_long c_lat = from_lat + random_lat_long_delta(10) c_long = from_lng + random_lat_long_delta(10) step_locations.append((c_lat, c_long, alt)) return step_locations def snap_to(self, to_lat, to_lng, to_alt): # type: (float, float, float) -> None """ This method is to correct a position you are near to. If you try and snap a distance over 10 meters, it will fail. """ # type: (float, float, float) -> None dist = distance(self.current_lat, self.current_lng, to_lat, to_lng) # Never snap big distances if dist > 15: return self._step_to(to_lat, to_lng, to_alt) def _step_to(self, lat, lng, alt): # type: (float, float, float) -> None self.api_wrapper.set_position(lat, lng, alt) new_lat, new_lng, new_alt = self.api_wrapper.get_position() self.current_lat = new_lat self.current_lng = new_lng self.current_alt = new_alt self.bot.fire("position_updated", coordinates=(new_lat, new_lng, new_alt)) self.bot.heartbeat() sleep(1) # sleep one second plus a random delta
class Stepper(object): AVERAGE_STRIDE_LENGTH_IN_METRES = 0.60 def __init__(self, bot): # type: (PokemonGoBot) -> None self.bot = bot self.api_wrapper = bot.api_wrapper self.config = bot.config self.speed = self.config.walk if self.config.walk > 0 else 4.16 self.path_finder = None self.pos = 1 self.step_limit = self.config.max_steps self.step_limit_squared = self.step_limit**2 self.origin_lat = self.bot.position[0] self.origin_lng = self.bot.position[1] self.origin_alt = self.bot.position[2] self.current_lat = self.origin_lat self.current_lng = self.origin_lng self.current_alt = self.origin_alt if self.config.path_finder == 'google': self.path_finder = GooglePathFinder(self) # pylint: disable=redefined-variable-type elif self.config.path_finder == 'direct': self.path_finder = DirectPathFinder(self) # pylint: disable=redefined-variable-type def start(self): # type: () -> None position = (self.origin_lat, self.origin_lng, self.origin_alt) self.api_wrapper.set_position(*position) def step(self, destination): # type: (Destination) -> None self.bot.fire("walking_started", coords=(destination.target_lat, destination.target_lng, destination.target_alt)) dist = distance(self.current_lat, self.current_lng, destination.target_lat, destination.target_lng) if destination.name: logger.log("Walking towards {} ({} away, eta {})".format( destination.name, format_dist(dist, self.config.distance_unit), format_time(len(destination.steps))), prefix="Navigation") for step in destination.steps: self._step_to(*step) yield step if destination.name: logger.log("Arrived at {} ({} away)".format( destination.name, format_dist(dist, self.config.distance_unit)), prefix="Navigation") self.bot.fire("walking_finished", coords=(destination.target_lat, destination.target_lng, destination.target_alt)) def get_route_between(self, from_lat, from_lng, to_lat, to_lng, alt): # type: (float, float, float) -> List[(float, float, float)] route_steps = list() # ask the path finder how to get there path_points = self.path_finder.path(from_lat, from_lng, to_lat, to_lng) for path_point in path_points: path_to_lat, path_to_lng = path_point path_steps = self._get_steps_between(from_lat, from_lng, path_to_lat, path_to_lng, alt) route_steps += path_steps # shift the path along from_lat = path_to_lat from_lng = path_to_lng return route_steps def _get_steps_between(self, from_lat, from_lng, to_lat, to_lng, alt): # type: (float, float, float) -> List[(float,float,float)] dist = distance(from_lat, from_lng, to_lat, to_lng) steps = (dist / (self.AVERAGE_STRIDE_LENGTH_IN_METRES * self.speed)) step_locations = list() if steps != 0: d_lat = (to_lat - from_lat) / steps d_long = (to_lng - from_lng) / steps total_steps = int(ceil(steps)) for _ in range(total_steps): from_lat += d_lat from_lng += d_long c_lat = from_lat + random_lat_long_delta(10) c_long = from_lng + random_lat_long_delta(10) step_locations.append((c_lat, c_long, alt)) return step_locations def snap_to(self, to_lat, to_lng, to_alt): # type: (float, float, float) -> None """ This method is to correct a position you are near to. If you try and snap a distance over 10 meters, it will fail. """ # type: (float, float, float) -> None dist = distance(self.current_lat, self.current_lng, to_lat, to_lng) # Never snap big distances if dist > 15: return self._step_to(to_lat, to_lng, to_alt) def _step_to(self, lat, lng, alt): # type: (float, float, float) -> None self.api_wrapper.set_position(lat, lng, alt) new_lat, new_lng, new_alt = self.api_wrapper.get_position() self.current_lat = new_lat self.current_lng = new_lng self.current_alt = new_alt self.bot.fire("position_updated", coords=(new_lat, new_lng, new_alt)) self.bot.heartbeat() sleep(1) # sleep one second plus a random delta
class Stepper(object): AVERAGE_STRIDE_LENGTH_IN_METRES = 0.60 def __init__(self, bot): # type: (PokemonGoBot) -> None self.bot = bot self.api_wrapper = bot.api_wrapper self.config = bot.config self.speed = self.config.walk if self.config.walk > 0 else 4.16 self.path_finder = None self.pos = 1 self.step_limit = self.config.max_steps self.step_limit_squared = self.step_limit ** 2 self.origin_lat = self.bot.position[0] self.origin_lng = self.bot.position[1] self.origin_alt = self.bot.position[2] self.current_lat = self.origin_lat self.current_lng = self.origin_lng self.current_alt = self.origin_alt if self.config.path_finder == 'google': self.path_finder = GooglePathFinder(self) # pylint: disable=redefined-variable-type elif self.config.path_finder == 'direct': self.path_finder = DirectPathFinder(self) # pylint: disable=redefined-variable-type def start(self): # type: () -> None position = (self.origin_lat, self.origin_lng, self.origin_alt) self.api_wrapper.set_position(*position) def walk_to(self, lat, lng, alt): # type: (float, float, float) -> None position_lat, position_lng, position_alt = self.api_wrapper.get_position() self.current_lat = position_lat self.current_lng = position_lng self.current_alt = position_alt self.bot.fire("walking_started", coords=(lat, lng, alt)) # ask the path finder how to get there steps = self.path_finder.path(position_lat, position_lng, lat, lng) for step in steps: to_lat, to_lng = step self._walk_to(to_lat, to_lng, alt) self.bot.fire("walking_finished", coords=(lat, lng, alt)) logger.log("[#] Walking Finished") def _walk_to(self, to_lat, to_lng, to_alt): # type: (float, float, float) -> None dist = distance(self.current_lat, self.current_lng, to_lat, to_lng) steps = (dist / (self.AVERAGE_STRIDE_LENGTH_IN_METRES * self.speed)) if self.config.debug: logger.log("[#] Walking from " + str((self.current_lat, self.current_lng)) + " to " + str( str((to_lat, to_lng))) + " for approx. " + str(format_time(ceil(steps)))) if steps != 0: d_lat = (to_lat - self.current_lat) / steps d_long = (to_lng - self.current_lng) / steps for _ in range(int(ceil(steps))): c_lat = self.current_lat + d_lat + random_lat_long_delta(10) c_long = self.current_lng + d_long + random_lat_long_delta(10) self._jump_to(c_lat, c_long, to_alt) self.bot.heartbeat() def snap_to(self, to_lat, to_lng, to_alt): # type: (float, float, float) -> None """ This method is to correct a position you are near to. If you try and snap a distance over 10 meters, it will fail. """ # type: (float, float, float) -> None dist = distance(self.current_lat, self.current_lng, to_lat, to_lng) # Never snap big distances if dist > 10: return self._jump_to(to_lat, to_lng, to_alt) def _jump_to(self, lat, lng, alt): # type: (float, float, float) -> None self.api_wrapper.set_position(lat, lng, alt) new_lat, new_lng, new_alt = self.api_wrapper.get_position() self.current_lat = new_lat self.current_lng = new_lng self.current_alt = new_alt self.bot.fire("position_updated", coords=(new_lat, new_lng, new_alt)) self.bot.heartbeat() sleep(1) # sleep one second plus a random delta map_cells = self.bot.mapper.get_cells(self.current_lat, self.current_lng) self.bot.work_on_cells(map_cells)