PinnZoo contains fast dependency-free C code for dynamics and kinematics functions for various robots (defined by URDFs) generated using Pinocchio and CasADI, along with a wrapper to generate a shared library and call the code from Julia. This was developed for internal RExLab use, both for speed and for making Pinocchio compatible with our in-lab conventions and other libraries like RigidBodyDynamics.jl (i.e. for configuration order) used by the RExLab that differ from Pinocchio, details can be found in the docs.
Note: You do not need to install Pinocchio or CasADI to use the models, the models are dependency free. You only need them to generate a new model.
Models can be found in the models directory. Each model folder should include the following:
- the URDF
- generate.py (file used to generate the C code)
- a generated_code directory where the C code is
- a <model_name>.jl file which wraps the C code so it can be called from Julia
- a README that provides basic model details, such as state vector order, bodies that kinematics were generated for, and anything else that may need clarification.
- any additional C or Julia files for model specific functions/behaviors (should be documented in README)
Refer to the docs (currently under docs/build/index.html) for details on the generated functions. While we wrap them in Julia, there are many ways you can use these functions, such as linking them into your own C or C++ project, or calling them from Python. An example of using the Julia wrapper is in the Get Started section below.
We don't currently provide Python bindings to the codegen C code. Reference src/symbolic_generator.py
for all of the dynamics and kinematics function generation (if you don't want to parse the Pinocchio docs this can be a quick reference for basic dynamics and kinematics calls).
First, clone the repository, and run the following commands in the terminal. You will need CMake and C compiler to be installed.
cd PinnZoo
mkdir build
cd build
cmake ..
cmake --build .
Note: If you'd only like to compile code for a certain model instead of all possible models, use cmake --build . --target <model_name>
.
Once you've finished compiling, you can install PinnZoo in your Julia environment with the following commands
using Pkg
Pkg.develop(path="<path to PinnZoo folder>")
Here are some examples of basic usage:
using PinnZoo
model = Cartpole()
x = randn_state(model) # Can also use zero_state(model)
u = randn(model.nv) # All DoFs are actuated by default
M = M_func(model, x) # Mass matrix
C = C_func(model, x) # Bias/nonlinear term
v_dot = forward_dynamics(model, x, u) # Solves for accelerations using manipulator equation (ABA)
x_dot = dynamics(model, x, u) # adds q_dot = E(q)v_dot to forward_dynamics
u_new = inverse_dynamics(model, x, v_dot) # Solves for torques using manipulator equation (RNEA)
locs = kinematics(model, x) # For cartpole, location of the pole tip in the world frame
J = kinematics_jacobian(model, x) # Jacobian of the pole tip w.r.t the state vector
Check out the documentation (currently under docs/build/index.html) for details on conventions and the functions available
To add a model, do the following:
- Create a folder under models with the model name, with the urdf, a generate.py file and a .jl file. Copy models/pendulum for a basic model, but make the parent type PinnZooFloatingBaseModel if it is a floating base (look at unitree_go1, unitree_go2 or Nadia for more). If curious, look at src/model_macro.jl to see what the macro is doing, it mainly adds a bunch of C pointers to the generated code to your struct, as well as fetching some model info.
- Run your generate.py file to generate the code
- Modify CMakeLists.txt to add your shared library
- cd into build and run
cmake ..
andcmake --build . --target <model_name>
- Modify src/PinnZoo.jl to include your model and export it
- Modify test/runtests.jl to include your model
- Run
julia -t auto test/runtests.jl
and make sure your model passes
You can run the following in the PinnZoo directory to re-generate all the generated code if a change is made to symbolic_generator.py
find models -type f -name generate.py -exec python {} \;
Make sure to run the PinnZoo test suite after regenerating.
You can convert from urdf to mjcf using MuJoCo in more recent versions by loading the model and using mj_saveLastXML.
- Generalize error_state and apply_Δx functions for any model with a quaternion in the state
- Fix velocity_kinematics, kinematics_velocity, kinematics_velocity_jacobian tests
- Fix forward_dynamics_deriv (failing tests)