【ポケモン剣盾】マイコンを使って5番道路の預かり屋さんで自動孵化を実現
こんばんは。TNハルカの夫です。
普段はバンギラス杯のポスターを作っています。
さて,このたび妻TNハルカがマイコンを使ったポケモンの自動孵化に挑戦しました。
もともと,次に紹介する記事のとおりにハシノマはらっぱでの自動孵化を実現させる計画だったのですが,一部うまくいかないところがあったため,夫婦で協力して修正・補足しながら5番道路の預かり屋さんで実現に至ったものです。
他の方の参考となるよう記事にすることを勧められたので,noteのアカウントを借りて書き残すことにしました。
0. はじめに
今回の自動孵化の実現にあたっては,こちらのブログ記事を参考にしました。
そのため,上記のブログ記事と両方を参照しながら進めてもらえればと思います。(この記事を見ればわかることの一部は省略しています。)
また,プログラムの書き換えに際しては元のプログラムを書かれた方の記事も参考にさせていただきました。元プログラムの開発も含めて,お礼を申し上げます。
1. 用意したもの
そもそも「マイコンって何?」というところからのスタートでしたが,「プログラムされたとおりにコントローラの操作信号を出力し続ける機械」のようです。何秒後にどのボタンを押し,次のどのボタンを何秒間押し続けて…というあらかじめ決めておいた操作を自動で続けてくれる一方,画面内の状況を判断して操作するような機能はありません。
今回は上記で紹介したブログ記事に沿って,こちらの商品を購入しました。
ちなみに,同梱されているトゲトゲのパーツは使いません。
ケーブルについては,PCとの接続・ドックとの接続にはTypeAオス-MicroBオスのUSBケーブル,Switch本体との接続にはTypeCオス-MicroBオスのUSBケーブルが必要です。
それぞれを買い揃えても良いのですが,たまたまTypeCメス-microBオスのUSB変換アダプタを持っていたので,まずこれを使うことにしました。
このアダプタの良いところは,ケーブルの抜き差し時に変換アダプタを持ってその先だけ抜き差しすればいいので,マイコン基板を壊してしまう危険が少ないことです。(MicroB USBケーブルの抜き差しを繰り返すと端子を折ってしまいそうで心配…。)
そのため,PCとアダプタの接続やドックとアダプタの接続にはSwitchプロコンに付属していたUSB充電ケーブルが使えました。また,Switch本体とアダプタとの接続にはAmazonで安かった下記のものを使用しました。短くて邪魔にならないのでいい感じです。
2. PCの設定(1) Arduino IDEのインストール
まず,PCにArduino IDEをインストールします。
ダウンロードは以下から。
しかし,ここで最初につまづきました。
使ったPCはWindows 10でしたが,ダウンロードするときに「Windows App」を選んでしまうと,次に出てくる「ID書き換え」ができません。(Microsoft StoreからダウンロードしたアプリケーションだとC:\Program Files内にフォルダが生成されないようです。)
そこで,アンインストールしてから改めて「Windows Installer for Windows 7 and UP」を選択するとうまくいきました。(使ったPCはWindows 10でしたが,7 "以上" なので大丈夫だったようです。ややこしい…。)
3. PCの設定(2) ID書き換え
次にIDの書き換えです。USBデバイスの個体を識別するためのIDを書き換える必要があるようです。
ソフトウェアのインストールがうまく済んでいれば,
C:\Program Files (x86)\Arduino\hardware\arduino\avr
というフォルダができているはずです。
この中の「boards.txt」を(できればメモ帳ではなくVisual Studio Codeなどのテキストエディタで)開き,
leonardo.vid.0=######
leonardo.pid.0=######
leonardo.vid.1=######
leonardo.pid.1=######
leonardo.vid.2=######
leonardo.pid.2=######
leonardo.vid.3=######
leonardo.pid.3=######
leonardo.vid.4=######
leonardo.pid.4=######
[…]
leonardo.build.vid=######
leonardo.build.pid=######
となっている(######は数字)ところを,
leonardo.vid.0=0x0f0d
leonardo.pid.0=0x0092
leonardo.vid.1=0x0f0d
leonardo.pid.1=0x0092
leonardo.vid.2=0x0f0d
leonardo.pid.2=0x0092
leonardo.vid.3=0x0f0d
leonardo.pid.3=0x0092
leonardo.vid.4=0x0f0d
leonardo.pid.4=0x0092
[…]
leonardo.build.vid=0x0f0d
leonardo.build.pid=0x0092
と書き換えます。0x0f0dと0x0092です。
このテキストファイルは非常に長く,この部分以外にも似たような箇所が何度も出てきますが,leonardoで始まるこの部分だけで大丈夫でした。
(今回使うマイコンはArduino Leonardoという商品に互換性のある別の商品なので,個体を認識させるためのIDを書き換える必要がある,ということのようです。)
4. PCの設定(3) プログラムの入手
次にSwitchを操作するためのプログラムのファイルが揃ったライブラリをダウンロードします(改めて開発者の方に感謝)。下記のページの「Clone or download」からファイルをダウンロードし,解凍します。
※読者の方からご指摘をいただきました。現在は「Clone or download」ボタンではなく「Code」ボタンに変わっているようです。「Code」ボタンを押して出てくるメニュー内の「Download ZIP」からダウンロードできます。(7月19日追記)
ドキュメントの中に「Arduino」というフォルダができているはずなので,解凍したファイルをその中の「libraries」というフォルダの中に置きます。
次の作業で開くファイル「auto_hatching.ino」は,この中にあります。
…\libraries\examples\pokemon\auto_hatching\auto_hatching.ino
5. スケッチを準備してマイコンに書き込む
マイコンに書き込むプログラムのことをスケッチというようです。
紹介している記事に従って操作し,手順に沿ってボードにスケッチを書き込みます。幸いにもここでエラーは出ませんでした。
6. しかし失敗
しかし,その先まで進めてSwitchのマイコンを繋いだのですが,うまくいきませんでした。
Switchに触れていないのに自動で操作が進むことに感動するところまでは良かったのですが,
1. 「預かり屋さんの方をむく→預かり屋さんのところに向かう」とき,歩く方向の角度が若干ずれていて,話しかけることができない。
2. ハシノマはらっぱをぐるぐる回っている間に,草むらから飛び出してきた野生ポケモンとエンカウントしてしまう。
という問題が生じてしまったのです。
1つ目はボタンを押す秒数の微調整でなんとかなるかな,とも思ったのですが,2つ目の野生ポケモンとのエンカウントはどうすることもできませんでした。草むらに突っ込むことがないように走り回る位置を調整する仕様にはなっていたのですが,何周もしているうちに出てきた野生ポケモンとぶつかってしまうことは避けられません。(アップデートとかで野生のポケモンの挙動が変わったのでしょうか?)
いろいろな記事やコメントをあたってみたのですが,同じような問題にあたっている方は見つからず,行き詰まってしまいました。
7. ハシノマはらっぱから5番道路へ
妻TNハルカ曰く,
「5番道路の預かり屋さんなら,野生ポケモンにぶつかることはないし,長い橋を一直線に走り続けるだけでいいのに…。」
しかし,5番道路の預かり屋さんでの自動孵化については情報がなかなか得られず,買ったものと同じマイコンを使って実装している方は見つけられません。ないなら自分で作るしかないということで,このソースコードを元にして書き換えてみることにしました。
ハシノマはらっぱでは,ハシノマはらっぱにいる状態でタウンマップを開き,そのまま空飛ぶタクシーに乗れば,預かり屋さんの前に戻ることができます。
しかし5番道路では,同じ動作をすると5番道路の中ほどにあるテントの前に飛んでしまいます。タウンマップを開いて,その少し右上にある預かり屋さんの前をカーソルで選択してから,空飛ぶタクシーに乗らなければなりません。このちょっとだけジョイスティックを倒す動作を追加します。
適切な位置に
tiltJoystick(20, -20, 0, 0, 200);
という追加するだけです。1行が1操作に対応しているので,追加する位置を間違えないよう気をつけてください。
// 空飛ぶタクシーでハシノマはらっぱに移動
void moveToInitialPlayerPosition(){
pushButton(Button::X, 1000);
pushHatButtonContinuous(Hat::LEFT_UP, 1000);
pushButton(Button::A, 2500);
tiltJoystick(20, -20, 0, 0, 200); /*←この行を追加します。*/
pushButton(Button::A, 1500, 2);
delay(2000);
}
なお「//」で始まる行や「/*」〜「*/」で挟まれた部分はプログラムの動作には影響しないので,気にならなければ書き換えなくて大丈夫です。
次に,空飛ぶタクシーで初期位置に戻ってから預かり屋さんに話しかけるまでの動きも変えねばなりません。「振り返る→直進」だったものを,「左に行く→後ろを向く」に変えます。
// 初期位置から育て屋さんに移動し卵を受け取る
void getEggFromBreeder(){
// 初期位置(ハシノマはらっぱ)から育て屋さんのところまで移動
pushButton(Button::PLUS, 1000);
tiltJoystick(-100, 0, 0, 0, 500); /*この行をカッコ内の数字を変えました。*/
tiltJoystick(0, -100, 0, 0, 500); /*この行をカッコ内の数字を変えました。*/
pushButton(Button::PLUS, 1000);
// 育て屋さんから卵をもらう
pushButton(Button::A, 1000, 4);
pushButton(Button::B, 500, 10);
}
ボタンを押す時間は調整してあるはずなので大丈夫ですが,もし左に行き過ぎてしまうor届かない場合は書き換えた1行目の最後の500を増やしたり減らしたりして何度か試してみてください。500というのは500ミリ秒(0.5秒)間ジョイスティックを倒すという意味です。
最後が難関のぐるぐる周りです。5番道路にはジョイスティックを一方向に倒しっぱなしで永遠にぐるぐる回り続けられるスペースがないので,道路を直進で往復する作戦をとるしかありません。測ってみたところ預かり屋さん前から右に17〜18秒ほどで突き当たったので,切りのいい15秒で折り返すことにします。
もとのプログラムの
// 初期位置(ハシノマはらっぱ)からぐるぐる走り回る
void runAround(int run_time_sec){
// 野生ポケモンとのエンカウントを避けるため初期位置から少し移動する
tiltJoystick(100, 0, 0, 0, 600);
// delayの秒数がintの最大値を越えないように30秒ごとに実行する
for(int i=0; i<run_time_sec/30; i++){
tiltJoystick(100, 100, -100, -100, 30000);
}
tiltJoystick(100, 100, -100, -100, (run_time_sec%30)*1000);
}
の部分を以下のとおり書き換えてください。
// 預かり屋さんの位置からスタートして5番道路を往復する
void runAround(int run_time_sec){
// 通行人とぶつかることを避けるため道路の中央位置に移動する
tiltJoystick(0, 100, 0, 0, 100);
// 15秒右へ行く→振り返る→15秒左へ行く→振り返るを繰り返す
for(int i=0; i<run_time_sec/30; i++){
tiltJoystick(100, 0, 0, 0, 15000);
pushButton(Button::PLUS, 500);
tiltJoystick(-100, 0, 0, 0, 500);
pushButton(Button::PLUS, 500);
tiltJoystick(-100, 0, 0, 0, 15000);
pushButton(Button::PLUS, 500);
tiltJoystick(100, 0, 0, 0, 500);
pushButton(Button::PLUS, 500);
}
// 最後に30秒に満たない端数分走る
if(15 < run_time_sec%30){
tiltJoystick(100, 0, 0, 0, 15000);
pushButton(Button::PLUS, 500);
tiltJoystick(-100, 0, 0, 0, 500);
pushButton(Button::PLUS, 500);
tiltJoystick(-100, 0, 0, 0, ((run_time_sec%30)*1000)-15000);
} else {
tiltJoystick(100, 0, 0, 0, (run_time_sec%30)*1000);
}
}
これで,完成しました。自転車に乗ったまま振り返ると走行位置がずれて通行人にぶつかってしまうので,いったん降りて振り返ってから再度自転車に乗るようにしました。
ここに書いた通りに書き換えられているかを確認したら,最後にプログラムの一番最初にある
const int TIME_TO_HATCHING_SEC = ###;
の秒数を、孵化させるタマゴが孵化に要する自転車走行秒数+10秒ほどの秒数にします。
ファイルを保存し,マイコンにスケッチを書き込みましょう。
8. Switchの設定
ハシノマはらっぱではなく,5番道路にいること。
それ以外の条件は同じです。
・5番道路で自転車に乗っていること
・5番道路の預かり屋さんに孵化対象のポケモンを預けていること
・手持ちポケモンが「ほのおのからだ」持ちの1匹だけであること
・ Xボタンを押したときに「タウンマップ」が一番左上にあり,「ポケモン」がその右にあること
・現在のボックス,そしてその次以降のボックスもなるべく空であること
9. ついに自動孵化に成功
まずはSwitch本体とマイコンを直接接続してみましょう。うまく行っていれば,勝手に操作が始まるはずです。
1. 空飛ぶタクシーで5番道路の預かり屋さんの前に移動
2. 20秒走る(最初のタマゴを産ませるため)
3. 空飛ぶタクシーで初期位置に戻る
4. 預かり屋さんに話しかけてタマゴを受け取る
5. 指定秒数走り続ける
6. 卵が孵る
7. 3.から6.を繰り返す
8. 5回ごとに手持ちの産まれた5匹をボックスに移す
9. 30回ごとに次のボックスへ移動する
10. これを無限に繰り返す
タマゴが孵るとき「おや…」のまましばらく進みませんが,安心してください。タマゴが孵っても,走り続けるはずだった最初の指定秒数は待ち続けてから次の操作に移ります。
孵化のスピードは,指定秒数+1分くらいで1回孵る感じです。75秒に指定した場合,1ボックス埋めるのに1時間強かかるペースでした。
10. ドックで一晩中自動孵化
無事に自動孵化が実現しましたが,Switch本体とマイコンを直接つないで自動孵化をし続けると,途中で本体のバッテリーが切れてしまいます。(この場合もスリープ状態に入るだけなので,充電して再起動すればそれまでの孵化は無駄にはなりませんでした。)
夜の間や仕事中に自動孵化を進めておくには,ドックで給電しながら操作した方が良さそうです。
1. ドックの外側(内側の電源端子の横はダメ)のUSB端子にSwitchプロコンに付属のUSB充電ケーブルでマイコンを接続する
2. 初期状態(5番道路で自転車に乗っている)のままスリープさせずにSwitch本体をドックに格納する
という手順でドックに格納すれば,画面は消えてしまいますがバックグラウンドで処理が続いてくれました。(この方法だと,裏でテレビ画面に出力する処理をするので操作のタイミングがずれる,という指摘を見かけましたが,今回のプログラムを動かすにあたっては支障はありませんでした。今後留意しておきたいと思います。)
この方法で二晩ぶんほど放置した結果,無事に色違いのメッソンが産まれていました!
11. その他
ずっと動かし続け,次のボックスが空でなくなった場合にどうなるかまでは試せていませんが,おそらく手持ちのポケモンを移すことができず,預かり屋さんから受け取った卵がボックスの空き位置に入り続ける(その後も1個受け取るごとに走り続けるが当然孵化はしない),と予想されます。
とはいえ,しっかりと空のボックスを並べておけば,一晩放っておいてもそんなことは起きないようですが。
もしマイコンがおかしな挙動をしたら,すぐにマイコンを抜けば大丈夫です。プログラムにおかしなところがないか確認し,修正したものをマイコンに書き込み直して再挑戦しましょう。
また,マイコンは一度抜くとリセットされる(次に接続したときはまた「1. 空飛ぶタクシーで5番道路の預かり屋さんの前に移動」から始まる)ようなので,一時中断するために抜いたり,誤って抜けてしまったりした場合,もう一度初期状態(手持ちを1匹のみにして現在のボックスを空にする)に戻してから再開してください。
12. まとめ
長くなってしまいましたが,以上です。
最初はマイコンというとハードルが高く感じていましたが,ボタン操作の組み合わせで作業が自動化できるというのは非常に便利ですね。
マイコンを試してみようかとお考えの方や,試してみたが同じように行き詰まっていた方など,どなたかの参考になれば幸いです。
(環境によってはうまく動作しない場合などもないとは限りませんので,お試しになる際は,諸々,自己責任でお願いします。)
孵化作業をしてくれる ばん
この記事が気に入ったらサポートをしてみませんか?