Image
1.7.2016 0 Comments

Vývoj pre Android – Využitie senzorov / 14. časť

Späť na úvod >> Späť na seriál

Moderné smartfóny a tablety majú bohatú senzorovú výbavu - spravidla ide o kompas, akcelerometer, gyroskop, merač intenzity osvetlenia, náklonomer a systém na určovanie polohy. Náklonomer a akcelerometer majú v tabletoch veľmi dôležitú funkciu, umožňujú nielen zistenie aktuálnej orientácie prístroja (na výšku či na šírku), ale pretože tablet nemá žiadne kurzorové tlačidlá ani nijaký ekvivalent joysticku, využíva sa naklápanie prístroja veľmi často aj na ovládanie hier.

Na ilustráciu možností predstavíme senzorovú výbavu Galaxy S5.

  • Proximity Sensor - v telefónoch meria vzdialenosť od ucha. Využíva sa na vypnutie dotykovej obrazovky počas priloženia telefónu k uchu.
  • Gyroskop - meria pootočenie zariadenia v trojrozmernom priestore.
  • Akcelerometer - meria pohyb zariadenia v trojrozmernom priestore.
  • Magnetický senzor - umožňuje funkciu digitálneho kompasu, prípadne vytvorenie aplikácie na hľadanie kovových predmetov v stene.
  • Barometer - meria atmosférický tlak v aktuálnom umiestnení, takže umožňuje vytvárať aplikácie typu výškomera.
  • Hall Sensor - magnetický senzor slúži na indikáciu otvorenia či zatvorenia krytu prístroja.
  • Light Sensor - meria intenzitu okolitého svetla. Slúži na automatické prispôsobenie jasu displeja okolitým svetelným podmienkam.
  • Gesture Sensor - infračervené pole sníma gestá používateľa nad displejom.
  • Snímač tepovej frekvencie - dvojica diód pod objektívom; červená osvetľuje priložený koniec prsta a snímacia meria zmenu intenzity osvetlenia v závislosti od toho, ako vo vlásočniciach pulzuje krv.

Okrem izolovaných údajov z jednotlivých senzorov poskytuje firmvér telefónu alebo tabletu aj komplexné informácie o dynamických zmenách polohy telefónu. Existujú totiž fyzické obmedzenia jednotlivých senzorov, pre ktoré môže byť ťažké určiť skutočnú orientáciu a pohyb zariadenia zo surových údajov z jednotlivých senzorov. Napríklad údaje z akcelerometra sú odvodené od zotrvačnosti vyplývajúcej z pohybu zariadenia. Gyroskop meria rýchlosť otáčania, no nie polohu. Preto sú v operačnom systéme implementované zložité geometrické výpočty, ktoré sú potrebné na zistenie polohy, orientácie a pohybu zo surových dát z jednotlivých senzorov. Na platforme Android ide o TYPE_ORIENTATION. Takéto informácie sú dôležité pre aplikácie pracujúce s rozšírenou realitou (augmented reality), ide hlavne o polohu, rotačné zrýchlenie a lineárne zrýchlenie.

Získavanie údajov zo senzorov

SensorManager je systémová služba na riadenie senzorov. Inštanciu objektu SensorManager získate pomocou metódy

getSystemService(Context.SENSOR_SERVICE)

Na prístup ku konkrétnemu senzoru využijete metódu

SensorManager.getDefaultSensor(int typ)

Senzor sa vyberá pomocou parametra typ:

  • TYPE_ACCELEROMETER - zrýchlenie v m/s2 v troch fyzických osiach (x, y, a z)
  • TYPE_AMBIENT_TEMPERATURE - teplota vzduchu miestnosti v °C
  • TYPE_GRAVITY - gravitačné zrýchlenie v m/s2 v troch osiach (x, y, z)
  • TYPE_GYROSCOPE - meria zrýchlenie rotácie v rad/s okolo troch osí (x, y, a z)
  • TYPE_LIGHT - meria osvetlenie v luxoch (lx)
  • TYPE_LINEAR_ACCELERATION - meria zrýchlenie v m/s2 bez vplyvu gravitácie v osiach (x, y, z)
  • TYPE_MAGNETIC_FIELD - hodnota geomagnetického poľa v troch osiach (x, y, z) v jednotkách μT
  • TYPE_ORIENTATION - komplexná informácia z viacerých senzorov - poloha, rotácia zariadenia okolo troch osí (x, y, z)
  • TYPE_PRESSURE - meria okolitý atmosférický tlak v jednotkách hPa alebo mbar
  • TYPE_PROXIMITY - meria vzdialenosť objektu v cm od displeja zariadenia
  • TYPE_RELATIVE_HUMIDITY - vlhkosť okolitého vzduchu v percentách (%)
  • TYPE_ROTATION_VECTOR - orientácia zariadenia vo vzťahu k trom vektorom
  • TYPE_TEMPERATURE - teplota v (°C)

Aplikácia získava údaje z vybraného senzora cez SensorEventListener, ktorý volá metódu onSensorChanged() po každej zmene hodnoty nameranej senzorom. Pri zmene presnosti merania sa volá procedúra onAccuracyChanged(). Poloha zariadenia sa určuje vzhľadom na tri osi x, y a z. Mapovanie osí na zariadenie sa po zmene jeho polohy nemení.

Poloha zariadenia sa určuje vo vzťahu k trom osiam x, y a z

Príklad - zobrazenie údajov z akcelerometra

Väčšina androidových zariadení disponuje akcelerometrom schopným merať zrýchlenie v troch osiach. V aplikáciách sa dá využiť napríklad na snímanie dynamiky pohybu pri ovládaní. V jednoduchom príklade vypíšeme hodnoty zrýchlenia v osiach X, Y a Z.

V aplikácii použijeme pripojenie na senzor TYPE_ACCELEROMETER, takže budú načítané absolútne hodnoty zrýchlenia, v osi Y sa teda aj v pokojovom stave zariadenia prejaví hodnota gravitačného zrýchlenia. V kóde hlavnej aktivity si všimnite, že listener pre senzor akcelerometra sa zakaždým deaktivuje, aby sa šetrila energia z batérie. Hodnota zrýchlenia sa načíta v metóde onSensorChanged(). Aby sa zobrazené hodnoty dali prečítať, aktualizuje sa hodnota každých 500 ms, teda vždy po pol sekunde. V tejto jednoduchej aplikácii zmenu presnosti, ktorá volá metódu onAccuracyChanged(), ignorujeme. Údaje sa vypisujú pomocou prvkov TextView.

public class MainActivity extends Activity implements SensorEventListener
{
private static final int INTERVAL = 500;
private SensorManager SM;
private Sensor acl; //akcelerometer
private TextView tvX, tvY, tvZ;
private long tAktual; //posledná aktualizácia
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvX = (TextView) findViewById(R.id.x_hodnota);
tvY = (TextView) findViewById(R.id.y_hodnota);
tvZ = (TextView) findViewById(R.id.z_hodnota);
SM = (SensorManager) getSystemService(SENSOR_SERVICE);
if ((acl = SM
.getDefaultSensor(Sensor.TYPE_ACCELEROMETER))==null)
finish();
}
@Override
protected void onResume()
{
super.onResume();
SM.registerListener(this, acl,
SensorManager.SENSOR_DELAY_UI);
tAktual = System.currentTimeMillis();
}
@Override
protected void onPause()
{
SM.unregisterListener(this);
super.onPause();
}
@Override
public void onSensorChanged(SensorEvent event)
{
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
{
long at = System.currentTimeMillis();
if (at - tAktual > INTERVAL)
{
tAktual = actualTime;
float x = event.values[0], y = event.values[1],
z = event.values[2];
tvX.setText(String.valueOf(x));
tvY.setText(String.valueOf(y));
tvZ.setText(String.valueOf(z));
}
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy)
{}
}

Teraz môžete aplikáciu spustiť. Skúste najskôr pohybovať zariadením v polohe podľa obrázka, na ktorom je súradnicový systém. Následne otáčajte zariadením a pozorujte, ako sa menia hodnoty v jednotlivých osiach, hlavne ich znamienka. Ak je zariadenie v pokoji, nameriate pri použití senzora TYPE_ACCELEROMETER v osi y hodnotu 9.81, čo je gravitačné zrýchlenie.

senzor2.png

Zobrazenie výstupov z akcelerometra

Pri tomto príklade platí modifikované úslovie „za málo úsilia málo úžitkovej hodnoty". Pozornejší čitatelia si určite na obrázku behu aplikácie všimli nezrovnalosť v hodnotách osí X a Y. Obrázok je totiž zosnímaný z tabletu Lenovo Yoga 10, obráteného na výšku. Na niektorých tabletoch sa totiž predpokladá základná orientácia na šírku, napríklad pre zabudovaný stojan. Pri týchto prístrojoch je súradnicová sústava oproti telefónom natočená o 90 stupňov, to znamená, že os Y je v smere kratšej hrany. Preto hodnota blízka 9,81 je na takomto tablete v osi X. Keby ste telefón alebo tablet pootočili o 45 stupňov, gravitačné zrýchlenie sa rovnomerne rozdelí do osí X a Y.

Ako riešiť tento problém, aby akcelerometer fungoval v každej polohe zariadenia? Pri pokusoch s aplikáciou v predchádzajúcej stati ste asi zistili, že sa prejavujú dve zložky zrýchlenia - malé zmeny spôsobené dynamickými otrasmi a dlhodobé pomalé zmeny, prípadne hodnoty posunuté o konštantu gravitačného zrýchlenia. Aby sme vedeli tieto hodnoty separovať, je účelné aplikovať na údaje z akcelerometra dva filtre. Filter typu horný priepust, ktorý prenesie len krátkodobé zmeny, napríklad otrasy, a dolný priepust, ktorý, naopak, tieto otrasy zadrží. Metódy na aplikáciu filtra horného a dolného priepustu sú pomerne jednoduché. Low pass filter vracia takzvaný vážený priemer, kde je 80 percent dlhodobej hodnoty + 20 percent aktuálne načítanej hodnoty:

private float lowPass(float akt, float grav)
{
return grav * 0.8f + akt * (1 - 0.8f);
}
private float highPass(float akt, float grav)
{
return akt - grav;
}

Skrátený kód hlavnej aktivity:

public class MainActivity extends Activity implements SensorEventListener
{
private SensorManager SM;
private Sensor acl; //akcelerometer
private float[] aAcel = new float[3];
private float[] aGrav = new float[3];
private TextView tvX, tvY,tvZ, tvXhi, tvYhi,tvZhi,
tvXlo, tvYlo,tvZlo ;
private long akt;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);
tvX = (TextView) findViewById(R.id.x_hodnota);

SM = (SensorManager) getSystemService(SENSOR_SERVICE);
if ((acl = SM.getDefaultSensor(Sensor.TYPE_ACCELEROMETER))==null)
finish();
akt = System.currentTimeMillis();
}
@Override
protected void onResume()
{
super.onResume();
SM.registerListener(this, acl,
SensorManager.SENSOR_DELAY_UI);
}
@Override
protected void onPause()
{
super.onPause();
SM.unregisterListener(this);
}
@Override
public void onSensorChanged(SensorEvent event)
{
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
{
long actualTime = System.currentTimeMillis();
if (actualTime - akt > 500)
{
akt = actualTime;
float rawX = event.values[0];
...
//low-pass filter
aGrav[0] = lowPass(rawX, aGrav[0]);
...
//high-pass filter
aAcel[0] = highPass(rawX, aGravitace[0]);

tvX.setText(String.valueOf(rawX));
...
tvXhi.setText(String.valueOf(aGrav[0]));
...
tvXlo.setText(String.valueOf(aAcel[0]));
..
}
}
}
}

Ako ilustráciu netradičného využitia akcelerometra môžete vytvoriť aplikáciu, ktorá premení telefón alebo tablet na fitnes pomôcku, napríklad na precvičenie zmeravených rúk pri práci s počítačom. Stačí držať tablet v predpažených rukách displejom k sebe a pohybovať ním od seba a k sebe, a to čo najrýchlejšie. Na základe údajov z akcelerometra (os Z) sa na jednoduchých stupniciach zobrazuje aktuálne zrýchlenie, akumulované zrýchlenie a časový progres.

 

Zobrazit Galériu

Nechajte si posielať prehľad najdôležitejších správ emailom

Mohlo by Vás zaujímať

ITPro

Linux súkromne i pracovne v2.0 (14. časť): Small Business Server

09.11.2016 14:57

Pojem Small Business Server (malý firemný server) začala používať spoločnosť Microsoft ešte v roku 2000 na označenie servera, ktorý ­dokázal plniť úlohy niekoľkých samostatných serverov. Aplikačná vrs ...

ITPro

Industry 4.0: Fikcia alebo už realita?

09.11.2016 14:52

Štvrtá priemyselná revolúcia je pomenovanie rozsiahlych zmien prudko vstupujúcich do súčasného priemyslu. Nositeľom týchto zmien je digitalizácia výroby a optimalizácia všetkých podnikových procesov v ...

ITPro

Vývoj aplikácií UWP pre Xbox One II.

09.11.2016 14:47

V predošlej časti sme ukázali postup, ako si ­vytvoriť vývojársky účet a aktivovať vývojársky režim na hernej konzole Xbox One, aby ste mohli testovať svoje aplikácie. Výhodou hernej konzoly Xbox je v ...

Žiadne komentáre

Vyhľadávanie

Kyocera - prve-zariadenia-formatu-a4-s-vykonom-a3

Najnovšie videá