aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--projet.pro16
-rw-r--r--src/boid.cc108
-rw-r--r--src/drone_controller.cc102
-rw-r--r--src/drone_controller.hh57
-rw-r--r--src/main.cc11
-rw-r--r--src/main_window.cc73
-rw-r--r--src/main_window.hh36
-rw-r--r--src/opengl_mesh.cc19
-rw-r--r--src/opengl_mesh.hh18
-rw-r--r--src/opengl_widget.cc143
-rw-r--r--src/opengl_widget.hh35
-rw-r--r--waypoints.json1
12 files changed, 619 insertions, 0 deletions
diff --git a/projet.pro b/projet.pro
new file mode 100644
index 0000000..5882ee4
--- /dev/null
+++ b/projet.pro
@@ -0,0 +1,16 @@
+QT += core gui widgets
+TARGET = projet
+TEMPLATE = app
+DEFINES += QT_DEPRECATED_WARNINGS
+CONFIG += qt debug
+
+SOURCES += src/main.cc
+SOURCES += src/main_window.cc
+SOURCES += src/opengl_mesh.cc
+SOURCES += src/opengl_widget.cc
+SOURCES += src/drone_controller.cc
+
+HEADERS += src/main_window.hh
+HEADERS += src/opengl_mesh.hh
+HEADERS += src/opengl_widget.hh
+HEADERS += src/drone_controller.hh
diff --git a/src/boid.cc b/src/boid.cc
new file mode 100644
index 0000000..9eeea41
--- /dev/null
+++ b/src/boid.cc
@@ -0,0 +1,108 @@
+#include "main_window.hh"
+
+#include <QVector3D>
+#include <QRandomGenerator>
+
+
+struct Fish {
+ QVector3D pos;
+ QVector3D vel;
+ float size;
+ float dist = 10;
+ float sqdist;
+
+ OpenGLMesh mesh;
+
+ Fish(QVector3D pos, OpenGLMesh mesh)
+ :pos(pos),
+ sqdist(dist * dist),
+ mesh(mesh) {}
+
+ void step() {
+ pos += vel;
+ mesh.mat.setToIdentity();
+ QMatrix4x4 rot;
+ rot.lookAt(pos, vel, {0, 1, 0});
+ mesh.mat.translate(pos);
+ // mesh.mat = rot * mesh.mat;
+ }
+
+ bool in_neighborhood(const QVector3D &p) const {
+ return (p - pos).lengthSquared() < sqdist;
+ }
+};
+
+
+struct Banc {
+ QVector<Fish> fishes;
+
+ Banc() {}
+
+ Banc(size_t nfishes) {
+ OpenGLMesh fish_mesh = OpenGLMesh({
+ 0, .1, 0,
+ -.0866, -.05, 0,
+ .0866, -.05, 0,
+ });
+ QRandomGenerator *rng = QRandomGenerator::global();
+ for (size_t i = 0; i < nfishes; i++) {
+ Fish fish({
+ (float) (rng->generateDouble() * 3 - 1.5),
+ (float) (rng->generateDouble() * 3 - 1.5),
+ (float) (rng->generateDouble() * 3 - 1.5)
+ }, fish_mesh);
+ fishes.append(fish);
+ }
+ }
+
+ void step() {
+ QVector<Fish> neighbors;
+ for (Fish &fish : fishes) {
+ QVector3D neighbors_cog;
+ QVector3D neighbors_vel;
+ size_t nneighbors = 0;
+ for (Fish &fish_b : fishes) {
+ if (fish_b.in_neighborhood(fish.pos)) {
+ nneighbors++;
+ neighbors_cog += fish_b.pos;
+ neighbors_vel += fish_b.vel;
+ }
+ }
+ neighbors_cog /= nneighbors;
+ neighbors_vel /= nneighbors;
+ QVector3D v1 = -(fish.pos - neighbors_cog);
+ QVector3D v2 = fish.vel - neighbors_vel;
+ QVector3D v3 = neighbors_cog - fish.pos;
+ QVector3D v = 1.5 * v1 + v2 + v3;
+ float L = .001;
+ fish.vel = (1-L) * fish.vel + L * v;
+ fish.step();
+ }
+ }
+};
+
+
+Banc banc;
+
+void MainWindow::init() {
+ banc = Banc(10);
+ for (Fish &fish : banc.fishes) {
+ glw.meshes.append(&fish.mesh);
+ }
+}
+
+
+void MainWindow::step() {
+ banc.step();
+ OpenGLWidget::instance->update();
+}
+
+
+void OpenGLWidget::paintGL() {
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ for (const Fish &fish : banc.fishes) {
+ glUniformMatrix4fv(model_attr, 1, GL_FALSE, fish.mesh.mat.data());
+ glBindVertexArray(fish.mesh.vao);
+ glDrawArrays(GL_TRIANGLES, 0, fish.mesh.nverts);
+ }
+}
diff --git a/src/drone_controller.cc b/src/drone_controller.cc
new file mode 100644
index 0000000..46acc7e
--- /dev/null
+++ b/src/drone_controller.cc
@@ -0,0 +1,102 @@
+#include "drone_controller.hh"
+
+#include <QJsonArray>
+#include <QDebug>
+
+
+Waypoint::Waypoint(unsigned frame, QVector3D pos)
+ :frame(frame),
+ pos(pos) {}
+
+
+Waypoint::Waypoint(const QJsonObject &json)
+ :Waypoint(json["frame"].toInt(),
+ QVector3D(json["position"]["lng_X"].toInt(),
+ json["position"]["alt_Y"].toInt(),
+ json["position"]["lat_Z"].toInt())) {}
+
+
+Drone::Drone(const QJsonObject &json) {
+ QJsonArray ja = json["waypoints"].toArray();
+ waypoints.reserve(ja.size());
+ for (const QJsonValue &o : ja) {
+ waypoints.append(Waypoint(o.toObject()));
+ }
+}
+
+
+const QVector<Waypoint> Drone::getWaypoints() const {
+ return waypoints;
+}
+
+
+DroneController::DroneController(const QJsonObject &json)
+ :framerate(json["framerate"].toInt()) {
+
+ // TODO: REMOVE!!
+ framerate = 1;
+
+ QJsonArray ja = json["drones"].toArray();
+ drones.reserve(ja.size());
+ for (const QJsonValue &o : ja) {
+ drones.append(Drone(o.toObject()));
+ }
+ for (const Drone &d : drones) {
+ for (const Waypoint &wp : d.getWaypoints()) {
+ if (wp.frame > duration) duration = wp.frame;
+ }
+ }
+
+ connect(&timer, &QTimer::timeout, this, &DroneController::step);
+ pause();
+}
+
+
+DroneController::~DroneController() {
+}
+
+
+int DroneController::getDuration() const {
+ return duration;
+}
+
+
+void DroneController::step() {
+ qDebug() << "frame " << frame << "/" << duration
+ << " (" << (double) frame / duration * 100 << "%)";
+ emit frameChanged(frame);
+ frame++;
+}
+
+
+void DroneController::play() {
+ paused = false;
+ timer.start(1000. / framerate);
+ qDebug() << "playing";
+}
+
+
+void DroneController::pause() {
+ paused = true;
+ timer.stop();
+ qDebug() << "pausing";
+}
+
+
+void DroneController::suspend() {
+ bool old_paused = paused;
+ pause();
+ paused = old_paused;
+}
+
+
+void DroneController::resume() {
+ if (!paused) play();
+}
+
+
+void DroneController::seek(int frame) {
+ if (this->frame == frame) return;
+ this->frame = frame;
+ step();
+}
diff --git a/src/drone_controller.hh b/src/drone_controller.hh
new file mode 100644
index 0000000..484cd57
--- /dev/null
+++ b/src/drone_controller.hh
@@ -0,0 +1,57 @@
+#ifndef DRONE_CONTROLLER_HH
+#define DRONE_CONTROLLER_HH
+
+#include <QJsonObject>
+#include <QVector3D>
+#include <QTimer>
+
+
+struct Waypoint {
+ int frame;
+ QVector3D pos;
+
+ Waypoint(unsigned frame, QVector3D pos);
+ Waypoint(const QJsonObject &json);
+};
+
+
+class Drone {
+ QVector<Waypoint> waypoints;
+
+public:
+ Drone(const QJsonObject &json);
+ const QVector<Waypoint> getWaypoints() const;
+};
+
+
+class DroneController : public QObject {
+ Q_OBJECT
+
+ int framerate;
+ int frame = 0;
+ int duration = 0;
+ QVector<Drone> drones;
+ QTimer timer;
+ bool paused = true;
+
+public:
+ DroneController(const QJsonObject &json);
+ ~DroneController();
+ int getDuration() const;
+
+signals:
+ void frameChanged(int frame);
+
+private slots:
+ void step();
+
+public slots:
+ void play();
+ void pause();
+ void suspend();
+ void resume();
+ void seek(int frame);
+};
+
+
+#endif
diff --git a/src/main.cc b/src/main.cc
new file mode 100644
index 0000000..c70cfaa
--- /dev/null
+++ b/src/main.cc
@@ -0,0 +1,11 @@
+#include "main_window.hh"
+
+#include <QApplication>
+
+
+int main(int argc, char *argv[]) {
+ QApplication app(argc, argv);
+ MainWindow mw;
+ mw.show();
+ return app.exec();
+}
diff --git a/src/main_window.cc b/src/main_window.cc
new file mode 100644
index 0000000..5e58660
--- /dev/null
+++ b/src/main_window.cc
@@ -0,0 +1,73 @@
+#include "main_window.hh"
+
+#include <QApplication>
+#include <QFile>
+#include <QFileDialog>
+#include <QJsonDocument>
+#include <QStyle>
+
+
+MainWindow::MainWindow(QWidget *parent) {
+ (void) parent;
+ connect(&glw, &OpenGLWidget::initialized,
+ this, &MainWindow::onOpenGLWidgetInitialized);
+ // connect(&timer, &QTimer::timeout, this, &MainWindow::step);
+ setCentralWidget(&glw);
+ addToolBar(Qt::TopToolBarArea, &top_tb);
+ open_action = top_tb.addAction("Ouvrir…", [&]() {
+ open(QFileDialog::getOpenFileName(this, "Ouvrir un fichier JSON"));
+ });
+ open_action->setEnabled(false);
+ addToolBar(Qt::BottomToolBarArea, &bottom_tb);
+ playpause_action = bottom_tb.addAction(style()->standardIcon(QStyle::SP_MediaPlay), "",
+ this, &MainWindow::play);
+ playpause_action->setEnabled(false);
+ slider = new QSlider(Qt::Horizontal);
+ bottom_tb.addWidget(slider);
+ slider->setEnabled(false);
+}
+
+
+void MainWindow::play() {
+ dc->play();
+ playpause_action->setIcon(style()->standardIcon(QStyle::SP_MediaPause));
+ disconnect(playpause_action, &QAction::triggered, nullptr, nullptr);
+ connect(playpause_action, &QAction::triggered, this, &MainWindow::pause);
+}
+
+
+void MainWindow::pause() {
+ dc->pause();
+ playpause_action->setIcon(style()->standardIcon(QStyle::SP_MediaPlay));
+ disconnect(playpause_action, &QAction::triggered, nullptr, nullptr);
+ connect(playpause_action, &QAction::triggered, this, &MainWindow::play);
+}
+
+
+void MainWindow::open(const QString &path) {
+ QFile file(path);
+ if (!file.open(QIODevice::ReadOnly)) {
+ qWarning("Impossible d’ouvrir le fichier.");
+ return;
+ }
+ QByteArray data = file.readAll();
+ QJsonDocument json_doc = QJsonDocument::fromJson(data);
+ if (dc) delete dc;
+ dc = new DroneController(json_doc.object());
+ playpause_action->setEnabled(true);
+ slider->setMinimum(0);
+ slider->setMaximum(dc->getDuration());
+ connect(slider, &QSlider::sliderPressed, dc, &DroneController::suspend);
+ connect(slider, &QSlider::sliderReleased, dc, &DroneController::resume);
+ connect(slider, &QSlider::valueChanged, dc, &DroneController::seek);
+ connect(dc, &DroneController::frameChanged, slider, &QSlider::setValue);
+ slider->setEnabled(true);
+}
+
+
+void MainWindow::onOpenGLWidgetInitialized() {
+ if (qApp->arguments().size() == 2) {
+ open(qApp->arguments().at(1));
+ }
+ open_action->setEnabled(true);
+}
diff --git a/src/main_window.hh b/src/main_window.hh
new file mode 100644
index 0000000..1e8868a
--- /dev/null
+++ b/src/main_window.hh
@@ -0,0 +1,36 @@
+#ifndef MAIN_WINDOW_HH
+#define MAIN_WINDOW_HH
+
+#include "opengl_widget.hh"
+#include "drone_controller.hh"
+
+#include <QMainWindow>
+#include <QTimer>
+#include <QToolBar>
+#include <QSlider>
+
+
+class MainWindow : public QMainWindow {
+ Q_OBJECT
+
+ OpenGLWidget glw;
+ QTimer timer;
+ QToolBar top_tb;
+ QToolBar bottom_tb;
+ QAction *open_action;
+ QAction *playpause_action;
+ QSlider *slider;
+ DroneController *dc = nullptr;
+ void play();
+ void pause();
+
+public:
+ MainWindow(QWidget *parent=nullptr);
+ void open(const QString &path);
+
+private slots:
+ void onOpenGLWidgetInitialized();
+};
+
+
+#endif
diff --git a/src/opengl_mesh.cc b/src/opengl_mesh.cc
new file mode 100644
index 0000000..cca91da
--- /dev/null
+++ b/src/opengl_mesh.cc
@@ -0,0 +1,19 @@
+#include "opengl_mesh.hh"
+
+#include "opengl_widget.hh"
+
+
+OpenGLMesh::OpenGLMesh(QVector<float> verts) {
+ OpenGLWidget::instance->makeCurrent();
+ QOpenGLFunctions_4_4_Core *glf = OpenGLWidget::instance;
+ nverts = verts.size() / 3;
+ glf->glGenVertexArrays(1, &vao);
+ glf->glGenBuffers(1, &vbo);
+ glf->glBindVertexArray(vao);
+ glf->glBindBuffer(GL_ARRAY_BUFFER, vbo);
+ glf->glBufferData(GL_ARRAY_BUFFER, nverts * 3 * sizeof (GLfloat), verts.data(), GL_STATIC_DRAW);
+ glf->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
+ glf->glEnableVertexAttribArray(0);
+ glf->glBindVertexArray(0);
+ OpenGLWidget::instance->doneCurrent();
+}
diff --git a/src/opengl_mesh.hh b/src/opengl_mesh.hh
new file mode 100644
index 0000000..e3b8ad2
--- /dev/null
+++ b/src/opengl_mesh.hh
@@ -0,0 +1,18 @@
+#ifndef MESH_HH
+#define MESH_HH
+
+#include <QMatrix4x4>
+#include <QVector>
+#include <QOpenGLFunctions>
+
+
+struct OpenGLMesh {
+ GLuint vao, vbo;
+ unsigned nverts;
+ QMatrix4x4 mat;
+
+ OpenGLMesh(QVector<float> verts);
+};
+
+
+#endif
diff --git a/src/opengl_widget.cc b/src/opengl_widget.cc
new file mode 100644
index 0000000..0251491
--- /dev/null
+++ b/src/opengl_widget.cc
@@ -0,0 +1,143 @@
+#include "opengl_widget.hh"
+
+
+static const GLchar *vertex_shader_source = R"glsl(
+#version 330 core
+
+layout(location = 0) in vec3 pos;
+
+uniform mat4 proj;
+uniform mat4 view;
+uniform mat4 model;
+
+void main() {
+ gl_Position = proj * view * model * vec4(pos, 1.0);
+}
+)glsl";
+
+static const GLchar *fragment_shader_source = R"glsl(
+#version 330 core
+
+out vec4 final_col;
+
+void main() {
+ final_col = vec4(0, 0, 0, 1);
+}
+)glsl";
+
+
+static void GLAPIENTRY opengl_debug_cb(GLenum source, GLenum type, GLuint id,
+ GLenum severity, GLsizei length,
+ const GLchar* message,
+ const void* userParam) {
+ (void) source; (void) type; (void) id; (void) severity; (void) length;
+ (void) userParam;
+ qDebug() << "OpenGL debug output:" << message;
+}
+
+
+OpenGLWidget *OpenGLWidget::instance = nullptr;
+
+
+OpenGLWidget::OpenGLWidget(QWidget *parent)
+ :QOpenGLWidget(parent) {
+ OpenGLWidget::instance = this;
+}
+
+
+OpenGLWidget::~OpenGLWidget() {
+ OpenGLWidget::instance = nullptr;
+}
+
+
+void OpenGLWidget::initializeGL() {
+ initializeOpenGLFunctions();
+ GLint major, minor;
+ glGetIntegerv(GL_MAJOR_VERSION, &major);
+ glGetIntegerv(GL_MINOR_VERSION, &minor);
+ qDebug("OpenGL version %d.%d", major, minor);
+
+ glEnable(GL_DEBUG_OUTPUT);
+ glDebugMessageCallback(opengl_debug_cb, 0);
+
+ /* Compile the vertex shader. */
+ GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER);
+ glShaderSource(vertex_shader, 1, &vertex_shader_source, NULL);
+ glCompileShader(vertex_shader);
+ GLint status;
+ glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &status);
+ if (status != GL_TRUE) {
+ char log[1024];
+ glGetShaderInfoLog(vertex_shader, sizeof log, NULL, log);
+ fprintf(stderr, "Failed to compile the vertex shader: %s\n", log);
+ exit(1);
+ }
+
+ /* Compile the fragment shader. */
+ GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
+ glShaderSource(fragment_shader, 1, &fragment_shader_source, NULL);
+ glCompileShader(fragment_shader);
+ glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &status);
+ if (status != GL_TRUE) {
+ char log[1024];
+ glGetShaderInfoLog(fragment_shader, sizeof log, NULL, log);
+ fprintf(stderr, "Failed to compile the fragment shader: %s\n", log);
+ exit(1);
+ }
+
+ /* Link the shader program. */
+ GLuint shader_program = glCreateProgram();
+ glAttachShader(shader_program, vertex_shader);
+ glAttachShader(shader_program, fragment_shader);
+ glBindFragDataLocation(shader_program, 0, "out_color");
+ glLinkProgram(shader_program);
+ glGetProgramiv(shader_program, GL_LINK_STATUS, &status);
+ if (status != GL_TRUE) {
+ char log[1024];
+ glGetProgramInfoLog(shader_program, sizeof log, NULL, log);
+ fprintf(stderr, "Failed to link the shader program: %s\n", log);
+ exit(1);
+ }
+
+ /* Use it. */
+ glUseProgram(shader_program);
+
+ /* Get the position attribute. */
+ pos_attr = glGetAttribLocation(shader_program, "pos");
+
+ proj_attr = glGetUniformLocation(shader_program, "proj");
+ view_attr = glGetUniformLocation(shader_program, "view");
+ model_attr = glGetUniformLocation(shader_program, "model");
+
+ QMatrix4x4 view;
+ view.translate(0, 0, 5);
+ glUniformMatrix4fv(view_attr, 1, GL_FALSE, view.data());
+
+ QMatrix4x4 trans;
+ trans.translate(0, 0, -5);
+ glUniformMatrix4fv(view_attr, 1, GL_FALSE, trans.data());
+
+ glClearColor(1, 1, 1, 0);
+
+ glEnable(GL_DEPTH_TEST);
+ glEnable(GL_MULTISAMPLE);
+
+ emit initialized();
+}
+
+
+void OpenGLWidget::resizeGL(int w, int h) {
+ QMatrix4x4 projection;
+ projection.perspective(FOV, (float) w/h, .1, 100);
+ glUniformMatrix4fv(proj_attr, 1, GL_FALSE, projection.data());
+}
+
+
+void OpenGLWidget::paintGL() {
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ for (const OpenGLMesh &mesh : meshes) {
+ glUniformMatrix4fv(model_attr, 1, GL_FALSE, mesh.mat.data());
+ glBindVertexArray(mesh.vao);
+ glDrawArrays(GL_TRIANGLES, 0, mesh.nverts);
+ }
+}
diff --git a/src/opengl_widget.hh b/src/opengl_widget.hh
new file mode 100644
index 0000000..48cb276
--- /dev/null
+++ b/src/opengl_widget.hh
@@ -0,0 +1,35 @@
+#ifndef OPENGL_WIDGET_HH
+#define OPENGL_WIDGET_HH
+
+#include "opengl_mesh.hh"
+
+#include <QOpenGLWidget>
+#include <QMatrix4x4>
+#include <QOpenGLFunctions_4_4_Core>
+#include <QOpenGLShaderProgram>
+
+#define FOV 70
+
+
+class OpenGLWidget : public QOpenGLWidget, public QOpenGLFunctions_4_4_Core {
+ Q_OBJECT
+
+ GLuint pos_attr, proj_attr, view_attr, model_attr;
+
+public:
+ static OpenGLWidget *instance;
+
+ QVector<OpenGLMesh> meshes;
+
+ OpenGLWidget(QWidget *parent=nullptr);
+ ~OpenGLWidget();
+ void initializeGL() override;
+ void resizeGL(int w, int h) override;
+ void paintGL() override;
+
+signals:
+ void initialized();
+};
+
+
+#endif
diff --git a/waypoints.json b/waypoints.json
new file mode 100644
index 0000000..f195375
--- /dev/null
+++ b/waypoints.json
@@ -0,0 +1 @@
+{"description": "DRONES_TESTS_COLLISION_X_31_VOL_v1.c4d", "drones": [{"id": 20, "waypoints": [{"frame": 0, "id": 1, "order": 1, "position": {"alt_Y": 500, "lat_Z": -646, "lng_X": -2918}}, {"frame": 30, "id": 2, "order": 2, "position": {"alt_Y": 589, "lat_Z": -646, "lng_X": -2918}}, {"frame": 60, "id": 3, "order": 3, "position": {"alt_Y": 785, "lat_Z": -646, "lng_X": -2918}}, {"frame": 90, "id": 4, "order": 4, "position": {"alt_Y": 959, "lat_Z": -646, "lng_X": -2918}}, {"frame": 120, "id": 5, "order": 5, "position": {"alt_Y": 1000, "lat_Z": -675, "lng_X": -2918}}, {"frame": 150, "id": 6, "order": 6, "position": {"alt_Y": 1000, "lat_Z": -969, "lng_X": -2918}}, {"frame": 180, "id": 7, "order": 7, "position": {"alt_Y": 1000, "lat_Z": -1374, "lng_X": -2918}}, {"frame": 210, "id": 8, "order": 8, "position": {"alt_Y": 1000, "lat_Z": -1634, "lng_X": -2918}}, {"frame": 240, "id": 9, "order": 9, "position": {"alt_Y": 1000, "lat_Z": -1539, "lng_X": -2918}}, {"frame": 270, "id": 10, "order": 10, "position": {"alt_Y": 1000, "lat_Z": -1208, "lng_X": -2918}}, {"frame": 300, "id": 11, "order": 11, "position": {"alt_Y": 1000, "lat_Z": -829, "lng_X": -2918}}, {"frame": 330, "id": 12, "order": 12, "position": {"alt_Y": 1000, "lat_Z": -646, "lng_X": -2918}}, {"frame": 360, "id": 13, "order": 13, "position": {"alt_Y": 1000, "lat_Z": -646, "lng_X": -2918}}, {"frame": 390, "id": 14, "order": 14, "position": {"alt_Y": 995, "lat_Z": -646, "lng_X": -2918}}, {"frame": 420, "id": 15, "order": 15, "position": {"alt_Y": 848, "lat_Z": -646, "lng_X": -2918}}, {"frame": 450, "id": 16, "order": 16, "position": {"alt_Y": 657, "lat_Z": -646, "lng_X": -2918}}, {"frame": 480, "id": 17, "order": 17, "position": {"alt_Y": 519, "lat_Z": -646, "lng_X": -2918}}]}, {"id": 19, "waypoints": [{"frame": 0, "id": 1, "order": 1, "position": {"alt_Y": 500, "lat_Z": -578, "lng_X": -2610}}, {"frame": 30, "id": 2, "order": 2, "position": {"alt_Y": 589, "lat_Z": -578, "lng_X": -2610}}, {"frame": 60, "id": 3, "order": 3, "position": {"alt_Y": 785, "lat_Z": -578, "lng_X": -2610}}, {"frame": 90, "id": 4, "order": 4, "position": {"alt_Y": 959, "lat_Z": -578, "lng_X": -2610}}, {"frame": 120, "id": 5, "order": 5, "position": {"alt_Y": 1000, "lat_Z": -607, "lng_X": -2610}}, {"frame": 150, "id": 6, "order": 6, "position": {"alt_Y": 1000, "lat_Z": -901, "lng_X": -2610}}, {"frame": 180, "id": 7, "order": 7, "position": {"alt_Y": 1000, "lat_Z": -1306, "lng_X": -2610}}, {"frame": 210, "id": 8, "order": 8, "position": {"alt_Y": 1000, "lat_Z": -1566, "lng_X": -2610}}, {"frame": 240, "id": 9, "order": 9, "position": {"alt_Y": 1000, "lat_Z": -1471, "lng_X": -2610}}, {"frame": 270, "id": 10, "order": 10, "position": {"alt_Y": 1000, "lat_Z": -1140, "lng_X": -2610}}, {"frame": 300, "id": 11, "order": 11, "position": {"alt_Y": 1000, "lat_Z": -760, "lng_X": -2610}}, {"frame": 330, "id": 12, "order": 12, "position": {"alt_Y": 1000, "lat_Z": -578, "lng_X": -2610}}, {"frame": 360, "id": 13, "order": 13, "position": {"alt_Y": 1000, "lat_Z": -578, "lng_X": -2610}}, {"frame": 390, "id": 14, "order": 14, "position": {"alt_Y": 995, "lat_Z": -578, "lng_X": -2610}}, {"frame": 420, "id": 15, "order": 15, "position": {"alt_Y": 848, "lat_Z": -578, "lng_X": -2610}}, {"frame": 450, "id": 16, "order": 16, "position": {"alt_Y": 657, "lat_Z": -578, "lng_X": -2610}}, {"frame": 480, "id": 17, "order": 17, "position": {"alt_Y": 519, "lat_Z": -578, "lng_X": -2610}}]}, {"id": 18, "waypoints": [{"frame": 0, "id": 1, "order": 1, "position": {"alt_Y": 500, "lat_Z": -510, "lng_X": -2303}}, {"frame": 30, "id": 2, "order": 2, "position": {"alt_Y": 589, "lat_Z": -510, "lng_X": -2303}}, {"frame": 60, "id": 3, "order": 3, "position": {"alt_Y": 785, "lat_Z": -510, "lng_X": -2303}}, {"frame": 90, "id": 4, "order": 4, "position": {"alt_Y": 959, "lat_Z": -510, "lng_X": -2303}}, {"frame": 120, "id": 5, "order": 5, "position": {"alt_Y": 1000, "lat_Z": -539, "lng_X": -2303}}, {"frame": 150, "id": 6, "order": 6, "position": {"alt_Y": 1000, "lat_Z": -833, "lng_X": -2303}}, {"frame": 180, "id": 7, "order": 7, "position": {"alt_Y": 1000, "lat_Z": -1238, "lng_X": -2303}}, {"frame": 210, "id": 8, "order": 8, "position": {"alt_Y": 1000, "lat_Z": -1498, "lng_X": -2303}}, {"frame": 240, "id": 9, "order": 9, "position": {"alt_Y": 1000, "lat_Z": -1402, "lng_X": -2303}}, {"frame": 270, "id": 10, "order": 10, "position": {"alt_Y": 1000, "lat_Z": -1072, "lng_X": -2303}}, {"frame": 300, "id": 11, "order": 11, "position": {"alt_Y": 1000, "lat_Z": -692, "lng_X": -2303}}, {"frame": 330, "id": 12, "order": 12, "position": {"alt_Y": 1000, "lat_Z": -510, "lng_X": -2303}}, {"frame": 360, "id": 13, "order": 13, "position": {"alt_Y": 1000, "lat_Z": -510, "lng_X": -2303}}, {"frame": 390, "id": 14, "order": 14, "position": {"alt_Y": 995, "lat_Z": -510, "lng_X": -2303}}, {"frame": 420, "id": 15, "order": 15, "position": {"alt_Y": 848, "lat_Z": -510, "lng_X": -2303}}, {"frame": 450, "id": 16, "order": 16, "position": {"alt_Y": 657, "lat_Z": -510, "lng_X": -2303}}, {"frame": 480, "id": 17, "order": 17, "position": {"alt_Y": 519, "lat_Z": -510, "lng_X": -2303}}]}, {"id": 17, "waypoints": [{"frame": 0, "id": 1, "order": 1, "position": {"alt_Y": 500, "lat_Z": -442, "lng_X": -1995}}, {"frame": 30, "id": 2, "order": 2, "position": {"alt_Y": 589, "lat_Z": -442, "lng_X": -1995}}, {"frame": 60, "id": 3, "order": 3, "position": {"alt_Y": 785, "lat_Z": -442, "lng_X": -1995}}, {"frame": 90, "id": 4, "order": 4, "position": {"alt_Y": 959, "lat_Z": -442, "lng_X": -1995}}, {"frame": 120, "id": 5, "order": 5, "position": {"alt_Y": 1000, "lat_Z": -471, "lng_X": -1995}}, {"frame": 150, "id": 6, "order": 6, "position": {"alt_Y": 1000, "lat_Z": -765, "lng_X": -1995}}, {"frame": 180, "id": 7, "order": 7, "position": {"alt_Y": 1000, "lat_Z": -1170, "lng_X": -1995}}, {"frame": 210, "id": 8, "order": 8, "position": {"alt_Y": 1000, "lat_Z": -1430, "lng_X": -1995}}, {"frame": 240, "id": 9, "order": 9, "position": {"alt_Y": 1000, "lat_Z": -1334, "lng_X": -1995}}, {"frame": 270, "id": 10, "order": 10, "position": {"alt_Y": 1000, "lat_Z": -1004, "lng_X": -1995}}, {"frame": 300, "id": 11, "order": 11, "position": {"alt_Y": 1000, "lat_Z": -624, "lng_X": -1995}}, {"frame": 330, "id": 12, "order": 12, "position": {"alt_Y": 1000, "lat_Z": -442, "lng_X": -1995}}, {"frame": 360, "id": 13, "order": 13, "position": {"alt_Y": 1000, "lat_Z": -442, "lng_X": -1995}}, {"frame": 390, "id": 14, "order": 14, "position": {"alt_Y": 995, "lat_Z": -442, "lng_X": -1995}}, {"frame": 420, "id": 15, "order": 15, "position": {"alt_Y": 848, "lat_Z": -442, "lng_X": -1995}}, {"frame": 450, "id": 16, "order": 16, "position": {"alt_Y": 657, "lat_Z": -442, "lng_X": -1995}}, {"frame": 480, "id": 17, "order": 17, "position": {"alt_Y": 519, "lat_Z": -442, "lng_X": -1995}}]}, {"id": 16, "waypoints": [{"frame": 0, "id": 1, "order": 1, "position": {"alt_Y": 500, "lat_Z": -374, "lng_X": -1688}}, {"frame": 30, "id": 2, "order": 2, "position": {"alt_Y": 589, "lat_Z": -374, "lng_X": -1688}}, {"frame": 60, "id": 3, "order": 3, "position": {"alt_Y": 785, "lat_Z": -374, "lng_X": -1688}}, {"frame": 90, "id": 4, "order": 4, "position": {"alt_Y": 959, "lat_Z": -374, "lng_X": -1688}}, {"frame": 120, "id": 5, "order": 5, "position": {"alt_Y": 1000, "lat_Z": -403, "lng_X": -1688}}, {"frame": 150, "id": 6, "order": 6, "position": {"alt_Y": 1000, "lat_Z": -697, "lng_X": -1688}}, {"frame": 180, "id": 7, "order": 7, "position": {"alt_Y": 1000, "lat_Z": -1102, "lng_X": -1688}}, {"frame": 210, "id": 8, "order": 8, "position": {"alt_Y": 1000, "lat_Z": -1362, "lng_X": -1688}}, {"frame": 240, "id": 9, "order": 9, "position": {"alt_Y": 1000, "lat_Z": -1266, "lng_X": -1688}}, {"frame": 270, "id": 10, "order": 10, "position": {"alt_Y": 1000, "lat_Z": -936, "lng_X": -1688}}, {"frame": 300, "id": 11, "order": 11, "position": {"alt_Y": 1000, "lat_Z": -556, "lng_X": -1688}}, {"frame": 330, "id": 12, "order": 12, "position": {"alt_Y": 1000, "lat_Z": -374, "lng_X": -1688}}, {"frame": 360, "id": 13, "order": 13, "position": {"alt_Y": 1000, "lat_Z": -374, "lng_X": -1688}}, {"frame": 390, "id": 14, "order": 14, "position": {"alt_Y": 995, "lat_Z": -374, "lng_X": -1688}}, {"frame": 420, "id": 15, "order": 15, "position": {"alt_Y": 848, "lat_Z": -374, "lng_X": -1688}}, {"frame": 450, "id": 16, "order": 16, "position": {"alt_Y": 657, "lat_Z": -374, "lng_X": -1688}}, {"frame": 480, "id": 17, "order": 17, "position": {"alt_Y": 519, "lat_Z": -374, "lng_X": -1688}}]}, {"id": 15, "waypoints": [{"frame": 0, "id": 1, "order": 1, "position": {"alt_Y": 500, "lat_Z": -306, "lng_X": -1380}}, {"frame": 30, "id": 2, "order": 2, "position": {"alt_Y": 589, "lat_Z": -306, "lng_X": -1380}}, {"frame": 60, "id": 3, "order": 3, "position": {"alt_Y": 785, "lat_Z": -306, "lng_X": -1380}}, {"frame": 90, "id": 4, "order": 4, "position": {"alt_Y": 959, "lat_Z": -306, "lng_X": -1380}}, {"frame": 120, "id": 5, "order": 5, "position": {"alt_Y": 1000, "lat_Z": -335, "lng_X": -1380}}, {"frame": 150, "id": 6, "order": 6, "position": {"alt_Y": 1000, "lat_Z": -628, "lng_X": -1380}}, {"frame": 180, "id": 7, "order": 7, "position": {"alt_Y": 1000, "lat_Z": -1034, "lng_X": -1380}}, {"frame": 210, "id": 8, "order": 8, "position": {"alt_Y": 1000, "lat_Z": -1293, "lng_X": -1380}}, {"frame": 240, "id": 9, "order": 9, "position": {"alt_Y": 1000, "lat_Z": -1198, "lng_X": -1380}}, {"frame": 270, "id": 10, "order": 10, "position": {"alt_Y": 1000, "lat_Z": -868, "lng_X": -1380}}, {"frame": 300, "id": 11, "order": 11, "position": {"alt_Y": 1000, "lat_Z": -488, "lng_X": -1380}}, {"frame": 330, "id": 12, "order": 12, "position": {"alt_Y": 1000, "lat_Z": -306, "lng_X": -1380}}, {"frame": 360, "id": 13, "order": 13, "position": {"alt_Y": 1000, "lat_Z": -306, "lng_X": -1380}}, {"frame": 390, "id": 14, "order": 14, "position": {"alt_Y": 995, "lat_Z": -306, "lng_X": -1380}}, {"frame": 420, "id": 15, "order": 15, "position": {"alt_Y": 848, "lat_Z": -306, "lng_X": -1380}}, {"frame": 450, "id": 16, "order": 16, "position": {"alt_Y": 657, "lat_Z": -306, "lng_X": -1380}}, {"frame": 480, "id": 17, "order": 17, "position": {"alt_Y": 519, "lat_Z": -306, "lng_X": -1380}}]}, {"id": 14, "waypoints": [{"frame": 0, "id": 1, "order": 1, "position": {"alt_Y": 500, "lat_Z": -237, "lng_X": -1072}}, {"frame": 30, "id": 2, "order": 2, "position": {"alt_Y": 589, "lat_Z": -237, "lng_X": -1072}}, {"frame": 60, "id": 3, "order": 3, "position": {"alt_Y": 785, "lat_Z": -237, "lng_X": -1072}}, {"frame": 90, "id": 4, "order": 4, "position": {"alt_Y": 959, "lat_Z": -237, "lng_X": -1072}}, {"frame": 120, "id": 5, "order": 5, "position": {"alt_Y": 1000, "lat_Z": -266, "lng_X": -1072}}, {"frame": 150, "id": 6, "order": 6, "position": {"alt_Y": 1000, "lat_Z": -560, "lng_X": -1072}}, {"frame": 180, "id": 7, "order": 7, "position": {"alt_Y": 1000, "lat_Z": -966, "lng_X": -1072}}, {"frame": 210, "id": 8, "order": 8, "position": {"alt_Y": 1000, "lat_Z": -1225, "lng_X": -1072}}, {"frame": 240, "id": 9, "order": 9, "position": {"alt_Y": 1000, "lat_Z": -1130, "lng_X": -1072}}, {"frame": 270, "id": 10, "order": 10, "position": {"alt_Y": 1000, "lat_Z": -800, "lng_X": -1072}}, {"frame": 300, "id": 11, "order": 11, "position": {"alt_Y": 1000, "lat_Z": -420, "lng_X": -1072}}, {"frame": 330, "id": 12, "order": 12, "position": {"alt_Y": 1000, "lat_Z": -237, "lng_X": -1072}}, {"frame": 360, "id": 13, "order": 13, "position": {"alt_Y": 1000, "lat_Z": -237, "lng_X": -1072}}, {"frame": 390, "id": 14, "order": 14, "position": {"alt_Y": 995, "lat_Z": -237, "lng_X": -1072}}, {"frame": 420, "id": 15, "order": 15, "position": {"alt_Y": 848, "lat_Z": -237, "lng_X": -1072}}, {"frame": 450, "id": 16, "order": 16, "position": {"alt_Y": 657, "lat_Z": -237, "lng_X": -1072}}, {"frame": 480, "id": 17, "order": 17, "position": {"alt_Y": 519, "lat_Z": -237, "lng_X": -1072}}]}, {"id": 13, "waypoints": [{"frame": 0, "id": 1, "order": 1, "position": {"alt_Y": 500, "lat_Z": -169, "lng_X": -765}}, {"frame": 30, "id": 2, "order": 2, "position": {"alt_Y": 589, "lat_Z": -169, "lng_X": -765}}, {"frame": 60, "id": 3, "order": 3, "position": {"alt_Y": 785, "lat_Z": -169, "lng_X": -765}}, {"frame": 90, "id": 4, "order": 4, "position": {"alt_Y": 959, "lat_Z": -169, "lng_X": -765}}, {"frame": 120, "id": 5, "order": 5, "position": {"alt_Y": 1000, "lat_Z": -198, "lng_X": -765}}, {"frame": 150, "id": 6, "order": 6, "position": {"alt_Y": 1000, "lat_Z": -492, "lng_X": -765}}, {"frame": 180, "id": 7, "order": 7, "position": {"alt_Y": 1000, "lat_Z": -898, "lng_X": -765}}, {"frame": 210, "id": 8, "order": 8, "position": {"alt_Y": 1000, "lat_Z": -1157, "lng_X": -765}}, {"frame": 240, "id": 9, "order": 9, "position": {"alt_Y": 1000, "lat_Z": -1062, "lng_X": -765}}, {"frame": 270, "id": 10, "order": 10, "position": {"alt_Y": 1000, "lat_Z": -732, "lng_X": -765}}, {"frame": 300, "id": 11, "order": 11, "position": {"alt_Y": 1000, "lat_Z": -352, "lng_X": -765}}, {"frame": 330, "id": 12, "order": 12, "position": {"alt_Y": 1000, "lat_Z": -169, "lng_X": -765}}, {"frame": 360, "id": 13, "order": 13, "position": {"alt_Y": 1000, "lat_Z": -169, "lng_X": -765}}, {"frame": 390, "id": 14, "order": 14, "position": {"alt_Y": 995, "lat_Z": -169, "lng_X": -765}}, {"frame": 420, "id": 15, "order": 15, "position": {"alt_Y": 848, "lat_Z": -169, "lng_X": -765}}, {"frame": 450, "id": 16, "order": 16, "position": {"alt_Y": 657, "lat_Z": -169, "lng_X": -765}}, {"frame": 480, "id": 17, "order": 17, "position": {"alt_Y": 519, "lat_Z": -169, "lng_X": -765}}]}, {"id": 12, "waypoints": [{"frame": 0, "id": 1, "order": 1, "position": {"alt_Y": 500, "lat_Z": -101, "lng_X": -457}}, {"frame": 30, "id": 2, "order": 2, "position": {"alt_Y": 589, "lat_Z": -101, "lng_X": -457}}, {"frame": 60, "id": 3, "order": 3, "position": {"alt_Y": 785, "lat_Z": -101, "lng_X": -457}}, {"frame": 90, "id": 4, "order": 4, "position": {"alt_Y": 959, "lat_Z": -101, "lng_X": -457}}, {"frame": 120, "id": 5, "order": 5, "position": {"alt_Y": 1000, "lat_Z": -130, "lng_X": -457}}, {"frame": 150, "id": 6, "order": 6, "position": {"alt_Y": 1000, "lat_Z": -424, "lng_X": -457}}, {"frame": 180, "id": 7, "order": 7, "position": {"alt_Y": 1000, "lat_Z": -830, "lng_X": -457}}, {"frame": 210, "id": 8, "order": 8, "position": {"alt_Y": 1000, "lat_Z": -1089, "lng_X": -457}}, {"frame": 240, "id": 9, "order": 9, "position": {"alt_Y": 1000, "lat_Z": -994, "lng_X": -457}}, {"frame": 270, "id": 10, "order": 10, "position": {"alt_Y": 1000, "lat_Z": -664, "lng_X": -457}}, {"frame": 300, "id": 11, "order": 11, "position": {"alt_Y": 1000, "lat_Z": -284, "lng_X": -457}}, {"frame": 330, "id": 12, "order": 12, "position": {"alt_Y": 1000, "lat_Z": -101, "lng_X": -457}}, {"frame": 360, "id": 13, "order": 13, "position": {"alt_Y": 1000, "lat_Z": -101, "lng_X": -457}}, {"frame": 390, "id": 14, "order": 14, "position": {"alt_Y": 995, "lat_Z": -101, "lng_X": -457}}, {"frame": 420, "id": 15, "order": 15, "position": {"alt_Y": 848, "lat_Z": -101, "lng_X": -457}}, {"frame": 450, "id": 16, "order": 16, "position": {"alt_Y": 657, "lat_Z": -101, "lng_X": -457}}, {"frame": 480, "id": 17, "order": 17, "position": {"alt_Y": 519, "lat_Z": -101, "lng_X": -457}}]}, {"id": 11, "waypoints": [{"frame": 0, "id": 1, "order": 1, "position": {"alt_Y": 500, "lat_Z": -33, "lng_X": -150}}, {"frame": 30, "id": 2, "order": 2, "position": {"alt_Y": 589, "lat_Z": -33, "lng_X": -150}}, {"frame": 60, "id": 3, "order": 3, "position": {"alt_Y": 785, "lat_Z": -33, "lng_X": -150}}, {"frame": 90, "id": 4, "order": 4, "position": {"alt_Y": 959, "lat_Z": -33, "lng_X": -150}}, {"frame": 120, "id": 5, "order": 5, "position": {"alt_Y": 1000, "lat_Z": -62, "lng_X": -150}}, {"frame": 150, "id": 6, "order": 6, "position": {"alt_Y": 1000, "lat_Z": -356, "lng_X": -150}}, {"frame": 180, "id": 7, "order": 7, "position": {"alt_Y": 1000, "lat_Z": -761, "lng_X": -150}}, {"frame": 210, "id": 8, "order": 8, "position": {"alt_Y": 1000, "lat_Z": -1021, "lng_X": -150}}, {"frame": 240, "id": 9, "order": 9, "position": {"alt_Y": 1000, "lat_Z": -926, "lng_X": -150}}, {"frame": 270, "id": 10, "order": 10, "position": {"alt_Y": 1000, "lat_Z": -596, "lng_X": -150}}, {"frame": 300, "id": 11, "order": 11, "position": {"alt_Y": 1000, "lat_Z": -216, "lng_X": -150}}, {"frame": 330, "id": 12, "order": 12, "position": {"alt_Y": 1000, "lat_Z": -33, "lng_X": -150}}, {"frame": 360, "id": 13, "order": 13, "position": {"alt_Y": 1000, "lat_Z": -33, "lng_X": -150}}, {"frame": 390, "id": 14, "order": 14, "position": {"alt_Y": 995, "lat_Z": -33, "lng_X": -150}}, {"frame": 420, "id": 15, "order": 15, "position": {"alt_Y": 848, "lat_Z": -33, "lng_X": -150}}, {"frame": 450, "id": 16, "order": 16, "position": {"alt_Y": 657, "lat_Z": -33, "lng_X": -150}}, {"frame": 480, "id": 17, "order": 17, "position": {"alt_Y": 519, "lat_Z": -33, "lng_X": -150}}]}, {"id": 10, "waypoints": [{"frame": 0, "id": 1, "order": 1, "position": {"alt_Y": 500, "lat_Z": 35, "lng_X": 158}}, {"frame": 30, "id": 2, "order": 2, "position": {"alt_Y": 589, "lat_Z": 35, "lng_X": 158}}, {"frame": 60, "id": 3, "order": 3, "position": {"alt_Y": 785, "lat_Z": 35, "lng_X": 158}}, {"frame": 90, "id": 4, "order": 4, "position": {"alt_Y": 959, "lat_Z": 35, "lng_X": 158}}, {"frame": 120, "id": 5, "order": 5, "position": {"alt_Y": 1000, "lat_Z": 6, "lng_X": 158}}, {"frame": 150, "id": 6, "order": 6, "position": {"alt_Y": 1000, "lat_Z": -288, "lng_X": 158}}, {"frame": 180, "id": 7, "order": 7, "position": {"alt_Y": 1000, "lat_Z": -693, "lng_X": 158}}, {"frame": 210, "id": 8, "order": 8, "position": {"alt_Y": 1000, "lat_Z": -953, "lng_X": 158}}, {"frame": 240, "id": 9, "order": 9, "position": {"alt_Y": 1000, "lat_Z": -858, "lng_X": 158}}, {"frame": 270, "id": 10, "order": 10, "position": {"alt_Y": 1000, "lat_Z": -528, "lng_X": 158}}, {"frame": 300, "id": 11, "order": 11, "position": {"alt_Y": 1000, "lat_Z": -148, "lng_X": 158}}, {"frame": 330, "id": 12, "order": 12, "position": {"alt_Y": 1000, "lat_Z": 35, "lng_X": 158}}, {"frame": 360, "id": 13, "order": 13, "position": {"alt_Y": 1000, "lat_Z": 35, "lng_X": 158}}, {"frame": 390, "id": 14, "order": 14, "position": {"alt_Y": 995, "lat_Z": 35, "lng_X": 158}}, {"frame": 420, "id": 15, "order": 15, "position": {"alt_Y": 848, "lat_Z": 35, "lng_X": 158}}, {"frame": 450, "id": 16, "order": 16, "position": {"alt_Y": 657, "lat_Z": 35, "lng_X": 158}}, {"frame": 480, "id": 17, "order": 17, "position": {"alt_Y": 519, "lat_Z": 35, "lng_X": 158}}]}, {"id": 9, "waypoints": [{"frame": 0, "id": 1, "order": 1, "position": {"alt_Y": 500, "lat_Z": 103, "lng_X": 466}}, {"frame": 30, "id": 2, "order": 2, "position": {"alt_Y": 589, "lat_Z": 103, "lng_X": 466}}, {"frame": 60, "id": 3, "order": 3, "position": {"alt_Y": 785, "lat_Z": 103, "lng_X": 466}}, {"frame": 90, "id": 4, "order": 4, "position": {"alt_Y": 959, "lat_Z": 103, "lng_X": 466}}, {"frame": 120, "id": 5, "order": 5, "position": {"alt_Y": 1000, "lat_Z": 74, "lng_X": 466}}, {"frame": 150, "id": 6, "order": 6, "position": {"alt_Y": 1000, "lat_Z": -220, "lng_X": 466}}, {"frame": 180, "id": 7, "order": 7, "position": {"alt_Y": 1000, "lat_Z": -625, "lng_X": 466}}, {"frame": 210, "id": 8, "order": 8, "position": {"alt_Y": 1000, "lat_Z": -885, "lng_X": 466}}, {"frame": 240, "id": 9, "order": 9, "position": {"alt_Y": 1000, "lat_Z": -790, "lng_X": 466}}, {"frame": 270, "id": 10, "order": 10, "position": {"alt_Y": 1000, "lat_Z": -459, "lng_X": 466}}, {"frame": 300, "id": 11, "order": 11, "position": {"alt_Y": 1000, "lat_Z": -79, "lng_X": 466}}, {"frame": 330, "id": 12, "order": 12, "position": {"alt_Y": 1000, "lat_Z": 103, "lng_X": 466}}, {"frame": 360, "id": 13, "order": 13, "position": {"alt_Y": 1000, "lat_Z": 103, "lng_X": 466}}, {"frame": 390, "id": 14, "order": 14, "position": {"alt_Y": 995, "lat_Z": 103, "lng_X": 466}}, {"frame": 420, "id": 15, "order": 15, "position": {"alt_Y": 848, "lat_Z": 103, "lng_X": 466}}, {"frame": 450, "id": 16, "order": 16, "position": {"alt_Y": 657, "lat_Z": 103, "lng_X": 466}}, {"frame": 480, "id": 17, "order": 17, "position": {"alt_Y": 519, "lat_Z": 103, "lng_X": 466}}]}, {"id": 8, "waypoints": [{"frame": 0, "id": 1, "order": 1, "position": {"alt_Y": 500, "lat_Z": 171, "lng_X": 773}}, {"frame": 30, "id": 2, "order": 2, "position": {"alt_Y": 589, "lat_Z": 171, "lng_X": 773}}, {"frame": 60, "id": 3, "order": 3, "position": {"alt_Y": 785, "lat_Z": 171, "lng_X": 773}}, {"frame": 90, "id": 4, "order": 4, "position": {"alt_Y": 959, "lat_Z": 171, "lng_X": 773}}, {"frame": 120, "id": 5, "order": 5, "position": {"alt_Y": 1000, "lat_Z": 142, "lng_X": 773}}, {"frame": 150, "id": 6, "order": 6, "position": {"alt_Y": 1000, "lat_Z": -152, "lng_X": 773}}, {"frame": 180, "id": 7, "order": 7, "position": {"alt_Y": 1000, "lat_Z": -557, "lng_X": 773}}, {"frame": 210, "id": 8, "order": 8, "position": {"alt_Y": 1000, "lat_Z": -817, "lng_X": 773}}, {"frame": 240, "id": 9, "order": 9, "position": {"alt_Y": 1000, "lat_Z": -721, "lng_X": 773}}, {"frame": 270, "id": 10, "order": 10, "position": {"alt_Y": 1000, "lat_Z": -391, "lng_X": 773}}, {"frame": 300, "id": 11, "order": 11, "position": {"alt_Y": 1000, "lat_Z": -11, "lng_X": 773}}, {"frame": 330, "id": 12, "order": 12, "position": {"alt_Y": 1000, "lat_Z": 171, "lng_X": 773}}, {"frame": 360, "id": 13, "order": 13, "position": {"alt_Y": 1000, "lat_Z": 171, "lng_X": 773}}, {"frame": 390, "id": 14, "order": 14, "position": {"alt_Y": 995, "lat_Z": 171, "lng_X": 773}}, {"frame": 420, "id": 15, "order": 15, "position": {"alt_Y": 848, "lat_Z": 171, "lng_X": 773}}, {"frame": 450, "id": 16, "order": 16, "position": {"alt_Y": 657, "lat_Z": 171, "lng_X": 773}}, {"frame": 480, "id": 17, "order": 17, "position": {"alt_Y": 519, "lat_Z": 171, "lng_X": 773}}]}, {"id": 7, "waypoints": [{"frame": 0, "id": 1, "order": 1, "position": {"alt_Y": 500, "lat_Z": 239, "lng_X": 1081}}, {"frame": 30, "id": 2, "order": 2, "position": {"alt_Y": 589, "lat_Z": 239, "lng_X": 1081}}, {"frame": 60, "id": 3, "order": 3, "position": {"alt_Y": 785, "lat_Z": 239, "lng_X": 1081}}, {"frame": 90, "id": 4, "order": 4, "position": {"alt_Y": 959, "lat_Z": 239, "lng_X": 1081}}, {"frame": 120, "id": 5, "order": 5, "position": {"alt_Y": 1000, "lat_Z": 210, "lng_X": 1081}}, {"frame": 150, "id": 6, "order": 6, "position": {"alt_Y": 1000, "lat_Z": -84, "lng_X": 1081}}, {"frame": 180, "id": 7, "order": 7, "position": {"alt_Y": 1000, "lat_Z": -489, "lng_X": 1081}}, {"frame": 210, "id": 8, "order": 8, "position": {"alt_Y": 1000, "lat_Z": -749, "lng_X": 1081}}, {"frame": 240, "id": 9, "order": 9, "position": {"alt_Y": 1000, "lat_Z": -653, "lng_X": 1081}}, {"frame": 270, "id": 10, "order": 10, "position": {"alt_Y": 1000, "lat_Z": -323, "lng_X": 1081}}, {"frame": 300, "id": 11, "order": 11, "position": {"alt_Y": 1000, "lat_Z": 57, "lng_X": 1081}}, {"frame": 330, "id": 12, "order": 12, "position": {"alt_Y": 1000, "lat_Z": 239, "lng_X": 1081}}, {"frame": 360, "id": 13, "order": 13, "position": {"alt_Y": 1000, "lat_Z": 239, "lng_X": 1081}}, {"frame": 390, "id": 14, "order": 14, "position": {"alt_Y": 995, "lat_Z": 239, "lng_X": 1081}}, {"frame": 420, "id": 15, "order": 15, "position": {"alt_Y": 848, "lat_Z": 239, "lng_X": 1081}}, {"frame": 450, "id": 16, "order": 16, "position": {"alt_Y": 657, "lat_Z": 239, "lng_X": 1081}}, {"frame": 480, "id": 17, "order": 17, "position": {"alt_Y": 519, "lat_Z": 239, "lng_X": 1081}}]}, {"id": 6, "waypoints": [{"frame": 0, "id": 1, "order": 1, "position": {"alt_Y": 500, "lat_Z": 307, "lng_X": 1388}}, {"frame": 30, "id": 2, "order": 2, "position": {"alt_Y": 589, "lat_Z": 307, "lng_X": 1388}}, {"frame": 60, "id": 3, "order": 3, "position": {"alt_Y": 785, "lat_Z": 307, "lng_X": 1388}}, {"frame": 90, "id": 4, "order": 4, "position": {"alt_Y": 959, "lat_Z": 307, "lng_X": 1388}}, {"frame": 120, "id": 5, "order": 5, "position": {"alt_Y": 1000, "lat_Z": 278, "lng_X": 1388}}, {"frame": 150, "id": 6, "order": 6, "position": {"alt_Y": 1000, "lat_Z": -16, "lng_X": 1388}}, {"frame": 180, "id": 7, "order": 7, "position": {"alt_Y": 1000, "lat_Z": -421, "lng_X": 1388}}, {"frame": 210, "id": 8, "order": 8, "position": {"alt_Y": 1000, "lat_Z": -681, "lng_X": 1388}}, {"frame": 240, "id": 9, "order": 9, "position": {"alt_Y": 1000, "lat_Z": -585, "lng_X": 1388}}, {"frame": 270, "id": 10, "order": 10, "position": {"alt_Y": 1000, "lat_Z": -255, "lng_X": 1388}}, {"frame": 300, "id": 11, "order": 11, "position": {"alt_Y": 1000, "lat_Z": 125, "lng_X": 1388}}, {"frame": 330, "id": 12, "order": 12, "position": {"alt_Y": 1000, "lat_Z": 307, "lng_X": 1388}}, {"frame": 360, "id": 13, "order": 13, "position": {"alt_Y": 1000, "lat_Z": 307, "lng_X": 1388}}, {"frame": 390, "id": 14, "order": 14, "position": {"alt_Y": 995, "lat_Z": 307, "lng_X": 1388}}, {"frame": 420, "id": 15, "order": 15, "position": {"alt_Y": 848, "lat_Z": 307, "lng_X": 1388}}, {"frame": 450, "id": 16, "order": 16, "position": {"alt_Y": 657, "lat_Z": 307, "lng_X": 1388}}, {"frame": 480, "id": 17, "order": 17, "position": {"alt_Y": 519, "lat_Z": 307, "lng_X": 1388}}]}, {"id": 5, "waypoints": [{"frame": 0, "id": 1, "order": 1, "position": {"alt_Y": 500, "lat_Z": 375, "lng_X": 1696}}, {"frame": 30, "id": 2, "order": 2, "position": {"alt_Y": 589, "lat_Z": 375, "lng_X": 1696}}, {"frame": 60, "id": 3, "order": 3, "position": {"alt_Y": 785, "lat_Z": 375, "lng_X": 1696}}, {"frame": 90, "id": 4, "order": 4, "position": {"alt_Y": 959, "lat_Z": 375, "lng_X": 1696}}, {"frame": 120, "id": 5, "order": 5, "position": {"alt_Y": 1000, "lat_Z": 346, "lng_X": 1696}}, {"frame": 150, "id": 6, "order": 6, "position": {"alt_Y": 1000, "lat_Z": 53, "lng_X": 1696}}, {"frame": 180, "id": 7, "order": 7, "position": {"alt_Y": 1000, "lat_Z": -353, "lng_X": 1696}}, {"frame": 210, "id": 8, "order": 8, "position": {"alt_Y": 1000, "lat_Z": -612, "lng_X": 1696}}, {"frame": 240, "id": 9, "order": 9, "position": {"alt_Y": 1000, "lat_Z": -517, "lng_X": 1696}}, {"frame": 270, "id": 10, "order": 10, "position": {"alt_Y": 1000, "lat_Z": -187, "lng_X": 1696}}, {"frame": 300, "id": 11, "order": 11, "position": {"alt_Y": 1000, "lat_Z": 193, "lng_X": 1696}}, {"frame": 330, "id": 12, "order": 12, "position": {"alt_Y": 1000, "lat_Z": 375, "lng_X": 1696}}, {"frame": 360, "id": 13, "order": 13, "position": {"alt_Y": 1000, "lat_Z": 375, "lng_X": 1696}}, {"frame": 390, "id": 14, "order": 14, "position": {"alt_Y": 995, "lat_Z": 375, "lng_X": 1696}}, {"frame": 420, "id": 15, "order": 15, "position": {"alt_Y": 848, "lat_Z": 375, "lng_X": 1696}}, {"frame": 450, "id": 16, "order": 16, "position": {"alt_Y": 657, "lat_Z": 375, "lng_X": 1696}}, {"frame": 480, "id": 17, "order": 17, "position": {"alt_Y": 519, "lat_Z": 375, "lng_X": 1696}}]}, {"id": 4, "waypoints": [{"frame": 0, "id": 1, "order": 1, "position": {"alt_Y": 500, "lat_Z": 444, "lng_X": 2003}}, {"frame": 30, "id": 2, "order": 2, "position": {"alt_Y": 589, "lat_Z": 444, "lng_X": 2003}}, {"frame": 60, "id": 3, "order": 3, "position": {"alt_Y": 785, "lat_Z": 444, "lng_X": 2003}}, {"frame": 90, "id": 4, "order": 4, "position": {"alt_Y": 959, "lat_Z": 444, "lng_X": 2003}}, {"frame": 120, "id": 5, "order": 5, "position": {"alt_Y": 1000, "lat_Z": 415, "lng_X": 2003}}, {"frame": 150, "id": 6, "order": 6, "position": {"alt_Y": 1000, "lat_Z": 121, "lng_X": 2003}}, {"frame": 180, "id": 7, "order": 7, "position": {"alt_Y": 1000, "lat_Z": -285, "lng_X": 2003}}, {"frame": 210, "id": 8, "order": 8, "position": {"alt_Y": 1000, "lat_Z": -544, "lng_X": 2003}}, {"frame": 240, "id": 9, "order": 9, "position": {"alt_Y": 1000, "lat_Z": -449, "lng_X": 2003}}, {"frame": 270, "id": 10, "order": 10, "position": {"alt_Y": 1000, "lat_Z": -119, "lng_X": 2003}}, {"frame": 300, "id": 11, "order": 11, "position": {"alt_Y": 1000, "lat_Z": 261, "lng_X": 2003}}, {"frame": 330, "id": 12, "order": 12, "position": {"alt_Y": 1000, "lat_Z": 444, "lng_X": 2003}}, {"frame": 360, "id": 13, "order": 13, "position": {"alt_Y": 1000, "lat_Z": 444, "lng_X": 2003}}, {"frame": 390, "id": 14, "order": 14, "position": {"alt_Y": 995, "lat_Z": 444, "lng_X": 2003}}, {"frame": 420, "id": 15, "order": 15, "position": {"alt_Y": 848, "lat_Z": 444, "lng_X": 2003}}, {"frame": 450, "id": 16, "order": 16, "position": {"alt_Y": 657, "lat_Z": 444, "lng_X": 2003}}, {"frame": 480, "id": 17, "order": 17, "position": {"alt_Y": 519, "lat_Z": 444, "lng_X": 2003}}]}, {"id": 3, "waypoints": [{"frame": 0, "id": 1, "order": 1, "position": {"alt_Y": 500, "lat_Z": 512, "lng_X": 2311}}, {"frame": 30, "id": 2, "order": 2, "position": {"alt_Y": 589, "lat_Z": 512, "lng_X": 2311}}, {"frame": 60, "id": 3, "order": 3, "position": {"alt_Y": 785, "lat_Z": 512, "lng_X": 2311}}, {"frame": 90, "id": 4, "order": 4, "position": {"alt_Y": 959, "lat_Z": 512, "lng_X": 2311}}, {"frame": 120, "id": 5, "order": 5, "position": {"alt_Y": 1000, "lat_Z": 483, "lng_X": 2311}}, {"frame": 150, "id": 6, "order": 6, "position": {"alt_Y": 1000, "lat_Z": 189, "lng_X": 2311}}, {"frame": 180, "id": 7, "order": 7, "position": {"alt_Y": 1000, "lat_Z": -217, "lng_X": 2311}}, {"frame": 210, "id": 8, "order": 8, "position": {"alt_Y": 1000, "lat_Z": -476, "lng_X": 2311}}, {"frame": 240, "id": 9, "order": 9, "position": {"alt_Y": 1000, "lat_Z": -381, "lng_X": 2311}}, {"frame": 270, "id": 10, "order": 10, "position": {"alt_Y": 1000, "lat_Z": -51, "lng_X": 2311}}, {"frame": 300, "id": 11, "order": 11, "position": {"alt_Y": 1000, "lat_Z": 329, "lng_X": 2311}}, {"frame": 330, "id": 12, "order": 12, "position": {"alt_Y": 1000, "lat_Z": 512, "lng_X": 2311}}, {"frame": 360, "id": 13, "order": 13, "position": {"alt_Y": 1000, "lat_Z": 512, "lng_X": 2311}}, {"frame": 390, "id": 14, "order": 14, "position": {"alt_Y": 995, "lat_Z": 512, "lng_X": 2311}}, {"frame": 420, "id": 15, "order": 15, "position": {"alt_Y": 848, "lat_Z": 512, "lng_X": 2311}}, {"frame": 450, "id": 16, "order": 16, "position": {"alt_Y": 657, "lat_Z": 512, "lng_X": 2311}}, {"frame": 480, "id": 17, "order": 17, "position": {"alt_Y": 519, "lat_Z": 512, "lng_X": 2311}}]}, {"id": 2, "waypoints": [{"frame": 0, "id": 1, "order": 1, "position": {"alt_Y": 500, "lat_Z": 580, "lng_X": 2619}}, {"frame": 30, "id": 2, "order": 2, "position": {"alt_Y": 589, "lat_Z": 580, "lng_X": 2619}}, {"frame": 60, "id": 3, "order": 3, "position": {"alt_Y": 785, "lat_Z": 580, "lng_X": 2619}}, {"frame": 90, "id": 4, "order": 4, "position": {"alt_Y": 959, "lat_Z": 580, "lng_X": 2619}}, {"frame": 120, "id": 5, "order": 5, "position": {"alt_Y": 1000, "lat_Z": 551, "lng_X": 2619}}, {"frame": 150, "id": 6, "order": 6, "position": {"alt_Y": 1000, "lat_Z": 257, "lng_X": 2619}}, {"frame": 180, "id": 7, "order": 7, "position": {"alt_Y": 1000, "lat_Z": -149, "lng_X": 2619}}, {"frame": 210, "id": 8, "order": 8, "position": {"alt_Y": 1000, "lat_Z": -408, "lng_X": 2619}}, {"frame": 240, "id": 9, "order": 9, "position": {"alt_Y": 1000, "lat_Z": -313, "lng_X": 2619}}, {"frame": 270, "id": 10, "order": 10, "position": {"alt_Y": 1000, "lat_Z": 17, "lng_X": 2619}}, {"frame": 300, "id": 11, "order": 11, "position": {"alt_Y": 1000, "lat_Z": 397, "lng_X": 2619}}, {"frame": 330, "id": 12, "order": 12, "position": {"alt_Y": 1000, "lat_Z": 580, "lng_X": 2619}}, {"frame": 360, "id": 13, "order": 13, "position": {"alt_Y": 1000, "lat_Z": 580, "lng_X": 2619}}, {"frame": 390, "id": 14, "order": 14, "position": {"alt_Y": 995, "lat_Z": 580, "lng_X": 2619}}, {"frame": 420, "id": 15, "order": 15, "position": {"alt_Y": 848, "lat_Z": 580, "lng_X": 2619}}, {"frame": 450, "id": 16, "order": 16, "position": {"alt_Y": 657, "lat_Z": 580, "lng_X": 2619}}, {"frame": 480, "id": 17, "order": 17, "position": {"alt_Y": 519, "lat_Z": 580, "lng_X": 2619}}]}, {"id": 1, "waypoints": [{"frame": 0, "id": 1, "order": 1, "position": {"alt_Y": 500, "lat_Z": 648, "lng_X": 2926}}, {"frame": 30, "id": 2, "order": 2, "position": {"alt_Y": 589, "lat_Z": 648, "lng_X": 2926}}, {"frame": 60, "id": 3, "order": 3, "position": {"alt_Y": 785, "lat_Z": 648, "lng_X": 2926}}, {"frame": 90, "id": 4, "order": 4, "position": {"alt_Y": 959, "lat_Z": 648, "lng_X": 2926}}, {"frame": 120, "id": 5, "order": 5, "position": {"alt_Y": 1000, "lat_Z": 619, "lng_X": 2926}}, {"frame": 150, "id": 6, "order": 6, "position": {"alt_Y": 1000, "lat_Z": 325, "lng_X": 2926}}, {"frame": 180, "id": 7, "order": 7, "position": {"alt_Y": 1000, "lat_Z": -80, "lng_X": 2926}}, {"frame": 210, "id": 8, "order": 8, "position": {"alt_Y": 1000, "lat_Z": -340, "lng_X": 2926}}, {"frame": 240, "id": 9, "order": 9, "position": {"alt_Y": 1000, "lat_Z": -245, "lng_X": 2926}}, {"frame": 270, "id": 10, "order": 10, "position": {"alt_Y": 1000, "lat_Z": 85, "lng_X": 2926}}, {"frame": 300, "id": 11, "order": 11, "position": {"alt_Y": 1000, "lat_Z": 465, "lng_X": 2926}}, {"frame": 330, "id": 12, "order": 12, "position": {"alt_Y": 1000, "lat_Z": 648, "lng_X": 2926}}, {"frame": 360, "id": 13, "order": 13, "position": {"alt_Y": 1000, "lat_Z": 648, "lng_X": 2926}}, {"frame": 390, "id": 14, "order": 14, "position": {"alt_Y": 995, "lat_Z": 648, "lng_X": 2926}}, {"frame": 420, "id": 15, "order": 15, "position": {"alt_Y": 848, "lat_Z": 648, "lng_X": 2926}}, {"frame": 450, "id": 16, "order": 16, "position": {"alt_Y": 657, "lat_Z": 648, "lng_X": 2926}}, {"frame": 480, "id": 17, "order": 17, "position": {"alt_Y": 519, "lat_Z": 648, "lng_X": 2926}}]}], "framerate": 30, "id": 1} \ No newline at end of file