BeoSonar.C

00001 #include "Robots/Beobot2/Hardware/BeoSonar.H"
00002 #include "Ice/BeobotEvents.ice.H"
00003 
00004 const ModelOptionCateg MOC_BeoSonar = {
00005         MOC_SORTPRI_3, "Beobot Sonar Related Options" };
00006 
00007 const ModelOptionDef OPT_SerialDev =
00008 { MODOPT_ARG(std::string), "SerialDev", &MOC_BeoSonar, OPTEXP_CORE,
00009         "The serial device file",
00010         "serial-dev", '\0', "/dev/ttyUSBX", "/dev/ttyUSB1"};
00011 
00012 // ######################################################################
00013 BeoSonar::BeoSonar(int id, OptionManager& mgr,
00014                    const std::string& descrName, const std::string& tagName) :
00015   RobotBrainComponent(mgr, descrName, tagName),
00016   itsSerial(new Serial(mgr)),
00017   itsData(5), itsOfs(new OutputFrameSeries(mgr)),
00018   itsDisplayUpdateRate(.05),
00019   itsSerialDev(&OPT_SerialDev, this, 0)
00020 {
00021   addSubComponent(itsSerial);
00022   addSubComponent(itsOfs);
00023   itsData[0].angle = -60;
00024   itsData[1].angle = -30;
00025   itsData[2].angle = 0;
00026   itsData[3].angle = 30;
00027   itsData[4].angle = 60;
00028 }
00029 
00030 // ######################################################################
00031 BeoSonar::~BeoSonar()
00032 {
00033 }
00034 
00035 void BeoSonar::start3()
00036 {
00037   itsSerial->configure (itsSerialDev.getVal().c_str(), 115200, "8N1", false, false, 0);
00038 
00039         //Check to ensure that our ttyUSB devices are set up correctly by polling their IDs
00040         LINFO("Checking for cooling board");
00041         const unsigned char cmd[1] = {0};
00042         std::vector<unsigned char> propIDvec = itsSerial->readFrame(cmd, 1, .5);
00043 
00044         std::string propID(propIDvec.begin(), propIDvec.end());
00045 
00046         if(propID == "")
00047                 LFATAL("ERROR! Unrecognized device on %s", itsSerialDev.getVal().c_str());
00048         else if(propID != "coolingboard")
00049                 LFATAL("ERROR! Incorrect device on %s: %s", itsSerialDev.getVal().c_str(), propID.c_str());
00050 
00051         LINFO("%s found on %s", propID.c_str(), itsSerialDev.getVal().c_str());
00052 }
00053 
00054 void BeoSonar::registerTopics()
00055 {
00056         registerPublisher("SonarReport");
00057 }
00058 
00059 void BeoSonar::evolve()
00060 {
00061         const unsigned char cmd[1] = {97};
00062 
00063         //Request a set of sonar readings from the cooling board
00064         std::vector<unsigned char> frame = itsSerial->readFrame(cmd, 1, .2);
00065 
00066         //If we recieved the expected 20 bytes back (4 bytes for each of the 5 sonars)
00067         //then let's parse them. The resulting values are the number of clock ticks
00068         //at 80Mhz that it took for the sonar pulse to leave the sonar, bounce off of the
00069         //nearest object, and return
00070         if(frame.size() == 20)
00071         {
00072                 unsigned int time0 = ((0x0FF & frame[0])  << 24) |
00073                                                                                             ((0x0FF & frame[1])  << 16) |
00074                                                                                                   ((0x0FF & frame[2])  << 8)  |
00075                                                                                                   ((0x0FF & frame[3])  << 0);
00076 
00077                 unsigned int time1 = ((0x0FF & frame[4])  << 24) |
00078                                             ((0x0FF & frame[5])  << 16) |
00079                                             ((0x0FF & frame[6])  << 8)  |
00080                                             ((0x0FF & frame[7])  << 0);
00081 
00082                 unsigned int time2 = ((0x0FF & frame[8])  << 24) |
00083                                             ((0x0FF & frame[9])  << 16) |
00084                                             ((0x0FF & frame[10]) << 8)  |
00085                                             ((0x0FF & frame[11]) << 0);
00086 
00087                 unsigned int time3 = ((0x0FF & frame[12]) << 24) |
00088                                             ((0x0FF & frame[13]) << 16) |
00089                                             ((0x0FF & frame[14]) << 8)  |
00090                                             ((0x0FF & frame[15]) << 0);
00091 
00092                 unsigned int time4 = ((0x0FF & frame[16]) << 24) |
00093                                             ((0x0FF & frame[17]) << 16) |
00094                                             ((0x0FF & frame[18]) << 8)  |
00095                                             ((0x0FF & frame[19]) << 0);
00096 
00097 
00098                 //Convert the number of clock ticks found above to meters
00099                 double distance0 = (double(time0) / double(80000000.0)) * double(343.0) / 2.0;
00100                 double distance1 = (double(time1) / double(80000000.0)) * double(343.0) / 2.0;
00101                 double distance2 = (double(time2) / double(80000000.0)) * double(343.0) / 2.0;
00102                 double distance3 = (double(time3) / double(80000000.0)) * double(343.0) / 2.0;
00103                 double distance4 = (double(time4) / double(80000000.0)) * double(343.0) / 2.0;
00104 
00105                 BeobotEvents::SonarReportPtr msg = new BeobotEvents::SonarReport;
00106                 msg->distances.resize(5);
00107                 msg->angles.resize(5);
00108                 msg->distances[0] = distance0; msg->angles[0] = -60;
00109                 msg->distances[1] = distance1; msg->angles[1] = -30;
00110                 msg->distances[2] = distance2; msg->angles[2] =   0;
00111                 msg->distances[3] = distance3; msg->angles[3] =  30;
00112                 msg->distances[4] = distance4; msg->angles[4] =  60;
00113                 this->publish("SonarReport", msg);
00114 
00115                 //Plot the distances
00116                 itsData[0].dist = distance0;
00117                 itsData[1].dist = distance1;
00118                 itsData[2].dist = distance2;
00119                 itsData[3].dist = distance3;
00120                 itsData[4].dist = distance4;
00121                 plotDists();
00122         }
00123         else
00124         {
00125                 LERROR("Invalid Frame Size Recieved from Sonar!");
00126         }
00127         usleep(100000);
00128 }
00129 
00130 // ######################################################################
00131 void BeoSonar::updateMessage(const RobotSimEvents::EventMessagePtr& eMsg,
00132     const Ice::Current&)
00133 {
00134 }
00135 
00136 // ######################################################################
00137 void BeoSonar::plotDists()
00138 {
00139         if(itsDisplayTimer.getSecs() > itsDisplayUpdateRate)
00140         {
00141                 itsDisplayTimer.reset();
00142 
00143                 Image<PixRGB<byte> > dispImg(512,512,ZEROS);
00144                 double rad;
00145                 double dist_scale = 70.0;
00146 
00147 
00148                 for (unsigned int i=0;i<itsData.size();i++)
00149                 {
00150                         PixRGB<byte> drawColor(0,255,0);
00151 
00152                         rad = std::min(itsData[i].dist,10.0);
00153                         rad = rad*dist_scale;
00154                         Point2D<int> pt;
00155                         pt.i = 256 - (int) rad*sin(itsData[i].angle*M_PI/180.0);
00156                         pt.j = 512 - (int) rad*cos(itsData[i].angle*M_PI/180.0);
00157 
00158                         if(i < itsData.size()-1)
00159                         {
00160                                 Point2D<int> nxt_pt;
00161                                 double rad2 = std::min(itsData[i+1].dist,10.0);
00162                                 rad2 *= dist_scale;
00163                                 nxt_pt.i = 256 - (int) rad2*sin(itsData[i+1].angle*M_PI/180.0);
00164                                 nxt_pt.j = 512 - (int) rad2*cos(itsData[i+1].angle*M_PI/180.0);
00165                                 drawLine(dispImg, pt, nxt_pt, PixRGB<byte>(0,0,255));
00166                         }
00167 
00168 
00169                         if(itsData[i].dist >= 10.0)
00170                                 drawColor = PixRGB<byte>(255,0,0);
00171 
00172                         drawCircle(dispImg, pt, 3, PixRGB<byte>(255,0,0));
00173                         drawLine(dispImg, Point2D<int>(256,512),pt,
00174                                         drawColor);
00175                         char buffer[128];
00176                         sprintf(buffer, "%0.2fm", itsData[i].dist);
00177                         writeText(dispImg, pt, buffer,
00178                                         PixRGB<byte>(255,255,255), PixRGB<byte>(0,0,0), SimpleFont::FIXED(6), true);
00179                 }
00180 
00181                 itsOfs->writeRGB(dispImg, "SonarData", FrameInfo("SonarData",SRC_POS));
00182                 itsOfs->updateNext();
00183         }
00184 }
00185 
Generated on Sun May 8 08:05:35 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3