SSC32Driver.cc
Go to the documentation of this file.00001 #include "SSC32Driver.h"
00002 #include "Shared/MarkScope.h"
00003 #include "Shared/get_time.h"
00004 #include "Shared/debuget.h"
00005
00006 using namespace std;
00007
00008 const unsigned int SSC32Driver::NUM_SERVO;
00009 const int SSC32Driver::UNUSED;
00010 const std::string SSC32Driver::autoRegisterSSC32Driver = DeviceDriver::getRegistry().registerType<SSC32Driver>("SSC32");
00011
00012 void SSC32Driver::motionStarting() {
00013 ASSERTRET(!motionActive,"SSC32Driver::motionStarting, but motionActive is true");
00014 MotionHook::motionStarting();
00015 CommPort * comm = CommPort::getRegistry().getInstance(commName);
00016 if(comm==NULL)
00017 std::cerr << "SSC32Driver \"" << instanceName << "\": could not find CommPort \"" << commName << "\"" << std::endl;
00018 else
00019 comm->open();
00020 motionActive=true;
00021 commName.addPrimitiveListener(this);
00022
00023 for(unsigned i = 0; i < NUM_SERVO; i++) {
00024 if(killSignalDelayed[i]) {
00025 sparse=true;
00026 queryServos=true;
00027 }
00028 }
00029 }
00030
00031 bool SSC32Driver::isConnected() {
00032 CommPort * comm = CommPort::getRegistry().getInstance(commName);
00033 return (comm!=NULL && comm->isWriteable());
00034 }
00035
00036 void SSC32Driver::motionStopping() {
00037 ASSERTRET(motionActive,"SSC32Driver::motionStopping, but motionActive is false");
00038 motionActive=false;
00039 if(!sensorsActive)
00040 commName.removePrimitiveListener(this);
00041 CommPort * comm = CommPort::getRegistry().getInstance(commName);
00042 if(comm!=NULL)
00043 comm->close();
00044 MotionHook::motionStopping();
00045 }
00046
00047 void SSC32Driver::motionCheck(const float outputs[][NumOutputs]) {
00048 CommPort * comm = CommPort::getRegistry().getInstance(commName);
00049 if(comm==NULL || !comm->isWriteable())
00050 return;
00051
00052 stringstream ss;
00053 for(unsigned int i=0; i<NUM_SERVO; i++) {
00054 int idx=servos[i];
00055 if(idx<0 || static_cast<unsigned int>(idx)>=NumOutputs) {
00056 if(idx!=UNUSED)
00057 std::cerr << "Warning: SSC32 driver mapping servo " << i << " to invalid output index " << idx << std::endl;
00058 continue;
00059 }
00060
00061
00062
00063
00064 if(isFirstCheck || !sparse || lastOutputs[idx]!=outputs[NumFrames-1][idx] ) {
00065
00066 setServo(ss, i, outputs[NumFrames-1][idx]);
00067 }
00068 }
00069 string s=ss.str();
00070 if(s.size()>0) {
00071 Thread::Lock& l = comm->getLock();
00072 unsigned int t=get_time();
00073
00074 unsigned int dt = static_cast<unsigned int>(NumFrames*FrameTime/((getTimeScale()>0)?getTimeScale():1.f));
00075 unsigned int giveup = t+dt*3/4;
00076 t+=dt;
00077 while(!l.trylock()) {
00078 if(get_time()>=giveup) {
00079 if(MotionHook::verbose>0)
00080 cerr << "Dropping SSC32 motion update: couldn't get lock on comm port" << endl;
00081 return;
00082 }
00083 usleep(1000);
00084 }
00085 MarkScope autolock(l); l.unlock();
00086 std::ostream os(&comm->getWriteStreambuf());
00087
00088
00089
00090 os.exceptions(ios_base::badbit);
00091
00092 unsigned int curt = get_time();
00093 if(curt>=t)
00094 os << s << '\r' << flush;
00095 else {
00096 dt=t-curt;
00097 os << s << 'T' << dt << '\r' << flush;
00098 }
00099 }
00100
00101 MotionHook::motionCheck(outputs);
00102 }
00103
00104
00105 unsigned int SSC32Driver::nextTimestamp() {
00106 CommPort * comm = CommPort::getRegistry().getInstance(commName);
00107 if(comm==NULL || !comm->isReadable())
00108 return -1U;
00109 return static_cast<unsigned int>(lastSensorTime + 1000.f/(*sensorFramerate) + .5f);
00110 }
00111
00112 void SSC32Driver::registerSource() {
00113 ASSERTRET(!sensorsActive,"SSC32Driver::registerSource, but sensorsActive is true");
00114 CommPort * comm = CommPort::getRegistry().getInstance(commName);
00115 if(comm!=NULL)
00116 comm->open();
00117 queryServos.addPrimitiveListener(this);
00118 if(queryServos) {
00119 for(unsigned int i=0; i<NUM_SERVO; i++) {
00120 provideOutput(servos[i]);
00121 servos[i].addPrimitiveListener(this);
00122 }
00123 }
00124 sensorsActive=true;
00125 commName.addPrimitiveListener(this);
00126 }
00127 void SSC32Driver::deregisterSource() {
00128 ASSERTRET(sensorsActive,"SSC32Driver::deregisterSource, but sensorsActive is false");
00129 CommPort * comm = CommPort::getRegistry().getInstance(commName);
00130 if(comm!=NULL)
00131 comm->close();
00132 if(queryServos) {
00133 for(unsigned int i=0; i<NUM_SERVO; ++i) {
00134 servos[i].removePrimitiveListener(this);
00135 ignoreOutput(servos[i]);
00136 }
00137 }
00138 queryServos.removePrimitiveListener(this);
00139 sensorsActive=false;
00140 if(!motionActive)
00141 commName.removePrimitiveListener(this);
00142 }
00143 void SSC32Driver::doUnfreeze() {
00144 MarkScope sl(poller.getStartLock());
00145 if(!poller.isStarted()) {
00146 poller.resetPeriod(1.0/(*sensorFramerate));
00147 poller.start();
00148 }
00149 sensorFramerate->addPrimitiveListener(this);
00150 }
00151 void SSC32Driver::doFreeze() {
00152 MarkScope sl(poller.getStartLock());
00153 if(poller.isStarted())
00154 poller.stop().join();
00155 sensorFramerate->removePrimitiveListener(this);
00156 }
00157
00158
00159 bool SSC32Driver::advance() {
00160 CommPort * comm = CommPort::getRegistry().getInstance(commName);
00161 if(comm==NULL || !comm->isReadable() || !comm->isWriteable())
00162 return false;
00163
00164 MarkScope commlock(comm->getLock());
00165 std::ostream os(&comm->getWriteStreambuf());
00166 std::istream is(&comm->getReadStreambuf());
00167
00168
00169
00170 os.exceptions(ios_base::badbit);
00171 is.exceptions(ios_base::badbit);
00172
00173 unsigned T = get_time();
00174
00175 MarkScope writelock(getSensorWriteLock());
00176
00177
00178
00179
00180 if((!isFirstCheck || DataSource::requiresFirstSensor) && queryServos) {
00181
00182 stringstream q;
00183 for(unsigned int i=0; i<NUM_SERVO; i++) {
00184 int idx=servos[i];
00185 if(idx<0 || static_cast<unsigned int>(idx)>=NumOutputs)
00186 continue;
00187 q << "QP " << i << ' ';
00188 }
00189 try {
00190 os << q.rdbuf() << '\r' << flush;
00191 } catch(const std::exception&) {}
00192 if(!os) {
00193 std::cerr << "SSC32 position query failed (bad write)" << std::endl;
00194 return false;
00195 }
00196 for(unsigned int i=0; i<NUM_SERVO; i++) {
00197 int idx=servos[i];
00198 if(idx<0 || static_cast<unsigned int>(idx)>=NumOutputs)
00199 continue;
00200 int check=is.get();
00201 if(check==-1) {
00202 cerr << "SSC32Driver: bad read!" << endl;
00203 return false;
00204 }
00205 unsigned int v=(unsigned char)check;
00206 if(killSignalDelayed[i]) {
00207 float val = getServo(i,v*10);
00208 float prev = getOutputValue(idx);
00209
00210 if(val != prev) {
00211 timeLastChanged[i] = T;
00212 } else if(timeLastChanged[i] != 0 && T - timeLastChanged[i] > 1000) {
00213 os<<"#"<<i<<"L\r";
00214 os.flush();
00215 timeLastChanged[i] = 0;
00216 }
00217 }
00218 setOutputValue(idx, getServo(i,v*10));
00219 }
00220 }
00221 stringstream aq,dq;
00222 bool acnt=false,dcnt=false;
00223 for(unsigned int i=0; i<NUM_INPUT; i++) {
00224 int idx=inputs[i];
00225 if(!buttonMode[i]) {
00226 if(idx<0 || static_cast<unsigned int>(idx)>=NumSensors) {
00227 if(idx!=UNUSED)
00228 std::cerr << "Warning: SSC32 driver mapping input " << i << " to invalid sensor index " << idx << std::endl;
00229 continue;
00230 }
00231 acnt=true;
00232 aq << 'V' << char('A'+i) << ' ';
00233 } else {
00234 if(idx<0 || static_cast<unsigned int>(idx)>=NumButtons) {
00235 if(idx!=UNUSED)
00236 std::cerr << "Warning: SSC32 driver mapping input " << i << " to invalid button index " << idx << std::endl;
00237 continue;
00238 }
00239 dcnt=true;
00240 dq << char('A'+i) << ' ' << char('A'+i) << "L ";
00241 }
00242 }
00243
00244
00245 try {
00246 if(dcnt)
00247 os << dq.str() << '\r';
00248 if(acnt)
00249 os << aq.str() << '\r';
00250 if(dcnt || acnt)
00251 os << flush;
00252 } catch(const std::exception&) {}
00253 if(!os) {
00254 std::cerr << "SSC32 sensor query failed (bad write)" << std::endl;
00255 return false;
00256 }
00257
00258
00259 if(dcnt) {
00260 for(unsigned int i=0; i<NUM_INPUT; i++) {
00261 int idx=inputs[i];
00262 if(idx>=0 && static_cast<unsigned int>(idx)<NumButtons && buttonMode[i]) {
00263 int check=is.get();
00264 if(check==-1) {
00265 cerr << "SSC32Driver: bad read!" << endl;
00266 return false;
00267 }
00268 unsigned char cur=check;
00269 check=is.get();
00270 if(check==-1) {
00271 cerr << "SSC32Driver: bad read!" << endl;
00272 return false;
00273 }
00274 unsigned char latch=check;
00275 setButtonValue(idx, getDigital(i,cur,latch));
00276 }
00277 }
00278 }
00279 if(acnt) {
00280 for(unsigned int i=0; i<NUM_INPUT; i++) {
00281 int idx=inputs[i];
00282 if(idx>=0 && static_cast<unsigned int>(idx)<NumSensors && !buttonMode[i]) {
00283 int check=is.get();
00284 if(check==-1) {
00285 cerr << "SSC32Driver: bad read!" << endl;
00286 return false;
00287 }
00288 setSensorValue(idx, getAnalog(i,check));
00289 }
00290 }
00291 }
00292 lastSensorTime=get_time();
00293 ++frameNumber;
00294 return true;
00295 }
00296
00297 void SSC32Driver::plistValueChanged(const plist::PrimitiveBase& pl) {
00298 if(&pl==&commName) {
00299
00300
00301 if(poller.isStarted())
00302 poller.stop().join();
00303
00304 CommPort * comm = CommPort::getRegistry().getInstance(commName.getPreviousValue());
00305 if(comm!=NULL) {
00306
00307 if(sensorsActive)
00308 comm->close();
00309 if(motionActive)
00310 comm->close();
00311 }
00312 comm = CommPort::getRegistry().getInstance(commName);
00313 if(comm==NULL) {
00314 std::cerr << "SSC32Driver \"" << instanceName << "\": could not find CommPort \"" << commName << "\"" << std::endl;
00315 } else {
00316
00317 if(sensorsActive)
00318 comm->open();
00319 if(motionActive)
00320 comm->open();
00321 }
00322
00323 if(getTimeScale()>0) {
00324 poller.resetPeriod(1.0/(*sensorFramerate));
00325 poller.start();
00326 }
00327 } else if(&pl==&queryServos) {
00328
00329
00330 if(queryServos) {
00331 for(unsigned int i=0; i<NUM_SERVO; i++) {
00332 provideOutput(servos[i]);
00333 servos[i].addPrimitiveListener(this);
00334 }
00335 } else {
00336 for(unsigned int i=0; i<NUM_SERVO; ++i) {
00337 servos[i].removePrimitiveListener(this);
00338 ignoreOutput(servos[i]);
00339 }
00340 }
00341 } else if(&pl==sensorFramerate) {
00342 poller.resetPeriod(1.0/(*sensorFramerate));
00343 } else {
00344
00345
00346 for(unsigned int i=0; i<NUM_SERVO; ++i) {
00347 if(&pl==&servos[i]) {
00348 ignoreOutput(servos[i].getPreviousValue());
00349 provideOutput(servos[i]);
00350 return;
00351 }
00352 }
00353 std::cerr << "Unhandled value change in " << getClassName() << ": " << pl.get() << std::endl;
00354 }
00355 }
00356
00357 void SSC32Driver::setServo(std::ostream& ss, unsigned int servoIdx, float v) {
00358
00359 unsigned int outputIdx = servos[servoIdx];
00360
00361 float outRange = outputRanges[outputIdx][MaxRange]-outputRanges[outputIdx][MinRange];
00362
00363 unsigned int servoRange = maxPW[servoIdx]-minPW[servoIdx];
00364
00365 float cmd = (v-outputRanges[outputIdx][MinRange])/outRange;
00366
00367
00368 #ifdef TGT_HAS_LEDS
00369 if(outputIdx<LEDOffset || outputIdx>=LEDOffset+NumLEDs)
00370 cmd=1-cmd;
00371 #endif
00372
00373 float pw = cmd*servoRange+minPW[servoIdx];
00374 if(pw<0)
00375 pw=0;
00376
00377 unsigned int bpw = static_cast<unsigned int>(pw+0.5);
00378
00379 if(bpw<minPW[servoIdx])
00380 bpw=minPW[servoIdx];
00381 if(bpw>maxPW[servoIdx])
00382 bpw=maxPW[servoIdx];
00383
00384 ss << '#' << servoIdx << " P" << bpw << ' ';
00385 }
00386
00387 float SSC32Driver::getServo(unsigned int servoIdx, unsigned int pw) {
00388 unsigned int outputIdx = servos[servoIdx];
00389
00390 float outRange = outputRanges[outputIdx][MaxRange]-outputRanges[outputIdx][MinRange];
00391
00392 unsigned int servoRange = maxPW[servoIdx]-minPW[servoIdx];
00393
00394 return (pw-minPW[servoIdx])*outRange/servoRange + outputRanges[outputIdx][MinRange];
00395 }
00396
00397 float SSC32Driver::getAnalog(unsigned int , unsigned char s) {
00398 return s*5.f/256;
00399 }
00400
00401 float SSC32Driver::getDigital(unsigned int , unsigned char cur, unsigned char latch) {
00402
00403 if (cur=='1')
00404 return 0;
00405
00406 return (latch=='1') ? 0.5f : 1;
00407 }
00408
00409
00410
00411
00412