I ran most of this lesson last year at a summer camp, but due to limited time/high variance in math background of the students, we weren't able to reach the point I wanted to reach. (Really what happened is that I volunteered to have another class join my class for three hours for an activity, which meant a lot of my prep time ended up being soldering leads on more potentiometers...)
This activity seemed promising so I went through it again, at a less hectic pace this time, to try and make a list of the tricky 'gotchas' that would be useful to provide as hints if the goal was to have most of the students complete the project in the class time allotted.
Students who have completed a class covering trigonometry should have sufficient mathematical background to cover the math, which is described nicely on this page: http://www.learnaboutrobots.com/inverseKinematics.htm
A partial list of the tricky parts students may get stuck on (beginners tend to try to build the whole thing at once; a few compound problems can make it very difficult to debug):
- Constructing the arm so it is sturdy enough to last until demonstration time.
- Including math.h and finding documentation for C trig functions
- Keeping track of radians vs degrees
- Measuring link lengths accurately and setting up the physical arm to match the model (the arm should physically be perfectly straight line if both servos are at their max range
- Mapping the analog inputs (reading from the potentiometers) to a reasonable range of the X and Y axis, in accordance with the units chosen for specifying the link length in the code
- Dealing with floating point error--floating point operations are not the optimal solution here but the goal here is to avoid adding more complex C programming concepts onto an already dense lesson. See the code for more detail. A good summary of the issues can be found here: http://www.engblaze.com/faster-code-fridays-avoid-floating-point-math/
- Using a separate power supply or filtering the Arduino power supply. The arm can otherwise get stuck in a cycle where servo moves, drawing a lot of power momentarily, which causes the analog inputs to jitter (and the onboard LEDs to flicker), which causes a new reading which causes the servo to move... Most students will use the separate power supply if it is provided, but it is also common for students to forget and tie everything to a single rail.
Here's an illustration of an issue that will happen if the student mounts the second link so that it cannot fold inwards. The green area on the left shows where the end of the second link (the 'hand') can reach. The shape is awkward to navigate. The right hand side shows the area reached by a better choice of angle limits for the second link. If it can fold inward, similar to how a human forearm/elbow/upper arm works, then it is easier to use. (This image assumes links are equal length).
I did mount the second servo flipped downwards, to reduce overall height of the assembly. That was a mistake in hindsight, because it means the arm can collide with itself.
Here's a video of the test arm I built, demonstrating that it more or less works correctly.
Finally here's the sketch. It isn't clean or commented...but I've decided it is better to share these things than to never get around to it at all.
Arduino Sketch for this project