Serg4451D commited on
Commit
a440694
·
verified ·
1 Parent(s): 02da079

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +213 -19
index.html CHANGED
@@ -1,19 +1,213 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="ru">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Инерциальный трекер</title>
7
+ <!-- Подключаем библиотеку Leaflet.js для карт OpenStreetMap -->
8
+ <link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" crossorigin=""/>
9
+ <script src="https://unpkg.com/[email protected]/dist/leaflet.js" integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script>
10
+ <style>
11
+ body, html { margin: 0; padding: 0; height: 100%; font-family: sans-serif; }
12
+ #map { height: 60%; width: 100%; }
13
+ #info { padding: 10px; height: 35%; overflow-y: auto; background-color: #f0f0f0; }
14
+ #info p { margin: 5px 0; }
15
+ #startButton {
16
+ position: absolute;
17
+ top: 70px;
18
+ right: 10px;
19
+ z-index: 1000;
20
+ padding: 10px 15px;
21
+ font-size: 16px;
22
+ background-color: #4CAF50;
23
+ color: white;
24
+ border: none;
25
+ border-radius: 5px;
26
+ cursor: pointer;
27
+ }
28
+ #startButton.active {
29
+ background-color: #f44336;
30
+ }
31
+ </style>
32
+ </head>
33
+ <body>
34
+
35
+ <div id="map"></div>
36
+ <button id="startButton">Старт</button>
37
+
38
+ <div id="info">
39
+ <h3>Панель данных</h3>
40
+ <p><strong>Статус:</strong> Ожидание старта...</p>
41
+ <p><strong>Текущие координаты (вычисленные):</strong> <span id="lat">N/A</span>, <span id="lon">N/A</span></p>
42
+ <p><strong>Начальные GPS координаты:</strong> <span id="startLat">N/A</span>, <span id="startLon">N/A</span></p>
43
+ <p><strong>Скорость (м/с):</strong> X: <span id="velocityX">0</span>, Y: <span id="velocityY">0</span></p>
44
+ <p><strong>Ускорение (м/с²):</strong> X: <span id="accelX">0</span>, Y: <span id="accelY">0</span>, Z: <span id="accelZ">0</span></p>
45
+ <p><strong>Ориентация:</strong> &alpha; (yaw): <span id="alpha">0</span>, &beta; (pitch): <span id="beta">0</span>, &gamma; (roll): <span id="gamma">0</span></p>
46
+ <p style="color: red; font-weight: bold;">ВНИМАНИЕ: Позиция будет быстро накапливать ошибку и не будет соответствовать реальности!</p>
47
+ </div>
48
+
49
+ <script>
50
+ // --- Инициализация карты Leaflet ---
51
+ const map = L.map('map').setView([55.751244, 37.618423], 13); // Центр Москвы по умолчанию
52
+ L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
53
+ maxZoom: 19,
54
+ attribution: '© OpenStreetMap'
55
+ }).addTo(map);
56
+
57
+ let startMarker, currentMarker;
58
+ let isTracking = false;
59
+
60
+ // --- Переменные для инерциальной навигации ---
61
+ let lastTimestamp = null;
62
+ let velocity = { x: 0, y: 0 }; // Скорость в метрах/секунду (Восток, Север)
63
+ let currentPosition = { lat: 0, lon: 0 };
64
+ let orientation = { alpha: 0, beta: 0, gamma: 0 }; // Углы ориентации
65
+
66
+ const startButton = document.getElementById('startButton');
67
+
68
+ startButton.addEventListener('click', () => {
69
+ if (!isTracking) {
70
+ startTracking();
71
+ } else {
72
+ stopTracking();
73
+ }
74
+ });
75
+
76
+ function startTracking() {
77
+ // 1. Получаем точную начальную позицию через GPS
78
+ if (!navigator.geolocation) {
79
+ alert('Геолокация не поддерживается вашим браузером');
80
+ return;
81
+ }
82
+
83
+ document.querySelector('#info p:nth-child(1)').innerHTML = '<strong>Статус:</strong> Получение начальных GPS координат...';
84
+
85
+ navigator.geolocation.getCurrentPosition(position => {
86
+ currentPosition.lat = position.coords.latitude;
87
+ currentPosition.lon = position.coords.longitude;
88
+
89
+ document.getElementById('startLat').textContent = currentPosition.lat.toFixed(6);
90
+ document.getElementById('startLon').textContent = currentPosition.lon.toFixed(6);
91
+
92
+ // Ставим маркеры
93
+ if (startMarker) map.removeLayer(startMarker);
94
+ if (currentMarker) map.removeLayer(currentMarker);
95
+
96
+ startMarker = L.marker([currentPosition.lat, currentPosition.lon]).addTo(map)
97
+ .bindPopup('Начальная точка (GPS)').openPopup();
98
+ currentMarker = L.marker([currentPosition.lat, currentPosition.lon], {
99
+ icon: L.icon({ iconUrl: 'https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-red.png', shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/images/marker-shadow.png', iconSize: [25, 41], iconAnchor: [12, 41], popupAnchor: [1, -34], shadowSize: [41, 41] })
100
+ }).addTo(map)
101
+ .bindPopup('Текущая точка (ИНС)');
102
+
103
+ map.setView([currentPosition.lat, currentPosition.lon], 18);
104
+
105
+ // 2. Начинаем слушать сенсоры
106
+ lastTimestamp = performance.now();
107
+ window.addEventListener('deviceorientation', handleOrientation);
108
+ window.addEventListener('devicemotion', handleMotion);
109
+
110
+ isTracking = true;
111
+ startButton.textContent = 'Стоп';
112
+ startButton.classList.add('active');
113
+ document.querySelector('#info p:nth-child(1)').innerHTML = '<strong>Статус:</strong> Отслеживание активно...';
114
+
115
+ }, error => {
116
+ alert(`Ошибка получения GPS: ${error.message}`);
117
+ document.querySelector('#info p:nth-child(1)').innerHTML = '<strong>Статус:</strong> Ошибка GPS.';
118
+ });
119
+ }
120
+
121
+ function stopTracking() {
122
+ window.removeEventListener('deviceorientation', handleOrientation);
123
+ window.removeEventListener('devicemotion', handleMotion);
124
+ isTracking = false;
125
+ startButton.textContent = 'Старт';
126
+ startButton.classList.remove('active');
127
+ document.querySelector('#info p:nth-child(1)').innerHTML = '<strong>Статус:</strong> Остановлено.';
128
+ // Сброс скорости
129
+ velocity = { x: 0, y: 0 };
130
+ }
131
+
132
+ // --- Обработчики сенсоров ---
133
+ function handleOrientation(event) {
134
+ // Сохраняем ориентацию устройства
135
+ orientation.alpha = event.alpha; // Z-ось (рыскание, yaw)
136
+ orientation.beta = event.beta; // X-ось (тангаж, pitch)
137
+ orientation.gamma = event.gamma; // Y-ось (крен, roll)
138
+ document.getElementById('alpha').textContent = orientation.alpha.toFixed(2);
139
+ document.getElementById('beta').textContent = orientation.beta.toFixed(2);
140
+ document.getElementById('gamma').textContent = orientation.gamma.toFixed(2);
141
+ }
142
+
143
+ function handleMotion(event) {
144
+ if (lastTimestamp === null) {
145
+ lastTimestamp = performance.now();
146
+ return;
147
+ }
148
+
149
+ const now = performance.now();
150
+ const dt = (now - lastTimestamp) / 1000.0; // Дельта времени в секундах
151
+ lastTimestamp = now;
152
+
153
+ // Получаем ускорение устройства, ВКЛЮЧАЯ гравитацию
154
+ const accel = event.accelerationIncludingGravity;
155
+
156
+ // В настоящей ИНС здесь был бы Фильтр Калмана (на основе метода Гаусса)
157
+ // для отделения гравитации и получения истинного ускорения.
158
+ // Мы делаем очень грубое приближение, используя данные без гравитации, если они доступны
159
+ const linearAccel = event.acceleration;
160
+
161
+ // Для простоты будем использовать линейное ускорение, если оно есть.
162
+ // Оно все равно очень неточное.
163
+ let ax = linearAccel.x || 0;
164
+ let ay = linearAccel.y || 0;
165
+
166
+ // --- Это критически важный, но очень сложный шаг ---
167
+ // Нужно повернуть вектор ускорения из системы координат устройства
168
+ // в мировую систему координат (Север, Восток, Вверх).
169
+ // Это требует сложных матричных преобразований (кватернионов).
170
+ // Для демонстрации мы пропустим этот шаг и будем считать, что
171
+ // ay - это движение на Север, а ax - на Восток, что верно, только
172
+ // если телефон лежит на столе экраном вверх и "смотрит" на север.
173
+ // В реальности это приведет к мгновенной ошибке.
174
+ let worldAccel = {
175
+ x: ax, // Движение на Восток
176
+ y: ay // Движение на Север
177
+ };
178
+
179
+ // Двойное интегрирование (причина накопления ошибки)
180
+ // 1. Обновляем скорость
181
+ velocity.x += worldAccel.x * dt;
182
+ velocity.y += worldAccel.y * dt;
183
+
184
+ // 2. Обновляем позицию (расстояние в метрах)
185
+ const deltaX = velocity.x * dt;
186
+ const deltaY = velocity.y * dt;
187
+
188
+ // Конвертируем смещение в метрах в градусы широты и долготы
189
+ const R = 6378137; // Радиус Земли в метрах
190
+ const dLat = deltaY / R;
191
+ const dLon = deltaX / (R * Math.cos(Math.PI * currentPosition.lat / 180));
192
+
193
+ currentPosition.lat += dLat * 180 / Math.PI;
194
+ currentPosition.lon += dLon * 180 / Math.PI;
195
+
196
+ // Обновляем информацию на экране
197
+ document.getElementById('accelX').textContent = (ax).toFixed(2);
198
+ document.getElementById('accelY').textContent = (ay).toFixed(2);
199
+ document.getElementById('accelZ').textContent = (linearAccel.z || 0).toFixed(2);
200
+ document.getElementById('velocityX').textContent = velocity.x.toFixed(2);
201
+ document.getElementById('velocityY').textContent = velocity.y.toFixed(2);
202
+ document.getElementById('lat').textContent = currentPosition.lat.toFixed(6);
203
+ document.getElementById('lon').textContent = currentPosition.lon.toFixed(6);
204
+
205
+ // Обновляем позицию маркера на карте
206
+ currentMarker.setLatLng([currentPosition.lat, currentPosition.lon]);
207
+ // map.panTo([currentPosition.lat, currentPosition.lon]); // Раскомментируйте, чтобы карта следовала за маркером
208
+ }
209
+
210
+ </script>
211
+
212
+ </body>
213
+ </html>