Robots are great fun! But they're also expensive, which makes it a big investment to play around with them. But why not just simulate a robot? Well, that can also easily take several weeks of figuring out how to install which software.
At JuliaCon 2019 we had the pleasure to sit together and set up all the packages from Julia Robotics that are needed to make a robot walk. The software has mainly been written by Twan Koolen and Robin Deits. It's fairly trivial to set up if you know what's needed - and it offers competitive speed to established, complex, C++-based software.
We can now load our robot (an earlier version of the Boston Dynamics Atlas robot), represented as a kinematic tree, where the vertices represent links (rigid bodies) and the edges represent the joints that connect the links.
Next, we'll create the controller that will allow Atlas to walk around on flat ground. Explaining precisely what's going on is beyond the scope of this article, but if you're interested, see this paper for details.
The particular type of controller used for this demo consists of a low-level momentum-based motion controller and a high-level controller that implements the walking behavior on top of the low-level controller. The low-level controller sets up and solves a quadratic program (QP) at every control time step (here, at 500 Hz). We're using the Parametron.jl package to efficiently set up the QPs and hand them to a QP solver, in this case the osqp solver via its Julia wrapper package:
The controller will run at a simulated 500 Hz. To simulate this, we wrap our walking controller in a so-called PeriodicController and create a Dynamics object, which represents the dynamics of our robot with this controller in the loop:
To visualize the robot during the simulation, we'll set up a callback that periodically updates the transforms of the mechanism's links to match the current state of the simulation:
callback=VisUpdater(mechanism, three_js_display, meshes, vis_elements);
set_state(three_js_display, meshes, vis_elements, nominal_state)
display# might need to execute two times because of websocket issue