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), 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
00031 timestamp=get_time();
00032 if(resourceSync!=NULL)
00033 resourceSync();
00034 static_cast<Resource&>(lock).releaseResource(d);
00035
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
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
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
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) {
00092 region = new RCRegion(minSize+padding);
00093
00094 }
00095 else if(region->Size() < minSize) {
00096
00097
00098 region->RemoveReference();
00099 region = new RCRegion(minSize+padding);
00100
00101 }
00102 regions.push_back(region);
00103 return region;
00104 }
00105
00106
00107
00108
00109
00110