Robotic Arm: Team A-November

From ENGR005 2008
Jump to: navigation, search

Team A-November is a lab group for the E-5 Robot Arm project. The A-November arm consists of two servos, two pieces of aluminum tubing, and various other hardware,used to create an arm of total length 35.5 cm with two degrees of freedom and the ability to be controlled by a computer. Specifically the arm draws a circle in a box, when a MatLab script is run.

Team Members

Design

Our Arm

To build the arm we were given two servos and our choice of several brackets and pieces of tubing. First we attached the servo motors to brackets so that they could be attached to other parts. The first bracket (the "shoulder") is a stand that holds the motor fixed several inches above the writing surface. The second, "elbow", bracket consists of a piece of sheet metal used to attach the servo to the upper arm and a "C" shaped bracket attached to output of the servo on one end and the lower arm on the other. The aluminum tubes we used were longer than most of the choices available because we felt that the shorter arms would limit both the range of motion of the arm and the size of our drawings. As we were choosing parts to make the arm we did use smaller tubes originally, but in the end we found that we preferred the longer arm. As we found out when we were testing it, the long arm did have its drawbacks. The distance from the servos of the pencil made every jerk of the motor a big jump. A smaller, sturdier design may have produced smoother drawings.

MatLab

To draw the circle inside the square, and to create a real time on-screen simulation we used one script. here is he source for that script:

Our robot drew this
    s=instrfind;    %Find any serial links (we can have only 1)
    delete(s);      %... and delete.
    %Create a new serial communications link - don't worry about details,
    s=serial('COM1','Baudrate',115200,'Terminator','CR');
    fopen(s);   %... and open it
    la=18; %length of the upper arm
    lb=17.5; %length of the lower arm
    T=.25; % time for each movment
    numPts=40; %number of points on each side of the square (1/4 of the number of pts on the circle)
    r=5; % radius of the circle
    %generate arrays for x2 and y2 (the end of the arm).
    x2=[linspace(20,20,numPts*.5), linspace(20,10,numPts), linspace(10,10,numPts), linspace(10,20,numPts), linspace(20,20,numPts*.5)];      
    y2=[linspace(15,20,numPts*.5), linspace(20,20,numPts), linspace(20,10,numPts), linspace(10,10,numPts), linspace(10,15,numPts*.5)];
    clf % clear the figure. 
    % loop through all the values of x2 and y2
    for i=1:length(x2),
       %First do inverse kinematics to find angles (for simulation)
       [theta_a, theta_b]= InverseKinematics(la, lb, x2(i), y2(i));
       %Then do forward kinematics to find arm locations.
       [xa ya xb yb] = forwardKinematics(la, lb, theta_a, theta_b);   
       gotoPts(s,x2(i), y2(i), la, lb, T*1000);   
       subplot(1,2,1);   %generate 1x2 plots, choose plot 1
       plot([0 xa xb],[0 ya yb],'b','LineWidth',2);
       axis([-35 35 -35 35]);
       axis('square');   
       subplot(1,2,2);   %choose second plot
       plot(xb,yb,'r.')  %plot red dots
       axis([8 22 8 22]);
       axis('square');
       hold on;          %don't erase this plot.
       pause (T);
    end
    theta=linspace(0, 2*pi, 4*numPts); %Generate and arry of angles theta around the circle.
                                       %we will draw 1 point at each angle.
    % loop through all the values of x2 and y2
    for i=1:length(theta),
        x2=r*cos(theta(i))+15; %find x & y for each theta, for the unit circle,
        y2=r*sin(theta(i))+15; % then scales by the radius and shifts to (15,15) (the center of the drawing)    
       %First do inverse kinematics to find angles (for simulation)
       [theta_a, theta_b]= InverseKinematics(la, lb, x2, y2);
       %Then do forward kinematics to find arm locations for the simulation.
       [xa ya xb yb] = forwardKinematics(la, lb, theta_a, theta_b);   
       gotoPts(s,x2, y2, la, lb, T*1000);   
       subplot(1,2,1);   %generate 1x2 plots, choose plot 1
       plot([0 xa xb],[0 ya yb],'b','LineWidth',2);
       axis([-35 35 -35 35]);
       axis('square');
       subplot(1,2,2);   %choose second plot
       plot(xb,yb,'b.')  %plot blue dots
       axis([8 22 8 22]);
       axis('square');
       hold on;          %don't erase this plot.
       pause (T);
    end

We use these functions in our script:

Simulation of the arm drawing
  • InverseKinematics - Find the angles for the shoulder and the elbow. In the script this is only used to help find the position of the elbow for the simulation. This function is used for the physical arm in the function gotoPts.
  function [ta, tb] = InverseKinematics(la, lb, xb, yb)
    %Calculate angles for given locations of the robot arms
    ta=atan2(yb,xb) - acos(((la^2)+((xb^2)+(yb^2))-(lb^2))/(2*la*sqrt((xb^2)+(yb^2))));
    tb=atan2(((yb-la*sin(ta))/(lb)),((xb-la*cos(ta))/(lb)));
    ta = ta * 180/pi;  %Convert angles to degrees.
    tb = tb * 180/pi;
  • forwardKinematics - Finds the (x,y) coordinates for the elbow and the pencil. (just for the simulation)
  function [x1, y1, x2, y2] = forwardKinematics(la, lb, ta, tb)
    %Calculate locations of arms of robot
    ta = ta * pi/180;  %Convert angles to radians.
    tb = tb * pi/180;
    x1 = la*cos(ta);      %find positions
    y1 = la*sin(ta);
    x2 = x1 + lb*cos(tb);
    y2 = y1 + lb*sin(tb);
  • gotoPts - Moves physical arm to put the pencil at any (x,y) coordinate (within its range)
  function gotoPts(s,x,y, la, lb, T)
    [ThetaA, ThetaB] = InverseKinematics(la, lb, x, y);
    ThetaA=ThetaA-115+90;
    ThetaB=ThetaB-170+90;
    ThetaB=ThetaB-ThetaA;
    pwA=(ThetaA-1.6e+002)/-.11; %Convert theta to pulse width
    pwB=(ThetaB-1.5e+002)/-.1;
    pwA=round(pwA); % make the pulse width and integer
    pwB=round(pwB);
    % T is time for move (in mS);
    cmd=['#2P' num2str(pwA) '#1P' num2str(pwB) 'T' num2str(T)];
    fprintf(s,cmd);