Robotic Arm - Are there any how-to's out there?

I've been interested in robotic arms for a good long while. When I saw the "open source" U-Arm, I became a bit rabid. Unfortunately, UFactory got funding and clammed up. Disappointing. Then teocreo got irritated and designed his own. He promised to send me DXF and DWG files of it after he made 3 or 4 changes. He needed an Inverse Kinematic sketch to run it with. I found one that was open source, so I sent it to him. I haven't heard from him since.

I ordered MG996R Metal Gears Digital RC Servo Motor
http://www.ebay.com/itm/181297738322?ssPageName=STRK:MEWNX:IT&_trksid=p3984.m1497.l2649
and bought a lazy susan ball bearing unit (not very good, but good enough for a first experiment),

1/8" birch plywood, 1/4" birch plywood, already have micro servos, arduino 2560 mega, and a lot of the other stuff I'll need.

I contacted Lebanon High School and the technical teacher said the school has a laser cutter and CNC machine that I can use. He is the instructor for Autocad, so we can do the drawings needed.

I have the program, which I will need help from you folks to adapt and improve on.

The first arm will be made of the aforementioned plywood. It probably won't be particularly great, but, with your help, we can improve it.

Eventually, it will evolve into something aluminium based that can be CNC'd or printed, glued to aluminium and bandsawn, jig sawn, or something like that. Not everyone has access to CNC machines.

On the other hand, did you notice that I am getting free access to HIGH SCHOOL equipment? Bet you could too. Ask. I did promise to include the kids in on the project, if they want.

I am kind of thinking about sponsoring a class project of making a robotic arm sitting on a robot car serving a soft drink to the teacher sitting on a chair in the basketball court at half-time. The robot operator being the student who contributes the most to the project.

But I diverge.

I plan to make a plywood box base sitting on a lazy susan bearing which has a little bit of slop in it. A plywood turntable with an MG996R servo to rotate it and a U-bracket of plywood or bent up aluminium sheet to hold the upper arm.

Plywood box upper arm (humerus). 1/8" sides, 1/16" top and bottom, glued on. Probably 3/4" or 1" cross section.
3/16" pivot bolts. Grease the wood holes. That's the bearing. (It's a toy, not production equipment).
Wood block glued to the inside of the arm to attach the MG996R servo to at the pivot point.

Plywood box lower arm(ulna). Same construction.
Same pivot.
Push-pull rod to the lower arm to flex it.
MG996R servo attached to the bottom of the upper arm push-pulling an extension of the elbow to move the lower arm.

Springs at the joints to offset some of the arm weight.

Micro servo to rotate the wrist up and down.

Micro servo to spin the gripper.

Micro servo to operate the gripper.

A lot of the details are not yet resolved - most actually.

I have some 6063-T3 aluminium left over from when I built my airplane (Baby Great Lakes). I will probably use some to make brackets and such.

I desperately need plans for a gripper. I have no idea whatsoever how to build such a thing. I do have a CNC machine available, however. :slight_smile:

The plywood I have is 12" x 12", so I will have to stay within that range. I'm guessing 250mm pivot points.

I will post anything and everything that I come up with. I will lean heavily on the members for advice. I have my own website, so I can post everything there if I can remember how to set it up. It's been several years since I monkeyed around with it. www.reckelfamily.com

I'll get started on it Monday or Tuesday.

John

What I would like to see would be to modify this code to become a library that could be called giving (x,y,z,w,r,g).
x,y,z coordinates
w=wrist bend angle
r=wrist rotation angle
g=gripper value

And, possibly, utilizing PID functionality.

It would also be good if it could be generalized enough to work with the palletizing arm, like the UArm, particularly if it could be done without complicating it.

Hopefully, all that could be done without making it too complex for beginners to easily understand.

Of course, I don't know how to do any of that, yet.

I see no reason for the servo shield. The Uno should be able to handle 6 servos.

/*

    This sketch was shamelessly lifted intact from
    www.circuitsathome.com/mcu/robotic-arm-inverse-kinematics-on-arduino
    in an article "Robotic Arm Inverse Kinematics on Arduino By Oleg Mazurov".
    
    Oleg has declared it to be open source.
    
    It was written to be used with a Lynxmotion AL5D robotic arm and a Renbotics
    servo shield.  The Renbotics shield uses a PCA9685 IC described below by NXP.
    
    This could be modified to use the Arduino Mega 2560 board which has 15 PWM pins.
    
    The PCA9685 is an I²C-bus controlled 16-channel LED controller optimized for 
    LCD Red/Green/Blue/Amber (RGBA) color backlighting applications. Each LED 
    output has its own 12-bit resolution (4096 steps) fixed frequency individual 
    PWM controller that operates at a programmable frequency from a typical of 
    40 Hz to 1000 Hz with a duty cycle that is adjustable from 0 % to 100 % to 
    allow the LED to be set to a specific brightness value. All outputs are set 
    to the same PWM frequency.

    Here is Oleg's description of the code.
       Here is a short description of the code. 
       The coordinate space follows one in Micromega AN44. set_arm() takes 3 
       coordinates and grip angle and sets servo angles for base, elbow, shoulder 
       and wrist. 
       Arm dimensions are defined in millimeters at the beginning of the sketch. 
       Three short functions are written to demonstrate the functionality. 
       
       zero_x() moves the arm in a straight line along the y-axis, 
       line() moves the arm side to side and 
       circle() moves the arm in a circle in y-z plane. 
       In all 3 functions, wrist angle is set to 0 degrees, 
       it can be changed to some other value to make motion more interesting.

    The sketch will have to be modified to fit any other robot arm and or servo shield.
*/

#include <ServoShield.h>
 
/* Servo control for AL5D arm */
 
/* Arm dimensions( mm ) */
#define BASE_HGT 67.31      //base hight 2.65"
#define HUMERUS 146.05      //shoulder-to-elbow "bone" 5.75"
#define ULNA 187.325        //elbow-to-wrist "bone" 7.375"
#define GRIPPER 100.00      //gripper (incl.heavy duty wrist rotate mechanism) length 3.94"
 
#define ftl(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))  //float to long conversion
 
/* Servo names/numbers */
/* Base servo HS-485HB */
#define BAS_SERVO 0
/* Shoulder Servo HS-5745-MG */
#define SHL_SERVO 1
/* Elbow Servo HS-5745-MG */
#define ELB_SERVO 2
/* Wrist servo HS-645MG */
#define WRI_SERVO 3
/* Wrist rotate servo HS-485HB */
#define WRO_SERVO 4
/* Gripper servo HS-422 */
#define GRI_SERVO 5
 
/* pre-calculations */
float hum_sq = HUMERUS*HUMERUS;
float uln_sq = ULNA*ULNA;
 
ServoShield servos;                       //ServoShield object
 
void setup()
{
  servos.setbounds( BAS_SERVO, 900, 2100 );
  servos.setbounds( SHL_SERVO, 1000, 2100 );
  servos.setbounds( ELB_SERVO, 900, 2100 );
  servos.setbounds( WRI_SERVO, 600, 2400 );
  servos.setbounds( WRO_SERVO, 600, 2400 );
  servos.setbounds( GRI_SERVO, 600, 2400 );
  /**/
  servos.start();                         //Start the servo shield
  servo_park();
  Serial.begin( 115200 );
  Serial.println("Start");
  delay( 500 );
}
 
void loop()
{
 
  //zero_x();
  //line();
  circle();
 }
 
/* arm positioning routine utilizing inverse kinematics */
/* z is height, y is distance from base center out, x is side to side. y,z can only be positive */
//void set_arm( uint16_t x, uint16_t y, uint16_t z, uint16_t grip_angle )
void set_arm( float x, float y, float z, float grip_angle_d )
{
  float grip_angle_r = radians( grip_angle_d );    //grip angle in radians for use in calculations
  /* Base angle and radial distance from x,y coordinates */
  float bas_angle_r = atan2( x, y );
  float rdist = sqrt(( x * x ) + ( y * y ));
  /* rdist is y coordinate for the arm */
  y = rdist;
  /* Grip offsets calculated based on grip angle */
  float grip_off_z = ( sin( grip_angle_r )) * GRIPPER;
  float grip_off_y = ( cos( grip_angle_r )) * GRIPPER;
  /* Wrist position */
  float wrist_z = ( z - grip_off_z ) - BASE_HGT;
  float wrist_y = y - grip_off_y;
  /* Shoulder to wrist distance ( AKA sw ) */
  float s_w = ( wrist_z * wrist_z ) + ( wrist_y * wrist_y );
  float s_w_sqrt = sqrt( s_w );
  /* s_w angle to ground */
  //float a1 = atan2( wrist_y, wrist_z );
  float a1 = atan2( wrist_z, wrist_y );
  /* s_w angle to humerus */
  float a2 = acos((( hum_sq - uln_sq ) + s_w ) / ( 2 * HUMERUS * s_w_sqrt ));
  /* shoulder angle */
  float shl_angle_r = a1 + a2;
  float shl_angle_d = degrees( shl_angle_r );
  /* elbow angle */
  float elb_angle_r = acos(( hum_sq + uln_sq - s_w ) / ( 2 * HUMERUS * ULNA ));
  float elb_angle_d = degrees( elb_angle_r );
  float elb_angle_dn = -( 180.0 - elb_angle_d );
  /* wrist angle */
  float wri_angle_d = ( grip_angle_d - elb_angle_dn ) - shl_angle_d;
 
  /* Servo pulses */
  float bas_servopulse = 1500.0 - (( degrees( bas_angle_r )) * 11.11 );
  float shl_servopulse = 1500.0 + (( shl_angle_d - 90.0 ) * 6.6 );
  float elb_servopulse = 1500.0 -  (( elb_angle_d - 90.0 ) * 6.6 );
  float wri_servopulse = 1500 + ( wri_angle_d  * 11.1 );
 
  /* Set servos */
  servos.setposition( BAS_SERVO, ftl( bas_servopulse ));
  servos.setposition( WRI_SERVO, ftl( wri_servopulse ));
  servos.setposition( SHL_SERVO, ftl( shl_servopulse ));
  servos.setposition( ELB_SERVO, ftl( elb_servopulse ));
 
}
 
/* move servos to parking position */
void servo_park()
{
  servos.setposition( BAS_SERVO, 1715 );
  servos.setposition( SHL_SERVO, 2100 );
  servos.setposition( ELB_SERVO, 2100 );
  servos.setposition( WRI_SERVO, 1800 );
  servos.setposition( WRO_SERVO, 600 );
  servos.setposition( GRI_SERVO, 900 );
  return;
}
 
void zero_x()
{
  for( double yaxis = 150.0; yaxis < 356.0; yaxis += 1 ) {
    set_arm( 0, yaxis, 127.0, 0 );
    delay( 10 );
  }
  for( double yaxis = 356.0; yaxis > 150.0; yaxis -= 1 ) {
    set_arm( 0, yaxis, 127.0, 0 );
    delay( 10 );
  }
}
 
/* moves arm in a straight line */
void line()
{
    for( double xaxis = -100.0; xaxis < 100.0; xaxis += 0.5 ) {
      set_arm( xaxis, 250, 100, 0 );
      delay( 10 );
    }
    for( float xaxis = 100.0; xaxis > -100.0; xaxis -= 0.5 ) {
      set_arm( xaxis, 250, 100, 0 );
      delay( 10 );
    }
}
 
void circle()
{
  #define RADIUS 80.0
  //float angle = 0;
  float zaxis,yaxis;
  for( float angle = 0.0; angle < 360.0; angle += 1.0 ) {
      yaxis = RADIUS * sin( radians( angle )) + 200;
      zaxis = RADIUS * cos( radians( angle )) + 200;
      set_arm( 0, yaxis, zaxis, 0 );
      delay( 1 );
  }
}

Here is one pretty good "how to" on robot arms; however, it is in Spanish - but google translate does a fairly good job with it:

As far as design of a robot arm is concerned, there is actually a ton of literature out there, mostly in dead-tree format - on industrial robotics design and control. A search on Amazon should turn up some titles. The uArm's design was based on an ARB palletizing robot - so it should be fairly easy to duplicate. I too am disappointed in what is quickly seeming to be turning into yet another KS scam. Fortunately, both I and another member of these forums were sent the laser cutter files for the arm - so the data isn't lost. I haven't released them yet, and I won't until I know for certain that the whole KS thing was a wash/scam. I guess I'm still holding out hope. That, and I said I wouldn't to the guy who sent them to me - but if it is a scam, all bets are off.

You might also look into how the old Armdroid and Microbot TeachMover robot trainer arms were constructed as well; there is actually a ton of info on the Armdroid out there, possibly enough to recreate it...

Finally - at