Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

DataSource.cc

Go to the documentation of this file.
00001 #include "DataSource.h"
00002 #include "Shared/StackTrace.h"
00003 #include "IPC/RCRegion.h"
00004 #include "Shared/get_time.h"
00005 
00006 
00007 bool DataSource::requiresFirstSensor = true;
00008 const plist::Primitive<float>* DataSource::sensorFramerate=NULL;
00009 SensorState * DataSource::sensorState=NULL;
00010 
00011 
00012 SensorState::SensorState() : timestamp(0), frameNumber(0), dirty(false), motionOverride(NULL), /*updateSignal(),*/ resourceSync(NULL), lock() {
00013   for(unsigned int i=0; i<NumOutputs; ++i) {
00014     providedOutputs[i]=0;
00015     outputs[i]=0;
00016   }
00017   for(unsigned int i=0; i<NumButtons; ++i)
00018     buttons[i]=0;
00019   for(unsigned int i=0; i<NumSensors; ++i)
00020     sensors[i]=0;
00021   for(unsigned int i=0; i<NumPIDJoints; ++i)
00022     pids[i][0]=pids[i][1]=pids[i][2] = pidduties[i] = 0;
00023 }
00024 
00025 void SensorState::releaseResource(Data& d) {
00026   Thread::NoCancelScope nc;
00027   if(!dirty) {
00028     static_cast<Resource&>(lock).releaseResource(d);
00029   } else {
00030     //++frameNumber;  // this is done in Simulator::sendSensor() instead, see DataSource::SensorState::frameNumber docs
00031     timestamp=get_time();
00032     if(resourceSync!=NULL)
00033       resourceSync();
00034     static_cast<Resource&>(lock).releaseResource(d);
00035     //updateSignal.broadcast(); 
00036   }
00037 }
00038 
00039 
00040 DataSource::~DataSource() {
00041   std::for_each(regions.begin(),regions.end(),std::mem_fun(&RCRegion::RemoveReference));
00042   regions.clear();
00043 }
00044 
00045 void DataSource::providingOutput(unsigned int i) {
00046   if(i>=NumOutputs) {
00047     ASSERT(i==-1U,"DataSource is trying to provide a bad output " << i);
00048     return;
00049   }
00050   ++sensorState->providedOutputs[i];
00051   if(sensorState->providedOutputs[i]>1)
00052     std::cerr << "WARNING: multiple (" << sensorState->providedOutputs[i] <<") data sources are claiming to provide feedback for " << outputNames[i] << std::endl;
00053   //std::cout << "PROVIDING " << i << " (" << outputNames[i] << ") now " << sensorState->providedOutputs[i] << std::endl;
00054 }
00055 
00056 void DataSource::ignoringOutput(unsigned int i) {
00057   if(i>=NumOutputs) {
00058     ASSERT(i==-1U,"DataSource is trying to ignore a bad output " << i);
00059     return;
00060   }
00061   if(sensorState->providedOutputs[i]==0) {
00062     std::cerr << "ERROR: DataSource output tracking underflow" << std::endl;
00063     stacktrace::displayCurrentStackTrace();
00064     return;
00065   }
00066   --sensorState->providedOutputs[i];
00067   if(sensorState->providedOutputs[i]==1)
00068     std::cerr << "NOTICE: feedback conflict for " << outputNames[i] << " has been resolved." << std::endl;
00069   //std::cout << "IGNORING " << i << " (" << outputNames[i] << ") now " << sensorState->providedOutputs[i] << std::endl;
00070 }
00071 
00072 void DataSource::setImage(const ImageHeader& header, const void * data) {
00073   const size_t datasize = header.width*header.height*header.components;
00074   RCRegion * r = getUnusedRegion(sizeof(header) + datasize,0);
00075   memcpy(r->Base(),&header,sizeof(header));
00076   memcpy(r->Base()+sizeof(header), data, datasize);
00077   setImage(r);
00078 }
00079 
00080 RCRegion* DataSource::getUnusedRegion(size_t minSize, size_t padding) {
00081   // find first 'unused' region
00082   RCRegion* region=NULL;
00083   for(std::list<RCRegion*>::iterator it=regions.begin();it!=regions.end(); ++it) {
00084     if((*it)->NumberOfReference()==1) {
00085       region=*it;
00086       regions.erase(it);
00087       break;
00088     }
00089   }
00090   
00091   if(region==NULL) { // if we didn't find one create one now
00092     region = new RCRegion(minSize+padding);
00093     //std::cout << "DataSource::getUnusedRegion() created " << region->ID().key << " size " << region->Size() << std::endl;
00094   }
00095   else if(region->Size() < minSize) {
00096     //too small -- free it and make a bigger one
00097     //std::cout << "DataSource::getUnusedRegion() released " << region->ID().key << " size " << region->Size() << std::endl;
00098     region->RemoveReference(); 
00099     region = new RCRegion(minSize+padding);
00100     //std::cout << "DataSource::getUnusedRegion() created " << region->ID().key << " size " << region->Size() << std::endl;
00101   }
00102   regions.push_back(region);
00103   return region;
00104 }
00105 
00106 
00107 /*! @file
00108  * @brief 
00109  * @author Ethan Tira-Thompson (ejt) (Creator)
00110  */

Tekkotsu Hardware Abstraction Layer 5.1CVS
Generated Mon May 9 05:01:38 2016 by Doxygen 1.6.3