Windows 7 API Codepackが未サポートのセンサーを追加する

やったぁ、新しいセンサーを手に入れた!!。Sensor & Location Platform対応のドライバーも手に入れた!!。これで、Windows 7でセンサーを活用したアプリが書けるぞ!!。ではC#でプログラムを書こうか…って…あれ?Codepackでサポートされていないっ!!・・・というあなたへ。

CodepackがサポートしていないセンサーをCodepackのAPIに追加する方法を説明します。VC++でNative Code/COMダイレクトでセンサーを使う方法もありますが、C#等のManagedを使ったほうがはるかに生産性が高いので、参考にしてくださいね。(1msecより短い時間間隔のハードリアルタイムシステムを作る時は別ですが)

まずは、Codepackの構造を覗いていてみましょう。Sensorsプロジェクトの下にSensorsというフォルダーがあって、その下に、“Light”、“Mechanical”、“Motion”という3つのフォルダーがあり、各フォルダーにAmibientLightSensor.cs、BooleanSwitchArray.cs、Acceleromitor3D.csと3つのC#ファイルが入っていますね。これらはFreescaleさんのSensor Development Kitボードに実装されている照度センサー、タッチアレイ、加速度センサーにそれぞれ対応しています。これらのファイルの中身を覗いて、Codepackのパターンをまず覚えましょう。

そして、新しく手に入れたセンサーをWindows 7 PCにつないで、以下のコードを実行して、そのセンサーのタイプとサポートしているプロパティを調べます。

foreach (var sensor in SensorManager.GetAllSensors()){    Guid? typeId = sensor.TypeId;    foreach (var property in sensor.GetSupportedProperties()){        Guid formatId = property.FormatId;        int pid = property.PropertyId;    }}

IOデータが提供している人感センサー(SENSOR-HM)を例にして説明すると、センサーのTypeIdが“{c138c12b-ad52-451c-9375-87f518ff10c6}”で、サポートしているプロパティが計測時刻と、FormatIdが“{2299288A-6D9E-4B0B-B7EC-3528F89E40AF}”、pidが2のプロパティであることがわかります。

これらのGuidをもとにWindows 7 SDKのsensors.hで探すとこのセンサーは、カテゴリがSENSOR_CATEGORY_ENVIRONMENTAL(環境センサー)、タイプがSENSOR_TYPE_HUMIDITY(つまり人感センサー)、プロパティがSENSOR_DATA_TYPE_HUMAN_PRESENCE(いる・いない)というBoolの値であることがわかります。なので、CodepackのSensorsプロジェクトの下のSensorsフォルダーに“Environmental”という名前のフォルダーを作成して、Humidityクラスを新規追加し、他のデフォルトで提供されているセンサーにならって、以下のようなコードを書けば、子の人感センサーをManagedコードでアクセスするためのラッパーが出来上がります。

class Humidity : Sensor{    public HumanPresense CurrentPresence {        get {            return new HumanPresense(this.DataReport);        }    }}class HumanPresense{    public HumanPresense(SensorReport report) {        if (report.Values.ContainsKey(SensorPropertyKeys.SENSOR_DATA_TYPE_HUMAN_PRESENCE.FormatId)) {            presence = (bool)report.Values[SensorPropertyKeys.SENSOR_DATA_TYPE_HUMAN_PRESENCE.FormatId][2];        }    }    public bool Presence {        get {            return presence;            }        }        bool presence = false;    }}

こんな感じ。準備ができたので、新しく追加したこのクラスを使って、

foreach (var sensor in SensorManager.GetSensorsByTypeId<Humidity>()){    Humidity humidity = sensor as Humidity;    ....}

のように書けば、IOデータの人感センサーをManagedコードで利用できるんだ。

目次へ