23 #include "context_thread.h"
25 #include "utils/version.h"
29 #include <XnCppWrapper.h>
46 :
Thread(
"OpenNiContextThread",
Thread::OPMODE_WAITFORWAKEUP),
60 sensor_server_pid_ = -1;
61 cfg_run_sensor_server_ =
false;
63 cfg_run_sensor_server_ =
config->
get_bool(
"/plugins/openni/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));
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) == XN_STATUS_OK) {
97 for (xn::NodeInfoList::Iterator i = list.Begin(); i != list.End(); ++i) {
98 if ((*i).GetDescription().Type == XN_NODE_TYPE_DEVICE) {
99 device_ =
new xn::Device();
100 (*i).GetInstance(*device_);
111 openni_->StopGeneratingAll();
113 #if XN_VERSION_GE(1, 3, 2, 0)
121 if (cfg_run_sensor_server_) {
123 stop_sensor_server();
131 if (openni_.
refcount() != last_refcount_) {
133 last_refcount_ = openni_.
refcount();
135 openni_->WaitNoneUpdateAll();
138 if ((check_now_ - &check_last_) > 5) {
140 check_last_ = check_now_;
147 type_to_string(XnProductionNodeType type)
150 case XN_NODE_TYPE_DEVICE:
return "device";
151 case XN_NODE_TYPE_DEPTH:
return "depth";
152 case XN_NODE_TYPE_IMAGE:
return "image";
153 case XN_NODE_TYPE_AUDIO:
return "audio";
154 case XN_NODE_TYPE_IR:
return "IR";
155 case XN_NODE_TYPE_USER:
return "user";
156 case XN_NODE_TYPE_RECORDER:
return "recorder";
157 case XN_NODE_TYPE_PLAYER:
return "player";
158 case XN_NODE_TYPE_GESTURE:
return "gesture";
159 case XN_NODE_TYPE_SCENE:
return "scene";
160 case XN_NODE_TYPE_HANDS:
return "hands";
161 case XN_NODE_TYPE_CODEC:
return "codec";
162 default:
return "unknown";
170 OpenNiContextThread::print_nodes()
172 xn::NodeInfoList nodes;
173 if (openni_->EnumerateExistingNodes(nodes) == XN_STATUS_OK) {
175 for (xn::NodeInfoList::Iterator n = nodes.Begin(); n != nodes.End(); ++n) {
176 const XnProductionNodeDescription &pnd = (*n).GetDescription();
177 const char * info = (*n).GetCreationInfo();
178 if (strlen(info) == 0)
181 xn::Generator generator;
182 bool have_gen = ((*n).GetInstance(generator) == XN_STATUS_OK);
185 " %-8s %8s (type: %-8s vendor: %-12s name: %-24s "
186 "version: %u.%u.%u.%u%s%s)",
187 (*n).GetInstanceName(),
188 have_gen ? (generator.IsGenerating() ?
"active" :
"inactive") :
"unknown",
189 type_to_string(pnd.Type),
194 pnd.Version.nMaintenance,
196 info ?
" info: " :
"",
206 OpenNiContextThread::verify_active()
208 xn::NodeInfoList nodes;
209 if (openni_->EnumerateExistingNodes(nodes) == XN_STATUS_OK) {
210 for (xn::NodeInfoList::Iterator n = nodes.Begin(); n != nodes.End(); ++n) {
211 xn::Generator generator;
212 bool have_gen = ((*n).GetInstance(generator) == XN_STATUS_OK);
215 const XnProductionNodeDescription &pnd = (*n).GetDescription();
217 if (pnd.Type != XN_NODE_TYPE_DEVICE) {
218 if (!generator.IsGenerating()) {
220 "Inactive node '%s' (%s, %s/%s), trying to activate",
221 (*n).GetInstanceName(),
222 type_to_string(pnd.Type),
225 generator.StartGenerating();
227 }
else if (!generator.IsDataNew()) {
228 if (dead_loops_.find((*n).GetInstanceName()) != dead_loops_.end()) {
229 dead_loops_[(*n).GetInstanceName()] += 1;
231 dead_loops_[(*n).GetInstanceName()] = 1;
234 }
else if (dead_loops_.find((*n).GetInstanceName()) != dead_loops_.end()) {
235 dead_loops_.erase((*n).GetInstanceName());
256 xn::ErrorStateCapability ecap = generator.GetErrorStateCap();
257 if (ecap.GetErrorState() != XN_STATUS_OK) {
259 "ERROR in node '%s': %s",
260 (*n).GetInstanceName(),
261 xnGetStatusString(ecap.GetErrorState()));
267 std::map<std::string, unsigned int>::iterator d;
268 for (d = dead_loops_.begin(); d != dead_loops_.end(); ++d) {
269 if (d->second >= 3) {
271 "Node '%s' had no fresh data for long time (%u tests)",
280 OpenNiContextThread::start_sensor_server()
282 if (sensor_server_pid_ != -1) {
283 throw Exception(
"Sensor server appears to be already running");
290 throw Exception(errno,
"Forking for new process failed: %s");
291 }
else if (pid == 0) {
295 signal(SIGINT, SIG_IGN);
299 char *argv[] = {(
char *)cfg_sensor_bin_.c_str(), NULL};
300 if (execve(cfg_sensor_bin_.c_str(), argv, environ) == -1) {
301 throw Exception(
"Failed to execute %s, exited with %i: %s\n",
302 cfg_sensor_bin_.c_str(),
308 sensor_server_pid_ = pid;
312 OpenNiContextThread::stop_sensor_server()
314 if (sensor_server_pid_ == -1) {
315 throw Exception(
"Sensor server appears not to be already running");
319 ::kill(sensor_server_pid_, SIGTERM);
320 for (
unsigned int i = 0; i < 200; ++i) {
323 int rv = waitpid(sensor_server_pid_, &status, WNOHANG);
327 if (errno == ECHILD) {
328 sensor_server_pid_ = -1;
332 sensor_server_pid_ = -1;
337 if (sensor_server_pid_ != -1) {
339 ::kill(sensor_server_pid_, SIGKILL);
340 sensor_server_pid_ = -1;