RaspberryPi Zeroを使って変愚蛮怒専用機を作った

これは?

f:id:inajob:20180902132057g:plain

f:id:inajob:20180902130755p:plain

変愚蛮怒変愚蛮怒 公式WEB )というローグライクRPGがあります。ローグライクRPGとは、いわゆる「シレン」や「トルネコ」の元となったゲームです。 特に昔ながらのローグライクRPGはテキストだけで画面が構成されているという非常に渋いゲームです。

f:id:inajob:20180902123907p:plain

一般的なRPGとは違い、死んでしまうと、そこで冒険は終わり。セーブデータには死亡回数が刻まれ、またレベル1からやり直すというハードなRPGです。 ゲーム内のキャラクタのデータはリセットされますが、プレイヤーはその経験を生かして次のプレイではより高いレベルまで成長できるという「プレイヤー自身が成長する」という感覚が魅力です。(と僕は思っています)

また、操作はキーボードを駆使して行います。装備変更は「e」食事を食べるのは「E」物を投げるのは「f」といった具合です。 そのため、スマートフォンやゲーム機に移植したものとは操作感覚が全然違います。やはりファンとしてはキーボードを使って操作したいところです。

ということで、変愚蛮怒専用機を作ることにしました。

材料

  • RaspberryPi Zero WH
    • WifiBluetoothが使える方のRaspberryPiZeroです。今回はBluetoothキーボードを使いたいのでWHのほうを選びました。

  • Raspberry Pi用の3.5インチ液晶
    • 解像度は480x320、SPI接続により映像信号を送るタイプです。(HDMI接続のモニタも試しましたが、HDMIケーブルの取り回しが難しくSPI接続のモニタにしました。 しかしSPI接続は転送速度が遅いので、アクションゲームなどには不向きです)

  • モバイルバッテリー
    • ダイソーの500円のモバイルバッテリーを用意しました。一般的なモバイルバッテリーは消費電力が少ないと電力供給をやめてしまうものが多いですが、このバッテリーはそのような動作をしませんでした。

【100均検証】ダイソーの500円モバイルバッテリー(3000mAh)を使ってみた結果…!! | ロケットニュース24 (この記事ではひどいこと言われてますが、このサイズ感は魅力です)

  • 3Dプリンタで作った筐体
    • 上記の部品を組み合わせた形がぴったりおさまる筐体を作りました。これはまだ改良の余地がありそうです。

Raspberry Piのセットアップ

RaspberryPiをセットアップして、変愚蛮怒が動作するようにします。

OTGケーブルによるPCとの接続

Raspberry Pi ZeroはOTG接続により、パソコンとネットワークを共有できます。 これによりWiFi接続などの設定をせずにパソコンからSSH接続でRaspberryPiを操作することができます。

この記事の情報を利用しました。 https://qiita.com/Liesegang/items/dcdc669f80d1bf721c21

液晶の設定

https://www.waveshare.com/wiki/3.5inch_RPi_LCD_(A) このページを参考にして、液晶の設定をします。 設定後、液晶をピンヘッダに接続して起動すると液晶画面にRaspberryPiの画面が表示され、タッチパネルも有効になります。

キーボードの設定

Bluetoothキーボードの設定はRaspberryPiのGUIから行いました。(コマンドでもできるはずです。) 一度ペアリングをしておくと、再起動後も引き続き有効のようです。

ここまで操作すると、PCからのSSH経由での操作の他にBluetoothキーボードでの操作もできるようになります。

簡素なGUIに変更

Raspberry Piの標準的なGUIは、便利ですが、変愚蛮怒専用機には不要です。 変愚蛮怒Xorg上で実行するつもりなのでXorgはそのままにして、session-managerとwindow-managerの設定を変更します。

  • /usr/bin/x-window-manager を消す(これは/etc/alternatives/x-window-managerを指していて、さらにopenboxを指しています)
$ sudo rm /usr/bin/x-window-manager
  • /usr/bin/x-session-managerを消す(これは /etc/alternativess/x-session-manager を指していてさらに /usr/bin/startlxde-pi を指しています)
$ sudo rm /usr/bin/x-window-manager

デフォルトのターミナルはlxterminalですが、これをxtermに変更しておきます。

$ sudo apt-get install xterm
$ sudo update-alternatives --config x-terminal-emulator
# /usr/bin/xterm を選択

$ sudo halt

ここで再起動すると、今までのGUIはどこかへ消え、真っ黒なターミナルが起動するようになります。

変愚蛮怒のビルド

変愚蛮怒Linux版はソースコードで提供されています。そのためビルドする必要があります。 必要なライブラリをインストールします。

$ sudo apt-get install libncurses5-dev libx11-dev libxt-dev 

変愚蛮怒をダウンロードして、ビルドを行います。 最新のリリースは https://ja.osdn.net/projects/hengband/releases/ で確認してください。

$ curl https://ja.osdn.net/projects/hengband/downloads/10331/hengband-1.6.2.tar.gz/
$ tar xzf hengband-1.6.2.tar.gz
$ cd hengband-1.6.2
$ ./configure
(略)
$ make
(略)
$ make install
(略)

EUC-JPロケールの追加

raspi-configを実行し、「4 Internationalisation Options」→「I1 Change Locale」を選択し、「ja_JP.EUC-JP EUC-JP」と「ja_JP.UTF-8 UTF-8」をスペースキーで選択します。 これによりEUC-JPロケールが追加されます。

12pxの日本語フォントの追加

320x480のディスプレイで変愚蛮怒を表示するには12pxのフォントが最適です。これをインストールします。

$ sudo apt-get install xfonts-shinonome

起動用のシェルスクリプトの追加

起動のための設定をシェルスクリプトとして作成します。

#!/bin/sh

export LANG="ja_JP.eucJP"
export ANGBAND_X11_FONT='-*-*-medium-r-normal--12-*-*-*-*-*-iso8859-1,-*-*-medium-r-normal--12-*-*-*-*-*-jisx0208.1983-0'

unset LC_ALL
unset LANGUAGE
unset XTERM_LOCALE

./hengband -- -n

起動して、キーボードでboot.shを実行することで変愚蛮怒で遊ぶことができるようになりました。

3Dプリンタでの筐体の作成

3Dプリンタで筐体を作成します。本当はこういう平べったいものはレーザーカッターのほうが作りやすそうなのですが、、 Fusion360でそれっぽく作ってみました。

f:id:inajob:20180902130109p:plain

まとめ

今回は電子工作を全くせず、ただ買ったものを組み合わせただけでゲーム機を作成しました。 RaspberryPi Zeroは非常に小さいので、こういうものを作るのには適していると感じました。 最近は自作キーボードなども流行っており、さらにそれに液晶を組み合わせて、小型のPCを作るのが流行っているようです。今回はキーボードは既存のbluetoothキーボードを使いましたが、次は自分で超小型のキーボードを作って組み合わせてみたいなと思っています。

ともあれ、これで通勤中も変愚蛮怒が遊べます!

f:id:inajob:20180902130755p:plain

Maker Faire Tokyo 2018でのRakuChordキット販売への道のり

Maker Faire Tokyo 2018に出展しました!

ここ数年と同様に、会社の知人のサークル「コネクト・ミー」に混ぜてもらって参加しました。

connect-me-net.tumblr.com

 

「コネクト・ミー」での僕の役割は、回路回りでのトラブルなどがあった際に知恵を貸すといった、「電子工作のスーパーバイザー」的なものです。

ただし、今回は7月に風邪で体調不良だったため、ほとんどお手伝いできず、、ただただ混ぜてもらっただけとなってしまいました。

今年は、「コネクト・ミー」としても”モノを売りたい!”というところで、コマーシャルMakerとしての出展を行いました。

 

「コネクト・ミー」メインの展示について

メインで販売していたのは、「みみにゃん」

電子工作的に面白いところはそれほどないのですが、耳の造形にこだわっており、そこそこそれっぽいネコミミだったのではと思っています。(会場内で購入してくれた方がつけているのをみて、わざわざ買いに来てくださる方がいるほどでした。)

f:id:inajob:20180806150055p:plain

また、みみと合わせて「ひげにゃん」という、猫の口を模したマスクを展示していました。(こちらは展示のみ)ひげにゃんは裏側に距離センサーが付いており、顔の前にマスクがある状態で、口をパクパクさせる動きを認識し、喋ったり、ひげが動いたりするというハイテク猫マスクです。

f:id:inajob:20180806150317p:plain

コネクト・ミーの展示は、子供連れの親子の方や、若い女性、カップルなど、多くの方にウケていました。

初めての販売だった「みみにゃん」についても、予定通りに売ることができました。

 

さて、ここまでは私が居候(?)させていただいている「コネクト・ミー」メインの展示の話でした。

 

コネクト・ミーの展示スペースの端を少し借りる形で、私も自分の作った電子工作の展示とキットの販売を行っていました。

inajobの独自コーナーについて

今年はコマーシャルMakerで参加ということで、僕は長年開発を続けている自作の電子楽器「RakuChord」を販売することにしました。完成品は難しそうなので、キットの販売です。

f:id:inajob:20180806152045p:plain

 

また、去年に引き続きですが、「組みひも組み器」ESP-WROOM-02ゲーム機」「自作Gamebuino」を展示しました。

さらに新作として「o-bako on ESP32」というESP32を使ったゲーム機も展示しました。

 

f:id:inajob:20180806151716p:plain

 

「組みひも組み器」は、興味を持ってくれる方が多く、たくさんの方が人が足を止めて説明を聞いてくれました。

またRakuChordを目当てに来てくれる方もいて、大変感激しました。

inajob.hatenablog.jp

inajob.hatenablog.jp

 

毎年自己紹介をすると「Twitterのこのアイコンの人ですね!」といわれることが多いので、今年は自分Tシャツを着て参加しました。

f:id:inajob:20180806151338p:plain

おかげで、ほかの方のブースに行った時にも一目で「おっあのひとだ!」と認識してもらえることが何度かありました。Twitterで活動してる方にはオススメです。

RakuChordのキットについて

RakuChordのキットについては、このイベントに向けてというわけではなく、ライフワーク的にコツコツと進めてきました。

このページを作ったのが今年の2月です。また同時にソースコードも公開しました。(GitHub - inajob/rakuchord

inajob.github.io

 

そして、興味のありそうな知人にRakuChordの貸し出しなどを行い、人に使ってもらう際のノウハウを集めました。

 

そうこうしていると今回のMaker Faire Tokyo 2018にコマーシャルMakerとして出ようというという話が出てきて、これは良い機会! ということでキットの準備を始めました。

組み立て説明書の作成

実はこれはMaker Faire Tokyo 2018参加が決まる前から作業していました。仮にこのイベントがなくともどこかでキットを配りたいなと思っていたからです。

inajob.github.io

1台を自分で組み立てる様子を写真で撮り、それに説明のテロップを追加して説明書を作成しました。

f:id:inajob:20180806144658p:plain

 

また部品の一覧表も作成しました。

手順は簡単なのですが、ステップにばらすと意外と枚数が多く、苦労しました。

販売個数の決定

今回は、お試しということで家に余っているRakuChordの基板(中国に発注する時は10枚で注文するので、大抵余る)を売ろう ということで、販売個数は8個に決定しました。

部品調達

基板は余っているものだったので、もう準備することはないのですが、それ以外の部品に関しては家にないので、調達する必要があります。

表計算ソフトに、必要な部品を列挙し、それぞれどこで何個購入するかをまとめて、発注しました。中国通販(AliExpress)で購入したり、普通に秋葉原の小売店で必要数購入したりして、部品をそろえました。

f:id:inajob:20180806144910p:plain

それぞれの部品の価格についてもまとめておきました。

部品製作(筐体)

今回は8個ということで、我が家にある3Dプリンタで作成しました。休みの日や、早く帰宅した日を利用して、淡々と出力しました。

3DデータはOpenSCADで作成しています。(後ほど公開予定です)

f:id:inajob:20180806145046p:plain

価格決定

ここはかなり悩みました。今回は単純に材料費の合計にマジックナンバーを掛けるという方式で価格を決定しました。

極端に安く売ることもできるのですが、売れば売るほど損をするようでは、僕の財布も、モチベーションも保てません。

スイッチサイエンスで販売されているキットの価格なども参考にしつつ、大まかな価格感を決定しました。

 

「4500円」

f:id:inajob:20180806145115p:plain

これが高いと感じるか、妥当と感じるかは人それぞれなのかなと思います。。

検品

キットなので組み立てて動作を確認することができません。怪しい部品については部品単位で動作を確認します。特に中国通販で買ったICに関しては、動作が怪しい気がしたので、確認したところ実際に期待した動作をしないものがあったりしました。

キッティング

部品が次々と届くわけですが、販売用にこれらをキット化する必要があります。文具屋やダイソーなどで小分けの袋を購入したり、説明用のチラシをネットプリントで印刷します。

そしてそれらをキットとしてパックします。

f:id:inajob:20180806145516p:plain

f:id:inajob:20180806145609p:plain細かく紛らわしい部品が多いので、一度詰めた後に再度確認しました。

運搬

わざわざ見出しを書きましたが、今回は8個だけだったので、普通に手提げ袋に入れて自分で運びました。大量に売るとなると運搬も業者に頼むなどが必要なのだろう、と思いました。

販売

実際の販売は楽しいものでした。Maker Faire Tokyoには何度も出展したことがあるので、同じ感じなのですが、販売をしていると、プラスアルファで「売れる」という喜びがあります。

たくさん在庫があると、売れ残ったらどうしよう・・みたいに思うところですが、今回は8個ということで、気楽に構えていました。

結果6個売れるということで、なかなかの戦果だったのでは?と思います。

まぁ実際買ってくれた方の多くは、以前からの知り合いやTwitterで仲良くしている方たちだったので、コネで売った 感はあります。初見でも「ほしい!」と思わせる何かを作るのは、大変なのだなと感じました。

販売後

Twitterなどで作成報告を書いてくださっている方もいて、販売後も楽しみがあります。(不備があるかも、、と考えると心配ではありますが・・)自分の作ったものが、他人にも認められて、購入されて、しかも活用されている!というのを見られるのはとても感慨深いものがあります。

まとめ

今回は自分で作った電子工作作品を他人に販売するという貴重な体験ができました。

RakuChordはライフワーク的に作っている楽器で、今後もソフトウェア面、ハードウェア面ともに改良を続けていく予定です。

また面白いものができたら販売していきたいなと感じました。次はネットで販売するのをやってみたいな!

f:id:inajob:20180806152344p:plain

 

3DプリンタX軸の自己修復的な修理

X軸の調子が悪い

3Dプリンタを買ってもう1年半ほどですが、どうも最近X軸の調子が悪い

inajob.hatenablog.jp

具体的にはX軸のベルトが頻繁に緩むようになっていました。

Y軸のベルトは対して緩まないのになぜX軸だけ、、?と思いながら、緩んでいるときには、ケーブルをきつく付け直していました。

f:id:inajob:20180725213828p:plain

↑緩んでいたのは赤く囲った部分のベルトです。

f:id:inajob:20180725213942p:plain

↑今回問題となったのはここの部品。この部分は3Dプリンタで作成されたものです。

f:id:inajob:20180725214046p:plain

現物はこんな感じです。一見問題ないように見えますが、モーターを固定している部分が大きく曲がってしまっているのです。

f:id:inajob:20180725214159p:plain

取り外すとわかりやすいですが、波打つように曲がってしまっています。

X軸のベルトの張力により、徐々にプラスチックが曲がってきてしまったようです。

そのためベルトが他の部品にこすれるようになってしまい、摩耗していましたし、X軸の移動もスムーズではなくなりかけていました。

f:id:inajob:20180725214356p:plain

そういえば3Dプリンタのマニュアルに、パーツのデータも同梱されていたので、同じものを3Dプリンタで出力。自分で自分を修理するというのができるのが3Dプリンタの面白いところです。

ベアリングがかなりきつくはめ込んであって外すの、入れなおすのも苦労しましたが、とりあえず新しいパーツに付け替えて今は問題なく動いています。

 

これにて修理終了。

f:id:inajob:20180725214804p:plain

左右でパーツの色が違っているのも愛嬌ということで。これからも働いてもらいます!

 

3Dプリンタを使って何が作れるかはこちら

inajob.hatenablog.jp

マイコンボードまとめ

最近マイコンボードがたくさん出てきているので、CPUごとにまとめました。(ついでにゲーム機もまとめました) Arduinoとか、mbedとかメジャーなものはまだ記載していません。

LPC1114

IchigoJam

PIC32

OrangePico

Machikania

STM32F103C8

Blue Pill

ESP8266

ESPr Developper

KOMAINO

ESP32

ESPr Developper 32

obniz

Nefty BT

m5stack

ATSAMD21

Gamebuino META

Arduino M0 Pro

LPC11U6x

pokitto

ATTiny85

8pino

Digispark

Atmega328

nekoboard2

ちっちゃいーの

Dotsuino

TinyDuino

Gamebuino Classic

Atmega32u4

Arduboy

Beetle

Arduino Esplora

nRF51822

micro:bit

未分類

Teensy

Trinket

micro:bit

Mbed

ESP32を使ったゲーム機"o-bako"のシミュレータを開発した

ESP32を使ったゲーム機 "o-bako"

”o-bako” とは最近僕が作っているゲーム機です。

ESP32と128×128の液晶、アンプとスピーカ。十字ボタンとA,Bボタン、スタートボタンを搭載しています。

さらにPS/2キーボードが接続できるようになっています。

f:id:inajob:20180527165238p:plain

ESP32-DevKitC を利用しており、arduino-esp32を使うことで、Arduinoのようにプログラムを組むことができます。

f:id:inajob:20180527175931p:plain f:id:inajob:20180527175958p:plain

3Dプリンタで簡易的なケースも作成しました。

f:id:inajob:20180527180919p:plain

構成としては最近話題のm5stackと似たようなものです。

また、Lua言語のインタプリタを動かせるようになっており、Luaで書いたプログラムを実行することができます。

さらにWiFi機能を使ってWebサーバとしても動作します。このWebサーバにアクセスすることで、Luaプログラムを閲覧したり、編集することができます。

 

f:id:inajob:20180527174542p:plain

o-bako Simulator

 o-bakoはまだ開発中なのですが、o-bakoで動かすLuaで書かれたゲームはそれ以外の環境でも、理論的には動かすことができます。

パソコンでプログラムを書いて、o-bakoに転送し、動作を検証し、という作業を効率化するためにブラウザで動作するo-bakoのシミュレータを開発しました。

inajob.github.io

 

f:id:inajob:20180527171658p:plain

理論的にはこのシミュレータで動作するように書いたプログラムは、o-bakoでも同じように動作します。

 

いまのところo-bakoが定義している命令は下記の9個だけです。(まだ追加する予定ですが、それほど大きく増やすつもりはありません。)

tone(no, freq, vol) 音を鳴らす(no: 0-2, vol: 0-255)
spr(x,y,w,h,sx,sy[,sw,sh]) (x,y)にspriteを(sx,sy)からサイズはw,hで描画する。sw,shを設定すると拡大、縮小できる。
pset(x,y) (x,y)に1ピクセルのドットを描画
color(r,g,b) ペンの色を[r,g,b]に設定。(r: 0-255, g: 0-255, b: 0-255)
text(s,x,y) (x,y)に文字列sを描画
drawrect(x,y,w,h) (x,y)にサイズw,hの四角形の枠線を描画
fillrect(x,y,w,h) (x,y)にサイズw,hの四角形を塗りつぶす
fillcircle(x,y,r) (x,y)を中心に半径rの円を塗りつぶす
btn(n) ボタンの入力を取得 ボタンを押してからのフレーム数が返る

テキストエリアにプログラムを書き込んで「Execute」をクリックするとゲームが動作するので、試してみてください。


ゲームプラットフォームとしての"o-bako" 

最近Arduboy, Gamebuino, Pokittoなど様々なゲームプラットフォームが出てきていますが、それぞれで作ったゲームはそのゲーム機専用になってしまい、ほかのプラットフォームでは動作しません。

Luaのようなもうすこし高レベルの層を定義し、それに向けたゲームを作るようにすることで、ほかのプラットフォームでも簡単に動作するものができるのではないか?と考えています。

LuaC言語が動作する環境であれば、非常に簡単に移植することができます。(メモリ、CPUがそこそこ必要ですが・・)

 

とか書きましたが実際のところは僕が作ってみたいので作ってるだけです。生暖かく見守ってください。

 

Arduinoで掃除しないルンバを作った

これは何?

f:id:inajob:20180331231312p:plain

ロボット作りの習作ということで、Arduinoを使っていわゆるルンバみたいな部屋の中を自律的に走行するロボット(ただし掃除はしない)を作ってみました。

 

材料

  • Arduino
  • モーターとギアボックス
  • タイヤ
  • モータードライバ(TA7291P)
  • 距離センサー(HC-SR04)
  • ブレッドボード
  • 9V電池
  • 3Dプリンタとフィラメント

筐体の作成

今回は作りながら構成を考えるということで、まずはこういうユニバーサルボードを作ってみます。

穴の大きさは11mm。僕がよく作るねじの直径が10mmなので、そのねじがうまく入るような大きさにしました。

f:id:inajob:20180331224926p:plain

ギアボックスと3mmのボルトとナットでで固定します。この時点でかなりそれっぽい!

f:id:inajob:20180331224834p:plain

OpenSCADでねじを作ります。

f:id:inajob:20180331225129p:plain

Fusion360でこういうのを作ります。

Arduino固定用パーツ

f:id:inajob:20180331225232p:plain

ブレッドボード固定用パーツ

f:id:inajob:20180331225321p:plain

9V電池固定用パーツ

f:id:inajob:20180331225703p:plain

 

で、こんな風に上にArduinoを固定します。

f:id:inajob:20180331225421p:plain

9V電池はこんな風に固定する

f:id:inajob:20180331225752p:plain

回路

下の記事を参考にして、モータードライバを制御しました。今回は両輪別々に制御したかったので、同じ回路を2つ並べました。

shangtian.hatenablog.com

 

超音波センサーについては下記記事を参考に。

deviceplus.jp

 

(この後紹介するスピーカーも含めた回路図です)

f:id:inajob:20180401225137p:plain

 

 

プログラムの作成

ほとんどプログラムも前述の記事の真似です。

自立制御の部分はテキトーに作りました。

50cm先に障害物を発見すると、バックして左に少し回転してまた前進します。

const int motor1A = 2;
const int motor1B = 3;
const int motor2A = 4;
const int motor2B = 5;
const int motorPwm = 6;

const int echoPin = 8;
const int trigPin = 7;

enum Mode{modeLeft, modeRight, modeForward, modeBackward};
Mode mode = modeForward;

void back(){
  digitalWrite(motor1A, HIGH);
  digitalWrite(motor1B, LOW);

  digitalWrite(motor2A, LOW);
  digitalWrite(motor2B, HIGH);
}
void backward(){
  digitalWrite(motor1A, HIGH);
  digitalWrite(motor1B, LOW);

  digitalWrite(motor2A, LOW);
  digitalWrite(motor2B, HIGH);
}
void forward(){
  digitalWrite(motor1A, LOW);
  digitalWrite(motor1B, HIGH);

  digitalWrite(motor2A, HIGH);
  digitalWrite(motor2B, LOW);
}
void turnLeft(){
  digitalWrite(motor1A, HIGH);
  digitalWrite(motor1B, LOW);

  digitalWrite(motor2A, HIGH);
  digitalWrite(motor2B, LOW);
}
void turnRight(){
  digitalWrite(motor1A, LOW);
  digitalWrite(motor1B, HIGH);

  digitalWrite(motor2A, LOW);
  digitalWrite(motor2B, HIGH);
}

double getDistance(){
  double duration = 0;
  double distance = 0;

  digitalWrite(trigPin, LOW); 
  delayMicroseconds(2); 
  digitalWrite( trigPin, HIGH );
  delayMicroseconds( 10 );
  digitalWrite( trigPin, LOW );
  duration = pulseIn( echoPin, HIGH );
  if (duration > 0) {
    duration = duration/2;
    distance = duration*340*100/1000000;
    if(distance > 100){
      distance = 100;
    }
  }
  return distance;
}

void setup() {
  Serial.begin(9600);
  pinMode(motor1A, OUTPUT);
  pinMode(motor2A, OUTPUT);
  pinMode(motor1B, OUTPUT);
  pinMode(motor2B, OUTPUT);
  pinMode(motorPwm, OUTPUT);

  digitalWrite(motorPwm, LOW);

  pinMode( echoPin, INPUT );
  pinMode( trigPin, OUTPUT );

  forward();
}

int sp = 255;
int nearCount = 0;
int forceTurnCount = 0;
int forceBackCount = 0;

void loop() {
  switch(mode){
    case modeLeft: turnLeft(); break;
    case modeRight: turnRight(); break;
    case modeForward: forward(); break;
    case modeBackward: backward(); break;
  }

  // speed
  analogWrite(motorPwm,sp);

  double distance = getDistance();
  if(distance < 50){
    nearCount ++;
  }else{
    nearCount = 0;
  }

  if(nearCount > 10 && mode == modeForward){
    mode = modeBackward;
    forceBackCount = 100;
    Serial.println("detect object. back");
  }else if(mode == modeBackward){
    forceBackCount --;
    if(forceBackCount == 0){
      forceTurnCount = 30;
      mode = modeLeft;
    }
    Serial.println("back");
  }else if(mode == modeLeft){
    forceTurnCount --;
    if(forceTurnCount == 0){
      mode = modeForward;
    }
    Serial.println("left");
  }else{
    mode = modeForward;
    Serial.println("forward");
  }
}

 動画

感想 

3Dプリンタがあると、こういう物理的な工作が簡単にできました。

また今回は初めからすべてを設計するのではなく、ユニバーサルボード的なものを作って、後付けパーツで組み立てていくという方式にしたため、簡単に設計を試行錯誤することができました。

 

そして自律的に動くものをプログラムするのは難しいと感じました。今回はとても単純な仕組みで作りましたが、これ以上賢く作るためには、このようなルールをどんどん入れていくか、ロボットが空間を把握するような仕組みをプログラムするか、、 いずれにしても大変そうです。

また気が向いたら改良していこうと思います。

 

追記:話せるようにしてみる

ちょうど家にあったDFPlayerMiniを使って状況に応じてmp3を再生させるようにしてみました。

 おきまりのセリフをしゃべるだけだけど、これだけでかなり愛着がわくものになった気がします。

 

音声は下記サイトのものを利用しました。

soundeffect-lab.info

 

参考部品リンク

Arduino

つかったのはこちら

www.aitendo.com

 普通のならこれかな?

【永久保証付き】Arduino Uno

【永久保証付き】Arduino Uno

 

 

モーターとギアボックス

つかったのはこれ。もう欠品のようだ

www.aitendo.com

 これが同じもののように見える。タイヤも付いている。

 モータードライバ

つかったのはこれ。ディスコンらしい。

akizukidenshi.com

 Amazonにもあるが別のモータードライバを使うのがよさそう。

 距離センサー

akizukidenshi.com

 Amazonならこれかな?

HC-SR04 超音波距離センサーモジュール For Arduino

HC-SR04 超音波距離センサーモジュール For Arduino

 
DFPlayerMini

 

 

ブレッドボード 

akizukidenshi.com

 Amazonならこれかな?

月10ドルのKubernetesクラスタに無料で取得したドメインでアクセスできるようにする

概要

前回は$10/月のKubernetesクラスタを作成しました。

inajob.hatenablog.jp

ここに自分用のWebサービスなどをデプロイすれば個人サーバとして活用できるわけですが、いつまでもIPアドレスでアクセスするというのはダサいですね。 今回は無料でドメインを取得しKubernetes上のサービスをその名前でアクセスできるようにしてみます。

f:id:inajob:20180228185422p:plain

ドメインをとるのはちょっと・・・という人はcurlのオプションでヘッダをつけてアクセスすることでその挙動を確認することができます。(が今回の記事では触れません)

TKドメインの取得

トラケウのドメインである.tkは無料で取得できます。

.tk - Wikipedia

もちろんすでにドメインを持っている人はこのような怪しいドメインを取得する必要はありません

https://my.freenom.com

とれるかな、、 f:id:inajob:20180228175551p:plain いけそう! f:id:inajob:20180228175618p:plain kubernetesのmasterのIPアドレスを入れる(あとで変えるので何でもよいのですが、、) f:id:inajob:20180228175858p:plain いい感じに入力する f:id:inajob:20180228175946p:plain 下記からアクセスすると所有しているドメインの一覧が確認できる。 https://my.freenom.com/clientarea.php?action=domains

CloudFlareでワイルドカードDNSの登録

FreenomでもDNSサービスは提供しているのですが、CloudFlareのほうが操作性がよくワイルドカードDNSが利用できるのでこちらを使うことにします。

www.cloudflare.com 右上のAdd Siteからドメインを追加画面に遷移 f:id:inajob:20180228180457p:plain

一番左の無料のやつを選択 f:id:inajob:20180228180524p:plain

いったんそのままContinue f:id:inajob:20180228180615p:plain

nameserverを変えろと言われる。 f:id:inajob:20180228180653p:plain

freenomに行って指示通りにNameserverを変更する f:id:inajob:20180228180847p:plain

Cloudflareにて反映されるのを待つ f:id:inajob:20180228180930p:plain

ページを行ったり来たりしていると数分で反映された f:id:inajob:20180228181223p:plain

いまこのドメインにアクセスすると下記のようになる。 これは名前からサーバまではいけるがそのサーバの80番が開いていないということのようだ。 登録したIPが間違っていたかな? f:id:inajob:20180228181250p:plain

nghttpx-ingress-controllerがデプロイされているホストをを調べる f:id:inajob:20180228181410p:plain

worker01にデプロイされているので、そのIPに設定する(masterのIPを指定していました;) (通常のPodは10.x.xのようなクラスタ内IPが付与されますがnghttpx-ingress-controllerは.spec.hostNetwork=trueとなっているためホストのIPとなっています my-vps-kubernetes/rc-default.yaml at master · inajob/my-vps-kubernetes · GitHubf:id:inajob:20180228181657p:plain

アクセスできた! この"default backend -404" というのはKubernetes上のサービスから返却しているものです。

f:id:inajob:20180228181819p:plain

図にするとこんな感じ f:id:inajob:20180228182434p:plain

$ kubectl get pods -n kube-system
NAME                                         READY     STATUS    RESTARTS   AGE
default-http-backend-55c6c69b88-vlqcx        1/1       Running   0          1h <--- これです
etcd-kubernetes                              1/1       Running   0          1h
kube-apiserver-kubernetes                    1/1       Running   0          1h
kube-controller-manager-kubernetes           1/1       Running   0          1h
kube-dns-6f4fd4bdf-c2995                     3/3       Running   0          1h
kube-proxy-622sq                             1/1       Running   0          1h
kube-proxy-j5754                             1/1       Running   0          1h
kube-scheduler-kubernetes                    1/1       Running   0          1h
monitoring-grafana-8dd9cb57f-4ms82           1/1       Running   0          1h
nghttpx-ingress-controller-78749dc54-8wlxr   1/1       Running   0          29m
node-exporter-5294m                          1/1       Running   0          1h
prometheus-8694d8cdd8-vmw7h                  1/1       Running   0          1h
weave-net-r5jft                              2/2       Running   0          1h
weave-net-wm7sn                              2/2       Running   0          1h

Ingressを試す

ドメインの取得、DNSサーバへの登録が終わり、無事取得したドメインでKubernetesクラスタまで到達できることが確認できました。 次はIngressを試します。

Ingressを利用するとVirtualHostのようにHostヘッダの値で違うServiceにアクセスさせることができます。

nginxをデプロイして、Serviceも作成します。

$ kubectl run nginx --image=nginx
deployment "nginx" created
$ kubectl expose deployment nginx --port=80
service "nginx" exposed

Ingressはコマンドでは作れないので下記のようなテキストファイルを用意します

nginx-ingress.yaml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx-ingress
spec:
  rules:
  - host: nginx.inajob-test.tk
    http:
      paths:
      - path: /
        backend:
          serviceName: nginx
          servicePort: 80

上記をKubernetesにデプロイします。

$ kubectl apply -f nginx-ingress.yaml
ingress "nginx-ingress" created

cloudflareにAレコードを追加します f:id:inajob:20180228183320p:plain

やった!アクセスできました。 f:id:inajob:20180228183400p:plain

新しいサブドメインIngressを用意するたびにcloudflareにAレコードを追加するのが面倒なのでワイルドカードドメインを追加してみます。

丸で囲ったところに注意です。CloudFlareではCloudFlareを経由しキャッシュを返したり、SSL化したりするような機能がありますが、ワイルドカードドメインの場合はそれが使えないので明示的にOFFにしています。

f:id:inajob:20180228183707p:plain

f:id:inajob:20180228183635p:plain

これであとはIngressを用意するだけでサブドメインが増えていくようになります。

まとめ

ここまでできると月$10のクラスタでもそこそこつかえるKubernetesが構築できたのではないかと思います。

ということで、vultrでサーバを作りましょう! (この記事が役立った!という人はぜひこちらのリンクからお願いします。)

www.vultr.com