00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include "Robots/IRobot/Roomba.H"
00040 #include "Devices/Serial.H"
00041 #include "Component/OptionManager.H"
00042 #include "Util/Timer.H"
00043 #include <vector>
00044
00045
00046 #define SERIAL_TIMEOUT 1.0 //The maximum number of seconds to wait for a serial response
00047
00048
00049 Roomba::Roomba(OptionManager& mgr, const std::string& descrName,
00050 const std::string& tagName, const char *defdev) :
00051 ModelComponent(mgr, descrName, tagName),itsPort(new Serial(mgr,"roomba-serial","roomba-serial"))
00052 {
00053
00054
00055 itsPort->configure(defdev, 57600, "8N1", false, false, 1);
00056
00057 addSubComponent(itsPort);
00058 itsSpeed = 0;
00059 itsRadius =0;
00060 itsAngle=0;
00061 itsDist = 0;
00062 }
00063
00064
00065
00066 Roomba::~Roomba()
00067 {}
00068
00069
00070
00071 int Roomba::getSpeed()
00072 {
00073 return itsSpeed;
00074 }
00075
00076
00077 int Roomba::getRadius()
00078 {
00079 return itsRadius;
00080 }
00081
00082
00083
00084 int Roomba::getAngle()
00085 {
00086 return itsAngle;
00087 }
00088
00089
00090 int Roomba::getDist()
00091 {
00092 return itsDist;
00093 }
00094
00095
00096 void Roomba::setSpeed(const int speed)
00097 {
00098 if(!robotStarted)
00099 LFATAL("You must send start command first");
00100
00101 itsSpeed = speed;
00102 sendDriveCommand();
00103 }
00104
00105
00106 void Roomba::setRadius(const int radius)
00107 {
00108 if(!robotStarted)
00109 LFATAL("You must send start command first");
00110
00111 itsRadius = radius;
00112 sendDriveCommand();
00113 }
00114
00115
00116 void Roomba::sendDriveCommand()
00117 {
00118 if(!robotStarted)
00119 LFATAL("You must send start command first");
00120
00121 unsigned char cmd[5];
00122 cmd[0] = 137;
00123 cmd[1] = ((short int)itsSpeed&0x00FF00)>>8;
00124 cmd[2] = ((short int)itsSpeed&0x0000FF);
00125
00126 if (itsRadius == 0)
00127 {
00128 cmd[3] = 0x7F;
00129 cmd[4] = 0xFF;
00130 }
00131 else {
00132 cmd[3] = ((short int)itsRadius&0x00FF00)>>8;
00133 cmd[4] = ((short int)itsRadius&0x0000FF);
00134 }
00135
00136
00137 itsPort->write(cmd, 5);
00138 usleep(15*1000);
00139
00140 }
00141
00142
00143 void Roomba::sendStart()
00144 {
00145 unsigned char cmd[1];
00146 cmd[0] = 128;
00147 itsPort->write(cmd,1);
00148 usleep(15*1000);
00149 robotStarted = 1;
00150 }
00151
00152 void Roomba::setMode(const int mode)
00153 {
00154 unsigned char cmd[1];
00155 cmd[0] = 0;
00156
00157 switch(mode)
00158 {
00159 case 1: cmd[0] = 131; break;
00160 case 2: cmd[0] = 132; break;
00161 default: LFATAL("bad mode bye");
00162 };
00163
00164 itsPort->write(cmd, 1);
00165 usleep(15*1000);
00166 }
00167
00168
00169 void Roomba::setDemo(const short demo)
00170 {
00171 unsigned char cmd[2];
00172 cmd[0] = 136;
00173 cmd[1] = demo;
00174
00175 itsPort->write(cmd,1);
00176
00177 }
00178
00179
00180 void Roomba::setLED(const short led, const short color, const short intensity)
00181 {
00182 unsigned char cmd[4];
00183 cmd[0] = 139;
00184
00185 switch(led)
00186 {
00187 case 1: cmd[1] = 8; break;
00188 case 2: cmd[1] = 2; break;
00189 case 3: cmd[1] = 10; break;
00190 default: cmd[1] = 0;
00191 };
00192
00193 cmd[2] = color;
00194 cmd[3] = intensity;
00195
00196 itsPort->write(cmd,4);
00197
00198 }
00199
00200
00201 void Roomba::playSong(int song)
00202 {
00203
00204
00205
00206 unsigned char s1[21] = {140, 0, 9, 55, 30, 55, 30, 55, 30, 51, 30, 58, 12, 55, 30, 51, 30, 58, 12, 55, 30};
00207
00208 unsigned char s2[21] = {140, 1, 9, 62, 30, 62, 30, 62, 30, 63, 30, 58, 12, 54, 30, 51, 30, 58, 12, 55, 30};
00209
00210 unsigned char cmd[2] ;
00211
00212 itsPort->write(s1,21);
00213 itsPort->write(s2,21);
00214
00215 cmd[0] = 141;
00216 cmd[1] = (short)song;
00217
00218 itsPort->write(cmd,2);
00219 }
00220
00221
00222
00223 void Roomba::getDistanceAngle(int& dist,int& ang)
00224 {
00225
00226 unsigned char buff[255];
00227 int len = itsPort->read(buff,255);
00228 printf("%d bytes cleared\n",len);
00229
00230
00231 unsigned char cmd[4];
00232 unsigned char data[255];
00233 cmd[0] = 149;
00234 cmd[1] = 2;
00235 cmd[2] = 19;
00236 cmd[3] = 20;
00237
00238 itsPort->write(cmd,4);
00239
00240 usleep(10*1000);
00241
00242
00243 len = itsPort->read(data, 4);
00244 std::vector<byte> data_rcvd;
00245 for(int i=0; i<len; i++) data_rcvd.push_back(data[i]);
00246
00247 Timer serialTimeout;
00248 serialTimeout.reset();
00249 while(data_rcvd.size() < 4 && serialTimeout.getSecs() < SERIAL_TIMEOUT)
00250 {
00251 len = itsPort->read(data, 4);
00252 for(int i=0; i<len; i++) data_rcvd.push_back(data[i]);
00253 }
00254 double timeToRcv = serialTimeout.getSecs();
00255
00256
00257
00258 printf("Read dist angle bytes %i\n", data_rcvd.size());
00259 short int rDist = 0, rAng = 0;
00260 if (data_rcvd.size() == 4)
00261 {
00262
00263
00264
00265 rDist = (int16_t)((data_rcvd[0]<<8) | data_rcvd[1]);
00266 rAng = (int16_t)((data_rcvd[2]<<8) | data_rcvd[3]);
00267
00268 }
00269 else
00270 LERROR("Read return = %d bytes -- took %fs", data_rcvd.size(), timeToRcv);
00271
00272 LINFO("Read Took %fs", timeToRcv);
00273 dist= rDist;
00274 ang = rAng;
00275 itsDist = dist;
00276 itsAngle = ang;
00277 }
00278
00279
00280 void Roomba::sendRawCmd(const std::string& data)
00281 {
00282 }
00283
00284
00285 void Roomba::sendDirectDriveCommand(float itsCurrentSteering)
00286 {
00287
00288 int rightWheel = (int)((itsSpeed*500) + (itsCurrentSteering*500));
00289 int leftWheel = (int)((itsSpeed*500) - (itsCurrentSteering*500));
00290
00291 if (rightWheel > 500) rightWheel = 500;
00292 if (rightWheel < -500) rightWheel = -500;
00293
00294 if (leftWheel > 500) leftWheel = 500;
00295 if (leftWheel < -500) leftWheel = -500;
00296
00297 unsigned char cmd[5];
00298 cmd[0] = 145;
00299 cmd[1] = ((short int)rightWheel&0xFFFF)>>8;
00300 cmd[2] = ((short int)rightWheel&0xFF);
00301
00302 cmd[3] = ((short int)leftWheel&0xFFFF)>>8;
00303 cmd[4] = ((short int)leftWheel&0xFF);
00304
00305 itsPort->write(cmd,5);
00306 }
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326