GPSy…

Dodaliśmy do naszej oferty małe odbiorniki GPS. Tym razem trochę nas zaskoczyli dostawcy z Chin. Gdy przyszły do nas, ze zdziwieniem obserwowaliśmy drobne zadrapania na antenach (widać na zdjęciu). Wyglądały jakby pochodziły z demontażu. Jednak dostawcy zarzekają się że to są nówki sztuki. Aż się chce dodać – Niemiec płakał jak sprzedawał 😉

Tym dziwniejsze jest to, że moduły pochodzą od dwóch różnych dostawców i od obu wyglądają tak samo. Za parę tygodni powinny też przyjść kolejne, od trzeciego dostawcy, zobaczymy czy też będą z ryskami.

Dla porównania popatrzyliśmy uważnie na nasz testowy egzemplarz, kupiony w Polsce na Allegro. No i… w pierwszej chwili wydawał się inny, bez charakterystycznych zadrapań. Ale.. tylko dlatego, że została doklejona czysta naklejka maskująca spód. Pod nią – dobrze znane zadrapania.

Dlatego – sprawdziliśmy każdy egzemplarz czy łapie pozycję i teraz już pewni że wszystko w porządku – GPSy są dostępne do sprzedaży: https://nettigo.pl/products/modul-gps-z-antena-wewnetrzna-vk2828u7g5lf

Nagrywanie zjazdów snowboardem za pomocą Maliny.

Od czasu do czasu fajnie jest pooglądać wyczyny ekstremalnych sportowców i rajdowców w internecie. Ostatnio modne są nagrania z punktu widzenia bohatera za pomocą kamerki przyczepionej do kasku. Nie wiem jak tobie, ale mi zawsze brakowało przy nich jakiś parametrów jazdy jak w relacjach z F1.

Technika DIY się rozwija w ciekawych kierunkach. Od czasu, gdy mamy do dyspozycji tanie Raspberry Pi możemy o wiele więcej.
wymyślił jak do swoich wyczynów snowboardowych na video dodać parametry zjazdu.

Wykorzystał do tego płytkę Raspberry PI model B oraz moduł kamery Raspberry PI. Do określania parametrów użył modułu GPS oraz czujnika temperatury DS18B20.

Kamerę przyczepił do kasku i podłączył do Maliny za pomocą przewodu o długości 1 metra. Przewód owinął folią aluminiową, ponieważ zakłócał GPS. Moduł GPS podłączył do wejścia szeregowego w złączu GPIO.

Całe oprogramowanie zostało napisane w języku Python.
Do nagrywania obrazu z kamery wykorzystał moduł “picamera”, który umożliwia w bardzo łatwy sposób nagrywanie z kamery do pliku na karcie SD.

Dane nakładane na obraz są tworzone bardzo sprytnie. Zajmuje się tym moduł PIL (moduł do tworzenia grafiki w Pythonie). Wygenerowane obrazki z danymi zapisuje jako seria plików JPG. Po zakończaniu nagrywania, obrazki przetwarzane są na plik video za pomocą programu mencoder i dodawane do pliku z nagraną jazdą za pomocą programu MP4Box.

Tak wygląda wynik działania programu:

sprae

Teensy 3.1 – dzień III – wydajność

Dziś wielkie starcie. W prawym narożniku Arduino Leonardo. Zawodnik o wadze 16 MHz. W lewym Teensy 3.1. Jego zegar to 96 MHz.

Sprawdźmy ile razy bardziej wydajne jest Teensy 3.1 w porównaniu do jednej z najbardziej popularnych płytek Arduino Leonardo.

Dzielenie liczb liczb jest jedną z najbardziej czasochłonnych operacji dla procesora. Procesor ARM Cortex M4 w Teensy 3.1 ma specjalny rozkaz, dzięki któremu dzieli liczby sprzętowo.
Procesor AVR w Arduino Leonardo nie ma dzielenia sprzętowego i musi zastępować je kilkoma innymi operacjami.

To program który porówna wydajności w dzieleniu:

unsigned long sum;

void setup()
{
  while (!Serial);
  Serial.begin(9600);
}

void loop()
{
  Serial.println(F("Start"));
  unsigned long timeBegin = millis();
  for (int a=0; a<10000; a++)
  {
    for (int b=1; b<100; b++)
    {
      sum += a / b;
    }
  }
  
  unsigned long processTime = millis() - timeBegin;
  Serial.println(F("End"));
  Serial.print(F("Czas obliczen: "));
  Serial.println(processTime);
}

Program dzieli przez siebie milion liczb i mierzy czas tej operacji.

  • Arduino Leonardo zajęło to 14,978 s
  • Teensy 3.1 zajęło to 0,127 s

Czyli w dzieleniu Teensy okazało się 118 razy szybsze.

Kolejny test jest dość zabawny. Polega na uruchomieniu na obydwu płytkach tego samego emulatora procesora 6502. Na emulatorze uruchomiłem język EhBASIC. Cały kod pochodzi z wątku na forum Arduino, o którym niedawno pisałem.

Uznałem, że emulator to dobre środowisko by przetestować różnorodne operacje. W końcu to taki duży skomplikowany program, który robi dużo obliczeń, dużo komunikuje się z pamięcią Flash i RAM. Będzie dobrze odzwierciedlał ogólną wydajność procesora.

W języku BASIC napisałem prosty program zliczający od 0 do 10000.

Czas jego działania dla każdej płytki to:

  • Arduino Leonardo: 57,22 s
  • Teensy 3.1: 9,8 s

W tym teście Teensy nie ma już takiej ogromnej przewagi. Ale nadal jest prawie 6 razy szybsze.

Na koniec zostawiłem najmocniejszy test. Wziąłem algorytmy do obliczeń GPS ze starego projektu licznika rowerowego. Jest w nich dużo liczb zmiennoprzecinkowych (float) i masa różnych funkcji trygonometrycznych typu sin, cos, tan, atan2.

W oparciu o to, napisałem program, który oblicza trasę 36km z Płocka na zachód. Co 0.0001 stopień szerokości geograficznej.

float lat = 52.512204;
float lon = 19.675606;
float lonTo = 19.143456;

float oldLat = lat;
float oldLon = lon;

float angle;
float distance;

float getDistance(float latf, float lonf, float latt, float lont)
{
  float distance = acos(cos(latf)*cos(lonf)*cos(latt)*cos(lont)+cos(latf)*sin(lonf)*cos(latt)*sin(lont)+sin(latf)*sin(latt)) * 6378.137;
  return distance;
}

float lonTox(float lon)
{
  float x = (lon + PI) / (2 * PI) * 2.0;
  return x;
}

float latToy(float lat)
{
  float y = (1.0 - log(tan(lat) + (1 / cos(lat))) / PI);
  return y;
}

float getAngle(float latf, float lonf, float latt, float lont)
{
  float xf = lonTox(lonf);
  float yf = latToy(latf);
  float xt = lonTox(lont);
  float yt = latToy(latt);
  
  float x = xt - xf;
  float y = yt - yf;
  float angle = atan2(y, x);
  return angle;
}

void setup()
{
  while (!Serial);
  Serial.begin(9600);
}

void loop()
{
  Serial.println(F("Start"));
  unsigned long timeBegin = millis();
  for (float a=lon; a>lonTo; a-=0.0001)
  {
    distance += getDistance(oldLat, oldLon, lat, a);
    angle = getAngle(oldLat, oldLon, lat, a);
    oldLat = lat;
    oldLon = a;
  }
  
  unsigned long processTime = millis() - timeBegin;
  Serial.println(F("End"));
  Serial.print(F("Czas obliczen: "));
  Serial.println(processTime);
  
  Serial.print(F("Odleglosc: "));
  Serial.println(distance);
  Serial.print(F("Kat: "));
  Serial.println(angle);
  distance = 0.0;
  angle = 0.0;
}

Program pokazuje jak dobrze sprawdza się Teensy w autopilotach i innych podobnych systemach związanych z nawigacją, położeniem i obliczeniami z przecinkiem.

  • Arduino Leonardo policzyło trasę w 10,242 s
  • Teensy 3.1 policzyło trasę w 4,215 s

W takich obliczeniach Teensy okazało się 2,6 raza wydajniejsze od Arduino Leonardo.

BTW. Jeśli interesujecie się nawigacją to w tym teście macie gotowe funkcje do obsługi GPS.

Funkcja “getDistance” oblicza odległość między dwoma punktami geograficznymi. Argumenty to długość i szerokość geograficzna punktu początkowego i długość i szerokość geograficzna punktu końcowego. Argumenty podajemy w radianach, a nie stopniach – co mi się zapomniało ;-).

Funkcja “getAngle” oblicza kąt pod jakim jest punkt geograficzny od nas względem zachodu. Jej argumenty są takie same jak “getDistance”.

Funkcje “latToy” i “lonTox” zamieniają długość i szerokość geograficzną na współrzędne punktu  x, y na płaskiej mapie.

Teensy 3.1 siłą rzeczy jest wydajniejsze od Arduino Leonardo. Dzięki testom dowiedziałeś się jak bardzo i w jakich operacjach radzi sobie najlepiej.

Pozytywnie zaskoczyło mnie dziś to, że programy pod Teensy obsługują pamięć Flash tak jak w Arduino. Można używać F() do tekstów. Autor Teensy przeniósł nawet bibliotekę “/avr/pgmspace.h”, żeby biblioteki Arduino obsługujące Flash działały na Teensy bez modyfikacji.

sprae