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
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
00064 std::vector<unsigned char> frame = itsSerial->readFrame(cmd, 1, .2);
00065
00066
00067
00068
00069
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
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
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