In questo articolo introdurremo l'affascinante tematica dei dispositivi sensoriali all'interno degli Ultrabook, esplicitando i casi d'uso e le applicazioni tipiche. Inoltre vedremo come interfacciarvisi tramite API nativa di Windows (in C++).
I sensori
Esistono vari tipi di sensori che le case produttrici includono oggi nei dispositivi. Ora parliamo di Ultrabook ma sono altrettanto comuni oggi alcuni smartphones che non nascondono la loro nativa predisposizione ad applicazioni sensor-based. Un esempio tipico è ormai quel sensore che permette al telefono di ruotare l'interfaccia utente al momento in cui ne ruotiamo la scocca, l'accelerometro.
La prima cosa da fare per poter lavorare con i sensori, su un Ultrabook, è verificarne l'effettivo stato di funzionamento ed impararne i parametri tipici. È infatti importante sapere che un valore tipico di un sensore "Compass" può variare tra 0 e 359, cosa quanto più indispensabile quando, a questi dati, dobbiamo dare un valore nella nostra applicazione.
Accelerometro
L'accelerometro stabilisce, in ogni istante, a quanta accelerazione è sottoposto il dispositivo lungo le tre assi di riferimento (Y,X,Z). Per stabilire su quali assi sia stato calibrato il sensore, occorre fare uso del "Sensor Diagnostic Tool" disponibile con il Windows SDK. Si tratta di uno strumento di troubleshooting che fa utilizzo della Sensor & Location API di Windows 7 e superiori.
Per stabilire quindi quali siano gli assi del dispositivo, avvieremo il tool e faremo attenzione ai valori in figura:
Che determinano l'unica componente di accelerazione nel caso stazionario, ovvero quando l'Ultrabook è privo di moto e appoggiato in posizione naturale su un piano. Questa condizione, come si può evidenziare, porta un asse (la Z) alla sua completa valorizzazione negativa (-1) che indica che l'accelerazione istantanea del dispositivo ha solo una componente verso il basso.
Nota: il principio dell'accelerazione di gravità della fisica, che stabilisce che ogni corpo in un qualsiasi momento è soggetto ad una accelerazione verso il centro della terra, ovvero verso il basso, di 9,8 m/s2. Questo valore, per comodità di accesso durante lo sviluppo, è "normalizzato" a 1.
Ora possiamo spostare il dispositivo inclinandolo verso sinistra/destra, per notare una cosa interessante: l'accelerazione ora ha due componenti: una, sull'asse Z; la seconda sull'asse X.
Nota: la somma vettoriale delle componenti di accelerazione, deve sempre portare al totale dell'accelerazione di gravità, se il corpo non è accelerato ed è in regime stazionario.
Infine, se incliniamo il dispositivo anche verso avanti/indietro, vedremo che la componente di accelerazione ora è presente su tutte e tre le assi dello stesso.
Le applicazioni di questo sensore sono la rilevazione dell'orientamento, delle differenze di accelerazione (degli shake) e, più praticamente, ci possono tornare utili per applicazioni in cui dobbiamo muovere il dispositivo per simulare un movimento ambientale (videogames).
Bussola (Compass)
La bussola digitale, il magnetometro (Compass, in inglese) è un dispositivo che ci indica, banalmente, dove si trovi il nord geografico.
Nota: In realtà questo non è del tutto esatto, poichè una bussola è sempre soggetta ad un fenomeno che chiamiamo declinazione magnetica. Si può tuttavia, per semplicità, assumere che il valore indicato da un Compass sia verosimilmente indicativo del nord geografico.
Come vediamo dalla figura sotto, i valori ottenuti da un Compass, come già evidenziato, sono angoli tra il nostro terminale e, appunto, il nord.
In quest'altra figura vediamo come l'angolo rilevato sia 90°, ovvero si stia tenendo l'Ultrabook verso Est.
L'utilità di questo sensore è quasi sempre correlato ad un sistema di mappe e/o navigazione. Difficilmente infatti, l'informazione geografica della sola posizione del nord, può rivelarsi utile ai fini applicativi.
Giroscopio
Il giroscopio è uno strumento che consente di stabilire la velocità angolare di rotazione dello stesso su tutti i suoi assi. In condizioni stazionarie il giroscopio quindi non dà alcuna informazione, poichè non avviene rotazione istantanea:
mentre durante la rotazione mostra valori significativi:
Questo sensore trova utilizzo in quelle applicazioni il cui solo sensore di accelerazione non basta a rendere l'esperienza dell'utente soddisfacente.
Si immagini ad esempio un gioco di guida dove il volante è proprio lo stesso Ultrabook che, ruotato, simula lo sterzo. In quel caso la velocità con cui si girà il volante è molto utile ai fini della simulazione e non si può ricavare facilmente dall'accelerazione istantanea.
Light sensor
Il sensore di luminosità è un dispositivo che stabilisce quanta luce incide sul nostro Ultrabook (si trova quasi sempre in prossimità della webcam), indicando un valore (in Lux) da 0 ad un numero potenzialmente molto alto (diverse centinaia). Nella figura vediamo un valore che si presenta in una stanza con luce artificiale alle 18.00 circa.
^f(d+)$
Nonostante l'oggettiva semplicità di questo sensore, le applicazioni sono moltissime. Sveglie intelligenti che al rilevare di un brusco incremento della luminosità ambientale, si spengono da sole; parti di sistema operativo che reagiscono innescando un cambiamento della luminosità dello schermo al cambiare della luminosità ambientale (meno luce esterna, meno contrasto del monitor).
NFC
Nella famiglia dei dispositivi integrati in un Ultrabook esistono alcuni "extra" che non sono propriamente sensori. Oltre alla ormai nota antenna WiFi e Bluetooth (e talvolta una scheda UMTS), oggi un Ultrabook monta anche un GPS (il cui meccanismo è noto a tutti) e un'antenna NFC.
L'NFC è una tecnologia che, anche ricordando l'RfiD, permette tuttavia di stabilire comunicazioni bidirezionali, permettendo quindi una connessione contact-less e peer-to-peer fino a 4cm di distanza. L'Ultrabook permette quindi di sbloccare alcuni scenari di applicazioni innovative basate su NFC, per comunicare con dispositivi diversi (smartphones, tablet, etc).
Sviluppare con la Sensor e Location API
Su Windows 7/8, esiste la Sensor & Location API che permette di interrogare i sensori di sistema tramite COM. Il tutto viene gestito da un oggetto chiamato sensor manager che permette di ottenere i sensori ed essere notificati dello stato di connettività degli stessi: una volta allocato il sensore, esso ci notificherà con i suoi aggiornamenti.
Vediamo come interagire con i sensori in C++. In primo luogo è necessario istanziare il sensor manager:
// Crea il sensor manager
hr = CoCreateInstance(CLSID_SensorManager,
NULL, CLSCTX_INPROC_SERVER,
IID_PPV_ARGS(&pSensorManager));
if (hr == HRESULT_FROM_WIN32 (ERROR_ACCESS_DISABLED_BY_POLICY))
{
// Impossibile ricevere a causa di una
// policy di sistema.
// Si raccomanda di notificare l'utente
}
Successivamente è necessario ottenere l'elenco dei sensori (per categoria, oppure per ID):
// Ottiene l'elenco dei sensori
hr = pSensorManager->GetSensorByCategory(
SAMPLE_SENSOR_CATEGORY_DATE_TIME,
&pSensorColl);
if(SUCCEEDED(hr))
{
ULONG ulCount = 0;
// Verifica l'esistenza di almeno 1 sensore
hr = pSensorColl->GetCount(&ulCount);
if(SUCCEEDED(hr))
{
wpring_s(L"nNessun Sensore!n");
gr = E_UNEXPECTEDM
}
else
{
// Richiesta di permesso
hr = pSensorManager->RequestPermissions(9, pSensorColl, FALSE);
}
}
A questo punto è necessario mettersi in ascolto sulle notifiche del sensore scelto, implementando una apposita interfaccia (prima)
class CMyEvents : public ISensorEvents
{
public:
STDMETHODIMP QueryInterface(...) {...}
STDMETHODIMP_(ULONG) AddRef() {...}
STDMETHODIMP_(ULONG) Release {...}
// Metodi di interfaccia
STDMETHODIMP OnEvent(...) {...}
STDMETHODIMP OnDataUpdated(...) {...}
STDMETHODIMP OnLeave(...) {...}
STDMETHODIMP OnStateChanged(...) {...}
}
e agganciandosi alla corrispettiva callback:
// Inizia a ricevere eventi
hr = pSensor->SetEventSink(pMyEvents);
In riferimento all'ultimo snippet di codice, per terminare l'acquisizione di dati, occorre ripetere la chiamata a SetEventSink
passando NULL
come parametro.
App nativa o gestita?
Soprattutto all'inizio, il mondo COM è difficile da digerire e, nello scenario attuale di applicazioni scritte con linguaggi e framework di alto livello, può anche sembrare anacronistico. Tuttavia esistono fattori, come ad esempio l'ottimizzazione delle risorse, che portano spesso alla scrittura di applicazioni e giochi in C++ e, generalmente, utilizzando le API nativamente. In questo contesto l'interrogazione dello stato dei sensori del vostro Ultrabook, è sicuramente ottimale.