A six-legged arthropod of the class Insecta (formerly Hexapoda); an insect.adj.
Saturday, March 25th, 2006:
My foot sensor need some more work. There was some discussion of it over at the LynxMotion Forums. Matt of micromagic systems seems to have a good solution. Next time I'm near a hardware store, I'll see what I can find to mimic his setup.
I've been kicking around the idea of how to get it to walk with all these controllers active. The limitations of the physics sim in Archy have left me without much of a path to follow. So I've started poking around trying to find new perceptions that would get Hexapus walking. First attempt so far has been a Step Height perception that looks at the relative depth between two leg groups (heading towards a tripod gait first). Using linkages similar to the height controller I can quite readily get the bot to step up and down, alternating as desired. The problem is that this perception when maintained around zero greatly inhibits the ability of the landing reflexes to find the ground. Forcing the difference in average depths of the two groups to 0 severly limits the field of tolerated ground variations.
One solution that it seems will solve this is to step outside of the PCT controller model and just move a leg group to where it needs to be, disconnecting it from the controllers. If feel as though this might be losing the spirit of the PCT solution. One thing I've been considering is a non-linear measurement of the error on the Step Height controller. Interpreting the error exponentially would allow me to create a range of error that is in effect tolerated by that controller before it kicks in. This may allow the landers to find the ground even at the expense of a tolerated error in step height, while still allowing a large reference change raise the next leg group when required.
Another possibility is that it simply doesn't matter. At some point the relative influence of different behavior generating controllers needs to be worked out. The StepHeight controller works out great when walking but causes problems when standing. The StrideLength controller that follows will have the same difficulties. Seems perfectly reasonably that an organism has some goals that are deactivated at times or only partially activated. Now the trick is just how to pull that off?
One way might be that the higher level controller that feeds the StepHeight reference also weights it's output. It will need to do this with the landers anyways because it makes no sense to obey the landers when a foot is intentionally in the air. In this manner it could decide to inhibit the output of the StepHeight controller when the landers have a large error. Perhaps this can be done as a simple negotiation between the two controllers. A large output on one inhibits the other?
Wednesday March 22nd, 2006:
Software overhaul! When it comes to writing software professionally, I do a resonably good job of keeping things properly factored and going back to clean code written during testing. Having been as excited about each development with the bot has made me throw all my good practices out the window. So a complete rewrite was long overdue. I've moved all the code to framework 2.0 while I was at it.
I've been working on creating a physical implementation of Richard Kennaway's "Archy". Hexapus (my bot is trying on that name) has some key differences from Archy. Most obviously is Hexapus's radial configuration as opposed the Archy's inline. This considerably alters the required linkage matrix to allow the controllers to properly affect their perceptions. I have maintained the weight coarsness (+1 and -1 rather than real) of linkages that Kennaway used.
The inaccruacies in the ratios are largely corrected by opposing controllers pulling back. This is limited in my setup because of the next major difference between the two models. Kennaway modelled the legs as having inline springs. My current setup would not allow this without overhauling the structural setup. Where I do get "some" compliance is because I'm basing the posture perceptions off of the potentiometer readings rather than the servos commanded positions. This is not as much compliance as I would like and am anxious to get 18 OpenServos built so that I can build a firmware for them where the internal PID is actually regulating angular velocity rather than position and will inherently allow for some slippage along with much more acurrate pot readings than I currently have.
In addition to Kennaway's 6 top level controllers, I have a 7th that controls the radius of the feet. This one is key in that it keeps the coarse linkages of the height controller in check.
Here is a video of the bot up on a paint can running through the first 6 top level controllers in the order (Forwards, Right, Heading, Height, Pitch, Roll). It's on the can because the video was shot prior to tuning all the PID gains such that it wouldn't oscillate wildly and shake itself apart when on the ground and loaded differently. Since then, the linkages of the Right controller have been tweaked a bit to make it perform a bit better and be in less conflict with the Forward controller.
Here and Here are two more videos (this time on the ground) with 6 additional top level controllers. They simply drive a foot downwards (same linkages as the height controller, but one per leg) in response to the FSRs sensing that the foot is in the air. These ones are not PID controlled, rather simple thresholds on the FSR readings. It may appear as though the deck of the bot is failing to stay parallel to the ground, when in fact it's controlling it quite well. The problem is another slight difference (though probably a temporary one) between Kennaway's and my implementation. The Height, Pitch, and Roll perceptions are all based off of an approximation of the plane between the feet of the bot that represents the ground. Kennaway's paper suggests his is calculated from a best fit plane of the feet that are on the ground. Since I'm a bit of a math weenie, I took a bit of a shortcut and averaged two planes. This was working great while all the feet were on the ground, but I can't exclude certain feet. So until I clean this up, the ground plane appears to be moving even when only one foot is in the air and moving. The slow speed is because of some very conservative PID gains to avoid oscillations. I expect that after a many hour tuning session, I can speed things up quite a bit.
LeftFore LeftMid LeftRear RightRear RightMid RightFore Height 0-- 0-- 0-- 0-- 0-- 0-- Forward +0- +00 +0+ -0+ -00 -0- Right +0+ 00+ -0+ -0- 00- +0- Heading +00 +00 +00 +00 +00 +00 Pitch 0-- 000 0++ 0++ 000 0-- Roll 0++ 0++ 0++ 0-- 0-- 0-- Radius 00- 00- 00- 00- 00- 00- Landing 0-- 0-- 0-- 0-- 0-- 0--
Tuesday February 28th, 2006:
Not too many updates, but not because I haven't been working. I've been reading everything I can get my hands on written by William T. Powers about PCT. I intend to take a stab at getting a PCT hierarchy running this guy. To that end I've added a FSR on each foot to determine ground contact. Yea, I was making progress with the NN detection, but I think I'm going to have enough of a challenge getting PCT running without flakey ground detection.
New foot: The leads of the FSR fit in the standard connectors I've been using, but not snugly enough. Soldered onto those pins are a set of 2 PCB pin headers.
Sensor Board Mounted
Schematic and code.
Mess-o-wires that has been worsened by the extra sensors. (really gotta do something about this)
Wednesday January 25th, 2006:
I've been busy... Got a Kalman filter up and running.
Working with a US First team. GO TEAM 1377!
Got 3 OpenServos assembled into a Hex Leg.
Wednesday January 11th, 2006:
Here's my first OpenServo.
Wednesday January 4th, 2006:
Above you see the interface for training a couple of neural nets to predict unloaded current draw. This is all wonderfully important because it has enabled the generation of this video which demonstrates the nets "feeling" the ground and stopping the leg at various speeds and heights [drive counts :)]
There's currently 1 net per servo. 3 inputs 6 hidden 1 output. Inputs are a moving average of current sense data, the distance traveled in the last 100ms, and the error in position relative to requested position. All normalized to 1. I run it a couple times at varying speeds with no obstructions and train the net on that data so that it can predict the unloaded current draw. Then run it with an obstruction and watch for deviations between actual and predicted current draw. Once it crosses a threshold, stop the leg.
The nets currently are trained with backpropagation. I'm going to start exploring connecting the nets together to see if I can drag any cooperation between servos out for better sensitivity.
In other news, I've gotten fairly involved with Mike Thompson's OpenServo project.
Wednesday December 28th, 2005:
Corrected the models dimensions, added a few rendered elements, finished the auto-calibration. Did a fair amount of work on reworking the geometry engine. Needs a great deal more.
Tuesday December 27th, 2005:
With the aid of Claudiu Chiculita, I've managed to write a C# client to his Tiny Bootloader. This was required because I can't run his client over the radio. Working great, updates are much easier than using those unreasonably short ICSP cables.
Been working on pot feedback interpretation. Before today it really wasn't very good, but I've nailed it.
Here is the plot of the error in interpretation across sweep of a servo. The error of 1 to 3 or so is around 1%. It's almost linear. There is still a slight curve in there, but it's close enough that I'm not going to mess with it anymore.
My target positions are of an arbitrary unit that corresponds linearly to the pulse length. They range from ~800 to ~3800 for 180 degrees. The feedback values in are read by a 10bit ADC in a PIC referenced from GND to ~2.1V. So my feedback values are in the ranges of ~350 to ~700.
EstimatedPosition = (RawPositionReading * PotRatio - PotOffset) - PhysicalOffset
I fear I'm going to have to calibrate it for each and every servo, but this one has values of Offset = 68 and Ratio = 4.232
Which brings me to the next bit I've been working on, automatic calibration based upon finding physical limits of the joints. Joints 2 and 3 of each leg can run into some structure of the bot within the range of the servo. By stretching out and watching the current sense to detect that collision, I hope to be able to automatically generate all the offsets (both electrical and physical) required for joints 2 and 3. Joint 1 just so happens to be very easy to do by eye.
Tuesday December 20th, 2005:
So I wrote a bunch of code to handle timeouts on the I2C bus and tested the hell out of it. Seems I tested every single scenario except for anything remotely like a real I2C timeout in the wild. So I've been fixing all the places I missed it in 1 by 1. I'm about 6 steps closer to I2C stability! :)
If you're not as color blind as I am and the jpg compression didn't stamp it out, you might see that the joints are rendered in varying shades of red representing how hard that joint is working. I've gotten the pot readings while the servo is on rock solid after lots of watching with the scope. I realized that most of my problem was the GND line bouncing around and the PICs a/d not catching it because of each of the controllers local caps. Ideally I'd use a VREF- line too that I could tie to the actual ground rail beyond the local caps, but I'm out of analog pins. So I delayed the position capture until after (12ms) the GND rail has quited from the servos jolting on and then average my high and low readings.
I've got a great deal of calibration left to to in terms of matching up the pot's readings to my requested pulses, taking into account joint assembly inaccuracies and variations between the servos pots.
Saturday December 17th, 2005:
Software! Building a Direct3D engine around the bot. Here is a snap from a simulation where I'm running a alternating tripod gait. The idea is that I should be able to plot sensor data so that I can see what it sees.
Thursday December 15th, 2005:
Overhaul! The bot has undergone 6 hip replacements! It's not even that old. Got sick and tired of the gears on the HS-475s breaking and they were always on the same joints in the legs (different legs). Those servos have been upgraded to HS-645MGs which have an entirely different sound that's kinda cool.
Lost a LiPo to a teeny-tiny little fan that I added to cool down the radio whose power consumption was about 30 times higher than it's case stated! Power board has been rebuilt from scratch, this time with a correct reading of the spec sheets for the ISRs :). Haven't rebuilt in the ability to shut down individual ISRs though there is room on the board if I find a good justification for it.
I hate connectors. I replaced some that I knew were a bit flakey and it fixed all manner of problems I had no idea were connector related. That along with some timing tweaks, I've reached that rare (in this project at least) condition of having a stable hardware platform. I've got all manner of sensors that I'm itching to add onboard but afraid to miss an oppurtunity to actually code something on a working robot :)
Sunday December 4th, 2005:
Static in check! Humidifiers, static strap, static mat, and a workstation ion blower. Overkill maybe, but there's too much work in this thing to have it disappear in a snap. Fixed a couple of loose connections, replaced a relay that was cutting out due to heavier radio draw. There's some startup race condition that's a bit irritating, most of the time everything is roses, others, nothing comes across the I2C bus. Time to recode some of the lesser used functions with the new guts... battery life and ISR enables. I went to a meeting of the Denver Area Robotics Club and met a bunch of local enthusiasts. Going to try to have this guy on his feet and out of the house (ad-hoc networks) be next Wed for a meeting of these folks.
Thursday November 17th, 2005:
Not quite dead yet!
Landed in my new home in Denver. Scared to death of the robot killing static. Will get back to work soon.
Saturday July 23rd, 2005:
WooHoo! Success on the rebuild! The new radio is up and running along with the new controllers. The shore side hardware has been eliminated entirely and replaced simply with a wireless access point. The servo's potentiometer data, current sense data, and new posture data is all being sent back and forth in under 4ms. I had quite a scare that my initial testing of the radio had been faulty when I got everything assembled and was seeing roundtrip times of over 30ms but found that I had inadvertantly been using the trailing chars feature of the radio that is supposed to only be enabled with packing. This is not true! Even with the packing feature disabled, the radio is looking for whatever chars are specified and upon seeing them sending the data immediately. Seems the default wait and pack interval with packing turned off is something on the order of 30ms.
If only I had more a shred of confidence in my circuit designs and hole diameters, I'd go for having boards printed. I've spent the past 2 days tracking down near shorts and loose connections on my protoboards (read: permanant) that make up the controllers. Each one has somewhere around 150 solder points and 80 odd tracks done with wires. Not to mention the back pains and burns involved with building those damn things! Enough whining. They work now.
Thursday July 14th, 2005:
Radio has arrived and I've been testing it out. This thing is great. It's far outpacing what I've been able to throw at it with a 230400 baud serial connection. Latency times are usually less than 1ms. There is the choice of using tcp or lossy udp. I've seen packet transit times of up to about 100ms when there is some noise which may lead me to tend towards the udp, not sure yet though. Haven't tested the range yet. WiBotics sent a rather beefy antenna and I could probably upgrade the antenna on my access point if it's a problem. Only complaint is heat. This thing generates a lot of it. Both the radio's metal case and the WiBotic's voltage regulator. They suggested that the heat would be a problem running much over 5V, but I'm running it at 5V and it's running very hot. I need to check the tolerances of the lexan and maybe add a fan.
Though I haven't yet tried to make any modifications, the SDK (they call it a CPK) has arrived for the radio as well. Looking through the code, the samples seem straightforward enough. Lots of room for doing other stuff with the 11 IO pins. CCS's PIC compiler oddly lets me set the baud for an 18F252 @ 40Mhz to 500000 but not 460800? So unless I figure that out, I'm stuck at 230400 pushing me towards using those GPIO pins to do a fast parallel interface to the PIC. But as it stands right now its already blowing away my throughput and latency requirements and may not bother trying to make it any faster.
Wednesday July 6th, 2005:
Yet Another Radio After emailing back and forth with Nick DeNicholas who is also building a Lynx Hex 3R and hearing his plans for the radio, I changed course yet again. www.wibotics.com/wpbkit.html has a nice breakout board for the Lantronix WiPort. 802.11b to two serial ports that actually look like my throughput and latency requirements will be met by. They've done a lot in the way of allowing changes to the algorithm that decides when to create a packet from the serial buffer. Furthermore, if the schemes they provide by default don't quite fit, they apparently allow you to bulid custom firmwares for the thing after an NDA. Aside from the power consumption (peak 430mA, avg 350mA), this thing looks perfect so far.
Saturday May 28th, 2005:
Decided to change the format here to more of a blog style which might reflect the ongoing nature of this project a bit more accurately.
It's got a sibling! Picked up on eBay another Hex IIIR from lynx. When I get around to it, I intend to make them duplicates and play around with cooperative navigation. I got this along with a BalBot from www.balbots.com . I've passed the balbot on to a nephew who's interested in robotics. I have to say that their choice of using IR rangers to detect angle to the floor was a terrible one. Furthermore, since the balance board is a closed loop system it doesn't seem that it could be upgraded to a gyro without replacing it entirely.
Potentiometer's a-hoy! Fed up with lack of direction on my current sense feedback, I've taken drastic steps. I've rebuilt the 3 controllers from scratch (yet again) to handle a reading off the servos internal potentiometer so that I can read it's position directly. This new data has also required that the radio be sped up. I tried bluetooth, but the latency was terrible. Considered adding a second channel of the 2.4g radios but instead I optimized the hell out of the protocol and got all the new data as well as the old able to fly back and forth at least twice in my 20ms frames. Needs just a bit more work then reassembly! I'm getting married so it might continue to live in the three different boxes under my desk for a while.
stand, walk around a bit, sit. (12MB)
current sense feedback (9MB): Here is a video showing the displaying the resistance enountered while trying to maintain a rigid position.
demonstrating position feedback data (8MB): In this video, I'm grabbing ahold of one leg whose servos are turned off and manipulating it. The bot is reading the internal potentiometers of this leg and mimicing the position in another leg which moves in sync. The computer positioned leg is a bit jumpy because the interpretation of the potentiometer data is still rather primitive. This should improve.
posture manipulation (9MB): Similar to the mimicry video above, but adjusting posture while standing.
Ground Sensing (10MB): The robot is "feeling" for the ground.
Innards: New innards with the Lantronix radio. Power board on the right. (The ICSP connector on the left has been moved to a less obstructed spot)
Top: New controllers w/o servos connected. I've replaced most those connectors to ones that are less flakey and ripped those caps off the controllers.
I'd like to hear from you!
email: andy at vizlog
yahoo messenger: andrewlippitt