Skip to content

Commit 8a7ceb6

Browse files
committed
Wrote in logic to finish part 3. Still need to implement 1-2 transforms and to fix a small list bug
1 parent bf4f433 commit 8a7ceb6

4 files changed

Lines changed: 129 additions & 189 deletions

File tree

GEMstack/onboard/perception/AgentTracker.py

Lines changed: 0 additions & 144 deletions
This file was deleted.

GEMstack/onboard/perception/IdTracker.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ class IdTracker():
22
"""Abstracts out id tracking
33
"""
44
def __init__(self):
5-
self.__ped_id = 0
5+
self.__id = 0
66

7-
def get_new_ped_id(self) -> int:
8-
"""Returns a unique pedestrian id
7+
def get_new_id(self) -> int:
8+
"""Returns a unique agent id
99
"""
1010
assigned_id = self.__id
11-
self.__ped_id += 1 # id will intentionally overflow to get back to 0
11+
self.__id += 1 # id will intentionally overflow to get back to 0
1212
return assigned_id

GEMstack/onboard/perception/PrevAgent.py

Lines changed: 0 additions & 17 deletions
This file was deleted.

GEMstack/onboard/perception/pedestrian_detection.py

Lines changed: 125 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import os
3434
from typing import List, Dict
3535
from collections import defaultdict
36+
from datetime import datetime
3637
# ROS, CV
3738
import rospy
3839
import message_filters
@@ -48,7 +49,7 @@
4849
from .pedestrian_detection_utils import *
4950
from ..interface.gem import GEMInterface
5051
from ..component import Component
51-
from .AgentTracker import AgentTracker
52+
from .IdTracker import IdTracker
5253

5354

5455
def box_to_fake_agent(box):
@@ -110,6 +111,10 @@ def __init__(self, vehicle_interface : GEMInterface) -> None:
110111
self.tf_listener = tf.TransformListener()
111112

112113
if self.debug: self.init_debug()
114+
115+
self.prev_time = None # Time in seconds since last scan for basic velocity calculation
116+
self.current_time = None # Time in seconds of current scan for basic velocity calculation
117+
self.id_tracker = IdTracker()
113118

114119
def init_debug(self,) -> None:
115120
# Debug Publishers
@@ -144,7 +149,7 @@ def find_dims(self, clusters: List[List[np.ndarray]]) -> List[np.ndarray]:
144149
# Work towards own tracking class instead of simple YOLO track?
145150
# Fix division by time
146151
# ret: Dict[track_id: vel[x, y, z]]
147-
def find_vels(self, track_ids: List[int], obj_centers: List[np.ndarray]) -> Dict[int, np.ndarray]:
152+
def find_vels(self, track_ids: List[int], obj_centers: List[np.ndarray], obj_dims: List[np.ndarray]) -> Dict[int, np.ndarray]:
148153
# Object not seen -> velocity = None
149154
track_id_center_map = dict(zip(track_ids, obj_centers))
150155
vels = defaultdict(lambda: np.array(())) # None is faster, np.array matches other find_ methods.
@@ -159,8 +164,7 @@ def find_vels(self, track_ids: List[int], obj_centers: List[np.ndarray]) -> Dict
159164
if prev_agent.pose.x and prev_agent.pose.y and prev_agent.pose.z and track_id_center_map[prev_agent.track_id].shape == 3:
160165
vels[prev_track_id] = (track_id_center_map[prev_track_id] - np.array([prev_agent.pose.x, prev_agent.pose.y, prev_agent.pose.z])) / (self.curr_time - self.prev_time)
161166
return vels
162-
163-
167+
164168
# TODO: Separate debug/viz class, bbox and 2d 3d points funcs
165169
def viz_object_states(self, cv_image, boxes, extracted_pts_all):
166170
# Extract 3D pedestrians points in lidar frame
@@ -221,7 +225,7 @@ def viz_object_states(self, cv_image, boxes, extracted_pts_all):
221225

222226

223227
def update_object_states(self, track_result: List[Results], extracted_pts_all: List[np.ndarray]) -> None:
224-
self.prev_agents = self.current_agents.copy()
228+
# self.prev_agents = self.current_agents.copy()
225229
self.current_agents.clear()
226230

227231
# Return if no track results available
@@ -263,27 +267,124 @@ def update_object_states(self, track_result: List[Results], extracted_pts_all: L
263267

264268
# TODO: CONVERT FROM VEHICLE FRAME TO START FRAME HERE
265269
# Then compare previous and current agents with the same id to calculate velocity
266-
obj_vels = self.find_vels(track_ids, obj_centers)
267-
268-
# Update Current AgentStates
269-
for ind in range(num_objs):
270-
obj_center = (None, None, None) if obj_centers[ind].size == 0 else obj_centers[ind]
271-
obj_dim = (None, None, None) if obj_dims[ind].size == 0 else obj_dims[ind]
272-
self.current_agents[track_ids[ind]] = (
273-
AgentState(
274-
track_id = track_ids[ind],
275-
pose=ObjectPose(t=0, x=obj_center[0], y=obj_center[1], z=obj_center[2] ,yaw=0,pitch=0,roll=0,frame=ObjectFrameEnum.CURRENT),
276-
# (l, w, h)
277-
# TODO: confirm (z -> l, x -> w, y -> h)
278-
dimensions=(obj_dim[0], obj_dim[1], obj_dim[2]),
279-
outline=None,
280-
type=AgentEnum.PEDESTRIAN,
281-
activity=AgentActivityEnum.MOVING,
282-
velocity= None if obj_vels[track_ids[ind]].size == 0 else tuple(obj_vels[track_ids[ind]]),
283-
yaw_rate=0
284-
))
270+
self.find_vels_and_ids(obj_centers, obj_dims)
271+
# obj_vels = self.find_vels(track_ids, obj_centers)
272+
273+
# # Update Current AgentStates
274+
# for ind in range(num_objs):
275+
# obj_center = (None, None, None) if obj_centers[ind].size == 0 else obj_centers[ind]
276+
# obj_dim = (None, None, None) if obj_dims[ind].size == 0 else obj_dims[ind]
277+
# self.current_agents[track_ids[ind]] = (
278+
# AgentState(
279+
# track_id = track_ids[ind],
280+
# pose=ObjectPose(t=0, x=obj_center[0], y=obj_center[1], z=obj_center[2] ,yaw=0,pitch=0,roll=0,frame=ObjectFrameEnum.CURRENT),
281+
# # (l, w, h)
282+
# # TODO: confirm (z -> l, x -> w, y -> h)
283+
# dimensions=(obj_dim[0], obj_dim[1], obj_dim[2]),
284+
# outline=None,
285+
# type=AgentEnum.PEDESTRIAN,
286+
# activity=AgentActivityEnum.MOVING,
287+
# velocity= None if obj_vels[track_ids[ind]].size == 0 else tuple(obj_vels[track_ids[ind]]),
288+
# yaw_rate=0
289+
# ))
290+
291+
def find_vels_and_ids(self, obj_centers: List[np.ndarray], obj_dims: List[np.ndarray]):
292+
new_prev_agents = {} # Stores current agents in START frame for next time through (since
293+
# planning wants us to send them agents in CURRENT frame)
294+
# Object not seen -> velocity = None
295+
vels = defaultdict(lambda: np.array(())) # None is faster, np.array matches other find_ methods.
296+
297+
# THIS ASSUMES EVERYTHING IS IN THE SAME FRAME WHICH WOULD WORK FOR STATIONARY CAR.
298+
# TODO: NEED TO STORE AND INCORPORATE TRANSFORMS SOMEHOW TO DEAL WITH MOVING CAR CASE
299+
assigned = False
300+
num_pairings = len(obj_centers)
301+
converted_centers = obj_centers # TODO: REPLACE WITH THIS: self.convert_vehicle_frame_to_start_frame(obj_centers)
302+
303+
# Loop through the indexes of the obj_center and obj_dim pairings
304+
for idx in range(num_pairings):
305+
assigned = False
306+
307+
# Loop through previous agents backwards
308+
for prev_id, prev_state in reversed(self.prev_agents.items()):
309+
# If an obj_center and obj_dim pair overlaps with a previous agent, assume that they're the same agent
310+
if self.agents_overlap(converted_centers[idx], obj_dims[idx], prev_state):
311+
assigned = True
312+
313+
if self.prev_time == None:
314+
# This shouldn't ever be triggered
315+
vel = 0
316+
else:
317+
delta_t = self.curr_time - self.prev_time
318+
vel = (obj_centers[idx] - np.array([prev_state.pose.x, prev_state.pose.y, prev_state.pose.z])) / delta_t.total_seconds()
319+
print("VELOCITY:")
320+
print(vel)
321+
322+
self.current_agents[prev_id] = (
323+
AgentState(
324+
track_id = prev_id,
325+
pose=ObjectPose(t=0, x=obj_centers[idx][0], y=obj_centers[idx][1], z=obj_centers[idx][2], yaw=0,pitch=0,roll=0,frame=ObjectFrameEnum.CURRENT),
326+
# (l, w, h)
327+
# TODO: confirm (z -> l, x -> w, y -> h)
328+
dimensions=(obj_dims[idx][0], obj_dims[idx][1], obj_dims[idx][2]),
329+
outline=None,
330+
type=AgentEnum.PEDESTRIAN,
331+
activity=AgentActivityEnum.MOVING,
332+
velocity= None if vel.size == 0 else tuple(vel),
333+
yaw_rate=0
334+
))
335+
del self.prev_agents[prev_id] # Remove previous agent from previous agents
336+
break
337+
338+
# If not assigned:
339+
if not assigned:
340+
# Set velocity to 0 and assign the new agent a new id with IdTracker
341+
id = self.id_tracker.get_new_id()
342+
self.current_agents[id] = (
343+
AgentState(
344+
track_id = id,
345+
pose=ObjectPose(t=0, x=obj_centers[idx][0], y=obj_centers[idx][1], z=obj_centers[idx][2] ,yaw=0,pitch=0,roll=0,frame=ObjectFrameEnum.CURRENT),
346+
# (l, w, h)
347+
# TODO: confirm (z -> l, x -> w, y -> h)
348+
dimensions=(obj_dims[idx][0], obj_dims[idx][1], obj_dims[idx][2]),
349+
outline=None,
350+
type=AgentEnum.PEDESTRIAN,
351+
activity=AgentActivityEnum.MOVING,
352+
velocity= None,
353+
yaw_rate=0
354+
))
355+
self.prev_agents = new_prev_agents
356+
357+
# Calculates whether 2 agents overlap in START frame. True if they do, false if not
358+
def agents_overlap(obj_center: np.ndarray, obj_dim: np.ndarray, prev_agent: AgentState) -> bool:
359+
# Calculate corners of obj_center and obj_dim pairing
360+
x1_min, x1_max = obj_center[0] - obj_dim[0] / 2.0, obj_center[0] + obj_dim[0] / 2.0
361+
y1_min, y1_max = obj_center[1] - obj_dim[1] / 2.0, obj_center[1] + obj_dim[1] / 2.0 # CENTER CALCULATION
362+
z1_min, z1_max = obj_center[2] - obj_dim[2] / 2.0, obj_center[2] + obj_dim[2] / 2.0
363+
364+
# Calculate corners of AgentState
365+
# Beware: AgentState(PhysicalObject) builds bbox from
366+
# dims [-l/2,l/2] x [-w/2,w/2] x [0,h], not
367+
# [-l/2,l/2] x [-w/2,w/2] x [-h/2,h/2]
368+
# TODO: confirm (z -> l, x -> w, y -> h)
369+
x2_min, x2_max = prev_agent.pose.x - prev_agent.dimensions.width / 2.0, prev_agent.pose.x + prev_agent.dimensions.width / 2.0
370+
y2_min, y2_max = prev_agent.pose.y, prev_agent.pose.y + prev_agent.dimensions.height # AGENT STATE CALCULATION
371+
z2_min, z2_max = prev_agent.pose.z - prev_agent.dimensions.length / 2.0, prev_agent.pose.z + prev_agent.dimensions.length / 2.0
372+
373+
# True if they overlap, false if not
374+
return (
375+
( (x1_min <= x2_min and x2_min <= x1_max) or (x2_min <= x1_min and x1_min <= x2_max) ) and
376+
( (y1_min <= y2_min and y2_min <= y1_max) or (y2_min <= y1_min and y1_min <= y2_max) ) and
377+
( (z1_min <= z2_min and z2_min <= z1_max) or (z2_min <= z1_min and z1_min <= z2_max) )
378+
)
379+
380+
def convert_vehicle_frame_to_start_frame(obj_centers: List[np.ndarray]) -> List[np.ndarray]:
381+
pass
285382

286383
def ouster_oak_callback(self, rgb_image_msg: Image, lidar_pc2_msg: PointCloud2):
384+
# Update times for basic velocity calculation
385+
self.prev_time = self.current_time
386+
self.current_time = datetime.now()
387+
287388
# Convert to cv2 image and run detector
288389
cv_image = self.bridge.imgmsg_to_cv2(rgb_image_msg, "bgr8")
289390
track_result = self.detector.track(source=cv_image, classes=self.classes_to_detect, persist=True, conf=self.confidence)

0 commit comments

Comments
 (0)