@jjlmoya/utils-drones 1.35.0 → 1.37.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/package.json +1 -1
  2. package/src/category/index.ts +4 -0
  3. package/src/entries.ts +8 -0
  4. package/src/index.ts +1 -0
  5. package/src/tests/locale_completeness.test.ts +2 -2
  6. package/src/tests/tool_validation.test.ts +2 -2
  7. package/src/tool/drone-mission-battery-reserve-planner/bibliography.astro +6 -0
  8. package/src/tool/drone-mission-battery-reserve-planner/bibliography.ts +7 -0
  9. package/src/tool/drone-mission-battery-reserve-planner/component.astro +229 -0
  10. package/src/tool/drone-mission-battery-reserve-planner/controller.ts +124 -0
  11. package/src/tool/drone-mission-battery-reserve-planner/dom-views.ts +114 -0
  12. package/src/tool/drone-mission-battery-reserve-planner/drone-mission-battery-reserve-planner.css +392 -0
  13. package/src/tool/drone-mission-battery-reserve-planner/entry.ts +27 -0
  14. package/src/tool/drone-mission-battery-reserve-planner/evaluator.ts +23 -0
  15. package/src/tool/drone-mission-battery-reserve-planner/i18n/de.ts +223 -0
  16. package/src/tool/drone-mission-battery-reserve-planner/i18n/en.ts +223 -0
  17. package/src/tool/drone-mission-battery-reserve-planner/i18n/es.ts +223 -0
  18. package/src/tool/drone-mission-battery-reserve-planner/i18n/fr.ts +223 -0
  19. package/src/tool/drone-mission-battery-reserve-planner/i18n/id.ts +223 -0
  20. package/src/tool/drone-mission-battery-reserve-planner/i18n/it.ts +223 -0
  21. package/src/tool/drone-mission-battery-reserve-planner/i18n/ja.ts +223 -0
  22. package/src/tool/drone-mission-battery-reserve-planner/i18n/ko.ts +223 -0
  23. package/src/tool/drone-mission-battery-reserve-planner/i18n/nl.ts +223 -0
  24. package/src/tool/drone-mission-battery-reserve-planner/i18n/pl.ts +223 -0
  25. package/src/tool/drone-mission-battery-reserve-planner/i18n/pt.ts +223 -0
  26. package/src/tool/drone-mission-battery-reserve-planner/i18n/ru.ts +223 -0
  27. package/src/tool/drone-mission-battery-reserve-planner/i18n/sv.ts +223 -0
  28. package/src/tool/drone-mission-battery-reserve-planner/i18n/tr.ts +223 -0
  29. package/src/tool/drone-mission-battery-reserve-planner/i18n/zh.ts +223 -0
  30. package/src/tool/drone-mission-battery-reserve-planner/index.ts +11 -0
  31. package/src/tool/drone-mission-battery-reserve-planner/logic.test.ts +94 -0
  32. package/src/tool/drone-mission-battery-reserve-planner/logic.ts +203 -0
  33. package/src/tool/drone-mission-battery-reserve-planner/seo.astro +15 -0
  34. package/src/tool/drone-mission-battery-reserve-planner/storage.ts +59 -0
  35. package/src/tool/drone-mission-battery-reserve-planner/ui.ts +78 -0
  36. package/src/tool/fpv-drone-speed-calculator/bibliography.astro +6 -0
  37. package/src/tool/fpv-drone-speed-calculator/bibliography.ts +14 -0
  38. package/src/tool/fpv-drone-speed-calculator/component.astro +115 -0
  39. package/src/tool/fpv-drone-speed-calculator/controller.ts +105 -0
  40. package/src/tool/fpv-drone-speed-calculator/dom-views.ts +80 -0
  41. package/src/tool/fpv-drone-speed-calculator/entry.ts +27 -0
  42. package/src/tool/fpv-drone-speed-calculator/fpv-drone-speed-calculator.css +558 -0
  43. package/src/tool/fpv-drone-speed-calculator/i18n/de.ts +20 -0
  44. package/src/tool/fpv-drone-speed-calculator/i18n/en.ts +47 -0
  45. package/src/tool/fpv-drone-speed-calculator/i18n/es.ts +40 -0
  46. package/src/tool/fpv-drone-speed-calculator/i18n/fr.ts +13 -0
  47. package/src/tool/fpv-drone-speed-calculator/i18n/id.ts +13 -0
  48. package/src/tool/fpv-drone-speed-calculator/i18n/it.ts +13 -0
  49. package/src/tool/fpv-drone-speed-calculator/i18n/ja.ts +13 -0
  50. package/src/tool/fpv-drone-speed-calculator/i18n/ko.ts +13 -0
  51. package/src/tool/fpv-drone-speed-calculator/i18n/nl.ts +13 -0
  52. package/src/tool/fpv-drone-speed-calculator/i18n/pl.ts +13 -0
  53. package/src/tool/fpv-drone-speed-calculator/i18n/pt.ts +13 -0
  54. package/src/tool/fpv-drone-speed-calculator/i18n/ru.ts +13 -0
  55. package/src/tool/fpv-drone-speed-calculator/i18n/sv.ts +13 -0
  56. package/src/tool/fpv-drone-speed-calculator/i18n/tr.ts +13 -0
  57. package/src/tool/fpv-drone-speed-calculator/i18n/zh.ts +13 -0
  58. package/src/tool/fpv-drone-speed-calculator/index.ts +11 -0
  59. package/src/tool/fpv-drone-speed-calculator/logic.test.ts +53 -0
  60. package/src/tool/fpv-drone-speed-calculator/logic.ts +126 -0
  61. package/src/tool/fpv-drone-speed-calculator/seo.astro +16 -0
  62. package/src/tool/fpv-drone-speed-calculator/ui.ts +47 -0
  63. package/src/tools.ts +7 -0
@@ -0,0 +1,392 @@
1
+ .drone-mission-battery-reserve-planner {
2
+ box-sizing: border-box;
3
+ display: flex;
4
+ flex-direction: column;
5
+ gap: 24px;
6
+ width: 100%;
7
+ max-width: 1100px;
8
+ margin: 0 auto;
9
+ padding: 24px;
10
+ border-radius: 16px;
11
+ background: var(--n-surface-card, #0d1322);
12
+ border: 1px solid var(--n-border, #1e293b);
13
+ color: var(--n-text-primary, #f8fafc);
14
+ }
15
+
16
+ .drone-mission-battery-reserve-planner * {
17
+ box-sizing: border-box;
18
+ }
19
+
20
+ .planner-top-bar {
21
+ display: flex;
22
+ flex-wrap: wrap;
23
+ align-items: center;
24
+ justify-content: space-between;
25
+ gap: 16px;
26
+ padding-bottom: 20px;
27
+ border-bottom: 1px solid var(--n-border, #1e293b);
28
+ }
29
+
30
+ .presets-section {
31
+ display: flex;
32
+ flex-direction: column;
33
+ gap: 8px;
34
+ }
35
+
36
+ .presets-label {
37
+ font-size: 11px;
38
+ font-weight: 700;
39
+ letter-spacing: 0.05em;
40
+ text-transform: uppercase;
41
+ color: var(--n-text-secondary, #94a3b8);
42
+ }
43
+
44
+ .presets-flex {
45
+ display: flex;
46
+ flex-wrap: wrap;
47
+ gap: 8px;
48
+ }
49
+
50
+ .preset-pill {
51
+ display: flex;
52
+ flex-direction: column;
53
+ align-items: flex-start;
54
+ padding: 8px 14px;
55
+ border-radius: 8px;
56
+ background: var(--n-surface-subtle, #151d30);
57
+ border: 1px solid var(--n-border, #2e3d5c);
58
+ color: var(--n-text-primary, #f8fafc);
59
+ cursor: pointer;
60
+ transition: all 0.2s ease;
61
+ }
62
+
63
+ .preset-pill:hover {
64
+ background: var(--n-surface-hover, #1e2942);
65
+ border-color: var(--n-brand, #3b82f6);
66
+ }
67
+
68
+ .preset-name {
69
+ font-size: 12px;
70
+ font-weight: 600;
71
+ }
72
+
73
+ .preset-meta {
74
+ font-size: 10px;
75
+ color: var(--n-text-secondary, #94a3b8);
76
+ }
77
+
78
+ .unit-switch-group {
79
+ display: flex;
80
+ background: var(--n-surface-subtle, #151d30);
81
+ padding: 3px;
82
+ border-radius: 8px;
83
+ border: 1px solid var(--n-border, #2e3d5c);
84
+ }
85
+
86
+ .unit-btn {
87
+ padding: 6px 16px;
88
+ border-radius: 6px;
89
+ border: none;
90
+ background: transparent;
91
+ color: var(--n-text-secondary, #94a3b8);
92
+ font-size: 12px;
93
+ font-weight: 600;
94
+ cursor: pointer;
95
+ transition: all 0.2s ease;
96
+ }
97
+
98
+ .unit-btn.active {
99
+ background: var(--n-brand, #3b82f6);
100
+ color: #fff;
101
+ }
102
+
103
+ .planner-main-grid {
104
+ display: grid;
105
+ grid-template-columns: 1fr 1fr;
106
+ gap: 24px;
107
+ }
108
+
109
+ @media (max-width: 860px) {
110
+ .planner-main-grid {
111
+ grid-template-columns: 1fr;
112
+ }
113
+ }
114
+
115
+ .planner-controls-panel {
116
+ display: flex;
117
+ flex-direction: column;
118
+ gap: 18px;
119
+ }
120
+
121
+ .panel-heading {
122
+ margin: 0;
123
+ font-size: 13px;
124
+ font-weight: 700;
125
+ letter-spacing: 0.05em;
126
+ text-transform: uppercase;
127
+ color: var(--n-brand-light, #60a5fa);
128
+ }
129
+
130
+ .control-row {
131
+ display: flex;
132
+ flex-direction: column;
133
+ gap: 6px;
134
+ }
135
+
136
+ .control-header {
137
+ display: flex;
138
+ justify-content: space-between;
139
+ align-items: center;
140
+ }
141
+
142
+ .control-header label {
143
+ font-size: 13px;
144
+ font-weight: 600;
145
+ }
146
+
147
+ .control-val-display {
148
+ font-size: 13px;
149
+ font-weight: 700;
150
+ color: var(--n-brand, #3b82f6);
151
+ }
152
+
153
+ .slider-with-number {
154
+ display: flex;
155
+ align-items: center;
156
+ gap: 12px;
157
+ }
158
+
159
+ .tactile-slider {
160
+ flex: 1;
161
+ accent-color: var(--n-brand, #3b82f6);
162
+ cursor: pointer;
163
+ }
164
+
165
+ .tactile-number {
166
+ width: 72px;
167
+ padding: 6px 8px;
168
+ border-radius: 6px;
169
+ background: var(--n-surface-subtle, #151d30);
170
+ border: 1px solid var(--n-border, #2e3d5c);
171
+ color: var(--n-text-primary, #f8fafc);
172
+ font-size: 13px;
173
+ font-weight: 600;
174
+ text-anchor: end;
175
+ }
176
+
177
+ .voltage-chips-row {
178
+ display: flex;
179
+ gap: 8px;
180
+ }
181
+
182
+ .voltage-chip {
183
+ flex: 1;
184
+ padding: 6px;
185
+ border-radius: 6px;
186
+ background: var(--n-surface-subtle, #151d30);
187
+ border: 1px solid var(--n-border, #2e3d5c);
188
+ color: var(--n-text-secondary, #94a3b8);
189
+ font-size: 11px;
190
+ font-weight: 600;
191
+ cursor: pointer;
192
+ }
193
+
194
+ .voltage-chip.active {
195
+ background: var(--n-brand, #3b82f6);
196
+ border-color: var(--n-brand, #3b82f6);
197
+ color: #fff;
198
+ }
199
+
200
+ .wind-dir-segmented {
201
+ display: flex;
202
+ gap: 8px;
203
+ }
204
+
205
+ .wind-seg-btn {
206
+ flex: 1;
207
+ display: flex;
208
+ flex-direction: column;
209
+ align-items: center;
210
+ padding: 8px;
211
+ border-radius: 8px;
212
+ background: var(--n-surface-subtle, #151d30);
213
+ border: 1px solid var(--n-border, #2e3d5c);
214
+ color: var(--n-text-secondary, #94a3b8);
215
+ font-size: 11px;
216
+ font-weight: 600;
217
+ cursor: pointer;
218
+ }
219
+
220
+ .wind-seg-btn.active {
221
+ border-color: var(--n-brand, #3b82f6);
222
+ color: var(--n-text-primary, #f8fafc);
223
+ background: var(--n-surface-hover, #1e2942);
224
+ }
225
+
226
+ .wind-tag {
227
+ font-size: 10px;
228
+ font-weight: 800;
229
+ color: var(--n-brand, #3b82f6);
230
+ }
231
+
232
+ .planner-telemetry-panel {
233
+ display: flex;
234
+ flex-direction: column;
235
+ gap: 16px;
236
+ }
237
+
238
+ .status-banner {
239
+ display: flex;
240
+ align-items: center;
241
+ gap: 12px;
242
+ padding: 14px 16px;
243
+ border-radius: 12px;
244
+ border: 1px solid var(--n-border, #2e3d5c);
245
+ }
246
+
247
+ .status-banner-optimal {
248
+ background: rgba(16, 185, 129, 0.1);
249
+ border-color: rgba(16, 185, 129, 0.3);
250
+ }
251
+
252
+ .status-banner-tight {
253
+ background: rgba(245, 158, 11, 0.1);
254
+ border-color: rgba(245, 158, 11, 0.3);
255
+ }
256
+
257
+ .status-banner-critical {
258
+ background: rgba(239, 68, 68, 0.1);
259
+ border-color: rgba(239, 68, 68, 0.3);
260
+ }
261
+
262
+ .status-banner-exceeded {
263
+ background: rgba(239, 68, 68, 0.15);
264
+ border-color: rgba(239, 68, 68, 0.5);
265
+ }
266
+
267
+ .status-icon-dot {
268
+ width: 10px;
269
+ height: 10px;
270
+ border-radius: 50%;
271
+ background: currentcolor;
272
+ }
273
+
274
+ .status-banner-optimal .status-icon-dot {
275
+ background: #10b981;
276
+ }
277
+
278
+ .status-banner-tight .status-icon-dot {
279
+ background: #f59e0b;
280
+ }
281
+
282
+ .status-banner-critical .status-icon-dot,
283
+ .status-banner-exceeded .status-icon-dot {
284
+ background: #ef4444;
285
+ }
286
+
287
+ .status-banner-text {
288
+ display: flex;
289
+ flex-direction: column;
290
+ }
291
+
292
+ .status-banner-title {
293
+ font-size: 13px;
294
+ font-weight: 800;
295
+ letter-spacing: 0.02em;
296
+ }
297
+
298
+ .status-banner-subtitle {
299
+ font-size: 11px;
300
+ color: var(--n-text-secondary, #94a3b8);
301
+ }
302
+
303
+ .telemetry-artwork-box {
304
+ width: 100%;
305
+ border-radius: 12px;
306
+ overflow: hidden;
307
+ }
308
+
309
+ .mission-telemetry-svg {
310
+ width: 100%;
311
+ height: auto;
312
+ display: block;
313
+ }
314
+
315
+ .metrics-grid {
316
+ display: grid;
317
+ grid-template-columns: 1fr 1fr;
318
+ gap: 12px;
319
+ }
320
+
321
+ .metric-card {
322
+ display: flex;
323
+ flex-direction: column;
324
+ padding: 12px 14px;
325
+ border-radius: 10px;
326
+ background: var(--n-surface-subtle, #151d30);
327
+ border: 1px solid var(--n-border, #1e293b);
328
+ }
329
+
330
+ .highlight-card {
331
+ border-color: var(--n-brand, #3b82f6);
332
+ background: rgba(59, 130, 246, 0.06);
333
+ }
334
+
335
+ .metric-label {
336
+ font-size: 11px;
337
+ font-weight: 600;
338
+ color: var(--n-text-secondary, #94a3b8);
339
+ }
340
+
341
+ .metric-value {
342
+ font-size: 18px;
343
+ font-weight: 800;
344
+ margin: 4px 0 2px;
345
+ color: var(--n-text-primary, #f8fafc);
346
+ }
347
+
348
+ .metric-sub {
349
+ font-size: 10px;
350
+ color: var(--n-text-secondary, #94a3b8);
351
+ }
352
+
353
+ .touchdown-energy-card {
354
+ display: flex;
355
+ flex-direction: column;
356
+ gap: 8px;
357
+ padding: 14px;
358
+ border-radius: 10px;
359
+ background: var(--n-surface-subtle, #151d30);
360
+ border: 1px solid var(--n-border, #1e293b);
361
+ }
362
+
363
+ .touchdown-info {
364
+ display: flex;
365
+ justify-content: space-between;
366
+ align-items: center;
367
+ }
368
+
369
+ .touchdown-title {
370
+ font-size: 12px;
371
+ font-weight: 600;
372
+ }
373
+
374
+ .touchdown-value {
375
+ font-size: 13px;
376
+ font-weight: 800;
377
+ color: var(--n-brand-light, #60a5fa);
378
+ }
379
+
380
+ .touchdown-progress-track {
381
+ width: 100%;
382
+ height: 8px;
383
+ border-radius: 4px;
384
+ background: #0f172a;
385
+ overflow: hidden;
386
+ }
387
+
388
+ .touchdown-progress-bar {
389
+ height: 100%;
390
+ border-radius: 4px;
391
+ transition: width 0.3s ease;
392
+ }
@@ -0,0 +1,27 @@
1
+ import type { DronesToolEntry, ToolLocaleContent } from '../../types';
2
+ import type { DroneMissionBatteryReservePlannerUI } from './ui';
3
+
4
+ export type { DroneMissionBatteryReservePlannerUI };
5
+ export type DroneMissionBatteryReservePlannerLocaleContent = ToolLocaleContent<DroneMissionBatteryReservePlannerUI>;
6
+
7
+ export const droneMissionBatteryReservePlanner: DronesToolEntry<DroneMissionBatteryReservePlannerUI> = {
8
+ id: 'drone-mission-battery-reserve-planner',
9
+ icons: { bg: 'mdi:drone', fg: 'mdi:battery-clock' },
10
+ i18n: {
11
+ de: () => import('./i18n/de').then((m) => m.content),
12
+ en: () => import('./i18n/en').then((m) => m.content),
13
+ es: () => import('./i18n/es').then((m) => m.content),
14
+ fr: () => import('./i18n/fr').then((m) => m.content),
15
+ id: () => import('./i18n/id').then((m) => m.content),
16
+ it: () => import('./i18n/it').then((m) => m.content),
17
+ ja: () => import('./i18n/ja').then((m) => m.content),
18
+ ko: () => import('./i18n/ko').then((m) => m.content),
19
+ nl: () => import('./i18n/nl').then((m) => m.content),
20
+ pl: () => import('./i18n/pl').then((m) => m.content),
21
+ pt: () => import('./i18n/pt').then((m) => m.content),
22
+ ru: () => import('./i18n/ru').then((m) => m.content),
23
+ sv: () => import('./i18n/sv').then((m) => m.content),
24
+ tr: () => import('./i18n/tr').then((m) => m.content),
25
+ zh: () => import('./i18n/zh').then((m) => m.content),
26
+ },
27
+ };
@@ -0,0 +1,23 @@
1
+ import type { MissionResults } from './logic';
2
+ import type { DroneMissionBatteryReservePlannerUI } from './ui';
3
+
4
+ export interface EvaluatorBadge {
5
+ label: string;
6
+ className: string;
7
+ }
8
+
9
+ export function evaluateMissionStatus(
10
+ results: MissionResults,
11
+ uiBadges: DroneMissionBatteryReservePlannerUI['statusBadges']
12
+ ): EvaluatorBadge {
13
+ switch (results.statusKey) {
14
+ case 'optimal':
15
+ return { label: uiBadges.optimal, className: 'status-badge--optimal' };
16
+ case 'tight':
17
+ return { label: uiBadges.tight, className: 'status-badge--tight' };
18
+ case 'critical':
19
+ return { label: uiBadges.critical, className: 'status-badge--critical' };
20
+ case 'exceeded':
21
+ return { label: uiBadges.exceeded, className: 'status-badge--exceeded' };
22
+ }
23
+ }
@@ -0,0 +1,223 @@
1
+ import type { DroneMissionBatteryReservePlannerLocaleContent } from '../entry';
2
+ import type { WithContext, SoftwareApplication, FAQPage, HowTo } from 'schema-dts';
3
+ import { bibliography } from '../bibliography';
4
+
5
+ const slug = 'drohnen-missions-akku-reserve-planer';
6
+ const title = 'Drohnen Missions Akku Reserve Planer';
7
+ const description = 'Berechnen Sie sichere Akku-Rückkehrreserven, Gegenwind-Leistungsverluste und maximale Einsatzradien für UAV-Flüge.';
8
+
9
+ const faqItems = [
10
+ {
11
+ question: 'Warum verbraucht das Fliegen gegen Gegenwind überproportional viel Energie?',
12
+ answer: 'Gegenwind erfordert einen steileren Neigungswinkel zur Überwindung des Luftwiderstands, was den Motorstromverbrauch exponenziell ansteigen lässt.',
13
+ },
14
+ {
15
+ question: 'Wie fließt die Verweilzeit am Zielort in den Point of No Return ein?',
16
+ answer: 'Die Einsatzzeit am Ziel zieht direkt Energie aus der nutzbaren Akkukapazität ab, bevor der verbleibende Transitradius berechnet wird.',
17
+ },
18
+ {
19
+ question: 'Was verursacht den Spannungsabfall unter Last bei LiPo-Akkus?',
20
+ answer: 'Hohe Stromstärken erhöhen die Verluste am Innenwiderstand der Lithiumzellen und verringern die effektiv nutzbare Energie.',
21
+ },
22
+ ];
23
+
24
+ const howToSteps = [
25
+ {
26
+ name: 'Akku- und Antriebsdaten eingeben',
27
+ text: 'Geben Sie Akkukapazität in Milliampere-Stunden, Nennspannung und durchschnittlichen Stromverbrauch ein.',
28
+ },
29
+ {
30
+ name: 'Flugdistanz und Zielzeit festlegen',
31
+ text: 'Bestimmen Sie die Einfachdistanz und die geplante Verweildauer über dem Zielgebiet.',
32
+ },
33
+ {
34
+ name: 'Windgeschwindigkeit und Richtung konfigurieren',
35
+ text: 'Wählen Sie Windgeschwindigkeit und Windrichtung bezogen auf den Hinflug.',
36
+ },
37
+ {
38
+ name: 'Sicherheitsradius und Telemetrie prüfen',
39
+ text: 'Analysieren Sie den berechneten Point of No Return, den Verbrauch pro Flugphase und den verbleibenden Akkustand.',
40
+ },
41
+ ];
42
+
43
+ const schemas: DroneMissionBatteryReservePlannerLocaleContent['schemas'] = [
44
+ {
45
+ '@context': 'https://schema.org',
46
+ '@type': 'FAQPage',
47
+ mainEntity: faqItems.map((item) => ({
48
+ '@type': 'Question',
49
+ name: item.question,
50
+ acceptedAnswer: { '@type': 'Answer', text: item.answer },
51
+ })),
52
+ } as WithContext<FAQPage>,
53
+ {
54
+ '@context': 'https://schema.org',
55
+ '@type': 'HowTo',
56
+ name: title,
57
+ description: description,
58
+ step: howToSteps.map((step, i) => ({
59
+ '@type': 'HowToStep',
60
+ position: i + 1,
61
+ name: step.name,
62
+ text: step.text,
63
+ })),
64
+ } as WithContext<HowTo>,
65
+ {
66
+ '@context': 'https://schema.org',
67
+ '@type': 'SoftwareApplication',
68
+ name: title,
69
+ description: description,
70
+ applicationCategory: 'UtilityApplication',
71
+ operatingSystem: 'Web',
72
+ offers: { '@type': 'Offer', price: '0', priceCurrency: 'EUR' },
73
+ } as WithContext<SoftwareApplication>,
74
+ ];
75
+
76
+ export const content: DroneMissionBatteryReservePlannerLocaleContent = {
77
+ slug,
78
+ title,
79
+ description,
80
+ ui: {
81
+ title: 'Drohnen Missions Akku Reserve Planer',
82
+ subtitle: 'Berechnen Sie Sicherheitsreserven für die Rückkehr, Windeinflüsse und Flugradien',
83
+ description: 'Präzise Berechnung der Akkureserve für Drohnenflüge mit Gegenwindanpassung und Point of No Return Schwellenwerten.',
84
+ sections: {
85
+ batteryPropulsion: '1. Akku & Antrieb',
86
+ flightAtmosphere: '2. Flugprofil & Atmosphäre',
87
+ },
88
+ inputs: {
89
+ unitSystemLabel: 'Einheitensystem',
90
+ metricLabel: 'Metrisch',
91
+ imperialLabel: 'Imperial',
92
+ presetLabel: 'Schnellkonfigurationen',
93
+ batteryCapacityLabel: 'Akkukapazität',
94
+ batteryVoltageLabel: 'Nennspannung',
95
+ averageCurrentLabel: 'Durchschnittlicher Reisestrom',
96
+ cruiseSpeedLabel: 'Eigengeschwindigkeit in der Luft',
97
+ oneWayDistanceLabel: 'Einfache Zielentfernung',
98
+ targetHoverTimeLabel: 'Einsatzdauer am Zielort',
99
+ windSpeedLabel: 'Windgeschwindigkeit',
100
+ windDirectionLabel: 'Windrichtung relativ zum Hinflug',
101
+ windHeadwindLabel: 'Gegenwind auf Hinflug',
102
+ windTailwindLabel: 'Rückenwind auf Hinflug',
103
+ windCrosswindLabel: 'Seitenwind',
104
+ reservePolicyLabel: 'Sicherheits-Reservepuffer',
105
+ },
106
+ presets: {
107
+ mappingSurvey: 'Fotogrammetrie & Vermessung',
108
+ fpvRecon: 'FPV Langstrecken-Erkundung',
109
+ cinematicInspection: 'Kineastische Bauwerksinspektion',
110
+ microRecon: 'Mikro-Drohnen-Erkundung',
111
+ surveyMeta: 'Vermessung',
112
+ scoutMeta: 'Erkundung',
113
+ hoverMeta: 'Schwebeflug',
114
+ },
115
+ results: {
116
+ totalCapacityEnergy: 'Gesamtkapazität Energie',
117
+ usableEnergy: 'Nutzbare Missionsenergie',
118
+ reserveEnergyBuffer: 'Reserve-Energiepuffer',
119
+ totalAutonomyTime: 'Gesamte Flugautonomie',
120
+ maxSafeMissionRadius: 'Point of No Return Radius',
121
+ outboundLegTime: 'Dauer Hinflug',
122
+ targetHoverTime: 'Dauer Zielverweilung',
123
+ returnLegTime: 'Dauer Rückflug',
124
+ totalMissionTime: 'Gesamte Transitdauer',
125
+ remainingEnergyLanding: 'Geschätzter Akkustand bei Landung',
126
+ feasibilityStatus: 'Bewertung der Einsatzdurchführbarkeit',
127
+ voltageSagSubLabel: 'Spannungsabfall',
128
+ maxRadiusSubLabel: 'Maximaler Sicherheitsradius mit Schwebeflug',
129
+ powerSubLabel: 'Leistung',
130
+ },
131
+ statusBadges: {
132
+ optimalTitle: 'OPTIMALER ENERGIERESERVE PUFFER',
133
+ optimalSubtitle: 'Sicheres Flugprofil mit ausreichender Landereserve',
134
+ tightTitle: 'KNAPPE AKKURESERVE WARNUNG',
135
+ tightSubtitle: 'Geringe Landereserve, überwachen Sie die Akkuspannung genau',
136
+ criticalTitle: 'KRITISCHE ENERGIEWARNUNG',
137
+ criticalSubtitle: 'Reserve unterschritten, leiten Sie sofort die Rückkehr ein',
138
+ exceededTitle: 'EINSATZ ÜBERSCHREITET SICHERE KAPAZITÄT',
139
+ exceededSubtitle: 'Unzureichende Energie für sichere Fertigstellung und Landung',
140
+ },
141
+ chart: {
142
+ batteryProfileTitle: 'NICHTLINEARES ENERGIE-VERTEILUNGSPROFIL',
143
+ modelTitle: 'AERODYNAMISCHES LEISTUNGS- UND WINDMODELL',
144
+ windLabel: 'Wind',
145
+ homeNode: 'START',
146
+ targetNode: 'ZIEL',
147
+ landNode: 'LANDUNG',
148
+ launchPadLabel: 'Startplatz',
149
+ surveyHoverLabel: 'Ziel-Schwebeflug',
150
+ safeRadiusLabel: 'Sicherheitsradius',
151
+ outboundSegment: 'Hinflug',
152
+ targetSegment: 'Schwebeflug',
153
+ returnSegment: 'Rückflug',
154
+ reserveSegment: 'Reserve',
155
+ },
156
+ },
157
+ seo: [
158
+ {
159
+ type: 'title',
160
+ text: 'Aerodynamische Leistungsverluste bei Gegenwind',
161
+ level: 2,
162
+ },
163
+ {
164
+ type: 'paragraph',
165
+ html: 'Die Flugsicherheit unbemannter Luftfahrzeuge basiert auf nichtlinearen physikalischen Gesetzen. Das Fliegen gegen den Wind erfordert eine stärkere Neigung, um den Luftwiderstand zu überwinden und die Bodengeschwindigkeit zu halten. Dies erhöht die erforderliche Schubleistung der Motoren und den Stromverbrauch exponentiell.',
166
+ },
167
+ {
168
+ type: 'paragraph',
169
+ html: 'Unser Planer berechnet dynamisch die Leistungsunterschiede für jeden Streckenabschnitt unter Berücksichtigung der Windverhältnisse.',
170
+ },
171
+ {
172
+ type: 'title',
173
+ text: 'Berücksichtigung der Verweilzeit im Zielgebiet',
174
+ level: 2,
175
+ },
176
+ {
177
+ type: 'paragraph',
178
+ html: 'Inspektions- und Vermessungsdrohnen verbringen viel Zeit im Schwebeflug über dem Ziel. Diese Phase verbraucht kontinuierlich Energie vor dem Rückflug. Die Point of No Return Formel zieht diese Energie vorab ab.',
179
+ },
180
+ {
181
+ type: 'list',
182
+ items: [
183
+ 'Geben Sie die geplante Verweildauer ein, bevor Sie Einsatzgrenzen berechnen.',
184
+ 'Berücksichtigen Sie Leistungsspitzen beim Hinflug gegen Gegenwind.',
185
+ 'Überwachen Sie den Spannungsabfall unter Last bei LiPo-Zellen.',
186
+ 'Leiten Sie die Rückkehr sofort bei Erreichen des Reservepuffers ein.',
187
+ ],
188
+ },
189
+ {
190
+ type: 'tip',
191
+ title: 'Warnung vor Spannungsabfall bei LiPo Akkus',
192
+ html: 'Hohe Entladeströme verursachen durch den Innenwiderstand von Lithium-Polymer-Zellen einen Spannungsabfall unter Last, was die nutzbare Energie verringert.',
193
+ },
194
+ {
195
+ type: 'title',
196
+ text: 'Formeln zur Berechnung der Akkureserve',
197
+ level: 2,
198
+ },
199
+ {
200
+ type: 'table',
201
+ headers: ['Parameter', 'Formel / Modell', 'Einheit'],
202
+ rows: [
203
+ ['Brutto-Energie', 'Kapazität (mAh) x Spannung (V) / 1000', 'Wattstunden (Wh)'],
204
+ ['Spannungsabfall-Verlust', 'Brutto-Energie x Sag-Faktor', 'Wattstunden (Wh)'],
205
+ ['Gegenwind-Leistung', 'Basis-Leistung x (1 + 0.65 x WindRatio)^1.3', 'Watt (W)'],
206
+ ['Maximaler Sicherheitsradius', '(Nutzbare Energie - Schwebe-Energie) / Verbrauch pro Km', 'Kilometer (km)'],
207
+ ],
208
+ },
209
+ {
210
+ type: 'title',
211
+ text: 'Bewährte Verfahren für die Flugplanung von Drohnen',
212
+ level: 2,
213
+ },
214
+ {
215
+ type: 'paragraph',
216
+ html: 'Vergleichen Sie stets automatische Telemetriedaten mit Vorflugberechnungen, um höchste Sicherheit bei allen gewerblichen UAV-Flügen zu gewährleisten.',
217
+ },
218
+ ],
219
+ faq: faqItems,
220
+ bibliography,
221
+ howTo: howToSteps,
222
+ schemas,
223
+ };