Skip to content

Commit 24fdd42

Browse files
committed
integrate lane based system
1 parent acc06b7 commit 24fdd42

9 files changed

Lines changed: 598 additions & 61 deletions

File tree

6.49 MB
Binary file not shown.

GEMstack/onboard/perception/parking_detection.py

Lines changed: 98 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44
from sensor_msgs.msg import PointCloud2
55
from typing import Dict
66
from ..component import Component
7-
from ...state import ObjectPose, ObjectFrameEnum, Obstacle, ObstacleMaterialEnum, ObstacleStateEnum
7+
from ...state import ObjectPose, ObjectFrameEnum, Obstacle, ObstacleMaterialEnum, ObstacleState
88
from ..interface.gem import GEMInterface
99
from .utils.constants import *
10+
from .utils.math_utils import *
1011
from .utils.detection_utils import *
1112
from .utils.parking_utils import *
1213
from .utils.visualization_utils import *
@@ -23,10 +24,11 @@ def __init__(
2324
# Init Variables
2425
self.vehicle_interface = vehicle_interface
2526
self.cone_pts_3D = []
26-
self.ordered_cone_ground_centers_2D = []
27-
self.goal_parking_spot = None
28-
self.parking_obstacles_pose = []
29-
self.parking_obstacles_dim = []
27+
self.grouped_ordered_ground_centers_2D = []
28+
self.parking_goal = None
29+
self.best_parking_spot = None
30+
self.parking_obstacles_poses = []
31+
self.parking_obstacles_dims = []
3032
self.ground_threshold = GROUND_THRESHOLD
3133
self.visualization = visualize_3d
3234

@@ -47,7 +49,8 @@ def __init__(
4749
self.pub_lidar_top_vehicle_pc2 = rospy.Publisher("lidar_top_vehicle/point_cloud", PointCloud2, queue_size=10)
4850
self.pub_vehicle_marker = rospy.Publisher("vehicle/marker", MarkerArray, queue_size=10)
4951
self.pub_cones_centers_pc2 = rospy.Publisher("cones_detection/centers/point_cloud", PointCloud2, queue_size=10)
50-
self.pub_parking_spot_marker = rospy.Publisher("parking_spot_detection/marker", MarkerArray, queue_size=10)
52+
self.pub_parking_spot_marker = rospy.Publisher("parking_spot_detection/spot/marker", MarkerArray, queue_size=10)
53+
self.pub_parking_goal_marker = rospy.Publisher("parking_spot_detection/goal/marker", MarkerArray, queue_size=10)
5154
self.pub_polygon_marker = rospy.Publisher("polygon_detection/marker", MarkerArray, queue_size=10)
5255
self.pub_obstacles_marker = rospy.Publisher("obstacle_detection/marker", MarkerArray, queue_size=10)
5356

@@ -59,10 +62,11 @@ def callback(self, top_lidar_msg):
5962
if self.visualization:
6063
self.visualize(
6164
self.cone_pts_3D,
62-
self.ordered_cone_ground_centers_2D,
63-
self.goal_parking_spot,
64-
self.parking_obstacles_pose,
65-
self.parking_obstacles_dim,
65+
self.grouped_ordered_ground_centers_2D,
66+
self.parking_goal,
67+
self.best_parking_spot,
68+
self.parking_obstacles_poses,
69+
self.parking_obstacles_dims,
6670
lidar_ouster_frame
6771
)
6872

@@ -81,10 +85,11 @@ def state_outputs(self) -> list:
8185

8286
def visualize(self,
8387
cone_pts_3D,
84-
ordered_cone_ground_centers_2D,
85-
goal_parking_spot,
86-
parking_obstacles_pose,
87-
parking_obstacles_dim,
88+
grouped_ordered_ground_centers_2D,
89+
parking_goal,
90+
best_parking_spot,
91+
parking_obstacles_poses,
92+
parking_obstacles_dims,
8893
lidar_ouster_frame):
8994
# Transform top lidar pointclouds to vehicle frame for visualization
9095
latest_lidar_vehicle = transform_points(lidar_ouster_frame, self.T_l2v)
@@ -104,69 +109,119 @@ def visualize(self,
104109
self.pub_polygon_marker.publish(ros_delete_polygon_marker)
105110
ros_delete_parking_spot_markers = delete_markers("parking_spot", MAX_PARKING_SPOT_MARKERS)
106111
self.pub_parking_spot_marker.publish(ros_delete_parking_spot_markers)
112+
ros_delete_parking_goal_markers = delete_markers("parking_goal", MAX_PARKING_GOAL_MARKERS)
113+
self.pub_parking_goal_marker.publish(ros_delete_parking_goal_markers)
107114
ros_delete_obstacles_markers = delete_markers("obstacles", MAX_OBSTACLE_MARKERS)
108115
self.pub_obstacles_marker.publish(ros_delete_obstacles_markers)
109116

110117
# Draw polygon first
111-
if len(ordered_cone_ground_centers_2D) > 0:
112-
ros_polygon_marker = create_polygon_marker(ordered_cone_ground_centers_2D, ref_frame=VEHICLE_FRAME)
113-
self.pub_polygon_marker.publish(ros_polygon_marker)
118+
if len(grouped_ordered_ground_centers_2D) > 0:
119+
ros_polygon_markers = create_polygon_markers(grouped_ordered_ground_centers_2D, ref_frame=VEHICLE_FRAME)
120+
self.pub_polygon_marker.publish(ros_polygon_markers)
114121

115122
# Create parking spot marker
116-
if goal_parking_spot:
117-
ros_parking_spot_marker = create_parking_spot_marker(goal_parking_spot, ref_frame=VEHICLE_FRAME)
123+
if best_parking_spot:
124+
ros_parking_spot_marker = create_parking_spot_marker(best_parking_spot, ref_frame="vehicle")
118125
self.pub_parking_spot_marker.publish(ros_parking_spot_marker)
119126

127+
# Create parking goal marker
128+
if parking_goal:
129+
ros_parking_goal_marker = create_parking_goal_marker(x = parking_goal[0],
130+
y = parking_goal[1],
131+
ref_frame="vehicle")
132+
self.pub_parking_goal_marker.publish(ros_parking_goal_marker)
133+
120134
# Create parking obstacles marker
121-
if parking_obstacles_pose and parking_obstacles_dim:
122-
ros_obstacles_marker = create_markers(parking_obstacles_pose,
123-
parking_obstacles_dim,
135+
if parking_obstacles_poses and parking_obstacles_dims:
136+
ros_obstacles_marker = create_markers(parking_obstacles_poses,
137+
parking_obstacles_dims,
124138
OBSTACLE_MARKER_COLOR,
125139
"obstacles", VEHICLE_FRAME)
126140
self.pub_obstacles_marker.publish(ros_obstacles_marker)
127141

128142
# Draw 3D cone centers
143+
cone_ground_centers = []
129144
if len(cone_pts_3D) > 0:
130145
cone_ground_centers = np.array(cone_pts_3D)
131146
cone_ground_centers[:, 2] = 0.0
132147
cone_ground_centers = [tuple(point) for point in cone_ground_centers]
133-
ros_cones_centers_pc2 = create_point_cloud(cone_ground_centers, color=CONE_CENTER_PC_COLOR)
134-
self.pub_cones_centers_pc2.publish(ros_cones_centers_pc2)
148+
ros_cones_centers_pc2 = create_point_cloud(cone_ground_centers, color=CONE_CENTER_PC_COLOR)
149+
self.pub_cones_centers_pc2.publish(ros_cones_centers_pc2)
135150

136151

137-
def update(self, cone_obstacles: Dict[str, Obstacle]):
152+
def update(self, cone_obstacles: Dict[str, ObstacleState]):
138153
# Initial variables
139-
goal_parking_spot = None
140-
parking_obstacles_pose = []
141-
parking_obstacles_dim = []
142-
ordered_cone_ground_centers_2D = []
154+
parking_goals = []
155+
best_parking_spots = []
156+
parking_obstacles_poses = []
157+
parking_obstacles_dims = []
158+
grouped_ordered_ground_centers_2D = []
143159

144160
# Populate cone points
145161
cone_pts_3D = []
146162
for cone in cone_obstacles.values():
147163
cone_pt_3D = (cone.pose.x, cone.pose.y, 0.0)
148164
cone_pts_3D.append(cone_pt_3D)
149165

150-
# Detect parking spot
166+
# Detect single/multi parking spot
151167
if len(cone_pts_3D) == NUM_CONES_PER_PARKING_SPOT:
152-
goal_parking_spot, parking_obstacles_pose, parking_obstacles_dim, ordered_cone_ground_centers_2D = detect_parking_spot(cone_pts_3D)
168+
# Find goal parking pose of that spot, obstacles and centers that forms the polygon
169+
parking_goal, best_parking_spot, parking_obstacles_pose, parking_obstacles_dim, ordered_ground_centers_2D = detect_parking_spot(cone_pts_3D)
170+
# add them to the list
171+
parking_goals.append(parking_goal)
172+
best_parking_spots.append(best_parking_spot)
173+
grouped_ordered_ground_centers_2D.append(ordered_ground_centers_2D)
174+
parking_obstacles_poses = parking_obstacles_pose
175+
parking_obstacles_dims = parking_obstacles_dim
176+
elif is_valid_multiple_of_k(len(cone_pts_3D), NUM_CONES_PER_PARKING_SPOT):
177+
grouped_cone_pts_3D = group_points_by_multiple_of_k(cone_pts_3D, NUM_CONES_PER_PARKING_SPOT)
178+
for gc in grouped_cone_pts_3D:
179+
# Find goal parking pose of that spot, obstacles and centers that forms the polygon
180+
parking_goal, best_parking_spot, parking_obstacles_pose, parking_obstacles_dim, ordered_ground_centers_2D = detect_parking_spot(gc)
181+
# add them to the list
182+
parking_goals.append(parking_goal)
183+
best_parking_spots.append(best_parking_spot)
184+
grouped_ordered_ground_centers_2D.append(ordered_ground_centers_2D)
185+
parking_obstacles_poses += parking_obstacles_pose
186+
parking_obstacles_dims += parking_obstacles_dim
187+
188+
# Return if no goal parking spot is found
189+
if len(parking_goals) < 1:
190+
self.parking_goal = None
191+
self.best_parking_spot = None
192+
self.cone_pts_3D = []
193+
self.grouped_ordered_ground_centers_2D = []
194+
self.parking_obstacles_poses = []
195+
self.parking_obstacles_dims = []
196+
return None
153197

154198
# Update local variables for visualization
155199
self.cone_pts_3D = cone_pts_3D
156-
self.ordered_cone_ground_centers_2D = ordered_cone_ground_centers_2D
157-
self.goal_parking_spot = goal_parking_spot
158-
self.parking_obstacles_pose = parking_obstacles_pose
159-
self.parking_obstacles_dim = parking_obstacles_dim
160-
161-
# Return if no goal parking spot is found
162-
if not goal_parking_spot:
200+
self.grouped_ordered_ground_centers_2D = grouped_ordered_ground_centers_2D
201+
self.parking_obstacles_poses = parking_obstacles_poses
202+
self.parking_obstacles_dims = parking_obstacles_dims
203+
204+
# Filter out None spots
205+
parking_goals = [x for x in parking_goals if x is not None]
206+
best_parking_spots = [x for x in best_parking_spots if x is not None]
207+
208+
# Now select the closest parking goal, return if none is found
209+
if len(parking_goals) > 1:
210+
self.parking_goal = closest_point_to_origin(parking_goals)
211+
self.best_parking_spot = closest_point_to_origin(best_parking_spot)
212+
elif len(parking_goals) == 1:
213+
self.parking_goal = parking_goals[0]
214+
self.best_parking_spot = best_parking_spots[0]
215+
else:
216+
self.parking_goal = None
217+
self.best_parking_spot = None
163218
return None
164219

165220
# Constructing parking obstacles
166221
current_time = self.vehicle_interface.time()
167-
obstacle_id = 0
222+
obstacle_id = PARKING_OBSTACLE_START_ID
168223
parking_obstacles = {}
169-
for o_pose, o_dim in zip(parking_obstacles_pose, parking_obstacles_dim):
224+
for o_pose, o_dim in zip(self.parking_obstacles_poses, self.parking_obstacles_dims):
170225
x, y, z, yaw = o_pose
171226
obstacle_pose = ObjectPose(
172227
t=current_time,
@@ -183,13 +238,13 @@ def update(self, cone_obstacles: Dict[str, Obstacle]):
183238
dimensions=o_dim,
184239
outline=None,
185240
material=ObstacleMaterialEnum.BARRIER,
186-
collidable=True, state=ObstacleStateEnum.STANDING
241+
collidable=True
187242
)
188-
parking_obstacles[f"parking_obstacle_{obstacle_id}"] = new_obstacle
243+
parking_obstacles[obstacle_id] = new_obstacle
189244
obstacle_id += 1
190245

191246
# Constructing goal pose
192-
x, y, yaw = goal_parking_spot
247+
x, y, yaw = self.parking_goal
193248
goal_pose = ObjectPose(
194249
t=current_time,
195250
x=x,

0 commit comments

Comments
 (0)