更新日: 2010 年 9 月 3 日

この How-To では、Windows 7 で新たに搭載された Sensor API を使って、アプリケーションに必要な計測データを正しく取得する方法について解説します。

尚、この How-To を実践するには、Windows 7 Sensor API 対応のセンサーが搭載された Windows 7 PC が必要です。センサーは販売時に搭載されているものでも、USB 等で接続するものでも構いません。

事前準備として、Windows® API Code Pack for Microsoft® .NET Framework (英語) をダウンロードして、適当な場所に解凍しておきます。アプリケーション開発用のソリューションに Code Pack の Core、Sensors プロジェクトを追加し、アプリケーションのプロジェクトに参照プロジェクトとして追加すれば、COM API で提供されている Sensor API を C# 等の Managed Code で活用することができます。

先ず、PC に搭載されている全てのセンサーの全ての測定データを表示するコードを紹介します。C# コードには、Microsoft.WindowsAPICodePack.Sensors 名前空間を using 文で加えてください。

~ コード 1 ~

C#
foreach (var sensor in SensorManager.GetAllSensors()) 
{ 
    Console.WriteLine( 
        string.Format("Sensor:FriendryName='{0}',TypeId={1},CategoryId={2}", 
            sensor.FriendlyName, 
            sensor.TypeId, 
            sensor.CategoryId)); 
    // … (1) 
    SensorReport report = sensor.DataReport; 
    SensorData values = report.Values; 
    foreach (var formatId in values.Keys) 
    { 
        Console.WriteLine(string.Format("    FormatId={0}",  
                                 formatId)); 
        foreach (var value in values[formatId])    // … (2) 
        { 
            Console.WriteLine(string.Format("      value={0}", 
                                      value.ToString())); 
        } 
    } 
} 
 

コード 1 を実行すると、搭載されているセンサーの通称 (FriendlyName) とセンサーの種別 (TypeId)、カテゴリ (CategolyId)、各センサーを通じて計測されたデータが表示されます。手元にある市販の方位センサー付 PC で実行してみると、

~ 表示結果 1 ~

Sensor:FriendryName=’Magnetic Sensor’,TypeId=76b5ce0d-17dd-414d-93a1-e127f40bdf6e,CategoryId=9e6c04b6-96fe-4954-b726-68682a473f69
    FormatId=db5e0cf2-cf1f-4c18-b46c-d86011d62150
        value=時間
     FormatId=1637d8a2-4248-4275-865d-558de84aedfd
        value=0~360の間の値
        value=0~360の間の値

と表示されます。これらの値の意味は、
Sensor Categories, Types, and Data Fields (英語) で説明されています。このページとリンクをたどることにより、カテゴリは方向 (SENSOR_CATEGORY_ORIENTATION)、センサー種別が、SENSOR_TYPE_COMPASS_3D であることがわかります。リンクをたどったページの下の方に、このカテゴリに属するセンサーの、計測可能なデータ種別一覧が載っています。計測データ種別は、GUID 型の FormatId と整数の PropertyId で一意に定義されています。表示結果 1 の 3 種類の計測データの内、後の 2 つがこの MSDN ページに示されている SENSOR_DATA_TYPE_ORIENTATION_GUID と同じ値の FormatId であることがわかりますが、表示された情報だけでは、どのデータ種別なのか判然としません。

各センサー デバイスの計測可能なデータはそれぞれ異なるため、コード 1 の (2) のループで表示される計測データの種別と出現順は、PC に搭載されたセンサー デバイスによって変わります。この点を考慮しないと、アプリケーションで正しく計測データを参照することができません。

計測データの種別、出現順は、以下のコードで確認することができます。前出のコードの (1) の部分に嵌め込みます。

~ コード 2 ~

C#
foreach (var sp in s.GetSupportedProperties()) 
    { 
        Console.WriteLine(string.Format( 
             "    Property:FormatId={0}, PropertyId{1}", 
             sp.FormatId, sp.PropertyId)); 
    } 
 
 

コード 2 を実行した際に表示される情報を抜粋すると、

~ 表示結果 2 ~

Property:FormatId=db5e0cf2-cf1f-4c18-b46c-d86011d62150, PropertyId=2
Property:FormatId=1637d8a2-4248-4275-865d-558de84aedfd, PropertyId=11
Property:FormatId=1637d8a2-4248-4275-865d-558de84aedfd, PropertyId=12

と表示されます。MSDN ページの定義を使って調べていくと、順に

であることがわかります。表示結果 1 の計測データの並びは、この並びと同じです。

アプリケーションで真の北極に対して現在向いている角度を取得したい場合には、アプリケーション初期化時に以下の様なコードを記述し、

~ コード 3 ~

C#
if (sensor.TypeId.Value.CompareTo( 
   new Guid("76b5ce0d-17dd-414d-93a1-e127f40bdf6e")) == 0) 
{ 
   int index=0; 
   var currentId = new Guid(); 
   foreach (var property in sensor.GetSupportedProperties()) 
   { 
       if (currentId.CompareTo(property.FormatId) != 0) 
       { 
          currentId = property.FormatId; 
          index = 0; 
       } 
       else index++; 
       if (property.FormatId.CompareTo( 
          new Guid("1637d8a2-4248-4275-865d-558de84aedfd")) == 0) 
       { 
          if (property.PropertyId == 12) 
          { 
              targetPropertyId = index; 
               break; 
           } 
       } 
   } 
   if (targetPropertyId != -1break 
} 
 
 

センサーからのデータ取得時には以下のコードを記述すれば、正しい値が参照できます。

~ コード 4 ~

C#
private Guid orientationCategoryPropGuid =  
new Guid("1637d8a2-4248-4275-865d-558de84aedfd"); 
    …… 
string angleStr =  
report.Values[orientationCategoryPropGuid][targetPropertyId].ToString() 
double angle = double.Parse(angleStr); 
 
 

センサーを使ったプログラミングに関する技術情報はこちらをご覧ください。


Code Recipe

ページのトップへ