Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Step 1: Implement A "Save State" Mechanism #2

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open

Conversation

mfekadu
Copy link
Owner

@mfekadu mfekadu commented Sep 8, 2019

Resolves Step 1 of Issue #1

CHANGES

  • The state of the simulation gets saved into a pickle file at each frame of the game
    • yes, this would generate a lot of data if ran for hours/days/etc ¯\_(ツ)_/¯
  • Added a new file called replay.py allows the user to replay any folder of space_dump_..._.pickle files
    • user can scrub forward +1 in time with RIGHT-ARROW key
    • user can scrub backward +1 in time with RIGHT-ARROW key
    • user can scrub forward +10 in time with UP-ARROW key
    • user can scrub backward +10 in time with DOWN-ARROW key
    • scrubbing to the last frame quits the replay

Here is a GIF showing the replay feature:

Sep-08-2019 11-57-36

this commit was an attempt to "just make it work" so the code is not elegant

dumping the space is as simple as `pickle.dump(space)`
but I cannot dump `pickle.dump([space, window, options])`
TODO: explore dumping window
TODO: explore dumping options

The zip files are folders that contain the dumps
You need to unzip the folders in order to run `./replay`

replay.py is the script to do "replay"
It will search for the first folder it finds in "space_dumps" directory
Then it will `pickle.load` each file in that folder it found
Then we need to `space.step()` to actually have each space displayed on the screen in sequential order
OH BTW... sorting the files is important.... otherwise it looks weird and jumpy

DUMPS_DIR added to cfg.py
TODO: figure out how to also dump the cfg.py data

TODO: figure out how to minimize `replay.py` because ideally replay.py can just do everything given the file & not need to perform any sort of setup
* for example replay.py needs to have the collision handler functions inside otherwise an error about "missing begin_collision in __main__" will occur
minimizing replay.py code to just the essentials
also include scrubbing via arrow keys
* holding right scrubs forward
* holding left scrubs in reverse
* UP/DOWN scrub faster

still TODO:
* import gzip into replay.py and sim.py
   * sim.py should batch pickle.dump and gzip at the end
   * replay.py should ungzip a given dump_file and also load it up for replay
* AVOID doing `import cfg` into replay.py
   * because cfg.py could change in the future
   * rather sim.py should save all of the replay values into the dump_file (save just once.... not into each dump_file... save into its own file)

* Here's an IDEA:
   * save replay.py with each batch of dump_files.zip.... that way every dump_files.zip will have a functional replay.... and replay can just be a script that works specifically for each batch of files. Self-contained. Would be nice. Could be annoying to have to recreate the replay.py script each time... but assuming sim.py will continue to change then replay.py will likely change along with it... so maybe that's the optimal solution? hmmm...
@mfekadu mfekadu mentioned this pull request Sep 8, 2019
26 tasks
because removing an element from a list that you are iterating over can be weird
@mfekadu
Copy link
Owner Author

mfekadu commented Sep 8, 2019

TODO

  • include data from cfg.py in the pickle.dump() to avoid having to import cfg into replay.py in case the contents of cfg change in the future
  • add version number 1 to each pickle.dump and remember to increment that number if any non-backwards-comparable changes to the file structure occur in the future

* replay.py now is a command-line utility
  * it does argparse of the dumps_dir
* replay.py is much more minimal and cool and not hard coded
* replay.py now includes a “version number” `v1.0` in the filename
    * Also the name says ’space_and_cfg_ to let you know what to expect out of the pickle.load

deleted the old incompatable pickle.dumps

include just 1 zip file containing space_and_cfg pickles

TODO: optimize the pickle.dump of cfg because it only needs to be done once. But for now the redundancy is fine because cfg only takes about 1KB... but 1KB * 1000 files would be 1MB... etc ...
before we had concrete position details of the yellow circle... but now we can wait helllllla long (like 30 seconds for 2000+ frames) to load and display each position of the bot over all time frames. Looks cool but it takes too long and needs too much data

TODO: compress the pickle files somehow
or dont save the entire space... maybe save useful statistics like "position over time" or "velocity" or "other stuff liike that" and save the functions to recreate the shapes but not the shapes themselves. And maybe dont use pymunk to replay. Maybe just plot the positions using matplotlib. ...
@mfekadu
Copy link
Owner Author

mfekadu commented Sep 13, 2019

New Problems:

  • The pickle files are massive (e.g., 24 MB for a 30-second simulation). (see b7889fe)
  • Ben Frederickson says "Don't Pickle Your Data" because Pickle is slow and insecure
  • I don't want to have to keep re-implementing this feature

New Solutions

  • Store the following data for sure
    • The position of the bot at each timeframe
    • The position of food at each timeframe
    • The cfg.py details
    • The rng.py because that’s where randomness goes, and it may be helpful to have that documented.
  • When storing
    • Compress the folder of various files into a gzip? if needed
  • Store the following data if reasonable (but keep these in mind for future updates)
    • the velocity of each object per frame
    • the functions to recreate the body and shape in Pymunk?
    • a boolean value per action per frame
      • E.g. Action=eat or action=grab
      • Activation of neurons per bot per frame??
      • Sensor values per bot or frame??
  • Replay the saved data with (pick a tool)
  • Make cool visualizations like
    • heat maps overlayed on the game window to show where the bot traveled
    • a simple path drawing that the bot traveled
  • Follow the dependency inversion principle by
    • make an interface/function for packing data into a file and for unpacking data

created init_food(...)

has purpose statement with clear explanation of inputs
no longer afraid to pass in the space object reference because now I know that's a "reference" in python and not a giant object value
no more global variables
keyboard interaction simplified (soon to be removed from sim.py)
helper functions
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant