Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

CreateDriver.cc

Go to the documentation of this file.
00001 #include "Shared/RobotInfo.h"
00002 #if defined(TGT_IS_CREATE) || defined(TGT_IS_CREATE2)
00003 
00004 #include "CreateDriver.h"
00005 #include "CreateCommands.h"
00006 #include "Shared/MarkScope.h"
00007 #include "Shared/get_time.h"
00008 #include "Shared/debuget.h"
00009 #include "Shared/TimeET.h"
00010 
00011 #include <arpa/inet.h>
00012 #include <stdio.h>
00013 #include <cmath>
00014 
00015 using namespace std; 
00016 
00017 #ifdef TGT_IS_CREATE
00018 const std::string CreateDriver::autoRegisterCreateDriver = DeviceDriver::getRegistry().registerType<CreateDriver>("Create");
00019 #else
00020 const std::string CreateDriver::autoRegisterCreateDriver = DeviceDriver::getRegistry().registerType<CreateDriver>("Create2");
00021 #endif
00022 
00023 void CreateDriver::motionStarting() {
00024   //  std::cout << "motionStarting called!" << std::endl;
00025   MotionHook::motionStarting();
00026   CommPort * comm = CommPort::getRegistry().getInstance(commName);
00027   if(comm==NULL)
00028     std::cerr << "CreateDriver \"" << instanceName << "\": could not find CommPort \"" << commName << "\"" << std::endl;
00029   else if(!comm->open())
00030     std::cerr << "CreateDriver \"" << instanceName << "\": unable to open comm port \"" << commName << "\"" << std::endl;
00031   else
00032     connect();
00033   motionActive=true;
00034   commName.addPrimitiveListener(this);
00035 }
00036 
00037 bool CreateDriver::isConnected() {
00038   CommPort * comm = CommPort::getRegistry().getInstance(commName);
00039   return (comm!=NULL && comm->isWriteable());
00040 }
00041 
00042 void CreateDriver::motionStopping() {
00043   motionActive=false;
00044   if(!sensorsActive) // listener count is not recursive, so only remove if we're the last one
00045     commName.removePrimitiveListener(this);
00046   CommPort * comm = CommPort::getRegistry().getInstance(commName);
00047   if(comm!=NULL)
00048     comm->close(); // this *is* recursive, so we always close it to match our open() in motionStarting()
00049   MotionHook::motionStopping();
00050 }
00051 
00052 void CreateDriver::motionCheck(const float outputs[][NumOutputs]) {
00053   CommPort * comm = CommPort::getRegistry().getInstance(commName);
00054   if(comm==NULL || !comm->isWriteable())
00055     return;
00056   
00057   vector<unsigned char> commands(0);
00058   
00059   commands.push_back(CREATE_DRIVE_DIRECT);
00060   short output;
00061   output = (short)outputs[NumFrames-1][RobotInfo::RWheelOffset];
00062   commands.push_back((unsigned char)(output >> 8));
00063   commands.push_back((unsigned char)(output & 0xFF));
00064   output = (short)outputs[NumFrames-1][RobotInfo::LWheelOffset];
00065   commands.push_back((unsigned char)(output >> 8));
00066   commands.push_back((unsigned char)(output & 0xFF));
00067   
00068   commands.push_back(CREATE_LEDS);
00069   unsigned char led = 0;
00070   if (calcLEDValue(RobotInfo::PlayLEDOffset-LEDOffset,outputs[NumFrames-1][RobotInfo::PlayLEDOffset]))
00071     led = led | 0x2;
00072   if (calcLEDValue(RobotInfo::AdvanceLEDOffset-LEDOffset,outputs[NumFrames-1][RobotInfo::AdvanceLEDOffset]))
00073     led = led | 0x8;
00074   commands.push_back(led);
00075   float red = outputs[NumFrames-1][RobotInfo::PowerRedLEDOffset];
00076   float green = outputs[NumFrames-1][RobotInfo::PowerGreenLEDOffset];
00077   if (red == 0 && green == 0)
00078     commands.push_back((unsigned char)0);
00079   else
00080     commands.push_back((unsigned char)(255 * red / (red + green)));
00081   commands.push_back((unsigned char)(255 * max(red, green)));
00082   
00083   /*
00084     unsigned char desiredMode = (unsigned char)outputs[NumFrames-1][RobotInfo::ModeOffset];
00085     if (desiredMode != 0 && desiredMode != lastDesiredMode) {
00086     if (desiredMode == RobotInfo::MODE_SAFE)
00087     commands.push_back(CREATE_SAFE);
00088     if (desiredMode == RobotInfo::MODE_PASSIVE)
00089     commands.push_back(CREATE_START);
00090     if (desiredMode == RobotInfo::MODE_FULL)
00091     commands.push_back(CREATE_FULL);
00092    
00093     lastDesiredMode = desiredMode;
00094     }
00095   */
00096   
00097   unsigned int dt = static_cast<unsigned int>(NumFrames*FrameTime/((getTimeScale()>0)?getTimeScale():1.f));
00098   sendCommand(commands, dt*3/4);
00099   MotionHook::motionCheck(outputs); // updates lastOutputs and isFirstCheck, we ignore its motionUpdated() call
00100 }
00101 
00102 bool CreateDriver::sendCommand(vector<unsigned char> bytes, unsigned int timeout) {
00103   CommPort * comm = CommPort::getRegistry().getInstance(commName);
00104   if(comm==NULL)
00105     return false;
00106   Thread::Lock& l = comm->getLock();
00107   
00108   //  cout << "CREATE: Trying to get lock for write." << endl;
00109   
00110   unsigned int t = get_time();
00111   unsigned int giveup = t + timeout;
00112   
00113   while (!l.trylock()) {
00114     if (get_time() >= giveup) {
00115       if(MotionHook::verbose>0)
00116   cerr << "CREATE: Unable to send command: couldn't get lock on comm port" << endl;
00117       return false;
00118     }
00119     usleep(1000);
00120   }
00121   
00122   MarkScope autolock(l); l.unlock(); //transfer lock to MarkScope
00123   
00124   std::ostream os(&comm->getWriteStreambuf());
00125   //cout << endl << "W";
00126   for (unsigned int i = 0; i < bytes.size(); i++) {
00127     os << bytes[i];
00128     //cout << " " << (int)bytes[i];
00129   }
00130   os << std::flush;
00131   //cout << endl;
00132   
00133   return true;
00134 }
00135 
00136 void CreateDriver::connect() {
00137   vector<unsigned char> commands(2);
00138   commands[0] = CREATE_START;
00139   commands[1] = CREATE_SAFE;
00140   sendCommand(commands, 3000000);
00141   // cout << "Connecting to CREATE\n" << flush;
00142 }
00143 
00144 unsigned int CreateDriver::nextTimestamp() {
00145   CommPort * comm = CommPort::getRegistry().getInstance(commName);
00146   if(comm==NULL || !comm->isReadable())
00147     return -1U;
00148   return get_time();
00149 }
00150 
00151 unsigned int CreateDriver::readUnsignedChar(std::istream &is, unsigned char &chk) {
00152   char b;
00153   
00154   // do non-blocking read until given timeout; wait for 100 ms
00155   TimeET giveup = TimeET() + TimeET((long)100);
00156   while (!is.readsome(&b,1)) {
00157     if (giveup < TimeET()) {
00158       return -1U; //throw std::runtime_error("CREATE DRIVER: Nothing to read");
00159     }
00160   }
00161   chk += (unsigned char)b;
00162   return (unsigned char)b;
00163 }
00164 
00165 unsigned int CreateDriver::readUnsignedShort(std::istream &is, unsigned char &chk) {
00166   unsigned int a = readUnsignedChar(is, chk);
00167   if ( a == -1U )
00168     return a;
00169   else {
00170     unsigned int b = readUnsignedChar(is, chk);
00171     if ( b == -1U )
00172       return b;
00173     else
00174       return (a << 8) | b;
00175   }
00176 }
00177 int CreateDriver::readPacket(std::istream &is, const char &type, CreateStatus &createStatus, unsigned char &chk) {
00178   int total = 0;
00179   unsigned int data = 0;
00180   int const fail = -1000;
00181   switch(type) {
00182   case CREATE_SENSOR_GROUP_0:
00183     total += readPacket(is, CREATE_SENSOR_DROP, createStatus, chk);
00184     if ( total < 0 ) return fail;
00185     total += readPacket(is, CREATE_SENSOR_WALL, createStatus, chk);
00186     if ( total < 0 ) return fail;
00187     total += readPacket(is, CREATE_SENSOR_CLIFF_LEFT, createStatus, chk);
00188     if ( total < 0 ) return fail;
00189     total += readPacket(is, CREATE_SENSOR_CLIFF_FRONT_LEFT, createStatus, chk);
00190     if ( total < 0 ) return fail;
00191     total += readPacket(is, CREATE_SENSOR_CLIFF_FRONT_RIGHT, createStatus, chk);
00192     if ( total < 0 ) return fail;
00193     total += readPacket(is, CREATE_SENSOR_CLIFF_RIGHT, createStatus, chk);
00194     if ( total < 0 ) return fail;
00195     total += readPacket(is, CREATE_SENSOR_VIRTUAL_WALL, createStatus, chk);
00196     if ( total < 0 ) return fail;
00197     total += readPacket(is, CREATE_SENSOR_OVERCURRENT, createStatus, chk);
00198     if ( total < 0 ) return fail;
00199     total += readPacket(is, CREATE_SENSOR_DIRT, createStatus, chk);
00200     if ( total < 0 ) return fail;
00201     total += readPacket(is, CREATE_SENSOR_UNUSED_2, createStatus, chk);
00202     if ( total < 0 ) return fail;
00203     total += readPacket(is, CREATE_SENSOR_IR, createStatus, chk);
00204     if ( total < 0 ) return fail;
00205     total += readPacket(is, CREATE_SENSOR_BUTTONS, createStatus, chk);
00206     if ( total < 0 ) return fail;
00207     total += readPacket(is, CREATE_SENSOR_DISTANCE, createStatus, chk);
00208     if ( total < 0 ) return fail;
00209     total += readPacket(is, CREATE_SENSOR_ANGLE, createStatus, chk);
00210     if ( total < 0 ) return fail;
00211     total += readPacket(is, CREATE_SENSOR_CHANGING_STATE, createStatus, chk);
00212     if ( total < 0 ) return fail;
00213     total += readPacket(is, CREATE_SENSOR_VOLTAGE, createStatus, chk);
00214     if ( total < 0 ) return fail;
00215     total += readPacket(is, CREATE_SENSOR_CURRENT, createStatus, chk);
00216     if ( total < 0 ) return fail;
00217     total += readPacket(is, CREATE_SENSOR_BATTERY_TEMP, createStatus, chk);
00218     if ( total < 0 ) return fail;
00219     total += readPacket(is, CREATE_SENSOR_BATTERY_CHARGE, createStatus, chk);
00220     if ( total < 0 ) return fail;
00221     total += readPacket(is, CREATE_SENSOR_BATTERY_CAPACITY, createStatus, chk);
00222     if ( total < 0 ) return fail;
00223     break; 
00224   case CREATE_SENSOR_GROUP_1:
00225     total += readPacket(is, CREATE_SENSOR_DROP, createStatus, chk);
00226     if ( total < 0 ) return fail;
00227     total += readPacket(is, CREATE_SENSOR_WALL, createStatus, chk);
00228     if ( total < 0 ) return fail;
00229     total += readPacket(is, CREATE_SENSOR_CLIFF_LEFT, createStatus, chk);
00230     if ( total < 0 ) return fail;
00231     total += readPacket(is, CREATE_SENSOR_CLIFF_FRONT_LEFT, createStatus, chk);
00232     if ( total < 0 ) return fail;
00233     total += readPacket(is, CREATE_SENSOR_CLIFF_FRONT_RIGHT, createStatus, chk);
00234     if ( total < 0 ) return fail;
00235     total += readPacket(is, CREATE_SENSOR_CLIFF_RIGHT, createStatus, chk);
00236     if ( total < 0 ) return fail;
00237     total += readPacket(is, CREATE_SENSOR_VIRTUAL_WALL, createStatus, chk);
00238     if ( total < 0 ) return fail;
00239     total += readPacket(is, CREATE_SENSOR_OVERCURRENT, createStatus, chk);
00240     if ( total < 0 ) return fail;
00241     total += readPacket(is, CREATE_SENSOR_DIRT, createStatus, chk);
00242     if ( total < 0 ) return fail;
00243     total += readPacket(is, CREATE_SENSOR_UNUSED_2, createStatus, chk);
00244     if ( total < 0 ) return fail;
00245     break;
00246   case CREATE_SENSOR_GROUP_2:
00247     total += readPacket(is, CREATE_SENSOR_IR, createStatus, chk);
00248     if ( total < 0 ) return fail;
00249     total += readPacket(is, CREATE_SENSOR_BUTTONS, createStatus, chk);
00250     if ( total < 0 ) return fail;
00251     total += readPacket(is, CREATE_SENSOR_DISTANCE, createStatus, chk);
00252     if ( total < 0 ) return fail;
00253     total += readPacket(is, CREATE_SENSOR_ANGLE, createStatus, chk);
00254     if ( total < 0 ) return fail;
00255     break;
00256   case CREATE_SENSOR_GROUP_3:
00257     total += readPacket(is, CREATE_SENSOR_CHANGING_STATE, createStatus, chk);
00258     if ( total < 0 ) return fail;
00259     total += readPacket(is, CREATE_SENSOR_VOLTAGE, createStatus, chk);
00260     if ( total < 0 ) return fail;
00261     total += readPacket(is, CREATE_SENSOR_CURRENT, createStatus, chk);
00262     if ( total < 0 ) return fail;
00263     total += readPacket(is, CREATE_SENSOR_BATTERY_TEMP, createStatus, chk);
00264     if ( total < 0 ) return fail;
00265     total += readPacket(is, CREATE_SENSOR_BATTERY_CHARGE, createStatus, chk);
00266     if ( total < 0 ) return fail;
00267     total += readPacket(is, CREATE_SENSOR_BATTERY_CAPACITY, createStatus, chk);
00268     if ( total < 0 ) return fail;
00269     break;
00270   case CREATE_SENSOR_GROUP_4:
00271     total += readPacket(is, CREATE_SENSOR_WALL_SIGNAL, createStatus, chk);
00272     if ( total < 0 ) return fail;
00273     total += readPacket(is, CREATE_SENSOR_CLIFF_L_SIGNAL, createStatus, chk);
00274     if ( total < 0 ) return fail;
00275     total += readPacket(is, CREATE_SENSOR_CLIFF_FL_SIGNAL, createStatus, chk);
00276     if ( total < 0 ) return fail;
00277     total += readPacket(is, CREATE_SENSOR_CLIFF_FR_SIGNAL, createStatus, chk);
00278     if ( total < 0 ) return fail;
00279     total += readPacket(is, CREATE_SENSOR_CLIFF_R_SIGNAL, createStatus, chk);
00280     if ( total < 0 ) return fail;
00281     total += readPacket(is, CREATE_SENSOR_DIGITAL_IN, createStatus, chk);
00282     if ( total < 0 ) return fail;
00283     total += readPacket(is, CREATE_SENSOR_ANALOG, createStatus, chk);
00284     if ( total < 0 ) return fail;
00285     total += readPacket(is, CREATE_SENSOR_CAN_CHARGE, createStatus, chk);
00286     if ( total < 0 ) return fail;
00287     break;
00288   case CREATE_SENSOR_GROUP_5:
00289     total += readPacket(is, CREATE_SENSOR_OI_MODE, createStatus, chk);
00290     if ( total < 0 ) return fail;
00291     total += readPacket(is, CREATE_SENSOR_SONG_NUMBER, createStatus, chk);
00292     if ( total < 0 ) return fail;
00293     total += readPacket(is, CREATE_SENSOR_SONG_PLAYING, createStatus, chk);
00294     if ( total < 0 ) return fail;
00295     total += readPacket(is, CREATE_SENSOR_STREAM_SIZE, createStatus, chk);
00296     if ( total < 0 ) return fail;
00297     total += readPacket(is, CREATE_SENSOR_REQ_VELOCITY, createStatus, chk);
00298     if ( total < 0 ) return fail;
00299     total += readPacket(is, CREATE_SENSOR_REQ_RADIUS, createStatus, chk);
00300     if ( total < 0 ) return fail;
00301     total += readPacket(is, CREATE_SENSOR_REQ_RIGHT_VELOCITY, createStatus, chk);
00302     if ( total < 0 ) return fail;
00303     total += readPacket(is, CREATE_SENSOR_REQ_LEFT_VELOCITY, createStatus, chk);
00304     if ( total < 0 ) return fail;
00305     break;
00306   case CREATE_SENSOR_GROUP_6:
00307     total += readPacket(is, CREATE_SENSOR_GROUP_0, createStatus, chk);
00308     if ( total < 0 ) return fail;
00309     total += readPacket(is, CREATE_SENSOR_GROUP_4, createStatus, chk);
00310     if ( total < 0 ) return fail;
00311     total += readPacket(is, CREATE_SENSOR_GROUP_5, createStatus, chk);
00312     if ( total < 0 ) return fail;
00313     break;
00314   #ifdef TGT_IS_CREATE2
00315   case CREATE_SENSOR_GROUP_100:
00316     total += readPacket(is, CREATE_SENSOR_GROUP_6, createStatus, chk);
00317     if ( total < 0 ) return fail;
00318     total += readPacket(is, CREATE_SENSOR_GROUP_101, createStatus, chk);
00319     if ( total < 0 ) return fail;
00320     break;
00321   case CREATE_SENSOR_GROUP_101:
00322     total += readPacket(is, CREATE_SENSOR_ENCODER_LEFT, createStatus, chk);
00323     if ( total < 0 ) return fail;
00324     total += readPacket(is, CREATE_SENSOR_ENCODER_RIGHT, createStatus, chk);
00325     if ( total < 0 ) return fail;
00326     total += readPacket(is, CREATE_SENSOR_LIGHT_BUMPER, createStatus, chk);
00327     if ( total < 0 ) return fail;
00328     total += readPacket(is, CREATE_SENSOR_GROUP_106, createStatus, chk);
00329     if ( total < 0 ) return fail;
00330     total += readPacket(is, CREATE_SENSOR_IR_LEFT, createStatus, chk);
00331     if ( total < 0 ) return fail;
00332     total += readPacket(is, CREATE_SENSOR_IR_RIGHT, createStatus, chk);
00333     if ( total < 0 ) return fail;
00334     total += readPacket(is, CREATE_SENSOR_GROUP_107, createStatus, chk);
00335     if ( total < 0 ) return fail;
00336     break;
00337   case CREATE_SENSOR_GROUP_106:
00338     total += readPacket(is, CREATE_SENSOR_LIGHT_L_BUMP, createStatus, chk);
00339     if ( total < 0 ) return fail;
00340     total += readPacket(is, CREATE_SENSOR_LIGHT_FL_BUMP, createStatus, chk);
00341     if ( total < 0 ) return fail;
00342     total += readPacket(is, CREATE_SENSOR_LIGHT_CL_BUMP, createStatus, chk);
00343     if ( total < 0 ) return fail;
00344     total += readPacket(is, CREATE_SENSOR_LIGHT_CR_BUMP, createStatus, chk);
00345     if ( total < 0 ) return fail;
00346     total += readPacket(is, CREATE_SENSOR_LIGHT_FR_BUMP, createStatus, chk);
00347     if ( total < 0 ) return fail;
00348     total += readPacket(is, CREATE_SENSOR_LIGHT_R_BUMP, createStatus, chk);
00349     if ( total < 0 ) return fail;
00350     break;
00351   case CREATE_SENSOR_GROUP_107:
00352     total += readPacket(is, CREATE_SENSOR_CURRENT_L_MOTOR, createStatus, chk);
00353     if ( total < 0 ) return fail;
00354     total += readPacket(is, CREATE_SENSOR_CURRENT_R_MOTOR, createStatus, chk);
00355     if ( total < 0 ) return fail;
00356     total += readPacket(is, CREATE_SENSOR_CURRENT_MAIN_BRUSH, createStatus, chk);
00357     if ( total < 0 ) return fail;
00358     total += readPacket(is, CREATE_SENSOR_CURRENT_SIDE_BRUSH, createStatus, chk);
00359     if ( total < 0 ) return fail;
00360     total += readPacket(is, CREATE_SENSOR_STASIS, createStatus, chk);
00361     if ( total < 0 ) return fail;
00362     break;
00363   #endif
00364   case CREATE_SENSOR_DROP:
00365     data = readUnsignedChar(is, chk);
00366     if ( data == -1U ) return fail;
00367     createStatus.bumpsWheelDrops = (unsigned char)data;
00368     total = 1;
00369     break;
00370   case CREATE_SENSOR_WALL:
00371     data = readUnsignedChar(is, chk);
00372     if ( data == -1U ) return fail;
00373     createStatus.wall = (unsigned char)data;
00374     total = 1;
00375     break;
00376   case CREATE_SENSOR_CLIFF_LEFT:
00377     data = readUnsignedChar(is, chk);
00378     if ( data == -1U ) return fail;
00379     createStatus.cliffLeft = (unsigned char)data;
00380     total = 1;
00381     break;
00382   case CREATE_SENSOR_CLIFF_FRONT_LEFT:
00383     data = readUnsignedChar(is, chk);
00384     if ( data == -1U ) return fail;
00385     createStatus.cliffFrontLeft = (unsigned char)data;
00386     total = 1;
00387     break;
00388   case CREATE_SENSOR_CLIFF_FRONT_RIGHT:
00389     data = readUnsignedChar(is, chk);
00390     if ( data == -1U ) return fail;
00391     createStatus.cliffFrontRight = (unsigned char)data;
00392     total = 1;
00393     break;
00394   case CREATE_SENSOR_CLIFF_RIGHT:
00395     data = readUnsignedChar(is, chk);
00396     if ( data == -1U ) return fail;
00397     createStatus.cliffRight = (unsigned char)data;
00398     total = 1;
00399     break;
00400   case CREATE_SENSOR_VIRTUAL_WALL:
00401     data = readUnsignedChar(is, chk);
00402     if ( data == -1U ) return fail;
00403     createStatus.virtualWall = (unsigned char)data;
00404     total = 1;
00405     break;
00406   case CREATE_SENSOR_OVERCURRENT:
00407     data = readUnsignedChar(is, chk);
00408     if ( data == -1U ) return fail;
00409     createStatus.overcurrents = (unsigned char)data;
00410     total = 1;
00411     break;
00412   #ifdef TGT_IS_CREATE2
00413   case CREATE_SENSOR_DIRT:
00414       data = readUnsignedChar(is, chk);
00415       if ( data == -1U ) return fail;
00416       createStatus.dirt = (char)data;
00417       total = 1;
00418       break;
00419   #else
00420   case CREATE_SENSOR_UNUSED_1:
00421   #endif
00422   case CREATE_SENSOR_UNUSED_2:
00423     data = readUnsignedChar(is, chk);
00424     if ( data == -1U ) return fail;
00425     total = 1;
00426     break;
00427   case CREATE_SENSOR_IR:
00428     data = readUnsignedChar(is, chk);
00429     if ( data == -1U ) return fail;
00430     createStatus.ir = (unsigned char)data;
00431     total = 1;
00432     break;
00433   case CREATE_SENSOR_BUTTONS:
00434     data = readUnsignedChar(is, chk);
00435     if ( data == -1U ) return fail;
00436     createStatus.buttons = (unsigned char)data;
00437     total = 1;
00438     break;
00439 
00440   #ifdef TGT_IS_CREATE2
00441   case CREATE_SENSOR_DISTANCE:
00442   case CREATE_SENSOR_ANGLE:
00443     data = readUnsignedShort(is, chk);
00444     if ( data == -1U ) return fail;
00445     total = 1;
00446     break;
00447   #else
00448 
00449   case CREATE_SENSOR_DISTANCE:
00450     data = readUnsignedShort(is, chk);
00451     if ( data == -1U ) return fail;
00452     createStatus.distance = (short)data;
00453     total = 2;
00454     break;
00455   case CREATE_SENSOR_ANGLE:
00456     data = readUnsignedShort(is, chk);
00457     if ( data == -1U ) return fail;
00458     createStatus.angle = (short)data;
00459     total = 2;
00460     break;
00461   #endif
00462   case CREATE_SENSOR_CHANGING_STATE:
00463     data = readUnsignedChar(is, chk);
00464     if ( data == -1U ) return fail;
00465     createStatus.chargingState = (unsigned char)data;
00466     total = 1;
00467     break;
00468   case CREATE_SENSOR_VOLTAGE:
00469     data = readUnsignedShort(is, chk);
00470     if ( data == -1U ) return fail;
00471     createStatus.voltage = (unsigned short)data;
00472     total = 2;
00473     break;
00474   case CREATE_SENSOR_CURRENT:
00475     data = readUnsignedShort(is, chk);
00476     if ( data == -1U ) return fail;
00477     createStatus.current = (short)data;
00478     total = 2;
00479     break;
00480   case CREATE_SENSOR_BATTERY_TEMP:
00481     data = readUnsignedChar(is, chk);
00482     if ( data == -1U ) return fail;
00483     createStatus.batteryTemperature = (char)data;
00484     total = 1;
00485     break;
00486   case CREATE_SENSOR_BATTERY_CHARGE:
00487     data = readUnsignedShort(is, chk);
00488     if ( data == -1U ) return fail;
00489     createStatus.batteryCharge = (unsigned short)data;
00490     total = 2;
00491     break;
00492   case CREATE_SENSOR_BATTERY_CAPACITY:
00493     data = readUnsignedShort(is, chk);
00494     if ( data == -1U ) return fail;
00495     createStatus.batteryCapacity = (unsigned short)data;
00496     total = 2;
00497     break;
00498   case CREATE_SENSOR_WALL_SIGNAL:
00499     data = readUnsignedShort(is, chk);
00500     if ( data == -1U ) return fail;
00501     createStatus.wallSignal = (unsigned short)data;
00502     total = 2;
00503     break;
00504   case CREATE_SENSOR_CLIFF_L_SIGNAL:
00505     data = readUnsignedShort(is, chk);
00506     if ( data == -1U ) return fail;
00507     createStatus.cliffLeftSignal = (unsigned short)data;
00508     total = 2;
00509     break;
00510   case CREATE_SENSOR_CLIFF_FL_SIGNAL:
00511     data = readUnsignedShort(is, chk);
00512     if ( data == -1U ) return fail;
00513     createStatus.cliffFrontLeftSignal = (unsigned short)data;
00514     total = 2;
00515     break;
00516   case CREATE_SENSOR_CLIFF_FR_SIGNAL:
00517     data = readUnsignedShort(is, chk);
00518     if ( data == -1U ) return fail;
00519     createStatus.cliffFrontRightSignal = (unsigned short)data;
00520     total = 2;
00521     break;
00522   case CREATE_SENSOR_CLIFF_R_SIGNAL:
00523     data = readUnsignedShort(is, chk);
00524     if ( data == -1U ) return fail;
00525     createStatus.cliffRightSignal = (unsigned short)data;
00526     total = 2;
00527     break;
00528   #ifdef TGT_IS_CREATE2
00529   case CREATE_SENSOR_UNUSED_3:
00530     data = readUnsignedChar(is, chk);
00531     if ( data == -1U ) return fail;
00532     total = 1;
00533     break;
00534   case CREATE_SENSOR_UNUSED_4:
00535     data = readUnsignedShort(is, chk);
00536     if ( data == -1U ) return fail;
00537     total = 1;
00538     break;
00539   #else
00540   case CREATE_SENSOR_DIGITAL_IN:
00541     data = readUnsignedChar(is, chk);
00542     if ( data == -1U ) return fail;
00543     createStatus.userDigitalInputs= (unsigned char)data;
00544     total = 1;
00545     break;
00546   case CREATE_SENSOR_ANALOG:
00547     data = readUnsignedShort(is, chk);
00548     if ( data == -1U ) return fail;
00549     createStatus.userAnalogInput = (unsigned short)data;
00550     total = 2;
00551     break;
00552   #endif
00553   case CREATE_SENSOR_CAN_CHARGE:
00554     data = readUnsignedChar(is, chk);
00555     if ( data == -1U ) return fail;
00556     createStatus.chargingSourcesAvailable = (unsigned char)data;
00557     total = 1;
00558     break;
00559   case CREATE_SENSOR_OI_MODE:
00560     data = readUnsignedChar(is, chk);
00561     if ( data == -1U ) return fail;
00562     createStatus.oiMode = (unsigned char)data;
00563     total = 1;
00564     break;
00565   case CREATE_SENSOR_SONG_NUMBER:
00566     data = readUnsignedChar(is, chk);
00567     if ( data == -1U ) return fail;
00568     createStatus.songNumber = (unsigned char)data;
00569     total = 1;
00570     break;
00571   case CREATE_SENSOR_SONG_PLAYING:
00572     data = readUnsignedChar(is, chk);
00573     if ( data == -1U ) return fail;
00574     createStatus.songPlay = (unsigned char)data;
00575     total = 1;
00576     break;
00577   case CREATE_SENSOR_STREAM_SIZE:
00578     data = readUnsignedChar(is, chk);
00579     if ( data == -1U ) return fail;
00580     createStatus.streamSize = (unsigned char)data;
00581     total = 1;
00582     break;
00583   case CREATE_SENSOR_REQ_VELOCITY:
00584     data = readUnsignedShort(is, chk);
00585     if ( data == -1U ) return fail;
00586     createStatus.velocity = (short)data;
00587     total = 2;
00588     break;
00589   case CREATE_SENSOR_REQ_RADIUS:
00590     data = readUnsignedShort(is, chk);
00591     if ( data == -1U ) return fail;
00592     createStatus.radius = (short)data;
00593     total = 2;
00594     break;
00595   case CREATE_SENSOR_REQ_RIGHT_VELOCITY:
00596     data = readUnsignedShort(is, chk);
00597     if ( data == -1U ) return fail;
00598     createStatus.rightVelocity = (short)data;
00599     total = 2;
00600     break;
00601   case CREATE_SENSOR_REQ_LEFT_VELOCITY:
00602     data = readUnsignedShort(is, chk);
00603     if ( data == -1U ) return fail;
00604     createStatus.leftVelocity = (short)data;
00605     total = 2;
00606     break;
00607   #ifdef TGT_IS_CREATE2
00608   case CREATE_SENSOR_IR_LEFT:
00609     data = readUnsignedChar(is, chk);
00610     if ( data == -1U ) return fail;
00611     createStatus.irLeft = (unsigned char)data;
00612     total = 1;
00613     break;
00614   case CREATE_SENSOR_IR_RIGHT:
00615     data = readUnsignedChar(is, chk);
00616     if ( data == -1U ) return fail;
00617     createStatus.irRight = (unsigned char)data;
00618     total = 1;
00619     break;
00620   case CREATE_SENSOR_ENCODER_LEFT:
00621     data = readUnsignedShort(is, chk);
00622     if ( data == -1U ) return fail;
00623     createStatus.encoderLeft = (short)data;
00624     total = 1;
00625     break;
00626   case CREATE_SENSOR_ENCODER_RIGHT:
00627     data = readUnsignedShort(is, chk);
00628     if ( data == -1U ) return fail;
00629     createStatus.encoderRight = (short)data;
00630     if (firstMessage) {
00631         firstMessage = false;
00632     }
00633     else {
00634       float const leftEncDelta = createStatus.encoderLeft - prevEncoderLeft;
00635       float const rightEncDelta = createStatus.encoderRight - prevEncoderRight;
00636       float const wheelCircumference = M_PI * RobotInfo::wheelDiameter;
00637       float const leftWheelTravel = leftEncDelta / RobotInfo::encoderTicksPerRev * wheelCircumference;
00638       float const rightWheelTravel = rightEncDelta / RobotInfo::encoderTicksPerRev * wheelCircumference;
00639       createStatus.distance = (rightWheelTravel + leftWheelTravel) / 2;
00640       createStatus.angle = (rightWheelTravel - leftWheelTravel) / RobotInfo::wheelBase * (180 / M_PI);
00641     }
00642     prevEncoderLeft = createStatus.encoderLeft;
00643     prevEncoderRight = createStatus.encoderRight;
00644     total = 1;
00645     break;
00646   case CREATE_SENSOR_LIGHT_BUMPER:
00647     data = readUnsignedChar(is, chk);
00648     if ( data == -1U ) return fail;
00649     createStatus.lightBumper = (unsigned char)data;
00650     total = 1;
00651     break;
00652   case CREATE_SENSOR_LIGHT_L_BUMP:
00653     data = readUnsignedShort(is, chk);
00654     if ( data == -1U ) return fail;
00655     createStatus.lightBumperLeft = (unsigned short)data;
00656     total = 1;
00657     break;
00658   case CREATE_SENSOR_LIGHT_FL_BUMP:
00659     data = readUnsignedShort(is, chk);
00660     if ( data == -1U ) return fail;
00661     createStatus.lightBumperFrontLeft = (unsigned short)data;
00662     total = 1;
00663     break;
00664   case CREATE_SENSOR_LIGHT_CL_BUMP:
00665     data = readUnsignedShort(is, chk);
00666     if ( data == -1U ) return fail;
00667     createStatus.lightBumperCenterLeft = (unsigned short)data;
00668     total = 1;
00669     break;
00670   case CREATE_SENSOR_LIGHT_CR_BUMP:
00671     data = readUnsignedShort(is, chk);
00672     if ( data == -1U ) return fail;
00673     createStatus.lightBumperCenterRight = (unsigned short)data;
00674     total = 1;
00675     break;
00676   case CREATE_SENSOR_LIGHT_FR_BUMP:
00677     data = readUnsignedShort(is, chk);
00678     if ( data == -1U ) return fail;
00679     createStatus.lightBumperFrontRight = (unsigned short)data;
00680     total = 1;
00681     break;
00682   case CREATE_SENSOR_LIGHT_R_BUMP:
00683     data = readUnsignedShort(is, chk);
00684     if ( data == -1U ) return fail;
00685     createStatus.lightBumperRight = (unsigned short)data;
00686     total = 1;
00687     break;
00688   case CREATE_SENSOR_CURRENT_L_MOTOR:
00689     data = readUnsignedShort(is, chk);
00690     if ( data == -1U ) return fail;
00691     createStatus.currentLeftMotor = (short)data;
00692     total = 1;
00693     break;
00694   case CREATE_SENSOR_CURRENT_R_MOTOR:
00695     data = readUnsignedShort(is, chk);
00696     if ( data == -1U ) return fail;
00697     createStatus.currentRightMotor = (short)data;
00698     total = 1;
00699     break;
00700   case CREATE_SENSOR_CURRENT_MAIN_BRUSH:
00701     data = readUnsignedShort(is, chk);
00702     if ( data == -1U ) return fail;
00703     createStatus.currentMainBrush = (short)data;
00704     total = 1;
00705     break;
00706   case CREATE_SENSOR_CURRENT_SIDE_BRUSH:
00707     data = readUnsignedShort(is, chk);
00708     if ( data == -1U ) return fail;
00709     createStatus.currentSideBrush = (short)data;
00710     total = 1;
00711     break;
00712   case CREATE_SENSOR_STASIS:
00713     data = readUnsignedChar(is, chk);
00714     if ( data == -1U ) return fail;
00715     createStatus.stasis = (unsigned char)data;
00716     total = 1;
00717     break;
00718   #endif
00719   default:
00720     //std::cerr << "CREATE DRIVER: unknown packet type " << (int) type << std::endl;
00721     break;
00722   }
00723   
00724   return total;
00725 }
00726 
00727 bool CreateDriver::attemptPacketRead(std::istream &is, CreateStatus &createStatus) {
00728   if(!is)
00729     return false;
00730   unsigned char chk;
00731 #ifdef TGT_IS_CREATE2
00732   int total = readPacket(is, CREATE_SENSOR_GROUP_100, createStatus, chk);
00733 #else
00734   int total = readPacket(is, CREATE_SENSOR_GROUP_6, createStatus, chk);
00735 #endif
00736   if ( total > 0 )
00737     return true;
00738   else
00739     return false;
00740 }
00741 
00742 // This obsolete code is for reading in streaming mode, which we're
00743 // presently not using because of the Create odometry bug.  It needs
00744 // to be rewritten to follow the new conventions where a read timeout
00745 // returns -1U instead of throwing and exception.
00746 bool CreateDriver::attemptStreamRead(std::istream &is, CreateStatus &createStatus) {
00747   // Begin packet reading...
00748   unsigned char in = 0;
00749   unsigned char type = 0;
00750   unsigned char numPackets = 0;
00751   unsigned char chk = 0;
00752   int i;
00753   
00754   if(!is)
00755     return false;
00756   
00757   // cout << "CREATE: Attempting packet read: ";
00758   
00759   try {
00760     type = readUnsignedChar(is, chk);
00761     int dropped = 0;
00762     while (type != 19 && dropped < PACKET_LENGTH) {
00763       dropped++;
00764       type = readUnsignedChar(is, chk);
00765     }
00766     
00767     if ( dropped > 0 )
00768       cout << "CREATE: Dropped " << dropped << " bytes searching for start of packet.\n";
00769     
00770     if (type != 19) {
00771       cout << "CREATE: 19 Not found, available data exhausted.\n";
00772       return false;
00773     }
00774     
00775     // cout << "CREATE: Reading packet...\n";
00776     
00777     chk = 19;
00778     numPackets = readUnsignedChar(is, chk);
00779     
00780     for(i = 0; i < numPackets; i+=in) {
00781       type = readUnsignedChar(is, chk);
00782       
00783       in = readPacket(is, type, createStatus, chk) + 1;
00784     }
00785     
00786     if(i != numPackets) {
00787       //cout << "CREATE: read in different amount than expected! Read " << i << " Expected " << (int)numPackets << endl;
00788       return false;
00789     }
00790     
00791     readUnsignedChar(is, chk);
00792     // unsigned char const checksum = readUnsignedChar(is, chk);
00793     // cout << "CREATE: Finished reading: chksum is " << (int)chk << " and checksum byte is " << (int)checksum << endl;
00794     
00795     if (chk != 0) {
00796       cout << "CREATE: Checksum does not match, discarding packet.\n";
00797       return false;
00798     }
00799   } catch (std::runtime_error &e) {
00800     // cout << "CREATE: Exception while trying to read data.\n";
00801     // cout << e.what() << endl;
00802     return false;
00803   }
00804   
00805   return true;
00806 }
00807 
00808 void CreateDriver::resetStatus(CreateStatus &status) {
00809   status.bumpsWheelDrops = 0;
00810   status.wall = 0;
00811   status.cliffLeft = 0;
00812   status.cliffFrontLeft = 0;
00813   status.cliffFrontRight = 0;
00814   status.cliffRight = 0;
00815   status.virtualWall = 0;
00816   status.overcurrents = 0;
00817   status.ir = 0;
00818   status.buttons = 0;
00819   status.distance = 0;
00820   status.angle = 0;
00821   status.chargingState = 0;
00822   status.voltage = 0;
00823   status.current = 0;
00824   status.batteryTemperature = 0;
00825   status.batteryCharge = 0;
00826   status.batteryCapacity = 0;
00827   status.wallSignal = 0;
00828   status.cliffLeftSignal = 0;
00829   status.cliffFrontLeftSignal = 0;
00830   status.cliffFrontRightSignal = 0;
00831   status.cliffRightSignal = 0;
00832   status.chargingSourcesAvailable = 0;
00833   status.oiMode = 0;
00834   status.songNumber = 0;
00835   status.songPlay = 0;
00836   status.streamSize = 0;
00837   status.velocity = 0;
00838   status.radius = 0;
00839   status.rightVelocity = 0;
00840   status.leftVelocity = 0;
00841   #ifdef TGT_IS_CREATE2
00842   status.dirt = 0;
00843   status.irLeft = 0;
00844   status.irRight = 0;
00845   status.encoderLeft = 0;
00846   status.encoderRight = 0;
00847   status.lightBumper = 0;
00848   status.lightBumperLeft = 0;
00849   status.lightBumperFrontLeft = 0;
00850   status.lightBumperCenterLeft = 0;
00851   status.lightBumperCenterRight = 0;
00852   status.lightBumperFrontRight = 0;
00853   status.lightBumperRight = 0;
00854   status.currentLeftMotor = 0;
00855   status.currentRightMotor = 0;
00856   status.currentMainBrush = 0;
00857   status.currentSideBrush = 0;
00858   status.stasis = 0;
00859   #else
00860   status.userDigitalInputs = 0;
00861   status.userAnalogInput = 0;
00862   #endif
00863 }
00864 
00865 void CreateDriver::mergeStatus(CreateStatus &oldStatus, CreateStatus &newStatus) {
00866   oldStatus.bumpsWheelDrops = newStatus.bumpsWheelDrops;
00867   oldStatus.wall = newStatus.wall;
00868   oldStatus.cliffLeft = newStatus.cliffLeft;
00869   oldStatus.cliffFrontLeft = newStatus.cliffFrontLeft;
00870   oldStatus.cliffFrontRight = newStatus.cliffFrontRight;
00871   oldStatus.cliffRight = newStatus.cliffRight;
00872   oldStatus.virtualWall = newStatus.virtualWall;
00873   oldStatus.overcurrents = newStatus.overcurrents;
00874   oldStatus.ir = newStatus.ir;
00875   oldStatus.buttons = newStatus.buttons;
00876   oldStatus.distance = oldStatus.distance + newStatus.distance;
00877   oldStatus.angle = oldStatus.angle + newStatus.angle;
00878   oldStatus.chargingState = newStatus.chargingState;
00879   oldStatus.voltage = newStatus.voltage;
00880   oldStatus.current = newStatus.current;
00881   oldStatus.batteryTemperature = newStatus.batteryTemperature;
00882   oldStatus.batteryCharge = newStatus.batteryCharge;
00883   oldStatus.batteryCapacity = newStatus.batteryCapacity;
00884   oldStatus.wallSignal = newStatus.wallSignal;
00885   oldStatus.cliffLeftSignal = newStatus.cliffLeftSignal;
00886   oldStatus.cliffFrontLeftSignal = newStatus.cliffFrontLeftSignal;
00887   oldStatus.cliffFrontRightSignal = newStatus.cliffFrontRightSignal;
00888   oldStatus.cliffRightSignal = newStatus.cliffRightSignal;
00889   oldStatus.chargingSourcesAvailable = newStatus.chargingSourcesAvailable;
00890   oldStatus.oiMode = newStatus.oiMode;
00891   oldStatus.songNumber = newStatus.songNumber;
00892   oldStatus.songPlay = newStatus.songPlay;
00893   oldStatus.streamSize = newStatus.streamSize;
00894   oldStatus.velocity = newStatus.velocity;
00895   oldStatus.radius = newStatus.radius;
00896   oldStatus.rightVelocity = newStatus.rightVelocity;
00897   oldStatus.leftVelocity = newStatus.leftVelocity;
00898   #ifdef TGT_IS_CREATE2
00899   oldStatus.dirt = newStatus.dirt;
00900   oldStatus.irLeft = newStatus.irLeft;
00901   oldStatus.irRight = newStatus.irRight;
00902   oldStatus.encoderLeft = newStatus.encoderLeft;
00903   oldStatus.encoderRight = newStatus.encoderRight;
00904   oldStatus.lightBumper = newStatus.lightBumper;
00905   oldStatus.lightBumperLeft = newStatus.lightBumperLeft;
00906   oldStatus.lightBumperFrontLeft = newStatus.lightBumperFrontLeft;
00907   oldStatus.lightBumperCenterLeft = newStatus.lightBumperCenterLeft;
00908   oldStatus.lightBumperCenterRight = newStatus.lightBumperCenterRight;
00909   oldStatus.lightBumperFrontRight = newStatus.lightBumperFrontRight;
00910   oldStatus.lightBumperRight = newStatus.lightBumperRight;
00911   oldStatus.currentLeftMotor = newStatus.currentLeftMotor;
00912   oldStatus.currentRightMotor = newStatus.currentRightMotor;
00913   oldStatus.currentMainBrush = newStatus.currentMainBrush;
00914   oldStatus.currentSideBrush = newStatus.currentSideBrush;
00915   oldStatus.stasis = newStatus.stasis;
00916   #else
00917   oldStatus.userAnalogInput = newStatus.userAnalogInput;
00918   oldStatus.userDigitalInputs = newStatus.userDigitalInputs;
00919   #endif
00920 }
00921 bool CreateDriver::advance() {
00922   CommPort * comm = CommPort::getRegistry().getInstance(commName);
00923   if(comm==NULL || !comm->isReadable() || !comm->isWriteable())
00924     return false;
00925   
00926   Thread::testCurrentCancel();
00927   
00928   CreateStatus tempStatus;
00929   resetStatus(tempStatus);
00930   
00931   // poll for next packet if it's time
00932   if ( get_time() > lastPollTime + pollInterval ) {
00933     lastPollTime = get_time();
00934     vector<unsigned char> commands(2);
00935     commands[0] = CREATE_SENSORS;
00936     #ifdef TGT_IS_CREATE2
00937     commands[1] = CREATE_SENSOR_GROUP_100;
00938     #else
00939     commands[1] = CREATE_SENSOR_GROUP_6;
00940     #endif
00941     sendCommand(commands, 1000);
00942     // cout << "Poll\n" << flush;
00943   }
00944 
00945   // now see if we have anything to read
00946   std::istream is(&comm->getReadStreambuf());
00947   
00948   //cout << "" << get_time() << ": ";
00949   
00950   bool valid = false;
00951   {
00952     //    MarkScope autolock(comm->getLock());
00953     valid = attemptPacketRead(is, tempStatus);
00954   }
00955   
00956   if (!valid) {
00957     packetFailures++;
00958     
00959     if (packetFailures > 0 && packetFailures % 10 == 0) {
00960       if (packetFailures == 10)
00961   cout << "CREATE DRIVER: Dropped 10 consecutive packets, attempting to reconnect to Create...\n";
00962       if (packetFailures % 20 == 0)
00963   cout << "CREATE DRIVER: Still attempting to reconnect to Create...\n";
00964       connect();
00965       usleep(500000);
00966     }
00967     return false;
00968   }
00969   else {
00970     packetFailures = 0;
00971     mergeStatus(globalStatus, tempStatus);
00972   }
00973   //std::cout << "got packet\n" << std::flush;
00974   
00975   // set back to safe if we need to
00976   if (tempStatus.oiMode == RobotInfo::MODE_PASSIVE) {
00977     vector<unsigned char> commands(1); commands[0] = CREATE_SAFE;
00978     sendCommand(commands, 1000);
00979   }
00980   #ifdef TGT_IS_CREATE2 
00981   setSensorValue(DirtDetectOffset, globalStatus.dirt);
00982   setSensorValue(IRLeftOffset, globalStatus.irLeft);
00983   setSensorValue(IRRightOffset, globalStatus.irRight);
00984   setSensorValue(LeftEncoderOffset, globalStatus.encoderLeft);
00985   setSensorValue(RightEncoderOffset, globalStatus.encoderRight);
00986   setSensorValue(LtBumpRightSignalOffset, globalStatus.lightBumperRight);
00987   setSensorValue(LtBumpFrontRightSignalOffset, globalStatus.lightBumperFrontRight);
00988   setSensorValue(LtBumpCenterRightSignalOffset, globalStatus.lightBumperCenterRight);
00989   setSensorValue(LtBumpCenterLeftSignalOffset, globalStatus.lightBumperCenterLeft);
00990   setSensorValue(LtBumpFrontLeftSignalOffset, globalStatus.lightBumperFrontLeft);
00991   setSensorValue(LtBumpLeftSignalOffset, globalStatus.lightBumperLeft);
00992   setSensorValue(LeftMotorCurrentOffset, globalStatus.currentLeftMotor);
00993   setSensorValue(RightMotorCurrentOffset, globalStatus.currentRightMotor);
00994   setSensorValue(MainBrushCurrentOffset, globalStatus.currentMainBrush);
00995   setSensorValue(SideBrushCurrentOffset, globalStatus.currentSideBrush);
00996   #else
00997   setSensorValue(DigitalInput0Offset, ((globalStatus.userDigitalInputs >> 0) & 0x1));
00998   setSensorValue(DigitalInput1Offset, ((globalStatus.userDigitalInputs >> 1) & 0x1));
00999   setSensorValue(DigitalInput2Offset, ((globalStatus.userDigitalInputs >> 2) & 0x1));
01000   setSensorValue(DigitalInput3Offset, ((globalStatus.userDigitalInputs >> 3) & 0x1));
01001   setSensorValue(AnalogSignalOffset,globalStatus.userAnalogInput);
01002   #endif
01003   setSensorValue(WallSignalOffset,globalStatus.wallSignal);
01004   setSensorValue(IRCommOffset,globalStatus.ir);
01005   setSensorValue(CliffLeftSignalOffset,globalStatus.cliffLeftSignal);
01006   setSensorValue(CliffFrontLeftSignalOffset,globalStatus.cliffFrontLeftSignal);
01007   setSensorValue(CliffFrontRightSignalOffset,globalStatus.cliffFrontRightSignal);
01008   setSensorValue(CliffRightSignalOffset,globalStatus.cliffRightSignal);
01009   setSensorValue(EncoderDistanceOffset,globalStatus.distance);
01010   setSensorValue(EncoderAngleOffset,globalStatus.angle);
01011   setSensorValue(VoltageOffset,globalStatus.voltage);
01012   setSensorValue(CurrentOffset,globalStatus.current);
01013   setSensorValue(BatteryChargeOffset,globalStatus.batteryCharge);
01014   setSensorValue(BatteryTempOffset,globalStatus.batteryTemperature);
01015   setSensorValue(ChargingStateOffset,globalStatus.chargingState);
01016   setSensorValue(ModeStateOffset,globalStatus.oiMode);
01017   
01018   #ifdef TGT_IS_CREATE2
01019   setButtonValue(CleanButOffset,(globalStatus.buttons & 0x1));
01020   setButtonValue(SpotButOffset,(globalStatus.buttons >> 1 ) & 0x1);
01021   setButtonValue(DockButOffset,(globalStatus.buttons >> 2 ) & 0x1);
01022   setButtonValue(MinuteButOffset,(globalStatus.buttons >> 3 ) & 0x1);
01023   setButtonValue(HourButOffset,(globalStatus.buttons >> 4 ) & 0x1);
01024   setButtonValue(DayButOffset,(globalStatus.buttons >> 5 ) & 0x1);
01025   setButtonValue(ScheduleButOffset,(globalStatus.buttons >> 6 ) & 0x1);
01026   setButtonValue(ClockButOffset,(globalStatus.buttons >> 7 ) & 0x1);
01027   
01028   setButtonValue(OvercurrentMainBrushOffset,(globalStatus.overcurrents >> 1) & 0x1);
01029   setButtonValue(OvercurrentSideBrushOffset,(globalStatus.overcurrents >> 0) & 0x1);
01030   
01031   setButtonValue(LtBumpRightOffset, (globalStatus.lightBumper >> 5) & 0x1);
01032   setButtonValue(LtBumpFrontRightOffset, (globalStatus.lightBumper >> 4) & 0x1);
01033   setButtonValue(LtBumpCenterRightOffset, (globalStatus.lightBumper >> 3) & 0x1);
01034   setButtonValue(LtBumpCenterLeftOffset, (globalStatus.lightBumper >> 2) & 0x1);
01035   setButtonValue(LtBumpFrontLeftOffset, (globalStatus.lightBumper >> 1) & 0x1);
01036   setButtonValue(LtBumpLeftOffset, (globalStatus.lightBumper >> 0 ) & 0x1);
01037   #else
01038   setButtonValue(PlayButOffset,(globalStatus.buttons & 0x1));
01039   setButtonValue(AdvanceButOffset,((globalStatus.buttons >> 2) & 0x1));
01040   setButtonValue(DropCasterButOffset,((globalStatus.bumpsWheelDrops >> 4) & 0x1));
01041   setButtonValue(LowSideDriver0ButOffset,((globalStatus.overcurrents >> 2) & 0x1));
01042   setButtonValue(LowSideDriver1ButOffset,((globalStatus.overcurrents >> 1) & 0x1));
01043   setButtonValue(LowSideDriver2ButOffset,((globalStatus.overcurrents >> 0) & 0x1));
01044   #endif
01045   setButtonValue(WallButOffset,globalStatus.wall);
01046   setButtonValue(DropLeftWheelButOffset,((globalStatus.bumpsWheelDrops >> 3) & 0x1));
01047   setButtonValue(DropRightWheelButOffset,((globalStatus.bumpsWheelDrops >> 2) & 0x1));
01048   setButtonValue(BumpLeftButOffset,((globalStatus.bumpsWheelDrops >> 1) & 0x1));
01049   setButtonValue(BumpRightButOffset,((globalStatus.bumpsWheelDrops >> 0) & 0x1));
01050   setButtonValue(OvercurrentLeftWheelOffset,((globalStatus.overcurrents >> 4) & 0x1));
01051   setButtonValue(OvercurrentRightWheelOffset,((globalStatus.overcurrents >> 3) & 0x1));
01052   setButtonValue(BaseChargerButOffset,((globalStatus.chargingSourcesAvailable >> 1) & 0x1));
01053   setButtonValue(InternalChargerButOffset,((globalStatus.chargingSourcesAvailable >> 0) & 0x1));
01054   
01055   ++frameNumber;
01056   return true;
01057 }
01058 
01059 void CreateDriver::registerSource() {
01060   CommPort * comm = CommPort::getRegistry().getInstance(commName);
01061   if(comm==NULL) {
01062     std::cerr << "CreateDriver \"" << instanceName << "\": could not find CommPort \"" << commName << "\"" << std::endl;
01063   } else if(!comm->open()) {
01064     std::cerr << "CreateDriver \"" << instanceName << "\": unable to open comm port \"" << commName << "\"" << std::endl;
01065   } else {
01066     connect();
01067   }
01068   sensorsActive=true;
01069   commName.addPrimitiveListener(this);
01070 }
01071 
01072 void CreateDriver::deregisterSource() {
01073   CommPort * comm = CommPort::getRegistry().getInstance(commName);
01074   if(comm!=NULL)
01075     comm->close();
01076   sensorsActive=false;
01077   if(!motionActive) // listener count is not recursive, so only remove if we're the last one
01078     commName.removePrimitiveListener(this);
01079 }
01080 
01081 void CreateDriver::doUnfreeze() {
01082   MarkScope sl(poller.getStartLock());
01083   if(!poller.isStarted()) {
01084     //poller.resetPeriod(1.0/(*sensorFramerate));
01085     poller.start();
01086   }
01087   sensorFramerate->addPrimitiveListener(this);
01088 }
01089 
01090 void CreateDriver::doFreeze() {
01091   MarkScope sl(poller.getStartLock());
01092   if(poller.isStarted())
01093     poller.stop().join();
01094   sensorFramerate->removePrimitiveListener(this);
01095 }
01096 
01097 void CreateDriver::plistValueChanged(const plist::PrimitiveBase& pl) {
01098   // std::cout << "plistvalueChanged Called!" << std::endl;
01099   if(&pl==&commName) {
01100     // if here, then motionStarted or setDataSourceThread has been called, thus when commName changes,
01101     // need to close old one and reopen new one
01102     if(poller.isStarted())
01103       poller.stop().join();
01104     
01105     CommPort * comm = CommPort::getRegistry().getInstance(commName.getPreviousValue());
01106     if(comm!=NULL) {
01107       // close each of our old references
01108       if(sensorsActive)
01109   comm->close();
01110       if(motionActive)
01111   comm->close();
01112     }
01113     comm = CommPort::getRegistry().getInstance(commName);
01114     if(comm==NULL) {
01115       std::cerr << "CreateDriver \"" << instanceName << "\": could not find CommPort \"" << commName << "\"" << std::endl;
01116     } else {
01117       // open each of our new references
01118       if(sensorsActive)
01119   comm->open();
01120       if(motionActive) {
01121   if(!comm->open())
01122     std::cerr << "CreateDriver \"" << instanceName << "\": unable to open comm port \"" << commName << "\"" << std::endl;
01123   else
01124     connect();
01125       }
01126     }
01127     
01128     if(getTimeScale()>0) {
01129       //poller.resetPeriod(1.0/(*sensorFramerate));
01130       poller.start();
01131     }
01132   } else if(&pl==sensorFramerate) {
01133     //poller.resetPeriod(1.0/(*sensorFramerate));
01134   }
01135 }
01136 
01137 float CreateDriver::getAnalog(unsigned int /*inputIdx*/, unsigned char s) {
01138   return s*5.f/256;
01139 }
01140 
01141 float CreateDriver::getDigital(unsigned int /*inputIdx*/, unsigned char cur, unsigned char latch) {
01142   if(cur=='0')
01143     return 0;
01144   return (latch=='0') ? 0.5f : 1;
01145 }
01146 
01147 /*! @file
01148  * @brief 
01149  * @author Benson Tsai (btsai)
01150  * @author Ethan Tira-Thompson (ejt)
01151  * @author Alex Grubb (agrubb1)
01152  */
01153 
01154 #endif
01155 

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