Figure 8. These buttons provide the human interface
to control the arm.
And Now, The Task
The arm will be able to move or stack three different
colored sheets of paper at four specific places in the work
area. The human interface with the arm will consist of a
series of buttons as shown in Figure 8. Using the buttons,
the user will be able to move the arm to one of the four
positions and pick up or drop a paper block. The user can
also request more complex actions such as PICK UP GREEN
or even something relatively complicated such as putting the
YELLOW ON RED.
In the above examples, we will want the arm to
demonstrate a reasonable amount of intelligence. The arm,
for example, should ignore a request to DROP a block if it is
not holding one. Even in complex situations, the arm should
try its best to achieve the requested goal. If, for example, you
ask it to place the YELLOW block on the RED block, it should
first clear any blocks that may already be on the RED block,
placing them at some temporary positions. It should then
pick up the YELLOW block, automatically discarding any
blocks that might be stacked on it, and finally drop the
YELLOW block on the RED block.
The program we are going to write will perform all of
the above functions and more, but it will not necessarily carry
out its orders in the most efficient manner because we will
use simplifications when possible. These simplifications will
ensure that the code will be easy to write and understand,
even for beginners. Once you see how the code works, we
encourage you to modify it in ways that eliminate some of
the idiosyncrasies created by our simplifications.
In order to make it easy to follow the logic of the code,
we will explore it using a top down approach. The most
complicated routine of our system is certainly the one that
can place any block on another block. In the spirit of
top-down design, this routine can be easily created if we
assume we have modules that can perform specific tasks for
us. The code to implement this ColorOnColor subroutine is
shown in Figure 9. The routine assumes that the human
interface portion of our code will put the source color
(Yellow in Figure 8) in the variable curcol1 and the
destination color (green in Figure 8) in the variable curcol2.
Notice how easy it is to implement this complicated routine if
we assume we have modules that can do the work for us.
The first thing this routine needs to do is remove any
blocks that may be on top of the destination color. We can
Robotic Arm Fundamentals
ColorOnColor:
// places color curcol1 ON curcol2
block = curcol2 // clear dest block
gosub PickUpColor
gosub Drop
block = curcol1
// get the block to stack
gosub PickUpColor
block = curcol2
gosub MoveOver
gosub Drop
return
Figure 9. This routine completes a complicated task by
letting other modules do most of the work.
easily clear away all the blocks by simply picking up the
destination color and then dropping it. This means that our
assumed subroutine PickUpColor must perform all that is
necessary to pick up the block whose color is held in the
variable block, including the discarding of any blocks piled on
it. The Drop routine will simply put the block currently held
by the hand down at the current arm position.
The next thing this routine needs to do is pick up the
source block, specified by curcol2. It can do this easily by
using the PickUpColor routine again. Next, a new routine,
MoveOver, will move the arm to the position of the block
specified by the variable block. At this point, the arm is holding the source block and is currently positioned over a cleared
destination block so all we have to do is call Drop again.
The power of this simplicity should not be taken lightly.
Our ColorOnColor routine operates much like the executive
of a large corporation who makes decisions about what
needs to be done, but relies on the expertise of appropriate
managers and workers to carry out the tasks. All of the
actual work performed in the ColorOnColor routine is
handled by subordinate subroutines. Of course, we must
build those routines too, and if they are complicated we will
assume there are even more subordinate routines to provide
additional help.
The MoveArm subroutine mentioned earlier will reside
at the lowest level of our hierarchal structure of subroutines
and directly control the hardware. None of the upper level
routines will access the hardware at all. This means you can
easily utilize most of the code designed for this project with
any arm you might build (regardless of what type of motors
you want to use) by simply writing your own MoveArm
routine. This principle allowed us to create a MoveArm for
our simulated arm so that you can experiment with our code
or write totally new routines of your own without the need
for a physical arm. You can download the complete
demonstration software discussed in the article, the full
source code for the simulated arm, as well as your copy of
RobotBASIC from www.RobotBASIC.com. SV
SERVO 05.2009
43