23 #include "context_thread.h" 24 #include "utils/version.h" 30 #include <XnCppWrapper.h> 44 :
Thread(
"OpenNiContextThread",
Thread::OPMODE_WAITFORWAKEUP),
60 __sensor_server_pid = -1;
61 __cfg_run_sensor_server =
false;
63 __cfg_run_sensor_server =
66 if (__cfg_run_sensor_server) {
70 __openni =
new xn::Context();
73 if ((st = __openni->Init()) != XN_STATUS_OK) {
75 throw Exception(
"Initializing OpenNI failed: %s", xnGetStatusString(st));
78 __last_refcount = __openni.
refcount();
84 __device_no_data_loops = 0;
87 if (__cfg_run_sensor_server) {
88 start_sensor_server();
95 xn::NodeInfoList list;
96 if (__openni->EnumerateProductionTrees(XN_NODE_TYPE_DEVICE, NULL, list)
99 for (xn::NodeInfoList::Iterator i = list.Begin(); i != list.End(); ++i) {
100 if ((*i).GetDescription().Type == XN_NODE_TYPE_DEVICE) {
101 __device =
new xn::Device();
102 (*i).GetInstance(*__device);
114 __openni->StopGeneratingAll();
116 #if XN_VERSION_GE(1,3,2,0) 119 __openni->Shutdown();
124 if (__cfg_run_sensor_server) {
126 stop_sensor_server();
135 if (__openni.
refcount() != __last_refcount) {
137 __last_refcount = __openni.
refcount();
139 __openni->WaitNoneUpdateAll();
142 if ((__check_now - &__check_last) > 5) {
144 __check_last = __check_now;
151 type_to_string(XnProductionNodeType type)
154 case XN_NODE_TYPE_DEVICE:
return "device";
155 case XN_NODE_TYPE_DEPTH:
return "depth";
156 case XN_NODE_TYPE_IMAGE:
return "image";
157 case XN_NODE_TYPE_AUDIO:
return "audio";
158 case XN_NODE_TYPE_IR:
return "IR";
159 case XN_NODE_TYPE_USER:
return "user";
160 case XN_NODE_TYPE_RECORDER:
return "recorder";
161 case XN_NODE_TYPE_PLAYER:
return "player";
162 case XN_NODE_TYPE_GESTURE:
return "gesture";
163 case XN_NODE_TYPE_SCENE:
return "scene";
164 case XN_NODE_TYPE_HANDS:
return "hands";
165 case XN_NODE_TYPE_CODEC:
return "codec";
166 default:
return "unknown";
174 OpenNiContextThread::print_nodes()
176 xn::NodeInfoList nodes;
177 if (__openni->EnumerateExistingNodes(nodes) == XN_STATUS_OK) {
179 for (xn::NodeInfoList::Iterator n = nodes.Begin(); n != nodes.End(); ++n) {
180 const XnProductionNodeDescription &pnd = (*n).GetDescription();
181 const char *info = (*n).GetCreationInfo();
182 if (strlen(info) == 0) info = NULL;
184 xn::Generator generator;
185 bool have_gen = ((*n).GetInstance(generator) == XN_STATUS_OK);
188 "version: %u.%u.%u.%u%s%s)",
189 (*n).GetInstanceName(),
190 have_gen ? (generator.IsGenerating() ?
"active" :
"inactive") :
"unknown",
191 type_to_string(pnd.Type), pnd.strVendor, pnd.strName,
192 pnd.Version.nMajor, pnd.Version.nMinor, pnd.Version.nMaintenance,
193 pnd.Version.nBuild, info ?
" info: " :
"", info ? info :
"");
203 OpenNiContextThread::verify_active()
205 xn::NodeInfoList nodes;
206 if (__openni->EnumerateExistingNodes(nodes) == XN_STATUS_OK) {
207 for (xn::NodeInfoList::Iterator n = nodes.Begin(); n != nodes.End(); ++n) {
208 xn::Generator generator;
209 bool have_gen = ((*n).GetInstance(generator) == XN_STATUS_OK);
212 const XnProductionNodeDescription &pnd = (*n).GetDescription();
214 if (pnd.Type != XN_NODE_TYPE_DEVICE) {
215 if (! generator.IsGenerating()) {
217 (*n).GetInstanceName(), type_to_string(pnd.Type),
218 pnd.strVendor, pnd.strName);
219 generator.StartGenerating();
221 }
else if (! generator.IsDataNew()) {
222 if (__dead_loops.find((*n).GetInstanceName()) != __dead_loops.end()) {
223 __dead_loops[(*n).GetInstanceName()] += 1;
225 __dead_loops[(*n).GetInstanceName()] = 1;
228 }
else if (__dead_loops.find((*n).GetInstanceName()) != __dead_loops.end()) {
229 __dead_loops.erase((*n).GetInstanceName());
250 xn::ErrorStateCapability ecap = generator.GetErrorStateCap();
251 if (ecap.GetErrorState() != XN_STATUS_OK) {
253 xnGetStatusString(ecap.GetErrorState()));
259 std::map<std::string, unsigned int>::iterator d;
260 for (d = __dead_loops.begin(); d != __dead_loops.end(); ++d) {
261 if (d->second >= 3) {
263 d->first.c_str(), d->second);
270 OpenNiContextThread::start_sensor_server()
272 if (__sensor_server_pid != -1) {
273 throw Exception(
"Sensor server appears to be already running");
280 throw Exception(errno,
"Forking for new process failed: %s");
281 }
else if (pid == 0) {
285 signal(SIGINT, SIG_IGN);
289 char *argv[] = {(
char *)__cfg_sensor_bin.c_str(), NULL};
290 if (execve(__cfg_sensor_bin.c_str(), argv, environ) == -1) {
291 throw Exception(
"Failed to execute %s, exited with %i: %s\n",
292 __cfg_sensor_bin.c_str(), errno, strerror(errno));
296 __sensor_server_pid = pid;
300 OpenNiContextThread::stop_sensor_server()
302 if (__sensor_server_pid == -1) {
303 throw Exception(
"Sensor server appears not to be already running");
307 ::kill(__sensor_server_pid, SIGTERM);
308 for (
unsigned int i = 0; i < 200; ++i) {
311 int rv = waitpid(__sensor_server_pid, &status, WNOHANG);
313 if (errno == EINTR)
continue;
314 if (errno == ECHILD) {
315 __sensor_server_pid = -1;
319 __sensor_server_pid = -1;
324 if (__sensor_server_pid != -1) {
326 ::kill(__sensor_server_pid, SIGKILL);
327 __sensor_server_pid = -1;
virtual void log_info(const char *component, const char *format,...)=0
Log informational message.
Fawkes library namespace.
virtual bool get_bool(const char *path)=0
Get value from configuration which is of type bool.
void unlock() const
Unlock object mutex.
Thread class encapsulation of pthreads.
virtual void finalize()
Finalize the thread.
Logger * logger
This is the Logger member used to access the logger.
Clock * clock
By means of this member access to the clock is given.
Thread aspect to use blocked timing.
Base class for exceptions in Fawkes.
void set_clock(Clock *clock)
Set clock for this instance.
void set_openni_context(LockPtr< xn::Context > openni_context)
Set the OpenNI context to use for aspect initialization.
const char * name() const
Get name of thread.
virtual void log_warn(const char *component, const char *format,...)=0
Log warning message.
Thread aspect provide a new aspect.
virtual void init()
Initialize the thread.
void kill(int sig)
Send signal to a thread.
void clear()
Set underlying instance to 0, decrementing reference count of existing instance appropriately.
virtual void loop()
Code to execute in the thread.
OpenNiContextThread()
Constructor.
Time & stamp()
Set this time to the current time.
virtual ~OpenNiContextThread()
Destructor.
Configuration * config
This is the Configuration member used to access the configuration.
void lock() const
Lock access to the encapsulated object.
virtual std::string get_string(const char *path)=0
Get value from configuration which is of type string.
int refcount() const
Get current refcount.