11from typing import List , Tuple , Union , Dict
22from ..component import Component
3- from ...state import AllState , VehicleState , Path , Trajectory , Route , ObjectFrameEnum , AgentState , Obstacle , ObjectPose
3+ from ...state import AllState , VehicleState , Path , Trajectory , Route , ObjectFrameEnum , AgentState , Obstacle , ObjectPose , PhysicalObject
44from ...utils import serialization , settings
55from ...mathutils .transforms import vector_madd
66from ...mathutils .quadratic_equation import quad_root
@@ -26,9 +26,9 @@ def __init__(self, vehicle=None, obstacles=None, actions=None):
2626 self ._vehicle = None
2727
2828 # SecondOrderDubinsCar() #x = (tx,ty,theta,v,dtheta) and u = (fwd_accel,wheel_angle_rate)
29- self .vehicle_sim = IntegratorControlSpace (SecondOrderDubinsCar (), T = 0.75 , dt = 0.25 )
29+ self .vehicle_sim = IntegratorControlSpace (SecondOrderDubinsCar (), T = 1 , dt = 0.1 )
3030 #@TODO create a more standardized way to define the actions
31- self ._actions = [(1 , - 0.5 ), (1 , - 0.25 ), (1 ,0 ), (1 , 0.25 ), (1 ,0.5 ),
31+ self ._actions = [(2 , - 0.5 ), (2 , - 0.25 ), (2 ,0 ), (2 , 0.25 ), (2 ,0.5 ),
3232 (0 ,0 ), (- 1 , - 0.5 ), (- 1 ,0 ), (- 1 , 0.5 )]
3333
3434 @property
@@ -60,19 +60,38 @@ def is_goal_reached(self, current: List[float], goal: List[float]):
6060 # @TODO Currently, the threshold is just a random number, get rid of magic constants
6161 # print(f"Current Pose: {current}")
6262 # print(f"Goal Pose: {goal}")
63- if np .abs (current [3 ]) > 0.5 : return False # car must be stopped, this equality will only work in simulation
63+ if np .abs (current [3 ]) > 1 : return False # car must be stopped, this equality will only work in simulation
6464 return np .linalg .norm (np .array ([current [0 ], current [1 ]]) - np .array ([goal [0 ], goal [1 ]])) < 0.5
6565 vehicle
66- def heuristic_cost_estimate (self , vehicle_state_1 , vehicle_state_2 ):
66+ def heuristic_cost_estimate (self , state_1 , state_2 ):
6767 # @TODO Consider creating a more sophisticated heuristic
68- """computes the 'direct' distance between two (x,y) tuples"""
68+ """computes the 'direct' distance between two (x,y) tuples.
69+ The states here are (x,y,theta,v,dtheta,t)
70+ """
71+ (x1 , y1 , theta1 , v1 , dtheta1 ,t1 ) = state_1
72+ (x2 , y2 , theta2 , v2 , dtheta2 , t2 ) = state_2
6973
70- return math .hypot (vehicle_state_2 [ 0 ] - vehicle_state_1 [ 0 ], vehicle_state_2 [ 1 ] - vehicle_state_1 [ 1 ] )
74+ return math .hypot (x2 - x1 , y2 - y1 , 2 * ( v2 - v1 ) )
7175 #return math.hypot(x2 - x1, y2 - y1, theta2 - theta1, v2-v1, dtheta2-dtheta1)
7276
73- def distance_between (self , n1 , n2 ):
74- """this method always returns 1, as two 'neighbors' are always adajcent"""
75- return 1
77+ def terminal_cost_estimate (self , state_1 , state_2 ):
78+ # @TODO Consider creating a more sophisticated heuristic
79+ """computes the 'direct' distance between two (x,y) tuples.
80+ The states here are (x,y,theta,v,dtheta,t)
81+ """
82+ (x1 , y1 , theta1 , v1 , dtheta1 ,t1 ) = state_1
83+ (x2 , y2 , theta2 , v2 , dtheta2 , t2 ) = state_2
84+
85+ return math .hypot (x2 - x1 , y2 - y1 )
86+
87+ def distance_between (self , state_1 , state_2 ):
88+ """
89+ The states here are (x,y,theta,v,dtheta,t)
90+ """
91+ (x1 , y1 , theta1 , v1 , dtheta1 ,t1 ) = state_1
92+ (x2 , y2 , theta2 , v2 , dtheta2 , t2 ) = state_2
93+
94+ return math .hypot (x2 - x1 , y2 - y1 )
7695
7796 def neighbors (self , node ):
7897 """ for a given configuration of the car in the maze, returns up to 4 adjacent(north,east,south,west)
@@ -101,13 +120,44 @@ def is_valid_neighbor(self, path):
101120 path (_type_): _description_
102121 """
103122 for obstacle in self .obstacles :
123+ # print(f"Obstacle: {obstacle}")
104124 for point in path :
125+ vehicle_polygon = self .state_to_polygon (point )
126+ # print(f"Vehicle Polygon: {vehicle_polygon}")
105127 # print(point)
106128 # print(obstacle.polygon_parent())
107- if collisions .circle_intersects_polygon_2d (point [:- 1 ], 1 , obstacle .polygon_parent ()):
129+ # print("====================================")
130+ # print(f"Vehicle Polygon: {vehicle_polygon}")
131+ # print(f"Obstacle Polygon: {obstacle.polygon_parent()}")
132+ # print(f"Point: {point}")
133+ if collisions .polygon_intersects_polygon_2d (vehicle_polygon , obstacle .polygon_parent ()):
108134 #polygon_intersects_polygon_2d when we have the acutal car geometry
109135 return False
110136 return True
137+
138+ def state_to_polygon (self , state ):
139+ """Convert a state to a polygon. The state is of the form (x,y,theta,v,dtheta,t)
140+
141+ Args:
142+ state (_type_): _description_
143+
144+ Returns:
145+ _type_: _description_
146+ """
147+ x = state [0 ]
148+ y = state [1 ]
149+ theta = state [2 ]
150+ v = state [3 ]
151+ dtheta = state [4 ]
152+ t = state [5 ]
153+
154+ pose = ObjectPose (frame = ObjectFrameEnum .START ,t = t , x = x ,y = y ,z = 0 ,yaw = theta )
155+
156+ temp_obj = PhysicalObject (pose = pose ,
157+ dimensions = self .vehicle .to_object ().dimensions ,
158+ outline = self .vehicle .to_object ().outline )
159+
160+ return temp_obj .polygon ()
111161
112162
113163class ParkingPlanner (Component ):
@@ -171,6 +221,9 @@ def update(self, state : AllState) -> Trajectory:
171221 """
172222 vehicle = state .vehicle # type: VehicleState
173223 obstacles = state .obstacles # type: Dict[str, Obstacle]
224+ agents = state .agents # type: Dict[str, AgentState]
225+ print (f"Obstacles { obstacles } " )
226+ print (f"Agents { agents } " )
174227 route = state .route
175228 goal_point = route .points [- 1 ] # I might need to change this to the same frame as the car?
176229 goal_pose = ObjectPose (frame = ObjectFrameEnum .START ,t = 15 , x = goal_point [0 ],y = goal_point [1 ],z = 0 ,yaw = 0 )
@@ -184,18 +237,19 @@ def update(self, state : AllState) -> Trajectory:
184237
185238
186239 # Update the planner
187- self .planner .obstacles = list (obstacles .values ())
240+ # self.planner.obstacles = list(obstacles.values())
241+ self .planner .obstacles = list (agents .values ())
188242 self .planner .vehicle = vehicle
189243
190244 # Compute the new trajectory and return it
191- res = list (self .planner .astar (start_state , goal_state ))
245+ res = list (self .planner .astar (start_state , goal_state , 100 ))
192246 points = [state [:2 ] for state in res ]
193247 times = [state [5 ] for state in res ]
194248 path = Path (frame = vehicle .pose .frame , points = points )
195249 traj = Trajectory (path .frame ,points ,times )
196- print ("===========================" )
197- print (f"Points: { points } " )
198- print (f"Times: { times } " )
250+ # print("===========================")
251+ # print(f"Points: {points}")
252+ # print(f"Times: {times}")
199253 # route = Path(frame=vehicle.pose.frame, points=points)
200254 # traj = longitudinal_plan(route, 2, -2, 10, vehicle.v, "milestone")
201255 # print(traj)
0 commit comments