Montag, 22. Dezember 2014

RaspberryPi und Roulette Kesselgucken nur Treffer mit dem SourceCode


RaspberryPi und Roulette Kesselgucken nur Treffer mit dem SourceCode

Author D.Selzer-McKenzie


 

den kompletten SourceCode finden Sie im

Forum http://Outbackbrumby.Blogspot.com

 

Sie wissen ja, mit dem RaspberryPi oder jedem anderen Computer ist es möglich, beim Roulette-Kesselgucken nur

noch Gewinne einzufahren, weil man beim Roulette noch nach Abwurf der Kugel kurz danach noch setzen kann.

Die Software beobachtet den Lauf der Kugel und gibt nach spätestens 2 Umdrehungen aus, in welches Fach

die Roulette-Kugel fallen wird. Also noch genug Zeit, um noch schnell zu setzen, da die Croupiers in den

Casinos es erlauben, noch kurz bis nach Andrehen der Kugel einen Satz zu machen.

 

 

Das Modul Bild-Identifiezierung bem Lauf der Kugel

In diesem besonderen Modul wird das Ereignis redBallDetected initialisiert. D.h. folgendes jedes Mal, wenn eine der sieben 30 Roulettezahlen ins Sichtfeld der Kamera kommt, wird für dieses Bild das Ereignis reservierte Speicherbereich mit Informationen über diese einzelne Roulettezahl aktualisiert. D.h., für alle 37 Roulettezahlen wird ein Speicherplatz reserviert und auch immer geupdatet, solang der Roulettekessel läuft. Dieser Speicherplatz wird über die integrierte Bibliothek zur Verfügung gestellt. Dadurch ist es natürlich möglich, für jede einzelne auf dem Kessel befindliche Roulettezahl, diese entsprechend zu beobachten in ihrer Laufgeschwindigkeit, auf Tausendstelsekunden, und dadurch erfolgt auch gleichzeitig die Berechnung, welche der 37 Zahlen nunmehr in diesem Coup, der gerade läuft, fällt. Nachstehend finden Sie für diesen Part den SourceCode.

 

 

Das Modul Geräusche-Identifizierung:

 

Mit dem folgenden Modul, können die Geräusche bzw. die Aufnahme und Verarbeitung der Geräusche ausgewertet werden. Dieses eigentlich nur eine zusätzliche Option, weil die Bilderkennung eigentlich schon genau berechnet, in welches Fach die Roulettekugel fallen wird. Diese Geräuschmessung hat allerdings in einem realen Casino große Bedeutung, weil die Software in diesem Falle die Umdrehungsgeräusche des Kessels ausgewertet und zusätzlich Informationen bekommt. Beispielsweise für Kessel Fehler Gucker wäre dieses Softwaremodul Ideal, weil die Software Kesselfehler oder Lauffehler in einem Kessel sofort identifizieren könnte. Natürlich bedarf es zur Feststellung von Kesselfehlern im Roulettekesseln mehrere Messungen, und es ist ja auch heute so das es keine Spieler mehr gibt, die Kesselfehler ausfindig machen wollen. Es kommt ja auch hinzu, dass wenn jetzt ein bestimmter Kesselfehler vorhanden ist, dass daraus nicht zu schließen ist, dass die Kugel in ein ganz bestimmtes Fach fallen würde. Deshalb sollten Sie sich besser auf die Software für die Objektbestimmung konzentrieren die ich ja oben in Ihrem Sourcecode dargestellt habe. Diesen Sourcecode können Sie für jedes Gerät, also auch für Handys benutzen, Sie müssen ihn nur eingeben.

 

 

 

In diesem besonderen Modul wird das Ereignis redBallDetected initialisiert. D.h. folgendes jedes Mal, wenn eine der sieben 30 Roulettezahlen ins Sichtfeld der Kamera kommt, wird für dieses Bild das Ereignis reservierte Speicherbereich mit Informationen über diese einzelne Roulettezahl aktualisiert. D.h., für alle 37 Roulettezahlen wird ein Speicherplatz reserviert und auch immer geupdatet, solang der Roulettekessel läuft. Dieser Speicherplatz wird über die integrierte Bibliothek zur Verfügung gestellt. Dadurch ist es natürlich möglich, für jede einzelne auf dem Kessel befindliche Roulettezahl, diese entsprechend zu beobachten in ihrer Laufgeschwindigkeit, auf Tausendstelsekunden, und dadurch erfolgt auch gleichzeitig die Berechnung, welche der 37 Zahlen nunmehr in diesem Coup, der gerade läuft, fällt. Nachstehend finden Sie für diesen Part den SourceCode.

cmake_minimum_required(VERSION 2.8)

#Name des Projekts

project(testevent)

find_package(qibuild)

#Source Codes zur Kompilierung

set(_srcs main.cpp testevent.h testevent.cpp)

#Einfügen einer eigenen Bibliothek wegen Kompilierungsproblemen

include_directories(".")

qi_create_lib(testevent_lib testevent.h testevent.cpp main.cpp)

qi_stage_lib(testevent_lib)

#Erstellen der ausführbaren Datei

qi_create_bin(testevent ${_srcs})

#Gibt die zu verwendenden Bibliotheken an

qi_use_lib(testevent testevent_lib ALCOMMON)

 

#ifndef _TESTEVENT_

#define _TESTEVENT_

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include "alaudio\alsoundextractor.h"

#include

#include

#include

namespace AL

{

class ALBroker;

}

class TestEvent : public AL::ALModule

{

public:

TestEvent(boost::shared_ptr broker, const std::string& name);

virtual ~TestEvent();

//Überladen der init() Funktion, welche direkt nach Konstruktor aufegrufen wird

virtual void init();

//callback funktion des events

void onRedBallDetected();

private:

AL::ALMemoryProxy fMemoryProxy; //Proxy für Speicherzugriff

AL::ALTextToSpeechProxy fTtsProxy; //Proxy zur Sprachausgabe

AL::ALMotionProxy fMotionProxy; //Proxy für Roboterbewegung

boost::shared_ptr fCallbackMutex; //Mutex

AL::ALValue RedBall; //Speichert Informationen über den Ball

int RedBallCounter; //Zählt wie oft ein Ball erkannt wird/ werden soll

bool isDetected;

};

#endif

#include "testevent.h"

TestEvent::TestEvent(boost::shared_ptr broker, const std::string& name) : AL::ALModule(broker,name),

fCallbackMutex(AL::ALMutex::createALMutex()), RedBall(AL::ALValue()), RedBallCounter(3)

{

setModuleDescription("This module is going to start a RedBallDetection while moving NAOs head");

functionName("onRedBallDetected",getName(),"Method called when red ball detected");

BIND_METHOD(TestEvent::onRedBallDetected);

}

TestEvent::~TestEvent()

{

fMemoryProxy.unsubscribeToEvent("RedBallDetected","TestEvent");

}

void TestEvent::init()

{

try

{

fMemoryProxy = AL::ALMemoryProxy(getParentBroker());

//abonniere Event

fMemoryProxy.subscribeToEvent("redBallDetected","TestEvent","onRedBallDetected");

}

catch(const AL::ALError& e)

{

qiLogError("module.example") << e.what() << std::endl;

}

try

{

fMotionProxy = AL::ALMotionProxy(getParentBroker());

AL::ALValue stiffness = 1.0f;

AL::ALValue time = 1.0f;

fMotionProxy.stiffnessInterpolation("HeadYaw",stiffness,time);

//setze Steifheit für "headyaw" Motor auf 1

//setze Ziel Winkel/rad und Zeiten/sec

AL::ALValue targetAngles = AL::ALValue::array(-1.5f,1.5f,0.0f);

AL::ALValue targetTimes = AL::ALValue::array(3.0f,6.0f,9.0f);

bool isAbsolute = true;

isDetected = false;

//Bewege so lange den Kopf hin und her bis ein roter Ball erkannt wird -> Suche

while(!isDetected)

{

fMotionProxy.angleInterpolation("HeadYaw",targetAngles,targetTimes, isAbsolute);

}

stiffness = 0.0f;

time = 1.0f;

fMotionProxy.stiffnessInterpolation("HeadYaw",stiffness,time);

}

catch(const AL::ALError& er)

{

qiLogError("module.example") << er.what() << std::endl;

}

void TestEvent::onRedBallDetected()

{

qiLogInfo("module.example") << "Callback method executed!" << std::endl;

//mutex damit die Methode thread-safe ist

AL::ALCriticalSection section(fCallbackMutex);

try

{

RedBall = fMemoryProxy.getData("redBallDetected");

if(RedBall.getSize() < 2) //enthält 3 Eigenschaften wenn erkannt

{

return;

}

else if(RedBallCounter > 0)

{

isDetected = true;

qiLogInfo("module.example") << "Red Ball Detected!" << std::endl;

fTtsProxy = AL::ALTextToSpeechProxy(getParentBroker());

//"post" des Objekts weil der Kopf immer noch in Bewegung sein könnte

fTtsProxy.post.say("Red ball detected!");

RedBall.clear(); //Setzt den Inhalt zurück

RedBallCounter--;

}

}

catch(const AL::ALError& err)

{

qiLogError("module.example") << << err.what() << std::endl;

#include

#include

#include

#include

#include "testevent.h"

int main(int argc, char* argv[])

{

int pport = 9559;

std::string pip = "127.0.0.1";

//checke die anzahl der argumente

if(argc != 1 && argc != 3 && argc != 5)

{

std::cerr << "Wrong number of arguments!" << std::endl;

std::cerr << "Usage: testevent [--pip ROBOT_IP] [--pport ROBOT_PORT]"

<

exit(2);

}

if(argc == 3)

{

if(std::string(argv[1]) == "--pip")

{

pip = argv[2];

}

else if(std::string(argv[1]) == "--pport")

{

pport = atoi(argv[2]);

}

else

{

std::cerr << "Wrong number of arguments!" << std::endl;

std::cerr << "Usage: testevent [--pip ROBOT_IP] [--pport ROBOT_PORT]"

<< std::endl;

exit(2);

}

}

//beide argumente gegeben

if(argc == 5)

{

if((std::string(argv[1]) == "--pip")&&(std::string(argv[3])=="--pport"))

{

pip = argv[2];

pport = atoi(argv[4]);

}

else if((std::string(argv[3])=="--pip")&&

(std::string(argv[1])=="--pport"))

{

pip = argv[4];

pport = atoi(argv[2]);

}

else

{

std::cerr << "Wrong number of arguments!" << std::endl;

std::cerr << "Usage: testevent [--pip ROBOT_IP] [--pport ROBOT_PORT]"

<< std::endl;

exit(2);

}

}

//SOAP serialisation für floats

setlocale(LC_NUMERIC, "C");

//broker name, ip und port deklarieren

const std::string brokerName = "testeventbroker";

int brokerPort = 54000;

const std::string brokerIP = "0.0.0.0";

boost::shared_ptr broker;

try

{

broker =

AL::ALBroker::createBroker(brokerName,brokerIP,brokerPort,pip,pport,0);

}

catch(...)

{

std::cerr << "Fail to connect broker to" <<

pip << ":" << pport << std::endl;

AL::ALBrokerManager::getInstance()->killAllBroker();

 

AL::ALBrokerManager::kill();

return 1;

}

//füge broker in NAOqi

AL::ALBrokerManager::setInstance(broker->fBrokerManager.lock());

AL::ALBrokerManager::getInstance()->addBroker(broker);

//erzeuge und lade Modul

AL::ALModule::createModule(broker, "TestEvent");

while(true)

qi::os::sleep(1);

return 0;

 

 

 

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

 

 

Mit dem folgenden Modul, können die Geräusche bzw. die Aufnahme und Verarbeitung der Geräusche ausgewertet werden. Dieses eigentlich nur eine zusätzliche Option, weil die Bilderkennung eigentlich schon genau berechnet, in welches Fach die Roulettekugel fallen wird. Diese Geräuschmessung hat allerdings in einem realen Casino große Bedeutung, weil die Software in diesem Falle die Umdrehungsgeräusche des Kessels ausgewertet und zusätzlich Informationen bekommt. Beispielsweise für Kessel Fehler Gucker wäre dieses Softwaremodul Ideal, weil die Software Kesselfehler oder Lauffehler in einem Kessel sofort identifizieren könnte. Natürlich bedarf es zur Feststellung von Kesselfehlern im Roulettekesseln mehrere Messungen, und es ist ja auch heute so das es keine Spieler mehr gibt, die Kesselfehler ausfindig machen wollen. Es kommt ja auch hinzu, dass wenn jetzt ein bestimmter Kesselfehler vorhanden ist, dass daraus nicht zu schließen ist, dass die Kugel in ein ganz bestimmtes Fach fallen würde. Deshalb sollten Sie sich besser auf die Software für die Objektbestimmung konzentrieren die ich ja oben in Ihrem Sourcecode dargestellt habe. Diesen Sourcecode können Sie für jedes Gerät, also auch für Handys benutzen, Sie müssen ihn nur eingeben.

 

Hier nun der Code Geräusche

cmake_minimum_required(VERSION 2.8)

project(soundbasedreaction)

find_package(qibuild)

set(_srcs main.cpp soundbasedreaction.h soundbasedreaction.cpp)

include_directories(".")

qi_create_lib(soundbasedreaction_lib soundbasedreaction.h soundbasedreaction.cpp main.cpp)

qi_stage_lib(soundbasedreaction_lib)

qi_create_bin(soundbasedreaction ${_srcs})

qi_use_lib(soundbasedreaction soundbasedreaction_lib ALCOMMON ALAUDIO)

#ifndef _SOUNDBASED_

#define _SOUNDBASED_

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include "alaudio\alsoundextractor.h"

using namespace AL;

class SoundBasedReaction : public ALSoundExtractor

{

public:

SoundBasedReaction(boost::shared_ptr broker, const std::string& name);

virtual ~SoundBasedReaction();

void init();

void process(const int& nbOfChannels,

const int& nbrOfSamplesByChannel,

const AL_SOUND_FORMAT* buffer,

const ALValue& timeStamp);

private:

ALTextToSpeechProxy fTtsProxy;

};

#endif

soundbasedreaction.cpp

#include "soundbasedreaction.h"

SoundBasedReaction::SoundBasedReaction(boost::shared_ptr broker, const std::string& name) : ALSoundExtractor(broker, name)

{

///Beschreibung auf der Homepage

setModuleDescription("This module launch a texttospeech command when a sudden

and significative noise is heard.");

}

void SoundBasedReaction::init()

{

//Sprache der Sprachverarbeitung wählen

fTtsProxy.setLanguage("English");

//Name des Moduls, 16000Hz, Front Channels, Deinterleaving nicht benötigt

audioDevice->callVoid("setClientPreferences", getName(),16000,(int)FRONTCHANNEL,0 );

}

SoundBasedReaction::~SoundBasedReaction()

{

stopDetection();

}

//Diese Funktion wird automatisch vom ALAudioDevice Modul aufgerufen und zwar

//alle 170ms mit passendem Audio buffer (front channel mit 16000Hz)

void SoundBasedReaction::process(const int& nbOfChannels, const int& nbrOfSamplesByChannel, const AL_SOUND_FORMAT* buffer, const ALValue& timeStamp)

{

int maxValueFront = 0;

for(int i = 0; i < nbrOfSamplesByChannel; i++)

{

if(buffer[i] > maxValueFront)

{

maxValueFront = buffer[i];

}

}

//Ausgabe in der Konsole

std::cout << "maxvalue: " << maxValueFront << std::endl;

//Wenn Wert überschritten->Text To Speech durchführen

if(maxValueFront > 10000)

{

fTtsProxy.say("Freeze ");

 

#include "soundbasedreaction.h"

#include

#include

int main(int argc, char* argv[])

{

int pport = 9559;

std::string pip = "192.168.1.2";

//check argumente

if((argc != 1) && (argc != 3) && (argc != 5))

{

std::cerr << "Wrong Number of Arguments!" << std::endl;

std::cerr << "Usage: --pip ROBOT_IP --pport ROBOT_PORT" << std::endl;

exit(2);

}

//PORT bzw IP

if(argc == 3)

{

if(std::string(argv[1]) == "--ppip")

{

pip = argv[2];

}

else if(std::string(argv[1]) == "--pport")

{

pport = atoi(argv[2]);

}

else

{

std::cerr << "Wrong Number of Arguments!" << std::endl;

std::cerr << "Usage: --pip ROBOT_IP --pport ROBOT_PORT"

<< std::endl;

exit(2);

}

}

//PORT und IP

if(argc == 5)

{

if((std::string(argv[1]) == "--pip")&&(std::string(argv[3])=="--pport"))

{

pip = argv[2];

pport = atoi(argv[4]);

}

else if((std::string(argv[3]) == "--pip")&&

(std::string(argv[1])=="--pport"))

{

pip = argv[4];

pport = atoi(argv[2]);

}

else

{

std::cerr << "Wrong Number of Arguments!" << std::endl;

std::cerr << "Usage: --pip ROBOT_IP --pport ROBOT_PORT"

<< std::endl;

exit(2);

}

}

//SOAP Serialisation floats

setlocale(LC_NUMERIC,"C");

//definiere broker name,ip und port

const std::string brokerName = "mybroker";

const std::string brokerIP = "0.0.0.0";

int brokerPort = 54000;

//erstelle broker

boost::shared_ptr pBroker;

try

{

pBroker = AL::ALBroker::createBroker(brokerName,brokerIP,brokerPort,pip,pport,0);

}

catch(...)

{

std::cerr << "Fail to connect broker to: " << pip << ":" << pport << std::endl;

AL::ALBrokerManager::getInstance()->killAllBroker(); //lösche alle broker

AL::ALBrokerManager::kill(); //setze brokermanager singleton zurück

return 1;

}

//lade broker

AL::ALBrokerManager::setInstance(pBroker->fBrokerManager.lock());

AL::ALBrokerManager::getInstance()->addBroker(pBroker);

//lade module

AL::ALModule::createModule(pBroker,"SoundBasedReaction");

while(true)

qi::os::sleep(1);

return 0;

}




Keine Kommentare:

Kommentar veröffentlichen

Hinweis: Nur ein Mitglied dieses Blogs kann Kommentare posten.