Sunday, November 26, 2023

Acuitas Diary #66 (November 2023)

This month has been all about the Text Parser. I'm pushing to get this latest revision done, and that has crowded out other work for the moment. The big thing I cracked this month - the thing this Parser revision was mostly aiming at - was the ability to nest branches and dependent clauses inside each other.

Photo by Ed Vaile ("Edric") from Palmpedia

What I call "branching" takes place when there is a coordinating conjunction in the sentence (like "and" or "but"). Branching can produce simple compounds, as in "Cats and dogs are animals." But sentences can also divide at any point and continue along two separate paths, as in "I fed the dog his dinner and gave Sarah her book." Or start out divided at the beginning and merge, as in "Are you or are you not a man?" Adding conjunction processing and branch management was one of my major accomplishments from last year. But this first version only really supported conjunctions in the uppermost layer of the sentence - not inside or between dependent clauses. Any interaction between branching and that other vital feature - nesting - had the potential to confuse the parser horribly. Not to mention that the code was a huge mess.

I'm a big believer in the design process that goes "Make a sloppy version that works; refine it later." Later became now and it was time to refine. I'm happy to report that I think I got clearer and better-organized code out of this month's work, in addition to enabling some sentences I couldn't manage before. Such as:

What you need and what you want are different things.
If you want or need the box, I can get it.
I don't know how you and Jack plan to find food.

There's still a ton of polishing to do and other small features to reintroduce, but this was the big hurdle.

Until the next cycle,
Jenny

Monday, November 20, 2023

Atronach's Eye 2023

I last made a blog about this project early last year, and now I'm back to it, being nearly done with the next iteration! It was a long, meandering process to get here, so I'll try to describe that (including all the things that didn't work) for everyone's edification.

The 3d-printed mechanical eyeball that is the topic of this post, with its top panels off so the motors and motor drivers are showing.

At the end of my last round of development, I identified several problems that still needed to be solved. I chose to concentrate on the electro-mechanical issues, specifically:

*Eyeball rolling motion not as smooth as I would like - too much friction, eyeball catches on socket
*Greater range of motion desired
*Slack in tendons when ball is near center of motion
*Limit sensing needed to provide feedback on eyeball angle and prevent motor stall

The friction issue was the only one on this list that turned out easy, because I had most of the solution already. It happens partly because 3d-printed objects just aren't smooth (no matter what, they'll have some layer lines) and partly because there's a seam in the middle of the eyeball - the two halves are printed separately and fit together so that I can put the camera inside. No amount of sanding and rounding off edges seemed to be good enough, but what did help was tying some extra pieces of nylon fishing line across the seam, from the tendon attachment holes to the back of the eye. So in the next design iteration, I added more holes - all around the "pupil" and the opening in the back for the "optic nerve" (camera cord). I used one of my thicker fishing lines and ran lengths of it, like lines of longitude on a globe, between twelve pairs of these holes. This proved a consistent solution, even when I further enclosed the eyeball by adding the shroud (more on that later). The nylon lines are very smooth and slippery and put a low-friction surface between the ball and the socket.


To address "range of motion" and "slack in tendons," I decided to move the tendon attachment points from the front of the eyeball to the back. The original design was drawn from biological inspiration: human eye muscles attach to the sides of the eyeball toward its front, well forward of the ball's "equator." But human eye muscles also automatically manage slack by getting shorter as they pull! My motor and differential tendon pair setup can't do that.

An illustration (using the 3d model of eyeball version 3) of how the distance from a tendon guide hole in the cradle, to a tendon attachment point next to the iris, differs from a straight line due to the curvature of the eyeball itself.

I always installed my tendons by putting the eye at a limit, tying the "fully extended" tendon on, then spinning the motor shaft until that tendon was "fully contracted" and tying on the other. And then, when I returned the eye to its center position, there would be slack in both tendons. The explanation is that the tendons when fully extended were following the curvature of the eyeball (which is longer than a straight line), but when the eye was at center, they were angled straight away from the eyeball toward their guide holes in the socket.

I considered various tricks to solve this. Moving the attachment points closer to the eyeball's equator would reduce that curvature effect, but also reduce range of motion. Moving the guide holes farther away would change the angle of the lines and keep them away from the eyeball even at its limit, but then I wouldn't be able to put the top panels on the eyeball case, because the tendons would no be able to run down through that central hole. It finally seemed that the best solution was to put some nubs or spars on the back of the ball as tie-on points for the tendons, and run the tendons *up* through the guide holes in the cradle, then back down to the motor shafts.

Two iterations of eyeball version 3, showing the spars on the back of the eyeball and the new limit switch contacts.

So, I tried it. Those new spars on the back also seemed like a good place to put one half of a limit switch contact. So I wrapped them in copper wire and connected them to the common ground, and put an aluminum foil signal contact on the underside of each quadrant of the cradle. I backed the foil with foam, in hopes that this would allow the spars to sink into the foil a bit and ensure a positive contact. Since the foil proved annoyingly fragile, I used pieces of (aluminum) soda can with the coating sanded off for a second attempt.

Attaching one of the new tendons

Well. Putting the tendons on the back of the eyeball did solve the tendon slack problem without hurting range of motion. BUT - the tension of the tendons against the front of the ball had been the only thing keeping the ball down in the cradle. And the eye isn't designed to be displayed lying on its back, it's supposed to hang on the wall. Whenever I raised it vertically like that, the ball wanted to fall forward out of the cradle. And the limit switches still didn't work well at all. The contact formed by touching wire to foil simply wasn't reliable, no matter how much I wanted it to be.

This was the point when I started doing smaller-scale prototypes, because I just needed to try a bunch of things and taking apart or redesigning the case for each one didn't seem smart. So I designed a smaller version of the eyeball and a little flat base with two motor mounts, all of which would use fewer materials to print - and I made it fairly modular, so that I could mix and match three different limit detection attempts and three different socket designs.

The prototype fully assembled with the mechanical limit switches and three-lobed shroud.

The three limit detection methods were 1) standard mechanical clicky switches installed in the cradle, with paddles attached to the levers, so the eyeball's spars would close a switch no matter where they hit the underside of the cradle, 2) Hall effect sensors on the spars, paired with magnet strips on the underside of the cradle, and 3) rotary encoders fitted on the ends of the motor shafts. I bought the parts to sample all three, and mechanical switches won. When I installed them in the prototype, they pretty much worked reliably on the first try. The encoders were a bust, by comparison. They required a surprising amount of force to turn, and just installing one at the end of a motor shaft caused the motor to struggle at the limits of the eyeball's motion. I'll have to keep them for some project with stronger motors. And the Hall sensors worked, but not as well as I wanted. They responded to small permanent magnets, but did not react to the flat magnetic strips I have; their field strength is apparently too weak. So I would have had to embed a whole bunch of magnets all along the underside of the cradle. Hall sensors are also proximity-based rather than contact-based, which is nice if you can't get a positive contact, but also kind of imprecise.

First version of the limit switches with paddles, assembled for the prototype.

The one tough thing about the limit switches was figuring out how to attach paddles to their levers to get a larger contact area. The levers don't seem designed for this at all; they're about as small as they can be, they don't have enough convenient holes, and they're made of metal. There's also very little clearance between the lever and the switch housing, so if you try to wrap anything around the level, wedge it into a slot, etc. then the switch can't close anymore. My first paddles were made from pieces I cut out of flat plastic lids (coffee-can style). I poked holes in the soft plastic with a needle, and tied the paddles to the switch levers with fine thread. It was janky, but it worked. Eventually I made 3d-printed paddles with built-in holes, and added a sleeve made of thin transparent plastic (the kind used for shell packaging), wired down to the paddle. I can't print something as thin and tight as that sleeve, which is why it's a separate piece. I can slide the switch lever between the sleeve and the paddle, and the sleeve holds it in place without hindering the switch's ability to close.

Final version of limit switches with paddles attached via sheet plastic and wire

To address the problem of the eye falling out of the cradle, I also designed three new sockets. All made use of the original cradle on the bottom/back side of the eyeball. One was a sort of clamshell - I added a second, inverted cradle on the top, with pegs and holes to fit into the bottom cradle, so the eye would be contained between the two. The other sockets both featured shrouds with fixed "eyelids" to wrap a little way around the front side of the eyeball and hold it in the cradle. I made one with a standard pair of eyelids at the top and bottom, as well as a weird one with three lids. I tested this second option specifically for Atronach's sake, since the eye has three-fold symmetry in most respects, and it would be a little weird to give it the ordinary two eyelids. I redesigned the cradle legs to grip the edges of the cradle instead of fitting into holes on its underside, so that the legs wouldn't interfere with the limit switch paddles in any way, and I made prototype versions with four and three legs, also.

I tested both shrouds in the prototype, and they worked out so well that I didn't even try the clamshell. With everything pretty well figured out, I was left to apply all of the design changes to the original model and re-print most of the case. I kept the wall pieces and motor mounts from the original, but all the top and bottom panels had to be redone, since various attachment and connection holes had changed. While I was at it, I made colored inserts for the Hebrew lettering on the top panels, so I don't have to paint them this time (the new version looks a lot cleaner).


So much printing! There's an amazing amount that goes into this one build.






And after all that, it's still going to need software improvements! I hope to report on those next year.

Until the next cycle,
Jenny