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
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
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
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
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
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
00386 }
00387 }
00388 firstMap = false;
00389
00390 }
00391
00392
00393
00394
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;
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
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
00460
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
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
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
00487 if( thiscell== (MapCell) MAP_WALL ) {
00488
00489 wall.x=ShmapCell2Point_X(i);
00490 wall.y=ShmapCell2Point_Y(j);
00491 } else if((j==1) || (j==20)){
00492
00493 wall.x=ShmapCell2Point_X(i);
00494 wall.y=ShmapCell2Point_Y(j);
00495 } else if ((i==1) || (i==29)) {
00496
00497 wall.x=ShmapCell2Point_X(i);
00498 wall.y=ShmapCell2Point_Y(j);
00499 }
00500
00501 if (wall.x >= 0.0) {
00502
00503 distance = distanceToObstacle(wall, 0.1);
00504 if (distance<min_distance) min_distance = distance;
00505 }
00506 }
00507 }
00508
00509
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);
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 }