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.
Now that I could stand up and sit down, I needed to be able to walk reliably for the length of a match. This wasn’t going to be easy because the direct drive motors were always a bit marginal in their power output to support the full robot, so I had my work cut out for me.
The short story is, I tried many things, spent about a day examining high speed video of walking, and made some improvements:
Inverse Kinematics: I discovered that my inverse kinematics were broken when the coaxial lower leg had a non-unity belt drive ratio, which I switched to partway through my mammal leg experiments.
Less bounce: I updated the leg to stay in the world frame until it was fully lifted and to enter the world frame before lowering. This would ensure it had zero lateral velocity relative to the ground when starting and stopping the swing phase.
More less bounce: I added a separate slew time for the lowering part of the phase, this allowed it to lower more slowly for a more gentle landing.
Event more less bounce: I used the moteus servo’s advanced features to lower the P controller term while the leg was lowering, so that it would hit more softly.
Despite all these improvements, the walking was still barely functional. Also, the robot was just too tippy. The servos didn’t have enough control authority for the mass of the machine, and it was likely going to tip over if another mech did so much as graze it. Also servos that were hot for long periods of time kept having their encoder calibration drift. This seemed to occur in a positive feedback cycle… if a motor was a little bit out of calibration, it might be a bit saggy, and thus would need more torque, which would make it hotter, which would make it more out of calibration.
Here’s a quick slow motion video of about the best walking gait I had achieved:
At this point, I was certainly somewhat dispirited. It was pretty clear that this machine could not reliably walk around the arena for the length of a match. But, there was still some time left and I figured I would not give up just quite yet.
In the spirit of failing upward, I decided to try and make a sprint towards a fully gearbox driven machine. Granted, I didn’t really have enough time to pull this off. The first 4 gearboxes I built each required about a day of 3d printing time and took me about 1.5 days of machining and assembly. When I made this call, there were about 8 days before my plane flight to Maker Faire. I would need to make at least 8 more gearboxes, as well as entirely new legs and shoulders, along with spares and then make it all work in an incredibly short period of time.