Aug 2023 Tweet
Browser-based robot dog simulator: walking controller
Previously, I have implemented a controller for a quadruped robot for stepping in place. It is a good starting point for implementing a controller for walking.
targets for placing feet
The only difference between stepping in place and walking — is selecting target points for lifting and planting feet.
An idea that is frequently used in procedural animation is to set this target points relative to the character’s torso. Then, when torso is moved, feet always automatically follow the torso, and step in the same direction.
Three.js already supports hierarchy of objects, so the only thing that's changing is putting the torso object as a parent for the feet targets objects.
For stepping in place, feet target points are attached to three.js scene, and do not change position:
this.step_targets[j] = new THREE.Mesh();
this.step_targets[j].geometry = new THREE.SphereGeometry(0.01, 30, 30);
this.step_targets[j].material = new THREE.MeshLambertMaterial();
scene.add(this.step_targets[j]);
And for walking, they are attached to the torso object, and move along with it:
this.step_targets[j] = new THREE.Mesh();
this.step_targets[j].geometry = new THREE.SphereGeometry(0.01, 30, 30);
this.step_targets[j].material = new THREE.MeshLambertMaterial();
this.targets["trunk"].add(this.step_targets[j]);
The video shows how feet targets (this.step_targets from the code above, shown with white spheres) move with the torso.
walking motion generation
In the post about stepping in place, I have posted the code for the motion generation. Code for walking motion is mostly the same — the only difference is transforming feet targets from local coordinates (relative to the torso), into world space coordinates.
Code for stepping in place:
[...]
// set the target for lifting the foot
// it's the same as the initial standing position
s.goal = this.step_targets[s.name].position.clone();
// only raised 0.1m above ground
s.goal.y += 0.1
[...]
And code modified to support walking:
[...]
// set the target for lifting the foot
// from the point attached to the torso
let w = new THREE.Vector3();
this.step_targets[s.name].getWorldPosition(w);
s.goal = w;
// raised 0.1m above ground
s.goal.y += 0.1;
[...]
This approach to motion generation is quite flexible, it works for different variations of gaits, for different directions of walking, and for turning:
Code is on github, and an interactive demo with first-person control of the robot is below. Use WASD keys on keyboard or on the screen for moving the robot.
This is a nice and simple approach, and I’m quite happy with how compact the code is. There are limitations of course:
- There is no sensing and no feedback loop, so if robots loses the balance, it will not recover and will most likely fall. A quadruped is quite a stable platform, but it's still easy to put it off balance by moving and turning abruptly.
- Simulation parameters are approximate, I tweaked values for the robot’s weight and for the motors settings; support for realistic parameters needs more work
- Only walking on flat surface is supported, any obstacles or elevation changes will lead to losing the balance