Microsoft OCR をデスクトップのWFPアプリで動かす方法

巷ではGoogleのリアルタイム翻訳アプリが流行っているのだが、あいにく手元にある Android が古いので、それほど面白い画像が取れない。ので、Google Cloud Vision で OCR 機能を試してみたのだが、実は Microsoft OCR もあるよ、ってことで。

こんなものがある。

Windows.Media.Ocr namespace – Windows app development
https://msdn.microsoft.com/library/windows/apps/windows.media.ocr.aspx?f=255&MSPPError=-2147217396&cs-save-lang=1&cs-lang=csharp#code-snippet-4

試してみると、Microsoft OCR も Google のそれに対してさほど悪い結果でないことが分かった。発表の頃はもうちょっとダメな感じがあったのだが、単純に文字列を読み取る OCR という点では Google のとどっこいどっこいという感じである。Google Cloud Vision の場合は無料枠だと 1,000回/月 という制限があるので、無料の範囲であって Windows 上であれば Microsoft OCR でも十分かもしれない。まあ、とはいえ Google のほうも 100万回/月にしたって $2.5 で使えるので実験レベルであれば十分だろう。

Microsoft OCR のサンプルがストアアプリになっている

Windows-universal-samples/Samples/OCR at master ・ Microsoft/Windows-universal-samples
https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/OCR

サンプルコードをダウンロードして実行してみると、UWPアプリ(ストアアプリ)で動く。

確かに、UWP アプリにするとストアにアップできたり、Windows IoT Core で動いたりと便利ではあるのだが、画像とファイルの扱いが面倒になっているので、できることならば従来通りのデスクトップアプリで試しておきたい…と思いつつ調べたのだが、サンプルが見当たらない。

実は OCR を提供している Windows.Media.Ocr が「Windows Runtime API」に入っていて UWP アプリで使うことを想定している状態なのであった。じゃあ仕方がない、以前の WinRT をライブラリを WPF アプリから使えるようにしてみよう、と思って作ったサンプルがこれです。

https://github.com/moonmile/google-cloud-vision-sample/tree/master/src/OCR/MsOcrWPF

WinRT のライブラリを使う準備

Windows 8.1 の頃にやった技は Windows 10 でも有効なので、*.csproj に TargetPlatformVersion タグを追加する。このバージョンは、適当に UWP アプリから取ってくる。

<TargetPlatformVersion>10.0.14393.0</TargetPlatformVersion>

すると参照設定で「Windows」→「コア」というのが使えるようになって、WinRT のアセンブリを指定できるようになる。

OCR は「Windows.Media」のほうに入っている。

OCR を使う場合は、結果的に

– Windows.Foundation
– Windows.Graphics
– Windows.Media
– Windows.Storage

の4つのWinRTアセンブリを追加することになる。

実は、サジェストを使ってアセンブリを自動的にロードすることもできるのだが、Windows.Foundation.UniversalApiContract が他のものと競合してしまってうまくいかないので、自前でやる。もし Windows.Foundation.UniversalApiContract が参照設定に入ってしまったときは、参照から外してしまう。

ビルドをするときに、WinRT のランタイムが足りないと怒られるので、System.Runtime.WindowsRuntime.dll も追加しておく。

C:/Program Files (x86)/Reference Assemblies/Microsoft/Framework/.NETCore/v4.5.1/System.Runtime.WindowsRuntime.dll

OCR を使うコード

実は Microsoft OCR を使うときのコードは非常に単純で、次のように SoftwareBitmap を渡して、OCR結果である OcrResult オブジェクトを受け取ることができる。

public async Task<OcrResult> detect( SoftwareBitmap bitmap)
{
    var ocrEngine = OcrEngine.TryCreateFromUserProfileLanguages();
    var ocrResult = await ocrEngine.RecognizeAsync(bitmap);
    return ocrResult;
}

画像を渡して結果を受け取るだけなので、使い方は単純なのだが、

  • SoftwareBitmap クラスを扱わないといけない
  • WinRT の Async はデスクトップの async/await とは違った形になっている

の2点が難関になっている。

GetAwaiter メソッドを自作で拡張する

http://blog.xin9le.net/entry/2012/11/12/123231

を参考にして…というかそのままコードを持ってきて、以下のように GetAwaiter メソッドを拡張する。

public static class TaskEx
{
    public static Task<T> AsTask<T>(this IAsyncOperation<T> operation)
    {
        var tcs = new TaskCompletionSource<T>();
        operation.Completed = delegate  //--- コールバックを設定
        {
            switch (operation.Status)   //--- 状態に合わせて完了通知
            {
                case AsyncStatus.Completed: tcs.SetResult(operation.GetResults()); break;
                case AsyncStatus.Error: tcs.SetException(operation.ErrorCode); break;
                case AsyncStatus.Canceled: tcs.SetCanceled(); break;
            }
        };
        return tcs.Task;  //--- 完了が通知されるTaskを返す
    }
    public static TaskAwaiter<T> GetAwaiter<T>(this IAsyncOperation<T> operation)
    {
        return operation.AsTask().GetAwaiter();
    }
}

実はアセンブリ System.Runtime.WindowsRuntime.dll を追加すれば拡張クラスがあるはずなのだが、うまくいかないので自前で作る。クラスを作らない場合は、こんなビルドエラーがでてくるはず。

エラー	CS0012	型 'IAsyncAction' は、参照されていないアセンブリに定義されています。アセンブリ 'Windows, Version=255.255.255.255, Culture=neutral, PublicKeyToken=null, ContentType=WindowsRuntime' に参照を追加する必要があります。

SoftwareBitmap クラスを扱えるようにする

SoftwareBitmap ってのも、WinRT の世界のものなので、デスクトップアプリからは直接扱えない。これでは面倒なので、デスクトップアプリで使えるようにファイルパスを渡して SoftwareBitmap オブジェクトを生成する関数を作っておく。

/// <summary>
/// ファイルパスを指定して SoftwareBitmap を取得
/// </summary>
/// <param name=&quot;path&quot;></param>
/// <returns></returns>
private async Task<SoftwareBitmap> LoadImage(string path)
{
    var fs = System.IO.File.OpenRead(path);
    var buf = new byte[fs.Length];
    fs.Read(buf, 0, (int)fs.Length);
    var mem = new MemoryStream(buf);
    mem.Position = 0;

    var stream = await ConvertToRandomAccessStream(mem);
    var bitmap = await LoadImage(stream);
    return bitmap;
}
/// <summary>
/// IRandomAccessStream から SoftwareBitmap を取得
/// </summary>
/// <param name=&quot;stream&quot;></param>
/// <returns></returns>
private async Task<SoftwareBitmap> LoadImage(IRandomAccessStream stream)
{
    var decoder = await Windows.Graphics.Imaging.BitmapDecoder.CreateAsync(stream);
    var bitmap = await decoder.GetSoftwareBitmapAsync(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied);
    return bitmap;
}
/// <summary>
/// MemoryStream から IRandomAccessStream へ変換
/// </summary>
/// <param name=&quot;memoryStream&quot;></param>
/// <returns></returns>
public async Task<IRandomAccessStream> ConvertToRandomAccessStream(MemoryStream memoryStream)
{
    var randomAccessStream = new InMemoryRandomAccessStream();
    var outputStream = randomAccessStream.GetOutputStreamAt(0);
    var dw = new DataWriter(outputStream);
    var task = new Task(() => dw.WriteBytes(memoryStream.ToArray()));
    task.Start();
    await task;
    await dw.StoreAsync();
    await outputStream.FlushAsync();
    return randomAccessStream;
}
  1. System.IO.File でファイルオープンして MemoryStream へ読み込み
  2. MemoryStream から IRandomAccessStream に変換
  3. IRandomAccessStream から SoftwareBitmap に変換
  4. SoftwareBitmap オブジェクトを OCRエンジンに渡す

というややこしい手順になっている。

画面にマークを付ける

UWP アプリのサンプルでは、マークを XAML の Rectangle を使っているが、デスクトップアプリの場合は Bitmap に直接書き込んだほうが手軽だろう。そのために WPF アプリでやりたいわけだし。

private async void clickDetect(object sender, RoutedEventArgs e)
{
    var bitmap = await LoadImage(screenFile);
    var result = await detect(bitmap);
    text1.Text = result.Text;

    // 認識した個所をマークする
    var bmp = Bitmap.FromFile(screenFile) as Bitmap;
    var g = Graphics.FromImage(bmp);
    var br = new SolidBrush(System.Drawing.Color.FromArgb(0x80, System.Drawing.Color.Blue));
    var text = &quot;&quot;;
    foreach (var line in result.Lines)
    {
        text += line.Text + &quot; &quot;;
        foreach (var it in line.Words )
        {
            var rc = new System.Drawing.Rectangle(
                (int)it.BoundingRect.X, (int)it.BoundingRect.Y,
                (int)it.BoundingRect.Width, (int)it.BoundingRect.Height); 
            g.FillRectangle(br, rc);
            g.DrawRectangle(Pens.Red, rc);
            text += it.Text + &quot; &quot;;
        }
    }
    image.Source = bmp.ToImageSource();
}

public static class BitmapEx
{
    /// <summary>
    /// Bitmap から BitmapSource へ変換
    /// </summary>
    /// <param name=&quot;bmp&quot;></param>
    /// <returns></returns>
    public static System.Windows.Media.ImageSource ToImageSource(this Bitmap bmp)
    {
        BitmapSource bitmapSource = Imaging.CreateBitmapSourceFromHBitmap
            (
                bmp.GetHbitmap(),
                IntPtr.Zero,
                Int32Rect.Empty,
                BitmapSizeOptions.FromEmptyOptions()
            );
        return bitmapSource;
    }
}

そんな訳で

C# – C#で画像ファイルからOCRしたい(14229)|teratail
https://teratail.com/questions/14229

な回答が分かった訳だが(この質問は、OCR のサンプルを作った後に見つけた)、これ、ちょっと大変過ぎるよ。どうしたものか。

サンプルコード

https://github.com/moonmile/google-cloud-vision-sample

参考先

非同期メソッド入門 (10) – WinRTとの相互運用 – xin9le.net
http://blog.xin9le.net/entry/2012/11/12/123231
WinRTのAPIをデスクトップアプリから使う 8.1版 – かずきのBlog@hatena
http://blog.okazuki.jp/entry/2014/06/26/201327
c# – Is there a way to convert a System.IO.Stream to a Windows.Storage.Streams.IRandomAccessStream? – Stack Overflow
http://stackoverflow.com/questions/7669311/is-there-a-way-to-convert-a-system-io-stream-to-a-windows-storage-streams-irando
C# – C#で画像ファイルからOCRしたい(14229)|teratail
https://teratail.com/questions/14229

カテゴリー: 開発, C#, WinRT | 1件のコメント

Android Things 上で Xamarin.Android を使って Lチカする

Android Things 上で Xamarin.Android を動かして F# を使う | Moonmile Solutions Blog
http://www.moonmile.net/blog/archives/8451

ここから暫く経ってしまいましたが、Android Things + Xamarin.Android の組み合わせでLチカ(GPIO制御)まで出来たので、サンプルを流しておきます。

サンプルコード

android-things-samples/GpioAndroid at master ・ moonmile/android-things-samples
https://github.com/moonmile/android-things-samples/tree/master/GpioAndroid

バインディングプロジェクトを作る

プロジェクトは本体の「GpioAndroid」とバインディングプロジェクトの「GpioBinding」に分かれています。バインディングプロジェクトは、JarをラップするC#コードを自動生成してくれるプロジェクトですね。OpenCV for Android を Xamarin で使うときにも使います。

「Binding Library(Android)」でプロジェクトを作成すると、Jars フォルダなどが作成されます。

この Jars フォルダにバインドしたい Jar ファイルを入れます。ここでは、Android Things のバインドファイルの「androidthings-0.1-devpreview.jar」を入れておきます。このファイルは、Android Studio で Android Things プロジェクトを作るときにダウンロードしてきたものを使うのですが、サンプルコードにも入っているのでそのまま使ってください。

バインドするクラスやメソッドを調節するために、Metadata.xml ファイルに記述します。このあたりは、

jonpryor/SimpleAndroidThingsBinding
https://github.com/jonpryor/SimpleAndroidThingsBinding

を参考にしています。

<metadata>
  <remove-node
      path=&quot;/api/package[@name='com.google.android.things.pio']/class[@name='GpioDriver']/method[@name='close' and count(parameter)=0]&quot;
  />
</metadata>

どうやら、Close メソッドがダブっているらしくそのままではビルドエラーになるんですよね。なので、このメソッドを無視するようにします。

本体のプロジェクトを作る

普通に Single-View App プロジェクトを作って、先の「GpioBinding」プロジェクトを参照設定します。

using Com.Google.Android.Things.Pio;
using System.Threading.Tasks;

public class MainActivity : Activity
{
    TextView text1;
    Gpio mLedGpio;

    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);

        // Set our view from the &quot;main&quot; layout resource
        SetContentView(Resource.Layout.Main);

        // Get our button from the layout resource,
        // and attach an event to it
        Button button = FindViewById<Button>(Resource.Id.MyButton);
        button.Click += Button_Click;
        text1 = FindViewById<TextView>(Resource.Id.textView1);

        PeripheralManagerService service = new PeripheralManagerService();
        try
        {
            var pinName = &quot;BCM4&quot;;   // RPi3 
            // String pinName = BoardDefaults.getGPIOForLED();
            mLedGpio = service.OpenGpio(pinName);
            mLedGpio.SetDirection(Gpio.DirectionOutInitiallyLow);
        }
        catch 
        {     
        }

        var task = new Task(async() => {
            while (true)
            {
                await Task.Delay(1000);
                mLedGpio.Value = !mLedGpio.Value;
                System.Diagnostics.Debug.WriteLine(&quot;led: {0}&quot;, mLedGpio.Value);

                RunOnUiThread(() => {
                    if (mLedGpio.Value)
                    {
                        text1.SetBackgroundColor(Android.Graphics.Color.LightPink);
                    }
                    else
                    {
                        text1.SetBackgroundColor(Android.Graphics.Color.White);
                    }
                });
            }
        });
        task.Start();
    }

    private void Button_Click(object sender, EventArgs e)
    {
        mLedGpio.Value = !mLedGpio.Value;
    }
}

書き方は、Windows IoT Core と似ていますね。

  1. PeripheralManagerService で IoT のサービスを作成する。
  2. service.OpenGpio で指定ピンをオープンする。”BCM4″ は 4ピンのことです。ここの名前は https://developer.android.com/things/hardware/raspberrypi-io.html に定義されています。
  3. GPIO の値は Value プロパティで設定します。

基本は、

Interact with Peripherals | Android Things
https://developer.android.com/things/training/first-device/peripherals.html

と動きを合わせちて、ループは.NETらしくTaskを使っています。画面に表示するときは、RunOnUiThreadを使うことを忘れずに。

バインドする androidthings-0.1-devpreview.jar ファイルですが、これはスタブファイルなので中身は空っぽです。実行時には、com.google.android.things が使われるように、Properties/AndroidManifest.xml に uses-library を追加しておきます。これをしないと実行時に PeripheralManagerService が生成できなくてエラーになりあます(かなりハマった)。

<?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?>
<manifest xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot; package=&quot;GpioAndroid.GpioAndroid&quot; android:versionCode=&quot;1&quot; android:versionName=&quot;1.0&quot; android:installLocation=&quot;auto&quot;>
	<uses-sdk android:minSdkVersion=&quot;24&quot; />
  <application android:label=&quot;GpioAndroid&quot; android:icon=&quot;@drawable/Icon&quot;>
    <uses-library android:name=&quot;com.google.android.things&quot;/>
  </application>
</manifest>

実行してみる

adb connect android.local で RPi 上の Android に接続して(WiFi経由で接続できます)、Visual Studio から実行すると次のように Lチカができます。

LED がチカチカとするのと同期して、画面のラベルの色が赤と白が交互に点滅します。

カテゴリー: Android, Xamarin | Android Things 上で Xamarin.Android を使って Lチカする はコメントを受け付けていません

Raspbian, Windows IoT Core, Android Things on Raspberry Pi の三役揃い踏み

新しい Raspberry Pi 3 と液晶ディスプレイが到着したので、3つ同時に動かしてみました、の記録です。

image

RPi3 がちょっと安くなってる

aliexpress で Raspberry Pi 3 がちょっとだけ安くなっています。$36 程度で購入が可能になっています。細かい違いや、あれこれを気にしない場合は国内よりもちょっと安く手に入ります。

2016 New Raspberry Pi 3 Model B https://www.aliexpress.com/item/2016-Original-UK-Made-Raspberry-Pi-3-Model-B-1GB-RAM-Quad-Core-1-2GHz-64bit/32643511924.html?spm=2114.13010608.0.0.6S4vZd

RPi に乗せる液晶ディスプレイ(800×480)はこれを愛用しています。GPIO ピンがふさがってしまうのが難点ですが(別途半田付けすればいいんだけど)、HDMI 表示が簡単なのと別電源が要らないので手軽に扱えます。

5 inch 800×480 Touch LCD Screen 5″ Display
https://www.aliexpress.com/item/5-inch-800×480-Touch-LCD-Screen-5-Display-For-Raspberry-Pi-Pi2-Model-B-A-Hot/32707062356.html?spm=2114.13010608.0.0.MHXpmP

RPi3 は、ひとつだけ買ったのですが micro SD カードを差し替えて Windows IoT Core と Android Things を交互に試すのが面倒になって、2個追加しました。これで3つ同時に扱えるようになりました。

これで、Linux, Windows, Android と3種類の OS が揃ったので(iOS が Raspberry Pi に載ることはないでしょうから)、IoT としても用途によって OS を選べる、という段階に来たと思います。もちろん、LattePanda のように組み込みボード自体を変えてしまえば、フルな Windows 10 が動く状況を作るとか色々できますが、Raspberry Pi ボードがあれば3種類のOSが「用途に依って」使い分けができるところが良いところですよね。

以下、ざっと各 OS のダウンロード先と特徴を書いておきます。

Raspbian on Raspberry Pi

Raspberry Pi Downloads – Software for the Raspberry Pi
https://www.raspberrypi.org/downloads/

本家本元からダウンロードして micro SD カードに焼き込みます。中身は Linux の Debian なので、普通に LAMP サーバーとして使うことができます。大抵のものは apt-get で取って来れるので、低電力のミニサーバーを作りたいときはこれで十分かもしれません(micro SD カードの容量と読み書きスピードに依存しますが)。

GPIO を扱うときは、Python を使うのがお手軽ですね。Scratch とか node.js とかが動きます。私の場合、大抵は Tera term で ssh 接続して使うのでコマンドラインで使うことが多いので特に問題はないのですが、テキストベースの扱いに慣れていないとちょっと使い辛いかもしれません。

mono の環境を「apt-get mono-compete」でインストールすれば、C# を使ってプログラミングができます。

Windows IoT Core on Raspberry Pi

Raspberry Pi 3 と Arduino での Windows 10 IoT アプリの開発 | Windows IoT
https://developer.microsoft.com/ja-jp/windows/iot

上記から専用のアプリをダウンロードして micro SD カードに焼き込みます。Windows となっていますが、中身は似て非なるものなので、徹底して UWP アプリ(Windows ストアアプリ)として使います。バックグラウンドで動かす機能もあるけど、それならば Linux で動かしたほうが手軽なので。

アプリを Visual Studio で C# で書いて RPi にデプロイという形式ですね。エンタプライズ版もあるけど、それはこれからといったところなので、パーソナルベースで使うのがベターかと。プログラムが C#(時には F# で)書けるのがミソで、普通の UWP アプリに GPIO のライブラリを追加して使うという方法ができます。

 

Android Things on Raspberry Pi

Android Things | Android Things
https://developer.android.com/things/hardware/index.html

OS のスタイルとしては Windows IoT Core と同じで、スマートフォンの Android のサブセットという形です。元々 Raspberry Pi で Android 4.4 を動かすことができたのですが、Android Things は本家 Google がサポートする OS です。

基本は Android Studio を使って Java で Android アプリを作ります。スマートフォンではないので、カメラ機能やホームの機能もないのですが、UI 廻りや API 廻りはひと通り揃っているようです。GPIO は、別途ライブラリをインポートして使います。

ベースが Android なので、Xamarin.Android が使えます。Visual Studio 2015 で Android アプリを使ってデプロイすることで、C# でプログラミングができます。GPIO まわりはうまく jar 内のクラスに対して設定すればよいらしいので、あとで試します。

 

で、3つ並べてどうするのか?

それぞれのプログラムを作るときは、Python, C#, Java で切り替えることになるのですが、mono/Xamarin の組み合わせだと、C# や F# が使えます。あとは UI をどうするかとか、OpenCV を使うとか、既存ライブラリを流用するとかによって、OS を変えていくのがよいのではと思っています。ひとまず、RPi3 だと WiFi/Bluetooth が載っているので、各 OS が標準で対応してくれます。Raspbian をサーバーにして、Windows IoT Core/Android Things をクライアントにして何かの通信デモとか作ってみようかなと。

カテゴリー: RaspberryPi | 2件のコメント

再び、札幌へと Microsoft MVP 受賞

年末に札幌に向かおうと思ったところ、大雪で欠航してしまったので、Retry to 千歳です(「千歳」は動詞です)。

13:50 の便に切り替えたのですが、さらにピンポイントにその便が今度は機体チェックで欠航になってしまったので、Retry to 千歳, again ということで、16:00 の便に切り替え。20:00 頃に札幌に実家に到着。

雪が大量にあります。

無事 Microsoft MVP を受賞しました

1/2 に受賞の連絡を待つのは、年末年始の心臓に悪いので、10月応募をお勧めしないのですが(苦笑) Tomoaki Masuda (増田 智明) にて、Visual Studio and Development Technologies と Windows Development で受賞しています。これで、今年分の MSDN は確保できて一安心です。これも皆様のおかげで、あれこれと発表をしたり本を書いたりブログをちまちま続けたり Qiita に殴り書きしたりしたおかげでもあります by 「ばくおん!!」第9巻(最終巻)

ところで「ばくおん!!」ってなぜ女子高生が短足ぎみなんですかね。意図的になのか、日本人の現実に即しているというか(いや、むしろ最近の子は長い傾向にあるから、昭和な比率なのでは?とか)、まあ、面白くて参考になる漫画です。「のうりん」と合わせてお読みになることをお薦めします。

MS MVP のダブル受賞があるのだから、フィギュアスケートのようにトリプルがあったりしないのか?と思ったりするのですが、Excel 方眼紙あたりを極めれば Office Servers and Services とか合わせ技になったりしませんかね。Office 365 あたりを重ねるとか。

それはさておき。

Xamarin の無償化に伴いユーザー数もぐんと増えた感じがします。Microsoft が Windows Mobile を諦めた(っぽい)ので、今後は Xamarin を中心に Android と iOS に軸足を移していくことでしょう。社内的にも Mac を使っている方も多いようなので、Surface よりも Mac のサポートが早くなったり、Google の .NET 参入もあり、Android Things + Xamarin の組み合わせ Microsoft から Google 業界へもあるかもしれません。また、Raspberry Pi の ARM がソフトバンク傘下になったことと、米国の内政もあり、日本の諸々なオリンピック政策もあるでしょう。中国の動向や、EU の揺れ具合もあります。そういう、多少浮ついた世相の中では、雌伏し基礎体力をつけてて最新情報とやらに右往左往する「石々混淆」の脇を一気にすり抜けることが可能なチャンスでもあります。

そんな訳で、物理屋さん発なプログラマとしては地味な地固めとしての「プロジェクトマネジメント」に踏み込んでいきますよ、ということで TOC/CCPM を含めていきます(このブログ、もともとはバグトラッカーのツールを作ろうとか、諸々の就職活動用のブログだったんですよね)。

カテゴリー: 雑談 | 再び、札幌へと Microsoft MVP 受賞 はコメントを受け付けていません

忙しいときほど重要なのはチキンライスでもプロジェクトマネジメントでも段取り八分で

さらに第4弾な料理シリーズ。夕飯は近くのスーパーでコロッケを買ってきて済ませてしまったので、お昼のチキンライスを例に解説をします。

段取り八分

段取り八分ってのは確か建築業界の用語で、いろいろな業者が入ってくるときちんと段取りをしておかないと待ちが入ったりして全体が遅くなる、という意味だったハズなんですが、巷の「段取り八分」の解説サイトは間違ったものが多いですね…。現場監督の管理の基本「段取り八分」って何のこと? | 負けるな新人!目指せ所長!0から始める建築現場監督への道 あたりとか、建築系のブログを見ると正しいものが書いてあります。他のサイトは大抵ダメです。

建築の場合、材料と人を集めて順番にこなす、というのが重要になり(途中で「雨」がまじるので、プロジェクトバッファは必須なのですが、これは別の機会に)、それ以下に工程を短くすることができません(手抜き工事は別)。これがクリティカルチェーンです。なので、あらかじめ工程表を作るときに、どの順番で何をやるのかを決めておく、そしてその通りに仕事をこなす、というのが建築界の職人的な技法でもあります。

IT業界の開発案件の場合は、タスク内のトラブルの頻度とリカバリまでの時間の幅/分散が広いので、この「段取り八分」だけではうまくいかないのですが、サーバー構築とかデータ移行手順、多数のPCのセッティング、ネットワーク敷設、外部ルーター等のセッティングなどの計画は、この「段取り八分」の工程表が役に立ちます。あと手順書ですね。まあ、そのあたりをとりまとめて「経験」と呼んでいたりします。

チキンライスを作る

料理の場合も同じで、段取り(レシピ)が頭に入っているかどうかが重要になります。特に、チキンライスのような強火で扱うものは一瞬ですからね。最初の仕込みが肝心です。鶏のひき肉は、コープの「ぱらぱらミンチ」です。少しだけ使うようなときに便利です。

冷蔵庫の残り物で作るので、材料は適宜集めます。

image

玉ねぎを1/4だけみじん切りにして、ご飯を3膳分温めます。あとは、胡椒と塩。

image

材料を揃えたら一気に料理します。料理時間は5分程度です。中華鍋に油をひいて、白い煙がでるぐらいまで強火で温めます。

image

玉ねぎを入れて一気に炒めて、少し焦げた頃に、鶏のひき肉を入れます。

image

冷凍トウモロコシを入れて炒めた後に、ご飯を投入します。

image

ご飯をヘラで切るようにしてバラバラにしながら、ケチャップを色づくまでがっと入れます。大体、ケチャップの色が広がったら、塩をひとつまみと胡椒を入れて完成です。

image

ここまで終始、強火で炒めるので本当は写真を撮っている暇はありません。がっと、皿に移して出来上がりです。

image

中華鍋は、時々てんぷらをすると油の馴染みがよくなるのですが…、ご飯の焦げはこびりついてしまうので、こんな風に煮立てて落とします。本当は、おこげスープにするといいんですけどね。子供に不評なので捨ててしまいますが。

image

こんな風に、中華鍋で5分間強火で料理している間だけが「料理」ではなくて、最初に材料を揃えたり玉ねぎをみじん切りするところも「料理」のうちで、その部分が「段取り八分」という例になるんですよ。大抵の料理番組は、この段取り八分の部分が省かれてしまっています。残念。昔、日曜の5時頃(サザエさんの前あたり)にやっていた料理番組が調理前の段取りの部分からやっていて参考になりました(魚の骨とりとか、みじん切りの仕方とかからスタートするので)。

カテゴリー: プロジェクト管理 | 1件のコメント

失敗をリカバリするのはミートスパゲティもプロジェクトマネジメントも同じ

しつこいけど第3弾な料理シリーズ。単に、子供向けの夕食を作るのにモチベーションが上がらないので、あれこれやっているだけです。一人だったら外食とか弁当にしちゃうんですけどね。

失敗してもリカバリする

基本、料理は段取りと手順(料理本に書いてある手順)に沿って従えば、大抵「食べられる」ものができあがります。時には炭になってしまうこともありますが、まあ、それは完全に失敗なパターンですよね。でも、ちょっとした手順を抜かしたり、前後させてしまったような間違いの場合は、食材と時間がもったいないので「捨てる」ことはあまりないでしょう(客に出すものだったらそうかもしれないけど、家で食べるものだし)。同じようなことは、プロジェクトマネジメントにも言えて、ちょっと失敗したからといってプロジェクト全体を失敗(プロジェクトを停止するということ)させることはありません。なんとか完遂しようとするでしょう(間違った方向に突き進んでしまう場合のデスマーチ・プロジェクトは別ものです。あれは失敗し続ける話なので)。なので、ちょっと失敗をリカバリするのがプロジェクトマネジメントの極意であったりします。つまりは「失敗する」ことを前提として、失敗したら「リカバリ」するを繰り返します。

このためには、

  • 失敗したことを認識/確認する
  • リカバリ手段を講じる

の2手が必須です。たまに、そのまま放置するというリカバリ手段もありますが、これは「そのまま放置する」というリカバリをすることになります。単に流してしまうことではありません。

まあ、そんなところも含めてミートスパゲティを作ります。

ミートスパゲティを作る

特に失敗したい訳ではないのですが、まあ、これぐらいの材料で作ります。パスタはディ・チェコを使っています。

image

ビールを呑み呑み。赤ワインはトマトを煮込むときに入れます。

image

ミートパスタの玉ねぎはみじん切りにします。こうやってあらかじめ櫛型に切っておくと後が楽です。

image

玉ねぎのみじん切りと、にんにくのスライスです。オリーブオイルで揚げた感じが好きなので、こんな風に薄切りにしておきます。にんにくは冷凍してあったものです。

image

油を温めてからニンニクを入れるとはねるので、常温のオリーブオイル大匙1より多めとニンニクを常温でフライパンにいれます。ここから火をつけます。フライパンはトマトを入れるので深めのものを使います。焦げ付きやすいので、フッ素加工のものを使うといいですよ。

image

玉ねぎを炒めます。今回は中火ぐらいでちまちまと炒めます。ここで粒が残るとミートにしたときに美味しくないので、10分位、ビールを飲みながらちびちび炒めます。

image

で、本来はひき肉入れるところなのですが、トマトの缶詰を入れてしまいました。トマトパスタならばこれでいいんですけどね。トマトソースだけにする場合は、このあと唐辛子を入れるとおいしいです。

image

ひき肉を入れたときに、順番が逆だったことに気付きました。うーむ、どうしたものかと思いつつそのまま混ぜます。

image

ひき肉を炒めていないので、えらいぺちゃっとなったミートソースになっていますが、仕方がないですね。既に失敗作になっていますが、食べれるようにしていきます。

ひき肉に火を通すために、少し強火にしてひき肉に十分に火が通るようにしておきます。塩ひとつまみ、胡椒を振ります。赤ワインを入れるタイミングを逃しましたが、まあそのままで。味見をして、少し塩気を多くしました。どうやらひき肉を炒めなかったのでうま味が足りないんですよね。でも食べれないことはないです。

image

大鍋にお湯を沸かします。たくさんの湯を使うのがいいのですが、時間が掛かるので半分ぐらいにしておきます。実は、パスタの場合は、湯の温度が下がらないからそんなに湯量は多くなくていいのです。生そばや生うどん、ラーメンの場合は湯温が下がらないように多めの湯にします。

パスタを入れる前に、大匙1の塩を入れます。

image

隣でミートを弱火で煮込みながらパスタをゆでます。あれば、ローリエを一枚入れます。無くても大丈夫です。ゆであがったら、ざるに移して、バター大さじ1/2を入れて、がっと混ぜます。こうするとパスタがくっつきません。ゆで汁を少し加えるのもいいでしょう。

パスタの量は3人弱の 250g 位になっています。

image

大皿にパスタを乗せて、ミートを半分位のせてできあがりです。残りのミートは冷凍しておいて別のときに使います。

image

ひき肉を炒めていないので、ミートのそぼろ感がないのがアレですが(苦笑)、まあ味のほうは大丈夫です。子供向きなミートスパゲティですね。大人の場合は、唐辛子を入れるとか胡椒を多めに入れるとかすると違った味になります。

カテゴリー: プロジェクト管理 | 失敗をリカバリするのはミートスパゲティもプロジェクトマネジメントも同じ はコメントを受け付けていません

PERT図とカレー調理の関係

チンゲン菜で作るおいしい餃子とプロジェクトマネジメントの関係 | Moonmile Solutions Blog の続きで、プロジェクトマネジメントと料理の関係です。いや、単純におらのカレーレシピですけどね。ちまちま、Windows 10 IoT Core Advent Calendar 2016 – Qiita を埋めつつ、中小規模のプロジェクトマネジメント案を練りつつということです。

タスクを並立させる

餃子料理の場合は、ひとりタスクになりますが、カレーの場合はいくつかのタスクが平行して動きます。複数名でプロジェクトを動かせば途中のマイルストーンがネックになり、ひとりでプロジェクトを動かしてもお客が絡めば応答時間によってマルチタスク的に動かせるという話です。ラピッドプロセスやJIT的に応答を返すのではなく、むしろ、その時間差を利用するという方法ですよね。どれだけ急いでも必ず時間が掛かるような薬剤の検査プロセスのようなものを想定してください。時間が掛かる部分は、止まっている必要はなくて、何か別のタスクを重ねることで全体の時間=クリティカルチェーンが短くなります。これは PERT 図とガントチャートを併用すること判明できます。

カレーを作る

今日は鶏肉でカレーを作ります。あらかじめ切ってあるのもいいけど、鳥皮が欲しいのでもも肉を買います。これでだいたい6人分です。カレーのルーが12人分なのと、鍋の大きさの関係を考慮すればokです。

image

ピーラーで向きます。便利ですね。

image

ジャガイモをざっくり切って、ニンジンは乱切りにして水につけておきます。ほんとうはジャガイモだけでいいんだけど、面倒なので人参も一緒に。

image

玉ねぎは、ざくざくと薄切りでokです。ホワイトシチューの場合は色を付けないために薄く切ったり、みじん切りにしますが、カレーだし、これで十分です。

image

生姜を微塵切りにします。皮は大匙でこそげるように向くと楽です。

image

こんな感じにみじん切りにして、

image

鍋に突っ込みます。まだ火をつけていない状態で、玉ねぎ、しょうがを入れて、オリーブオイルを大匙1か2ぐらい。

image

鶏肉をひと口大に切ります。野菜 → 肉類の順で切ると、包丁やまな板を洗う手間が減ります。ムダな手間を省くための「段取り」が大切です。

image

塩をひとつまみ、胡椒、酒を大さじ1入れて、小麦粉を大さじ1半位入れます。小麦を肉のまわりにつけるとなめらかになって美味しくなります。これを、パックの上で混ぜます。パックはそのまま捨てるから洗い物がひとつ減りますよね。

image

肉のほうは、塩や酒がしみこむまで「しばらく置く」ので、その時間を利用して玉ねぎを炒めます。ここがちょうどマルチタスクになっているところです。玉ねぎは強火で炒めてもokです。弱火のほうが焦げなくてすむのですが、時間がかかるので、強火で。カレーなので多少焦げても大丈夫です。

image

だいたい水分が飛んで玉ねぎに色がついてきたら、味がしみこんだ(だろう)鶏肉を投入。

image

ここもひたすら強火で大丈夫です。鍋に小麦粉が焦げ付きますが気にせず炒めていきます。へばりついた小麦は水を入れたときにきれいに落ちます。肉のまわりを少し焼いておくことで、水分が中に入り過ぎずにすみます。牛肉だったりすると肉汁が水にでなくなります。

image

人参とじゃかいもの水を切って鍋に投入。軽く混ぜます。

image

水を具が浸るまで入れます。これだと600ccぐらい。ルーが多いと堅めになるし、少ないと緩めのカレーになります。

image

別途、圧力釜で用意していたご飯も同時に炊き出します。カレーは15分煮込み。圧力釜のごはんは強火で沸騰させた後、5分だけ弱火で。

image

15分経って、蓋をあけて

image

6人分のルーを入れて、きちんとかき混ぜて、ひと煮立ちさせます。

image

うちにはシャトルシェフがあって、魔法瓶のように鍋ごと温めることができます。普通に煮込むのと同じ効果が得られ、これで15分置きます。トータル30分煮込むのですが、最後の15分は、火の番をしなくてよいので、皿を並べるとかご飯をよそうとか別のことができます。

image

15分経ってできあがりです。かき混ぜたりしないので煮崩れしないのが特徴です。大根の煮つけとか、崩れそうなものはこれを使うとうまくいきます。ガス代も浮くしね。

image

炊き上がったご飯にカレーを掛けてできあがり。

image

パラレルで料理を作る

この煮込んでいる間とか、味がしみこむ間を利用するのが、20分で2品おかず (ベターホームの料理の先生おすすめレシピ集) です。絶版?扱いになっていますが、この本には2品を同時に作る(同時にできあがる)レシピが載っています。

これはプロジェクト運営にも活用できるテクニックで、ひとりプロジェクトであってもひとつのタスクをシーケンシャルにこなすのではなく、何かの待ち時間をうまく利用してタスクを平行動作させるのです。複数名のプロジェクトでも、できるだけシーケンシャルにならないようにタスクを配置します。設計においても注意が必要で、実装時にマルチタスクで作業ができるように設計するという技があります。段取りとパラレルで料理を作ることを覚えると、同じことを実際のプロジェクトでもできるようになるので、試してみてください。

カテゴリー: プロジェクト管理 | PERT図とカレー調理の関係 はコメントを受け付けていません

チンゲン菜で作るおいしい餃子とプロジェクトマネジメントの関係

数十年振りの大雪で、千歳行きが欠航になってしまったよ~。そんな訳で、家に帰って餃子を作った記録です。ちなみに、道民としては千歳空港が大雪になるのだから、今年は特別どう仕方がないよね、な気分ですね。あそこは、雪が少ないので空港になっているので、例年、札幌が雪で埋まっていても千歳空港は大丈夫なのです。ちなみに、道民なので当然のごとくAIRDO を使いますよ。

さて、以前(と言っても7年前ですね)、PMBOKとCCPMのおいしい関係(仮) | Moonmile Solutions Blog というのを .NET ラボ勉強会で発表しました。CCPM 系のプロジェクトマネジメントも個人的には10年以上やっていますが、実際のプロジェクトでは試したことはありません(部分的にはあるけど)。その第一の理由に、WBS/PERT図/ガントチャート を同時に操れるツールが無く、また10年前にはその技術的な手段がなかったことがあげられます。去年の正月にひな形として、XAML + Xamarin + タブレットの組み合わせ少し作ってみたのですが、もう一度挑戦してみようとしているところです。まあ、ツールは「かなづち」でしかないので、中身のほうが本質的なんですけどね。本質的なほうは、年明けから書籍として書き始める予定です。

ソフトウェア開発と料理は似ている

2016-12-22 – 散財日記2008 ここに、ちょっとだけ言及してあったので賛同しておきましょう。プログラマやプロジェクトマネージャは「料理」をしてみると良いです。レシピ≒仕様的なものもあり、2,3品目を同時に作る≒タスクの同時並行なところも一緒です。ところどころで臨機応変なところとか(フライパンの状態をみたり、焼き加減をポーリングしたり)、下ごしらえをして準備をしておくところ(下味とか、中華料理の場合は材料を切っておくのが重要とか)も同じです。まあ、PMBOK に従って料理を作ってみるのもありでしょう。

まあ、学ぶところは多いのでプログラマ、プロジェクトマネージャな方は料理をやってみるとよいです。料理本のレシピの書き方とか(クックパッドでもいいけど)が参考になりますよ。

巨大チンゲン菜で餃子を作ろう

おらの畑で採れたチンゲン菜を使いましょう。買うときは、ひとたま全部使うとよいです。年末は、葉ものが高くなっているので、まあ、安くなったら作るということで。

2つ使おうと思って採ってきたのですが、さすがに多いのでひとつだけ使いました。重さは、まあ大体で大丈夫。白菜とかキャベツでも同じですが、茹でると小さくなるので。

鍋に入れて、1分間だけ茹でます。

ざるに開けて、荒熱を取ります。結構縮みましたね。

みじん切りに刻んでいきます。面倒なので、本当のみじん切りじゃなくて細切れぐらいになってますが、これで大丈夫です。

ほら、こんなに小さくなりました。

豚と牛のあいびき200グラムと混ぜます。これで40個分ができます。豚だけで作るとちょっと脂っこい感じの餃子になり、牛肉だけだとハンバーグっぽいニクニクしい餃子になります。作るときの好みで分けてください。量は、200~250グラムぐらいで大丈夫。

薬味のために、すりおろしの生姜を入れます。これも、好みで生姜のみじん切りとか、擦った後に汁だけ入れるとか、ニンニクを使うとかでもいいでしょう。肉の臭みが取れます。

ボールに入れて、最初は手で混ぜて後はヘラで混ぜています。手がべたべたになるので、手袋をしたりしますが、面倒なので4,5回だけ手を使ったほうがいいです。その後はヘラで十分。

調味料は、塩をひとつまみ、酒・醤油・ごま油を大匙1、入れています。ごま油を入れるとぐっと中華料理っぽくなるのでおすすめです。胡椒を入れるとちょっと洋風になります。

平たいバレットに移します。そのままスプーンですくってもいいのですが(お店の人はそれで作りますよね)、家だと餡が余っても困るので40等分できるように平たくします。ちなみに、余った分を単に焼いても美味しくないので、清く捨てています。

さて、40個を一人で包みます。ひとりで40個というのはなかなかの苦行なので、ビールを飲み飲みやると効果的です。餃子の皮は、大判のものを使います。ふつうの大きさだと餡が大きくなって包みにくい=時間が掛かる、ので嫌になるので、大判の皮を買ってちょっと少な目に餡を入れるのがコツです。

40個できたのが、この状態です。多少はみでてしまっても、少し口が開いていても大丈夫です。焼いても水餃子にして茹でても、餡が固まるので、見かけは関係なくおいしく食べられます。

ホットプレートに少し油をひいて、40個一気に並べます。油をひくのは少し焦げ目をつけたいのと、底の部分だけ最初に焼いてはがれやすくします。

200度で1,2分焼くと、こんな風に少し焼けた感じになります。こうすると、水を入れてもはがれやすくなるのです。

本当はお湯を入れるのがいいのですが、水でも大丈夫です。40個の餃子で150cc弱入れると、うまく水を吸ってくれます。多いとべたっとした感じになるし、少ないと皮が水分を含んでなくてぱりぱりすぎる感じになります。ここは何回かの試行錯誤が必要ですね。

image

水/湯を入れたら蓋を閉めて、むらし状態にします。餃子の王将と同じ製法です。

何回か開けて確かめてみて、こんな風に中身が透けて、水が程よくなくなったら蓋をあけます。最後の水分は、こうやって外に飛ばすようにします。こうすると、うまく底の部分が焼けます。

ホットプレートで金属のフライ返しはダメなんですが(フッ素加工が取れてしまうので)、まあ、フライ返しを使うのが楽です(このホットプレート自体も10年ものだし)。耐熱プラスチックのフライ返しを使ってもいいですよ。

焼いている底を見せるようにすると、美味く見えるのですが、自分用だし面倒なのでガンガン取り出してしまいます。

たれは、酢と辣油だけで ok です(醤油は入れていません)。S&B の辣油が辛くておいしいです。子供には、たれをつけずにそのままでも美味しい。家なので、七味を入れるとか、ポン酢を使うとか色々できます。

そんな訳で、白飯を温めて、ビールをもう一缶開けて戴きます。日本人だから、餃子には白いご飯が必要ですよね。by 孤独のグルメ

チンゲン菜の餃子レシピは、仕事で一緒した中国の方に教えてもらったものです。キャベツと違って臭くならないし、白菜よりも水分を含んでくれます。水餃子にしても美味しいので、ぜひお試しあれ。

カテゴリー: 雑談 | チンゲン菜で作るおいしい餃子とプロジェクトマネジメントの関係 はコメントを受け付けていません

中華な組み込みボードを買おう&使おう

手に入りやすい組み込みボードと言えば、Raspberry Pi や Arduino が有名ですが、ちょっと高め(とはいえ、PC やスマートフォンを買うよりは安いけど)が難点です。となれば、中国での互換機を買うのもよいですよ、という話です。

中国産だと品質がとか技適がというのもありますが(技適は「広い家」で実験すればいいですよね)、会社に納品と言うの場合は高品質&入手の継続性が求められますが、個人であれこれ実験する場合には中国産の製品でも十分です。というか、実質、深圳や上海から送られてくる製品は日本や欧米の製品を既に上回っていると思います(安いのは人件費廻りか?)。特に、組み込みボードの場合は、入手性を考えて予備を含めて2個以上買うことが多く初回の購入であってもそれなりに安いほうがお財布に優しいでしょう。

久し振りに「表徴の帝国」を読み返したのですが、東洋のパッケージの考え方は西洋のパッケージとは違います。表層にこそ意味を持たせ表層のみでも独立して意味を成すという考え方が日本や中国には共通してあることがわかるでしょう。欧米の Kickstater よりも中国のほうが箱のデザインに気を使っていることがわかります。まあ、中国郵便でガムテで貼ってあるし、部品関係は透明ラップでぐるぐる巻きですけどね。これはだいぶん慣れました。

Aliexpress で電子部品を買うと、だいたいこんな包装です。これは 7インチ液晶2枚です。

ちなみに、AliexpressAlibaba で購入して日本に送ると、ほとんどが中国郵便&無料発送で送られきます。UPS とかも使えますが高いので、中国郵便を使っています。これは日本郵便に引き渡されるので書留になるらしく、20回位買っていますが紛失は一度もありません。何でも安いのではなくて、深圳や上海で作っているものを買うと安いです(日本や欧米から輸入しているものは当然高い)。つまり、中国の工場で部品として作られて欧米に出しているものが安いわけです。そのほかは ebay のほうがいいかもしれません。

深圳、上海、香港は地理的に日本に近いので、中国郵便であっても向こうから Shipping(発送した)のメールが来てから1週間ぐらいで届きます。これが欧米だと船便だと1か月ぐらいかかります(以前、英国から Raspberry Pi 初代を送って貰ったときは、こちらに到着する直前に RS コンポーネントから発売されていましたよ)。そういう点で、部品を買うのに日本は欧米に比べると優位な位置にあります。

はじめて買うときは、いきなりスマートフォンのような1万円強を買うのではなく、中華 Arduino 300円のようなもので試してみましょう。長いと2週間位かかることもあるので、自分が欲しい時期と到着する時期がずれるので、無駄買いしないように気を付けてください。

以下は、手元の組み込みボードの色々を。

LattePanda

http://www.lattepanda.com/ で購入できる Windows 10 が動く組み込みボードです。Search LattePanda- DFRobot で $89 で購入して、Windows 10 Pro へアップグレードしています。Arduino がボードで直結している状態で Firmata で制御します。まあ、そうなると普通に PC + Arduino の組み合わせで良いのでは?とは思うけど、この手の Windows 組み込みボードとしては1万円弱なので安いほうかと。

NanoPi

NanoPi 2 Fire は http://www.nanopi.org/ で購入ができます。Raspberry Pi 互換機で Linux を動かすこともできるし、Android 5.1 が動きます。Android のほうは Google Play が動くもので、ソースコードがからビルドもできます。NanoPi2  Fire で $22.99 です。

Android Things が出てきたので、NanoPi  の役割が…と思わなくもないのですが、積極的に Android のコードに対応しているところをみると、Android Things のほうも独自に対応していくんじゃないかなと思ってます。

Orange Pi

Raspberry Pi 互換機の老舗? Orange Pi です。互換機の Orange Pi PC は Rasbian も動くし Scratch も動きます。Orange Pi PC は Aliexpress だと $15 位で買えます。

Android 4.4 が動くので購入してみたのですが、ちょっと重くて使い物にはなりません。なので、普通に Raspberry Pi 互換機として利用するのがベターかと。

orange pi pc – Orangepi

orange pi zero – Orangepi

Orange Pi Zero は、小型で WiFi 付きなのですが、HDMI がないのでディスプレイに出すのにひと苦労します。TVOUT の出力はあるので、そのあたりは自作するパターンで。

https://pbs.twimg.com/media/C0KbsegUoAAkU_v.jpg

Onion Omega

Onion – Invention Platform for IoT は、組み込み Linux のボードで $19.99 です。Onion が中国だったかは覚えていないのですが、Kickstarter でワンセットを買いました。

自前で WiFi を持っているので、Python を入れてサーバーとして使うことができます。

そんな訳で、23日発の羽田発千歳行きが欠航になってしまったので、気晴らしがてらにざっとまとめですよ。

カテゴリー: 組み込みボード | 中華な組み込みボードを買おう&使おう はコメントを受け付けていません

Android Things 上で Xamarin.Android を動かして F# を使う

この記事は、F# Advent Calendar 2016 – Qiita の 17日目です。なんか、曜日を勘違いしていて担当が日曜日だと思っていたんですよね。ほぼ日手帳が月曜日はじまりのカレンダーを使っているものだから、カレンダーの右端は日曜日なのですよね。長年使っていて便利です…という宣伝はさておき、F# の話です。

Android Things が発表された

Android Things が先週 Google から発表されました。

image

もともとあった、Brillo の進化形ということ(私は Brillo 自体をよく知らない)なのですが、前身はさておき、Raspberry Pi 等で Android が動くという環境です。もともと、Android の足回りは Linux な訳ですから、Raspberry Pi のように Linux 互換の OS(Raspbianなど)が動く組み込みボードであれば動く可能性もあったし、いままでも Raspberry Pi 上で Android 4.4 を動かすとか、Orange Pi や NanoPi のような Raspberry Pi 互換機で Android 5.1 が動くというパターンもありました。実は、つい先日  Android 5.1 をソースコードからビルドして NanoPi 2 Fire で動かすまで。 | Moonmile Solutions Blog な形で、Android のソースコードからビルドして NanoPi で Android 5.1 を動かすところまでたどり着いたところです。

もともと、スマートフォンの動作環境として開発された Android ですから、スマートフォンだけにターゲットを絞ると、Android Things が出てきた意味がよくわからないと思うので、少し背景を解説しましょう。

Android Things が現れた背景

スティックコンピュータと Raspberry Pi のような組み込みボード(ここでは OS が動く組み込みボードを対象にします)の違いは、その拡張性にあります。拡張性とはいっても、デスクトップ PC のようにストレージを増やせるとかメモリを増やせるとかということではなくて(そういう点でも、スティックコンピュータは拡張性がありません)、GPIO などを使って機器制御ができるという「拡張性」になります。いわゆるLチカのようにON/OFFでLEDを光らせるだけでなく、液晶ボードの I2C 通信や、各種サーボの PWM 制御によるロボットの動作、各種センサーのデータ収集などに使えます。

かつて、データ制御やロボット制御は、PC に高価な GPIO ボード(確か50万円位したはず)を繋げて制御したときもあるのですが、最近だと、安価な Raspberry Pi などを使う(学習用の組み込みであれば5,000円程度です)ことが可能です。そう、ある意味で「壊れても痛くない」程度の金額になります(まあ、個人でやると痛いけど)。

なので、今だとある程度工夫すれば、PC + 組み込みボードという金額的にも場所的にも費用が掛かるものを、組み込みボードで小型化かつ安価にできるようになってきました。

Raspberry Pi の場合、Linux を乗せて動くので基本はターミナルで動かします。学習用としてはデスクトップPCの代わりとして使えるけど、ディスプレイ無しの安価な制御PCとしてのほうが有効に使えます。というのも、画面まわりが非力で(最近は高機能になりましたが、PC のグラフィックボードよりは非力です)画面のあれこれと、制御のあれこれをやろうとすると、結構 CPU が大変なことになってしまうのです。ここで、「住み分け」として、高価な UI は PC でやって、制御絡みは組み込みボードでやります。やってもよいのですが、単体で動かすとやっぱりなんらかのモニタ的な表示がないと辛いものがあります。電源がついたあとに動いているかどうかすらわからないという状態に陥りますね。

ここで、Raspbian 上で Qt などを使って UI を作ってもよいのですが(実際、そうやって作っている方も多いt思います)、UI を作るとなると Windows や Android のように既にノウハウのあるところの開発者がいたほうがいいですよね。

そういう発想のもとで、UI の性能自体は OS の性能はぐっと落ちるかもしれないけど、アプリケーションは Windows のように作るというのが Windows IoT Core の考え方です。Windows IoT Core は、PC の Windows 10 とはかなり使い方は違っていますが UWP アプリ(ストアアプリ)という点では同じように作ることができます。その代り、PC の Windows 10 にあるようなスタート画面や高機能アプリは一切ありません。

同じ発想は、Android の組み込みボードの世界にもあって(購入すると3万円位かかります)、組み込みボードに Android を乗せて UI の部分は Android のものを使うというものがあります。先の Orange Pi や Raspberry Pi に乗せた Android は、スマートフォンに乗せているものと同じなので、非力な組み込みボードの CPU ではひどく重いものです。CPU を早くするとボード自体が高価になるし、Android の使い勝手をよくしようと思うとスマートフォンと同じ程度のスペックが組み込みボードに要求されてしまいます。この点で、かなり「詰んだ」状態にはなっていました。

そこで、Android Things の再登場です。

  • 通常の Android よりも低スペックで動作する。
  • Android UI を通常通りに使える。

この両方を満たすために、Windows IoT Core と同じ方法を Google は取りました。いわゆるスマートフォンを起動したときのホーム画面等が一切ありません。その分、ストレージや CPU への負担が軽くなっています。

更に云うと、実質(と思われる)Android SDK v7 で動くようになっています。スマートフォン用の API がどこまで削られてか分かりませんが、少なくとも Xamarin.Forms でビルドしたアプリを Android Things に乗せても平気なぐらい「API が削られていない」ことがわかります。

https://pbs.twimg.com/media/CzzlwS-VEAEDa0A.jpg

つまり、Android Things は

  • ほぼ API が削られていない(と思われる)Android SDK v7 が動く
  • GPIO 等を動かす、com.google.android.things.* が jar で提供されている

という組み合わせになります。jar ファイルは androidthings-0.1-devpreview.jar のようです。Windows IoT Core でもそうですが、この別口のライブラリをプロジェクトに追加することで、組み込みボードの制御ができます。ちなみに Linux 系は /sys/class/gpio のファイルを開くだけなのでスクリプトでも結構簡単にできるんですよね。Android Things が何を使っているかわかりませんが(あとでコードを見るつもり)、似た感じだと思います。

ちなみに Android Things では adb shell の中身が充実しています。

https://pbs.twimg.com/media/CzruhYaUcAARHgt.jpg

perl や python のようなスクリプト系の言語がないのは残念なのですが(いずれ入れられると思う)、posix 互換だそうなので、それなりにコマンドと API が揃っています。

 

Android Things と Xamarin.Android の関係

.NET 界隈では Xamarin が流行っている訳ですから、(私的には)Android とはいえ Java でやるよりも C#/.NET でやろうという訳です。そうなると、Xamarin.Android を使って Android Things のアプリを作れるといいですよね。

というわけで、xamarin/xamarin-forms-samples: Sample apps built using the Xamarin.Forms framework から、Xamarin.Forms のサンプルをいくつかダウンロードして動かしてみると、動きます。きちんと mono の環境が入って、C# でプログラミングをすることができます。

GPIO がらみは com.google.android.things.* をラップしないといけないのですが、

jonpryor/SimpleAndroidThingsBinding
https://github.com/jonpryor/SimpleAndroidThingsBinding 

な形で、XML を使ってマッピングができるそうなので、これも後で試していきます。こうなると、Android Studio を使わなくても、Xamarin.Android/Forms の開発スタイルで、Android Things で機器制御のプログラムが組めるということになります。

Raspberry Pi 3 で動かしたところ、オンボードの WiFi を認識して繋げることができました。Bluetooth はまだ試していないのでがつながるでしょう。あと、カメラとかの定番も試していきます。各種のサンプルは https://github.com/androidthings で提供されています。

アプリケーションは、Google Play がないので、adb installl でインストールします。Xamarin.Forms の場合は署名がなくてインストールできなかったのですが、リリースビルドをして署名をすれば入るでしょう。

mono が動くということは F# も動きますね

mono が動くことが確認できれば、もれなく F# が動きますよね :)

非常に簡単だけどボタンクリックのサンプルだけを動かしてみました。

えっ? F# 成分はこれだけですか…いや、まあ、これだけです。ちゃんとしたものはそのうちに。

image

日曜日に、年末恒例の矢野顕子「さとがえるコンサート」に行ってきたのでその写真でも。青色 LED がまぶしすぎて目がチカチカしますよ。輝度をもう少し下げたほうがいいかもしれません。手ぶれしているし。

では、皆さまのよきクリスマスを祈りつつ。

カテゴリー: Android | Android Things 上で Xamarin.Android を動かして F# を使う はコメントを受け付けていません