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)
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 
00014 using namespace std; 
00015 
00016 const std::string CreateDriver::autoRegisterCreateDriver = DeviceDriver::getRegistry().registerType<CreateDriver>("Create");
00017 
00018 void CreateDriver::motionStarting()
00019 {
00020   //  std::cout << "motionStarting called!" << std::endl;
00021   MotionHook::motionStarting();
00022   CommPort * comm = CommPort::getRegistry().getInstance(commName);
00023   if(comm==NULL) {
00024     std::cerr << "CreateDriver \"" << instanceName << "\": could not find CommPort \"" << commName << "\"" << std::endl;
00025   } else if(!comm->open()) {
00026     std::cerr << "CreateDriver \"" << instanceName << "\": unable to open comm port \"" << commName << "\"" << std::endl;
00027   } else {
00028     connect();
00029   }
00030   motionActive=true;
00031   commName.addPrimitiveListener(this);
00032 }
00033 
00034 bool CreateDriver::isConnected() {
00035   CommPort * comm = CommPort::getRegistry().getInstance(commName);
00036   return (comm!=NULL && comm->isWriteable());
00037 }
00038 
00039 void CreateDriver::motionStopping() {
00040   motionActive=false;
00041   if(!sensorsActive) // listener count is not recursive, so only remove if we're the last one
00042     commName.removePrimitiveListener(this);
00043   CommPort * comm = CommPort::getRegistry().getInstance(commName);
00044   if(comm!=NULL)
00045     comm->close(); // this *is* recursive, so we always close it to match our open() in motionStarting()
00046   MotionHook::motionStopping();
00047 }
00048 
00049 void CreateDriver::motionCheck(const float outputs[][NumOutputs]) {
00050   CommPort * comm = CommPort::getRegistry().getInstance(commName);
00051   if(comm==NULL || !comm->isWriteable())
00052     return;
00053   
00054   vector<unsigned char> commands(0);
00055   
00056   commands.push_back(CREATE_DRIVE_DIRECT);
00057   
00058   short output;
00059   output = (short)outputs[NumFrames-1][RobotInfo::RWheelOffset];
00060   commands.push_back((unsigned char)(output >> 8));
00061   commands.push_back((unsigned char)(output & 0xFF));
00062   
00063   output = (short)outputs[NumFrames-1][RobotInfo::LWheelOffset];
00064   commands.push_back((unsigned char)(output >> 8));
00065   commands.push_back((unsigned char)(output & 0xFF));
00066   
00067   commands.push_back(CREATE_LEDS);
00068   
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   
00076   float red = outputs[NumFrames-1][RobotInfo::PowerRedLEDOffset];
00077   float green = outputs[NumFrames-1][RobotInfo::PowerGreenLEDOffset];
00078   if (red == 0 && green == 0)
00079     commands.push_back((unsigned char)0);
00080   else
00081     commands.push_back((unsigned char)(255 * red / (red + green)));
00082   commands.push_back((unsigned char)(255 * max(red, green)));
00083   
00084   /*
00085    unsigned char desiredMode = (unsigned char)outputs[NumFrames-1][RobotInfo::ModeOffset];
00086    if (desiredMode != 0 && desiredMode != lastDesiredMode) {
00087    if (desiredMode == RobotInfo::MODE_SAFE)
00088    commands.push_back(CREATE_SAFE);
00089    if (desiredMode == RobotInfo::MODE_PASSIVE)
00090    commands.push_back(CREATE_START);
00091    if (desiredMode == RobotInfo::MODE_FULL)
00092    commands.push_back(CREATE_FULL);
00093    
00094    lastDesiredMode = desiredMode;
00095    }
00096    */
00097   
00098   unsigned int dt = static_cast<unsigned int>(NumFrames*FrameTime/((getTimeScale()>0)?getTimeScale():1.f));
00099   sendCommand(commands, dt*3/4);
00100   
00101   MotionHook::motionCheck(outputs); // updates lastOutputs and isFirstCheck, we ignore its motionUpdated() call
00102 }
00103 
00104 bool CreateDriver::sendCommand(vector<unsigned char> bytes, unsigned int timeout)
00105 {
00106   CommPort * comm = CommPort::getRegistry().getInstance(commName);
00107   if(comm==NULL)
00108     return false;
00109   Thread::Lock& l = comm->getLock();
00110   
00111   //  cout << "CREATE: Trying to get lock for write." << endl;
00112   
00113   unsigned int t = get_time();
00114   unsigned int giveup = t + timeout;
00115   
00116   while (!l.trylock()) {
00117     if (get_time() >= giveup) {
00118       if(MotionHook::verbose>0)
00119         cerr << "CREATE: Unable to send command: couldn't get lock on comm port" << endl;
00120       return false;
00121     }
00122     usleep(1000);
00123   }
00124   
00125   MarkScope autolock(l); l.unlock(); //transfer lock to MarkScope
00126   
00127   std::ostream os(&comm->getWriteStreambuf());
00128   //cout << endl << "W";
00129   for (unsigned int i = 0; i < bytes.size(); i++) {
00130     os << bytes[i];
00131     //cout << " " << (int)bytes[i];
00132   }
00133   os << std::flush;
00134   //cout << endl;
00135   
00136   return true;
00137 }
00138 
00139 void CreateDriver::connect()
00140 {
00141   vector<unsigned char> commands(2);
00142   commands[0] = CREATE_START;
00143   commands[1] = CREATE_SAFE;
00144   sendCommand(commands, 3000000);
00145   // cout << "Connecting to CREATE\n" << flush;
00146 }
00147 
00148 unsigned int CreateDriver::nextTimestamp() {
00149   CommPort * comm = CommPort::getRegistry().getInstance(commName);
00150   if(comm==NULL || !comm->isReadable())
00151     return -1U;
00152   return get_time();
00153 }
00154 
00155 char CreateDriver::readChar(std::istream &is, unsigned char &chk)
00156 {
00157   char b;
00158   
00159   // do non-blocking read until given timeout
00160   // wait for 100 ms
00161   TimeET giveup = TimeET() + TimeET((long)100);
00162   while (!is.readsome(&b,1)) {
00163     if (giveup < TimeET()) {
00164       throw std::runtime_error("CREATE DRIVER: Nothing to read");
00165     }
00166   }
00167   chk += (unsigned char)b;
00168   
00169   // cout << "R " << int((unsigned char)b) << " ";
00170   return b;
00171 }
00172 
00173 unsigned char CreateDriver::readUnsignedChar(std::istream &is, unsigned char &chk)
00174 {
00175   return (unsigned char)readChar(is,chk);
00176 }
00177 
00178 short CreateDriver::readShort(std::istream &is, unsigned char &chk){
00179   unsigned char a = readUnsignedChar(is, chk);
00180   unsigned char b = readUnsignedChar(is, chk);
00181   
00182   short ret = ((short) a << 8) | ((short) b);
00183   return ret;
00184 }
00185 
00186 unsigned short CreateDriver::readUnsignedShort(std::istream &is, unsigned char &chk){
00187   unsigned char a = readUnsignedChar(is, chk);
00188   unsigned char b = readUnsignedChar(is, chk);
00189   
00190   unsigned short ret = ((unsigned short) a << 8) | ((unsigned short) b);
00191   return ret;
00192 }
00193 
00194 int CreateDriver::readPacket(std::istream &is, const char &type, CreateStatus &createStatus, unsigned char &chk)
00195 {
00196   int total = 0;
00197   switch(type){
00198     case CREATE_SENSOR_GROUP_0:
00199       total += readPacket(is, CREATE_SENSOR_DROP, createStatus, chk);
00200       total += readPacket(is, CREATE_SENSOR_WALL, createStatus, chk);
00201       total += readPacket(is, CREATE_SENSOR_CLIFF_LEFT, createStatus, chk);
00202       total += readPacket(is, CREATE_SENSOR_CLIFF_FRONT_LEFT, createStatus, chk);
00203       total += readPacket(is, CREATE_SENSOR_CLIFF_FRONT_RIGHT, createStatus, chk);
00204       total += readPacket(is, CREATE_SENSOR_CLIFF_RIGHT, createStatus, chk);
00205       total += readPacket(is, CREATE_SENSOR_VIRTUAL_WALL, createStatus, chk);
00206       total += readPacket(is, CREATE_SENSOR_OVERCURRENT, createStatus, chk);
00207       total += readPacket(is, CREATE_SENSOR_UNUSED_1, createStatus, chk);
00208       total += readPacket(is, CREATE_SENSOR_UNUSED_2, createStatus, chk);
00209       total += readPacket(is, CREATE_SENSOR_IR, createStatus, chk);
00210       total += readPacket(is, CREATE_SENSOR_BUTTONS, createStatus, chk);
00211       total += readPacket(is, CREATE_SENSOR_DISTANCE, createStatus, chk);
00212       total += readPacket(is, CREATE_SENSOR_ANGLE, createStatus, chk);
00213       total += readPacket(is, CREATE_SENSOR_CHANGING_STATE, createStatus, chk);
00214       total += readPacket(is, CREATE_SENSOR_VOLTAGE, createStatus, chk);
00215       total += readPacket(is, CREATE_SENSOR_CURRENT, createStatus, chk);
00216       total += readPacket(is, CREATE_SENSOR_BATTERY_TEMP, createStatus, chk);
00217       total += readPacket(is, CREATE_SENSOR_BATTERY_CHARGE, createStatus, chk);
00218       total += readPacket(is, CREATE_SENSOR_BATTERY_CAPACITY, createStatus, chk);
00219       break; 
00220     case CREATE_SENSOR_GROUP_1:
00221       total += readPacket(is, CREATE_SENSOR_DROP, createStatus, chk);
00222       total += readPacket(is, CREATE_SENSOR_WALL, createStatus, chk);
00223       total += readPacket(is, CREATE_SENSOR_CLIFF_LEFT, createStatus, chk);
00224       total += readPacket(is, CREATE_SENSOR_CLIFF_FRONT_LEFT, createStatus, chk);
00225       total += readPacket(is, CREATE_SENSOR_CLIFF_FRONT_RIGHT, createStatus, chk);
00226       total += readPacket(is, CREATE_SENSOR_CLIFF_RIGHT, createStatus, chk);
00227       total += readPacket(is, CREATE_SENSOR_VIRTUAL_WALL, createStatus, chk);
00228       total += readPacket(is, CREATE_SENSOR_OVERCURRENT, createStatus, chk);
00229       total += readPacket(is, CREATE_SENSOR_UNUSED_1, createStatus, chk);
00230       total += readPacket(is, CREATE_SENSOR_UNUSED_2, createStatus, chk);
00231       break;
00232     case CREATE_SENSOR_GROUP_2:
00233       total += readPacket(is, CREATE_SENSOR_IR, createStatus, chk);
00234       total += readPacket(is, CREATE_SENSOR_BUTTONS, createStatus, chk);
00235       total += readPacket(is, CREATE_SENSOR_DISTANCE, createStatus, chk);
00236       total += readPacket(is, CREATE_SENSOR_ANGLE, createStatus, chk);
00237       break;
00238     case CREATE_SENSOR_GROUP_3:
00239       total += readPacket(is, CREATE_SENSOR_CHANGING_STATE, createStatus, chk);
00240       total += readPacket(is, CREATE_SENSOR_VOLTAGE, createStatus, chk);
00241       total += readPacket(is, CREATE_SENSOR_CURRENT, createStatus, chk);
00242       total += readPacket(is, CREATE_SENSOR_BATTERY_TEMP, createStatus, chk);
00243       total += readPacket(is, CREATE_SENSOR_BATTERY_CHARGE, createStatus, chk);
00244       total += readPacket(is, CREATE_SENSOR_BATTERY_CAPACITY, createStatus, chk);
00245       break;
00246     case CREATE_SENSOR_GROUP_4:
00247       total += readPacket(is, CREATE_SENSOR_WALL_SIGNAL, createStatus, chk);
00248       total += readPacket(is, CREATE_SENSOR_CLIFF_L_SIGNAL, createStatus, chk);
00249       total += readPacket(is, CREATE_SENSOR_CLIFF_FL_SIGNAL, createStatus, chk);
00250       total += readPacket(is, CREATE_SENSOR_CLIFF_FR_SIGNAL, createStatus, chk);
00251       total += readPacket(is, CREATE_SENSOR_CLIFF_R_SIGNAL, createStatus, chk);
00252       total += readPacket(is, CREATE_SENSOR_DIGITAL_IN, createStatus, chk);
00253       total += readPacket(is, CREATE_SENSOR_ANALOG, createStatus, chk);
00254       total += readPacket(is, CREATE_SENSOR_CAN_CHARGE, createStatus, chk);
00255       break;
00256     case CREATE_SENSOR_GROUP_5:
00257       total += readPacket(is, CREATE_SENSOR_OI_MODE, createStatus, chk);
00258       total += readPacket(is, CREATE_SENSOR_SONG_NUMBER, createStatus, chk);
00259       total += readPacket(is, CREATE_SENSOR_SONG_PLAYING, createStatus, chk);
00260       total += readPacket(is, CREATE_SENSOR_STREAM_SIZE, createStatus, chk);
00261       total += readPacket(is, CREATE_SENSOR_REQ_VELOCITY, createStatus, chk);
00262       total += readPacket(is, CREATE_SENSOR_REQ_RADIUS, createStatus, chk);
00263       total += readPacket(is, CREATE_SENSOR_REQ_RIGHT_VELOCITY, createStatus, chk);
00264       total += readPacket(is, CREATE_SENSOR_REQ_LEFT_VELOCITY, createStatus, chk);
00265       break;
00266     case CREATE_SENSOR_GROUP_6:
00267       total += readPacket(is, CREATE_SENSOR_DROP, createStatus, chk);
00268       total += readPacket(is, CREATE_SENSOR_WALL, createStatus, chk);
00269       total += readPacket(is, CREATE_SENSOR_CLIFF_LEFT, createStatus, chk);
00270       total += readPacket(is, CREATE_SENSOR_CLIFF_FRONT_LEFT, createStatus, chk);
00271       total += readPacket(is, CREATE_SENSOR_CLIFF_FRONT_RIGHT, createStatus, chk);
00272       total += readPacket(is, CREATE_SENSOR_CLIFF_RIGHT, createStatus, chk);
00273       total += readPacket(is, CREATE_SENSOR_VIRTUAL_WALL, createStatus, chk);
00274       total += readPacket(is, CREATE_SENSOR_OVERCURRENT, createStatus, chk);
00275       total += readPacket(is, CREATE_SENSOR_UNUSED_1, createStatus, chk);
00276       total += readPacket(is, CREATE_SENSOR_UNUSED_2, createStatus, chk);
00277       total += readPacket(is, CREATE_SENSOR_IR, createStatus, chk);
00278       total += readPacket(is, CREATE_SENSOR_BUTTONS, createStatus, chk);
00279       total += readPacket(is, CREATE_SENSOR_DISTANCE, createStatus, chk);
00280       total += readPacket(is, CREATE_SENSOR_ANGLE, createStatus, chk);
00281       total += readPacket(is, CREATE_SENSOR_CHANGING_STATE, createStatus, chk);
00282       total += readPacket(is, CREATE_SENSOR_VOLTAGE, createStatus, chk);
00283       total += readPacket(is, CREATE_SENSOR_CURRENT, createStatus, chk);
00284       total += readPacket(is, CREATE_SENSOR_BATTERY_TEMP, createStatus, chk);
00285       total += readPacket(is, CREATE_SENSOR_BATTERY_CHARGE, createStatus, chk);
00286       total += readPacket(is, CREATE_SENSOR_BATTERY_CAPACITY, createStatus, chk);
00287       total += readPacket(is, CREATE_SENSOR_WALL_SIGNAL, createStatus, chk);
00288       total += readPacket(is, CREATE_SENSOR_CLIFF_L_SIGNAL, createStatus, chk);
00289       total += readPacket(is, CREATE_SENSOR_CLIFF_FL_SIGNAL, createStatus, chk);
00290       total += readPacket(is, CREATE_SENSOR_CLIFF_FR_SIGNAL, createStatus, chk);
00291       total += readPacket(is, CREATE_SENSOR_CLIFF_R_SIGNAL, createStatus, chk);
00292       total += readPacket(is, CREATE_SENSOR_DIGITAL_IN, createStatus, chk);
00293       total += readPacket(is, CREATE_SENSOR_ANALOG, createStatus, chk);
00294       total += readPacket(is, CREATE_SENSOR_CAN_CHARGE, createStatus, chk);
00295       total += readPacket(is, CREATE_SENSOR_OI_MODE, createStatus, chk);
00296       total += readPacket(is, CREATE_SENSOR_SONG_NUMBER, createStatus, chk);
00297       total += readPacket(is, CREATE_SENSOR_SONG_PLAYING, createStatus, chk);
00298       total += readPacket(is, CREATE_SENSOR_STREAM_SIZE, createStatus, chk);
00299       total += readPacket(is, CREATE_SENSOR_REQ_VELOCITY, createStatus, chk);
00300       total += readPacket(is, CREATE_SENSOR_REQ_RADIUS, createStatus, chk);
00301       total += readPacket(is, CREATE_SENSOR_REQ_RIGHT_VELOCITY, createStatus, chk);
00302       total += readPacket(is, CREATE_SENSOR_REQ_LEFT_VELOCITY, createStatus, chk);
00303       break;
00304     case CREATE_SENSOR_DROP:
00305       total = 1;
00306       createStatus.bumpsWheelDrops = readUnsignedChar(is, chk);
00307       break;
00308     case CREATE_SENSOR_WALL:
00309       total = 1;
00310       createStatus.wall = readUnsignedChar(is, chk);
00311       break;
00312     case CREATE_SENSOR_CLIFF_LEFT:
00313       total = 1;
00314       createStatus.cliffLeft = readUnsignedChar(is, chk);
00315       break;
00316     case CREATE_SENSOR_CLIFF_FRONT_LEFT:
00317       total = 1;
00318       createStatus.cliffFrontLeft = readUnsignedChar(is, chk);
00319       break;
00320     case CREATE_SENSOR_CLIFF_FRONT_RIGHT:
00321       total = 1;
00322       createStatus.cliffFrontRight = readUnsignedChar(is, chk);
00323       break;
00324     case CREATE_SENSOR_CLIFF_RIGHT:
00325       total = 1;
00326       createStatus.cliffRight = readUnsignedChar(is, chk);
00327       break;
00328     case CREATE_SENSOR_VIRTUAL_WALL:
00329       total = 1;
00330       createStatus.virtualWall = readUnsignedChar(is, chk);
00331       break;
00332     case CREATE_SENSOR_OVERCURRENT:
00333       total = 1;
00334       createStatus.overcurrents = readUnsignedChar(is, chk);
00335       break;
00336     case CREATE_SENSOR_UNUSED_1:
00337     case CREATE_SENSOR_UNUSED_2:
00338       total = 1;
00339       readUnsignedChar(is, chk);
00340       break;
00341     case CREATE_SENSOR_IR:
00342       total = 1;
00343       createStatus.ir = readUnsignedChar(is, chk);
00344       break;
00345     case CREATE_SENSOR_BUTTONS:
00346       total = 1;
00347       createStatus.buttons = readUnsignedChar(is, chk);
00348       break;
00349     case CREATE_SENSOR_DISTANCE:
00350       total = 2;
00351       createStatus.distance = readShort(is, chk);
00352       break;
00353     case CREATE_SENSOR_ANGLE:
00354       total = 2;
00355       createStatus.angle = readShort(is, chk);
00356       break;
00357     case CREATE_SENSOR_CHANGING_STATE:
00358       total = 1;
00359       createStatus.chargingState = readUnsignedChar(is, chk);
00360       break;
00361     case CREATE_SENSOR_VOLTAGE:
00362       total = 2;
00363       createStatus.voltage = readUnsignedShort(is, chk);
00364       break;
00365     case CREATE_SENSOR_CURRENT:
00366       total = 2;
00367       createStatus.current = readShort(is, chk);
00368       break;
00369     case CREATE_SENSOR_BATTERY_TEMP:
00370       total = 1;
00371       createStatus.batteryTemperature = readChar(is, chk);
00372       break;
00373     case CREATE_SENSOR_BATTERY_CHARGE:
00374       total = 2;
00375       createStatus.batteryCharge = readUnsignedShort(is, chk);
00376       break;
00377     case CREATE_SENSOR_BATTERY_CAPACITY:
00378       total = 2;
00379       createStatus.batteryCapacity = readUnsignedShort(is, chk);
00380       break;
00381     case CREATE_SENSOR_WALL_SIGNAL:
00382       total = 2;
00383       createStatus.wallSignal = readUnsignedShort(is, chk);
00384       break;
00385     case CREATE_SENSOR_CLIFF_L_SIGNAL:
00386       total = 2;
00387       createStatus.cliffLeftSignal = readUnsignedShort(is, chk);
00388       break;
00389     case CREATE_SENSOR_CLIFF_FL_SIGNAL:
00390       total = 2;
00391       createStatus.cliffFrontLeftSignal = readUnsignedShort(is, chk);
00392       break;
00393     case CREATE_SENSOR_CLIFF_FR_SIGNAL:
00394       total = 2;
00395       createStatus.cliffFrontRightSignal = readUnsignedShort(is, chk);
00396       break;
00397     case CREATE_SENSOR_CLIFF_R_SIGNAL:
00398       total = 2;
00399       createStatus.cliffRightSignal = readUnsignedShort(is, chk);
00400       break;
00401     case CREATE_SENSOR_DIGITAL_IN:
00402       total = 1;
00403       createStatus.userDigitalInputs= readUnsignedChar(is, chk);
00404       break;
00405     case CREATE_SENSOR_ANALOG:
00406       total = 2;
00407       createStatus.userAnalogInput = readUnsignedShort(is, chk);
00408       break;
00409     case CREATE_SENSOR_CAN_CHARGE:
00410       total = 1;
00411       createStatus.chargingSourcesAvailable = readUnsignedChar(is, chk);
00412       break;
00413     case CREATE_SENSOR_OI_MODE:
00414       total = 1;
00415       createStatus.oiMode = readUnsignedChar(is, chk);
00416       break;
00417     case CREATE_SENSOR_SONG_NUMBER:
00418       total = 1;
00419       createStatus.songNumber = readUnsignedChar(is, chk);
00420       break;
00421     case CREATE_SENSOR_SONG_PLAYING:
00422       total = 1;
00423       createStatus.songPlay = readUnsignedChar(is, chk);
00424       break;
00425     case CREATE_SENSOR_STREAM_SIZE:
00426       total = 1;
00427       createStatus.streamSize = readUnsignedChar(is, chk);
00428       break;
00429     case CREATE_SENSOR_REQ_VELOCITY:
00430       total = 2;
00431       createStatus.velocity = readShort(is, chk);
00432       break;
00433     case CREATE_SENSOR_REQ_RADIUS:
00434       total = 2;
00435       createStatus.radius = readShort(is, chk);
00436       break;
00437     case CREATE_SENSOR_REQ_RIGHT_VELOCITY:
00438       total = 2;
00439       createStatus.rightVelocity = readShort(is, chk);
00440       break;
00441     case CREATE_SENSOR_REQ_LEFT_VELOCITY:
00442       total = 2;
00443       createStatus.leftVelocity = readShort(is, chk);
00444       break;
00445     default:
00446       //std::cerr << "CREATE DRIVER: unknown packet type " << (int) type << std::endl;
00447       break;
00448   }
00449   
00450   return total;
00451 }
00452 
00453 bool CreateDriver::attemptPacketRead(std::istream &is, CreateStatus &createStatus)
00454 {
00455   // Begin packet reading...
00456   unsigned char temp;
00457   
00458   if(!is)
00459     return false;
00460   
00461   // cout << "CREATE: Attempting packet read: ";
00462   
00463   try {
00464     readPacket(is, CREATE_SENSOR_GROUP_6, createStatus, temp);
00465     // cout << " Good packet\n" << flush;
00466   } catch (std::runtime_error &e) {
00467     // cout << "CREATE: Exception while trying to read data.\n";
00468     // cout << e.what() << endl;
00469     return false;
00470   }
00471   return true;
00472 }
00473 
00474 // This code is for reading in streaming mode, which we're presently not using
00475 // because of the Create odometry bug.
00476 bool CreateDriver::attemptStreamRead(std::istream &is, CreateStatus &createStatus)
00477 {
00478   // Begin packet reading...
00479   unsigned char in = 0;
00480   unsigned char type = 0;
00481   unsigned char numPackets = 0;
00482   unsigned char chk = 0;
00483   int i;
00484   
00485   if(!is)
00486     return false;
00487   
00488   // cout << "CREATE: Attempting packet read: ";
00489   
00490   try {
00491     type = readUnsignedChar(is, chk);
00492     int dropped = 0;
00493     while (type != 19 && dropped < PACKET_LENGTH) {
00494       dropped++;
00495       type = readUnsignedChar(is, chk);
00496     }
00497     
00498     if ( dropped > 0 )
00499       cout << "CREATE: Dropped " << dropped << " bytes searching for start of packet.\n";
00500     
00501     if (type != 19) {
00502       cout << "CREATE: 19 Not found, available data exhausted.\n";
00503       return false;
00504     }
00505     
00506     // cout << "CREATE: Reading packet...\n";
00507     
00508     chk = 19;
00509     numPackets = readUnsignedChar(is, chk);
00510     
00511     for(i = 0; i < numPackets; i+=in){
00512       type = readUnsignedChar(is, chk);
00513       
00514       in = readPacket(is, type, createStatus, chk) + 1;
00515     }
00516     
00517     if(i != numPackets){
00518       //cout << "CREATE: read in different amount than expected! Read " << i << " Expected " << (int)numPackets << endl;
00519       return false;
00520     }
00521     
00522     readUnsignedChar(is, chk);
00523     // unsigned char const checksum = readUnsignedChar(is, chk);
00524     // cout << "CREATE: Finished reading: chksum is " << (int)chk << " and checksum byte is " << (int)checksum << endl;
00525     
00526     if (chk != 0) {
00527       cout << "CREATE: Checksum does not match, discarding packet.\n";
00528       return false;
00529     }
00530   } catch (std::runtime_error &e) {
00531     // cout << "CREATE: Exception while trying to read data.\n";
00532     // cout << e.what() << endl;
00533     return false;
00534   }
00535   
00536   return true;
00537 }
00538 
00539 void CreateDriver::resetStatus(CreateStatus &status)
00540 {
00541   status.bumpsWheelDrops = 0;
00542   status.wall = 0;
00543   status.cliffLeft = 0;
00544   status.cliffFrontLeft = 0;
00545   status.cliffFrontRight = 0;
00546   status.cliffRight = 0;
00547   status.virtualWall = 0;
00548   status.overcurrents = 0;
00549   status.ir = 0;
00550   status.buttons = 0;
00551   status.distance = 0;
00552   status.angle = 0;
00553   status.chargingState = 0;
00554   status.voltage = 0;
00555   status.current = 0;
00556   status.batteryTemperature = 0;
00557   status.batteryCharge = 0;
00558   status.batteryCapacity = 0;
00559   status.wallSignal = 0;
00560   status.cliffLeftSignal = 0;
00561   status.cliffFrontLeftSignal = 0;
00562   status.cliffFrontRightSignal = 0;
00563   status.cliffRightSignal = 0;
00564   status.userDigitalInputs = 0;
00565   status.userAnalogInput = 0;
00566   status.chargingSourcesAvailable = 0;
00567   status.oiMode = 0;
00568   status.songNumber = 0;
00569   status.songPlay = 0;
00570   status.streamSize = 0;
00571   status.velocity = 0;
00572   status.radius = 0;
00573   status.rightVelocity = 0;
00574   status.leftVelocity = 0;
00575 }
00576 
00577 void CreateDriver::mergeStatus(CreateStatus &oldStatus, CreateStatus &newStatus)
00578 {
00579   oldStatus.bumpsWheelDrops = newStatus.bumpsWheelDrops;
00580   oldStatus.wall = newStatus.wall;
00581   oldStatus.cliffLeft = newStatus.cliffLeft;
00582   oldStatus.cliffFrontLeft = newStatus.cliffFrontLeft;
00583   oldStatus.cliffFrontRight = newStatus.cliffFrontRight;
00584   oldStatus.cliffRight = newStatus.cliffRight;
00585   oldStatus.virtualWall = newStatus.virtualWall;
00586   oldStatus.overcurrents = newStatus.overcurrents;
00587   oldStatus.ir = newStatus.ir;
00588   oldStatus.buttons = newStatus.buttons;
00589   oldStatus.distance = oldStatus.distance + newStatus.distance;
00590   oldStatus.angle = oldStatus.angle + newStatus.angle;
00591   oldStatus.chargingState = newStatus.chargingState;
00592   oldStatus.voltage = newStatus.voltage;
00593   oldStatus.current = newStatus.current;
00594   oldStatus.batteryTemperature = newStatus.batteryTemperature;
00595   oldStatus.batteryCharge = newStatus.batteryCharge;
00596   oldStatus.batteryCapacity = newStatus.batteryCapacity;
00597   oldStatus.wallSignal = newStatus.wallSignal;
00598   oldStatus.cliffLeftSignal = newStatus.cliffLeftSignal;
00599   oldStatus.cliffFrontLeftSignal = newStatus.cliffFrontLeftSignal;
00600   oldStatus.cliffFrontRightSignal = newStatus.cliffFrontRightSignal;
00601   oldStatus.cliffRightSignal = newStatus.cliffRightSignal;
00602   oldStatus.userDigitalInputs = newStatus.userDigitalInputs;
00603   oldStatus.userAnalogInput = newStatus.userAnalogInput;
00604   oldStatus.chargingSourcesAvailable = newStatus.chargingSourcesAvailable;
00605   oldStatus.oiMode = newStatus.oiMode;
00606   oldStatus.songNumber = newStatus.songNumber;
00607   oldStatus.songPlay = newStatus.songPlay;
00608   oldStatus.streamSize = newStatus.streamSize;
00609   oldStatus.velocity = newStatus.velocity;
00610   oldStatus.radius = newStatus.radius;
00611   oldStatus.rightVelocity = newStatus.rightVelocity;
00612   oldStatus.leftVelocity = newStatus.leftVelocity;
00613 }
00614 
00615 bool CreateDriver::advance() {
00616   CommPort * comm = CommPort::getRegistry().getInstance(commName);
00617   if(comm==NULL || !comm->isReadable() || !comm->isWriteable())
00618     return false;
00619   
00620   Thread::testCurrentCancel();
00621   
00622   CreateStatus tempStatus;
00623   resetStatus(tempStatus);
00624   
00625   // poll for next packet if it's time
00626   if ( get_time() > lastPollTime + pollInterval ) {
00627     lastPollTime = get_time();
00628     vector<unsigned char> commands(2);
00629     commands[0] = CREATE_SENSORS;
00630     commands[1] = CREATE_SENSOR_GROUP_6;
00631     sendCommand(commands, 1000);
00632     // cout << "Poll\n" << flush;
00633   }
00634 
00635   // now see if we have anything to read
00636   std::istream is(&comm->getReadStreambuf());
00637   
00638   //cout << "" << get_time() << ": ";
00639   
00640   bool valid = false;
00641   {
00642     //    MarkScope autolock(comm->getLock());
00643     valid = attemptPacketRead(is, tempStatus);
00644   }
00645   
00646   if (!valid) {
00647     packetFailures++;
00648     
00649     if (packetFailures > 0 && packetFailures % 10 == 0) {
00650       if (packetFailures == 10)
00651         cout << "CREATE DRIVER: Dropped 10 consecutive packets, attempting to reconnect to Create...\n";
00652       if (packetFailures % 20 == 0)
00653         cout << "CREATE DRIVER: Still attempting to reconnect to Create...\n";
00654       connect();
00655       usleep(500000);
00656     }
00657     return false;
00658   }
00659   else {
00660     packetFailures = 0;
00661     mergeStatus(globalStatus, tempStatus);
00662   }
00663   // std::cout << "got packet\n" << std::flush;
00664   
00665   // set back to safe if we need to
00666   if (tempStatus.oiMode == RobotInfo::MODE_PASSIVE) {
00667     vector<unsigned char> commands(1); commands[0] = CREATE_SAFE;
00668     sendCommand(commands, 1000);
00669   }
00670   
00671   setSensorValue(DigitalInput0Offset, ((globalStatus.userDigitalInputs >> 0) & 0x1));
00672   setSensorValue(DigitalInput1Offset, ((globalStatus.userDigitalInputs >> 1) & 0x1));
00673   setSensorValue(DigitalInput2Offset, ((globalStatus.userDigitalInputs >> 2) & 0x1));
00674   setSensorValue(DigitalInput3Offset, ((globalStatus.userDigitalInputs >> 3) & 0x1));
00675   setSensorValue(AnalogSignalOffset,globalStatus.userAnalogInput);
00676   setSensorValue(WallSignalOffset,globalStatus.wallSignal);
00677   setSensorValue(IRCommOffset,globalStatus.ir);
00678   setSensorValue(CliffLeftSignalOffset,globalStatus.cliffLeftSignal);
00679   setSensorValue(CliffFrontLeftSignalOffset,globalStatus.cliffFrontLeftSignal);
00680   setSensorValue(CliffFrontRightSignalOffset,globalStatus.cliffFrontRightSignal);
00681   setSensorValue(CliffRightSignalOffset,globalStatus.cliffRightSignal);
00682   setSensorValue(EncoderDistanceOffset,globalStatus.distance);
00683   setSensorValue(EncoderAngleOffset,globalStatus.angle);
00684   setSensorValue(VoltageOffset,globalStatus.voltage);
00685   setSensorValue(CurrentOffset,globalStatus.current);
00686   setSensorValue(BatteryChargeOffset,globalStatus.batteryCharge);
00687   setSensorValue(BatteryTempOffset,globalStatus.batteryTemperature);
00688   setSensorValue(ChargingStateOffset,globalStatus.chargingState);
00689   setSensorValue(ModeStateOffset,globalStatus.oiMode);
00690   
00691   setButtonValue(PlayButOffset,(globalStatus.buttons & 0x1));
00692   setButtonValue(AdvanceButOffset,((globalStatus.buttons >> 2) & 0x1));
00693   setButtonValue(WallButOffset,globalStatus.wall);
00694   setButtonValue(DropCasterButOffset,((globalStatus.bumpsWheelDrops >> 4) & 0x1));
00695   setButtonValue(DropLeftWheelButOffset,((globalStatus.bumpsWheelDrops >> 3) & 0x1));
00696   setButtonValue(DropRightWheelButOffset,((globalStatus.bumpsWheelDrops >> 2) & 0x1));
00697   setButtonValue(BumpLeftButOffset,((globalStatus.bumpsWheelDrops >> 1) & 0x1));
00698   setButtonValue(BumpRightButOffset,((globalStatus.bumpsWheelDrops >> 0) & 0x1));
00699   setButtonValue(OvercurrentLeftWheelOffset,((globalStatus.overcurrents >> 4) & 0x1));
00700   setButtonValue(OvercurrentRightWheelOffset,((globalStatus.overcurrents >> 3) & 0x1));
00701   setButtonValue(LowSideDriver0ButOffset,((globalStatus.overcurrents >> 2) & 0x1));
00702   setButtonValue(LowSideDriver1ButOffset,((globalStatus.overcurrents >> 1) & 0x1));
00703   setButtonValue(LowSideDriver2ButOffset,((globalStatus.overcurrents >> 0) & 0x1));
00704   setButtonValue(BaseChargerButOffset,((globalStatus.chargingSourcesAvailable >> 1) & 0x1));
00705   setButtonValue(InternalChargerButOffset,((globalStatus.chargingSourcesAvailable >> 0) & 0x1));
00706   
00707   ++frameNumber;
00708   return true;
00709 }
00710 
00711 void CreateDriver::registerSource() {
00712   CommPort * comm = CommPort::getRegistry().getInstance(commName);
00713   if(comm==NULL) {
00714     std::cerr << "CreateDriver \"" << instanceName << "\": could not find CommPort \"" << commName << "\"" << std::endl;
00715   } else if(!comm->open()) {
00716     std::cerr << "CreateDriver \"" << instanceName << "\": unable to open comm port \"" << commName << "\"" << std::endl;
00717   } else {
00718     connect();
00719   }
00720   sensorsActive=true;
00721   commName.addPrimitiveListener(this);
00722 }
00723 
00724 void CreateDriver::deregisterSource() {
00725   CommPort * comm = CommPort::getRegistry().getInstance(commName);
00726   if(comm!=NULL)
00727     comm->close();
00728   sensorsActive=false;
00729   if(!motionActive) // listener count is not recursive, so only remove if we're the last one
00730     commName.removePrimitiveListener(this);
00731 }
00732 
00733 void CreateDriver::doUnfreeze() {
00734   MarkScope sl(poller.getStartLock());
00735   if(!poller.isStarted()) {
00736     //poller.resetPeriod(1.0/(*sensorFramerate));
00737     poller.start();
00738   }
00739   sensorFramerate->addPrimitiveListener(this);
00740 }
00741 
00742 void CreateDriver::doFreeze() {
00743   MarkScope sl(poller.getStartLock());
00744   if(poller.isStarted())
00745     poller.stop().join();
00746   sensorFramerate->removePrimitiveListener(this);
00747 }
00748 
00749 void CreateDriver::plistValueChanged(const plist::PrimitiveBase& pl) {
00750   // std::cout << "plistvalueChanged Called!" << std::endl;
00751   if(&pl==&commName) {
00752     // if here, then motionStarted or setDataSourceThread has been called, thus when commName changes,
00753     // need to close old one and reopen new one
00754     if(poller.isStarted())
00755       poller.stop().join();
00756     
00757     CommPort * comm = CommPort::getRegistry().getInstance(commName.getPreviousValue());
00758     if(comm!=NULL) {
00759       // close each of our old references
00760       if(sensorsActive)
00761         comm->close();
00762       if(motionActive)
00763         comm->close();
00764     }
00765     comm = CommPort::getRegistry().getInstance(commName);
00766     if(comm==NULL) {
00767       std::cerr << "CreateDriver \"" << instanceName << "\": could not find CommPort \"" << commName << "\"" << std::endl;
00768     } else {
00769       // open each of our new references
00770       if(sensorsActive)
00771         comm->open();
00772       if(motionActive) {
00773         if(!comm->open())
00774           std::cerr << "CreateDriver \"" << instanceName << "\": unable to open comm port \"" << commName << "\"" << std::endl;
00775         else
00776           connect();
00777       }
00778     }
00779     
00780     if(getTimeScale()>0) {
00781       //poller.resetPeriod(1.0/(*sensorFramerate));
00782       poller.start();
00783     }
00784   } else if(&pl==sensorFramerate) {
00785     //poller.resetPeriod(1.0/(*sensorFramerate));
00786   }
00787 }
00788 
00789 float CreateDriver::getAnalog(unsigned int /*inputIdx*/, unsigned char s) {
00790   return s*5.f/256;
00791 }
00792 
00793 float CreateDriver::getDigital(unsigned int /*inputIdx*/, unsigned char cur, unsigned char latch) {
00794   if(cur=='0')
00795     return 0;
00796   return (latch=='0') ? 0.5f : 1;
00797 }
00798 
00799 /*! @file
00800  * @brief 
00801  * @author Benson Tsai (btsai)
00802  * @author Ethan Tira-Thompson (ejt)
00803  * @author Alex Grubb (agrubb1)
00804  */
00805 
00806 #endif

Tekkotsu Hardware Abstraction Layer 5.1CVS
Generated Tue Jan 31 04:35:30 2012 by Doxygen 1.6.3