Andrew Hoyer
 

about

experiments:

(sudoku solver)

(simple fractals)

(cloth simulation)

(numbers to words)

(particle systems)

(quantum cryptography)

(something a day)

(drip sessions)

photos (flickr)

work

 

flickr (dolinski)

facebook

twitter

linkedin

email

 

Getting off the hook:

Any downloadable material on this site is provided as is. If something bad happens, Andrew Hoyer will in no way take any responsibility (though he would most definitely send his heart felt remorse). © 2010 Andrew Hoyer

 
Wikipedia Affiliate Button

Robotic Arm:

Moving your arm to a certain point may seem like a super simple task, but for a computer this isn't the case. To do this, the problem is transformed into that of non-linear root finding.

Click within the bounding circle to make the arm move around.

 

How it actually works:

First, each section of the arm looked at individually so that we can come up with a general equation that describes the arm as a whole. This equation, when given a set of angles, should calculate the (x,y) position of the arm. This is probably the most important step, as without an accurate model of how the arm is to behave, the later calculations would not be possible.

Now that we have a way to model the arm and calculate where it currently located, we need a way to do the inverse of this. e.g Given an (x,y) coordinate try to calculate the angle of each arm to reach the (x,y) point. This is inherently more difficult as we're dealing with non-linear equations. To do this I used Newtons iterative method of root finding in two dimensions, if you want you can read more about it here. Though I'm not going to go into the details of these calculations here as they will likely be uninteresting to most people...

So now assuming we have a way of calculating the angles that are required to move the arm to a specified point, the problem is basically solved. If you're really curious about how everything actually works you can keep reading below.

Wacky fun details (for the nerd in us all):

Note: if you're not sure what a derivative or a matrix is, this part may not be for you...

Lets start by looking at the equations that actually describe the arm. Each axis is calculated individually depending on the length of the arm and the angles at which the joints are positioned.

function calcPos(t){
    var x = Math.cos(t.elementAt(1)) + Math.cos(t.elementAt(2));
    var y = Math.sin(t.elementAt(1)) + Math.sin(t.elementAt(2));
    //returns a vector.
    return $V([ARM_LENGTH*x,ARM_LENGTH*y]);
}

You can see that each arm follows are rather simple equation, pretty much like using polar-coordinates.

The next big thing is to explain how iterative root finding actually works. There are many ways to do this, some faster and maybe more accurate than others. For its simplicity and speed (and partially because I like saying the word Jacobian) I chose to use Newtons method. In one dimension this approach is dead simple:

  1. Choose a starting point.
  2. Calculate the derivative at that point.
  3. Find the point at which the derivative crosses the x-axis.
  4. Use this as a starting point for the next set of calculations.
  5. Repeat starting at step 2.

The multidimensional approach is almost the same, though instead of calculating the derivative at a single point, you calculate a Jacobian matrix (which is essentially the derivative with respect to every variable in every equation) at a multidimensional point. Heres what the calculation of the Jacobian actually looks like:

function calcJacobian(t){
    var f1 = -ARM_LENGTH*Math.sin(t.elementAt(1));
    var f2 = -ARM_LENGTH*Math.sin(t.elementAt(2));
    var f3 =  ARM_LENGTH*Math.cos(t.elementAt(1));
    var f4 =  ARM_LENGTH*Math.cos(t.elementAt(2));
    //returns a matrix.
    return $M([[f1,f2],[f3,f4]]);
}

If you're wondering where these equations are coming from, f1 is the derivative of the 'x' function (from calcPos) with respect to the first angle, f2 is the derivative of the 'x' function with respect to the second angle, f3 is the derivative of the 'y' function (from calcPos) with respect to the first angle, f4 is the derivative of the 'y' function with respect to the second angle.

Now we're pretty much ready to actually show how Newtons method in 2D takes place:

function calcThetas(position, theta){
    var n = 40;
    for(var i=0; i<n ;i++){
        var f = calcPos(theta).subtract(position).scale(-1);
        var J = calcJacobian(theta);
        var s = J.solve(f);
        theta = theta.add(s);
        if(s.length() < (1e-6))
            break;
    }
    return theta;
}

calcThetas takes two arguments: position which is the final position that we actually want to reach, and theta which is the starting angles of the arm. Essentially what happens here is that we want to solve the system [Jacobian]*[s] = [-pos] for the variable [s]. Where [s] is the step value which we then add to the angles we're trying to calculate. If everything goes as planned, [s] will start out rather large and then quickly decrease such that it adds a negligible amount to theta, at which point we can stop iterating as we've found what we were hoping to calculate!

Now it should be noted that Newtons method doesn't always converge, meaning that the '[s]' variable grows instead shrinks as the iteration goes on. This was a big problem when I first started coding the arm (the arm would flail wildly and then land on the wrong position). To combat it, I divide the path between the arm's current position and the desired position into 25 pixel sections and then perform newtons method on each section. This pretty much guarantees that Newtons method will converge to the root. And now we're pretty much done!

Woo-Hooo!

Supported Browsers
safari firefox chrome opera
3 3 4? 10?