Uncategorized

Robot Arm IK Singularities Problem: Can you help?

My goal is to make a 6 degree of freedom robot arm for less, and make it available to everyone.

My first robot arm was 3 degrees of freedom. Given what I’d made before it was pretty straightforward.

My next is an attempt at 5 degrees of freedom.

I’ve got forward kinematics working in software. I tell the shoulder to move and then I can get a point describing the finger tip position and two vectors that describe the finger orientation.

I’m really really stuck on the inverse kinematics. With inverse kinematics I have the position and orientation of the finger tip and I want to find the angle of each joint. I can calculate the position of the finger tip, the wrist, the elbow, the shoulder, and the base. I can even reuse the code from the 3DOF arm to find the angle of the base, the shoulder, and the elbow. The trouble is the angle at each of those positions.

Singlularities

Try this: grab your right index finger with your left hand, then move your right elbow without moving or turning your finger. Each elbow position is a valid answer to the question “how do I move my arm to put the finger here?” A singularity is when there are many answers for the same question, and singularities are trouble for programmers.

Here’s the latest code so you can see for yourself. A picture is worth a thousand words. what’s an interactive simulation worth?

If you have Java you should be able to run this program. fingers crossed! Definitely with eclipse. WASD flies around, QE flies up/down, left click+mouse movement looks around. RF,TG,YH,UJ,IK,OL move the six joints. P switches between forward kinematics (default mode) and inverse kinematics.
You’ll see that in FK the thick model and the thin model always follow each other. In IK the thin model is correct and the thick model is way off. It’s pretty easy make the fat model suddenly flip over or turn unexpectedly – try U and J to make the wrist wave like paint fence:

The software tries to use the bend in the wrist to figure out the twist in the wrist, which doesn’t work the moment the wrist goes totally straight or flips over.

If your code-fu is greater than mine, please show me how it’s done. I’d love to talk to any robotics people out there who might be able to shed some light on this. I feel pretty silly reinventing the wheel. Please help, internet hive mind!

Uncategorized

Robot arm update

I’ve committed myself to writing something every weekday for the next month, even if it’s pretty short.

Today I’m working on the robot arm software, overcoming a few challenges. You can read about my latest progress.

Send me questions about what you’d like to see here and I’ll get some more written.

Side note: this weekend broke single-day sales record. Woo!

Uncategorized

How to Make a Line Following Robot

So you’ve just finished your Arduino Starter Kit and now you’re wondering “what next?”  Let’s take what you’ve learned and put it into a line following robot.

Line following robot CANDO2

(more…)

Uncategorized

How Makelangelo turns images to gcode

Lots of people are suggesting great ideas for new image filters on the Makelangelo. I wish I had time to do them all myself. As a compromise I’d like to make it so easy to write new filters that anyone can do it.  I’m going to walk you through the simplest image filter and show you how it works.

Here is the image I converted to gcode:

original

Here is the result as it looks in the Makelangelo program after I converted it with the “scanline” style:

Converted

In general the process is:

  • load a picture.  This has been done for you before the filter starts.
  • move around the picture and interpret what you see as you go.  This is where you do your magic.
  • write down what you interpret as instructions for the robot.  This has been made simple.

Let’s take a look at a practical example, based on the converted image above.  In the github project you’ll find several Filter_* classes.  The simplest Filter has only one method called Convert.

[code]public void Convert(BufferedImage img) throws IOException {
// The picture might be in color.  Smash it to 255 shades of grey.
Filter_BlackAndWhite bw = new Filter_BlackAndWhite(255);
img = bw.Process(img);  //"process" is for filters that change the original image.  "convert" should create a few file without modifying the original.

// Open the destination file
OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(dest),"UTF-8");
// Set up the conversion from image space to paper space, select the current tool, etc.
ImageStart(img,out);
// "please change to tool X and press any key to continue"
tool.WriteChangeTo(out);
// Make sure the pen is up for the first move
liftPen(out);

// figure out how many lines we’re going to have on this image.
int steps = (int)Math.ceil(tool.GetDiameter()/(1.75*scale));
if(steps<1) steps=1;

// these next three might not be strictly necessary.  Call me paranoid.
lastup=true;
previous_x=0;
previous_y=0;

// Color values are from 0…255 inclusive.  255 is white, 0 is black.
// Lift the pen any time the color value is > level (128 or more).
double level=255.0/2.0;

// from top to bottom of the image…
int x,y,z,i=0;
for(y=0;y<image_height;y+=steps) {
++i;
if((i%2)==0) {
// every even line move left to right

//MoveTo(file,x,y,pen up?)
MoveTo(out,(float)0,(float)y,true);
for(x=0;x<image_width;++x) {
// read the image at x,y
z=TakeImageSample(img,x,y);
MoveTo(out,(float)x,(float)y,( z > level ));
}
MoveTo(out,(float)image_width,(float)y,true);
} else {
// every odd line move right to left
MoveTo(out,(float)image_width,(float)y,true);
for(x=image_width-1;x>=0;–x) {
z=TakeImageSample(img,x,y);
MoveTo(out,(float)x,(float)y,( z > level ));
}
MoveTo(out,(float)0,(float)y,true);
}
}

// TODO Sign name here?

// pen is already lifted.  Return to home.
tool.WriteMoveTo(out, 0, 0);

// close the file
out.close();
}[/code]