PokemonGoF / PokemonGo-Bot

The Pokemon Go Bot, baking with community.
MIT License
3.86k stars 1.54k forks source link

Polyline should handle one point Postal address precision API returns (was: Bot not closely following path from GPX file) #5391

Open cantelope opened 7 years ago

cantelope commented 7 years ago

Expected Behavior

I physically walked along a short 1.2km path consisting of two loops and recorded my path as a .gpx file using the GPSies app. Then I reviewed this path using www.maplorer.com, which confirmed that my path was smooth and matched the two loops that I had walked. So when I feed this gpx file to my bot, I expect it to follow the path I'd reviewed at www.maplorer.com

The path is supposed to look like this image

Actual Behavior

Bot is not walking that smooth path at all. Instead, it seems to be walking around semi-randomly. image

Your FULL config.json (remove your username, password, gmapkey and any other private info)

I've added my config.json below. Note that there is no movement task in there apart from FollowPath. MoveToMapPokemon was moved into "skipped_tasks", FollowSpiral was deleted and MoveToFort is disabled. In addition, I've turned GPS xy noise and z noise to false.

{ "websocket_server": true, "heartbeat_threshold": 10, "enable_social": true, "live_config_update": { "enabled": true, "tasks_only": true }, "skipped_tasks": [ { "type": "HandleSoftBan" }, { "type": "MoveToMapPokemon", "config": { "enabled": true, "address": "http://my.ip.address:8000", "max_distance": 890, "min_time": 60, "min_ball": 50, "prioritize_vips": true, "snipe": false, "snipe_high_prio_only": true, "snipe_high_prio_threshold": 400, "update_map": true, "mode": "priority", "map_path": "raw_data", "walker": "StepWalker", "catch": { "==========Legendaries==========": 0, "Aerodactyl": 1000, "Snorlax": 1000, "Articuno": 1000, "Zapdos": 1000, "Moltres": 1000, "Dratini": 1000, "Dragonair": 1000, "Dragonite": 1000, "Mewtwo": 1000, "Mew": 1000,

        "==========Region Locked==========": 0,
        "Farfetch'd": 1000,
        "Kangaskhan": 1000,
        "Mr. Mime": 1000,
        "Tauros": 1000,

        "==========Very Rare==========": 0,
        "Lapras": 900,
        "Electabuzz": 900,
        "Magmar": 900,
        "Ditto": 900,

        "==========Starters==========": 0,
        "__Bulbasaur": 400,
        "Ivysaur": 600,
        "Venusaur": 1000,
        "Charmander": 400,
        "Charmeleon": 600,
        "Charizard": 1000,

        "__Squirtle": 400,
        "Wartortle": 600,
        "Blastoise": 1000,

        "__Pikachu": 600,
        "Raichu": 1000,

        "==========Semi Rare==========": 0,
        "__Porygon": 200,
        "__Scyther": 200,
        "__Jynx": 200,

        "==========Uncommon==========": 0,

        "__Omanyte": 150,
        "__Omastar": 500,

        "__Seel": 300,
        "__Dewgong": 500,

        "__Grimer": 200,
        "__Muk": 500,

        "__Shellder": 200,
        "__Cloyster": 500,

        "__Gastly": 200,
        "__Haunter": 500,
        "__Gengar": 1000,

        "__Onix": 600,

        "__Drowzee": 600,

        "__Hypno": 600,

        "__Vulpix": 200,
        "__Ninetales": 600,

        "__Paras": 100,
        "__Parasect": 500,

        "__Growlithe": 200,
        "__Arcanine": 700,

        "__Tentacool": 200,
        "__Tentacruel": 500,

        "__Mankey": 150,
        "__Primeape": 500,

        "__Clefairy": 150,
        "__Clefable": 500,

        "__Jigglypuff": 150,
        "__Wigglytuff": 500,

        "__Venonat": 100,
        "__Venomoth": 500,

        "__Diglett": 200,
        "__Dugtrio": 500,

        "__Meowth": 250,
        "__Persian": 500,

        "__Psyduck": 150,
        "__Golduck": 500,

        "__Geodude": 100,
        "__Graveler": 500,
        "__Golem": 800,

        "Eevee": 200,
        "Vaporeon": 800,
        "Jolteon": 800,
        "Flareon": 800,

        "__Kabuto": 150,
        "__Kabutops": 500,

        "Magikarp": 150,
        "Gyarados": 800,

        "__Pinsir": 150,

        "__Ponyta": 200,
        "__Rapidash": 500,

        "__Slowpoke": 200,
        "__Slowbro": 500,

        "__Magnemite": 250,
        "__Magneton": 500,

        "__Krabby": 100,
        "__Kingler": 500,

        "__Voltorb": 200,
        "__Electrode": 500,

        "Exeggcute": 250,
        "Exeggcutor": 500,

        "__Cubone": 300,
        "__Marowak": 800,

        "__Hitmonlee": 400,

        "__Hitmonchan": 400,

        "__Lickitung": 500,

        "__Koffing": 200,
        "__Weezing": 500,

        "__Rhyhorn": 200,
        "__Rhydon": 500,

        "__Chansey": 800,

        "__Tangela": 300,

        "__Horsea": 200,
        "__Seadra": 600,

        "__Goldeen": 150,
        "__Seaking": 500,

        "__Staryu": 200,
        "__Starmie": 800,

        "==========T1 Evolvers==========": 0,
        "__Caterpie": 10,
        "__Metapod": 10,
        "__Butterfree": 500,

        "__Weedle": 10,
        "__Kakuna": 10,
        "__Beedrill": 500,

        "__Pidgey": 10,
        "__Pidgeotto": 10,
        "__Pidgeot": 300,

        "==========T2 Evolvers==========": 0,
        "__Nidoran F": 10,
        "__Nidorina": 10,
        "__Nidoqueen": 10,

        "__Nidoran M": 10,
        "__Nidorino": 10,
        "__Nidoking": 10,

        "__Oddish": 100,
        "__Gloom": 200,
        "__Vileplume": 600,

        "__Poliwag": 200,
        "__Poliwhirl": 400,
        "__Poliwrath": 800,

        "__Abra": 300,
        "__Kadabra": 600,
        "__Alakazam": 800,

        "__Machop": 150,
        "__Machoke": 400,
        "__Machamp": 800,

        "__Bellsprout": 100,
        "__Weepinbell": 400,
        "__Victreebel": 800,

        "==========Trash==========": 0,

        "__Rattata": 10,
        "__Raticate": 10,

        "__Spearow": 10,
        "__Fearow": 10,

        "__Ekans": 10,
        "__Arbok": 10,

        "__Sandshrew": 10,
        "__Sandslash": 10,

        "__Zubat": 10,
        "__Golbat": 10,

        "__Doduo": 10,
        "__Dodrio": 10
      }
    }
 }
],
"tasks": [
   {
    "type": "TelegramTask",
    "config": {
      "enabled": false,
      "master": null,
      "// old syntax, still supported: alert_catch": ["all"],
      "// new syntax:": {},
      "alert_catch": {
        "all": {"operator": "and", "cp": 1300, "iv": 0.95},
        "Snorlax": {"operator": "or", "cp": 900, "iv": 0.9}
      }
    }
  },
  {
    "type": "DiscordTask",
    "config": {
      "enabled": false,
      "master": null,
      "// old syntax, still supported: alert_catch": ["all"],
      "// new syntax:": {},
      "alert_catch": {
        "all": {"operator": "and", "cp": 1300, "iv": 0.95},
        "Snorlax": {"operator": "or", "cp": 900, "iv": 0.9}
      }
    }
  },
  {
    "//NOTE: This task MUST be placed on the top of task list": {},
    "type": "RandomAlivePause",
    "config": {
      "enabled": true,
      "min_duration": "00:00:10",
      "max_duration": "00:10:00",
      "min_interval": "00:05:00",
      "max_interval": "01:30:00"
    }
  },
  {
        "type": "RandomPause",
        "config": {
          "enabled": true,
          "min_duration": "00:00:10",
          "max_duration": "01:15:00",
          "min_interval": "00:02:00",
          "max_interval": "08:00:00"
        }
  },
  {
    "type": "CompleteTutorial",
    "config": {
      "enabled": false,
      "// set a name": "",
      "nickname": "",
      "// 0 = No Team, 1 = Blue, 2 = Red, 3 = Yellow": "",
      "team": 0
    }
  },
  {
    "type": "CollectLevelUpReward",
    "config": {
      "collect_reward": true,
      "level_limit": 19
    }
  },
  {
    "type": "IncubateEggs",
    "config": {
      "enabled": true,
      "infinite_longer_eggs_first": false,
      "breakable_longer_eggs_first": true,
      "min_interval": 120,
      "infinite": [2,5,10],
      "breakable": [20]
    }
  },
  {
    "type": "UpdateLiveStats",
    "config": {
      "enabled": false,
      "min_interval": 10,
      "stats": ["username", "uptime", "stardust_earned", "xp_earned", "xp_per_hour", "stops_visited"],
      "terminal_log": true,
      "terminal_title": true
    }
  },
  {
    "type": "UpdateLiveInventory",
    "config": {
      "enabled": true,
      "min_interval": 626,
      "show_all_multiple_lines": false,
      "items": ["space_info", "pokeballs", "greatballs", "ultraballs", "razzberries", "luckyegg"]
    }
  },
   {
    "type": "ShowBestPokemon",
    "config": {
      "enabled": true,
      "min_interval": 60,
      "amount": 5,
      "order_by": "cp",
      "info_to_show": ["cp", "ivcp", "dps", "hp"]
    }
  },
  {
    "type": "TransferPokemon",
    "config": {
      "enabled": true,
      "min_free_slot": 50,
      "transfer_wait_min": 3,
      "transfer_wait_max": 5

    }
  },
  {
    "type": "NicknamePokemon",
    "config": {
      "enabled": false,
      "nickname_above_iv": 0.9,
      "nickname_template": "{iv_pct}_{iv_ads}",
      "nickname_wait_min": 3,
      "nickname_wait_max": 5
    }
  },
  {
    "type": "EvolvePokemon",
    "config": {
        "enabled": false,

        "// evolve only pidgey and drowzee": "",
        "// evolve_list": "pidgey, drowzee",
        "// donot_evolve_list": "none",

        "// evolve all but pidgey and drowzee": "",
        "// evolve_list": "all",
        "// donot_evolve_list": "pidgey, drowzee",

        "evolve_list": "all",
        "donot_evolve_list": "none",

        "first_evolve_by": "cp",
        "evolve_above_cp": 500,
        "evolve_above_iv": 0.8,
        "logic": "or",
        "min_evolve_speed": 26,
        "max_evolve_speed": 30,
        "use_lucky_egg": false
   }
  },
  {
    "type": "UseIncense",
    "config": {
      "use_incense": false,
      "use_order": [
        "ordinary",
        "spicy",
        "cool",
        "floral"
      ]
    }
  },
  {
    "type": "RecycleItems",
    "config": {
      "enabled": true,
      "min_empty_space": 30,
      "max_balls_keep": 150,
      "max_potions_keep": 50,
      "max_berries_keep": 70,
      "max_revives_keep": 10,
      "item_filter": {
        "Pokeball":       { "keep" : 150 },
        "Potion":         { "keep" : 10 },
        "Super Potion":   { "keep" : 20 },
        "Hyper Potion":   { "keep" : 30 },
        "Revive":         { "keep" : 10 },
        "Razz Berry":     { "keep" : 70 }
      },
      "recycle_wait_min": 2,
      "recycle_wait_max": 5,
      "recycle_force": true,
      "recycle_force_min": "00:01:00",
      "recycle_force_max": "00:05:00"
    }
  },
  {
    "type": "CatchPokemon",
    "config": {
      "enabled": true,
      "catch_visible_pokemon": true,
      "catch_lured_pokemon": true,
      "min_ultraball_to_keep": 3,
      "berry_threshold": 0.35,
      "vip_berry_threshold": 0.9,
      "treat_unseen_as_vip": true,
      "daily_catch_limit": 573,
      "vanish_settings": {
        "consecutive_vanish_limit": 5,
        "rest_duration_min": "02:00:00",
        "rest_duration_max": "04:00:00"
      },
      "catch_throw_parameters": {
        "excellent_rate": 0.05,
        "great_rate": 0.2,
        "nice_rate": 0.35,
        "normal_rate": 0.4,
        "spin_success_rate" : 0.4,
        "hit_rate": 0.66
      },
      "catch_simulation": {
        "flee_count": 3,
        "flee_duration": 2,
        "catch_wait_min": 4,
        "catch_wait_max": 9,
        "berry_wait_min": 3,
        "berry_wait_max": 5,
        "changeball_wait_min": 3,
        "changeball_wait_max": 5,
        "newtodex_wait_min": 20,
        "newtodex_wait_max": 30
      }
    }
  },
  {
    "type": "SpinFort",
    "config": {
      "enabled": true,
      "spin_wait_min": 3,
      "spin_wait_max": 5,
      "daily_spin_limit": 1900
    }
  },
  { "type": "UpdateWebInventory",
    "config": {
      "enabled": true
    }
  },
  {
    "type": "FollowPath",
    "config": {
      "enabled": true,
      "walker": "PolylineWalker",
      "path_mode": "loop",
      "path_start_mode": "closest",
      "path_file": "../VivocityCircleX2.gpx",
      "number_lap": 10,
      "timer_restart_min": "00:10:00",
      "timer_restart_max": "00:20:00"
    }
  },
  {
    "type": "MoveToFort",
    "config": {
      "enabled": false,
      "lure_attraction": true,
      "lure_max_distance": 1000,
      "walker": "PolylineWalker",
      "log_interval": 5
    }
  }
],
"map_object_cache_time": 10,
"forts": {
  "avoid_circles": true,
  "max_circle_size": 50,
  "cache_recent_forts": true
},
"pokemon_bag": {
  "// if 'show_at_start' is true, it will log all the pokemons in the bag (not eggs) at bot start": {},
  "show_at_start": true,
  "// if 'show_count' is true, it will show the amount of each pokemon (minimum 1)": {},
  "show_count": false,
  "// 'pokemon_info' parameter define which info to show for each pokemon": {},
  "// the available options are": {},
  "// ['cp', 'iv_ads', 'iv_pct', 'ivcp', 'ncp', 'level', 'hp', 'moveset', 'dps']": {},
  "pokemon_info": ["cp", "iv_pct"]
},
"save_pokemon_spawn": true,
"walk_max": 4.71,
"walk_min": 1.36,
"alt_min": 3,
"alt_max": 30,
"sleep_schedule": {
  "enabled": true,
  "enable_reminder": false,
  "reminder_interval": 600,
  "entries": [
    {
      "enabled": true,
      "time": "12:00",
      "duration": "5:30",
      "time_random_offset": "00:30",
      "duration_random_offset": "00:30",
      "wake_up_at_location": ""
    },
    {
      "enabled": true,
      "time": "17:45",
      "duration": "3:00",
      "time_random_offset": "01:00",
      "duration_random_offset": "00:30",
      "wake_up_at_location": ""
    }
  ]
},
"gps_default_altitude": 6.3,
"replicate_gps_xy_noise": false,
"replicate_gps_z_noise": false,
"gps_xy_noise_range": 0.000025,
"gps_z_noise_range": 2.0,
"debug": false,
"test": false,
"walker_limit_output": false,
"health_record": false,
"location_cache": true,
"distance_unit": "km",
"reconnecting_timeout": 15,
"logging": {
  "color": true,
  "show_datetime": true,
  "show_process_name": true,
  "show_log_level": true,
  "show_thread_name": false
},
"catch": {
  "any": {"candy_threshold" : 400 ,"catch_above_cp": 0, "catch_above_iv": 0, "logic": "or"},
  "// Example of always catching Rattata:": {},
  "// Rattata": { "always_catch" : true }
},
"release": {
  "any": {"keep_best_cp": 2, "keep_best_iv": 2},
  "Pidgey": {"release_below_cp": 220, "release_below_iv": 0.35, "logic": "and"},
  "Rattata": {"release_below_cp": 320, "release_below_iv": 0.65, "logic": "and"},
  "Caterpie": {"release_below_cp": 320, "release_below_iv": 0.65, "logic": "and"},
  "Weedle": {"release_below_cp": 320, "release_below_iv": 0.65, "logic": "or"},
  "// any": {"release_below_cp": 0, "release_below_iv": 0, "logic": "or"},
  "// Example of always releasing Rattata:": {},
  "// Rattata": {"always_release": true},
  "// Example of keeping 3 stronger (based on CP) Pidgey:": {},
  "// Pidgey": {"keep_best_cp": 3},
  "// Example of keeping 2 stronger (based on IV) Zubat:": {},
  "// Zubat": {"keep_best_iv": 2},
  "// Also, it is working with any": {},
  "// any": {"keep_best_iv": 3},
  "// Example of keeping the 2 strongest (based on CP) and 3 best (based on IV) Zubat:": {},
  "// Zubat": {"keep_best_cp": 2, "keep_best_iv": 3}
},
"vips" : {
     "Any pokemon put here directly force to use Berry & Best Ball to capture, to secure the capture rate": {},
    "any": {"catch_above_cp": 1200, "catch_above_iv": 0.9, "logic": "or" },
    "Lapras": {},
    "Moltres": {},
    "Zapdos": {},
    "Articuno": {},

    "// S-Tier pokemons (if pokemon can be evolved into tier, list the representative)": {},
    "Mewtwo": {},
    "Dragonite": {},
    "Snorlax": {},
    "// Mew evolves to Mewtwo": {},
    "Mew": {},
    "Arcanine": {},
    "Vaporeon": {},
    "Gyarados": {},
    "Exeggutor": {},
    "Muk": {},
    "Weezing": {},
    "Flareon": {}

},
"websocket": {
        "start_embedded_server": true,
        "server_url": "127.0.0.1:8001"
}

}

Steps to Reproduce

I've asked on slack channel, and one idea was that PolylineWalker might be attempting to use Google Navigation to walk between each of the GPX points. That might be a good idea with json paths, but with my GPX file where each point is only 10-50m apart, I think that it should attempt to walk directly between points.

Other Information

OS: Linux Branch: dev Git Commit: cb9ebb392eeb711999b0f38c7094ab9a1eb4900c Python Version: 2.7.6

ghost commented 7 years ago

Try to change PolylineWalker to StepWalker. PolylineWalker is trying to get directions using the Google Maps API, which doesn't work very well for detailed paths with lots of stops.

cantelope commented 7 years ago

Does StepWalker report altitude properly?

jmarenas commented 7 years ago

Apparently the task "MoveToMapPokemon" is causing your problem. This task is enable and before that the task "FollowPath", if it is before, the bot will priorize that task. If you set "enabled" to false in the "MoveToMapPokemon" task, should fix your problem.

ghost commented 7 years ago

Does StepWalker report altitude properly?

If your path includes altitude data, it sure does.

th3w4y commented 7 years ago

PolylineWlaker fetches Google Directions and Elevation Informations.

If your point are close in between themselves and you also have elevations then you also have no particular reason to use PolylineWalker!

But if you do it would still work (you should not get the walking you described) and would give you correct elevations for free.. when you don't have them

StepWalker only gives you a smooth transition from the last altitude you last had towards the altitude you provide...

th3w4y commented 7 years ago

@acurioustale I believe it should work... what issues do you have with the PolylineWalker in those cases? (Beside the fact that actually you are waisting your Google API calls for nothing... when the distance between the points in the paths is small, and the fact that you don't get much of an advantage by using it with a gpx file... Please describe the behaviour you get.. I want to identify if there are any bugs in the code...)

acurioustale commented 9 hours ago Try to change PolylineWalker to StepWalker. PolylineWalker is trying to get directions using the Google Maps API, which doesn't work very well for detailed paths with lots of stops.

th3w4y commented 7 years ago

@cantelope I am very interested in your case... could i get more details about the location geography?

Your walk was it on grass... pavements... how known is the location for Google? Can you overlay your gpx file over a map?

(@jmarenas in the config he attached the MoveToMapPokemon task is in the skipped tasks)

jmarenas commented 7 years ago

@th3w4y You are right, my bad. FYI this is my configuration that work for me: SO: Ubuntu Linux 16.04 Python 2.7.12 Git commit: 11123a82cb18c172a262dc9e46e7b2c175666828 { "type": "FollowPath", "config": { "enabled": true, "walker": "StepWalker", "path_mode": "loop", "path_start_mode": "first", "path_file": "configs/points.gpx", "number_lap": -1, "timer_restart_min": "00:5:00", "timer_restart_max": "00:10:00" } } The .gpx file that I have, I made it in gpsies.com, the file is without modification.

th3w4y commented 7 years ago

I identified the issue... It has to do with Google Directions not recognising the area....

When coding the Polyline I made an assumption that to go from O to D (origin destination..) i would have to insert the GooglePoints in between O..D and create a line:

O + (points returned by Google API) + D.

For unknown areas Google has only one point closest known "Postal Adress" precision thus returning only one point...

The resulting walk would be O...GooglePoint(closest_known_postal_address)...D

I will handle this in the code... if the API does not return us minim 2 points between O...D then the resulting line should be only O...D (without adding the skewed GooglePoint)

cantelope commented 7 years ago

Thanks all for your assistance - did not respond as it was nighttime for me.

@acurioustale, I'd previously switched to PolylineWalker as I'd read somewhere that PolylineWalker submitted elevations to the underlying api correctly and it wasn't clear if StepWalker did so too. I guess that as long as StepWalker does elevations, I should use it for gpx paths.

I wonder, should the config.json.path.example perhaps include a comment that StepWalker is preferred for gpx files with many points and with altitude already present, whereas PolylineWalker is preferred otherwise (probably in most cases, actually).

@jmarenas, yup as th3w4y said, the MoveToMapPokemon was put into a skipped_tasks section... a throwback from a time when there was no enabled flag. Thanks for the hint on your working FollowPath config!

@th3w4y, thanks! the terrain is in a mall. Google Maps knows about it (you can zoom into it and see individual outlets), but I suspect that Google Navigation isn't able to give directions from one point to another within the mall. So it looks like your solution is the correct technical one, while the others told me how to solve my problem.

th3w4y commented 7 years ago

@cantelope yes i identified the issue and they provided you with the workaround...

... which you should use for now since i have no time to fix the code ATM