Even everybody prefers to share successful works and amazing prototypes, here I’m going to take the other way: Almost all hobby-grade robotic arm makers focus industrial type robotic arms, I intended to make a humanoid hand and arm assembly with the mechanicals and functionalities almost same as on the human body, but on the cheapest way as possible. But due to abilities of materials and components, it became a story of fails, however a story-of-fails is also a story-of-lessons learnt.
At first, I started to watch out and study on movements of my hand, as well as its dimensions, and even while walking around, so I took a significant risk that almost all the people on my neighborhood may think that I have a strong mental disease :)
The first design is completed in 2-3 months, then prototype is made by using cardboard and toothpicks. It was good to see whether mechanical approach is satisfactory and able to achieve the basic requirements.
Then I took a long break for thinking on better opinions.
First design had lots of parts on mechanical side, and it should be optimized. So, I decided to restart from scratch, and chose material at the beginning: Balsa Wood, but that choice would force me to end Project earlier than I think. Anyway, I can say that it worked well.
Autumn 2018 :: Restarted from ScratchAfter deciding material, I restarted mechanical design by using mono-block parts as much as possible. All the Metacarpal / Proximal/ Medial / Distal “bones”, Trapezium and Wrist section are designed, virtually assembled and interacted with each other on computer. During that period, I also noticed that my current design is not able to hold up something. Why?
Because at the initial stage palm of hand was exactly flat, as same as most of the other robotic hands available. So it leads slipping out the object, even the fingers are closed.
However, palm of human hand is not so. If you hold your fingers straight and look from side, you may think that it’s flat. But when you look by facing to fingertips directly (you can also touch on top of your hand), it’s clear that your palm has a concave structure created by Metacarpal bones led by a concave Trapezium. By the way, when you close your fingers, they cover a spherical volume from all sides and together with your palm.
So I reflected that to my design: Trapezium is reshaped to have a concave face, consequently Palm became concave due to Metacarpals aligned by Trapezium. Just needed several trials by adjusting angles, and yes, it worked theoretically :)
At that period, I also would like to go beyond mechanical-only and started to think about actuation. But how? I had to use servo motors but even I use the smallest types, I had no place to locate them on Hand section including Wrist. I noticed that, I need 12 servos just for Hand and Wrist section to imitate all of their movements. In the meantime, I decided also how the “muscles” and “tendons” shall be imitated: After trials with few different materials, I found fishing ropes are the best “muscles” due to strength and flexibility, and packaging rubbers as “tendons” (we will also talk about them). During those trials, I also implemented “muscle guides” by using 6mm PVC tubes.
It was clear that arm sections should also be designed.But since Front Arm has twisting and levering movements, just one possible place remained for servos: Upper Arm.
And it would be good to actuate also Upper Arm, but establishing a universal joint on Upper Arm-Shoulder connection, would be extremely complicated and hard. Anyway Upper Arm might be levered only and whole structure might be turned by Shoulder, so I decided to limit mechanical structure at Shoulder.
First Problem :: Twisting the WristAfter assembling the Hand and Wrist sections, I started to study on Front Arm, and immediately question came up: How can I twist my hand?
Perhaps till now you also never thought about that. Mechanically, twisting actions require a pivot connection. But how is it assembled on human body? The answer I seek was on a pages by Stan Prokopenko: https://www.proko.com/types-of-joints/
(Many thanks to him for that great guideline. In the meantime, I also learnt that twisting movements are called as “pronation”and “supination” on medics.)
So it’s clear that there’s a pivot connection between Ulna- and Radius-bones. But why that pivot is located on the back-end, on the elbow? Isn’t it something hard to do? And how could I imitate that mechanism?
As can be seen on Prokopenko’s animations, Ulna-and Radius-bones wrapped together around pivot. When the dedicated muscle stretches, Radius revolves onto Ulna so the Wrist will be twisted.
So I did exactly the same at first: I prepared a prototype by placing pivot onto the elbow-end, fixed both of Ulna and Radius to the Wrist, and finally wrapped them at elbow-end by using packaging rubbers.However, that configuration could not move smoothly even by manually. After a bit more careful look to the mechanism I took completely different way by reshaping Ulna and Radius completely: Ulna is designed to lever only and it’s fully separated from Wrist. Ulna-Radius pivot is relocated onto the middle section of Front Arm. Finally, Wrist is fixed only onto Radius. So, also the shapes of Ulna and Radius finally became similar to the real bones.
(On your Front Arm, that pivot is located on elbow end, because that’s the best place to protect pivot against any damage. If Front Arm bone(s) are fractured due to any impact, you can continue using it normally when healed completely. However, if pivot was placed at the middle, it would get damage in case of mechanical impacts, so possibly you would never be able to twist your hand anymore even it healed.)
After solving this issue, now I had to decide routing of “muscles”. The routing should not be effected by movement of Ulna and Radius, so it was clear that all muscle ropes should reach to actuators at Upper Arm by passing through Ulna-Radius pivot. So I sacrificed a pen to use its body as a hollow joint.
At the end, entire Humanoid Arm + Hand Mechanicals were able to perform almost all movements of the real one: Opening and closing Fingers as well as ability of holding something up, turning right-left and up-down at the Wrist, twisting the Front Arm nearly 270 degrees as well as levering it, levering the Upper Arm, and turning whole arm structure nearly 180-degrees at Shoulder.
Note that if I counted correctly, real human arm has 27 axes of movement from Shoulder to Hand:
- Turning, levering and circling of Upper Arm = 3 axes
- Levering and twisting Front Arm = 2 axes
- Turning Wrist horizontally (right-left) and vertically(up-down) = 2 axes
- Circling and levering Thumb Metacarpal = 2 axes
- Levering Thumb Proximal and Distal = 2 axes
- Levering Proximals, Medials and Distals of Index, Middle, Ring and Pinky Fingers = 3 x 4 = 12 axes
- Closing and opening Index, Middle, Ring and Pinky Fingers on a horizontal plane while keeping all straight = 1 x 4 = 4 axes - try to show Vulkan Salute :)
So, the completed mechanical prototype was able to do all those on 22 axes, except circling of Upper Arm and moving fingers for Vulkan Salute.
By completing Front Arm mechanics, necessity of 13th Servo came up for “pronation” and “supination”, and 14th one for levering the whole Front Arm.
Upper Arm and Shoulder designs were easier comparing to Front Arm mechanical. But due to the weakness of balsa, shoulder-end of Upper Arm should be supported well from inside and 40 mm diameter PVC pipe perfectly did it. And a part of 25 mm PVC pipe is driven through, so the levering axis of Upper Arm is completed.
(Here I’m writing as quickly done, but it wasn’t so. Before realizing something, all the parts are modeled, matched and interacted with others, and checked for suitability on computer. Implementation comes after Engineering.)
However, since the beginning of actuation idea, there was also another question in my mind…
“OK, up to now we did quite well, but… how shall we support that thing, baby?”Supporting question was not only for mechanical structure. It was also needed to fix controllers somewhere, but close to mechanical structure due to limited length of jumper wires. During days, I imagined a support structure specially made by wood, pipe, other materials… But I loved none of those ideas.
And at one night, I found a perfect solution already hanged beside my table since long ago: My camera tripod. Just by replacing its screw with a bolt to hold the turning axis of Shoulder, it may work perfectly, and worked.
So I designed just an axis and bottom plate for Shoulder finally, and just by using my excess furniture parts, plastic waste water pipe caps and balsa wood. Then everything is placed onto tripod.
Now I could start to install muscles, actuators and further, but before that another thing came up…
“There must be one more controller…”Just after decided to actuate the whole arm, I counted the signals I have to use and faced with the bad news unavoidably: I had only one Arduino Due, and even it has lots of input/outputs comparing to the other models, still it was not enough. At first I have to define the further necessities, and then I found Arduino Leonardo as optimum solution for the secondary controller. Upon preparing an Input/Output List and a bit study on it, Hand- and Wrist-section are left under Due’s scope; while controlling of Front Arm, Upper Arm and Shoulder are to be managed by Leonardo.
Then, another question raised…
“Which controller should be the master, and how should they ‘talk’ to each other?”Because of higher capacity and faster speed, it would be better to assign Due as master. However, there was a problem on “talking”: Due runs at 3.3V while Leonardo is at 5V level. Since their I2C communication use also same voltage levels as controllers, direct connection would burn Due.
I had to make that interface as simple as possible and the best way was to use analog (voltage) signals. Simply Leonardo should “understand”;
- which part shall be actuated, and,
- to which position it should be moved.
So I decided to use DAC0 and DAC1 analog (voltage) outputs on Due, and correspondingly A0 and A1 on Leonardo to define those.
However, stabilization of voltage outputs take a bit time. So Leonardo could misunderstand the requests by Due, so it should know also whether the commands are ready to be read. The third signal of communication appeared: “Execute”. Good news is, it could be directly wired from Due’s Ch.50 (digital output) to Leonardo’s Ch.8 (digital input).
Finally, how would Due understand that its command is executed? A fourth signal should be sent from Leonardo to Due: “Command Executed” feedback, but there’s a problem because of above mentioned voltage levels. If that confirmation signal would be wired directly from Leonardo’s Ch.12 (digital output) to Due’s Ch.51 (digital input), then I should organize a funeral ceremony for poor Due :)
Anyway, this problem was the easiest of entire project: Leonardo’s 5V output might be divided by just two kiloohm-level resistors, and then it might be sent to Due as ~3.3V. At the implementation-stage, just a 270k and a 470k worked very well.
Muscles and TendonsYou actuate muscles to take some action, but then body section must be returned back to original position when related muscle is released. So there are tendons on your body, located contrary to the muscles. But tendons are not strong as corresponding muscle due their intention of use.
I already wrote above the materials I decided to use as Muscles and Tendons. However, during trials I noticed that fishing ropes might be easily jammed between mechanical joints. So it would be better to use some kind of “guides”, and 6mm diameter PVC tube parts are exactly fit to that purpose.
No any tendons are used for Ulna and Upper Arm, since gravity would act well.
When I decided to actuate the arm, necessity of Limit Switches directly came up. Without them it would be very easy to damage the mechanical parts by servos. But unfortunately, servos were not powerful as I thought.
At the beginning I thought Limit switches would be one of the easiest parts, but it wasn’t so, especially on fingers. Actually that problem came up due to 2 main reasons: First is the balsa wood again, due to its weakness. And the second one is scale of my design. As you can see on some photos above, my intention was to make a humanoid hand and arm at 1:1 scale.
Anyway, I made contact points by just by wires and aluminum tape. Even they were essential to protect mechanicals, they lost their functionalities in time especially on Fingers due to wears on balsa parts.
Position Sensors are implemented by using potentiometers at few points only and they worked almost well.
Due to limited space, I had just one choice to actuate (perhaps I should say “stretch” or "flexion/extension" as on medical terminology) “muscles” dedicated for Front Arm, Wrist and Hand sections, including Fingers as well: Multi-turn Micro Servo Motors. All of those should be located onto Upper Arm, so the Upper Arm design is done by considering rope routing as well.
At first, I made ~10 mm diameter pulleys made of balsa. However, output torques of Micro Servos were quite low. Then I modified their wheel horns: Diameters are reduced by grinding and a washer is used between horn and servo, and drilled close to the centers to connect ropes.By such a way, Servos could be able pull a bit higher loads.
At later stages, another pulley sets are required also to lever Front Arm and Upper Arm, so they’re done. Even Micro Servo could handle levering of Front Arm, standard servo is needed for Upper Arm, since it should handle the weight of Upper Arm, Front Arm, Hand and all wiring on them as well.
Another standard servo is used also for turning Shoulder.
And the best way to do that, was to make some kind of “terminal assemblies”. After studying few days, I found that 3 Terminal Assemblies could be made just by 2 pieces of 8x2 cm pre-fabricated PCBs.
- TB01 is designed to handle all signals dedicated for Hand, Wrist and Radius (to twist Front Arm), as well as servos dedicated for Wrist and Radius (to twist Front Arm)
- TB02 is designed to handle all signals and motors dedicated for Shoulder, Upper Arm and Ulna (to lever Front Arm)
- TB03 is designed to handle just servos for Fingers
Of course all Terminal Assemblies should be tested after first “manufacturing” and during soldering of wires.
After -almost- everything installed, I took just Arduino Leonardo and started to test each servo by a simple routine individually to check it out whether it’s able to function as required. That routine was very basic and written to operate just one servo at lowest speed and direction selected by digital inputs. At that time it was possible to operate everything one by one. But when all the servos are energized together, an unexpected surprise came up. Later we’re going to talk about that trouble.
Even I modified the servo arms to use as extremely low-diameter pulleys, yet it was not enough to “pronate” and “supinate” the Radius. So I made a micro pulley set.
The first one worked well, but it was too large. So it’s minimized on next step.
Unfortunately, still there was too much torque on respective Servo. I tried to adjust, but while Front Arm is at horizontal position and the Servo brought Radius fully onto Ulna and then tried to release, respective “tendon” rubber failed to return it because of frictions and counterforces on micro pulley. I tightened tendon, but then the servo was not able to pull anymore… After few trials, servo became unstable and soon later its motor controller burned. That was the first victim of Project. Please salute and pray for nameless hero -no, sorry its tag is “11FR”- :)
(Of course every single point/component had its own unique tag. Otherwise it would be impossible to make all that construction, wiring and programming. Patience, we’re going to talk also about importance of Engineering.)
So I decided to stop trials for twisting the Front Arm. It would need significant torque, but in the meantime further trials could lead damaging of entire Front Arm.
Other Trials :: FingersNothing particular to say. At the beginning, everything was looking OK… Until servos were dead and balsa parts worn out.
First Codes :: Due<->Leonardo IntercommunicationI already mentioned above the principles, and on the programming stage it was the first section. On analog channels, Due/DAC0and Leonardo/A0 are assigned for Set Value Register to transmit and receive set values as percentage. Due/DAC1 and Leonardo/A1 are assigned for Section Selector.
But it was just needed to make some ranging: Due can use the full range but since DACx outputs would generate corresponding voltages in 0.75-2.55V range, matching scales should be adjusted on Leonardo.So, Leonardo is configured to read Set Value between (integer) 168-846corresponding to 0-100%. For the section selector the full range is divided into 5 sections on Due-side, and corresponding values are calculated for Leonardo. But in that implementation it was also necessary to use deadband. So, even the exact values used on Due, they're interpreted on Leonardo as (Value +/- Deadband) to ensure selected section.
At the end, intercommunication routines completed as follows on both controllers and worked well.
on Due:
const int _FA_Radius = 840; // Front Arm Radius Section
const int _FA_Ulna = 1530; // Front Arm Ulna Section
const int _UpperArm = 2220; // Upper Arm Section
const int _Shoulder = 2910; // Front Arm Radius Section
void CommandToLeonardo(String Section, int SetValue) {
/* SetValue is given as Percentage */
int Section_Num=0;
if (Section=="_11FR") Section_Num = _FA_Radius;
else if (Section=="_11FU") Section_Num = _FA_Ulna;
else if (Section=="_21UA") Section_Num = _UpperArm;
else if (Section=="_31SH") Section_Num = _Shoulder;
if (Section_Num==0)
Serial.println("Section cannot be recognized.");
if ((SetValue<0) || (SetValue>100))
Serial.println("Set Value should be between 0-100).");
if ((Section_Num!=0) && (SetValue>=0) && (SetValue<=100) )
{
Serial.print(String(SetValue) + "% -> ");
switch(Section_Num){
case _FA_Radius: Serial.println("Front Arm-Radius");
break;
case _FA_Ulna : Serial.println("Front Arm-Ulna");
break;
case _UpperArm : Serial.println("Upper Arm"); break;
case _Shoulder : Serial.println("Shoulder"); break;
}
analogWrite (_00XXCM, Section_Num);
analogWrite (_00XXSP, map(SetValue, 0, 100, 0, 4095));
delay(50); // Delay for stabilization of outputs
digitalWrite(_00XXXC, HIGH); // Execute Command
do { // Wait until getting OK from Leonardo
} while(!digitalRead(_00XXOK));
Serial.println("ARD LNRD = OK.");
analogWrite (_00XXCM, 0);
analogWrite (_00XXSP, 0);
// Resetting Section and Set Value outputs
delay(50); // Delay for stabilization of outputs
digitalWrite(_00XXXC, LOW); // Resetting Command
} /* End of "if (Section_Num!=0)" */
} /* End of "void CommandToLeonardo()" */
void loop() {
if (Serial.available())
{
String Command=ReadUserInputOverSerial();
Serial.println(Command);
if (Command.substring(0,1)=="?") /* Help */
{
Serial.println("Commands:");
Serial.println(" CTL [Section] [SetValue (0-100)]");
Serial.println(" CommandToLeonardo - Section: First 5 characters of PWM Tag (e.g. _10WH for _10WHCM).");
Serial.end(); Serial.begin(_BAUDRATE);
while(!Serial) { };
}
if (Command.substring(0,3)=="CTL")
CommandToLeonardo(Command.substring(4,9),
Command.substring(10).toInt());
CommandPromptOverSerial("[ARD DUE/] > ");
} /* End of "if (Serial.available())..." */
} /* End of "void loop()": ARDUINO DUE */
on Leonardo:
const int _FA_Radius = 310; // Front Arm Radius Section
const int _FA_Ulna = 425; // Front Arm Ulna Section
const int _UpperArm = 540; // Upper Arm Section
const int _Shoulder = 655; // Front Arm Radius Section
const int _ICDB = 40; // Deadband
/* Since the signals cannot generate exact integer values,
* Section shall be identified by [ (SectionValue) +/- _ICDB ]
* reading.
*/
void setup() {
/* Initial Feedback to Due */
digitalWrite(_00XXOK, LOW);
}
void CommandFromDue() {
CommandFromDue_Section = analogRead(_00XXCM);
if ( ((_FA_Radius-_ICDB)<=CommandFromDue_Section) &&
(CommandFromDue_Section<=(_FA_Radius+_ICDB)) )
CommandFromDue_Section=_FA_Radius;
else if ( ((_FA_Ulna-_ICDB)<=CommandFromDue_Section) &&
(CommandFromDue_Section<=(_FA_Ulna+_ICDB)) )
CommandFromDue_Section=_FA_Ulna;
else if ( ((_UpperArm-_ICDB)<=CommandFromDue_Section) &&
(CommandFromDue_Section<=(_UpperArm+_ICDB)) )
CommandFromDue_Section=_UpperArm;
else if ( ((_Shoulder-_ICDB)<=CommandFromDue_Section) &&
(CommandFromDue_Section<=(_Shoulder+_ICDB)) )
CommandFromDue_Section=_Shoulder;
else
CommandFromDue_Section=0;
CommandFromDue_SetValue =
map(analogRead(_00XXSP),168,846,0,100);
/* Due generates DAC outputs between 0.55-2.75 V and it
* corresponds (int) 168-846 on Arduino Leonardo.
* Here analog reading is converted to Percentage.
*/
boolean CommandFromDue_Execute = digitalRead(_00XXXC);
String Section = "";
int Speed = 0;
if ((CommandFromDue_Section!=0) && CommandFromDue_Execute)
{
Serial.println();
Serial.print("Command by ARD DUE: "+
String(CommandFromDue_SetValue) + "% -> ");
switch(CommandFromDue_Section){
case _FA_Radius: Serial.println("Front Arm-Radius");
Section = "_11FR";
Speed = 20;
break;
case _FA_Ulna : Serial.println("Front Arm-Ulna");
Section = "_11FU";
Speed = 20;
break;
case _UpperArm : Serial.println("Upper Arm");
Section = "_21UA";
Speed = 90;
break;
case _Shoulder : Serial.println("Shoulder");
Section = "_31SH";
Speed = 30;
break;
}
Serial.println(" -action-");
MoveToPosition(Section, Speed, CommandFromDue_SetValue);
Serial.println("OK -> ARD DUE.");
CommandPromptOverSerial("[ARD LNRD/] > ");
digitalWrite(_00XXOK, HIGH); delay(100);
digitalWrite(_00XXOK, LOW); // OK Feedback to Due
} /* End of "if (Section_Num!=0)" */
} /* End of "void CommandFromDue()" */
Other than intercommunication, here I'm not going to explain deep details of further codes just to avoid boring reader, since at the end you can find complete programs as 800+ lines for Due and 500+ lines for Leonardo, as well as explanatory notes. As you can see on programs, there are already functions with same names. Principally such functions are exactly same in principle/algorithm but just some changes made due to scopes of controls.
void CommandPromptOverSerial(Prompt)
It's created just to make that fancy command line interface. Besides that, it also reinitialized serial communication so that ensures flush.
String ReadUserInputOverSerial()
reads the user input at Serial Monitor, and returns it as string.
void Read(Tag)
void LoopTest()
Both of those functions are created for testing of individual loops (input/output channels).
LoopTest() has already subsections dedicated for Analog Input, Analog Output, Digital Input, Digital Output and PWM-Output types; but Read(Tag) is intended only to read an input directly from top-level without going to LoopTest().
void CommandToServo(Tag, Value)
As you recognized till now, I referred everything as tags. That's also the intention of this function: It sends set value (0-180)to the Servo motor assigned to "Tag".
void FullTravelDurationMeasurement(PWM_Tag, LimitSw_CCW, LimitSw_CW, int Speed)
This function is written to check full travel durations for the Fingers since they could not be equipped with actual position sensors. According to results, they could be pulled or released by timing. Even it worked theoretically by manual forcing on input/outputs, it could not be used on actual system because switches could not work properly due to the wears on mechanicals. Consequently, full travel durations could be determined by manual trials only, instead of using this function.
void MoveDuringMillis(Tag, Direction, Speed, Milliseconds)
This function is also written to actuate a Finger defined by Tag, at the specified Direction and during specified Milliseconds.
void MoveToPosition (Section, Speed, SetValue)
This function is written to move a Section to the position given by SetValue and at the specified Speed. Note that Section should also be equipped with position sensor.
void Fingers_Hold()
void Fingers_Release()
These functions are written to close (to hold something) and release the fingers -almost- simultaneously. Unfortunately, only once and partially the Fingers could work…
void Final_Demo()
As its name says: At the end only the levering mechanicals of Front Arm and Upper Arm, and rotating of Shoulder was able to be used. So this function is written to demonstrate them.
Upon successfully testing all individual signals and functions, I finished mechanical connections between servos and mechanical sections. Now, arm was ready for testing real functionality but…
Energized :: Crazy ServosAfter testing and adjusting all servos one by one and individually, it was the time to power all servos in once. But the result was not as I expected.
My original design had 14x Micro Servos at Upper Arm to handle lightweight loads, while 2x standard servos were placed at Shoulder for levering of Upper Arm and turning Shoulder. All of them were able to accept one common voltage level, 6V, so I did that.
But once I operated a standard servo, some micro servos are just started without any command. Fortunately, I put a switch onto power supply line, so I could cut all in once but anyway some Fingers are over forced because of instant and extreme acceleration. Again I unscrewed the pulleys of all micro servos, then re-energized all. The result was the same:Unstable micro servos could never be adjusted, or could not keep stability even adjusted, and even unloaded.
My first doubt was suitability of power supply: I used a 6V, 3Ah adapter.
According to available data, each micro servo consumes 6 mA at idle, 120 mA at no-load operation and 800 mA at stall conditions. For standard servos only one parameter is given: 100 mA as operating current, I considered it for no-load operation, and assumed the rest of the parameters similar to micro servos.
So, my power supply would be enough since only one servo would be operated at a moment. So, what could be the reason of fail?
Still I was thinking on power supply, and started to monitor it by oscilloscope. The result was interesting while just one of standard servo was running:
When I saw those changes, I had a theory: Possibly micro servos were more sensitive against voltage fluctuations, and those were misinterpreted by them as “command”. Then I decided to power micro- and standard servos separately. Standard servos are kept connected at current power supply together with just one micro servo (the one dedicated for levering Front Arm), while all other micro servos are connected to other power supply separately. And that modification worked.
Fingers :: One Last TimeAs I already wrote above, at the end I was not able to operate all sections because of wears. Anyway, it could open and close fingers just once, and possibly I would kill the remaining 6 micro servos if I continue trying. So it was the best to stop here. Theoretically, you would see sequential but smoother working if the balsa parts were not worn.
Final DemoFinally after ~4.5 months of design and assembling, it was possible to operate only levering functions for Front- and Upper-Arms, and turning function of Shoulder.
Engineering :: Industrial Practices RevisitedPerhaps you can follow everything by your eyes and hands if your project is within very small area and contain just few or several devices.
But if you have to work on ~1-meter length equipment contain 500+ parts in 140+ different types, ~60 electrical and electronic devices (switches, potentiometers, servo motors), 60+ signals on two different controllers as well as interconnecting both, and hundreds of wires for connections; then working on computer and papers become a must and would be the best for troubleshooting.
So everything started by designing mechanicals on computer. At later stages; servo motors, switches, position sensors and terminal assemblies were added onto model.
As I mentioned on previous sections, dedicated unique tags are also assigned to all individual parts. You’re going to see those tags also on the programs, those made life a bit easier. At the end, there are “3D Model”, “Pulley Rope Routing Sketches”, “Instrument List”, “I/O List”, “Instrument Layout”, “Terminal Board Layout” and “Wiring Diagram” as the documentation package of Project.
I agree that my design is extremely primitive. My initial intention was just to imitate the human hand and arm mechanically, but later I decided to try actuating whole structure.
On the mechanical design-side everything was almost as expected: All mechanical parts perfectly matched and interacted with each other manually.
Anyway, the first bottleneck was the chosen material, the balsa wood: I chose just because it’s available in pre-formed/pre-cut parts widely for hobby works, very cheap to use on prototyping, easy to form by simple hand tools, easy to repair just by using strong glues. And by using balsa wood, I could avoid buying a quite expensive CNC or 3D printing machine as well as their accessories and consumables.
However, balsa wood is also a very weak material, and led wears especially on fingers earlier than I imagined.
Besides those, 1:1 scale of my design “amplified” the weakness of balsa. I had to make repairs on many places during building up and trying to operate. As final example, holder plates of servo motors on Upper Arm were also made of balsa, and after few removals they started to crack.
And also it was not possible to use any bearings, especially on hand section due to the scale.
Even though, I recommend balsa wood for making mechanical prototypes on cheapest way.
The other bottleneck was size and power of the servos. Because of the scale, I had to use micro- and standard servos only, but they have limited abilities. That's also the reason of pulley sets considered for pronation of Radius and flexion of Ulna and Upper Arm, so entire arm had a crane-type structure instead of a real robotic one.
For Future :: LessonsImitating of natural mechanisms is a very hard and complicated project, since some of their functionalities provided by flexible (nearly universal) connections between mechanical sections (=bones) held together by actuators (=muscles) and reversing springs (=tendons). Also tendons could be stretched - even a bit and not much as muscles.
But that’s not all. When you actuate a “section”, you also know it’s actual position in real-time, as well as interlocking actuation if it’s reached to the movement limits. It means, a position sensor and at least 2 limit switches should be used for each section.
As you noticed, I had to use servo motors, but the alternatives are stepper motors if you would like to avoid position sensors. However, 4 digital outputs would be needed for each stepper in that case, consequently 2 Arduino-class controllers would not be enough.
Do you think that we finished? No, not yet.
Let’s make a simple experiment: Hold your right hand with facing your palm straight upwards. Then bend index finger of your right hand, and “hang” it at side of left hand palm. Now, try to holding your right hand just by tip of your left-index finger, while pushing right hand to straight upwards. Do you see that? Up to a certain limit, you can withstand against muscles on your arm, just by muscles controlling the index finger bones.
If you try to do that by imitated mechanisms, it’s almost sure that they’re going to be broken. During even simple trials, I burned 7 micro servos.
And more:
On the natural mechanisms, the "actuators" are placed very close to the mechanical sections. Today the best way to do that on mechanical imitations, might be to use hydraulic cylinders. But in that case, a powerful hydraulic pump system, oil reservoir, check valves, solenoid valves…should also be used and that would bring necessity of far larger space requirements and controller + input/output capacities.
Those latest 2 paragraphs mean that, far smaller and far more powerful actuators are needed.
Finished? No, there’s one more issue:
Let you try to move a finger…
Now try moving 2 or 3 fingers simultaneously… Good.
Try moving all fingers while moving your hand up-down at the wrist, then left-right… Perfect.
Move all fingers while twisting your wrist while levering your front arm…
[ What? Are you OK? Look at me, shall we take you to a clinic? :)) ]
If you have no any serious health problem, you could do all, right? Now how can we do it with a mechanical imitation?
As I mentioned already, human arm and hand have ~30 different movements (axes) in total, so one actuator must be used for each, for a realistic imitation able to act smoothly.
If we would like to do it by using some simple controllers like Arduino-class, simply we need one sub-controller for each axis, and a master-controller to command them all. Sub-controllers should have their specific routines define only specific movements of respective section, for predefined overall movements of entire system. Master should just send set points and requested overall movement information to the sub-controllers, and then send an “execute” command to all in once, and wait for confirmations.
For example, each sub-controller dedicated individually for Proximal, Medial and Distal sections of Index-, Middle-, Ring- and Pinky-fingers (so we're talking about 12 sub-controllers together with actuators, position sensors, limit switches and so on as needed) should have -for example- a "Hold_a_Circular_Plate()" subroutine defines specific movement only for the respective section. When the master controller sends "Command_to_Hold_Circular_Plate()", it should trigger just one output goes to all sub-controllers simultaneously. But another important issue is to synchronize sub-controllers in microseconds, otherwise all would fail on action.
Second option is to use a far more powerful controller and actuators with far more faster responses, so that switching between different actuators shall not be recognizable.
Third option is the best one is, if possible: To use the most powerful controller ever made, that is able to perform absolute multi-processing at extreme speeds: An organic brain together with neural system, preferably a human brain for a humanoid arm (fictionally it's been done on Robocop-series).
:: Ending ::Even today some companies are manufacturing prosthetic humanoid hands for disabled people, and even they’re fantastic designs and making people’s life easier, we cannot say that all those are perfect imitations.
I think almost all of us see possibly the most amazing robot “Atlas” designed and constructed by Boston Dynamics. Such research and developments consume extreme amount of money, time and requires long hours of studies, trials, countless fails and so on. For example, Boston Dynamics has been founded in 1992 and since that time they’re continuously working on robots.That means, as of today, there’s nearly 30 years of study, trials, fails, retries… and so on behind Atlas.
On the budget side, “fathers” and “mothers” of Atlas are funded by US Defense Advanced Research Projects Agency. Yes, unfortunately military agencies are the master supporters of such amazing projects and mankind is still very good on finding the best ways to kill each other :(
And such amazing things cannot be made by consumer products on markets. All the mechanical, electronics, actuators, sensors…should be specifically and individually designed by customized parameters as tailor-made for the Project.
Perhaps recently-invented artificial muscles may help to develop better prostheses.
In all cases, I hope you find all that long story, and your body as well, interesting from mechanical and controls point of view…
Comments
Please log in or sign up to comment.