Kurzbeschreibung

building a 3D printed robotic gripper for Poppy humanoid 

Dokumentation

Arbeitsplan : 

In der ingenieruspraxis mit dem Thema “ Poppy Humanoid Sensors “ soll für den Poppy einen Greifer entworfen werden , der durch einen Muskel Sensor gesteuert wird . 

Erste aufgäbe wird es sein die Motoren von Poppy zu konfigurieren mit Hilfe von Herborist und zwar die IDs und angle limits zu bestimmen. Anschließend wird der Greifer von der Skizze zum extrudierten 3D-Modell mit Onschape erstellt. Dieser schritt hat am längsten gedauert . Der Schwerpunkt dabei ist das , dass der Greifer  gleichzeitig zu Poppy und zu dem Servomotor passen muss . Deswegen war das design irgendwie begrenzt und die Dimensionen sehr klein . Was der 3D-Druck kompliziert gemacht hat.

Zweite aufgäbe war nämlich den Muskel sensor von Grund auf neu mit Hilfe von 2 Chips zu bauen . Bei diesem Process geht es darum , die Muskel Aktivität zu messen  und danach zu verarbeiten , um sie zu dem Mikrocontroller geeignet zu machen . 

Anschließend werden alle diese Teile zusammen mit Hilfe von Arduino (bzw ESP8266) verbunden . Ein Programm leitet das EMG verarbeitete Signal von den Oberflächenelektroden zu dem Greifer weiter . 

Motor configuration :

Während mein Ingenieurpraxis habe ich die einzelne Motoren von Poppy Humanoid konfiguriert . Dazu habe ich Herborist benutzt . Das ist ein grafisches Werkzeug in Python geschrieben .

Man soll immer nur einen Motor auf ein mal mit Odroid xu4 verbinden ansonsten könnten die IDs von den einzelnen Motoren verwechselt werden . 

Dann setzt man : 

    • die IDs entsprechend die Konvention .
    • Baudrates : 1 000 000 bps .
    • Delay time :  0 ms .

Der Betriebswinkel den Robotis dynamical ist zwar 0° - 360° aber für einen einwandfreien Betrieb dem Poppy soll man Grenzwerte für die winkeln einsetzen . 

durch experimentieren mit den einzelnen Motoren könnte ich die angle limits festgestellt . 

Hierbei sind die Namen , IDs und angle limits den einzelnen Motoren : 

3D-gedruckter-Greifer :

Für den Poppy humanoid habe ich einen 3D gedruckter Greifer entworfen .  Der Greifer besteht aus 4 Teile und einen servo Motor :

a. Gripper-Fixation :                                           

Dieses Teil verknüpft den Servomotor  mit dem Robotic Arm . Dieses teil ist sehr wichtig für einen einwandfreien betrieb des Greifers und muss gleichzeitig perfekt zu dem Unterarm von dem Poppy. 


   Bild 1.3 : Onshape drawing : gripper-fixation

https://cad.onshape.com/documents/fff4dc0efbc05805462f921e/w/b7c3b53d66185136d8881f4e/e/059b9f95a6b81862fef529b2


b.  Gripper-fixed-part :  

 Diese teil ist fix und ist direkt an dem Gripper-Fixation mit zwei Schrauben M2  befestigt .

Dieses teil hat die selbe Dimensionen wie das rotierende teil .

 Das komplizierte teil war dabei , das graue Detail so zu platzieren , damit das fix-und das rotierende Teil symmetrisch miteinander fallen. 

Bild 1.4 : Onshape drawing :Fixteil 

https://cad.onshape.com/documents/fd77a92e48fa024d438dfd4d/w/a72f2f51e61ea5b639ad088f/e/cfa28743da3fa253a6c9817d


 c. Sockel :

Am Anfang hatte ich vor , einfach eine Achse an dem Servomotor zu kleben um den Greifer  rotieren zu lassen . Anschließend habe ich mich entschieden eine neue Basis für den Servomotor zu bauen . 

Sie dient dazu , das rotierenden Teil an dem Servomotor  zu befestigen und einen symmetrischen Aufbau dem Greifer zu sichern . 

Bild 1.5 : Onshape drawing : Sockel 

https://cad.onshape.com/documents/cff903a3c38e64aec3d7ba55/w/a86681e70fcb1e989488f430/e/ce4c0083a55c7941d88d50c8


            d.  Gripper - rotative - part :  

    Das rotierende Teil dem Greifer ist gleichzeitig an dem Servomotor und dem Sockel befestigt . 

    Wegen fehlenden freiheitsgrades ist der Betriebswinkel dem Servomotor  : 34° , 161° geworden . 

Bild 1.6 : Onshape Drawing : das Rotierende Teil 

https://cad.onshape.com/documents/c5c584afafdb0af16cb1c707/w/38fc4e26aadc7033526ebeba/e/566b5f115f8f11cc373549ab



Assembly 

 Fixation wird an den Fixteil dem Greifer mit zwei Schrauben (diameter 2.5 ,länge 4 mm) befestigt.                      

Der Sockel wird an den Servo geschraubt . 

Mit einer Schraube ( diameter 2.5 mm  , länge 8 mm ) wird der servo motor und das Fixation verbunden . 

Das rotierende Teil dem Greifer wird einfach an dem servo montiert . 

Der Greifer wird dann mit zwei Schrauben ( diameter 2 mm , länge 30 mm ) und zwei Nüsse an Poppy befestigt . 


MQTT , ESP8266 und Greifer :

 Das Programm stellt eine Verbindung zu einem MQTT server her . Es abonniert den Topic “ servo “ , konvertiert die “ messages “ zu String und gibt sie auf den Bildschirm wieder aus . Bei diesem Programm werden die Nachrichten wieder zu Integer konvertiert und mit dem Befehl “ int pos = map(resultado, 1, 100, 32, 165); “ : rechnet den Wert in den Wertebereich des Servomotors (zwischen 34° und 161°) . Der servomotor wird auf eine Position gesteuert , die mittels die von einem MQTT client veröffentlichten Nachrichten festgelegt wird .“ myservo.write(pos)“.

https://github.com/Mariemnoui/mqtt-servo-client/blob/master/MQTT_client.servo.ino

 Hier stellt ein MQTT client eine Verbindung zu dem MQTT server und veröffentlicht die Nachricht “50” zu dem Topic “ servo “ . Diese Nachricht stellt die Goto-position von dem Servomotor . 

 Der servomotor ist mit dem VIN , GND  und dem  digitalen Pin D4 verbunden .

MQTT_client.servo
#include <ESP8266WiFi.h>
#include <PubSubClient.h>



#include <Servo.h> 
Servo myservo; 



const char* ssid = "LDV-CPP";
const char* password = "LDV-LK-C++";
const char* mqtt_server = "ajax-der-kleine.clients.ldv.ei.tum.de";    ///broker MQTT
 
WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;

void setup() {

  Serial.begin(115200);
   myservo.attach(2);  // attach your servo to pin D4 
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
}

void setup_wifi() {

  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void callback(char* topic, byte* payload, unsigned int length) {
   String string;

  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
   // Serial.print((char)payload[i]);
     string+=((char)payload[i]);  // converting the message received to a string 
  }
  
    Serial.print(string);

if (topic ="servo")   
    Serial.print(" ");
   int resultado = string.toInt();   // converting the string to integer 
   int pos = map(resultado, 1, 100, 32, 165); // converting the integer to an Angle for the servo motor 
   Serial.println(pos);
    myservo.write(pos);
    delay(15); 
   
 }


void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("ESP8266Client")) {

      Serial.println("connected");
      client.subscribe("servo");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}
void loop() {



   
  if (!client.connected()) {
    reconnect();

  }
  client.loop();


 delay(100);
  
}


Muscle Sensor : 


Statt ein ready-to-use muscle sensor zu benutzen habe ich selbe einen aufgebaut . Dieser sensor besteht hauptsächlich aus zwei Chips : TL072 IC und INA106 IC

Bei diesem Sensor geht es um die Bearbeitung der gemessenen Spannungsdifferenz zwischen die zwei Elektroden an dem Muskel . Diese Bearbeitung besteht aus 4 Schritte : 

    1. Signal Erwerbung :

Bei diesem Teil geht es um die Erwerbung des Signals durch die Messung der elektrischen Impulse , die die Muskelfasern aktivieren. Dazu benutzt man hauptsächlich den INA106 chip .


    2. Signal Verstärkung :

  Hier wird das erworbene Signal invertiert und verstärkt . Dazu benutzt man den TL072 Chip . Mit einem Hochpassfilter kann man das DC offset (offsetting of a signal from zero) entfernen . 


    3. Signal Rektifikation :

Da das Signal im 2.Schritt invertiert wurde muss man den negativen Teil wieder positiv machen durch ein active full-wave rectifier bestehen unteranderem aus einem TL072 Chip  . Danach mit Hilfe von einem Tiefpassfilter wandelt man das AC signal zum DC um . Das letzte Schritt ist genauso wichtig um das Signal für den Mikrocontroller zu bereiten .


    4. Signal Glätten :

Mit einem Tiefpassfilter  hat man das Signal glatt gemacht und bereit für den Mikrocontroller . Der Tiefpassfilter besteht hauptsächlich aus einem TL072 Chip , Widerstände und Kondensator . Mit Hilfe von einem Potentiometer kann man die Verstärkung ändern .

muscle sensor.mp4

a schematic circuit of the Muscle Sensor using LTspice : 

 

Bevor man den sensor an dem Mikrocontroller ansteckt muss man prüfen dass die Spannung an dem Ausgang des Sensors in dem erlaubten Spannungsintervall von dem Mikrocontroller passt 

Ich habe hier ein Oszilloskop benutzt.Die gemessene Ausgangsspannung  von dem sensor war ca 0.7 v und ich habe einen Arduino benutzt . Bei dem ist die eingangsspanung : 0-5V

 ARDUINO , Muskel Sensor und Greifer :

 Bei diesem Abschnitt geht es um die 

Steuerung von dem Greifer mit Hilfe von der elektrischen Muskelaktivität . 

Die Oberflächenelektroden messen das Aktionspotential eines ganzen Muskels . 

   Rot : Referenz 

   Grün : Mid Muskel 

   Gelb : End Muskel 

deswegen ist eine präzise Platzierung der Elektroden auf das Muskel ganz wichtig . Diese Prozess heißt Die Elektromyografie (EMG). 

Die elektrische Aktivität des Muskels wird dann an dem sensor abgeleitet und dort verarbeitet. 

Nach der Verarbeitung ist das EMG signal Betriebsbereit für den Mikrocontroller . Mit einem geeigneten Arduino Programm könnte ich durch Beobachtung des serial Monitor den Mittelwert der elektrischen Aktivität im ruhenden und im kontrahiertem Muskel bestimmen.

Bild 1.14: Serial Plotter : EMG Signal 

Dieses Arduino-Programm dient dazu , das verarbeitet EMG Signal zu dem Greifer herzuleiten . 

Mit Hilfe von einem if-command wird der Greifer durch die Muskel Aktivität gesteuert .

https://github.com/Mariemnoui/Muscle_sensor_servo-/blob/master/muscle_sensor_servo_.ino

Wiring : 

     

Pin 1 von dem letzten TL072 Chip geht zu Pin A5 von dem Arduino ( Analog Input Erforderlich ) 

Servo Motor geht zu Pin 1 von Arduino ( Digital (PMW))

muscle_sensor_servo_
#include <Servo.h> 


const int x = 200 ; //This is the reference value and it

//will depend on your setup. You have to find it out 

//yourself by looking at the serial monitor and finding

//a value between the maximum and minimum value.



//Naming the servos

Servo servo;





void setup() 

{ 

//Starting the serial monitor

Serial.begin(9600); 




//Configuring servo pins

servo.attach(2); // pinky




} 





void loop() 

{ 

//Printing the EMG data

Serial.println(analogRead(5)); 




//If the EMG data is greater than x the hand closes

  if(analogRead(5) > x) {

    servo.write(160);

    

  }




//If the EMG data is lower than x the hand opens

  else if (analogRead(5) < x) {

    servo.write(34);

    

  }




//A delay to slow down the process

  delay(100);

} 





 ESP8266,Muskel Sensor und MQTT :

 Bei diesem Programm geht es darum , Nachrichten zu den Topic “servo” zu veröffentlichen . 

Wenn das eingetroffene Signal größer als der Grenzwert bedeutet das , dass der Muskel kontrahiert ist . Dann wird die Nachricht “hand closed” zu dem Server veröffentlicht ansonsten wir “hand open” veröffentlicht. 

diese Programm kann dazu beitragen , der Greifer mit Ordroid XU4 zu verbinden . Dadurch , dass der Ordroid zu dem selben Topic “servo” abonniert , diese Nachrichten erhalt und sie zu einem Mikrocontroller (u.a Arduino),der einem PWM Ausgang hat ; weiter leitet . Der Mikrocontroller steuert dann , mit den erhaltenen Nachrichten , den Servomotor von dem Greifer . 

https://github.com/Mariemnoui/mqtt_publish_servo/blob/master/mqtt_publish_muscle_sensor_.ino




IMG_9019.mp4IMG_9020.mp4

mqtt_publish_muscle_sensor_
#include <PubSubClient.h>

#include <ESP8266WiFi.h>




#define MQTT_SERVER "ajax-der-kleine.clients.ldv.ei.tum.de"

const char* ssid = "LDV-CPP";

const char* password = "LDV-LK-C++";

const int x = 800 ; //This is the reference value

char* Topic = "servo";

//MQTT callback

void callback(char* topic, byte* payload, unsigned int length) {

  //we're not subscribed to any topics so we dont need to have anything here

}




WiFiClient wifiClient;

PubSubClient client(MQTT_SERVER, 1883, callback, wifiClient);

void setup() {

 //start the serial line for debugging

  Serial.begin(115200);

  delay(100); 

//start wifi subsystem

  WiFi.begin(ssid, password);




  //attempt to connect to the WIFI network and then connect to the MQTT server

  reconnect();




  //wait a bit before starting the main loop

      delay(2000);

}




void loop() {

   //reconnect if connection is lost

  if (!client.connected() && WiFi.status() == 3) {reconnect();}

    client.loop();

    if(analogRead(A0) > x) {

      client.publish(Topic,"hand closed");

    

  }




//If the EMG data is lower than x the hand opens

  else if (analogRead(A0) < x) {

    client.publish(Topic,"hand open");

    

  }




//A delay to slow down the process

  delay(100);




}




void reconnect() {




  //attempt to connect to the wifi if connection is lost

  if(WiFi.status() != WL_CONNECTED){

    //debug printing

    Serial.print("Connecting to ");

    Serial.println(ssid);




    //loop while we wait for connection

    while (WiFi.status() != WL_CONNECTED) {

      delay(500);

      Serial.print(".");

    }




    //print out some more debug once connected

    Serial.println("");

    Serial.println("WiFi connected");  

    Serial.println("IP address: ");

    Serial.println(WiFi.localIP());

  }




  //make sure we are connected to WIFI before attemping to reconnect to MQTT

  if(WiFi.status() == WL_CONNECTED){

  // Loop until we're reconnected to the MQTT server

    while (!client.connected()) {

      Serial.print("Attempting MQTT connection...");




      // Generate client name based on MAC address and last 8 bits of microsecond counter

      String clientName;

      clientName += "esp8266-";

      uint8_t mac[6];

      WiFi.macAddress(mac);

      clientName += macToStr(mac);




      //if connected, subscribe to the topic(s) we want to be notified about

      if (client.connect((char*) clientName.c_str())) {

        Serial.print("\tMTQQ Connected");

        client.subscribe(Topic);

      }




      //otherwise print failed for debugging

      else{Serial.println("\tFailed."); abort();}

    }

  }

}




//generate unique name from MAC addr

String macToStr(const uint8_t* mac){




  String result;




  for (int i = 0; i < 6; ++i) {

    result += String(mac[i], 16);




    if (i < 5){

      result += ':';

    }

  }




  return result;

}






Fazit : 


Der Lehrstuhl Datenverarbeitung ist meiner Meinung nach ein sehr guter Praktikumsplatz für an dieser Branche und Fächer interessierte Studenten.Stefan Röhrl, mein Betreuer, war immer willig mir alle meine Fragen bis in kleinste Details zu erklären und auch darüber hinaus mir Funktionsweisen von bestimmten Dingen von sich aus näher zu bringen.


Ich bin sehr zufrieden mit diesem Ingenieurpraxis an der Lehrstuhl Datenverarbeitung , da ich dabei in wenig zeit viel gelernt habe und mit verschiedene Softwares und Hardwares gearbeitet habe , die ich am Anfang wenig Erfahrung damit hatte .




  • Keine Stichwörter