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.