Go To Eat が使えるお店を 地図で見るためのサービス「Go To Eat 埼玉 マップ! 」を作った

これは何?

今話題のGo To Eatですが、その利用可能店舗を知るためには、利用可能店舗一覧ページを見るしかなく、それぞれに住所は書いてあるものの、地図上で確認することが出来ませんでした。

 

そこで、上記の情報を基に埼玉県のGo To Eat対象店舗を地図上で見ることが出来るWebサービス 「Go To Eat 埼玉マップ!」を作りました。

 

※ここで扱うのは埼玉県のGo To Eatの食事券が使える店舗です。これ以外に予約サイトのポイントがたまるというのもGo To Eatの施策がありますが、そちらに対応している店舗はもっとあるはずです。

f:id:inajob:20201109134633p:plain

 

 

類似サービス

同じような課題を感じている方は他にもいて、下記のような類似サービスが開発されているようです。

正直なところ、私が作ったものより、これらのサービスのほうが使い勝手が良いと感じます。また埼玉県以外もサポートしているようです。

まぁすでに自分も作ってしまったし、同じようなサービスが切磋琢磨したほうが良いものができると思うので、皆さんそれぞれのサイトを使ってみてください。

 

go-to-eat-map.com

gotoeatmap.net

自由な地図API

地図系のサービスを作るということであれば Google MapsYahoo! 地図が真っ先に思い浮かぶのですが、Google Mapsは有料化され、Yahoo! 地図のAPIは廃止されています。

map.yahoo.co.jp

 

(後で良く良く調べると、Google Mapsは条件によっては無料で使えるらしく、今回の用途であればマイマップを使うのが良かったかもしれません。類似サービスの中には枚マップを使ったものもありました。)

qiita.com

まぁ、ともあれ、地図系のWebサービスを作るときに他社のご機嫌をうかがいながら開発するのも気持ちの良いものではありません。

 

ということで、今回はLeafletと国土地理院の地図を使ってみることにしました。

 

leafletjs.com

Leafletというのは ブラウザ上で地図を表示するためのオープンソースJavaScriptライブラリです。OpenStreetMapのタイルサーバを参照することで、世界中の地図を表示することが出来ます。

また地図のドラッグアンドドロップや、地図上にマーカーを描画するなど、いわゆるYahoo! 地図やGoogle Mapsのような使い勝手を、非常に少ないコーディングで実現することが出来ます。

 

Leafletについては下記サイトが非常に参考になりました。

ops.jig-saw.com

 

日本の政府機関である国土地理院は、OpenStreetMap互換のタイルサーバを提供しています。

maps.gsi.go.jp

利用のガイドラインも非常に緩く、今回の用途でも問題なく利用できそうでした。

地理院タイルをウェブサイトやソフトウェア、アプリケーション上でリアルタイムに読み込んで利用する場合、地理院タイルは出典の明示のみで申請不要でご利用いただけます。

本当はOpenStreetMapの本家のタイルサーバを利用したかったのですが、これは不特定多数が利用するWebサービスから参照することは、規約上NGのようだったので、使用を見送りました。

wiki.openstreetmap.org

住所文字列から緯度経度への変換

Go To Eatの対象店舗情報は、各自治体ごとに公表されています。

埼玉県の場合は下記サイトにHTMLで一覧が記載されています。

saitama-goto-eat.com

ここには店の名前、電話番号、住所などが記載されていますが、地図上に表示する際に必要な「緯度・経度」が記載されていません。

 

ということで「住所文字列から緯度・経度を求める」必要があります。

 

幸いなことにYahoo! JAPANが提供しているAPIに良いものがありました。

developer.yahoo.co.jp

ということで材料はそろいました。

埼玉県のGo To Eat対象店舗一覧のHTMLをスクレイピングして、店舗の情報を取得し、YOLPのジオコーダAPIをつかい、それらの緯度・経度を求めます。

 

最後にこれらの情報をLeafletを使って国土地理院のタイルの上に描画すれば完成です。

 

マーカーが多すぎる問題の回避

Leafletを使って、マーカーを大量に配置すると、ブラウザが固まってしまうほど動作が遅くなってしまいました。

これはLeafletあるある、な問題のようで、今回はMarkerではなくCircleMarkerという別の仕組みを使って地点を描画することで、この問題を回避しました。

f:id:inajob:20201109142415p:plain

MakerはDOMを生成するため大量に登録するとブラウザが重くなるようです、しかしCircleMarkerの場合はCanvasに図形を描画するため、ブラウザはそこまで重くならないようです。

 

下記のStackoverflowが参考になりました。

stackoverflow.com

埼玉県への要望

できれば、Go To Eat対象店舗の情報をCSVのようなコンピュータで扱いやすい形式で公開してほしいです。

ちょうど埼玉県のオープンデータのポータルがあるようなので、ここで公開するのが良いのでは?と考えています。

https://opendata.pref.saitama.lg.jp/

(すでに上記サイトから要望は送ってみました)

最後に

まぁこんな感じで無事「Go To Eat 埼玉マップ!」が完成しました。

MITライセンスでソースコードもオープンにしているので、似たようなものを作りたい人は参考にしてみてください。

また、修正点・改善点のPullRequestもお待ちしています。

 

github.com

 

エンジニアパパ 6か月の娘との初めての外泊 東京ディズニーランドホテル

はじめに

娘が生まれてはや6か月。ずっと育休を取得し、妻と一緒に子育てを続けています。

しかし、やはりずっと家にいて子守しているというのはマンネリ化してくるものです。

そんな中 Go To Travelを活用して外泊をしてみないか?という話が持ち上がりました。

 

f:id:inajob:20201107220311p:plain

候補探し

今回の大きな目的は「6か月の娘と初めて外泊する」「親も気分転換をする」です。

これをもう少し具体的に考え・・

  • 赤ちゃんの受け入れに慣れている
  • 普段行かないようなゴージャスさ

あたりをキーワードに近場の宿の候補を探しました。

 

このページが非常に参考になりました。

travel.biglobe.ne.jp

さて、上記のページを見ていると、ディズニーリゾートの周辺のホテルが多いことに気付きました。

6か月の娘と一緒の旅ということで、さすがにまだディズニーは早すぎるだろうということで、深く考えてなかったのですが、「ディズニーランド周辺のホテル」というのは、実は今回の要件をよく満たしているのではないかと思い直し、ディズニーランド周辺のホテルを深堀調査しました。

f:id:inajob:20201107221526p:plain

ディズニーランド周辺のホテルは、赤ちゃん連れに非常に適しており、ベビーベッドの貸し出し哺乳瓶の洗浄キットの用意、赤ちゃん連れの客が多く多少騒がしくしても目立たない従業員が赤ちゃんに慣れている、など設備・サービスの面でも今回の要件と一致していました。

 

加えてディズニーランドの最寄り駅である舞浜駅」は様々な方法でアクセスできるのも選んだ理由の一つです。自分は認識していなかったのですが武蔵野線を使うと埼玉のほうからも意外と電車1・2本でいけるというのには驚きました。

f:id:inajob:20201107163158p:plain

https://beta-map.yahoo.co.jp/route/train?from=%E6%9D%B1%E5%B7%9D%E5%8F%A3&to=%E8%88%9E%E6%B5%9C&t=1&y=202011&d=07&h=16&m=31&sort=1&lat=35.798034581996575&lon=139.69056968504947&zoom=10&maptype=basic&no=1

 

ディズニーランド周辺のホテルには「ディズニーホテル」「オフィシャルホテル」「パートナーホテル」など、様々種類があり、値段やグレードもまちまちでした。

 

今回の旅の目的から考えると ゴージャスなホテル、という話なので、そこそこいい感じのホテルを選びたいところです。

妻とホテル一覧を眺めていると「ディズニーホテル」というのは、いわゆる一般的な高級ホテルというのとは少し毛色が違っていることに気付きました。

 

外装・内装がディズニーの世界観に合わせてあり、建物のあちこちにディズニーキャラクターをあしらったオブジェなどが設置されているのです。

 

他のホテルに関しても、子供向けのポップな色合いなどの内装ではあるものの、ディズニーキャラクターなどは使えないようで、ディズニーホテルほどの「思い切ったキラキラ感」は無いようでした。

 

折角行くなら、この楽しげな「ディズニーホテル」が良いだろう。ということで、今回は数あるディズニーホテルの中でも、その佇まいが最もゴージャスそうな「ディズニーランドホテル」への宿泊に挑戦することにしました。

f:id:inajob:20201107220955p:plain

Go To Travelとディズニーランドホテル

ディズニーランドホテルの宿泊予約は公式ホームページからできるようでしたが、この申し込み方法だと、Go To Travelは適用されません。

しかし、ここであきらめずに調べていると、、例えば一休(ホテル予約・旅館予約[一休.com])のような、宿泊予約サービスを経由して予約することで Go To Travelの恩恵を受けることが出来ることに気付きました。

 

ちなみに今、ディズニーランドホテルは「外壁工事」を行っており、客室の一部は窓が開けられない状態になっているようで、少し安いプランになっているのですが、あまり人気がないようで、比較的予約が空いていました。

f:id:inajob:20201107220711p:plain

まぁ、今回の主役である6か月の娘は終始眠っているし、あまり外の景色にはこだわらないで良いだろうという選択と集中」作戦により、少し安めの「外壁工事部屋」を予約しました。

(この辺、謎にケチるのが自分らしいな、と思ったりします・・)

 

ともかく宿は予約できました。

ホテルのサービスとしてベビーベッドがあるというのは把握していたので備考欄でベビーベッドを用意してほしいと伝えました。

旅行の予定を立てる(スケジュール)

なんといっても生後6か月の娘を連れての初めての外泊です。ちゃんと計画を立てないと大変なことになりそうです・・

ということでまずはタイムスケジュールを検討しました。

現在の娘は朝寝、昼寝、(昼寝が不十分な時は)夕寝、が必要で、離乳食は2回食、完ミ(母乳ではなくミルクのみを飲む)という状態です。

 

離乳食は慣れさせるために与えているので旅行の間くらいは食べなくても大丈夫そうです。睡眠は、その時間になったら眠るので、親の食事や移動時間とうまく合わせられるとよさそう、、といった感じでタイムスケジュールを考えました。

 

1泊2日の予定を考えているとまぁ、とてもディズニーランド内に入っている余裕はなさそうだったので、大まかな予定としては

 

移動 → 宿泊 → ちょっとウロウロする → 家に帰る

 

という感じに決まりました。

ディズニーランドホテルに泊まりつつ、ディズニーランドに入らないなんて、なんと不思議な旅なんだ!と思っていましたが、実際にホテルの方に聞いてみると、そういうお客さんも結構いるらしいです。

旅行の予定を立てる(持ち物)

次に気になるのが持ち物です。

おむつ、哺乳瓶、保湿用のミルクローション、、哺乳瓶洗浄用のブラシは必要?、服は何枚必要?

と、戸惑いながらも書きだしたうえで整理して、必要なものを用意しました。

結構量が多いので、今回はホテルに荷物を送りつける作戦を採用しました。

 

事前にホテルに送る荷物

  • おむつ x20
  • ミルク缶(ビニール袋に入れる)
  • 保湿用ミルクローション
  • おしりふき

手荷物で持っていくもの

  • 短肌着 x4
  • 普通長袖 x2
  • 厚手長袖 x3
  • 靴下x2
  • レッグウォーマーx1
  • 防寒用ポンチョ
  • タオル x3
  • ガーゼ x6
  • 哺乳瓶 x4
  • ブランケット
  • おくるみ x1
  • 抱っこ紐
  • 皮膚の炎症を抑える軟膏
  • ベビーソープ(風呂用)
  • BOS袋(おむつがにおわない袋)
  • ビニール袋
  • お気に入りのおもちゃ
  • おむつ替えセット(数回分)(おむつ、おしりふき)
  • ミルクセット(2回ほどミルクが作れるように)(粉ミルク、お湯、湯冷まし)

全部を大き目の肩掛けバッグにいれて、準備しました。

ベビーカーも今回大活躍したアイテムです。

 

ホテルに事前に確認すると下記はホテルで貸してくれるということで荷物が少し減りました。

  • 哺乳瓶電子レンジ除菌箱
  • 哺乳瓶用スポンジ
  • 哺乳瓶用洗剤

実際のスケジュール

今回の旅行の実際のスケジュールをまとめてみました。

f:id:inajob:20201107204743p:plain

細かいところはスケジュール表を見てください。

ミルク、睡眠と いつもの娘のスケジュールをこなしつつディズニー周辺を満喫してきました。

 

今回良かったのは、移動中やいつもと違う部屋にもかかわらず娘がちゃんと寝て、ちゃんと飲んでくれたことです。おかげでかなりスムーズに旅をすることが出来ました。

 

恒例の食事難民とGo To Travel 地域共通クーポンの罠

今回ハラハラしたのは食事です。娘がどこでどういうぐずり方をするかわからなかったので、「最悪コンビニ飯で・・」というつもりで何の予約もせずに出発したものですから、案の定 食事の調達に苦労しました。

 

加えて今回はGo To Travelキャンペーンで、地域共通クーポンというものが発行されており、これも使い切ってしまいたいという気持ちがありました。このあたりもう少し事前に調べておけばよかったです。

 

Go To Travelの地域共通クーポンが使えるお店は

map.goto.jata-net.or.jp

を見ると、地図上で確認することが出来ました(が、スマートフォンで見ると異常に動作が重たいのがつらかった・・)

 

夕食をどうしようかとこの地図を見てみると、地域共通クーポンが使えるお店は大手コンビニ以外では、ホテルのレストランがほとんどで、当然それらは予約で埋まっていました。また、この地域共通クーポンは「電子クーポン」と「紙クーポン」の2種類があり、店舗によっては「紙クーポン」しか扱っていないところもありました。

 

「最悪お土産を地域共通クーポンで買えるかな?」と思っていたのですが、ディズニーのお土産が買えるお店で利用できるのはすべて「紙クーポン」だけでした。

 

電子クーポン・・ダメじゃん・・

 

しかし我々はあきらめません・・

夜ごはんは唯一電子クーポンが使えて、予約などが不要そうな「ベッカーズ」にて調達することに成功しました!

f:id:inajob:20201107205635p:plain

ベッカーズは初めて利用したのですが、まぁいわゆるちょっと良いハンバーガーチェーンという感じで、ややジャンキーな感じはありましたが、夕食を堪能しました。

また、ベッカーズの買い物の道中にちょうどディズニーランドの花火が上がっているのを見ることができ、ちょっとラッキーな気持ちになりました。

 

ただ、娘が就寝していたため、ホテルの部屋の隅で薄暗い中食べるという、ちょっと不思議な夕食となりました。

f:id:inajob:20201107221222p:plain

 翌朝の朝ご飯は、まぁ普段もそんなにしっかり食べないということもあったので、コンビニでテキトーなものを買って済ませました。一応朝ごはんのビュッフェも予約が空いていないかを夜に確認したのですが、まぁいっぱいでした。そうですよね、、事前に予約が基本なんですよね・・

 

そして最後のチェックアウト後の昼ごはん、、ダメもとでお昼のタイミングでビュッフェの状況を聞いてみたところ「すぐに入れますよ」とのこと・・・!!!

最後の最後でホテルの素敵なビュッフェにありつけたのです!!

 

f:id:inajob:20201107221315p:plain

f:id:inajob:20201107221343p:plain

後で冷静になって考えると、ホテルの性質上、宿泊者の多くはディズニーランド内で昼ごはんを食べるため、ホテルのレストランは比較的空いているということのようでした。

 

ということでGo To Travelの地域共通クーポンも使い切ることが出来ました

今回は食事周りがハラハラしましたが、結果オーライでした!

 

ディズニーランドに入らないディズニー観光

まぁ正直なところ、入らないと特にできることは何もありません。そんな中見て回ったのはホテルの庭「アリスガーデン」「シャーウッドガーデン」、ホテルの玄関「ファンタジアコート」です。ベビーカーを押しながらウロウロするにはちょうど良い広さで、ディズニーの雰囲気を感じつつ、まったりと散歩しました。

f:id:inajob:20201108075852p:plain

 

ディズニーランドからは1駅離れた葛西臨海公園にも遊びに行きました。ここはディズニーランドとは打って変わって、広々としていて自然が美しい公園でした。

娘に初めて海を見せることが出来て、親としては満足しました(娘はすこし寒かったのか不機嫌でしたが・・)

f:id:inajob:20201107222028p:plain

あれが夢の国か・・from 葛西臨海公園

ちょっとスケジュール的にきつくて葛西臨海公園は急いで歩き回る羽目になりましたが、水族館や観覧車などもあり、ここだけでも楽しく観光できそうな公園でした。

 

最後にディズニーをぐるっと一周しているモノレールである「ディズニーリゾートライン」に乗り、ディズニーランド・ディズニーシーを一周見渡してから、家に向かいました。

 

f:id:inajob:20201107221440p:plain

まぁちょっと物足りないですが、ディズニーランドに入るのは、娘がもう少し大きくなってから挑戦しようと思います。

 

まとめ

娘を連れて初めての外泊、ということでGo To Travelを使って東京ディズニーランドホテルに行ってきました。

今までの夫婦二人の旅行は まったり、くつろぎに行く、という感じでしたが、子連れの旅行というのは、ハラハラドキドキ、でも充実感がある、スポーツのような感じがしました。

これはこれで気分転換としては面白く、これから始まるエキサイティングな育児の片鱗を味わったような、そんな旅行でした。

 

ここまでの記事で書いたように、私は結構長めの育児休業を取得しており、そのおかげでこのような充実した時間を家族と過ごすことが出来ています。

育児休業いいですよ!!とアピールしてこの記事を締めます。

 

f:id:inajob:20201108080634p:plain

 

エンジニアパパの初めての娘の風邪

初めての風邪

うちの娘も生後5か月。そろそろ離乳食も始めています。

そんなある日・・ 初めて娘が風邪をひきました・・・

兆候

くしゃみが多いな・・という日があり、それがひき始めだったのかな?と思います。そのうちせき込むようになり、鼻詰まりが気になるようになってきました。

発熱は無し、だけどミルクを飲むときにせき込んだり、睡眠中にもせき込んで目が覚めるなど、辛そうでした。

小児科を受診

検診や予防接種で小児科には何度も行っているので、まぁいつもの感じで小児科に行きました。聴診器をあてられ、のどをちょっと見てもらい、気管支を広げる薬と、咳をおさえる薬を処方してもらいました。

親も風邪をひく

そうこうしているうちに、親も風邪の症状が出始めました。熱は出ないものの鼻水と咳が・・・

家族3人、全員ダウンです。これはつらい・・

一応、娘に風邪っぽい症状が出始めたころから、娘のおもちゃや、プレイマット、家じゅうの取っ手などはアルコール消毒していたのですが、時すでに遅しというやつだったんでしょうね・・

鼻水を吸い取る

赤ちゃんは鼻水を「チーン」できないので、親が吸い取る必要があるそうです。

ということで、スポイト式「鼻水吸い取り器」を使って鼻水を吸い取ろうと頑張りました・・が、大して吸い取れない割に娘は大泣き・・ これは心が折れる

鼻水もだばぁと出ているわけではなく、鼻の奥にたまっているような状態なので、スポイト式で吸い取るには難易度が高い状態のようでした。

 

他には、親が口で吸い取るという下記のような商品もあるのですが、これは話を聞く限り「子供の風邪が親にうつる」らしいので、却下。

 

 

そこで、少し高いですが「電動鼻水吸い取り器」を購入しました。子育て仲間の友人のアドバイスをもらいつつ、機種を選定し下記を購入しました。

相変わらず娘は大泣きしますが、確実に素早く鼻水を吸い取ることができ、大活躍しました。

 

f:id:inajob:20201015152748p:plain


 

最大-75kPaと結構な吸引力で、鼻の奥にたまってしまった鼻水もずぞぞっと吸い取れます。分解して洗浄するのがちょっと面倒ですが、逆に考えると、細かい部品単位でばらばらにでき、細部まで洗浄することが出来るということです。

 

他にも似たような価格帯では以下のような鼻水吸い取り器があるようです。

自分が買ったやつが一番「メカメカしい」ですね。レビューなどを見る限り、吸い取る力はそこまで変わらず、メンテナンス性にちょっと違いがあるのかなといった所でした。

ピジョン 電動鼻吸い器

ピジョン 電動鼻吸い器

  • 発売日: 2018/08/24
  • メディア: Baby Product
 

参考にしたサイト: とある医師の買ったものを記すブログ - スマイルキュートとメルシーポットどっちを買うべき?比較論に答える https://www.a-certain-doctor.com/2019/03/mercipot-and-smilecute.html

 

粉薬どうやって飲むの?

小児科で処方していただいた薬は「粉薬」。これをどうやって飲ますのか・・

薬局で薬をもらう際に聞いたところ、「少しの水で練って頬っぺたの裏にくっつける」または「水で溶いてスポイトで飲ませる」のどちらかが良いとのことでした。

 

始めは「少しの水で練って頬っぺたの裏にくっつける」を実践しようとしたのですが、水が少しでも多いと、サラサラになってしまい、うまくできず、うまく団子状にできても、味が濃すぎて、口に入れた時に娘が非常に嫌がってしまいました。

 

ということでスポイトを購入して飲ませる作戦に切り替えました。この方法だと、口に入れた直後は嫌がるものの、初めの方法ほどは嫌がらずに飲み込んでくれました。

 

一安心。

 

もう少し月齢が進めば下のような、ゼリー状のオブラートが使えそうなので、次回があれば挑戦してみたいところです。

龍角散 おくすり飲めたね ぶどう 200g×5個

龍角散 おくすり飲めたね ぶどう 200g×5個

  • メディア: ヘルスケア&ケア用品
 

 

徐々に回復

幸いにして親は3日ほどで風邪の症状は回復しました。娘は結局2週間くらいかけて回復し、今では鼻水もまったく出なくなり元気になりました。

結局最後まで発熱することもなく、ひどくなることもなかったのでほっと胸をなでおろしました。

 

まとめ

初めてのことばかりで、ちょっと風邪を引くだけで、びくびくしているエンジニアパパですが、娘とともに親も一歩ずつ成長できています。

とはいえ、病気はなるべくしないでいて欲しいな、と思った一件でした。

CNCルーターの活用:基板の切削 「親バカ サンプラー」の作成

CNCルーターについて

さて、先日購入し、アクリルカットもできるようになったCNCルーターですが、今回は「回路」の掘削に挑戦してみました。

inajob.hatenablog.jp

inajob.hatenablog.jp

イデアから論理回路の作成

回路の作成は、プリント基板を作るときと同様です。

まずはアイデアを出し、ブレッドボードなどでプロトタイピングをしたのちに、回路図を書き起こすのが失敗を少なくするコツです。

今回作成するのは 「静電容量によるタッチセンサーを使ったmp3再生装置」です。

いわゆるサンプラーというDTM機器に近いものです。主な部品はATmega328とMP3再生モジュールであるDFPlayer Miniです。

まぁ、今回は掘削の話がメインなので、この辺は割愛して、、、 出来上がった論理回路図がこちらです。

f:id:inajob:20200922134413p:plain

左上がレギュレータ。右上にスピーカ端子。その下がDFPlayer Mini(フットプリントを新規に作るのが面倒だったので、ピンヘッダのフットプリントで代用)です。

 

左下に大きくあるのがArduinoのコアと同じATmega328、右下にあるのがタッチセンサーです。

配線図の作成

さて、これを基に配線図を作成します。回路規模も小さいのでテキトーに手で配線します。

プリント基板の場合は両面基板を良く作るのですが、今回は簡単に掘削できるように片面基板で作る事にします。

立体交差ができないため、配線図を作る際には工夫が必要です。

f:id:inajob:20200922134809p:plain

またデザインルールにも注意が必要です。CNCルータの性能により、このパラメータは様々ですが、今回は配線幅1mm クリアランス0.41mmにしました。

(後から考えるとクリアランスはもう少しあったほうが良かったです。)

 

静電容量タッチ用のPadは図形ポリゴンツールで描きました。

また、TO-92のようなパッケージはフットプリントのPadが近すぎて上記のデザインルールを見たさにため使うことができません。

f:id:inajob:20200922135229p:plain

https://akizukidenshi.com/catalog/g/gI-08973/

例えば上記のレギュレータのフットプリントは下記ですが、パッドが近すぎてうまく掘削できません。

f:id:inajob:20200922135415p:plain

今回はたまたま、パッドの間隔が広い部品しか使う必要がなかったので、特に工夫は不要でした。

掘削用データの作成

FlatCAMというソフトを使ってガーバーファイルを掘削用データであるgcodeに変換します。

細かい手順は下記サイトを参考にしました。

denshikousakusenka.jimdofree.com

注意する点としては左右反転が必要だということです。

f:id:inajob:20200922135726p:plain

また、Tool diaの設定より細い隙間掘削することはできないので、上記の図で水色の領域が正しく配線の間を分割しているかどうかを確認します。(クリアランスをTool diaより大きくしておけば基本的には問題ないはずです)

 

Tool diaの単位はインチで、掘削に利用するドリルの直径に設定しておきます。

またCut Zで基板表面からどれだけ深く基板を掘削するかを設定します。今回はTool diaは0.016、Cut Zは-0.002を設定しました。

 

ここまで出来たら、後は掘削するだけです。

AutoLevelの実行

と、アクリルのカットの場合はここから掘削するだけだったのですが、基板掘削の場合は、Z方向にかなりの精度が要求されます。今回の場合だと掘削時のZ方向の掘削幅は-0.002inchでおよそ-0.5mmです。

XY平面が平らでない場合は、基板の一部で回路を深く掘りすぎてパターンが途切れたり、浅く掘ってしまったがためにほかの配線とショートしてしまうなどの問題が起きていまします。

 

そこで、実際の基板が水平からどれだけずれているかを測定し、掘削時にその誤差分を補正することで、仮に基板がZ方向に斜めになっていても、うまく掘削できるようにする機能であるAutoLevelを利用します。

 

AutoLevelでの測定は、ドリルと基板にそれぞれ電極を取り付け、ゆっくりとドリルをZ方向に下げていき、ドリルと基板が接触したところをゼロ点として記録することを、格子の交点ごとに行い、対象物の形状を測定します。

f:id:inajob:20200922195021p:plain

基板データは今回のものとは違うけど、こんな感じに測定できます。

bCNCでは、このAutoLevelを実行することで、掘削用のgcodeをうまい具合に補正してくれます。

 

AutoLevelを利用するためには、まずドリルと基板に取り付ける電極が必要です。家にあるものでチャチャッと作り、CNCのメイン基板のA5端子とGND端子に取り付けます(写真の右下のProble(Probeの間違い?)という端子)。

f:id:inajob:20200922180208p:plain

f:id:inajob:20200922142605p:plain

https://www.aliexpress.com/item/4000264419927.html

実際のAutoLevelの使い方は下記2つのサイトを参考にしました。

Auto Level - 電子工作専科

martyworkshopdiary.blogspot.com

トラブル!!!

このAutolevel、素晴らしい仕組みなのですが、手順を間違えるとすぐにドリルを破損してしまいます。

いくつかのトラブル例を紹介します。

Probeつけ忘れ

Probe端子はワニ口クリップとなっており、ドリルと基板に取り付けますが、AutoLevel実行時、この端子が外れてしまっていると、AutoLevel機能はドリルと基板の接触を検知できません。

そのため、ドリルが基板に接触しているにもかかわらず、さらにドリルを下げ続けて、基板がゆがみ、ドリルは折れてしまいます。ステッピングモーターにも無理がかかってしまいます。

基板範囲の逸脱(バイスへの衝突)

AutoLevelはメッシュの交点を測定していくのですが、そのメッシュが測定対象の基板より大きい場合、様々な問題が発生します。

その1つがバイスへの衝突です。基板をステージに固定するために、バイス(万力)を使っているのですが、設定が間違っているとAutoLevelの測定中にドリルがこのバイスにぶつかってしまいます。

このトラブルでは、ドリルが折れ、破片が飛散するので危険です。また、モーターにも無理がかかってしまいます。

基板範囲の逸脱(捨て板へのめりこみ)

基板範囲の逸脱で起きるもう一つの問題が捨て板へのめり込みです。これはProbeつけ忘れと同様に、ドリルが捨て板にめり込んでしまい、折れてしまう事象です。

AutoLevel時、基板表面にドリルが接触すれば検知されるのですが、検査範囲が測定対象よりも広い場合は、基板表面に触れることなく捨て板にドリルがめり込みます。

 

AutoLevelの設定で最大下降幅を指定できるので、この値をうまく設定することで、このトラブルを防ぐことができます。

基板掘削・穴あけ

AutoLevelがうまく実行出来たらいよいよ基板の掘削です。

ここまでうまくできていれば、待つだけで基板は完成します。今回の基板の作成はおおよそ30分程度で完了しました。

 

f:id:inajob:20200922180318p:plain

基板掘削用ドリル

パターンの掘削が終わったら、最後にドリルでの穴あけを行います。これも15分程度で終わりました。

f:id:inajob:20200922180250p:plain

0.8mm穴開け用ドリル

回路パターン掘削用のドリルビットと、穴開け用のドリルが別の場合は、基板を固定したままで、ドリルを交換して、続きの作業を行います。

 

手元には0.8mmの穴開け用のドリルがあったのでこれを使いましたが、一般的なピンヘッダの直径は0.8mmちょうどで、ぴったり過ぎて、うまく挿入できませんでした、0.9mmか1mm程度の穴をあけるのがよさそうに思います。

 

今回は外形のカットは行わないので、ここまでで基板は完成です。

f:id:inajob:20200922180428p:plain

部品実装

f:id:inajob:20200922194132p:plainf:id:inajob:20200922194205p:plain

基板ができたので、部品を実装します。まぁプリント基板に部品を実装するのと同じですが、いくつか注意点があります。

  • 穴部分はスルーホール加工できていないので、ちょっとはんだ付けがやりづらい
  • ピンヘッダにQIコネクタなどを差し込む場合、銅箔と積層板の接着力でピンを保持することになり、簡単に基板からピンが外れてしまう(下の写真を参照)。
  • プリント基板と違いソルダーマスクが塗られていないので、意図しない配線にはんだが乗ってしまうことがある

まぁ、こんなところです。

f:id:inajob:20200922194357p:plain

この辺は掘削基板だけでなく、エッチングを使って作成した基板などでも同じ問題が起きると思います。

完成・プログラミング

部品が実装できれば基板は完成です。

次はプログラムを作成します。

 

静電容量タッチの検出にはADCTouchというライブラリを使っています。

github.com

下記はほとんどDFRobotDFPlayerMiniライブラリのサンプルそのままです。

6つのパッドをloopでスキャンすると、loopの実行間隔が長くなってしまい、サンプラーの醍醐味である「音源の先頭部分を繰り返し再生する」遊びができなくなってしまいます。また、タッチの反応速度も悪くなってしまいます。

この対策として、ADCTouch.readの第2引数をデフォルトの100から10に変更していることと、メインループのdelayを削除しているのが大きな変更点です。

 

(6つある変数を配列にすべきですね・・ とりあえず動いているのでこのままで・・)

 

#include <ADCTouch.h>
#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"
SoftwareSerial mySoftwareSerial(10, 11); // RX, TX
DFRobotDFPlayerMini myDFPlayer;


int ref0, ref1, ref2, ref3, ref4, ref5;     //reference values to remove offset

void setup() 
{
    // No pins to setup, pins can still be used regularly, although it will affect readings

    Serial.begin(9600);

    ref0 = ADCTouch.read(A0, 500);    //create reference values to 
    ref1 = ADCTouch.read(A1, 500);    //account for the capacitance of the pad
    ref2 = ADCTouch.read(A2, 500);
    ref3 = ADCTouch.read(A3, 500);
    ref4 = ADCTouch.read(A4, 500);
    ref5 = ADCTouch.read(A5, 500);
    
    mySoftwareSerial.begin(9600);

    if (!myDFPlayer.begin(mySoftwareSerial)) {  //Use softwareSerial to communicate with mp3.
      Serial.println(F("Unable to begin:"));
      Serial.println(F("1.Please recheck the connection!"));
      Serial.println(F("2.Please insert the SD card!"));
      while(true){
        delay(0); // Code to compatible with ESP8266 watch dog.
      }
    }
  Serial.println(F("DFPlayer Mini online."));
  
  myDFPlayer.volume(15);  //Set volume value. From 0 to 30
  myDFPlayer.play(1);  //Play the first mp3
} 

int trigger0 = 0;
int trigger1 = 0;
int trigger2 = 0;
int trigger3 = 0;
int trigger4 = 0;
int trigger5 = 0;

void loop() 
{
    int value0 = ADCTouch.read(A0,10);   //no second parameter
    int value1 = ADCTouch.read(A1,10);   //   --> 100 samples
    int value2 = ADCTouch.read(A2,10);
    int value3 = ADCTouch.read(A3,10);
    int value4 = ADCTouch.read(A4,10);
    int value5 = ADCTouch.read(A5,10);


    value0 -= ref0;       //remove offset
    value1 -= ref1;
    value2 -= ref2;
    value3 -= ref3;
    value4 -= ref4;
    value5 -= ref5;
    
    //Serial.print(value0 > 40);    //send (boolean) pressed or not pressed
    //Serial.print("\t");           //use if(value > threshold) to get the state of a button
    if(value0 > 40){
      if(trigger0 == 0){
        myDFPlayer.play(1);
      }
      trigger0 ++;
    }else{
      trigger0 = 0;
    }

    //Serial.print(value1 > 40);
    //Serial.print("\t\t");
    if(value1 > 40){
      if(trigger1 == 0){
        myDFPlayer.play(2);
      }
      trigger1 ++;
    }else{
      trigger1 = 0;
    }

    if(value2 > 40){
      if(trigger2 == 0){
        myDFPlayer.play(3);
      }
      trigger2 ++;
    }else{
      trigger2 = 0;
    }

    if(value3 > 40){
      if(trigger3 == 0){
        myDFPlayer.play(4);
      }
      trigger3 ++;
    }else{
      trigger3 = 0;
    }

    if(value4 > 40){
      if(trigger4 == 0){
        myDFPlayer.play(5);
      }
      trigger4 ++;
    }else{
      trigger4 = 0;
    }

    if(value5 > 40){
      if(trigger5 == 0){
        myDFPlayer.play(6);
      }
      trigger5 ++;
    }else{
      trigger5 = 0;
    }
    //Serial.print(value0);             //send actual reading
    //Serial.print("\t");
	
    //Serial.println(value1);
    //delay(100);
}

 

「親バカサンプラー」化

「静電容量によるタッチセンサーを使ったmp3再生装置」は、完成しました、後はDFPlayer Miniに挿入するSDカードに6つのmp3音源を入れるだけです。

 

一般的なサンプラーの場合は、ドラムセットのサンプリング音源を入れたりするのですが、今回は、かわいい我が娘(生後5か月)の声のmp3データを入れることにしました。

 

これにて「親バカサンプラーの完成です。

 

基板上の四角いパッドを連打すると、いい感じに我が娘の声が再生されます。

 

まとめ

ということで、CNCルーターで基板を作成し、実用的な(?)ガジェットを作る事ができました。

これでもうもじゃもじゃした配線と格闘することなくプロトタイピングを楽しむことができます。

 

ここでもう一度CNCルーターを使った基板作成の制限について列挙しておきます。

  • 基本的に片面基板しか作れない(両面基板も作れなくはないですが、位置合わせが大変そうです。スルーホールでもないし、viaも自分で打つ必要があります。)
  • デザインルールが厳しい。配線幅、クリアランスなど。
  • この程度の基板なら1時間以内で作れるが、大量に作るのは大変。

このように、CNCルーターを使った基板作成には、多くの制約が課されますが、それでも短時間でそこそこ複雑な回路を作る事ができるので、家でのプロトタイピングがはかどると感じました。

 

前回の記事ではアクリル板の切削、今回は基板の切削に挑戦しました。これにてCNCルーターを購入時に考えていた項目をすべて実現することができました。

どちらも期待通りの成果で、CNCルーターの購入により我が家でのプロトタイピングがさらにやりやすくなりました。

 

前回の記事でも書きましたが、良い買い物をしました!

この記事を読んでいる皆さんも、CNCルーター買いませんか?!

CNCルーターの活用:アクリル板の切削 CNCはレーザーカッターの代わりになるか?

CNCルータについて

さて、7月末に手に入れたこの「CNCルーターですが、コツコツと使い方をマスターしてきています。

今回紹介するのはアクリル板の切削です。

inajob.hatenablog.jp

モデルの作成

今回は私が作っているRakuChordのフロントパネルを作成します。

これは厚さ1mmの透明なアクリル板を材料としており、今まではレーザーカッターで作っていたものです。

f:id:inajob:20200921081400p:plain

このデータはOpenSCADで作成し、そこからSVGに変換してレーザーカットに使っていました。

今回はOpenSCADからDXFに変換します。

inajob.hatenablog.jp

DXFをCNCの加工のためのデータ形式であるgcodeに変換する必要がありますが・・ここではbCNCというソフトを使います。

github.com

DXFはカットしたい形状の輪郭線を表していますが、CNCで削るためにはドリルの径を考慮する必要があります。

 

DXFを読み込むとこのような感じです。

f:id:inajob:20200920214043p:plain

Profileツールを使ってドリルの径を考慮したエッジを生成します。

外形線は外側に少し大きめに、内側のくりぬく部分は内側に少し小さめにエッジを生成しています。(Dirctionの inside/outside を設定して上のProfileをクリックしていきます。)

他にもStockやMaterial、EndMillなども適切に指定する必要がありますが、ここでは割愛します。

詳しいところは下記を参考にして設定しました。

htlab.net

f:id:inajob:20200920214437p:plain

鋭角になっているくりぬきの部分は下図のように角っこでちょっと飛び出すような、面白い軌跡になります。

f:id:inajob:20200920214637p:plain

この軌跡を1回のパスでカットする場合はこれで良いのですが、少しずつ掘り下げながら数回パスでくりぬくためには「Cut」ツールを使います。(詳しくは上記記事を参照してください)

 

また加工の順序を編集し、外形線の掘削が一番最後になるように順序を変更しておきます。(外形線を先に掘削すると固定していたアクリル板が浮いてしまい内側を削るときに盛大にずれてしまうため)

 

さて、ここまで来たら実際の加工です。

アクリル板をステージに固定する

アクリル板をステージの上に置くのですが、ドリルがアクリル板を少し突き抜けて加工することになるので、加工したいアクリル板の下にいわゆる「捨て板」を配置する必要があります。

今回はスタイロフォームを捨て板に使いました。が、バイスでアクリル板を固定するときに圧力に負けてスタイロフォームが少し沈んでしまい、アクリル板が浮いてしまったので、もう少し固いものを捨て板にするのが良かったと思います。

(のちに木材を捨て板にするようにしました。)

f:id:inajob:20200921072157p:plain

(写真は加工した後のものです・・)

f:id:inajob:20200921081931p:plain

アクリル板が捨て板から浮いてしまうのを防ぐために、両面テープと養生テープで捨て板に固定しました。

アクリル板には保護シートが貼ってあったので、両面テープの「ねばねば」はアクリル板そのものには影響しません。

アクリル板を加工する

X,Y,Zの原点を適切な位置に調整して加工スタートです。後は待っているだけでアクリル板が指定した形状にくりぬかれます。

モーターの回転数や、ドリルの種類、ドリルの移動スピードなど、様々なパラメータにより加工精度は大きく変化します。今回も何度かパラメータを変更して挑戦してみましたが、まだまだ追い詰められていない感じです。

 

パラメータがまずいと、アクリル板が熱で溶けて切断面がガタガタになったり、アクリルを切断しきれていないのにドリルを移動してしまい、ドリルが折れてしまったりと、様々なトラブルが起きます。

 

Twitterでいろいろなアドバイスをいただいたので少し貼り付けておきます。もし同じようなことに挑戦しようとしている方の助けになれば幸いです。

 

ひとまず掘削完了・レーザーカットとの比較

まぁそんなこんなでアクリル板の掘削ができました。

エッジの部分がささくれているのがわかると思います。もう少しパラメータを攻めればさらにいい感じになると思います。

f:id:inajob:20200920221809p:plain

RakuChordに取り付けるとこんな感じ。いいね!

f:id:inajob:20200920221910p:plain

レーザーカッターで作ったものに比べると下記の点が気になりました

  • 加工したエッジ部分が鋭利なので、指でこすったりするとケガをしそう。(レーザーの場合は熱で溶けてちょうどいい感じに滑らかになります。
  • ドリルの歯が丸いのでとがった角のくりぬき加工ができない(今回は3mmのドリルを使ったので、くりぬき時は半径3㎜の丸い角となりました。)
  • 元データからドリル分のオフセットを指定する必要があり、やや面倒(レーザーはほとんど幅を持たないのであまり気にしたことがない)

まぁそのまま比べられるものではありませんが、これらの点に注意して加工すれば、CNCルーターでもレーザーカッターで行うようなアクリル板のくりぬき加工ができることが実証できました。

 

10枚20枚と大量に同じ形でくりぬく場合はレーザーカッターのほうが有利ですが、レーザーカッターは簡単にご家庭に導入できるものではありません。(最近いいくらいのサイズのレーザーカッターも出てきているようですが・・)

その点CNCルーターはレーザーカッターに比べると安価で、場所もそれほど取らないため、家で簡単にアクリル板の加工ができます

最終製品はレーザーで加工することを念頭に起きつつ、家でのプロトタイピングではCNCルーターで加工するというのが良い使い分けのように感じました。

 

特に昨今、コロナの影響で外に出ることがはばかられており、今ままで気軽に立ち寄っていた工作スペースへもちょっと行きづらい雰囲気です。そんな時におうちにCNCがあれば、サクッとプロトタイピングができて大変良いです。

いやぁ良い買い物をしたなと思っています。

 

最後に注意点

CNCルーターは結構大きな音がします、またドリルで削っているため、細かい粉塵のゴミが発生します。さらに折れたドリルや、素材の削りカスが結構な勢いで飛んできたりして危険なことがあります。これらの処理はご家庭にCNCルータを導入する際には大きな課題になると感じました。

我が家では下の写真のような「囲い」を作って、粉塵の飛散と危険な破片が飛び散るのを防いでいます。また動作時には「ゴーグル」を付けて目に危険な破片が飛んでくることを防止しています。

音については未対策で、動作中は部屋の扉を閉める、くらいしかやっていないので、ちょっとうるさいです。

本当は防音箱を作ってその中で動作させるのが良いと思います。

f:id:inajob:20200921092522p:plain

 もしこの記事を読んで、CNCルーターを買おうと考えている方は、これらの点に十分気を付けてください。

 

次回は・・?

さて、ここまででCNCを購入してやりたかった2つのことのうちの1つである「アクリル板のカット」をクリアしました。

もう一つの目的である「基板の掘削」についても書きました!こちらの記事もぜひ読んでみてください。

inajob.hatenablog.jp

Google Homeで子育て支援:「こもりうたタイム」を作った!

これは何?

我が家には生後4か月ほどの娘がいます。

生後2か月ごろから、いわゆる「ねんねトレーニング(ねんトレ)」をはじめ、ある程度スケジュールに沿って、授乳・睡眠をさせています。

 

さて、この「スケジュール」ですが、基本的には親が気にしながら生活して、ミルクを与えたり、ベッドに連れて行ったりするのですが、せっかくなら娘にもスケジュールを意識してほしい! ということで 睡眠時間が近づくと「こもりうた」を再生し、それにより「これから寝るんだな!」ということを意識してもらおうと考えました。

(この月齢で、そういうことが意識できるのかはよく知りませんが、まぁそういうのもやってみるといいのかも・・程度で実践しているだけです。)

f:id:inajob:20200831102029p:plain

要件

さて、では要件を整理します

  • 1日数回の決められた時間で再生する
  • 再生する曲は毎回同じ曲
  • 曲の長さは3分ほど

まぁ、こんなとこですね。

Google Homeがあれば簡単?

我が家にはGoogle Homeがあります。ということで当初はそんなこと簡単に出来るだろうと思い調査を始めました。

 

まずは「決められた時間」という点です。これはGoogle Home「ルーティン」という機能が使えそうでした。この機能は、「時刻」と「Google Homeへ伝える文字列」を登録することで、その時間になると、Google Homeに自動的に命令が発行される仕組みです。

この「ルーティン」機能で「こもりうたを再生する何らかの命令」を実行することで、要件を満たせると考えました。

 

Google Homeで指定した曲を再生する

我が家のGoogle Homeの音楽のプロバイダはSpotifyの無料アカウントで登録しています。ということで 「〇〇を再生して」と伝えるとSpotifyにより音楽が再生されます。しかし無料アカウントの範囲では、指定した曲を再生することはできず、代わりに適当なプレイリストの曲がランダムに再生される仕様となっています。

 

ということで、Google Homeで標準的に音楽再生を指示する「〇〇を再生して」を「ルーティン」で実行するだけでは要件である「再生する曲は毎回同じ曲」を満たすことができません。

 

ちなみに、こもりうたの音源は同じ曲であれば何でも良いと考えていたので、著作権フリーのこもりうた音源のmp3ファイルを探してきました。しかしGoogle Homeではこのmp3ファイルを再生することができないようです。

手元にスマートスピーカーとmp3ファイルがあるのに、これを定時に自動再生することができない・・というのは、何とももどかしい話です。

 

Actions on Google

ここであきらめないのがエンジニアです。

Google Homeで動かすコマンドは自作できる、ということを知っていたので、それを駆使して、こもりうたの再生を試みることにします。

そのために利用するのがActions on Googleです。これを使うことでGoogle HomeGoogle アシスタント用のチャットボットを作る事ができます。

 

プログラム不要で作れる「こもりうたタイム」

Actions on Googleでのアプリケーション開発はDialogflowというWeb開発ツールで行います。複雑なアプリケーションの場合はそこからさらに外部のWebサービスを作成し、そのサービスとやり取りをするような仕組みを作る必要があります。

しかし今回作ろうとしているのは「単にmp3を再生するだけ」の仕組みです。

そのようなややこしい開発をせずともDialogflowを少し使うだけで作る事ができました。

 

具体的には「Default Welcome Intent」という、対象のActionが呼び出された際に起動するIntentに少し細工をするだけです。IntentにはResponseと呼ばれる「返答」を登録することができ、そこには通常日本語の文字列を登録します。

 

例えば「はろー」と登録しておくと、そのActionが呼ばれたとき(「OK Google。〇〇につないで」といったとき)「はろー」とGoogle Homeがしゃべります。

 

実はこの部分、単なる日本語以外にも「SSML」という言語を記述することができます。

音声合成マークアップ言語(SSML)  |  Cloud Text-to-Speech のドキュメント  |  Google Cloud

これを利用すると下記のように記述することで、mp3ファイルを再生することができます。

<speak>お休みの時間です。<break time="1s" /><audio src="MP3ファイルのURL" /></speak>

これだけで、目的のActoinは完成です。

 Actionの公開

さて、1行だけの簡単なActionですが、完成しました。

ということで「Assistant Directory(Google Assistant)」に公開申請をしてみます。

プライバシーポリシー文書の用意や、Directoryでの説明用の文言などを登録し公開申請をします。

何度かRejectされましたが、修正することで無事公開することができました。

 

https://assistant.google.com/services/a/uid/0000002b0ea1b142

f:id:inajob:20200831094559p:plain

ということで下記のようにルーティンを設定することで、指定した時間にこもりうたを再生できるようになりました!やったー!

f:id:inajob:20200831102813p:plain

 

困っていること

さて、ここまでで無事 Actionが作れて、ひとまずは意図した動作をしています。

我が家では娘が寝る時間の15分前になると「こもりうた」が流れるようになりました。

 

しかし、現在もまだ解決していない問題がいくつかあります。

 

時々こもりうたが再生されない

SSMLのAudioタグが時々失敗しているようなのです。紹介したSSMLで「お休みの時間です」と喋った後にmp3が再生されず、延々とGoogleHomeがアプリに接続したままになってしまうという現象が、結構な頻度で起きます(10回中1回くらい?)

 

この原因がさっぱりわからず、またデバッグの方法もわかりません

個人的には再生エラーをGoogle Home側で検知し、mp3ファイルの再生をリトライしてほしいところです。

 

ルーティン以外から起動することが難しい

このActionの名前は「こもりうたタイム」としました。

そのためGoogle Homeから起動するときは「こもりうたタイム につないで」と伝える必要があります。

 

「ルーティン」で登録する場合は、この文言をアプリから文字として入力するので、問題なく起動します。

 

しかし、口頭でこのアプリにつなげる際に問題が生じます。しゃべり方によっては「子守歌タイムにつないで」と勝手に漢字に変換されてしまい、Actionが起動しないことがあるのです。

口頭だと必ず漢字に変換されるかというとそんなこともなく、なんとなくゆっくり目にしゃべるとひらがなとして認識されたりもします。

個人的には日本語の場合は、「読み」でActionを特定するようにしてほしいです、もしくはActionに複数の名前を登録できるのであればそれでも解決できます。

 

ActionのPermaLinkのOGP/Twitter Cardがおかしい

せっかく作ったActionなのでほかの人にも使って欲しい!と思いActionのPermaLinkTwitterFacebookに貼るわけですが、その際のOGP/Twitter Cardがおかしいです。

 

f:id:inajob:20200831095902p:plain

nullって・・

折角画像も作ったのにこれもOGP/Twitter Cardに反映されていません・・これは残念です・・

まとめ

さて、いくつか問題が残っていますが、当初予定していた「決められた時間に子守歌を再生する」という要件を満たす仕組みをGoogle Homeを使って実現することができました。

 

しかし、Google Homeは何でもできるようで意外なところで痒い所に手が届かないなという印象です。またGoogle Actionsもまだまだ完成度が低く、あまり使われていないような印象を受けました。

 

子育てを始めて、両手がふさがっているシチュエーションというのが意外に増えてきたので、Google Homeなどのスマートスピーカーの有用性を身にしみて感じています。今後この記事に書いたような問題点が解消し、さらに使いやすいスマートスピーカーとなってくれることを期待しています。

Arduboy用ゲーム『APPRENTICE WIZARD (みならいまほうつかい)』のリリースとミニゲーム開発フローの紹介

これはなに?

APPRENTICE WIZARD (みならいまほうつかい)』はArduboy専用のゲームです。

 

まずArduboyというのは下のゲーム機です。

Arduinoを基にしているこのゲーム機は、誰でもゲームを開発することができます。 

今回このArudoy向けのゲームコンテストである「Game Jam 5」が開催されているということで、自分もゲームを作ってみました。

community.arduboy.com

このGame Jamではテーマが決まっており今回は「Pretty」+「Simple」です。

 

さて、肝心の『APPRENTICE WIZARD (みならいまほうつかい)』ですが、「魔法陣を描く」ゲームです。

f:id:inajob:20200821220354p:plain

右側に見本の魔法陣が表示されるので、それと同じ魔法陣を描いていきます。

f:id:inajob:20200821220445p:plain

まぁこれだけのゲームなのですが、この「魔法陣を描く」というのをどうやってゲーム機で操作するのか?というのがこのゲームのキモです。

 

Arduboyには上下左右とA、Bキーしかないので、これだけのキーで魔法陣を描きます。描き方は下記の通り。

  • 上・下: 未確定図形の拡大・縮小
  • 左・右: 未確定図形の種類変更
  • A: 未確定図形を確定する
  • B+A: 今まで描いた魔法陣をリセットする
  • B+上、B+下: 未確定図形の上・下移動
  • B+左、B+右: 未確定図形の左・右回転 

このように、キーをフル活用して魔法陣を描きます。

このゲームではこれらの操作を順番に学べるようにステージを配置しています。

 

さらにちょっと頑張った点としては、このゲームは珍しく日本語にも対応しています。

f:id:inajob:20200821221339p:plain

Arduboyの実機を持っていなくてもこのゲームを遊ぶことができます。

下記リンクからブラウザで動作するArduboyエミュレータでこのゲームを遊ぶことができます。

ProjectABE - Arduboy Emulator

 

Arduboyを実機をお持ちの方は、Release v1.1 · inajob/arduboy-apprentice-wizard · GitHubからHEXファイルをダウンロードしてArduboyに書き込むことで遊べます。

 

 

ゲームの動いている様子の動画は下記Tweetからも見ることができます。 

 

どのようにして、このゲームを作ったのか?

折角なので、この記事ではこのゲームをどうやって作ったのかを紹介しようと思います。特にプログラミングの細かいテクニックではなく、アイデア出しから、ゲームを徐々に完成させていくというワークフローについて紹介します

 

というのも、巷にはプログラミングの細かいテクニックは多く紹介されていますが、ゲームを作るための一連の流れについてはあまり見たことがなかったからです。

 

重厚長大なゲームの場合はこのプロセスは複雑で説明も難しいものとなってしまいますが、今回のようなミニゲームであれば、比較的簡単に説明できるため、題材としてはちょうど良いと感じています。

イデア出し

まずはどんなゲームを作るか?を考えます。今回のGame Jamはテーマがあるので、まずはそれをとっかかりにしてアイデアを出します。

Simple というのは 「操作やルールが簡単でゲームを普段やらない人でも遊べる」こと、Prettyというのは「画面が魅力的で遊びたくなるものである」こと、ということのようでした。

 

まずはこれらのテーマから思い浮かぶ単語や、既存のゲームを書きだしました。

その時のメモがこれです↓。

f:id:inajob:20200822160814p:plain

 本当に思いつくPrettyでSimpleそうな単語を書きだしていきました。ちょうどそこで思い出したのがPlayStation2用のゲームであるFANTAVISIONです。

FANTAVISION

FANTAVISION

  • 発売日: 2000/03/09
  • メディア: Video Game
 

 まぁ、自分は遊んだことがなかったのですが、PlayStation2が発売された当時CMで何度も目にしました。自分が知っている中ではこのゲームはかなりPrettyでした。そして何より「花火のゲーム」という新ジャンル感が強烈で、印象に残っています。

 

さて、ではここで「花火のゲーム」を作るか・・このGame Jamではパーティクルを使うと評価が高いといったことも書かれていたので、ちょっと考えたのですが、なかなかArduboyの狭い画面のモノクロの画面で「花火のゲーム」をうまく構築できる気がしませんでした。

 

ここで、ちょっと立ち止まって「きれいなもの(花火)を題材にする」という点に着目して思いついたのが「魔法陣」です。

 

何を隠そうこの私、「魔法陣」にはこだわりがあって、過去にたくさんの「魔法陣」がらみのプロダクトを作ってきました。

inajob.github.io

inajob.github.io

ということで、「魔法陣」なら何か自分も得意だし(?)、ゲームが作れるのでは?ということで、魔法陣が題材となるゲームを作る事に決めました。

ゲームデザインとプロトタイピング

「魔法陣」が題材 と決まりましたが、どんなゲームか考える必要があります。

今まで自分は「魔法陣」を描くプログラム言語などを作ってきたこともあり、「魔法陣を描く楽しさ」のようなものを伝えられるようなゲームがいいなと考えました。

 

そこでとりあえず、「見本の通り魔法陣を作るゲーム」を作ってみることにしました。

Arduboyのゲーム画面はモノクロで128×64と、非常にミニマルなので、ゲームの試作としては「ドットエディタ」でゲーム画面を描いてみるのがおすすめです。

f:id:inajob:20200822162745p:plain

 最終的な画面からはずいぶんと異なりますが、画面の大きさ的に魔法陣を描くスペースはありそうだなということがわかりました。

重要なのは、ここまではプログラミングせずに、メモ帳やペイントだけで進めているということです。

(ちなみに利用したドット絵エディタは高機能ドット絵エディタ EDGE | TAKABO SOFT です。)

 

さて、ここからは実際に動くものを作りながら内容をチューニングしていきます。

プログラミングによるプロトタイピング

そもそも「魔法陣」をどのように描くのか・・これを考えるためには、操作性などの兼ね合いもあるので、実際にプログラミングしながら考えることにしました。

 

ぼんやりと頭に描いていたのは、回転・拡縮・平行移動をキー入力で行い、Viewポートを移動させつつ円や四角、三角、星などの基本図形を配置していくという方法です。

f:id:inajob:20200822220138p:plain

最終的にはこれに近い方法を採用することになったのですが、一番初めに作ったプロトタイピングでは、もっと自由度が高い操作を許容していました。

 

その結果・・・「答え合わせができない」という問題に直面しました。任意の回数の回転・拡縮・平行移動を組み合わせて基本図形を配置する方法では、同じ魔法陣を得るために必要な操作の組み合わせが非常に多くなってしまい、答え合わせをすることが困難となってしまいました。

操作の答え合わせができないなら、最終的な図形が同じものかどうかを座標で判定する方法も考えたのですが、デジタルデータの誤差などをうまく許容して答え合わせをする必要があり、微妙に似た魔法陣をどのように扱うかなどが難しく、またプレイヤーにとっても、もどかしい感じになってしまいそうだと考え、この方法も却下しました。

 

ここで、一度「見本と同じ魔法陣を描くゲーム」というのを作るのは難しいのでは・・?と考え、別の案にしようかと思い始めました。

しかし、改めて前述の自由すぎる魔法陣システムを見直すと、答え合わせが簡単な魔法陣しか描けないように制限することで、ゲームとして成立するのでは?という気がしてきました。

 

答え合わせが難しくなる原因は任意の回数の回転・拡縮・平行移動のためです、それぞれの操作を決まった順番でしか適用できないように制限することで、ほぼ一意に魔法陣を特定できそうだということを思いつきました。

 

ゲーム開発の面白いところは、このようにゲームのルールを実装の難易度に合わせて、変更できることです。有名な例では「スペランカー」の「ある程度早い速度で移動したら死ぬ」というルールや、よくあるシューティングゲームの「壁に当たると即死」というようなルールがこれに当たります。(ある程度より速い速度で移動すると小さなキャラクタを飛び越してワープする現象が発生する、また壁に当たらないように制御するためには、めり込み判定し、めり込まない位置までキャラクタを戻す必要があるなど)

 

ということで、「魔法陣を描くゲーム」の操作方法として、回転、移動、拡縮は1回のみで適用順序は 回転→移動→拡縮のみ と制限しました。

これで大半の魔法陣を操作の照合だけで同定することができるようになりました。

 

また、回転は45度単位、移動は8マスのみ、拡縮は8段階とすることで、操作をそこそこ簡単にしつつ、解空間はなるべく広くとれるようにしました(8x8x8=512通り)

 

円の場合は下図のような位置を指定できます(この図も魔法陣言語で書きましたMagicalCircleEngine - 魔法陣エンジン

f:id:inajob:20200822220805p:plain

Arduboyは上下左右とABしかボタンがないことも問題でした。回転・移動・拡縮、図形の切り替えを、ある程度直感的になるように、これら6つのボタンに割り当てるのは苦労しました。

 

その過程で「一度配置した図形を消す」という操作用意しないことにして「今まで配置したすべての図形を消す」ということしかできないようにしました。

これにより魔法陣を描くという点では不便になりましたが、ゲームに緊張感が出るようになったのではと感じています。

おそらく本当の魔法陣を描く際も、書き直しなどしていたら魔法は正しく発動しないでしょう(しらんけど)

魔法陣の同定ロジック

ここまでで説明したように、操作を「回転→移動→拡縮」とすることで、魔法陣を操作の照合だけで同定できるようになりましたが、いくつか例外があります。

この段階で基本図形として考えていたのは四角です。

これらの図形は点対称です。そのため、原点に配置した場合、それを何度か回転した図形が同じ図形となる場合があります。

が原点に配置された場合は、どれだけ回転しても同じ図形であるため、回転角は無視する必要があります。

四角が原点に配置された場合は、90度回転するたびに同じ図形となるため、回転角の90度に対する剰余が同じかどうかで同じ図形かどうかを判定します。

f:id:inajob:20200822222303p:plain

(MagicalCircleEngine - 魔法陣エンジン)

 

このように、ここまでシンプルにした魔法陣の生成ルールにおいても、手順を見るだけで単純に図形の同定をすることは難しかったです。

基本図形の選定

ここまでで基本図形は四角でしたが、これだけでは自分が描きたい魔法陣を描くことができませんでした。

どうしても描きたい魔法陣の1つに六芒星がありました。これは正三角形を2つ組み合わせて作る事ができます。(六芒星という図形を足しても良いのですが、せっかくならプリミティブな図形のほうが良いと思いました)

f:id:inajob:20200822221149p:plain

(MagicalCircleEngine - 魔法陣エンジン)

そこで、基本図形に正三角形を追加するわけですが、、ここで問題が生じます。

原点を中心とする六芒星は正三角形を2つ180度回転させて配置することで描くことができますが、原点以外を中心とする六芒星をここまでのルールで描くことができません。

f:id:inajob:20200822221936p:plain

それは回転→移動→拡縮という操作しか許さないルールに対して、原点以外を中心とする六芒星の作成には移動→回転という操作が必要だからです。

 

ここで、今までのルールに例外を作るなども考えたのですが、プレイヤーが混乱するような操作体系しか思いつかず、断念し、素直に 180度反転した正三角形も基本図形に加えることにしました。

最後に縦線図形も基本図形に加えました。この図形はちょっと特殊で拡大縮小ができません。これは複数本の短い縦線と、拡大した縦線の同定を行うことが面倒という理由によるものです。

 

ということで最終的な基本図形は下記のように 四角、丸、上三角、下三角、縦棒 となりました。

f:id:inajob:20200822222435p:plain

ゲームとしての構成

ゲームのルールは、ここまでで固まり、ある程度面白いものになりそうだという感覚もつかめました。

ここからはゲームとしての構成をプログラミングしていきます。具体的には「タイトル画面」「ステージクリア画面」などを作っていきます。

今回は以下の画面を用意しました

  • タイトル画面
  • 操作方法説明付きREADY画面
  • ゲーム中画面
  • ステージクリア画面
  • 全面クリア画面

さらに、せっかくなのでいくつかのモードを用意しました。

普通に面を1面ずつ攻略していく「アーケードモード」、時間が計測されるタイムアタックモード」、見本がなく好きに魔法陣を描ける「プラクティスモード」です。

まぁ3つもモードがありますが、すべてアーケードモードの亜種です。

ステージの構築

ここからはお楽しみ!ステージの作成です。プラクティスモードを活用して良さそうな魔法陣を描いて、それをソースコードにします。ステージが多いとエディタなどを作ったりするのですが、今回は20以下のステージ数となりそうだったので、手で頑張ってステージを打ち込みました。

余談ですが、ちょっとメモ端末に魔法陣の例を書いていると、「魔導書」みたいでテンションが上がりました。

f:id:inajob:20200822222540p:plain

途中からデバッグ用に好きなステージから始められる機能を付けて、ステージの確認が簡単に出来るようにしました。(リリース時はコメントアウトしています。ソースをいじれば有効にできるので、気になる人はやってみてください。)

プラスアルファ: 日本語モード

ここまでで、ややROM容量に余裕があったので、「日本語化」というのに挑戦してみました。このゲームは、文字が少ないので容量さえ許せば、日本語化は比較的簡単です。

これを実現するために

github.com

こちらのライブラリを利用しています。このライブラリを使うことで8x8ドットのフォントとして有名な「美咲フォント」をArduboyから簡単に利用できます。

f:id:inajob:20200821221339p:plain

漢字を含むとさすがに容量が多くなりそうだったので、ひらがなとカタカナのみを利用しています。そういった容量削減の工夫もこのライブラリの機能として提供されているので、非常に使いやすかったです。

見た目のブラッシュアップ

だいたいステージができてきたところで、ブラッシュアップを始めました。タイトル画面にいい感じに魔法陣を表示したり、図形を切り替えるときに選択肢を表示するポップアップ画面を作ったりしました。

 

最後にAllClear画面を作りこんで、、完成!

 

と思いつつが無かったので、キー入力時に音が鳴るように、ちょちょいとコードを書き足して本当に完成!!

公開用のもろもろ

開発はGitで管理していたので、基本的にはGitHubにPushするだけでOK。 README.mdとLICENSEを配置して、、 と実はここでタイトルを決めました(はじめは MagicalCircleって名前にしていました)

 

タイトルは・・・ APPRENTICE WIZARD (みならいまほうつかい)』

正直「見習い」なんて単語初めて知りました;

 

で、ドキドキしながらArduboyのフォーラムに投稿!!!

community.arduboy.com

まとめと今後

ということで、無事『APPRENTICE WIZARD (みならいまほうつかい)』のv1.0が完成しました。ざっとここまでで10日くらい、1日1~2時間くらいの作業だったかな?

Arduboyはこのようなコンパクトなゲームを作るのにぴったりで、特に128×64で白黒しか表示できないディスプレイのおかげでゲームのコア要素に集中できる点が素晴らしいです。

今回うれしいことにフォーラムでたくさんのコメントをいただき、そこからGitHubにもいくつかのPRをいただき、もう少しこのゲームの開発は続きそうです。

このように面白いゲームができた場合は、ほかの方とのコラボレーションが楽しめるというのもコミュニティが活発なArduboyならではの楽しみです。

 

これを読んでいる皆さんも、まずはドット絵エディタで 128x64のゲーム画面を描くところから始めてみませんか?