見出し画像

Python×Jetson Nanoでルンバをもっと自由に!中級者向け完全ガイド


はじめに

こんにちは!この記事は、前回の「Jetson NanoでRoomba 980を操作しよう!初心者のための完全ガイド」の続編です。前回の記事で基本的な操作方法を学んだ皆さんに、さらに一歩進んだルンバのプログラミングテクニックをお伝えします。
今回は、Pythonを使ってより高度な制御を行い、Jetson Nanoの能力を最大限に活用してルンバをよりインテリジェントに動作させる方法を探っていきます。では、さっそく始めましょう!


前回のおさらい

前回の記事では、以下の内容を学びました:

  1. Jetson NanoとRoomba 980の接続方法

  2. 基本的な動作コマンドの実行

これらの基礎知識を踏まえて、今回はさらに高度なテクニックに挑戦していきます。


高度なセンサーデータの取得と活用

ルンバには多くのセンサーが搭載されています。これらのセンサーから詳細な情報を取得することで、より高度な制御が可能になります。以下のコードを見てみましょう:


from time import sleep
from pyroombaadapter import PyRoombaAdapter
from loguru import logger
 PORT = "/dev/ttyACM0"
 @logger.catch
def main():
    logger.info("PyRoombaAdapterを初期化中")
    adapter = PyRoombaAdapter(PORT)
    adapter.change_mode_to_passive()
     logger.info("センサー値を手動でリクエスト中")
    sensor_functions = [
        ("Charging State (充電状態)", adapter.request_charging_state),
        ("Voltage (電圧)", adapter.request_voltage),
        ("Current (電流)", adapter.request_current),
        ("Temperature (温度)", adapter.request_temperature),
        ("Charge (充電量)", adapter.request_charge),
        ("Capacity (バッテリー容量)", adapter.request_capacity),
        ("OI Mode (OIモード)", adapter.request_oi_mode),
        ("Distance (移動距離)", adapter.request_distance),
        ("Angle (回転角度)", adapter.request_angle),
    ]
     for sensor_name, sensor_func in sensor_functions:
        value = sensor_func()
        logger.info(f"{sensor_name}: {value}")
     logger.info("データストリームを開始")
    adapter.data_stream_start([
        "Charging State",  # 充電状態
        "Voltage",         # 電圧
        "Current",         # 電流
        "Temperature",     # 温度
        "Battery Charge",  # バッテリー充電量
        "Battery Capacity",# バッテリー容量
        "OI Mode"          # OIモード
    ])
     for i in range(3):
        sleep(1)
        data = adapter.data_stream_read()
        logger.info(f"データストリーム({i+1}回目): {data}")
     logger.info("データストリームを停止")
    adapter.data_stream_stop()
 if __name__ == "__main__":
    main()




 maki@maki-jetson5:~/SPARK$ python3 sensors.py 
2024-07-03 20:01:39.911 | INFO     | __main__:main:9 - PyRoombaAdapterを初期化中
Serial port is open, presumably to a roomba...
2024-07-03 20:01:40.914 | INFO     | __main__:main:13 - センサー値を手動でリクエスト中
2024-07-03 20:01:40.928 | INFO     | __main__:main:28 - Charging State (充電状態): 0
2024-07-03 20:01:40.946 | INFO     | __main__:main:28 - Voltage (電圧): 15697
2024-07-03 20:01:40.964 | INFO     | __main__:main:28 - Current (電流): -250
2024-07-03 20:01:40.976 | INFO     | __main__:main:28 - Temperature (温度): 19
2024-07-03 20:01:40.994 | INFO     | __main__:main:28 - Charge (充電量): 3140
2024-07-03 20:01:41.006 | INFO     | __main__:main:28 - Capacity (バッテリー容量): 3414
2024-07-03 20:01:41.024 | INFO     | __main__:main:28 - OI Mode (OIモード): 1
2024-07-03 20:01:41.042 | INFO     | __main__:main:28 - Distance (移動距離): 0
2024-07-03 20:01:41.054 | INFO     | __main__:main:28 - Angle (回転角度): 0.0
2024-07-03 20:01:41.054 | INFO     | __main__:main:30 - データストリームを開始
2024-07-03 20:01:42.056 | INFO     | __main__:main:44 - データストリーム(1回目): [0, 15697, -258, 18, 3140, 3414, 1]
2024-07-03 20:01:43.059 | INFO     | __main__:main:44 - データストリーム(2回目): [0, 15697, -258, 17, 3140, 3414, 1]
2024-07-03 20:01:44.061 | INFO     | __main__:main:44 - データストリーム(3回目): [0, 15697, -258, 17, 3140, 3414, 1]
2024-07-03 20:01:44.061 | INFO     | __main__:main:46 - データストリームを停止
maki@maki-jetson5:~/SPARK$ 


このコードでは、以下のような高度な操作を行っています:

  1. **多様なセンサーデータの取得**: 充電状態、電圧、電流、温度など、様々なセンサーの情報を取得しています。

  2. **データストリームの利用**: 連続的にデータを取得するためのデータストリーム機能を使用しています。

  3. **ログ記録**: `loguru`ライブラリを使用して、詳細なログを記録しています。

これらの情報を活用することで、ルンバの状態をリアルタイムで把握し、適切な判断を行うことができます。


ルンバの動作制御

次に、ルンバの動作を制御する方法を見ていきましょう。以下のコードは、ルンバを回転させる例です:


import create
import time
from loguru import logger
 # ログ設定
logger.add("roomba.log", rotation="500 MB", encoding="utf-8")
 ROOMBA_PORT = "/dev/ttyACM0"
 def main():
    try:
        # Roombaに接続
        logger.info(f"ポート {ROOMBA_PORT} に接続しています...")
        robot = create.Create(ROOMBA_PORT)
        logger.info("接続に成功しました!")
         # センサー情報を出力
        logger.info("センサー情報:")
        robot.printSensors()
         # 安全モードに移行
        logger.info("安全モードに移行しています...")
        robot.toSafeMode()
        logger.info("安全モードになりました!")
         # 回転開始
        logger.info("回転を開始します (速度: 0cm/s, 角速度: 10deg/s)")
        robot.go(0, 10)
        logger.info("回転中...")
        time.sleep(2)  # 2秒間回転
         # Roombaを停止
        logger.info("Roombaを停止します。")
        robot.stop()
         # 接続を終了
        robot.close()
        logger.info("接続を終了しました。")
     except serial.SerialException as e:
        logger.error(f"シリアル接続エラー: {e}")
 if __name__ == "__main__":
    main()




 024-07-03 18:06:55.481 | INFO     | __main__:main:13 - ポート /dev/ttyACM0 に接続しています...
PORT is /dev/ttyACM0
Serial port did open, presumably to a roomba...
Putting the robot into safe mode...
2024-07-03 18:06:56.896 | INFO     | __main__:main:15 - 接続に成功しました!
2024-07-03 18:06:56.897 | INFO     | __main__:main:18 - センサー情報:
                   LEFT_BUMP: 0
                  RIGHT_BUMP: 0
             LEFT_WHEEL_DROP: 0
            RIGHT_WHEEL_DROP: 0
           CENTER_WHEEL_DROP: 0
              WALL_IR_SENSOR: 0
                  CLIFF_LEFT: 0
            CLIFF_FRONT_LEFT: 0
           CLIFF_FRONT_RIGHT: 0
                 CLIFF_RIGHT: 0
                VIRTUAL_WALL: 0
      LEFT_WHEEL_OVERCURRENT: 0
     RIGHT_WHEEL_OVERCURRENT: 0
               INFRARED_BYTE: 0
                 PLAY_BUTTON: 0
              ADVANCE_BUTTON: 0
                 POSE X (cm): 0.0
                 POSE Y (cm): 0.0
               POSE TH (deg): 0.0
              CHARGING_STATE: 0
                     VOLTAGE: 15808
                     CURRENT: -250
                BATTERY_TEMP: 21
              BATTERY_CHARGE: 3197
            BATTERY_CAPACITY: 3414
                 WALL_SIGNAL: 7
           CLIFF_LEFT_SIGNAL: 2144
     CLIFF_FRONT_LEFT_SIGNAL: 2132
    CLIFF_FRONT_RIGHT_SIGNAL: 2177
          CLIFF_RIGHT_SIGNAL: 2131
                     OI_MODE: 2
                 SONG_NUMBER: 0
                SONG_PLAYING: 0
                ENCODER_LEFT: 63047
               ENCODER_RIGHT: 13753
                   LIGHTBUMP: 0
              LIGHTBUMP_LEFT: 0
        LIGHTBUMP_FRONT_LEFT: 1
       LIGHTBUMP_CENTER_LEFT: 1
      LIGHTBUMP_CENTER_RIGHT: 0
      LIGHTBUMP_CENTER_RIGHT: 0
             LIGHTBUMP_RIGHT: 28
  CHARGING_SOURCES_AVAILABLE: 0
2024-07-03 18:06:56.922 | INFO     | __main__:main:22 - 安全モードに移行しています...
2024-07-03 18:06:57.234 | INFO     | __main__:main:24 - 安全モードになりました!
2024-07-03 18:06:57.235 | INFO     | __main__:main:27 - 回転を開始します (速度: 0cm/s, 角速度: 10deg/s)
2024-07-03 18:06:57.237 | INFO     | __main__:main:29 - 回転中...
2024-07-03 18:06:59.240 | INFO     | __main__:main:33 - Roombaを停止します。
2024-07-03 18:06:59.721 | INFO     | __main__:main:38 - 接続を終了しました。
maki@maki-jetson5:~/SPARK$ 
 

このコードでは以下のような操作を行っています:

  1. **接続とモード設定**: ルンバに接続し、安全モードに設定しています。

  2. **動作制御**: `go`メソッドを使用して、ルンバを回転させています。

  3. **エラーハンドリング**: `try-except`文を使用して、エラーを適切に処理しています。



音楽再生機能の活用

ルンバには音楽を再生する機能もあります。これを使って、動作の開始や終了を音で知らせることができます:


from time import sleep
from pyroombaadapter import PyRoombaAdapter
 PORT = "/dev/ttyACM0"
adapter = PyRoombaAdapter(PORT)
 adapter.send_song_cmd(0, 9,
                      [69, 69, 69, 65, 72, 69, 65, 72, 69],
                      [40, 40, 40, 30, 10, 40, 30, 10, 80])
adapter.send_play_cmd(0)
sleep(10.0)


このコードは、スターウォーズのダース・ベイダーのテーマ曲の一部を再生します。音楽再生機能を使うことで、ルンバの動作をより直感的に理解できるようになります。


ログ記録とデバッグ

前述のコード例では、`loguru`ライブラリを使用してログを記録しています。ログを取ることで、以下のような利点があります:

  1. プログラムの動作を詳細に追跡できる

  2. エラーが発生した際に、原因の特定が容易になる

  3. ルンバの長期的な動作パターンを分析できる

ログ情報を活用することで、より安定したプログラムの開発が可能になります。


まとめと次のステップ

今回の記事では、Pythonを使ってJetson NanoでRoomba 980をより高度に制御する方法を紹介しました。センサーデータの詳細な取得と活用、複雑な動作制御、音楽再生機能の利用、そしてログ記録とデバッグについて学びました。
これらの技術を組み合わせることで、非常に柔軟で高度なルンバの制御が可能になります。例えば:

  1. センサーデータを分析して、効率的な清掃ルートを自動生成する

  2. 音楽再生機能を使って、清掃の開始や終了を知らせる

  3. ログデータを分析して、ルンバの動作パターンや効率を改善する

  4. 複数のセンサーデータを組み合わせて、より高度な判断ロジックを実装する

など、アイデア次第で様々な応用が考えられます。
次のステップとしては、以下のような発展的なトピックに挑戦してみるのも面白いでしょう:

  • 画像認識を用いた障害物の検出と回避

  • 機械学習を使用した最適な清掃パターンの学習

  • Webインターフェースによるリモートコントロールシステムの構築

ルンバのプログラミングは、実世界の問題を解決するロボット工学の素晴らしい入り口です。ここで学んだ技術は、他の種類のロボットや、IoTデバイスのプログラミングにも応用できるでしょう。
ぜひ、これらの技術を活用して、あなただけのユニークなルンバプログラムを作ってみてください。プログラミングの楽しさと、ロボット工学の奥深さを存分に味わえるはずです。
Happy coding!

この記事が気に入ったらサポートをしてみませんか?