det_output에서 검출된 인스턴스(features), 앵커(embed), 분류(classification) 및 예측(prediction) 결과를 추출num_det (예: 50) 인스턴스를 선택하여 후속 연산에서 노이즈를 줄이고 연산량을 감소시킵니다.instance_feature: 원본 shape → [B, 900, 256] anchor_embed: [B, 900, 256] det_classification: [B, 900, 10] (sigmoid 적용 후) det_anchors: [B, 900, 11] instance_feature_selected: [B, 50, 256] anchor_embed_selected: [B, 50, 256]map_output에서 지도(정적 맵) 관련 인스턴스 feature와 앵커 정보를 추출하고, 상위 num_map (예: 10) 개를 선택합니다.map_instance_feature: [B, 100, 256] map_anchor_embed: [B, 100, 256] map_classification: [B, 100, 3] (sigmoid 적용 후) map_anchors: [B, 100, 40] map_instance_feature_selected: [B, 10, 256] map_anchor_embed_selected: [B, 10, 256]instance_queue.get(...) 호출을 통해 자차(Ego)와 주변 객체의 시간적 이력을 포함한 특징(temporal features)과 앵커 정보를 얻습니다. ego_feature: [B, 1, 256] ego_anchor: [B, 1, 11] temp_instance_feature: [B, 901, 4, 256] temp_anchor: [B, 901, 4, 11] temp_mask: [B, 901, 4] ego_anchor_embed는 anchor_encoder(ego_anchor)로 얻어지며 → [B, 1, 256] temp_anchor_embed는 anchor_encoder(temp_anchor) 후 flatten → [B*901, 4, 256] temp_instance_feature와 temp_mask도 flatten하여 각 [B*901, 4, ...].get_motion_anchor 함수를 통해 검출 결과를 기반으로 각 검출 인스턴스에 대한 모션 예측의 초기 앵커를 생성합니다. [B, 900, 6, 12, 2] (예: 900개의 인스턴스, 6 모달, 12 시점, 2D 좌표).self.plan_anchor)를 배치 차원으로 타일링하여 사용합니다. [B, cmd_mode, modal_mode, ego_fut_ts, 2] (예: B=1, cmd_mode 보통 1 또는 3, modal_mode=6, ego_fut_ts=6).motion_anchor[..., -1, :] → [B, 900, 6, 2] (각 인스턴스의 마지막 시점의 좌표). gen_sineembed_for_position를 적용하여 [B, 900, 6, 256]로 변환 후, motion_anchor_encoder 적용 → 최종 shape [B, 900, 6, 256].plan_anchor[..., -1, :] → (예: [B, cmd_mode, 6, 2]). gen_sineembed_for_position 후 plan_anchor_encoder → [B, cmd_mode, 6, 256] [B, 1, cmd_mode * 6, 256] (예: [1,1,6,256] 혹은 [1,1,18,256] 등, 실제 값은 cmd_mode에 따라 다름).instance_feature_selected: 기존 [B, 50, 256]에 Ego feature [B, 1, 256]를 concat → [B, 51, 256]. anchor_embed_selected: [B, 51, 256]. instance_feature와 anchor_embed에도 Ego 정보를 추가하여, 각각 [B, 901, 256]. interact_operation_order=(
[
"temp_gnn",
"gnn",
"norm",
"cross_gnn",
"norm",
"ffn",
"norm",
] * 3 +
[
"refine",
]
),
목적 및 흐름:
검출 및 Ego 관련 인스턴스의 특징과 앵커 임베딩을 시간적/공간적 상호작용을 통해 정제하고, temp_instance_feature 끼리 어텐션temp_anchor_embed 끼리 어텐션instance_feature.flatten(0,1).unsqueeze(1) → shape: [B*(900+1), 1, 256]. temp_instance_feature → [B*901, 4, 256]. anchor_embed.flatten(0,1).unsqueeze(1) → [B*901, 1, 256]. temp_anchor_embed → [B*901, 4, 256]. temp_mask → [B*901, 4].[B, 901, 256].instance_feature_selected)과 앵커 임베딩(anchor_embed_selected)을 사용해, 전체 인스턴스 특징에 대해 self-attention 기반 공간적 관계를 학습합니다.instance_feature → [B, 901, 256]. instance_feature_selected → [B, 51, 256]. anchor_embed → [B, 901, 256]. anchor_embed_selected → [B, 51, 256].[B, 901, 256].[B, 901, 256].instance_feature → [B, 901, 256]. map_instance_feature_selected → [B, 10, 256]. anchor_embed → [B, 901, 256]. map_anchor_embed_selected → [B, 10, 256].[B, 901, 256].[B, 900, 6, 256])와 Plan Query ([B, 1, 6, 256])를 받아 세분화된 예측값으로 정제(refinement)하는 역할미래 궤적의 존재 여부 또는 신뢰도(확률)를 산출미래 시점마다 2차원 좌표(또는 추가 상태)를 예측Ego 차량의 현재 상태나 주행 상황을 요약하는 벡터 motion_mode_query + (instance_feature + anchor_embed)[:, :num_anchor].unsqueeze(2) motion_mode_query: [B, 900, 6, 256] (instance_feature + anchor_embed)[:, :num_anchor]: [B, 900, 256] → unsqueeze(2) → [B, 900, 1, 256] [B, 900, 6, 256]plan_mode_query + (instance_feature + anchor_embed)[:, num_anchor:].unsqueeze(2) plan_mode_query: [B, 1, 6, 256] (instance_feature + anchor_embed)[:, num_anchor:]: [B, 1, 256] → unsqueeze(2) → [B, 1, 1, 256] [B, 1, 6, 256]ego_feature: [B, 1, 256]ego_anchor_embed: (B, 1, 256)motion_cls_branch:
classification logits, shape ([B, 900, 6, 1]) [B, 900, 6]) 각 인스턴스와 각 모달에 대해 모션 예측의 신뢰도 혹은 분류 점수를 산출motion_reg_branch:
각 인스턴스에 대해, 6가지 모달 별로 12 시점의 2차원 좌표 (혹은 추가 상태)를 예측ego_feature + ego_anchor_embed [B, 1, 256])Planning Status, shape: \([B, 1, 10]\) Ego 차량의 상태 혹은 주행 상황을 나타내는 상태 벡터를 산출 (예: 10차원 벡터)motion_cls: [B, 900, 6] motion_reg: [B, 900, fut_mode, fut_ts, 2] (예: [B, 900, 6, 12, 2]) plan_cls: None (코드에서는 주석 처리됨) plan_reg: None (코드에서는 주석 처리됨) planning_status: [B, 1, 10] diff_operation_order=(
[
"traj_pooler",
"self_attn",
"norm",
# "modulation",
"agent_cross_gnn",
"norm",
"anchor_cross_gnn",
"norm",
# "modulation",
"ffn",
"norm",
"modulation",
"diff_refine",
] * 2
),
plan_query)를 기반으로, diffusion scheduler를 사용하여 계획 궤적을 추가 정제plan_query (shape: [B, 1, 18, 256])를 squeeze하여 [B, 18, 256]로 만든 후, 재구성하여 [B, 3, ego_fut_mode, 256] (예: [1, 3, 6, 256])로 변환합니다. metas['gt_ego_fut_cmd'])를 통해 명령(cmd)을 선택하여, 선택된 plan query인 cmd_plan_nav_query의 shape는 [B, ego_fut_mode, 256] (예: [1,6,256]).plan_anchor에서 명령에 해당하는 부분을 선택하고, 연속된 앵커들 간의 차이를 계산하여 목표(ground truth) 계획 궤적의 변화량(tgt_cmd_plan_anchor)을 구합니다. plan_anchor → 원래 shape [B, cmd_mode, modal_mode, ego_fut_ts, 2] cmd_plan_anchor: [B, ego_fut_mode, 6, 2] tgt_cmd_plan_anchor: [B, ego_fut_mode, 6-1, 2] (예: [1,6,5,2])tgt_cmd_plan_anchor를 normalize_ego_fut_trajs를 통해 정규화하고, reshape하여 [B * ego_fut_mode, ego_fut_ts, 2] (예: [6,6,2])로 만듭니다.[6,6,2] → 노이즈 추가 후에도 동일한 shape.gen_sineembed_for_position)을 통해 임베딩한 후, plan_pos_encoder를 적용하여 최종 traj_feature를 생성합니다.[B*ego_fut_mode, ego_fut_ts, 2] (예: [6,6,2]) [6,6,hidden_dim] (예: hidden_dim=128) [6, 6*hidden_dim] (예: [6,768]) plan_pos_encoder 변환 후 → traj_feature: [6, embed_dims] (예: [6,256]) [B, ego_fut_mode, embed_dims] (예: [1,6,256])time_mlp를 적용하여 time embedding을 얻고, shape는 [B, ego_fut_mode, embed_dims] (예: [1,6,256]).k (예: 두 개의 단계)[B*ego_fut_mode, embed_dims].[B*ego_fut_mode, embed_dims].cmd_plan_nav_query)와 교차하여, 앵커 기반 정보를 반영합니다. diff_plan_reg: 보통 [B*ego_fut_mode, ego_fut_ts, 2] (예: [6,6,2])diff_plan_cls: 분류 결과, shape는 예를 들어 [B*ego_fut_mode, num_cls_plan].step 메서드를 호출하여, 모델 출력(x_start)를 기반으로 노이즈를 제거하며 최종 예측 궤적을 복원합니다.[B, 1, ego_fut_mode, ego_fut_ts, 2]로 변환되고, 반복(repeat)하여 modal dimension을 확장합니다. (예: 최종 shape → [B, 1, 3*ego_fut_mode, ego_fut_ts, 2])"classification": interact 단계에서 얻은 motion 분류 결과 리스트 (각 항목의 shape 예: [B, 900, 6, num_cls_motion]) "prediction": motion 회귀 결과 리스트 (예: [B, 900, 6, fut_ts, reg_dim]) "period" 및 "anchor_queue": 인스턴스 큐 관련 메타정보."classification": interact 단계에서 얻은 plan 분류 결과 리스트 "prediction": plan 회귀 결과 리스트 (refine 단계 및 diffusion 정제 결과 포함) "status": plan 상태 정보 "diffusion_prediction"와 "diffusion_classification"에 저장됨.forward_test는 (motion_output, planning_output)을 반환합니다.각 단계에서의 입력과 출력 텐서들은 위에서 언급한 스펙(예: [B, 900, 256], [B,900,6,256], [B, 1,6,256], [B, ego_fut_mode, ego_fut_ts, 2] 등)을 따르며, 이는 모델의 각 모듈들이 공간적, 시간적, 그리고 다중 모달 정보를 효율적으로 융합하여 최종 주행 계획을 산출할 수 있도록 설계되어 있습니다.
이와 같이 forward_test 메서드는 전체적인 파이프라인을 통해 검출 및 지도 정보, 시간적 이력, Ego 정보, 그리고 사전 정의된 앵커 및 쿼리들을 결합하여, Motion과 Planning의 최종 예측을 생성하는 역할을 수행합니다.
instance_feature 와 anchor_embed 어떻게 만드는지 알아야함""" det_output : Dict
instance_feature: (1, 900, 256)
anchor_embed: (1, 900, 256)
len(det_output['classification']): 6
det_output['classification'][-1].shape: torch.Size([1, 900, 10])
len(det_output['prediction']): 6
det_output['prediction'][-1].shape: torch.Size([1, 900, 11])
len(det_output['quality']): 6
det_output['quality'][-1].shape: torch.Size([1, 900, 2])
"""
---------------------------
""" map_output: Dict
instance_feature: (1, 100, 256)
anchor_embed: (1, 100, 256)
len(map_output['classification']): 6
map_output['classification'][-1].shape: torch.Size([1, 100, 3])
len(map_output['prediction']): 6
map_output['prediction'][-1].shape: torch.Size([1, 100, 40])
"""
---------------------------
"""
feature_maps : List[Tensor]
[0]: (1, 89760, 256)
– 여러 스케일(또는 레벨)과 카메라에서 추출된 feature map들을 공간적 위치(픽셀 또는 패치) 단위로 평탄화(flatten)하여 하나의 큰 텐서로 연결한 결과
– 여기서 89760는 모든 카메라와 모든 스케일의 픽셀(또는 패치) 수의 총합이고, 256는 각 위치에서의 feature 채널 수를 의미
– 즉, 이 텐서는 배치와 카메라 차원을 합쳐서 모든 spatial 위치의 특징들을 한 번에 처리할 수 있도록 만들어진 “열(feature column)” 형태의 표현
[1]: (6, 4, 2)
– 각 카메라(6)와 각 스케일(레벨, 4)에서 원래의 공간적 크기(높이, 너비)를 나타내는 정보
– 여기서 6는 카메라의 수, 4는 각 카메라에서 사용한 스케일(또는 레벨)의 수, 2는 각각 (높이, 너비)를 의미
– 이 정보는 평탄화된 col_feats를 다시 원래의 spatial 구조로 복원할 때 기준으로 사용
[2]: (6, 4)
– 각 카메라별, 각 스케일별로 평탄화된 col_feats 내에서 해당 스케일의 feature들이 시작하는 인덱스를 나타냅
– (6, 4)에서 6는 카메라 수, 4는 각 카메라에서의 스케일 수를 의미하며,
이 값들을 이용해 분할된 feature map 들을 다시 각 스케일 단위로 분리하거나 재구성할 수 있음
"""
""" motion_output : Dict
"classification": len = 1
(1, 900, fut_mode=6)
"prediction": len = 1
(1, 900, fut_mode=6, fut_ts=12, 2)
"period": (1, 900)
"anchor_queue": len = 4
(1, 900, 11)
"""
-------------------------
""" planning_output : Dict
classification: len 1
(1, 1, cmd_mode(3)*modal_mode(6)=18)
prediction: len 1
(1, 1, cmd_mode(3)*modal_mode(6)=18, ego_fut_mode=6, 2)
status: len 1
(1, 1, 10)
anchor_queue: len 4
(1, 1, 11)
period: ( 1, 11)
"""
""" det_output : Dict
len(det_output['classification']): 6
det_output['classification'][-1].shape: torch.Size([1, 900, 10])
len(det_output['prediction']): 6
det_output['prediction'][-1].shape: torch.Size([1, 900, 11])
len(det_output['quality']): 6
det_output['quality'][-1].shape: torch.Size([1, 900, 2])
"""
------------------------------------------------------
""" motion_output : Dict
"classification": len = 1
(1, 900, fut_mode=6)
"prediction": len = 1
(1, 900, fut_mode=6, fut_ts=12, 2)
"period": (1, 900)
"anchor_queue": len = 4
(1, 900, 11)
"""
------------------------------------------------------
""" planning_output : Dict
classification: len 1
(1, 1, cmd_mode(3)*modal_mode(6)=18)
prediction: len 1
(1, 1, cmd_mode(3)*modal_mode(6)=18, ego_fut_mode=6, 2)
status: len 1
(1, 1, 10)
anchor_queue: len 4
(1, 1, 11)
period: ( 1, 11)
"""
""" motion_result: List, len = 1 (아마 batch size 만큼 나올 것)
dict
trajs_3d: (300, fut_mode=6, fut_ts=12, 2)
trajs_score: (300, fut_mode=6)
anchor_queue: (300, max_length(=4), 10)
period: (300)
"""
--------------------------------------
""" planning result: len = 1 (아마 batch size 만큼 나올 것)
dict
planning_score: (cmd_mode=3, modal_mode=6)
planning: (cmd_mode=3, modal_mode=6, ego_fut_mode=6, 2)
final_planning: (ego_fut_mode=6, 2)
ego_period: (1)
ego_anchor_queue: (1, max_length=4, 10)
"""
V13MotionPlanningHead는 자율주행 시스템에서 객체 검출 및 지도 결과(det_output, map_output)를 기반으로
입력 및 Feature 통합:
차선, 경계, 보행자 횡단보도ego_feature, ego_anchor 등)를 제공하여 시간적 연속성을 확보 쿼리 생성 및 상호작용:
| 용어 | 의미 | 예시 설명 |
|---|---|---|
| fut_mode | 다른 객체(예: 주변 차량, 보행자 등)의 미래 궤적 예측에서 고려하는 모드의 수 | 주변 차량의 미래 경로가 여러 방식(급격한 변화, 완만한 변화 등)으로 예측될 때, 그 후보 수 (예: 6) |
| ego_fut_mode | 자차(ego vehicle)의 미래 궤적 예측에서 고려하는 모드의 수 | 자차의 미래 경로가 여러 방식(예: 다른 주행 전략)으로 예측될 때, 그 후보 수 (예: 6) |
| cmd_mode | 자차가 수행할 고수준 주행 명령의 종류 (어떤 행동을 할 것인가에 대한 분류) | 예를 들어, "직진", "좌회전", "우회전" 등, 각 명령이 하나의 cmd_mode (예: 3개)로 표현될 수 있음 |
| modal_mode | 각 고수준 주행 명령(cmd_mode) 내에서 예측할 수 있는 여러 세부 경로 후보 (세부 실행 전략) | 예를 들어, "좌회전" 명령 내에서 급격하게 좌회전하는 경우, 완만하게 좌회전하는 경우 등 여러 후보(예: 6개) |
최종 출력 및 후처리:
손실 및 디코딩:
이처럼 V13MotionPlanningHead는 감지, 지도, temporal 정보를 통합해 미래 모션 및 자차 플래닝을 정밀하게 예측하는 핵심 모듈
V13MotionPlanningHead는 객체 검출(det_output) 및 지도(map_output) 모듈에서 얻은 정보를 기반으로
미래 모션(다른 객체의 모션)과 자차(ego) 플래닝(경로 예측)을 동시에 수행하는 최종 모션 플래닝 모듈후보 특징 통합 및 정제:
interact_operation_order)을 통해 쿼리 생성 및 앵커 선택:
| 용어 | 의미 | 예시 설명 |
|---|---|---|
| fut_mode | 다른 객체(예: 주변 차량, 보행자 등)의 미래 궤적 예측에서 고려하는 모드의 수 | 주변 차량의 미래 경로가 여러 방식(급격한 변화, 완만한 변화 등)으로 예측될 때, 그 후보 수 (예: 6) |
| ego_fut_mode | 자차(ego vehicle)의 미래 궤적 예측에서 고려하는 모드의 수 | 자차의 미래 경로가 여러 방식(예: 다른 주행 전략)으로 예측될 때, 그 후보 수 (예: 6) |
| cmd_mode | 자차가 수행할 고수준 주행 명령의 종류 (어떤 행동을 할 것인가에 대한 분류) | 예를 들어, "직진", "좌회전", "우회전" 등, 각 명령이 하나의 cmd_mode (예: 3개)로 표현될 수 있음 |
| modal_mode | 각 고수준 주행 명령(cmd_mode) 내에서 예측할 수 있는 여러 세부 경로 후보 (세부 실행 전략) | 예를 들어, "좌회전" 명령 내에서 급격하게 좌회전하는 경우, 완만하게 좌회전하는 경우 등 여러 후보(예: 6개) |
모션 및 플래닝 예측:
fut_mode(예: 6) 모드별 분류 점수를 산출 noisy한 자차 미래 궤적(noisy_traj_points)을 점진적으로 정제하고, 후처리 및 최종 출력:
motion_anchor:
plan_anchor:
motion_anchor_encoder:
plan_anchor_encoder & plan_pos_encoder:
Motion Sampler (MotionTarget):
Planning Sampler (V1PlanningTarget):
Motion Losses:
Plan Losses:
Motion Decoder (SparseBox3DMotionDecoder):
Planning Decoder (HierarchicalPlanningDecoder):