From 7fbe0814d52ba861a02b0560d4e6872845ef241e Mon Sep 17 00:00:00 2001 From: ccolin Date: Tue, 22 Dec 2020 13:15:23 +0100 Subject: [PATCH] initial commit --- projet.pro | 16 +++++ src/boid.cc | 108 ++++++++++++++++++++++++++++++ src/drone_controller.cc | 102 ++++++++++++++++++++++++++++ src/drone_controller.hh | 57 ++++++++++++++++ src/main.cc | 11 ++++ src/main_window.cc | 73 ++++++++++++++++++++ src/main_window.hh | 36 ++++++++++ src/opengl_mesh.cc | 19 ++++++ src/opengl_mesh.hh | 18 +++++ src/opengl_widget.cc | 143 ++++++++++++++++++++++++++++++++++++++++ src/opengl_widget.hh | 35 ++++++++++ waypoints.json | 1 + 12 files changed, 619 insertions(+) create mode 100644 projet.pro create mode 100644 src/boid.cc create mode 100644 src/drone_controller.cc create mode 100644 src/drone_controller.hh create mode 100644 src/main.cc create mode 100644 src/main_window.cc create mode 100644 src/main_window.hh create mode 100644 src/opengl_mesh.cc create mode 100644 src/opengl_mesh.hh create mode 100644 src/opengl_widget.cc create mode 100644 src/opengl_widget.hh create mode 100644 waypoints.json 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 +#include + + +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 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 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 +#include + + +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 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 +#include +#include + + +struct Waypoint { + int frame; + QVector3D pos; + + Waypoint(unsigned frame, QVector3D pos); + Waypoint(const QJsonObject &json); +}; + + +class Drone { + QVector waypoints; + +public: + Drone(const QJsonObject &json); + const QVector getWaypoints() const; +}; + + +class DroneController : public QObject { + Q_OBJECT + + int framerate; + int frame = 0; + int duration = 0; + QVector 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 + + +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 +#include +#include +#include +#include + + +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 +#include +#include +#include + + +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 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 +#include +#include + + +struct OpenGLMesh { + GLuint vao, vbo; + unsigned nverts; + QMatrix4x4 mat; + + OpenGLMesh(QVector 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 +#include +#include +#include + +#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 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