Thankfully, I’m now at the point where I’m fixing actual dynamics problems on the robot. Doubly thankfully I have a robot which is pretty robust and keeps working! That said, it is still, shall we say, “non-ideal”, to be testing code for the first time ever on a real robot.
Back with my HerkuleX based Super Mega MicroBot, I had a working DART based simulation which was decently accurate. However, the actuators for that machine were so limited that it didn’t really make sense to do any work in simulation. The only way to be effective with that machine was to tweak and tweak on the real platform and rely on exactly the right amount of bouncing and wiggling that would get it moving smoothly.
Now that I can accurately control force at 400Hz and beyond, that isn’t a problem anymore, so I’m working to resurrect the bitrotted simulator. In the end though, it turned out to be a complete re-write as basically nothing of the original made sense to use.
Here’s a video of the very first time it moved around in sim (which means there are still many problems left!)
This gait is basically the same thing as I ran on the quad A0 in principle. The opposing feet are picked up according to a rigid schedule, and moved to a point opposite their “idle” position based on the current movement speed. Any feet that are completely placed on the ground just move with the inverse of the robot’s velocity.
What differs now is that the leg positions and forces are controlled in 3D at a high rate, 400Hz for now. At each time step, the position and velocity of all 12 joints is measured. The gait algorithm calculates a desired 3D position, velocity, and force. Feedforward force is currently only used to control the weight supporting legs. Then, those 3D parameters are transformed into a joint position, velocity, and force based on the current joint position, and the command is sent out.
While not conceptually too different, just controlling the system in 3D at a high rate gives significantly improved results for a range of walking parameters. There is still a lot left to do, but it is a good start!
While not perfect, now that I have flux braking in place, I have now succesfully pronked around for a while without faulting! There are a number of outstanding problems that still need to be addressed:
Sometimes the landing phase is erroneously cut short
There is occasionally a grinding like noise that sounds like some controller is unstable
I think the lateral movement is not working correctly
The gait needs to be smarter about moving the legs past the center point when in mid-flight, and changing the gait period to achieve different speeds
And probably a bunch of other problems I haven’t even identified yet
That said, it is still fun to watch it romp around!
Now that I can do controlled jumps, and have a UI which allows me to use the joystick, I finally started actually working towards pronking gaits. Too bad for you, this post doesn’t have any details, merely a video snapshot of my learning and debugging process…
Now that I have a full rate inverse kinematics and dynamics solution, I can begin to do more interesting things. A while ago I did the first jump on the quad A0 — in that video I used a limited technique just to verify that the platform was indeed capable of jumping. The joints were commanded in an open loop fashion, and really only at the transition points of the jump sequence, relying on the control loops in the servo to actually achieve each stage of the jump cycle. That resulted in the jump only being minimally controlled… tracking errors would result in the robot taking off from a not-level position and the timing was not super reliable to boot.
Now I’ve taken that demonstration to the next level by controlling the full position, velocity, and force profile of each of the 4 legs at 150Hz during the jump maneuver. In the launch phase, all four legs follow a constant acceleration trajectory while maintaining a level body. During the flight phase, the force is cut to the legs and the velocity of each leg is monitored. A few milliseconds after the legs have been detected as moving, the velocity is sampled and a controlled constant acceleration profile is selected which results in zero velocity when the robot reaches its initial takeoff point. After that, it just moves at a constant velocity back to the starting height.
Next up is chaining these together into a pronking gait.
The old SMMB / HerkuleX control software commanded the servo positions in an open loop, which did not take into account the actual position of the joints in any way. What I’ve done now is implemented a control flow where at each cycle the state of all 12 servos is sampled, then the control laws are applied based on that state, then the resulting commands are sent out.
So far, the only control laws I have ported are a simple one which just sends raw commands to each joint, and a somewhat more useful one which commands the end effector of each joint in terms of position, velocity, and force. Here’s a quick video showing it commanding various constant forces with no position constraints. The scale isn’t super accurate, nor is the actual force coming out of the device, but I think it should be good enough.
A while ago I derived some closed form solutions for the inverse force dynamics for a 2 dimensional mammal geometry leg. Now that I want to execute more dynamic gaits, I need to be able to control the velocity and force of the 3 dimensional leg in real time. That means I need to be able to go forward and back between the two representations. The first being joint angles, joint velocities, and joint torques — the second being 3D position, velocity, and force.
Rather than derive those myself in 3 dimensions, I decided to save a bit of time now by using the DART kinematics and dynamics routines. I might need to undo this later if it turns out to be too slow at runtime, but if nothing else it can be a good ground truth for anything I do myself. I also took this opportunity to do all calculations in consistent rational coordinate frames, where before I had conventions that while documented, were rather unorthodox.
As it turns out, this demonstrated that my old 3 dimensional force calculation, was as I had expected, slightly incorrect.
The shoulder torque was the most affected, being off by 20% or so.
My outdoor filming for the project update video was cut short when the machine cut power to the motors, fell down, and one of the legs snapped off. Fortunately, I already had plenty of footage when that happened, so it didn’t really impact the video.
First, this demonstrates the not too surprising fact that this particular part of the leg design could use to be improved. Second, and the topic of this post, is improving what the machine does when the inevitable failure does occur.
What happened — just the facts ma’am
In this particular instance, I had been running the machine outside continuously outside for an hour or so on a relatively warm day. This iteration of the servos has basically no heatsinking whatsoever on the servo control board. With the gearboxes, it isn’t necessary for short duration or low power testing. However in this case, one of the servos eventually reached its temperature limit and entered a fault state.
As implemented now, any individual servo that hits a hard fault immediately cuts all power. Also, at that time, the overall gait control, upon sensing any servo failure, immediately cuts power to all the other servos too. As you can imagine, when a machine that weights 10kg loses all power to all joints with a few milliseconds, it falls down pretty hard.
Areas to improve
There are of course many areas of improvement which this event demonstrates. One, the servos need better thermal properties. This was known, and I hope to address in the second revision where I can heatsink the controller properly. Second, the leg should be strong enough to handle falling down. And third, it would be nice, if it could, if the machine would do something more graceful when continuing on in a controlled manner isn’t possible.
I tackled that third step right now in two phases. First, I set up an optional communications watchdog in the servo. If control commands aren’t received in a timely manner, the servo enters a new mode where it merely commands a zero velocity with no position control at all. This means that if the control software segfaults, or the primary computer goes out to lunch, the machine will gently lower to the ground rather than dropping like a rock.
Second, I modified the control software’s reaction to an individual servo fault. Now, it commands this new zero-velocity state of all unfaulted servos so as to minimize the amount of damage done to the overall machine. If only one or two servos have faulted, this will still result in a relatively gradual let down.
Here’s a quick video demonstrating the two failure types:
Back when I was getting Super Mega Microbot “Junior” ready for Maker Fair Bay Area 2019, I made it minimally self sufficient through a quick hack of adding some PVC pipe that allowed it to manipulate its feet into a known good position while the robot was safely up in the air.
This worked, but had a number of obvious disadvantages. For one, it looked ugly! Second, the machine couldn’t squat down very far before getting stranded on the “resting legs”. I’ve finally gotten around to doing at least a first attempt at something better!
The basic problem is that normal gaits result in having the feet positioned under the robot. Then, if you want to sit down, you can’t do it because your feet are in the way. What I’ve done for now is have the robot take some steps to widen its stance so that the feet are out of the way, then sit down. Standing up is the inverse. First the feet are positioned in the widened stance, lowered until the machine is at the correct height, then some steps are taken to get into the normal walking gait stance.
At this point, even this is somewhat of a hack, because the gait generation code is only minimally modified from what I had back in 2014. When it gets modernized, this standing up procedure will need to be re-implemented, but for now this will let me both lose the ugliness, and experiment with things like bigger jumps.
To demonstrate the dynamic capability of the full rotation quadruped, I figured I would start by doing some full machine jump tests to a relatively low height, just to show that it was capable.
Thus, I rigged up an open loop script which squatted a small fraction of the available distance, and then powered up at a relatively small fraction of the available maximum speed. I don’t have the telemetry yet to extrapolate how high this will be able to go at maximum, but I think it should be a fair amount higher. For now, I want to do some more instrumentation and walking testing (and have more spares) before I manage to break things by jumping really high.