この記事はスタックチャン(Stack-chan) Advent Calendar 2023の12月17日公開の記事となります。
はじめに: (自己紹介)
はい、2023年春に、robo8080さんのAIスタックチャンの流れを受けてデビュー、夏のお誕生会でもライトニングトークをさせてもらいました【まっく@まるちぷろとこる】と申します。私の自己紹介の内容と、スタックチャン2歳のお誕生日会で使ったライトニングトークの資料はこちらに置いておきますね。
- まっく@まるちぷろとこる
今回はクリスマスに向けてという事で、せっかくLEDでパリピなスタックチャンを作っていたのもありますので、クリスマスツリーにコラボできるような構成で、改めて調整しましたー。
スタックチャンを作ってお迎えしよう
皆さんは大体?robo8080さんのAIスタックチャンや、タカオさんのアバター等、M5Burnerで公開されているものをまず焼き焼きして…というのが多いかと思います。私のヤツもクリスマスイルミネーションを意識した形でファームウェアイメージをアップしましたので、気が向いたらスタックチャン魂を入れてみてください。
スタックチャンの手元へのお迎え方法は、おきもくさんの下記のXポストが参考になるものと思います。
オリジナルなエフェクトを作る!
RGB LEDテープは色々プログラムを使ってエフェクトを変更することができますが、私はArduinoでよく利用される【FastLED】をライブラリで利用しています。このエフェクトを外出しした拡張ライブラリとしてGitHubで公開されている【NeoPixelEffects】にオリジナルのエフェクトを追加しようと思い、がんばってソースコードを10月ぐらいから?見始めました。
そして、今回のLEDテープの構成はこんな感じです。私はスイッチサイエンスで購入しました。
ChatGPTさん(有償版)、すごいぞw
とはいっても、まっくさんは本格的にプログラムをやってきてはおらず、正直全くわかりません。そんな時はChatGPTさんに聞きまくりw
実は会社でも、積極的に生成AIを使って仕事の効率化を図るように指示があり、うちのチームはどういうシチュエーションでどれだけのレベルで質疑応答をしていけば良いか?という調査もしていたのもあって、実際にゼロベースからどこまで対応できるか?をやってみました。
- まずは【お願い】【目的】【情報】【ルール】【出力】等のプロンプトを明確に指定します
- 下記は追加エフェクトとしてボールが3つランダムに弾むエフェクトを書いてもらいます
#お願い
M5Stack CORE2 for AWS IoTを用いてLEDエフェクトをプログラムを追加したいです。
現在基本となるLEDエフェクトの拡張ライブラリのNeoPixelEffect.hとNeoPixelEffect.cppの中に新しいエフェクトを
追加することを想定しています。
新しいエフェクトは、ボールが弾むエフェクト『Bouncing Ball』エフェクトを作ってほしいです。
私にプログラムコードを教えてもらえますか?
#目的
クリスマスの時期が近いため、クリスマスツリーに取り付けしたいと思います。
LEDイルミネーションの光り方をコントロールしたいと思っています。
#情報
LEDは60個のNeoPixel互換LEDテープを使用します。
プログラムコードはArduinoIDEスケッチでC++で開発します。
利用環境はVSCodeとPlatformIOを使って開発します。
LEDエフェクトのライブラリはFastLEDを用います。
#ルール
必ず日本語で回答してください。
作成する『Bouncing Ball』エフェクトですが、同時に3つのボールがランダムに弾むようなエフェクトにしたいです。
Bouncing Ballエフェクトは下記のコードを参考にしたいです。
https://github.com/davepl/DavesGarageLEDSeries/tree/master/LED%20Episode%2007
こちらのsrc/main.cppとbounce.hを動きを真似したいです。
私のプログラムはこちらにアップロードしています。
https://github.com/ToshihiroMakuuchi/stackchan-bluetooth-simple
その内容は事前に解析してください。
このLEDエフェクトの拡張ライブラリである『NeoPixelEffects』のGitHubソースはこちらです。
https://github.com/nolanmoore/NeoPixelEffects
この中の下記2つのコード内に追加していきます。
NeoPixelEffect.h
NeoPixelEffect.cpp
#出力
出来上がったものをそのままArduinoIDEスケッチに反映させたいため、実装コードをそのまま提供してください。
こんな感じでChatGPTさんに投げ込みます。
後は生成されたコードを反映して、その時に出てきた結果と記載したコードを改めてChatGPTさんに教えて…を繰り返していきます。当然狙ったような動きにならない場合は、今どのような状態か?実際のコードをファイルもしくは直接貼り付けて理解してもらうのを続けていきます。当然人間ならば【ふざけんなっ!自分で調べろや、ボケがぁ!】と怒られるのかもしれませんが…いくら質問しても彼は怒りません。むしろ様々な角度から提案してくれます。これはとてもすばらしいです。なので、1日で仕上げるのではなく、じっくりとやり取りをする事で洗練されたコードをいただくことができるものと思います。
まとめ:
今回、追加エフェクトを5つ追加しました。詳しい内容とそれぞれのエフェクトの光り方の動画も用意しましたので、GitHubのリポジトリをご覧ください。
また操作は簡単です。全部で17種のエフェクトがありますが、順番で選べますのでスタックチャンの顔の左ほっぺ(真ん中左)をタップしてください。少し低い音が鳴ります。
また、一応ですがイメージな動画はこちらです。ワイのおうちのツリーは180㎝なのでLEDテープ2本を連結させて、1本(120弾)にして光らせてみました。そして、Bluetoothスピーカーでお歌も歌わせています。
いかがでしたか?スタックチャンのある暮らし。
AIスタックチャンでおしゃべりも楽しいですが、お飾りなお仕事スタックチャンもほっこりします!w
それではみなさま、良いクリスマスをー!
Appendix:
ChatGPTさんとの、エフェクト完成までのやり取りをした一部も貼っておきます。質疑応答の聞き方の参考にしてください。
NeoPixelEffect.hとNeoPixelEffect.cppをアップロードします。その内容に合わせて修正をしてください。
それでは次の段階として、updateBouncingEffect()内に書く必要のあるボールが跳ねるようなエフェクトの
ロジックを実装します。どのようなコードを記載したらよいか教えてください。
こちら、記載しましたがLEDの最初の部分が赤色で点灯しそのまま動きません。
何かおかしい部分を探してください。
private:に void updateBouncingEffect(); を追加しています。これではだめなのでしょうか?
それではNeoPixelEffect.cppのコードをアップロードします。このコードの内容を見て、おかしなところがないか?
確認および修正点を提案してください。
現在、internal_leds、pb_leds、pc_ledsと3つのポートを使ってLED出力していますが、PortBで利用するpb_ledsは
光り続けたままフリーズしました。
Port BやPort Cに対して同時の処理がフリーズせずに利用できるようにするのは可能でしょうか?
何かメモリ等の使い方がおかしいですか?跳ねる動作が終わると再起動しました。
この2つでBouncing Ballエフェクトを前回追加しましたが、切り替えたら処理はされるようですが、Switch文で
次のエフェクトへ切り替えができず、ボールが弾み終わったら、M5Stack CORE2が再起動してしまう状況になりました。
これを解消したいです。
この2つのコードで合わせてmain.cppとなります。記憶してください。
また、ボールが弾むエフェクトであるBouncing Ballエフェクトはcase17で利用しています。
画面をタップしてエフェクトを切り替えていき、このエフェクトまでいくと、2秒程度稼働しますが、
その後フリーズしM5Stack CORE2は再起動してしまうことがわかりました。
これではよくわからないので、提案してくれたコードをNeoPixelEffect.hとNeoPixelEffect.cppのどこに
入力するかを含め詳細を教えてください。
BOUNCINGエフェクトですが、ほんの少しですが速度は上がったように感じますが、全然滑らかではなく、
非常に遅いです。
提案ありがとうございます。
それでは浮動小数点の計算を最適化したり不要な更新を減らしたりする、具体的な新しいコードの提案を
教えてください。updateBouncingEffect()にすぐ記述を変更できるような方法で私に教えてください。
先ほどよりも非常にパフォーマンスが上がったように感じました。ありがとうございます。
main.cppではパラメータで色を指定できたはずです。現在はRed固定になっています。パラメータで色を
可変させられるように修正できますか?
狙ったように色を可変できました。次に、このBOUNCING処理を、最後の床まで全部達したら、また跳ねる動きを
繰り返したいです。どのようにすればよいでしょう?
今、稼働しているBOUNCINGエフェクトは下記のコードになります。
このコードの中に、ボールがほぼ停止したと見なされる場合、速度を再設定するコードを入れたいです。
どこにどのように入れればよいか具体的に提案してください。
うまくエフェクトが繰り返されません。3つのボールがほぼ床についた状態となったら、また最初からボールを
弾ませて、そのエフェクトを繰り返したいです。
うーん、うまくいきません。3つのボールが床に設置した後、改めて再度跳ねるエフェクトが始まりません。
だめです、うまくいきません。このコードを入れましたが、やはり床に全部設置した状況から改めてバウンドは
しません。何か根本的に違っているのでしょうか?初期化が効いていないのでしょうか?
提案してくれたコードに差し替えましたが、うまくBOUNCINGエフェクトは繰り返されませんでした。
main.cppの方で何か初期化や繰り返しエフェクトの阻害となるようなものがあるのでしょうか?
それでは、今教えてくれたことを考慮して、main.cppを分析、どうすればBOUNCINGエフェクトが選択されたときに
繰り返し動作継続するかを考えて、具体的にコードを提案してください。
それでは、今分析してくれたことを踏まえて、私に具体的にmain.cppの内容をどのように修正したら良いかを
教えてください。それに従いコードを修正します。
今記載してくれたコードはNeoPixelEffect.cppに書くのですか?main.cppに書くのですか?
main.cppの条件を変更せず、NeoPixelEffect.cppにコードを追加したいです。
そちらで具体的な修正コードを提案してくれませんか?
現在のNeoPixelEffect.cppのupdateBouncingEffect()の内容を下記にコードをアップロードします。
提案してくれた内容と合わせて、マージしたものを私に修正コードとして教えてください。
今回BOUNCINGエフェクトの最終的にうまくいったコードはこちらです。
より軽快な挙動になるよう、メモリやCPUなど動きを軽くする、もっと考慮する点はありますか?
これら考慮する点を踏まえ、今回のBOUNCINGエフェクトをより改良する点はありますか?私に具体的に変更すべきコードを教えてください。
今、COMET等で使われている_aoeの値が利用できると思います。
現在固定で、3つのボールが動かせるようになっていますが、これを_aoe変数を用いれるようにupdateBouncingEffect()を書き換えできますか?
再度NeoPixelEffect.hとNeoPixelEffect.cppのコードの内容をアップロードします。
今教えてくれたコードをどの部分にどう記載したらよいかを具体的に指示してください。
すみません。もう一度改めて検討しましょう。私の指示が悪かったようで、わからなくなってしまいました。
私は先ほどうまくいったBOUNCINGエフェクトのコードをmain.cppのswitch文の中でLED数を可変させ、
ボールの数を指定したいと思っています。他のエフェクトでLED数の定義をされる_pixaoeを使えば簡単にLED数を
指定できると思いました。そのupdateBouncingEffect()内で修正したいと思っています。
具体的なコードを私に教えてください。
うまくいきました。でもLEDを可変させる上限は4つが限界のようです。5つ以上指定するとフリーズ、
再起動してしまいます。
わかりました。まずはこのコードのまま他のパラメータに対応できるようにしましょう。
エフェクトの方向を示すものとして、FORWARDとREVERSEが他のNeoPixelEffectでは使われています。NeoPixelEffect.hのbool _direction;が利用されているようです。
これを考慮して、今回のBOUNCINGエフェクトのコードを修正できますか?
残念ながら、狙ったように動きません。
現在3つのLEDを設定していますが、2つのLEDが速度を変えて端まで行ったり来たりして、床に止まるようなエフェクトではなくなってしまいました。
どうもうまくいきません。一旦FORWARD、REVERSEの制御をやめます。
コードを元に戻します。