@@ -45,8 +45,16 @@ def __init__(self):
4545 self .to_goal_cost_gain = 0.15
4646 self .speed_cost_gain = 1.0
4747 self .obstacle_cost_gain = 1.0
48+ self .robot_type = 'circle' # circle or rectangle
49+
50+ # if robot_type == circle
51+ # Also used to check if goal is reached in both types
4852 self .robot_radius = 1.0 # [m] for collision check
4953
54+ # if robot_type == rectangle
55+ self .robot_width = 0.5 # [m] for collision check
56+ self .robot_length = 1.2 # [m] for collision check
57+
5058
5159def motion (x , u , dt ):
5260 """
@@ -141,8 +149,25 @@ def calc_obstacle_cost(trajectory, ob, config):
141149 dx = trajectory [:, 0 ] - ox [:, None ]
142150 dy = trajectory [:, 1 ] - oy [:, None ]
143151 r = np .sqrt (np .square (dx ) + np .square (dy ))
144- if (r <= config .robot_radius ).any ():
145- return float ("Inf" )
152+
153+ if config .robot_type == 'rectangle' :
154+ yaw = trajectory [:, 2 ]
155+ rot = np .array ([[np .cos (yaw ), - np .sin (yaw )], [np .sin (yaw ), np .cos (yaw )]])
156+ local_ob = ob [:, None ] - trajectory [:, 0 :2 ]
157+ local_ob = local_ob .reshape (- 1 , local_ob .shape [- 1 ])
158+ local_ob = np .array ([local_ob @ - x for x in rot .T ])
159+ local_ob = local_ob .reshape (- 1 , local_ob .shape [- 1 ])
160+ upper_check = local_ob [:, 0 ] <= config .robot_length / 2
161+ right_check = local_ob [:, 1 ] <= config .robot_width / 2
162+ bottom_check = local_ob [:, 0 ] >= - config .robot_length / 2
163+ left_check = local_ob [:, 1 ] >= - config .robot_width / 2
164+ if (np .logical_and (np .logical_and (upper_check , right_check ),
165+ np .logical_and (bottom_check , left_check ))).any ():
166+ return float ("Inf" )
167+ elif config .robot_type == 'circle' :
168+ if (r <= config .robot_radius ).any ():
169+ return float ("Inf" )
170+
146171 min_r = np .min (r )
147172 return 1.0 / min_r # OK
148173
@@ -166,7 +191,30 @@ def plot_arrow(x, y, yaw, length=0.5, width=0.1): # pragma: no cover
166191 plt .plot (x , y )
167192
168193
169- def main (gx = 10.0 , gy = 10.0 ):
194+ def plot_robot (x , y , yaw , config ): # pragma: no cover
195+ if config .robot_type == 'rectangle' :
196+ outline = np .array ([[- config .robot_length / 2 , config .robot_length / 2 ,
197+ (config .robot_length / 2 ), - config .robot_length / 2 ,
198+ - config .robot_length / 2 ],
199+ [config .robot_width / 2 , config .robot_width / 2 ,
200+ - config .robot_width / 2 , - config .robot_width / 2 ,
201+ config .robot_width / 2 ]])
202+ Rot1 = np .array ([[math .cos (yaw ), math .sin (yaw )],
203+ [- math .sin (yaw ), math .cos (yaw )]])
204+ outline = (outline .T .dot (Rot1 )).T
205+ outline [0 , :] += x
206+ outline [1 , :] += y
207+ plt .plot (np .array (outline [0 , :]).flatten (),
208+ np .array (outline [1 , :]).flatten (), "-k" )
209+ elif config .robot_type == 'circle' :
210+ circle = plt .Circle ((x , y ), config .robot_radius , color = "b" )
211+ plt .gcf ().gca ().add_artist (circle )
212+ out_x , out_y = (np .array ([x , y ]) +
213+ np .array ([np .cos (yaw ), np .sin (yaw )]) * config .robot_radius )
214+ plt .plot ([x , out_x ], [y , out_y ], "-k" )
215+
216+
217+ def main (gx = 10.0 , gy = 10.0 , robot_type = 'circle' ):
170218 print (__file__ + " start!!" )
171219 # initial state [x(m), y(m), yaw(rad), v(m/s), omega(rad/s)]
172220 x = np .array ([0.0 , 0.0 , math .pi / 8.0 , 0.0 , 0.0 ])
@@ -193,6 +241,7 @@ def main(gx=10.0, gy=10.0):
193241 # input [forward speed, yawrate]
194242 u = np .array ([0.0 , 0.0 ])
195243 config = Config ()
244+ config .robot_type = robot_type
196245 trajectory = np .array (x )
197246
198247 while True :
@@ -206,6 +255,7 @@ def main(gx=10.0, gy=10.0):
206255 plt .plot (x [0 ], x [1 ], "xr" )
207256 plt .plot (goal [0 ], goal [1 ], "xb" )
208257 plt .plot (ob [:, 0 ], ob [:, 1 ], "ok" )
258+ plot_robot (x [0 ], x [1 ], x [2 ], config )
209259 plot_arrow (x [0 ], x [1 ], x [2 ])
210260 plt .axis ("equal" )
211261 plt .grid (True )
0 commit comments