Skip to content

Commit aa321cd

Browse files
committed
Added back the code which converts AgentStates to start frame and tracks them
1 parent b990e35 commit aa321cd

1 file changed

Lines changed: 70 additions & 57 deletions

File tree

GEMstack/onboard/perception/combined_detection.py

Lines changed: 70 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from ...state import AllState, VehicleState, ObjectPose, ObjectFrameEnum, AgentState, AgentEnum, AgentActivityEnum
22
from ..interface.gem import GEMInterface
33
from ..component import Component
4-
# from .perception_utils import *
4+
from .pedestrian_utils import pose_to_matrix
55
from .pedestrian_utils_gem import *
66
from typing import Dict, List, Optional, Tuple
77
import rospy
@@ -240,15 +240,7 @@ def update(self, vehicle: VehicleState) -> Dict[str, AgentState]:
240240
self.start_pose_abs = vehicle.pose
241241
rospy.loginfo("CombinedDetector3D latched start pose.")
242242

243-
current_frame_agents = self._fuse_bounding_boxes(yolo_bbx_array, pp_bbx_array, vehicle, current_time)
244-
245-
return {}
246-
# Tracking disabled for now
247-
# if self.enable_tracking:
248-
# self._update_tracking(current_frame_agents)
249-
# else:
250-
# self.tracked_agents = current_frame_agents # NOTE: No deepcopy
251-
# return self.tracked_agents
243+
return self._fuse_bounding_boxes(yolo_bbx_array, pp_bbx_array, vehicle, current_time)
252244

253245

254246
def _fuse_bounding_boxes(self,
@@ -270,7 +262,7 @@ def _fuse_bounding_boxes(self,
270262
Dictionary of agent states
271263
"""
272264
original_header = yolo_bbx_array.header
273-
current_agents_in_frame: Dict[str, AgentState] = {}
265+
agents: Dict[str, AgentState] = {}
274266
yolo_boxes: List[BoundingBox] = yolo_bbx_array.boxes
275267
pp_boxes: List[BoundingBox] = pp_bbx_array.boxes
276268

@@ -335,64 +327,85 @@ def _fuse_bounding_boxes(self,
335327
quat_w = box.pose.orientation.w
336328
yaw, pitch, roll = R.from_quat([quat_x, quat_y, quat_z, quat_w]).as_euler('zyx', degrees=False)
337329

338-
# Transform to start frame if needed
339-
if self.use_start_frame and self.start_pose_abs is not None:
340-
vehicle_pose_in_start_frame = vehicle_state.pose.to_frame(
341-
ObjectFrameEnum.START, vehicle_state.pose, self.start_pose_abs
342-
)
343-
T_vehicle_to_start = pose_to_matrix(vehicle_pose_in_start_frame)
344-
object_pose_current_h = np.array([[pos_x],[pos_y],[pos_z],[1.0]])
345-
object_pose_start_h = T_vehicle_to_start @ object_pose_current_h
346-
final_x, final_y, final_z = object_pose_start_h[:3, 0]
347-
else:
348-
final_x, final_y, final_z = pos_x, pos_y, pos_z
330+
# Convert to start frame
331+
vehicle_pose_in_start_frame = vehicle_state.pose.to_frame(
332+
ObjectFrameEnum.START, vehicle_state.pose, self.start_pose_abs
333+
)
334+
T_vehicle_to_start = pose_to_matrix(vehicle_pose_in_start_frame)
335+
object_pose_current_h = np.array([[pos_x],[pos_y],[pos_z],[1.0]])
336+
object_pose_start_h = T_vehicle_to_start @ object_pose_current_h
337+
final_x, final_y, final_z = object_pose_start_h[:3, 0]
349338

350-
final_pose = ObjectPose(
339+
new_pose = ObjectPose(
351340
t=current_time, x=final_x, y=final_y, z=final_z,
352341
yaw=yaw, pitch=pitch, roll=roll, frame=output_frame_enum
353342
)
354343
dims = (box.dimensions.x, box.dimensions.y, box.dimensions.z)
355-
######### Mapping based on label (integer) from BoundingBox msg
356-
# Set agent type based on label
357-
agent_type = AgentEnum.PEDESTRIAN if box.label == 0 else AgentEnum.UNKNOWN
358-
activity = AgentActivityEnum.UNKNOWN # Placeholder
359-
360-
# temp id
361-
# _update_tracking assign persistent IDs
362-
temp_agent_id = f"pedestrian{i}"
363-
364-
current_agents_in_frame[temp_agent_id] = AgentState(
365-
pose=final_pose, dimensions=dims, outline=None, type=agent_type,
366-
activity=activity, velocity=(0.0,0.0,0.0), yaw_rate=0.0
367-
# score=box.value # score
344+
345+
new_pose = ObjectPose(
346+
t=current_time, x=final_x, y=final_y, z=final_z - box.dimensions.z / 2.0,
347+
yaw=yaw, pitch=pitch, roll=roll, frame=output_frame_enum
348+
)
349+
dims[2] = dims[2] * 2.0 # AgentState has z center on the floor and height is full height.
350+
351+
existing_id = match_existing_pedestrian(
352+
new_center=np.array([new_pose.x, new_pose.y, new_pose.z]),
353+
new_dims=dims,
354+
existing_agents=self.tracked_agents,
355+
distance_threshold=2.0
368356
)
357+
358+
if existing_id is not None:
359+
old_state = self.tracked_agents[existing_id]
360+
dt = new_pose.t - old_state.pose.t
361+
vx, vy, vz = compute_velocity(old_state.pose, new_pose, dt)
362+
updated_agent = AgentState(
363+
pose=new_pose,
364+
dimensions=dims,
365+
outline=None,
366+
type=AgentEnum.PEDESTRIAN,
367+
activity=AgentActivityEnum.MOVING,
368+
velocity=(vx, vy, vz),
369+
yaw_rate=0
370+
)
371+
agents[existing_id] = updated_agent
372+
self.tracked_agents[existing_id] = updated_agent
373+
else:
374+
agent_id = f"pedestrian{self.ped_counter}"
375+
self.ped_counter += 1
376+
new_agent = AgentState(
377+
pose=new_pose,
378+
dimensions=dims,
379+
outline=None,
380+
type=AgentEnum.PEDESTRIAN,
381+
activity=AgentActivityEnum.MOVING,
382+
velocity=(0, 0, 0),
383+
yaw_rate=0
384+
)
385+
agents[agent_id] = new_agent
386+
self.tracked_agents[agent_id] = new_agent
387+
369388
except Exception as e:
370389
rospy.logwarn(f"Failed to convert final BoundingBox {i} to AgentState: {e}")
371390
continue
372391

373392
self.pub_fused.publish(fused_bb_array)
374-
return current_agents_in_frame
375-
376-
377-
def _update_tracking(self, current_frame_agents: Dict[str, AgentState]):
378-
379-
# Todo tracking
380-
## Match 'current_frame_agents' to 'self.tracked_agents'.
381-
## - Use position (already in correct START or CURRENT frame), maybe size/type.
382-
## - Need a matching algorithm (e.g., nearest neighbor within radius, Hungarian).
383-
## For matched pairs:
384-
## - Update the existing agent in 'self.tracked_agents' (e.g., smooth pose, update timestamp).
385-
## For unmatched 'current_frame_agents':
386-
## - These are new detections. Assign a persistent ID (e.g., f"Ped_{self.ped_counter}").
387-
## - Increment self.ped_counter.
388-
## - Add them to 'self.tracked_agents'.
389-
## For unmatched 'self.tracked_agents' (agents not seen this frame):
390-
## - Increment a 'missed frames' counter or check timestamp.
391-
## - If missed for too long (e.g., > 1 second), remove from 'self.tracked_agents'.
392-
393-
# return without tracking
394-
self.tracked_agents = current_frame_agents
395393

394+
stale_ids = [agent_id for agent_id, agent in self.tracked_agents.items()
395+
if current_time - agent.pose.t > 5.0]
396+
for agent_id in stale_ids:
397+
rospy.loginfo(f"Removing stale agent: {agent_id}\n")
398+
for agent_id, agent in agents.items():
399+
p = agent.pose
400+
# Format pose and velocity with 3 decimals (or as needed)
401+
rospy.loginfo(
402+
f"Agent ID: {agent_id}\n"
403+
f"Pose: (x: {p.x:.3f}, y: {p.y:.3f}, z: {p.z:.3f}, "
404+
f"yaw: {p.yaw:.3f}, pitch: {p.pitch:.3f}, roll: {p.roll:.3f})\n"
405+
f"Velocity: (vx: {agent.velocity[0]:.3f}, vy: {agent.velocity[1]:.3f}, vz: {agent.velocity[2]:.3f})\n"
406+
)
407+
408+
return agents
396409

397410

398411
# Fake 2D Combined Detector for testing purposes

0 commit comments

Comments
 (0)