This post details how grips are produced and how grips can be customised in Artichoke V1.2.
This tutorial is for:
You will need:
Brunel hand with Chestnut board, running Beetroot
Computer running Arduino
Beetroot incorporates 6 predefined grip patterns;
G0 Fist Grip
G1 Hook Grip (Fist Grip but with thumb extended)
G6 Finger Roll
G7 Thumb Roll
When using Serial control, the grip is selected based on the grip number (G#) entered, when using muscle control, the grips are cycled through from 0-7 when the outer forearm muscle is tensed for a set duration, and when using HANDle control, the grips can be cycled through by pressing either of the buttons.
(Each of the control methods ABOVE will link to their specific tutorial)
Each grip pattern is simply a combination of the individual finger positions, and each grip movement is a conversion of the desired grip position into the desired position of each finger within the grip. Passing a value of 0 - 100 to Grip.setPos() and then calling Grip.run() will map the target position from 0 - 100 to an individual position for each finger, using the positions in the defaultGripPos[ ][ ][ ] array (in Grips_default.cpp).
Without needing to know how the grip positions are processed (discussed in ‘COMPLEX’ section), you can modify the positions of the fingers within each grip by modifying the values within the 'default_GripPos[ ][ ][ ]' array within the 'Grips_default.cpp' file.
The array is split into 7 segments, where each segment represents one of the 7 grips. Each grip segment is then split into 5 columns, a grip position column (COUNT) and 4 finger position columns (F0 - F3 & F4).
The array can be read by looking at the grip segment you wish to modify, then read down the grip position column to the grip position at which you wish to modify the finger positions, the finger position at that grip position can then be changed.
For example, if you wish to modify the position of a finger when the hand is closed in the point grip, you would look at the third segment (POINT), look along the bottom row (COUNT = 100) and modify the finger position of the desired finger.
Both FULLY_OPEN and FULLY_CLOSED are defined presets within FingerLib.h, and are the maximum and minimum positions of the motors (50 - 973).
As detailed above, the array is read by first reading from the segment relating to the grip, the grip position is then used to determine the row of finger positions to use, however the actual function of this grip control is slightly more complex.
The class method 'Grip.run()’ starts by looking through the COUNT column of the desired grip pattern, and searches for two elements that the target grip position (0 - 100) is between. For example, in the above image, a grip position of 5 would be between Row 0 (COUNT = 0) and Row 5 (COUNT = 100); any BLANK positions are ignored and passed over.
After determining the two count values either side of the grip position (COUNT = 0 and COUNT = 100), the position of the finger is determined by reading the finger position along the same row as the COUNT values (e.g Row 0 & Row 5). If the finger position reading along the upper COUNT row is read as BLANK, then the finger position from the row above is used, and if the finger position reading along the lower COUNT row is read as BLANK, then the finger position from the row below is used. The grip position (0 - 100) is then mapped from the range of COUNT (0 - 100), to POS (finger pos at upper and lower COUNT vals), which calculates the finger position values between the ones in the array.
For example, to add an intermediate position for one of the fingers, simply add a position within the COUNT column (e.g. COUNT = 50) and then assign a position to a finger within the relevant finger column, on the same row as the COUNT = 50.
For more details see our old tutorial here.