Skip to content

Chrispresso/PyGenoCar

Repository files navigation

PyGenoCar - V1.0

Welcome to PyGenoCar - The world in which cars are made using Genetic Algorithms!
Feel free to mess around with the settings and see how the cars change over the generations!
This contains information on the following:

  • Installation
  • Command Line Arguments
  • Controls
  • Settings

Installation

This requires Python3.6+

The installation here might seem like a lot of work, but I promise it isn't. I cannot include everything into a requirements.txt since Box2D is a bit more work than that. If you want the installation instructions from the box2d repo, head over to https://github.com/jonasschneider/box2d-py/blob/master/INSTALL.md. Otherwise just read below for what I did:

Windows:

  1. git clone https://github.com/pybox2d/pybox2d (optional: -b 2.3.2)
  2. Download SWIG. Easiest way is to use prebuilt executables from: https://sourceforge.net/projects/swig/files/swigwin/swigwin-4.0.1/swigwin-4.0.1.zip/download?use_mirror=cfhcable.
  3. Unzip and add swigwin-4.0.1 to your System Variables PATH (environment variable).
  4. cd /path/to/pybox2d/clone/location
  5. python setup.py build
  6. python setup.py install

Linux

  1. sudo apt-get install swig
  2. git clone https://github.com/pybox2d/pybox2d (optional: -b 2.3.2)
  3. cd /path/to/pybox2d/clone/location
  4. python setup.py build
  5. sudo python setup.py install

To test open a new Python terminal:

  1. import Box2D
  2. Box2D.__version__

If everything goes right, you should see a version printed.
You can now run pip3 install -r requirements.txt to finish installing the below requirements:

  1. numpy
  2. pyqt5
  3. dill

Command Line Arguments

Most of the stuff you are going to want to change is done in settings. The reason for this is there are just so many parameters, and having everything be modifiable through the command line would be overwhelming. There are however some things you may want to use the command line for:

-h: Basic help message.
--save-best <location>: You can specify a /path/to/save the best car from each generation to. Make sure that folder is empty or at least does not contain previous generation cars, otherwise they are at risk of being overwritten and the program won't allow that.
--save-pop <location>: If you want, you can specify a /path/to/save the entire population after each generation. Not really advised, but if you want to, it's here.
--save-pop-on-close <location>: /path/to/save the population when the program exits.
--replay-from-folder <location>: Can be used to replay individuals from a folder you saved to. Currently only supports playing one car at a time. Useful for seeing how best individuals are changing over the generations.

Controls

It might seem weird to have controls for a Genetic Algorithm, but the controls are for being able to move the camera around to get a better idea of the environment. Below are the current supported controls and their functions:

    Z: Zoom camera out
    C: Zoom camera in
    W, A, S, D: Pan camera up, left, down and right, respectively
    R: [R]eset to normal control, i.e. follow the leading car
    E: Goes back to default zoom (scal[e]). E is next to R....

Settings

This is broken up into two subsections: boxcar and ga. Boxcar consists of all settings that are used in the creation of cars, the world, and anything related to physics. Genetic Algorithm (ga) consists of all settings used in the overall control for the GA.

It is important to note that units are in MKS (meters, kilograms, seconds). If you change parameters, keep that in mind. Also keep in mind that Box2D, the physics engine used here, is meant for smaller objects. If you create a wheel that has a 50m radius, it might work, but it might not model the best.

Boxcar settings

Floor params
floor_tile_height [float]: The height that each floor tile in the world will be created with.
floor_tile_width [float]: The width that each floor tile in the world will be created with.
max_floor_tiles [int]: Maximum number of floor tiles that will be created in the world.
gaussian_floor_seed [int]: If you choose to create a gaussian floor, this seed will be used for the random number generator.
floor_creation_type [str]: Determines what type of floor will be generated for cars to compete on. Options are: gaussian, ramp and jagged

    gaussian
    Gaussian creation creates a very random track. There are modifiers to help the track be easier in the beginning and potentially harder at the end. Elevation gain and loss are both possible. Below are settings you can modify if floor_creation_type == `gaussian`:
    tile_angle_mu [float]: When a random gaussian floor tile is created, it is created with a gaussian random angle centered around this value.
    tile_angle_std [float]: When a random gaussian floor tile is created, it is created with a gaussian random angle with standard deviation of this value.

    Please see equation and explanation at the bottom of the page for what these two parameters control
    tile_gaussian_denominator [float]: Used for calculating a scale between [0,1] to multiply the angle by.
    tile_gaussian_threshold [float]: Used for calculating a scale between [0,1] to multiple the angle by.

    ramp
    Ramp creation creates a specified ramp and a jump distance that the cars will need to clear. The approach and landing zone are flat in order to prioritize learning of the ramp. Below are settings you can modify if floor_creation_type == `ramp`:
    ramp_constant_angle: [float/None]: If this value is defined, the ramp will go up at a constant angle.

    ramp_constant_distance: [float]: Only used if ramp_constant_angle is defined. Determines the length of the ramp.
    ramp_increasing_angle: [float]: If ramp_constant_angle is None this will be used. Will create a ramp at an increasing angle of this value.
    ramp_start_angle: [float]: Angle to start the ramp at.
    ramp_increasing_type: [str]: Options consist of `multiply` and `add` for now. The equation for the increasing ramp angle is: ramp_start_angle OPERATOR ramp_increasing_angle. Example:
    `ramp_start_angle = 1.0` and `ramp_increasing_angle=2.0`. The angles for the first 5 tiles of the ramp would be: `1, 2, 4, 8, 16`.
    ramp_max_angle: [float] Maximum angle to make a tile before ending the ramp creation.

    ramp_approach_distance [float]: Flat distance used as a runway before starting the ramp. ramp_distance_needed_to_jump [float]: Distance needed to jump before there is a landing zone. Distance is measured from the end ramp location to beginning of landing zone.

    jagged
    Jagged creation creates a jagged road for the cars to travel over. There is no elevation gain and nothing to jump here. It is simply a jagged course and simulates rough terrain. Below are settings you can modify if floor_creation_type == `jagged`:
    jagged_increasing_angle [float]: The amount the jagged edge will increase by.
    jagged_decreasing_angle [float]: The amount the jagged edge will decrease by.

Car params
car_max_tries [int]: Maximum number of tries a car can do without improving before it dies. One try per frame. An improvement is measured by reaching a farther max distance while moving faster than ~ 0.9mph (.4m/s)

Chassis params
min_chassis_axis [float]: Minimum length that a chassis part can have.
max_chassis_axis [float]: Maximum length that a chassis part can have.
min_chassis_density [float]: Minimum density a chassis part can have.
max_chassis_density [float]: Maximum density a chassis part can have.

Wheel params
min_wheel_density [float]: Minimum density a wheel can have.
max_wheel_density [float]: Maximum density a wheel can have.
min_num_wheels [float]: Minimum number of wheels a car can have.
max_num_wheels [float]: Maximum number of wheels a car can have.
min_wheel_radius [float]: Minimum radius a wheel can have.
max_wheel_radius [float]: Maximum radius a wheel can have.

World params
gravity [float, float]: (x, y) amount of gravity to have in the world.

Display params
show [bool]: Whether or not to have the graphics display.
fps [float]: The FPS to run the simulation at. If you are using show, you are basically limited to your monitor refresh rate. Otherwise you can set this to a value between [0, 1000].

Genetic Algorithm Settings

Selection params
num_parents [int]: Number of parents to select from the population for reproduction. This is also the default number of individuals spawned into the world. Will only reduce the size of the population if using selection_type plus.
num_offspring [int]: Number of offspring to create from the parents. Only used if selection_type plus is selected. Otherwise there will always be num_parents.
selection_type [str]: Options are plus and comma.
If plus is used, then the number of offspring in the next generation will be num_parents + num_offspring.
If comma is used, then the number of offspring in the next generation will be num_parents.
lifespan [int/np.inf]: The lifespan of an individual when it is created. Each generation that an individual survies, the lifespan of that individual decreases. Once the lifespan hits 0 the individual will not be selected to go onto the next generation, even if it is a top performer. This can help with exploration of the search space.

Mutation params
probability_gaussian [float]: When mutation occurs, this determines at what rate the mutation is gaussian.
gaussian_mutation_scale [float]: If there is a gaussian mutation it is multiplied by this value. This can help reduce the mutation to smaller values.
probability_random_uniform [float]: When mutation occurs, this determines at what rate the mutation is uniform.
mutation_rate [float]: The probability that each given gene in the chromosome will mutate.
mutation_rate_type [float]: Options are static and decaying. If static, then the mutation_rate is always the same, otherwise it decays as the generations increase.

Crossover params
probability_SBX [float]: When crossover occurs, this determines at what rate the crossover is simulated binary crossover (SBX).
SBX_eta [float]: eta is a control param for SBX. The smaller values create offspring further from the parents while larger values create offspring closer to the parents.
crossover_selection [str]: Options are tournament and roulette. These options create either tournament or roulette wheel selection when deciding which parents to select for crossover.

Misc.

Fitness function
The fitness function determines the overall fitness of an individual - calculated at the end of the generation. The great thing is you can change the fitness function directly from settings.py and choose what params to inclue and how to weight those params. Below are the params that will be passed to the fitness function:

    max_position [float]: This is the maximum position in the x direction that an individual made it.
    num_wheels [int]: Number of wheels that the individual has.
    total_chassis_volume [float]: Total volume that makes up the chassis of the car.
    total_wheels_volume [float]: Total volume of all wheels on the car.
    frames [int]: Total frames the that individual stayed alive for.

Random

Gaussian threshold explained:
When creating gaussian random tiles, you may want the tiles to start off at an easier angle and progressively get more chaotic. Because of this I introduced two concepts that you can modify to tweak the rate at which tile angles become more chaotic.

The equation is:

threshold = get_boxcar_constant('tile_gaussian_threshold')
denominator = get_boxcar_constant('tile_gaussian_denominator')
numerator = min(i, threshold)
scale = min(numerator / denominator, 1.0)
angle = random(mu, std) * scale

where i goes from [0, num_tiles)

So if num_tiles = tile_gaussian_threshold = tile_gaussian_denominator then scale won't be 1.0 until the very end. This just makes it so the potential of random(mu, std) is less until the end of the track. If you want just pure potential chaos, set both tile_gaussian_threshold = tile_gaussian_denominator = 1.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages