これは Pololu 3pi Robot User’s Guide ≫ 8.f. Improving the Maze-Solving Code の非公式日本語訳です。
目次
前: 8.e. Simplifying the Solution
次: 9. Pin Assignment Tables
8.f. Improving the Maze-Solving Code
We have gone over the most important parts of the code; the other bits and pieces (like the function display_path(), the start-up sequence and calibration, etc.) can be found with everything else in the folder examples\atmegaxx8\3pi-mazesolver
. After you have the code working and you understand it well, you should try to improve your robot to be as fast as possible. There are many things you can do to try to make it better:
コードの最も重要な部分については説明しました。他の細々としたコード(display_path()
関数、スタートアップシーケンス、キャリブレーションなど)は、他のすべてのものと一緒にexamples\atmegaxx8\3pi-mazesolver
フォルダにあります。コード作業とコードを良く理解した後に、ロボットを可能な限り早くなるように改善してください。改善のためにできることはたくさんあります:
-
Increasing the line-following speed.
-
Improving the line-following PID constants.
-
Increasing turning speed.
-
Identifying situations where the robot has gotten lost.
-
Adjusting the speed based on what is coming up; e.g. driving straight through an ‘S’ at full speed.
-
ライン追従速度を上げる。
-
ライン追従のPID定数の改善。
-
旋回速度を上げる。
-
ロボットが道に迷ったことを特定する。
-
何が起きているかに基づいて速度を調整する。例えば、"S"の始めから終わりまでフルスピードで直進する。
The following video shows a 3pi prototype—it only has one blue power LED, but it is otherwise functionally identical to the final version—that we programmed to compete in LVBots Challenge 4.0. The code is more advanced (and complicated) than the sample maze-solving code we have just provided. Improvements over the sample program include a higher base running speed with better-tuned line-following PID constants, faster and smoother turns, and increased speed on long straight segments.
以下のビデオは LVBots Challenge 4.0 に参加するためにプログラミングした3piのプロトタイプ-1つの青い電源LEDしか持っていませんが、それ以外の機能的には最新版と同じ-をお見せします。このコードは、提供したばかりの迷路解決のサンプルコードよりも高度(かつ複雑)です。サンプルプログラムの改善は、ライン追従のPID定数のチューニングによるより速い基本走行速度、より速くより滑らかな旋回、長い直線区間の速度向上を含みます。
When we were trying to improve the 3pi’s maze performance, our first step was to improve its line-following ability by better tuning the PID constants as we slowly increased the robot’s maximum speed, and our second step was to improve the turns to be faster and smoother. Very quickly, however, we noticed that further speed improvement was being limited by the intersections. If the robot was moving too quickly when it hit them, it would invariably screw up somewhere. Going slowly enough to survive the intersections led to unnecessarily slow driving on long straight segments, however.
3piの迷路パフォーマンスを改善しようとしていたときの最初のステップは、ロボットの最高速度をゆっくり上げながらPID定数をより良くチューニングすることによって、ライン追従能力を改善することでした。そして2つ目のステップは、旋回を速く、なめらかに改善することでした。とても速く、しかしながら、交差点によってさらなる速度の改善が制限されていることに気付きました。交差点にぶつかったときにロボットがあまりに速く移動していたなら、決まってどこかで失敗するでしょう。しかしながら、交差点を切り抜けるために十分ゆっくり進むことは長い直線区間を不必要にゆっくり進むことにつながりました。
Our solution was to time the length of every segment the robot encountered during the learning phase. The code would reset the timer at an intersection and then stop it when the 3pi hit the following intersection. As the program stored an array of visited intersections, it also stored the segment times in a parallel array, producing something like:
解決策は、ロボットが学習フェーズの間に遭遇した区画ごとに長さを《訳注:時間単位で》計ることでした。コードは交差点でタイマをリセットし、3piが次の交差点にぶつかったときに停止します。プログラムは訪れた交差点の配列を格納するように、区画の時間も並列する配列に格納し、次のようなものを生成します:
{ L, S, S, R, L, ... }
{ 3, 3, 6, 5, 8, ... }
The top array gives the action performed at each visited intersection (L = turned left, S = went straight, R = turned right), and the bottom array gives the amount of time spent driving along the segment that directly led to that intersection. The units of the segment times were chosen to provide numbers that can allow the robot to meaningfully differentiate between longer and shorter segments but that never exceed 255 for any segment in the maze. This second restriction means that the values can be stored in an array of unsigned chars (i.e. each segment’s time takes up just one byte of memory), which helps keep memory usage down. The ATmega168 has just 1024 bytes of RAM, so it’s important that applications like this store data in an efficient way that leaves enough room for the stack, which is also stored in RAM. A good rule of thumb is to leave 300 – 400 bytes of RAM available for the stack and data used by the Pololu AVR library (or more if you have some deeply nested functions or functions with a lot of local variables). Note that the ATmega328 has 2048 bytes of RAM, which gives you a bit more room for your data.
上の配列は訪れた交差点ごとに実行されたアクション(L=左折、S=直進、R=右折)を示し、下の配列は交差点に直接つながった区画の走行にかかった時間を示します。区画の時間の単位は、長い区画と短い区画を有意に区別できるように、しかし迷路のどの区画でも決して255を超えない値を提供できるように選ばれました。2つ目の制約は unsigned int 配列に格納できることを意味します(つまり、区画ごとの時間は1バイトのメモリのみを消費する)。これはメモリ使用量を抑えるのに役立ちます。 ATmega168 はたった1024バイトのRAMしかないため、アプリケーションがこのようにデータを効率的な方法で格納することは重要です。これはRAMに配置されるスタックに十分なスペースを残します。良い経験則は、Pololu AVR library が使用するスタックとデータ用に300~400バイトのRAMを残しておくことです(または深くネストされた関数や大量のローカル変数を持つ関数がある場合はそれ以上)。 ATmega328 は2048バイトのRAMを持ち、データ用の空間がもうちょっとあります。
Once the 3pi has learned the maze, the maze-driving algorigthm is essentially:
3piが迷路を学んだら、迷路走行アルゴリズムは本質的に:
-
If the robot is going straight at the next intersection, drive the current segment at high speed; don’t even worry about slowing down until we know we have an intersection coming up that will require a turn.
-
Otherwise, drive the current segment at high speed until time T has elapsed, at which point slow back down to normal speed until the next intersection is reached.
-
ロボットが次の交差点で直進する場合、現在の区画は高速で走行します。曲がる必要のある交差点が近づいたことを知るまで速度を落とす必要はありません。
-
その他の場合、時間Tが経過するまで現在の区画を高速に走行し、その時点で、次の交差点に到達するまでの間、通常の速度までゆっくり減速します。
The value T is computed from a function that uses the previously measured segment “length”. For short segments, T is negative and the 3pi just drives the entire segment at normal speed. For longer segments, T is positive and causes the 3pi to drive most of the segment at high speed before slowing down just in time to handle the intersection safely. We came up with a function for T on paper and then ran a series of tests to get the various constants right.
値Tは、前もって計測されたセグメントの長さを使用する関数から計算されます。短い区画では、Tは負の値になり、3piは区画全体を通常の速度で走行します。長い区画では、Tは正の値になり、交差点を安全に処理するためにちょうど間に合うように減速するまで、区画の大部分を高速で走行します。私たちはTの関数を机上で考えた後、様々な定数を正しく得るために、一連のテストを実施しました。
Typically, one might use encoders to measure the lengths of the segments. We were able to just use timing on the 3pi, however, because of the 3pi’s power system, which uses a regulated voltage for the motors and produces highly repeatable results. With a more traditional power system, motor speed would decrease as the batteries discharge, and a timing approach like this would potentially produce unreliable results. For example, if you were to use a robot with a more traditional power system, the function you come up with for T when the batteries are freshly charged might work poorly when they are nearly drained.
典型的には、区画の長さを測定する為にエンコーダを使用することがあります。3piの電源システムは、モーター用に調整された電圧を使用し、再現性の高い結果を作り出すため、3piではタイミングを使用するだけでした。より伝統的な電源システムでは、電池が放電するにつれてモーター速度は低下し、このようなタイミングアプローチは潜在的に信頼できない結果を作り出すでしょう。例えば、より伝統的な電源システムでロボットを使用しようとしていたとすると、電池が充電されたばかりのときにTに対して考え出した関数は、電池が空に近くなった時にうまく働かないかもしれません。
《訳注:3piの電源システムはモーターに出力する電圧を調整しており、電池残量の過多によってモーターの回転が変動することがない。そのため、タイミング情報(モーターの速度、駆動時間など?)があれば区画の長さを測定できる?》
Tip: Once you start significantly increasing your maze-solving speed, performance becomes dependent on the traction of the tires. Unfortunately, traction decreases over time as the tires pick up dust and dirt from the course. Our fast maze solver needs to have its tires cleaned every few runs or else it starts fishtailing on the turns, which slows it down and can even cause it to mess up. You can see the effects of this on the second (solution) run of the video (the tires hadn’t been cleaned recently). You can easily clean the tires by wiping them with a little rubbing alcohol on a paper towel.
ヒント: 迷路解決の速度を大幅に向上させ始めると、パフォーマンスはタイヤの静止摩擦に依存するようになります。残念なことに、タイヤがコースからゴミやほこりを拾うにつれて、静止摩擦は時間とともに減少します。私たちの高速な迷路ソルバーは、数回の走行ごとにタイヤを清掃する必要があります。そうしないと、旋回においてフィッシュテール【訳注:タイヤがスリップして尻振り状態になるさま】が始まり、速度の減少や混乱を招くこともあります。これがビデオの2回目の走行に影響することがわかります(タイヤはクリーニングされていません)。ペーパータオルと少量の消毒用アルコールで拭くことによって、あなたは簡単にタイヤをきれいにすることができます。