エスカレーターのシミュレーション

ひたすら人々がエスカレーターで昇っていく動画です。

 

4種類のエスカレーターがあり、右から、

  • 両側とも詰めて乗り、歩かない。
  • 両側とも1段おきに乗り、歩かない。
  • 左側は1段おきに乗り、歩かない。右側は歩く。
  • 左側は1段おきに乗り、歩かない。右側は歩く。ただし、右側に来る人の頻度は低い。

を表しています。

ソースコードは、Tools-2016 (GitHub) にあります。

参照
Escalator Simulator (YouTube)
エスカレーターは歩かずに立ってるほうが結局速い。ロンドン地下鉄が実証

カテゴリー: ツール. タグ: . Leave a Comment »

マウスのドラッグ イベントを Rx で実装する

WPF などの GUI アプリケーションでマウスのドラッグ操作を扱うには、
例えばマウスのドラッグ中の各点の情報も通知するなどの要件に合わせて、
基本的には自分で実装することになると思います。

従来であれば、MouseDown などの各イベントごとにイベントハンドラーを登録して実装していましたが、
リアクティブ プログラミングにすることで、より抽象度の高い形式で扱えるようになります。
今回は、WPF のマウスのドラッグ イベントを Reactive Extensions (Rx) で実装してみます。

WPF アプリケーション プロジェクトを作成して、NuGet で System.Reactive をインストールします。
そして次のクラスを作成します。

イベントと IObservable は、本質的には等価です。
まず Observable.FromEventPattern メソッドを使って、
MouseDown などの既存のイベントを IObservable<MouseEventArgs> に変換します。

ドラッグの実装方法については、
MouseDown が発生してから MouseUp または MouseLeave が発生するまでの間、MouseMove を通知させます。
これが MouseDown の発生のたびに開始するため、
MouseDrag の型は IObservable<IObservable<Vector>> のような入れ子になります。
ここでは、MouseDown イベントが発生した位置からの変位を通知することにしています。
(要件によって実装方法は異なるでしょう。)

次に、上で実装した MouseDrag を利用するには、次のコードのようになります (主にコンストラクターの部分)。
完全なソースコードは MouseRx2Wpf (GitHub) にあります。

ウィンドウには、変位とそれを表す 8 方向の矢印を表示しています。

MouseRx2Wpf

 

この方法はマウス以外にも応用できます。
Leap Image Pinch は、Leap Motion Controller を使って空中で 2 本の指でつまんで画像をドラッグする例です。

作成したサンプル
MouseRx2Wpf (GitHub)

バージョン情報
.NET Framework 4.5

参照
System.Reactive
Reactive Extensionsの概要と利用方法
Leap Image Pinch

アートのプロセスについて

前回のメディアアートについてで書いた通り、アートの基本となるのは概念の抽出です。
アーティストが作品を制作する際にはテーマに対する徹底的なリサーチが含まれており、そのプロセスはさながら研究といえるでしょう。
(こういうプロセスが不要な人は天才と呼ばれます。)

今回は、アートのプロセスについて考えてみたいと思います。

 

現代美術の展覧会を鑑賞すると、「難度の高い IQ テスト」という感想を持つことがあります。
作品を見ても最初は「これは何だろう」で思考が停止してしまうのですが、
作品の意味を聞くと納得でき、もはやそういうものにしか見えなくなります。
むしろ、なぜ最初に気付けなかったのだろう、と思うのです。

これに近い現象は他の分野でも起こります。
数学や MENSA においても、良い問題というのは
「解き方を知ってしまうとその解き方が当然のように見えてしまうが、それに気付くのは難しい」という側面があります。
実はプログラミングにおいても、「プログラミングの知識があるからといって、実装ができる人とは限らない」ということがあります。

では、なぜこのような非対称性が発生するかというと、

  • 「この技術を使うと、これが実現できる」は演繹 (deduction)
  • 「これを実現するには、この技術を使うとよさそう」は仮説的推論 (abduction)

という違いがあるからだと考えます。

仮説的推論 (仮説形成、アブダクション) とは、不確実性下で尤もらしい解を導くことです。
演繹では結果が保証されますが、仮説的推論では結果が 100% 保証されるとは限りません。
簡潔な説明が Wikipedia の論理的推論に載っています。
人工知能などのコンテキストで、仮説的推論や帰納は、より人間らしい創造的な能力であると説明されます。

プログラミングにおいては、学習時には主に演繹の形式で理解するのに対して、開発の現場では仮説的推論が必要になります。
現場で品質がばらばらになるのはこのためです。
この意味で、プログラミング自体が創造的な側面を持っているといえるでしょう。
(ちなみに、対比のメタファーとして、製造業のアルバイトが挙げられます。
製造業のアルバイトでは、作業手順のマニュアルがあるため、それに従えば一定の品質が保たれます。)

このように考えると、アーティスティック (芸術的、審美的) な研究のプロセスでは
「どのように作ったか」よりも「どのように思い付いたか」が重要になってきます。
前者を知って真似することはできても、後者を知って真似することは難しいはずです。
短期的な投資をする人たちにとっては前者でよいですが、長期的な投資のためには後者が必要です。

そしてそのために必要なものは何かというと、概念をより多く知ることではないかと考えています。
パターンを増やす、多様性、ともいえます。
上位のコンテキストを捉えられれば、より汎用的な能力を身に付けることになります。

例えば数学の研究において、概念を拡張することは重要な仕事の一つですが、
概念を拡張するには、「このように定義すれば、さまざまな事象を共通的に記述できるだろう」と気付くことが必要です。
既知の概念やパターンが増えてくれば、同時に「まだ整理されていない事象は何か」「未知の領域は何か」に気付きやすくなり、
考察の対象を絞り込めるようになるでしょう。

前回: メディアアートについて

カテゴリー: 芸術. タグ: . 1 Comment »

メディアアートについて

私はこれまでに、2015 年の菅野創+やんツー「SEMI-SENSELESS DRAWING MODULES #2 – Letters」および
2016 年の菅野創+やんツー「Asemic Languages」というメディアアートの作品の制作に、技術協力として参加してきました。
この 2 つの作品はいずれも、入力となる筆跡データに近い新たな筆跡データを生成して機械が描くというもので、
私は新たな筆跡データを生成する部分を担当し、機械学習を利用して実装しました。

さて、私は美術を専門とはしていませんが、
以下では、これまでの活動を通じてメディアアートについて得られた知見を書いていきたいと思います。

 

アートおよびメディアアート

一般の多くの人たちが思い浮かべる「美術」は、自身が高校生以前の「図画工作」「美術」の授業で扱った内容の知識で
止まっていることと思います。それらはおそらく、古典美術やビジュアルデザインなどに分類されるものでしょう。
美術のカテゴリの中で、とくにコンセプトを問うのが現代美術 (contemporary art) で、
さらに現代技術 (ハードウェアやソフトウェア) と融合したものがメディアアートです (個人の見解です)。

アートの基本となるのは、概念の抽出やパターン認識です。これは数学や哲学でも同じです。
事象から概念を抽出し、それらの関係を変化させることで美しさや非日常的な興を生み出すことができます。
アーティストは作品を通じて、鑑賞者に概念的な気付きを与えてくれます。

現代美術の作品は、答えではなく問いである、といえるでしょう。
答えが出てしまっているものは、アートではなくデザインです。
プログラマーは既に経験した技術を使い、デザイナーは既存の概念を使い、アーティストは概念を問うたり創り出したりします。

例えば上で紹介した作品では、「線が文字っぽく見えるとはどういうことか」
「人工知能やロボットが自発的に生成した絵画は、特定のアーティストの作品と呼べるのか」 などということを世の中に問うているのです。

時には芸術作品の意味が理解できないこともあるでしょう。
同じように、例えば哲学や経営の本を読んだとき、賛否を論じる以前にピンとこない、難しい、著者の意図が分からない、
ということがあると思います。この状況はすなわち、これまでの人生でその概念を獲得できていなかったということを示します。
より高い概念を獲得した人たちの間では共通認識、暗黙の了解のようなものが生まれ、より複雑な状況下での判断ができるようになります。

アートと歴史

言うまでもなく、アートは現代に始まったものではありません。
日本の歴史においても、庭園、茶道、茶器、絵画など、さまざまな種類が挙げられるでしょう。
時代劇などでも地位の高い人を招いて美学やわびさびを論じさせるという描写があり、その応対を通して、
相手の人物がどの水準の概念を獲得できているか、空気を読めているか、大局的な判断ができるかなどを鑑定していたことが想像できます。
これについては現代社会でも同様だと思います。

アートと都市

アルス・エレクトロニカは展覧会のほかにも Futurelab という研究機関を併せ持ち、
メディアアートから企業のイノベーションまでをつなぐサイクルが成り立っています。
アルス・エレクトロニカの運営資金は、リンツ市が 35~40% を支援しているそうで、
研究開発の成果は都市のいたるところにインストールされています。
日本では芸術祭の開催に積極的な都市もあり、このような都市が登場してくる可能性はあります。

アートと企業

将来、創造性の低い職業はロボットで置き換えられていき、利益率も下がると言われていますが、
取って代わられない職業の最たるものがアーティストです。
アーティストはコンセプトを見出す能力や 0 から 1 を創り出す能力に優れているため、例えば自社の製品を作品に使ってもらったり、
ワークショップを開催したりするなど、アーティストと連携していくことが効果的であると考えています。

第一線の創造的事業を継続するためには、本業を軸として芸術分野に投資することも求められていきます。
「本業で」というのがポイントで、例えば、自動車業界であれば F1 をはじめとするモータースポーツを通じて、
自動車の研究開発を世に問うています。 また、現在では多くの企業が博物館をはじめとする展示施設を運営しており、
そこからそれぞれのテーマに関する新たな知見を得ていることでしょう。

次回: アートのプロセスについて

 

これまでの展覧会

カテゴリー: 芸術. タグ: . 1 Comment »

Azure Web ジョブでバッチを実行する

Azure Web ジョブでバッチを実行するための簡易的な作業手順と、タイムアウトなどの注意点について記述します。

まず、Azure Web ジョブを配置するまでの基本的な流れは次の通りです。

  • ストレージを作成する
  • Web App を作成する
  • Web ジョブを開発して配置する

これらについて、以下に詳細を書いていきます。

■ ストレージを作成する

Azure ポータルで、ストレージを 1 つ作成します。
厳密には、

  • ログを格納するためのストレージ (AzureWebJobsDashboard)
  • バッチが利用するストレージ (AzureWebJobsStorage)

の 2 種類なのですが、1 つのストレージに両方の役割を持たせてもかまいません。
また、後の手順で接続文字列を使うため、[キー] からコピーしておきます。

■ Web App を作成する

Azure のポータルで、Web App を作成します。
[アプリケーション設定] の [接続文字列] で、「AzureWebJobsDashboard」をキーとする設定を追加します。
これで、WebJobs ダッシュボードを利用できるようになります。

接続文字列

 

■ Web ジョブを開発して配置する

Visual Studio で、新規のプロジェクトを [Azure WebJob] のテンプレートから作成します。
App.config を開くと、接続文字列の設定が 2 種類あります。
この両方に、先ほどと同じ接続文字列を設定します。

接続文字列

以下、Web ジョブの開発の流れを簡単に書いておきます。
なお、今回作成したサンプルは TaskWebJob (GitHub) にあります。バッチ処理の題材として、素数を求めています

(1) 手動またはスケジュールで開始する場合
詳細は Web ジョブ SDK を使用して Azure テーブル ストレージを使用する方法などを参照。

  • メソッドに [NoAutomaticTrigger] を付ける
  • JobHost.Call メソッドで、そのメソッドを呼び出す
  • Azure WebJob として発行する
    • オンデマンド実行またはスケジュール実行を選択する
  • 実行するには、ポータルの Web App の [Web ジョブ] で実行する

(2) キューをトリガーとして開始する場合
詳細は Web ジョブ SDK を使用して Azure キュー ストレージを操作する方法などを参照。

  • メソッドの引数に [QueueTrigger] を付ける
  • JobHost.RunAndBlock メソッドを使う
  • Azure WebJob として発行する
    • 連続実行を選択する
  • 実行するには、指定したキューにメッセージを追加する
    • 引数を渡すこともできる

 

以上で、Azure Web ジョブにバッチを配置することができました。
さて、バッチを実際に実行してみると、タイムアウトしてしまうことがあります。
以下では、タイムアウトについて書いていきます。

■ 有料プランの場合

既定では Web App の [アプリケーション設定] の [常時接続] がオフに設定されており、
Web App (というより Kudu?) が 20 分ほどでタイムアウトしてしまいます。
[常時接続] をオンに設定すれば解決します。

■ 無料プランの場合

無料プランでは、[常時接続] をオンにできません。
バッチの実行がタイムアウトする原因は 2 つあります。

  • Web App のタイムアウト
    • タイムアウトは 20 分ほどです。
    • Kudu への要求が連続的にされていれば、タイムアウトは延長されます。
  • CPU 時間の制限
    • 実際の時間ではなく、CPU を使用した時間です。
    • 例えば、連続して 3 分使うと、Web App が停止します。

したがって、WebJobs ダッシュボードなどを表示したままにして、
かつ CPU 使用率の低いバッチであれば実行可能ということになります。

そこで、例えば Thread.Sleep メソッドをコードに含めるという方法があります。
Thread.Sleep などでスレッドを中断しながら実行すると、CPU 利用率を激減させることができます。

CPU 時間の使用量は [クォータ] で見ることができます。

クォータ

 

作成したサンプル
TaskWebJob (GitHub)

参照
Azure Web ジョブのリソース
Azure App Service に .NET Web ジョブを作成する
Web ジョブ SDK を使用して Azure キュー ストレージを操作する方法
Web ジョブ SDK を使用して Azure テーブル ストレージを使用する方法
Web ジョブでバックグラウンド タスクを実行する
Visual Studio を使用して Web ジョブを展開する

LINQ で素数を求める (C#)

カテゴリー: クラウド. タグ: , . Leave a Comment »

WPF で外枠にはみ出さないようにする

WPF で、Border や Grid などの枠の中に、その領域をはみ出すようなコントロールを配置して、
それを Transform などで移動させるとします。
すると、そのコントロールの一部が切り取られてしまったり、外枠にはみ出てしまうなど、期待通りの動作にならないことがあります。
以下では、この現象をどうすれば回避できるかを試していきます。
(追記: Canvas で ClipToBounds="True" とすればよい、とコメントを頂いたため、後半に追記しました。)

Blend for Visual Studio で WPF アプリケーション プロジェクトを作成して、
Border の中に Rectangle を配置して、Rectangle を期待通りに動かせるかどうかを調べます。

Window の領域を 4 つに分けて、以下の方法を試してみます。

  • 左上: Border の中に Rectangle を配置するだけ
  • 右上: Border と Rectangle の間に Canvas を配置する
  • 左下: Border と Rectangle の間に ScrollViewer と Canvas を配置する
  • 右下: Border と Rectangle の間に ScrollContentPresenter と Canvas を配置する

ScrollViewer を使うことで、外側にはみ出さないようにします。
スクロールバーを消すために、VerticalScrollBarVisibility プロパティを Disabled に設定します。
また、ScrollContentPresenter は、ScrollViewer の中で使われているコントロールです。

すると、Blend for Visual Studio のデザイナーでは次のように表示されます。
この時点で、右上の方法では外枠の Border の上に描画されてしまうことがわかります。

FrameLayoutWpf

また、この 4 つの Rectangle に対して、TranslateZoomRotateBehavior を設定します。
(Blend for Visual Studio のアセットからドラッグ アンド ドロップします。)
これで、実行時にタッチ操作などでコントロールを動かせるようになります。

全体の XAML は次のようになります。

このアプリケーションを実際に動かしてみます。

FrameLayoutWpf

  • 左上: 初期配置の領域以外の部分は切り取られてしまいます。
  • 右上: Rectangle が枠外にはみ出します。
  • 左下: 期待通りです。
  • 右下: 期待通りの動作ですが、ScrollContentPresenter.Content が既定プロパティではないため、
    上の階層がデザインツールに表示されません。

 

ここで、よねやんさんから、Canvas の ClipToBounds プロパティの値を True にすればよい、とコメントを頂きました。

右上の Canvas を変更して実行してみます。

FrameLayoutWpf

期待通りです。
というわけで、ScrollViewer などは不要になりました。
Canvas を配置して、ClipToBounds="True" を設定するだけです。

 

作成したサンプル
FrameLayoutWpf (GitHub)

バージョン情報
.NET Framework 4.5

参照
UIElement.ClipToBounds プロパティ

Kinect for Windows v1 の KinectInteraction

Kinect for Windows Developer Toolkit には、KinectInteraction という、
つまむ操作 (Grip) や押す操作 (Press) を判定するためのライブラリが含まれています。
今回は、KinectInteraction でこれらのジェスチャ認識を実装するための方法について説明します。
Kinect for Windows のバージョンは 1.8 とします。

Kinect for Windows Developer Toolkit に付属するサンプルの中にある「ControlsBasics-WPF」では、
Microsoft.Kinect.Toolkit.Controls プロジェクトの中で UI コントロールまで作り込まれていますが、
ここでは KinectInteraction を単独で利用してみます。

KinectInteraction を利用するには、次の DLL が必要になります。

  • Microsoft.Kinect.dll
  • Microsoft.Kinect.Toolkit.Interaction.dll
  • KinectInteraction180_32.dll (ネイティブ、32 ビット向け)
  • KinectInteraction180_64.dll (ネイティブ、64 ビット向け)

ちなみに、Microsoft.Kinect.Toolkit.dll は KinectInteraction とは直接には関係がないため不要です。

 

■ プロジェクトの作成と参照の追加

Visual Studio で、WPF アプリケーション プロジェクトを作成します。
既定では [プラットフォーム ターゲット] が Any CPU、[32 ビットの優先] がオンに設定されています。
この設定のままであれば、32 ビット用の DLL を利用します。

64 ビットで動作させたい場合は、
[プラットフォーム ターゲット] を x64 に設定するか、[32 ビットの優先] をオフに設定して、
64 ビット用の DLL を利用します。

.NET の DLL への参照は、[参照の追加] から 1 つずつ追加してもよいのですが、
なるべく環境変数を利用したいので、プロジェクト ファイル (.csproj) を直接編集します。
次のように、Kinect に関連する部分を ItemGroup に追加します。


<Reference Include="Microsoft.Kinect">
  <HintPath>$(KINECTSDK10_DIR)Assemblies\Microsoft.Kinect.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Kinect.Toolkit.Interaction">
  <HintPath>$(KINECT_TOOLKIT_DIR)Redist\Microsoft.Kinect.Toolkit.Interaction.dll</HintPath>
</Reference>


次に、ネイティブの DLL をビルド時にコピーさせるための設定です。
プロジェクト ファイルの下のほうに、次の ItemGroup を追加します。


<ItemGroup>
  <Content Include="$(KINECT_TOOLKIT_DIR)Redist\x86\KinectInteraction180_32.dll">
    <Link>KinectInteraction180_32.dll</Link>
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
  </Content>
</ItemGroup>


 

プロジェクトのプロパティ

 

■ 実装について

今回は、取得できるプロパティの値の一覧を表示するアプリケーションを実装します。
次のコードはその一部です (全体のソースコードは KinectInteraction (GitHub) にあります)。

InteractionStream のコンストラクターには、IInteractionClient オブジェクトを渡す必要があります。
IInteractionClient インターフェイスの実装については公式ドキュメントも存在しないようで、詳細は不明です。
ここでは、とくに何の処理もしない DummyClient クラスを用意しています。
(サンプルの「ControlsBasics-WPF」には、 IInteractionClient インターフェイスを実装した KinectAdapter クラスが存在します。)

InteractionStream クラスは、DepthImageStream と SkeletonStream を拡張したクラスとなっており、
AllFramesReady イベント ハンドラーでそれぞれのデータを InteractionStream に渡します。
すると、InteractionFrameReady イベントで UserInfo のコレクションを取得できます。
最大で 2 人まで同時に認識できるようです。

次の図は、アプリケーションを実行した結果です。

InteractionWpf

表示されているのは、主に InteractionHandPointer クラスのプロパティの値です。
IsInteractive が true となるには、それぞれの手が有効な範囲に入る必要があります。
有効な範囲とは、左手であれば左肩周辺、右手であれば右肩周辺です。
この領域の左上が (X, Y) = (0, 0)、右下が (X, Y) = (1, 1) となります。

IsTracked は有効な範囲に入っていなくても true になることがあります。
IsInteractive は、IsTracked かつ (X ,Y) が (0, 0) から (1, 1) までの四角形の範囲に入っている状態です。

座標を取得するためのプロパティとして、X, Y, PressExtent, RawX, RawY, RawZ があります。
X, Y と RawX, RawY はそれぞれ同じ値のようです。
PressExtent ≧ 1 のとき、IsPressed が true となります。
PressExtent は、下限値が 0 で、1 より大きい値にもなります。

有効な範囲が高い位置にあるため、少し下の位置で使えるようにしたいとは思うのですが、
とくに PressExtent と RawZ は、有効な範囲にないときの値はあまり信用できません。
このためか、IsInteractive でないときも IsPressed になることがあるため注意が必要です。
したがって、ジェスチャを判定するときは先に IsInteractive が true であることを確認しましょう。

 

作成したサンプル
KinectInteraction (GitHub)

バージョン情報
.NET Framework 4.5
Kinect for Windows SDK 1.8

参照
KinectInteraction
Microsoft.Kinect.Toolkit.Interaction Namespace

Kinect for Windows SDK のセットアップ

カテゴリー: 周辺機器. タグ: . Leave a Comment »