Project FISIKA
The Name:
FISIKA, a Fully-Integrated Speedy Inverse-Kinematics Arm developed from scratch to teach myself the ins and outs of, you guessed it, inverse kinematics. The name is derived from the Indonesian word, "fisikas", which translates into English as "physics". Considering my experience with physics engines in the past, and the nature of inverse kinematics systems, it was a logical name, partially inspired by my Indonesian friend who gave me a push in this direction.
—
The Hardware:
For now I'll be using entirely LEGO parts, primarily the LEGO MindStorms NXT robotics kit. I may add in a WiiMote's IR tracking camera with the IR-pass filter removed, but for now I'm not including that into my designs for simplicity's sake. The NXT kit is composed primarily of a "brick" that houses the dual processors, memory, 4 buttons, a monochrome 100x64 LCD, the power supply (6 AAs), and all the necessary ports to attach the motors and sensors. Unfortunately I'm using Ni-MH rechargeables, so instead of a full 9V I can only draw up to 7.2V. The processors are a 32-bit Atmel AT91SAM7S256 (256 KB flash memory, 64 KB RAM) and an 8-bit Atmel ATmega48 @ 4 MHz (4 KB flash memory, 512 Bytes RAM).
There are 4 dedicated "Sensor Ports" on one end of the brick, and 3 dedicated ports for the motors. Each port is essentially the same, combining analog input/output, I2C, and RS-485 into a 6-pin connection. The motors are continuous-rotation servos, with a top speed at full power of ~170 RPM at 9V, and ~135 RPM at 7.2V. The internal rotary encoders are accessible with +/-1° of accuracy, providing realtime feedback on speed and direction, as well as current position. While there are a wide variety of sensors available to use with this modular kit, I'm focusing on just two: a "Light Sensor" and "Touch Sensor". The light sensor is, as would be expected, an ambient LED-based photosensor, and also includes a red LED, which can be used as both an indicator light or just to provide extra light to the sensor, primarily for reading reflected light levels. The touch sensor is effectively a pressure-sensitive button, with an ~8mm travel distance.
—
The Software:
I use third-party software to program the main processors (bundled together with the batteries in a single unit known as the 'intelligent brick' or just 'brick'). Primarily I work in an IDE known as BricxCC, which allows the use of a C-based language (known as "NXC"/"Not eXactly C") in place of the standard graphical, block-based programing language that comes with the LEGO MindStorms set. Using this linear, text-based programming language is more comfortable to work with and allows more complex operations and deeper access to hardware; the most notable improvement is a vast increase in performance due to stripped-down code and heavy optimization.
—
The Idea:
I've always been an outside-the-box thinker, particularly when it comes to limited resources on electronics platforms. For example, by making use of the ghosting effect on slow, cheap monochrome pixel displays, I was able to achieve 6-shade greyscale on a typically black-and-white screen; I've utilized the light source in the LED-based photosensor as an output/indicator for different programs, and even gone so far as to PWM the LED via realtime code, similar to my previously-mentioned work on the display. I've always enjoyed pushing boundaries and seeing what things can be done that nobody else would do, so when I got the idea to point the light sensor at the ground and measure the amount of light being reflected back, I realized I'd created a primitive short-range distance sensor. Adding this to a segway-style robot was a logical next-step, building a balancing system based solely on a photosensor. Many others have done this as well, it turns out, so I moved on, building more advanced balancing systems, including an autonomous self-balancing tightrope-traversing unicycle. I even wrote several physics engines from scratch that ran locally, writing a small pinball game to show off some of what I'd worked on. Eventually I ran out of ways to challenge myself and push boundaries, but recently a friend of mine from Indonesia was looking over older projects of mine, and noticed that despite learning PID and realtime physics engines, I'd never done anything with inverse kinematics, so he suggested I focus on that next. I'd always avoided it, as it seemed rather advanced and daunting; but after a fair bit of discussions and sketches I decided to try my hand at it.
As usual, my ambitions and goals for this project are way over-the-top, and I doubt I'll get to complete some of them, but it's better to be creative and ambitious than unoriginal and boring, yeah? Anyways, the main purpose of this was to develop a platform upon which to teach myself the ins and outs of inverse kinematics, much like I've done with balancing systems/etc. I've built two and a half arm-like structures (one I never finished), and since only one of them was entirely my design, the other being a slight improvement upon someone else's, I started looking up better arm designs. I came across a problem; most systems operated a single joint at a time, with very little or no system for measuring and correcting movement, resulting in very slow, choppy movement with little to no accuracy. Soon I added a second main point in my sketches: not only was I working on teaching myself inverse kinematics, but I was also creating a more thoughtfully-designed arm, instead of something just thrown together; hardware designed with software in mind, and vice-versa, rather than the code being more of an afterthought.
The more I looked through designs the more I noticed how fragile and wobbly many arms were, with long, heavy linkages and slipping drive trains, and nary a control loop to watch for and correct errors. This soon became a third point for me to focus on: building something speedy, sturdy, and yet still accurate. With that in mind, I began to take measurements, and looked up old notes for centers of gravity, balance, leverage, torque, etc etc, and ended up putting a lot more engineering work into the arm's structure than I even intended to. I ended up borrowing part of one turntable design from the arm schematic I'd previously improved upon, and re-tooled that to fit with the structure type I was going for, even going so far as to completely invert some aspects of the design. In the end, though, everything from cabling to inertia was thought out in advance and carefully planned for in construction, resulting in a design that purposely makes use of invariably weighty parts (the motors and brick, for example) and then leverages that weight (hah, a pun!) to drive the system and reduce the need for actual torque from the motors.
A thought experiment: if you have a child sitting on one end of a see-saw, and you need to lift them up with a motor attached to the middle, it will be much, much easier to do so if an equal-weighted (or slightly heavier) child is on the other end of the seesaw. I tried to engineer a design that allowed for shifting weights, but due to the modular, simplified nature of LEGO parts, this was too much work, and I abandoned the idea. If I had access to a 3D printer/metal parts that I could mill/lathe from scratch, I might re-visit the design, but since the whole point is just to build a platform to teach myself inverse kinematics, I think that would just be over engineering it at that point. Ah well.
—
The Other Ideas:
As someone who's designed more mobile robots than stationary ones, I've always worked hard at creating fully autonomous systems that can not only navigate their environment, but learn about it and react to it accordingly. As such, I wanted to include the pressure sensor in the tip of the arm, to truly 'get a feel' for its surroundings, but after some thought on the design I decided to move it back, further up the arm, with a mechanical linkage that placed the photodetector at the tip instead. This will allow me to not only detect touch/collision/pressure, but also read ambient and reflected light levels, project a light, and to a degree determine color. (If a few objects of known color are present, such as a set of red, green, blue, and yellow cubes, the individual colors could be easily determined because they are in a known set.) Something I've seen growing in popularity is taking a long-exposure photograph of an arm like this, with a light source attached to the end, to create 3D light sculptures. While this is definitely one of my more ambitious and potentially problematic ideas, I definitely look forward to tackling it.
In summary, while my main focus was just to engineer a structurally-sound arm that would act as a platform to teach myself inverse kinematics, I've gradually added other ideas into the mix, and if everything is successful it will end up as a fully autonomous, explorative unit that behaves with a unique personality. With multiple forms of sensory input (servo rotary encoders for realtime position data and a pressure-sensing nub combined with reflected+ambient light sensing at the tip), this will easily be one of the most advanced projects I've worked on. And who knows, if I can figure out a way to get my WiiMote connected to the mix, I'll have a (up to) 4-point color/IR tracking camera to throw into the mix as well, but I'm not so sure I'll get that working within a reasonable time frame.
Massive shout-out to everyone on the MindBoards forum (which is a bit dead right now, due to switching servers), in particular folks like Mightor and mattallen37, for helping me work out critical bugs, condense massive chunks of code into simple structures, and even helping out with low-level I2C processing libraries. I couldn't have gotten this far without you guys!
—
Expected Challenges:
The most painfully obvious challenge I have is that I'm dealing with pre-designed modular hardware, rather than building something from scratch. As much as I'd love to be able to grab some acrylic and a laser cutter and sketch out some designs, everything has to fall within certain parameters designated by LEGO. Dimensions, weight, balancing, speed, gear ratios, alignment, even attachment points are all pre-engineered by them. While that does take a very small portion of the work out of things, I'm then forced to work around that, so it's more of a curse than a blessing.
Another issue I have seen a-plenty, and have worked hard to try and prevent in this design, is gear slippage. Too many times I've seen an excellent design, in theory, turn out to be weak and sometimes unusable due to a fragile gear train. Things pop out of place, gears hop or grind, and sometimes axles even bend or shatter from unbalanced torque. Oddly enough, I'm very qualified to tackle this problem. In high school I was lucky enough to become involved in a youth RoboCup league. One of our team's challenges was to create an autonomous vehicle capable of navigating through an obstacle course. One obstacle was a narrow, extreme incline, and our unit was suffering from traction loss on one side due to a loose pair of gears that were extremely worn out. The axle would occasionally skip, especially under heavy load, such as when it was climbing the ramp. I was tasked with fixing this issue, and decided to focus on the servos' tachometers to keep better track of our wheel movement—or in this case, the lack thereof. When I graphed rotational velocity over time, assuming the servo had a constant strain in one direction, the resulting graph would be a fairly smooth (if slightly offset) line. If a gear slipped a single tooth, the line would spike slightly as the gear mechanisms jumped for a brief period then caught again and resumed normal operation, resulting in a very unique and distinguishable 'heartbeat' pulse on the graph. If the gears continued slipping, the line would be replaced by a constant rapid series of these heartbeat pulses. As a result, by keeping track of the tacho readings, I could very easily identify and estimate the type and amplitude of a problem, and then quickly adjust to fix it. I hobbled together some simple algorithms to autonomously interpret the data on the fly, and we were able to make it to the final rounds (but unfortunately we did not place first). That sort of experience has greatly benefitted me for various aspects of robotics and programming, and I find it somewhat amusing that I've circled back around to the same old code concepts for the same applications, albeit an arm instead of a vehicle.
Since the inverse kinematic system I'm dealing with is, essentially, two arms of a triangle on a rotating base, with the distance between the tip and the base forming the hypotenuse, it is important not only to understand and monitor angles, but also arm lengths. Obviously, the two portions of the arm are fixed lengths, with simple motorized hinges adusting the shape and size of the triangle. If two angles of a triangle are known, in this case two internal angles, then the third can be easily and quickly computed, as the sum of all interior angles of a triangle is 180°. Similarly, since two sides of the triangle are known, then the theoretical hypoteneuse can be calculated as well. With this information, then, it is possible to calculate the difference between one such 'triangle', i.e. the current position of the arm, and another triangle, i.e. the desired position or 'goal', and then calculate the simplest way to progress from one position to the other. This is, in a nutshell, inverse kinematics (and according to wikipedia, using this to accomplish tasks by moving from place to place is known as 'motion planning'.)
—
Other thoughts:
F.I.S.I.K.A. stands for a fully-integrated sturdy inverse kinematics arm, and while I've alluded to it, I haven't outright discussed the 'fully-integrated' aspect of this arm yet. Because the NXT platform has internal bluetooth, it is possible to take advantage of two-way communications, and have a beefy computer run all the processing while just returning commands and instructions to the arm. I previously explored this when I was dealing with an OpenGL-based 3D engine in conjunction with my from-scratch physics engine, as I was running into severe issues with the lack of processing power being mostly eaten up by the 3D rendering math. (Eventually I scrapped this, because my bluetooth dongle was extremely finicky and unreliable, and ended up writing a localized pseudo 3D engine from scratch as well.)
Despite the ability to do this sort of off-loaded processing, I've decided to keep things entirely on the brick this time. Everything will be fully integrated into the platform: all the input will be localized, the software responsible for structuring and modeling the rigid-body physics, calculating optimal angles and running anti-collision systems (don't want the robot crashing into itself!), etc. All will be running on-brick.
The AI is something I'm just a little apprehensive about; the most I've developed was a 2D room mapper/maze solver combo that could scan a room with an ultrasonic sensor, moving around and keeping track of its location in 2D space while continuing to map the room until it was fully mapped, then solve for the most direct and safest routes from point to point. With the motion tracking that will be involved with Fisika, however, everything will be in 3D and much more complex. Considering the pressure sensor integrated into the tip of the arm, and factoring in the amount of torque generated by the motors in realtime combined with the internal motion tracking, I'll be able to also measure things such as how much force is necessary to move or bend objects the tip collides with. I'm not sure if that actually has any useful applications, but then again, that's rarely what I'm ever focusing on.
I was slightly indecisive on what I'd use the S to represent, and it was a toss-up between Sturdy and Speedy. Most LEGO arms I see are either speedy or sturdy, and I've actually watched one tear itself apart as it attempted to move things back and forth faster than a competitor's arm had done. Again, one of the limitations of dealing with LEGO parts is the modularity; if the parts weren't so expensive, I'd often find myself cutting and gluing them to meet my needs. (In fact I have done this once in the past, I built a few universal joints and then discovered LEGO sold them pre-made.) I've put a lot of effort into seriously beefing up the physical supports necessary for keeping the entire system balanced and nimble. By including the heavy weight and mass of the brick, and also carefully balancing the motors as counterweights, I am fairly certain I'll be able to develop a fluid control system that integrates the feedback sensors to work in harmony and keep the powerful structure from destroying itself. Much work was done weighing motor units and even the simple structures themselves, and other important factors such as acceleration due to rotational momentum have been factored into both the physical design of the structure and even the code. (I once built a mounted inverted pendulum that balanced itself upright, but rather than driving back and forth in a linear manner to keep its center of gravity centered, it actually used a secondary pendulum attached to the top and pointed upwards as well to act as a counter-rotational force on the entire body. By controlling its movements, I was able to combine angular momentum and shifting centers of gravity to keep the unit upright.)
Since I'm well aware there will be much trigonometry going into Fisika's code, I decided to simply something by making both arms' lengths the same. I've dealt with a lot of triangulation in the past and I'm well aware of how quickly math can get overly complicated, so by reducing the variables as much as possible in hardware, I'll reduce the complexity in software, resulting in cleaner, faster code. I'm also working with geared joints (namely, from base to tip: 1:7, 1:3, 1:1), putting more torque at in the heavier sections dealign with more weight, and also increasing accuracy of the rotation sensors.
One big problem I always see for robotic arms is how to transmit power and data to all the joints. There are multiple solutions to this issue; one solution is to have wireless modules with each servo system, requiring individualized power supply units and a central processing station. Another solution is to daisy-chain all your servos with individualized, on-board processing units. Unfortunately, neither solution is possible for me, since I'm dealing with a pre-designed modular robotics system. As a result, I have put extra care and thought into the location and orientation of each part that will require an attached cable, so as to reduce or eliminate the potential catching and pulling on cables.
I've already mentioned the potential modification of including a WiiMote for object/point tracking, and in a similar but somewhat inverse idea, I've considered adding a laser pointer into the system. A 3DOF-articulated laser would certainly be interesting, and while it would not be nearly as fast as galvanometer-controlled laser projection systems, it could still be fun to play with.
Lastly, I have twice tackled the idea of having an 'alive'/interactive arm, by emulating the way humans and animals react to being approached, touched, and pushed. Due to the lack of a stable, fluid movement platform, I never went very far on the hardware side of things, but I put lots of work into the software side of things, and ended up with a few iterations of an anthropomorphized arm. Hopefully I'll be able to include some aspects of that into Fisika, perhaps giving it the option of a free-roaming 'exploratory' mode.
—
References/Resources:
I've decided, for the sake of keeping things clean and organized, to put all the links at the bottom. I've referenced several things throughout this document, such as the BricxCC IDE, and for those curious or looking to learn more I have links below. Also included in a section of wikipedia links, all articles that are in some way relevant to what I'm working on. For anyone who's worked on hexapods/other inverse kinematic platforms, and has experience in the area, any other resources you could recommend would be immensely useful! Thank you for your time and I hope you enjoyed reading this unfortunately extensive document.
http://bricxcc.sourceforge.net
https://hackaday.io/project/249
http://mindboards.trella.biz/index.php
http://www.nxtprograms.com/robot_arm
http://www.philohome.com/motors/motorcomp.htm
https://en.wikipedia.org/wiki/OMPL
https://en.wikipedia.org/wiki/Euler_anglehttps://en.wikipedia.org/wiki/Kinematic_chain
https://en.wikipedia.org/wiki/Motion_planning
https://en.wikipedia.org/wiki/Robot_kinematics
https://en.wikipedia.org/wiki/Inverse_kinematics
https://en.wikipedia.org/wiki/Lego_Mindstorms_NXT