Maker Faire Tokyo 2023の作品の組み立て方:コウモリ
コウモリの組み立て方です。
最初の状態
点線に沿って、羽の部分を折ります。この向きだと山谷山谷山ですね。
点線に沿って、真中部分を折ります。ここが結構難しいです。横点線が山で、斜め線が谷ですね。
完成。上と下を持って、パタパタさせます。
#MFTokyo2023 #今作ってます
— Akiya Mizukoshi (@Akiyah) 2023年10月11日
カッティングプロッターでコウモリ作成中 pic.twitter.com/qMaajBTIbM
カッティングプロッター(スキャンカット ScanNCut CM300)を使った工作
私がカッティングプロッターを使ってどのように工作しているのか、メモとして書いておきます。
カッティングプロッター
スキャンカット ScanNCut CM300というカッティングプロッターを使っています。
カッティングプロッターの中では比較的リーズナブルなものだと思います。
スキャンする機能もあるのですが、私はスキャンはほとんど使っていなくて、作った設計図のとおりにカットさせることが多いです。
設計
GeoGebra 幾何
GeoGebra 幾何を使って設計することが多いです。
こんなふうに直線や円をたくさん使って図形を作ってから、
不要な点や線は非表示にしてカットする線(あるいは点線)だけを残します。非表示にしないとそれらがsvgファイルに入ってしまって、あとで都合が悪いんですよね。保存して、svgファイルをダウンロードします。
CodePen(JavaScript)
GeoGebra 幾何では作れないような複雑な曲線を使いたい場合などは、CodePenを使ってJavaScriptで設計することもあります。自由度は高いのですが、お手軽ではないため、最後の手段という感じですね。
例えばこんな設計をしました。三次元空間内で計算した座標を二次元の座標にマッピングして曲線を作ったりしていますね。
See the Pen N枚羽(楕円)のりしろ付き(ハロウィン) by mizukoshi akiya (@akiyah) on CodePen.
GeoGebra 幾何と同じように、svgファイルをアウトプットできるようにしています。
CanvasWorkspace
svgファイルをカッティングプロッター(スキャンカット ScanNCut CM300)に入れるために、brotherのCanvasWorkspaceというWebのサービスを使います。svgファイルをアップロードして、カットする線や点線を指定して、うまく並べて、完成したら保存してfcmという拡張子のファイルをダウンロードします。カッティングプロッター(スキャンカット ScanNCut CM300)には、USBケーブル経由でfcmファイルを入れます。
カッティング
あとはカットだけです。カッティングマットに紙やクリアファイルを貼って、fcmファイルを指定してカットします。私が使っているカッティングマットは弱粘着ですが、もう粘着は弱くなっていて頼れないので、素材の端をテープでとめて使っています。
線でカットするだけでなく、折れ線をつけるために点線でカットするときもあります。というか点線(折れ線)は多用しています。本来なら「刃の出し量」と「カット圧力」を調整して薄くカットすることで折れ線をつけたほうがいいのでしょうが、「刃の出し量」も「カット圧力」も、1回のカッティングでは設定変更できないので、点線を指定したほうが楽なのです。ただ、点線はうるさいのと時間がかかるので、その点は注意です。
以上が私のカッティングプロッターの基本的な使い方です。個別の工夫などもまだありますので、メイカーフェアに展示する商品ごとの解説記事もこのあと書いてみますね。
Maker Faire Tokyo 2023にベランダラボ(D-01-01)で出展します
今年もMaker Faire Tokyo 2023にベランダラボで出展します。D-01-01という場所で、退場口の近くですね。
今年は何をしようか悩んだのですが、カッティングプロッターを使った作品を展示することにしました。カッティングプロッターも持ち込んで、そこでカットも行います。(うるさかったり、準備が必要だったりするので、どれくらい動かせるのかはまだわかりません)
この写真に写っている作品は、ツル、菱形十二面体、カボチャ🎃、宝石💎、コウモリ🦇、ヘキサフレクサゴンです。それぞれの解説やカッティングプロッターの使い方なども、別エントリーで書いてみる予定です。
Seriaの6角形のミラー風タイルシールでお手軽に鏡の中のサッカーボール
gym-super-mario-brosのマリオのスピードを取得する
gym-super-mario-brosのマリオの座標だけでなくスピードを取得する方法がわかったのでメモします。
方針
スーパーマリオのメモリマップからx方向とy方向のスピードを探し出して、取得します。
メモリマップの参考
Super Mario Bros.:RAM map - Data Crystal
A Comprehensive Super Mario Bros. Disassembly · GitHub
実装
下記のように SuperMarioBrosEnv
クラスに x_speed
メソッドと y_speed
メソッドを実装します。
元々あった_x_positionメソッドや_y_positionメソッドをマネしています。
def x_speed(self): s = self.ram[0x57] return s if s < 0x80 else s - 0x100 def y_speed(self): s = self.ram[0x9f] return s if s < 0x80 else s - 0x100 SuperMarioBrosEnv.x_speed = x_speed SuperMarioBrosEnv.y_speed = y_speed
_x_position
メソッドや _y_position
メソッドと同様に _
で始まるメソッド名にしようかとも考えたのですが、そうするとWrapperクラスもメソッドを追加する手間が増えるので、 _
はつけませんでした。
今回のColab
Colabの中で動かすとコマ送りできるので研究がはかどります。
gym-super-mario-brosのジャンプの研究
前回からの続きです。 akiyah.hatenablog.com
今回は、gym-super-mario-brosのジャンプを研究します。
最大ジャンプのAボタンフレーム数
Aボタンを押すとジャンプするのですが、押している長さに応じて高さが変わるようです。 もちろんずーっと押し続けると最大ジャンプをするのですが、何フレーム押し続ければ最大ジャンプと同じジャンプをするのか調べてみました。
Aボタンを押し続けるフレーム数を何パターンか調べたところ、25フレームが最大ジャンプであることがわかりました。それ以上押しても同じ高さですし、24フレームだと少しだけ滞空時間が短いようです。
連続ジャンプ
試してわかったのですが、ずーっとAボタンを押し続けても一回しかジャンプしてくれません。Aボタンを離してから再び押すと次のジャンプをしてくれるようです。(ファミコンのスーパーマリオはこうだったのか、覚えていません。)
調べてみると、最大ジャンプの場合、着地する45フレーム目の2フレーム前である43フレーム目でAボタンが離れていて、その次のフレームからAボタンを押し続けると、連続ジャンプをしてくれるようです。 ジャンプしてから落下中にAボタンを離しておいて、着地直前にAボタンを押せば、隙間なく連続でジャンプしてくれるのですね。(なかなかシビアです)
今回のColab
アニメーションgifと違って、Colabの中だと1フレームずつ動かすことができるので、研究する時はこちらがオススメです。
gym-super-mario-bros 1-1を1歩ずつ5歩先のrewardを計算してクリアする
前回の続きです。 akiyah.hatenablog.com
backupした状態までresetで戻れるようになったので、それを使ってマリオの1-1をクリアしてみました。
行動は「走る(["right", "B"])」か「走りながらジャンプ(["right", "B", "A"])」の2通りです。5歩先までマリオを進めて、その時のrewardを記録し、resetして戻ります。25=32パターンのうちで一番大きいrewardに繋がる1歩目を採用して進み、そこでbackupします。
この手順をゴールするかゲームオーバーまで繰り返します。20分ほどの計算で、見事ゴールしてくれました!
「走る」と「走りながらジャンプ」のうち、「走る」の方を優先しているロジックになっているからか、低いジャンプで進んでいることがわかりますね。
Google Colaboratoryも貼っておきます。 colab.research.google.com
ちなみに、1歩=4フレームです。1フレームごとに操作できるので、1フレームごとに次の行動を計算してもいいのですが、計算が多くなるので1歩=4フレームくらいが良さそうです。
クリアした後にソースコードを少し変更したりして試してみたのですが、どうもこのクリアは偶然らしくて、ちょっといじるとゴールできなかったりします。どう操作しても5歩先でゲームオーバーになってしまうような状況におちいってしまうことがあるようです。ジャンプしてしまって10歩先くらいでガケに落ちるような。(行動が「走る」か「走りながらジャンプ」だけでやっているのでブレーキとかかけられないんですよね)
5歩先ではなく10歩先、あるいはもっと先までを計算対象にしたらいいのでしょうが、そうすると計算量が爆発的に増えてしまうので、何かいい方法がないか考えてみようと思っています。