This example makes a robot arm track the mouse position. If you hold the left mouse button down and move the mouse, the arm moves so the wrist is at the mouse position, if that is possible.

See the post Draw a robot arm with a hand that points downward in C# for information about the basics of arm drawing and how the program keeps the hand pointing downward.

Often you need a robot to move to a particular position, perhaps to pick something up or put something down. For this example, we need to figure out how to move the arm so its wrist is at the mouse’s position.

To see how to do this, look at the picture above. Suppose the lengths of the upper and lower are L1 and L2. Then the elbow can reach any point on the orange circle, which has radius L1.

The purple circle, which has radius L2, shows the points that are distance L2 from the mouse position. If the elbow is at any position on the purple circle, then the wrist could be at the mouse position.

So all we need to do is find the points of intersection between the orange and purple circles. Those are the points where the elbow could be to place the wrist at the mouse position. See the post Determine where two circles intersect in C# to see how to find the points of intersection between the two circles.

After you find the points of intersection, there are still three issues to consider: the number of solutions, calculating joint angles, and constraining joint angles.

# Number of Solutions

There could be 0, 1, or 2 points of intersection between the two circles. (There are 2 in the picture above.)

If there are 0 intersections, then the arm cannot reach the mouse position. This happens if the position is too far away or if it’s so close to the origin that the lower arm can’t reach it.

If there is 1 solution, then the two circles just barely meet and there’s only one way the arm can reach the mouse position.

If there are 2 solutions, then the program arbitrarily uses the first one.

# Calculating Joint Angles

Normally the way you control a real robot arm is to specify the joint angles. For this example, that means we need to convert the elbow and wrist positions into joint angles.

If the difference in X and Y coordinate from the shoulder to the elbow are `dx1` and `dy1`, then the shoulder’s angle is `angle1 = arctan(dy1 / dx1)`.

Next if the difference in X and Y coordinate from the elbow to the wrist are `dx2` and `dy2`, then the elbow’s angle is `angle2 = arctan(dy2 / dx2) - angle1 - π`.

After the calculates the angles, the program sets its scroll bar values to show them.

# Constraining Joint Angles

Many real robot joints cannot turn to every possible angle. For example, a joint may be unable to reach very small angles. (Try bending your elbow to 0 degrees so your wrist is inside your shoulder.) In this example the values allowed by the scroll bars do not permit every possible angle.

To satisfy those constraints, the program checks the angles it calculated. If either one lies outside of the allowed values, then the program tries to use the other point where the two circles intersect.

That means the program sometimes jumps discontinuously from one point to the other when you move the mouse around. Obviously a real robot arm could not do that so you would need to be careful not to make the wrist follow a path that required that kind of jump.

In some real robot arms you can record motion and play it back. You first put the robot in recording mode. You then grab the hand and move it where you want it to go. Later you can play back the recorded motions.

Note that the problem is different for different arm configurations. For example, if the arm has three sections (upper, middle, and lower arm), then there are usually an infinite number of ways you can put the arm in a particular position. That extra flexibility means you will need to jump discontinuously less often, but it also means you need a way to pick one of the possible solutions.