Skip to content

Commit ca1b6b7

Browse files
committed
2 parents 0067577 + 4fcd203 commit ca1b6b7

File tree

4 files changed

+90
-36
lines changed

4 files changed

+90
-36
lines changed

.github/workflows/greetings.yml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
name: Greetings
2+
3+
on: [pull_request, issues]
4+
5+
jobs:
6+
greeting:
7+
runs-on: ubuntu-latest
8+
steps:
9+
- uses: actions/first-interaction@v1
10+
with:
11+
repo-token: ${{ secrets.GITHUB_TOKEN }}
12+
issue-message: 'Message that will be displayed on users'' This is first issue for you on this project'
13+
pr-message: 'Message that will be displayed on users'' This is first pr for you on this project'
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
name: Python package
2+
3+
on: [push]
4+
5+
jobs:
6+
build:
7+
8+
runs-on: ubuntu-latest
9+
strategy:
10+
max-parallel: 4
11+
matrix:
12+
python-version: [3.6, 3.7]
13+
14+
steps:
15+
- uses: actions/checkout@v1
16+
- name: Set up Python ${{ matrix.python-version }}
17+
uses: actions/setup-python@v1
18+
with:
19+
python-version: ${{ matrix.python-version }}
20+
- name: Install dependencies
21+
run: |
22+
python -m pip install --upgrade pip
23+
pip install -r requirements.txt
24+
- name: Lint with flake8
25+
run: |
26+
pip install flake8
27+
# stop the build if there are Python syntax errors or undefined names
28+
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
29+
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
30+
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
31+
- name: install coverage
32+
run: pip install coverage
33+
- name: Test
34+
run: bash runtests.sh

PathPlanning/DynamicWindowApproach/dynamic_window_approach.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
Mobile robot motion planning sample with Dynamic Window Approach
44
5-
author: Atsushi Sakai (@Atsushi_twi), Goktug Karakasli
5+
author: Atsushi Sakai (@Atsushi_twi), Göktuğ Karakaşlı
66
77
"""
88

@@ -172,7 +172,7 @@ def calc_obstacle_cost(trajectory, ob, config):
172172
rot = np.transpose(rot, [2, 0, 1])
173173
local_ob = ob[:, None] - trajectory[:, 0:2]
174174
local_ob = local_ob.reshape(-1, local_ob.shape[-1])
175-
local_ob = np.array([local_ob @ -x for x in rot])
175+
local_ob = np.array([local_ob @ x for x in rot])
176176
local_ob = local_ob.reshape(-1, local_ob.shape[-1])
177177
upper_check = local_ob[:, 0] <= config.robot_length / 2
178178
right_check = local_ob[:, 1] <= config.robot_width / 2

PathPlanning/InformedRRTStar/informed_rrt_star.py

Lines changed: 41 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ def informed_rrt_star_search(self, animation=True):
4040
self.node_list = [self.start]
4141
# max length we expect to find in our 'informed' sample space, starts as infinite
4242
cBest = float('inf')
43-
pathLen = float('inf')
4443
solutionSet = set()
4544
path = None
4645

@@ -74,25 +73,24 @@ def informed_rrt_star_search(self, animation=True):
7473
newNode = self.get_new_node(theta, nind, nearestNode)
7574
d = self.line_cost(nearestNode, newNode)
7675

77-
isCollision = self.collision_check(newNode, self.obstacle_list)
78-
isCollisionEx = self.check_collision_extend(nearestNode, theta, d)
76+
noCollision = self.check_collision(nearestNode, theta, d)
7977

80-
if isCollision and isCollisionEx:
78+
if noCollision:
8179
nearInds = self.find_near_nodes(newNode)
8280
newNode = self.choose_parent(newNode, nearInds)
8381

8482
self.node_list.append(newNode)
8583
self.rewire(newNode, nearInds)
8684

8785
if self.is_near_goal(newNode):
88-
solutionSet.add(newNode)
89-
lastIndex = len(self.node_list) - 1
90-
tempPath = self.get_final_course(lastIndex)
91-
tempPathLen = self.get_path_len(tempPath)
92-
if tempPathLen < pathLen:
93-
path = tempPath
94-
cBest = tempPathLen
95-
86+
if self.check_segment_collision(newNode.x, newNode.y, self.goal.x , self.goal.y):
87+
solutionSet.add(newNode)
88+
lastIndex = len(self.node_list) - 1
89+
tempPath = self.get_final_course(lastIndex)
90+
tempPathLen = self.get_path_len(tempPath)
91+
if tempPathLen < cBest:
92+
path = tempPath
93+
cBest = tempPathLen
9694
if animation:
9795
self.draw_graph(xCenter=xCenter,
9896
cBest=cBest, cMin=cMin,
@@ -110,7 +108,7 @@ def choose_parent(self, newNode, nearInds):
110108
dy = newNode.y - self.node_list[i].y
111109
d = math.sqrt(dx ** 2 + dy ** 2)
112110
theta = math.atan2(dy, dx)
113-
if self.check_collision_extend(self.node_list[i], theta, d):
111+
if self.check_collision(self.node_list[i], theta, d):
114112
dList.append(self.node_list[i].cost + d)
115113
else:
116114
dList.append(float('inf'))
@@ -194,17 +192,6 @@ def get_nearest_list_index(nodes, rnd):
194192
minIndex = dList.index(min(dList))
195193
return minIndex
196194

197-
@staticmethod
198-
def collision_check(newNode, obstacleList):
199-
for (ox, oy, size) in obstacleList:
200-
dx = ox - newNode.x
201-
dy = oy - newNode.y
202-
d = dx * dx + dy * dy
203-
if d <= 1.1 * size ** 2:
204-
return False # collision
205-
206-
return True # safe
207-
208195
def get_new_node(self, theta, nind, nearestNode):
209196
newNode = copy.deepcopy(nearestNode)
210197

@@ -234,20 +221,40 @@ def rewire(self, newNode, nearInds):
234221
if nearNode.cost > scost:
235222
theta = math.atan2(newNode.y - nearNode.y,
236223
newNode.x - nearNode.x)
237-
if self.check_collision_extend(nearNode, theta, d):
224+
if self.check_collision(nearNode, theta, d):
238225
nearNode.parent = n_node - 1
239226
nearNode.cost = scost
227+
228+
@staticmethod
229+
def distance_squared_point_to_segment(v, w, p):
230+
# Return minimum distance between line segment vw and point p
231+
if (np.array_equal(v, w)):
232+
return (p-v).dot(p-v) # v == w case
233+
l2 = (w-v).dot(w-v) # i.e. |w-v|^2 - avoid a sqrt
234+
# Consider the line extending the segment, parameterized as v + t (w - v).
235+
# We find projection of point p onto the line.
236+
# It falls where t = [(p-v) . (w-v)] / |w-v|^2
237+
# We clamp t from [0,1] to handle points outside the segment vw.
238+
t = max(0, min(1, (p - v).dot(w - v) / l2))
239+
projection = v + t * (w - v) # Projection falls on the segment
240+
return (p-projection).dot(p-projection)
241+
242+
def check_segment_collision(self, x1, y1, x2, y2):
243+
for (ox, oy, size) in self.obstacle_list:
244+
dd = self.distance_squared_point_to_segment(
245+
np.array([x1, y1]),
246+
np.array([x2, y2]),
247+
np.array([ox, oy]))
248+
if dd <= size**2:
249+
return False # collision
250+
return True
240251

241-
def check_collision_extend(self, nearNode, theta, d):
242-
tmpNode = copy.deepcopy(nearNode)
243-
244-
for i in range(int(d / self.expand_dis)):
245-
tmpNode.x += self.expand_dis * math.cos(theta)
246-
tmpNode.y += self.expand_dis * math.sin(theta)
247-
if not self.collision_check(tmpNode, self.obstacle_list):
248-
return False
249252

250-
return True
253+
def check_collision(self, nearNode, theta, d):
254+
tmpNode = copy.deepcopy(nearNode)
255+
endx = tmpNode.x + math.cos(theta)*d
256+
endy = tmpNode.y + math.sin(theta)*d
257+
return self.check_segment_collision(tmpNode.x, tmpNode.y, endx, endy)
251258

252259
def get_final_course(self, lastIndex):
253260
path = [[self.goal.x, self.goal.y]]

0 commit comments

Comments
 (0)