diff --git a/src/drone.cc b/src/drone.cc index 2c0fad8..50bc5e7 100644 --- a/src/drone.cc +++ b/src/drone.cc @@ -31,6 +31,10 @@ Drone::Drone(const QJsonObject &json) for (const QJsonValue &o : ja) { waypoints.append(Waypoint(o.toObject())); } + for (int i = 0; i < waypoints.size() - 1; i++) { + waypoints[i].computed_speed = (waypoints[i + 1].pos - waypoints[i].pos).length() + / (waypoints[i + 1].frame - waypoints[i].frame); + } setTo(0); } @@ -55,10 +59,13 @@ void Drone::setTo(int frame) { } if (next > -1 && prev == -1) { pos = next_wp->pos; + speed = next_wp->computed_speed; } else if (prev > -1 && next == -1) { pos = prev_wp->pos; + speed = prev_wp->computed_speed; } else { pos = lerp(prev_wp->pos, next_wp->pos, (double) (frame-prev) / (next-prev)); + speed = prev_wp->computed_speed; } } @@ -73,6 +80,11 @@ int Drone::getId() const { } +double Drone::getSpeed() const { + return speed; +} + + const OpenGLMesh *Drone::getMesh() const { return mesh; } diff --git a/src/drone.hh b/src/drone.hh index 873bb27..bc69554 100644 --- a/src/drone.hh +++ b/src/drone.hh @@ -22,6 +22,7 @@ class Drone { QVector waypoints; QVector3D pos; int id; + double speed = 0; public: Drone(int id); @@ -30,6 +31,7 @@ public: void setTo(int frame); const QVector3D getPos() const; int getId() const; + double getSpeed() const; const OpenGLMesh *getMesh() const; }; diff --git a/src/drone_controller.cc b/src/drone_controller.cc index cede63d..58f0359 100644 --- a/src/drone_controller.cc +++ b/src/drone_controller.cc @@ -261,6 +261,23 @@ void DroneController::computeCollisions(double sphere_radius) { } +void DroneController::computeSpeedingViolations(double speed) { + speed_violations.clear(); + for (int i = 0; i < duration; i++) { + for (Drone &d : drones) { + d.setTo(i); + if (d.getSpeed() > speed) { + speed_violations[i].append(d.getId()); + emit speedViolation(d.getId(), d.getSpeed(), i); + } + } + } + for (Drone &d : drones) { + d.setTo(frame); + } +} + + void DroneController::displaySpheres(double sphere_radius) { draw_spheres = true; this->sphere_radius = sphere_radius; diff --git a/src/drone_controller.hh b/src/drone_controller.hh index 6099e08..3c09089 100644 --- a/src/drone_controller.hh +++ b/src/drone_controller.hh @@ -25,6 +25,8 @@ class DroneController : public QObject, public Painter { QMap>> collisions; bool draw_trajectories = false; bool draw_guides = false; + QMap> speed_violations; + double speed_limit = 0; static OpenGLMesh *sphere; static const unsigned char sphere_neutral[]; @@ -44,6 +46,7 @@ signals: void playing(); void pausing(); void collision(int idA, int idB, int frame); + void speedViolation(int id, double speed, int frame); private slots: void step(); @@ -55,6 +58,7 @@ public slots: void resume(); void seek(int frame); void computeCollisions(double sphere_radius); + void computeSpeedingViolations(double speed); void displaySpheres(double sphere_radius); void setDrawTrajectories(bool enable); void setDrawGuides(bool enable); diff --git a/src/main_window.cc b/src/main_window.cc index 285294f..39261dd 100644 --- a/src/main_window.cc +++ b/src/main_window.cc @@ -82,17 +82,27 @@ void MainWindow::open(const QString &path) { // Settings pane connect(settings_pane, &SettingsPane::bookmarkClicked, slider, &QSlider::setValue); + connect(dc, &DroneController::collision, settings_pane, &SettingsPane::addCollision); + connect(dc, &DroneController::speedViolation, settings_pane, &SettingsPane::addSpeedingViolation); + connect(settings_pane, &SettingsPane::sphereRadiusChanged, [&](double _) { Q_UNUSED(_); settings_pane->clearCollisions(); }); connect(settings_pane, &SettingsPane::sphereRadiusChanged, dc, &DroneController::computeCollisions); connect(settings_pane, &SettingsPane::sphereRadiusChanged, dc, &DroneController::displaySpheres); + + connect(settings_pane, &SettingsPane::speedLimitChanged, + [&](double _) { Q_UNUSED(_); settings_pane->clearSpeedingViolations(); }); + connect(settings_pane, &SettingsPane::speedLimitChanged, + dc, &DroneController::computeSpeedingViolations); + connect(settings_pane, &SettingsPane::toggledTrajectories, dc, &DroneController::setDrawTrajectories); connect(settings_pane, &SettingsPane::toggledGuides, dc, &DroneController::setDrawGuides); + settings_pane->setEnabled(true); glw.setPainter(dc); diff --git a/src/settings_pane.cc b/src/settings_pane.cc index 7d3b10f..e580d37 100644 --- a/src/settings_pane.cc +++ b/src/settings_pane.cc @@ -12,6 +12,8 @@ SettingsPane::SettingsPane(QWidget *parent) :QWidget(parent) { QDoubleSpinBox *sphere_radius = new QDoubleSpinBox(); sphere_radius->setSingleStep(.1); + QDoubleSpinBox *speed_limit = new QDoubleSpinBox(); + speed_limit->setSingleStep(.1); QCheckBox *show_trajectories = new QCheckBox(); QCheckBox *show_guides = new QCheckBox(); collisions = new QListWidget(); @@ -19,6 +21,8 @@ SettingsPane::SettingsPane(QWidget *parent) connect(sphere_radius, QOverload::of(&QDoubleSpinBox::valueChanged), this, &SettingsPane::sphereRadiusChanged); + connect(speed_limit, QOverload::of(&QDoubleSpinBox::valueChanged), + this, &SettingsPane::speedLimitChanged); connect(show_trajectories, &QCheckBox::stateChanged, this, &SettingsPane::toggledTrajectories); connect(show_guides, &QCheckBox::stateChanged, @@ -32,6 +36,7 @@ SettingsPane::SettingsPane(QWidget *parent) QFormLayout *layout = new QFormLayout; layout->addRow("Taille de la sphère de collision", sphere_radius); + layout->addRow("Limite de vitesse", speed_limit); layout->addRow("Afficher les trajectoires", show_trajectories); layout->addRow("Afficher les guides", show_guides); @@ -52,7 +57,7 @@ void SettingsPane::addCollision(int idA, int idB, int frame) { } -void SettingsPane::addSpeedingViolation(int id, int frame, double speed) { +void SettingsPane::addSpeedingViolation(int id, double speed, int frame) { BookmarkItem *item = new BookmarkItem("Frame " + QString::number(frame) + ": #" + QString::number(id) + " (" + QString::number(speed) + ")", frame); diff --git a/src/settings_pane.hh b/src/settings_pane.hh index 8b2e04c..8b92690 100644 --- a/src/settings_pane.hh +++ b/src/settings_pane.hh @@ -28,7 +28,7 @@ public: public slots: void addCollision(int idA, int idB, int frame); - void addSpeedingViolation(int id, int frame, double speed); + void addSpeedingViolation(int id, double speed, int frame); void clearCollisions(); void clearSpeedingViolations(); diff --git a/src/waypoint.hh b/src/waypoint.hh index 4b455fd..f304ead 100644 --- a/src/waypoint.hh +++ b/src/waypoint.hh @@ -8,6 +8,7 @@ struct Waypoint { int frame; QVector3D pos; + double computed_speed = 0; Waypoint(unsigned frame, QVector3D pos); Waypoint(const QJsonObject &json);