Reacting to a vision event: face detected¶
This section explains how to implement a module reacted to a complex event and how to retrieve the information stored in this event.
Principle¶
This example follows the same principle as here Reacting to an event: bumper, but is based on an event generated by ALVideoDevice: FaceDetetected.
This time, the data put into the memory corresponding to the “FaceDetected” key is more complex than aboolean: it is an ALValue containing information about the detected face(s).
To retrieve this information, use a proxy to ALMemory, and retrieve the data stored in the corresponding key.
Example: OnFaceDetection module¶
This example follows the same principle as here Reacting to an event: bumper, but is based on an event generated by ALVideoDevice: FaceDetetected. This time, the data put into the memory corresponding to the “FaceDetected” key is more complex than a boolean: it is an ALValue containing information about the detected face(s).
This example will make NAO say the number of faces it detects.
The whole example is available here: onfacedetection.zip
Header:
+++++++
/**
*
* This file was generated by Aldebaran Robotics ModuleGenerator
*/
#ifndef ONFACEDETECTION_ONFACEDETECTION_H
#define ONFACEDETECTION_ONFACEDETECTION_H
#include <boost/shared_ptr.hpp>
#include <alcommon/almodule.h>
#include <string>
#include <alproxies/almemoryproxy.h>
#include <alproxies/altexttospeechproxy.h>
#include <althread/almutex.h>
namespace AL
{
class ALBroker;
}
class OnFaceDetection : public AL::ALModule
{
public:
OnFaceDetection(boost::shared_ptr<AL::ALBroker> broker, const std::string& name);
virtual ~OnFaceDetection();
virtual void init();
/**
* Method called each time a face is detected.
* Makes NAO say the number of detected faces.
*/
void callback();
private:
/** Memory proxy for event subscription and data access. */
AL::ALMemoryProxy fMemoryProxy;
/** TTS proxy to make NAO talk. */
AL::ALTextToSpeechProxy fTtsProxy;
/** ALValue containing the information on detected faces. */
AL::ALValue fFaces;
/** Current count of detected faces. */
unsigned int fFacesCount;
/** Mutex to make the callback function thread-safe. */
boost::shared_ptr<AL::ALMutex> fCallbackMutex;
};
#endif // ONFACEDETECTION_ONFACEDETECTION_H
Source file:¶
/**
*
* Version : $Id$
* This file was generated by Aldebaran Robotics ModuleGenerator
*/
#include "onfacedetection.h"
#include <alvalue/alvalue.h>
#include <alcommon/alproxy.h>
#include <alcommon/albroker.h>
#include <althread/alcriticalsection.h>
#include <qi/log.hpp>
OnFaceDetection::OnFaceDetection(
boost::shared_ptr<AL::ALBroker> broker,
const std::string& name):
AL::ALModule(broker, name),
fMemoryProxy(getParentBroker()),
fFaces(AL::ALValue()),
fFacesCount(0),
fCallbackMutex(AL::ALMutex::createALMutex())
{
setModuleDescription("This is an autogenerated module, this descriptio needs to be updated.");
functionName("callback", getName(), "");
BIND_METHOD(OnFaceDetection::callback);
}
OnFaceDetection::~OnFaceDetection() {}
void OnFaceDetection::init() {
try {
/** See if there is any face already detected at initialization. */
fFaces = fMemoryProxy.getData("FaceDetected");
if (fFaces.getSize() < 2) {
qiLogInfo("module.example") << "No face detected" << std::endl;
fTtsProxy.say("No face detected");
}
/** Subscribe to the event FaceDetected, with appropriate callback function. */
fMemoryProxy.subscribeToEvent("FaceDetected", "OnFaceDetection", "callback");
}
catch (const AL::ALError& e) {
qiLogError("module.name") << e.what() << std::endl;
}
}
void OnFaceDetection::callback() {
/** Use a mutex to make it all thread safe. */
AL::ALCriticalSection section(fCallbackMutex);
try {
/** Retrieve the data raised by the event. */
fFaces = fMemoryProxy.getData("FaceDetected");
/** Check that there are faces effectively detected. */
if (fFaces.getSize() < 2 ) {
if (fFacesCount != 0) {
qiLogInfo("module.example") << "No face detected" << std::endl;
fTtsProxy.say("No face detected.");
fFacesCount = 0;
}
return;
}
/** Check the number of faces from the FaceInfo field, and check that it has
* changed from the last event.*/
if (fFaces[1].getSize() - 1 != fFacesCount) {
qiLogInfo("module.name") << fFaces[1].getSize() - 1 << " face(s) detected." << std::endl;
char buffer[50];
sprintf(buffer, "%d faces detected.", fFaces[1].getSize() - 1);
fTtsProxy.say(std::string(buffer));
/** Update the current number of detected faces. */
fFacesCount = fFaces[1].getSize() - 1;
}
}
catch (const AL::ALError& e) {
qiLogError("module.name") << e.what() << std::endl;
}
}
Main:¶
/**
* @author
*
* \section Description
* This file was generated by Aldebaran Robotics ModuleGenerator
*/
#include <signal.h>
#include <boost/shared_ptr.hpp>
#include <alcommon/albroker.h>
#include <alcommon/almodule.h>
#include <alcommon/albrokermanager.h>
#include <alcommon/altoolsmain.h>
#include "onfacedetection.h"
#ifdef ONFACEDETECTION_IS_REMOTE
# define ALCALL
#else
# ifdef _WIN32
# define ALCALL __declspec(dllexport)
# else
# define ALCALL
# endif
#endif
extern "C"
{
ALCALL int _createModule(boost::shared_ptr<AL::ALBroker> pBroker)
{
// init broker with the main broker instance
// from the parent executable
AL::ALBrokerManager::setInstance(pBroker->fBrokerManager.lock());
AL::ALBrokerManager::getInstance()->addBroker(pBroker);
AL::ALModule::createModule<OnFaceDetection>( pBroker, "OnFaceDetection" );
return 0;
}
ALCALL int _closeModule()
{
return 0;
}
}
#ifdef ONFACEDETECTION_IS_REMOTE
int main(int argc, char *argv[])
{
// pointer to createModule
TMainType sig;
sig = &_createModule;
// call main
ALTools::mainFunction("onfacedetection", argc, argv, sig);
}
#endif
CMakeLists.txt:¶
The CMakeLists.txt file is:
cmake_minimum_required(VERSION 2.8)
project(onfacedetection)
find_package(qibuild)
option(ONFACEDETECTION_IS_REMOTE
"module is compiled as a remote module (ON or OFF)"
ON)
set(_srcs
main.cpp
onfacedetection.h
onfacedetection.cpp
)
if(ONFACEDETECTION_IS_REMOTE)
add_definitions(" -DONFACEDETECTION_IS_REMOTE ")
qi_create_bin(onfacedetection ${_srcs})
else()
qi_create_lib(onfacedetection SHARED ${_srcs} SUBFOLDER naoqi)
endif()
qi_use_lib(onfacedetection ALCOMMON ALPROXIES ALTHREAD)