Espruino:Примеры/Карманный GPS-трекер, использующий систему OS Grid References

Материал из Онлайн справочника
Перейти к навигацииПерейти к поиску

Перевод: Максим Кузьмин
Проверка/Оформление/Редактирование: Мякишев Е.А.


Карманный 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();

См.также

Внешние ссылки