以下の文章はブログ記事 Learning to Drive Smoothly in Minuts を勝手に翻訳したものです。
このブログ記事のタイトルから..前に読んだ論文「Learn to Drive in a Day」 (勝手日本語訳はこちら)に喧嘩売ってを意識してるんだろうなあ..きっと..
-----
Unityシミュレータのてれオペレーションコントロールパネルで動作中のDonkeycar
この記事では、自動運転レーシングカーを数分でトレーニングする方法と、その制御を円滑にする方法について説明します。この方法は、強化学習(RL)に基づいており、ここではシミュレーション(Donkey Car simulator)で提示されていますが、現実の世界に適用できるように設計されています。それは自動運転にフォーカスしている Wayve.ai というスタートアップの作業上でビルドしています。
この記事で使用されているコードとシミュレータはオープンソースで公開されています。詳細については、関連するGitHubレポジトリを確認してください。 :)(トレーニング済みのコントローラもダウンロード可能)
https://github.com/araffin/learning-to-drive-in-5-minutes
数年前の DIY Robocars を立ち上げ以来、数多くの自動運転レーシングカーの競技会が開催されています(例:Toulouse Robot Race、Iron Carなど )。それらの目標はシンプルです:あなたはレーシングカーを持っていて、入力としてその搭載カメラからの画像だけを与えられて、トラックにとどまっている間できるだけ速く走行する。
DIY Robocarに触発されたDonkeyシミュレータの倉庫シーン
自動運転への挑戦は、ロボット工学に入門するための良い方法です。学習を容易にするために、オープンソースの自動運転プラットフォームである Donkey Car が開発されました。そのエコシステムでは、その小型ロボットを特色とする Unityシミュレータ があります。このDonkey Carベースで提案されているアプローチをテストします。
小規模な自動運転車の競技で使用されているさまざまな方法を簡単に検討した後、強化学習とは何かを提示してから、私たちのアプローチの詳細に入ります。
Arduino、Raspberry Pi、PiCamera を搭載した自動運転レーシングロボット
強化学習を紹介する前に、まずRCカーの競技会で現在使用されているさまざまなソリューションについて簡単に説明します。
以前のブログ記事では、私は組み合わせて自律的に駆動するための最初のアプローチである、コンピュータビジョンとPIDコントローラについて説明しました。このアイデアはシンプルで多くの設定に適用できますが、それは(トラックの中心がどこにあるかを車に伝えるために)データの手動ラベリングを必要とします(手間のかかるラベリングは楽しいことではありません)。
他のアプローチとして、競合他社の多くは人間の運転手の行動を再現するために教師つき学習を利用しています。そのためには、人間は数周ほど車を手動で運転し、カメラ画像とそれに関連するジョイスティックからの制御入力を記録する必要があります。それから、モデルは人間の運転を再現するためにトレーニングされます。しかし、このテクニックは一般的に極めて悪いものであるため、実際には堅牢ではなく、均一な運転とトラックごとに再学習を要求されます。
上記の問題を考慮すると、強化学習(RL:Reinforcement Learning)は興味深い代替方法のです。
強化学習の設定では、エージェント(またはロボット)はその環境に基づいて行動し、フィードバックとして報酬を受け取ります。それは肯定的な報酬(ロボットが何か良いことをした)または否定的な報酬(ロボットがペナルティを科されるべきである)であるかもしれません。
ロボットの目標は累積報酬を最大化することです。そうするために、それは世界との相互作用を通して、感覚による入力を行動にマッピングするいわゆるポリシー(あるいは振る舞い/コントローラ)を学びます。
私たちの場合、入力はカメラ画像で、アクションはスロットルとステアリングアングルです。そのため、車が軌道に乗ってその速度を最大にするように報酬をモデル化すれば、完了です。
stable-baselines:便利な強化学習ライブラリ
これが強化学習の美しさです、あなたはほんの少しの仮定(ここでは報酬関数を設計するだけ)を必要とします、そしてそれはあなたが望むものを直接最適化します(レースに勝つために軌道に早く行きます!)
次に、私たちの方法の基礎である Wayve.ai アプローチを詳細に検討することから始めましょう。
Wayve.ai は、物理世界で自動運転車を単純な道路でトレーニングする方法を説明しています。このメソッドはいくつかの重要な要素で構成されています。
Wayve.ai アプローチ:1日で運転を学習する
最初に、彼らは画像をより低い次元の空間に圧縮するために特徴抽出器(ここではVariational Auto-EncoderまたはVAE)をトレーニングします。モデルは入力画像を再構築するようにトレーニングされていますが、情報を圧縮することを強制するボトルネックを含んでいます。
生データから関連情報を抽出するこのステップは、状態表現学習(SRL)と呼ばれ、私の主な研究テーマでした。それは特に検索スペースを減らすことを可能にし、それ故にトレーニングを加速させます。以下は、SRLとエンドツーエンドの強化学習、つまりピクセルから直接制御ポリシーを学習する方法の関係を示す図です。
ポリシ学習からの特徴抽出の分離
2つ目の重要な要素は、入力としてVAE機能を使用してコントロールポリシを学習する、ディープ決定論的ポリシ勾配(DDPG)という名前のRLアルゴリズムの使用です。このポリシは各エピソードの後に更新されます。アルゴリズムの重要な側面のひとつとして、再生バッファと呼ばれるメモリを持つことです。記録され後で"再生"可能な環境で相互に再生バッファでやりとりを行います。そのため、車が世界とやり取りしない場合でも、このバッファから経験をサンプリングしてポリシを更新できます。
車は人間の介入前に走行したメータの数を最大にするようにトレーニングされています。そしてそれが最後の重要な要素です。自動車が道路から外れ始めるとすぐに、オペレータはエピソードを終了します。この早期終了は(Deep Mimicによって示されているように)本当に重要であり、車がタスクを解決するのに面白くない領域を探索するのを防ぎます。
ここまで、何も新しいものは提示していません。Wayve.ai アプローチを要約しただけです。以下は、基本テクニックに対して行った変更のすべてです。
Wayve.ai のテクニックは原理的にはうまくいくかもしれませんが、それを自動運転RCカーに適用するために取り組む場合にはいくつかの問題があります。
まず、特徴抽出器(VAE)は各エピソードの後にトレーニングされるので、特徴の分布は定常的ではないことです。つまり、特徴量は時間の経過とともに変化し、ポリシトレーニングが不安定になる可能性があります。また、ラップトップで(GPUなしで)VAEをトレーニングするのは非常に遅いので、各エピソードの後にVAEを再トレーニングすることは避けたいと思います。
これら2つの問題に対処するために、私は事前にVAEをトレーニングし、私のコンピュータを保護するためにGoogle Colabノートブックを使用しました。このようにして、ポリシは固定機能抽出プログラムでトレーニングされます。
下の画像では、VAEが学んだことを探索します。私たちはその潜在空間を(スライダーを使って)ナビゲートし、再構成された画像を観察します。
その場合、DDPGは不安定であることが知られており(トレーニング中にそのパフォーマンスが壊滅的に低下する可能性があるという意味で)、調整するのは非常に困難です。幸いなことに、最近の Soft Actor-Critic(SAC)というアルゴリズムは同等の性能を持ち、調整がはるかに簡単です。
私がstable-baselinesのために記述し、stable-baselines内で最後に実装した、Soft Actor-Critic(SAC)実装を使用しました。(RLを使っている方は、ちょっと覗いてみることをおすすめします😋 )
最後に、コントロールを滑らかにしてスピードを最大にするために、報酬機能とアクションスペースを更新しました。
ロボットカーには走行距離も(速度センサも)含まれていないため、走行したメータ数(速度も)を報酬として使用することはできません。
したがって、私は各タイムステップで「ライフボーナス」(すなわち、トラックにとどまることに対して+1の報酬)を与え、トラックを離れた場合「クラッシュペナルティ」(-10の報酬)を使ってロボットにペナルティを科すことにしました。さらに、あまりにも速く道路を外れることを罰することも有益であると思いました:スロットルに比例して追加の負の報酬がクラッシュペナルティに追加されます。
最後に、レーシングカーとしてできるだけ速く走りたいので、現在のスロットルに比例した「スロットルボーナス」を追加しました。 そのようにして、ロボットは軌道上にとどまり、同時にその速度を最大化しようとします。
まとめると、
ここで、w1 と w2 は目的のバランスをとることを可能にする単なる定数( w1 << 10 と w2 << 1 は2次目的であるため)。
あなたがこれまでに提示されたアプローチを適用するならば、それはうまくいくでしょう:車は軌道上にとどまり、速く走ろうとします。しかし、あなたはおそらく不安定なコントロールになってしまうでしょう。車は上の画像に示すように振動します。そうしないのはインセンティブがないからです。報酬を最大化しようとするだけです。
コントロールを円滑にするための解決策は、 *前のコマンド(ステアリングとスロットル)の履歴で入力を増やしながら、ステアリング角度の変化を制限する* ことです。そのように、あなたはステアリングに連続性を課します。
例として、現在の自動車の操舵角が0°で、突然90°に操縦しようとすると、連続性制約では、たとえば40°に操縦できるようになります。従って、2つの連続する操舵コマンド間の差は所与の範囲内に留まることになります。この追加の制約には、もう少しトレーニングが必要です。
私は満足のいく解決策を見つける前に、その問題を解決しようと数日を過ごしました。ここで私は試してみましたがうまくいきませんでした。
私たちのアプローチでは、ポリシ学習を特徴抽出から切り離し、制御を円滑にするために制約を追加します。
まず、人間は車を手動で運転してデータを収集します(手動運転で約5分で10k枚の画像)。これらの画像はVAEをトレーニングするために使用されます。
それから、私達は探索エピソード(確率論的ポリシが使用される)とポリシトレーニング(費やされた時間を最適化するために、人間が車を軌道に戻す際に行われる)の間で交替します。
ポリシをトレーニングするために、画像はまずVAE(ここでは64次元の潜在空間)を使用して符号化され、行われた最後の10の動作(スロットルおよびステアリング)の履歴と連結され84次元の特徴ベクトルを生成する。
コントロールポリシは、ニューラルネットワーク(ReLUまたはELU活性化機能を有する32および16ユニットの2つの完全に接続された層)によって表されます。
このコントローラはステアリングアングルとスロットルを出力します。スロットルを一定の範囲内に収めるように制限し、現在と前のステアリング角の差も制限します。
この記事では、カメラだけを使用して、数分でDonkeycarのためのなめらかなコントロールポリシを学習するためのアプローチを紹介しました。
この方法は現実の世界に適用されるように設計されおり、このプロジェクトにおける私の次のステップでもあります。実際のRCカーでアプローチをテストしました(下記参照)。これは Raspberry Pi で実行するためにVAEモデルを縮小することを必要とします(ポリシーネットワークは既にかなり小さい)。
これですべてです。コードをテストしたり、コメントしたり、質問したりすることを躊躇しないでください。共有はとても気にしています。
------
Donkey Carのデフォルトモデルは、教師あり学習ベースなのだけど、すでに強化学習の既存のアルゴリズムを複数用いて挑戦している人がおり、海外の研究速度の速さにあらためて驚かされた。
実際の自動運転車は、(運転しない)人や荷物を載せないと意味がないんだよなあ..
今まで振動(左右に振りながらの運転)には目をつぶってたけど、実現させるにはそれもクリアし無くてはならない要件の一つであることを思い出させてくれたよ..
このブログ記事のタイトルから..前に読んだ論文「Learn to Drive in a Day」 (勝手日本語訳はこちら)
-----
Learning to Drive Smoothly in Minuts
小さなレーシングカー上で強化学習- 2019年1月27日
- 著者: Antonin RAFFIN
Unityシミュレータのてれオペレーションコントロールパネルで動作中のDonkeycar
この記事では、自動運転レーシングカーを数分でトレーニングする方法と、その制御を円滑にする方法について説明します。この方法は、強化学習(RL)に基づいており、ここではシミュレーション(Donkey Car simulator)で提示されていますが、現実の世界に適用できるように設計されています。それは自動運転にフォーカスしている Wayve.ai というスタートアップの作業上でビルドしています。
この記事で使用されているコードとシミュレータはオープンソースで公開されています。詳細については、関連するGitHubレポジトリを確認してください。 :)(トレーニング済みのコントローラもダウンロード可能)
動画
GitHub リポジトリ: 結果の再現
[GitHub] Learning to Drive Smoothly in Minutshttps://github.com/araffin/learning-to-drive-in-5-minutes
はじめに:レージングカー競技
数年前の DIY Robocars を立ち上げ以来、数多くの自動運転レーシングカーの競技会が開催されています(例:Toulouse Robot Race、Iron Carなど )。それらの目標はシンプルです:あなたはレーシングカーを持っていて、入力としてその搭載カメラからの画像だけを与えられて、トラックにとどまっている間できるだけ速く走行する。
DIY Robocarに触発されたDonkeyシミュレータの倉庫シーン
自動運転への挑戦は、ロボット工学に入門するための良い方法です。学習を容易にするために、オープンソースの自動運転プラットフォームである Donkey Car が開発されました。そのエコシステムでは、その小型ロボットを特色とする Unityシミュレータ があります。このDonkey Carベースで提案されているアプローチをテストします。
アウトライン
小規模な自動運転車の競技で使用されているさまざまな方法を簡単に検討した後、強化学習とは何かを提示してから、私たちのアプローチの詳細に入ります。
Arduino、Raspberry Pi、PiCamera を搭載した自動運転レーシングロボット
自動運転競技で使用される方法:ライン追跡と行動クローニング
強化学習を紹介する前に、まずRCカーの競技会で現在使用されているさまざまなソリューションについて簡単に説明します。
以前のブログ記事では、私は組み合わせて自律的に駆動するための最初のアプローチである、コンピュータビジョンとPIDコントローラについて説明しました。このアイデアはシンプルで多くの設定に適用できますが、それは(トラックの中心がどこにあるかを車に伝えるために)データの手動ラベリングを必要とします(手間のかかるラベリングは楽しいことではありません)。
他のアプローチとして、競合他社の多くは人間の運転手の行動を再現するために教師つき学習を利用しています。そのためには、人間は数周ほど車を手動で運転し、カメラ画像とそれに関連するジョイスティックからの制御入力を記録する必要があります。それから、モデルは人間の運転を再現するためにトレーニングされます。しかし、このテクニックは一般的に極めて悪いものであるため、実際には堅牢ではなく、均一な運転とトラックごとに再学習を要求されます。
強化学習(RL)とは?なぜ使用すべきなのか?
上記の問題を考慮すると、強化学習(RL:Reinforcement Learning)は興味深い代替方法のです。
強化学習の設定では、エージェント(またはロボット)はその環境に基づいて行動し、フィードバックとして報酬を受け取ります。それは肯定的な報酬(ロボットが何か良いことをした)または否定的な報酬(ロボットがペナルティを科されるべきである)であるかもしれません。
ロボットの目標は累積報酬を最大化することです。そうするために、それは世界との相互作用を通して、感覚による入力を行動にマッピングするいわゆるポリシー(あるいは振る舞い/コントローラ)を学びます。
私たちの場合、入力はカメラ画像で、アクションはスロットルとステアリングアングルです。そのため、車が軌道に乗ってその速度を最大にするように報酬をモデル化すれば、完了です。
stable-baselines:便利な強化学習ライブラリ
これが強化学習の美しさです、あなたはほんの少しの仮定(ここでは報酬関数を設計するだけ)を必要とします、そしてそれはあなたが望むものを直接最適化します(レースに勝つために軌道に早く行きます!)
注意 :これは、小さな自動運転車に強化学習についての最初のブログ記事はありません。しかし既存のアプローチと比較して、現在のテクニックは良質でなめらかなコントロールポリシを数分(数時間ではない)で(なめらかなコントローラのために5~10分、20分以内にとてもなめらかなコントローラを)学習します。
次に、私たちの方法の基礎である Wayve.ai アプローチを詳細に検討することから始めましょう。
1日で運転を学ぶーWayve.ai アプローチの重要な要素
Wayve.ai は、物理世界で自動運転車を単純な道路でトレーニングする方法を説明しています。このメソッドはいくつかの重要な要素で構成されています。
Wayve.ai アプローチ:1日で運転を学習する
最初に、彼らは画像をより低い次元の空間に圧縮するために特徴抽出器(ここではVariational Auto-EncoderまたはVAE)をトレーニングします。モデルは入力画像を再構築するようにトレーニングされていますが、情報を圧縮することを強制するボトルネックを含んでいます。
生データから関連情報を抽出するこのステップは、状態表現学習(SRL)と呼ばれ、私の主な研究テーマでした。それは特に検索スペースを減らすことを可能にし、それ故にトレーニングを加速させます。以下は、SRLとエンドツーエンドの強化学習、つまりピクセルから直接制御ポリシーを学習する方法の関係を示す図です。
注意:Auto Encoder をトレーニングすることは、有用な特徴を抽出するための唯一の解決策ではありません。例えば、インバースダイナミクスモデルをトレーニングすることもできます。
ポリシ学習からの特徴抽出の分離
2つ目の重要な要素は、入力としてVAE機能を使用してコントロールポリシを学習する、ディープ決定論的ポリシ勾配(DDPG)という名前のRLアルゴリズムの使用です。このポリシは各エピソードの後に更新されます。アルゴリズムの重要な側面のひとつとして、再生バッファと呼ばれるメモリを持つことです。記録され後で"再生"可能な環境で相互に再生バッファでやりとりを行います。そのため、車が世界とやり取りしない場合でも、このバッファから経験をサンプリングしてポリシを更新できます。
車は人間の介入前に走行したメータの数を最大にするようにトレーニングされています。そしてそれが最後の重要な要素です。自動車が道路から外れ始めるとすぐに、オペレータはエピソードを終了します。この早期終了は(Deep Mimicによって示されているように)本当に重要であり、車がタスクを解決するのに面白くない領域を探索するのを防ぎます。
ここまで、何も新しいものは提示していません。Wayve.ai アプローチを要約しただけです。以下は、基本テクニックに対して行った変更のすべてです。
数分で運転を学習ー最新のアプローチ
Wayve.ai のテクニックは原理的にはうまくいくかもしれませんが、それを自動運転RCカーに適用するために取り組む場合にはいくつかの問題があります。
まず、特徴抽出器(VAE)は各エピソードの後にトレーニングされるので、特徴の分布は定常的ではないことです。つまり、特徴量は時間の経過とともに変化し、ポリシトレーニングが不安定になる可能性があります。また、ラップトップで(GPUなしで)VAEをトレーニングするのは非常に遅いので、各エピソードの後にVAEを再トレーニングすることは避けたいと思います。
これら2つの問題に対処するために、私は事前にVAEをトレーニングし、私のコンピュータを保護するためにGoogle Colabノートブックを使用しました。このようにして、ポリシは固定機能抽出プログラムでトレーニングされます。
下の画像では、VAEが学んだことを探索します。私たちはその潜在空間を(スライダーを使って)ナビゲートし、再構成された画像を観察します。
VAEが学習した潜在空間を探る
その場合、DDPGは不安定であることが知られており(トレーニング中にそのパフォーマンスが壊滅的に低下する可能性があるという意味で)、調整するのは非常に困難です。幸いなことに、最近の Soft Actor-Critic(SAC)というアルゴリズムは同等の性能を持ち、調整がはるかに簡単です。
実験中に、PPO 、SAC、DDPGを試しました。DDPGとSACはいくつかのエピソードで最高の結果を出していましたが、SACは調整が簡単でした。
私がstable-baselinesのために記述し、stable-baselines内で最後に実装した、Soft Actor-Critic(SAC)実装を使用しました。(RLを使っている方は、ちょっと覗いてみることをおすすめします😋 )
[GitHub] hill-a/stable-baselines
https://github.com/hill-a/stable-baselines
Open AI baselines をフォークした、強化学習アルゴリズム群の実装
最後に、コントロールを滑らかにしてスピードを最大にするために、報酬機能とアクションスペースを更新しました。
報酬関数:早く走行しなさい、ただしトラック内にとどまりなさい!
ロボットカーには走行距離も(速度センサも)含まれていないため、走行したメータ数(速度も)を報酬として使用することはできません。
したがって、私は各タイムステップで「ライフボーナス」(すなわち、トラックにとどまることに対して+1の報酬)を与え、トラックを離れた場合「クラッシュペナルティ」(-10の報酬)を使ってロボットにペナルティを科すことにしました。さらに、あまりにも速く道路を外れることを罰することも有益であると思いました:スロットルに比例して追加の負の報酬がクラッシュペナルティに追加されます。
最後に、レーシングカーとしてできるだけ速く走りたいので、現在のスロットルに比例した「スロットルボーナス」を追加しました。 そのようにして、ロボットは軌道上にとどまり、同時にその速度を最大化しようとします。
まとめると、
ここで、w1 と w2 は目的のバランスをとることを可能にする単なる定数( w1 << 10 と w2 << 1 は2次目的であるため)。
不安定な制御を回避:なめらかに運転するための学習
世界は実際には確率的ではありません。
お気づきのとおり、ロボットが自発的に揺れ始めるのではありません。
RLアルゴリズムを接続しない限り。
- エモトドロフ
左:振動コントロール、右:提案手法によるなめらかなコントロール
あなたがこれまでに提示されたアプローチを適用するならば、それはうまくいくでしょう:車は軌道上にとどまり、速く走ろうとします。しかし、あなたはおそらく不安定なコントロールになってしまうでしょう。車は上の画像に示すように振動します。そうしないのはインセンティブがないからです。報酬を最大化しようとするだけです。
コントロールを円滑にするための解決策は、 *前のコマンド(ステアリングとスロットル)の履歴で入力を増やしながら、ステアリング角度の変化を制限する* ことです。そのように、あなたはステアリングに連続性を課します。
例として、現在の自動車の操舵角が0°で、突然90°に操縦しようとすると、連続性制約では、たとえば40°に操縦できるようになります。従って、2つの連続する操舵コマンド間の差は所与の範囲内に留まることになります。この追加の制約には、もう少しトレーニングが必要です。
私は満足のいく解決策を見つける前に、その問題を解決しようと数日を過ごしました。ここで私は試してみましたがうまくいきませんでした。
- 絶対ステアリングではなく出力相対ステアリング:低周波数の振動を生成
- 連続性のペナルティを追加(ステアリングの大きな変更に対してロボットにペナルティを課す):ロボットは正しいことを最適化しません。ときどき動作しますが、軌道に乗らないようにします。そのペナルティのコストが低すぎる場合は、無視します。
- 最大ステアリングを制限:最も急な方向転換では、車はこれ以上とどまることができなくなります。
- いくつかの速度情報を与えるために複数のフレームを積み重ねる:より低い周波数の振動を生み出しました。
注意 :最近、ETHチューリッヒの研究者は、継続的でエネルギー効率の高い管理をするためにカリキュラム学習を使用することを提案しました。これは2番目の解決策になる可能性があります(ただし調整が少し困難です)。
アプローチのまとめ
私たちのアプローチでは、ポリシ学習を特徴抽出から切り離し、制御を円滑にするために制約を追加します。
まず、人間は車を手動で運転してデータを収集します(手動運転で約5分で10k枚の画像)。これらの画像はVAEをトレーニングするために使用されます。
それから、私達は探索エピソード(確率論的ポリシが使用される)とポリシトレーニング(費やされた時間を最適化するために、人間が車を軌道に戻す際に行われる)の間で交替します。
ポリシをトレーニングするために、画像はまずVAE(ここでは64次元の潜在空間)を使用して符号化され、行われた最後の10の動作(スロットルおよびステアリング)の履歴と連結され84次元の特徴ベクトルを生成する。
コントロールポリシは、ニューラルネットワーク(ReLUまたはELU活性化機能を有する32および16ユニットの2つの完全に接続された層)によって表されます。
このコントローラはステアリングアングルとスロットルを出力します。スロットルを一定の範囲内に収めるように制限し、現在と前のステアリング角の差も制限します。
結論
この記事では、カメラだけを使用して、数分でDonkeycarのためのなめらかなコントロールポリシを学習するためのアプローチを紹介しました。
この方法は現実の世界に適用されるように設計されおり、このプロジェクトにおける私の次のステップでもあります。実際のRCカーでアプローチをテストしました(下記参照)。これは Raspberry Pi で実行するためにVAEモデルを縮小することを必要とします(ポリシーネットワークは既にかなり小さい)。
wayve.ai アプローチは本物のRCカーでRoma Sokolov によって再現されました。しかしこの再現には、なめらかなコントロールのための最新の改良を含んでいませんでした。
これですべてです。コードをテストしたり、コメントしたり、質問したりすることを躊躇しないでください。共有はとても気にしています。
------
Donkey Carのデフォルトモデルは、教師あり学習ベースなのだけど、すでに強化学習の既存のアルゴリズムを複数用いて挑戦している人がおり、海外の研究速度の速さにあらためて驚かされた。
実際の自動運転車は、(運転しない)人や荷物を載せないと意味がないんだよなあ..
今まで振動(左右に振りながらの運転)には目をつぶってたけど、実現させるにはそれもクリアし無くてはならない要件の一つであることを思い出させてくれたよ..
0 件のコメント:
コメントを投稿