Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "openni2_camera/openni2_device_manager.h"
00033 #include "openni2_camera/openni2_convert.h"
00034 #include "openni2_camera/openni2_device.h"
00035 #include "openni2_camera/openni2_exception.h"
00036
00037 #include <boost/make_shared.hpp>
00038
00039 #include <ros/ros.h>
00040
00041 #include <set>
00042 #include <string>
00043
00044 #include "OpenNI.h"
00045
00046 namespace openni2_wrapper
00047 {
00048
00049 class OpenNI2DeviceInfoComparator
00050 {
00051 public:
00052 bool operator()(const OpenNI2DeviceInfo& di1, const OpenNI2DeviceInfo& di2)
00053 {
00054 return (di1.uri_.compare(di2.uri_) < 0);
00055 }
00056 };
00057
00058 typedef std::set<OpenNI2DeviceInfo, OpenNI2DeviceInfoComparator> DeviceSet;
00059
00060 class OpenNI2DeviceListener : public openni::OpenNI::DeviceConnectedListener,
00061 public openni::OpenNI::DeviceDisconnectedListener,
00062 public openni::OpenNI::DeviceStateChangedListener
00063 {
00064 public:
00065 OpenNI2DeviceListener() :
00066 openni::OpenNI::DeviceConnectedListener(),
00067 openni::OpenNI::DeviceDisconnectedListener(),
00068 openni::OpenNI::DeviceStateChangedListener()
00069 {
00070 openni::OpenNI::addDeviceConnectedListener(this);
00071 openni::OpenNI::addDeviceDisconnectedListener(this);
00072 openni::OpenNI::addDeviceStateChangedListener(this);
00073
00074
00075 openni::Array<openni::DeviceInfo> device_info_list;
00076 openni::OpenNI::enumerateDevices(&device_info_list);
00077
00078 for (int i = 0; i < device_info_list.getSize(); ++i)
00079 {
00080 onDeviceConnected(&device_info_list[i]);
00081 }
00082 }
00083
00084 ~OpenNI2DeviceListener()
00085 {
00086 openni::OpenNI::removeDeviceConnectedListener(this);
00087 openni::OpenNI::removeDeviceDisconnectedListener(this);
00088 openni::OpenNI::removeDeviceStateChangedListener(this);
00089 }
00090
00091 virtual void onDeviceStateChanged(const openni::DeviceInfo* pInfo, openni::DeviceState state)
00092 {
00093 ROS_INFO("Device \"%s\" error state changed to %d\n", pInfo->getUri(), state);
00094
00095 switch (state)
00096 {
00097 case openni::DEVICE_STATE_OK:
00098 onDeviceConnected(pInfo);
00099 break;
00100 case openni::DEVICE_STATE_ERROR:
00101 case openni::DEVICE_STATE_NOT_READY:
00102 case openni::DEVICE_STATE_EOF:
00103 default:
00104 onDeviceDisconnected(pInfo);
00105 break;
00106 }
00107 }
00108
00109 virtual void onDeviceConnected(const openni::DeviceInfo* pInfo)
00110 {
00111 boost::mutex::scoped_lock l(device_mutex_);
00112
00113 const std::string serial = getSerial(pInfo->getUri());
00114 const OpenNI2DeviceInfo device_info_wrapped = openni2_convert(pInfo, serial);
00115
00116 ROS_INFO("Device \"%s\" with serial number \"%s\" connected\n", pInfo->getUri(), serial.c_str());
00117
00118
00119 device_set_.erase(device_info_wrapped);
00120 device_set_.insert(device_info_wrapped);
00121 }
00122
00123 virtual std::string getSerial(const std::string Uri)
00124 {
00125 openni::Device openni_device;
00126 std::string ret;
00127
00128
00129 if (Uri.length() > 0 && openni_device.open(Uri.c_str()) == openni::STATUS_OK)
00130 {
00131 int serial_len = 100;
00132 char serial[serial_len];
00133
00134 openni::Status rc = openni_device.getProperty(openni::DEVICE_PROPERTY_SERIAL_NUMBER, serial, &serial_len);
00135 if (rc == openni::STATUS_OK)
00136 ret = serial;
00137 else
00138 {
00139 ROS_ERROR("Device \"%s\": failed to query serial number.\n", Uri.c_str());
00140 }
00141
00142
00143 openni_device.close();
00144 }
00145 else
00146 {
00147 ROS_DEBUG("Device \"%s\": failed to open for serial number query. It's probably used by another process.\n", Uri.c_str());
00148 }
00149
00150 return ret;
00151 }
00152
00153 virtual void onDeviceDisconnected(const openni::DeviceInfo* pInfo)
00154 {
00155 boost::mutex::scoped_lock l(device_mutex_);
00156
00157 ROS_WARN("Device \"%s\" disconnected\n", pInfo->getUri());
00158
00159 const OpenNI2DeviceInfo device_info_wrapped = openni2_convert(pInfo);
00160 device_set_.erase(device_info_wrapped);
00161 }
00162
00163 boost::shared_ptr<std::vector<std::string> > getConnectedDeviceURIs()
00164 {
00165 boost::mutex::scoped_lock l(device_mutex_);
00166
00167 boost::shared_ptr<std::vector<std::string> > result = boost::make_shared<std::vector<std::string> >();
00168
00169 result->reserve(device_set_.size());
00170
00171 std::set<OpenNI2DeviceInfo, OpenNI2DeviceInfoComparator>::const_iterator it;
00172 std::set<OpenNI2DeviceInfo, OpenNI2DeviceInfoComparator>::const_iterator it_end = device_set_.end();
00173
00174 for (it = device_set_.begin(); it != it_end; ++it)
00175 result->push_back(it->uri_);
00176
00177 return result;
00178 }
00179
00180 boost::shared_ptr<std::vector<OpenNI2DeviceInfo> > getConnectedDeviceInfos()
00181 {
00182 boost::mutex::scoped_lock l(device_mutex_);
00183
00184 boost::shared_ptr<std::vector<OpenNI2DeviceInfo> > result = boost::make_shared<std::vector<OpenNI2DeviceInfo> >();
00185
00186 result->reserve(device_set_.size());
00187
00188 DeviceSet::const_iterator it;
00189 DeviceSet::const_iterator it_end = device_set_.end();
00190
00191 for (it = device_set_.begin(); it != it_end; ++it)
00192 result->push_back(*it);
00193
00194 return result;
00195 }
00196
00197 std::size_t getNumOfConnectedDevices()
00198 {
00199 boost::mutex::scoped_lock l(device_mutex_);
00200
00201 return device_set_.size();
00202 }
00203
00204 boost::mutex device_mutex_;
00205 DeviceSet device_set_;
00206 };
00207
00209
00210 boost::shared_ptr<OpenNI2DeviceManager> OpenNI2DeviceManager::singelton_;
00211
00212 OpenNI2DeviceManager::OpenNI2DeviceManager()
00213 {
00214 openni::Status rc = openni::OpenNI::initialize();
00215 if (rc != openni::STATUS_OK)
00216 THROW_OPENNI_EXCEPTION("Initialize failed\n%s\n", openni::OpenNI::getExtendedError());
00217
00218 device_listener_ = boost::make_shared<OpenNI2DeviceListener>();
00219 }
00220
00221 OpenNI2DeviceManager::~OpenNI2DeviceManager()
00222 {
00223 }
00224
00225 boost::shared_ptr<OpenNI2DeviceManager> OpenNI2DeviceManager::getSingelton()
00226 {
00227 if (singelton_.get()==0)
00228 singelton_ = boost::make_shared<OpenNI2DeviceManager>();
00229
00230 return singelton_;
00231 }
00232
00233 boost::shared_ptr<std::vector<OpenNI2DeviceInfo> > OpenNI2DeviceManager::getConnectedDeviceInfos() const
00234 {
00235 return device_listener_->getConnectedDeviceInfos();
00236 }
00237
00238 boost::shared_ptr<std::vector<std::string> > OpenNI2DeviceManager::getConnectedDeviceURIs() const
00239 {
00240 return device_listener_->getConnectedDeviceURIs();
00241 }
00242
00243 std::size_t OpenNI2DeviceManager::getNumOfConnectedDevices() const
00244 {
00245 return device_listener_->getNumOfConnectedDevices();
00246 }
00247
00248 boost::shared_ptr<OpenNI2Device> OpenNI2DeviceManager::getAnyDevice()
00249 {
00250 return boost::make_shared<OpenNI2Device>("");
00251 }
00252 boost::shared_ptr<OpenNI2Device> OpenNI2DeviceManager::getDevice(const std::string& device_URI)
00253 {
00254 return boost::make_shared<OpenNI2Device>(device_URI);
00255 }
00256
00257
00258 std::ostream& operator << (std::ostream& stream, const OpenNI2DeviceManager& device_manager) {
00259
00260 boost::shared_ptr<std::vector<OpenNI2DeviceInfo> > device_info = device_manager.getConnectedDeviceInfos();
00261
00262 std::vector<OpenNI2DeviceInfo>::const_iterator it;
00263 std::vector<OpenNI2DeviceInfo>::const_iterator it_end = device_info->end();
00264
00265 for (it = device_info->begin(); it != it_end; ++it)
00266 {
00267 stream << "Uri: " << it->uri_ << " (Vendor: " << it->vendor_ <<
00268 ", Name: " << it->name_ <<
00269 ", Vendor ID: " << it->vendor_id_ <<
00270 ", Product ID: " << it->product_id_ <<
00271 ")" << std::endl;
00272 }
00273 }
00274
00275
00276 }