Package: leggedsnake
leggedsnakeLeggedSnake 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.OverviewFirst, you will define a linkage to be optimized.
Here we use thestrider linkagebyWade 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.InstallationThe package is hosted on PyPi asleggedsnake, use:pipinstallleggedsnakeBuild from sourceDownload this repository.gitclonehttps://github.com/hugofara/leggedsnakeConda Virtual EnvironmentWe provide anenvironment.ymlfile for conda.condaenvupdate--fileenvironment.yml--nameleggedsnake-envIt will install the requirements in a separate environment.Other installationIf you are looking for a development version, check the GitHub repo underHugoFara/leggedsnake.UsageFirst, you define the linkage you want to use.
The demo script isstrider.py, which
demonstrates all the techniques about theStrider linkage.In a nutshell, the two main parts are:Define a Linkage.Run the optimization.Defining aWalkeryou need to define joints for yourWalkeras described inpylinkagedocumentation.
You may use a dictionary, that looks like that:importleggedsnakeasls# Quick definition of a linkage as a dict of jointslinkage={"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 linkagemy_walker=ls.Walker(joints=linkage.values(),name="My Walker")# It is often faster to add pairs of legs this waymy_walker.add_legs(3)# Then, run launch a GUI simulation withls.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=10deftotal_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 conversionsworld.add_linkage(walker)# Simulation duration (in seconds)duration=40steps=int(duration/ls.params["simul"]["physics_period"])for_inrange(steps):world.update()returnworld.linkages[0].body.position.x,pos# Prepare the optimization, with any fitness_function(dna) -> scoreoptimizer=ls.GeneticOptimization(dna=dna,fitness=total_distance,max_pop=population,)# Run for 100 iterations, on 4 processesoptimized_walkers=optimizer.run(iters=100,processes=4)# The following line will display the resultsls.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 ourfitness_function).ResultsFinally, 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 scorebest_dna=optimized_walkers[0]# Change the dimensionsmy_walker.set_num_constraints(best_dna[1])my_walker.set_coords(best_dna[2])# Once again launch the videols.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 thestepandstridemethod from theutility moduleas fitness functions.
This set of rules should work well for a stridemaximisationproblem: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 usingstepfunction. If not, its score is 0.Eventually measure the length of its stride with thestridefunction. Return this length as its score.Main featuresWe handle planarleg mechanismsin three main parts:Linkage conception in simple Python relies onpylinkage.Optionalkinematic optimization withWalkerclass, inherits from pylinkage'sLinkageclass.Dynamic simulation and its optimization use genetic algorithms.AdviceUse 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 andthengo for a long run will make you save a lot
of time.Do notuse 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.ContributeThis project is open to contribution and actively looking for contributors.
You can help making it better!For everyoneYou candrop a star,fork this projector simply share the link to your best media.The more people get engaged into this project, the better it will develop!For developersYou can follow the guide atCONTRIBUTING.md. Feel free to me any pull request.Quick linksFor the documentation, check the docs athugofara.github.io/leggedsnake!Source code is hosted on GitHub asHugoFara/leggedsnakeWe also provide a Python package on PyPi, testleggedsnake.If you just want to chill out looking at walking linkages striving to survive, join thediscussions.Contributors are welcome!