Xamarin.Forms で .NET Standard を利用してファイルアクセスするまで

Xamarin.Forms プロジェクトのPCLを .NET Standard 化する方法を調べていくと、Visual Studio 2017 のリリース前だったりするので、project.json の変更があって「あれ?」となってしまうので、ちょっと記録的に。
ちなみに、この記事も半年ぐらい経つと意味がなくなるような気がするので、まあ、そのときはそのときで。

Xamarin.Formsでプロジェクトを作る

普通にXamarin.FormsでPCLを使ったプロジェクトを作ります。

Visual Studio 2017 の場合は、コード共有で「ポータブルクラスライブラリ」のほうを選択。

.NET Standard のクラスライブラリを追加する

[Visual C#]→[.NET Standard]で、「クラスライブラリ(.NET Stanrdard)」を追加

.NET Standardのプロジェクトを編集して、PackageTargetFallbackの部分を追加。これがないと、NuGetからXamarin.Formsを取り込めません。

<Project Sdk=&quot;Microsoft.NET.Sdk&quot;>
  <PropertyGroup>
    <TargetFramework>netstandard1.6</TargetFramework>
    <PackageTargetFallback>$(PackageTargetFallback);portable-net45+win8+wp8+wpa81;</PackageTargetFallback>
  </PropertyGroup>

その後で、NuGetからXamarin.Formsをインストールします。

PCLプロジェクトからファイルをコピー

ソリューションエクスプローラで、「App.xaml」と「MainPage.xaml」をマウスでドラッグして、.NET Standardのプロジェクトにコピーします。
csprojファイルを開いて、ItemGroupのところをコピーしてもよいです。

Properties/AssemblyInfo.cs ファイルだけはコピーしません。内部的に、AssemblyTitle やらが作らている模様。

ちなみに、.NET Standardプロジェクトを追加したあとで、PCLプロジェクトをアンロードすると二度とロードできないという現象が発生します。なんだかなー。そういうときは、一度、.NET Standardプロジェクトを外して、PCLプロジェクトをロードします。

この手順を逆にして、.NET Standardプロジェクトのcsprojの内容を、PCLプロジェクトのほうにコピーしてもOKです。

Xamarin.iOS/Adnroidプロジェクトの参照を変更する

Xamarin.iOS/AdnroidプロジェクトからPCLプロジェクトが参照されているところを、.NET Standardプロジェクトのほうに変更します。
と、同時に Xamarin.Forms のバージョンも合わせておきます。

これでやっとこさ、Xamarin.Formsで.NET Standardが使える状態が完了です。まあ、ここまで作れたものをXamarin.Formsのプロジェクトテンプレートとして置いておけばよいので、一度作れると後は楽かも。

試しにファイルアクセスさせる

MainPage.xaml をこんな感じで修正しておいて、

<StackLayout>
    <Label Text=&quot;Welcome to Xamarin Forms!&quot; />
    <Button Text=&quot;save&quot; Clicked=&quot;Save_Clicked&quot; ></Button>
    <Button Text=&quot;load&quot; Clicked=&quot;Load_Clicked&quot; ></Button>
    <Label x:Name=&quot;text1&quot;  Text=&quot;output&quot; />
</StackLayout>

Save/Loadボタンをクリックしたときのイベントがこんな感じ。

private async void Save_Clicked(object sender, EventArgs e)
{
    var path = "/data/user/0/App18.Android/files/";
    var st = System.IO.File.Open(path + "sample.txt", FileMode.OpenOrCreate);
    using (var sw = new StreamWriter(st))
    {
        await sw.WriteLineAsync("sample data");
    }
}

private async void Load_Clicked(object sender, EventArgs e)
{
    var path = "/data/user/0/App18.Android/files/";
    var st = System.IO.File.Open(path + "sample.txt", FileMode.Open);
    using (var sr = new StreamReader(st))
    {
        var text = await sr.ReadToEndAsync();
        text1.Text = text;
    }
}

Xamarim.iOS/Androidであれば、「System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments)」と書くところが、パスを直書きになっているのがアレですね。iOS/Androidの場合分けが必要でしょう。どうやって書くのか判りませんが。
Xamarin.Forms の場合は、System.IO.Fileがないので、これが使えるということは無事 .NET Standard 化しているということです。

Androidエミュレータで実行すると、こんな感じになります。

じゃあ、PCLは.NET Standardに完全に置き換わるのか?

standard/docs/netstandard-20 at master ・ dotnet/standard
https://github.com/dotnet/standard/tree/master/docs/netstandard-20

を見る限り、「No PCL left behind. Dakota can consume a PCL based assembly from a .NET Standard-based library without having to jump through hoops.」とあるので、生のままでPCLを使うことは少なくなるんでしょう。少なくともProfileの順列組み合わせ状態は激減するかなと。現状、あまり意味がないし。
その後は、.NET Standard が肥大化しちゃうか、機種依存な機能が漏れてしまうかのところなんだけど、いまのところXamarin.Formsに関しては下回りのPCLは必須な感じがします。

カテゴリー: 開発, Xamarin | Xamarin.Forms で .NET Standard を利用してファイルアクセスするまで はコメントを受け付けていません

Azure 上の .NET Core では DbSet の Join ができない

ひどくピンポイントかつ3時間ほどハマってしまったので、メモ書き的に残しておく。

環境は、

  • ASP.NET Core
  • .NET Core 1.1
  • EF Core を利用

ASP.NET Core で Web API を作っていて、ローカルの .NET Core で LINQ の Join が動いていたのだが、いざ Azure にアップロードして動作させると、Join 部分がうまくいかなくて意味不明なエラーを返した。

var cnt1 = (
        from ti in _context.TicketView
        join st in _context.Status on ti.Status_Id equals st.Id
        where ti.ProjectId == project.Id &&
                ti.Tracker_Id == tr.Id &&
                st.IsClosed == false
        select ti.Id
    ).Count();

とあるところで、こんな風に TicketView と Statues テーブルを JOIN させた。何をやりたかったかというと、Statues テーブルの IsClosed フラグを見て、その数をカウントしたかったのだ。これを、ローカル PC の ASP.NET Core で動作させると、するすると動いたので、そのまま Azure に乗せてみると…

テーブル構造が違っているからマイグレーションしろ、

というお達しが来る。最初は、エラーの意味が解らなくて四苦八苦したのだが、少しずつ障害を絞り込んでいくとここの JOIN 部分に至った。この JOIN を消してしまって、var cnt1 = 0 とすると動作することが分かったので、あれこれやって、

var status = _context.Status.OrderBy(x =&gt; x.Position).ToList();
var ticketviews = _context.TicketView.Where(x =&gt; x.ProjectId == project.Id).ToList();

var cnt1 = (from ti in ticketviews
            join st in status on ti.Status_Id equals st.Id 
            where ti.ProjectId == project.Id &&
                    ti.Tracker_Id == tr.Id &&
                    st.IsClosed == false
            select ti.Id).Count();

な風に、一度 List に取り込んでから JOIN するとうまく動くようになった。

LINQ を使ってジェネリックの List 同士を Join させる分には大丈夫と解っているのだが、_context.Status のほう(DbSet<Status> などで DI されている)の Join の動作が不明である。もともと、ローカル PC で DbSet 同士の Join ができちゃうのがおかしいのか、それとも Azure 上の .NET Core で DbSet 同士の Join ができないのがおかしいのか。

どちらにせよ、同じコードをローカル PC と Azure 上で動かしたときに、挙動が違うのは「おかしい」ので、ここは調べないといけない。これ、Linux 上の .NET Core だとどうなのだろうか? 後で調べるか思案中。

追記 2017/05/11

Ubuntu に donet 1.0.3 をインストールして構築してみると、上の Join が動くようになったので、Azure 上だけがダメな模様。

Azure の App Service のコンソールでバージョンを調べると doetnet コマンド自体が 1.0.1 、.net core のバージョンが Version  : 1.1.0-preview1-001100-00 になっているので、この違いと思われる。ちなみに、ローカルPC の場合は、1.1.0 になっている。この微妙な差(Azure のほうが previewのままなのが)原因らしい。

Build 2017 の微妙な時期なので、これが終わると 2.0 にアップデートされるかもしれん。

追記 2017/05/19

現時点で、.NET Command Line Tools (2.0.0-preview1-005977)  になっているので、join が正常に動いている。やったー。

カテゴリー: Azure, OpenCCPM | Azure 上の .NET Core では DbSet の Join ができない はコメントを受け付けていません

オーケストラに学ぶプロジェクトマネジメント

さて、やっとこさ書き上げて発売されたのでブログも再開。

[amazonjs asin=”4798050024″ locale=”JP” title=”成功するチームの作り方 オーケストラに学ぶプロジェクトマネジメント”]

目次

第1章 コンダクターとプロジェクトマネジメント
1 チームにおけるコンダクター(指揮者)の役目
2 プロフェッショナルな奏者≒プロフェッショナルなエンジニア
3 ハーモニー(調和)とは何か
4 チームが成し遂げる作品(製品)は何か

第2章 プロジェクト計画、プランニングの伝達
1 計画駆動とアジャイル開発とオーケストレーションと
2 形作る作品をイメージで共有する
3 どうやって形作っていくのか
4 三面図(WBS、PERT、ガントチャート)
5 CCPMと焦らない心

第3章 プロジェクトの構成員
1 新人が持っていない能力は何か
2 中途採用が持っている能力は何か
3 プロフェッショナルなエンジニア/プログラマとは
4 コンダクターとプロジェクトメンバーの関係
5 客演という外注

第4章 メンバーの技量
1 メンバーの能力を相互に知る
2 メンバーの能力を相互に尊重する
3 見極めに利用できるもの(ブログ、GitHub、資格)
4 「一緒に仕事ができる」条件を並べる

第5章 継続的な努力
1 チームに参加する時点が最低の実力
2 プロジェクトが終わった時点で最高点に達する
3 「Google 20%ルール」の本来の意味
4 「40時間勤務」の本来の意味
5 ツールを残して次回に備える

第6章 先人の知恵を活用する
1 新しいことを安易に取り入れない理由
2 暗黙知と形式知
3 UMLとパターンランゲージ
4 ISO9001と品質工学
5 温故知新の上にある新しい技術

第7章 現実を計測する
1 難破船のように漂わないために羅針盤を使う
2 現実に適応するためにハンドルを使う
3 希望が挫けないために航海日誌を書く
4 進捗率の自動計測とTDD
5 EVの本来の使い方
6 下降する進捗グラフ(バーンダウンチャート)

第8章 変化は好きですか?

1 世の中は思い通りにはいかない
2 世の中は変化ばかりではない
3 効果的な変化とは≒レバレッジ
4 計画駆動と要件定義
5 アジャイル開発とTOC
[コラム]すべてに目を光らせるために

第9章 仕事とバランス
1 チームでは何が有利か
2 チームでは何が不利か
3 「刺身システム」と「のりしろ」
4 マリッジリスクに対応する「ゆとり」
5 「ゆとり」の時間を何に活用するのか

第10章 ドロップアウトの条件
1 チームが悲鳴を上げる時
2 「排除すべき人」を排除する
3 ゼロ生産者とマイナス生産者に対応する
4 決断する「閾値」を決めておく
[コラム]戦略と戦術の違い

第11章 インセンティブと報酬
1 鞭のない「飴」
2 プロを雇うための費用を算出する
3 インセンティブを提案する
4 成果にのみ「報酬」を与える
[コラム]努力をムダにしない

第12章 差異と反復
1 ジル・ドゥルーズの『差異と反復』
2 本能で違いを読み取れ—差異
3 繰り返しで拡張しろ—反復
4 リスク管理とフェールセーフ
5 失敗学と危険な匂い

カテゴリー: 開発, プロジェクト管理 | オーケストラに学ぶプロジェクトマネジメント はコメントを受け付けていません

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図とカレー調理の関係 はコメントを受け付けていません