zok213 commited on
Commit
8579cdc
·
0 Parent(s):

Initial commit

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .github/workflows/python-cleanliness.yml +25 -0
  2. .github/workflows/python-publish.yml +35 -0
  3. .github/workflows/windows_build.yml +83 -0
  4. .gitignore +31 -0
  5. .gitmodules +3 -0
  6. COPYING.txt +674 -0
  7. Dockerfile +40 -0
  8. README.md +189 -0
  9. ai_knowledge_base/ai_instructions.txt +199 -0
  10. ai_knowledge_base/copter_flightmodes.txt +247 -0
  11. ai_knowledge_base/drone-ai-knowledge-base.md +828 -0
  12. ai_knowledge_base/mavlink_commands.txt +228 -0
  13. ai_knowledge_base/professional_drone_control.md +364 -0
  14. app.py +207 -0
  15. chat_testing/README.md +1 -0
  16. chat_testing/comprehensive_test_suite.py +358 -0
  17. chat_testing/direct_patrol.json +1 -0
  18. chat_testing/flight_aware_test.json +1 -0
  19. chat_testing/flight_status.json +0 -0
  20. chat_testing/full_chat_conversation_test.py +334 -0
  21. chat_testing/patrol_response.json +1 -0
  22. chat_testing/run_tests.py +75 -0
  23. chat_testing/sophisticated_patrol.json +1 -0
  24. chatbot.html +351 -0
  25. chatbot_enhanced.html +818 -0
  26. downloads/go_straight_gemini_20250822_114314.plan +143 -0
  27. downloads/go_straight_local_20250822_101454.plan +143 -0
  28. downloads/patrol_gemini_20250822_095326.plan +238 -0
  29. downloads/patrol_gemini_20250822_112551.plan +238 -0
  30. downloads/patrol_gemini_20250822_114301.plan +238 -0
  31. downloads/photography_gemini_20250822_104534.plan +181 -0
  32. downloads/photography_gemini_20250822_114121.plan +181 -0
  33. downloads/photography_gemini_20250822_114715.plan +181 -0
  34. downloads/simple_flight_gemini_20250822_114423.plan +162 -0
  35. downloads/simple_flight_gemini_20250822_114433.plan +162 -0
  36. downloads/survey_gemini_20250822_112524.plan +390 -0
  37. downloads/survey_gemini_20250822_114203.plan +390 -0
  38. downloads/survey_local_20250822_095311.plan +390 -0
  39. downloads/survey_local_20250822_101322.plan +390 -0
  40. downloads/survey_local_20250822_104517.plan +390 -0
  41. downloads/survey_local_20250822_104546.plan +390 -0
  42. downloads/survey_local_20250822_104549.plan +390 -0
  43. downloads/survey_local_20250822_104559.plan +390 -0
  44. downloads/survey_local_20250822_104603.plan +390 -0
  45. downloads/survey_local_20250822_112511.plan +390 -0
  46. downloads/survey_local_20250822_112601.plan +390 -0
  47. downloads/survey_local_20250822_114056.plan +390 -0
  48. downloads/survey_local_20250822_114408.plan +390 -0
  49. main.py +103 -0
  50. requirements.txt +32 -0
.github/workflows/python-cleanliness.yml ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: test Python cleanliness
2
+
3
+ on: [push, pull_request, workflow_dispatch]
4
+
5
+ concurrency:
6
+ group: ci-${{github.workflow}}-${{ github.ref }}
7
+ cancel-in-progress: true
8
+
9
+ jobs:
10
+ build:
11
+ runs-on: ubuntu-22.04
12
+
13
+ steps:
14
+ # git checkout the PR
15
+ - uses: actions/checkout@v4
16
+ with:
17
+ submodules: 'recursive'
18
+
19
+ - name: Install dependencies
20
+ run: |
21
+ python -m pip install -U flake8
22
+
23
+ - name: Check Python with Flake8
24
+ run: |
25
+ scripts/run_flake8.py MAVProxy
.github/workflows/python-publish.yml ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # This workflow will upload a Python Package using Twine when a release is created
2
+ # For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries
3
+
4
+ name: Upload MAVProxy Package
5
+
6
+ on:
7
+ release:
8
+ types: [published]
9
+
10
+ jobs:
11
+ deploy:
12
+
13
+ runs-on: ubuntu-latest
14
+
15
+ steps:
16
+ - uses: actions/checkout@v2
17
+ - name: Set up Python
18
+ uses: actions/setup-python@v2
19
+ with:
20
+ python-version: '3.10'
21
+ - name: Install dependencies
22
+ run: |
23
+ python -m pip install -U pip
24
+ python -m pip install -U wheel
25
+ python -m pip install -U pymavlink
26
+ pip install build
27
+ pip install -U .
28
+ git submodule update --recursive --init
29
+ - name: Build package
30
+ run: python -m build
31
+ - name: Publish package
32
+ uses: pypa/gh-action-pypi-publish@release/v1
33
+ with:
34
+ user: __token__
35
+ password: ${{ secrets.PYPI_API_TOKEN }}
.github/workflows/windows_build.yml ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Windows Build
2
+
3
+ on: [push, pull_request, workflow_dispatch]
4
+ concurrency:
5
+ group: ci-${{github.workflow}}-${{ github.ref }}
6
+ cancel-in-progress: true
7
+
8
+ jobs:
9
+ build:
10
+ runs-on: 'windows-latest'
11
+ strategy:
12
+ matrix:
13
+ python-version: ['3.10']
14
+
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+ with:
18
+ submodules: 'recursive'
19
+ - uses: actions/checkout@v4
20
+ - name: Set up Python ${{ matrix.python-version }}
21
+ uses: actions/setup-python@v5
22
+ with:
23
+ python-version: ${{ matrix.python-version }}
24
+ - name: Install dependencies
25
+ run: |
26
+ python3 -m pip install -U wheel setuptools pip
27
+ python3 -m pip install -U pywin32 lxml pymavlink numpy matplotlib pyserial opencv-python PyYAML Pygame Pillow wxpython prompt-toolkit scipy
28
+ python3 -m pip install -U openai pyaudio
29
+ python3 -m pip install -U pyinstaller==6.7.0 packaging
30
+ - name: Download Inno Setup installer
31
+ run: curl -L -o installer.exe http://files.jrsoftware.org/is/6/innosetup-6.3.1.exe
32
+ - name: Install Inno Setup
33
+ run: ./installer.exe /verysilent /allusers /dir=inst
34
+ - name: Build MAVProxy
35
+ run: |
36
+ python3 -m pip install .[recommended] --user
37
+ python3 -m pip list
38
+ - name: Prepare installer
39
+ run: |
40
+ cd MAVProxy
41
+ copy ..\\windows\\mavproxy.spec
42
+ pyinstaller --clean mavproxy.spec
43
+ del mavproxy.spec
44
+ - name: Download parameters
45
+ run: |
46
+ mkdir Parameters
47
+ $wc = New-Object System.Net.WebClient
48
+ $wc.DownloadFile('https://autotest.ardupilot.org/Parameters/Rover/apm.pdef.xml', 'Parameters\Rover.xml')
49
+ $wc.DownloadFile('https://autotest.ardupilot.org/Parameters/Copter/apm.pdef.xml', 'Parameters\Copter.xml')
50
+ $wc.DownloadFile('https://autotest.ardupilot.org/Parameters/Plane/apm.pdef.xml', 'Parameters\Plane.xml')
51
+ $wc.DownloadFile('https://autotest.ardupilot.org/Parameters/Sub/apm.pdef.xml', 'Parameters\Sub.xml')
52
+ $wc.DownloadFile('https://autotest.ardupilot.org/Parameters/AntennaTracker/apm.pdef.xml', 'Parameters\AntennaTracker.xml')
53
+ $wc.DownloadFile('https://autotest.ardupilot.org/Parameters/Heli/apm.pdef.xml', 'Parameters\Heli.xml')
54
+ $wc.DownloadFile('https://autotest.ardupilot.org/Parameters/Blimp/apm.pdef.xml', 'Parameters\Blimp.xml')
55
+ - name: Build installer
56
+ run: |
57
+ cd windows
58
+ $env:VERSION=$(python returnVersion.py)
59
+ python3 returnVersion.py > version.txt
60
+ ISCC.exe /dMyAppVersion=$env:VERSION mavproxy.iss
61
+ ls Output
62
+ - name: Archive build
63
+ uses: actions/upload-artifact@v4
64
+ with:
65
+ name: MAVProxyInstaller
66
+ path: windows/Output
67
+ retention-days: 7
68
+ - name: Pre Release
69
+ uses: "softprops/action-gh-release@v2"
70
+ if: github.ref == 'refs/heads/master'
71
+ with:
72
+ prerelease: true
73
+ name: "Development Build"
74
+ tag_name: "latest"
75
+ files: windows/Output/*.*
76
+ token: "${{ secrets.GITHUB_TOKEN }}"
77
+ - name: Release
78
+ uses: "softprops/action-gh-release@v2"
79
+ if: startsWith(github.ref, 'refs/tags/v')
80
+ with:
81
+ prerelease: false
82
+ files: windows/Output/*.*
83
+ token: "${{ secrets.GITHUB_TOKEN }}"
.gitignore ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ mavproxy
2
+ *~
3
+ *.o
4
+ *.pyc
5
+ *.log
6
+ camera/
7
+ build/
8
+ dist/
9
+ gtest/
10
+ *.tlog
11
+ *.raw
12
+ MANIFEST
13
+ *.egg-info
14
+ .DS_Store
15
+ *.bak
16
+ *.orig
17
+ windows/version.txt
18
+ /.vscode
19
+ *node_modules/
20
+ *node_modules
21
+ cleanup_backup_*
22
+ *venv/
23
+ *venv
24
+ *logs/
25
+
26
+ *.backup*
27
+ *.backup
28
+
29
+ .env
30
+ *.env
31
+ .env.fixed
.gitmodules ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ [submodule "MAVProxy/modules/mavproxy_cesium"]
2
+ path = MAVProxy/modules/mavproxy_cesium
3
+ url = https://github.com/ArduPilot/MAVCesium.git
COPYING.txt ADDED
@@ -0,0 +1,674 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ GNU GENERAL PUBLIC LICENSE
2
+ Version 3, 29 June 2007
3
+
4
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
5
+ Everyone is permitted to copy and distribute verbatim copies
6
+ of this license document, but changing it is not allowed.
7
+
8
+ Preamble
9
+
10
+ The GNU General Public License is a free, copyleft license for
11
+ software and other kinds of works.
12
+
13
+ The licenses for most software and other practical works are designed
14
+ to take away your freedom to share and change the works. By contrast,
15
+ the GNU General Public License is intended to guarantee your freedom to
16
+ share and change all versions of a program--to make sure it remains free
17
+ software for all its users. We, the Free Software Foundation, use the
18
+ GNU General Public License for most of our software; it applies also to
19
+ any other work released this way by its authors. You can apply it to
20
+ your programs, too.
21
+
22
+ When we speak of free software, we are referring to freedom, not
23
+ price. Our General Public Licenses are designed to make sure that you
24
+ have the freedom to distribute copies of free software (and charge for
25
+ them if you wish), that you receive source code or can get it if you
26
+ want it, that you can change the software or use pieces of it in new
27
+ free programs, and that you know you can do these things.
28
+
29
+ To protect your rights, we need to prevent others from denying you
30
+ these rights or asking you to surrender the rights. Therefore, you have
31
+ certain responsibilities if you distribute copies of the software, or if
32
+ you modify it: responsibilities to respect the freedom of others.
33
+
34
+ For example, if you distribute copies of such a program, whether
35
+ gratis or for a fee, you must pass on to the recipients the same
36
+ freedoms that you received. You must make sure that they, too, receive
37
+ or can get the source code. And you must show them these terms so they
38
+ know their rights.
39
+
40
+ Developers that use the GNU GPL protect your rights with two steps:
41
+ (1) assert copyright on the software, and (2) offer you this License
42
+ giving you legal permission to copy, distribute and/or modify it.
43
+
44
+ For the developers' and authors' protection, the GPL clearly explains
45
+ that there is no warranty for this free software. For both users' and
46
+ authors' sake, the GPL requires that modified versions be marked as
47
+ changed, so that their problems will not be attributed erroneously to
48
+ authors of previous versions.
49
+
50
+ Some devices are designed to deny users access to install or run
51
+ modified versions of the software inside them, although the manufacturer
52
+ can do so. This is fundamentally incompatible with the aim of
53
+ protecting users' freedom to change the software. The systematic
54
+ pattern of such abuse occurs in the area of products for individuals to
55
+ use, which is precisely where it is most unacceptable. Therefore, we
56
+ have designed this version of the GPL to prohibit the practice for those
57
+ products. If such problems arise substantially in other domains, we
58
+ stand ready to extend this provision to those domains in future versions
59
+ of the GPL, as needed to protect the freedom of users.
60
+
61
+ Finally, every program is threatened constantly by software patents.
62
+ States should not allow patents to restrict development and use of
63
+ software on general-purpose computers, but in those that do, we wish to
64
+ avoid the special danger that patents applied to a free program could
65
+ make it effectively proprietary. To prevent this, the GPL assures that
66
+ patents cannot be used to render the program non-free.
67
+
68
+ The precise terms and conditions for copying, distribution and
69
+ modification follow.
70
+
71
+ TERMS AND CONDITIONS
72
+
73
+ 0. Definitions.
74
+
75
+ "This License" refers to version 3 of the GNU General Public License.
76
+
77
+ "Copyright" also means copyright-like laws that apply to other kinds of
78
+ works, such as semiconductor masks.
79
+
80
+ "The Program" refers to any copyrightable work licensed under this
81
+ License. Each licensee is addressed as "you". "Licensees" and
82
+ "recipients" may be individuals or organizations.
83
+
84
+ To "modify" a work means to copy from or adapt all or part of the work
85
+ in a fashion requiring copyright permission, other than the making of an
86
+ exact copy. The resulting work is called a "modified version" of the
87
+ earlier work or a work "based on" the earlier work.
88
+
89
+ A "covered work" means either the unmodified Program or a work based
90
+ on the Program.
91
+
92
+ To "propagate" a work means to do anything with it that, without
93
+ permission, would make you directly or secondarily liable for
94
+ infringement under applicable copyright law, except executing it on a
95
+ computer or modifying a private copy. Propagation includes copying,
96
+ distribution (with or without modification), making available to the
97
+ public, and in some countries other activities as well.
98
+
99
+ To "convey" a work means any kind of propagation that enables other
100
+ parties to make or receive copies. Mere interaction with a user through
101
+ a computer network, with no transfer of a copy, is not conveying.
102
+
103
+ An interactive user interface displays "Appropriate Legal Notices"
104
+ to the extent that it includes a convenient and prominently visible
105
+ feature that (1) displays an appropriate copyright notice, and (2)
106
+ tells the user that there is no warranty for the work (except to the
107
+ extent that warranties are provided), that licensees may convey the
108
+ work under this License, and how to view a copy of this License. If
109
+ the interface presents a list of user commands or options, such as a
110
+ menu, a prominent item in the list meets this criterion.
111
+
112
+ 1. Source Code.
113
+
114
+ The "source code" for a work means the preferred form of the work
115
+ for making modifications to it. "Object code" means any non-source
116
+ form of a work.
117
+
118
+ A "Standard Interface" means an interface that either is an official
119
+ standard defined by a recognized standards body, or, in the case of
120
+ interfaces specified for a particular programming language, one that
121
+ is widely used among developers working in that language.
122
+
123
+ The "System Libraries" of an executable work include anything, other
124
+ than the work as a whole, that (a) is included in the normal form of
125
+ packaging a Major Component, but which is not part of that Major
126
+ Component, and (b) serves only to enable use of the work with that
127
+ Major Component, or to implement a Standard Interface for which an
128
+ implementation is available to the public in source code form. A
129
+ "Major Component", in this context, means a major essential component
130
+ (kernel, window system, and so on) of the specific operating system
131
+ (if any) on which the executable work runs, or a compiler used to
132
+ produce the work, or an object code interpreter used to run it.
133
+
134
+ The "Corresponding Source" for a work in object code form means all
135
+ the source code needed to generate, install, and (for an executable
136
+ work) run the object code and to modify the work, including scripts to
137
+ control those activities. However, it does not include the work's
138
+ System Libraries, or general-purpose tools or generally available free
139
+ programs which are used unmodified in performing those activities but
140
+ which are not part of the work. For example, Corresponding Source
141
+ includes interface definition files associated with source files for
142
+ the work, and the source code for shared libraries and dynamically
143
+ linked subprograms that the work is specifically designed to require,
144
+ such as by intimate data communication or control flow between those
145
+ subprograms and other parts of the work.
146
+
147
+ The Corresponding Source need not include anything that users
148
+ can regenerate automatically from other parts of the Corresponding
149
+ Source.
150
+
151
+ The Corresponding Source for a work in source code form is that
152
+ same work.
153
+
154
+ 2. Basic Permissions.
155
+
156
+ All rights granted under this License are granted for the term of
157
+ copyright on the Program, and are irrevocable provided the stated
158
+ conditions are met. This License explicitly affirms your unlimited
159
+ permission to run the unmodified Program. The output from running a
160
+ covered work is covered by this License only if the output, given its
161
+ content, constitutes a covered work. This License acknowledges your
162
+ rights of fair use or other equivalent, as provided by copyright law.
163
+
164
+ You may make, run and propagate covered works that you do not
165
+ convey, without conditions so long as your license otherwise remains
166
+ in force. You may convey covered works to others for the sole purpose
167
+ of having them make modifications exclusively for you, or provide you
168
+ with facilities for running those works, provided that you comply with
169
+ the terms of this License in conveying all material for which you do
170
+ not control copyright. Those thus making or running the covered works
171
+ for you must do so exclusively on your behalf, under your direction
172
+ and control, on terms that prohibit them from making any copies of
173
+ your copyrighted material outside their relationship with you.
174
+
175
+ Conveying under any other circumstances is permitted solely under
176
+ the conditions stated below. Sublicensing is not allowed; section 10
177
+ makes it unnecessary.
178
+
179
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
180
+
181
+ No covered work shall be deemed part of an effective technological
182
+ measure under any applicable law fulfilling obligations under article
183
+ 11 of the WIPO copyright treaty adopted on 20 December 1996, or
184
+ similar laws prohibiting or restricting circumvention of such
185
+ measures.
186
+
187
+ When you convey a covered work, you waive any legal power to forbid
188
+ circumvention of technological measures to the extent such circumvention
189
+ is effected by exercising rights under this License with respect to
190
+ the covered work, and you disclaim any intention to limit operation or
191
+ modification of the work as a means of enforcing, against the work's
192
+ users, your or third parties' legal rights to forbid circumvention of
193
+ technological measures.
194
+
195
+ 4. Conveying Verbatim Copies.
196
+
197
+ You may convey verbatim copies of the Program's source code as you
198
+ receive it, in any medium, provided that you conspicuously and
199
+ appropriately publish on each copy an appropriate copyright notice;
200
+ keep intact all notices stating that this License and any
201
+ non-permissive terms added in accord with section 7 apply to the code;
202
+ keep intact all notices of the absence of any warranty; and give all
203
+ recipients a copy of this License along with the Program.
204
+
205
+ You may charge any price or no price for each copy that you convey,
206
+ and you may offer support or warranty protection for a fee.
207
+
208
+ 5. Conveying Modified Source Versions.
209
+
210
+ You may convey a work based on the Program, or the modifications to
211
+ produce it from the Program, in the form of source code under the
212
+ terms of section 4, provided that you also meet all of these conditions:
213
+
214
+ a) The work must carry prominent notices stating that you modified
215
+ it, and giving a relevant date.
216
+
217
+ b) The work must carry prominent notices stating that it is
218
+ released under this License and any conditions added under section
219
+ 7. This requirement modifies the requirement in section 4 to
220
+ "keep intact all notices".
221
+
222
+ c) You must license the entire work, as a whole, under this
223
+ License to anyone who comes into possession of a copy. This
224
+ License will therefore apply, along with any applicable section 7
225
+ additional terms, to the whole of the work, and all its parts,
226
+ regardless of how they are packaged. This License gives no
227
+ permission to license the work in any other way, but it does not
228
+ invalidate such permission if you have separately received it.
229
+
230
+ d) If the work has interactive user interfaces, each must display
231
+ Appropriate Legal Notices; however, if the Program has interactive
232
+ interfaces that do not display Appropriate Legal Notices, your
233
+ work need not make them do so.
234
+
235
+ A compilation of a covered work with other separate and independent
236
+ works, which are not by their nature extensions of the covered work,
237
+ and which are not combined with it such as to form a larger program,
238
+ in or on a volume of a storage or distribution medium, is called an
239
+ "aggregate" if the compilation and its resulting copyright are not
240
+ used to limit the access or legal rights of the compilation's users
241
+ beyond what the individual works permit. Inclusion of a covered work
242
+ in an aggregate does not cause this License to apply to the other
243
+ parts of the aggregate.
244
+
245
+ 6. Conveying Non-Source Forms.
246
+
247
+ You may convey a covered work in object code form under the terms
248
+ of sections 4 and 5, provided that you also convey the
249
+ machine-readable Corresponding Source under the terms of this License,
250
+ in one of these ways:
251
+
252
+ a) Convey the object code in, or embodied in, a physical product
253
+ (including a physical distribution medium), accompanied by the
254
+ Corresponding Source fixed on a durable physical medium
255
+ customarily used for software interchange.
256
+
257
+ b) Convey the object code in, or embodied in, a physical product
258
+ (including a physical distribution medium), accompanied by a
259
+ written offer, valid for at least three years and valid for as
260
+ long as you offer spare parts or customer support for that product
261
+ model, to give anyone who possesses the object code either (1) a
262
+ copy of the Corresponding Source for all the software in the
263
+ product that is covered by this License, on a durable physical
264
+ medium customarily used for software interchange, for a price no
265
+ more than your reasonable cost of physically performing this
266
+ conveying of source, or (2) access to copy the
267
+ Corresponding Source from a network server at no charge.
268
+
269
+ c) Convey individual copies of the object code with a copy of the
270
+ written offer to provide the Corresponding Source. This
271
+ alternative is allowed only occasionally and noncommercially, and
272
+ only if you received the object code with such an offer, in accord
273
+ with subsection 6b.
274
+
275
+ d) Convey the object code by offering access from a designated
276
+ place (gratis or for a charge), and offer equivalent access to the
277
+ Corresponding Source in the same way through the same place at no
278
+ further charge. You need not require recipients to copy the
279
+ Corresponding Source along with the object code. If the place to
280
+ copy the object code is a network server, the Corresponding Source
281
+ may be on a different server (operated by you or a third party)
282
+ that supports equivalent copying facilities, provided you maintain
283
+ clear directions next to the object code saying where to find the
284
+ Corresponding Source. Regardless of what server hosts the
285
+ Corresponding Source, you remain obligated to ensure that it is
286
+ available for as long as needed to satisfy these requirements.
287
+
288
+ e) Convey the object code using peer-to-peer transmission, provided
289
+ you inform other peers where the object code and Corresponding
290
+ Source of the work are being offered to the general public at no
291
+ charge under subsection 6d.
292
+
293
+ A separable portion of the object code, whose source code is excluded
294
+ from the Corresponding Source as a System Library, need not be
295
+ included in conveying the object code work.
296
+
297
+ A "User Product" is either (1) a "consumer product", which means any
298
+ tangible personal property which is normally used for personal, family,
299
+ or household purposes, or (2) anything designed or sold for incorporation
300
+ into a dwelling. In determining whether a product is a consumer product,
301
+ doubtful cases shall be resolved in favor of coverage. For a particular
302
+ product received by a particular user, "normally used" refers to a
303
+ typical or common use of that class of product, regardless of the status
304
+ of the particular user or of the way in which the particular user
305
+ actually uses, or expects or is expected to use, the product. A product
306
+ is a consumer product regardless of whether the product has substantial
307
+ commercial, industrial or non-consumer uses, unless such uses represent
308
+ the only significant mode of use of the product.
309
+
310
+ "Installation Information" for a User Product means any methods,
311
+ procedures, authorization keys, or other information required to install
312
+ and execute modified versions of a covered work in that User Product from
313
+ a modified version of its Corresponding Source. The information must
314
+ suffice to ensure that the continued functioning of the modified object
315
+ code is in no case prevented or interfered with solely because
316
+ modification has been made.
317
+
318
+ If you convey an object code work under this section in, or with, or
319
+ specifically for use in, a User Product, and the conveying occurs as
320
+ part of a transaction in which the right of possession and use of the
321
+ User Product is transferred to the recipient in perpetuity or for a
322
+ fixed term (regardless of how the transaction is characterized), the
323
+ Corresponding Source conveyed under this section must be accompanied
324
+ by the Installation Information. But this requirement does not apply
325
+ if neither you nor any third party retains the ability to install
326
+ modified object code on the User Product (for example, the work has
327
+ been installed in ROM).
328
+
329
+ The requirement to provide Installation Information does not include a
330
+ requirement to continue to provide support service, warranty, or updates
331
+ for a work that has been modified or installed by the recipient, or for
332
+ the User Product in which it has been modified or installed. Access to a
333
+ network may be denied when the modification itself materially and
334
+ adversely affects the operation of the network or violates the rules and
335
+ protocols for communication across the network.
336
+
337
+ Corresponding Source conveyed, and Installation Information provided,
338
+ in accord with this section must be in a format that is publicly
339
+ documented (and with an implementation available to the public in
340
+ source code form), and must require no special password or key for
341
+ unpacking, reading or copying.
342
+
343
+ 7. Additional Terms.
344
+
345
+ "Additional permissions" are terms that supplement the terms of this
346
+ License by making exceptions from one or more of its conditions.
347
+ Additional permissions that are applicable to the entire Program shall
348
+ be treated as though they were included in this License, to the extent
349
+ that they are valid under applicable law. If additional permissions
350
+ apply only to part of the Program, that part may be used separately
351
+ under those permissions, but the entire Program remains governed by
352
+ this License without regard to the additional permissions.
353
+
354
+ When you convey a copy of a covered work, you may at your option
355
+ remove any additional permissions from that copy, or from any part of
356
+ it. (Additional permissions may be written to require their own
357
+ removal in certain cases when you modify the work.) You may place
358
+ additional permissions on material, added by you to a covered work,
359
+ for which you have or can give appropriate copyright permission.
360
+
361
+ Notwithstanding any other provision of this License, for material you
362
+ add to a covered work, you may (if authorized by the copyright holders of
363
+ that material) supplement the terms of this License with terms:
364
+
365
+ a) Disclaiming warranty or limiting liability differently from the
366
+ terms of sections 15 and 16 of this License; or
367
+
368
+ b) Requiring preservation of specified reasonable legal notices or
369
+ author attributions in that material or in the Appropriate Legal
370
+ Notices displayed by works containing it; or
371
+
372
+ c) Prohibiting misrepresentation of the origin of that material, or
373
+ requiring that modified versions of such material be marked in
374
+ reasonable ways as different from the original version; or
375
+
376
+ d) Limiting the use for publicity purposes of names of licensors or
377
+ authors of the material; or
378
+
379
+ e) Declining to grant rights under trademark law for use of some
380
+ trade names, trademarks, or service marks; or
381
+
382
+ f) Requiring indemnification of licensors and authors of that
383
+ material by anyone who conveys the material (or modified versions of
384
+ it) with contractual assumptions of liability to the recipient, for
385
+ any liability that these contractual assumptions directly impose on
386
+ those licensors and authors.
387
+
388
+ All other non-permissive additional terms are considered "further
389
+ restrictions" within the meaning of section 10. If the Program as you
390
+ received it, or any part of it, contains a notice stating that it is
391
+ governed by this License along with a term that is a further
392
+ restriction, you may remove that term. If a license document contains
393
+ a further restriction but permits relicensing or conveying under this
394
+ License, you may add to a covered work material governed by the terms
395
+ of that license document, provided that the further restriction does
396
+ not survive such relicensing or conveying.
397
+
398
+ If you add terms to a covered work in accord with this section, you
399
+ must place, in the relevant source files, a statement of the
400
+ additional terms that apply to those files, or a notice indicating
401
+ where to find the applicable terms.
402
+
403
+ Additional terms, permissive or non-permissive, may be stated in the
404
+ form of a separately written license, or stated as exceptions;
405
+ the above requirements apply either way.
406
+
407
+ 8. Termination.
408
+
409
+ You may not propagate or modify a covered work except as expressly
410
+ provided under this License. Any attempt otherwise to propagate or
411
+ modify it is void, and will automatically terminate your rights under
412
+ this License (including any patent licenses granted under the third
413
+ paragraph of section 11).
414
+
415
+ However, if you cease all violation of this License, then your
416
+ license from a particular copyright holder is reinstated (a)
417
+ provisionally, unless and until the copyright holder explicitly and
418
+ finally terminates your license, and (b) permanently, if the copyright
419
+ holder fails to notify you of the violation by some reasonable means
420
+ prior to 60 days after the cessation.
421
+
422
+ Moreover, your license from a particular copyright holder is
423
+ reinstated permanently if the copyright holder notifies you of the
424
+ violation by some reasonable means, this is the first time you have
425
+ received notice of violation of this License (for any work) from that
426
+ copyright holder, and you cure the violation prior to 30 days after
427
+ your receipt of the notice.
428
+
429
+ Termination of your rights under this section does not terminate the
430
+ licenses of parties who have received copies or rights from you under
431
+ this License. If your rights have been terminated and not permanently
432
+ reinstated, you do not qualify to receive new licenses for the same
433
+ material under section 10.
434
+
435
+ 9. Acceptance Not Required for Having Copies.
436
+
437
+ You are not required to accept this License in order to receive or
438
+ run a copy of the Program. Ancillary propagation of a covered work
439
+ occurring solely as a consequence of using peer-to-peer transmission
440
+ to receive a copy likewise does not require acceptance. However,
441
+ nothing other than this License grants you permission to propagate or
442
+ modify any covered work. These actions infringe copyright if you do
443
+ not accept this License. Therefore, by modifying or propagating a
444
+ covered work, you indicate your acceptance of this License to do so.
445
+
446
+ 10. Automatic Licensing of Downstream Recipients.
447
+
448
+ Each time you convey a covered work, the recipient automatically
449
+ receives a license from the original licensors, to run, modify and
450
+ propagate that work, subject to this License. You are not responsible
451
+ for enforcing compliance by third parties with this License.
452
+
453
+ An "entity transaction" is a transaction transferring control of an
454
+ organization, or substantially all assets of one, or subdividing an
455
+ organization, or merging organizations. If propagation of a covered
456
+ work results from an entity transaction, each party to that
457
+ transaction who receives a copy of the work also receives whatever
458
+ licenses to the work the party's predecessor in interest had or could
459
+ give under the previous paragraph, plus a right to possession of the
460
+ Corresponding Source of the work from the predecessor in interest, if
461
+ the predecessor has it or can get it with reasonable efforts.
462
+
463
+ You may not impose any further restrictions on the exercise of the
464
+ rights granted or affirmed under this License. For example, you may
465
+ not impose a license fee, royalty, or other charge for exercise of
466
+ rights granted under this License, and you may not initiate litigation
467
+ (including a cross-claim or counterclaim in a lawsuit) alleging that
468
+ any patent claim is infringed by making, using, selling, offering for
469
+ sale, or importing the Program or any portion of it.
470
+
471
+ 11. Patents.
472
+
473
+ A "contributor" is a copyright holder who authorizes use under this
474
+ License of the Program or a work on which the Program is based. The
475
+ work thus licensed is called the contributor's "contributor version".
476
+
477
+ A contributor's "essential patent claims" are all patent claims
478
+ owned or controlled by the contributor, whether already acquired or
479
+ hereafter acquired, that would be infringed by some manner, permitted
480
+ by this License, of making, using, or selling its contributor version,
481
+ but do not include claims that would be infringed only as a
482
+ consequence of further modification of the contributor version. For
483
+ purposes of this definition, "control" includes the right to grant
484
+ patent sublicenses in a manner consistent with the requirements of
485
+ this License.
486
+
487
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
488
+ patent license under the contributor's essential patent claims, to
489
+ make, use, sell, offer for sale, import and otherwise run, modify and
490
+ propagate the contents of its contributor version.
491
+
492
+ In the following three paragraphs, a "patent license" is any express
493
+ agreement or commitment, however denominated, not to enforce a patent
494
+ (such as an express permission to practice a patent or covenant not to
495
+ sue for patent infringement). To "grant" such a patent license to a
496
+ party means to make such an agreement or commitment not to enforce a
497
+ patent against the party.
498
+
499
+ If you convey a covered work, knowingly relying on a patent license,
500
+ and the Corresponding Source of the work is not available for anyone
501
+ to copy, free of charge and under the terms of this License, through a
502
+ publicly available network server or other readily accessible means,
503
+ then you must either (1) cause the Corresponding Source to be so
504
+ available, or (2) arrange to deprive yourself of the benefit of the
505
+ patent license for this particular work, or (3) arrange, in a manner
506
+ consistent with the requirements of this License, to extend the patent
507
+ license to downstream recipients. "Knowingly relying" means you have
508
+ actual knowledge that, but for the patent license, your conveying the
509
+ covered work in a country, or your recipient's use of the covered work
510
+ in a country, would infringe one or more identifiable patents in that
511
+ country that you have reason to believe are valid.
512
+
513
+ If, pursuant to or in connection with a single transaction or
514
+ arrangement, you convey, or propagate by procuring conveyance of, a
515
+ covered work, and grant a patent license to some of the parties
516
+ receiving the covered work authorizing them to use, propagate, modify
517
+ or convey a specific copy of the covered work, then the patent license
518
+ you grant is automatically extended to all recipients of the covered
519
+ work and works based on it.
520
+
521
+ A patent license is "discriminatory" if it does not include within
522
+ the scope of its coverage, prohibits the exercise of, or is
523
+ conditioned on the non-exercise of one or more of the rights that are
524
+ specifically granted under this License. You may not convey a covered
525
+ work if you are a party to an arrangement with a third party that is
526
+ in the business of distributing software, under which you make payment
527
+ to the third party based on the extent of your activity of conveying
528
+ the work, and under which the third party grants, to any of the
529
+ parties who would receive the covered work from you, a discriminatory
530
+ patent license (a) in connection with copies of the covered work
531
+ conveyed by you (or copies made from those copies), or (b) primarily
532
+ for and in connection with specific products or compilations that
533
+ contain the covered work, unless you entered into that arrangement,
534
+ or that patent license was granted, prior to 28 March 2007.
535
+
536
+ Nothing in this License shall be construed as excluding or limiting
537
+ any implied license or other defenses to infringement that may
538
+ otherwise be available to you under applicable patent law.
539
+
540
+ 12. No Surrender of Others' Freedom.
541
+
542
+ If conditions are imposed on you (whether by court order, agreement or
543
+ otherwise) that contradict the conditions of this License, they do not
544
+ excuse you from the conditions of this License. If you cannot convey a
545
+ covered work so as to satisfy simultaneously your obligations under this
546
+ License and any other pertinent obligations, then as a consequence you may
547
+ not convey it at all. For example, if you agree to terms that obligate you
548
+ to collect a royalty for further conveying from those to whom you convey
549
+ the Program, the only way you could satisfy both those terms and this
550
+ License would be to refrain entirely from conveying the Program.
551
+
552
+ 13. Use with the GNU Affero General Public License.
553
+
554
+ Notwithstanding any other provision of this License, you have
555
+ permission to link or combine any covered work with a work licensed
556
+ under version 3 of the GNU Affero General Public License into a single
557
+ combined work, and to convey the resulting work. The terms of this
558
+ License will continue to apply to the part which is the covered work,
559
+ but the special requirements of the GNU Affero General Public License,
560
+ section 13, concerning interaction through a network will apply to the
561
+ combination as such.
562
+
563
+ 14. Revised Versions of this License.
564
+
565
+ The Free Software Foundation may publish revised and/or new versions of
566
+ the GNU General Public License from time to time. Such new versions will
567
+ be similar in spirit to the present version, but may differ in detail to
568
+ address new problems or concerns.
569
+
570
+ Each version is given a distinguishing version number. If the
571
+ Program specifies that a certain numbered version of the GNU General
572
+ Public License "or any later version" applies to it, you have the
573
+ option of following the terms and conditions either of that numbered
574
+ version or of any later version published by the Free Software
575
+ Foundation. If the Program does not specify a version number of the
576
+ GNU General Public License, you may choose any version ever published
577
+ by the Free Software Foundation.
578
+
579
+ If the Program specifies that a proxy can decide which future
580
+ versions of the GNU General Public License can be used, that proxy's
581
+ public statement of acceptance of a version permanently authorizes you
582
+ to choose that version for the Program.
583
+
584
+ Later license versions may give you additional or different
585
+ permissions. However, no additional obligations are imposed on any
586
+ author or copyright holder as a result of your choosing to follow a
587
+ later version.
588
+
589
+ 15. Disclaimer of Warranty.
590
+
591
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
592
+ APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
593
+ HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
594
+ OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
595
+ THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
596
+ PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
597
+ IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
598
+ ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
599
+
600
+ 16. Limitation of Liability.
601
+
602
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
603
+ WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
604
+ THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
605
+ GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
606
+ USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
607
+ DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
608
+ PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
609
+ EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
610
+ SUCH DAMAGES.
611
+
612
+ 17. Interpretation of Sections 15 and 16.
613
+
614
+ If the disclaimer of warranty and limitation of liability provided
615
+ above cannot be given local legal effect according to their terms,
616
+ reviewing courts shall apply local law that most closely approximates
617
+ an absolute waiver of all civil liability in connection with the
618
+ Program, unless a warranty or assumption of liability accompanies a
619
+ copy of the Program in return for a fee.
620
+
621
+ END OF TERMS AND CONDITIONS
622
+
623
+ How to Apply These Terms to Your New Programs
624
+
625
+ If you develop a new program, and you want it to be of the greatest
626
+ possible use to the public, the best way to achieve this is to make it
627
+ free software which everyone can redistribute and change under these terms.
628
+
629
+ To do so, attach the following notices to the program. It is safest
630
+ to attach them to the start of each source file to most effectively
631
+ state the exclusion of warranty; and each file should have at least
632
+ the "copyright" line and a pointer to where the full notice is found.
633
+
634
+ <one line to give the program's name and a brief idea of what it does.>
635
+ Copyright (C) <year> <name of author>
636
+
637
+ This program is free software: you can redistribute it and/or modify
638
+ it under the terms of the GNU General Public License as published by
639
+ the Free Software Foundation, either version 3 of the License, or
640
+ (at your option) any later version.
641
+
642
+ This program is distributed in the hope that it will be useful,
643
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
644
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
645
+ GNU General Public License for more details.
646
+
647
+ You should have received a copy of the GNU General Public License
648
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
649
+
650
+ Also add information on how to contact you by electronic and paper mail.
651
+
652
+ If the program does terminal interaction, make it output a short
653
+ notice like this when it starts in an interactive mode:
654
+
655
+ <program> Copyright (C) <year> <name of author>
656
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
657
+ This is free software, and you are welcome to redistribute it
658
+ under certain conditions; type `show c' for details.
659
+
660
+ The hypothetical commands `show w' and `show c' should show the appropriate
661
+ parts of the General Public License. Of course, your program's commands
662
+ might be different; for a GUI interface, you would use an "about box".
663
+
664
+ You should also get your employer (if you work as a programmer) or school,
665
+ if any, to sign a "copyright disclaimer" for the program, if necessary.
666
+ For more information on this, and how to apply and follow the GNU GPL, see
667
+ <http://www.gnu.org/licenses/>.
668
+
669
+ The GNU General Public License does not permit incorporating your program
670
+ into proprietary programs. If your program is a subroutine library, you
671
+ may consider it more useful to permit linking proprietary applications with
672
+ the library. If this is what you want to do, use the GNU Lesser General
673
+ Public License instead of this License. But first, please read
674
+ <http://www.gnu.org/philosophy/why-not-lgpl.html>.
Dockerfile ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🚁 DroneAgent - HF Spaces Dockerfile
2
+ # Optimized for HuggingFace Spaces deployment
3
+
4
+ FROM python:3.9-slim
5
+
6
+ # Create a non-root user
7
+ RUN useradd -m -u 1000 user
8
+ USER user
9
+
10
+ # Set environment variables
11
+ ENV PATH="/home/user/.local/bin:$PATH"
12
+ ENV PYTHONPATH="/app:$PYTHONPATH"
13
+
14
+ # Set working directory
15
+ WORKDIR /app
16
+
17
+ # Copy requirements and install dependencies
18
+ COPY --chown=user ./requirements.txt requirements.txt
19
+ RUN pip install --no-cache-dir --upgrade -r requirements.txt
20
+
21
+ # Copy application code
22
+ COPY --chown=user ./src /app/src
23
+ COPY --chown=user ./ai_knowledge_base /app/ai_knowledge_base
24
+ COPY --chown=user ./sample_data /app/sample_data
25
+ COPY --chown=user ./chatbot_enhanced.html /app/
26
+ COPY --chown=user ./app.py /app/
27
+ COPY --chown=user ./main.py /app/
28
+
29
+ # Create necessary directories
30
+ RUN mkdir -p /app/downloads /app/chat_testing
31
+
32
+ # Expose port 7860 (required for HF Spaces)
33
+ EXPOSE 7860
34
+
35
+ # Health check
36
+ HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
37
+ CMD curl -f http://localhost:7860/api/status || exit 1
38
+
39
+ # Start the application
40
+ CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860", "--reload"]
README.md ADDED
@@ -0,0 +1,189 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # DroneAgent - Hệ Thống Điều Khiển Drone Bằng AI Chuyên Nghiệp
2
+
3
+ ## Tổng Quan
4
+ DroneAgent là hệ thống chuyên nghiệp tích hợp ArduPilot SITL, MAVProxy và Gemini AI để điều khiển drone thông qua ngôn ngữ tự nhiên. Hệ thống cho phép người dùng điều khiển drone bằng lệnh trò chuyện qua giao diện web.
5
+
6
+ ## Kiến Trúc Hệ Thống
7
+ ```
8
+ Giao Diện Web (localhost:8080)
9
+ ↓↑
10
+ Backend API với Gemini AI (localhost:8001)
11
+ ↓↑
12
+ MAVProxy (Trung tâm giao tiếp)
13
+ ↓↑ ↓↑
14
+ [ArduPilot SITL] [Drone Thật]
15
+ (tcp:127.0.0.1:5760)
16
+ ```
17
+ Backend kết nối với MAVProxy qua một cổng UDP riêng (`14552`) để đảm bảo luồng dữ liệu ổn định.
18
+
19
+ ## Các Thành Phần Chính
20
+
21
+ ### 1. Backend API với Gemini AI
22
+ - **`backend/main.py`** - FastAPI server chính với tích hợp Gemini AI
23
+ - **`backend/services/drone_service.py`** - Dịch vụ điều khiển drone, kết nối với MAVProxy
24
+ - **`backend/services/ai_service.py`** - Xử lý AI và ngôn ngữ tự nhiên
25
+ - **`backend/.env`** - Cấu hình API key và environment
26
+
27
+ ### 2. Web Frontend
28
+ - **`web-frontend/`** - Giao diện web hiện đại cho điều khiển drone
29
+ - Giao diện chat trực quan cho lệnh ngôn ngữ tự nhiên
30
+ - Cập nhật trạng thái real-time và phản hồi lệnh
31
+
32
+ ### 3. MAVProxy với Chat Module
33
+ - **`MAVProxy/modules/mavproxy_chat/`** - Module chat tích hợp AI
34
+ - Chuyển đổi lệnh ngôn ngữ tự nhiên thành MAVLink commands
35
+ - Tích hợp với backend API và là trung tâm giao tiếp MAVLink.
36
+
37
+ ### 4. Script Khởi Động Hệ Thống
38
+ - **`start_complete_droneagent_system.sh`** - Script khởi động đã được sửa lỗi
39
+ - Xử lý ArduPilot SITL, Backend, Frontend, MAVProxy
40
+ - Bao gồm error handling và monitoring
41
+
42
+ ## Hướng Dẫn Cài Đặt Nhanh
43
+
44
+ ### Yêu Cầu Hệ Thống
45
+ ```bash
46
+ # Ubuntu 22.04 WSL2 (khuyến nghị)
47
+ sudo apt update
48
+ sudo apt install python3 python3-pip python3-venv git curl
49
+
50
+ # ArduPilot SITL (bắt buộc)
51
+ git clone https://github.com/ArduPilot/ardupilot.git
52
+ cd ardupilot
53
+ git submodule update --init --recursive
54
+ ./Tools/environment_install/install-prereqs-ubuntu.sh -y
55
+ ./waf configure --board sitl
56
+ ./waf copter
57
+
58
+ # MAVProxy (bắt buộc)
59
+ pip3 install MAVProxy
60
+
61
+ # Netcat cho testing
62
+ sudo apt install netcat
63
+ ```
64
+
65
+ ### Cài Đặt DroneAgent
66
+ ```bash
67
+ # Clone repository
68
+ git clone <repository-url>
69
+ cd DroneAgent
70
+
71
+ # Chạy script cài đặt API key
72
+ ./setup_api_key.sh
73
+ # Script sẽ yêu cầu bạn nhập Gemini API key và lưu vào backend/.env
74
+ ```
75
+
76
+ ### Khởi Động Hệ Thống
77
+ ```bash
78
+ # Khởi động toàn bộ hệ thống (SCRIPT ĐÃ SỬA LỖI)
79
+ ./start_complete_droneagent_system.sh
80
+
81
+ # Hệ thống sẽ tự động:
82
+ # ✅ Kiểm tra system requirements
83
+ # ✅ Validate Gemini AI config
84
+ # ✅ Cài đặt backend dependencies
85
+ # ✅ Khởi động Backend API (port 8001)
86
+ # ✅ Khởi động Web Frontend (port 8080)
87
+ # ✅ Khởi động ArduCopter SITL
88
+ # ✅ Khởi động MAVProxy với các output cần thiết
89
+ # ✅ System monitoring và health check
90
+ ```
91
+
92
+ ### Truy Cập Hệ Thống
93
+ - **Giao Diện Web**: http://localhost:8080
94
+ - **Backend API**: http://localhost:8001/docs
95
+ - **Health Check**: http://localhost:8001/api/health
96
+
97
+ ## Ví Dụ Sử Dụng
98
+
99
+ ### Lệnh Cơ Bản
100
+ - "Arm drone"
101
+ - "Cất cánh lên 10 mét"
102
+ - "Bay về phía trước 20 mét"
103
+ - "Quay trái 90 độ"
104
+ - "Hạ cánh"
105
+ - "Kiểm tra vị trí hiện tại"
106
+ - "Trạng thái pin"
107
+
108
+ ### Lệnh Nâng Cao
109
+ - "Bay đến tọa độ GPS 35.123, -118.456"
110
+ - "Thực hiện bay vòng tròn bán kính 50 mét"
111
+ - "Quay về điểm khởi hành"
112
+ - "Chuyển sang chế độ GUIDED"
113
+ - "Thực hiện mission tự động"
114
+
115
+
116
+
117
+ ## Tích Hợp Drone Thật (Thay Thế SITL)
118
+
119
+ ### 1. Nguyên tắc
120
+ Kiến trúc hệ thống được thiết kế để không thay đổi code ở backend khi chuyển từ SITL sang drone thật. Backend **luôn luôn** giao tiếp với MAVProxy. Bạn chỉ cần thay đổi "master" connection của MAVProxy từ SITL sang cổng serial của drone thật (ví dụ: `/dev/ttyUSB0`).
121
+
122
+ ### 2. Cấu Hình Telemetry Connection
123
+ ```bash
124
+ # Chỉnh sửa start_complete_droneagent_system.sh
125
+ nano start_complete_droneagent_system.sh
126
+
127
+ # Tìm dòng MAVProxy startup và thay đổi --master
128
+ # Từ: --master=tcp:127.0.0.1:5760
129
+ # Thành: --master=/dev/ttyUSB0,57600
130
+ # (Baud rate 57600 có thể thay đổi tùy vào cấu hình radio của bạn)
131
+ ```
132
+ **Lưu ý:** Khi dùng drone thật, bạn nên vô hiệu hóa việc khởi động SITL trong script `start_complete_droneagent_system.sh`.
133
+
134
+ ## Monitoring và Logs
135
+
136
+ ### Real-time Monitoring
137
+ ```bash
138
+ # Monitor tất cả processes
139
+ watch -n 2 'ps aux | grep -E "(python.*main|mavproxy|arducopter)"'
140
+
141
+ # Monitor network connections
142
+ watch -n 2 'netstat -tulpn | grep -E "(8001|8080|5760|14550|14552)"'
143
+
144
+ # Monitor system resources
145
+ htop
146
+ ```
147
+
148
+ ### Log Analysis
149
+ ```bash
150
+ # Backend logs
151
+ tail -f backend/output.log
152
+
153
+ # MAVProxy logs
154
+ tail -f /tmp/mavproxy.log
155
+
156
+ # Startup logs
157
+ tail -f startup_progress.log
158
+ ```
159
+
160
+ ## Troubleshooting (Xử Lý Sự Cố)
161
+
162
+ ### 1. Lỗi "Address already in use"
163
+ Lỗi này xảy ra khi một port (ví dụ 8001, 8080, 5760) chưa được giải phóng hoàn toàn bởi hệ điều hành sau khi một tiến trình bị dừng đột ngột.
164
+ - **Giải pháp**: Script `start_complete_droneagent_system.sh` đã tích hợp lệnh `fuser -k` để tự động giải phóng các port này khi khởi động. Nếu vẫn gặp lỗi, hãy thử chạy lại script.
165
+
166
+ ### 2. Drone hiện "Disconnected" trên Web UI
167
+ - **Kiểm tra MAVProxy**: Đảm bảo MAVProxy đang chạy và có output tới `udp:127.0.0.1:14552`. Kiểm tra log `/tmp/mavproxy.log`.
168
+ - **Kiểm tra Backend**: Đảm bảo backend đang chạy và không có lỗi trong `backend/output.log`.
169
+ - **Kiểm tra SITL/Drone**: Đảm bảo SITL đang chạy (có port 5760) hoặc drone thật đã kết nối.
170
+
171
+ ### 3. Lỗi "AI is in fallback mode"
172
+ - **Kiểm tra API Key**: Đảm bảo `GEMINI_API_KEY` trong file `backend/.env` là chính xác và còn hiệu lực.
173
+ - **Kiểm tra kết nối mạng**: Backend cần kết nối internet để gọi tới Gemini API.
174
+
175
+ ### 4. Gazebo không khởi động (hoặc gây treo máy)
176
+ - **Tài nguyên hệ thống**: Gazebo rất nặng. Nếu WSL2 của bạn không được cấp đủ RAM (tối thiểu 4GB-6GB), Gazebo có thể không chạy được.
177
+ - **Tắt Gazebo**: Bạn có thể tắt Gazebo trong script `start_complete_droneagent_system.sh` bằng cách thay đổi biến `ENABLE_GAZEBO` thành `false`. Hệ thống vẫn sẽ hoạt động với mô phỏng vật lý của SITL nhưng không có đồ họa 3D.
178
+ ```bash
179
+ # Trong start_complete_droneagent_system.sh
180
+ ENABLE_GAZEBO=false # true để bật, false để tắt
181
+ ```
182
+
183
+ ## Phụ Lục: Chi Tiết Các Cổng Mạng
184
+
185
+ - `localhost:8080`: Giao diện Web Frontend.
186
+ - `localhost:8001`: Backend FastAPI API.
187
+ - `tcp:127.0.0.1:5760`: SITL ArduCopter MAVLink output.
188
+ - `udp:127.0.0.1:14550`: MAVProxy output cho các Ground Control Station (ví dụ QGroundControl).
189
+ - `udp:127.0.0.1:14552`: MAVProxy output **dành riêng** cho Backend `DroneService`.
ai_knowledge_base/ai_instructions.txt ADDED
@@ -0,0 +1,199 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # AI Assistant Instructions - Professional Drone Control
2
+ # COMPREHENSIVE GUIDANCE FOR INTELLIGENT REASONING AND UNDERSTANDING
3
+ # Version 3.0.0 - Updated with Latest Safety Standards and Best Practices
4
+
5
+ ## 🤖 CORE AI IDENTITY AND PRINCIPLES
6
+
7
+ ### Primary Directive
8
+ You are DroneBot, a professional AI assistant specialized in unmanned aerial vehicle (UAV) mission planning and control. You operate ArduPilot/PX4 compatible systems with emphasis on SAFETY FIRST, intelligent reasoning, and comprehensive explanations.
9
+
10
+ ### Core Principles
11
+ - **SAFETY FIRST**: Every decision must prioritize human life, property, and regulatory compliance
12
+ - **INTELLIGENT REASONING**: Demonstrate deep understanding of drone operations, physics, and regulations
13
+ - **COMPREHENSIVE EXPLANATIONS**: Provide detailed reasoning for all decisions and recommendations
14
+ - **PROFESSIONAL EXCELLENCE**: Generate industry-standard mission plans and communications
15
+ - **ADAPTIVE LEARNING**: Continuously improve based on user feedback and operational experience
16
+
17
+ ## 🚁 VEHICLE TYPES AND CAPABILITIES
18
+
19
+ ### 1. Multicopter Platforms
20
+ - **Quadcopters/Hexacopters/Octocopters**: Most common, VTOL capable, hover efficiency
21
+ - **Tricopters**: Specialized, yaw control via servo, high maneuverability
22
+ - **Traditional Helicopters**: Autorotation capable, complex control systems
23
+ - **Coaxial Configurations**: Enhanced stability, industrial applications
24
+
25
+ ### 2. Fixed-Wing Platforms
26
+ - **Conventional Airplanes**: Long endurance, forward flight optimized
27
+ - **Quadplanes**: VTOL + forward flight hybrid, best of both worlds
28
+ - **Flying Wings**: Minimal drag, specialized for mapping/surveillance
29
+
30
+ ### 3. Ground Vehicles (Rovers)
31
+ - **Cars/Trucks**: Autonomous navigation, obstacle avoidance
32
+ - **Boats**: Surface water operations, current compensation
33
+ - **Tracked Vehicles**: Rough terrain capability
34
+
35
+ ### 4. Underwater Vehicles (Submarines)
36
+ - **Depth Control**: Pressure-based navigation
37
+ - **Buoyancy Management**: Ballast system control
38
+ - **Limited Communication**: Acoustic positioning systems
39
+
40
+ ## 🧠 CRITICAL REASONING FRAMEWORK
41
+
42
+ ### Phase 1: Intent Analysis and Risk Assessment
43
+ 1. **Parse User Intent**: Extract mission objectives, constraints, and preferences from natural language
44
+ 2. **Context Understanding**: Consider environmental conditions, regulatory constraints, and technical limitations
45
+ 3. **Risk Assessment**: Evaluate all potential hazards including weather, terrain, airspace restrictions
46
+ 4. **Capability Matching**: Ensure drone capabilities match mission requirements
47
+
48
+ ### Phase 2: Technical Feasibility Analysis
49
+ 1. **Battery Analysis**: Calculate energy requirements vs available capacity (minimum 30% reserve)
50
+ 2. **Range Assessment**: GPS accuracy, signal strength, and operational boundaries
51
+ 3. **Payload Evaluation**: Weight, power consumption, and operational requirements
52
+ 4. **Environmental Factors**: Wind, temperature, humidity, and visibility impacts
53
+
54
+ ### Phase 3: Mission Planning and Optimization
55
+ 1. **Route Optimization**: Most efficient path considering wind, terrain, and obstacles
56
+ 2. **Altitude Planning**: Optimal heights for mission type, visibility, and safety
57
+ 3. **Speed Optimization**: Balance between efficiency, stability, and mission requirements
58
+ 4. **Contingency Planning**: Emergency procedures, alternate landing sites, fail-safes
59
+
60
+ ### Phase 4: Execution and Monitoring
61
+ 1. **Real-time Monitoring**: Track performance metrics and environmental conditions
62
+ 2. **Adaptive Adjustments**: Modify mission parameters based on real-time data
63
+ 3. **Emergency Response**: Immediate action for critical situations
64
+ 4. **Post-mission Analysis**: Learning and improvement for future operations
65
+
66
+ ## 📋 MISSION PLANNING INTELLIGENCE
67
+
68
+ ### Coordinate System Expertise
69
+ - **WGS84 Standard**: Primary coordinate system for all GPS operations
70
+ - **UTM Conversion**: Universal Transverse Mercator for local planning
71
+ - **MGRS Integration**: Military Grid Reference System for precision operations
72
+ - **Relative Positioning**: Local coordinate systems for precision work
73
+
74
+ ### Advanced Mission Types
75
+ 1. **Survey/Mapping Missions**:
76
+ - Grid patterns with 70-80% overlap
77
+ - Optimal altitude: 50-120m based on camera specifications
78
+ - Speed: 8-12 m/s for stability
79
+ - Ground resolution optimization
80
+
81
+ 2. **Inspection Missions**:
82
+ - Close proximity operations (10-50m altitude)
83
+ - Slow speed requirements (3-8 m/s)
84
+ - Multi-angle coverage for comprehensive inspection
85
+ - High-precision waypoint navigation
86
+
87
+ 3. **Surveillance/Patrol Missions**:
88
+ - Perimeter patterns with sensor coverage optimization
89
+ - Altitude: 30-80m for overview while maintaining detail
90
+ - Speed: 8-15 m/s for area coverage efficiency
91
+ - Loiter capabilities for extended observation
92
+
93
+ 4. **Photography/Videography**:
94
+ - Strategic positioning for optimal lighting angles
95
+ - Gimbal control integration
96
+ - Multi-pass coverage for different perspectives
97
+ - Weather-dependent scheduling
98
+
99
+ ### Real-time Adaptation
100
+ - **Weather Compensation**: Adjust altitude and speed for wind conditions
101
+ - **Battery Optimization**: Dynamic power management based on remaining capacity
102
+ - **Obstacle Response**: Real-time path recalculation for dynamic environments
103
+ - **Communication Quality**: Adaptive data rates based on signal strength
104
+
105
+ ## 🛡️ COMPREHENSIVE SAFETY PROTOCOLS
106
+
107
+ ### Pre-Flight Safety Checks
108
+ - **Weather Assessment**: Wind < 20 knots, no precipitation, good visibility
109
+ - **GPS Verification**: Minimum 8 satellites, HDOP < 2.0, stable lock
110
+ - **Battery Health**: Voltage > 3.7V/cell, capacity > 80%, balanced cells
111
+ - **Hardware Inspection**: Motor functionality, propeller condition, frame integrity
112
+ - **Software Validation**: Firmware up-to-date, parameter consistency, telemetry link
113
+ - **Regulatory Compliance**: Local airspace restrictions, NOTAMs, permit verification
114
+
115
+ ### In-Flight Safety Monitoring
116
+ - **Telemetry Integrity**: Continuous data link, real-time parameter monitoring
117
+ - **Geofence Enforcement**: Automatic RTL for boundary violations
118
+ - **Battery Management**: Dynamic power optimization, low-voltage warnings
119
+ - **Obstacle Avoidance**: Sensor-based collision prevention (if equipped)
120
+ - **Communication Loss**: Automatic RTL after failsafe timeout
121
+ - **Emergency Protocols**: Immediate landing for critical system failures
122
+
123
+ ### Post-Flight Safety Procedures
124
+ - **Data Review**: Analyze telemetry for anomalies and improvement opportunities
125
+ - **Hardware Check**: Inspect for damage, wear, or contamination
126
+ - **Log Analysis**: Review system logs for potential issues
127
+ - **Maintenance Planning**: Schedule service based on operational hours
128
+
129
+ ## 🎯 ERROR HANDLING AND RECOVERY
130
+
131
+ ### Common Error Scenarios
132
+ 1. **GPS Loss**: Immediate switch to position hold, gradual RTL when signal recovered
133
+ 2. **Low Battery**: Progressive warnings, automatic RTL at critical threshold
134
+ 3. **Communication Loss**: Configurable failsafe actions (RTL, land, continue)
135
+ 4. **Motor Failure**: Emergency landing protocols, autorotation for helicopters
136
+ 5. **Sensor Malfunction**: Fallback to redundant systems, conservative operation
137
+
138
+ ### Recovery Strategies
139
+ 1. **Immediate Actions**: Stop current operation, assess situation, initiate failsafe
140
+ 2. **Alternative Planning**: Generate new mission path around obstacles/failures
141
+ 3. **Progressive Degradation**: Maintain partial functionality when possible
142
+ 4. **Emergency Landing**: Identify and execute safest landing option
143
+
144
+ ### User Communication
145
+ - **Clear Error Messages**: Explain what went wrong and why
146
+ - **Actionable Guidance**: Provide specific steps to resolve issues
147
+ - **Preventive Measures**: Suggest how to avoid similar issues in future
148
+ - **Alternative Options**: Offer different approaches when primary method fails
149
+
150
+ ## 💬 COMMUNICATION AND USER EXPERIENCE
151
+
152
+ ### Interaction Style
153
+ - **Professional yet Approachable**: Technical accuracy with clear explanations
154
+ - **Contextual Awareness**: Remember user preferences and past interactions
155
+ - **Educational Focus**: Explain concepts to build user understanding
156
+ - **Proactive Guidance**: Anticipate user needs and offer helpful suggestions
157
+
158
+ ### Response Structure
159
+ 1. **Acknowledge Request**: Show understanding of user intent
160
+ 2. **Provide Analysis**: Explain reasoning and considerations
161
+ 3. **Present Solution**: Clear, actionable recommendations
162
+ 4. **Explain Safety**: Highlight safety considerations and precautions
163
+ 5. **Offer Alternatives**: Provide options when multiple approaches exist
164
+
165
+ ### Error Communication
166
+ - **Empathetic Tone**: Acknowledge user frustration while maintaining professionalism
167
+ - **Clear Diagnosis**: Explain the root cause in understandable terms
168
+ - **Immediate Solutions**: Provide step-by-step resolution instructions
169
+ - **Preventive Guidance**: Explain how to avoid similar issues
170
+
171
+ ## 🌍 REGULATORY COMPLIANCE
172
+
173
+ ### International Standards
174
+ - **ICAO Guidelines**: International Civil Aviation Organization standards
175
+ - **FAA Regulations**: Federal Aviation Administration rules (US)
176
+ - **EASA Standards**: European Aviation Safety Agency requirements
177
+ - **Local Regulations**: Country-specific drone operation laws
178
+
179
+ ### Operational Limits
180
+ - **Altitude Restrictions**: Maximum heights based on airspace classification
181
+ - **Distance Limits**: Visual line of sight and operational boundaries
182
+ - **Time Restrictions**: Operational windows and curfew compliance
183
+ - **Weather Minimums**: Visibility, wind, and precipitation limits
184
+
185
+ ## 🔄 CONTINUOUS IMPROVEMENT
186
+
187
+ ### Learning Mechanisms
188
+ - **User Feedback Integration**: Learn from user corrections and preferences
189
+ - **Performance Analysis**: Review mission outcomes to improve planning
190
+ - **Error Pattern Recognition**: Identify and prevent recurring issues
191
+ - **Technology Updates**: Stay current with drone technology advancements
192
+
193
+ ### Adaptation Strategies
194
+ - **Environmental Learning**: Adjust for local weather patterns and terrain
195
+ - **User Behavior Analysis**: Adapt to individual user preferences and patterns
196
+ - **System Performance**: Optimize based on hardware capabilities and limitations
197
+ - **Regulatory Updates**: Maintain current knowledge of changing regulations
198
+
199
+ Remember: Your ultimate goal is to be the most reliable, safe, and intelligent drone mission planning assistant possible. Every decision should prioritize SAFETY, demonstrate deep technical understanding, and provide exceptional user experience.
ai_knowledge_base/copter_flightmodes.txt ADDED
@@ -0,0 +1,247 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copter Flight Modes - Professional AI Knowledge Base
2
+ # Complete mapping of Copter flight modes for intelligent reasoning
3
+
4
+ ## 🎮 MANUAL CONTROL MODES
5
+
6
+ ### STABILIZE (Mode 0)
7
+ - **Control**: Direct angle control with RC sticks
8
+ - **Throttle**: Direct control via throttle stick
9
+ - **Usage**: Basic flying, training, manual control
10
+ - **Safety**: Most forgiving mode, good for beginners
11
+ - **GPS Required**: No
12
+ - **Best For**: Learning to fly, basic maneuvers
13
+
14
+ ### ACRO (Mode 1)
15
+ - **Control**: Direct body-frame angular rate control
16
+ - **Throttle**: Direct control via throttle stick
17
+ - **Usage**: Aerobatic flying, extreme maneuvers
18
+ - **Safety**: Advanced mode, requires pilot skill
19
+ - **GPS Required**: No
20
+ - **Best For**: Experienced pilots, 3D flying
21
+
22
+ ## 🏠 POSITION HOLD MODES
23
+
24
+ ### ALT_HOLD (Mode 2)
25
+ - **Control**: Angle control with altitude hold
26
+ - **Throttle**: Controls climb/descent rate
27
+ - **Usage**: Hovering, altitude maintenance
28
+ - **Safety**: Good for photography, inspection
29
+ - **GPS Required**: No (uses barometer)
30
+ - **Best For**: Stationary work, aerial photography
31
+
32
+ ### POSHOLD (Mode 16)
33
+ - **Control**: Position and altitude hold with manual override
34
+ - **Throttle**: Controls climb/descent rate
35
+ - **Usage**: Precise position maintenance
36
+ - **Safety**: Excellent for inspection work
37
+ - **GPS Required**: Yes
38
+ - **Best For**: Structure inspection, precise hovering
39
+
40
+ ### LOITER (Mode 5)
41
+ - **Control**: 3D speed control with position hold
42
+ - **Throttle**: Controls climb/descent rate
43
+ - **Usage**: Surveillance, waiting, precision work
44
+ - **Safety**: Automatically holds position
45
+ - **GPS Required**: Yes
46
+ - **Best For**: Security monitoring, waiting for commands
47
+
48
+ ### CIRCLE (Mode 7)
49
+ - **Control**: Automatic circular flight pattern
50
+ - **Throttle**: Automatic altitude and speed control
51
+ - **Usage**: Search patterns, area surveillance
52
+ - **Safety**: Predictable flight path
53
+ - **GPS Required**: Yes
54
+ - **Best For**: Area coverage, search operations
55
+
56
+ ## 🤖 AUTONOMOUS MODES
57
+
58
+ ### AUTO (Mode 3)
59
+ - **Control**: Full autonomous waypoint following
60
+ - **Throttle**: Automatic altitude and speed control
61
+ - **Usage**: Pre-planned mission execution
62
+ - **Safety**: Follows programmed flight path
63
+ - **GPS Required**: Yes
64
+ - **Best For**: Survey missions, automated inspections
65
+
66
+ ### GUIDED (Mode 4)
67
+ - **Control**: Fly to coordinates via MAVLink commands
68
+ - **Throttle**: Automatic altitude and speed control
69
+ - **Usage**: Real-time mission updates, follow-me
70
+ - **Safety**: Responds to external commands
71
+ - **GPS Required**: Yes
72
+ - **Best For**: Dynamic missions, API control
73
+
74
+ ### GUIDED_NOGPS (Mode 20)
75
+ - **Control**: Attitude and altitude control via commands
76
+ - **Throttle**: Manual throttle control
77
+ - **Usage**: Indoor flying, GPS-denied environments
78
+ - **Safety**: Requires careful altitude management
79
+ - **GPS Required**: No
80
+ - **Best For**: Indoor operations, testing
81
+
82
+ ## 🚨 EMERGENCY & SAFETY MODES
83
+
84
+ ### RTL (Mode 6)
85
+ - **Control**: Automatic return to launch point
86
+ - **Throttle**: Automatic climb and descent
87
+ - **Usage**: Emergency return home
88
+ - **Safety**: HIGHEST PRIORITY - overrides all other commands
89
+ - **GPS Required**: Yes (for precision RTL)
90
+ - **Best For**: Emergency situations, low battery
91
+
92
+ ### SMART_RTL (Mode 21)
93
+ - **Control**: Intelligent return by retracing flight path
94
+ - **Throttle**: Automatic climb and descent
95
+ - **Usage**: Safe return avoiding obstacles
96
+ - **Safety**: Smarter than standard RTL
97
+ - **GPS Required**: Yes
98
+ - **Best For**: Complex environments, obstacle avoidance
99
+
100
+ ### LAND (Mode 9)
101
+ - **Control**: Automatic landing at current position
102
+ - **Throttle**: Controlled descent to surface
103
+ - **Usage**: Emergency landing, mission termination
104
+ - **Safety**: Safe landing with position hold
105
+ - **GPS Required**: No
106
+ - **Best For**: Emergency landing situations
107
+
108
+ ### BRAKE (Mode 17)
109
+ - **Control**: Full brake using GPS and inertial systems
110
+ - **Throttle**: Automatic deceleration
111
+ - **Usage**: Emergency stop, rapid deceleration
112
+ - **Safety**: Maximum deceleration without GPS loss
113
+ - **GPS Required**: Yes
114
+ - **Best For**: Collision avoidance, emergency stops
115
+
116
+ ## 🎪 SPECIALIZED MODES
117
+
118
+ ### DRIFT (Mode 11)
119
+ - **Control**: Semi-autonomous position and yaw control
120
+ - **Throttle**: Manual control
121
+ - **Usage**: Smooth cinematic flying
122
+ - **Safety**: Limited use, requires skill
123
+ - **GPS Required**: Yes
124
+ - **Best For**: Cinematography, smooth movements
125
+
126
+ ### SPORT (Mode 13)
127
+ - **Control**: Manual earth-frame rate control
128
+ - **Throttle**: Manual control
129
+ - **Usage**: Sport flying, racing
130
+ - **Safety**: Advanced mode for experienced pilots
131
+ - **GPS Required**: Yes
132
+ - **Best For**: Competitive flying, high-speed maneuvers
133
+
134
+ ### THROW (Mode 18)
135
+ - **Control**: Automatic launch after throwing
136
+ - **Throttle**: Automatic after launch
137
+ - **Usage**: Hand-launch operations
138
+ - **Safety**: Designed for safe hand-launch
139
+ - **GPS Required**: No
140
+ - **Best For**: Portable operations, emergency launch
141
+
142
+ ### FLIP (Mode 14)
143
+ - **Control**: Automatic 360-degree flip
144
+ - **Throttle**: Automatic during flip
145
+ - **Usage**: Acrobatic demonstrations
146
+ - **Safety**: Risky maneuver, use with caution
147
+ - **GPS Required**: No
148
+ - **Best For**: Shows, demonstrations
149
+
150
+ ## 🛠️ MAINTENANCE & TESTING MODES
151
+
152
+ ### AUTOTUNE (Mode 15)
153
+ - **Control**: Automatic PID gain tuning
154
+ - **Throttle**: Manual control during tuning
155
+ - **Usage**: Performance optimization
156
+ - **Safety**: Requires open space, monitor closely
157
+ - **GPS Required**: No
158
+ - **Best For**: Performance improvement, setup
159
+
160
+ ### SYSTEMID (Mode 25)
161
+ - **Control**: Automated system identification
162
+ - **Throttle**: Automatic test signals
163
+ - **Usage**: Control system analysis
164
+ - **Safety**: Test mode only, not for normal flying
165
+ - **GPS Required**: No
166
+ - **Best For**: Advanced tuning, system analysis
167
+
168
+ ## 🚁 HELICOPTER-SPECIFIC MODES
169
+
170
+ ### AUTOROTATE (Mode 26)
171
+ - **Control**: Autonomous autorotation landing
172
+ - **Throttle**: Automatic collective management
173
+ - **Usage**: Emergency landing for helicopters
174
+ - **Safety**: Critical for helicopter emergencies
175
+ - **GPS Required**: No
176
+ - **Best For**: Helicopter emergency situations
177
+
178
+ ### AUTO_RTL (Mode 27)
179
+ - **Control**: Return to launch using Auto mission path
180
+ - **Throttle**: Automatic climb and descent
181
+ - **Usage**: Mission-aware return home
182
+ - **Safety**: Uses planned mission path
183
+ - **GPS Required**: Yes
184
+ - **Best For**: Mission continuity, safe returns
185
+
186
+ ### TURTLE (Mode 28)
187
+ - **Control**: Flip vehicle to recover from crash
188
+ - **Throttle**: Automatic during recovery
189
+ - **Usage**: Post-crash recovery
190
+ - **Safety**: Last resort recovery mode
191
+ - **GPS Required**: No
192
+ - **Best For**: Emergency recovery situations
193
+
194
+ ## 🔄 MODE TRANSITION RULES
195
+
196
+ ### Safe Transitions
197
+ - **Manual → Auto**: Always safe, GPS recommended
198
+ - **Loiter → RTL**: Safe, preserves position awareness
199
+ - **Guided → Auto**: Safe, maintains mission context
200
+ - **Any Mode → RTL**: Always safe, emergency priority
201
+
202
+ ### Risky Transitions
203
+ - **Auto → Stabilize**: May cause disorientation
204
+ - **Land → Any Mode**: Can cause immediate takeoff
205
+ - **Acro → Auto**: May cause erratic behavior
206
+ - **Sport → RTL**: High speed may affect accuracy
207
+
208
+ ## 🛡️ SAFETY CONSIDERATIONS BY MODE
209
+
210
+ ### High Safety Modes (Recommended for Most Operations)
211
+ - **LOITER**: Excellent for safety, holds position
212
+ - **POSHOLD**: Precise control with position hold
213
+ - **ALT_HOLD**: Good for altitude-critical work
214
+ - **RTL/SMART_RTL**: Essential emergency modes
215
+
216
+ ### Medium Safety Modes (Use with Caution)
217
+ - **AUTO**: Good for planned missions
218
+ - **GUIDED**: Good for API control
219
+ - **LAND**: Safe for controlled landings
220
+ - **BRAKE**: Safe for emergency stops
221
+
222
+ ### Low Safety Modes (Advanced Users Only)
223
+ - **STABILIZE**: Basic mode, requires skill
224
+ - **ACRO**: Expert mode, high risk
225
+ - **DRIFT**: Specialized, limited use
226
+ - **FLIP**: Dangerous, demonstration only
227
+
228
+ ## 📊 PERFORMANCE CHARACTERISTICS
229
+
230
+ ### Battery Usage by Mode
231
+ - **STABILIZE/ACRO**: High (constant pilot input)
232
+ - **ALT_HOLD/LOITER**: Medium (position maintenance)
233
+ - **AUTO/GUIDED**: Low-Medium (efficient path following)
234
+ - **RTL/LAND**: Low (optimized return path)
235
+
236
+ ### GPS Requirements
237
+ - **Essential for**: AUTO, GUIDED, RTL, LOITER, POSHOLD, CIRCLE
238
+ - **Recommended for**: ALT_HOLD, BRAKE, DRIFT, SPORT
239
+ - **Not Required for**: STABILIZE, ACRO, LAND, AUTOTUNE, FLIP, THROW
240
+
241
+ ### Skill Level Requirements
242
+ - **Beginner**: STABILIZE, ALT_HOLD, LOITER, LAND
243
+ - **Intermediate**: AUTO, GUIDED, RTL, BRAKE, CIRCLE
244
+ - **Advanced**: ACRO, DRIFT, SPORT, FLIP, THROW
245
+ - **Expert**: AUTOTUNE, SYSTEMID, AUTOROTATE, TURTLE
246
+
247
+ This comprehensive flight mode reference provides everything needed for safe and effective copter operations across all mission types.
ai_knowledge_base/drone-ai-knowledge-base.md ADDED
@@ -0,0 +1,828 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🚁 COMPREHENSIVE DRONE CONTROL & MISSION PLANNING KNOWLEDGE BASE
2
+ # Version 5.0 - Professional-Grade AI-Driven Mission Planning
3
+
4
+ ## 📍 GPS COORDINATE SYSTEM FUNDAMENTALS
5
+
6
+ ### Core Principles
7
+ - **Latitude** measures north-south position (0° at equator, ±90° at poles)
8
+ - **Longitude** measures east-west position (0° at Prime Meridian, ±180° at International Date Line)
9
+ - **Altitude** typically referenced to WGS84 ellipsoid or EGM96 geoid
10
+
11
+ ### Direction Rules
12
+ - **North**: Latitude INCREASES
13
+ - **South**: Latitude DECREASES
14
+ - **East**: Longitude INCREASES
15
+ - **West**: Longitude DECREASES
16
+
17
+ ### Enhanced Conversion Formulas
18
+ ```
19
+ Earth's equatorial radius: 6,378,137 meters
20
+ Earth's polar radius: 6,356,752 meters (flattened spheroid)
21
+
22
+ 1 degree latitude ≈ 111,000 meters (constant globally)
23
+ 1 degree longitude ≈ 111,000 × cos(latitude) meters (varies by latitude)
24
+
25
+ High-precision conversion (Haversine formula):
26
+ - Distance = 2 × R × arcsin(sqrt(sin²(Δlat/2) + cos(lat1) × cos(lat2) × sin²(Δlon/2)))
27
+ - Where R = 6,371,000 meters (mean radius)
28
+ ```
29
+
30
+ ### Precise Coordinate Calculation
31
+ For accurate coordinate offsets using Vincenty formula (6 decimal places precision):
32
+ ```python
33
+ def calculate_new_coordinates(lat, lon, distance_m, bearing_deg):
34
+ """
35
+ Calculate new coordinates using Vincenty formula for high accuracy
36
+ """
37
+ R = 6371000.0 # Mean Earth radius in meters
38
+ lat_rad = math.radians(lat)
39
+ lon_rad = math.radians(lon)
40
+ bearing_rad = math.radians(bearing_deg)
41
+
42
+ # Angular distance
43
+ angular_distance = distance_m / R
44
+
45
+ # Calculate new latitude
46
+ new_lat_rad = math.asin(
47
+ math.sin(lat_rad) * math.cos(angular_distance) +
48
+ math.cos(lat_rad) * math.sin(angular_distance) * math.cos(bearing_rad)
49
+ )
50
+
51
+ # Calculate new longitude
52
+ new_lon_rad = lon_rad + math.atan2(
53
+ math.sin(bearing_rad) * math.sin(angular_distance) * math.cos(lat_rad),
54
+ math.cos(angular_distance) - math.sin(lat_rad) * math.sin(new_lat_rad)
55
+ )
56
+
57
+ return math.degrees(new_lat_rad), math.degrees(new_lon_rad)
58
+
59
+ # Usage example
60
+ start_lat, start_lon = 16.047, 108.206
61
+ new_lat, new_lon = calculate_new_coordinates(start_lat, start_lon, 100, 0) # 100m North
62
+ ```
63
+
64
+ ### Coordinate System Standards
65
+ - **WGS84**: Primary GPS coordinate system, EPSG:4326
66
+ - **UTM**: Universal Transverse Mercator, metric grid system
67
+ - **MGRS**: Military Grid Reference System, 10m precision
68
+ - **Local ENU**: East-North-Up for precision work
69
+ - **Altitude References**:
70
+ - MSL (Mean Sea Level)
71
+ - AGL (Above Ground Level)
72
+ - WGS84 ellipsoid
73
+ - EGM96 geoid
74
+
75
+ ### Precision Considerations
76
+ - **GPS**: 3-5m accuracy (standard), 1-3m (differential), <1m (RTK)
77
+ - **Barometric**: ±10m accuracy for altitude
78
+ - **Inertial**: Drift over time, requires periodic GPS updates
79
+ - **Combined**: Best accuracy with sensor fusion
80
+
81
+ ## 🔗 MAVLINK PROTOCOL ESSENTIALS
82
+
83
+ ### MAVLink Architecture
84
+ - **Message-based protocol** for UAV communication
85
+ - **Microservices architecture** with heartbeat and status messages
86
+ - **Command/Response pattern** with acknowledgment system
87
+ - **Extensible design** supporting custom messages
88
+ - **Multi-transport** (UART, TCP, UDP, CAN)
89
+
90
+ ### Core MAVLink Commands
91
+
92
+ #### NAV_TAKEOFF (Command ID: 22)
93
+ ```
94
+ Purpose: Controlled takeoff to specified altitude
95
+ Safety: Requires GPS lock and battery checks
96
+ Parameters:
97
+ param1: Minimum pitch (degrees, 0 for multicopters)
98
+ param2: Empty (reserved)
99
+ param3: Empty (reserved)
100
+ param4: Yaw angle (degrees, NaN = current heading)
101
+ param5: Latitude (WGS84)
102
+ param6: Longitude (WGS84)
103
+ param7: Altitude (meters, frame-dependent)
104
+ Frames: GLOBAL_RELATIVE_ALT (recommended), GLOBAL
105
+ Best Practice: Always use GLOBAL_RELATIVE_ALT for safety
106
+ ```
107
+
108
+ #### NAV_WAYPOINT (Command ID: 16)
109
+ ```
110
+ Purpose: Navigate to specific GPS waypoint
111
+ Safety: Includes acceptance radius for precision
112
+ Parameters:
113
+ param1: Hold time (seconds, 0 = no hold)
114
+ param2: Acceptance radius (meters, 2-10 recommended)
115
+ param3: Pass through radius (meters, 0 = straight to point)
116
+ param4: Desired yaw (degrees, NaN = maintain current)
117
+ param5: Latitude (WGS84)
118
+ param6: Longitude (WGS84)
119
+ param7: Altitude (meters, frame-dependent)
120
+ Frames: GLOBAL_RELATIVE_ALT, GLOBAL
121
+ Optimization: Use appropriate acceptance radius for mission type
122
+ ```
123
+
124
+ #### NAV_LAND (Command ID: 21)
125
+ ```
126
+ Purpose: Controlled landing at specified location
127
+ Safety: Most critical command - requires careful altitude management
128
+ Parameters:
129
+ param1: Descent rate (m/s, 0 = default ~0.5 m/s)
130
+ param2: Empty (reserved)
131
+ param3: Empty (reserved)
132
+ param4: Yaw angle (degrees, NaN = current)
133
+ param5: Latitude (0 = current position)
134
+ param6: Longitude (0 = current position)
135
+ param7: Altitude (0 = land at surface level)
136
+ Frames: GLOBAL_RELATIVE_ALT, GLOBAL
137
+ Emergency: Can be interrupted by failsafe conditions
138
+ ```
139
+
140
+ #### NAV_RETURN_TO_LAUNCH (Command ID: 20)
141
+ ```
142
+ Purpose: Emergency return to launch/home position
143
+ Safety: HIGHEST PRIORITY - overrides all other commands
144
+ Parameters:
145
+ All parameters: Empty (ignored)
146
+ Frame: MAV_FRAME_MISSION (special case)
147
+ Behavior:
148
+ - Climbs to RTL_ALTITUDE parameter
149
+ - Returns to launch position
150
+ - Lands automatically
151
+ - Cannot be interrupted except by failsafe
152
+ Failsafe: Automatically triggered by low battery, RC loss, etc.
153
+ ```
154
+
155
+ ### MAVLink Coordinate Frames
156
+
157
+ #### MAV_FRAME_GLOBAL_RELATIVE_ALT_INT (ID: 6) - RECOMMENDED
158
+ - **Most widely used and safest frame for drone missions**
159
+ - Altitude relative to home/takeoff position (AGL)
160
+ - Coordinates as integers (degrees × 10^7) for precision
161
+ - **Best Practice**: Use this frame for 99% of missions
162
+ - **Safety**: Prevents altitude errors from terrain variations
163
+ - **Compatibility**: Preferred by QGroundControl and all major autopilots
164
+
165
+ #### MAV_FRAME_GLOBAL_RELATIVE_ALT (ID: 3)
166
+ - Altitude relative to home/takeoff position (AGL)
167
+ - Coordinates as floating-point degrees
168
+ - **Use Case**: When integer precision not required
169
+ - **Safety**: Safer than MSL-based frames
170
+
171
+ #### MAV_FRAME_GLOBAL_INT (ID: 5)
172
+ - Altitude relative to mean sea level (MSL)
173
+ - Coordinates as integers for bandwidth optimization
174
+ - **Risk**: MSL altitude can cause issues over varying terrain
175
+ - **Use Case**: Long-range missions where MSL is required
176
+
177
+ #### MAV_FRAME_GLOBAL (ID: 0)
178
+ - Altitude relative to mean sea level (MSL)
179
+ - Coordinates as floating-point degrees
180
+ - **Risk**: MSL altitude variations over varying terrain
181
+ - **Use Case**: Survey missions requiring absolute altitude
182
+
183
+ #### MAV_FRAME_MISSION (ID: 2)
184
+ - **Special purpose frame for mission commands**
185
+ - Not a coordinate frame - indicates mission-specific command
186
+ - **Used for**: RTL, mode changes, non-positioning commands
187
+ - **Safety**: Highest priority command frame
188
+
189
+ ## 📋 QGROUNDCONTROL MISSION STRUCTURE
190
+
191
+ ### Complete QGC Plan File Format
192
+ ```json
193
+ {
194
+ "fileType": "Plan",
195
+ "groundStation": "QGroundControl",
196
+ "version": 1,
197
+ "mission": {
198
+ "cruiseSpeed": 15,
199
+ "firmwareType": 12,
200
+ "globalPlanAltitudeMode": 1,
201
+ "hoverSpeed": 5,
202
+ "items": [
203
+ {
204
+ "type": "SimpleItem",
205
+ "command": 22,
206
+ "frame": 3,
207
+ "params": [0, 0, 0, null, 16.047000, 108.206000, 50],
208
+ "autoContinue": true
209
+ }
210
+ ],
211
+ "plannedHomePosition": [16.047000, 108.206000, 50],
212
+ "vehicleType": 2,
213
+ "version": 2
214
+ },
215
+ "geoFence": {"circles": [], "polygons": [], "version": 2},
216
+ "rallyPoints": {"points": [], "version": 2}
217
+ }
218
+ ```
219
+
220
+ ### Key QGC Fields
221
+ - **firmwareType**: 12=PX4, 3=ArduPilot
222
+ - **globalPlanAltitudeMode**: 0=Absolute, 1=Relative
223
+ - **vehicleType**: 2=Quadrotor, 1=Fixed Wing
224
+ - **command**: MAV_CMD enum value
225
+ - **frame**: MAV_FRAME enum value
226
+ - **params**: Array of 7 command parameters
227
+ - **autoContinue**: Continue to next waypoint automatically
228
+
229
+ ## 🛩️ DRONE NAVIGATION PRINCIPLES
230
+
231
+ ### Straight Line Navigation
232
+ For "go south 100m" type commands:
233
+ ```python
234
+ def create_straight_line_waypoints(start_lat, start_lon, bearing, distance, num_points):
235
+ waypoints = []
236
+ segment_distance = distance / num_points
237
+
238
+ for i in range(num_points + 1):
239
+ current_distance = i * segment_distance
240
+ lat, lon = calculate_coordinate_offset(start_lat, start_lon, current_distance, bearing)
241
+ waypoints.append({"lat": lat, "lon": lon})
242
+
243
+ return waypoints
244
+ ```
245
+
246
+ ### Mission Pattern Types
247
+
248
+ #### 1. Straight Line Mission
249
+ - **Use case**: Point-to-point navigation
250
+ - **Spacing**: 100-500m for long distances
251
+ - **Example**: Simple transit between locations
252
+
253
+ #### 2. Grid Survey Pattern
254
+ - **Use case**: Mapping, photography, area inspection
255
+ - **Pattern**: Lawnmower/boustrophedon
256
+ - **Spacing**: 20-50m depending on camera requirements
257
+ - **Altitude**: 60-120m AGL
258
+
259
+ #### 3. Circular Patrol Pattern
260
+ - **Use case**: Perimeter security, surveillance
261
+ - **Pattern**: Waypoints around circle perimeter
262
+ - **Spacing**: 50-200m based on sensor coverage
263
+ - **Altitude**: 30-80m AGL
264
+
265
+ #### 4. Search Pattern
266
+ - **Use case**: Search and rescue, area coverage
267
+ - **Pattern**: Expanding square or parallel tracks
268
+ - **Spacing**: 10-30m for detailed examination
269
+
270
+ ## ✈️ COMMON DRONE MISSION TYPES
271
+
272
+ ### Survey/Mapping Missions
273
+ - **Altitude**: 60-120m AGL
274
+ - **Speed**: 10-15 m/s
275
+ - **Overlap**: 75%+ for image processing
276
+ - **Pattern**: Grid survey with consistent altitude
277
+
278
+ ### Inspection Flights
279
+ - **Altitude**: 10-50m AGL for detail
280
+ - **Speed**: 3-8 m/s for stability
281
+ - **Approach**: Waypoints around structure
282
+ - **Pattern**: Multi-altitude passes
283
+
284
+ ### Patrol Missions
285
+ - **Altitude**: 30-80m AGL for overview
286
+ - **Speed**: 8-12 m/s
287
+ - **Pattern**: Perimeter or figure-8
288
+ - **Coverage**: Overlapping sensor footprints
289
+
290
+ ### Photography Missions
291
+ - **Altitude**: 20-100m depending on subject
292
+ - **Speed**: 5-10 m/s for stability
293
+ - **Timing**: Account for lighting conditions
294
+ - **Positioning**: Consider sun angle and shadows
295
+
296
+ ## 🛡️ SAFETY AND BEST PRACTICES
297
+
298
+ ### Altitude Safety Guidelines
299
+ - **Minimum AGL**: 10m (except takeoff/landing)
300
+ - **Maximum legal**: 400ft (122m) AGL in most countries
301
+ - **Obstacle clearance**: 20m minimum above highest obstacle
302
+ - **Urban areas**: 50-80m for noise reduction
303
+ - **Emergency altitude**: Plan alternative altitudes for wind/obstacles
304
+
305
+ ### Coordinate Validation
306
+ ```python
307
+ def validate_coordinates(lat, lon):
308
+ errors = []
309
+ if lat < -90 or lat > 90:
310
+ errors.append("Invalid latitude: must be -90 to 90")
311
+ if lon < -180 or lon > 180:
312
+ errors.append("Invalid longitude: must be -180 to 180")
313
+ return errors
314
+ ```
315
+
316
+ ### Mission Planning Safety Checks
317
+ 1. **Pre-flight validation**:
318
+ - All coordinates within valid ranges
319
+ - Waypoints within operational boundaries
320
+ - Adequate obstacle clearance
321
+
322
+ 2. **Battery planning**:
323
+ - 30% reserve minimum
324
+ - Account for headwinds
325
+ - Plan shorter segments for safety
326
+
327
+ 3. **Failsafe planning**:
328
+ - Return-to-launch as final command
329
+ - Loss-of-communication procedures
330
+ - Emergency landing sites identified
331
+
332
+ ## 🔧 COORDINATE CALCULATION MODULE
333
+
334
+ ### Basic Offset Calculations
335
+ ```python
336
+ # Simple approximation (good for short distances < 10km)
337
+ def simple_offset(lat, lon, distance_m, direction):
338
+ lat_deg_per_m = 1.0 / 111000.0
339
+ lon_deg_per_m = 1.0 / (111000.0 * math.cos(math.radians(lat)))
340
+
341
+ if direction == 'north':
342
+ return lat + distance_m * lat_deg_per_m, lon
343
+ elif direction == 'south':
344
+ return lat - distance_m * lat_deg_per_m, lon
345
+ elif direction == 'east':
346
+ return lat, lon + distance_m * lon_deg_per_m
347
+ elif direction == 'west':
348
+ return lat, lon - distance_m * lon_deg_per_m
349
+ ```
350
+
351
+ ### Direction Vector Library
352
+ ```python
353
+ # Bearing definitions (degrees from north, clockwise)
354
+ BEARINGS = {
355
+ 'north': 0,
356
+ 'northeast': 45,
357
+ 'east': 90,
358
+ 'southeast': 135,
359
+ 'south': 180,
360
+ 'southwest': 225,
361
+ 'west': 270,
362
+ 'northwest': 315
363
+ }
364
+ ```
365
+
366
+ ## 🎯 TROUBLESHOOTING COMMON ERRORS
367
+
368
+ ### Coordinate Calculation Errors
369
+ **Problem**: Wrong coordinates (like 15.99138888888889, 16.108 instead of 16, 180)
370
+ **Solution**:
371
+ - Use proper coordinate system understanding
372
+ - Latitude changes for north/south movement
373
+ - Longitude changes for east/west movement
374
+ - Apply correct mathematical formulas
375
+
376
+ ### Mission Pattern Problems
377
+ **Problem**: Square patterns instead of straight lines
378
+ **Solution**:
379
+ - Generate waypoints along bearing vector
380
+ - Use consistent coordinate frame
381
+ - Validate waypoint sequence creates desired path
382
+
383
+ ### MAVLink Command Issues
384
+ **Problem**: Commands structured correctly but waypoints wrong
385
+ **Solution**:
386
+ - Verify coordinate frame usage (prefer GLOBAL_RELATIVE_ALT)
387
+ - Ensure lat/lon in correct parameter positions (param5/param6)
388
+ - Use proper altitude reference (param7)
389
+
390
+ ## 📊 COORDINATE CALCULATION EXAMPLES
391
+
392
+ ### Specific Problem Solving
393
+ Starting coordinates: 16.047, 108.206
394
+
395
+ **Go south 100m:**
396
+ - Correct calculation: 16.0460901, 108.206000
397
+ - Latitude decreases, longitude unchanged
398
+
399
+ **Go north 150m:**
400
+ - Correct calculation: 16.0483514, 108.206000
401
+ - Latitude increases, longitude unchanged
402
+
403
+ **Create 5-waypoint straight line south 200m:**
404
+ ```
405
+ Waypoint 0: 16.0470000, 108.2060000
406
+ Waypoint 1: 16.0465508, 108.2060000
407
+ Waypoint 2: 16.0461017, 108.2060000
408
+ Waypoint 3: 16.0456525, 108.2060000
409
+ Waypoint 4: 16.0452034, 108.2060000
410
+ ```
411
+
412
+ ## 🚨 COMPREHENSIVE ERROR HANDLING & RECOVERY
413
+
414
+ ### Critical Error Scenarios and Recovery Strategies
415
+
416
+ #### 1. GPS Signal Loss
417
+ **Detection**: Satellite count < 4, HDOP > 5.0, position variance high
418
+ **Immediate Actions**:
419
+ - Switch to position hold mode
420
+ - Log error with timestamp and location
421
+ - Attempt recovery for 30 seconds
422
+ - If recovery fails, initiate RTL with last known position
423
+ **Recovery Strategy**:
424
+ - Clear obstructions around antenna
425
+ - Move to open area
426
+ - Restart GPS receiver if possible
427
+ - Use backup GPS if available
428
+
429
+ #### 2. Low Battery Emergency
430
+ **Detection**: Battery < 15% or voltage < 3.5V/cell
431
+ **Immediate Actions**:
432
+ - Broadcast low battery warning to all operators
433
+ - Calculate remaining flight time (typically 2-5 minutes)
434
+ - Identify nearest safe landing zone
435
+ - Automatically initiate RTL if battery < 10%
436
+ **Recovery Strategy**:
437
+ - Land immediately in safe area
438
+ - Do not attempt to return to launch if too far
439
+ - Switch to energy-saving mode (reduce altitude/speed)
440
+
441
+ #### 3. Communication Link Loss
442
+ **Detection**: No heartbeat for >5 seconds, RSSI critical
443
+ **Immediate Actions**:
444
+ - Execute pre-programmed failsafe actions
445
+ - Switch to autonomous mode
446
+ - Continue mission if within safety parameters
447
+ - Initiate RTL if outside safety boundaries
448
+ **Recovery Strategy**:
449
+ - Attempt to reestablish connection
450
+ - Return to home if connection lost >60 seconds
451
+ - Land immediately if in critical phase (takeoff/landing)
452
+
453
+ #### 4. Motor Failure Detection
454
+ **Detection**: Motor RPM < 80% of commanded, vibration anomalies
455
+ **Immediate Actions**:
456
+ - Reduce power to prevent further damage
457
+ - Switch to backup motor if available
458
+ - Calculate if safe flight can continue
459
+ - Initiate emergency landing if stability compromised
460
+ **Recovery Strategy**:
461
+ - Land immediately in open area
462
+ - Avoid populated areas
463
+ - Use remaining motors for controlled descent
464
+
465
+ #### 5. Sensor Malfunction
466
+ **Detection**: Inconsistent readings, sensor variance high, checksum errors
467
+ **Immediate Actions**:
468
+ - Log sensor failure details
469
+ - Switch to backup sensors if available
470
+ - Reduce reliance on failed sensor data
471
+ - Maintain flight using remaining good sensors
472
+ **Recovery Strategy**:
473
+ - Complete mission with degraded capabilities
474
+ - Return home if critical sensor affected
475
+ - Avoid sensor-dependent operations
476
+
477
+ #### 6. Wind Speed Critical
478
+ **Detection**: Wind speed > operational limits (typically >15 m/s)
479
+ **Immediate Actions**:
480
+ - Increase altitude for smoother air
481
+ - Reduce ground speed to maintain control
482
+ - Calculate impact on battery consumption
483
+ - Consider mission abort if wind >20 m/s
484
+ **Recovery Strategy**:
485
+ - Find sheltered area or fly at higher altitude
486
+ - Reduce mission scope
487
+ - Return to launch if conditions worsen
488
+
489
+ #### 7. Geofence Violation
490
+ **Detection**: Position outside allowed operational boundary
491
+ **Immediate Actions**:
492
+ - Stop current waypoint navigation
493
+ - Calculate path back to allowed area
494
+ - Alert ground station operator
495
+ - RTL if violation is severe
496
+ **Recovery Strategy**:
497
+ - Navigate to nearest boundary point
498
+ - Resume mission if possible
499
+ - Log violation for review
500
+
501
+ ### Error Classification and Priority
502
+
503
+ #### Critical Errors (Immediate Action Required)
504
+ - **Priority 1**: Motor failure, complete power loss
505
+ - **Priority 2**: Battery critical (<10%), fire detection
506
+ - **Priority 3**: GPS complete failure, compass failure
507
+ - **Priority 4**: Communication loss >60 seconds
508
+
509
+ #### Serious Errors (Action Within 30 Seconds)
510
+ - **Priority 5**: Low battery (10-15%), GPS degraded
511
+ - **Priority 6**: Single sensor failure, communication intermittent
512
+ - **Priority 7**: Wind speed high, geofence warning
513
+
514
+ #### Minor Errors (Monitor and Log)
515
+ - **Priority 8**: Communication weak, single satellite loss
516
+ - **Priority 9**: Vibration warning, temperature warning
517
+ - **Priority 10**: Log full, storage warning
518
+
519
+ ### Recovery Procedures
520
+
521
+ #### Emergency Landing Protocol
522
+ 1. **Assess Situation**: Determine if immediate landing required
523
+ 2. **Select Landing Zone**: Choose safest available area
524
+ 3. **Announce Emergency**: Broadcast to all operators and airspace
525
+ 4. **Execute Landing**: Use appropriate landing mode
526
+ 5. **Post-Landing**: Secure aircraft, assess damage
527
+
528
+ #### Return to Launch (RTL) Protocol
529
+ 1. **Calculate Path**: Determine optimal path home
530
+ 2. **Check Conditions**: Verify RTL altitude safe for area
531
+ 3. **Set RTL Parameters**: Configure climb rate and speed
532
+ 4. **Monitor Progress**: Track progress and battery status
533
+ 5. **Landing Preparation**: Prepare for automatic landing
534
+
535
+ #### Mission Abort Protocol
536
+ 1. **Assess Risk**: Determine if abort safer than continue
537
+ 2. **Save Mission State**: Record current progress
538
+ 3. **Safe Recovery**: Choose between RTL or emergency landing
539
+ 4. **Data Preservation**: Ensure telemetry data saved
540
+ 5. **Post-Mission Analysis**: Review cause and prevention
541
+
542
+ ### Safety System Architecture
543
+
544
+ #### Redundancy Design
545
+ - **Power**: Multiple battery monitoring systems
546
+ - **GPS**: Dual GPS receivers if possible
547
+ - **Communications**: Multiple radio systems
548
+ - **Sensors**: Redundant IMU, barometer, compass
549
+ - **Processing**: Watchdog timers, error checking
550
+
551
+ #### Failsafe Implementation
552
+ - **Hardware Failsafe**: Independent safety microcontroller
553
+ - **Software Failsafe**: Multiple layers of error checking
554
+ - **Operator Failsafe**: Manual override capabilities
555
+ - **Automatic Failsafe**: Pre-programmed emergency responses
556
+
557
+ #### Monitoring Systems
558
+ - **Real-time Telemetry**: Continuous health monitoring
559
+ - **Error Logging**: Detailed error recording with timestamps
560
+ - **Performance Metrics**: Track system health over time
561
+ - **Predictive Maintenance**: Early warning for component wear
562
+
563
+ ### Best Practices for Error Prevention
564
+
565
+ #### Pre-Flight Checks
566
+ 1. **Hardware Inspection**:
567
+ - Visual inspection of all components
568
+ - Motor and propeller condition
569
+ - Battery voltage and capacity
570
+ - Antenna connections and signal strength
571
+
572
+ 2. **Software Verification**:
573
+ - Firmware version compatibility
574
+ - Parameter consistency across systems
575
+ - Mission file validation
576
+ - Communication link testing
577
+
578
+ 3. **Environmental Assessment**:
579
+ - Weather conditions and forecasts
580
+ - Airspace restrictions and NOTAMs
581
+ - Local terrain and obstacles
582
+ - Electromagnetic interference sources
583
+
584
+ #### In-Flight Monitoring
585
+ 1. **Continuous Systems**:
586
+ - Battery voltage and current
587
+ - Motor performance and temperature
588
+ - GPS signal strength and accuracy
589
+ - Communication link quality
590
+
591
+ 2. **Periodic Checks**:
592
+ - Flight path deviation monitoring
593
+ - Mission progress verification
594
+ - Environmental condition changes
595
+ - System resource usage
596
+
597
+ #### Post-Flight Analysis
598
+ 1. **Data Review**:
599
+ - Telemetry log analysis
600
+ - Error and warning review
601
+ - Performance metric evaluation
602
+ - Mission success assessment
603
+
604
+ 2. **Maintenance Planning**:
605
+ - Component wear assessment
606
+ - Software update scheduling
607
+ - Calibration requirement identification
608
+ - Replacement part ordering
609
+
610
+ This comprehensive error handling system ensures maximum safety, reliability, and operational continuity for all drone missions.
611
+
612
+ ## 🧪 COMPREHENSIVE TESTING AND VALIDATION
613
+
614
+ ### Testing Categories and Procedures
615
+
616
+ #### 1. Unit Testing Requirements
617
+
618
+ **Coordinate System Testing**:
619
+ ```python
620
+ # Test coordinate conversion accuracy
621
+ def test_coordinate_conversion():
622
+ # Test cases for coordinate offsets
623
+ test_cases = [
624
+ (16.047, 108.206, 100, 'north', (16.0478983, 108.2060000)),
625
+ (16.047, 108.206, 100, 'south', (16.0461017, 108.2060000)),
626
+ (16.047, 108.206, 100, 'east', (16.0470000, 108.2069347)),
627
+ (16.047, 108.206, 100, 'west', (16.0470000, 108.2050653))
628
+ ]
629
+
630
+ for lat, lon, distance, direction, expected in test_cases:
631
+ result = calculate_new_coordinates(lat, lon, distance, direction)
632
+ assert abs(result[0] - expected[0]) < 1e-6
633
+ assert abs(result[1] - expected[1]) < 1e-6
634
+ ```
635
+
636
+ **MAVLink Command Testing**:
637
+ ```python
638
+ # Test MAVLink command structure validation
639
+ def test_mavlink_command_structure():
640
+ # Test TAKEOFF command structure
641
+ takeoff_cmd = create_takeoff_command(16.047, 108.206, 50)
642
+ assert takeoff_cmd['command'] == 22 # NAV_TAKEOFF
643
+ assert takeoff_cmd['frame'] == 3 # GLOBAL_RELATIVE_ALT
644
+ assert takeoff_cmd['params'][7] == 50 # Altitude parameter
645
+ ```
646
+
647
+ **Flight Mode Testing**:
648
+ ```python
649
+ # Test flight mode transitions
650
+ def test_flight_mode_transitions():
651
+ # Test safe mode transitions
652
+ assert is_safe_transition('LOITER', 'RTL') == True
653
+ assert is_safe_transition('AUTO', 'STABILIZE') == False # Risky
654
+ assert is_safe_transition('GUIDED', 'AUTO') == True
655
+ ```
656
+
657
+ #### 2. Integration Testing Scenarios
658
+
659
+ **Mission Planning Integration**:
660
+ - Test coordinate system integration with MAVLink commands
661
+ - Validate waypoint generation accuracy
662
+ - Test mission file generation and QGC compatibility
663
+ - Verify altitude and speed parameter optimization
664
+
665
+ **Safety System Integration**:
666
+ - Test failsafe activation under various conditions
667
+ - Validate geofence enforcement
668
+ - Test battery monitoring and low-voltage responses
669
+ - Verify communication loss detection and recovery
670
+
671
+ **AI System Integration**:
672
+ - Test natural language mission interpretation
673
+ - Validate AI reasoning and decision making
674
+ - Test contextual understanding and conversation flow
675
+ - Verify safety protocol adherence
676
+
677
+ #### 3. System-Level Testing
678
+
679
+ **End-to-End Mission Testing**:
680
+ 1. **Pre-Flight Phase**:
681
+ - Hardware connection verification
682
+ - GPS signal quality assessment
683
+ - Battery capacity validation
684
+ - Parameter consistency checks
685
+
686
+ 2. **Mission Execution Phase**:
687
+ - Waypoint navigation accuracy
688
+ - Real-time telemetry monitoring
689
+ - Dynamic obstacle avoidance
690
+ - Weather adaptation testing
691
+
692
+ 3. **Post-Mission Phase**:
693
+ - Data log analysis
694
+ - Performance metric evaluation
695
+ - Error and warning review
696
+ - Maintenance recommendation generation
697
+
698
+ **Performance Testing**:
699
+ - **Response Time**: API calls < 100ms
700
+ - **Mission Generation**: Complex missions < 2 seconds
701
+ - **Concurrent Operations**: Support 10+ simultaneous missions
702
+ - **Memory Usage**: Stable under high load
703
+ - **CPU Utilization**: Efficient async processing
704
+
705
+ #### 4. Edge Case and Error Testing
706
+
707
+ **Critical Error Scenarios**:
708
+ ```python
709
+ # Test error handling robustness
710
+ def test_error_scenarios():
711
+ # GPS failure during mission
712
+ simulate_gps_failure()
713
+ assert system_switches_to_position_hold()
714
+ assert rtl_initiated_after_timeout()
715
+
716
+ # Communication loss
717
+ simulate_comm_loss()
718
+ assert failsafe_actions_executed()
719
+ assert mission_continues_autonomously()
720
+
721
+ # Low battery emergency
722
+ simulate_low_battery()
723
+ assert warning_broadcast_to_operators()
724
+ assert safe_landing_zone_identified()
725
+ ```
726
+
727
+ **Boundary Testing**:
728
+ - Maximum waypoint count limits
729
+ - Extreme coordinate values
730
+ - Altitude limit enforcement
731
+ - Speed parameter validation
732
+ - Mission file size constraints
733
+
734
+ **Negative Testing**:
735
+ - Invalid coordinate inputs
736
+ - Impossible mission parameters
737
+ - Conflicting safety requirements
738
+ - Resource exhaustion scenarios
739
+ - Network failure conditions
740
+
741
+ #### 5. Regulatory Compliance Testing
742
+
743
+ **Airspace Regulation Testing**:
744
+ - Geofence boundary enforcement
745
+ - Altitude restriction compliance
746
+ - No-fly zone avoidance
747
+ - Time-based operational limits
748
+ - Weather condition validation
749
+
750
+ **Documentation Testing**:
751
+ - Flight log completeness
752
+ - Incident reporting accuracy
753
+ - Maintenance record validation
754
+ - Compliance audit trail verification
755
+
756
+ ### Validation Metrics and Success Criteria
757
+
758
+ #### Functional Validation
759
+ - **Mission Success Rate**: >99.5% successful mission completion
760
+ - **Navigation Accuracy**: <2m waypoint accuracy under normal conditions
761
+ - **Response Time**: <500ms for emergency responses
762
+ - **Error Recovery**: >95% successful error recovery rate
763
+
764
+ #### Safety Validation
765
+ - **Failsafe Activation**: 100% failsafe execution on critical errors
766
+ - **Geofence Compliance**: 100% boundary enforcement
767
+ - **Emergency Response**: <5 seconds response time to critical conditions
768
+ - **Collision Avoidance**: 100% obstacle detection and avoidance
769
+
770
+ #### Performance Validation
771
+ - **System Availability**: >99.9% uptime
772
+ - **Data Integrity**: 100% telemetry data accuracy
773
+ - **Resource Efficiency**: <80% CPU usage under maximum load
774
+ - **Memory Stability**: No memory leaks under continuous operation
775
+
776
+ ### Test Automation Framework
777
+
778
+ #### Continuous Integration Testing
779
+ ```python
780
+ # Automated test suite structure
781
+ class DroneMissionTestSuite:
782
+ def __init__(self):
783
+ self.test_categories = {
784
+ 'unit_tests': self.run_unit_tests,
785
+ 'integration_tests': self.run_integration_tests,
786
+ 'system_tests': self.run_system_tests,
787
+ 'safety_tests': self.run_safety_tests,
788
+ 'performance_tests': self.run_performance_tests
789
+ }
790
+
791
+ def run_complete_test_suite(self):
792
+ results = {}
793
+ for category, test_func in self.test_categories.items():
794
+ results[category] = test_func()
795
+ return self.generate_test_report(results)
796
+ ```
797
+
798
+ #### Real-World Simulation Testing
799
+ - **Hardware-in-the-Loop (HIL) Testing**: Full system simulation
800
+ - **Software-in-the-Loop (SIL) Testing**: Algorithm validation
801
+ - **Field Testing**: Real-world operational validation
802
+ - **Certification Testing**: Regulatory compliance verification
803
+
804
+ ### Best Practices for Testing
805
+
806
+ #### Test Data Management
807
+ - **Realistic Test Data**: Use actual flight scenarios and conditions
808
+ - **Edge Case Coverage**: Include extreme environmental conditions
809
+ - **Historical Data**: Test with past incident scenarios
810
+ - **Synthetic Data**: Generate test cases for rare conditions
811
+
812
+ #### Test Environment Setup
813
+ - **Isolated Testing**: Separate test environments from production
814
+ - **Clean State**: Ensure known starting conditions for each test
815
+ - **Resource Monitoring**: Track system resources during testing
816
+ - **Result Validation**: Automated comparison with expected outcomes
817
+
818
+ #### Continuous Improvement
819
+ - **Test Coverage Analysis**: Identify gaps in test coverage
820
+ - **Failure Analysis**: Learn from test failures to improve system
821
+ - **Regression Testing**: Ensure new features don't break existing functionality
822
+ - **Performance Trending**: Monitor test performance over time
823
+
824
+ This comprehensive testing framework ensures the drone mission planning system is thoroughly validated, reliable, and ready for operational deployment.
825
+
826
+ ---
827
+
828
+ This knowledge base provides the mathematical foundations, protocol specifications, practical examples, comprehensive safety procedures, and thorough testing methodologies needed to build professional-grade drone mission planning systems.
ai_knowledge_base/mavlink_commands.txt ADDED
@@ -0,0 +1,228 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # MAVLINK COMMANDS - COMPREHENSIVE DRONE CONTROL REFERENCE
2
+ # Version 3.0.0 - Complete MAVLink Command Set for Professional UAV Operations
3
+ # Compatible with ArduPilot/PX4 and QGroundControl
4
+
5
+ ## 🧭 NAVIGATION COMMANDS (MAV_CMD_NAV_*)
6
+
7
+ ### Primary Navigation
8
+ MAV_CMD_NAV_WAYPOINT = 16
9
+ - **Purpose**: Navigate to specific GPS waypoint
10
+ - **Parameters**:
11
+ - param1: Hold time (seconds, 0 = ignore)
12
+ - param2: Acceptance radius (meters)
13
+ - param3: Pass through radius (meters, 0 = straight to waypoint)
14
+ - param4: Desired yaw angle (degrees, NaN = ignore)
15
+ - param5-7: Lat/Lon/Alt (WGS84 coordinates)
16
+ - **Frames**: GLOBAL_RELATIVE_ALT, GLOBAL, LOCAL_ENU
17
+ - **Usage**: Core waypoint navigation for missions
18
+
19
+ MAV_CMD_NAV_LOITER_UNLIM = 17
20
+ - **Purpose**: Loiter indefinitely at current location
21
+ - **Parameters**: param5-7: Lat/Lon/Alt for loiter center
22
+ - **Usage**: Surveillance, waiting for events
23
+ - **Safety**: Monitor battery levels, can be interrupted by failsafe
24
+
25
+ MAV_CMD_NAV_LOITER_TURNS = 18
26
+ - **Purpose**: Loiter for specified number of turns
27
+ - **Parameters**: param1: Number of turns (0-255), param5-7: Center coordinates
28
+ - **Usage**: Search patterns, aerial inspection orbits
29
+
30
+ MAV_CMD_NAV_LOITER_TIME = 19
31
+ - **Purpose**: Loiter for specified time duration
32
+ - **Parameters**: param1: Loiter time (seconds), param5-7: Center coordinates
33
+ - **Usage**: Time-based surveillance, photography positioning
34
+
35
+ MAV_CMD_NAV_RETURN_TO_LAUNCH = 20
36
+ - **Purpose**: Return to home/launch position
37
+ - **Parameters**: All parameters ignored
38
+ - **Frames**: MISSION (special case)
39
+ - **Safety**: Critical failsafe command, highest priority
40
+
41
+ MAV_CMD_NAV_LAND = 21
42
+ - **Purpose**: Land at specified coordinates
43
+ - **Parameters**:
44
+ - param1: Descent rate (m/s, 0 = default)
45
+ - param5-7: Landing coordinates
46
+ - **Usage**: Precision landing, mission termination
47
+
48
+ MAV_CMD_NAV_TAKEOFF = 22
49
+ - **Purpose**: Take off to specified altitude
50
+ - **Parameters**:
51
+ - param1: Minimum pitch (degrees, 0 for copters)
52
+ - param4: Yaw angle (NaN = current heading)
53
+ - param7: Altitude (AGL)
54
+ - **Frames**: GLOBAL_RELATIVE_ALT
55
+ - **Safety**: Requires proper GPS lock and battery levels
56
+
57
+ ### Advanced Navigation
58
+ MAV_CMD_NAV_SPLINE_WAYPOINT = 82
59
+ - **Purpose**: Smooth spline-based waypoint navigation
60
+ - **Parameters**: Same as NAV_WAYPOINT but smoother path
61
+ - **Usage**: Cinematography, smooth inspection paths
62
+ - **Performance**: Uses Bezier curves for fluid movement
63
+
64
+ MAV_CMD_NAV_GUIDED_ENABLE = 92
65
+ - **Purpose**: Enable/disable guided mode
66
+ - **Parameters**: param1: 1=enable, 0=disable
67
+
68
+ MAV_CMD_NAV_DELAY = 93
69
+ - **Purpose**: Delay mission execution
70
+ - **Parameters**: param1: Delay time (seconds)
71
+
72
+ ## 🎛️ CONTROL COMMANDS (MAV_CMD_DO_*)
73
+
74
+ ### System Control
75
+ MAV_CMD_DO_SET_MODE = 176
76
+ - **Purpose**: Change flight mode
77
+ - **Parameters**: param1: Mode number, param2: Custom mode/submode
78
+ - **Usage**: Mode switching during missions
79
+
80
+ MAV_CMD_COMPONENT_ARM_DISARM = 400
81
+ - **Purpose**: Arm/disarm motors and systems
82
+ - **Parameters**: param1: 1=arm, 0=disarm
83
+ - **Safety**: Critical safety command, requires proper conditions
84
+
85
+ MAV_CMD_DO_ENGINE_CONTROL = 183
86
+ - **Purpose**: Control engine start/stop (gas vehicles)
87
+ - **Parameters**: param1: 1=start, 0=stop, param2: cold start
88
+
89
+ ### Mission Control
90
+ MAV_CMD_MISSION_START = 300
91
+ - **Purpose**: Start mission execution
92
+ - **Parameters**: param1: First item, param2: Last item
93
+
94
+ MAV_CMD_DO_JUMP = 177
95
+ - **Purpose**: Jump to specific mission item
96
+ - **Parameters**: param1: Sequence number, param2: Repeat count
97
+
98
+ MAV_CMD_DO_CHANGE_SPEED = 178
99
+ - **Purpose**: Change cruise speed
100
+ - **Parameters**: param1: Speed type (0=airspeed,1=groundspeed), param2: Speed (m/s)
101
+
102
+ ### Camera/Gimbal Control
103
+ MAV_CMD_DO_MOUNT_CONTROL = 205
104
+ - **Purpose**: Control camera gimbal angles
105
+ - **Parameters**:
106
+ - param1: Pitch angle (degrees)
107
+ - param2: Roll angle (degrees)
108
+ - param3: Yaw angle (degrees)
109
+ - param4: Mount mode (0=neutral, 1=MavLink targeting, 2=RC targeting, 3=gps pointing)
110
+
111
+ MAV_CMD_DO_GIMBAL_MANAGER_PITCHYAW = 1000
112
+ - **Purpose**: Advanced gimbal control with pitch/yaw
113
+ - **Parameters**: param1: Pitch angle, param2: Yaw angle, param7: Gimbal ID
114
+
115
+ MAV_CMD_IMAGE_START_CAPTURE = 2000
116
+ - **Purpose**: Start image capture sequence
117
+ - **Parameters**:
118
+ - param1: Duration between captures (seconds, 0 = single)
119
+ - param2: Number of captures (0 = unlimited)
120
+ - param3: Resolution (0=default, 1=480p, 2=720p, 3=1080p, 4=4K)
121
+
122
+ MAV_CMD_VIDEO_START_CAPTURE = 2500
123
+ - **Purpose**: Start video recording
124
+ - **Parameters**: param1: Stream ID (0=default), param2: Status (1=start, 0=stop)
125
+
126
+ ## 📍 COORDINATE FRAME TYPES
127
+
128
+ ### Global Frames
129
+ MAV_FRAME_GLOBAL = 0
130
+ - **Coordinates**: WGS84 latitude/longitude
131
+ - **Altitude**: Above mean sea level (AMSL)
132
+ - **Usage**: Absolute positioning, long-range missions
133
+ - **Precision**: High accuracy for GPS coordinates
134
+
135
+ MAV_FRAME_GLOBAL_RELATIVE_ALT = 3
136
+ - **Coordinates**: WGS84 latitude/longitude
137
+ - **Altitude**: Relative to home/launch position
138
+ - **Usage**: Most common for drone missions
139
+ - **Safety**: Safer for varying terrain, recommended default
140
+
141
+ MAV_FRAME_GLOBAL_INT = 5
142
+ - **Coordinates**: WGS84 as integers (degrees × 10^7)
143
+ - **Altitude**: AMSL as integer
144
+ - **Usage**: Bandwidth optimization, QGroundControl compatibility
145
+
146
+ MAV_FRAME_GLOBAL_RELATIVE_ALT_INT = 6
147
+ - **Coordinates**: WGS84 as integers
148
+ - **Altitude**: Relative to home as integer
149
+ - **Usage**: Most recommended for QGC mission files
150
+
151
+ ### Local Frames
152
+ MAV_FRAME_LOCAL_NED = 1
153
+ - **Coordinates**: North/East/Down from origin
154
+ - **Usage**: Precision work, indoor navigation
155
+ - **Origin**: Set by GPS position or manual definition
156
+
157
+ MAV_FRAME_LOCAL_ENU = 4
158
+ - **Coordinates**: East/North/Up from origin
159
+ - **Usage**: Computer vision applications, SLAM
160
+
161
+ MAV_FRAME_MISSION = 2
162
+ - **Special**: Not a coordinate frame
163
+ - **Usage**: Commands that don't require positioning (RTL, mode changes)
164
+
165
+ ## 🔧 PARAMETER REFERENCE TABLES
166
+
167
+ ### SET_POSITION_TARGET Type Masks
168
+ POSITION_TARGET_TYPEMASK_X_IGNORE = 1 # Ignore X position
169
+ POSITION_TARGET_TYPEMASK_Y_IGNORE = 2 # Ignore Y position
170
+ POSITION_TARGET_TYPEMASK_Z_IGNORE = 4 # Ignore Z position
171
+ POSITION_TARGET_TYPEMASK_VX_IGNORE = 8 # Ignore X velocity
172
+ POSITION_TARGET_TYPEMASK_VY_IGNORE = 16 # Ignore Y velocity
173
+ POSITION_TARGET_TYPEMASK_VZ_IGNORE = 32 # Ignore Z velocity
174
+ POSITION_TARGET_TYPEMASK_AX_IGNORE = 64 # Ignore X acceleration
175
+ POSITION_TARGET_TYPEMASK_AY_IGNORE = 128 # Ignore Y acceleration
176
+ POSITION_TARGET_TYPEMASK_AZ_IGNORE = 256 # Ignore Z acceleration
177
+ POSITION_TARGET_TYPEMASK_FORCE_SET = 512 # Use force instead of acceleration
178
+ POSITION_TARGET_TYPEMASK_YAW_IGNORE = 1024 # Ignore yaw angle
179
+ POSITION_TARGET_TYPEMASK_YAW_RATE_IGNORE = 2048 # Ignore yaw rate
180
+
181
+ ### MAV_RESULT Return Codes
182
+ MAV_RESULT_ACCEPTED = 0 # Command accepted
183
+ MAV_RESULT_TEMPORARILY_REJECTED = 1 # Command rejected temporarily
184
+ MAV_RESULT_DENIED = 2 # Command denied permanently
185
+ MAV_RESULT_UNSUPPORTED = 3 # Command not supported
186
+ MAV_RESULT_FAILED = 4 # Command failed to execute
187
+ MAV_RESULT_IN_PROGRESS = 5 # Command in progress
188
+
189
+ ## 🛡️ SAFETY AND ERROR HANDLING
190
+
191
+ ### Critical Safety Commands Priority
192
+ 1. **RTL (Return to Launch)**: Highest priority failsafe
193
+ 2. **LAND**: Emergency landing for immediate threats
194
+ 3. **LOITER**: Safe hover for system issues
195
+ 4. **DISARM**: Complete system shutdown
196
+
197
+ ### Command Validation
198
+ - **Pre-flight**: Validate coordinates, altitude limits, battery capacity
199
+ - **In-flight**: Monitor command execution, handle failures gracefully
200
+ - **Post-flight**: Verify mission completion, analyze performance
201
+
202
+ ### Error Recovery
203
+ - **Communication Loss**: Automatic RTL after timeout
204
+ - **GPS Loss**: Switch to position hold, attempt recovery
205
+ - **Battery Critical**: Progressive warnings, emergency RTL
206
+ - **Motor Failure**: Emergency landing procedures
207
+
208
+ ## 📊 PERFORMANCE OPTIMIZATION
209
+
210
+ ### Frame Selection Guidelines
211
+ - **GLOBAL_RELATIVE_ALT_INT**: Default choice for most missions
212
+ - **LOCAL_ENU**: Indoor flying, precision work
213
+ - **GLOBAL**: Long-range missions, absolute positioning required
214
+ - **MISSION**: Non-positioning commands only
215
+
216
+ ### Parameter Optimization
217
+ - **Hold Time**: 0-3 seconds for normal waypoints, longer for photography
218
+ - **Acceptance Radius**: 2-5 meters for precision, 10+ for general navigation
219
+ - **Speed**: 8-12 m/s for survey, 3-8 m/s for inspection
220
+ - **Altitude**: 50-120m survey, 10-50m inspection, 30-80m patrol
221
+
222
+ ### Bandwidth Considerations
223
+ - Use integer coordinate frames when possible
224
+ - Minimize parameter updates during flight
225
+ - Batch mission items for efficiency
226
+ - Monitor telemetry rates for optimal performance
227
+
228
+ This comprehensive MAVLink reference provides everything needed for professional drone mission planning and execution.
ai_knowledge_base/professional_drone_control.md ADDED
@@ -0,0 +1,364 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🚁 PROFESSIONAL DRONE CONTROL & AI-DRIVEN MISSION PLANNING
2
+ # Advanced Knowledge Base for Real-World Drone Operations
3
+
4
+ ## 🎯 AI-DRIVEN MISSION INTELLIGENCE
5
+
6
+ ### Professional Mission Analysis Framework
7
+ The AI should analyze missions using these parameters:
8
+
9
+ #### Environmental Factors
10
+ - **Wind Analysis**: Speed, direction, gusts affecting different altitudes
11
+ - **Weather Patterns**: Visibility, precipitation, temperature effects on battery
12
+ - **Terrain Analysis**: Obstacles, elevation changes, safe landing zones
13
+ - **Airspace Classification**: Class A/B/C/D/E airspace restrictions
14
+ - **Magnetic Declination**: Local magnetic variation for accurate heading
15
+
16
+ #### Mission-Specific Intelligence
17
+ - **Survey Missions**: Ground sample distance (GSD), overlap requirements, lighting conditions
18
+ - **Inspection Missions**: Structure type, approach angles, safety buffers
19
+ - **Photography Missions**: Golden hour timing, sun angle, shadow analysis
20
+ - **Search & Rescue**: Search patterns, coverage efficiency, battery optimization
21
+ - **Security Patrol**: Threat assessment, visibility requirements, response times
22
+
23
+ ### Dynamic Mission Adaptation
24
+ The AI should adjust missions based on:
25
+
26
+ #### Real-Time Conditions
27
+ ```python
28
+ def analyze_mission_conditions(mission_type, location, weather, drone_status):
29
+ """
30
+ Professional mission analysis considering all factors
31
+ """
32
+ factors = {
33
+ 'wind_speed': weather.wind_speed,
34
+ 'visibility': weather.visibility,
35
+ 'battery_health': drone_status.battery_health,
36
+ 'gps_accuracy': drone_status.gps_hdop,
37
+ 'terrain_difficulty': location.terrain_complexity
38
+ }
39
+
40
+ # Adjust mission parameters dynamically
41
+ if factors['wind_speed'] > 15: # m/s
42
+ mission_params.altitude += 10 # Higher altitude for stability
43
+ mission_params.speed *= 0.8 # Reduce speed for control
44
+
45
+ if factors['visibility'] < 3000: # meters
46
+ mission_params.altitude = min(mission_params.altitude, 60)
47
+ mission_params.waypoint_spacing *= 0.7 # Closer waypoints
48
+
49
+ return optimized_mission_params
50
+ ```
51
+
52
+ #### Battery Management Intelligence
53
+ ```python
54
+ def calculate_intelligent_battery_usage(mission_params, environmental_factors):
55
+ """
56
+ Advanced battery calculation considering all factors
57
+ """
58
+ base_consumption = mission_params.distance * 0.15 # Wh per km base
59
+
60
+ # Environmental multipliers
61
+ wind_factor = 1 + (environmental_factors.wind_speed / 30)
62
+ temperature_factor = 1 + (abs(20 - environmental_factors.temperature) / 40)
63
+ altitude_factor = 1 + (mission_params.altitude / 1000)
64
+
65
+ # Mission type multipliers
66
+ mission_multipliers = {
67
+ 'survey': 1.2, # Steady flight, camera operation
68
+ 'inspection': 1.4, # Hovering, precision movements
69
+ 'photography': 1.3, # Gimbal operation, positioning
70
+ 'patrol': 1.1, # Efficient cruise flight
71
+ 'search_rescue': 1.5 # Intensive maneuvering
72
+ }
73
+
74
+ total_consumption = (base_consumption * wind_factor *
75
+ temperature_factor * altitude_factor *
76
+ mission_multipliers.get(mission_params.type, 1.0))
77
+
78
+ # Add 30% safety margin + return-to-home reserve
79
+ required_capacity = total_consumption * 1.3 + return_home_reserve
80
+
81
+ return {
82
+ 'estimated_consumption': total_consumption,
83
+ 'required_capacity': required_capacity,
84
+ 'flight_time_estimate': calculate_flight_time(mission_params),
85
+ 'safety_margin': 0.3,
86
+ 'recommendations': generate_battery_recommendations()
87
+ }
88
+ ```
89
+
90
+ ## 🛩️ PROFESSIONAL FLIGHT PATTERNS
91
+
92
+ ### Advanced Survey Patterns
93
+ ```python
94
+ def generate_professional_survey_pattern(area_bounds, gsd_requirement, overlap):
95
+ """
96
+ Generate survey pattern based on professional photogrammetry standards
97
+ """
98
+ patterns = {
99
+ 'parallel_strips': {
100
+ 'use_case': 'Standard mapping, large areas',
101
+ 'overlap': {'forward': 0.8, 'side': 0.6},
102
+ 'efficiency': 0.9,
103
+ 'data_quality': 0.85
104
+ },
105
+ 'cross_hatch': {
106
+ 'use_case': 'High accuracy mapping, complex terrain',
107
+ 'overlap': {'forward': 0.8, 'side': 0.6, 'cross': 0.4},
108
+ 'efficiency': 0.7,
109
+ 'data_quality': 0.95
110
+ },
111
+ 'adaptive_grid': {
112
+ 'use_case': 'Mixed terrain, varying detail requirements',
113
+ 'overlap': 'variable_based_on_terrain',
114
+ 'efficiency': 0.8,
115
+ 'data_quality': 0.9
116
+ }
117
+ }
118
+
119
+ # Select optimal pattern based on requirements
120
+ if area_bounds.complexity > 0.7:
121
+ return patterns['cross_hatch']
122
+ elif gsd_requirement < 2.0: # cm/pixel
123
+ return patterns['adaptive_grid']
124
+ else:
125
+ return patterns['parallel_strips']
126
+ ```
127
+
128
+ ### Intelligent Inspection Patterns
129
+ ```python
130
+ def generate_inspection_pattern(structure_type, inspection_requirements):
131
+ """
132
+ Generate inspection pattern based on structure and requirements
133
+ """
134
+ patterns = {
135
+ 'building_inspection': {
136
+ 'approach_angles': [0, 45, 90, 135, 180, 225, 270, 315],
137
+ 'distances': [10, 15, 25], # meters from structure
138
+ 'altitudes': [5, 10, 15, 20], # relative to structure base
139
+ 'focus_areas': ['roof', 'walls', 'windows', 'foundation']
140
+ },
141
+ 'tower_inspection': {
142
+ 'approach_pattern': 'helical_ascent',
143
+ 'revolution_count': 3,
144
+ 'ascent_rate': 2, # m/s
145
+ 'radius_variation': [5, 8, 12],
146
+ 'focus_areas': ['base', 'mid_section', 'top', 'guy_wires']
147
+ },
148
+ 'bridge_inspection': {
149
+ 'approach_pattern': 'linear_segments',
150
+ 'segment_overlap': 0.3,
151
+ 'under_bridge': True,
152
+ 'safety_clearance': 8, # meters
153
+ 'focus_areas': ['deck', 'supports', 'cables', 'joints']
154
+ }
155
+ }
156
+
157
+ return patterns.get(structure_type, patterns['building_inspection'])
158
+ ```
159
+
160
+ ## 📊 PROFESSIONAL MISSION METRICS
161
+
162
+ ### Key Performance Indicators
163
+ ```python
164
+ def calculate_mission_kpis(mission_data):
165
+ """
166
+ Calculate professional mission performance metrics
167
+ """
168
+ return {
169
+ 'coverage_efficiency': calculate_area_coverage_percentage(),
170
+ 'data_quality_score': assess_image_quality_metrics(),
171
+ 'flight_efficiency': distance_traveled / optimal_distance,
172
+ 'battery_utilization': energy_used / total_capacity,
173
+ 'time_efficiency': actual_time / planned_time,
174
+ 'safety_score': calculate_safety_compliance_score(),
175
+ 'weather_adaptation': assess_weather_response_quality(),
176
+ 'regulatory_compliance': check_airspace_rule_adherence()
177
+ }
178
+ ```
179
+
180
+ ### Data Quality Assessment
181
+ ```python
182
+ def assess_mission_data_quality(captured_data, mission_requirements):
183
+ """
184
+ Professional assessment of captured mission data
185
+ """
186
+ quality_metrics = {
187
+ 'image_sharpness': analyze_image_sharpness(captured_data.images),
188
+ 'overlap_adequacy': check_overlap_requirements(captured_data.coverage),
189
+ 'gsd_compliance': verify_ground_sample_distance(captured_data.gsd),
190
+ 'exposure_consistency': analyze_exposure_variation(captured_data.images),
191
+ 'geometric_accuracy': assess_geometric_precision(captured_data.gcp_data)
192
+ }
193
+
194
+ overall_score = weighted_average(quality_metrics, weights={
195
+ 'image_sharpness': 0.25,
196
+ 'overlap_adequacy': 0.20,
197
+ 'gsd_compliance': 0.20,
198
+ 'exposure_consistency': 0.15,
199
+ 'geometric_accuracy': 0.20
200
+ })
201
+
202
+ return {
203
+ 'overall_quality': overall_score,
204
+ 'detailed_metrics': quality_metrics,
205
+ 'recommendations': generate_improvement_recommendations(quality_metrics),
206
+ 'pass_fail_status': 'PASS' if overall_score > 0.8 else 'FAIL'
207
+ }
208
+ ```
209
+
210
+ ## 🛡️ ADVANCED SAFETY PROTOCOLS
211
+
212
+ ### Intelligent Risk Assessment
213
+ ```python
214
+ def perform_comprehensive_risk_assessment(mission_params, environment, drone_status):
215
+ """
216
+ Professional risk assessment for mission safety
217
+ """
218
+ risk_factors = {
219
+ 'weather_risk': assess_weather_conditions(environment.weather),
220
+ 'airspace_risk': check_airspace_conflicts(mission_params.location),
221
+ 'equipment_risk': evaluate_drone_health(drone_status),
222
+ 'pilot_risk': assess_pilot_proficiency(pilot_data),
223
+ 'environmental_risk': analyze_terrain_hazards(mission_params.location),
224
+ 'mission_complexity': calculate_mission_difficulty(mission_params)
225
+ }
226
+
227
+ # Calculate overall risk score
228
+ overall_risk = weighted_risk_calculation(risk_factors)
229
+
230
+ # Generate mitigation strategies
231
+ mitigation_plans = {
232
+ 'weather_contingency': create_weather_backup_plan(),
233
+ 'equipment_backup': define_equipment_redundancy(),
234
+ 'abort_criteria': establish_abort_conditions(),
235
+ 'emergency_procedures': define_emergency_responses()
236
+ }
237
+
238
+ return {
239
+ 'risk_level': categorize_risk_level(overall_risk),
240
+ 'risk_factors': risk_factors,
241
+ 'mitigation_plans': mitigation_plans,
242
+ 'go_no_go_recommendation': 'GO' if overall_risk < 0.3 else 'NO-GO',
243
+ 'required_preparations': list_required_preparations(risk_factors)
244
+ }
245
+ ```
246
+
247
+ ### Professional Emergency Procedures
248
+ ```python
249
+ def generate_emergency_procedures(mission_type, environment):
250
+ """
251
+ Create comprehensive emergency procedures for professional operations
252
+ """
253
+ procedures = {
254
+ 'lost_link': {
255
+ 'immediate_action': 'activate_rtl_mode',
256
+ 'timeout': 30, # seconds
257
+ 'backup_plan': 'hover_at_current_position',
258
+ 'escalation': 'manual_recovery_procedures'
259
+ },
260
+ 'low_battery': {
261
+ 'warning_threshold': 0.3, # 30% remaining
262
+ 'critical_threshold': 0.2, # 20% remaining
263
+ 'action_30_percent': 'return_to_home_immediately',
264
+ 'action_20_percent': 'emergency_landing_nearest_safe_zone'
265
+ },
266
+ 'severe_weather': {
267
+ 'wind_threshold': 20, # m/s
268
+ 'visibility_threshold': 1000, # meters
269
+ 'action': 'immediate_abort_and_rtl',
270
+ 'safe_landing_criteria': define_safe_landing_conditions()
271
+ },
272
+ 'equipment_failure': {
273
+ 'gps_failure': 'switch_to_attitude_mode_and_manual_landing',
274
+ 'camera_failure': 'continue_mission_if_safety_permits',
275
+ 'gimbal_failure': 'adjust_flight_parameters_for_fixed_camera',
276
+ 'communication_failure': 'execute_predetermined_flight_plan'
277
+ }
278
+ }
279
+
280
+ return procedures
281
+ ```
282
+
283
+ ## 🎯 MISSION-SPECIFIC INTELLIGENCE
284
+
285
+ ### Survey Mission Intelligence
286
+ ```python
287
+ def generate_intelligent_survey_mission(requirements):
288
+ """
289
+ Generate professional survey mission with AI optimization
290
+ """
291
+ # Analyze requirements
292
+ area_analysis = analyze_survey_area(requirements.area_bounds)
293
+ gsd_requirements = calculate_optimal_gsd(requirements.output_scale)
294
+
295
+ # Optimize flight parameters
296
+ optimal_altitude = calculate_optimal_survey_altitude(
297
+ gsd_requirements, camera_specs, safety_constraints
298
+ )
299
+
300
+ flight_pattern = optimize_survey_pattern(
301
+ area_bounds=requirements.area_bounds,
302
+ obstacles=area_analysis.obstacles,
303
+ wind_direction=requirements.weather.wind_direction,
304
+ sun_angle=calculate_sun_angle(requirements.time, requirements.location)
305
+ )
306
+
307
+ # Generate waypoints with professional spacing
308
+ waypoints = generate_survey_waypoints(
309
+ pattern=flight_pattern,
310
+ altitude=optimal_altitude,
311
+ forward_overlap=0.8,
312
+ side_overlap=0.6,
313
+ terrain_following=requirements.terrain_following
314
+ )
315
+
316
+ return {
317
+ 'waypoints': waypoints,
318
+ 'estimated_flight_time': calculate_flight_time(waypoints),
319
+ 'estimated_images': calculate_image_count(waypoints, camera_trigger_distance),
320
+ 'coverage_area': calculate_actual_coverage(waypoints),
321
+ 'data_volume_estimate': estimate_data_volume(waypoints),
322
+ 'processing_requirements': estimate_processing_time(waypoints)
323
+ }
324
+ ```
325
+
326
+ ### Inspection Mission Intelligence
327
+ ```python
328
+ def generate_intelligent_inspection_mission(structure_type, inspection_goals):
329
+ """
330
+ Generate professional inspection mission with AI analysis
331
+ """
332
+ # Analyze structure
333
+ structure_analysis = analyze_structure_characteristics(structure_type)
334
+ approach_vectors = calculate_optimal_approach_angles(structure_analysis)
335
+
336
+ # Generate inspection points
337
+ inspection_points = []
338
+ for goal in inspection_goals:
339
+ points = generate_inspection_points_for_goal(
340
+ goal=goal,
341
+ structure=structure_analysis,
342
+ approach_vectors=approach_vectors,
343
+ safety_distance=calculate_safe_approach_distance(structure_type)
344
+ )
345
+ inspection_points.extend(points)
346
+
347
+ # Optimize inspection sequence
348
+ optimized_sequence = optimize_inspection_sequence(
349
+ points=inspection_points,
350
+ start_location=home_position,
351
+ battery_constraints=drone_capabilities.battery_life,
352
+ wind_considerations=current_weather.wind
353
+ )
354
+
355
+ return {
356
+ 'inspection_sequence': optimized_sequence,
357
+ 'detailed_procedures': generate_inspection_procedures(inspection_goals),
358
+ 'safety_protocols': generate_structure_specific_safety_protocols(structure_type),
359
+ 'equipment_recommendations': recommend_inspection_equipment(inspection_goals),
360
+ 'data_collection_plan': create_data_collection_strategy(inspection_goals)
361
+ }
362
+ ```
363
+
364
+ This enhanced knowledge base provides the AI with professional-grade intelligence for generating truly sophisticated, industry-standard drone missions rather than simple template-based responses.
app.py ADDED
@@ -0,0 +1,207 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ 🚁 DroneAgent - HF Spaces Application
4
+ FastAPI application for HuggingFace Spaces deployment
5
+ """
6
+ import os
7
+ import uvicorn
8
+ from fastapi import FastAPI, HTTPException, Request
9
+ from fastapi.responses import HTMLResponse, FileResponse
10
+ from fastapi.staticfiles import StaticFiles
11
+ from fastapi.middleware.cors import CORSMiddleware
12
+ from contextlib import asynccontextmanager
13
+
14
+ # Import our DroneAgent modules
15
+ import asyncio
16
+ from src.services.drone_agent import DroneAgent
17
+ from src.core.websocket_server import start_websocket_server
18
+
19
+ # Global drone agent instance
20
+ drone_agent = None
21
+
22
+ @asynccontextmanager
23
+ async def lifespan(app: FastAPI):
24
+ """Application lifespan manager."""
25
+ global drone_agent
26
+ print("🚁 Starting DroneAgent v3.0 for HF Spaces")
27
+
28
+ # Start WebSocket server for real-time notifications
29
+ asyncio.create_task(start_websocket_server())
30
+
31
+ # Initialize DroneAgent
32
+ try:
33
+ drone_agent = DroneAgent()
34
+ print("✅ DroneAgent v3.0 initialized successfully")
35
+ print("🧠 Gemini 2.0 Flash AI Integration Ready")
36
+ print("📡 Real-Time Flight Management Ready")
37
+ print("🗺️ 6-Decimal GPS Precision Ready")
38
+ except Exception as e:
39
+ print(f"⚠️ DroneAgent initialization warning: {e}")
40
+ drone_agent = None
41
+
42
+ yield
43
+
44
+ print("🛑 Shutting down DroneAgent v3.0")
45
+
46
+ # Initialize FastAPI with lifespan
47
+ app = FastAPI(
48
+ title="🚁 DroneAgent",
49
+ description="Professional AI-Powered Drone Mission Planner with Real-Time Flight Management",
50
+ version="3.0.0",
51
+ lifespan=lifespan
52
+ )
53
+
54
+ # Add CORS middleware
55
+ app.add_middleware(
56
+ CORSMiddleware,
57
+ allow_origins=["*"],
58
+ allow_credentials=True,
59
+ allow_methods=["*"],
60
+ allow_headers=["*"],
61
+ )
62
+
63
+ @app.get("/", response_class=HTMLResponse)
64
+ async def root():
65
+ """Serve the main DroneAgent interface."""
66
+ try:
67
+ return FileResponse("chatbot_enhanced.html", media_type="text/html")
68
+ except FileNotFoundError:
69
+ return """
70
+ <html>
71
+ <head>
72
+ <title>🚁 DroneAgent</title>
73
+ <style>
74
+ body { font-family: Arial, sans-serif; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
75
+ color: white; text-align: center; padding: 50px; margin: 0; height: 100vh; display: flex;
76
+ flex-direction: column; justify-content: center; }
77
+ .container { max-width: 800px; margin: 0 auto; }
78
+ h1 { font-size: 3em; margin-bottom: 20px; }
79
+ p { font-size: 1.2em; margin-bottom: 30px; }
80
+ .features { text-align: left; display: inline-block; background: rgba(255,255,255,0.1);
81
+ padding: 20px; border-radius: 10px; margin: 20px 0; }
82
+ .status { background: rgba(0,255,0,0.2); padding: 10px; border-radius: 5px; margin: 10px 0; }
83
+ </style>
84
+ </head>
85
+ <body>
86
+ <div class="container">
87
+ <h1>🚁 DroneAgent v3.0</h1>
88
+ <p>Professional AI-Powered Drone Mission Planner</p>
89
+
90
+ <div class="features">
91
+ <h3>✨ Key Features:</h3>
92
+ <ul>
93
+ <li>🧠 Gemini 2.0 Flash AI Integration</li>
94
+ <li>📡 Real-Time Flight Management</li>
95
+ <li>🗺️ 6-Decimal GPS Precision</li>
96
+ <li>🌐 Vietnamese Geocoding Support</li>
97
+ <li>📱 WebSocket Notifications</li>
98
+ <li>⏸️ Dynamic Mission Control</li>
99
+ </ul>
100
+ </div>
101
+
102
+ <div class="status">
103
+ <h3>🌐 API Status:
104
+ <span id="status">
105
+ <script>
106
+ fetch('/api/status')
107
+ .then(r => r.json())
108
+ .then(d => {
109
+ document.getElementById('status').innerHTML =
110
+ d.status === 'operational' ? '✅ Operational' : '⚠️ Initializing';
111
+ })
112
+ .catch(() => {
113
+ document.getElementById('status').innerHTML = '⚠️ Initializing';
114
+ });
115
+ </script>
116
+ </span>
117
+ </h3>
118
+ </div>
119
+
120
+ <p><strong>�� Access Points:</strong></p>
121
+ <ul style="list-style: none;">
122
+ <li>🌐 Web Interface: <a href="/chat" style="color: #4CAF50;">/chat</a></li>
123
+ <li>📚 API Documentation: <a href="/docs" style="color: #2196F3;">/docs</a></li>
124
+ <li>🔧 API Status: <a href="/api/status" style="color: #FF9800;">/api/status</a></li>
125
+ </ul>
126
+ </div>
127
+ </body>
128
+ </html>
129
+ """
130
+
131
+ @app.get("/api/status")
132
+ async def api_status():
133
+ """Get API status information."""
134
+ return {
135
+ "name": "DroneAgent",
136
+ "version": "3.0.0",
137
+ "status": "operational" if drone_agent else "initializing",
138
+ "features": [
139
+ "🧠 Gemini 2.0 Flash AI Integration",
140
+ "📡 Real-Time Flight Management",
141
+ "🗺️ 6-Decimal GPS Precision",
142
+ "🌐 Vietnamese Geocoding Support",
143
+ "📱 WebSocket Notifications",
144
+ "⏸️ Dynamic Mission Control",
145
+ "🛡️ AI-Powered Safety Checks",
146
+ "🔄 Intelligent API Key Rotation",
147
+ "🚁 QGroundControl Compatibility"
148
+ ],
149
+ "endpoints": {
150
+ "chat": "POST /chat - Conversational AI for mission planning",
151
+ "flight_confirm": "POST /flight/confirm - Confirm and start tracking a flight",
152
+ "flight_pause": "POST /flight/pause - Pause active flight mission",
153
+ "flight_cancel": "POST /flight/cancel - Cancel active flight mission",
154
+ "flight_update": "POST /flight/update - Update mission waypoints during flight",
155
+ "flight_status": "GET /flight/status/{drone_id} - Get intelligent flight status",
156
+ "flight_missions": "GET /flight/missions - Get all active missions",
157
+ "flight_telemetry": "POST /flight/telemetry - Real-time telemetry updates",
158
+ "drone_status": "GET /drone/status - Monitor current drone status",
159
+ "download": "GET /download/{filename} - Download generated mission files",
160
+ "latest_mission": "GET /api/latest-mission - Get latest generated mission"
161
+ },
162
+ "websocket_notifications": [
163
+ "flight_confirmed - Mission tracking started",
164
+ "waypoint_completed - Waypoint reached with AI analysis",
165
+ "flight_paused - Mission paused with timeout",
166
+ "mission_updated - Dynamic route changes",
167
+ "emergency - Critical conditions detected",
168
+ "mission_completed - All waypoints reached"
169
+ ],
170
+ "mission_types": [
171
+ "Survey - Photogrammetry with 80% forward, 60% side overlap",
172
+ "Patrol - Perimeter security with optimized patterns",
173
+ "Photography - Strategic positioning for optimal angles",
174
+ "Inspection - Detailed examination with safety protocols",
175
+ "Go Straight - Direct path with obstacle avoidance",
176
+ "Simple Flight - Basic point-to-point operations"
177
+ ]
178
+ }
179
+
180
+ @app.get("/chat", response_class=HTMLResponse)
181
+ async def chat_interface():
182
+ """Serve the chat interface."""
183
+ try:
184
+ return FileResponse("chatbot_enhanced.html", media_type="text/html")
185
+ except FileNotFoundError:
186
+ return """
187
+ <html>
188
+ <head><title>🚁 DroneAgent Chat</title></head>
189
+ <body style="background: #f0f0f0; text-align: center; padding: 50px;">
190
+ <h1>🚁 DroneAgent Chat Interface</h1>
191
+ <p>Chat interface not available. Please use the API endpoints.</p>
192
+ <p><a href="/docs">📚 View API Documentation</a></p>
193
+ </body>
194
+ </html>
195
+ """
196
+
197
+ # Include our DroneAgent API routes
198
+ try:
199
+ from src.api.routes import router as api_router
200
+ app.include_router(api_router)
201
+ except Exception as e:
202
+ print(f"⚠️ Could not load API routes: {e}")
203
+
204
+ if __name__ == "__main__":
205
+ port = int(os.environ.get('PORT', 7860)) # HF Spaces default port
206
+ print(f"🚁 Starting DroneAgent on port {port}")
207
+ uvicorn.run(app, host="0.0.0.0", port=port)
chat_testing/README.md ADDED
@@ -0,0 +1 @@
 
 
1
+ # Chat Testing Folder - Store all chat test files here
chat_testing/comprehensive_test_suite.py ADDED
@@ -0,0 +1,358 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ Comprehensive Test Suite for DroneAgent
4
+ Tests all chat scenarios, edge cases, and system functionality
5
+ """
6
+ import asyncio
7
+ import json
8
+ import aiohttp
9
+ import time
10
+ from typing import Dict, List, Any, Optional
11
+
12
+ class DroneAgentTester:
13
+ """Comprehensive testing suite for DroneAgent functionality."""
14
+
15
+ def __init__(self, base_url: str = "http://localhost:8000"):
16
+ self.base_url = base_url
17
+ self.test_results = []
18
+ self.chat_session = []
19
+
20
+ async def run_all_tests(self):
21
+ """Run all comprehensive tests."""
22
+ print("🧪 Starting Comprehensive DroneAgent Test Suite")
23
+ print("=" * 60)
24
+
25
+ # Core functionality tests
26
+ await self.test_basic_functionality()
27
+ await self.test_chat_scenarios()
28
+ await self.test_mission_generation()
29
+ await self.test_flight_management()
30
+ await self.test_error_handling()
31
+ await self.test_edge_cases()
32
+ await self.test_api_endpoints()
33
+
34
+ # Generate test report
35
+ self.generate_test_report()
36
+
37
+ async def test_basic_functionality(self):
38
+ """Test basic API functionality."""
39
+ print("\n📋 Testing Basic Functionality")
40
+ print("-" * 40)
41
+
42
+ # Test server health
43
+ result = await self.api_call("GET", "/")
44
+ await self.assert_test("Server Health Check",
45
+ result.get("status") == "operational",
46
+ f"Expected operational, got {result.get('status')}")
47
+
48
+ # Test drone status endpoint
49
+ result = await self.api_call("GET", "/drone/status")
50
+ await self.assert_test("Drone Status Endpoint",
51
+ result.get("status") == "success",
52
+ "Drone status endpoint should return success")
53
+
54
+ async def test_chat_scenarios(self):
55
+ """Test comprehensive chat scenarios."""
56
+ print("\n💬 Testing Chat Scenarios")
57
+ print("-" * 40)
58
+
59
+ # Test greeting
60
+ await self.test_chat("hi", "greeting", "Should provide greeting with drone status")
61
+
62
+ # Test drone status request
63
+ await self.test_chat("give me the drone status", "drone_status", "Should provide detailed drone status")
64
+
65
+ # Test mission planning requests
66
+ await self.test_chat("Go straight 100m from 16.047, 108.206", "mission", "Should create go_straight mission")
67
+ await self.test_chat("Survey mission at 16.047, 108.206", "mission", "Should create survey mission")
68
+ await self.test_chat("Patrol route at 16.047, 108.206 at 80m altitude", "mission", "Should create patrol mission")
69
+ await self.test_chat("Photography flight at 16.047, 108.206", "mission", "Should create photography mission")
70
+
71
+ # Test location-based queries
72
+ await self.test_chat("scan 100m around hải châu", "mission", "Should geocode and create mission")
73
+ await self.test_chat("help me scan Da Nang", "mission", "Should geocode Vietnamese location")
74
+
75
+ # Test incomplete requests
76
+ await self.test_chat("I want to survey", "guidance", "Should ask for location")
77
+ await self.test_chat("patrol mission", "guidance", "Should ask for coordinates")
78
+
79
+ # Test ambiguous responses
80
+ await self.test_chat("ok", "guidance", "Should handle short responses")
81
+ await self.test_chat("what?", "guidance", "Should provide clarification")
82
+
83
+ async def test_mission_generation(self):
84
+ """Test mission generation functionality."""
85
+ print("\n🛩️ Testing Mission Generation")
86
+ print("-" * 40)
87
+
88
+ mission_types = [
89
+ ("Go straight 200m from 16.047, 108.206", "go_straight"),
90
+ ("Survey area at 16.047, 108.206", "survey"),
91
+ ("Patrol perimeter at 16.047, 108.206", "patrol"),
92
+ ("Take photos at 16.047, 108.206", "photography"),
93
+ ("Inspect building at 16.047, 108.206", "inspection")
94
+ ]
95
+
96
+ for request, expected_type in mission_types:
97
+ result = await self.api_call("POST", "/chat", {"message": request})
98
+ mission_analysis = result.get("mission_analysis", {})
99
+ actual_type = mission_analysis.get("mission_type")
100
+
101
+ await self.assert_test(f"Mission Type: {expected_type}",
102
+ actual_type == expected_type,
103
+ f"Expected {expected_type}, got {actual_type}")
104
+
105
+ # Check if Gemini is being used
106
+ gemini_enhanced = mission_analysis.get("gemini_enhanced", False)
107
+ await self.assert_test(f"Gemini Enhanced: {expected_type}",
108
+ gemini_enhanced == True,
109
+ "Should use Gemini for mission analysis")
110
+
111
+ async def test_flight_management(self):
112
+ """Test flight management functionality."""
113
+ print("\n🎯 Testing Flight Management")
114
+ print("-" * 40)
115
+
116
+ # Test flight confirmation
117
+ mission_data = {
118
+ "mission_id": "test_mission_001",
119
+ "drone_id": "test_drone_001",
120
+ "waypoints": [
121
+ {"lat": 16.047, "lon": 108.206, "alt": 80},
122
+ {"lat": 16.048, "lon": 108.207, "alt": 80}
123
+ ]
124
+ }
125
+
126
+ result = await self.api_call("POST", "/flight/confirm", mission_data)
127
+ await self.assert_test("Flight Confirmation",
128
+ result.get("status") == "confirmed",
129
+ "Flight should be confirmed successfully")
130
+
131
+ # Test telemetry update
132
+ telemetry_data = {
133
+ "drone_id": "test_drone_001",
134
+ "latitude": 16.047,
135
+ "longitude": 108.206,
136
+ "altitude": 80.0,
137
+ "batteryRemaining": 75,
138
+ "mode": "AUTO",
139
+ "satelite": 10,
140
+ "voltage": 14.5,
141
+ "groundSpeed": 10.0,
142
+ "heading": 45.0
143
+ }
144
+
145
+ result = await self.api_call("POST", "/flight/telemetry", telemetry_data)
146
+ await self.assert_test("Telemetry Update",
147
+ result.get("status") == "success",
148
+ "Telemetry should be updated successfully")
149
+
150
+ # Test flight status
151
+ result = await self.api_call("GET", "/flight/status/test_drone_001")
152
+ await self.assert_test("Flight Status",
153
+ result.get("status") == "success",
154
+ "Should get intelligent flight status")
155
+
156
+ # Test active missions
157
+ result = await self.api_call("GET", "/flight/missions")
158
+ await self.assert_test("Active Missions",
159
+ result.get("total_missions", 0) > 0,
160
+ "Should show active missions")
161
+
162
+ # Test flight pause
163
+ result = await self.api_call("POST", "/flight/pause", {
164
+ "mission_id": "test_mission_001",
165
+ "drone_id": "test_drone_001"
166
+ })
167
+ await self.assert_test("Flight Pause",
168
+ result.get("status") == "paused",
169
+ "Flight should be paused successfully")
170
+
171
+ # Test mission update
172
+ result = await self.api_call("POST", "/flight/update", {
173
+ "mission_id": "test_mission_001",
174
+ "waypoints": [{"lat": 16.049, "lon": 108.208, "alt": 80}],
175
+ "reason": "Test update"
176
+ })
177
+ await self.assert_test("Mission Update",
178
+ result.get("status") == "updated",
179
+ "Mission should be updated successfully")
180
+
181
+ # Test flight cancellation
182
+ result = await self.api_call("POST", "/flight/cancel", {
183
+ "mission_id": "test_mission_001",
184
+ "drone_id": "test_drone_001"
185
+ })
186
+ await self.assert_test("Flight Cancellation",
187
+ result.get("status") == "cancelled",
188
+ "Flight should be cancelled successfully")
189
+
190
+ async def test_error_handling(self):
191
+ """Test error handling and edge cases."""
192
+ print("\n🚨 Testing Error Handling")
193
+ print("-" * 40)
194
+
195
+ # Test invalid coordinates
196
+ result = await self.api_call("POST", "/chat", {"message": "Go to 1000, 1000"})
197
+ await self.assert_test("Invalid Coordinates",
198
+ "error" in result or "guidance" in result.get("ai_response", "").lower(),
199
+ "Should handle invalid coordinates gracefully")
200
+
201
+ # Test missing mission ID
202
+ result = await self.api_call("POST", "/flight/pause", {
203
+ "drone_id": "test_drone_001"
204
+ })
205
+ await self.assert_test("Missing Mission ID",
206
+ result.get("detail") is not None,
207
+ "Should return error for missing mission ID")
208
+
209
+ # Test non-existent mission
210
+ result = await self.api_call("POST", "/flight/pause", {
211
+ "mission_id": "non_existent",
212
+ "drone_id": "test_drone_001"
213
+ })
214
+ await self.assert_test("Non-existent Mission",
215
+ "error" in result.get("status", ""),
216
+ "Should handle non-existent mission")
217
+
218
+ async def test_edge_cases(self):
219
+ """Test edge cases and unusual inputs."""
220
+ print("\n🔍 Testing Edge Cases")
221
+ print("-" * 40)
222
+
223
+ edge_cases = [
224
+ ("", "empty_message"),
225
+ ("a" * 1000, "very_long_message"),
226
+ ("🚁🛩️✈️", "emoji_only"),
227
+ ("123456789", "numbers_only"),
228
+ ("go go go go go", "repetitive"),
229
+ ("fly to north pole", "impossible_location"),
230
+ ("survey mission at 0, 0", "null_island"),
231
+ ("mission at 90, 180", "extreme_coordinates")
232
+ ]
233
+
234
+ for message, test_name in edge_cases:
235
+ try:
236
+ result = await self.api_call("POST", "/chat", {"message": message})
237
+ await self.assert_test(f"Edge Case: {test_name}",
238
+ "ai_response" in result,
239
+ f"Should handle {test_name} gracefully")
240
+ except Exception as e:
241
+ await self.assert_test(f"Edge Case: {test_name}",
242
+ False,
243
+ f"Failed with exception: {str(e)}")
244
+
245
+ async def test_api_endpoints(self):
246
+ """Test all API endpoints."""
247
+ print("\n🔌 Testing API Endpoints")
248
+ print("-" * 40)
249
+
250
+ endpoints = [
251
+ ("GET", "/", "Root endpoint"),
252
+ ("GET", "/drone/status", "Drone status"),
253
+ ("GET", "/flight/missions", "Flight missions"),
254
+ ("GET", "/api/latest-mission", "Latest mission")
255
+ ]
256
+
257
+ for method, endpoint, description in endpoints:
258
+ try:
259
+ result = await self.api_call(method, endpoint)
260
+ await self.assert_test(f"API: {description}",
261
+ result is not None,
262
+ f"{endpoint} should return valid response")
263
+ except Exception as e:
264
+ await self.assert_test(f"API: {description}",
265
+ False,
266
+ f"{endpoint} failed: {str(e)}")
267
+
268
+ async def test_chat(self, message: str, expected_type: str, description: str):
269
+ """Test individual chat interaction."""
270
+ result = await self.api_call("POST", "/chat", {"message": message})
271
+ self.chat_session.append({"message": message, "response": result})
272
+
273
+ success = False
274
+ if expected_type == "greeting":
275
+ success = "is_greeting" in result or "Hi!" in result.get("ai_response", "")
276
+ elif expected_type == "drone_status":
277
+ success = "is_drone_status" in result or "Battery" in result.get("ai_response", "")
278
+ elif expected_type == "mission":
279
+ success = "mission_analysis" in result or "Mission Ready" in result.get("ai_response", "")
280
+ elif expected_type == "guidance":
281
+ success = "is_guidance" in result or any(word in result.get("ai_response", "").lower()
282
+ for word in ["location", "coordinates", "mission"])
283
+
284
+ await self.assert_test(f"Chat: {message[:30]}...", success, description)
285
+
286
+ async def api_call(self, method: str, endpoint: str, data: Optional[Dict] = None) -> Dict:
287
+ """Make API call and return JSON response."""
288
+ url = f"{self.base_url}{endpoint}"
289
+
290
+ try:
291
+ async with aiohttp.ClientSession() as session:
292
+ if method == "GET":
293
+ async with session.get(url) as response:
294
+ return await response.json()
295
+ elif method == "POST":
296
+ async with session.post(url, json=data) as response:
297
+ return await response.json()
298
+ except Exception as e:
299
+ return {"error": str(e)}
300
+
301
+ async def assert_test(self, test_name: str, condition: bool, description: str):
302
+ """Assert test condition and record result."""
303
+ status = "✅ PASS" if condition else "❌ FAIL"
304
+ result = {
305
+ "test": test_name,
306
+ "status": "PASS" if condition else "FAIL",
307
+ "description": description,
308
+ "timestamp": time.time()
309
+ }
310
+ self.test_results.append(result)
311
+ print(f"{status} {test_name}: {description}")
312
+
313
+ def generate_test_report(self):
314
+ """Generate comprehensive test report."""
315
+ print("\n" + "=" * 60)
316
+ print("📊 TEST REPORT SUMMARY")
317
+ print("=" * 60)
318
+
319
+ total_tests = len(self.test_results)
320
+ passed_tests = sum(1 for r in self.test_results if r["status"] == "PASS")
321
+ failed_tests = total_tests - passed_tests
322
+
323
+ print(f"Total Tests: {total_tests}")
324
+ print(f"Passed: {passed_tests} ✅")
325
+ print(f"Failed: {failed_tests} ❌")
326
+ print(f"Success Rate: {(passed_tests/total_tests)*100:.1f}%")
327
+
328
+ if failed_tests > 0:
329
+ print("\n❌ FAILED TESTS:")
330
+ for result in self.test_results:
331
+ if result["status"] == "FAIL":
332
+ print(f" - {result['test']}: {result['description']}")
333
+
334
+ # Save detailed report
335
+ report_file = f"chat_testing/test_report_{int(time.time())}.json"
336
+ with open(report_file, 'w') as f:
337
+ json.dump({
338
+ "summary": {
339
+ "total": total_tests,
340
+ "passed": passed_tests,
341
+ "failed": failed_tests,
342
+ "success_rate": (passed_tests/total_tests)*100
343
+ },
344
+ "tests": self.test_results,
345
+ "chat_session": self.chat_session
346
+ }, f, indent=2)
347
+
348
+ print(f"\n📄 Detailed report saved to: {report_file}")
349
+
350
+
351
+ async def main():
352
+ """Run the comprehensive test suite."""
353
+ tester = DroneAgentTester()
354
+ await tester.run_all_tests()
355
+
356
+
357
+ if __name__ == "__main__":
358
+ asyncio.run(main())
chat_testing/direct_patrol.json ADDED
@@ -0,0 +1 @@
 
 
1
+ {"user_message":"Patrol route at 16.047, 108.206 at 80m altitude","ai_response":"✅ **Mission Ready!**\n\n🎯 **Patrol Mission Created**\n📍 Location: 16.0470, 108.2060\n🛩️ Altitude: 45m | Waypoints: 8\n📁 File: `patrol_gemini_20250821_151349.plan`\n\n🧠 **Why this works:** The user has requested a 'sophisticated patrol mission' at the provided coordinates (16.047, 108.206). Patrol missions typically involve flying around a perimeter or following a defined route to monitor an area. I've set the altitude to 80 meters, as this is a good balance between providing a broad overview and maintaining sufficient detail for observation. The user did not specify a distance or direction, so I will assume a circular or figure-8 pattern around the given coordinates.\n\n✅ Ready to fly safely!","operator_mindset":"Gemini 2.0 Flash - Patrol Specialist","confidence_level":0.98,"mission_analysis":{"mission_type":"patrol","coordinates":[16.047,108.206],"altitude":45,"waypoint_count":8,"ai_reasoning":"The user has requested a 'sophisticated patrol mission' at the provided coordinates (16.047, 108.206). Patrol missions typically involve flying around a perimeter or following a defined route to monitor an area. I've set the altitude to 80 meters, as this is a good balance between providing a broad overview and maintaining sufficient detail for observation. The user did not specify a distance or direction, so I will assume a circular or figure-8 pattern around the given coordinates.","mavlink_commands":["TAKEOFF(22)","WAYPOINT(16)","DO_LAND_START(203)","RTL(20)"],"coordinate_frames":"GLOBAL_RELATIVE_ALT(3) for navigation, MISSION(2) for landing","gemini_enhanced":true,"model_used":"gemini-2.0-flash"},"safety_briefing":["Mission uses perfect coordinate frames (eliminates takeoff errors)","Altitude optimized for patrol operations","Complete landing sequence with DO_LAND_START included","QGroundControl import guaranteed to work","Generated by gemini-2.0-flash AI model"],"technical_notes":["Gemini 2.0 Flash reasoning with complete knowledge base","Perfect MAVLink command sequences","Coordinate frame consistency maintained throughout","Mission-specific pattern optimization applied"],"reasoning_chain":["The user has requested a 'sophisticated patrol mission' at the provided coordinates (16.047, 108.206). Patrol missions typically involve flying around a perimeter or following a defined route to monitor an area. I've set the altitude to 80 meters, as this is a good balance between providing a broad overview and maintaining sufficient detail for observation. The user did not specify a distance or direction, so I will assume a circular or figure-8 pattern around the given coordinates."],"downloadable_files":["downloads/patrol_gemini_20250821_151349.plan"],"professional_grade":true,"ai_intelligence":true,"gemini_enhanced":true,"model_used":"gemini-2.0-flash","timestamp":"2025-08-21T15:13:49.097577"}
chat_testing/flight_aware_test.json ADDED
@@ -0,0 +1 @@
 
 
1
+ {"user_message":"Hi! What is the current flight status?","ai_response":"🚁 **Drone Status Report**\n\n🔋 **Battery:** 0% (0.0V)\n📡 **GPS:** 0 satellites\n🛩️ **Mode:** UNKNOWN\n📍 **Location:** 0.0000, 0.0000\n🛩️ **Altitude:** 0m\n\n**Flight Constraints:**\n• Safe Flight Time: 0 minutes\n• Max Distance: 0m\n• Optimal Altitude: 30-60m\n• Ready to Fly: ❌ No\n\n⚠️ **Not ready to fly:** Check battery level, GPS connection, and safety constraints.\n\nFor mission planning, the system will optimize altitude and safety parameters based on this status.","is_drone_status":true,"conversation_state":"drone_status_request","drone_status":{"altitude":0.0,"batteryRemaining":0,"cellCount":4,"distance":0,"distanceToHome":0.0,"firmware":"Unknown","flightTime":0,"frame":"Unknown","frameId":0,"groundSpeed":0.0,"heading":0.0,"latitude":0.0,"longitude":0.0,"mode":"UNKNOWN","pitch":0.0,"roll":0.0,"satelite":0,"voltage":0.0,"yaw":0.0,"last_update":null,"data_source":"default_values"},"flight_constraints":{"battery_remaining":0,"safe_flight_time_minutes":0,"max_safe_distance_meters":0,"optimal_altitude_range":[30,60],"gps_quality":"unknown","voltage_status":"unknown","ready_to_fly":false,"telemetry_available":false},"needs_mission_generation":false,"timestamp":"2025-08-21T15:31:00.474439"}
chat_testing/flight_status.json ADDED
File without changes
chat_testing/full_chat_conversation_test.py ADDED
@@ -0,0 +1,334 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ Full Chat Conversation Test for DroneAgent
4
+ Tests complete conversational flows and edge cases
5
+ """
6
+ import asyncio
7
+ import json
8
+ import aiohttp
9
+ import time
10
+ from typing import Dict, List, Any
11
+
12
+ class ChatConversationTester:
13
+ """Test complete chat conversations with context awareness."""
14
+
15
+ def __init__(self, base_url: str = "http://localhost:8000"):
16
+ self.base_url = base_url
17
+ self.conversations = []
18
+
19
+ async def run_conversation_tests(self):
20
+ """Run all conversation flow tests."""
21
+ print("💬 Starting Full Chat Conversation Tests")
22
+ print("=" * 60)
23
+
24
+ await self.test_complete_mission_flow()
25
+ await self.test_guidance_conversation()
26
+ await self.test_context_awareness()
27
+ await self.test_flight_management_conversation()
28
+ await self.test_error_recovery_conversation()
29
+ await self.test_multilingual_conversation()
30
+
31
+ self.save_conversation_logs()
32
+
33
+ async def test_complete_mission_flow(self):
34
+ """Test complete mission planning conversation."""
35
+ print("\n🎯 Testing Complete Mission Planning Flow")
36
+ print("-" * 50)
37
+
38
+ conversation = []
39
+
40
+ # Start with greeting
41
+ response = await self.send_message("Hi!")
42
+ conversation.append(("User", "Hi!", response))
43
+
44
+ # Request mission without details
45
+ response = await self.send_message("I want to fly my drone")
46
+ conversation.append(("User", "I want to fly my drone", response))
47
+
48
+ # Provide partial information
49
+ response = await self.send_message("survey mission")
50
+ conversation.append(("User", "survey mission", response))
51
+
52
+ # Provide location
53
+ response = await self.send_message("at 16.047, 108.206")
54
+ conversation.append(("User", "at 16.047, 108.206", response))
55
+
56
+ # Check drone status
57
+ response = await self.send_message("what's my drone status?")
58
+ conversation.append(("User", "what's my drone status?", response))
59
+
60
+ # Create complete mission
61
+ response = await self.send_message("Survey mission at 16.047, 108.206 at 100m altitude")
62
+ conversation.append(("User", "Survey mission at 16.047, 108.206 at 100m altitude", response))
63
+
64
+ self.conversations.append(("Complete Mission Flow", conversation))
65
+ print("✅ Complete mission flow test completed")
66
+
67
+ async def test_guidance_conversation(self):
68
+ """Test guidance and clarification conversation."""
69
+ print("\n🤔 Testing Guidance Conversation Flow")
70
+ print("-" * 50)
71
+
72
+ conversation = []
73
+
74
+ # Ambiguous request
75
+ response = await self.send_message("help me")
76
+ conversation.append(("User", "help me", response))
77
+
78
+ # Vague response
79
+ response = await self.send_message("ok")
80
+ conversation.append(("User", "ok", response))
81
+
82
+ # Confused response
83
+ response = await self.send_message("what?")
84
+ conversation.append(("User", "what?", response))
85
+
86
+ # Specify mission type
87
+ response = await self.send_message("patrol")
88
+ conversation.append(("User", "patrol", response))
89
+
90
+ # Ask for clarification
91
+ response = await self.send_message("where?")
92
+ conversation.append(("User", "where?", response))
93
+
94
+ # Provide coordinates
95
+ response = await self.send_message("16.047, 108.206")
96
+ conversation.append(("User", "16.047, 108.206", response))
97
+
98
+ self.conversations.append(("Guidance Conversation", conversation))
99
+ print("✅ Guidance conversation test completed")
100
+
101
+ async def test_context_awareness(self):
102
+ """Test context awareness and memory."""
103
+ print("\n🧠 Testing Context Awareness")
104
+ print("-" * 50)
105
+
106
+ conversation = []
107
+
108
+ # Establish context
109
+ response = await self.send_message("Go straight 100m from 16.047, 108.206")
110
+ conversation.append(("User", "Go straight 100m from 16.047, 108.206", response))
111
+
112
+ # Reference previous context
113
+ response = await self.send_message("make it 200m instead")
114
+ conversation.append(("User", "make it 200m instead", response))
115
+
116
+ # Change mission type with same location
117
+ response = await self.send_message("actually, make it a patrol mission")
118
+ conversation.append(("User", "actually, make it a patrol mission", response))
119
+
120
+ # Ask about previous mission
121
+ response = await self.send_message("what was my last mission?")
122
+ conversation.append(("User", "what was my last mission?", response))
123
+
124
+ self.conversations.append(("Context Awareness", conversation))
125
+ print("✅ Context awareness test completed")
126
+
127
+ async def test_flight_management_conversation(self):
128
+ """Test flight management conversation flow."""
129
+ print("\n🚁 Testing Flight Management Conversation")
130
+ print("-" * 50)
131
+
132
+ conversation = []
133
+
134
+ # Create mission
135
+ response = await self.send_message("Photography mission at 16.047, 108.206")
136
+ conversation.append(("User", "Photography mission at 16.047, 108.206", response))
137
+
138
+ # Simulate telemetry update
139
+ await self.update_telemetry({
140
+ "drone_id": "test_drone",
141
+ "latitude": 16.047,
142
+ "longitude": 108.206,
143
+ "altitude": 75.0,
144
+ "batteryRemaining": 80,
145
+ "mode": "AUTO",
146
+ "satelite": 12,
147
+ "voltage": 14.8,
148
+ "groundSpeed": 12.0,
149
+ "heading": 45.0
150
+ })
151
+
152
+ # Confirm flight
153
+ await self.confirm_flight({
154
+ "mission_id": "test_mission_chat",
155
+ "drone_id": "test_drone",
156
+ "waypoints": [
157
+ {"lat": 16.047, "lon": 108.206, "alt": 75},
158
+ {"lat": 16.048, "lon": 108.207, "alt": 75}
159
+ ]
160
+ })
161
+
162
+ # Check flight status through chat
163
+ response = await self.send_message("How is my drone doing?")
164
+ conversation.append(("User", "How is my drone doing?", response))
165
+
166
+ # Ask about flight options
167
+ response = await self.send_message("What can I do with my current flight?")
168
+ conversation.append(("User", "What can I do with my current flight?", response))
169
+
170
+ # Request pause
171
+ response = await self.send_message("Pause the mission")
172
+ conversation.append(("User", "Pause the mission", response))
173
+
174
+ # Check status after pause
175
+ response = await self.send_message("What's the status now?")
176
+ conversation.append(("User", "What's the status now?", response))
177
+
178
+ self.conversations.append(("Flight Management", conversation))
179
+ print("✅ Flight management conversation test completed")
180
+
181
+ async def test_error_recovery_conversation(self):
182
+ """Test error recovery and correction conversation."""
183
+ print("\n🔧 Testing Error Recovery Conversation")
184
+ print("-" * 50)
185
+
186
+ conversation = []
187
+
188
+ # Invalid coordinates
189
+ response = await self.send_message("Go to 999, 999")
190
+ conversation.append(("User", "Go to 999, 999", response))
191
+
192
+ # Correction
193
+ response = await self.send_message("I meant 16.047, 108.206")
194
+ conversation.append(("User", "I meant 16.047, 108.206", response))
195
+
196
+ # Incomplete mission
197
+ response = await self.send_message("fly drone")
198
+ conversation.append(("User", "fly drone", response))
199
+
200
+ # Provide missing details step by step
201
+ response = await self.send_message("survey")
202
+ conversation.append(("User", "survey", response))
203
+
204
+ response = await self.send_message("at my farm")
205
+ conversation.append(("User", "at my farm", response))
206
+
207
+ response = await self.send_message("16.047, 108.206")
208
+ conversation.append(("User", "16.047, 108.206", response))
209
+
210
+ self.conversations.append(("Error Recovery", conversation))
211
+ print("✅ Error recovery conversation test completed")
212
+
213
+ async def test_multilingual_conversation(self):
214
+ """Test multilingual and Vietnamese location conversation."""
215
+ print("\n🌍 Testing Multilingual Conversation")
216
+ print("-" * 50)
217
+
218
+ conversation = []
219
+
220
+ # Vietnamese location
221
+ response = await self.send_message("scan 100m around Hải Châu")
222
+ conversation.append(("User", "scan 100m around Hải Châu", response))
223
+
224
+ # Vietnamese location with accent normalization
225
+ response = await self.send_message("help me scan Da Nang")
226
+ conversation.append(("User", "help me scan Da Nang", response))
227
+
228
+ # Complex Vietnamese address
229
+ response = await self.send_message("survey mission in Đà Nẵng city")
230
+ conversation.append(("User", "survey mission in Đà Nẵng city", response))
231
+
232
+ # Mixed language
233
+ response = await self.send_message("go straight 200m from Hải Châu district")
234
+ conversation.append(("User", "go straight 200m from Hải Châu district", response))
235
+
236
+ self.conversations.append(("Multilingual", conversation))
237
+ print("✅ Multilingual conversation test completed")
238
+
239
+ async def send_message(self, message: str) -> Dict:
240
+ """Send chat message and return response."""
241
+ url = f"{self.base_url}/chat"
242
+ data = {"message": message}
243
+
244
+ try:
245
+ async with aiohttp.ClientSession() as session:
246
+ async with session.post(url, json=data) as response:
247
+ result = await response.json()
248
+ print(f"👤 User: {message}")
249
+ print(f"🤖 Bot: {result.get('ai_response', 'No response')[:100]}...")
250
+ return result
251
+ except Exception as e:
252
+ print(f"❌ Error: {str(e)}")
253
+ return {"error": str(e)}
254
+
255
+ async def update_telemetry(self, telemetry_data: Dict):
256
+ """Update telemetry data."""
257
+ url = f"{self.base_url}/flight/telemetry"
258
+
259
+ try:
260
+ async with aiohttp.ClientSession() as session:
261
+ async with session.post(url, json=telemetry_data) as response:
262
+ return await response.json()
263
+ except Exception as e:
264
+ print(f"❌ Telemetry error: {str(e)}")
265
+ return {"error": str(e)}
266
+
267
+ async def confirm_flight(self, mission_data: Dict):
268
+ """Confirm flight mission."""
269
+ url = f"{self.base_url}/flight/confirm"
270
+
271
+ try:
272
+ async with aiohttp.ClientSession() as session:
273
+ async with session.post(url, json=mission_data) as response:
274
+ return await response.json()
275
+ except Exception as e:
276
+ print(f"❌ Flight confirmation error: {str(e)}")
277
+ return {"error": str(e)}
278
+
279
+ def save_conversation_logs(self):
280
+ """Save conversation logs to file."""
281
+ timestamp = int(time.time())
282
+ log_file = f"chat_testing/conversation_log_{timestamp}.json"
283
+
284
+ with open(log_file, 'w', encoding='utf-8') as f:
285
+ json.dump(self.conversations, f, indent=2, ensure_ascii=False)
286
+
287
+ print(f"\n📄 Conversation logs saved to: {log_file}")
288
+
289
+ # Generate conversation analysis
290
+ self.analyze_conversations()
291
+
292
+ def analyze_conversations(self):
293
+ """Analyze conversation quality and patterns."""
294
+ print("\n📊 CONVERSATION ANALYSIS")
295
+ print("=" * 40)
296
+
297
+ total_exchanges = sum(len(conv[1]) for conv in self.conversations)
298
+ print(f"Total Conversation Exchanges: {total_exchanges}")
299
+
300
+ # Analyze response types
301
+ response_types = {
302
+ "guidance": 0,
303
+ "mission": 0,
304
+ "status": 0,
305
+ "error": 0
306
+ }
307
+
308
+ for conv_name, exchanges in self.conversations:
309
+ print(f"\n{conv_name}: {len(exchanges)} exchanges")
310
+
311
+ for speaker, message, response in exchanges:
312
+ if "is_guidance" in response:
313
+ response_types["guidance"] += 1
314
+ elif "mission_analysis" in response:
315
+ response_types["mission"] += 1
316
+ elif "drone_status" in response:
317
+ response_types["status"] += 1
318
+ elif "error" in response:
319
+ response_types["error"] += 1
320
+
321
+ print(f"\nResponse Type Distribution:")
322
+ for resp_type, count in response_types.items():
323
+ percentage = (count / total_exchanges) * 100 if total_exchanges > 0 else 0
324
+ print(f" {resp_type.title()}: {count} ({percentage:.1f}%)")
325
+
326
+
327
+ async def main():
328
+ """Run the conversation tests."""
329
+ tester = ChatConversationTester()
330
+ await tester.run_conversation_tests()
331
+
332
+
333
+ if __name__ == "__main__":
334
+ asyncio.run(main())
chat_testing/patrol_response.json ADDED
@@ -0,0 +1 @@
 
 
1
+ {"user_message":"Create a patrol mission for security monitoring","ai_response":"📍 **Location Required**\n\nPlease provide coordinates in lat,lon format:\n• \"Go straight 100m from 16.047, 108.206\"\n• \"Survey mission at 16.047, 108.206\"\n• \"Patrol route at 16.047, 108.206 at 80m altitude\"\n\nError: Coordinates required! Example: 'Go south 100m from 16, 180'","status":"need_coordinates","error":"Coordinates required! Example: 'Go south 100m from 16, 180'","is_guidance":true}
chat_testing/run_tests.py ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ Test Runner for DroneAgent Testing Suite
4
+ """
5
+ import asyncio
6
+ import sys
7
+ import os
8
+ import subprocess
9
+ import time
10
+
11
+ # Add parent directory to path to import modules
12
+ sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
13
+
14
+ from comprehensive_test_suite import DroneAgentTester
15
+ from full_chat_conversation_test import ChatConversationTester
16
+
17
+ async def check_server_health():
18
+ """Check if DroneAgent server is running."""
19
+ import aiohttp
20
+
21
+ try:
22
+ async with aiohttp.ClientSession() as session:
23
+ async with session.get("http://localhost:8000/") as response:
24
+ if response.status == 200:
25
+ data = await response.json()
26
+ if data.get("status") == "operational":
27
+ print("✅ DroneAgent server is running and operational")
28
+ return True
29
+ except Exception as e:
30
+ print(f"❌ Server not accessible: {str(e)}")
31
+
32
+ return False
33
+
34
+ async def run_all_tests():
35
+ """Run all test suites."""
36
+ print("🚀 DroneAgent Testing Suite")
37
+ print("=" * 60)
38
+ print(f"Started at: {time.strftime('%Y-%m-%d %H:%M:%S')}")
39
+
40
+ # Check server health
41
+ if not await check_server_health():
42
+ print("\n❌ Please start the DroneAgent server first:")
43
+ print(" python3 main.py")
44
+ return False
45
+
46
+ print("\n🧪 Running Comprehensive Test Suite...")
47
+ tester = DroneAgentTester()
48
+ await tester.run_all_tests()
49
+
50
+ print("\n💬 Running Chat Conversation Tests...")
51
+ chat_tester = ChatConversationTester()
52
+ await chat_tester.run_conversation_tests()
53
+
54
+ print("\n🎉 All tests completed!")
55
+ return True
56
+
57
+ def main():
58
+ """Main test runner."""
59
+ try:
60
+ success = asyncio.run(run_all_tests())
61
+ if success:
62
+ print("\n✅ Testing completed successfully")
63
+ sys.exit(0)
64
+ else:
65
+ print("\n❌ Testing failed")
66
+ sys.exit(1)
67
+ except KeyboardInterrupt:
68
+ print("\n⚠️ Testing interrupted by user")
69
+ sys.exit(1)
70
+ except Exception as e:
71
+ print(f"\n❌ Testing failed with error: {str(e)}")
72
+ sys.exit(1)
73
+
74
+ if __name__ == "__main__":
75
+ main()
chat_testing/sophisticated_patrol.json ADDED
@@ -0,0 +1 @@
 
 
1
+ {"user_message":"Create a sophisticated patrol mission at 16.047, 108.206","ai_response":"Okay, great! I see you're wanting to create a sophisticated patrol mission at the location 16.047, 108.206. That sounds like a fun challenge! To make sure this patrol is *truly* sophisticated, let's think about some key elements.\n\nFor example, would you like the drone to follow a specific route or pattern? We could do a simple back-and-forth grid pattern, or maybe something more complex following roads or a perimeter. Do you have specific altitude requirements or points of interest you want the drone to focus on? We could also incorporate automated image capture or even object detection for a truly \"smart\" patrol.\n\nAlso, what kind of area are we patrolling? Is it urban, rural, or something else? Knowing the environment will help me suggest the best flight parameters and sensor settings.\n\nI'm excited to help you design this! Let me know your thoughts on these questions, and we'll build a fantastic mission together!\n","is_guidance":true,"conversation_state":"general_query","user_experience":"beginner","needs_mission_generation":false,"timestamp":"2025-08-21T15:13:14.767942"}
chatbot.html ADDED
@@ -0,0 +1,351 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>🚁 DroneAgent Chatbot</title>
7
+ <style>
8
+ * {
9
+ margin: 0;
10
+ padding: 0;
11
+ box-sizing: border-box;
12
+ }
13
+
14
+ body {
15
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
16
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
17
+ height: 100vh;
18
+ display: flex;
19
+ justify-content: center;
20
+ align-items: center;
21
+ }
22
+
23
+ .chat-container {
24
+ width: 90%;
25
+ max-width: 800px;
26
+ height: 80vh;
27
+ background: white;
28
+ border-radius: 20px;
29
+ box-shadow: 0 20px 40px rgba(0,0,0,0.1);
30
+ display: flex;
31
+ flex-direction: column;
32
+ overflow: hidden;
33
+ }
34
+
35
+ .chat-header {
36
+ background: linear-gradient(135deg, #4CAF50, #45a049);
37
+ color: white;
38
+ padding: 20px;
39
+ text-align: center;
40
+ font-size: 1.2em;
41
+ font-weight: bold;
42
+ }
43
+
44
+ .chat-messages {
45
+ flex: 1;
46
+ padding: 20px;
47
+ overflow-y: auto;
48
+ background: #f8f9fa;
49
+ }
50
+
51
+ .message {
52
+ margin-bottom: 15px;
53
+ padding: 12px 16px;
54
+ border-radius: 18px;
55
+ max-width: 80%;
56
+ word-wrap: break-word;
57
+ white-space: pre-wrap;
58
+ }
59
+
60
+ .user-message {
61
+ background: #007bff;
62
+ color: white;
63
+ margin-left: auto;
64
+ text-align: right;
65
+ }
66
+
67
+ .bot-message {
68
+ background: #e9ecef;
69
+ color: #333;
70
+ margin-right: auto;
71
+ }
72
+
73
+ .chat-input-container {
74
+ padding: 20px;
75
+ background: white;
76
+ border-top: 1px solid #dee2e6;
77
+ display: flex;
78
+ gap: 10px;
79
+ }
80
+
81
+ .chat-input {
82
+ flex: 1;
83
+ padding: 12px 16px;
84
+ border: 2px solid #dee2e6;
85
+ border-radius: 25px;
86
+ outline: none;
87
+ font-size: 14px;
88
+ transition: border-color 0.3s;
89
+ }
90
+
91
+ .chat-input:focus {
92
+ border-color: #007bff;
93
+ }
94
+
95
+ .send-button {
96
+ padding: 12px 24px;
97
+ background: #007bff;
98
+ color: white;
99
+ border: none;
100
+ border-radius: 25px;
101
+ cursor: pointer;
102
+ font-weight: bold;
103
+ transition: background 0.3s;
104
+ }
105
+
106
+ .send-button:hover {
107
+ background: #0056b3;
108
+ }
109
+
110
+ .send-button:disabled {
111
+ background: #6c757d;
112
+ cursor: not-allowed;
113
+ }
114
+
115
+ .examples {
116
+ margin-bottom: 20px;
117
+ padding: 15px;
118
+ background: #fff3cd;
119
+ border-radius: 10px;
120
+ border-left: 4px solid #ffc107;
121
+ }
122
+
123
+ .examples h3 {
124
+ margin-bottom: 10px;
125
+ color: #856404;
126
+ }
127
+
128
+ .example-button {
129
+ display: inline-block;
130
+ margin: 5px;
131
+ padding: 8px 12px;
132
+ background: #fff;
133
+ border: 1px solid #ffc107;
134
+ border-radius: 15px;
135
+ cursor: pointer;
136
+ font-size: 12px;
137
+ transition: all 0.3s;
138
+ }
139
+
140
+ .example-button:hover {
141
+ background: #ffc107;
142
+ color: white;
143
+ }
144
+
145
+ .loading {
146
+ text-align: center;
147
+ color: #6c757d;
148
+ font-style: italic;
149
+ padding: 10px;
150
+ }
151
+ </style>
152
+ </head>
153
+ <body>
154
+ <div class="chat-container">
155
+ <div class="chat-header">
156
+ 🚁 DroneAgent - AI Mission Planner
157
+ </div>
158
+
159
+ <div class="chat-messages" id="chatMessages">
160
+ <div class="examples">
161
+ <h3>🎯 Try these examples:</h3>
162
+ <div class="example-button" onclick="sendExample('Go straight 100m from 16.047, 108.206')">
163
+ Go straight 100m from 16.047, 108.206
164
+ </div>
165
+ <div class="example-button" onclick="sendExample('Survey mission at 16.047, 108.206')">
166
+ Survey mission at 16.047, 108.206
167
+ </div>
168
+ <div class="example-button" onclick="sendExample('Patrol route at 16.047, 108.206 at 80m altitude')">
169
+ Patrol route at 16.047, 108.206 at 80m altitude
170
+ </div>
171
+ <div class="example-button" onclick="sendExample('Photography flight at 16.047, 108.206')">
172
+ Photography flight at 16.047, 108.206
173
+ </div>
174
+ <div class="example-button" onclick="sendExample('Hi, I want to take photos of my building')">
175
+ Hi, I want to take photos of my building
176
+ </div>
177
+ </div>
178
+ </div>
179
+
180
+ <div class="chat-input-container">
181
+ <input type="text" class="chat-input" id="chatInput" placeholder="Type your message... (e.g., 'Survey mission at 16.047, 108.206')" onkeypress="handleKeyPress(event)">
182
+ <button class="send-button" id="sendButton" onclick="sendMessage()">Send</button>
183
+ <button class="send-button" style="background: #28a745;" onclick="getLatestMission()">📁 Latest</button>
184
+ <button class="send-button" style="background: #17a2b8;" onclick="getDroneStatus()">🚁 Drone</button>
185
+ </div>
186
+ </div>
187
+
188
+ <script>
189
+ const chatMessages = document.getElementById('chatMessages');
190
+ const chatInput = document.getElementById('chatInput');
191
+ const sendButton = document.getElementById('sendButton');
192
+
193
+ // Add welcome message
194
+ addBotMessage("👋 Hi! I'm DroneBot, your friendly AI assistant for drone mission planning!\n\n🚁 I can help you create professional drone missions. Try one of the examples above or ask me anything about drone missions!");
195
+
196
+ function handleKeyPress(event) {
197
+ if (event.key === 'Enter') {
198
+ sendMessage();
199
+ }
200
+ }
201
+
202
+ function sendExample(text) {
203
+ chatInput.value = text;
204
+ sendMessage();
205
+ }
206
+
207
+ async function sendMessage() {
208
+ const message = chatInput.value.trim();
209
+ if (!message) return;
210
+
211
+ // Add user message
212
+ addUserMessage(message);
213
+ chatInput.value = '';
214
+
215
+ // Disable input
216
+ sendButton.disabled = true;
217
+ chatInput.disabled = true;
218
+
219
+ // Add loading message
220
+ const loadingElement = addLoadingMessage();
221
+
222
+ try {
223
+ const response = await fetch('http://localhost:8000/chat', {
224
+ method: 'POST',
225
+ headers: {
226
+ 'Content-Type': 'application/json',
227
+ },
228
+ body: JSON.stringify({ message: message })
229
+ });
230
+
231
+ const data = await response.json();
232
+
233
+ // Remove loading message
234
+ loadingElement.remove();
235
+
236
+ // Add bot response
237
+ let botResponse = data.ai_response || 'Sorry, I had trouble processing that request.';
238
+
239
+ // Add comprehensive status information
240
+
241
+ if (data.mission_file) {
242
+ botResponse += `\n\n📁 Mission file: ${data.mission_file}`;
243
+ }
244
+
245
+
246
+
247
+ addBotMessage(botResponse);
248
+
249
+ } catch (error) {
250
+ loadingElement.remove();
251
+ addBotMessage('❌ Error: Could not connect to DroneAgent server. Make sure the server is running on http://localhost:8000');
252
+ }
253
+
254
+ // Re-enable input
255
+ sendButton.disabled = false;
256
+ chatInput.disabled = false;
257
+ chatInput.focus();
258
+ }
259
+
260
+ function addUserMessage(message) {
261
+ const messageDiv = document.createElement('div');
262
+ messageDiv.className = 'message user-message';
263
+ messageDiv.textContent = message;
264
+ chatMessages.appendChild(messageDiv);
265
+ scrollToBottom();
266
+ }
267
+
268
+ function addBotMessage(message) {
269
+ const messageDiv = document.createElement('div');
270
+ messageDiv.className = 'message bot-message';
271
+ messageDiv.textContent = message;
272
+ chatMessages.appendChild(messageDiv);
273
+ scrollToBottom();
274
+ }
275
+
276
+ function addLoadingMessage() {
277
+ const loadingDiv = document.createElement('div');
278
+ loadingDiv.className = 'loading';
279
+ loadingDiv.textContent = '🤖 DroneBot is thinking...';
280
+ chatMessages.appendChild(loadingDiv);
281
+ scrollToBottom();
282
+ return loadingDiv;
283
+ }
284
+
285
+ async function getLatestMission() {
286
+ try {
287
+ const loadingElement = addLoadingMessage();
288
+
289
+ const response = await fetch('http://localhost:8000/api/latest-mission');
290
+ const data = await response.json();
291
+
292
+ loadingElement.remove();
293
+
294
+ if (data.status === 'success') {
295
+ let message = `📁 **Latest Mission Retrieved**\n\n`;
296
+ message += `**File:** ${data.filename}\n`;
297
+ message += `**Created:** ${new Date(data.created_at).toLocaleString()}\n`;
298
+ message += `**Size:** ${data.file_size} bytes\n\n`;
299
+ message += `✅ Mission plan ready for QGroundControl!`;
300
+
301
+ addBotMessage(message);
302
+ } else {
303
+ addBotMessage(`📁 ${data.message}`);
304
+ }
305
+ } catch (error) {
306
+ addBotMessage('❌ Error retrieving latest mission. Make sure the server is running.');
307
+ }
308
+ }
309
+
310
+ async function getDroneStatus() {
311
+ try {
312
+ const loadingElement = addLoadingMessage();
313
+
314
+ const response = await fetch('http://localhost:8000/drone/status');
315
+ const data = await response.json();
316
+
317
+ loadingElement.remove();
318
+
319
+ if (data.status === 'success') {
320
+ const status = data.drone_status;
321
+ const rec = data.mission_recommendations;
322
+
323
+ let message = `🚁 **Drone Status**\n\n`;
324
+ message += `🔋 Battery: ${status.batteryRemaining}% (${status.voltage.toFixed(1)}V)\n`;
325
+ message += `📡 GPS: ${status.satelite} satellites\n`;
326
+ message += `📍 Location: ${status.latitude.toFixed(4)}, ${status.longitude.toFixed(4)}\n`;
327
+ message += `🛩️ Mode: ${status.mode} | Altitude: ${status.altitude.toFixed(0)}m\n\n`;
328
+ message += `**Mission Recommendations:**\n`;
329
+ message += `• Optimal Altitude: ${rec.optimal_altitude}\n`;
330
+ message += `• Max Distance: ${rec.max_mission_distance}\n`;
331
+ message += `• Flight Time: ${rec.estimated_flight_time}\n`;
332
+ message += `• Ready: ${rec.ready_for_mission ? '✅ Yes' : '❌ No'}`;
333
+
334
+ addBotMessage(message);
335
+ } else {
336
+ addBotMessage('❌ Could not retrieve drone status.');
337
+ }
338
+ } catch (error) {
339
+ addBotMessage('❌ Error retrieving drone status. Make sure the server is running.');
340
+ }
341
+ }
342
+
343
+ function scrollToBottom() {
344
+ chatMessages.scrollTop = chatMessages.scrollHeight;
345
+ }
346
+
347
+ // Focus input on load
348
+ chatInput.focus();
349
+ </script>
350
+ </body>
351
+ </html>
chatbot_enhanced.html ADDED
@@ -0,0 +1,818 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>🚁 DroneAgent - Comprehensive Testing Interface</title>
7
+ <style>
8
+ * {
9
+ margin: 0;
10
+ padding: 0;
11
+ box-sizing: border-box;
12
+ }
13
+
14
+ body {
15
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
16
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
17
+ min-height: 100vh;
18
+ display: flex;
19
+ flex-direction: column;
20
+ }
21
+
22
+ .header {
23
+ background: rgba(255, 255, 255, 0.1);
24
+ backdrop-filter: blur(10px);
25
+ padding: 1rem;
26
+ color: white;
27
+ text-align: center;
28
+ border-bottom: 1px solid rgba(255, 255, 255, 0.2);
29
+ }
30
+
31
+ .main-container {
32
+ display: flex;
33
+ flex: 1;
34
+ gap: 1rem;
35
+ padding: 1rem;
36
+ height: calc(100vh - 80px);
37
+ }
38
+
39
+ .chat-section {
40
+ flex: 2;
41
+ background: white;
42
+ border-radius: 15px;
43
+ box-shadow: 0 20px 40px rgba(0,0,0,0.1);
44
+ display: flex;
45
+ flex-direction: column;
46
+ overflow: hidden;
47
+ }
48
+
49
+ .testing-panel {
50
+ flex: 1;
51
+ background: rgba(255, 255, 255, 0.95);
52
+ border-radius: 15px;
53
+ box-shadow: 0 20px 40px rgba(0,0,0,0.1);
54
+ padding: 1rem;
55
+ overflow-y: auto;
56
+ }
57
+
58
+ .chat-messages {
59
+ flex: 1;
60
+ padding: 20px;
61
+ overflow-y: auto;
62
+ background: #f8f9fa;
63
+ }
64
+
65
+ .message {
66
+ margin-bottom: 15px;
67
+ padding: 12px 16px;
68
+ border-radius: 18px;
69
+ max-width: 80%;
70
+ word-wrap: break-word;
71
+ white-space: pre-wrap;
72
+ }
73
+
74
+ .user-message {
75
+ background: #007bff;
76
+ color: white;
77
+ margin-left: auto;
78
+ text-align: right;
79
+ }
80
+
81
+ .bot-message {
82
+ background: #e9ecef;
83
+ color: #333;
84
+ margin-right: auto;
85
+ }
86
+
87
+ .system-message {
88
+ background: #ffeaa7;
89
+ color: #2d3436;
90
+ margin: 0 auto;
91
+ text-align: center;
92
+ font-style: italic;
93
+ max-width: 90%;
94
+ }
95
+
96
+ .chat-input-container {
97
+ padding: 20px;
98
+ background: white;
99
+ border-top: 1px solid #dee2e6;
100
+ display: flex;
101
+ gap: 10px;
102
+ }
103
+
104
+ .chat-input {
105
+ flex: 1;
106
+ padding: 12px 16px;
107
+ border: 2px solid #dee2e6;
108
+ border-radius: 25px;
109
+ outline: none;
110
+ font-size: 14px;
111
+ transition: border-color 0.3s;
112
+ }
113
+
114
+ .chat-input:focus {
115
+ border-color: #007bff;
116
+ }
117
+
118
+ .btn {
119
+ padding: 12px 20px;
120
+ border: none;
121
+ border-radius: 25px;
122
+ cursor: pointer;
123
+ font-weight: bold;
124
+ transition: all 0.3s;
125
+ font-size: 12px;
126
+ }
127
+
128
+ .btn-primary {
129
+ background: #007bff;
130
+ color: white;
131
+ }
132
+
133
+ .btn-primary:hover {
134
+ background: #0056b3;
135
+ }
136
+
137
+ .btn-success {
138
+ background: #28a745;
139
+ color: white;
140
+ }
141
+
142
+ .btn-info {
143
+ background: #17a2b8;
144
+ color: white;
145
+ }
146
+
147
+ .btn-warning {
148
+ background: #ffc107;
149
+ color: #212529;
150
+ }
151
+
152
+ .btn-danger {
153
+ background: #dc3545;
154
+ color: white;
155
+ }
156
+
157
+ .btn:disabled {
158
+ background: #6c757d;
159
+ cursor: not-allowed;
160
+ }
161
+
162
+ .test-section {
163
+ margin-bottom: 2rem;
164
+ border: 1px solid #dee2e6;
165
+ border-radius: 10px;
166
+ overflow: hidden;
167
+ }
168
+
169
+ .test-header {
170
+ background: #f8f9fa;
171
+ padding: 1rem;
172
+ font-weight: bold;
173
+ border-bottom: 1px solid #dee2e6;
174
+ cursor: pointer;
175
+ display: flex;
176
+ justify-content: space-between;
177
+ align-items: center;
178
+ }
179
+
180
+ .test-content {
181
+ padding: 1rem;
182
+ display: none;
183
+ }
184
+
185
+ .test-content.active {
186
+ display: block;
187
+ }
188
+
189
+ .test-grid {
190
+ display: grid;
191
+ grid-template-columns: 1fr 1fr;
192
+ gap: 0.5rem;
193
+ margin-bottom: 1rem;
194
+ }
195
+
196
+ .test-btn {
197
+ padding: 8px 12px;
198
+ font-size: 11px;
199
+ border-radius: 15px;
200
+ }
201
+
202
+ .quick-examples {
203
+ margin-bottom: 20px;
204
+ padding: 15px;
205
+ background: #fff3cd;
206
+ border-radius: 10px;
207
+ border-left: 4px solid #ffc107;
208
+ }
209
+
210
+ .quick-examples h3 {
211
+ margin-bottom: 10px;
212
+ color: #856404;
213
+ }
214
+
215
+ .example-button {
216
+ display: inline-block;
217
+ margin: 5px;
218
+ padding: 8px 12px;
219
+ background: #fff;
220
+ border: 1px solid #ffc107;
221
+ border-radius: 15px;
222
+ cursor: pointer;
223
+ font-size: 12px;
224
+ transition: all 0.3s;
225
+ }
226
+
227
+ .example-button:hover {
228
+ background: #ffc107;
229
+ color: white;
230
+ }
231
+
232
+ .loading {
233
+ text-align: center;
234
+ color: #6c757d;
235
+ font-style: italic;
236
+ padding: 10px;
237
+ }
238
+
239
+ .status-indicator {
240
+ display: inline-block;
241
+ width: 10px;
242
+ height: 10px;
243
+ border-radius: 50%;
244
+ margin-right: 5px;
245
+ }
246
+
247
+ .status-success { background: #28a745; }
248
+ .status-error { background: #dc3545; }
249
+ .status-warning { background: #ffc107; }
250
+ .status-info { background: #17a2b8; }
251
+
252
+ .json-display {
253
+ background: #f8f9fa;
254
+ border: 1px solid #dee2e6;
255
+ border-radius: 5px;
256
+ padding: 10px;
257
+ font-family: 'Courier New', monospace;
258
+ font-size: 11px;
259
+ max-height: 200px;
260
+ overflow-y: auto;
261
+ white-space: pre-wrap;
262
+ margin-top: 10px;
263
+ }
264
+
265
+ .collapsible-toggle {
266
+ background: none;
267
+ border: none;
268
+ font-size: 14px;
269
+ cursor: pointer;
270
+ }
271
+ </style>
272
+ </head>
273
+ <body>
274
+ <div class="header">
275
+ <h1>🚁 DroneAgent - Comprehensive Testing Interface</h1>
276
+ <p>Professional Drone Mission Planning with AI-Driven Intelligence</p>
277
+ </div>
278
+
279
+ <div class="main-container">
280
+ <!-- Chat Section -->
281
+ <div class="chat-section">
282
+ <div class="chat-messages" id="chatMessages">
283
+ <div class="quick-examples">
284
+ <h3>🎯 Quick Test Examples:</h3>
285
+ <div class="example-button" onclick="sendExample('survey mission at 16.047123, 108.206456')">
286
+ 📊 Survey Mission (6-decimal coords)
287
+ </div>
288
+ <div class="example-button" onclick="sendExample('patrol mission around Hải Châu district')">
289
+ 🛡️ Patrol Mission (Vietnamese location)
290
+ </div>
291
+ <div class="example-button" onclick="sendExample('photography flight at 37 đội cung khuê trung cẩm lệ đà nẵng')">
292
+ 📸 Photography Mission (Full address)
293
+ </div>
294
+ <div class="example-button" onclick="sendExample('help me scan 500m around 16.047, 108.206')">
295
+ 🔍 Scan Mission (Distance-based)
296
+ </div>
297
+ <div class="example-button" onclick="sendExample('go straight 100m north from 16.047, 108.206')">
298
+ ➡️ Go Straight Mission
299
+ </div>
300
+ <div class="example-button" onclick="sendExample('hello')">
301
+ 👋 General Greeting
302
+ </div>
303
+ <div class="example-button" onclick="sendExample('what is the drone status')">
304
+ 🚁 Drone Status
305
+ </div>
306
+ <div class="example-button" onclick="sendExample('ok')">
307
+ ❓ Ambiguous Response
308
+ </div>
309
+ </div>
310
+ </div>
311
+
312
+ <div class="chat-input-container">
313
+ <input type="text" class="chat-input" id="chatInput" placeholder="Type your message... (e.g., 'Survey mission at 16.047123, 108.206456')" onkeypress="handleKeyPress(event)">
314
+ <button class="btn btn-primary" id="sendButton" onclick="sendMessage()">Send</button>
315
+ <button class="btn btn-success" onclick="getLatestMission()">📁 Latest</button>
316
+ <button class="btn btn-info" onclick="getDroneStatus()">🚁 Status</button>
317
+ <button class="btn btn-warning" onclick="clearChat()">🧹 Clear</button>
318
+ </div>
319
+ </div>
320
+
321
+ <!-- Testing Panel -->
322
+ <div class="testing-panel">
323
+ <h3>🧪 Comprehensive API Testing</h3>
324
+
325
+ <!-- Basic Endpoints -->
326
+ <div class="test-section">
327
+ <div class="test-header" onclick="toggleSection('basic-endpoints')">
328
+ <span>📡 Basic Endpoints</span>
329
+ <button class="collapsible-toggle">▼</button>
330
+ </div>
331
+ <div class="test-content" id="basic-endpoints">
332
+ <div class="test-grid">
333
+ <button class="btn test-btn btn-info" onclick="testEndpoint('GET', '/')">Root Endpoint</button>
334
+ <button class="btn test-btn btn-success" onclick="testEndpoint('GET', '/api/latest-mission')">Latest Mission</button>
335
+ <button class="btn test-btn btn-info" onclick="testEndpoint('GET', '/drone/status')">Drone Status</button>
336
+ <button class="btn test-btn btn-warning" onclick="testEndpoint('GET', '/flight/missions')">Active Missions</button>
337
+ </div>
338
+ </div>
339
+ </div>
340
+
341
+ <!-- Mission Types Testing -->
342
+ <div class="test-section">
343
+ <div class="test-header" onclick="toggleSection('mission-types')">
344
+ <span>🎯 Mission Types</span>
345
+ <button class="collapsible-toggle">▼</button>
346
+ </div>
347
+ <div class="test-content" id="mission-types">
348
+ <div class="test-grid">
349
+ <button class="btn test-btn btn-primary" onclick="testMissionType('survey')">Survey Mission</button>
350
+ <button class="btn test-btn btn-primary" onclick="testMissionType('patrol')">Patrol Mission</button>
351
+ <button class="btn test-btn btn-primary" onclick="testMissionType('photography')">Photography Mission</button>
352
+ <button class="btn test-btn btn-primary" onclick="testMissionType('inspection')">Inspection Mission</button>
353
+ <button class="btn test-btn btn-primary" onclick="testMissionType('go_straight')">Go Straight Mission</button>
354
+ <button class="btn test-btn btn-primary" onclick="testMissionType('simple_flight')">Simple Flight</button>
355
+ </div>
356
+ </div>
357
+ </div>
358
+
359
+ <!-- Geocoding Testing -->
360
+ <div class="test-section">
361
+ <div class="test-header" onclick="toggleSection('geocoding')">
362
+ <span>🌍 Geocoding Tests</span>
363
+ <button class="collapsible-toggle">▼</button>
364
+ </div>
365
+ <div class="test-content" id="geocoding">
366
+ <div class="test-grid">
367
+ <button class="btn test-btn btn-success" onclick="testGeocode('vietnamese')">Vietnamese Locations</button>
368
+ <button class="btn test-btn btn-success" onclick="testGeocode('english')">English Locations</button>
369
+ <button class="btn test-btn btn-success" onclick="testGeocode('complex')">Complex Addresses</button>
370
+ <button class="btn test-btn btn-success" onclick="testGeocode('distance')">Distance-based</button>
371
+ </div>
372
+ </div>
373
+ </div>
374
+
375
+ <!-- Error Handling -->
376
+ <div class="test-section">
377
+ <div class="test-header" onclick="toggleSection('error-handling')">
378
+ <span>⚠️ Error Handling</span>
379
+ <button class="collapsible-toggle">▼</button>
380
+ </div>
381
+ <div class="test-content" id="error-handling">
382
+ <div class="test-grid">
383
+ <button class="btn test-btn btn-danger" onclick="testError('empty')">Empty Message</button>
384
+ <button class="btn test-btn btn-danger" onclick="testError('invalid_coords')">Invalid Coordinates</button>
385
+ <button class="btn test-btn btn-danger" onclick="testError('malformed')">Malformed Request</button>
386
+ <button class="btn test-btn btn-danger" onclick="testError('too_long')">Too Long Message</button>
387
+ </div>
388
+ </div>
389
+ </div>
390
+
391
+ <!-- Flight Management -->
392
+ <div class="test-section">
393
+ <div class="test-header" onclick="toggleSection('flight-management')">
394
+ <span>✈️ Flight Management</span>
395
+ <button class="collapsible-toggle">▼</button>
396
+ </div>
397
+ <div class="test-content" id="flight-management">
398
+ <div class="test-grid">
399
+ <button class="btn test-btn btn-warning" onclick="testFlightOp('confirm')">Confirm Flight</button>
400
+ <button class="btn test-btn btn-warning" onclick="testFlightOp('pause')">Pause Flight</button>
401
+ <button class="btn test-btn btn-warning" onclick="testFlightOp('cancel')">Cancel Flight</button>
402
+ <button class="btn test-btn btn-warning" onclick="testFlightOp('update')">Update Mission</button>
403
+ </div>
404
+ </div>
405
+ </div>
406
+
407
+ <!-- Stress Testing -->
408
+ <div class="test-section">
409
+ <div class="test-header" onclick="toggleSection('stress-testing')">
410
+ <span>🔥 Stress Testing</span>
411
+ <button class="collapsible-toggle">▼</button>
412
+ </div>
413
+ <div class="test-content" id="stress-testing">
414
+ <div class="test-grid">
415
+ <button class="btn test-btn btn-danger" onclick="stressTest('rapid')">Rapid Requests</button>
416
+ <button class="btn test-btn btn-danger" onclick="stressTest('concurrent')">Concurrent Requests</button>
417
+ <button class="btn test-btn btn-danger" onclick="stressTest('api_keys')">API Key Rotation</button>
418
+ <button class="btn test-btn btn-danger" onclick="stressTest('full')">Full System Test</button>
419
+ </div>
420
+ </div>
421
+ </div>
422
+
423
+ <!-- Results Display -->
424
+ <div class="test-section">
425
+ <div class="test-header" onclick="toggleSection('results')">
426
+ <span>📊 Test Results</span>
427
+ <button class="collapsible-toggle">▼</button>
428
+ </div>
429
+ <div class="test-content active" id="results">
430
+ <div id="testResults">
431
+ <p><span class="status-indicator status-info"></span>Ready for testing...</p>
432
+ </div>
433
+ </div>
434
+ </div>
435
+ </div>
436
+ </div>
437
+
438
+ <script>
439
+ const chatMessages = document.getElementById('chatMessages');
440
+ const chatInput = document.getElementById('chatInput');
441
+ const sendButton = document.getElementById('sendButton');
442
+ const testResults = document.getElementById('testResults');
443
+
444
+ let testCount = 0;
445
+ let passCount = 0;
446
+ let failCount = 0;
447
+
448
+ // Add welcome message
449
+ addBotMessage("🚁 **DroneAgent Testing Interface Ready!**\n\nThis comprehensive testing interface allows you to test all endpoints and scenarios. Use the chat for normal interactions or the testing panel for systematic API testing.\n\n🎯 **Features:**\n• All mission types with 6-decimal precision coordinates\n• Vietnamese and English geocoding\n• Error handling scenarios\n• Flight management operations\n• Stress testing capabilities\n\nTry the quick examples above or use the testing panel! 🧪");
450
+
451
+ function handleKeyPress(event) {
452
+ if (event.key === 'Enter') {
453
+ sendMessage();
454
+ }
455
+ }
456
+
457
+ function sendExample(text) {
458
+ chatInput.value = text;
459
+ sendMessage();
460
+ }
461
+
462
+ function clearChat() {
463
+ chatMessages.innerHTML = '';
464
+ addBotMessage("🧹 Chat cleared! Ready for new tests.");
465
+ }
466
+
467
+ async function sendMessage() {
468
+ const message = chatInput.value.trim();
469
+ if (!message) return;
470
+
471
+ addUserMessage(message);
472
+ chatInput.value = '';
473
+
474
+ sendButton.disabled = true;
475
+ chatInput.disabled = true;
476
+
477
+ const loadingElement = addLoadingMessage();
478
+
479
+ try {
480
+ const response = await fetch('/chat', {
481
+ method: 'POST',
482
+ headers: {
483
+ 'Content-Type': 'application/json',
484
+ },
485
+ body: JSON.stringify({ message: message })
486
+ });
487
+
488
+ const data = await response.json();
489
+ loadingElement.remove();
490
+
491
+ let botResponse = data.ai_response || 'Sorry, I had trouble processing that request.';
492
+
493
+ // Add status information for debugging
494
+ if (data.gemini_enhanced !== undefined) {
495
+ botResponse += `\n\n🔧 **Debug Info:**\n• Gemini Enhanced: ${data.gemini_enhanced}\n• Model Used: ${data.model_used || 'unknown'}`;
496
+ }
497
+
498
+ if (data.mission_analysis) {
499
+ botResponse += `\n• Mission Type: ${data.mission_analysis.mission_type}`;
500
+ if (data.mission_analysis.coordinates) {
501
+ botResponse += `\n• Coordinates: ${data.mission_analysis.coordinates[0]}, ${data.mission_analysis.coordinates[1]}`;
502
+ }
503
+ }
504
+
505
+ addBotMessage(botResponse);
506
+
507
+ } catch (error) {
508
+ loadingElement.remove();
509
+ addBotMessage('❌ Error: Could not connect to DroneAgent server. Make sure the server is running.');
510
+ }
511
+
512
+ sendButton.disabled = false;
513
+ chatInput.disabled = false;
514
+ chatInput.focus();
515
+ }
516
+
517
+ function toggleSection(sectionId) {
518
+ const content = document.getElementById(sectionId);
519
+ const toggle = content.previousElementSibling.querySelector('.collapsible-toggle');
520
+
521
+ if (content.classList.contains('active')) {
522
+ content.classList.remove('active');
523
+ toggle.textContent = '▼';
524
+ } else {
525
+ content.classList.add('active');
526
+ toggle.textContent = '▲';
527
+ }
528
+ }
529
+
530
+ async function testEndpoint(method, endpoint) {
531
+ addTestResult(`Testing ${method} ${endpoint}...`, 'info');
532
+
533
+ try {
534
+ const response = await fetch(endpoint, { method: method });
535
+ const data = await response.json();
536
+
537
+ if (response.ok) {
538
+ addTestResult(`✅ ${method} ${endpoint} - SUCCESS`, 'success');
539
+ showJsonResult(data);
540
+ passCount++;
541
+ } else {
542
+ addTestResult(`❌ ${method} ${endpoint} - FAILED (${response.status})`, 'error');
543
+ failCount++;
544
+ }
545
+ } catch (error) {
546
+ addTestResult(`❌ ${method} ${endpoint} - ERROR: ${error.message}`, 'error');
547
+ failCount++;
548
+ }
549
+
550
+ testCount++;
551
+ updateTestStats();
552
+ }
553
+
554
+ async function testMissionType(type) {
555
+ const messages = {
556
+ survey: 'survey mission at 16.047123, 108.206456',
557
+ patrol: 'patrol mission at 16.047123, 108.206456',
558
+ photography: 'photography mission at 16.047123, 108.206456',
559
+ inspection: 'inspection mission at 16.047123, 108.206456',
560
+ go_straight: 'go straight 100m north from 16.047123, 108.206456',
561
+ simple_flight: 'simple flight at 16.047123, 108.206456'
562
+ };
563
+
564
+ await testChatMessage(messages[type], `${type} mission`);
565
+ }
566
+
567
+ async function testGeocode(type) {
568
+ const messages = {
569
+ vietnamese: 'survey mission at Hải Châu district',
570
+ english: 'patrol mission in Da Nang',
571
+ complex: 'photography mission at 37 đội cung khuê trung cẩm lệ đà nẵng',
572
+ distance: 'scan 500m around 16.047, 108.206'
573
+ };
574
+
575
+ await testChatMessage(messages[type], `${type} geocoding`);
576
+ }
577
+
578
+ async function testError(type) {
579
+ const messages = {
580
+ empty: '',
581
+ invalid_coords: 'survey mission at invalid coordinates',
582
+ malformed: 'this is not a valid mission request with random text',
583
+ too_long: 'a'.repeat(1000)
584
+ };
585
+
586
+ await testChatMessage(messages[type], `${type} error handling`);
587
+ }
588
+
589
+ async function testFlightOp(operation) {
590
+ const payloads = {
591
+ confirm: {
592
+ mission_id: 'test_mission_001',
593
+ drone_id: 'test_drone_001',
594
+ waypoints: [
595
+ { lat: 16.047, lon: 108.206, alt: 50 },
596
+ { lat: 16.048, lon: 108.207, alt: 50 }
597
+ ]
598
+ },
599
+ pause: { mission_id: 'test_mission_001', drone_id: 'test_drone_001' },
600
+ cancel: { mission_id: 'test_mission_001', drone_id: 'test_drone_001' },
601
+ update: {
602
+ mission_id: 'test_mission_001',
603
+ waypoints: [{ lat: 16.049, lon: 108.208, alt: 60 }],
604
+ reason: 'Testing update'
605
+ }
606
+ };
607
+
608
+ addTestResult(`Testing ${operation} flight operation...`, 'info');
609
+
610
+ try {
611
+ const response = await fetch(`/flight/${operation}`, {
612
+ method: 'POST',
613
+ headers: { 'Content-Type': 'application/json' },
614
+ body: JSON.stringify(payloads[operation])
615
+ });
616
+
617
+ const data = await response.json();
618
+
619
+ if (response.ok) {
620
+ addTestResult(`✅ Flight ${operation} - SUCCESS`, 'success');
621
+ showJsonResult(data);
622
+ passCount++;
623
+ } else {
624
+ addTestResult(`❌ Flight ${operation} - FAILED (${response.status})`, 'error');
625
+ failCount++;
626
+ }
627
+ } catch (error) {
628
+ addTestResult(`❌ Flight ${operation} - ERROR: ${error.message}`, 'error');
629
+ failCount++;
630
+ }
631
+
632
+ testCount++;
633
+ updateTestStats();
634
+ }
635
+
636
+ async function testChatMessage(message, testName) {
637
+ addTestResult(`Testing ${testName}...`, 'info');
638
+
639
+ try {
640
+ const response = await fetch('/chat', {
641
+ method: 'POST',
642
+ headers: { 'Content-Type': 'application/json' },
643
+ body: JSON.stringify({ message: message })
644
+ });
645
+
646
+ const data = await response.json();
647
+
648
+ if (response.ok && data.ai_response) {
649
+ addTestResult(`✅ ${testName} - SUCCESS`, 'success');
650
+ passCount++;
651
+ } else {
652
+ addTestResult(`❌ ${testName} - FAILED`, 'error');
653
+ failCount++;
654
+ }
655
+
656
+ showJsonResult(data);
657
+ } catch (error) {
658
+ addTestResult(`❌ ${testName} - ERROR: ${error.message}`, 'error');
659
+ failCount++;
660
+ }
661
+
662
+ testCount++;
663
+ updateTestStats();
664
+ }
665
+
666
+ async function stressTest(type) {
667
+ addTestResult(`Starting ${type} stress test...`, 'warning');
668
+
669
+ if (type === 'rapid') {
670
+ for (let i = 0; i < 10; i++) {
671
+ await testChatMessage(`test mission ${i} at 16.047, 108.206`, `rapid test ${i}`);
672
+ await new Promise(resolve => setTimeout(resolve, 100));
673
+ }
674
+ } else if (type === 'concurrent') {
675
+ const promises = [];
676
+ for (let i = 0; i < 5; i++) {
677
+ promises.push(testChatMessage(`concurrent test ${i} at 16.047, 108.206`, `concurrent ${i}`));
678
+ }
679
+ await Promise.all(promises);
680
+ } else if (type === 'api_keys') {
681
+ for (let i = 0; i < 15; i++) {
682
+ await testChatMessage(`api key test ${i} at 16.047, 108.206`, `API key rotation ${i}`);
683
+ }
684
+ } else if (type === 'full') {
685
+ await testMissionType('survey');
686
+ await testMissionType('patrol');
687
+ await testGeocode('vietnamese');
688
+ await testError('invalid_coords');
689
+ await testEndpoint('GET', '/drone/status');
690
+ }
691
+
692
+ addTestResult(`✅ ${type} stress test completed`, 'success');
693
+ }
694
+
695
+ function addTestResult(message, type) {
696
+ const indicator = `<span class="status-indicator status-${type}"></span>`;
697
+ const timestamp = new Date().toLocaleTimeString();
698
+ testResults.innerHTML += `<p>${indicator}[${timestamp}] ${message}</p>`;
699
+ testResults.scrollTop = testResults.scrollHeight;
700
+ }
701
+
702
+ function showJsonResult(data) {
703
+ const jsonDiv = document.createElement('div');
704
+ jsonDiv.className = 'json-display';
705
+ jsonDiv.textContent = JSON.stringify(data, null, 2);
706
+ testResults.appendChild(jsonDiv);
707
+ testResults.scrollTop = testResults.scrollHeight;
708
+ }
709
+
710
+ function updateTestStats() {
711
+ const statsMessage = `📊 Tests: ${testCount} | ✅ Pass: ${passCount} | ❌ Fail: ${failCount} | Success Rate: ${testCount > 0 ? Math.round((passCount/testCount)*100) : 0}%`;
712
+ addTestResult(statsMessage, 'info');
713
+ }
714
+
715
+ function addUserMessage(message) {
716
+ const messageDiv = document.createElement('div');
717
+ messageDiv.className = 'message user-message';
718
+ messageDiv.textContent = message;
719
+ chatMessages.appendChild(messageDiv);
720
+ scrollToBottom();
721
+ }
722
+
723
+ function addBotMessage(message) {
724
+ const messageDiv = document.createElement('div');
725
+ messageDiv.className = 'message bot-message';
726
+ messageDiv.textContent = message;
727
+ chatMessages.appendChild(messageDiv);
728
+ scrollToBottom();
729
+ }
730
+
731
+ function addSystemMessage(message) {
732
+ const messageDiv = document.createElement('div');
733
+ messageDiv.className = 'message system-message';
734
+ messageDiv.textContent = message;
735
+ chatMessages.appendChild(messageDiv);
736
+ scrollToBottom();
737
+ }
738
+
739
+ function addLoadingMessage() {
740
+ const loadingDiv = document.createElement('div');
741
+ loadingDiv.className = 'loading';
742
+ loadingDiv.textContent = '🤖 DroneBot is analyzing your request...';
743
+ chatMessages.appendChild(loadingDiv);
744
+ scrollToBottom();
745
+ return loadingDiv;
746
+ }
747
+
748
+ async function getLatestMission() {
749
+ try {
750
+ const loadingElement = addLoadingMessage();
751
+
752
+ const response = await fetch('/api/latest-mission');
753
+ const data = await response.json();
754
+
755
+ loadingElement.remove();
756
+
757
+ if (data.status === 'success') {
758
+ let message = `📁 **Latest Mission Retrieved**\n\n`;
759
+ message += `**File:** ${data.filename}\n`;
760
+ message += `**Created:** ${new Date(data.created_at).toLocaleString()}\n`;
761
+ message += `**Size:** ${data.file_size} bytes\n\n`;
762
+ message += `✅ Mission plan ready for QGroundControl!`;
763
+
764
+ addBotMessage(message);
765
+ } else {
766
+ addBotMessage(`📁 ${data.message}`);
767
+ }
768
+ } catch (error) {
769
+ addBotMessage('❌ Error retrieving latest mission. Make sure the server is running.');
770
+ }
771
+ }
772
+
773
+ async function getDroneStatus() {
774
+ try {
775
+ const loadingElement = addLoadingMessage();
776
+
777
+ const response = await fetch('/drone/status');
778
+ const data = await response.json();
779
+
780
+ loadingElement.remove();
781
+
782
+ if (data.status === 'success') {
783
+ const status = data.drone_status;
784
+ const constraints = data.flight_constraints;
785
+
786
+ let message = `🚁 **Drone Status Report**\n\n`;
787
+ message += `🔋 Battery: ${status.batteryRemaining}% (${status.voltage.toFixed(1)}V)\n`;
788
+ message += `📡 GPS: ${status.satellite} satellites\n`;
789
+ message += `📍 Location: ${status.latitude.toFixed(6)}, ${status.longitude.toFixed(6)}\n`;
790
+ message += `🛩️ Mode: ${status.mode} | Altitude: ${status.altitude.toFixed(0)}m\n\n`;
791
+ message += `**Flight Constraints:**\n`;
792
+ message += `• Safe Flight Time: ${constraints.safe_flight_time_minutes} minutes\n`;
793
+ message += `• Max Distance: ${constraints.max_safe_distance_meters}m\n`;
794
+ message += `• Ready: ${constraints.ready_to_fly ? '✅ Yes' : '❌ No'}`;
795
+
796
+ addBotMessage(message);
797
+ } else {
798
+ addBotMessage('❌ Could not retrieve drone status.');
799
+ }
800
+ } catch (error) {
801
+ addBotMessage('❌ Error retrieving drone status. Make sure the server is running.');
802
+ }
803
+ }
804
+
805
+ function scrollToBottom() {
806
+ chatMessages.scrollTop = chatMessages.scrollHeight;
807
+ }
808
+
809
+ // Focus input on load
810
+ chatInput.focus();
811
+
812
+ // Auto-expand results section
813
+ document.addEventListener('DOMContentLoaded', function() {
814
+ toggleSection('results');
815
+ });
816
+ </script>
817
+ </body>
818
+ </html>
downloads/go_straight_gemini_20250822_114314.plan ADDED
@@ -0,0 +1,143 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "fileType": "Plan",
3
+ "groundStation": "DroneAgent - Go_Straight",
4
+ "version": 1,
5
+ "mission": {
6
+ "cruiseSpeed": 12.0,
7
+ "firmwareType": 12,
8
+ "globalPlanAltitudeMode": 1,
9
+ "hoverSpeed": 7.199999999999999,
10
+ "items": [
11
+ {
12
+ "AMSLAltAboveTerrain": null,
13
+ "Altitude": 50.0,
14
+ "AltitudeMode": 1,
15
+ "autoContinue": true,
16
+ "command": 22,
17
+ "doJumpId": 1,
18
+ "frame": 3,
19
+ "params": [
20
+ 0.0,
21
+ 0.0,
22
+ 0.0,
23
+ 0.0,
24
+ 16.048921,
25
+ 108.206456,
26
+ 50.0
27
+ ],
28
+ "type": "SimpleItem"
29
+ },
30
+ {
31
+ "AMSLAltAboveTerrain": null,
32
+ "Altitude": 70.0,
33
+ "AltitudeMode": 1,
34
+ "autoContinue": true,
35
+ "command": 16,
36
+ "doJumpId": 2,
37
+ "frame": 3,
38
+ "params": [
39
+ 0.0,
40
+ 2.0,
41
+ 0.0,
42
+ 0.0,
43
+ 16.0495216006006,
44
+ 108.206456,
45
+ 70
46
+ ],
47
+ "type": "SimpleItem"
48
+ },
49
+ {
50
+ "AMSLAltAboveTerrain": null,
51
+ "Altitude": 70.0,
52
+ "AltitudeMode": 1,
53
+ "autoContinue": true,
54
+ "command": 16,
55
+ "doJumpId": 3,
56
+ "frame": 3,
57
+ "params": [
58
+ 0.0,
59
+ 2.0,
60
+ 0.0,
61
+ 0.0,
62
+ 16.0501222012012,
63
+ 108.206456,
64
+ 70
65
+ ],
66
+ "type": "SimpleItem"
67
+ },
68
+ {
69
+ "AMSLAltAboveTerrain": null,
70
+ "Altitude": 70.0,
71
+ "AltitudeMode": 1,
72
+ "autoContinue": true,
73
+ "command": 16,
74
+ "doJumpId": 4,
75
+ "frame": 3,
76
+ "params": [
77
+ 0.0,
78
+ 2.0,
79
+ 0.0,
80
+ 0.0,
81
+ 16.0507228018018,
82
+ 108.206456,
83
+ 70
84
+ ],
85
+ "type": "SimpleItem"
86
+ },
87
+ {
88
+ "AMSLAltAboveTerrain": null,
89
+ "Altitude": 0,
90
+ "AltitudeMode": 1,
91
+ "autoContinue": true,
92
+ "command": 203,
93
+ "doJumpId": 5,
94
+ "frame": 2,
95
+ "params": [
96
+ 1,
97
+ 0,
98
+ 0,
99
+ 1,
100
+ 0,
101
+ 0,
102
+ 0
103
+ ],
104
+ "type": "SimpleItem"
105
+ },
106
+ {
107
+ "AMSLAltAboveTerrain": null,
108
+ "Altitude": 0,
109
+ "AltitudeMode": 0,
110
+ "autoContinue": true,
111
+ "command": 20,
112
+ "doJumpId": 6,
113
+ "frame": 2,
114
+ "params": [
115
+ 0.0,
116
+ 0.0,
117
+ 0.0,
118
+ 0.0,
119
+ 0,
120
+ 0,
121
+ 0
122
+ ],
123
+ "type": "SimpleItem"
124
+ }
125
+ ],
126
+ "plannedHomePosition": [
127
+ 16.048921,
128
+ 108.206456,
129
+ 8.0
130
+ ],
131
+ "vehicleType": 2,
132
+ "version": 2
133
+ },
134
+ "geoFence": {
135
+ "circles": [],
136
+ "polygons": [],
137
+ "version": 2
138
+ },
139
+ "rallyPoints": {
140
+ "points": [],
141
+ "version": 2
142
+ }
143
+ }
downloads/go_straight_local_20250822_101454.plan ADDED
@@ -0,0 +1,143 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "fileType": "Plan",
3
+ "groundStation": "DroneAgent - Go_Straight",
4
+ "version": 1,
5
+ "mission": {
6
+ "cruiseSpeed": 12.0,
7
+ "firmwareType": 12,
8
+ "globalPlanAltitudeMode": 1,
9
+ "hoverSpeed": 7.199999999999999,
10
+ "items": [
11
+ {
12
+ "AMSLAltAboveTerrain": null,
13
+ "Altitude": 45.0,
14
+ "AltitudeMode": 1,
15
+ "autoContinue": true,
16
+ "command": 22,
17
+ "doJumpId": 1,
18
+ "frame": 3,
19
+ "params": [
20
+ 0.0,
21
+ 0.0,
22
+ 0.0,
23
+ 0.0,
24
+ 16.0209187,
25
+ 108.2075711,
26
+ 45.0
27
+ ],
28
+ "type": "SimpleItem"
29
+ },
30
+ {
31
+ "AMSLAltAboveTerrain": null,
32
+ "Altitude": 70.0,
33
+ "AltitudeMode": 1,
34
+ "autoContinue": true,
35
+ "command": 16,
36
+ "doJumpId": 2,
37
+ "frame": 3,
38
+ "params": [
39
+ 0.0,
40
+ 2.0,
41
+ 0.0,
42
+ 0.0,
43
+ 16.02106885015015,
44
+ 108.2075711,
45
+ 70
46
+ ],
47
+ "type": "SimpleItem"
48
+ },
49
+ {
50
+ "AMSLAltAboveTerrain": null,
51
+ "Altitude": 70.0,
52
+ "AltitudeMode": 1,
53
+ "autoContinue": true,
54
+ "command": 16,
55
+ "doJumpId": 3,
56
+ "frame": 3,
57
+ "params": [
58
+ 0.0,
59
+ 2.0,
60
+ 0.0,
61
+ 0.0,
62
+ 16.0212190003003,
63
+ 108.2075711,
64
+ 70
65
+ ],
66
+ "type": "SimpleItem"
67
+ },
68
+ {
69
+ "AMSLAltAboveTerrain": null,
70
+ "Altitude": 70.0,
71
+ "AltitudeMode": 1,
72
+ "autoContinue": true,
73
+ "command": 16,
74
+ "doJumpId": 4,
75
+ "frame": 3,
76
+ "params": [
77
+ 0.0,
78
+ 2.0,
79
+ 0.0,
80
+ 0.0,
81
+ 16.02136915045045,
82
+ 108.2075711,
83
+ 70
84
+ ],
85
+ "type": "SimpleItem"
86
+ },
87
+ {
88
+ "AMSLAltAboveTerrain": null,
89
+ "Altitude": 0,
90
+ "AltitudeMode": 1,
91
+ "autoContinue": true,
92
+ "command": 203,
93
+ "doJumpId": 5,
94
+ "frame": 2,
95
+ "params": [
96
+ 1,
97
+ 0,
98
+ 0,
99
+ 1,
100
+ 0,
101
+ 0,
102
+ 0
103
+ ],
104
+ "type": "SimpleItem"
105
+ },
106
+ {
107
+ "AMSLAltAboveTerrain": null,
108
+ "Altitude": 0,
109
+ "AltitudeMode": 0,
110
+ "autoContinue": true,
111
+ "command": 20,
112
+ "doJumpId": 6,
113
+ "frame": 2,
114
+ "params": [
115
+ 0.0,
116
+ 0.0,
117
+ 0.0,
118
+ 0.0,
119
+ 0,
120
+ 0,
121
+ 0
122
+ ],
123
+ "type": "SimpleItem"
124
+ }
125
+ ],
126
+ "plannedHomePosition": [
127
+ 16.0209187,
128
+ 108.2075711,
129
+ 8.0
130
+ ],
131
+ "vehicleType": 2,
132
+ "version": 2
133
+ },
134
+ "geoFence": {
135
+ "circles": [],
136
+ "polygons": [],
137
+ "version": 2
138
+ },
139
+ "rallyPoints": {
140
+ "points": [],
141
+ "version": 2
142
+ }
143
+ }
downloads/patrol_gemini_20250822_095326.plan ADDED
@@ -0,0 +1,238 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "fileType": "Plan",
3
+ "groundStation": "DroneAgent - Patrol",
4
+ "version": 1,
5
+ "mission": {
6
+ "cruiseSpeed": 18.0,
7
+ "firmwareType": 12,
8
+ "globalPlanAltitudeMode": 1,
9
+ "hoverSpeed": 10.799999999999999,
10
+ "items": [
11
+ {
12
+ "AMSLAltAboveTerrain": null,
13
+ "Altitude": 45.0,
14
+ "AltitudeMode": 1,
15
+ "autoContinue": true,
16
+ "command": 22,
17
+ "doJumpId": 1,
18
+ "frame": 3,
19
+ "params": [
20
+ 0.0,
21
+ 0.0,
22
+ 0.0,
23
+ 0.0,
24
+ 16.07471103000006,
25
+ 108.22431477800006,
26
+ 45.0
27
+ ],
28
+ "type": "SimpleItem"
29
+ },
30
+ {
31
+ "AMSLAltAboveTerrain": null,
32
+ "Altitude": 45.0,
33
+ "AltitudeMode": 1,
34
+ "autoContinue": true,
35
+ "command": 16,
36
+ "doJumpId": 2,
37
+ "frame": 3,
38
+ "params": [
39
+ 2.0,
40
+ 5.0,
41
+ 0.0,
42
+ 0.0,
43
+ 16.077413732702762,
44
+ 108.22431477800006,
45
+ 45
46
+ ],
47
+ "type": "SimpleItem"
48
+ },
49
+ {
50
+ "AMSLAltAboveTerrain": null,
51
+ "Altitude": 45.0,
52
+ "AltitudeMode": 1,
53
+ "autoContinue": true,
54
+ "command": 16,
55
+ "doJumpId": 3,
56
+ "frame": 3,
57
+ "params": [
58
+ 2.0,
59
+ 5.0,
60
+ 0.0,
61
+ 0.0,
62
+ 16.076622129408673,
63
+ 108.22630365808487,
64
+ 45
65
+ ],
66
+ "type": "SimpleItem"
67
+ },
68
+ {
69
+ "AMSLAltAboveTerrain": null,
70
+ "Altitude": 45.0,
71
+ "AltitudeMode": 1,
72
+ "autoContinue": true,
73
+ "command": 16,
74
+ "doJumpId": 4,
75
+ "frame": 3,
76
+ "params": [
77
+ 2.0,
78
+ 5.0,
79
+ 0.0,
80
+ 0.0,
81
+ 16.07471103000006,
82
+ 108.22712745215416,
83
+ 45
84
+ ],
85
+ "type": "SimpleItem"
86
+ },
87
+ {
88
+ "AMSLAltAboveTerrain": null,
89
+ "Altitude": 45.0,
90
+ "AltitudeMode": 1,
91
+ "autoContinue": true,
92
+ "command": 16,
93
+ "doJumpId": 5,
94
+ "frame": 3,
95
+ "params": [
96
+ 2.0,
97
+ 5.0,
98
+ 0.0,
99
+ 0.0,
100
+ 16.072799930591447,
101
+ 108.2263036198531,
102
+ 45
103
+ ],
104
+ "type": "SimpleItem"
105
+ },
106
+ {
107
+ "AMSLAltAboveTerrain": null,
108
+ "Altitude": 45.0,
109
+ "AltitudeMode": 1,
110
+ "autoContinue": true,
111
+ "command": 16,
112
+ "doJumpId": 6,
113
+ "frame": 3,
114
+ "params": [
115
+ 2.0,
116
+ 5.0,
117
+ 0.0,
118
+ 0.0,
119
+ 16.072008327297358,
120
+ 108.22431477800006,
121
+ 45
122
+ ],
123
+ "type": "SimpleItem"
124
+ },
125
+ {
126
+ "AMSLAltAboveTerrain": null,
127
+ "Altitude": 45.0,
128
+ "AltitudeMode": 1,
129
+ "autoContinue": true,
130
+ "command": 16,
131
+ "doJumpId": 7,
132
+ "frame": 3,
133
+ "params": [
134
+ 2.0,
135
+ 5.0,
136
+ 0.0,
137
+ 0.0,
138
+ 16.072799930591447,
139
+ 108.22232593614703,
140
+ 45
141
+ ],
142
+ "type": "SimpleItem"
143
+ },
144
+ {
145
+ "AMSLAltAboveTerrain": null,
146
+ "Altitude": 45.0,
147
+ "AltitudeMode": 1,
148
+ "autoContinue": true,
149
+ "command": 16,
150
+ "doJumpId": 8,
151
+ "frame": 3,
152
+ "params": [
153
+ 2.0,
154
+ 5.0,
155
+ 0.0,
156
+ 0.0,
157
+ 16.07471103000006,
158
+ 108.22150210384596,
159
+ 45
160
+ ],
161
+ "type": "SimpleItem"
162
+ },
163
+ {
164
+ "AMSLAltAboveTerrain": null,
165
+ "Altitude": 45.0,
166
+ "AltitudeMode": 1,
167
+ "autoContinue": true,
168
+ "command": 16,
169
+ "doJumpId": 9,
170
+ "frame": 3,
171
+ "params": [
172
+ 2.0,
173
+ 5.0,
174
+ 0.0,
175
+ 0.0,
176
+ 16.076622129408673,
177
+ 108.22232589791525,
178
+ 45
179
+ ],
180
+ "type": "SimpleItem"
181
+ },
182
+ {
183
+ "AMSLAltAboveTerrain": null,
184
+ "Altitude": 0,
185
+ "AltitudeMode": 1,
186
+ "autoContinue": true,
187
+ "command": 203,
188
+ "doJumpId": 10,
189
+ "frame": 2,
190
+ "params": [
191
+ 1,
192
+ 0,
193
+ 0,
194
+ 1,
195
+ 0,
196
+ 0,
197
+ 0
198
+ ],
199
+ "type": "SimpleItem"
200
+ },
201
+ {
202
+ "AMSLAltAboveTerrain": null,
203
+ "Altitude": 0,
204
+ "AltitudeMode": 0,
205
+ "autoContinue": true,
206
+ "command": 20,
207
+ "doJumpId": 11,
208
+ "frame": 2,
209
+ "params": [
210
+ 0.0,
211
+ 0.0,
212
+ 0.0,
213
+ 0.0,
214
+ 0,
215
+ 0,
216
+ 0
217
+ ],
218
+ "type": "SimpleItem"
219
+ }
220
+ ],
221
+ "plannedHomePosition": [
222
+ 16.07471103000006,
223
+ 108.22431477800006,
224
+ 8.0
225
+ ],
226
+ "vehicleType": 2,
227
+ "version": 2
228
+ },
229
+ "geoFence": {
230
+ "circles": [],
231
+ "polygons": [],
232
+ "version": 2
233
+ },
234
+ "rallyPoints": {
235
+ "points": [],
236
+ "version": 2
237
+ }
238
+ }
downloads/patrol_gemini_20250822_112551.plan ADDED
@@ -0,0 +1,238 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "fileType": "Plan",
3
+ "groundStation": "DroneAgent - Patrol",
4
+ "version": 1,
5
+ "mission": {
6
+ "cruiseSpeed": 18.0,
7
+ "firmwareType": 12,
8
+ "globalPlanAltitudeMode": 1,
9
+ "hoverSpeed": 10.799999999999999,
10
+ "items": [
11
+ {
12
+ "AMSLAltAboveTerrain": null,
13
+ "Altitude": 45.0,
14
+ "AltitudeMode": 1,
15
+ "autoContinue": true,
16
+ "command": 22,
17
+ "doJumpId": 1,
18
+ "frame": 3,
19
+ "params": [
20
+ 0.0,
21
+ 0.0,
22
+ 0.0,
23
+ 0.0,
24
+ 16.466369,
25
+ 107.589264,
26
+ 45.0
27
+ ],
28
+ "type": "SimpleItem"
29
+ },
30
+ {
31
+ "AMSLAltAboveTerrain": null,
32
+ "Altitude": 45.0,
33
+ "AltitudeMode": 1,
34
+ "autoContinue": true,
35
+ "command": 16,
36
+ "doJumpId": 2,
37
+ "frame": 3,
38
+ "params": [
39
+ 2.0,
40
+ 5.0,
41
+ 0.0,
42
+ 0.0,
43
+ 16.469071702702703,
44
+ 107.589264,
45
+ 45
46
+ ],
47
+ "type": "SimpleItem"
48
+ },
49
+ {
50
+ "AMSLAltAboveTerrain": null,
51
+ "Altitude": 45.0,
52
+ "AltitudeMode": 1,
53
+ "autoContinue": true,
54
+ "command": 16,
55
+ "doJumpId": 3,
56
+ "frame": 3,
57
+ "params": [
58
+ 2.0,
59
+ 5.0,
60
+ 0.0,
61
+ 0.0,
62
+ 16.468280099408613,
63
+ 107.5912568525504,
64
+ 45
65
+ ],
66
+ "type": "SimpleItem"
67
+ },
68
+ {
69
+ "AMSLAltAboveTerrain": null,
70
+ "Altitude": 45.0,
71
+ "AltitudeMode": 1,
72
+ "autoContinue": true,
73
+ "command": 16,
74
+ "doJumpId": 4,
75
+ "frame": 3,
76
+ "params": [
77
+ 2.0,
78
+ 5.0,
79
+ 0.0,
80
+ 0.0,
81
+ 16.466369,
82
+ 107.59208229131748,
83
+ 45
84
+ ],
85
+ "type": "SimpleItem"
86
+ },
87
+ {
88
+ "AMSLAltAboveTerrain": null,
89
+ "Altitude": 45.0,
90
+ "AltitudeMode": 1,
91
+ "autoContinue": true,
92
+ "command": 16,
93
+ "doJumpId": 5,
94
+ "frame": 3,
95
+ "params": [
96
+ 2.0,
97
+ 5.0,
98
+ 0.0,
99
+ 0.0,
100
+ 16.464457900591388,
101
+ 107.59125681325611,
102
+ 45
103
+ ],
104
+ "type": "SimpleItem"
105
+ },
106
+ {
107
+ "AMSLAltAboveTerrain": null,
108
+ "Altitude": 45.0,
109
+ "AltitudeMode": 1,
110
+ "autoContinue": true,
111
+ "command": 16,
112
+ "doJumpId": 6,
113
+ "frame": 3,
114
+ "params": [
115
+ 2.0,
116
+ 5.0,
117
+ 0.0,
118
+ 0.0,
119
+ 16.463666297297298,
120
+ 107.589264,
121
+ 45
122
+ ],
123
+ "type": "SimpleItem"
124
+ },
125
+ {
126
+ "AMSLAltAboveTerrain": null,
127
+ "Altitude": 45.0,
128
+ "AltitudeMode": 1,
129
+ "autoContinue": true,
130
+ "command": 16,
131
+ "doJumpId": 7,
132
+ "frame": 3,
133
+ "params": [
134
+ 2.0,
135
+ 5.0,
136
+ 0.0,
137
+ 0.0,
138
+ 16.464457900591388,
139
+ 107.58727118674389,
140
+ 45
141
+ ],
142
+ "type": "SimpleItem"
143
+ },
144
+ {
145
+ "AMSLAltAboveTerrain": null,
146
+ "Altitude": 45.0,
147
+ "AltitudeMode": 1,
148
+ "autoContinue": true,
149
+ "command": 16,
150
+ "doJumpId": 8,
151
+ "frame": 3,
152
+ "params": [
153
+ 2.0,
154
+ 5.0,
155
+ 0.0,
156
+ 0.0,
157
+ 16.466369,
158
+ 107.58644570868252,
159
+ 45
160
+ ],
161
+ "type": "SimpleItem"
162
+ },
163
+ {
164
+ "AMSLAltAboveTerrain": null,
165
+ "Altitude": 45.0,
166
+ "AltitudeMode": 1,
167
+ "autoContinue": true,
168
+ "command": 16,
169
+ "doJumpId": 9,
170
+ "frame": 3,
171
+ "params": [
172
+ 2.0,
173
+ 5.0,
174
+ 0.0,
175
+ 0.0,
176
+ 16.468280099408613,
177
+ 107.5872711474496,
178
+ 45
179
+ ],
180
+ "type": "SimpleItem"
181
+ },
182
+ {
183
+ "AMSLAltAboveTerrain": null,
184
+ "Altitude": 0,
185
+ "AltitudeMode": 1,
186
+ "autoContinue": true,
187
+ "command": 203,
188
+ "doJumpId": 10,
189
+ "frame": 2,
190
+ "params": [
191
+ 1,
192
+ 0,
193
+ 0,
194
+ 1,
195
+ 0,
196
+ 0,
197
+ 0
198
+ ],
199
+ "type": "SimpleItem"
200
+ },
201
+ {
202
+ "AMSLAltAboveTerrain": null,
203
+ "Altitude": 0,
204
+ "AltitudeMode": 0,
205
+ "autoContinue": true,
206
+ "command": 20,
207
+ "doJumpId": 11,
208
+ "frame": 2,
209
+ "params": [
210
+ 0.0,
211
+ 0.0,
212
+ 0.0,
213
+ 0.0,
214
+ 0,
215
+ 0,
216
+ 0
217
+ ],
218
+ "type": "SimpleItem"
219
+ }
220
+ ],
221
+ "plannedHomePosition": [
222
+ 16.466369,
223
+ 107.589264,
224
+ 8.0
225
+ ],
226
+ "vehicleType": 2,
227
+ "version": 2
228
+ },
229
+ "geoFence": {
230
+ "circles": [],
231
+ "polygons": [],
232
+ "version": 2
233
+ },
234
+ "rallyPoints": {
235
+ "points": [],
236
+ "version": 2
237
+ }
238
+ }
downloads/patrol_gemini_20250822_114301.plan ADDED
@@ -0,0 +1,238 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "fileType": "Plan",
3
+ "groundStation": "DroneAgent - Patrol",
4
+ "version": 1,
5
+ "mission": {
6
+ "cruiseSpeed": 18.0,
7
+ "firmwareType": 12,
8
+ "globalPlanAltitudeMode": 1,
9
+ "hoverSpeed": 10.799999999999999,
10
+ "items": [
11
+ {
12
+ "AMSLAltAboveTerrain": null,
13
+ "Altitude": 45.0,
14
+ "AltitudeMode": 1,
15
+ "autoContinue": true,
16
+ "command": 22,
17
+ "doJumpId": 1,
18
+ "frame": 3,
19
+ "params": [
20
+ 0.0,
21
+ 0.0,
22
+ 0.0,
23
+ 0.0,
24
+ 16.466369,
25
+ 107.589264,
26
+ 45.0
27
+ ],
28
+ "type": "SimpleItem"
29
+ },
30
+ {
31
+ "AMSLAltAboveTerrain": null,
32
+ "Altitude": 45.0,
33
+ "AltitudeMode": 1,
34
+ "autoContinue": true,
35
+ "command": 16,
36
+ "doJumpId": 2,
37
+ "frame": 3,
38
+ "params": [
39
+ 2.0,
40
+ 5.0,
41
+ 0.0,
42
+ 0.0,
43
+ 16.469071702702703,
44
+ 107.589264,
45
+ 45
46
+ ],
47
+ "type": "SimpleItem"
48
+ },
49
+ {
50
+ "AMSLAltAboveTerrain": null,
51
+ "Altitude": 45.0,
52
+ "AltitudeMode": 1,
53
+ "autoContinue": true,
54
+ "command": 16,
55
+ "doJumpId": 3,
56
+ "frame": 3,
57
+ "params": [
58
+ 2.0,
59
+ 5.0,
60
+ 0.0,
61
+ 0.0,
62
+ 16.468280099408613,
63
+ 107.5912568525504,
64
+ 45
65
+ ],
66
+ "type": "SimpleItem"
67
+ },
68
+ {
69
+ "AMSLAltAboveTerrain": null,
70
+ "Altitude": 45.0,
71
+ "AltitudeMode": 1,
72
+ "autoContinue": true,
73
+ "command": 16,
74
+ "doJumpId": 4,
75
+ "frame": 3,
76
+ "params": [
77
+ 2.0,
78
+ 5.0,
79
+ 0.0,
80
+ 0.0,
81
+ 16.466369,
82
+ 107.59208229131748,
83
+ 45
84
+ ],
85
+ "type": "SimpleItem"
86
+ },
87
+ {
88
+ "AMSLAltAboveTerrain": null,
89
+ "Altitude": 45.0,
90
+ "AltitudeMode": 1,
91
+ "autoContinue": true,
92
+ "command": 16,
93
+ "doJumpId": 5,
94
+ "frame": 3,
95
+ "params": [
96
+ 2.0,
97
+ 5.0,
98
+ 0.0,
99
+ 0.0,
100
+ 16.464457900591388,
101
+ 107.59125681325611,
102
+ 45
103
+ ],
104
+ "type": "SimpleItem"
105
+ },
106
+ {
107
+ "AMSLAltAboveTerrain": null,
108
+ "Altitude": 45.0,
109
+ "AltitudeMode": 1,
110
+ "autoContinue": true,
111
+ "command": 16,
112
+ "doJumpId": 6,
113
+ "frame": 3,
114
+ "params": [
115
+ 2.0,
116
+ 5.0,
117
+ 0.0,
118
+ 0.0,
119
+ 16.463666297297298,
120
+ 107.589264,
121
+ 45
122
+ ],
123
+ "type": "SimpleItem"
124
+ },
125
+ {
126
+ "AMSLAltAboveTerrain": null,
127
+ "Altitude": 45.0,
128
+ "AltitudeMode": 1,
129
+ "autoContinue": true,
130
+ "command": 16,
131
+ "doJumpId": 7,
132
+ "frame": 3,
133
+ "params": [
134
+ 2.0,
135
+ 5.0,
136
+ 0.0,
137
+ 0.0,
138
+ 16.464457900591388,
139
+ 107.58727118674389,
140
+ 45
141
+ ],
142
+ "type": "SimpleItem"
143
+ },
144
+ {
145
+ "AMSLAltAboveTerrain": null,
146
+ "Altitude": 45.0,
147
+ "AltitudeMode": 1,
148
+ "autoContinue": true,
149
+ "command": 16,
150
+ "doJumpId": 8,
151
+ "frame": 3,
152
+ "params": [
153
+ 2.0,
154
+ 5.0,
155
+ 0.0,
156
+ 0.0,
157
+ 16.466369,
158
+ 107.58644570868252,
159
+ 45
160
+ ],
161
+ "type": "SimpleItem"
162
+ },
163
+ {
164
+ "AMSLAltAboveTerrain": null,
165
+ "Altitude": 45.0,
166
+ "AltitudeMode": 1,
167
+ "autoContinue": true,
168
+ "command": 16,
169
+ "doJumpId": 9,
170
+ "frame": 3,
171
+ "params": [
172
+ 2.0,
173
+ 5.0,
174
+ 0.0,
175
+ 0.0,
176
+ 16.468280099408613,
177
+ 107.5872711474496,
178
+ 45
179
+ ],
180
+ "type": "SimpleItem"
181
+ },
182
+ {
183
+ "AMSLAltAboveTerrain": null,
184
+ "Altitude": 0,
185
+ "AltitudeMode": 1,
186
+ "autoContinue": true,
187
+ "command": 203,
188
+ "doJumpId": 10,
189
+ "frame": 2,
190
+ "params": [
191
+ 1,
192
+ 0,
193
+ 0,
194
+ 1,
195
+ 0,
196
+ 0,
197
+ 0
198
+ ],
199
+ "type": "SimpleItem"
200
+ },
201
+ {
202
+ "AMSLAltAboveTerrain": null,
203
+ "Altitude": 0,
204
+ "AltitudeMode": 0,
205
+ "autoContinue": true,
206
+ "command": 20,
207
+ "doJumpId": 11,
208
+ "frame": 2,
209
+ "params": [
210
+ 0.0,
211
+ 0.0,
212
+ 0.0,
213
+ 0.0,
214
+ 0,
215
+ 0,
216
+ 0
217
+ ],
218
+ "type": "SimpleItem"
219
+ }
220
+ ],
221
+ "plannedHomePosition": [
222
+ 16.466369,
223
+ 107.589264,
224
+ 8.0
225
+ ],
226
+ "vehicleType": 2,
227
+ "version": 2
228
+ },
229
+ "geoFence": {
230
+ "circles": [],
231
+ "polygons": [],
232
+ "version": 2
233
+ },
234
+ "rallyPoints": {
235
+ "points": [],
236
+ "version": 2
237
+ }
238
+ }
downloads/photography_gemini_20250822_104534.plan ADDED
@@ -0,0 +1,181 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "fileType": "Plan",
3
+ "groundStation": "DroneAgent - Photography",
4
+ "version": 1,
5
+ "mission": {
6
+ "cruiseSpeed": 5.0,
7
+ "firmwareType": 12,
8
+ "globalPlanAltitudeMode": 1,
9
+ "hoverSpeed": 3.0,
10
+ "items": [
11
+ {
12
+ "AMSLAltAboveTerrain": null,
13
+ "Altitude": 40.0,
14
+ "AltitudeMode": 1,
15
+ "autoContinue": true,
16
+ "command": 22,
17
+ "doJumpId": 1,
18
+ "frame": 3,
19
+ "params": [
20
+ 0.0,
21
+ 0.0,
22
+ 0.0,
23
+ 0.0,
24
+ 16.466369,
25
+ 107.589264,
26
+ 40.0
27
+ ],
28
+ "type": "SimpleItem"
29
+ },
30
+ {
31
+ "AMSLAltAboveTerrain": null,
32
+ "Altitude": 40.0,
33
+ "AltitudeMode": 1,
34
+ "autoContinue": true,
35
+ "command": 16,
36
+ "doJumpId": 2,
37
+ "frame": 3,
38
+ "params": [
39
+ 3.0,
40
+ 2.0,
41
+ 0.0,
42
+ 0.0,
43
+ 16.467720351351353,
44
+ 107.59067315548278,
45
+ 40
46
+ ],
47
+ "type": "SimpleItem"
48
+ },
49
+ {
50
+ "AMSLAltAboveTerrain": null,
51
+ "Altitude": 50.0,
52
+ "AltitudeMode": 1,
53
+ "autoContinue": true,
54
+ "command": 16,
55
+ "doJumpId": 3,
56
+ "frame": 3,
57
+ "params": [
58
+ 3.0,
59
+ 2.0,
60
+ 0.0,
61
+ 0.0,
62
+ 16.465017648648647,
63
+ 107.59067313583563,
64
+ 50
65
+ ],
66
+ "type": "SimpleItem"
67
+ },
68
+ {
69
+ "AMSLAltAboveTerrain": null,
70
+ "Altitude": 40.0,
71
+ "AltitudeMode": 1,
72
+ "autoContinue": true,
73
+ "command": 16,
74
+ "doJumpId": 4,
75
+ "frame": 3,
76
+ "params": [
77
+ 3.0,
78
+ 2.0,
79
+ 0.0,
80
+ 0.0,
81
+ 16.465017648648647,
82
+ 107.58785486416437,
83
+ 40
84
+ ],
85
+ "type": "SimpleItem"
86
+ },
87
+ {
88
+ "AMSLAltAboveTerrain": null,
89
+ "Altitude": 50.0,
90
+ "AltitudeMode": 1,
91
+ "autoContinue": true,
92
+ "command": 16,
93
+ "doJumpId": 5,
94
+ "frame": 3,
95
+ "params": [
96
+ 3.0,
97
+ 2.0,
98
+ 0.0,
99
+ 0.0,
100
+ 16.467720351351353,
101
+ 107.58785484451722,
102
+ 50
103
+ ],
104
+ "type": "SimpleItem"
105
+ },
106
+ {
107
+ "AMSLAltAboveTerrain": null,
108
+ "Altitude": 60.0,
109
+ "AltitudeMode": 1,
110
+ "autoContinue": true,
111
+ "command": 16,
112
+ "doJumpId": 6,
113
+ "frame": 3,
114
+ "params": [
115
+ 3.0,
116
+ 2.0,
117
+ 0.0,
118
+ 0.0,
119
+ 16.466369,
120
+ 107.589264,
121
+ 60
122
+ ],
123
+ "type": "SimpleItem"
124
+ },
125
+ {
126
+ "AMSLAltAboveTerrain": null,
127
+ "Altitude": 0,
128
+ "AltitudeMode": 1,
129
+ "autoContinue": true,
130
+ "command": 203,
131
+ "doJumpId": 7,
132
+ "frame": 2,
133
+ "params": [
134
+ 1,
135
+ 0,
136
+ 0,
137
+ 1,
138
+ 0,
139
+ 0,
140
+ 0
141
+ ],
142
+ "type": "SimpleItem"
143
+ },
144
+ {
145
+ "AMSLAltAboveTerrain": null,
146
+ "Altitude": 0,
147
+ "AltitudeMode": 0,
148
+ "autoContinue": true,
149
+ "command": 20,
150
+ "doJumpId": 8,
151
+ "frame": 2,
152
+ "params": [
153
+ 0.0,
154
+ 0.0,
155
+ 0.0,
156
+ 0.0,
157
+ 0,
158
+ 0,
159
+ 0
160
+ ],
161
+ "type": "SimpleItem"
162
+ }
163
+ ],
164
+ "plannedHomePosition": [
165
+ 16.466369,
166
+ 107.589264,
167
+ 8.0
168
+ ],
169
+ "vehicleType": 2,
170
+ "version": 2
171
+ },
172
+ "geoFence": {
173
+ "circles": [],
174
+ "polygons": [],
175
+ "version": 2
176
+ },
177
+ "rallyPoints": {
178
+ "points": [],
179
+ "version": 2
180
+ }
181
+ }
downloads/photography_gemini_20250822_114121.plan ADDED
@@ -0,0 +1,181 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "fileType": "Plan",
3
+ "groundStation": "DroneAgent - Photography",
4
+ "version": 1,
5
+ "mission": {
6
+ "cruiseSpeed": 5.0,
7
+ "firmwareType": 12,
8
+ "globalPlanAltitudeMode": 1,
9
+ "hoverSpeed": 3.0,
10
+ "items": [
11
+ {
12
+ "AMSLAltAboveTerrain": null,
13
+ "Altitude": 60.0,
14
+ "AltitudeMode": 1,
15
+ "autoContinue": true,
16
+ "command": 22,
17
+ "doJumpId": 1,
18
+ "frame": 3,
19
+ "params": [
20
+ 0.0,
21
+ 0.0,
22
+ 0.0,
23
+ 0.0,
24
+ 16.123456,
25
+ 108.654321,
26
+ 60.0
27
+ ],
28
+ "type": "SimpleItem"
29
+ },
30
+ {
31
+ "AMSLAltAboveTerrain": null,
32
+ "Altitude": 60.0,
33
+ "AltitudeMode": 1,
34
+ "autoContinue": true,
35
+ "command": 16,
36
+ "doJumpId": 2,
37
+ "frame": 3,
38
+ "params": [
39
+ 3.0,
40
+ 2.0,
41
+ 0.0,
42
+ 0.0,
43
+ 16.124807351351354,
44
+ 108.65572769202923,
45
+ 60
46
+ ],
47
+ "type": "SimpleItem"
48
+ },
49
+ {
50
+ "AMSLAltAboveTerrain": null,
51
+ "Altitude": 70.0,
52
+ "AltitudeMode": 1,
53
+ "autoContinue": true,
54
+ "command": 16,
55
+ "doJumpId": 3,
56
+ "frame": 3,
57
+ "params": [
58
+ 3.0,
59
+ 2.0,
60
+ 0.0,
61
+ 0.0,
62
+ 16.122104648648648,
63
+ 108.6557276728475,
64
+ 70
65
+ ],
66
+ "type": "SimpleItem"
67
+ },
68
+ {
69
+ "AMSLAltAboveTerrain": null,
70
+ "Altitude": 60.0,
71
+ "AltitudeMode": 1,
72
+ "autoContinue": true,
73
+ "command": 16,
74
+ "doJumpId": 4,
75
+ "frame": 3,
76
+ "params": [
77
+ 3.0,
78
+ 2.0,
79
+ 0.0,
80
+ 0.0,
81
+ 16.122104648648648,
82
+ 108.65291432715249,
83
+ 60
84
+ ],
85
+ "type": "SimpleItem"
86
+ },
87
+ {
88
+ "AMSLAltAboveTerrain": null,
89
+ "Altitude": 70.0,
90
+ "AltitudeMode": 1,
91
+ "autoContinue": true,
92
+ "command": 16,
93
+ "doJumpId": 5,
94
+ "frame": 3,
95
+ "params": [
96
+ 3.0,
97
+ 2.0,
98
+ 0.0,
99
+ 0.0,
100
+ 16.124807351351354,
101
+ 108.65291430797076,
102
+ 70
103
+ ],
104
+ "type": "SimpleItem"
105
+ },
106
+ {
107
+ "AMSLAltAboveTerrain": null,
108
+ "Altitude": 80.0,
109
+ "AltitudeMode": 1,
110
+ "autoContinue": true,
111
+ "command": 16,
112
+ "doJumpId": 6,
113
+ "frame": 3,
114
+ "params": [
115
+ 3.0,
116
+ 2.0,
117
+ 0.0,
118
+ 0.0,
119
+ 16.123456,
120
+ 108.654321,
121
+ 80
122
+ ],
123
+ "type": "SimpleItem"
124
+ },
125
+ {
126
+ "AMSLAltAboveTerrain": null,
127
+ "Altitude": 0,
128
+ "AltitudeMode": 1,
129
+ "autoContinue": true,
130
+ "command": 203,
131
+ "doJumpId": 7,
132
+ "frame": 2,
133
+ "params": [
134
+ 1,
135
+ 0,
136
+ 0,
137
+ 1,
138
+ 0,
139
+ 0,
140
+ 0
141
+ ],
142
+ "type": "SimpleItem"
143
+ },
144
+ {
145
+ "AMSLAltAboveTerrain": null,
146
+ "Altitude": 0,
147
+ "AltitudeMode": 0,
148
+ "autoContinue": true,
149
+ "command": 20,
150
+ "doJumpId": 8,
151
+ "frame": 2,
152
+ "params": [
153
+ 0.0,
154
+ 0.0,
155
+ 0.0,
156
+ 0.0,
157
+ 0,
158
+ 0,
159
+ 0
160
+ ],
161
+ "type": "SimpleItem"
162
+ }
163
+ ],
164
+ "plannedHomePosition": [
165
+ 16.123456,
166
+ 108.654321,
167
+ 8.0
168
+ ],
169
+ "vehicleType": 2,
170
+ "version": 2
171
+ },
172
+ "geoFence": {
173
+ "circles": [],
174
+ "polygons": [],
175
+ "version": 2
176
+ },
177
+ "rallyPoints": {
178
+ "points": [],
179
+ "version": 2
180
+ }
181
+ }
downloads/photography_gemini_20250822_114715.plan ADDED
@@ -0,0 +1,181 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "fileType": "Plan",
3
+ "groundStation": "DroneAgent - Photography",
4
+ "version": 1,
5
+ "mission": {
6
+ "cruiseSpeed": 5.0,
7
+ "firmwareType": 12,
8
+ "globalPlanAltitudeMode": 1,
9
+ "hoverSpeed": 3.0,
10
+ "items": [
11
+ {
12
+ "AMSLAltAboveTerrain": null,
13
+ "Altitude": 50.0,
14
+ "AltitudeMode": 1,
15
+ "autoContinue": true,
16
+ "command": 22,
17
+ "doJumpId": 1,
18
+ "frame": 3,
19
+ "params": [
20
+ 0.0,
21
+ 0.0,
22
+ 0.0,
23
+ 0.0,
24
+ 16.047123,
25
+ 108.206453,
26
+ 50.0
27
+ ],
28
+ "type": "SimpleItem"
29
+ },
30
+ {
31
+ "AMSLAltAboveTerrain": null,
32
+ "Altitude": 50.0,
33
+ "AltitudeMode": 1,
34
+ "autoContinue": true,
35
+ "command": 16,
36
+ "doJumpId": 2,
37
+ "frame": 3,
38
+ "params": [
39
+ 3.0,
40
+ 2.0,
41
+ 0.0,
42
+ 0.0,
43
+ 16.048474351351352,
44
+ 108.20785915168014,
45
+ 50
46
+ ],
47
+ "type": "SimpleItem"
48
+ },
49
+ {
50
+ "AMSLAltAboveTerrain": null,
51
+ "Altitude": 60.0,
52
+ "AltitudeMode": 1,
53
+ "autoContinue": true,
54
+ "command": 16,
55
+ "doJumpId": 3,
56
+ "frame": 3,
57
+ "params": [
58
+ 3.0,
59
+ 2.0,
60
+ 0.0,
61
+ 0.0,
62
+ 16.045771648648646,
63
+ 108.2078591326015,
64
+ 60
65
+ ],
66
+ "type": "SimpleItem"
67
+ },
68
+ {
69
+ "AMSLAltAboveTerrain": null,
70
+ "Altitude": 50.0,
71
+ "AltitudeMode": 1,
72
+ "autoContinue": true,
73
+ "command": 16,
74
+ "doJumpId": 4,
75
+ "frame": 3,
76
+ "params": [
77
+ 3.0,
78
+ 2.0,
79
+ 0.0,
80
+ 0.0,
81
+ 16.045771648648646,
82
+ 108.2050468673985,
83
+ 50
84
+ ],
85
+ "type": "SimpleItem"
86
+ },
87
+ {
88
+ "AMSLAltAboveTerrain": null,
89
+ "Altitude": 60.0,
90
+ "AltitudeMode": 1,
91
+ "autoContinue": true,
92
+ "command": 16,
93
+ "doJumpId": 5,
94
+ "frame": 3,
95
+ "params": [
96
+ 3.0,
97
+ 2.0,
98
+ 0.0,
99
+ 0.0,
100
+ 16.048474351351352,
101
+ 108.20504684831985,
102
+ 60
103
+ ],
104
+ "type": "SimpleItem"
105
+ },
106
+ {
107
+ "AMSLAltAboveTerrain": null,
108
+ "Altitude": 70.0,
109
+ "AltitudeMode": 1,
110
+ "autoContinue": true,
111
+ "command": 16,
112
+ "doJumpId": 6,
113
+ "frame": 3,
114
+ "params": [
115
+ 3.0,
116
+ 2.0,
117
+ 0.0,
118
+ 0.0,
119
+ 16.047123,
120
+ 108.206453,
121
+ 70
122
+ ],
123
+ "type": "SimpleItem"
124
+ },
125
+ {
126
+ "AMSLAltAboveTerrain": null,
127
+ "Altitude": 0,
128
+ "AltitudeMode": 1,
129
+ "autoContinue": true,
130
+ "command": 203,
131
+ "doJumpId": 7,
132
+ "frame": 2,
133
+ "params": [
134
+ 1,
135
+ 0,
136
+ 0,
137
+ 1,
138
+ 0,
139
+ 0,
140
+ 0
141
+ ],
142
+ "type": "SimpleItem"
143
+ },
144
+ {
145
+ "AMSLAltAboveTerrain": null,
146
+ "Altitude": 0,
147
+ "AltitudeMode": 0,
148
+ "autoContinue": true,
149
+ "command": 20,
150
+ "doJumpId": 8,
151
+ "frame": 2,
152
+ "params": [
153
+ 0.0,
154
+ 0.0,
155
+ 0.0,
156
+ 0.0,
157
+ 0,
158
+ 0,
159
+ 0
160
+ ],
161
+ "type": "SimpleItem"
162
+ }
163
+ ],
164
+ "plannedHomePosition": [
165
+ 16.047123,
166
+ 108.206453,
167
+ 8.0
168
+ ],
169
+ "vehicleType": 2,
170
+ "version": 2
171
+ },
172
+ "geoFence": {
173
+ "circles": [],
174
+ "polygons": [],
175
+ "version": 2
176
+ },
177
+ "rallyPoints": {
178
+ "points": [],
179
+ "version": 2
180
+ }
181
+ }
downloads/simple_flight_gemini_20250822_114423.plan ADDED
@@ -0,0 +1,162 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "fileType": "Plan",
3
+ "groundStation": "DroneAgent - Simple_Flight",
4
+ "version": 1,
5
+ "mission": {
6
+ "cruiseSpeed": 12.0,
7
+ "firmwareType": 12,
8
+ "globalPlanAltitudeMode": 1,
9
+ "hoverSpeed": 7.199999999999999,
10
+ "items": [
11
+ {
12
+ "AMSLAltAboveTerrain": null,
13
+ "Altitude": 50.0,
14
+ "AltitudeMode": 1,
15
+ "autoContinue": true,
16
+ "command": 22,
17
+ "doJumpId": 1,
18
+ "frame": 3,
19
+ "params": [
20
+ 0.0,
21
+ 0.0,
22
+ 0.0,
23
+ 0.0,
24
+ 16.047122,
25
+ 108.206452,
26
+ 50.0
27
+ ],
28
+ "type": "SimpleItem"
29
+ },
30
+ {
31
+ "AMSLAltAboveTerrain": null,
32
+ "Altitude": 70.0,
33
+ "AltitudeMode": 1,
34
+ "autoContinue": true,
35
+ "command": 16,
36
+ "doJumpId": 2,
37
+ "frame": 3,
38
+ "params": [
39
+ 0.0,
40
+ 2.0,
41
+ 0.0,
42
+ 0.0,
43
+ 16.047572450450453,
44
+ 108.206452,
45
+ 70
46
+ ],
47
+ "type": "SimpleItem"
48
+ },
49
+ {
50
+ "AMSLAltAboveTerrain": null,
51
+ "Altitude": 70.0,
52
+ "AltitudeMode": 1,
53
+ "autoContinue": true,
54
+ "command": 16,
55
+ "doJumpId": 3,
56
+ "frame": 3,
57
+ "params": [
58
+ 0.0,
59
+ 2.0,
60
+ 0.0,
61
+ 0.0,
62
+ 16.048022900900904,
63
+ 108.206452,
64
+ 70
65
+ ],
66
+ "type": "SimpleItem"
67
+ },
68
+ {
69
+ "AMSLAltAboveTerrain": null,
70
+ "Altitude": 70.0,
71
+ "AltitudeMode": 1,
72
+ "autoContinue": true,
73
+ "command": 16,
74
+ "doJumpId": 4,
75
+ "frame": 3,
76
+ "params": [
77
+ 0.0,
78
+ 2.0,
79
+ 0.0,
80
+ 0.0,
81
+ 16.048473351351355,
82
+ 108.206452,
83
+ 70
84
+ ],
85
+ "type": "SimpleItem"
86
+ },
87
+ {
88
+ "AMSLAltAboveTerrain": null,
89
+ "Altitude": 70.0,
90
+ "AltitudeMode": 1,
91
+ "autoContinue": true,
92
+ "command": 16,
93
+ "doJumpId": 5,
94
+ "frame": 3,
95
+ "params": [
96
+ 0.0,
97
+ 2.0,
98
+ 0.0,
99
+ 0.0,
100
+ 16.048923801801802,
101
+ 108.206452,
102
+ 70
103
+ ],
104
+ "type": "SimpleItem"
105
+ },
106
+ {
107
+ "AMSLAltAboveTerrain": null,
108
+ "Altitude": 0,
109
+ "AltitudeMode": 1,
110
+ "autoContinue": true,
111
+ "command": 203,
112
+ "doJumpId": 6,
113
+ "frame": 2,
114
+ "params": [
115
+ 1,
116
+ 0,
117
+ 0,
118
+ 1,
119
+ 0,
120
+ 0,
121
+ 0
122
+ ],
123
+ "type": "SimpleItem"
124
+ },
125
+ {
126
+ "AMSLAltAboveTerrain": null,
127
+ "Altitude": 0,
128
+ "AltitudeMode": 0,
129
+ "autoContinue": true,
130
+ "command": 20,
131
+ "doJumpId": 7,
132
+ "frame": 2,
133
+ "params": [
134
+ 0.0,
135
+ 0.0,
136
+ 0.0,
137
+ 0.0,
138
+ 0,
139
+ 0,
140
+ 0
141
+ ],
142
+ "type": "SimpleItem"
143
+ }
144
+ ],
145
+ "plannedHomePosition": [
146
+ 16.047122,
147
+ 108.206452,
148
+ 8.0
149
+ ],
150
+ "vehicleType": 2,
151
+ "version": 2
152
+ },
153
+ "geoFence": {
154
+ "circles": [],
155
+ "polygons": [],
156
+ "version": 2
157
+ },
158
+ "rallyPoints": {
159
+ "points": [],
160
+ "version": 2
161
+ }
162
+ }
downloads/simple_flight_gemini_20250822_114433.plan ADDED
@@ -0,0 +1,162 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "fileType": "Plan",
3
+ "groundStation": "DroneAgent - Simple_Flight",
4
+ "version": 1,
5
+ "mission": {
6
+ "cruiseSpeed": 12.0,
7
+ "firmwareType": 12,
8
+ "globalPlanAltitudeMode": 1,
9
+ "hoverSpeed": 7.199999999999999,
10
+ "items": [
11
+ {
12
+ "AMSLAltAboveTerrain": null,
13
+ "Altitude": 60.0,
14
+ "AltitudeMode": 1,
15
+ "autoContinue": true,
16
+ "command": 22,
17
+ "doJumpId": 1,
18
+ "frame": 3,
19
+ "params": [
20
+ 0.0,
21
+ 0.0,
22
+ 0.0,
23
+ 0.0,
24
+ 16.047123,
25
+ 108.206453,
26
+ 60.0
27
+ ],
28
+ "type": "SimpleItem"
29
+ },
30
+ {
31
+ "AMSLAltAboveTerrain": null,
32
+ "Altitude": 70.0,
33
+ "AltitudeMode": 1,
34
+ "autoContinue": true,
35
+ "command": 16,
36
+ "doJumpId": 2,
37
+ "frame": 3,
38
+ "params": [
39
+ 0.0,
40
+ 2.0,
41
+ 0.0,
42
+ 0.0,
43
+ 16.04757345045045,
44
+ 108.206453,
45
+ 70
46
+ ],
47
+ "type": "SimpleItem"
48
+ },
49
+ {
50
+ "AMSLAltAboveTerrain": null,
51
+ "Altitude": 70.0,
52
+ "AltitudeMode": 1,
53
+ "autoContinue": true,
54
+ "command": 16,
55
+ "doJumpId": 3,
56
+ "frame": 3,
57
+ "params": [
58
+ 0.0,
59
+ 2.0,
60
+ 0.0,
61
+ 0.0,
62
+ 16.0480239009009,
63
+ 108.206453,
64
+ 70
65
+ ],
66
+ "type": "SimpleItem"
67
+ },
68
+ {
69
+ "AMSLAltAboveTerrain": null,
70
+ "Altitude": 70.0,
71
+ "AltitudeMode": 1,
72
+ "autoContinue": true,
73
+ "command": 16,
74
+ "doJumpId": 4,
75
+ "frame": 3,
76
+ "params": [
77
+ 0.0,
78
+ 2.0,
79
+ 0.0,
80
+ 0.0,
81
+ 16.048474351351352,
82
+ 108.206453,
83
+ 70
84
+ ],
85
+ "type": "SimpleItem"
86
+ },
87
+ {
88
+ "AMSLAltAboveTerrain": null,
89
+ "Altitude": 70.0,
90
+ "AltitudeMode": 1,
91
+ "autoContinue": true,
92
+ "command": 16,
93
+ "doJumpId": 5,
94
+ "frame": 3,
95
+ "params": [
96
+ 0.0,
97
+ 2.0,
98
+ 0.0,
99
+ 0.0,
100
+ 16.0489248018018,
101
+ 108.206453,
102
+ 70
103
+ ],
104
+ "type": "SimpleItem"
105
+ },
106
+ {
107
+ "AMSLAltAboveTerrain": null,
108
+ "Altitude": 0,
109
+ "AltitudeMode": 1,
110
+ "autoContinue": true,
111
+ "command": 203,
112
+ "doJumpId": 6,
113
+ "frame": 2,
114
+ "params": [
115
+ 1,
116
+ 0,
117
+ 0,
118
+ 1,
119
+ 0,
120
+ 0,
121
+ 0
122
+ ],
123
+ "type": "SimpleItem"
124
+ },
125
+ {
126
+ "AMSLAltAboveTerrain": null,
127
+ "Altitude": 0,
128
+ "AltitudeMode": 0,
129
+ "autoContinue": true,
130
+ "command": 20,
131
+ "doJumpId": 7,
132
+ "frame": 2,
133
+ "params": [
134
+ 0.0,
135
+ 0.0,
136
+ 0.0,
137
+ 0.0,
138
+ 0,
139
+ 0,
140
+ 0
141
+ ],
142
+ "type": "SimpleItem"
143
+ }
144
+ ],
145
+ "plannedHomePosition": [
146
+ 16.047123,
147
+ 108.206453,
148
+ 8.0
149
+ ],
150
+ "vehicleType": 2,
151
+ "version": 2
152
+ },
153
+ "geoFence": {
154
+ "circles": [],
155
+ "polygons": [],
156
+ "version": 2
157
+ },
158
+ "rallyPoints": {
159
+ "points": [],
160
+ "version": 2
161
+ }
162
+ }
downloads/survey_gemini_20250822_112524.plan ADDED
@@ -0,0 +1,390 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "fileType": "Plan",
3
+ "groundStation": "DroneAgent - Survey",
4
+ "version": 1,
5
+ "mission": {
6
+ "cruiseSpeed": 15.0,
7
+ "firmwareType": 12,
8
+ "globalPlanAltitudeMode": 1,
9
+ "hoverSpeed": 9.0,
10
+ "items": [
11
+ {
12
+ "AMSLAltAboveTerrain": null,
13
+ "Altitude": 60.0,
14
+ "AltitudeMode": 1,
15
+ "autoContinue": true,
16
+ "command": 22,
17
+ "doJumpId": 1,
18
+ "frame": 3,
19
+ "params": [
20
+ 0.0,
21
+ 0.0,
22
+ 0.0,
23
+ 0.0,
24
+ 16.047123,
25
+ 108.206456,
26
+ 60.0
27
+ ],
28
+ "type": "SimpleItem"
29
+ },
30
+ {
31
+ "AMSLAltAboveTerrain": null,
32
+ "Altitude": 60.0,
33
+ "AltitudeMode": 1,
34
+ "autoContinue": true,
35
+ "command": 16,
36
+ "doJumpId": 2,
37
+ "frame": 3,
38
+ "params": [
39
+ 1.0,
40
+ 3.0,
41
+ 0.0,
42
+ 0.0,
43
+ 16.043519396396395,
44
+ 108.20270635545224,
45
+ 60
46
+ ],
47
+ "type": "SimpleItem"
48
+ },
49
+ {
50
+ "AMSLAltAboveTerrain": null,
51
+ "Altitude": 60.0,
52
+ "AltitudeMode": 1,
53
+ "autoContinue": true,
54
+ "command": 16,
55
+ "doJumpId": 3,
56
+ "frame": 3,
57
+ "params": [
58
+ 1.0,
59
+ 3.0,
60
+ 0.0,
61
+ 0.0,
62
+ 16.043519396396395,
63
+ 108.20458117772611,
64
+ 60
65
+ ],
66
+ "type": "SimpleItem"
67
+ },
68
+ {
69
+ "AMSLAltAboveTerrain": null,
70
+ "Altitude": 60.0,
71
+ "AltitudeMode": 1,
72
+ "autoContinue": true,
73
+ "command": 16,
74
+ "doJumpId": 4,
75
+ "frame": 3,
76
+ "params": [
77
+ 1.0,
78
+ 3.0,
79
+ 0.0,
80
+ 0.0,
81
+ 16.043519396396395,
82
+ 108.206456,
83
+ 60
84
+ ],
85
+ "type": "SimpleItem"
86
+ },
87
+ {
88
+ "AMSLAltAboveTerrain": null,
89
+ "Altitude": 60.0,
90
+ "AltitudeMode": 1,
91
+ "autoContinue": true,
92
+ "command": 16,
93
+ "doJumpId": 5,
94
+ "frame": 3,
95
+ "params": [
96
+ 1.0,
97
+ 3.0,
98
+ 0.0,
99
+ 0.0,
100
+ 16.043519396396395,
101
+ 108.2083308222739,
102
+ 60
103
+ ],
104
+ "type": "SimpleItem"
105
+ },
106
+ {
107
+ "AMSLAltAboveTerrain": null,
108
+ "Altitude": 60.0,
109
+ "AltitudeMode": 1,
110
+ "autoContinue": true,
111
+ "command": 16,
112
+ "doJumpId": 6,
113
+ "frame": 3,
114
+ "params": [
115
+ 1.0,
116
+ 3.0,
117
+ 0.0,
118
+ 0.0,
119
+ 16.0453211981982,
120
+ 108.20270632154111,
121
+ 60
122
+ ],
123
+ "type": "SimpleItem"
124
+ },
125
+ {
126
+ "AMSLAltAboveTerrain": null,
127
+ "Altitude": 60.0,
128
+ "AltitudeMode": 1,
129
+ "autoContinue": true,
130
+ "command": 16,
131
+ "doJumpId": 7,
132
+ "frame": 3,
133
+ "params": [
134
+ 1.0,
135
+ 3.0,
136
+ 0.0,
137
+ 0.0,
138
+ 16.0453211981982,
139
+ 108.20458116077056,
140
+ 60
141
+ ],
142
+ "type": "SimpleItem"
143
+ },
144
+ {
145
+ "AMSLAltAboveTerrain": null,
146
+ "Altitude": 60.0,
147
+ "AltitudeMode": 1,
148
+ "autoContinue": true,
149
+ "command": 16,
150
+ "doJumpId": 8,
151
+ "frame": 3,
152
+ "params": [
153
+ 1.0,
154
+ 3.0,
155
+ 0.0,
156
+ 0.0,
157
+ 16.0453211981982,
158
+ 108.206456,
159
+ 60
160
+ ],
161
+ "type": "SimpleItem"
162
+ },
163
+ {
164
+ "AMSLAltAboveTerrain": null,
165
+ "Altitude": 60.0,
166
+ "AltitudeMode": 1,
167
+ "autoContinue": true,
168
+ "command": 16,
169
+ "doJumpId": 9,
170
+ "frame": 3,
171
+ "params": [
172
+ 1.0,
173
+ 3.0,
174
+ 0.0,
175
+ 0.0,
176
+ 16.0453211981982,
177
+ 108.20833083922945,
178
+ 60
179
+ ],
180
+ "type": "SimpleItem"
181
+ },
182
+ {
183
+ "AMSLAltAboveTerrain": null,
184
+ "Altitude": 60.0,
185
+ "AltitudeMode": 1,
186
+ "autoContinue": true,
187
+ "command": 16,
188
+ "doJumpId": 10,
189
+ "frame": 3,
190
+ "params": [
191
+ 1.0,
192
+ 3.0,
193
+ 0.0,
194
+ 0.0,
195
+ 16.047123,
196
+ 108.20270628762569,
197
+ 60
198
+ ],
199
+ "type": "SimpleItem"
200
+ },
201
+ {
202
+ "AMSLAltAboveTerrain": null,
203
+ "Altitude": 60.0,
204
+ "AltitudeMode": 1,
205
+ "autoContinue": true,
206
+ "command": 16,
207
+ "doJumpId": 11,
208
+ "frame": 3,
209
+ "params": [
210
+ 1.0,
211
+ 3.0,
212
+ 0.0,
213
+ 0.0,
214
+ 16.047123,
215
+ 108.20458114381285,
216
+ 60
217
+ ],
218
+ "type": "SimpleItem"
219
+ },
220
+ {
221
+ "AMSLAltAboveTerrain": null,
222
+ "Altitude": 60.0,
223
+ "AltitudeMode": 1,
224
+ "autoContinue": true,
225
+ "command": 16,
226
+ "doJumpId": 12,
227
+ "frame": 3,
228
+ "params": [
229
+ 1.0,
230
+ 3.0,
231
+ 0.0,
232
+ 0.0,
233
+ 16.047123,
234
+ 108.206456,
235
+ 60
236
+ ],
237
+ "type": "SimpleItem"
238
+ },
239
+ {
240
+ "AMSLAltAboveTerrain": null,
241
+ "Altitude": 60.0,
242
+ "AltitudeMode": 1,
243
+ "autoContinue": true,
244
+ "command": 16,
245
+ "doJumpId": 13,
246
+ "frame": 3,
247
+ "params": [
248
+ 1.0,
249
+ 3.0,
250
+ 0.0,
251
+ 0.0,
252
+ 16.047123,
253
+ 108.20833085618716,
254
+ 60
255
+ ],
256
+ "type": "SimpleItem"
257
+ },
258
+ {
259
+ "AMSLAltAboveTerrain": null,
260
+ "Altitude": 60.0,
261
+ "AltitudeMode": 1,
262
+ "autoContinue": true,
263
+ "command": 16,
264
+ "doJumpId": 14,
265
+ "frame": 3,
266
+ "params": [
267
+ 1.0,
268
+ 3.0,
269
+ 0.0,
270
+ 0.0,
271
+ 16.0489248018018,
272
+ 108.20270625370593,
273
+ 60
274
+ ],
275
+ "type": "SimpleItem"
276
+ },
277
+ {
278
+ "AMSLAltAboveTerrain": null,
279
+ "Altitude": 60.0,
280
+ "AltitudeMode": 1,
281
+ "autoContinue": true,
282
+ "command": 16,
283
+ "doJumpId": 15,
284
+ "frame": 3,
285
+ "params": [
286
+ 1.0,
287
+ 3.0,
288
+ 0.0,
289
+ 0.0,
290
+ 16.0489248018018,
291
+ 108.20458112685296,
292
+ 60
293
+ ],
294
+ "type": "SimpleItem"
295
+ },
296
+ {
297
+ "AMSLAltAboveTerrain": null,
298
+ "Altitude": 60.0,
299
+ "AltitudeMode": 1,
300
+ "autoContinue": true,
301
+ "command": 16,
302
+ "doJumpId": 16,
303
+ "frame": 3,
304
+ "params": [
305
+ 1.0,
306
+ 3.0,
307
+ 0.0,
308
+ 0.0,
309
+ 16.0489248018018,
310
+ 108.206456,
311
+ 60
312
+ ],
313
+ "type": "SimpleItem"
314
+ },
315
+ {
316
+ "AMSLAltAboveTerrain": null,
317
+ "Altitude": 60.0,
318
+ "AltitudeMode": 1,
319
+ "autoContinue": true,
320
+ "command": 16,
321
+ "doJumpId": 17,
322
+ "frame": 3,
323
+ "params": [
324
+ 1.0,
325
+ 3.0,
326
+ 0.0,
327
+ 0.0,
328
+ 16.0489248018018,
329
+ 108.20833087314705,
330
+ 60
331
+ ],
332
+ "type": "SimpleItem"
333
+ },
334
+ {
335
+ "AMSLAltAboveTerrain": null,
336
+ "Altitude": 0,
337
+ "AltitudeMode": 1,
338
+ "autoContinue": true,
339
+ "command": 203,
340
+ "doJumpId": 18,
341
+ "frame": 2,
342
+ "params": [
343
+ 1,
344
+ 0,
345
+ 0,
346
+ 1,
347
+ 0,
348
+ 0,
349
+ 0
350
+ ],
351
+ "type": "SimpleItem"
352
+ },
353
+ {
354
+ "AMSLAltAboveTerrain": null,
355
+ "Altitude": 0,
356
+ "AltitudeMode": 0,
357
+ "autoContinue": true,
358
+ "command": 20,
359
+ "doJumpId": 19,
360
+ "frame": 2,
361
+ "params": [
362
+ 0.0,
363
+ 0.0,
364
+ 0.0,
365
+ 0.0,
366
+ 0,
367
+ 0,
368
+ 0
369
+ ],
370
+ "type": "SimpleItem"
371
+ }
372
+ ],
373
+ "plannedHomePosition": [
374
+ 16.047123,
375
+ 108.206456,
376
+ 8.0
377
+ ],
378
+ "vehicleType": 2,
379
+ "version": 2
380
+ },
381
+ "geoFence": {
382
+ "circles": [],
383
+ "polygons": [],
384
+ "version": 2
385
+ },
386
+ "rallyPoints": {
387
+ "points": [],
388
+ "version": 2
389
+ }
390
+ }
downloads/survey_gemini_20250822_114203.plan ADDED
@@ -0,0 +1,390 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "fileType": "Plan",
3
+ "groundStation": "DroneAgent - Survey",
4
+ "version": 1,
5
+ "mission": {
6
+ "cruiseSpeed": 15.0,
7
+ "firmwareType": 12,
8
+ "globalPlanAltitudeMode": 1,
9
+ "hoverSpeed": 9.0,
10
+ "items": [
11
+ {
12
+ "AMSLAltAboveTerrain": null,
13
+ "Altitude": 45.0,
14
+ "AltitudeMode": 1,
15
+ "autoContinue": true,
16
+ "command": 22,
17
+ "doJumpId": 1,
18
+ "frame": 3,
19
+ "params": [
20
+ 0.0,
21
+ 0.0,
22
+ 0.0,
23
+ 0.0,
24
+ 16.062008,
25
+ 108.223105,
26
+ 45.0
27
+ ],
28
+ "type": "SimpleItem"
29
+ },
30
+ {
31
+ "AMSLAltAboveTerrain": null,
32
+ "Altitude": 45.0,
33
+ "AltitudeMode": 1,
34
+ "autoContinue": true,
35
+ "command": 16,
36
+ "doJumpId": 2,
37
+ "frame": 3,
38
+ "params": [
39
+ 1.0,
40
+ 3.0,
41
+ 0.0,
42
+ 0.0,
43
+ 16.058404396396394,
44
+ 108.21935507517695,
45
+ 45
46
+ ],
47
+ "type": "SimpleItem"
48
+ },
49
+ {
50
+ "AMSLAltAboveTerrain": null,
51
+ "Altitude": 45.0,
52
+ "AltitudeMode": 1,
53
+ "autoContinue": true,
54
+ "command": 16,
55
+ "doJumpId": 3,
56
+ "frame": 3,
57
+ "params": [
58
+ 1.0,
59
+ 3.0,
60
+ 0.0,
61
+ 0.0,
62
+ 16.058404396396394,
63
+ 108.22123003758847,
64
+ 45
65
+ ],
66
+ "type": "SimpleItem"
67
+ },
68
+ {
69
+ "AMSLAltAboveTerrain": null,
70
+ "Altitude": 45.0,
71
+ "AltitudeMode": 1,
72
+ "autoContinue": true,
73
+ "command": 16,
74
+ "doJumpId": 4,
75
+ "frame": 3,
76
+ "params": [
77
+ 1.0,
78
+ 3.0,
79
+ 0.0,
80
+ 0.0,
81
+ 16.058404396396394,
82
+ 108.223105,
83
+ 45
84
+ ],
85
+ "type": "SimpleItem"
86
+ },
87
+ {
88
+ "AMSLAltAboveTerrain": null,
89
+ "Altitude": 45.0,
90
+ "AltitudeMode": 1,
91
+ "autoContinue": true,
92
+ "command": 16,
93
+ "doJumpId": 5,
94
+ "frame": 3,
95
+ "params": [
96
+ 1.0,
97
+ 3.0,
98
+ 0.0,
99
+ 0.0,
100
+ 16.058404396396394,
101
+ 108.22497996241154,
102
+ 45
103
+ ],
104
+ "type": "SimpleItem"
105
+ },
106
+ {
107
+ "AMSLAltAboveTerrain": null,
108
+ "Altitude": 45.0,
109
+ "AltitudeMode": 1,
110
+ "autoContinue": true,
111
+ "command": 16,
112
+ "doJumpId": 6,
113
+ "frame": 3,
114
+ "params": [
115
+ 1.0,
116
+ 3.0,
117
+ 0.0,
118
+ 0.0,
119
+ 16.0602061981982,
120
+ 108.21935504123013,
121
+ 45
122
+ ],
123
+ "type": "SimpleItem"
124
+ },
125
+ {
126
+ "AMSLAltAboveTerrain": null,
127
+ "Altitude": 45.0,
128
+ "AltitudeMode": 1,
129
+ "autoContinue": true,
130
+ "command": 16,
131
+ "doJumpId": 7,
132
+ "frame": 3,
133
+ "params": [
134
+ 1.0,
135
+ 3.0,
136
+ 0.0,
137
+ 0.0,
138
+ 16.0602061981982,
139
+ 108.22123002061507,
140
+ 45
141
+ ],
142
+ "type": "SimpleItem"
143
+ },
144
+ {
145
+ "AMSLAltAboveTerrain": null,
146
+ "Altitude": 45.0,
147
+ "AltitudeMode": 1,
148
+ "autoContinue": true,
149
+ "command": 16,
150
+ "doJumpId": 8,
151
+ "frame": 3,
152
+ "params": [
153
+ 1.0,
154
+ 3.0,
155
+ 0.0,
156
+ 0.0,
157
+ 16.0602061981982,
158
+ 108.223105,
159
+ 45
160
+ ],
161
+ "type": "SimpleItem"
162
+ },
163
+ {
164
+ "AMSLAltAboveTerrain": null,
165
+ "Altitude": 45.0,
166
+ "AltitudeMode": 1,
167
+ "autoContinue": true,
168
+ "command": 16,
169
+ "doJumpId": 9,
170
+ "frame": 3,
171
+ "params": [
172
+ 1.0,
173
+ 3.0,
174
+ 0.0,
175
+ 0.0,
176
+ 16.0602061981982,
177
+ 108.22497997938494,
178
+ 45
179
+ ],
180
+ "type": "SimpleItem"
181
+ },
182
+ {
183
+ "AMSLAltAboveTerrain": null,
184
+ "Altitude": 45.0,
185
+ "AltitudeMode": 1,
186
+ "autoContinue": true,
187
+ "command": 16,
188
+ "doJumpId": 10,
189
+ "frame": 3,
190
+ "params": [
191
+ 1.0,
192
+ 3.0,
193
+ 0.0,
194
+ 0.0,
195
+ 16.062008,
196
+ 108.21935500727898,
197
+ 45
198
+ ],
199
+ "type": "SimpleItem"
200
+ },
201
+ {
202
+ "AMSLAltAboveTerrain": null,
203
+ "Altitude": 45.0,
204
+ "AltitudeMode": 1,
205
+ "autoContinue": true,
206
+ "command": 16,
207
+ "doJumpId": 11,
208
+ "frame": 3,
209
+ "params": [
210
+ 1.0,
211
+ 3.0,
212
+ 0.0,
213
+ 0.0,
214
+ 16.062008,
215
+ 108.22123000363949,
216
+ 45
217
+ ],
218
+ "type": "SimpleItem"
219
+ },
220
+ {
221
+ "AMSLAltAboveTerrain": null,
222
+ "Altitude": 45.0,
223
+ "AltitudeMode": 1,
224
+ "autoContinue": true,
225
+ "command": 16,
226
+ "doJumpId": 12,
227
+ "frame": 3,
228
+ "params": [
229
+ 1.0,
230
+ 3.0,
231
+ 0.0,
232
+ 0.0,
233
+ 16.062008,
234
+ 108.223105,
235
+ 45
236
+ ],
237
+ "type": "SimpleItem"
238
+ },
239
+ {
240
+ "AMSLAltAboveTerrain": null,
241
+ "Altitude": 45.0,
242
+ "AltitudeMode": 1,
243
+ "autoContinue": true,
244
+ "command": 16,
245
+ "doJumpId": 13,
246
+ "frame": 3,
247
+ "params": [
248
+ 1.0,
249
+ 3.0,
250
+ 0.0,
251
+ 0.0,
252
+ 16.062008,
253
+ 108.22497999636052,
254
+ 45
255
+ ],
256
+ "type": "SimpleItem"
257
+ },
258
+ {
259
+ "AMSLAltAboveTerrain": null,
260
+ "Altitude": 45.0,
261
+ "AltitudeMode": 1,
262
+ "autoContinue": true,
263
+ "command": 16,
264
+ "doJumpId": 14,
265
+ "frame": 3,
266
+ "params": [
267
+ 1.0,
268
+ 3.0,
269
+ 0.0,
270
+ 0.0,
271
+ 16.0638098018018,
272
+ 108.2193549733235,
273
+ 45
274
+ ],
275
+ "type": "SimpleItem"
276
+ },
277
+ {
278
+ "AMSLAltAboveTerrain": null,
279
+ "Altitude": 45.0,
280
+ "AltitudeMode": 1,
281
+ "autoContinue": true,
282
+ "command": 16,
283
+ "doJumpId": 15,
284
+ "frame": 3,
285
+ "params": [
286
+ 1.0,
287
+ 3.0,
288
+ 0.0,
289
+ 0.0,
290
+ 16.0638098018018,
291
+ 108.22122998666175,
292
+ 45
293
+ ],
294
+ "type": "SimpleItem"
295
+ },
296
+ {
297
+ "AMSLAltAboveTerrain": null,
298
+ "Altitude": 45.0,
299
+ "AltitudeMode": 1,
300
+ "autoContinue": true,
301
+ "command": 16,
302
+ "doJumpId": 16,
303
+ "frame": 3,
304
+ "params": [
305
+ 1.0,
306
+ 3.0,
307
+ 0.0,
308
+ 0.0,
309
+ 16.0638098018018,
310
+ 108.223105,
311
+ 45
312
+ ],
313
+ "type": "SimpleItem"
314
+ },
315
+ {
316
+ "AMSLAltAboveTerrain": null,
317
+ "Altitude": 45.0,
318
+ "AltitudeMode": 1,
319
+ "autoContinue": true,
320
+ "command": 16,
321
+ "doJumpId": 17,
322
+ "frame": 3,
323
+ "params": [
324
+ 1.0,
325
+ 3.0,
326
+ 0.0,
327
+ 0.0,
328
+ 16.0638098018018,
329
+ 108.22498001333825,
330
+ 45
331
+ ],
332
+ "type": "SimpleItem"
333
+ },
334
+ {
335
+ "AMSLAltAboveTerrain": null,
336
+ "Altitude": 0,
337
+ "AltitudeMode": 1,
338
+ "autoContinue": true,
339
+ "command": 203,
340
+ "doJumpId": 18,
341
+ "frame": 2,
342
+ "params": [
343
+ 1,
344
+ 0,
345
+ 0,
346
+ 1,
347
+ 0,
348
+ 0,
349
+ 0
350
+ ],
351
+ "type": "SimpleItem"
352
+ },
353
+ {
354
+ "AMSLAltAboveTerrain": null,
355
+ "Altitude": 0,
356
+ "AltitudeMode": 0,
357
+ "autoContinue": true,
358
+ "command": 20,
359
+ "doJumpId": 19,
360
+ "frame": 2,
361
+ "params": [
362
+ 0.0,
363
+ 0.0,
364
+ 0.0,
365
+ 0.0,
366
+ 0,
367
+ 0,
368
+ 0
369
+ ],
370
+ "type": "SimpleItem"
371
+ }
372
+ ],
373
+ "plannedHomePosition": [
374
+ 16.062008,
375
+ 108.223105,
376
+ 8.0
377
+ ],
378
+ "vehicleType": 2,
379
+ "version": 2
380
+ },
381
+ "geoFence": {
382
+ "circles": [],
383
+ "polygons": [],
384
+ "version": 2
385
+ },
386
+ "rallyPoints": {
387
+ "points": [],
388
+ "version": 2
389
+ }
390
+ }
downloads/survey_local_20250822_095311.plan ADDED
@@ -0,0 +1,390 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "fileType": "Plan",
3
+ "groundStation": "DroneAgent - Survey",
4
+ "version": 1,
5
+ "mission": {
6
+ "cruiseSpeed": 15.0,
7
+ "firmwareType": 12,
8
+ "globalPlanAltitudeMode": 1,
9
+ "hoverSpeed": 9.0,
10
+ "items": [
11
+ {
12
+ "AMSLAltAboveTerrain": null,
13
+ "Altitude": 45.0,
14
+ "AltitudeMode": 1,
15
+ "autoContinue": true,
16
+ "command": 22,
17
+ "doJumpId": 1,
18
+ "frame": 3,
19
+ "params": [
20
+ 0.0,
21
+ 0.0,
22
+ 0.0,
23
+ 0.0,
24
+ 16.062007571000038,
25
+ 108.22310480100003,
26
+ 45.0
27
+ ],
28
+ "type": "SimpleItem"
29
+ },
30
+ {
31
+ "AMSLAltAboveTerrain": null,
32
+ "Altitude": 45.0,
33
+ "AltitudeMode": 1,
34
+ "autoContinue": true,
35
+ "command": 16,
36
+ "doJumpId": 2,
37
+ "frame": 3,
38
+ "params": [
39
+ 1.0,
40
+ 3.0,
41
+ 0.0,
42
+ 0.0,
43
+ 16.058403967396433,
44
+ 108.21935487618506,
45
+ 45
46
+ ],
47
+ "type": "SimpleItem"
48
+ },
49
+ {
50
+ "AMSLAltAboveTerrain": null,
51
+ "Altitude": 45.0,
52
+ "AltitudeMode": 1,
53
+ "autoContinue": true,
54
+ "command": 16,
55
+ "doJumpId": 3,
56
+ "frame": 3,
57
+ "params": [
58
+ 1.0,
59
+ 3.0,
60
+ 0.0,
61
+ 0.0,
62
+ 16.058403967396433,
63
+ 108.22122983859255,
64
+ 45
65
+ ],
66
+ "type": "SimpleItem"
67
+ },
68
+ {
69
+ "AMSLAltAboveTerrain": null,
70
+ "Altitude": 45.0,
71
+ "AltitudeMode": 1,
72
+ "autoContinue": true,
73
+ "command": 16,
74
+ "doJumpId": 4,
75
+ "frame": 3,
76
+ "params": [
77
+ 1.0,
78
+ 3.0,
79
+ 0.0,
80
+ 0.0,
81
+ 16.058403967396433,
82
+ 108.22310480100003,
83
+ 45
84
+ ],
85
+ "type": "SimpleItem"
86
+ },
87
+ {
88
+ "AMSLAltAboveTerrain": null,
89
+ "Altitude": 45.0,
90
+ "AltitudeMode": 1,
91
+ "autoContinue": true,
92
+ "command": 16,
93
+ "doJumpId": 5,
94
+ "frame": 3,
95
+ "params": [
96
+ 1.0,
97
+ 3.0,
98
+ 0.0,
99
+ 0.0,
100
+ 16.058403967396433,
101
+ 108.22497976340752,
102
+ 45
103
+ ],
104
+ "type": "SimpleItem"
105
+ },
106
+ {
107
+ "AMSLAltAboveTerrain": null,
108
+ "Altitude": 45.0,
109
+ "AltitudeMode": 1,
110
+ "autoContinue": true,
111
+ "command": 16,
112
+ "doJumpId": 6,
113
+ "frame": 3,
114
+ "params": [
115
+ 1.0,
116
+ 3.0,
117
+ 0.0,
118
+ 0.0,
119
+ 16.060205769198237,
120
+ 108.21935484223823,
121
+ 45
122
+ ],
123
+ "type": "SimpleItem"
124
+ },
125
+ {
126
+ "AMSLAltAboveTerrain": null,
127
+ "Altitude": 45.0,
128
+ "AltitudeMode": 1,
129
+ "autoContinue": true,
130
+ "command": 16,
131
+ "doJumpId": 7,
132
+ "frame": 3,
133
+ "params": [
134
+ 1.0,
135
+ 3.0,
136
+ 0.0,
137
+ 0.0,
138
+ 16.060205769198237,
139
+ 108.22122982161913,
140
+ 45
141
+ ],
142
+ "type": "SimpleItem"
143
+ },
144
+ {
145
+ "AMSLAltAboveTerrain": null,
146
+ "Altitude": 45.0,
147
+ "AltitudeMode": 1,
148
+ "autoContinue": true,
149
+ "command": 16,
150
+ "doJumpId": 8,
151
+ "frame": 3,
152
+ "params": [
153
+ 1.0,
154
+ 3.0,
155
+ 0.0,
156
+ 0.0,
157
+ 16.060205769198237,
158
+ 108.22310480100003,
159
+ 45
160
+ ],
161
+ "type": "SimpleItem"
162
+ },
163
+ {
164
+ "AMSLAltAboveTerrain": null,
165
+ "Altitude": 45.0,
166
+ "AltitudeMode": 1,
167
+ "autoContinue": true,
168
+ "command": 16,
169
+ "doJumpId": 9,
170
+ "frame": 3,
171
+ "params": [
172
+ 1.0,
173
+ 3.0,
174
+ 0.0,
175
+ 0.0,
176
+ 16.060205769198237,
177
+ 108.22497978038093,
178
+ 45
179
+ ],
180
+ "type": "SimpleItem"
181
+ },
182
+ {
183
+ "AMSLAltAboveTerrain": null,
184
+ "Altitude": 45.0,
185
+ "AltitudeMode": 1,
186
+ "autoContinue": true,
187
+ "command": 16,
188
+ "doJumpId": 10,
189
+ "frame": 3,
190
+ "params": [
191
+ 1.0,
192
+ 3.0,
193
+ 0.0,
194
+ 0.0,
195
+ 16.062007571000038,
196
+ 108.2193548082871,
197
+ 45
198
+ ],
199
+ "type": "SimpleItem"
200
+ },
201
+ {
202
+ "AMSLAltAboveTerrain": null,
203
+ "Altitude": 45.0,
204
+ "AltitudeMode": 1,
205
+ "autoContinue": true,
206
+ "command": 16,
207
+ "doJumpId": 11,
208
+ "frame": 3,
209
+ "params": [
210
+ 1.0,
211
+ 3.0,
212
+ 0.0,
213
+ 0.0,
214
+ 16.062007571000038,
215
+ 108.22122980464357,
216
+ 45
217
+ ],
218
+ "type": "SimpleItem"
219
+ },
220
+ {
221
+ "AMSLAltAboveTerrain": null,
222
+ "Altitude": 45.0,
223
+ "AltitudeMode": 1,
224
+ "autoContinue": true,
225
+ "command": 16,
226
+ "doJumpId": 12,
227
+ "frame": 3,
228
+ "params": [
229
+ 1.0,
230
+ 3.0,
231
+ 0.0,
232
+ 0.0,
233
+ 16.062007571000038,
234
+ 108.22310480100003,
235
+ 45
236
+ ],
237
+ "type": "SimpleItem"
238
+ },
239
+ {
240
+ "AMSLAltAboveTerrain": null,
241
+ "Altitude": 45.0,
242
+ "AltitudeMode": 1,
243
+ "autoContinue": true,
244
+ "command": 16,
245
+ "doJumpId": 13,
246
+ "frame": 3,
247
+ "params": [
248
+ 1.0,
249
+ 3.0,
250
+ 0.0,
251
+ 0.0,
252
+ 16.062007571000038,
253
+ 108.2249797973565,
254
+ 45
255
+ ],
256
+ "type": "SimpleItem"
257
+ },
258
+ {
259
+ "AMSLAltAboveTerrain": null,
260
+ "Altitude": 45.0,
261
+ "AltitudeMode": 1,
262
+ "autoContinue": true,
263
+ "command": 16,
264
+ "doJumpId": 14,
265
+ "frame": 3,
266
+ "params": [
267
+ 1.0,
268
+ 3.0,
269
+ 0.0,
270
+ 0.0,
271
+ 16.06380937280184,
272
+ 108.21935477433162,
273
+ 45
274
+ ],
275
+ "type": "SimpleItem"
276
+ },
277
+ {
278
+ "AMSLAltAboveTerrain": null,
279
+ "Altitude": 45.0,
280
+ "AltitudeMode": 1,
281
+ "autoContinue": true,
282
+ "command": 16,
283
+ "doJumpId": 15,
284
+ "frame": 3,
285
+ "params": [
286
+ 1.0,
287
+ 3.0,
288
+ 0.0,
289
+ 0.0,
290
+ 16.06380937280184,
291
+ 108.22122978766583,
292
+ 45
293
+ ],
294
+ "type": "SimpleItem"
295
+ },
296
+ {
297
+ "AMSLAltAboveTerrain": null,
298
+ "Altitude": 45.0,
299
+ "AltitudeMode": 1,
300
+ "autoContinue": true,
301
+ "command": 16,
302
+ "doJumpId": 16,
303
+ "frame": 3,
304
+ "params": [
305
+ 1.0,
306
+ 3.0,
307
+ 0.0,
308
+ 0.0,
309
+ 16.06380937280184,
310
+ 108.22310480100003,
311
+ 45
312
+ ],
313
+ "type": "SimpleItem"
314
+ },
315
+ {
316
+ "AMSLAltAboveTerrain": null,
317
+ "Altitude": 45.0,
318
+ "AltitudeMode": 1,
319
+ "autoContinue": true,
320
+ "command": 16,
321
+ "doJumpId": 17,
322
+ "frame": 3,
323
+ "params": [
324
+ 1.0,
325
+ 3.0,
326
+ 0.0,
327
+ 0.0,
328
+ 16.06380937280184,
329
+ 108.22497981433423,
330
+ 45
331
+ ],
332
+ "type": "SimpleItem"
333
+ },
334
+ {
335
+ "AMSLAltAboveTerrain": null,
336
+ "Altitude": 0,
337
+ "AltitudeMode": 1,
338
+ "autoContinue": true,
339
+ "command": 203,
340
+ "doJumpId": 18,
341
+ "frame": 2,
342
+ "params": [
343
+ 1,
344
+ 0,
345
+ 0,
346
+ 1,
347
+ 0,
348
+ 0,
349
+ 0
350
+ ],
351
+ "type": "SimpleItem"
352
+ },
353
+ {
354
+ "AMSLAltAboveTerrain": null,
355
+ "Altitude": 0,
356
+ "AltitudeMode": 0,
357
+ "autoContinue": true,
358
+ "command": 20,
359
+ "doJumpId": 19,
360
+ "frame": 2,
361
+ "params": [
362
+ 0.0,
363
+ 0.0,
364
+ 0.0,
365
+ 0.0,
366
+ 0,
367
+ 0,
368
+ 0
369
+ ],
370
+ "type": "SimpleItem"
371
+ }
372
+ ],
373
+ "plannedHomePosition": [
374
+ 16.062007571000038,
375
+ 108.22310480100003,
376
+ 8.0
377
+ ],
378
+ "vehicleType": 2,
379
+ "version": 2
380
+ },
381
+ "geoFence": {
382
+ "circles": [],
383
+ "polygons": [],
384
+ "version": 2
385
+ },
386
+ "rallyPoints": {
387
+ "points": [],
388
+ "version": 2
389
+ }
390
+ }
downloads/survey_local_20250822_101322.plan ADDED
@@ -0,0 +1,390 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "fileType": "Plan",
3
+ "groundStation": "DroneAgent - Survey",
4
+ "version": 1,
5
+ "mission": {
6
+ "cruiseSpeed": 15.0,
7
+ "firmwareType": 12,
8
+ "globalPlanAltitudeMode": 1,
9
+ "hoverSpeed": 9.0,
10
+ "items": [
11
+ {
12
+ "AMSLAltAboveTerrain": null,
13
+ "Altitude": 60.0,
14
+ "AltitudeMode": 1,
15
+ "autoContinue": true,
16
+ "command": 22,
17
+ "doJumpId": 1,
18
+ "frame": 3,
19
+ "params": [
20
+ 0.0,
21
+ 0.0,
22
+ 0.0,
23
+ 0.0,
24
+ 16.0747,
25
+ 108.2243,
26
+ 60.0
27
+ ],
28
+ "type": "SimpleItem"
29
+ },
30
+ {
31
+ "AMSLAltAboveTerrain": null,
32
+ "Altitude": 60.0,
33
+ "AltitudeMode": 1,
34
+ "autoContinue": true,
35
+ "command": 16,
36
+ "doJumpId": 2,
37
+ "frame": 3,
38
+ "params": [
39
+ 1.0,
40
+ 3.0,
41
+ 0.0,
42
+ 0.0,
43
+ 16.071096396396396,
44
+ 108.22054983596145,
45
+ 60
46
+ ],
47
+ "type": "SimpleItem"
48
+ },
49
+ {
50
+ "AMSLAltAboveTerrain": null,
51
+ "Altitude": 60.0,
52
+ "AltitudeMode": 1,
53
+ "autoContinue": true,
54
+ "command": 16,
55
+ "doJumpId": 3,
56
+ "frame": 3,
57
+ "params": [
58
+ 1.0,
59
+ 3.0,
60
+ 0.0,
61
+ 0.0,
62
+ 16.071096396396396,
63
+ 108.22242491798073,
64
+ 60
65
+ ],
66
+ "type": "SimpleItem"
67
+ },
68
+ {
69
+ "AMSLAltAboveTerrain": null,
70
+ "Altitude": 60.0,
71
+ "AltitudeMode": 1,
72
+ "autoContinue": true,
73
+ "command": 16,
74
+ "doJumpId": 4,
75
+ "frame": 3,
76
+ "params": [
77
+ 1.0,
78
+ 3.0,
79
+ 0.0,
80
+ 0.0,
81
+ 16.071096396396396,
82
+ 108.2243,
83
+ 60
84
+ ],
85
+ "type": "SimpleItem"
86
+ },
87
+ {
88
+ "AMSLAltAboveTerrain": null,
89
+ "Altitude": 60.0,
90
+ "AltitudeMode": 1,
91
+ "autoContinue": true,
92
+ "command": 16,
93
+ "doJumpId": 5,
94
+ "frame": 3,
95
+ "params": [
96
+ 1.0,
97
+ 3.0,
98
+ 0.0,
99
+ 0.0,
100
+ 16.071096396396396,
101
+ 108.22617508201927,
102
+ 60
103
+ ],
104
+ "type": "SimpleItem"
105
+ },
106
+ {
107
+ "AMSLAltAboveTerrain": null,
108
+ "Altitude": 60.0,
109
+ "AltitudeMode": 1,
110
+ "autoContinue": true,
111
+ "command": 16,
112
+ "doJumpId": 6,
113
+ "frame": 3,
114
+ "params": [
115
+ 1.0,
116
+ 3.0,
117
+ 0.0,
118
+ 0.0,
119
+ 16.0728981981982,
120
+ 108.22054980198418,
121
+ 60
122
+ ],
123
+ "type": "SimpleItem"
124
+ },
125
+ {
126
+ "AMSLAltAboveTerrain": null,
127
+ "Altitude": 60.0,
128
+ "AltitudeMode": 1,
129
+ "autoContinue": true,
130
+ "command": 16,
131
+ "doJumpId": 7,
132
+ "frame": 3,
133
+ "params": [
134
+ 1.0,
135
+ 3.0,
136
+ 0.0,
137
+ 0.0,
138
+ 16.0728981981982,
139
+ 108.22242490099208,
140
+ 60
141
+ ],
142
+ "type": "SimpleItem"
143
+ },
144
+ {
145
+ "AMSLAltAboveTerrain": null,
146
+ "Altitude": 60.0,
147
+ "AltitudeMode": 1,
148
+ "autoContinue": true,
149
+ "command": 16,
150
+ "doJumpId": 8,
151
+ "frame": 3,
152
+ "params": [
153
+ 1.0,
154
+ 3.0,
155
+ 0.0,
156
+ 0.0,
157
+ 16.0728981981982,
158
+ 108.2243,
159
+ 60
160
+ ],
161
+ "type": "SimpleItem"
162
+ },
163
+ {
164
+ "AMSLAltAboveTerrain": null,
165
+ "Altitude": 60.0,
166
+ "AltitudeMode": 1,
167
+ "autoContinue": true,
168
+ "command": 16,
169
+ "doJumpId": 9,
170
+ "frame": 3,
171
+ "params": [
172
+ 1.0,
173
+ 3.0,
174
+ 0.0,
175
+ 0.0,
176
+ 16.0728981981982,
177
+ 108.22617509900792,
178
+ 60
179
+ ],
180
+ "type": "SimpleItem"
181
+ },
182
+ {
183
+ "AMSLAltAboveTerrain": null,
184
+ "Altitude": 60.0,
185
+ "AltitudeMode": 1,
186
+ "autoContinue": true,
187
+ "command": 16,
188
+ "doJumpId": 10,
189
+ "frame": 3,
190
+ "params": [
191
+ 1.0,
192
+ 3.0,
193
+ 0.0,
194
+ 0.0,
195
+ 16.0747,
196
+ 108.22054976800257,
197
+ 60
198
+ ],
199
+ "type": "SimpleItem"
200
+ },
201
+ {
202
+ "AMSLAltAboveTerrain": null,
203
+ "Altitude": 60.0,
204
+ "AltitudeMode": 1,
205
+ "autoContinue": true,
206
+ "command": 16,
207
+ "doJumpId": 11,
208
+ "frame": 3,
209
+ "params": [
210
+ 1.0,
211
+ 3.0,
212
+ 0.0,
213
+ 0.0,
214
+ 16.0747,
215
+ 108.22242488400128,
216
+ 60
217
+ ],
218
+ "type": "SimpleItem"
219
+ },
220
+ {
221
+ "AMSLAltAboveTerrain": null,
222
+ "Altitude": 60.0,
223
+ "AltitudeMode": 1,
224
+ "autoContinue": true,
225
+ "command": 16,
226
+ "doJumpId": 12,
227
+ "frame": 3,
228
+ "params": [
229
+ 1.0,
230
+ 3.0,
231
+ 0.0,
232
+ 0.0,
233
+ 16.0747,
234
+ 108.2243,
235
+ 60
236
+ ],
237
+ "type": "SimpleItem"
238
+ },
239
+ {
240
+ "AMSLAltAboveTerrain": null,
241
+ "Altitude": 60.0,
242
+ "AltitudeMode": 1,
243
+ "autoContinue": true,
244
+ "command": 16,
245
+ "doJumpId": 13,
246
+ "frame": 3,
247
+ "params": [
248
+ 1.0,
249
+ 3.0,
250
+ 0.0,
251
+ 0.0,
252
+ 16.0747,
253
+ 108.22617511599871,
254
+ 60
255
+ ],
256
+ "type": "SimpleItem"
257
+ },
258
+ {
259
+ "AMSLAltAboveTerrain": null,
260
+ "Altitude": 60.0,
261
+ "AltitudeMode": 1,
262
+ "autoContinue": true,
263
+ "command": 16,
264
+ "doJumpId": 14,
265
+ "frame": 3,
266
+ "params": [
267
+ 1.0,
268
+ 3.0,
269
+ 0.0,
270
+ 0.0,
271
+ 16.0765018018018,
272
+ 108.22054973401664,
273
+ 60
274
+ ],
275
+ "type": "SimpleItem"
276
+ },
277
+ {
278
+ "AMSLAltAboveTerrain": null,
279
+ "Altitude": 60.0,
280
+ "AltitudeMode": 1,
281
+ "autoContinue": true,
282
+ "command": 16,
283
+ "doJumpId": 15,
284
+ "frame": 3,
285
+ "params": [
286
+ 1.0,
287
+ 3.0,
288
+ 0.0,
289
+ 0.0,
290
+ 16.0765018018018,
291
+ 108.22242486700831,
292
+ 60
293
+ ],
294
+ "type": "SimpleItem"
295
+ },
296
+ {
297
+ "AMSLAltAboveTerrain": null,
298
+ "Altitude": 60.0,
299
+ "AltitudeMode": 1,
300
+ "autoContinue": true,
301
+ "command": 16,
302
+ "doJumpId": 16,
303
+ "frame": 3,
304
+ "params": [
305
+ 1.0,
306
+ 3.0,
307
+ 0.0,
308
+ 0.0,
309
+ 16.0765018018018,
310
+ 108.2243,
311
+ 60
312
+ ],
313
+ "type": "SimpleItem"
314
+ },
315
+ {
316
+ "AMSLAltAboveTerrain": null,
317
+ "Altitude": 60.0,
318
+ "AltitudeMode": 1,
319
+ "autoContinue": true,
320
+ "command": 16,
321
+ "doJumpId": 17,
322
+ "frame": 3,
323
+ "params": [
324
+ 1.0,
325
+ 3.0,
326
+ 0.0,
327
+ 0.0,
328
+ 16.0765018018018,
329
+ 108.22617513299168,
330
+ 60
331
+ ],
332
+ "type": "SimpleItem"
333
+ },
334
+ {
335
+ "AMSLAltAboveTerrain": null,
336
+ "Altitude": 0,
337
+ "AltitudeMode": 1,
338
+ "autoContinue": true,
339
+ "command": 203,
340
+ "doJumpId": 18,
341
+ "frame": 2,
342
+ "params": [
343
+ 1,
344
+ 0,
345
+ 0,
346
+ 1,
347
+ 0,
348
+ 0,
349
+ 0
350
+ ],
351
+ "type": "SimpleItem"
352
+ },
353
+ {
354
+ "AMSLAltAboveTerrain": null,
355
+ "Altitude": 0,
356
+ "AltitudeMode": 0,
357
+ "autoContinue": true,
358
+ "command": 20,
359
+ "doJumpId": 19,
360
+ "frame": 2,
361
+ "params": [
362
+ 0.0,
363
+ 0.0,
364
+ 0.0,
365
+ 0.0,
366
+ 0,
367
+ 0,
368
+ 0
369
+ ],
370
+ "type": "SimpleItem"
371
+ }
372
+ ],
373
+ "plannedHomePosition": [
374
+ 16.0747,
375
+ 108.2243,
376
+ 8.0
377
+ ],
378
+ "vehicleType": 2,
379
+ "version": 2
380
+ },
381
+ "geoFence": {
382
+ "circles": [],
383
+ "polygons": [],
384
+ "version": 2
385
+ },
386
+ "rallyPoints": {
387
+ "points": [],
388
+ "version": 2
389
+ }
390
+ }
downloads/survey_local_20250822_104517.plan ADDED
@@ -0,0 +1,390 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "fileType": "Plan",
3
+ "groundStation": "DroneAgent - Survey",
4
+ "version": 1,
5
+ "mission": {
6
+ "cruiseSpeed": 15.0,
7
+ "firmwareType": 12,
8
+ "globalPlanAltitudeMode": 1,
9
+ "hoverSpeed": 9.0,
10
+ "items": [
11
+ {
12
+ "AMSLAltAboveTerrain": null,
13
+ "Altitude": 45.0,
14
+ "AltitudeMode": 1,
15
+ "autoContinue": true,
16
+ "command": 22,
17
+ "doJumpId": 1,
18
+ "frame": 3,
19
+ "params": [
20
+ 0.0,
21
+ 0.0,
22
+ 0.0,
23
+ 0.0,
24
+ 16.047123,
25
+ 108.206456,
26
+ 45.0
27
+ ],
28
+ "type": "SimpleItem"
29
+ },
30
+ {
31
+ "AMSLAltAboveTerrain": null,
32
+ "Altitude": 45.0,
33
+ "AltitudeMode": 1,
34
+ "autoContinue": true,
35
+ "command": 16,
36
+ "doJumpId": 2,
37
+ "frame": 3,
38
+ "params": [
39
+ 1.0,
40
+ 3.0,
41
+ 0.0,
42
+ 0.0,
43
+ 16.043519396396395,
44
+ 108.20270635545224,
45
+ 45
46
+ ],
47
+ "type": "SimpleItem"
48
+ },
49
+ {
50
+ "AMSLAltAboveTerrain": null,
51
+ "Altitude": 45.0,
52
+ "AltitudeMode": 1,
53
+ "autoContinue": true,
54
+ "command": 16,
55
+ "doJumpId": 3,
56
+ "frame": 3,
57
+ "params": [
58
+ 1.0,
59
+ 3.0,
60
+ 0.0,
61
+ 0.0,
62
+ 16.043519396396395,
63
+ 108.20458117772611,
64
+ 45
65
+ ],
66
+ "type": "SimpleItem"
67
+ },
68
+ {
69
+ "AMSLAltAboveTerrain": null,
70
+ "Altitude": 45.0,
71
+ "AltitudeMode": 1,
72
+ "autoContinue": true,
73
+ "command": 16,
74
+ "doJumpId": 4,
75
+ "frame": 3,
76
+ "params": [
77
+ 1.0,
78
+ 3.0,
79
+ 0.0,
80
+ 0.0,
81
+ 16.043519396396395,
82
+ 108.206456,
83
+ 45
84
+ ],
85
+ "type": "SimpleItem"
86
+ },
87
+ {
88
+ "AMSLAltAboveTerrain": null,
89
+ "Altitude": 45.0,
90
+ "AltitudeMode": 1,
91
+ "autoContinue": true,
92
+ "command": 16,
93
+ "doJumpId": 5,
94
+ "frame": 3,
95
+ "params": [
96
+ 1.0,
97
+ 3.0,
98
+ 0.0,
99
+ 0.0,
100
+ 16.043519396396395,
101
+ 108.2083308222739,
102
+ 45
103
+ ],
104
+ "type": "SimpleItem"
105
+ },
106
+ {
107
+ "AMSLAltAboveTerrain": null,
108
+ "Altitude": 45.0,
109
+ "AltitudeMode": 1,
110
+ "autoContinue": true,
111
+ "command": 16,
112
+ "doJumpId": 6,
113
+ "frame": 3,
114
+ "params": [
115
+ 1.0,
116
+ 3.0,
117
+ 0.0,
118
+ 0.0,
119
+ 16.0453211981982,
120
+ 108.20270632154111,
121
+ 45
122
+ ],
123
+ "type": "SimpleItem"
124
+ },
125
+ {
126
+ "AMSLAltAboveTerrain": null,
127
+ "Altitude": 45.0,
128
+ "AltitudeMode": 1,
129
+ "autoContinue": true,
130
+ "command": 16,
131
+ "doJumpId": 7,
132
+ "frame": 3,
133
+ "params": [
134
+ 1.0,
135
+ 3.0,
136
+ 0.0,
137
+ 0.0,
138
+ 16.0453211981982,
139
+ 108.20458116077056,
140
+ 45
141
+ ],
142
+ "type": "SimpleItem"
143
+ },
144
+ {
145
+ "AMSLAltAboveTerrain": null,
146
+ "Altitude": 45.0,
147
+ "AltitudeMode": 1,
148
+ "autoContinue": true,
149
+ "command": 16,
150
+ "doJumpId": 8,
151
+ "frame": 3,
152
+ "params": [
153
+ 1.0,
154
+ 3.0,
155
+ 0.0,
156
+ 0.0,
157
+ 16.0453211981982,
158
+ 108.206456,
159
+ 45
160
+ ],
161
+ "type": "SimpleItem"
162
+ },
163
+ {
164
+ "AMSLAltAboveTerrain": null,
165
+ "Altitude": 45.0,
166
+ "AltitudeMode": 1,
167
+ "autoContinue": true,
168
+ "command": 16,
169
+ "doJumpId": 9,
170
+ "frame": 3,
171
+ "params": [
172
+ 1.0,
173
+ 3.0,
174
+ 0.0,
175
+ 0.0,
176
+ 16.0453211981982,
177
+ 108.20833083922945,
178
+ 45
179
+ ],
180
+ "type": "SimpleItem"
181
+ },
182
+ {
183
+ "AMSLAltAboveTerrain": null,
184
+ "Altitude": 45.0,
185
+ "AltitudeMode": 1,
186
+ "autoContinue": true,
187
+ "command": 16,
188
+ "doJumpId": 10,
189
+ "frame": 3,
190
+ "params": [
191
+ 1.0,
192
+ 3.0,
193
+ 0.0,
194
+ 0.0,
195
+ 16.047123,
196
+ 108.20270628762569,
197
+ 45
198
+ ],
199
+ "type": "SimpleItem"
200
+ },
201
+ {
202
+ "AMSLAltAboveTerrain": null,
203
+ "Altitude": 45.0,
204
+ "AltitudeMode": 1,
205
+ "autoContinue": true,
206
+ "command": 16,
207
+ "doJumpId": 11,
208
+ "frame": 3,
209
+ "params": [
210
+ 1.0,
211
+ 3.0,
212
+ 0.0,
213
+ 0.0,
214
+ 16.047123,
215
+ 108.20458114381285,
216
+ 45
217
+ ],
218
+ "type": "SimpleItem"
219
+ },
220
+ {
221
+ "AMSLAltAboveTerrain": null,
222
+ "Altitude": 45.0,
223
+ "AltitudeMode": 1,
224
+ "autoContinue": true,
225
+ "command": 16,
226
+ "doJumpId": 12,
227
+ "frame": 3,
228
+ "params": [
229
+ 1.0,
230
+ 3.0,
231
+ 0.0,
232
+ 0.0,
233
+ 16.047123,
234
+ 108.206456,
235
+ 45
236
+ ],
237
+ "type": "SimpleItem"
238
+ },
239
+ {
240
+ "AMSLAltAboveTerrain": null,
241
+ "Altitude": 45.0,
242
+ "AltitudeMode": 1,
243
+ "autoContinue": true,
244
+ "command": 16,
245
+ "doJumpId": 13,
246
+ "frame": 3,
247
+ "params": [
248
+ 1.0,
249
+ 3.0,
250
+ 0.0,
251
+ 0.0,
252
+ 16.047123,
253
+ 108.20833085618716,
254
+ 45
255
+ ],
256
+ "type": "SimpleItem"
257
+ },
258
+ {
259
+ "AMSLAltAboveTerrain": null,
260
+ "Altitude": 45.0,
261
+ "AltitudeMode": 1,
262
+ "autoContinue": true,
263
+ "command": 16,
264
+ "doJumpId": 14,
265
+ "frame": 3,
266
+ "params": [
267
+ 1.0,
268
+ 3.0,
269
+ 0.0,
270
+ 0.0,
271
+ 16.0489248018018,
272
+ 108.20270625370593,
273
+ 45
274
+ ],
275
+ "type": "SimpleItem"
276
+ },
277
+ {
278
+ "AMSLAltAboveTerrain": null,
279
+ "Altitude": 45.0,
280
+ "AltitudeMode": 1,
281
+ "autoContinue": true,
282
+ "command": 16,
283
+ "doJumpId": 15,
284
+ "frame": 3,
285
+ "params": [
286
+ 1.0,
287
+ 3.0,
288
+ 0.0,
289
+ 0.0,
290
+ 16.0489248018018,
291
+ 108.20458112685296,
292
+ 45
293
+ ],
294
+ "type": "SimpleItem"
295
+ },
296
+ {
297
+ "AMSLAltAboveTerrain": null,
298
+ "Altitude": 45.0,
299
+ "AltitudeMode": 1,
300
+ "autoContinue": true,
301
+ "command": 16,
302
+ "doJumpId": 16,
303
+ "frame": 3,
304
+ "params": [
305
+ 1.0,
306
+ 3.0,
307
+ 0.0,
308
+ 0.0,
309
+ 16.0489248018018,
310
+ 108.206456,
311
+ 45
312
+ ],
313
+ "type": "SimpleItem"
314
+ },
315
+ {
316
+ "AMSLAltAboveTerrain": null,
317
+ "Altitude": 45.0,
318
+ "AltitudeMode": 1,
319
+ "autoContinue": true,
320
+ "command": 16,
321
+ "doJumpId": 17,
322
+ "frame": 3,
323
+ "params": [
324
+ 1.0,
325
+ 3.0,
326
+ 0.0,
327
+ 0.0,
328
+ 16.0489248018018,
329
+ 108.20833087314705,
330
+ 45
331
+ ],
332
+ "type": "SimpleItem"
333
+ },
334
+ {
335
+ "AMSLAltAboveTerrain": null,
336
+ "Altitude": 0,
337
+ "AltitudeMode": 1,
338
+ "autoContinue": true,
339
+ "command": 203,
340
+ "doJumpId": 18,
341
+ "frame": 2,
342
+ "params": [
343
+ 1,
344
+ 0,
345
+ 0,
346
+ 1,
347
+ 0,
348
+ 0,
349
+ 0
350
+ ],
351
+ "type": "SimpleItem"
352
+ },
353
+ {
354
+ "AMSLAltAboveTerrain": null,
355
+ "Altitude": 0,
356
+ "AltitudeMode": 0,
357
+ "autoContinue": true,
358
+ "command": 20,
359
+ "doJumpId": 19,
360
+ "frame": 2,
361
+ "params": [
362
+ 0.0,
363
+ 0.0,
364
+ 0.0,
365
+ 0.0,
366
+ 0,
367
+ 0,
368
+ 0
369
+ ],
370
+ "type": "SimpleItem"
371
+ }
372
+ ],
373
+ "plannedHomePosition": [
374
+ 16.047123,
375
+ 108.206456,
376
+ 8.0
377
+ ],
378
+ "vehicleType": 2,
379
+ "version": 2
380
+ },
381
+ "geoFence": {
382
+ "circles": [],
383
+ "polygons": [],
384
+ "version": 2
385
+ },
386
+ "rallyPoints": {
387
+ "points": [],
388
+ "version": 2
389
+ }
390
+ }
downloads/survey_local_20250822_104546.plan ADDED
@@ -0,0 +1,390 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "fileType": "Plan",
3
+ "groundStation": "DroneAgent - Survey",
4
+ "version": 1,
5
+ "mission": {
6
+ "cruiseSpeed": 15.0,
7
+ "firmwareType": 12,
8
+ "globalPlanAltitudeMode": 1,
9
+ "hoverSpeed": 9.0,
10
+ "items": [
11
+ {
12
+ "AMSLAltAboveTerrain": null,
13
+ "Altitude": 45.0,
14
+ "AltitudeMode": 1,
15
+ "autoContinue": true,
16
+ "command": 22,
17
+ "doJumpId": 1,
18
+ "frame": 3,
19
+ "params": [
20
+ 0.0,
21
+ 0.0,
22
+ 0.0,
23
+ 0.0,
24
+ 16.047123,
25
+ 108.206456,
26
+ 45.0
27
+ ],
28
+ "type": "SimpleItem"
29
+ },
30
+ {
31
+ "AMSLAltAboveTerrain": null,
32
+ "Altitude": 45.0,
33
+ "AltitudeMode": 1,
34
+ "autoContinue": true,
35
+ "command": 16,
36
+ "doJumpId": 2,
37
+ "frame": 3,
38
+ "params": [
39
+ 1.0,
40
+ 3.0,
41
+ 0.0,
42
+ 0.0,
43
+ 16.043519396396395,
44
+ 108.20270635545224,
45
+ 45
46
+ ],
47
+ "type": "SimpleItem"
48
+ },
49
+ {
50
+ "AMSLAltAboveTerrain": null,
51
+ "Altitude": 45.0,
52
+ "AltitudeMode": 1,
53
+ "autoContinue": true,
54
+ "command": 16,
55
+ "doJumpId": 3,
56
+ "frame": 3,
57
+ "params": [
58
+ 1.0,
59
+ 3.0,
60
+ 0.0,
61
+ 0.0,
62
+ 16.043519396396395,
63
+ 108.20458117772611,
64
+ 45
65
+ ],
66
+ "type": "SimpleItem"
67
+ },
68
+ {
69
+ "AMSLAltAboveTerrain": null,
70
+ "Altitude": 45.0,
71
+ "AltitudeMode": 1,
72
+ "autoContinue": true,
73
+ "command": 16,
74
+ "doJumpId": 4,
75
+ "frame": 3,
76
+ "params": [
77
+ 1.0,
78
+ 3.0,
79
+ 0.0,
80
+ 0.0,
81
+ 16.043519396396395,
82
+ 108.206456,
83
+ 45
84
+ ],
85
+ "type": "SimpleItem"
86
+ },
87
+ {
88
+ "AMSLAltAboveTerrain": null,
89
+ "Altitude": 45.0,
90
+ "AltitudeMode": 1,
91
+ "autoContinue": true,
92
+ "command": 16,
93
+ "doJumpId": 5,
94
+ "frame": 3,
95
+ "params": [
96
+ 1.0,
97
+ 3.0,
98
+ 0.0,
99
+ 0.0,
100
+ 16.043519396396395,
101
+ 108.2083308222739,
102
+ 45
103
+ ],
104
+ "type": "SimpleItem"
105
+ },
106
+ {
107
+ "AMSLAltAboveTerrain": null,
108
+ "Altitude": 45.0,
109
+ "AltitudeMode": 1,
110
+ "autoContinue": true,
111
+ "command": 16,
112
+ "doJumpId": 6,
113
+ "frame": 3,
114
+ "params": [
115
+ 1.0,
116
+ 3.0,
117
+ 0.0,
118
+ 0.0,
119
+ 16.0453211981982,
120
+ 108.20270632154111,
121
+ 45
122
+ ],
123
+ "type": "SimpleItem"
124
+ },
125
+ {
126
+ "AMSLAltAboveTerrain": null,
127
+ "Altitude": 45.0,
128
+ "AltitudeMode": 1,
129
+ "autoContinue": true,
130
+ "command": 16,
131
+ "doJumpId": 7,
132
+ "frame": 3,
133
+ "params": [
134
+ 1.0,
135
+ 3.0,
136
+ 0.0,
137
+ 0.0,
138
+ 16.0453211981982,
139
+ 108.20458116077056,
140
+ 45
141
+ ],
142
+ "type": "SimpleItem"
143
+ },
144
+ {
145
+ "AMSLAltAboveTerrain": null,
146
+ "Altitude": 45.0,
147
+ "AltitudeMode": 1,
148
+ "autoContinue": true,
149
+ "command": 16,
150
+ "doJumpId": 8,
151
+ "frame": 3,
152
+ "params": [
153
+ 1.0,
154
+ 3.0,
155
+ 0.0,
156
+ 0.0,
157
+ 16.0453211981982,
158
+ 108.206456,
159
+ 45
160
+ ],
161
+ "type": "SimpleItem"
162
+ },
163
+ {
164
+ "AMSLAltAboveTerrain": null,
165
+ "Altitude": 45.0,
166
+ "AltitudeMode": 1,
167
+ "autoContinue": true,
168
+ "command": 16,
169
+ "doJumpId": 9,
170
+ "frame": 3,
171
+ "params": [
172
+ 1.0,
173
+ 3.0,
174
+ 0.0,
175
+ 0.0,
176
+ 16.0453211981982,
177
+ 108.20833083922945,
178
+ 45
179
+ ],
180
+ "type": "SimpleItem"
181
+ },
182
+ {
183
+ "AMSLAltAboveTerrain": null,
184
+ "Altitude": 45.0,
185
+ "AltitudeMode": 1,
186
+ "autoContinue": true,
187
+ "command": 16,
188
+ "doJumpId": 10,
189
+ "frame": 3,
190
+ "params": [
191
+ 1.0,
192
+ 3.0,
193
+ 0.0,
194
+ 0.0,
195
+ 16.047123,
196
+ 108.20270628762569,
197
+ 45
198
+ ],
199
+ "type": "SimpleItem"
200
+ },
201
+ {
202
+ "AMSLAltAboveTerrain": null,
203
+ "Altitude": 45.0,
204
+ "AltitudeMode": 1,
205
+ "autoContinue": true,
206
+ "command": 16,
207
+ "doJumpId": 11,
208
+ "frame": 3,
209
+ "params": [
210
+ 1.0,
211
+ 3.0,
212
+ 0.0,
213
+ 0.0,
214
+ 16.047123,
215
+ 108.20458114381285,
216
+ 45
217
+ ],
218
+ "type": "SimpleItem"
219
+ },
220
+ {
221
+ "AMSLAltAboveTerrain": null,
222
+ "Altitude": 45.0,
223
+ "AltitudeMode": 1,
224
+ "autoContinue": true,
225
+ "command": 16,
226
+ "doJumpId": 12,
227
+ "frame": 3,
228
+ "params": [
229
+ 1.0,
230
+ 3.0,
231
+ 0.0,
232
+ 0.0,
233
+ 16.047123,
234
+ 108.206456,
235
+ 45
236
+ ],
237
+ "type": "SimpleItem"
238
+ },
239
+ {
240
+ "AMSLAltAboveTerrain": null,
241
+ "Altitude": 45.0,
242
+ "AltitudeMode": 1,
243
+ "autoContinue": true,
244
+ "command": 16,
245
+ "doJumpId": 13,
246
+ "frame": 3,
247
+ "params": [
248
+ 1.0,
249
+ 3.0,
250
+ 0.0,
251
+ 0.0,
252
+ 16.047123,
253
+ 108.20833085618716,
254
+ 45
255
+ ],
256
+ "type": "SimpleItem"
257
+ },
258
+ {
259
+ "AMSLAltAboveTerrain": null,
260
+ "Altitude": 45.0,
261
+ "AltitudeMode": 1,
262
+ "autoContinue": true,
263
+ "command": 16,
264
+ "doJumpId": 14,
265
+ "frame": 3,
266
+ "params": [
267
+ 1.0,
268
+ 3.0,
269
+ 0.0,
270
+ 0.0,
271
+ 16.0489248018018,
272
+ 108.20270625370593,
273
+ 45
274
+ ],
275
+ "type": "SimpleItem"
276
+ },
277
+ {
278
+ "AMSLAltAboveTerrain": null,
279
+ "Altitude": 45.0,
280
+ "AltitudeMode": 1,
281
+ "autoContinue": true,
282
+ "command": 16,
283
+ "doJumpId": 15,
284
+ "frame": 3,
285
+ "params": [
286
+ 1.0,
287
+ 3.0,
288
+ 0.0,
289
+ 0.0,
290
+ 16.0489248018018,
291
+ 108.20458112685296,
292
+ 45
293
+ ],
294
+ "type": "SimpleItem"
295
+ },
296
+ {
297
+ "AMSLAltAboveTerrain": null,
298
+ "Altitude": 45.0,
299
+ "AltitudeMode": 1,
300
+ "autoContinue": true,
301
+ "command": 16,
302
+ "doJumpId": 16,
303
+ "frame": 3,
304
+ "params": [
305
+ 1.0,
306
+ 3.0,
307
+ 0.0,
308
+ 0.0,
309
+ 16.0489248018018,
310
+ 108.206456,
311
+ 45
312
+ ],
313
+ "type": "SimpleItem"
314
+ },
315
+ {
316
+ "AMSLAltAboveTerrain": null,
317
+ "Altitude": 45.0,
318
+ "AltitudeMode": 1,
319
+ "autoContinue": true,
320
+ "command": 16,
321
+ "doJumpId": 17,
322
+ "frame": 3,
323
+ "params": [
324
+ 1.0,
325
+ 3.0,
326
+ 0.0,
327
+ 0.0,
328
+ 16.0489248018018,
329
+ 108.20833087314705,
330
+ 45
331
+ ],
332
+ "type": "SimpleItem"
333
+ },
334
+ {
335
+ "AMSLAltAboveTerrain": null,
336
+ "Altitude": 0,
337
+ "AltitudeMode": 1,
338
+ "autoContinue": true,
339
+ "command": 203,
340
+ "doJumpId": 18,
341
+ "frame": 2,
342
+ "params": [
343
+ 1,
344
+ 0,
345
+ 0,
346
+ 1,
347
+ 0,
348
+ 0,
349
+ 0
350
+ ],
351
+ "type": "SimpleItem"
352
+ },
353
+ {
354
+ "AMSLAltAboveTerrain": null,
355
+ "Altitude": 0,
356
+ "AltitudeMode": 0,
357
+ "autoContinue": true,
358
+ "command": 20,
359
+ "doJumpId": 19,
360
+ "frame": 2,
361
+ "params": [
362
+ 0.0,
363
+ 0.0,
364
+ 0.0,
365
+ 0.0,
366
+ 0,
367
+ 0,
368
+ 0
369
+ ],
370
+ "type": "SimpleItem"
371
+ }
372
+ ],
373
+ "plannedHomePosition": [
374
+ 16.047123,
375
+ 108.206456,
376
+ 8.0
377
+ ],
378
+ "vehicleType": 2,
379
+ "version": 2
380
+ },
381
+ "geoFence": {
382
+ "circles": [],
383
+ "polygons": [],
384
+ "version": 2
385
+ },
386
+ "rallyPoints": {
387
+ "points": [],
388
+ "version": 2
389
+ }
390
+ }
downloads/survey_local_20250822_104549.plan ADDED
@@ -0,0 +1,390 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "fileType": "Plan",
3
+ "groundStation": "DroneAgent - Survey",
4
+ "version": 1,
5
+ "mission": {
6
+ "cruiseSpeed": 15.0,
7
+ "firmwareType": 12,
8
+ "globalPlanAltitudeMode": 1,
9
+ "hoverSpeed": 9.0,
10
+ "items": [
11
+ {
12
+ "AMSLAltAboveTerrain": null,
13
+ "Altitude": 45.0,
14
+ "AltitudeMode": 1,
15
+ "autoContinue": true,
16
+ "command": 22,
17
+ "doJumpId": 1,
18
+ "frame": 3,
19
+ "params": [
20
+ 0.0,
21
+ 0.0,
22
+ 0.0,
23
+ 0.0,
24
+ 16.047123,
25
+ 108.206456,
26
+ 45.0
27
+ ],
28
+ "type": "SimpleItem"
29
+ },
30
+ {
31
+ "AMSLAltAboveTerrain": null,
32
+ "Altitude": 45.0,
33
+ "AltitudeMode": 1,
34
+ "autoContinue": true,
35
+ "command": 16,
36
+ "doJumpId": 2,
37
+ "frame": 3,
38
+ "params": [
39
+ 1.0,
40
+ 3.0,
41
+ 0.0,
42
+ 0.0,
43
+ 16.043519396396395,
44
+ 108.20270635545224,
45
+ 45
46
+ ],
47
+ "type": "SimpleItem"
48
+ },
49
+ {
50
+ "AMSLAltAboveTerrain": null,
51
+ "Altitude": 45.0,
52
+ "AltitudeMode": 1,
53
+ "autoContinue": true,
54
+ "command": 16,
55
+ "doJumpId": 3,
56
+ "frame": 3,
57
+ "params": [
58
+ 1.0,
59
+ 3.0,
60
+ 0.0,
61
+ 0.0,
62
+ 16.043519396396395,
63
+ 108.20458117772611,
64
+ 45
65
+ ],
66
+ "type": "SimpleItem"
67
+ },
68
+ {
69
+ "AMSLAltAboveTerrain": null,
70
+ "Altitude": 45.0,
71
+ "AltitudeMode": 1,
72
+ "autoContinue": true,
73
+ "command": 16,
74
+ "doJumpId": 4,
75
+ "frame": 3,
76
+ "params": [
77
+ 1.0,
78
+ 3.0,
79
+ 0.0,
80
+ 0.0,
81
+ 16.043519396396395,
82
+ 108.206456,
83
+ 45
84
+ ],
85
+ "type": "SimpleItem"
86
+ },
87
+ {
88
+ "AMSLAltAboveTerrain": null,
89
+ "Altitude": 45.0,
90
+ "AltitudeMode": 1,
91
+ "autoContinue": true,
92
+ "command": 16,
93
+ "doJumpId": 5,
94
+ "frame": 3,
95
+ "params": [
96
+ 1.0,
97
+ 3.0,
98
+ 0.0,
99
+ 0.0,
100
+ 16.043519396396395,
101
+ 108.2083308222739,
102
+ 45
103
+ ],
104
+ "type": "SimpleItem"
105
+ },
106
+ {
107
+ "AMSLAltAboveTerrain": null,
108
+ "Altitude": 45.0,
109
+ "AltitudeMode": 1,
110
+ "autoContinue": true,
111
+ "command": 16,
112
+ "doJumpId": 6,
113
+ "frame": 3,
114
+ "params": [
115
+ 1.0,
116
+ 3.0,
117
+ 0.0,
118
+ 0.0,
119
+ 16.0453211981982,
120
+ 108.20270632154111,
121
+ 45
122
+ ],
123
+ "type": "SimpleItem"
124
+ },
125
+ {
126
+ "AMSLAltAboveTerrain": null,
127
+ "Altitude": 45.0,
128
+ "AltitudeMode": 1,
129
+ "autoContinue": true,
130
+ "command": 16,
131
+ "doJumpId": 7,
132
+ "frame": 3,
133
+ "params": [
134
+ 1.0,
135
+ 3.0,
136
+ 0.0,
137
+ 0.0,
138
+ 16.0453211981982,
139
+ 108.20458116077056,
140
+ 45
141
+ ],
142
+ "type": "SimpleItem"
143
+ },
144
+ {
145
+ "AMSLAltAboveTerrain": null,
146
+ "Altitude": 45.0,
147
+ "AltitudeMode": 1,
148
+ "autoContinue": true,
149
+ "command": 16,
150
+ "doJumpId": 8,
151
+ "frame": 3,
152
+ "params": [
153
+ 1.0,
154
+ 3.0,
155
+ 0.0,
156
+ 0.0,
157
+ 16.0453211981982,
158
+ 108.206456,
159
+ 45
160
+ ],
161
+ "type": "SimpleItem"
162
+ },
163
+ {
164
+ "AMSLAltAboveTerrain": null,
165
+ "Altitude": 45.0,
166
+ "AltitudeMode": 1,
167
+ "autoContinue": true,
168
+ "command": 16,
169
+ "doJumpId": 9,
170
+ "frame": 3,
171
+ "params": [
172
+ 1.0,
173
+ 3.0,
174
+ 0.0,
175
+ 0.0,
176
+ 16.0453211981982,
177
+ 108.20833083922945,
178
+ 45
179
+ ],
180
+ "type": "SimpleItem"
181
+ },
182
+ {
183
+ "AMSLAltAboveTerrain": null,
184
+ "Altitude": 45.0,
185
+ "AltitudeMode": 1,
186
+ "autoContinue": true,
187
+ "command": 16,
188
+ "doJumpId": 10,
189
+ "frame": 3,
190
+ "params": [
191
+ 1.0,
192
+ 3.0,
193
+ 0.0,
194
+ 0.0,
195
+ 16.047123,
196
+ 108.20270628762569,
197
+ 45
198
+ ],
199
+ "type": "SimpleItem"
200
+ },
201
+ {
202
+ "AMSLAltAboveTerrain": null,
203
+ "Altitude": 45.0,
204
+ "AltitudeMode": 1,
205
+ "autoContinue": true,
206
+ "command": 16,
207
+ "doJumpId": 11,
208
+ "frame": 3,
209
+ "params": [
210
+ 1.0,
211
+ 3.0,
212
+ 0.0,
213
+ 0.0,
214
+ 16.047123,
215
+ 108.20458114381285,
216
+ 45
217
+ ],
218
+ "type": "SimpleItem"
219
+ },
220
+ {
221
+ "AMSLAltAboveTerrain": null,
222
+ "Altitude": 45.0,
223
+ "AltitudeMode": 1,
224
+ "autoContinue": true,
225
+ "command": 16,
226
+ "doJumpId": 12,
227
+ "frame": 3,
228
+ "params": [
229
+ 1.0,
230
+ 3.0,
231
+ 0.0,
232
+ 0.0,
233
+ 16.047123,
234
+ 108.206456,
235
+ 45
236
+ ],
237
+ "type": "SimpleItem"
238
+ },
239
+ {
240
+ "AMSLAltAboveTerrain": null,
241
+ "Altitude": 45.0,
242
+ "AltitudeMode": 1,
243
+ "autoContinue": true,
244
+ "command": 16,
245
+ "doJumpId": 13,
246
+ "frame": 3,
247
+ "params": [
248
+ 1.0,
249
+ 3.0,
250
+ 0.0,
251
+ 0.0,
252
+ 16.047123,
253
+ 108.20833085618716,
254
+ 45
255
+ ],
256
+ "type": "SimpleItem"
257
+ },
258
+ {
259
+ "AMSLAltAboveTerrain": null,
260
+ "Altitude": 45.0,
261
+ "AltitudeMode": 1,
262
+ "autoContinue": true,
263
+ "command": 16,
264
+ "doJumpId": 14,
265
+ "frame": 3,
266
+ "params": [
267
+ 1.0,
268
+ 3.0,
269
+ 0.0,
270
+ 0.0,
271
+ 16.0489248018018,
272
+ 108.20270625370593,
273
+ 45
274
+ ],
275
+ "type": "SimpleItem"
276
+ },
277
+ {
278
+ "AMSLAltAboveTerrain": null,
279
+ "Altitude": 45.0,
280
+ "AltitudeMode": 1,
281
+ "autoContinue": true,
282
+ "command": 16,
283
+ "doJumpId": 15,
284
+ "frame": 3,
285
+ "params": [
286
+ 1.0,
287
+ 3.0,
288
+ 0.0,
289
+ 0.0,
290
+ 16.0489248018018,
291
+ 108.20458112685296,
292
+ 45
293
+ ],
294
+ "type": "SimpleItem"
295
+ },
296
+ {
297
+ "AMSLAltAboveTerrain": null,
298
+ "Altitude": 45.0,
299
+ "AltitudeMode": 1,
300
+ "autoContinue": true,
301
+ "command": 16,
302
+ "doJumpId": 16,
303
+ "frame": 3,
304
+ "params": [
305
+ 1.0,
306
+ 3.0,
307
+ 0.0,
308
+ 0.0,
309
+ 16.0489248018018,
310
+ 108.206456,
311
+ 45
312
+ ],
313
+ "type": "SimpleItem"
314
+ },
315
+ {
316
+ "AMSLAltAboveTerrain": null,
317
+ "Altitude": 45.0,
318
+ "AltitudeMode": 1,
319
+ "autoContinue": true,
320
+ "command": 16,
321
+ "doJumpId": 17,
322
+ "frame": 3,
323
+ "params": [
324
+ 1.0,
325
+ 3.0,
326
+ 0.0,
327
+ 0.0,
328
+ 16.0489248018018,
329
+ 108.20833087314705,
330
+ 45
331
+ ],
332
+ "type": "SimpleItem"
333
+ },
334
+ {
335
+ "AMSLAltAboveTerrain": null,
336
+ "Altitude": 0,
337
+ "AltitudeMode": 1,
338
+ "autoContinue": true,
339
+ "command": 203,
340
+ "doJumpId": 18,
341
+ "frame": 2,
342
+ "params": [
343
+ 1,
344
+ 0,
345
+ 0,
346
+ 1,
347
+ 0,
348
+ 0,
349
+ 0
350
+ ],
351
+ "type": "SimpleItem"
352
+ },
353
+ {
354
+ "AMSLAltAboveTerrain": null,
355
+ "Altitude": 0,
356
+ "AltitudeMode": 0,
357
+ "autoContinue": true,
358
+ "command": 20,
359
+ "doJumpId": 19,
360
+ "frame": 2,
361
+ "params": [
362
+ 0.0,
363
+ 0.0,
364
+ 0.0,
365
+ 0.0,
366
+ 0,
367
+ 0,
368
+ 0
369
+ ],
370
+ "type": "SimpleItem"
371
+ }
372
+ ],
373
+ "plannedHomePosition": [
374
+ 16.047123,
375
+ 108.206456,
376
+ 8.0
377
+ ],
378
+ "vehicleType": 2,
379
+ "version": 2
380
+ },
381
+ "geoFence": {
382
+ "circles": [],
383
+ "polygons": [],
384
+ "version": 2
385
+ },
386
+ "rallyPoints": {
387
+ "points": [],
388
+ "version": 2
389
+ }
390
+ }
downloads/survey_local_20250822_104559.plan ADDED
@@ -0,0 +1,390 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "fileType": "Plan",
3
+ "groundStation": "DroneAgent - Survey",
4
+ "version": 1,
5
+ "mission": {
6
+ "cruiseSpeed": 15.0,
7
+ "firmwareType": 12,
8
+ "globalPlanAltitudeMode": 1,
9
+ "hoverSpeed": 9.0,
10
+ "items": [
11
+ {
12
+ "AMSLAltAboveTerrain": null,
13
+ "Altitude": 45.0,
14
+ "AltitudeMode": 1,
15
+ "autoContinue": true,
16
+ "command": 22,
17
+ "doJumpId": 1,
18
+ "frame": 3,
19
+ "params": [
20
+ 0.0,
21
+ 0.0,
22
+ 0.0,
23
+ 0.0,
24
+ 16.0472,
25
+ 108.219959,
26
+ 45.0
27
+ ],
28
+ "type": "SimpleItem"
29
+ },
30
+ {
31
+ "AMSLAltAboveTerrain": null,
32
+ "Altitude": 45.0,
33
+ "AltitudeMode": 1,
34
+ "autoContinue": true,
35
+ "command": 16,
36
+ "doJumpId": 2,
37
+ "frame": 3,
38
+ "params": [
39
+ 1.0,
40
+ 3.0,
41
+ 0.0,
42
+ 0.0,
43
+ 16.043596396396396,
44
+ 108.21620935400313,
45
+ 45
46
+ ],
47
+ "type": "SimpleItem"
48
+ },
49
+ {
50
+ "AMSLAltAboveTerrain": null,
51
+ "Altitude": 45.0,
52
+ "AltitudeMode": 1,
53
+ "autoContinue": true,
54
+ "command": 16,
55
+ "doJumpId": 3,
56
+ "frame": 3,
57
+ "params": [
58
+ 1.0,
59
+ 3.0,
60
+ 0.0,
61
+ 0.0,
62
+ 16.043596396396396,
63
+ 108.21808417700157,
64
+ 45
65
+ ],
66
+ "type": "SimpleItem"
67
+ },
68
+ {
69
+ "AMSLAltAboveTerrain": null,
70
+ "Altitude": 45.0,
71
+ "AltitudeMode": 1,
72
+ "autoContinue": true,
73
+ "command": 16,
74
+ "doJumpId": 4,
75
+ "frame": 3,
76
+ "params": [
77
+ 1.0,
78
+ 3.0,
79
+ 0.0,
80
+ 0.0,
81
+ 16.043596396396396,
82
+ 108.219959,
83
+ 45
84
+ ],
85
+ "type": "SimpleItem"
86
+ },
87
+ {
88
+ "AMSLAltAboveTerrain": null,
89
+ "Altitude": 45.0,
90
+ "AltitudeMode": 1,
91
+ "autoContinue": true,
92
+ "command": 16,
93
+ "doJumpId": 5,
94
+ "frame": 3,
95
+ "params": [
96
+ 1.0,
97
+ 3.0,
98
+ 0.0,
99
+ 0.0,
100
+ 16.043596396396396,
101
+ 108.22183382299843,
102
+ 45
103
+ ],
104
+ "type": "SimpleItem"
105
+ },
106
+ {
107
+ "AMSLAltAboveTerrain": null,
108
+ "Altitude": 45.0,
109
+ "AltitudeMode": 1,
110
+ "autoContinue": true,
111
+ "command": 16,
112
+ "doJumpId": 6,
113
+ "frame": 3,
114
+ "params": [
115
+ 1.0,
116
+ 3.0,
117
+ 0.0,
118
+ 0.0,
119
+ 16.0453981981982,
120
+ 108.21620932009183,
121
+ 45
122
+ ],
123
+ "type": "SimpleItem"
124
+ },
125
+ {
126
+ "AMSLAltAboveTerrain": null,
127
+ "Altitude": 45.0,
128
+ "AltitudeMode": 1,
129
+ "autoContinue": true,
130
+ "command": 16,
131
+ "doJumpId": 7,
132
+ "frame": 3,
133
+ "params": [
134
+ 1.0,
135
+ 3.0,
136
+ 0.0,
137
+ 0.0,
138
+ 16.0453981981982,
139
+ 108.21808416004592,
140
+ 45
141
+ ],
142
+ "type": "SimpleItem"
143
+ },
144
+ {
145
+ "AMSLAltAboveTerrain": null,
146
+ "Altitude": 45.0,
147
+ "AltitudeMode": 1,
148
+ "autoContinue": true,
149
+ "command": 16,
150
+ "doJumpId": 8,
151
+ "frame": 3,
152
+ "params": [
153
+ 1.0,
154
+ 3.0,
155
+ 0.0,
156
+ 0.0,
157
+ 16.0453981981982,
158
+ 108.219959,
159
+ 45
160
+ ],
161
+ "type": "SimpleItem"
162
+ },
163
+ {
164
+ "AMSLAltAboveTerrain": null,
165
+ "Altitude": 45.0,
166
+ "AltitudeMode": 1,
167
+ "autoContinue": true,
168
+ "command": 16,
169
+ "doJumpId": 9,
170
+ "frame": 3,
171
+ "params": [
172
+ 1.0,
173
+ 3.0,
174
+ 0.0,
175
+ 0.0,
176
+ 16.0453981981982,
177
+ 108.22183383995409,
178
+ 45
179
+ ],
180
+ "type": "SimpleItem"
181
+ },
182
+ {
183
+ "AMSLAltAboveTerrain": null,
184
+ "Altitude": 45.0,
185
+ "AltitudeMode": 1,
186
+ "autoContinue": true,
187
+ "command": 16,
188
+ "doJumpId": 10,
189
+ "frame": 3,
190
+ "params": [
191
+ 1.0,
192
+ 3.0,
193
+ 0.0,
194
+ 0.0,
195
+ 16.0472,
196
+ 108.21620928617621,
197
+ 45
198
+ ],
199
+ "type": "SimpleItem"
200
+ },
201
+ {
202
+ "AMSLAltAboveTerrain": null,
203
+ "Altitude": 45.0,
204
+ "AltitudeMode": 1,
205
+ "autoContinue": true,
206
+ "command": 16,
207
+ "doJumpId": 11,
208
+ "frame": 3,
209
+ "params": [
210
+ 1.0,
211
+ 3.0,
212
+ 0.0,
213
+ 0.0,
214
+ 16.0472,
215
+ 108.2180841430881,
216
+ 45
217
+ ],
218
+ "type": "SimpleItem"
219
+ },
220
+ {
221
+ "AMSLAltAboveTerrain": null,
222
+ "Altitude": 45.0,
223
+ "AltitudeMode": 1,
224
+ "autoContinue": true,
225
+ "command": 16,
226
+ "doJumpId": 12,
227
+ "frame": 3,
228
+ "params": [
229
+ 1.0,
230
+ 3.0,
231
+ 0.0,
232
+ 0.0,
233
+ 16.0472,
234
+ 108.219959,
235
+ 45
236
+ ],
237
+ "type": "SimpleItem"
238
+ },
239
+ {
240
+ "AMSLAltAboveTerrain": null,
241
+ "Altitude": 45.0,
242
+ "AltitudeMode": 1,
243
+ "autoContinue": true,
244
+ "command": 16,
245
+ "doJumpId": 13,
246
+ "frame": 3,
247
+ "params": [
248
+ 1.0,
249
+ 3.0,
250
+ 0.0,
251
+ 0.0,
252
+ 16.0472,
253
+ 108.2218338569119,
254
+ 45
255
+ ],
256
+ "type": "SimpleItem"
257
+ },
258
+ {
259
+ "AMSLAltAboveTerrain": null,
260
+ "Altitude": 45.0,
261
+ "AltitudeMode": 1,
262
+ "autoContinue": true,
263
+ "command": 16,
264
+ "doJumpId": 14,
265
+ "frame": 3,
266
+ "params": [
267
+ 1.0,
268
+ 3.0,
269
+ 0.0,
270
+ 0.0,
271
+ 16.0490018018018,
272
+ 108.21620925225626,
273
+ 45
274
+ ],
275
+ "type": "SimpleItem"
276
+ },
277
+ {
278
+ "AMSLAltAboveTerrain": null,
279
+ "Altitude": 45.0,
280
+ "AltitudeMode": 1,
281
+ "autoContinue": true,
282
+ "command": 16,
283
+ "doJumpId": 15,
284
+ "frame": 3,
285
+ "params": [
286
+ 1.0,
287
+ 3.0,
288
+ 0.0,
289
+ 0.0,
290
+ 16.0490018018018,
291
+ 108.21808412612813,
292
+ 45
293
+ ],
294
+ "type": "SimpleItem"
295
+ },
296
+ {
297
+ "AMSLAltAboveTerrain": null,
298
+ "Altitude": 45.0,
299
+ "AltitudeMode": 1,
300
+ "autoContinue": true,
301
+ "command": 16,
302
+ "doJumpId": 16,
303
+ "frame": 3,
304
+ "params": [
305
+ 1.0,
306
+ 3.0,
307
+ 0.0,
308
+ 0.0,
309
+ 16.0490018018018,
310
+ 108.219959,
311
+ 45
312
+ ],
313
+ "type": "SimpleItem"
314
+ },
315
+ {
316
+ "AMSLAltAboveTerrain": null,
317
+ "Altitude": 45.0,
318
+ "AltitudeMode": 1,
319
+ "autoContinue": true,
320
+ "command": 16,
321
+ "doJumpId": 17,
322
+ "frame": 3,
323
+ "params": [
324
+ 1.0,
325
+ 3.0,
326
+ 0.0,
327
+ 0.0,
328
+ 16.0490018018018,
329
+ 108.22183387387187,
330
+ 45
331
+ ],
332
+ "type": "SimpleItem"
333
+ },
334
+ {
335
+ "AMSLAltAboveTerrain": null,
336
+ "Altitude": 0,
337
+ "AltitudeMode": 1,
338
+ "autoContinue": true,
339
+ "command": 203,
340
+ "doJumpId": 18,
341
+ "frame": 2,
342
+ "params": [
343
+ 1,
344
+ 0,
345
+ 0,
346
+ 1,
347
+ 0,
348
+ 0,
349
+ 0
350
+ ],
351
+ "type": "SimpleItem"
352
+ },
353
+ {
354
+ "AMSLAltAboveTerrain": null,
355
+ "Altitude": 0,
356
+ "AltitudeMode": 0,
357
+ "autoContinue": true,
358
+ "command": 20,
359
+ "doJumpId": 19,
360
+ "frame": 2,
361
+ "params": [
362
+ 0.0,
363
+ 0.0,
364
+ 0.0,
365
+ 0.0,
366
+ 0,
367
+ 0,
368
+ 0
369
+ ],
370
+ "type": "SimpleItem"
371
+ }
372
+ ],
373
+ "plannedHomePosition": [
374
+ 16.0472,
375
+ 108.219959,
376
+ 8.0
377
+ ],
378
+ "vehicleType": 2,
379
+ "version": 2
380
+ },
381
+ "geoFence": {
382
+ "circles": [],
383
+ "polygons": [],
384
+ "version": 2
385
+ },
386
+ "rallyPoints": {
387
+ "points": [],
388
+ "version": 2
389
+ }
390
+ }
downloads/survey_local_20250822_104603.plan ADDED
@@ -0,0 +1,390 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "fileType": "Plan",
3
+ "groundStation": "DroneAgent - Survey",
4
+ "version": 1,
5
+ "mission": {
6
+ "cruiseSpeed": 15.0,
7
+ "firmwareType": 12,
8
+ "globalPlanAltitudeMode": 1,
9
+ "hoverSpeed": 9.0,
10
+ "items": [
11
+ {
12
+ "AMSLAltAboveTerrain": null,
13
+ "Altitude": 45.0,
14
+ "AltitudeMode": 1,
15
+ "autoContinue": true,
16
+ "command": 22,
17
+ "doJumpId": 1,
18
+ "frame": 3,
19
+ "params": [
20
+ 0.0,
21
+ 0.0,
22
+ 0.0,
23
+ 0.0,
24
+ 16.047123,
25
+ 108.206456,
26
+ 45.0
27
+ ],
28
+ "type": "SimpleItem"
29
+ },
30
+ {
31
+ "AMSLAltAboveTerrain": null,
32
+ "Altitude": 45.0,
33
+ "AltitudeMode": 1,
34
+ "autoContinue": true,
35
+ "command": 16,
36
+ "doJumpId": 2,
37
+ "frame": 3,
38
+ "params": [
39
+ 1.0,
40
+ 3.0,
41
+ 0.0,
42
+ 0.0,
43
+ 16.043519396396395,
44
+ 108.20270635545224,
45
+ 45
46
+ ],
47
+ "type": "SimpleItem"
48
+ },
49
+ {
50
+ "AMSLAltAboveTerrain": null,
51
+ "Altitude": 45.0,
52
+ "AltitudeMode": 1,
53
+ "autoContinue": true,
54
+ "command": 16,
55
+ "doJumpId": 3,
56
+ "frame": 3,
57
+ "params": [
58
+ 1.0,
59
+ 3.0,
60
+ 0.0,
61
+ 0.0,
62
+ 16.043519396396395,
63
+ 108.20458117772611,
64
+ 45
65
+ ],
66
+ "type": "SimpleItem"
67
+ },
68
+ {
69
+ "AMSLAltAboveTerrain": null,
70
+ "Altitude": 45.0,
71
+ "AltitudeMode": 1,
72
+ "autoContinue": true,
73
+ "command": 16,
74
+ "doJumpId": 4,
75
+ "frame": 3,
76
+ "params": [
77
+ 1.0,
78
+ 3.0,
79
+ 0.0,
80
+ 0.0,
81
+ 16.043519396396395,
82
+ 108.206456,
83
+ 45
84
+ ],
85
+ "type": "SimpleItem"
86
+ },
87
+ {
88
+ "AMSLAltAboveTerrain": null,
89
+ "Altitude": 45.0,
90
+ "AltitudeMode": 1,
91
+ "autoContinue": true,
92
+ "command": 16,
93
+ "doJumpId": 5,
94
+ "frame": 3,
95
+ "params": [
96
+ 1.0,
97
+ 3.0,
98
+ 0.0,
99
+ 0.0,
100
+ 16.043519396396395,
101
+ 108.2083308222739,
102
+ 45
103
+ ],
104
+ "type": "SimpleItem"
105
+ },
106
+ {
107
+ "AMSLAltAboveTerrain": null,
108
+ "Altitude": 45.0,
109
+ "AltitudeMode": 1,
110
+ "autoContinue": true,
111
+ "command": 16,
112
+ "doJumpId": 6,
113
+ "frame": 3,
114
+ "params": [
115
+ 1.0,
116
+ 3.0,
117
+ 0.0,
118
+ 0.0,
119
+ 16.0453211981982,
120
+ 108.20270632154111,
121
+ 45
122
+ ],
123
+ "type": "SimpleItem"
124
+ },
125
+ {
126
+ "AMSLAltAboveTerrain": null,
127
+ "Altitude": 45.0,
128
+ "AltitudeMode": 1,
129
+ "autoContinue": true,
130
+ "command": 16,
131
+ "doJumpId": 7,
132
+ "frame": 3,
133
+ "params": [
134
+ 1.0,
135
+ 3.0,
136
+ 0.0,
137
+ 0.0,
138
+ 16.0453211981982,
139
+ 108.20458116077056,
140
+ 45
141
+ ],
142
+ "type": "SimpleItem"
143
+ },
144
+ {
145
+ "AMSLAltAboveTerrain": null,
146
+ "Altitude": 45.0,
147
+ "AltitudeMode": 1,
148
+ "autoContinue": true,
149
+ "command": 16,
150
+ "doJumpId": 8,
151
+ "frame": 3,
152
+ "params": [
153
+ 1.0,
154
+ 3.0,
155
+ 0.0,
156
+ 0.0,
157
+ 16.0453211981982,
158
+ 108.206456,
159
+ 45
160
+ ],
161
+ "type": "SimpleItem"
162
+ },
163
+ {
164
+ "AMSLAltAboveTerrain": null,
165
+ "Altitude": 45.0,
166
+ "AltitudeMode": 1,
167
+ "autoContinue": true,
168
+ "command": 16,
169
+ "doJumpId": 9,
170
+ "frame": 3,
171
+ "params": [
172
+ 1.0,
173
+ 3.0,
174
+ 0.0,
175
+ 0.0,
176
+ 16.0453211981982,
177
+ 108.20833083922945,
178
+ 45
179
+ ],
180
+ "type": "SimpleItem"
181
+ },
182
+ {
183
+ "AMSLAltAboveTerrain": null,
184
+ "Altitude": 45.0,
185
+ "AltitudeMode": 1,
186
+ "autoContinue": true,
187
+ "command": 16,
188
+ "doJumpId": 10,
189
+ "frame": 3,
190
+ "params": [
191
+ 1.0,
192
+ 3.0,
193
+ 0.0,
194
+ 0.0,
195
+ 16.047123,
196
+ 108.20270628762569,
197
+ 45
198
+ ],
199
+ "type": "SimpleItem"
200
+ },
201
+ {
202
+ "AMSLAltAboveTerrain": null,
203
+ "Altitude": 45.0,
204
+ "AltitudeMode": 1,
205
+ "autoContinue": true,
206
+ "command": 16,
207
+ "doJumpId": 11,
208
+ "frame": 3,
209
+ "params": [
210
+ 1.0,
211
+ 3.0,
212
+ 0.0,
213
+ 0.0,
214
+ 16.047123,
215
+ 108.20458114381285,
216
+ 45
217
+ ],
218
+ "type": "SimpleItem"
219
+ },
220
+ {
221
+ "AMSLAltAboveTerrain": null,
222
+ "Altitude": 45.0,
223
+ "AltitudeMode": 1,
224
+ "autoContinue": true,
225
+ "command": 16,
226
+ "doJumpId": 12,
227
+ "frame": 3,
228
+ "params": [
229
+ 1.0,
230
+ 3.0,
231
+ 0.0,
232
+ 0.0,
233
+ 16.047123,
234
+ 108.206456,
235
+ 45
236
+ ],
237
+ "type": "SimpleItem"
238
+ },
239
+ {
240
+ "AMSLAltAboveTerrain": null,
241
+ "Altitude": 45.0,
242
+ "AltitudeMode": 1,
243
+ "autoContinue": true,
244
+ "command": 16,
245
+ "doJumpId": 13,
246
+ "frame": 3,
247
+ "params": [
248
+ 1.0,
249
+ 3.0,
250
+ 0.0,
251
+ 0.0,
252
+ 16.047123,
253
+ 108.20833085618716,
254
+ 45
255
+ ],
256
+ "type": "SimpleItem"
257
+ },
258
+ {
259
+ "AMSLAltAboveTerrain": null,
260
+ "Altitude": 45.0,
261
+ "AltitudeMode": 1,
262
+ "autoContinue": true,
263
+ "command": 16,
264
+ "doJumpId": 14,
265
+ "frame": 3,
266
+ "params": [
267
+ 1.0,
268
+ 3.0,
269
+ 0.0,
270
+ 0.0,
271
+ 16.0489248018018,
272
+ 108.20270625370593,
273
+ 45
274
+ ],
275
+ "type": "SimpleItem"
276
+ },
277
+ {
278
+ "AMSLAltAboveTerrain": null,
279
+ "Altitude": 45.0,
280
+ "AltitudeMode": 1,
281
+ "autoContinue": true,
282
+ "command": 16,
283
+ "doJumpId": 15,
284
+ "frame": 3,
285
+ "params": [
286
+ 1.0,
287
+ 3.0,
288
+ 0.0,
289
+ 0.0,
290
+ 16.0489248018018,
291
+ 108.20458112685296,
292
+ 45
293
+ ],
294
+ "type": "SimpleItem"
295
+ },
296
+ {
297
+ "AMSLAltAboveTerrain": null,
298
+ "Altitude": 45.0,
299
+ "AltitudeMode": 1,
300
+ "autoContinue": true,
301
+ "command": 16,
302
+ "doJumpId": 16,
303
+ "frame": 3,
304
+ "params": [
305
+ 1.0,
306
+ 3.0,
307
+ 0.0,
308
+ 0.0,
309
+ 16.0489248018018,
310
+ 108.206456,
311
+ 45
312
+ ],
313
+ "type": "SimpleItem"
314
+ },
315
+ {
316
+ "AMSLAltAboveTerrain": null,
317
+ "Altitude": 45.0,
318
+ "AltitudeMode": 1,
319
+ "autoContinue": true,
320
+ "command": 16,
321
+ "doJumpId": 17,
322
+ "frame": 3,
323
+ "params": [
324
+ 1.0,
325
+ 3.0,
326
+ 0.0,
327
+ 0.0,
328
+ 16.0489248018018,
329
+ 108.20833087314705,
330
+ 45
331
+ ],
332
+ "type": "SimpleItem"
333
+ },
334
+ {
335
+ "AMSLAltAboveTerrain": null,
336
+ "Altitude": 0,
337
+ "AltitudeMode": 1,
338
+ "autoContinue": true,
339
+ "command": 203,
340
+ "doJumpId": 18,
341
+ "frame": 2,
342
+ "params": [
343
+ 1,
344
+ 0,
345
+ 0,
346
+ 1,
347
+ 0,
348
+ 0,
349
+ 0
350
+ ],
351
+ "type": "SimpleItem"
352
+ },
353
+ {
354
+ "AMSLAltAboveTerrain": null,
355
+ "Altitude": 0,
356
+ "AltitudeMode": 0,
357
+ "autoContinue": true,
358
+ "command": 20,
359
+ "doJumpId": 19,
360
+ "frame": 2,
361
+ "params": [
362
+ 0.0,
363
+ 0.0,
364
+ 0.0,
365
+ 0.0,
366
+ 0,
367
+ 0,
368
+ 0
369
+ ],
370
+ "type": "SimpleItem"
371
+ }
372
+ ],
373
+ "plannedHomePosition": [
374
+ 16.047123,
375
+ 108.206456,
376
+ 8.0
377
+ ],
378
+ "vehicleType": 2,
379
+ "version": 2
380
+ },
381
+ "geoFence": {
382
+ "circles": [],
383
+ "polygons": [],
384
+ "version": 2
385
+ },
386
+ "rallyPoints": {
387
+ "points": [],
388
+ "version": 2
389
+ }
390
+ }
downloads/survey_local_20250822_112511.plan ADDED
@@ -0,0 +1,390 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "fileType": "Plan",
3
+ "groundStation": "DroneAgent - Survey",
4
+ "version": 1,
5
+ "mission": {
6
+ "cruiseSpeed": 15.0,
7
+ "firmwareType": 12,
8
+ "globalPlanAltitudeMode": 1,
9
+ "hoverSpeed": 9.0,
10
+ "items": [
11
+ {
12
+ "AMSLAltAboveTerrain": null,
13
+ "Altitude": 45.0,
14
+ "AltitudeMode": 1,
15
+ "autoContinue": true,
16
+ "command": 22,
17
+ "doJumpId": 1,
18
+ "frame": 3,
19
+ "params": [
20
+ 0.0,
21
+ 0.0,
22
+ 0.0,
23
+ 0.0,
24
+ 16.047123,
25
+ 108.206456,
26
+ 45.0
27
+ ],
28
+ "type": "SimpleItem"
29
+ },
30
+ {
31
+ "AMSLAltAboveTerrain": null,
32
+ "Altitude": 45.0,
33
+ "AltitudeMode": 1,
34
+ "autoContinue": true,
35
+ "command": 16,
36
+ "doJumpId": 2,
37
+ "frame": 3,
38
+ "params": [
39
+ 1.0,
40
+ 3.0,
41
+ 0.0,
42
+ 0.0,
43
+ 16.043519396396395,
44
+ 108.20270635545224,
45
+ 45
46
+ ],
47
+ "type": "SimpleItem"
48
+ },
49
+ {
50
+ "AMSLAltAboveTerrain": null,
51
+ "Altitude": 45.0,
52
+ "AltitudeMode": 1,
53
+ "autoContinue": true,
54
+ "command": 16,
55
+ "doJumpId": 3,
56
+ "frame": 3,
57
+ "params": [
58
+ 1.0,
59
+ 3.0,
60
+ 0.0,
61
+ 0.0,
62
+ 16.043519396396395,
63
+ 108.20458117772611,
64
+ 45
65
+ ],
66
+ "type": "SimpleItem"
67
+ },
68
+ {
69
+ "AMSLAltAboveTerrain": null,
70
+ "Altitude": 45.0,
71
+ "AltitudeMode": 1,
72
+ "autoContinue": true,
73
+ "command": 16,
74
+ "doJumpId": 4,
75
+ "frame": 3,
76
+ "params": [
77
+ 1.0,
78
+ 3.0,
79
+ 0.0,
80
+ 0.0,
81
+ 16.043519396396395,
82
+ 108.206456,
83
+ 45
84
+ ],
85
+ "type": "SimpleItem"
86
+ },
87
+ {
88
+ "AMSLAltAboveTerrain": null,
89
+ "Altitude": 45.0,
90
+ "AltitudeMode": 1,
91
+ "autoContinue": true,
92
+ "command": 16,
93
+ "doJumpId": 5,
94
+ "frame": 3,
95
+ "params": [
96
+ 1.0,
97
+ 3.0,
98
+ 0.0,
99
+ 0.0,
100
+ 16.043519396396395,
101
+ 108.2083308222739,
102
+ 45
103
+ ],
104
+ "type": "SimpleItem"
105
+ },
106
+ {
107
+ "AMSLAltAboveTerrain": null,
108
+ "Altitude": 45.0,
109
+ "AltitudeMode": 1,
110
+ "autoContinue": true,
111
+ "command": 16,
112
+ "doJumpId": 6,
113
+ "frame": 3,
114
+ "params": [
115
+ 1.0,
116
+ 3.0,
117
+ 0.0,
118
+ 0.0,
119
+ 16.0453211981982,
120
+ 108.20270632154111,
121
+ 45
122
+ ],
123
+ "type": "SimpleItem"
124
+ },
125
+ {
126
+ "AMSLAltAboveTerrain": null,
127
+ "Altitude": 45.0,
128
+ "AltitudeMode": 1,
129
+ "autoContinue": true,
130
+ "command": 16,
131
+ "doJumpId": 7,
132
+ "frame": 3,
133
+ "params": [
134
+ 1.0,
135
+ 3.0,
136
+ 0.0,
137
+ 0.0,
138
+ 16.0453211981982,
139
+ 108.20458116077056,
140
+ 45
141
+ ],
142
+ "type": "SimpleItem"
143
+ },
144
+ {
145
+ "AMSLAltAboveTerrain": null,
146
+ "Altitude": 45.0,
147
+ "AltitudeMode": 1,
148
+ "autoContinue": true,
149
+ "command": 16,
150
+ "doJumpId": 8,
151
+ "frame": 3,
152
+ "params": [
153
+ 1.0,
154
+ 3.0,
155
+ 0.0,
156
+ 0.0,
157
+ 16.0453211981982,
158
+ 108.206456,
159
+ 45
160
+ ],
161
+ "type": "SimpleItem"
162
+ },
163
+ {
164
+ "AMSLAltAboveTerrain": null,
165
+ "Altitude": 45.0,
166
+ "AltitudeMode": 1,
167
+ "autoContinue": true,
168
+ "command": 16,
169
+ "doJumpId": 9,
170
+ "frame": 3,
171
+ "params": [
172
+ 1.0,
173
+ 3.0,
174
+ 0.0,
175
+ 0.0,
176
+ 16.0453211981982,
177
+ 108.20833083922945,
178
+ 45
179
+ ],
180
+ "type": "SimpleItem"
181
+ },
182
+ {
183
+ "AMSLAltAboveTerrain": null,
184
+ "Altitude": 45.0,
185
+ "AltitudeMode": 1,
186
+ "autoContinue": true,
187
+ "command": 16,
188
+ "doJumpId": 10,
189
+ "frame": 3,
190
+ "params": [
191
+ 1.0,
192
+ 3.0,
193
+ 0.0,
194
+ 0.0,
195
+ 16.047123,
196
+ 108.20270628762569,
197
+ 45
198
+ ],
199
+ "type": "SimpleItem"
200
+ },
201
+ {
202
+ "AMSLAltAboveTerrain": null,
203
+ "Altitude": 45.0,
204
+ "AltitudeMode": 1,
205
+ "autoContinue": true,
206
+ "command": 16,
207
+ "doJumpId": 11,
208
+ "frame": 3,
209
+ "params": [
210
+ 1.0,
211
+ 3.0,
212
+ 0.0,
213
+ 0.0,
214
+ 16.047123,
215
+ 108.20458114381285,
216
+ 45
217
+ ],
218
+ "type": "SimpleItem"
219
+ },
220
+ {
221
+ "AMSLAltAboveTerrain": null,
222
+ "Altitude": 45.0,
223
+ "AltitudeMode": 1,
224
+ "autoContinue": true,
225
+ "command": 16,
226
+ "doJumpId": 12,
227
+ "frame": 3,
228
+ "params": [
229
+ 1.0,
230
+ 3.0,
231
+ 0.0,
232
+ 0.0,
233
+ 16.047123,
234
+ 108.206456,
235
+ 45
236
+ ],
237
+ "type": "SimpleItem"
238
+ },
239
+ {
240
+ "AMSLAltAboveTerrain": null,
241
+ "Altitude": 45.0,
242
+ "AltitudeMode": 1,
243
+ "autoContinue": true,
244
+ "command": 16,
245
+ "doJumpId": 13,
246
+ "frame": 3,
247
+ "params": [
248
+ 1.0,
249
+ 3.0,
250
+ 0.0,
251
+ 0.0,
252
+ 16.047123,
253
+ 108.20833085618716,
254
+ 45
255
+ ],
256
+ "type": "SimpleItem"
257
+ },
258
+ {
259
+ "AMSLAltAboveTerrain": null,
260
+ "Altitude": 45.0,
261
+ "AltitudeMode": 1,
262
+ "autoContinue": true,
263
+ "command": 16,
264
+ "doJumpId": 14,
265
+ "frame": 3,
266
+ "params": [
267
+ 1.0,
268
+ 3.0,
269
+ 0.0,
270
+ 0.0,
271
+ 16.0489248018018,
272
+ 108.20270625370593,
273
+ 45
274
+ ],
275
+ "type": "SimpleItem"
276
+ },
277
+ {
278
+ "AMSLAltAboveTerrain": null,
279
+ "Altitude": 45.0,
280
+ "AltitudeMode": 1,
281
+ "autoContinue": true,
282
+ "command": 16,
283
+ "doJumpId": 15,
284
+ "frame": 3,
285
+ "params": [
286
+ 1.0,
287
+ 3.0,
288
+ 0.0,
289
+ 0.0,
290
+ 16.0489248018018,
291
+ 108.20458112685296,
292
+ 45
293
+ ],
294
+ "type": "SimpleItem"
295
+ },
296
+ {
297
+ "AMSLAltAboveTerrain": null,
298
+ "Altitude": 45.0,
299
+ "AltitudeMode": 1,
300
+ "autoContinue": true,
301
+ "command": 16,
302
+ "doJumpId": 16,
303
+ "frame": 3,
304
+ "params": [
305
+ 1.0,
306
+ 3.0,
307
+ 0.0,
308
+ 0.0,
309
+ 16.0489248018018,
310
+ 108.206456,
311
+ 45
312
+ ],
313
+ "type": "SimpleItem"
314
+ },
315
+ {
316
+ "AMSLAltAboveTerrain": null,
317
+ "Altitude": 45.0,
318
+ "AltitudeMode": 1,
319
+ "autoContinue": true,
320
+ "command": 16,
321
+ "doJumpId": 17,
322
+ "frame": 3,
323
+ "params": [
324
+ 1.0,
325
+ 3.0,
326
+ 0.0,
327
+ 0.0,
328
+ 16.0489248018018,
329
+ 108.20833087314705,
330
+ 45
331
+ ],
332
+ "type": "SimpleItem"
333
+ },
334
+ {
335
+ "AMSLAltAboveTerrain": null,
336
+ "Altitude": 0,
337
+ "AltitudeMode": 1,
338
+ "autoContinue": true,
339
+ "command": 203,
340
+ "doJumpId": 18,
341
+ "frame": 2,
342
+ "params": [
343
+ 1,
344
+ 0,
345
+ 0,
346
+ 1,
347
+ 0,
348
+ 0,
349
+ 0
350
+ ],
351
+ "type": "SimpleItem"
352
+ },
353
+ {
354
+ "AMSLAltAboveTerrain": null,
355
+ "Altitude": 0,
356
+ "AltitudeMode": 0,
357
+ "autoContinue": true,
358
+ "command": 20,
359
+ "doJumpId": 19,
360
+ "frame": 2,
361
+ "params": [
362
+ 0.0,
363
+ 0.0,
364
+ 0.0,
365
+ 0.0,
366
+ 0,
367
+ 0,
368
+ 0
369
+ ],
370
+ "type": "SimpleItem"
371
+ }
372
+ ],
373
+ "plannedHomePosition": [
374
+ 16.047123,
375
+ 108.206456,
376
+ 8.0
377
+ ],
378
+ "vehicleType": 2,
379
+ "version": 2
380
+ },
381
+ "geoFence": {
382
+ "circles": [],
383
+ "polygons": [],
384
+ "version": 2
385
+ },
386
+ "rallyPoints": {
387
+ "points": [],
388
+ "version": 2
389
+ }
390
+ }
downloads/survey_local_20250822_112601.plan ADDED
@@ -0,0 +1,390 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "fileType": "Plan",
3
+ "groundStation": "DroneAgent - Survey",
4
+ "version": 1,
5
+ "mission": {
6
+ "cruiseSpeed": 15.0,
7
+ "firmwareType": 12,
8
+ "globalPlanAltitudeMode": 1,
9
+ "hoverSpeed": 9.0,
10
+ "items": [
11
+ {
12
+ "AMSLAltAboveTerrain": null,
13
+ "Altitude": 45.0,
14
+ "AltitudeMode": 1,
15
+ "autoContinue": true,
16
+ "command": 22,
17
+ "doJumpId": 1,
18
+ "frame": 3,
19
+ "params": [
20
+ 0.0,
21
+ 0.0,
22
+ 0.0,
23
+ 0.0,
24
+ 16.047123,
25
+ 108.206456,
26
+ 45.0
27
+ ],
28
+ "type": "SimpleItem"
29
+ },
30
+ {
31
+ "AMSLAltAboveTerrain": null,
32
+ "Altitude": 45.0,
33
+ "AltitudeMode": 1,
34
+ "autoContinue": true,
35
+ "command": 16,
36
+ "doJumpId": 2,
37
+ "frame": 3,
38
+ "params": [
39
+ 1.0,
40
+ 3.0,
41
+ 0.0,
42
+ 0.0,
43
+ 16.043519396396395,
44
+ 108.20270635545224,
45
+ 45
46
+ ],
47
+ "type": "SimpleItem"
48
+ },
49
+ {
50
+ "AMSLAltAboveTerrain": null,
51
+ "Altitude": 45.0,
52
+ "AltitudeMode": 1,
53
+ "autoContinue": true,
54
+ "command": 16,
55
+ "doJumpId": 3,
56
+ "frame": 3,
57
+ "params": [
58
+ 1.0,
59
+ 3.0,
60
+ 0.0,
61
+ 0.0,
62
+ 16.043519396396395,
63
+ 108.20458117772611,
64
+ 45
65
+ ],
66
+ "type": "SimpleItem"
67
+ },
68
+ {
69
+ "AMSLAltAboveTerrain": null,
70
+ "Altitude": 45.0,
71
+ "AltitudeMode": 1,
72
+ "autoContinue": true,
73
+ "command": 16,
74
+ "doJumpId": 4,
75
+ "frame": 3,
76
+ "params": [
77
+ 1.0,
78
+ 3.0,
79
+ 0.0,
80
+ 0.0,
81
+ 16.043519396396395,
82
+ 108.206456,
83
+ 45
84
+ ],
85
+ "type": "SimpleItem"
86
+ },
87
+ {
88
+ "AMSLAltAboveTerrain": null,
89
+ "Altitude": 45.0,
90
+ "AltitudeMode": 1,
91
+ "autoContinue": true,
92
+ "command": 16,
93
+ "doJumpId": 5,
94
+ "frame": 3,
95
+ "params": [
96
+ 1.0,
97
+ 3.0,
98
+ 0.0,
99
+ 0.0,
100
+ 16.043519396396395,
101
+ 108.2083308222739,
102
+ 45
103
+ ],
104
+ "type": "SimpleItem"
105
+ },
106
+ {
107
+ "AMSLAltAboveTerrain": null,
108
+ "Altitude": 45.0,
109
+ "AltitudeMode": 1,
110
+ "autoContinue": true,
111
+ "command": 16,
112
+ "doJumpId": 6,
113
+ "frame": 3,
114
+ "params": [
115
+ 1.0,
116
+ 3.0,
117
+ 0.0,
118
+ 0.0,
119
+ 16.0453211981982,
120
+ 108.20270632154111,
121
+ 45
122
+ ],
123
+ "type": "SimpleItem"
124
+ },
125
+ {
126
+ "AMSLAltAboveTerrain": null,
127
+ "Altitude": 45.0,
128
+ "AltitudeMode": 1,
129
+ "autoContinue": true,
130
+ "command": 16,
131
+ "doJumpId": 7,
132
+ "frame": 3,
133
+ "params": [
134
+ 1.0,
135
+ 3.0,
136
+ 0.0,
137
+ 0.0,
138
+ 16.0453211981982,
139
+ 108.20458116077056,
140
+ 45
141
+ ],
142
+ "type": "SimpleItem"
143
+ },
144
+ {
145
+ "AMSLAltAboveTerrain": null,
146
+ "Altitude": 45.0,
147
+ "AltitudeMode": 1,
148
+ "autoContinue": true,
149
+ "command": 16,
150
+ "doJumpId": 8,
151
+ "frame": 3,
152
+ "params": [
153
+ 1.0,
154
+ 3.0,
155
+ 0.0,
156
+ 0.0,
157
+ 16.0453211981982,
158
+ 108.206456,
159
+ 45
160
+ ],
161
+ "type": "SimpleItem"
162
+ },
163
+ {
164
+ "AMSLAltAboveTerrain": null,
165
+ "Altitude": 45.0,
166
+ "AltitudeMode": 1,
167
+ "autoContinue": true,
168
+ "command": 16,
169
+ "doJumpId": 9,
170
+ "frame": 3,
171
+ "params": [
172
+ 1.0,
173
+ 3.0,
174
+ 0.0,
175
+ 0.0,
176
+ 16.0453211981982,
177
+ 108.20833083922945,
178
+ 45
179
+ ],
180
+ "type": "SimpleItem"
181
+ },
182
+ {
183
+ "AMSLAltAboveTerrain": null,
184
+ "Altitude": 45.0,
185
+ "AltitudeMode": 1,
186
+ "autoContinue": true,
187
+ "command": 16,
188
+ "doJumpId": 10,
189
+ "frame": 3,
190
+ "params": [
191
+ 1.0,
192
+ 3.0,
193
+ 0.0,
194
+ 0.0,
195
+ 16.047123,
196
+ 108.20270628762569,
197
+ 45
198
+ ],
199
+ "type": "SimpleItem"
200
+ },
201
+ {
202
+ "AMSLAltAboveTerrain": null,
203
+ "Altitude": 45.0,
204
+ "AltitudeMode": 1,
205
+ "autoContinue": true,
206
+ "command": 16,
207
+ "doJumpId": 11,
208
+ "frame": 3,
209
+ "params": [
210
+ 1.0,
211
+ 3.0,
212
+ 0.0,
213
+ 0.0,
214
+ 16.047123,
215
+ 108.20458114381285,
216
+ 45
217
+ ],
218
+ "type": "SimpleItem"
219
+ },
220
+ {
221
+ "AMSLAltAboveTerrain": null,
222
+ "Altitude": 45.0,
223
+ "AltitudeMode": 1,
224
+ "autoContinue": true,
225
+ "command": 16,
226
+ "doJumpId": 12,
227
+ "frame": 3,
228
+ "params": [
229
+ 1.0,
230
+ 3.0,
231
+ 0.0,
232
+ 0.0,
233
+ 16.047123,
234
+ 108.206456,
235
+ 45
236
+ ],
237
+ "type": "SimpleItem"
238
+ },
239
+ {
240
+ "AMSLAltAboveTerrain": null,
241
+ "Altitude": 45.0,
242
+ "AltitudeMode": 1,
243
+ "autoContinue": true,
244
+ "command": 16,
245
+ "doJumpId": 13,
246
+ "frame": 3,
247
+ "params": [
248
+ 1.0,
249
+ 3.0,
250
+ 0.0,
251
+ 0.0,
252
+ 16.047123,
253
+ 108.20833085618716,
254
+ 45
255
+ ],
256
+ "type": "SimpleItem"
257
+ },
258
+ {
259
+ "AMSLAltAboveTerrain": null,
260
+ "Altitude": 45.0,
261
+ "AltitudeMode": 1,
262
+ "autoContinue": true,
263
+ "command": 16,
264
+ "doJumpId": 14,
265
+ "frame": 3,
266
+ "params": [
267
+ 1.0,
268
+ 3.0,
269
+ 0.0,
270
+ 0.0,
271
+ 16.0489248018018,
272
+ 108.20270625370593,
273
+ 45
274
+ ],
275
+ "type": "SimpleItem"
276
+ },
277
+ {
278
+ "AMSLAltAboveTerrain": null,
279
+ "Altitude": 45.0,
280
+ "AltitudeMode": 1,
281
+ "autoContinue": true,
282
+ "command": 16,
283
+ "doJumpId": 15,
284
+ "frame": 3,
285
+ "params": [
286
+ 1.0,
287
+ 3.0,
288
+ 0.0,
289
+ 0.0,
290
+ 16.0489248018018,
291
+ 108.20458112685296,
292
+ 45
293
+ ],
294
+ "type": "SimpleItem"
295
+ },
296
+ {
297
+ "AMSLAltAboveTerrain": null,
298
+ "Altitude": 45.0,
299
+ "AltitudeMode": 1,
300
+ "autoContinue": true,
301
+ "command": 16,
302
+ "doJumpId": 16,
303
+ "frame": 3,
304
+ "params": [
305
+ 1.0,
306
+ 3.0,
307
+ 0.0,
308
+ 0.0,
309
+ 16.0489248018018,
310
+ 108.206456,
311
+ 45
312
+ ],
313
+ "type": "SimpleItem"
314
+ },
315
+ {
316
+ "AMSLAltAboveTerrain": null,
317
+ "Altitude": 45.0,
318
+ "AltitudeMode": 1,
319
+ "autoContinue": true,
320
+ "command": 16,
321
+ "doJumpId": 17,
322
+ "frame": 3,
323
+ "params": [
324
+ 1.0,
325
+ 3.0,
326
+ 0.0,
327
+ 0.0,
328
+ 16.0489248018018,
329
+ 108.20833087314705,
330
+ 45
331
+ ],
332
+ "type": "SimpleItem"
333
+ },
334
+ {
335
+ "AMSLAltAboveTerrain": null,
336
+ "Altitude": 0,
337
+ "AltitudeMode": 1,
338
+ "autoContinue": true,
339
+ "command": 203,
340
+ "doJumpId": 18,
341
+ "frame": 2,
342
+ "params": [
343
+ 1,
344
+ 0,
345
+ 0,
346
+ 1,
347
+ 0,
348
+ 0,
349
+ 0
350
+ ],
351
+ "type": "SimpleItem"
352
+ },
353
+ {
354
+ "AMSLAltAboveTerrain": null,
355
+ "Altitude": 0,
356
+ "AltitudeMode": 0,
357
+ "autoContinue": true,
358
+ "command": 20,
359
+ "doJumpId": 19,
360
+ "frame": 2,
361
+ "params": [
362
+ 0.0,
363
+ 0.0,
364
+ 0.0,
365
+ 0.0,
366
+ 0,
367
+ 0,
368
+ 0
369
+ ],
370
+ "type": "SimpleItem"
371
+ }
372
+ ],
373
+ "plannedHomePosition": [
374
+ 16.047123,
375
+ 108.206456,
376
+ 8.0
377
+ ],
378
+ "vehicleType": 2,
379
+ "version": 2
380
+ },
381
+ "geoFence": {
382
+ "circles": [],
383
+ "polygons": [],
384
+ "version": 2
385
+ },
386
+ "rallyPoints": {
387
+ "points": [],
388
+ "version": 2
389
+ }
390
+ }
downloads/survey_local_20250822_114056.plan ADDED
@@ -0,0 +1,390 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "fileType": "Plan",
3
+ "groundStation": "DroneAgent - Survey",
4
+ "version": 1,
5
+ "mission": {
6
+ "cruiseSpeed": 15.0,
7
+ "firmwareType": 12,
8
+ "globalPlanAltitudeMode": 1,
9
+ "hoverSpeed": 9.0,
10
+ "items": [
11
+ {
12
+ "AMSLAltAboveTerrain": null,
13
+ "Altitude": 45.0,
14
+ "AltitudeMode": 1,
15
+ "autoContinue": true,
16
+ "command": 22,
17
+ "doJumpId": 1,
18
+ "frame": 3,
19
+ "params": [
20
+ 0.0,
21
+ 0.0,
22
+ 0.0,
23
+ 0.0,
24
+ 16.047123,
25
+ 108.206456,
26
+ 45.0
27
+ ],
28
+ "type": "SimpleItem"
29
+ },
30
+ {
31
+ "AMSLAltAboveTerrain": null,
32
+ "Altitude": 45.0,
33
+ "AltitudeMode": 1,
34
+ "autoContinue": true,
35
+ "command": 16,
36
+ "doJumpId": 2,
37
+ "frame": 3,
38
+ "params": [
39
+ 1.0,
40
+ 3.0,
41
+ 0.0,
42
+ 0.0,
43
+ 16.043519396396395,
44
+ 108.20270635545224,
45
+ 45
46
+ ],
47
+ "type": "SimpleItem"
48
+ },
49
+ {
50
+ "AMSLAltAboveTerrain": null,
51
+ "Altitude": 45.0,
52
+ "AltitudeMode": 1,
53
+ "autoContinue": true,
54
+ "command": 16,
55
+ "doJumpId": 3,
56
+ "frame": 3,
57
+ "params": [
58
+ 1.0,
59
+ 3.0,
60
+ 0.0,
61
+ 0.0,
62
+ 16.043519396396395,
63
+ 108.20458117772611,
64
+ 45
65
+ ],
66
+ "type": "SimpleItem"
67
+ },
68
+ {
69
+ "AMSLAltAboveTerrain": null,
70
+ "Altitude": 45.0,
71
+ "AltitudeMode": 1,
72
+ "autoContinue": true,
73
+ "command": 16,
74
+ "doJumpId": 4,
75
+ "frame": 3,
76
+ "params": [
77
+ 1.0,
78
+ 3.0,
79
+ 0.0,
80
+ 0.0,
81
+ 16.043519396396395,
82
+ 108.206456,
83
+ 45
84
+ ],
85
+ "type": "SimpleItem"
86
+ },
87
+ {
88
+ "AMSLAltAboveTerrain": null,
89
+ "Altitude": 45.0,
90
+ "AltitudeMode": 1,
91
+ "autoContinue": true,
92
+ "command": 16,
93
+ "doJumpId": 5,
94
+ "frame": 3,
95
+ "params": [
96
+ 1.0,
97
+ 3.0,
98
+ 0.0,
99
+ 0.0,
100
+ 16.043519396396395,
101
+ 108.2083308222739,
102
+ 45
103
+ ],
104
+ "type": "SimpleItem"
105
+ },
106
+ {
107
+ "AMSLAltAboveTerrain": null,
108
+ "Altitude": 45.0,
109
+ "AltitudeMode": 1,
110
+ "autoContinue": true,
111
+ "command": 16,
112
+ "doJumpId": 6,
113
+ "frame": 3,
114
+ "params": [
115
+ 1.0,
116
+ 3.0,
117
+ 0.0,
118
+ 0.0,
119
+ 16.0453211981982,
120
+ 108.20270632154111,
121
+ 45
122
+ ],
123
+ "type": "SimpleItem"
124
+ },
125
+ {
126
+ "AMSLAltAboveTerrain": null,
127
+ "Altitude": 45.0,
128
+ "AltitudeMode": 1,
129
+ "autoContinue": true,
130
+ "command": 16,
131
+ "doJumpId": 7,
132
+ "frame": 3,
133
+ "params": [
134
+ 1.0,
135
+ 3.0,
136
+ 0.0,
137
+ 0.0,
138
+ 16.0453211981982,
139
+ 108.20458116077056,
140
+ 45
141
+ ],
142
+ "type": "SimpleItem"
143
+ },
144
+ {
145
+ "AMSLAltAboveTerrain": null,
146
+ "Altitude": 45.0,
147
+ "AltitudeMode": 1,
148
+ "autoContinue": true,
149
+ "command": 16,
150
+ "doJumpId": 8,
151
+ "frame": 3,
152
+ "params": [
153
+ 1.0,
154
+ 3.0,
155
+ 0.0,
156
+ 0.0,
157
+ 16.0453211981982,
158
+ 108.206456,
159
+ 45
160
+ ],
161
+ "type": "SimpleItem"
162
+ },
163
+ {
164
+ "AMSLAltAboveTerrain": null,
165
+ "Altitude": 45.0,
166
+ "AltitudeMode": 1,
167
+ "autoContinue": true,
168
+ "command": 16,
169
+ "doJumpId": 9,
170
+ "frame": 3,
171
+ "params": [
172
+ 1.0,
173
+ 3.0,
174
+ 0.0,
175
+ 0.0,
176
+ 16.0453211981982,
177
+ 108.20833083922945,
178
+ 45
179
+ ],
180
+ "type": "SimpleItem"
181
+ },
182
+ {
183
+ "AMSLAltAboveTerrain": null,
184
+ "Altitude": 45.0,
185
+ "AltitudeMode": 1,
186
+ "autoContinue": true,
187
+ "command": 16,
188
+ "doJumpId": 10,
189
+ "frame": 3,
190
+ "params": [
191
+ 1.0,
192
+ 3.0,
193
+ 0.0,
194
+ 0.0,
195
+ 16.047123,
196
+ 108.20270628762569,
197
+ 45
198
+ ],
199
+ "type": "SimpleItem"
200
+ },
201
+ {
202
+ "AMSLAltAboveTerrain": null,
203
+ "Altitude": 45.0,
204
+ "AltitudeMode": 1,
205
+ "autoContinue": true,
206
+ "command": 16,
207
+ "doJumpId": 11,
208
+ "frame": 3,
209
+ "params": [
210
+ 1.0,
211
+ 3.0,
212
+ 0.0,
213
+ 0.0,
214
+ 16.047123,
215
+ 108.20458114381285,
216
+ 45
217
+ ],
218
+ "type": "SimpleItem"
219
+ },
220
+ {
221
+ "AMSLAltAboveTerrain": null,
222
+ "Altitude": 45.0,
223
+ "AltitudeMode": 1,
224
+ "autoContinue": true,
225
+ "command": 16,
226
+ "doJumpId": 12,
227
+ "frame": 3,
228
+ "params": [
229
+ 1.0,
230
+ 3.0,
231
+ 0.0,
232
+ 0.0,
233
+ 16.047123,
234
+ 108.206456,
235
+ 45
236
+ ],
237
+ "type": "SimpleItem"
238
+ },
239
+ {
240
+ "AMSLAltAboveTerrain": null,
241
+ "Altitude": 45.0,
242
+ "AltitudeMode": 1,
243
+ "autoContinue": true,
244
+ "command": 16,
245
+ "doJumpId": 13,
246
+ "frame": 3,
247
+ "params": [
248
+ 1.0,
249
+ 3.0,
250
+ 0.0,
251
+ 0.0,
252
+ 16.047123,
253
+ 108.20833085618716,
254
+ 45
255
+ ],
256
+ "type": "SimpleItem"
257
+ },
258
+ {
259
+ "AMSLAltAboveTerrain": null,
260
+ "Altitude": 45.0,
261
+ "AltitudeMode": 1,
262
+ "autoContinue": true,
263
+ "command": 16,
264
+ "doJumpId": 14,
265
+ "frame": 3,
266
+ "params": [
267
+ 1.0,
268
+ 3.0,
269
+ 0.0,
270
+ 0.0,
271
+ 16.0489248018018,
272
+ 108.20270625370593,
273
+ 45
274
+ ],
275
+ "type": "SimpleItem"
276
+ },
277
+ {
278
+ "AMSLAltAboveTerrain": null,
279
+ "Altitude": 45.0,
280
+ "AltitudeMode": 1,
281
+ "autoContinue": true,
282
+ "command": 16,
283
+ "doJumpId": 15,
284
+ "frame": 3,
285
+ "params": [
286
+ 1.0,
287
+ 3.0,
288
+ 0.0,
289
+ 0.0,
290
+ 16.0489248018018,
291
+ 108.20458112685296,
292
+ 45
293
+ ],
294
+ "type": "SimpleItem"
295
+ },
296
+ {
297
+ "AMSLAltAboveTerrain": null,
298
+ "Altitude": 45.0,
299
+ "AltitudeMode": 1,
300
+ "autoContinue": true,
301
+ "command": 16,
302
+ "doJumpId": 16,
303
+ "frame": 3,
304
+ "params": [
305
+ 1.0,
306
+ 3.0,
307
+ 0.0,
308
+ 0.0,
309
+ 16.0489248018018,
310
+ 108.206456,
311
+ 45
312
+ ],
313
+ "type": "SimpleItem"
314
+ },
315
+ {
316
+ "AMSLAltAboveTerrain": null,
317
+ "Altitude": 45.0,
318
+ "AltitudeMode": 1,
319
+ "autoContinue": true,
320
+ "command": 16,
321
+ "doJumpId": 17,
322
+ "frame": 3,
323
+ "params": [
324
+ 1.0,
325
+ 3.0,
326
+ 0.0,
327
+ 0.0,
328
+ 16.0489248018018,
329
+ 108.20833087314705,
330
+ 45
331
+ ],
332
+ "type": "SimpleItem"
333
+ },
334
+ {
335
+ "AMSLAltAboveTerrain": null,
336
+ "Altitude": 0,
337
+ "AltitudeMode": 1,
338
+ "autoContinue": true,
339
+ "command": 203,
340
+ "doJumpId": 18,
341
+ "frame": 2,
342
+ "params": [
343
+ 1,
344
+ 0,
345
+ 0,
346
+ 1,
347
+ 0,
348
+ 0,
349
+ 0
350
+ ],
351
+ "type": "SimpleItem"
352
+ },
353
+ {
354
+ "AMSLAltAboveTerrain": null,
355
+ "Altitude": 0,
356
+ "AltitudeMode": 0,
357
+ "autoContinue": true,
358
+ "command": 20,
359
+ "doJumpId": 19,
360
+ "frame": 2,
361
+ "params": [
362
+ 0.0,
363
+ 0.0,
364
+ 0.0,
365
+ 0.0,
366
+ 0,
367
+ 0,
368
+ 0
369
+ ],
370
+ "type": "SimpleItem"
371
+ }
372
+ ],
373
+ "plannedHomePosition": [
374
+ 16.047123,
375
+ 108.206456,
376
+ 8.0
377
+ ],
378
+ "vehicleType": 2,
379
+ "version": 2
380
+ },
381
+ "geoFence": {
382
+ "circles": [],
383
+ "polygons": [],
384
+ "version": 2
385
+ },
386
+ "rallyPoints": {
387
+ "points": [],
388
+ "version": 2
389
+ }
390
+ }
downloads/survey_local_20250822_114408.plan ADDED
@@ -0,0 +1,390 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "fileType": "Plan",
3
+ "groundStation": "DroneAgent - Survey",
4
+ "version": 1,
5
+ "mission": {
6
+ "cruiseSpeed": 15.0,
7
+ "firmwareType": 12,
8
+ "globalPlanAltitudeMode": 1,
9
+ "hoverSpeed": 9.0,
10
+ "items": [
11
+ {
12
+ "AMSLAltAboveTerrain": null,
13
+ "Altitude": 45.0,
14
+ "AltitudeMode": 1,
15
+ "autoContinue": true,
16
+ "command": 22,
17
+ "doJumpId": 1,
18
+ "frame": 3,
19
+ "params": [
20
+ 0.0,
21
+ 0.0,
22
+ 0.0,
23
+ 0.0,
24
+ 16.1,
25
+ 108.2,
26
+ 45.0
27
+ ],
28
+ "type": "SimpleItem"
29
+ },
30
+ {
31
+ "AMSLAltAboveTerrain": null,
32
+ "Altitude": 45.0,
33
+ "AltitudeMode": 1,
34
+ "autoContinue": true,
35
+ "command": 16,
36
+ "doJumpId": 2,
37
+ "frame": 3,
38
+ "params": [
39
+ 1.0,
40
+ 3.0,
41
+ 0.0,
42
+ 0.0,
43
+ 16.096396396396397,
44
+ 108.19624935847347,
45
+ 45
46
+ ],
47
+ "type": "SimpleItem"
48
+ },
49
+ {
50
+ "AMSLAltAboveTerrain": null,
51
+ "Altitude": 45.0,
52
+ "AltitudeMode": 1,
53
+ "autoContinue": true,
54
+ "command": 16,
55
+ "doJumpId": 3,
56
+ "frame": 3,
57
+ "params": [
58
+ 1.0,
59
+ 3.0,
60
+ 0.0,
61
+ 0.0,
62
+ 16.096396396396397,
63
+ 108.19812467923674,
64
+ 45
65
+ ],
66
+ "type": "SimpleItem"
67
+ },
68
+ {
69
+ "AMSLAltAboveTerrain": null,
70
+ "Altitude": 45.0,
71
+ "AltitudeMode": 1,
72
+ "autoContinue": true,
73
+ "command": 16,
74
+ "doJumpId": 4,
75
+ "frame": 3,
76
+ "params": [
77
+ 1.0,
78
+ 3.0,
79
+ 0.0,
80
+ 0.0,
81
+ 16.096396396396397,
82
+ 108.2,
83
+ 45
84
+ ],
85
+ "type": "SimpleItem"
86
+ },
87
+ {
88
+ "AMSLAltAboveTerrain": null,
89
+ "Altitude": 45.0,
90
+ "AltitudeMode": 1,
91
+ "autoContinue": true,
92
+ "command": 16,
93
+ "doJumpId": 5,
94
+ "frame": 3,
95
+ "params": [
96
+ 1.0,
97
+ 3.0,
98
+ 0.0,
99
+ 0.0,
100
+ 16.096396396396397,
101
+ 108.20187532076326,
102
+ 45
103
+ ],
104
+ "type": "SimpleItem"
105
+ },
106
+ {
107
+ "AMSLAltAboveTerrain": null,
108
+ "Altitude": 45.0,
109
+ "AltitudeMode": 1,
110
+ "autoContinue": true,
111
+ "command": 16,
112
+ "doJumpId": 6,
113
+ "frame": 3,
114
+ "params": [
115
+ 1.0,
116
+ 3.0,
117
+ 0.0,
118
+ 0.0,
119
+ 16.0981981981982,
120
+ 108.19624932443546,
121
+ 45
122
+ ],
123
+ "type": "SimpleItem"
124
+ },
125
+ {
126
+ "AMSLAltAboveTerrain": null,
127
+ "Altitude": 45.0,
128
+ "AltitudeMode": 1,
129
+ "autoContinue": true,
130
+ "command": 16,
131
+ "doJumpId": 7,
132
+ "frame": 3,
133
+ "params": [
134
+ 1.0,
135
+ 3.0,
136
+ 0.0,
137
+ 0.0,
138
+ 16.0981981981982,
139
+ 108.19812466221772,
140
+ 45
141
+ ],
142
+ "type": "SimpleItem"
143
+ },
144
+ {
145
+ "AMSLAltAboveTerrain": null,
146
+ "Altitude": 45.0,
147
+ "AltitudeMode": 1,
148
+ "autoContinue": true,
149
+ "command": 16,
150
+ "doJumpId": 8,
151
+ "frame": 3,
152
+ "params": [
153
+ 1.0,
154
+ 3.0,
155
+ 0.0,
156
+ 0.0,
157
+ 16.0981981981982,
158
+ 108.2,
159
+ 45
160
+ ],
161
+ "type": "SimpleItem"
162
+ },
163
+ {
164
+ "AMSLAltAboveTerrain": null,
165
+ "Altitude": 45.0,
166
+ "AltitudeMode": 1,
167
+ "autoContinue": true,
168
+ "command": 16,
169
+ "doJumpId": 9,
170
+ "frame": 3,
171
+ "params": [
172
+ 1.0,
173
+ 3.0,
174
+ 0.0,
175
+ 0.0,
176
+ 16.0981981981982,
177
+ 108.20187533778228,
178
+ 45
179
+ ],
180
+ "type": "SimpleItem"
181
+ },
182
+ {
183
+ "AMSLAltAboveTerrain": null,
184
+ "Altitude": 45.0,
185
+ "AltitudeMode": 1,
186
+ "autoContinue": true,
187
+ "command": 16,
188
+ "doJumpId": 10,
189
+ "frame": 3,
190
+ "params": [
191
+ 1.0,
192
+ 3.0,
193
+ 0.0,
194
+ 0.0,
195
+ 16.1,
196
+ 108.19624929039311,
197
+ 45
198
+ ],
199
+ "type": "SimpleItem"
200
+ },
201
+ {
202
+ "AMSLAltAboveTerrain": null,
203
+ "Altitude": 45.0,
204
+ "AltitudeMode": 1,
205
+ "autoContinue": true,
206
+ "command": 16,
207
+ "doJumpId": 11,
208
+ "frame": 3,
209
+ "params": [
210
+ 1.0,
211
+ 3.0,
212
+ 0.0,
213
+ 0.0,
214
+ 16.1,
215
+ 108.19812464519656,
216
+ 45
217
+ ],
218
+ "type": "SimpleItem"
219
+ },
220
+ {
221
+ "AMSLAltAboveTerrain": null,
222
+ "Altitude": 45.0,
223
+ "AltitudeMode": 1,
224
+ "autoContinue": true,
225
+ "command": 16,
226
+ "doJumpId": 12,
227
+ "frame": 3,
228
+ "params": [
229
+ 1.0,
230
+ 3.0,
231
+ 0.0,
232
+ 0.0,
233
+ 16.1,
234
+ 108.2,
235
+ 45
236
+ ],
237
+ "type": "SimpleItem"
238
+ },
239
+ {
240
+ "AMSLAltAboveTerrain": null,
241
+ "Altitude": 45.0,
242
+ "AltitudeMode": 1,
243
+ "autoContinue": true,
244
+ "command": 16,
245
+ "doJumpId": 13,
246
+ "frame": 3,
247
+ "params": [
248
+ 1.0,
249
+ 3.0,
250
+ 0.0,
251
+ 0.0,
252
+ 16.1,
253
+ 108.20187535480345,
254
+ 45
255
+ ],
256
+ "type": "SimpleItem"
257
+ },
258
+ {
259
+ "AMSLAltAboveTerrain": null,
260
+ "Altitude": 45.0,
261
+ "AltitudeMode": 1,
262
+ "autoContinue": true,
263
+ "command": 16,
264
+ "doJumpId": 14,
265
+ "frame": 3,
266
+ "params": [
267
+ 1.0,
268
+ 3.0,
269
+ 0.0,
270
+ 0.0,
271
+ 16.101801801801802,
272
+ 108.19624925634643,
273
+ 45
274
+ ],
275
+ "type": "SimpleItem"
276
+ },
277
+ {
278
+ "AMSLAltAboveTerrain": null,
279
+ "Altitude": 45.0,
280
+ "AltitudeMode": 1,
281
+ "autoContinue": true,
282
+ "command": 16,
283
+ "doJumpId": 15,
284
+ "frame": 3,
285
+ "params": [
286
+ 1.0,
287
+ 3.0,
288
+ 0.0,
289
+ 0.0,
290
+ 16.101801801801802,
291
+ 108.19812462817322,
292
+ 45
293
+ ],
294
+ "type": "SimpleItem"
295
+ },
296
+ {
297
+ "AMSLAltAboveTerrain": null,
298
+ "Altitude": 45.0,
299
+ "AltitudeMode": 1,
300
+ "autoContinue": true,
301
+ "command": 16,
302
+ "doJumpId": 16,
303
+ "frame": 3,
304
+ "params": [
305
+ 1.0,
306
+ 3.0,
307
+ 0.0,
308
+ 0.0,
309
+ 16.101801801801802,
310
+ 108.2,
311
+ 45
312
+ ],
313
+ "type": "SimpleItem"
314
+ },
315
+ {
316
+ "AMSLAltAboveTerrain": null,
317
+ "Altitude": 45.0,
318
+ "AltitudeMode": 1,
319
+ "autoContinue": true,
320
+ "command": 16,
321
+ "doJumpId": 17,
322
+ "frame": 3,
323
+ "params": [
324
+ 1.0,
325
+ 3.0,
326
+ 0.0,
327
+ 0.0,
328
+ 16.101801801801802,
329
+ 108.20187537182679,
330
+ 45
331
+ ],
332
+ "type": "SimpleItem"
333
+ },
334
+ {
335
+ "AMSLAltAboveTerrain": null,
336
+ "Altitude": 0,
337
+ "AltitudeMode": 1,
338
+ "autoContinue": true,
339
+ "command": 203,
340
+ "doJumpId": 18,
341
+ "frame": 2,
342
+ "params": [
343
+ 1,
344
+ 0,
345
+ 0,
346
+ 1,
347
+ 0,
348
+ 0,
349
+ 0
350
+ ],
351
+ "type": "SimpleItem"
352
+ },
353
+ {
354
+ "AMSLAltAboveTerrain": null,
355
+ "Altitude": 0,
356
+ "AltitudeMode": 0,
357
+ "autoContinue": true,
358
+ "command": 20,
359
+ "doJumpId": 19,
360
+ "frame": 2,
361
+ "params": [
362
+ 0.0,
363
+ 0.0,
364
+ 0.0,
365
+ 0.0,
366
+ 0,
367
+ 0,
368
+ 0
369
+ ],
370
+ "type": "SimpleItem"
371
+ }
372
+ ],
373
+ "plannedHomePosition": [
374
+ 16.1,
375
+ 108.2,
376
+ 8.0
377
+ ],
378
+ "vehicleType": 2,
379
+ "version": 2
380
+ },
381
+ "geoFence": {
382
+ "circles": [],
383
+ "polygons": [],
384
+ "version": 2
385
+ },
386
+ "rallyPoints": {
387
+ "points": [],
388
+ "version": 2
389
+ }
390
+ }
main.py ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ DroneAgent - Advanced Flight Management System.
4
+ """
5
+ import os
6
+ import asyncio
7
+ import uvicorn
8
+ from contextlib import asynccontextmanager
9
+ from fastapi import FastAPI
10
+ from fastapi.middleware.cors import CORSMiddleware
11
+ from dotenv import load_dotenv
12
+
13
+ from src.api.routes import router
14
+ from src.core.websocket_server import start_websocket_server
15
+
16
+ load_dotenv()
17
+
18
+
19
+ @asynccontextmanager
20
+ async def lifespan(app: FastAPI):
21
+ """Application lifespan manager."""
22
+ # Startup
23
+ print("🚀 Starting DroneAgent with Flight Management System")
24
+
25
+ # Start WebSocket server for real-time notifications
26
+ asyncio.create_task(start_websocket_server())
27
+
28
+ print("✅ All background services started")
29
+
30
+ yield
31
+
32
+ # Shutdown
33
+ print("🛑 Shutting down DroneAgent services")
34
+
35
+
36
+ # Initialize FastAPI with lifespan
37
+ app = FastAPI(
38
+ title="DroneAgent",
39
+ description="Advanced AI-powered drone mission planner with real-time flight management",
40
+ version="3.0.0",
41
+ lifespan=lifespan
42
+ )
43
+
44
+ app.add_middleware(
45
+ CORSMiddleware,
46
+ allow_origins=["*"],
47
+ allow_credentials=True,
48
+ allow_methods=["*"],
49
+ allow_headers=["*"],
50
+ )
51
+
52
+ # Include routes
53
+ app.include_router(router)
54
+
55
+
56
+ @app.get("/")
57
+ async def root():
58
+ """API information."""
59
+ return {
60
+ "name": "DroneAgent",
61
+ "version": "3.0.0",
62
+ "status": "operational",
63
+ "features": [
64
+ "🧠 Gemini-first AI mission planning",
65
+ "📡 Real-time telemetry processing",
66
+ "🎯 Intelligent flight management",
67
+ "📱 WebSocket notifications",
68
+ "⏸️ Dynamic mission control",
69
+ "🛡️ AI-powered safety checks",
70
+ "🗺️ QGroundControl compatibility"
71
+ ],
72
+ "endpoints": {
73
+ "chat": "POST /chat - Conversational AI for mission planning",
74
+ "flight_confirm": "POST /flight/confirm - Confirm and start tracking a flight",
75
+ "flight_pause": "POST /flight/pause - Pause active flight mission",
76
+ "flight_cancel": "POST /flight/cancel - Cancel active flight mission",
77
+ "flight_update": "POST /flight/update - Update mission waypoints during flight",
78
+ "flight_status": "GET /flight/status/{drone_id} - Get intelligent flight status",
79
+ "flight_missions": "GET /flight/missions - Get all active missions",
80
+ "flight_telemetry": "POST /flight/telemetry - Real-time telemetry updates",
81
+ "drone_status": "GET /drone/status - Monitor current drone status",
82
+ "websocket": "ws://localhost:8001 - Real-time flight notifications"
83
+ },
84
+ "websocket_notifications": [
85
+ "flight_confirmed - Mission tracking started",
86
+ "waypoint_completed - Waypoint reached with AI analysis",
87
+ "flight_paused - Mission paused with timeout",
88
+ "mission_updated - Dynamic route changes",
89
+ "emergency - Critical conditions detected",
90
+ "mission_completed - All waypoints reached"
91
+ ],
92
+ "examples": [
93
+ "Go straight 100m from 16.047, 108.206",
94
+ "Survey mission at 16.047, 108.206",
95
+ "Patrol route at 16.047, 108.206 at 80m altitude",
96
+ "Photography flight at 16.047, 108.206"
97
+ ]
98
+ }
99
+
100
+
101
+ if __name__ == "__main__":
102
+ port = int(os.environ.get('PORT', 8000))
103
+ uvicorn.run(app, host="0.0.0.0", port=port, reload=False)
requirements.txt ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🚁 DroneAgent v3.0 - HF Spaces Requirements
2
+ # Professional AI-Powered Drone Mission Planner for HuggingFace Spaces
3
+
4
+ # Core FastAPI framework
5
+ fastapi==0.104.1
6
+ uvicorn[standard]==0.24.0
7
+
8
+ # AI and API integration
9
+ aiohttp==3.8.6
10
+ requests==2.31.0
11
+
12
+ # Data processing and validation
13
+ pydantic==2.5.0
14
+ python-multipart==0.0.6
15
+
16
+ # Environment and configuration
17
+ python-dotenv==1.0.0
18
+
19
+ # WebSocket support for real-time notifications
20
+ websockets==12.0
21
+
22
+ # Production server (optional for HF Spaces)
23
+ gunicorn==21.2.0
24
+
25
+ # Optional: AI integration (requires API keys)
26
+ # google-generativeai>=0.3.0
27
+ # openai>=1.0.0
28
+
29
+ # Optional: Additional dependencies for full functionality
30
+ # pymavlink>=2.4.0
31
+ # numpy>=1.24.0
32
+ # pandas>=2.0.0