Introduction

Instructions for building a self levelling hand for the InMoov robot (www.inmoov.fr) using slightly adjusted InMoov parts, an orientation sensor, an arduino nano and an additional servo.

Hardware 1

9629063c06bd9b11bd275eb3245c7b87b84adf2b

This is the part responsible for the magic. It is a joy to have such an easy to use accurate device available for only ~30€.

Hardware 2

Bdce56252374446cee3db47dd1fedace7daddb4e

For another ~25€ (2€ if ordered in china) you can get an arduino nano for reading the sensor data and control the rotation and bending servos.

Hardware 3

76c0142d8551dbe2d5392ce348bb450ae0575443

I use this servo for rotation and bending movement (Hobbyking). Specs are (6V) .15 sec / 60 deg. and 30 kg.cm and did cost 28€ each. They are digital and do a good job. Do not expect the hand to carry heavy stuff however, angles are small and the strings far off of being a human tendon.

To bend the wrist

74a207276adc3932c8ca235812c04bc60672ff1b

On this schema we have the hand to the left, the wrist to the right. In order to minimize friction the strings move over rolls on 3 redirection axis's. I used nails as axis and spacers on the nails to avoid sharp turns. The connections to the hand have a slight X-offset allowing 2 different spacers on the middle axis as they rotate in different directions when moving. I also added a honk to the hand to get a better point for pulling the hand up/down.

The Modified Hand

34c0e06cd2df3c2aef1b6c4c278c0ef60c332826

Here you can see the slightly offset honks to provide a better point for creating a bending movement. You can also see that I have rearranged the channels as I needed an area in the center to fix the strings. There is also a slighly larger middle channel for the thumb (middle hole to the right) as my sensor wires (4) need to pass through there.

Wrist to Hand Connector

828797ccd801aff285d4d94ff49c97364d64c1cc

This is the adjusted Rotawrist3 providing holes for the redirection axis and a reduced turn axis holder to avoid collisions with the hand when bending.

180 Degree Wrist Rotation

6fde13259bc67b241dc253304fddf3bfd8f72403

I spent quite some time on making the wrist rotate 180 degrees. Had a kind of working solution with the existing gears and a winch servo. However the winch servo just moved too slow and far and it did not result in a steady hand control. So I swiched to gears that allow a 180 degree wrist roatation with a 180 degree wrist servo. I do use thin strings (Marowil, 0.58 mm, ~50 kg) so I was able to squeeze the holes into the reduced size gear. The yellow holes are the ones for the bending strings. They have an X-offset to each other and make sure you use the correct hole for upper/lower string.

Reduced Gear Size

91c4e1aecde703a90040fbcc887bf8f10b1de61c

Needed to adjust Rotawrist2 for the smaller middle gear part. My servo with the gear on top also did not fit so I added 1 mm to the heigt of the part.

Rotawrist1

4facb4be3daf1d6f9abc333c5c2cb53b7fc602db

I needed 2 more holes for my bending strings. I also removed parts that prevented my servo to sink completely into the part.

Rotawrist1

Af4fea67622f81d990e70374beffefff6b7b2ce4

At the bottom I have added a connection block to allow for a fixing screw with the lower forearm.

Forearm

F4e6e39432857ce7f509c5f85356e28e1ef06488

The forearm has pillars for the bending servo. I decided to have this servo upright to get a more direct path for the strings when passing through the wrist gear.

Pulley

De6368a4454bc464cb0efd8d3a9815b2d16b320b

The pulley for the bending servo has an offset rotation axis because the strings do not move equal distances when the hand bends. As my math is not the best I spent a lot of time trying to find the right dimension and point of rotatioin for the pulley. Finally Excel Solver optimized it for me.

Tool for Redesigning Parts

All my adjustments to the parts have been made with OpenScad. I can load .stl files into my scripts and then modify the part in OpenScad

Hand Cover

Cfc92a19a8d6cb2caf27f4888a04203bb24d7e12

As the cover needed to be shortened to allow the bending movement it would have destroyed the InMoov inprint on it. I asked Gaël to make me a cover with a replaced inprint and he helped me out almost immediately (also complaining that it was a more time consuming task then he expected it to be).

Hiding the Sensor and Fixing Screws

33084f8cd62695ebd4e78aae2174efb6d883e7fb

Made some room for the sensor and screws inside the hand cover.

Programming the Arduino Nano

The adafruit bno055 comes with example code how to work with the sensor. My additions were rather easy.

**Some definitions for the servo controlling

#define PIN_COMMAND (8) int pitchServoPin = 9; int rollServoPin = 10; int FeedbackPin = 13; /* interne gelbe LED */

Servo rollServo; // create servo object to control turning movement Servo pitchServo; // create servo object to control bending movement

int CommandMode; int ModeBefore;

int rollValue = 1500; // variable to store the servo position int rollMin = 600; int rollMax = 2400; int rollRead; // normalized roll value int rollKorr = 5;

int pitchValue = 1500; // variable to store the target servo position int pitchMin = 600; int pitchMax = 2400; int pitchRead; // calibrated pitch value int pitchKorr = -1;

/* Set the delay between fresh samples */ #define BNO055SAMPLERATEDELAY_MS (20)

**... initialization of the pin used to activate the self control pinMode(PINCOMMAND, INPUTPULLUP); // the self-control is activated with pin in high state (1) ModeBefore = LOW;

... and the additions in the loop

/* Check for activated Command pin */ CommandMode = digitalRead(PIN_COMMAND);

if (CommandMode == HIGH) {

if (ModeBefore == LOW) {
    rollServo.attach(rollServoPin);  // attaches the servo on pin 10 to the servo object
    pitchServo.attach(pitchServoPin);  // attaches the servo on pin  9 to the servo object
    ModeBefore = HIGH;
    digitalWrite(FeedbackPin, HIGH);
}

/* Get a new sensor event */
bno.getEvent(&event);


/* use pitch value to change servo command
-----------------------------------------*/
pitchRead = event.orientation.y + pitchKorr;

if (abs(pitchRead) > 10) {
  pitchValue = pitchValue + (pitchRead * 5);
} else {
  pitchValue = pitchValue + (pitchRead * 3);
}

/* limit to min value */    
if (pitchValue > pitchMax) pitchValue = pitchMax;
if (pitchValue < pitchMin) pitchValue = pitchMin;


pitchServo.writeMicroseconds(pitchValue);

Serial.print("\tPitch: ");
Serial.print(event.orientation.y);
Serial.print("\t pitchServo target: ");
Serial.print(pitchValue);


/* as the sensor is below the hand the goal is to get 180 degree roll 
normalize the value
*/
if (event.orientation.z < 0) rollRead = 360 + event.orientation.z + rollKorr;
if (event.orientation.z >= 0) rollRead = event.orientation.z + rollKorr;
Serial.print("\trollRead: "); Serial.print(rollRead);


rollValue = rollValue - ((rollRead - 180) * 5);

/* do not cross the limits */
if (rollValue > rollMax) rollValue = rollMax;
if (rollValue < rollMin) rollValue = rollMin;


Serial.print("\t rollServo target: ");
Serial.print(rollValue);
rollServo.writeMicroseconds(rollValue);


/* New line for the next sample */
Serial.println("");

} else { if (ModeBefore == HIGH) { rollServo.detach(); // detaches the servo on pin 10 to the servo object pitchServo.detach(); // detaches the servo on pin 9 to the servo object ModeBefore = LOW; digitalWrite(FeedbackPin, LOW); } }

/* Wait the specified delay before requesting nex data */ delay(BNO055SAMPLERATEDELAY_MS);

Using MRL to Activate the Self-Levelling

In MRL (the software controlling the whole robot) Alessandro showed me how to control a digital pin in the main Arduino Mega to inform the Arduino Nano about its mode:

get a reference to the arduino to set a digital output pin

arduino = Runtime.getService("i01.right") # get arduino for pin setting keepHorizontalOutPin = 12 keepHorizontal = False arduino.pinMode(keepHorizontalOutPin, Arduino.OUTPUT) #set as output port arduino.digitalWrite(keepHorizontalOutPin, 0) #disable levelling

and a little function to pass control of the wrist to the Arduino Nano

def startSelfLevellingHand(): global keepHorizontal keepHorizontal = True i01.rightHand.wrist.detach(); arduino.digitalWrite(keepHorizontalOutPin, 1) #enable levelling

Conclusion

It was rather easy to create the prototype of the hand, actually adding it to the robot was a huge task. Not only did I spend a lot of time with adjusting, printing, adjusting, printing ... of the modified parts, in general the handling of the strings in the wrist sometimes forced me to a break as my fingers just couldn't handle it any more. There is still room for enhancement, I am planning to adjust the axis that connects the hand as it has a bit too much inpact on the fingers when bending it. Stay tuned and if you actually try to make your own let me know whether I left out something.

The respective author is responsible for articles (snaptips) within this service.

Leave a comment

xYou need to be logged in to leave a comment

Login