9
9
10
10
"""
11
11
12
+ from collections import deque
12
13
import numpy as np
13
14
import matplotlib .pyplot as plt
14
15
15
16
# Parameters
16
17
KP = 5.0 # attractive potential gain
17
18
ETA = 100.0 # repulsive potential gain
18
19
AREA_WIDTH = 30.0 # potential area width [m]
20
+ # the number of previous positions used to check oscillations
21
+ OSCILLATIONS_DETECTION_LENGTH = 3
19
22
20
23
show_animation = True
21
24
22
25
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
28
31
xw = int (round ((maxx - minx ) / reso ))
29
32
yw = int (round ((maxy - miny ) / reso ))
30
33
@@ -84,10 +87,26 @@ def get_motion_model():
84
87
return motion
85
88
86
89
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
+
87
106
def potential_field_planning (sx , sy , gx , gy , ox , oy , reso , rr ):
88
107
89
108
# 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 )
91
110
92
111
# search path
93
112
d = np .hypot (sx - gx , sy - gy )
@@ -106,14 +125,17 @@ def potential_field_planning(sx, sy, gx, gy, ox, oy, reso, rr):
106
125
107
126
rx , ry = [sx ], [sy ]
108
127
motion = get_motion_model ()
128
+ previous_ids = deque ()
129
+
109
130
while d >= reso :
110
131
minp = float ("inf" )
111
132
minix , miniy = - 1 , - 1
112
133
for i , _ in enumerate (motion ):
113
134
inx = int (ix + motion [i ][0 ])
114
135
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 :
116
137
p = float ("inf" ) # outside area
138
+ print ("outside potential!" )
117
139
else :
118
140
p = pmap [inx ][iny ]
119
141
if minp > p :
@@ -128,6 +150,10 @@ def potential_field_planning(sx, sy, gx, gy, ox, oy, reso, rr):
128
150
rx .append (xp )
129
151
ry .append (yp )
130
152
153
+ if (oscillations_detection (previous_ids , ix , iy )):
154
+ print ("Oscillation detected at ({},{})!" .format (ix , iy ))
155
+ break
156
+
131
157
if show_animation :
132
158
plt .plot (ix , iy , ".r" )
133
159
plt .pause (0.01 )
0 commit comments