• nRF51822とは

    nRF51822はiBeaconで有名なestimoteも利用しているBLEチップのことです。
    estimoteってこれね
    スクリーンショット 2014-06-25 22.35.02
    出典: estimote.com

    NordicSemiconductorが発売しているARM Cortex-M0コアなチップです。必要な物はだいたいチップの中に入っていて、変調回路とかもチップの中です。だからチップに電源を供給してちょっとした周辺回路だけ用意してあとはアンテナをつなげばOKと言った感じになっています。

    そして、そのちょっとした周辺回路とアンテナまで用意されていてあとはPCとつないでプログラムするだけっていうものが売られています。
    http://www.amazon.co.jp/BLE-%E9%96%8B%E7%99%BA%E3%82%AD%E3%83%83%E3%83%88-J-Link-segger%EF%BC%9ABVMCN5102-BK-KIT-PLUS/dp/B00KGB3XXY/ref=pd_cp_e_0

    Braveridgeというところが作っているモジュールでこのamazonで売っているやつは書き込み用のJLinkデバッガまでセットでついています。
    これだけ買っちゃえばnRF51822を使ったBLEの開発が出来ちゃいます。

    このシリーズではnRF51822の開発に関してBLEやBLEを使ったiBeaconの出し方などを扱います。
    ちなみに開発環境としてはKeilを使っていきます。

  • GoとRevelをサーバーに入れる

    手元で動かしていたRevelのアプリをサーバーに入れて動かしたくなりました。僕はさくらのVPSを使っていますが、まだRevel入れてないですし、そもそもGoも入れていません。
    今回はGoを入れてRevelを入れます。

    1. Goを入れる

    まずGoを入れましょう。その前にまずVPSにログインします

    [shell]

    ssh yourserver.com

    [/shell]

    やることは
    1. wget でDownloadする
    2. 展開してインストール
    3. 環境変数の設定
    です。

    http://golang.org/doc/install
    全部ここに書いてあります。細かく説明していきます。まずはファイルをDLしなきゃいけません。ファイルってのは
    https://code.google.com/p/go/downloads/list
    にあるファイルのことです。サーバーですから恐らくLInuxでしょう、そしてだいたい64bitなので
    LInux64bitを選びます。いまはGo言語のバージョンが1.2.1なので
    https://go.googlecode.com/files/go1.2.1.linux-amd64.tar.gz
    これが欲しいファイルです。これをサーバーに落とします。
    自分のhomeフォルダ(ユーザー名がyukiなら/home/yukiかな)に移動してwgetしましょう

    [shell]
    cd /home/yuki
    wget https://go.googlecode.com/files/go1.2.1.linux-amd64.tar.gz
    [/shell]

    これでファイルが手に入ります。あとは実行しちゃうだけ

    [shell]
    tar -C /usr/local -xzf go1.2.1.linux-amd64.tar.gz
    [/shell]

    これでGoが入ります。もし入らなかったら sudo を頭につけてroot権限でやっちゃいましょう。
    ちなみに/usr/local/goに入ります。次に環境変数の設定です。bash_profioleを編集します。今あなたがユーザーフォルダに居るなら

    [shell]
    vi .bash_profile
    [/shell]

    で編集画面が開けます。vi なので iを押して編集画面に以下のPAHTを追加します

    [shell]
    export PATH=$PATH:/usr/local/go/bin
    export GOPATH=~/gocode
    export PATH="$PATH:$GOPATH/bin"
    [/shell]

    一番上はGoそのものの場所を教えています。これでどこにいてもgoを打てばgoが実行できます。
    2番めと3番目はGOPATHというものを設定しています。revelを使うにはこれが必要です。
    さて、これを入れたらエスケープを押して:wqで書き込み終了。反映させるために

    [shell]
    source .bash_profile
    [/shell]

    これで環境変数が設定されました。
    Goが使えるか試してみましょう

    [shell]
    go version
    [/shell]

    これで確認できます。Goのバージョンが出てくるはず。
    ちなみに、もし「GOPATHがおかしい」みたいなエラーが出たらそれはgocodeというディレクトリがユーザーディレクトリにないからです。mkdir gocodeを実行すればOKです。

    2.Revelを入れる

    Revelを入れるにはGitとMercurialを入れる必要があります。
    Gitは多分皆入ってるでしょうが、Mercurialはないかも。一番簡単に入れるなら

    [shell]
    yum install python-devel python-setuptools
    easy_install pip
    pip install Mercurial
    [/shell]

    この3つを実行すればいけます。
    easy_installはアプリ管理アプリです。そしてそれを使ってpipというアプリ管理アプリを入れています。最終的にはそのpipでMercurialを入れます。
    ここまでいけばGoがはいってGitとMercurialが入っているのでRevelが入ります。

    [shell]
    go get <span style="text-decoration: underline;">github.com/robfig/revel</span>
    [/shell]

    これでrevelが入るはず。

    [shell]
    revel
    [/shell]

    と書いて呼んでみましょう。いつものrevelの画面が出ると思います。

    トラブルシューティング

    1. Goは入るがrevelが入らない
    go get github.com/robfig/revel

    package bufio: unrecognized import path “bufio”
    みたいなエラーが出て入らないことがあると思います。
    原因はGOROOTの間違いです。
    今回は指定しませんでしたが、goはインストール先を選べます。
    選んだ場合はGOROOTという環境変数を設定するのですが、これが間違っているとこのようなエラーが出ます。
    もし、特別指定しないでGoをインストールしたならGOROOTを設定する必要はないのでその環境設定を消しましょう。bash_profileに書いちゃったなら消してlogoutして再度loginしましょう。それで動くと思います。

  • プログラムのバグとは何か

    ゲームやいろんなアプリはプログラムで出来ています。プログラムに問題があることを「バグがある」という言い方をします。では、バグとは何でしょう。

    プログラムとは

    プログラムは作業手順を示すものです。今回はゆうきカフェ(仮)で働くウェイトレスロボットのプログラムを考えてみましょう。ウェイトレスがやることを作業手順としてプログラムにします。では、ウェイトレスは何をしているでしょうか。基本的にこんな感じでしょうか。

    1. お客さんを空いてる席に連れて行く
    2. 注文を聞く
    3. 注文をキッチンに知らせる
    4. キッチンから食べ物をお客さんのところに運ぶ
    5. 食べ終わったら会計をする
    6. 皿を片付ける

    これだけのことができたらウェイトレスとして使えそうですね。そして、これも1つのプログラムです。作業手順を示していますからね。

    IF THEN

    ただ、もっとプログラムらしくしましょうか。プログラムはIF THEN で書かれています。つまり、このことがあったときにこれをやる。という書き方をします。「ボタンが押されたらモーターを動かす」とかそういうのです。これでいくと、例えば1つめはお客さんが来たら席に連れて行きます。お客さんが来てないのに席に連れて行く必要はないのです 。別のロボットとおしゃべりしててもいいですしね。ですから席に連れて行くって動きをする条件はお客さんが来ることなのですから IF お客さんが来る THEN お客さんを席に連れて行く ということになります。この書き方で全てを書き直すと

    1. IF お客さんが来る THEN お客さんを席に連れて行く
    2. IF お客さんが注文する THEN お客さんの注文を聞く
    3. IF 注文を聞き終わる THEN キッチンに知らせる
    4. IF お客さんの料理ができる THEN 料理を運ぶ
    5. IF 食べ終わる THEN 会計する・皿を片付ける

    会計したら即座に皿を片付けできますから5と6は一緒にできますね。このプログラムを書き込んだロボットがいればお客さんにちゃんとサービスできそうです。しかし、このプログラムには問題があります。このロボットは席が空いてなかったらどうするでしょうか。

    想定していない事態:限界状態

    1のIFを満たすのに、THENの行動ができません。ロボットには想定できていない状況です。ロボットはどう動くでしょうか。それは、空いてる席をどうやって探していたかに大きく影響します。例えば、目を使って周りをとにかく見回すロボットだった場合、空いてる席がないかずっと探して探して探して、、、お客さんが来たとたんに店の中を永遠に探しまわるでしょう。だって、席が空いてないなんて考えてなかったんだから探せばあるわけだからずっと探しますよね。または、「席を窓際から探して空いている席に入れる」とプログラムされていた場合、2つのパターンがありそうです。1つはこれまた永遠に探し続けるパターン、最後まで探してまた窓際に目を向けて探すんです。1つは最後まで探したけど見つからないから最後の席に連れて行ってしまうというパターンです(何故そうなるかはfor文がわかると分かる。今回は割愛)。どちらにしろ、まともな対応はできません。このように、何かの限界というのはプログラムの問題になりやすいです。こういうことを想定する必要があります。だから、1だけちょっと書き直しましょう。

    1. IF (お客さんが来る AND 席が空いている) THEN お客さんを席に連れて行く

    変わった書き方をしましたが、これはお客さんが気た時に同時に席も空いていた時だけお客さんを連れて行く というのをANDを使って書いてみたものです。これなら問題なさそうですね。ですが、不親切です。お客さんが来ても席が開いていなければロボットはなにもしないわけです。席が開いていないのかロボットが壊れているのかわかりません。これもプログラムによくあることで、とりあえず問題を避けるだけの対策(めんどくさいのでこれをよくやってしまう)をすると問題はないけど、不親切なプログラムになりがちです。この場合はせめて

    1. IF (お客さんが来る AND 席が空いている) THEN お客さんを席に連れて行く
    2. IF (お客さんが来る AND 席が空いていない) THEN お客さんに席が空いてませんと言う

    という条件を増やすべきでしょう。さて、これでとりあえずお客さんを席に誘導できそうです。ロボットは注文をとりはじめました。ここで、また問題があります。注文を聞いてる時に新しいお客さんが来たらどうするでしょう。

    想定していない事態:同時発生とロック

    人間なら注文を聞いてる途中で新しいお客さんの方に行くのは有り得ません。失礼ですからね。でも、さっきのプログラムには IF (お客さんが来る AND 席が空いている) THEN お客さんを席に連れて行く という条件がありました。この条件を満たしてるかどうかを考えて下さい。どうです?満たしてますよね。だから、ロボットは新しいお客さんを席に連れて行くべきなのです。少なくとも連れて行っても文句は言えません。これもよく起きる問題です。何かの作業をしている時に他の条件が成立してしまうということです 。これは起こっても文句が言えないことです。ではどうしましょう。一番簡単なのは

    1. 作業中は他のIFを無視する

    ということです。これでだいたい問題を解決できます。ですが、完璧ではありません。もし、このお客さんが注文にものすごく悩んだらどうなるでしょう。このロボットは全く動くことが出来ません。新しいお客さんが来ても、席にいる人が「お会計お願いします!」と言っても無反応です。ロボットはロックされた状態になります。注文が完了すれば動けるのでまぁ、まだ許せますが一番最悪なのはお客さんが注文の途中で「ちょっとトイレ言ってくる」といって帰ってしまうことです。その場合このロボットは注文の途中なので、この人が戻ってきて何かを注文するまで動くことが出来ません。店長はしぶしぶリセットボタンを押すしかなくなります。よくやる対策が

    1. ある時間経ったら作業を中止する

    というプログラムを仕込むことです。これをやれば店長が自分からリセットを押す必要はなくなるし、注文の遅いお客さんから離れてロボットを有効に使うことも出来ます。そのお客さんは、注文したければもう一度呼べるし、その時はいい注文の仕方をしてくれるでしょうしね。これを加えればどこかで同時に発生しても、かりに何かの理由で作業が終わらなくてもなんとかなりそうです。

    今回試しにロボットのプログラムを考えてみましたが、注文をとるところまでで既に2つもバグを出してしまいましたね。バグというのはプログラムの問題ですが、別に最初に書いたものがまったくだめだったわけじゃありません。ある条件ならちゃんと動くしね。バグとは基本的には「想定外」なことが起きた時にトラブって初めて気づくものです。今回は忘れがちな「限界」と「同時発生」を扱いました。他にも有名なものが沢山ありますが、そろそろ眠いのでこのへんで。

  • 実行してみる

    前回プロジェクトを作成しました。
    では早速実行してみましょう。

    プログラムの実行はXcodeのこの再生ボタンみたいなやつです。
    これを押すと実行されます。

    こんな感じの な〜んにもないウインドウが出てきたんじゃないでしょうか。

    なんで何もプログラムを書いてないのにウインドウが出てきたのかって?
    実はプロジェクトは作られた段階でとりあえずウインドウが出るプログラムが仕組まれています。
    だから実行を押したらそれが実行されてウインドウだけが出てきたんですね〜。

    ちなみにプログラムの停止は隣の四角い停止ボタンを押せばできます。
    実行中にもう1回実行押すと再起動になります。

    //まとめ
    ・Xcodeはプロジェクト作成時にとりあえずウインドウが出るプログラムが入っている
    ・実行は三角、停止は四角いボタン

  • プロジェクトを作成する

    [ プロジェクトとは ]
    もしソフトが1つのファイルにプログラムをがーーーーと書けたらいいんですが、
    普通読みにくいので大きくなるほどファイルも分割しますし、
    それに画像とか音のファイルとかも沢山必要になってきます。
    そういったものを1つにまとめるのがプロジェクトです。
    基本的に1つのソフトを作ろうとしたら1つプロジェクトを作って
    その中にプログラムとか画像とかをまとめて 最終的にソフトとして完成させます。

    では作りましょう。

    [ プロジェクト作成 ]
    Xcodeを起動して 「Create a new Xcode project」を押します。

    そしたらどんなプロジェクトを作るのか聞いてきます。
    コマンドラインで動く文字だけのものか、ライブラリなのか。
    今回はボタンとか絵も出せるGUIで遊ぶわけなので
    OSX Application のなかから 「Cocoa Application」を選択して「Next」

    そしたら次は名前とかを決める画面です。
    ここでは色々プロジェクト全体の設定をするのですが、今回は名前だけでOK
    とりあえず「test」とかにしましょう そして「Next」

    次は保存先を聞かれます。どこでもいいので選んでCreateを押しましょう。
    ちなみに下にある「Create local git repository for this project」はチェックが入ってるとGit initの手間が省けます。
    といっても今このページを見てる人でgitを知ってる人は居ないと思うのですっ飛ばします。
    チェックが入ってても入ってなくても問題無いです。

    これで作成したらやっとプログラムを書ける画面に行きます。
    これがプロジェクトの画面です。
    画面の上にはtest.xcodeprojと出てますね。
    左側にあるのがプロジェクトに含まれるファイルです。
    AppDelegate.hとかほか色いろあると思います。

    今回はここで終わり。

    //まとめ
    ・ソフトを作るのに必要なプログラムや画像は”プロジェクト”というもので管理する
    ・プロジェクトはCocoaApplicationを選んで名前決めて作成する。