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;
OpenNiContextThread()
Constructor.
virtual void init()
Initialize the thread.
virtual void loop()
Code to execute in the thread.
virtual ~OpenNiContextThread()
Destructor.
virtual void finalize()
Finalize the thread.
Thread aspect provide a new aspect.
Thread aspect to use blocked timing.
Clock * clock
By means of this member access to the clock is given.
Configuration * config
This is the Configuration member used to access the configuration.
virtual bool get_bool(const char *path)=0
Get value from configuration which is of type bool.
virtual std::string get_string(const char *path)=0
Get value from configuration which is of type string.
Base class for exceptions in Fawkes.
void lock() const
Lock access to the encapsulated object.
int refcount() const
Get current refcount.
void clear()
Set underlying instance to 0, decrementing reference count of existing instance appropriately.
void unlock() const
Unlock object mutex.
virtual void log_warn(const char *component, const char *format,...)=0
Log warning message.
virtual void log_info(const char *component, const char *format,...)=0
Log informational message.
Logger * logger
This is the Logger member used to access the logger.
void set_openni_context(LockPtr< xn::Context > openni_context)
Set the OpenNI context to use for aspect initialization.
Thread class encapsulation of pthreads.
void kill(int sig)
Send signal to a thread.
const char * name() const
Get name of thread.
void set_clock(Clock *clock)
Set clock for this instance.
Time & stamp()
Set this time to the current time.
Fawkes library namespace.