.. note:: こんにちは!SunFounder Raspberry Pi & Arduino & ESP32 Enthusiasts Communityへようこそ!Raspberry Pi、Arduino、ESP32について、他の愛好者と一緒にさらに深く学びましょう。 **参加する理由** - **専門家のサポート**: 購入後の問題や技術的な課題を、コミュニティやチームのサポートで解決できます。 - **学びと共有**: ヒントやチュートリアルを交換して、スキルを向上させましょう。 - **特別なプレビュー**: 新製品の発表や先行公開に早期アクセスできます。 - **特別割引**: 新製品に対して限定割引を楽しめます。 - **祝祭プロモーションとプレゼント**: プレゼントや祝祭プロモーションに参加できます。 👉 私たちと一緒に探求し、創造する準備はできましたか?[|link_sf_facebook|]をクリックして、今すぐ参加しましょう! .. _py_bull: 7. ブルファイト ================= PiCrawlerを怒った雄牛に変身させましょう!そのカメラを使って赤い布を追跡し、突進させます! .. .. image:: img/bullfight.png **コードを実行する** .. raw:: html .. code-block:: cd ~/picrawler/examples sudo python3 7_bull_fight.py **画像の表示** コードが実行されると、ターミナルには以下のようなプロンプトが表示されます: .. code-block:: No desktop ! * Serving Flask app "vilib.vilib" (lazy loading) * Environment: production WARNING: Do not use the development server in a production environment. Use a production WSGI server instead. * Debug mode: off * Running on http://0.0.0.0:9000/ (Press CTRL+C to quit) その後、ブラウザで ``http://:9000/mjpg`` を入力して、ビデオ画面を表示できます。例: ``https://192.168.18.113:9000/mjpg`` .. image:: img/display.png **コード** .. note:: 以下のコードは **修正/リセット/コピー/実行/停止** できます。ただし、まずソースコードのパス(例: ``picrawler/examples`` )に移動する必要があります。コードを修正した後、直接実行して効果を確認できます。 .. raw:: html .. code-block:: python from picrawler import Picrawler from time import sleep, time from robot_hat import Music from vilib import Vilib # Create robot and audio controller objects crawler = Picrawler() music = Music() def main(): # Start camera and enable preview window Vilib.camera_start(vflip=False, hflip=False) Vilib.display(local=False, web=True) # Enable red color detection Vilib.color_detect("red") speed = 80 # Movement speed last_seen = False # Indicates whether the red target was detected in previous loop last_beep = 0 # Timestamp of last sound playback BEEP_COOLDOWN = 1.0 # Minimum interval between sound effects (seconds) # Stand once before starting tracking crawler.do_step('stand', 40) sleep(1.0) try: while True: # Read detection result if Vilib.detect_obj_parameter.get('color_n', 0) != 0: # Get horizontal coordinate of detected red object coordinate_x = Vilib.detect_obj_parameter.get('color_x', 0) # Play sound effect with cooldown to avoid spamming now = time() if now - last_beep >= BEEP_COOLDOWN: try: music.sound_play_threading('./sounds/talk1.wav') except Exception: pass last_beep = now # Steering logic based on horizontal position # Left side of image if coordinate_x < 100: crawler.do_action('turn left', 1, speed) # Right side of image elif coordinate_x > 220: crawler.do_action('turn right', 1, speed) # Center area → move forward else: crawler.do_action('forward', 2, speed) last_seen = True sleep(0.05) else: # No red target detected # Stop movement only once when target is lost # This prevents repeated stand() calls that cause "push-up" effect if last_seen: crawler.do_step('stand', 40) last_seen = False sleep(0.15) except KeyboardInterrupt: # Stop program safely when Ctrl+C is pressed print("\nStop.") finally: # Cleanup section to avoid exit errors # Disable color detection try: Vilib.color_detect("close") except Exception: pass # Close camera safely try: Vilib.camera_close() except Exception: pass # Make the robot sit before exit try: crawler.do_step('sit', 40) sleep(1.0) except Exception: pass if __name__ == "__main__": main() **仕組み** #. カメラの初期化 .. code-block:: python Vilib.camera_start(vflip=False, hflip=False) Vilib.display(local=False, web=True) Vilib.color_detect("red") カメラを起動し、Webプレビューを有効にします。 赤色の検出機能が有効になります。 Vilib はバックグラウンドで継続的にフレームを処理し、 検出結果を ``detect_obj_parameter`` に保存します。 #. ロボットの準備 .. code-block:: python crawler.do_step('stand', 40) sleep(1.0) 追跡を開始する前に、ロボットは立ち上がる動作を行います。 短い待機時間を入れることで、姿勢が安定します。 #. ターゲットの検出 .. code-block:: python if Vilib.detect_obj_parameter.get('color_n', 0) != 0: coordinate_x = Vilib.detect_obj_parameter.get('color_x', 0) プログラムは赤色の物体が検出されているかどうかを確認します。 検出された場合、画像内における赤色物体の水平方向の中心座標 (x位置)を取得します。 #. 進行方向の判断ロジック .. code-block:: python if coordinate_x < 100: crawler.do_action('turn left', 1, speed) elif coordinate_x > 220: crawler.do_action('turn right', 1, speed) else: crawler.do_action('forward', 2, speed) 画像は水平方向に3つの領域に分割されます: 左・中央・右。 • 左の領域 → 左に旋回 • 右の領域 → 右に旋回 • 中央の領域 → 前進 これにより、ロボットは赤色の物体を追跡しながら移動できます。 #. サウンドのクールダウン機構 .. code-block:: python now = time() if now - last_beep >= BEEP_COOLDOWN: music.sound_play_threading('./sounds/talk1.wav') last_beep = now クールダウンタイマーにより、音声が連続して再生されるのを防ぎます。 物体が継続して検出されている場合でも、 効果音は最大で1秒に1回だけ再生されます。 #. ターゲット消失時の処理 .. code-block:: python if last_seen: crawler.do_step('stand', 40) last_seen = False 赤色の物体が画面から消えた場合、 ロボットは停止し、安定した立ち姿勢に戻ります。 ``last_seen`` フラグにより、``stand()`` が1回だけ呼び出されるようにします。 これにより、姿勢リセットが繰り返されてロボットが揺れるのを防ぎます。 #. 安全な終了とクリーンアップ .. code-block:: python finally: Vilib.color_detect("close") Vilib.camera_close() crawler.do_step('sit', 40) プログラムが終了する際(例:Ctrl+C)、 色検出を無効化し、 カメラを安全に閉じ、 ロボットは座る動作を行います。 これにより、カメラエラーや不安定な終了動作を防ぎます。