Využitie senzorov


Prístroje pod taktovkou operačného systému Windows Phone 7 sú vybavené kompasom, akcelerometrom, gyroskopom a systémom pre určovanie polohy. Akceleromerer je povinná súčasť, kompas a gyroskop prístroje rôznych výrobcov môžu a nemusia obsahovať. Akcelerometer má v mobilnom telefóne veľmi dôležitú funkciu, umožňuje nielen zistenie aktuálnej orientácie prístroja (na výšku, či na šírku), ale nakoľko prístroj nemá žiadne kurzorové tlačidlá ani nijaký ekvivalent joysticku využíva sa naklápanie prístroja aj na ovládanie hier.

Ak zariadenia, alebo emulátor nepodporujú gyroskop, prípadne kompas, je potrebné v aplikácii túto skutočnosť ošetriť

if (compass == null)

{

compass = new Compass();

compass.TimeBetweenUpdates = TimeSpan.FromMilliseconds(20);

compass.CurrentValueChanged

+= new EventHandler<SensorReadingEventArgs<CompassReading>>

(compass_CurrentValueChanged);

}

 

try

{

statusTextBlock.Text = “…inicializácia kompasu”;

compass.Start();

}

catch (InvalidOperationException)

{

statusTextBlock.Text = “Zariadenie nepodporuje kompas.”;

}

 

 

 

if (!Gyroscope.IsSupported)

{

statusTextBlock.Text = “Zariadenie nepodporuje gyroskop”;

startButton.IsEnabled = false;

stopButton.IsEnabled = false;

}

 

Ak zariadenia, alebo emulátor nepodporujú gyroskop, prípadne kompas, je potrebné v aplikácii túto skutočnosť ošetriť

Pre úplnosť uvádzame aj fragmenty kódu pre čítanie hodnôt kompasu

xTextBlock.Text = “X: ” + reading.MagnetometerReading.X.ToString(“0.00”);

yTextBlock.Text = “Y: ” + reading.MagnetometerReading.Y.ToString(“0.00”);

zTextBlock.Text = “Z: ” + reading.MagnetometerReading.Z.ToString(“0.00”);

a gyroskopu

Vector3 rotationRate = gyroscopeReading.RotationRate;

 

xTextBlock.Text = “X: ” + rotationRate.X.ToString(“0.00”);

yTextBlock.Text = “Y: ” + rotationRate.Y.ToString(“0.00”);

zTextBlock.Text = “Z: ” + rotationRate.Z.ToString(“0.00”);

 

 

Novinkou verzie “Mango” sú 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 čidiel Windows Phone. 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é zistenie polohy orientácie a pohybu zo surových dát z jednotlivých senzorov. Takéto informácie sú dôležité pre aplikácie pracujúce s rozšírenou realitou (augmented reality), jedná sa hlavne o polohu, rotačné zrýchlenie, a lineárne zrýchlenie.

Akcelerometer

Senzor akcelerometru musí byť povolený (implicitné nastavenie) v súbore WMAppManifest.xml v sekcii <Capabilities>.

<Capabilities>

<Capability Name=”ID_CAP_GAMERSERVICES”/>

<Capability Name=”ID_CAP_IDENTITY_DEVICE”/>

<Capability Name=”ID_CAP_IDENTITY_USER”/>

<Capability Name=”ID_CAP_LOCATION”/>

<Capability Name=”ID_CAP_MEDIALIB”/>

<Capability Name=”ID_CAP_MICROPHONE”/>

<Capability Name=”ID_CAP_NETWORKING”/>

<Capability Name=”ID_CAP_PHONEDIALER”/>

<Capability Name=”ID_CAP_PUSH_NOTIFICATION”/>

<Capability Name=”ID_CAP_SENSORS”/>

<Capability Name=”ID_CAP_WEBBROWSERCOMPONENT”/>

</Capabilities>

 

Budeme monitorovať zabudovaný akcelerometer, pre lepšie pochopenie údajov, ktoré vracia ich budeme vypisovať v textovej podobe pomocou prvku TextBlock

<!–ContentPanel – place additional content here–>

<Grid x:Name=”ContentPanel” Grid.Row=”1″ Margin=”12,0,12,0″>

<TextBlock Name=”tblVypis”

HorizontalAlignment=”Center” VerticalAlignment=”Center” />

</Grid>

Je potrebné vytvoriť referenciu na knižnicu Microsoft.Devices.Sensors.

Vytvorenie referencie na knižnicu Microsoft.Devices.Sensors

Do kódu v súbore MainPage.xaml.cs je potrebné pridať referenciu na namespace.

using Microsoft.Devices.Sensors;

 

V konštruktore vytvorte objekt Accelerometer. Následne vytvorte procedúru ktorá bude reagovať na udalosť ReadingChanged, ktorá nastane pri zmene polohy telefónu s akcelerometrom

// Constructor

public MainPage()

{

InitializeComponent();

Accelerometer aclr = new Accelerometer();

aclr.ReadingChanged += OnAclrReadingChanged;

 

try

{

aclr.Start();

}

catch (Exception exc)

{

tblVypis.Text = exc.Message;

}

}

V tele obslužnej procedúry pre výpis údajov z akcelerometra vypíšeme hodnotu posunov v jednotlivých osiach a komplexný parameter Magnitúda. Magnitúda sa vypočíta ako odmocnina so súčtu druhých mocnín vektorov X,Y a Y. V procedúre si dajte pozor, nakoľko sa vypisujú údaje z iného threadu.

void OnAclrReadingChanged(object sender, AccelerometerReadingEventArgs args)

{

string str = String.Format(“X = {0:F2}\n” +

“Y = {1:F2}\n” +

“Z = {2:F2}\n\n” +

“M = {3:F2}\n\n”,

args.X, args.Y, args.Z,

Math.Sqrt(args.X * args.X + args.Y * args.Y + args.Z *

args.Z));

 

if (tblVypis.CheckAccess())

{

SetTextBlockText(tblVypis, str);

}

else

{

tblVypis.Dispatcher.BeginInvoke(new

SetTextBlockTextDelegate(SetTextBlockText),

tblVypis, str);

}

}

 

delegate void SetTextBlockTextDelegate(TextBlock txtblk, string text);

 

void SetTextBlockText(TextBlock txtblk, string text)

{

txtblk.Text = text;

}

 

Aplikáciu využívajúcu akcelerometer môžete vo verzii SDK 7.1 otestovať aj v emulátore. Zmena polohy (náklon) prístroja sa simuluje posúvaním ružového bodu, pričom zmeny pozície je možné zaznamenať a následne ako sekvenciu činností prehrať, takže aplikáciu využívajúcu akcelerometer bude možné ladiť počas simulovania identických pohybov.

Text akcelerometra na emulátore

Geografická lokalizácia

Najpresnejšie je GPS, ale je pomalé a nadá sa použiť v budovách, alebo husto zastavaných oblastiach. Preto Win Phone 7 používa univerzálnu koncepcia zisťovania aktuálnej polohy cez GPS, WiFi a GSM

Univerzálna koncepcia lokalizácie

Ak chcete geografickú lokalizáciu využívať vo svojom projekte, Je potrebné vytvoriť referenciu na knižnicu System.Device.

using System.Device.Location;

Námetom jednoduchej aplikácie je výpis aktuálnych súradníc

public partial class MainPage : PhoneApplicationPage

{

// Constructor

public MainPage()

{

InitializeComponent();

 

GeoCoordinateWatcher gcw = new GeoCoordinateWatcher();

gcw.PositionChanged += OnGcwChanged;

 

try

{

gcw.Start();

}

catch (Exception exc)

{

tblVypis.Text = exc.Message;

}

}

 

void OnGcwChanged(object sender, GeoPositionChangedEventArgs<GeoCoordinate> args)

{

string str = String.Format(“Zemep. dĺžka: {0:F3}\r\n” +

“Zemep. šírka: {1:F3}\r\n” +

“Výška: {2}”,

args.Position.Location.Longitude,

args.Position.Location.Latitude,

args.Position.Location.Altitude);

 

if (tblVypis.CheckAccess())

{

SetTextBlockText(tblVypis, str);

}

else

{

tblVypis.Dispatcher.BeginInvoke(new

SetTextBlockTextDelegate(SetTextBlockText),

tblVypis, str);

}

 

}

delegate void SetTextBlockTextDelegate(TextBlock txtblk, string text);

 

void SetTextBlockText(TextBlock txtblk, string text)

{

txtblk.Text = text;

}

 

}

 

Mapové služby

V príklade pre využitie mapových služieb budeme využívať mapovú službu Microsoft Research Maps http://msrmaps.com. Do projektu aplikácie pridajte referenciu na službu (položka kontextového menu Add Service Reference) http://msrmaps.com/TerraService2.asmx?WSDL

Referencia na mapovú službu

Službu pomenujte napríklad MsrMapsService

V XAML návrhu pridajte prvok typu text block navýpis

<!–ContentPanel – place additional content here–>

<Grid x:Name=”ContentPanel” Grid.Row=”1″ Margin=”12,0,12,0″>

<TextBlock Name=”tblVypis” HorizontalAlignment=”Center”

VerticalAlignment=”Center” TextWrapping=”Wrap” />

</Grid>

 

Do kódu pridajte referencie na menné priestory

using System.Device.Location;

using System.IO;

using System.Windows.Media.Imaging;

using MapoveSlužby.MsrMapsService;

 

kód

namespace MapoveSlužby

{

public partial class MainPage : PhoneApplicationPage

{

 

GeoCoordinateWatcher gcw = new GeoCoordinateWatcher();

TerraServiceSoapClient proxy = new TerraServiceSoapClient();

 

// Constructor

public MainPage()

{

InitializeComponent();

Loaded += OnMainPageLoaded;

}

 

void OnMainPageLoaded(object sender, RoutedEventArgs args)

{

// udalosti pre TerraServiceSoapClient proxy

proxy.GetAreaFromPtCompleted += OnProxyGetAreaFromPtCompleted;

proxy.GetTileCompleted += OnProxyGetTileCompleted;

 

// Start gcw

tblVypis.Text = “Zisťovanie polohy…”;

gcw.PositionChanged += OngcwPositionChanged;

gcw.Start();

}

 

void OngcwPositionChanged(object sender, GeoPositionChangedEventArgs<GeoCoordinate> args)

{

// zastav gcw

gcw.PositionChanged -= OngcwPositionChanged;

gcw.Stop();

 

// Výpis súradníc do záhlavia

GeoCoordinate coord = args.Position.Location;

ApplicationTitle.Text += “: ” + String.Format(“{0:F2}°{1} {2:F2}°{3}”,

Math.Abs(coord.Latitude),

coord.Latitude > 0 ? ‘N’ : ‘S’,

Math.Abs(coord.Longitude),

coord.Longitude > 0 ? ‘E’ : ‘W’);

// Dotaz na službu na aktuálnu oblasť

LonLatPt center = new LonLatPt();

center.Lon = args.Position.Location.Longitude;

center.Lat = args.Position.Location.Latitude;

 

tblVypis.Text = “Prístup k mapovej službe…”;

proxy.GetAreaFromPtAsync(center, 1, Scale.Scale16m, (int)ContentPanel.ActualWidth,

(int)ContentPanel.ActualHeight);

}

 

void OnProxyGetAreaFromPtCompleted(object sender, GetAreaFromPtCompletedEventArgs args)

{

if (args.Error != null)

{

tblVypis.Text = args.Error.Message;

return;

}

 

tblVypis.Text = “Načítanie mapy…”;

 

AreaBoundingBox box = args.Result;

int xBeg = box.NorthWest.TileMeta.Id.X;

int yBeg = box.NorthWest.TileMeta.Id.Y;

int xEnd = box.NorthEast.TileMeta.Id.X;

int yEnd = box.SouthWest.TileMeta.Id.Y;

 

// Loop through the tiles

for (int x = xBeg; x <= xEnd; x++)

for (int y = yBeg; y >= yEnd; y–)

{

// Create Image object to display tile

Image img = new Image();

img.Stretch = Stretch.None;

img.HorizontalAlignment = HorizontalAlignment.Left;

img.VerticalAlignment = VerticalAlignment.Top;

img.Margin = new Thickness((x – xBeg) * 200 –

box.NorthWest.Offset.XOffset,

(yBeg – y) * 200 – box.NorthWest.Offset.YOffset, 0, 0);

 

// Insert after TextBlock but before Image with logo

ContentPanel.Children.Insert(1, img);

 

// Define the tile ID

TileId tileId = box.NorthWest.TileMeta.Id;

tileId.X = x;

tileId.Y = y;

 

// Call proxy to get the tile (Notice that Image is user object)

proxy.GetTileAsync(tileId, img);

}

}

 

void OnProxyGetTileCompleted(object sender, GetTileCompletedEventArgs args)

{

if (args.Error != null)

{

return;

}

 

Image img = args.UserState as Image;

BitmapImage bmp = new BitmapImage();

bmp.SetSource(new MemoryStream(args.Result));

img.Source = bmp;

}

}


Test príkladu využívajúceho mapové služby


 

About Luboslav Lacko

Záujem o využitie moderných telefónov pre biznis a osobný život. Cloud computing, virtualizácia, vývoj aplikácií, business intelligence
This entry was posted in Win Phone 7 and tagged , , , . Bookmark the permalink.

Pridaj komentár

Zadajte svoje údaje, alebo kliknite na ikonu pre prihlásenie:

WordPress.com Logo

Na komentovanie používate váš WordPress.com účet. Odhlásiť sa /  Zmeniť )

Google photo

Na komentovanie používate váš Google účet. Odhlásiť sa /  Zmeniť )

Twitter picture

Na komentovanie používate váš Twitter účet. Odhlásiť sa /  Zmeniť )

Facebook photo

Na komentovanie používate váš Facebook účet. Odhlásiť sa /  Zmeniť )

Connecting to %s