------
mancas
------

Gyro Hut

Bart ist mein Avatar und wird duch meinen Hut gesteuert.

Der Avatar übernimmt meine Bewegungen

Bart, mein Präsenz-Roboter würde für mich an Besprechungen teilnehmen.
BART bedeuted Blue-Avatar-RoboteR.

Neben Bild- und Tonübertragung, wie bei einer Web-Konferenz, sollte der Roboter den Kopf jeweils dem Gesprächspartner zuwenden.

Der Roboter holt sich dazu Steuerungssignale von seinem Server um sich in einem entfernten Besprechungsraum zu bewegen. Eine Steuerungseinheit auf meinem Hut bereitet diese aus meinen Kopfbewegungen auf.


Definition des Steuerungs Files

Das File enthält die Daten, wo der Avatar hinschauen soll.

{"XGo":90, "YGo":-30, "Action":0}

WerteBereich für XGo ist von -150 bis + 150, für YGo von -60 bis +60. Bart schaut also, aus seiner Sicht gesehen, in diesem Beispiel nach links unten. Er frägt den Server ständig ab und reagiert sobald er eine Veränderung am File erkennt.


Der Gyroskop Hut

&

Das kleine Modul GX521 enthält einen MPU-6050. Dieser liefert Drehbeschleunigungen, die mit der Library MPU6050_light zu Winkeln im Raum ausgewertet werden.

Dies übernimmt ein ESP32. Er erstellt dann ein Json File und hostet es über seinen Webserver im Wlan.


**************************************************************
 * Use the MP5060_light library to get gyro datas from MPU6050
 * (build in the GX521) and deliver these datas as Json file
 * with a webserver to control movements of a robot
 * mancas at lug-saar.de
 * some code found at elektro . turanis .de
 * ************************************************************
 */

// initialise GX521 with MPU6050
#include <Wire.h>
#include <MPU6050_light.h>

MPU6050 mpu(Wire);
String YPos, XPos, ZPos;
float XPosfloat, YPosfloat;


// variable for wait without delay
long previousMillis = 0; // saves the time at which it was last switched on


// initialise Webserver
#include <WiFi.h>
#include <WiFiClient.h>
#include <WebServer.h>
#include <ESPmDNS.h>

// wifi datas
const char* ssid = "xxx";
const char* password = "xxxx1";

WebServer server(80);
const int led = 13;
String JsonFile;

void handleRoot() {
  digitalWrite(led, 1);
  server.send(200, "text/plain", JsonFile);
  digitalWrite(led, 0);
}

void handleNotFound() {
  digitalWrite(led, 1);
  String message = "File Not Found\n\n";
  message += "URI: ";
  message += server.uri();
  message += "\nMethod: ";
  message += (server.method() == HTTP_GET) ? "GET" : "POST";
  message += "\nArguments: ";
  message += server.args();
  message += "\n";
  for (uint8_t i = 0; i < server.args(); i++) {
    message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
  }
  server.send(404, "text/plain", message);
  digitalWrite(led, 0);
}


// ***********************************************************
void setup() {
Serial.begin(115200);

// setup MPU6050
    Serial.flush();
    Wire.begin();
    mpu.begin();
    Serial.println(F("evaluating gyro basic datas, do not move"));
    delay(1000);
    mpu.calcGyroOffsets();
    Serial.println("Done.");


// setup webserver    
  pinMode(led, OUTPUT);
  digitalWrite(led, 0);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  Serial.println("");

  // Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());

  if (MDNS.begin("esp32")) {
    Serial.println("MDNS responder started");
  }

JsonFile = "Hi, here is my JsonFile";
  server.on("/", handleRoot);

  server.on("/inline", []() {
    server.send(200, "text/plain", "this works as well");
  });

  server.onNotFound(handleNotFound);

  server.begin();
  Serial.println("HTTP server started");

}

//************************************************************
void loop() {

// calculate in each loop to have correct values
mpu.update();
    YPosfloat = round(1.5 * mpu.getAngleX());
    XPosfloat = round(3.0 * mpu.getAngleZ());
    ZPos = 2;

    XPos = String(int(XPosfloat));
    YPos = String(int(YPosfloat));

//give out the results each 2000 ms
long currentMillis = millis(); // Current time
 if (currentMillis - previousMillis >= 2000) {
  previousMillis = currentMillis;

  // assemble the Json file
  JsonFile = ("{\"XGo\":" + XPos + ", \"YGo\":" + YPos + ", \"Action\":" + ZPos + "}" );
  Serial.println(JsonFile);
 
//  Serial.print(XPosfloat); // for test with the serial plotter
//  Serial.print(",");
//  Serial.print(YPosfloat);
//  Serial.println("");
 }
 // let the web server run
  server.handleClient();

}

Der Befehl delay darf im Softwareablauf nicht verwendet werden, da mit einem Stop des ESP32 die kontinuierliche Berechnung angehalten wird, die Positionswerte dann nicht mehr sauber integriert werden und weglaufen.


Leider bringt der ESP32-Webserver mit seiner index.html bei einer direkten Verbindung den ESP32-Webclient im Roboter reproduzierbar zum Absturz.

Plotter

Als Ursache vermute ich: Die index.html enthält nur das Json File, keine <head>-tags mit weiteren Informationen für den Server. Zum Betrieb des Avatars wird die Json-Seite jedoch auf meinen Raspberry gespiegelt und ins Web gehosted. So kann der Avatar an einem entfernten Ort auf meine Bewegungen reagieren. Über den Raspi trat das Problem nicht mehr auf, obwohl die index.html nicht verändert wurde.