Tag Archives: quad

New leg cable management

Now that the quad A1 has been running faster, it has started “running” through its ad-hoc cable management too. After replacing a harness for the nth time, I decided to actually design something rather than just keep re-building over and over again.

My current best effort uses semi-flexible nylon split conduit, captured in 3d printed forms at each joint. Inside that conduit is basically the same harness I had before, with the cables selected to be more robust to repetitive motion. The nylon conduit is only semi-flexible, so it enforces a relatively large minimum bending radius on the wires within, while still sticking to the black quad A1 color motif.

To verify this would be at least a minimal step up, I ran some endurance testing with around 100,000 cycles of the leg moving. With no degradation of the cables in that window, I’m calling this good enough for this iteration of improvement.

Stable gait sequencing

In the last post, I described the newer gait engine which takes a desired command and produces a set of gait parameters. At that point, the gait engine needs to implement those gait parameters in a way that is stable with respect to disturbances and keeps the two legs properly out of phase with one another.

The gait variables that the gait selection procedure emits are as follows, each “leg” is actually a pair of legs.

  • swing time: This is the amount of time between when a leg lifts off the ground, and when it lands again.
  • one leg time: This is the amount of time spent with only a single leg on the ground.
  • two leg time: The amount of time with both legs on the ground.
  • flight time: The amount of time with no legs on the ground.

I’ve chosen to implement this for now with two controllable variables, when to pick up the next leg to begin its swing phase and how far out to place the foot when landing. When in flight, the swing time is fixed to be exactly what the gait engine selected. When on the ground, the leg position and velocity are fixed in the world frame to match the current command. This results in the other three parameters, one leg, two leg, and flight time, being approximated as best as possible.

When to lift

When there is no flight time, then the heuristic for when to lift the leg is identical to that described in “Balancing gait in 2D“. The trailing leg is lifted when the opposing leg is half of a swing time away from crossing the balance point.

When there is a flight time present, we have to add a corrective term to that heuristic, otherwise the two legs can lose their phase synchronization. If the correct out of phase relationship is being held, then the leg will be lifted when the alternate leg is in flight and has the “flight time” remaining in its swing cycle. The correction for that leg is calculated as a difference in time around that point such that the correction is positive before that point and negative after scaling in a linear manner. This has the desired property that the two legs are kept out of phase, without enforcing a strict leg cycle time.

Where to place

Once again, when there is no flight time, the placement location is the same as before. When there is a flight time, then the placement location is even simpler. Now it is just a position forward of the balance point by one half of the “one leg time”. This results in the machine spending roughly half of its time on each side of the balance point.

Further work

I’ve got one further enhancement to this technique to describe, at which point I think I’ll have basically exhausted its promise. Further advances will likely have to come from using an optimization based controller rather than a heuristic driven approach.

Higher speed gait formulation

As hinted in my earlier video I’ve been working towards some higher speed gaits with the quad A1. To accomplish that, I had to restructure the gait sequencing logic to permit changing cycle times and allow flight phases.

For now, I’ve tentatively broken down the trot gait into 5 regimes, based on how fast the machine is moving:

  1. At the slowest speeds, the flight legs swing through a step in the configured maximum flight time. The interval between flight times is fixed at a configured maximum. Here the speed is determined by how far the flight legs move.
  2. Once the flight legs are moving through their maximum allowed distance, then the amount of time spent with both legs on the ground is reduced in order to increase speed.
  3. At the point when both legs are not on the ground at the same time, then there begins to be a flight phase. Increasing the length of the flight phase increases the speed.
  4. When the flight phase reaches a configured maximum, then the swing time is decreased until it reaches a configured minimum.
  5. When the swing time is at a configured minimum, the flight time is at a configured maximum, and the legs are moving through their maximum range, then the machine is moving at its maximum speed.

Depending upon the current commanded rotation rate and translation velocity, the distance available for the legs to travel through may change. This uses the same mechanism from the step selection technique to determine the maximum distance at each update cycle, then selects which of the above regimes is active based on the commanded speed.

For a given maximum distance the legs can move through, that results in key gait parameters changing with speed as in the plot below:

Next up I’ll cover the heuristics used to implement any given set of gait parameters in a stable manner.

quad A1 stand-up sequence part N

I’ve worked through a number of different iterations of the stand-up sequence for the quad A1 (2019-05, 2019-09). The version I’ve been using for the last 6 months or so works pretty well, but because it drags the legs along the ground to get them into position, it can have problems when operating on surfaces with a lot of traction, like EVA foam, besides being uselessly noisy.

To make things just a bit more robust, I’ve now tweaked the startup routine so that the shoulders lift legs clear off the ground before positioning the legs, then lowers them back down into place. This makes the stand up routine much more likely to succeed on just about any surface:

Updated web UI

I first wrote about the very very simple web UI for the quad A1 some time ago. That UI served its purpose, although it was largely inscrutable to anyone but myself, as the primary data display was a giant wall of unformatted JSON which filled most of the page. It was also pretty easy to accidentally pick the wrong mode, cause the robot to jump instead of walk, or cut power to everything.

In advance of some wider testing, I went ahead and made the first revision to this now. It has the same basic structure as before, in that the robot serves up one each of an html/css/js file, and provides a websocket interface for ongoing command and control. The change here is just that the html and javascript are even minimally usable:

Clearly I’m not going to win any design awards… but since all the styling is done with CSS, it should be not too hard to make something that looks arbitrarily nice without a whole lot of effort. As a bonus, I also added some minimal keyboard bindings for movement, so the joystick isn’t required if you don’t care about precise or aggressive maneuvers.

micro-BOM management

I’ve now built 3 or 4 complete quad A1 style robots depending upon how you look at it. Each was somewhat of a one-off, incrementally modified over time as I discovered failure modes and improved the design. Before starting to serially build quad A1 style robots, I wanted to get a better understanding of how much actually goes into making one. The quad A1 has a fair number of sub-assemblies, custom PCBs, harnesses, and assembly steps that go into its production. During previous builds, I kept running into problems where I would run out of some component, fastener, or raw material unexpectedly, then have to wait for its lead time before I could continue.

I’m currently using a simplified Kanban inventory tracking system where I re-order parts and components when their inventory level reaches a critical threshold. However, given the discontinuous nature of my production, setting those levels is really hard. I didn’t know, for instance, just how many M3x8 bolts were necessary between the chassis, legs, and all the other sub-assemblies, since I had never really built multiple of all of them at one time before.

Incremental improvement

To make my life a little easier, I’ve started on a “micro-BOM” management solution. It currently is just a simple C++ application that reads a tree of JSON5 (mostly so I can use the obvious comment style) files on disk. Each JSON5 file describes a single stock item, what sub-components it consists of, and what it takes to acquire it in terms of cash, assembly time, 3d printer time, ordering information, and assembly procedures.

{
  "name" : "quada1_leg_lower",
  "version" : "20200701.0",
  "uuid" : "ad3f6ce2-aa13-42a2-8a4c-2d4b4e799ab0",
  "components" : [
    { "name" : "quada1_leg_foot", "qty" : 1 },  // the squash ball
  ],
  "resources" : [
    { "mk3s" : 7.5, "petg_black" : 71.54, "hours_tech1" : 0.1 },
  ],
  "procure" : {
    "print" : "20200625-lower_leg_and_bracket.3mf",
  },
}

That tool can then follow the hierarchy to count up how many stock units of each type are necessary for any top level item, and how many “resources” are necessary to make that happen.

Thus after entering in ~85 separate “stock units”, I now know that the current version of a full quad A1 requires approximately 300 hours of MK3s printer time between all of its assemblies and sub-assemblies, 132 heat set inserts, and 310 fasteners of various types (assuming the qdd100s are pre-assembled)!

Next steps

Given that I have relatively deep sub-assembly trees, and that I expect to be keeping some stock of all of them, I want to make this tool inventory-aware. That way it knows I already have N leg sub-assemblies in stock or Y qdd100s already built, and thus can tell me how many more bolts and such are necessary to build a full robot.

I’d also like to be able to export the results from this to replace the human-readable bom.txt entries sprinkled throughout git. That will make them both more accurate, and easier to maintain.