Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Dynamic Vehicle Routing のシミュレーションを Streamlitで作ってみた

Dynamic Vehicle Routing のシミュレーションを Streamlitで作ってみた

More Decks by NearMeの技術発表資料です

Other Decks in Technology

Transcript

  1. 1 • ⾃動運転キャッチアップしたいな ◦ 「Autoware :⾃動運転ソフトウェア⼊⾨」を読む ◦ 要素技術多すぎて、勉強会ネタとしてはまとめきれない。。 • 要素技術の⼀つであるROSにフォーカスするか

    • ROSで複数⾞両のルーティングのシミュレーションやってるのないかな ◦ あった ▪ https://github.com/shineyruan/vehicle-routing-ros2?tab=readme-ov-file ◦ 元のPython実装もあった ▪ https://github.com/lb-robotics/python-vehicle-routing ◦ 元の論⽂もあった ▪ “Dynamic Vehicle Routing for Robotic Systems”(Bullo et al., 2011) ▪ https://stanfordasl.github.io/wp-content/papercite-data/pdf/Bullo.Fraz zoli.ea.IEEEProc11.pdf • ⾯⽩いのでやっぱりDynamic Vehicle Routingにフォーカス • こういうシミュレーション基盤も作りたかったな ◦ Streamlitでマルチスレッド処理できるかな? ◦ https://zenn.dev/ohtaman/articles/streamlit_start_stop ◦ いけそうなので作ってみるか (勉強会ネタのチョイスの紆余曲折)
  2. 2 Dynamic Vehicle Routingについて • 動的に変わる環境 ◦ 確率的に出現する注⽂/タスク • 複数⾞両/ロボットによるアサイン

    ◦ ⾃律的な最適化 ◦ 協調的なコントロール • ポリシーの違いによってパフォーマンスは⼤きく異なる • 協調的なコントロールは必須 • 注⽂の確率分布に応じて⾞両をバランスよく配置するこ とも重要 • 注⽂数/⾞両数のバランスの違いによってもパフォーマン スは異なる ◦ 注⽂数が多い時は、TSPが有効 https://github.com/lb-robotics/python-vehicle-routing
  3. 3 シミュレータ作ってみた こちらからダウンロードして実⾏ https://gist.github.com/kenji4569/8da401b4d1bbfe2b0b6be41ac6d3d1a2 以下のコマンドを実行 pip install streamlit numpy scipy

    pandas altair readerwriterlock streamlit run app.py (wandb利用の場合は以下も実行 ) wandb login pip install wandb ブラウザでStreamlitアプリが立ち上がったら “Start”ボタンを押下
  4. 4 マルチスレッドについて class Vehicle(threading.Thread): def __init__(self, events: Events, location: Location,

    **kwargs): super().__init__(**kwargs) self.done = threading.Event() ... def run(self): while not self.done.wait(0): time.sleep(TIME_STEP) self._move() class Timer(threading.Thread): def __init__(self, events: Events, **kwargs): super().__init__(**kwargs) self.done = threading.Event() ... def run(self): while not self.done.wait(0): time.sleep(TIME_STEP) self.elapsed_time += TIME_STEP • Timerのスレッド • Vehicle x nのスレッド 各スレッドが並列動く (Streamlitではグローバルにキャッシュでスレッドのオブジェクトを保持する必要あり) @st.cache_resource def get_root_manager(): return RootManager()
  5. 5 マルチスレッドの注意点 • ロック処理をしないとどうなるか def _move(self): diff = self.target_location -

    self.location diff_norm = np.linalg.norm(diff) if diff_norm < self.pickup_threshold: self.location = self.target_location self._pickup_demand() else: movement = diff * (self.speed / diff_norm) self.location = self.location + TIME_STEP * movement def _pickup_demand(self): if not self.target_demand: return target_demand = self.target_demand with self.lock.gen_wlock(): if not target_demand.picked_up: target_demand.picked_up = True self.events.append( Event( "pickup_demand", {"demand_uid": target_demand.uid, "vehicle_uid": self.uid}, ) ) ここでロック ロックしないとこの値が 書き変わる可能性がある ピックアップイベントが 複数回記録される可能性がある 距離が近くなったら ピックアップ