VÝVOJ APLIKÁCIÍ PRE WINDOWS 8

Využitie senzorov

Mo­der­né tab­le­ty a kon­ver­ti­bil­né za­ria­de­nia pod tak­tov­kou ope­rač­né­ho sys­té­mu Win­dows 8.1 sú vy­ba­ve­né nie­koľ­ký­mi uži­toč­ný­mi sen­zor­mi, kto­ré mô­že­te vy­užiť vo svo­jich ap­li­ká­ciách. Spra­vid­la ide o kom­pas, ak­ce­le­ro­me­ter, gy­ros­kop, nák­lo­no­mer a sní­mač in­ten­zi­ty os­vet­le­nia. Nák­lo­no­mer a ak­ce­le­ro­me­ter ma­jú v tab­le­toch veľ­mi dô­le­ži­tú fun­kciu, umož­ňu­jú nie­len zis­te­nie ak­tuál­nej orien­tá­cie prís­tro­ja (na vý­šku či na šír­ku), ale keď­že tab­let ne­má žiad­ne kur­zo­ro­vé tla­čid­lá ani ni­ja­ký ek­vi­va­lent joys­tic­ku, vy­uží­va sa nak­lá­pa­nie prís­tro­ja veľ­mi čas­to aj na ov­lá­da­nie hier.

Mož­nos­ti sen­zo­rov bu­de­me de­monštro­vať na jed­no­du­chých prak­tic­kých prík­la­doch reál­nych ap­li­ká­cií auto­ra člán­ku, kto­ré náj­de­te vo Win­dows ob­cho­de. V ap­li­ká­cii mu­sí­te po­čí­tať aj s tým, že niek­to­ré za­ria­de­nie prís­luš­ný sen­zor ne­pod­po­ru­je. Ak si pou­ží­va­teľ ap­li­ká­ciu nain­šta­lu­je na kla­sic­kom no­te­boo­ku bez sen­zo­ra, zob­ra­zí sa mu upo­zor­ne­nie na tú­to sku­toč­nosť a zvy­šok fun­kcio­na­li­ty bu­de za­blo­ko­va­ný. Sku­toč­nosť, že va­ša ap­li­ká­cia vy­uží­va sen­zo­ry, tre­ba dek­la­ro­vať aj v špe­ciál­nych po­žia­dav­kách pre ap­li­ká­ciu vo Win­dows ob­cho­de. Do kó­du ap­li­ká­cií mu­sí­me pri­dať re­fe­ren­ciu na men­né pries­to­ry.

using Win­dows.De­vi­ces.Sen­sors;
using Win­dows.UI.Co­re;

Mag­ne­tic­ký kom­pas

Ap­li­ká­cie ty­pu kom­pas vy­uží­va­jú po­lo­vo­di­čo­vý sen­zor na me­ra­nie mag­ne­tic­ké­ho po­ľa. Umož­ňu­jú ur­čiť orien­tá­ciu za­ria­de­nia vzhľa­dom na se­ver­ný mag­ne­tic­ký pól. Na pre­zen­to­va­nie sa naj­čas­tej­šie pou­ží­va kru­ho­vá stup­ni­ca s ob­ráz­kom tzv. mag­ne­tic­ké­ho krí­ža, kto­rý preh­ľad­ne uka­zu­je hlav­né sve­to­vé stra­ny. Na jej otá­ča­nie sa dá vy­užiť ani­má­cia.

Main­Pa­ge.xaml
<Grid
<Grid.Re­sour­ces>
<Sto­ry­board x:Na­me="Sto­ry­board">
<Doub­leA­ni­ma­tion x:Na­me="daA­nim"
Sto­ry­board.Tar­get­Na­me="Ro­ta­teI­ma­ge"
Sto­ry­board.Tar­get­Pro­per­ty="(UIEle­ment.Ren­derTran­sform)
.(Ro­ta­teT­ran­sform.Ang­le)"
From="0" To="360" Du­ra­tion="00:00:1.000" />
</Sto­ry­board>
</Grid.Re­sour­ces>
<Ima­ge x:Na­me="ro­tI­ma­ge"
Sour­ce="As­sets/kom­pas1.png" Ren­derTran­sfor­mO­ri­gin="0.5, 0.5">
<Ima­ge.Ren­derTran­sform>
<Ro­ta­teT­ran­sform Ang­le="0" />
</Ima­ge.Ren­derTran­sform>
</Ima­ge>
</Grid>

V konštruk­to­re Main­Pa­ge sa naj­skôr pri­po­jí­me na sen­zor.

_com­pass = Com­pass.Get­De­fault();

Hod­no­ta zo sen­zo­ra sa čí­ta v pro­ce­dú­re Rea­dingChan­ged vždy vte­dy, keď dôj­de k zme­ne hod­no­ty.

pri­va­te void pa­ge­Root_Loa­ded(ob­ject sen­der, Rou­te­dE­ven­tArgs e)
{
_com­pass.Re­por­tIn­ter­val = _de­si­red­Re­por­tIn­ter­val;
_com­pass.Rea­dingChan­ged += new Ty­pe­dE­ven­tHan­dler<Com­pass,
Com­pas­sRea­dingChan­ge­dE­ven­tArgs>(Rea­dingChan­ged);
}
async pri­va­te void Rea­dingChan­ged(ob­ject sen­der, Com­pas­sRea­dingChan­ge­dE­ven­tArgs e)
{
await Dis­pat­cher.Ru­nA­sync(Co­re­Dis­pat­cherPrio­ri­ty.Nor­mal, () =>
{
Com­pas­sRea­ding rea­ding = e.Rea­ding;
nA­zi­mut = 360- Con­vert.ToIn­t32(rea­ding.Hea­din­gMag­ne­tic­North);
daA­nim.From = nFrom;
daA­nim.To = nA­zi­mut;
nFrom = nA­zi­mut;
Sce­na­rio1Sto­ry­board.Be­gin();
tbNorth.Text = String.For­mat("{0,5:0.00}", rea­ding.Hea­din­gMag­ne­tic­North);
});
}

Senzor2 copy.jpg

Ap­li­ká­cia Mag­ne­tic com­pass

Sen­zor os­vet­le­nia

Sen­zor me­ra­jú­ci in­ten­zi­tu os­vet­le­nia, kto­ré im­pli­cit­ne vy­uží­va na auto­ma­tic­kú re­gu­lá­ciu ja­su dis­ple­ja, mož­no vy­užiť aj ap­li­ká­ciách. Pou­ži­tie je jed­no­du­ché.

_sen­sor = Lig­htSen­sor.Get­De­fault();

V ob­slu­he uda­los­ti Loa­ded nas­ta­ví­me pe­rio­di­ci­tu sní­ma­nia úda­jov zo sen­zo­ra os­vet­le­nia a ob­slu­hu uda­los­ti - zme­ny na­me­ra­nej in­ten­zi­ty os­vet­le­nia.

pri­va­te void pa­ge­Root_Loa­ded(ob­ject sen­der, Rou­te­dE­ven­tArgs e)
{
uint mi­nInt = _sen­sor.Mi­ni­mum­Re­por­tIn­ter­val;
_sen­sor.Re­por­tIn­ter­val = mi­nInt > 100 ? mi­nI : 100;
_sen­sor.Rea­dingChan­ged += new Ty­pe­dE­ven­tHan­dler<Lig­htSen­sor,
Lig­htSen­sorRea­dingChan­ge­dE­ven­tArgs>(Rea­dingChan­ged);
}

V ob­slu­he uda­los­ti zme­ny os­vet­le­nia na­me­ra­nú hod­no­tu vy­pí­še­me, prí­pad­ne ju vhod­ne gra­fic­ky zná­zor­ní­me. Mô­že­te vy­tvo­riť so­fis­ti­ko­va­nej­šiu ap­li­ká­ciu s pre­pí­na­ním cit­li­vos­ti.

async pri­va­te void Rea­dingChan­ged(ob­ject sen­der,
Lig­htSen­sorRea­dingChan­ge­dE­ven­tArgs e)
{
await Dis­pat­cher.Ru­nA­sync(Co­re­Dis­pat­cherPrio­ri­ty.Nor­mal, () =>
{
Lig­htSen­sorRea­ding rea­ding = e.Rea­ding;
int nLux = Con­vert.ToIn­t32(rea­ding.Illu­mi­nan­ceIn­Lux);
tbLight.Text = String.For­mat("{0,5:0.00}", nLux) + " lx";
});
}

Luxmeter1 copy.jpg

Ap­li­ká­cia Di­gi­tal Luxme­ter

Uve­de­nú pro­ce­dú­ru sta­čí up­ra­viť, aby sta­vo­vý auto­mat in­kre­men­to­val po­čí­tad­lo po pre­cho­de sní­ma­ča zo svet­la do tmy a opäť do svet­la, a má­te tzv. op­tic­kú ram­pu či­že za­ria­de­nie po­čí­ta­jú­ce nap­rík­lad ľu­dí pri vstu­pe do pries­to­ru. Ob­jek­ty bu­dú ini­cio­vať po­čí­ta­nie tým, že bu­dú pre­chá­dzať me­dzi zdro­jom svet­la a sen­zo­rom in­ten­zi­ty os­vet­le­nia vhod­ne umies­tne­né­ho tab­le­tu.

Prin­cíp sa dá ďa­lej roz­ši­ro­vať, nap­rík­lad o auto­ma­tic­ké zho­to­ve­nie fo­tog­ra­fie, ak niek­to v mies­tnos­ti roz­svie­ti, prí­pad­ne ako do­čas­ný op­tic­ký alarm pre vy­sta­ve­ný exem­plár, kto­rý bu­de chrá­niť tab­let ne­ná­pad­ne umies­tne­ný ved­ľa pred­me­tu, pri­čom opod­stat­ne­nosť tab­le­tu sa auto­ma­tic­ky od­ôvod­ní tým, že je na ňom opis expo­ná­tu.

Ak­ce­le­ro­me­ter

Väč­ši­na tab­le­tov dis­po­nu­je ak­ce­le­ro­met­rom schop­ným me­rať zrý­chle­nie v troch osiach. V ap­li­ká­ciách sa dá vy­užiť nap­rík­lad na sní­ma­nie dy­na­mi­ky po­hy­bu pri ov­lá­da­ní. V jed­no­du­chom prík­la­de vy­pí­še­me hod­no­ty zrý­chle­nia v osiach X, Y a Z.

XAML

<Grid >
<TextBlock x:Na­me="txtXAxis" Ho­ri­zon­ta­lA­lig­nment="Left" Height="15"
Mar­gin="70,16,0,0" Text="-" Ver­ti­ca­lA­lig­nment="Top" Width="61" />
<TextBlock x:Na­me="txtYAxis" Ho­ri­zon­ta­lA­lig­nment="Left" Height="15"
Mar­gin="70,49,0,0" Text="-" Ver­ti­ca­lA­lig­nment="Top" Width="53" />
<TextBlock x:Na­me="txtZAxis" Ho­ri­zon­ta­lA­lig­nment="Left" Height="15"
Mar­gin="70,80,0,0" Text="-" Ver­ti­ca­lA­lig­nment="Top" Width="53" />
</Grid>

C#

pri­va­te Ac­ce­le­ro­me­ter _ac­ce­le­ro­me­ter;
pri­va­te void pa­ge­Root_Loa­ded(ob­ject sen­der, Rou­te­dE­ven­tArgs e)
{
uint miIn­ter­val = _ac­ce­le­ro­me­ter.Mi­ni­mum­Re­por­tIn­ter­val;
uint re­por­tIn­ter­val = mi­nIn­ter­val > 16 ? mi­nIn­ter­val : 16;
_ac­ce­le­ro­me­ter.Re­por­tIn­ter­val = re­por­tIn­ter­val;
_ac­ce­le­ro­me­ter.Rea­dingChan­ged += new Ty­pe­dE­ven­tHan­dler<Ac­ce­le­ro­me­ter,
Ac­ce­le­ro­me­terRea­dingChan­ge­dE­ven­tArgs>(Rea­dingChan­ged);
}
pri­va­te async void Rea­dingChan­ged(ob­ject sen­der,
Ac­ce­le­ro­me­terRea­dingChan­ge­dE­ven­tArgs e)
{
await Dis­pat­cher.Ru­nA­sync(Co­re­Dis­pat­cherPrio­ri­ty.Nor­mal, () =>
{
Ac­ce­le­ro­me­terRea­ding ar = e.Rea­ding;
txtXAxis.Text = String.For­mat("{0,5:0.00}", ar.Ac­ce­le­ra­tionX);
txtYAxis.Text = String.For­mat("{0,5:0.00}", ar.Ac­ce­le­ra­tio­nY);
txtZAxis.Text = String.For­mat("{0,5:0.00}", ar.Ac­ce­le­ra­tionZ);
});
}

Ako ilus­trá­ciu net­ra­dič­né­ho vy­uži­tia ak­ce­le­ro­met­ra mô­že­te vy­tvo­riť ap­li­ká­ciu, kto­rá pre­me­ní tab­let na po­môc­ku fit­nes, nap­rík­lad na prec­vi­če­nie zme­ra­ve­ných rúk pri prá­ci s po­čí­ta­čom. Sta­čí dr­žať tab­let v pred­pa­že­ných ru­kách dis­ple­jom k se­be a po­hy­bo­vať ním od se­ba a k se­be, a to čo naj­rý­chlej­šie. Na zá­kla­de úda­jov z ak­ce­le­ro­met­ra (os Z) sa na jed­no­du­chých stup­ni­ciach zob­ra­zu­je ak­tuál­ne zrý­chle­nie, aku­mu­lo­va­né zrý­chle­nie a ča­so­vý prog­res.

senzor3 copy.jpg

Ap­li­ká­cia Exer­ci­se Dum­bell vy­uží­va­jú­ca ak­ce­le­ro­me­ter

Kom­plexné in­for­má­cie o po­lo­he

Ok­rem izo­lo­va­ných úda­jov z jed­not­li­vých sen­zo­rov pos­ky­tu­je RT API aj kom­plexné in­for­má­cie o dy­na­mic­kých zme­nách po­lo­hy te­le­fó­nu. Exis­tu­jú to­tiž fy­zic­ké ob­me­dzenia jed­not­li­vých sen­zo­rov, pre kto­ré mô­že byť ťaž­ké ur­čiť sku­toč­nú orien­tá­ciu a po­hyb za­ria­de­nia zo su­ro­vých úda­jov z jed­not­li­vých sen­zo­rov. Nap­rík­lad úda­je z ak­ce­le­ro­met­ra sú od­vo­de­né od zotr­vač­nos­ti vy­plý­va­jú­cej z po­hy­bu za­ria­de­nia. Gy­ros­kop me­ria rých­losť otá­ča­nia, no nie po­lo­hu. Pre­to sú v API im­ple­men­to­va­né zlo­ži­té geo­met­ric­ké vý­poč­ty, kto­ré sú pot­reb­né na zis­te­nie po­lo­hy, orien­tá­cie a po­hy­bu zo su­ro­vých dát z jed­not­li­vých sen­zo­rov. Úda­je o po­lo­he, tak­zva­ný Sen­sorQuater­nion, zís­ka­te pros­tred­níc­tvom trie­dy Orien­ta­tion­Sen­sor.

pri­va­te Orien­ta­tion­Sen­sor _sen­sor;
pri­va­te void pa­ge­Root_Loa­ded(ob­ject sen­der, Rou­te­dE­ven­tArgs e)
{
uint min­Re­por­tIn­ter­val = _sen­sor.Mi­ni­mum­Re­por­tIn­ter­val;
_Re­por­tIn­ter­val = min­Re­por­tIn­ter­val > 16 ? min­Re­por­tIn­ter­val : 16; _sen­sor.Rea­dingChan­ged -= new Ty­pe­dE­ven­tHan­dler<Orien­ta­tion­Sen­sor, Orien­ta­tion­Sen­sorRea­dingChan­ge­dE­ven­tArgs>(Rea­dingChan­ged);
}
async pri­va­te void Rea­dingChan­ged(ob­ject sen­der,
Orien­ta­tion­Sen­sorRea­dingChan­ge­dE­ven­tArgs e)
{
await Dis­pat­cher.Ru­nA­sync(Co­re­Dis­pat­cherPrio­ri­ty.Nor­mal, () =>
{
Orien­ta­tion­Sen­sorRea­ding rea­ding = e.Rea­ding;
Sen­sorQuater­nion quater­nion = rea­ding.Quater­nion;
X.Text = String.For­mat("{0,8:0.00000}", quater­nion.X);
Y.Text = String.For­mat("{0,8:0.00000}", quater­nion.Y);
Z.Text = String.For­mat("{0,8:0.00000}", quater­nion.Z);
W.Text = String.For­mat("{0,8:0.00000}", quater­nion.W);
Sen­sorRo­ta­tion­Mat­rix ro­ta­tion­Mat­rix = rea­ding.Ro­ta­tion­Mat­rix;
M11.Text = String.For­mat("{0,8:0.00000}", ro­ta­tion­Mat­rix.M11);
M12.Text = String.For­mat("{0,8:0.00000}", ro­ta­tion­Mat­rix.M12);
M13.Text = String.For­mat("{0,8:0.00000}", ro­ta­tion­Mat­rix.M13);
M21.Text = String.For­mat("{0,8:0.00000}", ro­ta­tion­Mat­rix.M21);

M33.Text = String.For­mat("{0,8:0.00000}", ro­ta­tion­Mat­rix.M33);
});
}

senzor4.jpg

Gra­fic­ká rep­re­zen­tá­cia ob­jek­tu quater­nion na kom­plexné ur­če­nie po­lo­hy za­ria­de­nia v pries­to­re

Zdroj: IW 5-6/2014



Ohodnoťte článok:
   
 

24 hodín

týždeň

mesiac

Najnovšie články

Cloud a je­ho do­sah na vý­voj IT tr­hu. CFO a CIO to vi­dia inak.
Ako môže ovplyvniť nástup cloudových technológií rozhodovacie a prevádzkové procesy v bežnej ekonomicky aktívnej spoločnosti? čítať »
 
Vy­uži­tie sen­zo­rov
Moderné tablety a konvertibilné zariadenia pod taktovkou operačného systému Windows 8.1 sú vybavené niekoľkými užitočnými senzormi, ktoré môžete využiť vo svojich aplikáciách. Spravidla ide o kompas, akcelerometer, gyroskop, náklonomer a snímač intenzity osvetlenia.  čítať »
 
No­vý Thin­kPad X1 Car­bon
ThinkPad X1 Carbon tretej generácie je naozaj veľmi ľahký vďaka tomu, že je vyrobený z karbónového vlákna, ktoré má menšiu hmotnosť ako horčíkové alebo hliníkové. Vďaka konštrukcii z uhlíkových vlákien je model X1 Carbon vôbec najodolnejší notebook z radu ThinkPad. čítať »
 
Da­ta Dis­co­ve­ry - ob­ja­vo­va­nie vzo­rov v dá­tach
Dnes hýbu svetom biznisu nielen peniaze, ale hlavne informácie. V tejto informačnej dobe sa na dáta, ako aj na nástroje na ich spracovanie kladú vysoké nároky. čítať »
 
No­vý pro­ce­sor IBM Power8: 50× rých­lej­ší pri ana­lý­ze dát ako x86
Spoločnosť IBM predstavila prvé servery vybavené novou generáciou procesora Power8. Zároveň pripomenula svoju nadáciu, ktorá otvára architektúru POWER záujemcom o jej ďalší vývoj. čítať »
 
 
 
  Zdieľaj cez Facebook Zdieľaj cez Google+ Zdieľaj cez Twitter Zdieľaj cez LinkedIn Správy z RSS Správy na smartfóne Správy cez newsletter