]> rtime.felk.cvut.cz Git - eurobot/public.git/commitdiff
Merge branch 'maint-demo' master
authorMichal Sojka <sojkam1@fel.cvut.cz>
Fri, 28 Mar 2014 00:09:54 +0000 (01:09 +0100)
committerMichal Sojka <sojkam1@fel.cvut.cz>
Fri, 28 Mar 2014 00:09:54 +0000 (01:09 +0100)
Conflicts:
src/robomon/RobomonAtlantis.h

1  2 
src/robomon/RobomonAtlantis.cpp
src/robomon/RobomonAtlantis.h

index 63270a711a1911992a5058d9cedd9d7e6ebe86ac,6679b8ed36b3b1427d174a7e01f446bf948752af..9a2a30987191f88eab53e0daa39987a6d86b258d
@@@ -46,7 -46,7 +46,7 @@@
  #include <QMessageBox>
  
  RobomonAtlantis::RobomonAtlantis(QWidget *parent)
-       : QWidget(parent)
+     : QWidget(parent), motorSimulation(orte)
  {
        QFont font;
        font.setPointSize(7);
@@@ -65,7 -65,6 +65,7 @@@
        createOrte();
        createRobots();
        createActions();
 +      createMap();
  
  //    connect(vidle, SIGNAL(valueChanged(int)),
  //            robotEstPosBest, SLOT(setVidle(int)));
@@@ -175,16 -174,19 +175,22 @@@ void RobomonAtlantis::createMiscGroupBo
  
        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);
  }
@@@ -281,6 -283,46 +287,6 @@@ void RobomonAtlantis::createPowerGroupB
        powerGroupBox->setLayout(layout);
  }
  
 -#if 0
 -void RobomonAtlantis::createMotorsGroupBox()
 -{
 -      enginesGroupBox = new QGroupBox(tr("Motors"));
 -      QVBoxLayout *layout = new QVBoxLayout();
 -      QHBoxLayout *layout1 = new QHBoxLayout();
 -      QHBoxLayout *layout2 = new QHBoxLayout();
 -
 -      leftMotorSlider = new QSlider(Qt::Vertical);
 -      rightMotorSlider = new QSlider(Qt::Vertical);
 -      bothMotorsCheckBox = new QCheckBox(tr("Lock both"));
 -      stopMotorsPushButton = new QPushButton(tr("Stop Motors"));
 -
 -      leftMotorSlider->setMinimum(-100);
 -      leftMotorSlider->setMaximum(100);
 -      leftMotorSlider->setTracking(false);
 -      leftMotorSlider->setTickPosition(QSlider::TicksLeft);
 -
 -      rightMotorSlider->setMinimum(-100);
 -      rightMotorSlider->setMaximum(100);
 -      rightMotorSlider->setTracking(false);
 -      rightMotorSlider->setTickPosition(QSlider::TicksRight);
 -
 -      stopMotorsPushButton->setMaximumWidth(90);
 -
 -      layout1->addWidget(leftMotorSlider);
 -      layout1->addWidget(MiscGui::createLabel("0"));
 -      layout1->addWidget(rightMotorSlider);
 -
 -      layout2->addWidget(bothMotorsCheckBox);
 -
 -      layout->addWidget(MiscGui::createLabel("100"));
 -      layout->addLayout(layout1);
 -      layout->addWidget(MiscGui::createLabel("-100"));
 -      layout->addLayout(layout2);
 -      layout->addWidget(stopMotorsPushButton);
 -      enginesGroupBox->setLayout(layout);
 -}
 -#endif
 -
  void RobomonAtlantis::createRobots()
  {
        robotRefPos = new Robot("Ref", QPen(Qt::darkBlue), QBrush(Qt::NoBrush));
  
  }
  
 +void RobomonAtlantis::createMap()
 +{
 +      mapImage = new Map();
 +      mapImage->setZValue(5);
 +      mapImage->setTransform(QTransform().scale(MAP_CELL_SIZE_MM, MAP_CELL_SIZE_MM), true);
 +
 +
 +      playgroundScene->addItem(mapImage);
 +}
 +
  /**********************************************************************
   * GUI actions
   **********************************************************************/
@@@ -353,8 -385,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;
                        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)
  {
        if (state)
@@@ -464,7 -485,7 +473,7 @@@ void RobomonAtlantis::showMap(bool show
                        disconnect(mapTimer, SIGNAL(timeout()), this, SLOT(paintMap()));
                }
        }
 -      playgroundScene->showMap(show);
 +      mapImage->setVisible(show);
  }
  
  void RobomonAtlantis::paintMap()
  
          if (!map) return;
  
 -      for(int i=0; i < MAP_WIDTH; i++) {
 -              for(int j=0; j<MAP_HEIGHT; j++) {
 +      for(int i = 0; i < MAP_WIDTH; i++) {
 +              for(int j = 0; j < MAP_HEIGHT; j++) {
                          QColor color;
  
                          struct map_cell *cell = &map->cells[j][i];
                          if (cell->flags & MAP_FLAG_DET_OBST)
                                  color = cyan;
  
 -                        playgroundScene->setMapColor(i, j, color);
 +                      color.setAlpha(200);
 +                        mapImage->setPixelColor(i, MAP_HEIGHT - j - 1, color);
                  }
        }
  }
@@@ -556,8 -576,7 +565,8 @@@ void RobomonAtlantis::simulateObstacles
  
        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;
@@@ -590,11 -609,8 +599,11 @@@ bool RobomonAtlantis::event(QEvent *eve
                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();
@@@ -774,15 -790,14 +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);
                        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;
@@@ -920,69 -932,6 +923,69 @@@ double RobomonAtlantis::distanceToWallH
        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
@@@ -1044,6 -993,15 +1047,15 @@@ void RobomonAtlantis::setTeamColor(int 
        ORTEPublicationSend(orte.publication_robot_switches);
  }
  
+ void RobomonAtlantis::setMotorSimulation(int state)
+ {
+     if (state) {
+         motorSimulation.start();
+     } else {
+         motorSimulation.stop();
+     }
+ }
  void RobomonAtlantis::resetTrails()
  {
        trailRefPos->reset();
index f62fe99c9b7d28bd683abd43a54d9990ff9bd307,f7983628b3200db586dd4012ae648f9291e85440..f7239bed5ffa13f352951673480b2017f980a124
  #define ROBOMON_ATLANTIS_H
  
  #include <QDialog>
+ #include <QDateTime>
+ #include <QTimer>
  
  #include <trgen.h>
  #include "PlaygroundScene.h"
  #include "playgroundview.h"
  #include "Robot.h"
 +#include "Map.h"
  #include <roboorte_robottype.h>
  #include "trail.h"
  #include "hokuyoscan.h"
@@@ -38,8 -39,40 +40,41 @@@ class QDial
  class QSlider;
  class QProgressBar;
  class QFont;
 +class QImage;
  
+ class MotorSimulation : QObject {
+     Q_OBJECT
+     QTimer timer;
+     qint64 last_time;
+     struct robottype_orte_data &orte;
+ public:
+     MotorSimulation(struct robottype_orte_data &orte) : QObject(), timer(this), orte(orte) {}
+     void start()
+     {
+         robottype_publisher_motion_irc_create(&orte, 0, 0);
+         connect(&timer, SIGNAL(timeout()), this, SLOT(updateIRC()));
+         timer.start(50);
+     }
+     void stop()
+     {
+         robottype_publisher_motion_irc_destroy(&orte);
+         timer.stop();
+         disconnect(&timer, SIGNAL(timeout()), this, SLOT(updateIRC()));
+     }
+ private slots:
+     void updateIRC()
+     {
+         qint64 now = QDateTime::currentMSecsSinceEpoch();
+         orte.motion_irc.left += orte.motion_speed.left * (now - last_time);   // TODO: Find constant for speed to irc conversion
+         orte.motion_irc.right+= orte.motion_speed.right * (now - last_time);
+         ORTEPublicationSend(orte.publication_motion_irc);
+         last_time = now;
+     }
+ };
  class RobomonAtlantis : public QWidget
  {
        Q_OBJECT
@@@ -57,7 -90,7 +92,7 @@@ signals
        void motionStatusReceivedSignal();
        void actualPositionReceivedSignal();
        void powerVoltageReceivedSignal();
 -      
 +
  public slots:
        void showMap(bool show);
        void useOpenGL(bool use);
        void resetTrails();
  private slots:
        /************************************************************
 -       * GUI actions 
 +       * GUI actions
         ************************************************************/
        void setVoltage33(int state);
        void setVoltage50(int state);
        void changeObstacle(QPointF position);
        void sendStart(int plug);
        void setTeamColor(int plug);
 +        void changeStrategy_1();
 +        void changeStrategy_0();
+       void setMotorSimulation(int state);
  
        /************************************************************
 -       * ORTE 
 +       * ORTE
         ************************************************************/
        void motionStatusReceived();
        void actualPositionReceived();
@@@ -112,7 -144,6 +148,7 @@@ private
  
        void createRobots();
        void createActions();
 +      void createMap();
  
        QVBoxLayout *leftLayout;
        QVBoxLayout *rightLayout;
@@@ -161,20 -192,18 +197,21 @@@ private
  
        /* misc */
        QCheckBox *obstacleSimulationCheckBox;
+       QCheckBox *motorSimulationCheckBox;
        QLabel *fsm_main_state;
        QLabel *fsm_act_state;
        QLabel *fsm_motion_state;
        QCheckBox *startPlug;
        QCheckBox *colorChoser;
 +        QPushButton *strategyButton;
  public:
        /* robot */
        Robot *robotRefPos;
        Robot *robotEstPosBest;
        Robot *robotEstPosIndepOdo;
        Robot *robotEstPosOdo;
 +
 +      Map *mapImage;
  private:
        Trail *trailRefPos;
        Trail *trailEstPosBest;
        void openSharedMemory();
        bool sharedMemoryOpened;
        QTimer *mapTimer;
 -      
 +
        /* obstacle simulation */
        double distanceToWallHokuyo(int beamnum);
        double distanceToObstacleHokuyo(int beamnum, Point obstacle, double obstacleSize);
 +      double distanceToCircularObstacleHokuyo(int beamnum, Point center, double diameter);
        int simulationEnabled;
  
        QTimer *obstacleSimulationTimer;
        Point simulatedObstacle;
  
+       class MotorSimulation motorSimulation;
        /************************************************************
 -       * ORTE 
 +       * ORTE
         ************************************************************/
        void createOrte();