TOBI SignalServer  0.1
/home/breidi/Dropbox/signalserver/src/hardware/kinect.cpp
Go to the documentation of this file.
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
 All Data Structures Files Functions Variables