Simulate and optimize planar leg mechanisms using PSO and GA
Project description
leggedsnake
LeggedSnake makes the simulation of walking linkages fast and easy. We believe that building walking linkages is fun and could be useful. Our philosophy is to provide a quick way of building, optimizing and testing walking linkages.
Overview
First, you will define a linkage to be optimized. Here we use the strider linkage by Wade Wagle and Team Trotbot.
Dimensions are intentionally wrong, so that the robots fails to walk properly.
Let's take several identical linkages, and make them reproduce and evolve through many generations. Here is how it looks:
Finally, we will extract the best linkage, and here is our optimized model that do not fall.
Installation
The package is hosted on PyPi as leggedsnake, use:
pip install leggedsnake
Build from source
Download this repository.
git clone https://github.com/hugofara/leggedsnake
Conda Virtual Environment
We provide an environment.yml file for conda.
conda env update --file environment.yml --name leggedsnake-env
It will install the requirements in a separate environment.
Other installation
If you are looking for a development version, check the GitHub repo under HugoFara/leggedsnake.
Usage
First, you define the linkage you want to use. The demo script is strider.py, which demonstrates all the techniques about the Strider linkage.
In a nutshell, the two main parts are:
- Define a Linkage.
- Run the optimization.
Defining a Walker
you need to define joints for your Walker
as described in pylinkage
documentation.
You may use a dictionary, that looks like that:
import leggedsnake as ls
# Quick definition of a linkage as a dict of joints
linkage = {
"A": ls.Static(x=0, y=0, name="A"),
"B": ls.Crank(1, 0, distance=1, angle=0.31, name="Crank")
# etc...
}
# Conversion to a dynamic linkage
my_walker = ls.Walker(
joints=linkage.values(),
name="My Walker"
)
# It is often faster to add pairs of legs this way
my_walker.add_legs(3)
# Then, run launch a GUI simulation with
ls.video(my_walker)
It should display something like the following.
Optimization using Genetic Algorithm (GA)
The next step is to optimize your linkage. We use a genetic algorithm here.
# Definition of an individual as (fitness, dimensions, initial coordinates)
dna = [0, list(my_walker.get_num.constraints()), list(my_walker.get_coords())]
population = 10
def total_distance(walker):
"""
Evaluates the final horizontal position of the input linkage.
Return final distance and initial position of joints.
"""
pos = tuple(walker.step())[-1]
world = ls.World()
# We handle all the conversions
world.add_linkage(walker)
# Simulation duration (in seconds)
duration = 40
steps = int(duration / ls.params["simul"]["physics_period"])
for _ in range(steps):
world.update()
return world.linkages[0].body.position.x, pos
# Prepare the optimization, with any fitness_function(dna) -> score
optimizer = ls.GeneticOptimization(
dna=dna,
fitness=total_distance,
max_pop=population,
)
# Run for 100 iterations, on 4 processes
optimized_walkers = optimizer.run(iters=100, processes=4)
# The following line will display the results
ls.all_linkages_video(optimized_walkers)
For 100 iterations, 10 linkages will be simulated and evaluated by fitness_function. The fittest individuals are kept and will propagate their genes (with mutations).
Now you should see something like the following.
This is a simulation from the last generation of 10 linkages.
Most of them cover a larger distance (this is the target of our fitness_function
).
Results
Finally, only the best linkage at index 0 may be kept.
# Results are sorted by best fitness first,
# so we use the walker with the best score
best_dna = optimized_walkers[0]
# Change the dimensions
my_walker.set_num_constraints(best_dna[1])
my_walker.set_coords(best_dna[2])
# Once again launch the video
ls.video(my_walker)
So now it has a small ski pole, does not fall and goes much farther away!
Kinematic optimization using Particle Swarm Optimization (PSO)
You may need a kinematic optimization, depending solely on pylinkage.
You should use the step
and stride
method from the
utility module as fitness functions.
This set of rules should work well for a stride maximisation problem:
- Rebuild the Walker with the provided set of dimensions, and do a complete turn.
- If the Walker raises an UnbuildableError, its score is 0 (or
-float('inf')
if you use other evaluation functions). - Verify if it can pass a certain obstacle using
step
function. If not, its score is 0. - Eventually measure the length of its stride with the
stride
function. Return this length as its score.
Main features
We handle planar leg mechanisms in three main parts:
- Linkage conception in simple Python relies on pylinkage.
- Optional kinematic optimization with
Walker
class, inherits from pylinkage'sLinkage
class. - Dynamic simulation and its optimization use genetic algorithms.
Advice
Use the visualisation tools provided! The optimization tools should always give you a score with a better fitness, but it might not be what you expected. Tailor your optimization and then go for a long run will make you save a lot of time.
Do not use optimized linkages from the start! The risk is to fall to quickly into a suboptimal solution. They are several mechanisms to prevent that (starting from random position), but it can always have an impact on the rest of the optimization.
Try to minimize the number of elements in the optimizations! You can often use some linkage properties to reduce the number of simulation parameters. For instance, the Strider linkage has axial symmetry. While it is irrelevant to use this property in dynamic simulation, you can use "half" your Strider in a kinematic optimization, which is much faster.
Contribute
This project is open to contribution and actively looking for contributors. You can help making it better!
For everyone
You can drop a star, fork this project or simply share the link to your best media.
The more people get engaged into this project, the better it will develop!
For developers
You can follow the guide at CONTRIBUTING.md. Feel free to me any pull request.
Quick links
- For the documentation, check the docs at hugofara.github.io/leggedsnake!
- Source code is hosted on GitHub as HugoFara/leggedsnake
- We also provide a Python package on PyPi, test leggedsnake.
- If you just want to chill out looking at walking linkages striving to survive, join the discussions.
Contributors are welcome!
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file leggedsnake-0.4.0.tar.gz
.
File metadata
- Download URL: leggedsnake-0.4.0.tar.gz
- Upload date:
- Size: 61.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.9.17
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | b0e398959f381d383336c034d8f8a53df9caa32808d7714cf2b7817fa3246475 |
|
MD5 | 24c96405a50b8527f84367f4022994e6 |
|
BLAKE2b-256 | 7fda3d58ebce705b1dceab8c5ac8c3b17babec4357f278c4db97379886dd206c |
File details
Details for the file leggedsnake-0.4.0-py3-none-any.whl
.
File metadata
- Download URL: leggedsnake-0.4.0-py3-none-any.whl
- Upload date:
- Size: 28.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.9.17
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 5859be416dd1eb88c545e3d8d1cf70a1ce6735f33f9dab517b32ca5561abcfdb |
|
MD5 | cff89a0c87535abce145f5e55809fa51 |
|
BLAKE2b-256 | e240a88c58bdd6765ebebefaec30ed4d9cf8ddc3fd838d780490628da003c35d |