Skip to content

Commit effddd2

Browse files
authored
Potential field - potential range and ocillations (AtsushiSakai#345)
* Potential cover start and goal as well * Oscillation detection and fix potential look if outside range * Formatting * cleaner and flexible oscillation detection Co-authored-by: Adi Vardi <[email protected]>
1 parent fa1585d commit effddd2

File tree

1 file changed

+33
-7
lines changed

1 file changed

+33
-7
lines changed

PathPlanning/PotentialFieldPlanning/potential_field_planning.py

+33-7
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,25 @@
99
1010
"""
1111

12+
from collections import deque
1213
import numpy as np
1314
import matplotlib.pyplot as plt
1415

1516
# Parameters
1617
KP = 5.0 # attractive potential gain
1718
ETA = 100.0 # repulsive potential gain
1819
AREA_WIDTH = 30.0 # potential area width [m]
20+
# the number of previous positions used to check oscillations
21+
OSCILLATIONS_DETECTION_LENGTH = 3
1922

2023
show_animation = True
2124

2225

23-
def calc_potential_field(gx, gy, ox, oy, reso, rr):
24-
minx = min(ox) - AREA_WIDTH / 2.0
25-
miny = min(oy) - AREA_WIDTH / 2.0
26-
maxx = max(ox) + AREA_WIDTH / 2.0
27-
maxy = max(oy) + AREA_WIDTH / 2.0
26+
def calc_potential_field(gx, gy, ox, oy, reso, rr, sx, sy):
27+
minx = min(min(ox), sx, gx) - AREA_WIDTH / 2.0
28+
miny = min(min(oy), sy, gy) - AREA_WIDTH / 2.0
29+
maxx = max(max(ox), sx, gx) + AREA_WIDTH / 2.0
30+
maxy = max(max(oy), sy, gy) + AREA_WIDTH / 2.0
2831
xw = int(round((maxx - minx) / reso))
2932
yw = int(round((maxy - miny) / reso))
3033

@@ -84,10 +87,26 @@ def get_motion_model():
8487
return motion
8588

8689

90+
def oscillations_detection(previous_ids, ix, iy):
91+
previous_ids.append((ix, iy))
92+
93+
if (len(previous_ids) > OSCILLATIONS_DETECTION_LENGTH):
94+
previous_ids.popleft()
95+
96+
# check if contains any duplicates by copying into a set
97+
previous_ids_set = set()
98+
for index in previous_ids:
99+
if index in previous_ids_set:
100+
return True
101+
else:
102+
previous_ids_set.add(index)
103+
return False
104+
105+
87106
def potential_field_planning(sx, sy, gx, gy, ox, oy, reso, rr):
88107

89108
# calc potential field
90-
pmap, minx, miny = calc_potential_field(gx, gy, ox, oy, reso, rr)
109+
pmap, minx, miny = calc_potential_field(gx, gy, ox, oy, reso, rr, sx, sy)
91110

92111
# search path
93112
d = np.hypot(sx - gx, sy - gy)
@@ -106,14 +125,17 @@ def potential_field_planning(sx, sy, gx, gy, ox, oy, reso, rr):
106125

107126
rx, ry = [sx], [sy]
108127
motion = get_motion_model()
128+
previous_ids = deque()
129+
109130
while d >= reso:
110131
minp = float("inf")
111132
minix, miniy = -1, -1
112133
for i, _ in enumerate(motion):
113134
inx = int(ix + motion[i][0])
114135
iny = int(iy + motion[i][1])
115-
if inx >= len(pmap) or iny >= len(pmap[0]):
136+
if inx >= len(pmap) or iny >= len(pmap[0]) or inx < 0 or iny < 0:
116137
p = float("inf") # outside area
138+
print("outside potential!")
117139
else:
118140
p = pmap[inx][iny]
119141
if minp > p:
@@ -128,6 +150,10 @@ def potential_field_planning(sx, sy, gx, gy, ox, oy, reso, rr):
128150
rx.append(xp)
129151
ry.append(yp)
130152

153+
if (oscillations_detection(previous_ids, ix, iy)):
154+
print("Oscillation detected at ({},{})!".format(ix, iy))
155+
break
156+
131157
if show_animation:
132158
plt.plot(ix, iy, ".r")
133159
plt.pause(0.01)

0 commit comments

Comments
 (0)