Selamat datang di dunia indah perencanaan gerak non-holonomis . Saya sarankan melakukan ini menggunakan perencana jalur grid kisi . Alternatif lain termasuk RRT kinodinamik , dan optimisasi lintasan . Sistem non-holonomis meliputi mobil, perahu, unicycles, atau benar-benar apa pun di mana kendaraan tidak dapat melakukan perjalanan ke arah yang diinginkan. Perencanaan untuk sistem ini jauh lebih sulit daripada sistem ekonomi dan sampai ~ 2000 berada di tepi penelitian akademis. Saat ini ada banyak algoritma untuk dipilih yang berfungsi dengan baik.
Begini cara kerjanya.
Negara
Konfigurasi mobil Anda q sebenarnya adalah keadaan 3D yang berisi posisi x, y mobil dan orientasinya t . Node dalam algoritma A * Anda sebenarnya adalah vektor 3D.
class Node
{
// The position and orientation of the car.
float x, y, theta;
}
Tindakan
Jadi bagaimana dengan tepinya?
Itu sedikit lebih sulit, karena mobil Anda benar-benar dapat memilih cara yang tidak terbatas untuk memutar setir. Jadi, kita dapat membuat ini dapat diakses grid perencana kisi dengan membatasi jumlah tindakan mobil dapat dilakukan untuk satu set diskrit, A . Demi kesederhanaan mari kita asumsikan bahwa mobil tidak mempercepat tetapi lebih dapat mengubah kecepatannya secara instan. Dalam kasus kami, A dapat sebagai berikut:
class Action
{
// The direction of the steering wheel.
float wheelDirection;
// The speed to go at in m/s.
float speed;
// The time that it takes to complete an action in seconds.
float dt;
}
Sekarang, kita dapat membuat serangkaian tindakan terpisah yang dapat diambil mobil kapan saja. Misalnya, kanan yang keras sambil menekan gas secara penuh selama 0,5 detik akan terlihat seperti ini:
Action turnRight;
turnRight.speed = 1;
turnRight.wheelDirection = 1;
turnRight.dt = 0.5;
Membuat mobil terbalik dan membuat cadangan akan terlihat seperti ini:
Action reverse;
reverse.speed = -1;
reverse.wheelDirection = 0;
reverse.dt = 0.5;
Dan daftar tindakan Anda akan terlihat seperti ini:
List<Action> actions = { turnRight, turnLeft, goStraight, reverse ...}
Anda juga membutuhkan cara untuk mendefinisikan bagaimana suatu tindakan yang dilakukan pada suatu simpul menghasilkan simpul baru. Ini disebut dinamika ke depan sistem.
// These forward dynamics are for a dubin's car that can change its
// course instantaneously.
Node forwardIntegrate(Node start, Action action)
{
// the speed of the car in theta, x and y.
float thetaDot = action.wheelDirection * TURNING_RADIUS;
// the discrete timestep in seconds that we integrate at.
float timestep = 0.001;
float x = start.x;
float y = start.y;
float theta = start.theta;
// Discrete Euler integration over the length of the action.
for (float t = 0; t < action.dt; t += timestep)
{
theta += timestep * thetaDot;
float xDot = action.speed * cos(theta);
float yDot = action.speed * sin(theta);
x += timestep * xDot;
y += timestep * yDot;
}
return Node(x, y, theta);
}
Sel Grid Terpisah
Sekarang, untuk membangun grid kisi, semua yang perlu kita lakukan adalah hash negara bagian mobil ke sel-sel jaringan diskrit. Ini mengubahnya menjadi node diskrit yang dapat diikuti oleh A *. Ini sangat penting karena jika tidak A * tidak akan memiliki cara untuk mengetahui apakah dua keadaan mobil sebenarnya sama untuk membandingkannya. Dengan hashing untuk integer nilai-nilai sel grid, ini menjadi sepele.
GridCell hashNode(Node node)
{
GridCell cell;
cell.x = round(node.x / X_RESOLUTION);
cell.y = round(node.y / Y_RESOLUTION);
cell.theta = round(node.theta / THETA_RESOLUTION);
return cell;
}
Sekarang, kita bisa melakukan rencana A * di mana GridCells adalah node, Actions adalah tepi antara node, dan Start dan Goal diekspresikan dalam istilah GridCells. Heuristik antara dua GridCell adalah jarak dalam x dan y ditambah jarak sudut dalam theta.
Mengikuti Jalan
Sekarang kita memiliki jalur dalam hal GridCells dan Tindakan di antara mereka, kita dapat menulis pengikut jalur untuk mobil. Karena sel-sel grid terpisah, mobil akan melompat di antara sel. Jadi kita harus memuluskan gerakan mobil di sepanjang jalan. Jika gim Anda menggunakan mesin fisika, ini dapat dilakukan dengan menulis pengendali kemudi yang mencoba menjaga mobil sedekat mungkin ke jalan setapak. Jika tidak, Anda dapat menghidupkan jalur menggunakan kurva bezier atau hanya dengan rata-rata beberapa titik terdekat di jalur.