Espruino:Примеры/Карманный GPS-трекер, использующий систему OS Grid References: различия между версиями
Myagkij (обсуждение | вклад) (Новая страница: «{{Espruino/Панель перехода}} {{Перевод от Сubewriter}} {{Myagkij-редактор}} =<ref>[ www.espruino.com - ]</ref>= <syntaxhighligh...») |
Нет описания правки |
||
(не показаны 2 промежуточные версии 2 участников) | |||
Строка 3: | Строка 3: | ||
{{Myagkij-редактор}} | {{Myagkij-редактор}} | ||
=<ref>[ www.espruino.com - ]</ref>= | =Карманный GPS-трекер, использующий систему OS Grid References<ref>[https://www.espruino.com/Pocket+Walking+GPS www.espruino.com - Pocket 'walking' GPS]</ref>= | ||
В Великобритании все карты пешеходных маршрутов используют систему [https://en.wikipedia.org/wiki/Ordnance_Survey_National_Grid OS Grid References]. То есть, зная всего одно число, вы можете узнать своё точное местонахождение. | |||
Это очень полезная технология, которая встроена в большинство [[GPS-трекер]]ов. Однако зачастую, чтобы добраться до нужного меню, нужно сделать очень много лишних пальцедвижений. Но что, если бы у вас было простое, маленькое устройство, которое делало бы всего одну вещь: показывало OS-координаты вашего местонахождения при помощи большого и удобочитаемого текста? | |||
== Вам понадобятся == | |||
* Одна [https://www.espruino.com/Original плата Espruino] | |||
* [https://www.espruino.com/PCD8544 LCD-дисплей Nokia 5110] | |||
* [https://www.espruino.com/GPS GPS-модуль] | |||
* [https://www.espruino.com/Battery Батарея] | |||
== Подключение == | |||
Просто подключите [https://www.espruino.com/GPS GPS-модуль] и [https://www.espruino.com/PCD8544 LCD-дисплей Nokia 5110] как описано на их страницах. Это всё! | |||
== Код == | |||
Немного погуглив, я нашёл [http://www.movable-type.co.uk/scripts/latlong-os-gridref.html отличный JavaScript-код], преобразующий обычные ширину и долготу в OS-координаты. Он заметно упрощает нашу задачу. Сам код смотрите ниже: | |||
<syntaxhighlight lang="javascript"> | |||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ | |||
/* Код для использования Ordnance Survey Grid Reference | |||
(c) Крис Венесс 2005-2014 */ | |||
/* - www.movable-type.co.uk/scripts/gridref.js */ | |||
/* - www.movable-type.co.uk/scripts/latlon-gridref.html */ | |||
/* - - - - - - - - - - - - - - - - --- - - - - - - - - - - - - - - */ | |||
function OsGridRef(easting, northing) { | |||
this.easting = 0|easting; | |||
this.northing = 0|northing; | |||
} | |||
OsGridRef.latLongToOsGrid = function(point) { | |||
var lat = point.lat.toRad(); | |||
var lon = point.lon.toRad(); | |||
// Большая и малая полуоси эллипсоида Airy 1830: | |||
var a = 6377563.396, b = 6356256.909; | |||
// Фактор масштабирования NatGrid для центрального меридиана: | |||
var F0 = 0.9996012717; | |||
// Абсолютное начало координат NatGrid – 49°N, 2°W: | |||
var lat0 = (49).toRad(), lon0 = (-2).toRad(); | |||
// Расстояние к северу и востоку | |||
// от абсолютного начала координат (в метрах): | |||
var N0 = -100000, E0 = 400000; | |||
// Эксцентриситет в квадрате: | |||
var e2 = 1 - (b*b)/(a*a); | |||
var n = (a-b)/(a+b), n2 = n*n, n3 = n*n*n; | |||
var cosLat = Math.cos(lat), sinLat = Math.sin(lat); | |||
// радиус кривизны, перпендикулярный меридиану: | |||
var nu = a*F0/Math.sqrt(1-e2*sinLat*sinLat); | |||
// меридианный радиус кривизны: | |||
var rho = a*F0*(1-e2)/Math.pow(1-e2*sinLat*sinLat, 1.5); | |||
var eta2 = nu/rho-1; | |||
var Ma = (1 + n + (5/4)*n2 + (5/4)*n3) * (lat-lat0); | |||
var Mb = (3*n + 3*n*n + (21/8)*n3) * Math.sin(lat-lat0) * Math.cos(lat+lat0); | |||
var Mc = ((15/8)*n2 + (15/8)*n3) * Math.sin(2*(lat-lat0)) * Math.cos(2*(lat+lat0)); | |||
var Md = (35/24)*n3 * Math.sin(3*(lat-lat0)) * Math.cos(3*(lat+lat0)); | |||
// меридианная арка: | |||
var M = b * F0 * (Ma - Mb + Mc - Md); | |||
var cos3lat = cosLat*cosLat*cosLat; | |||
var cos5lat = cos3lat*cosLat*cosLat; | |||
var tan2lat = Math.tan(lat)*Math.tan(lat); | |||
var tan4lat = tan2lat*tan2lat; | |||
var I = M + N0; | |||
var II = (nu/2)*sinLat*cosLat; | |||
var III = (nu/24)*sinLat*cos3lat*(5-tan2lat+9*eta2); | |||
var IIIA = (nu/720)*sinLat*cos5lat*(61-58*tan2lat+tan4lat); | |||
var IV = nu*cosLat; | |||
var V = (nu/6)*cos3lat*(nu/rho-tan2lat); | |||
var VI = (nu/120) * cos5lat * (5 - 18*tan2lat + tan4lat + 14*eta2 - 58*tan2lat*eta2); | |||
var dLon = lon-lon0; | |||
var dLon2 = dLon*dLon, dLon3 = dLon2*dLon, dLon4 = dLon3*dLon, dLon5 = dLon4*dLon, dLon6 = dLon5*dLon; | |||
var N = I + II*dLon2 + III*dLon4 + IIIA*dLon6; | |||
var E = E0 + IV*dLon + V*dLon3 + VI*dLon5; | |||
return new OsGridRef(E, N); | |||
}; | |||
// --------------- Функция-обёртка, необходимая, чтобы всё заработало: | |||
Number.prototype.toRad = function() { | |||
return this*Math.PI/180; | |||
}; | |||
SPI3.setup({ baud: 1000000, sck:B3, mosi:B5 }); | |||
var g; | |||
function onInit() { | |||
// Мы настраиваем LCD-дисплей здесь, | |||
// потому что он должен быть инициализирован | |||
// сразу при включении питания: | |||
g = require("PCD8544").connect(SPI3,B6,B7,B8, function () { | |||
// Это вызывается при инициализации... | |||
g.clear(); | |||
g.drawString("Загрузка...", 20,20); | |||
g.flip(); | |||
}); | |||
} | |||
Serial4.setup(9600,{tx:C10,rx:C11}); | |||
var gps = require("GPS").connect(Serial4, function(data) { | |||
var os = OsGridRef.latLongToOsGrid(data); | |||
g.clear(); | |||
g.setFontBitmap(); | |||
g.drawString("Northing", 10,0); | |||
g.drawString("Easting", 10,24); | |||
g.setFontVector(14); | |||
g.drawString(os.northing, 0,5); | |||
g.drawString(os.easting, 0,29); | |||
g.flip(); | |||
}); | |||
onInit(); | |||
</syntaxhighlight> | </syntaxhighlight> | ||
=См.также= | =См.также= | ||
=Внешние ссылки= | =Внешние ссылки= | ||
Строка 18: | Строка 134: | ||
<references /> | <references /> | ||
{{Навигационная таблица/Espruino | {{Навигационная таблица/Портал/Espruino}} | ||
Текущая версия от 19:55, 23 мая 2023
Карманный GPS-трекер, использующий систему OS Grid References[1]
В Великобритании все карты пешеходных маршрутов используют систему OS Grid References. То есть, зная всего одно число, вы можете узнать своё точное местонахождение.
Это очень полезная технология, которая встроена в большинство GPS-трекеров. Однако зачастую, чтобы добраться до нужного меню, нужно сделать очень много лишних пальцедвижений. Но что, если бы у вас было простое, маленькое устройство, которое делало бы всего одну вещь: показывало OS-координаты вашего местонахождения при помощи большого и удобочитаемого текста?
Вам понадобятся
Подключение
Просто подключите GPS-модуль и LCD-дисплей Nokia 5110 как описано на их страницах. Это всё!
Код
Немного погуглив, я нашёл отличный JavaScript-код, преобразующий обычные ширину и долготу в OS-координаты. Он заметно упрощает нашу задачу. Сам код смотрите ниже:
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* Код для использования Ordnance Survey Grid Reference
(c) Крис Венесс 2005-2014 */
/* - www.movable-type.co.uk/scripts/gridref.js */
/* - www.movable-type.co.uk/scripts/latlon-gridref.html */
/* - - - - - - - - - - - - - - - - --- - - - - - - - - - - - - - - */
function OsGridRef(easting, northing) {
this.easting = 0|easting;
this.northing = 0|northing;
}
OsGridRef.latLongToOsGrid = function(point) {
var lat = point.lat.toRad();
var lon = point.lon.toRad();
// Большая и малая полуоси эллипсоида Airy 1830:
var a = 6377563.396, b = 6356256.909;
// Фактор масштабирования NatGrid для центрального меридиана:
var F0 = 0.9996012717;
// Абсолютное начало координат NatGrid – 49°N, 2°W:
var lat0 = (49).toRad(), lon0 = (-2).toRad();
// Расстояние к северу и востоку
// от абсолютного начала координат (в метрах):
var N0 = -100000, E0 = 400000;
// Эксцентриситет в квадрате:
var e2 = 1 - (b*b)/(a*a);
var n = (a-b)/(a+b), n2 = n*n, n3 = n*n*n;
var cosLat = Math.cos(lat), sinLat = Math.sin(lat);
// радиус кривизны, перпендикулярный меридиану:
var nu = a*F0/Math.sqrt(1-e2*sinLat*sinLat);
// меридианный радиус кривизны:
var rho = a*F0*(1-e2)/Math.pow(1-e2*sinLat*sinLat, 1.5);
var eta2 = nu/rho-1;
var Ma = (1 + n + (5/4)*n2 + (5/4)*n3) * (lat-lat0);
var Mb = (3*n + 3*n*n + (21/8)*n3) * Math.sin(lat-lat0) * Math.cos(lat+lat0);
var Mc = ((15/8)*n2 + (15/8)*n3) * Math.sin(2*(lat-lat0)) * Math.cos(2*(lat+lat0));
var Md = (35/24)*n3 * Math.sin(3*(lat-lat0)) * Math.cos(3*(lat+lat0));
// меридианная арка:
var M = b * F0 * (Ma - Mb + Mc - Md);
var cos3lat = cosLat*cosLat*cosLat;
var cos5lat = cos3lat*cosLat*cosLat;
var tan2lat = Math.tan(lat)*Math.tan(lat);
var tan4lat = tan2lat*tan2lat;
var I = M + N0;
var II = (nu/2)*sinLat*cosLat;
var III = (nu/24)*sinLat*cos3lat*(5-tan2lat+9*eta2);
var IIIA = (nu/720)*sinLat*cos5lat*(61-58*tan2lat+tan4lat);
var IV = nu*cosLat;
var V = (nu/6)*cos3lat*(nu/rho-tan2lat);
var VI = (nu/120) * cos5lat * (5 - 18*tan2lat + tan4lat + 14*eta2 - 58*tan2lat*eta2);
var dLon = lon-lon0;
var dLon2 = dLon*dLon, dLon3 = dLon2*dLon, dLon4 = dLon3*dLon, dLon5 = dLon4*dLon, dLon6 = dLon5*dLon;
var N = I + II*dLon2 + III*dLon4 + IIIA*dLon6;
var E = E0 + IV*dLon + V*dLon3 + VI*dLon5;
return new OsGridRef(E, N);
};
// --------------- Функция-обёртка, необходимая, чтобы всё заработало:
Number.prototype.toRad = function() {
return this*Math.PI/180;
};
SPI3.setup({ baud: 1000000, sck:B3, mosi:B5 });
var g;
function onInit() {
// Мы настраиваем LCD-дисплей здесь,
// потому что он должен быть инициализирован
// сразу при включении питания:
g = require("PCD8544").connect(SPI3,B6,B7,B8, function () {
// Это вызывается при инициализации...
g.clear();
g.drawString("Загрузка...", 20,20);
g.flip();
});
}
Serial4.setup(9600,{tx:C10,rx:C11});
var gps = require("GPS").connect(Serial4, function(data) {
var os = OsGridRef.latLongToOsGrid(data);
g.clear();
g.setFontBitmap();
g.drawString("Northing", 10,0);
g.drawString("Easting", 10,24);
g.setFontVector(14);
g.drawString(os.northing, 0,5);
g.drawString(os.easting, 0,29);
g.flip();
});
onInit();
См.также
Внешние ссылки