メインコンテンツへスキップ
見出し画像

VSCodeとMicroPico拡張機能でソフトウェア(SHINDO ROBOT)をカスタマイズ

    この記事では、オリジナルロボット「SHINDO ROBOT」のソフトウェアカスタマイズを例に、VSCodeとMicroPico拡張機能を使ってカスタマイズする方法を紹介します。

    必要なもの

    今回紹介する例では、上記3点をお手元に用意してください。

    前準備:VSCodeのインストール

    まずは、ソフトウェアをカスタマイズする前準備として下記リンクからVSCodeをインストールします。
    ※既にVSCodeをインストール済みの方は、この手順をスキップして大丈夫です。また、今回はWindows OSを搭載しているPCを前提に準備手順を紹介します。Macなどを使っている方は、適宜Windowsのアイコンやボタンについては、Macのアイコンやボタンに置き換えてお読みください。

    「Download for Windows」というボタンをクリックしてインストーラをダウンロード後、ファイルを開きます。

    画像
    インストーラ画面

    ファイルを開くとこのようなセットアップ画面が開くので、「同意する」にチェックを入れ、「次へ」をクリックします。

    画像
    追加タスクの選択

    続いて、追加タスクの選択では必要な項目にチェックを入れ、「次へ」をクリックします。私の場合は、上図のようなかたちでチェックを入れてセットアップしていて、「Codeで開く」アクションとかはよく右クリックで表示されるメニューで使用しているので選択している形です。

    画像
    インストール準備完了

    上図のような画面になったら、「インストール」をクリックしてインストールします。

    画像
    インストール完了

    インストールが完了すると、上のような画面になりインストールが完了したことが分かります。以上でVSCodeの準備完了です。

    MicroPico拡張機能をインストール

    VSCodeをインストール後、VSCodeを起動してMicroPicoをインストールします。MicroPicoのインストールは簡単で下図のようにVSCodeの左メニューにある拡張アイコンのボタンをクリック後、「micropico」と検索して「インストール」をクリックすることでインストールできます。

    画像
    MicoPicoを拡張機能メニューから検索
    画像
    インストール後の画面

    以上で、ソフトウェアをカスタマイズする準備完了です。

    カスタマイズするソフトウェア(SHINDO ROBOT)をGitHubからクローン

    カスタマイズするソフトウェアについて、今回はSHINDO ROBOTのソフトウェアを用います。SHINDO ROBOTのソフトウェアは、下記リンクにあるようにGitHubで公開しているのでこれを例に説明します。

    前準備2:Git&TortoiseGitのインストール

    GitHubからコードをクローンするには、Gitのインストールが必要です。Gitのインストールがまだの方は、こちらの手順も参考にインストールしてください。

    上記リンクから「Git for Windows/x64 Setup.」をクリックし、Gitのインストーラをダウンロードしてセットアップします。
    インストーラが起動後は、選択されているチェックボックスをデフォルトの状態から変更せずにどんどん「Next」をクリックしていって大丈夫です。

    画像
    インストール完了後の画面

    インストール完了後、上のような画面になればインストール完了です。
    続いて、TortoiseGitというソフトウェアをインストールします。このソフトウェアをインストールしておくと、エクスプローラのフォルダ上で右クリックから簡単にGitHubのコードをクローン出来るのでこちらもインストールしておくと便利です。

    上記リンクから、「for 64-bit Windows」をクリックしてインストーラをダウンロードしてインストールしていきます。
    ダウンロードしたインストーラのファイルをクリックして起動後、「Next」をクリックします。

    画像
    インストーラ画面

    その次と次に表示される画面でも特に何もいじらずそのまま「Next」をクリックします。

    画像
    インストール完了

    そうすると、上のような画面になりインストールが完了します。
    以上でGitHubからクローンする前準備が完了です。

    GitHubからコード(ソフトウェア)をクローンする

    画像
    クローンするURLを取得

    「<>Code」をクリックし、HTTPSのURLで記載されているURL「https://github.com/kou1-310/shindo-robot.git」を右横にあるコピーするためのアイコンをクリックしてコピーします。

    画像
    エクスプローラのフォルダ上で右クリックしてCloneする

    コピーした後、エクスプローラの画面を開き上図のように適当なフォルダを作成後、そのフォルダの白い部分のどこかを右クリックし「Clone」をクリックします。

    画像
    Cloneの確認画面

    その後、上のような画面が表示されるので、URLの入力欄に先ほどコピーしたURLをコピペして「OK」をクリックします。

    画像
    クローン完了

    そうすると上のようにエクスプローラ上にフォルダが現れ、クローンが完了した画面が表示されると思います。これでSHINDO ROBOTのソフトウェアコードのクローンは完了です。

    クローンしたソフトウェアをカスタマイズ

    これでようやくクローンしたソフトウェアをカスタマイズできるようになりました。続いてソフトウェアをカスタマイズするには、前準備でインストールしたVSCodeを起動してクローンしたフォルダ「shindo-robot」を開いていきます。
    VSCodeの画面を開いて、左上の「ファイル」をクリックし「フォルダーを開く」をクリック後、下図のように先ほどクローンした「shindo-robot」のフォルダを選択して「フォルダーを選択します。」

    画像
    クローンしたフォルダを選択

    フォルダを選択後、下図のような画面が開けばカスタマイズする準備はOKです。

    画像
    カスタマイズするフォルダをVSCodeで開いた状態

    最初右下に「No COM device found. ~~」というエラーメッセージがでていますが、これは表示されていたとしても問題ありません。SHINDO ROBOTにUSBケーブルで接続していないと、このようにこのプロジェクトで書き込む先のマイコンが見つからなかったという意味合いのものなので、SHINDO ROBOTと接続していない場合は無視してしまって大丈夫です。

    画像
    SHINDO ROBOTと接続しているときは上図のようにターミナルが開く状態に

    SHINDO ROBOTの起動音をカスタマイズ

    カスタマイズ例としてSHINDO ROBOTの起動音をカスタマイズしようと思います。SHINDO ROBOTのファイル構成については、README.md内を確認いただければと思いますが、今回カスタマイズするのはこの中の"sound_controller.py"(サウンド制御のファイル)です。

    起動音はこのsound_controller.pyのplay_random_boot_sound関数内にある関数を使って再生しています。デフォルトでは4種類の起動サウンドが登録されていますが、これを10種類に増やしてみようと思います。

    ただ、起動サウンドを一々圧電スピーカーの周波数や何秒流すのかというのを手動で確認して好みの音の起動サウンドを作るというのは結構大変なため、今回はChatGPTに聞いて起動サウンドを増やしてもらおうと思います。

    ChatGPTでは、sound_controller.pyのコードをコピペしてその下に、下記のようなプロンプトを投げてみました。

    ーーー
    <中略>
    # ランダムにスリープ light_duration = random.randint(2, 10) self.light.random_light_show(light_duration) print("=== Random Boot Sound Ended ===")
    ーーー
    上記ロボットの起動サウンドを記述したmicropythonコードになる。今はランダムで4種類しか起動サウンドがないため、これを参考に10種類まで起動サウンドを増やしてほしい。また、起動サウンドについては、かわいいロボットらしさを出したサウンドとかっこいいロボットらしさを出したサウンドを追加して。

    プロンプトを投げて返ってきた回答を基に改良したsound_controller.pyの中身がこちら。

    # 音制御
    import time
    from time import sleep, sleep_ms
    import random
    from config import *
    
    class SoundController:
        def __init__(self, hardware, light_controller):
            self.hw = hardware
            self.light = light_controller
        
        def play_race_countdown(self):
            """レースゲームのカウントダウン「3、2、1」のピー音を再生する"""
            print("Play Race countdown「3、2、1」")
            
            # カウントダウン音の定義: (周波数, 持続時間ms)のタプルのリスト
            countdown = [
                (550, 500), (0, 80),      # 「3」+ 間隔
                (550, 500), (0, 80),      # 「2」+ 間隔
                (550, 500), (0, 80),      # 「1」+ 間隔
                (1100, 500)               # 「スタート」の高音ピー
            ]
            
            # LED色を変化させながらカウントダウン
            colors = [GREEN, GREEN, YELLOW, YELLOW, RED, RED, BLUE]
            
            for i, (freq, duration) in enumerate(countdown):
                if freq > 0:  # 休符でない場合はLEDを点灯
                    self.hw.led_set(colors[i % len(colors)])
                    print(f"Countdown: {'3' if i == 0 else '2' if i == 2 else '1' if i == 4 else 'GO!'}")
                else:
                    self.hw.led_off()
                    
                self.hw.play_tone(freq, duration)
            
            self.hw.led_off()
        
        def play_random_melody(self):
            """ランダムなメロディーを再生する"""
            melody_length = random.randint(3, 6)
            
            for _ in range(melody_length):
                freq = random.choice(NOTES)
                duration = random.randint(200, 500)
                self.hw.play_tone(freq, duration)
                time.sleep_ms(50)
        
        def play_random_beep(self):
            """ランダムなビープ音を再生する"""
            freq = random.randint(200, 2000)
            duration = random.randint(100, 300)
            self.hw.play_tone(freq, duration)
    
    
        def tone(self, freq, duration_ms):
            self.hw.buzzer.freq(freq)
            self.hw.buzzer.duty_u16(30000)  # 中程度の音量
            sleep_ms(duration_ms)
            self.hw.buzzer.duty_u16(0)
            sleep_ms(50)
    
        def boot_sound(self):
            # シンプルな未来的な起動音のイメージ
            self.tone(880, 100)    # 高めのピッ
            self.tone(660, 100)
            sleep(0.1)
            self.tone(880, 100)
            self.tone(660, 100)
            sleep(0.2)
    
            # ビープ連打
            for _ in range(4):
                self.tone(1200, 60)
                sleep(0.05)
    
            # ブゥーン(上昇する周波数)
            for f in range(400, 1600, 20):
                self.hw.buzzer.freq(f)
                self.hw.buzzer.duty_u16(30000)
                sleep(0.01)
            self.hw.buzzer.duty_u16(0)
    
        def sweep(self, start, end, step, speed):
            for f in range(start, end, step):
                self.hw.buzzer.freq(f)
                self.hw.buzzer.duty_u16(30000)
                sleep(speed)
            self.hw.buzzer.duty_u16(0)
            sleep(0.1)
    
        def robot_boot_sound(self):
            # ガチャン的な短い重め音
            self.tone(300, 100)
            self.tone(200, 80)
    
            # ウィーン(低周波→高周波)
            self.sweep(400, 1600, 30, 0.01)
    
            # 一瞬の静寂
            sleep(0.2)
    
            # ピピピ(起動チェックっぽい)
            for freq in [1000, 1200, 1500]:
                self.tone(freq, 80)
    
            # 起動完了ビープ(上昇→下降)
            self.sweep(800, 1600, 40, 0.005)
            self.sweep(1600, 800, -40, 0.005)
    
    
        def hardcore_robot_boot_sound(self):
            # メカニカルな「ガキン!ガガガ...ウィーン」
            self.tone(150, 120)    # 金属音的
            self.tone(180, 100)
            sleep(0.1)
    
            # 動力起動
            self.sweep(300, 800, 10, 0.01)
    
            # ガガガとチェック音(重くて無骨)
            for _ in range(3):
                self.tone(250, 60)
                sleep(0.1)
            
            # ゆっくり立ち上がるような重い上昇音
            self.sweep(600, 1400, 5, 0.02)
    
            self.hw.buzzer.duty_u16(0)
    
        def anime_ai_robot_boot_sound(self):
            # 軽快な起動音
            self.tone(1000, 80)
            self.tone(1300, 80)
            self.tone(1600, 80)
            sleep(0.1)
    
            # ピピピ(診断中)
            for _ in range(2):
                self.tone(1800, 60)
                sleep(0.05)
                self.tone(1400, 60)
                sleep(0.05)
    
            # 起動完了サウンド(下降)
            self.sweep(2000, 1000, -30, 0.005)
    
            # 最後にピロロンと鳴く感じ
            self.tone(1200, 60)
            self.tone(1500, 120)
    
            self.hw.buzzer.duty_u16(0)
        
        def cute_robot_boot_sound(self):
            # キュイーンと可愛い起動
            self.tone(1500, 80)
            self.tone(1800, 100)
            sleep(0.1)
    
            # ピコピコ音
            for freq in [1200, 1400, 1600, 1800]:
                self.tone(freq, 60)
                sleep(0.05)
    
            # 最後に「にゃー」っぽい下降音
            self.sweep(1800, 1000, -50, 0.01)
    
        def playful_boot_sound(self):
            # 遊び心あるランダム音
            for _ in range(3):
                self.tone(random.randint(800, 1600), 80)
                sleep(0.05)
    
            # ピロピロ音
            self.sweep(1000, 2000, 50, 0.005)
            self.sweep(2000, 1200, -40, 0.005)
    
        def hero_robot_boot_sound(self):
            # 勇ましい起動
            self.tone(500, 120)
            self.tone(700, 100)
            self.tone(900, 100)
            sleep(0.1)
    
            # 上昇するファンファーレっぽい音
            self.sweep(400, 1600, 40, 0.01)
            self.tone(2000, 200)
    
        def stealth_robot_boot_sound(self):
            # 静かな起動(低音主体)
            self.tone(200, 150)
            sleep(0.1)
            self.tone(250, 150)
            sleep(0.2)
    
            # フワーっと上昇
            self.sweep(300, 1200, 20, 0.02)
    
            # 最後に短い確認音
            self.tone(800, 80)
    
        def cyberpunk_robot_boot_sound(self):
            # サイバーなビープ連打
            for _ in range(3):
                self.tone(1600, 60)
                self.tone(800, 60)
                sleep(0.05)
    
            # 電子音っぽいジリジリ音
            for f in range(1000, 2000, 100):
                self.tone(f, 30)
    
            # 終了ビープ
            self.tone(2200, 120)
    
        def majestic_robot_boot_sound(self):
            # 威厳のある低音から始まる
            self.tone(300, 200)
            self.tone(400, 200)
            self.tone(500, 200)
    
            # ゆっくり上昇
            self.sweep(500, 1800, 30, 0.015)
    
            # 勝利ファンファーレ風
            for f in [1500, 1800, 2000]:
                self.tone(f, 120)
    
        def play_random_boot_sound(self):
            """ランダムで起動サウンド(4種類のうちいずれか)を再生"""
            boot_sounds = [
                self.boot_sound,
                self.robot_boot_sound,
                self.hardcore_robot_boot_sound,
                self.anime_ai_robot_boot_sound,
                self.cute_robot_boot_sound,
                self.playful_boot_sound,
                self.hero_robot_boot_sound,
                self.stealth_robot_boot_sound,
                self.cyberpunk_robot_boot_sound,
                self.majestic_robot_boot_sound
            ]
            
            selected = random.choice(boot_sounds)
            print(f"Playing boot sound: {selected.__name__}")
            selected()
    
        def play_random_boot_sound_loop(self):
            """ランダムで起動サウンド(4種類のうちいずれか)をループ再生"""
            boot_sounds = [
                self.boot_sound,
                self.robot_boot_sound,
                self.hardcore_robot_boot_sound,
                self.anime_ai_robot_boot_sound
            ]
            
            loop_count = 0
            
            while loop_count < MAX_BOOT_SOUND_LOOPS:
                loop_count += 1
                print(f"Random Boot Sound Loop {loop_count}/{MAX_BOOT_SOUND_LOOPS}")
                
                color = random.choice(COLORS)
                self.hw.led_set(color)
            
                # ランダムに起動音を選択
                selected = random.choice(boot_sounds)
                print(f"Playing boot sound: {selected.__name__}")
                selected()
                
                # ランダムにスリープ
                light_duration = random.randint(2, 10)
                self.light.random_light_show(light_duration)
                
            print("=== Random Boot Sound Ended ===")
    

    このコードをsound_controller.pyにコピペして、「Ctrl + s」でファイルを保存後このコードで本当にSHINDO ROBOTの起動音が変わるかを確認します。

    画像
    Ctrl + Shift + pを押して、「MicroPico」と入力
    または、左下の「All commands」をクリック

    SHINDO ROBOTに変更したsound_controller.pyを反映するには、まずSHINDO ROBOTとPCをUSBケーブル(Type-C)で接続した後、VSCode上で「Ctrl + Shift + p」を同時に押します。その後コマンドパレットと呼ばれる画面が上部に現れるので、その入力欄で「MicroPico」と入力します。そうするとMicroPicoに関係するコマンドが出てくるので、その中の「Upload project to Pico」を選択します。
    すると、先ほど変更したsound_controller.pyがSHINDO ROBOTに転送され、起動音が4種類から10種類に増えているはずです。

    試しにスイッチをスライドして電源を入れた後、起動音が再生されるのをRESETボタンを押して何回か試してみてください。すると下記動画のように元からあった起動音はそのままで、新たに6種類の起動音が追加されているのが確認できると思います。

    以上がソフトウェアのカスタマイズ方法についての簡単な例になります。
    他にも音がなった後のLEDの制御や、ロボットに搭載されている振動モーターをどのタイミングで動作させるかといったことが自分でカスタマイズすることが可能です。

    ソフトウェアの素人でも、今回のようにChatGPTに聞くと簡単にどう改良すればいいのか教えてくれるので、AIと一緒にコードを書くというのもまた面白いと思います。

    こうしたカスタマイズ可能なロボットを今後もいくつか作っていこうと思いますので、是非手に取っていただきその創造力をROBOTにぶつけて楽しんでいただければなと思います。(ただ、眺めるも良しです👍)

     
     

    kou1

     
     
    趣味で3Dプリンターを使いロボットを製作しているソフトウェアエンジニアです。

    あなたへのおすすめ