Package: physical_education
import physical_education as peA library to help:model robots and animals which run around anddo cool stuffrun trajectory optimization to understand those modelsanimate and plot the resultsIt's for research into legged crittersExample:Let's model a monoped hopper, shown in the left on this diagram:(The complicated quadruped model on the right is where this library starts to shine)We'll use a rotary joint for the hip (connection between upper link and body) and Hooke's joint for the knee (connection between upper link and lower link), shown in the following diagram:On to the code:importphysical_educationaspe# create a link called 'base', aligned along the x-axis.# by default, we use Euler-321 for angle orientationbase=pe.links.Link3D('base','+x',base=True,mass=5.,radius=0.4,length=0.4,)# we think of this link as starting at the center# of mass of the base, and pointing downwards (-z)upper=pe.links.Link3D('upper','-z',start_I=base.Pb_I,mass=.6,radius=0.01,length=0.25,)lower=pe.links.Link3D('lower','-z',start_I=upper.bottom_I,mass=.4,radius=0.01,length=0.25,)# use an 8-sided polygon for the friction modelpe.foot.add_foot(lower,at='bottom',nsides=8,friction_coeff=1.)# add relationships between links# the base has two degrees of freedom with respect# to the thigh - like a human's hipbase.add_hookes_joint(upper,about='xy')pe.motor.add_torque(base,upper,about='xy',torque_bounds=(-2.,2.),no_load_speed=20,)# the thigh has one degree of freedom with respect# to the calf - like a human's kneeupper.add_revolute_joint(lower,about='y')pe.motor.add_torque(upper,lower,about='y',torque_bounds=(-2.,2.),no_load_speed=20,)# combine into a robotrobot=pe.system.System3D('3D monoped',[base,upper,lower],)# calculate the equations of motion of the robot# symbolically, then lambdify them into a regular# python function# we'll simplify the equations in parallel, using 8 coresrobot.calc_eom(simp_func=lambdax:pe.utils.parsimp(x,nprocs=8),)# if you don't want to wait for simplification:# >>> robot.calc_eom()# create a pyomo model# we'll discretize the problem into 50 finite elements,# use implicit euler for integration, and give a starting# total time of 1 second whilst allowing individual# finite elements to vary by +-20%robot.make_pyomo_model(nfe=50,collocation='implicit_euler',total_time=1.0,vary_timestep_within=(0.8,1.2),)# let's start with a drop test# we'll have to write some code, but the idea is that# this library gives you the tools + example code to# complete a task. It doesn't have all tasks built in -# that's what your research is about!initial_height=3.0# metersnfe=len(robot.m.fe)ncp=len(robot.m.cp)body=robot['base']# start at the originbody['q'][1,ncp,'x'].fix(0)body['q'][1,ncp,'y'].fix(0)body['q'][1,ncp,'z'].fix(initial_height)# fix initial angleforlinkinrobot.links:forangin('phi','theta','psi'):link['q'][1,ncp,ang].fix(0)# start stationaryforlinkinrobot.links:forqinlink.pyomo_sets['q_set']:link['dq'][1,ncp,q].fix(0)# initialize to the y planeforlinkinrobot.links:forangin('phi','theta','psi'):link['q'][:,:,ang].value=0# knee slightly bent at the endang=0.01upper['q'][nfe,ncp,'theta'].setlb(ang)lower['q'][nfe,ncp,'theta'].setub(-ang)# but not properly fallen overbody['q'][nfe,ncp,'z'].setlb(0.2)# objective: reduce foot penalty (more on that later!)frompyomo.environimportObjectivepen_cost=pe.foot.feet_penalty(robot)robot.m.cost=Objective(expr=1000*pen_cost)# solve! This assumes you have linear solver HSL MA86.# Let's use L-BGFS, which is _much_ faster for large modelspe.utils.set_ipopt_path('~/CoinIpopt/build/bin/ipopt')pe.utils.default_solver(max_mins=10,solver='ma86',OF_hessian_approximation='limited-memory',).solve(robot.m,tee=True)# check final penalty value, and so onrobot.post_solve({'penalty':pen_cost})# animate the result at 1/3 speed, and view along the x-axis# also, make the camera track the link named 'base'robot.animate(view_along='x',t_scale=3,track='base')# let's also view along an elevation of -120 degrees, and# an azimuth of 35 degreesrobot.animate(view_along=(35,-120),track='base')Getting started1. Decide on a python implementationLarger models benefit tremendously from usingPyPyinstead ofCPythonas your python implementation. If you want more clarity on the differences, readthis explanation. Anecdotally, PyPy is at least twice as fast when simplifying large models using sympy, and twenty times as fast when setting up models using pyomo. That's the difference of 30 seconds vs 10 minutes!2. Install a nonlinear optimizer, like IPOPT... which is at times much easier said than done. Instructions arehere. You'll also need to install a linear solver. The HSL solvers are the best for many tasks, and their multi-core MA86 solver in particular is very fast. There'sa pageabout HSL + Ipopt, which you should read. This step is usually far easier when done in a Unix environment, likeUbuntuand others like itIf you use a multi-core solver like MA86, you can configure the number of threads to use by setting theOMP_NUM_THREADSenvironment variablebeforeyou launch Python. This can be done on Ubuntu by adding a line like,# set the number of threads for eg. ma86
OMP_NUM_THREADS=8to the/etc/environmentfile, then entering. /etc/environmentin a shell or just rebooting. There are other ways of doing this, but due to the way PyOmo runs IPOPT, I've found this to be the easiest and most reliable.Another way to get the Ipopt binary (plus mumps as a default solver) is by using cyipopt package, which has asuper easy installation process(conda install -c conda-forge cyipopt) on Linux and MacWhile you're waiting for things to compile/install, please read this article onsupporting black scholars in robotics. All fields (even technical ones, like robotics) are political, and it's crucial that you make an active effort to learn about and combat injustices, such as racism and sexism.3. Installphysical_educationIt's recommended that you use a virtual environment - whether that'sconda,venv,poetryor whatever else seems easiest to you. This library is onpypi.org, so you should be able to pip install it as follows:python-mpipinstallphysical_educationIF you use conda, instructions are as follows:use pypy, as recommended, now that pypyis availablevia conda. In the code below, replaceENV_NAMEwith the name you want to use for your virtual environment:$condaconfig--setchannel_prioritystrict
$condacreate-nENV_NAMEpypy
$condaactivateENV_NAME
$pypy3-mpipinstallphysical_educationor, using CPython:$condacreate--nameENV_NAME
$condaactivateENV_NAME
$condainstallpip
$python-mpipinstallphysical_educationDocs on how to navigate environments can be foundhere.Test that it's working:$python>>>importphysical_educationaspe>>>pe.visual.success('it worked!')You can remove an environment using:$condaenvremove--nameENV_NAMEThat's mentioned in case you eg. try pypy, find it doesn't work, and then want to switch4. Optional but recommended: installjupyterlabJupyterlab is the current version of the Jupyter IDE, which is used to view and run jupyter notebooks. Alex will shamelessly plug hisguideon a good setup for this, if you have two computers: a laptop which you want to work on, and a beefy computer where you want optimizations to run5. Look through through the examplesand then start your project. Good luck, and please open an issue if anything is unclear!Documentationoutside of commented code/examples, is currently non-existent. I'm finishing off my dissertation now, but intend on working on that afterwards. I have a chapter on this library which serves as a nice intro to everything.