robomon.cpp

00001 #include <math.h>
00002 #include "robomon.h"
00003 #include "robomon_orte.h"
00004 #include "robot.h"
00005 #include <pthread.h>
00006 #include <stdio.h>
00007 #include <stdlib.h>
00008 #include <path_planner.h>
00009 
00010 #include <QCoreApplication>
00011 #include <QEvent>
00012 #include <QDebug>
00013 #include <QMessageBox>
00014 #include <sharp.h>
00015 #include <fstream>
00016 #include <iostream>
00017 #include <trgen.h>
00018 
00019 bool robomon::event(QEvent *event) 
00020 {
00021         char buffer[20];
00022         switch(event->type()) {
00023                 case QEvent::GraphicsSceneMousePress:
00024                         break;
00025                 case EVENT_POS:
00026                         sprintf(buffer,"%f",pozice.x);
00027                         this->tbX->setText(buffer);
00028                         sprintf(buffer,"%f",pozice.y);
00029                         this->tbY->setText(buffer);
00030                         sprintf(buffer,"%f",pozice.phi);
00031                         this->tbPhi->setText(buffer);
00032                         if(!isnan(pozice.x) || !isnan(pozice.y) || !isnan(pozice.phi))
00033                                 this->rob->moveRobot(pozice.x,pozice.y,pozice.phi);
00034                         return TRUE;
00035                         break;
00036                 case EVENT_IR:
00037                         this->setIR(stateIR);
00038                         return TRUE;
00039                         break;
00040                 case EVENT_SHARP:
00041                         this->setSharp();
00042                         return TRUE;
00043                         break;
00044                 case EVENT_DI:
00045                         this->setDI(stateDI);
00046                         return TRUE;
00047                         break;
00048                 default:
00049                         return FALSE;
00050         }
00051         return FALSE;
00052 }
00053 
00054 void robomon::setDI(stateDigIn stateDI)
00055 {
00056         this->cbDI0->setChecked((stateDI.state & (1<<0)));
00057         this->cbDI1->setChecked((stateDI.state & (1<<1)));
00058         this->cbDI2->setChecked((stateDI.state & (1<<2)));
00059         this->cbDI3->setChecked((stateDI.state & (1<<3)));
00060         this->cbDI4->setChecked((stateDI.state & (1<<4)));
00061         this->cbDI5->setChecked((stateDI.state & (1<<5)));
00062         this->cbDI6->setChecked((stateDI.state & (1<<6)));
00063         this->cbDI7->setChecked((stateDI.state & (1<<7)));
00064 }
00065 
00066 void robomon::setIR(unsigned short int stateIR)
00067 {
00068         this->cbIR1->setChecked((sir.front & (1<<7)));
00069         this->cbIR2->setChecked((sir.front & (1<<6)));
00070         this->cbIR3->setChecked((sir.front & (1<<5)));
00071         this->cbIR4->setChecked((sir.front & (1<<4)));
00072         this->cbIR5->setChecked((sir.front & (1<<3)));
00073         this->cbIR6->setChecked((sir.front & (1<<2)));
00074         this->cbIR7->setChecked((sir.front & (1<<1)));
00075         this->cbIR8->setChecked((sir.front & (1<<0)));
00076         this->cbIR9->setChecked((sir.back & (1<<0)));
00077         this->cbIR10->setChecked((sir.back & (1<<1)));
00078         this->cbIR11->setChecked((sir.back & (1<<2)));
00079         this->cbIR12->setChecked((sir.back & (1<<3)));
00080         this->cbIR13->setChecked((sir.back & (1<<4)));
00081         this->cbIR14->setChecked((sir.back & (1<<5)));
00082         this->cbIR15->setChecked((sir.back & (1<<6)));
00083         this->cbIR16->setChecked((sir.back & (1<<7)));
00084 }
00085 
00086 robomon::robomon(QWidget* parent, Qt::WFlags fl)
00087 : QWidget( parent, fl ), Ui::Form()
00088 {       
00089         setupUi(this);
00090 
00091         QObject::connect(this->btStopMotors, SIGNAL(clicked()), this, SLOT(stopMotors()));
00092         
00093         QObject::connect(this->dServo3, SIGNAL(valueChanged(int)), this, SLOT(moveServo(int)));
00094         QObject::connect(this->dServo4, SIGNAL(valueChanged(int)), this, SLOT(moveServo(int)));
00095         
00096         QObject::connect(this->cbFrontDoor, SIGNAL(stateChanged(int)), this, SLOT(frontDoor(int)));
00097         QObject::connect(this->cbInnerDoor, SIGNAL(stateChanged(int)), this, SLOT(innerDoor(int)));
00098         QObject::connect(this->cbBackDoor, SIGNAL(stateChanged(int)), this, SLOT(backDoor(int)));
00099         QObject::connect(this->cbLaunch, SIGNAL(stateChanged(int)), this, SLOT(launchFront(int)));
00100 
00101 
00102         QObject::connect(this->btDopravnikFront, SIGNAL(clicked()), this, SLOT(stopDopravnikFront()));
00103 
00104         QObject::connect(this->btDopravnikBack, SIGNAL(clicked()), this, SLOT(stopDopravnikBack()));
00105         QObject::connect(this->btMap, SIGNAL(clicked()), this, SLOT(showMap()));
00106 
00107         QObject::connect(this->cbDO0, SIGNAL(stateChanged(int)), this, SLOT(setDO(int)));
00108         QObject::connect(this->cbDO1, SIGNAL(stateChanged(int)), this, SLOT(setDO(int)));
00109         QObject::connect(this->cbDO2, SIGNAL(stateChanged(int)), this, SLOT(setDO(int)));
00110         QObject::connect(this->cbDO3, SIGNAL(stateChanged(int)), this, SLOT(setDO(int)));
00111         QObject::connect(this->cbDO4, SIGNAL(stateChanged(int)), this, SLOT(setDO(int)));
00112         QObject::connect(this->cbDO5, SIGNAL(stateChanged(int)), this, SLOT(setDO(int)));
00113         QObject::connect(this->cbDO6, SIGNAL(stateChanged(int)), this, SLOT(setDO(int)));
00114         QObject::connect(this->cbDO7, SIGNAL(stateChanged(int)), this, SLOT(setDO(int)));
00115 
00116         QObject::connect(this->slMotorLeft, SIGNAL(valueChanged(int)), this, SLOT(setMotor(int)));
00117         QObject::connect(this->slMotorRight, SIGNAL(valueChanged(int)), this, SLOT(setMotor(int)));
00118         
00119     QObject::connect(this->cbSimulation, SIGNAL(stateChanged(int)), this, SLOT(setSimul(int)));
00120         
00121         QObject::connect(this->slB1, SIGNAL(valueChanged(int)), this, SLOT(setSharpVal(int)));
00122         QObject::connect(this->slB2, SIGNAL(valueChanged(int)), this, SLOT(setSharpVal(int)));
00123         QObject::connect(this->slB3, SIGNAL(valueChanged(int)), this, SLOT(setSharpVal(int)));
00124         
00125         QObject::connect(this->slA1, SIGNAL(valueChanged(int)), this, SLOT(setSharpVal(int)));
00126         QObject::connect(this->slA2, SIGNAL(valueChanged(int)), this, SLOT(setSharpVal(int)));
00127         QObject::connect(this->slA3, SIGNAL(valueChanged(int)), this, SLOT(setSharpVal(int)));
00128         QObject::connect(this->slA4, SIGNAL(valueChanged(int)), this, SLOT(setSharpVal(int)));
00129         
00130 
00131         this->scene = new PlaygroundScene();
00132     this->gvPlayground->setScene(this->scene);
00133 
00134     QObject::connect(this->cbObstackle, SIGNAL(stateChanged(int)), this, SLOT(setSimul(int)));
00135     QObject::connect(this->cbObstackle, SIGNAL(stateChanged(int)), this, SLOT(obstackleSimulation(int)));
00136     connect(this->cbObstackle, SIGNAL(stateChanged(int)), this->scene, SLOT(showObstacle(int)));
00137     connect(this->scene, SIGNAL(obstacleChanged(QPointF)), this, SLOT(changeObstacle(QPointF)));
00138 
00139         rob = new robot(NULL, scene);
00140         rob->setZValue(10);
00141         
00142         scene->addItem(rob);
00143 //      rob->moveRobot(pos.x,pos.y,pos.phi);
00144         
00145         orte_function(this);
00146         serva.transporterInner = TRANSPORTER_OFF;
00147         serva.transporterFront = TRANSPORTER_OFF;
00148         serva.frontDoor = FRONT_DOOR_UP;
00149         serva.backDoor = BACK_DOOR_UP;
00150         serva.innerDoor = INNER_DOOR_UP;
00151 }
00152 
00153 
00154 robomon::~robomon()
00155 {
00156         shmdt((void*)map);
00157 
00158         ORTEDomainAppDestroy(d);
00159 }
00160 
00161 void robomon::setSimul(int value)
00162 {
00163         if(value) {
00164                 publisherCreateSensShort(this);
00165                 publisherCreateSensLong(this);
00166         }
00167         else {
00168                 ORTEPublicationDestroy(publisherSharpShort);
00169                 ORTEPublicationDestroy(publisherSharpLong);
00170         }
00171 }
00172 
00173 void robomon::moveServo(int value)
00174 {
00175         serva.transporterInner = this->dServo3->value();
00176         serva.transporterFront = this->dServo4->value();
00177         ORTEPublicationSend(publisherServa);
00178 }
00179 
00180 void robomon::frontDoor(int state)
00181 {
00182         if(state) serva.frontDoor = FRONT_DOOR_UP;
00183         else serva.frontDoor = FRONT_DOOR_DOWN;
00184         ORTEPublicationSend(publisherServa);
00185 }
00186 
00187 void robomon::launchFront(int state)
00188 {
00189         if(state) serva.release = 255;
00190         else serva.release = 50;
00191         ORTEPublicationSend(publisherServa);
00192 }
00193 
00194 void robomon::innerDoor(int state)
00195 {
00196         if(state) serva.innerDoor = INNER_DOOR_UP;
00197         else serva.innerDoor = INNER_DOOR_DOWN;
00198         ORTEPublicationSend(publisherServa);
00199 }
00200 
00201 void robomon::backDoor(int state)
00202 {
00203         if(state) serva.backDoor = BACK_DOOR_UP;
00204         else serva.backDoor = BACK_DOOR_DOWN;
00205         ORTEPublicationSend(publisherServa);
00206 }
00207 
00208 void robomon::stopDopravnikFront(void)
00209 {
00210         serva.transporterInner = TRANSPORTER_OFF;
00211         this->dServo3->setValue(TRANSPORTER_OFF);       
00212         ORTEPublicationSend(publisherServa);
00213 }
00214 
00215 void robomon::stopDopravnikBack(void)
00216 {
00217         serva.transporterFront = TRANSPORTER_OFF;
00218         this->dServo4->setValue(TRANSPORTER_OFF);       
00219         ORTEPublicationSend(publisherServa);
00220 }
00221 
00222 void robomon::setSharpVal(int x)
00223 {       
00224         sharpyLahve.short1 = this->slA1->value();
00225         sharpyLahve.short2 = this->slA2->value();
00226         sharpyLahve.short3 = this->slA3->value();
00227         sharpyLahve.short4 = this->slA4->value();
00228         ORTEPublicationSend(publisherSharpShort);
00229         sharpySouper.longSharpDist1 = this->slB1->value()/1000.0;
00230     sharpySouper.longSharpDist2 = this->slB2->value()/1000.0;
00231     sharpySouper.longSharpDist3 = this->slB3->value()/1000.0;
00232     ORTEPublicationSend(publisherSharpLong);
00233 }
00234 
00235 void robomon::setDO(int x)
00236 {       
00237         stateDO[0] = this->cbDO0->isChecked();
00238         stateDO[1] = this->cbDO1->isChecked();
00239         stateDO[2] = this->cbDO2->isChecked();
00240         stateDO[3] = this->cbDO3->isChecked();
00241         stateDO[4] = this->cbDO4->isChecked();
00242         stateDO[5] = this->cbDO5->isChecked();
00243         stateDO[6] = this->cbDO6->isChecked();
00244         stateDO[7] = this->cbDO7->isChecked();
00245         ORTEPublicationSend(publisherDO);
00246 }
00247 
00248 void robomon::setSharp()
00249 {
00250         char buffer[20];
00251     int val;
00252     val = ss1.longSharpDist1*1000;
00253         sprintf(buffer,"%dmm",val);
00254         this->tbSharpLong1->setText(buffer);
00255     if (val > pbSharpLong1->maximum()) val = pbSharpLong1->maximum();
00256     this->pbSharpLong1->setValue(val);
00257     
00258     val = ss1.longSharpDist2*1000;
00259 //      sprintf(buffer,"%dmm",s_ir2mmLong(ss1.longSharp2));
00260     sprintf(buffer,"%dmm",val);
00261         this->tbSharpLong2->setText(buffer);
00262     if (val > pbSharpLong2->maximum()) val = pbSharpLong2->maximum();
00263     this->pbSharpLong2->setValue(val);
00264     
00265     val = ss1.longSharpDist3*1000;
00266 //      sprintf(buffer,"%dmm",s_ir2mmLong(ss1.longSharp3));
00267     sprintf(buffer,"%dmm",val);
00268         this->tbSharpLong3->setText(buffer);
00269     if (val > pbSharpLong3->maximum()) val = pbSharpLong3->maximum();
00270     this->pbSharpLong3->setValue(val);
00271         
00272     this->pbSharpShort1->setValue(s_ir2mmShort(ss2.short1));
00273         sprintf(buffer,"%d",s_ir2mmShort(ss2.short1));
00274         this->tbSharpShort1->setText(buffer);
00275         this->pbSharpShort2->setValue(s_ir2mmShort(ss2.short2));
00276         sprintf(buffer,"%d",s_ir2mmShort(ss2.short2));
00277         this->tbSharpShort2->setText(buffer);
00278         this->pbSharpShort3->setValue(s_ir2mmShort(ss2.short3));
00279         sprintf(buffer,"%d",s_ir2mmShort(ss2.short3));
00280         this->tbSharpShort3->setText(buffer);
00281         this->pbSharpShort4->setValue(s_ir2mmShort(ss2.short4));
00282         sprintf(buffer,"%d",s_ir2mmShort(ss2.short4));
00283         this->tbSharpShort4->setText(buffer);
00284 }
00285 
00286 void robomon::setMotor(int x)
00287 {
00288         short int motorL;
00289         short int motorR;
00290 
00291         if(this->cbJoinMotors->isChecked()) {
00292                 slMotorRight->setValue(slMotorLeft->value());
00293         }
00294         motorL = (short int)(MOTOR_LIMIT * (slMotorLeft->value()/100.0));
00295         motorR = (short int)(MOTOR_LIMIT * (slMotorRight->value()/100.0));
00296         
00297         mspeed.left = motorL;
00298         mspeed.right = motorR;
00299 
00300         ORTEPublicationSend(publisherMotor);
00301 }
00302 
00303 void robomon::stopMotors()
00304 {
00305         slMotorLeft->setValue(0);
00306         slMotorRight->setValue(0);
00307 }
00308 
00309 void robomon::showMap()
00310 {
00311         size = PG_X / MAP_WIDTH;
00312         
00313         shared_segment_size = sizeof(char) * MAP_WIDTH * MAP_HEIGHT;
00314         
00315         /* Get segment identificator in a read only mode  */
00316         segment_id = shmget (SHM_MAP_KEY, shared_segment_size, S_IRUSR );
00317         if(segment_id==-1) {
00318                 QMessageBox::critical(this,"robomon","Unable to open shared memory segment!");
00319                 return;
00320         }
00321 
00322         /* Attach the shared memory segment */
00323         map =  (_Map*)shmat (segment_id, (void*) 0, 0);
00324 
00325         timer = new QTimer(this);
00326         connect(timer, SIGNAL(timeout()), this, SLOT(paintMap()));
00327         timer->start(200);
00328         
00329 }
00330 
00331 void robomon::paintMap()
00332 {
00333     using namespace Qt;
00334         static QGraphicsRectItem *rects[MAP_WIDTH][MAP_HEIGHT];
00335         static bool firstMap = true;
00336         int x,y;
00337         
00338         for(int i=0; i < MAP_WIDTH; i++) {
00339                 for(int j=0; j<MAP_HEIGHT; j++) {
00340                         x = TOP_LEFT_X+i*size;
00341                         y = TOP_LEFT_Y+j*size;
00342                                 
00343                         if(firstMap) {                  
00344                                 rects[i][j] = this->scene->addRect(QRectF(x,y,size,size),QPen(QBrush(Qt::black),1,Qt::SolidLine,Qt::FlatCap,Qt::BevelJoin),QBrush(Qt::lightGray));
00345                         
00346                                 rects[i][j]->setZValue(4);
00347                         }
00348                                 
00349                         switch(map->cells[j][i]) {              
00350                                 case MAP_WALL:
00351                                         rects[i][j]->setBrush(QBrush(Qt::yellow));
00352                                         break;
00353                                 case MAP_WALL_CSPACE:
00354                                         rects[i][j]->setBrush(QBrush(Qt::darkYellow));
00355                                         break;
00356                                 case MAP_PATH:
00357                                         rects[i][j]->setBrush(QBrush(Qt::darkRed));
00358                                         break;
00359                                 case MAP_START:
00360                                         rects[i][j]->setBrush(QBrush(Qt::red));
00361                                         break;
00362                                 case MAP_GOAL:
00363                                         rects[i][j]->setBrush(QBrush(Qt::green));
00364                                         break;
00365                                 case MAP_NEW_OBSTACLE:
00366                                         rects[i][j]->setBrush(QBrush(Qt::blue));
00367                                         break;
00368                                 case MAP_NEW_OBSTACLE_CSPACE:
00369                                         rects[i][j]->setBrush(QBrush(Qt::cyan));
00370                                         break;
00371                                 case MAP_FREE:
00372                                         rects[i][j]->setBrush(QBrush(lightGray));
00373                                         break;
00374                                 default: {
00375                     QColor c1(lightGray), c2(blue);
00376                     double f = map->cells[j][i]/251.0;
00377                     QColor c(c1.red()   + f*(c2.red()   - c1.red()),
00378                              c1.green() + f*(c2.green() - c1.green()),
00379                              c1.blue()  + f*(c2.blue()  - c1.blue()));
00380                     
00381                                         rects[i][j]->setBrush(QBrush(c));
00382                                         break;
00383                 }
00384                         }
00385                         //this->gvPlayground->update();
00386                 }
00387         }
00388         firstMap = false;
00389         
00390 }
00391 
00392 
00393 
00394 /*$SPECIALIZATION$*/
00395 
00396 
00400 void robomon::obstackleSimulation(int state)
00401 {
00402     if (state) {
00403         ShmapInit(0);
00404         obstSimTimer = new QTimer(this);
00405         connect(obstSimTimer, SIGNAL(timeout()), this, SLOT(simulateObstackles()));
00406         obstSimTimer->start(100);
00407         this->setMouseTracking(true);
00408     } else {
00409         if (obstSimTimer) delete obstSimTimer;
00410         double distance = 0.8;
00411         sharpySouper.longSharpDist1 = distance;
00412         sharpySouper.longSharpDist2 = distance;
00413         sharpySouper.longSharpDist3 = distance;
00414         ORTEPublicationSend(publisherSharpLong);
00415 
00416     }
00417 }
00418 
00429 static double distanceToObstacle(Point obstacle, double obstacleSize)
00430 {
00431     Point robot(pozice.x, pozice.y);
00432     const double sensorRange = 1.0; /*[meters]*/
00433 
00434     double distance, angle;
00435 
00436     angle = robot.angleTo(obstacle) - pozice.phi;
00437     angle = fmod(angle, 2.0*M_PI);
00438     if (angle > +M_PI) angle -= 2.0*M_PI;
00439     if (angle < -M_PI) angle += 2.0*M_PI;
00440     angle = fabs(angle);
00441     distance = robot.distanceTo(obstacle)-0.11;
00442     if (angle < atan(obstacleSize/2.0 / (distance+0.001))) {
00443         // We can see the obstackle from here.
00444         if (angle < M_PI/2.0) {
00445             distance = distance/cos(angle);
00446         }
00447         if (distance > sensorRange) distance = sensorRange;
00448     } else {
00449         distance = sensorRange;
00450     }
00451     return distance;
00452 }
00453 
00454 static double distanceToWall(){
00455         double distance=1.0, min_distance=1.0;
00456         int i,j;
00457         Point wall;
00458 #if 0
00459         // Simulate wall
00460         //TODO change to macros
00461         for (i=1;i<30;i=i+28){
00462                 for(j=0;j<21;j++){
00463                         wall.x=i/10.0;
00464                         wall.y=j/10.0;
00465                     //printf("(%f,%f)",wall.x, wall.y);
00466                         distance = distanceToObstacle(wall, 0.01);
00467                         if (distance<min_distance) min_distance = distance;
00468                 }
00469         }
00470         for(j=1;j<21;j=j+19){
00471                 for (i=1;i<30;i++){
00472                         wall.x=i/10.0;
00473                         wall.y=j/10.0;
00474                         printf("(%f,%f)\n",wall.x, wall.y);
00475                         distance = distanceToObstacle(wall, 0.01);
00476                         if (distance<min_distance) min_distance = distance;
00477                 }
00478         }
00479 #endif
00480 #if 1
00481         // Simulate obstacles
00482         for(j=1;j<21;j++){
00483                 for (i=1;i<30;i++){
00484                         MapCell thiscell = ShmapGetCellValue(i,j);
00485                         wall.x=-1.0;
00486                         //printf("Cell : %02X\n", thiscell);
00487                         if( thiscell== (MapCell) MAP_WALL ) {
00488                                 // WALL
00489                                 wall.x=ShmapCell2Point_X(i);
00490                                 wall.y=ShmapCell2Point_Y(j);
00491                         } else if((j==1) || (j==20)){
00492                                 // Vertical borders
00493                                 wall.x=ShmapCell2Point_X(i);
00494                                 wall.y=ShmapCell2Point_Y(j);
00495                         } else if ((i==1) || (i==29)) {
00496                                 // Horizontal Borders
00497                                 wall.x=ShmapCell2Point_X(i);
00498                                 wall.y=ShmapCell2Point_Y(j);
00499                         }
00500                         
00501                         if (wall.x >= 0.0) {
00502                                 //printf("[%d,%d],(%f,%f)\n",i,j,wall.x, wall.y);
00503                                 distance = distanceToObstacle(wall, 0.1);
00504                                 if (distance<min_distance) min_distance = distance;
00505                         }
00506                 }
00507         }
00508         //ShmapDt();
00509         //ShmapFree();
00510 #endif
00511         return min_distance;
00512 }
00513 
00514 
00518 void robomon::simulateObstackles()
00519 {
00520     double distance, wall_distance;
00521 
00522     
00523     wall_distance = distanceToWall();
00524     distance = distanceToObstacle(simulatedObstacle, 0.5/*meters*/);
00525     if (wall_distance<distance) distance = wall_distance;
00526     
00527     sharpySouper.longSharpDist1 = distance;
00528     sharpySouper.longSharpDist2 = distance;
00529     sharpySouper.longSharpDist3 = distance;
00530     ORTEPublicationSend(publisherSharpLong);
00531 
00532     
00533 }
00534 
00535 
00536 void robomon::changeObstacle(QPointF pos)
00537 {
00538     simulatedObstacle.x = pos.x();
00539     simulatedObstacle.y = pos.y();
00540     simulateObstackles();
00541 }

Generated on Thu Sep 13 11:28:28 2007 for DCE-Eurobot by  doxygen 1.5.3