]> rtime.felk.cvut.cz Git - eurobot/public.git/blobdiff - src/robomon/RobomonAtlantis.cpp
Merge branch 'maint-demo'
[eurobot/public.git] / src / robomon / RobomonAtlantis.cpp
index 94172078e0f71c978ab55bd6357ef32994e129aa..9a2a30987191f88eab53e0daa39987a6d86b258d 100644 (file)
@@ -46,7 +46,7 @@
 #include <QMessageBox>
 
 RobomonAtlantis::RobomonAtlantis(QWidget *parent)
-       : QWidget(parent)
+    : QWidget(parent), motorSimulation(orte)
 {
        QFont font;
        font.setPointSize(7);
@@ -175,13 +175,22 @@ void RobomonAtlantis::createMiscGroupBox()
 
        obstacleSimulationCheckBox = new QCheckBox(tr("&Obstacle simulation"));
        obstacleSimulationCheckBox->setShortcut(tr("o"));
+       obstacleSimulationCheckBox->setToolTip("When enabled, simulates an obstacle,\npublishes simlated hokuyo data and \ndisplays robot's map by using shared memory.");
        layout->addWidget(obstacleSimulationCheckBox);
 
+       motorSimulationCheckBox = new QCheckBox(tr("&Motor simulation"));
+       motorSimulationCheckBox->setShortcut(tr("m"));
+       motorSimulationCheckBox->setToolTip("Subscribes to motion_speed and\nbased on this publishes motion_irc.");
+       layout->addWidget(motorSimulationCheckBox);
+
        startPlug = new QCheckBox("&Start plug");
        layout->addWidget(startPlug);
 
        colorChoser = new QCheckBox("&Team color");
        layout->addWidget(colorChoser);
+        
+        strategyButton= new QPushButton(tr("Strategy"));
+        layout->addWidget(strategyButton);
 
        miscGroupBox->setLayout(layout);
 }
@@ -320,7 +329,7 @@ void RobomonAtlantis::createRobots()
 void RobomonAtlantis::createMap()
 {
        mapImage = new Map();
-       mapImage->setZValue(3);
+       mapImage->setZValue(5);
        mapImage->setTransform(QTransform().scale(MAP_CELL_SIZE_MM, MAP_CELL_SIZE_MM), true);
 
 
@@ -350,6 +359,8 @@ void RobomonAtlantis::createActions()
 
        connect(startPlug, SIGNAL(stateChanged(int)), this, SLOT(sendStart(int)));
        connect(colorChoser, SIGNAL(stateChanged(int)), this, SLOT(setTeamColor(int)));
+        connect(strategyButton, SIGNAL(pressed()), this, SLOT(changeStrategy_1()));
+        connect(strategyButton, SIGNAL(released()), this, SLOT(changeStrategy_0()));
 
        /* obstacle simulation */
        simulationEnabled = 0;
@@ -361,6 +372,21 @@ void RobomonAtlantis::createActions()
                        playgroundScene, SLOT(showObstacle(int)));
        connect(playgroundScene, SIGNAL(obstacleChanged(QPointF)),
                        this, SLOT(changeObstacle(QPointF)));
+
+       connect(motorSimulationCheckBox, SIGNAL(stateChanged(int)),
+               this, SLOT(setMotorSimulation(int)));
+}
+
+void RobomonAtlantis::changeStrategy_1()
+{
+        orte.robot_switches.strategy = true;
+        ORTEPublicationSend(orte.publication_robot_switches);
+}
+
+void RobomonAtlantis::changeStrategy_0()
+{
+        orte.robot_switches.strategy = false;
+        ORTEPublicationSend(orte.publication_robot_switches);
 }
 
 void RobomonAtlantis::setVoltage33(int state)
@@ -539,7 +565,8 @@ void RobomonAtlantis::simulateObstaclesHokuyo()
 
        for (i=0; i<HOKUYO_ARRAY_SIZE; i++) {
                wall_distance = distanceToWallHokuyo(i);
-               distance = distanceToObstacleHokuyo(i, simulatedObstacle, SIM_OBST_SIZE_M/*meters*/);
+
+               distance = distanceToCircularObstacleHokuyo(i, simulatedObstacle, SIM_OBST_SIZE_M);
                if (wall_distance < distance)
                        distance = wall_distance;
                hokuyo[i] = distance*1000;
@@ -572,8 +599,11 @@ bool RobomonAtlantis::event(QEvent *event)
                case QEVENT(QEV_HOKUYO_SCAN):
                        hokuyoScan->newScan(&orte.hokuyo_scan);
                        break;
-               case QEVENT(QEV_VIDLE_CMD):
-                       robotEstPosBest->setVidle(orte.vidle_cmd.req_pos);
+               case QEVENT(QEV_JAWS_CMD):
+                       robotEstPosBest->setJaws(orte.jaws_cmd.req_pos.left);
+                       robotRefPos->setJaws(orte.jaws_cmd.req_pos.left);
+                       robotEstPosIndepOdo->setJaws(orte.jaws_cmd.req_pos.left);
+                       robotEstPosOdo->setJaws(orte.jaws_cmd.req_pos.left);
                        break;
                case QEVENT(QEV_REFERENCE_POSITION):
                        emit actualPositionReceivedSignal();
@@ -753,17 +783,12 @@ void RobomonAtlantis::createOrte()
 {
        int rv;
 
-       orte.strength = 11;
-
        memset(&orte, 0, sizeof(orte));
        rv = robottype_roboorte_init(&orte);
        if (rv) {
                printf("RobomonAtlantis: Unable to initialize ORTE\n");
        }
 
-       /* publishers */
-       robottype_publisher_motion_speed_create(&orte, dummy_publisher_callback, NULL);
-
        robottype_publisher_pwr_ctrl_create(&orte, dummy_publisher_callback, NULL);
        robottype_publisher_robot_cmd_create(&orte, NULL, &orte);
        robottype_publisher_robot_switches_create(&orte, dummy_publisher_callback, &orte);
@@ -783,18 +808,15 @@ void RobomonAtlantis::createOrte()
                        generic_rcv_cb, new OrteCallbackInfo(this, QEV_ESTIMATED_POSITION_BEST));
        robottype_subscriber_hokuyo_scan_create(&orte,
                        generic_rcv_cb, new OrteCallbackInfo(this, QEV_HOKUYO_SCAN));
-       robottype_subscriber_vidle_cmd_create(&orte,
-                       generic_rcv_cb, new OrteCallbackInfo(this, QEV_VIDLE_CMD));
+       robottype_subscriber_jaws_cmd_create(&orte,
+                      generic_rcv_cb, new OrteCallbackInfo(this, QEV_JAWS_CMD));
        robottype_subscriber_fsm_main_create(&orte,
                                             rcv_fsm_main_cb, this);
        robottype_subscriber_fsm_motion_create(&orte,
                                             rcv_fsm_motion_cb, this);
        robottype_subscriber_fsm_act_create(&orte,
                                             rcv_fsm_act_cb, this);
-
-       /* motors */
-       orte.motion_speed.left = 0;
-       orte.motion_speed.right = 0;
+    robottype_subscriber_motion_speed_create(&orte, NULL, NULL);
 
        /* power management */
         orte.pwr_ctrl.voltage33 = true;
@@ -901,6 +923,69 @@ double RobomonAtlantis::distanceToWallHokuyo(int beamnum)
        return min_distance;
 }
 
+double RobomonAtlantis::distanceToCircularObstacleHokuyo(int beamnum, Point center, double diameter)
+{
+       struct robot_pos_type e = orte.est_pos_best;
+       double sensor_a;
+       struct sharp_pos s;
+
+       s.x = HOKUYO_CENTER_OFFSET_M;
+       s.y = 0.0;
+       s.ang = HOKUYO_INDEX_TO_RAD(beamnum);
+
+       Point sensor(e.x + s.x*cos(e.phi) - s.y*sin(e.phi),
+                    e.y + s.x*sin(e.phi) + s.y*cos(e.phi));
+       sensor_a = e.phi + s.ang;
+
+       const double sensorRange = 4.0; /*[meters]*/
+
+       double distance = sensorRange;
+       double angle;
+
+       angle = sensor.angleTo(center) - sensor_a;
+       angle = fmod(angle, 2.0*M_PI);
+       if (angle > +M_PI) angle -= 2.0*M_PI;
+       if (angle < -M_PI) angle += 2.0*M_PI;
+       angle = fabs(angle);
+
+       double k = tan(sensor_a);
+       double r = diameter / 2.0;
+
+       double A = 1 + k*k;
+       double B = 2 * (sensor.y*k - center.x - k*k*sensor.x - center.y*k);
+       double C = center.x*center.x + center.y*center.y +
+               k*k*sensor.x*sensor.x - 2*sensor.y*k*sensor.x +
+               sensor.y*sensor.y + 2*k*sensor.x*center.y -
+               2*sensor.y*center.y - r*r;
+
+       double D = B*B - 4*A*C;
+       
+       if (D > 0) {
+               Point ob1, ob2;
+
+               ob1.x = (-B + sqrt(D)) / (2*A);
+               ob2.x = (-B - sqrt(D)) / (2*A);
+               ob1.y = k * (ob1.x - sensor.x) + sensor.y;
+               ob2.y = k * (ob2.x - sensor.x) + sensor.y;
+
+               double distance1 = sensor.distanceTo(ob1);
+               double distance2 = sensor.distanceTo(ob2);
+               distance = (distance1 < distance2) ? distance1 : distance2;
+       } else if (D == 0) {
+               Point ob;
+               ob.x = -B / (2*A);
+               ob.y = k * (ob.x - sensor.x) + sensor.y;
+               distance = sensor.distanceTo(ob);
+       }
+       distance = distance + (drand48()-0.5)*3.0e-2;
+       if (D < 0 || angle > atan(r / distance))
+               distance = sensorRange;
+       if (distance > sensorRange)
+               distance = sensorRange;
+
+       return distance;
+}
+
 /**
  * Calculation for Hokuyo simulation. Calculates distance that would
  * be returned by Hokuyo sensors, if there is only one obstacle (as
@@ -962,6 +1047,15 @@ void RobomonAtlantis::setTeamColor(int plug)
        ORTEPublicationSend(orte.publication_robot_switches);
 }
 
+void RobomonAtlantis::setMotorSimulation(int state)
+{
+    if (state) {
+        motorSimulation.start();
+    } else {
+        motorSimulation.stop();
+    }
+}
+
 void RobomonAtlantis::resetTrails()
 {
        trailRefPos->reset();