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