ORCA避障原始碼筆記

kashin05發表於2024-12-08

參考資料

https://gamma.cs.unc.edu/ORCA/publications/ORCA.pdf

https://gamma.cs.unc.edu/RVO2/

數學知識

1.向量的點乘 dotProduct,計算方法:1. 2.

作用:點積如果為負,則a,b形成的角為鈍角;如果為零,那麼a,b垂直;如果為正,那麼a,b形成的角為銳角

2.向量a,向量b,det(a,b)表示行列式的值,計算方法x1y2 - x2y1,同時也是叉乘的值

作用:1.以兩個向量為鄰邊的平行四邊形的有向面積,2.小於0表示b在a的順時針方向,大於0表示b在a逆時針方向,等於0表示a,b平行

下圖是碰撞需要修正,並且保證最短修正的兩種情況,

1) 將速度修正到切線上

2) 將速度修正到圓

1,

final double dotProduct1 = w.dotProduct(relativePosition);
dotProduct1 < 0.0 && dotProduct1 * dotProduct1 > combinedRadiusSq * wLengthSq

這個程式碼是為了判斷當前是哪種情況,

向量w = 相對速度 - 相對位置

dotProduct1小於0,表示向量w與相對位置的夾角為鈍角,即AE與AO的角為銳角(需要先判斷這個,只有銳角範圍內cos單調遞減)

dotProduct1 * dotProduct1 > combinedRadiusSq * wLengthSq,角OAE小於角OAD

推導:

cos在0-90單調遞減

角OAE < 角OAD

=> cosOAE > cosOAD

=> OA*cosOAE > OA*cosOAD (同時乘以OA)

=> OA*cosOAE > AD (OA*cosOAD = AD)

=> OA * AE * cosOAE > AE * AD (同時乘以AE)

=> dotProduct1 * dotProduct1 > combinedRadiusSq * wLengthSq

2

direction = new Vector2D(relativePosition.getX() * leg - relativePosition.getY() * combinedRadius, relativePosition.getX() * combinedRadius + relativePosition.getY() * leg)

這段程式碼為了計算第一情況,修正速度的落點,

leg為OD的長度,假設direction為line的方向,即向量OD的單位向量DIR(a, b)順時針的單位向量DIE (b, -a),A的座標(x, y)

向量OA 點乘 向量DIR = 向量OA的長度 * 1 * cosAOD

=> x*a + y*b = leg

向量OA 點乘 向量DIE = 向量OA的長度 * 1 * cosOAD

=>x*b - y*a = combinedRadius

結合這兩個式子就可以解a,b,

RVOMath.det(relativePosition, w) > 0.0

這個在判斷修正方向是在相對位置的左邊還是右邊

3

速度的可選區域為line方向的左側, linearProgram2 找到可行域的交集,即line的交集

3.1

RVOMath.det(lines.get(lineNo).direction, lines.get(lineNo).point.subtract(newVelocity)) > 0.0

大於0說明newVelocity在line的右側,不在line的可行域內,需要重新計算速度

3.2

如圖,綠色為line i, 黑色為line no

final double denominator = RVOMath.det(lines.get(lineNo).direction, lines.get(i).direction);
final double numerator = RVOMath.det(lines.get(i).direction, lines.get(lineNo).point.subtract(lines.get(i).point));
final double t = numerator / denominator;

denominator為BCED的面積 = 2個DBC的面積 = 2 * 1/2 * BP2 * 高

numerator為PGFP2的面積 = 2個GPP2 的面積 = 2個DBP2的面積 = 2 * 1/2 * BC * 高

t = numerator / denominator = BP2 / BC = BP2

t 為line i 和 line no 的交點 到 line point 的距離

4

linearProgram3

如果找不到line的交集,則執行linearProgram3,從上次失敗的line開始往後遍歷

將line i 之前的line做一個修正,修正的方法是:(1)將point修正到交點,(2)將方向修正到角平分線,靠近i的方向

RVOMath.det(lines.get(i).direction, lines.get(i).point.subtract(newVelocity)) > distance

這段程式碼用來判斷是否需要修正速度,如果修正後的速度與當前line的距離大於前一個line的距離大,那麼需要修正。

因為修正後速度將在角平分線上,一定距離當前line更近

相關文章