TOBI SignalServer
0.1
|
00001 /* 00002 This file is part of the TOBI SignalServer. 00003 00004 Commercial Usage 00005 Licensees holding valid Graz University of Technology Commercial 00006 licenses may use this file in accordance with the Graz University 00007 of Technology Commercial License Agreement provided with the 00008 Software or, alternatively, in accordance with the terms contained in 00009 a written agreement between you and Graz University of Technology. 00010 00011 -------------------------------------------------- 00012 00013 GNU General Public License Usage 00014 Alternatively, this file may be used under the terms of the GNU 00015 General Public License version 3.0 as published by the Free Software 00016 Foundation and appearing in the file gpl.txt included in the 00017 packaging of this file. Please review the following information to 00018 ensure the GNU General Public License version 3.0 requirements will be 00019 met: http://www.gnu.org/copyleft/gpl.html. 00020 00021 In case of GNU General Public License Usage ,the TOBI SignalServer 00022 is distributed in the hope that it will be useful, 00023 but WITHOUT ANY WARRANTY; without even the implied warranty of 00024 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00025 GNU General Public License for more details. 00026 00027 You should have received a copy of the GNU General Public License 00028 along with the TOBI SignalServer. If not, see <http://www.gnu.org/licenses/>. 00029 00030 Copyright 2010 Graz University of Technology 00031 Contact: SignalServer@tobi-project.org 00032 */ 00033 00038 #include <iostream> 00039 00040 #include "hardware/kinect.h" 00041 00042 using boost::interprocess::shared_memory_object; 00043 using boost::interprocess::open_only; 00044 using boost::interprocess::read_write; 00045 00046 using boost::posix_time::millisec; 00047 using boost::posix_time::microsec_clock; 00048 00049 using std::vector; 00050 using std::pair; 00051 using std::string; 00052 using std::cout; 00053 using std::endl; 00054 00055 namespace tobiss 00056 { 00057 00058 const HWThreadBuilderTemplateRegistratorWithoutIOService<KinectShmReader> KinectShmReader::FACTORY_REGISTRATOR_ ("kinect"); 00059 const char *KinectShmReader::SHARED_MEMORY_NAME = "MotionSensingSharedMemory"; 00060 00061 //----------------------------------------------------------------------------- 00062 KinectShmReader::KinectShmReader(ticpp::Iterator<ticpp::Element> hw) 00063 : HWThread(), old_frame_id_(0), connected_(false), event_reset_needed_(false), KinectShmReader_data_(6, 0) 00064 { 00065 #ifdef DEBUG 00066 cout << "KinectShmReader: Constructor" << endl; 00067 #endif 00068 00069 // setup shared memory 00070 try{ 00071 shared_memory_obj_ = new shared_memory_object(open_only, SHARED_MEMORY_NAME, read_write); 00072 region_ = new boost::interprocess::mapped_region(*shared_memory_obj_, read_write); 00073 void *addr = region_->get_address(); 00074 shared_memory_ = static_cast<shared_memory_struct *>(addr); 00075 } catch(boost::interprocess::interprocess_exception &ex) 00076 { 00077 throw(std::runtime_error("KinectShmReader::KinectShmReader -- unable to open shared memory. Is the motion sensing software running?")); 00078 } 00079 00080 // increase the client counter in order to prevent that the motion sensing software destroys/* the shared memory when the client is still active 00081 shared_memory_->mutex.lock(); 00082 shared_memory_->clients++; 00083 shared_memory_->mutex.unlock(); 00084 00085 setType("KinectShmReader motion sensing device"); 00086 00087 checkMandatoryHardwareTags(hw); 00088 00089 if(mode_ != APERIODIC) 00090 throw(std::invalid_argument("KinectShmReader motion sensing device has to be started as aperiodic device!")); 00091 00092 setChannelSettings(0); 00093 00094 data_.init(1, channel_types_.size() , channel_types_); 00095 vector<boost::uint32_t> v; 00096 empty_block_.init(0, 0, v); 00097 00098 last_change_ = microsec_clock::local_time(); 00099 } 00100 00101 //--------------------------------------------------------------------------------------- 00102 00103 KinectShmReader::~KinectShmReader() 00104 { 00105 shared_memory_->mutex.lock(); 00106 shared_memory_->clients--; 00107 shared_memory_->mutex.unlock(); 00108 00109 delete region_; 00110 delete shared_memory_obj_; 00111 } 00112 00113 //--------------------------------------------------------------------------------------- 00114 00115 void KinectShmReader::setDeviceSettings(ticpp::Iterator<ticpp::Element>const&) 00116 { 00117 #ifdef DEBUG 00118 cout << "KinectShmReader: setDeviceSettings" << endl; 00119 #endif 00120 } 00121 00122 //--------------------------------------------------------------------------------------- 00123 00124 void KinectShmReader::setChannelSettings(ticpp::Iterator<ticpp::Element>const&) 00125 { 00126 #ifdef DEBUG 00127 cout << "KinectShmReader: setChannelSettings" << endl; 00128 #endif 00129 00130 channel_types_.push_back(SIG_USER_2); 00131 channel_types_.push_back(SIG_USER_2); 00132 channel_types_.push_back(SIG_USER_2); 00133 channel_types_.push_back(SIG_USER_3); 00134 channel_types_.push_back(SIG_USER_3); 00135 channel_types_.push_back(SIG_USER_3); 00136 00137 channel_info_.insert(pair<boost::uint16_t, pair<string, boost::uint32_t> >(1, pair<string, boost::uint32_t>("x", SIG_USER_2))); 00138 channel_info_.insert(pair<boost::uint16_t, pair<string, boost::uint32_t> >(2, pair<string, boost::uint32_t>("y", SIG_USER_2))); 00139 channel_info_.insert(pair<boost::uint16_t, pair<string, boost::uint32_t> >(3, pair<string, boost::uint32_t>("z", SIG_USER_2))); 00140 channel_info_.insert(pair<boost::uint16_t, pair<string, boost::uint32_t> >(4, pair<string, boost::uint32_t>("confidence", SIG_USER_3))); 00141 channel_info_.insert(pair<boost::uint16_t, pair<string, boost::uint32_t> >(5, pair<string, boost::uint32_t>("event", SIG_USER_3))); 00142 channel_info_.insert(pair<boost::uint16_t, pair<string, boost::uint32_t> >(6, pair<string, boost::uint32_t>("state", SIG_USER_3))); 00143 00144 homogenous_signal_type_ = 0; 00145 nr_ch_ = 6; 00146 } 00147 00148 //--------------------------------------------------------------------------------------- 00149 00150 SampleBlock<double> KinectShmReader::getAsyncData() 00151 { 00152 #ifdef DEBUG 00153 cout << "KinectShmReader: getAsyncData" << endl; 00154 #endif 00155 00156 bool dirty = false; 00157 00158 shared_memory_->mutex.lock(); 00159 00160 boost::uint32_t frame_id = shared_memory_->frame_id; 00161 00162 if (frame_id - old_frame_id_ > 1 && old_frame_id_ != 0) 00163 { 00164 std::cout << std::endl << "* warning: missed " << frame_id - old_frame_id_ + 1 << " motion frames, ensure that master's sample rate is sufficiently high" << std::endl; 00165 } 00166 00167 if (frame_id != old_frame_id_) // new frame was written to shared memory 00168 { 00169 dirty = true; 00170 00171 KinectShmReader_data_[0] = shared_memory_->x; 00172 KinectShmReader_data_[1] = shared_memory_->y; 00173 KinectShmReader_data_[2] = shared_memory_->z; 00174 KinectShmReader_data_[3] = shared_memory_->confidence; 00175 KinectShmReader_data_[4] = shared_memory_->event; 00176 KinectShmReader_data_[5] = shared_memory_->state; 00177 00178 old_frame_id_ = frame_id; 00179 last_change_ = microsec_clock::local_time(); 00180 00181 if (!connected_) 00182 { 00183 std::cout << std::endl << " * connected to motion sensing software" << std::endl; 00184 connected_ = true; 00185 } 00186 } 00187 else if (last_change_ + millisec(TIMEOUT) < microsec_clock::local_time() && connected_) // timeout, no new data frame was written to the shared memory for some time 00188 { 00189 dirty = true; 00190 00191 KinectShmReader_data_[0] = 0; 00192 KinectShmReader_data_[1] = 0; 00193 KinectShmReader_data_[2] = 0; 00194 KinectShmReader_data_[3] = 0; 00195 KinectShmReader_data_[4] = 0; 00196 KinectShmReader_data_[5] = 0; 00197 00198 std::cout << std::endl << " * connection to motion sensing software timed out" << std::endl; 00199 connected_ = false; 00200 } 00201 00202 shared_memory_->mutex.unlock(); 00203 00204 if (dirty || event_reset_needed_) 00205 { 00206 data_.setSamples(KinectShmReader_data_); 00207 if (KinectShmReader_data_[4] != 0) // a hack to ensure that *discrete* events will still be discrete events on the client side 00208 { 00209 KinectShmReader_data_[4] = 0; 00210 event_reset_needed_ = true; 00211 } 00212 else 00213 { 00214 event_reset_needed_ = false; 00215 } 00216 return(data_); 00217 } 00218 else 00219 { 00220 return(empty_block_); 00221 } 00222 } 00223 00224 //----------------------------------------------------------------------------- 00225 00226 void KinectShmReader::run() { } 00227 00228 //----------------------------------------------------------------------------- 00229 00230 void KinectShmReader::stop() { } 00231 00232 //----------------------------------------------------------------------------- 00233 00234 } // Namespace tobiss