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

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

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.

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}, ) ) ここでロック ロックしないとこの値が 書き変わる可能性がある ピックアップイベントが 複数回記録される可能性がある 距離が近くなったら ピックアップ