[Backend] DynamicSceneGraph - src/dynamic_scene_graph.cpp

About_work·2024년 10월 23일
0

lifelong scene graph

목록 보기
45/56

DSG에서의 주요 개념 정의

1. 정적 레이어 (Static Layers)

정적 레이어시간에 따라 변화하지 않는 또는 변화가 적은 노드들을 포함하는 레이어입니다. 이 레이어는 일반적으로 환경의 고정된 구조적 요소를 나타내며, 예를 들어:

  • 객체(Object): 책상, 의자, 나무 등과 같은 고정된 물체.
  • 장소(Place): 특정 위치나 지역.
  • 방(Room): 건물 내부의 특정 공간.
  • 건물(Building): 건물 자체의 구조.

정적 레이어의 노드들은 로봇이나 센서가 환경을 탐색하면서 수집한 정보에 기반하여 생성되며, 위치나 속성이 크게 변하지 않습니다.

2. 동적 레이어 (Dynamic Layers)

동적 레이어시간에 따라 변화하는 또는 움직이는 객체들을 나타내는 레이어입니다. 이 레이어는 동적으로 생성되고 업데이트되며, 예를 들어:

  • 사람(Pedestrian): 환경에서 이동하는 사람들.
  • 차량(Vehicle): 움직이는 자동차나 자전거 등.
  • 로봇(Robot): 다른 이동 로봇들.

동적 레이어의 노드들은 위치, 속도, 방향 등의 속성이 시간에 따라 변하며, 이러한 변화를 실시간으로 반영하기 위해 그래프 내에서 동적으로 관리됩니다.

3. 인터레이어 엣지 (Interlayer Edges)

인터레이어 엣지서로 다른 레이어에 있는 노드들 사이의 관계를 나타내는 엣지입니다. 이는 정적 레이어 간 또는 정적 레이어와 동적 레이어 간의 연결을 포함합니다. 이 엣지를 통해 레이어 간의 계층적 구조나 속성 관계를 표현할 수 있습니다. 예를 들어:

  • 객체-장소 관계: 특정 객체가 어느 장소에 위치하는지.
  • 장소-방 관계: 특정 장소가 어느 방에 속하는지.
  • 방-건물 관계: 특정 방이 어느 건물에 속하는지.

인터레이어 엣지는 그래프의 계층 구조를 형성하고, 노드들 간의 부모-자식 관계나 속성 관계를 명확히 합니다.

4. 동적 인터레이어 엣지 (Dynamic Interlayer Edges)

동적 인터레이어 엣지동적 레이어의 노드와 다른 레이어(정적 또는 동적)의 노드 간의 관계를 나타내는 엣지입니다. 이는 시간에 따라 생성되거나 제거될 수 있으며, 동적인 상황 변화를 반영합니다. 예를 들어:

  • 사람-장소 관계: 사람이 특정 장소에 있을 때 해당 노드들 사이에 엣지가 생성되고, 사람이 떠나면 엣지가 제거됩니다.
  • 차량-도로 관계: 차량이 도로를 따라 이동할 때 도로 노드와 차량 노드 사이에 엣지가 존재합니다.

동적 인터레이어 엣지는 동적인 객체들의 상태 변화에 따라 그래프 구조가 변하도록 하여, 환경의 동적 특성을 효과적으로 모델링합니다.


이러한 개념들을 종합하면, Dynamic Scene Graph(DSG)는 환경을 계층적이고 동적으로 표현하기 위한 구조로서:

  • 정적 레이어를 통해 환경의 고정된 부분을 나타내고,
  • 동적 레이어를 통해 시간에 따라 변하는 요소를 나타내며,
  • 인터레이어 엣지를 통해 레이어 간의 관계를 정의하고,
  • 동적 인터레이어 엣지를 통해 동적 요소와 다른 요소 간의 관계 변화를 모델링합니다.

이를 통해 DSG는 복잡한 환경을 효과적으로 표현하고 분석할 수 있게 합니다.


DynamicSceneGraph의 mergeGraph 함수 상세 분석

개요

  • mergeGraph 함수는 현재의 DynamicSceneGraph 객체다른 DynamicSceneGraph 객체(other)를 병합하는 역할을 합니다.
  • 이 과정에서 두 그래프의 노드(Node), 엣지(Edge), 레이어(Layer)를 통합하여 전체적인 장면 그래프(Scene Graph)의 구조를 확장하거나 업데이트합니다.
  • 병합 시에는 GraphMergeConfig 객체인 config를 사용하여 병합 과정에서의 세부 동작을 제어합니다.
  • 예를 들어, 제거된 노드나 엣지를 어떻게 처리할지, 부모-자식 관계를 강제할지 등을 설정할 수 있습니다.

요약

  • mergeGraph 함수는 다른 DynamicSceneGraph 객체를 현재 그래프에 병합하는 기능을 제공합니다.
  • 동적 레이어, 정적 레이어, 인터레이어 엣지, 동적 인터레이어 엣지를 순차적으로 병합합니다.
  • 병합 과정에서 제거된 노드와 엣지를 처리하고, 노드 ID의 변경 사항을 반영합니다.
  • GraphMergeConfig 객체를 통해 병합 동작을 세부적으로 제어할 수 있습니다.
  • 메쉬 데이터의 병합은 현재 구현되어 있지 않으며, 추후 추가 작업이 필요합니다.


결론

mergeGraph 함수는 DynamicSceneGraph의 핵심 기능 중 하나로, 그래프 데이터를 통합하고 업데이트하는 데 사용됩니다. 이 함수를 완전히 이해하려면 그래프 구조, 레이어 개념, 노드 및 엣지의 관리 방식에 대한 깊은 이해가 필요합니다. 향후 이 코드를 검토하거나 수정할 때 이 설명이 도움이 되기를 바랍니다.


함수의 주요 흐름

  • 함수는 크게 다음과 같은 단계로 구성되어 있습니다:
  1. 동적 레이어(Dynamic Layers) 병합
  2. 정적 레이어(Static Layers) 병합
  3. 인터레이어 엣지(Interlayer Edges) 병합
  4. 동적 인터레이어 엣지(Dynamic Interlayer Edges) 병합
  5. 기타 추가 작업 (TODO)
  • 각 단계별로 자세히 살펴보겠습니다.

1. 동적 레이어 병합

단계 설명

  • 목적: other 그래프의 동적 레이어를 현재 그래프에 병합합니다.
  • 작업 내용:
    • other의 모든 동적 레이어를 순회합니다.
    • 각 동적 레이어에 대해 현재 그래프에 동일한 레이어가 없으면 생성합니다.
    • 해당 동적 레이어를 현재 그래프의 대응 레이어에 병합합니다.

상세 동작

for (auto&& [l_id, other_layers] : other.dynamicLayers()) {
  for (auto&& [prefix, other_layer] : other_layers) {
    if (!hasLayer(l_id, prefix)) {
      createDynamicLayer(l_id, prefix);
    }

    dynamic_layers_[l_id][prefix]->mergeLayer(*other_layer, config, &node_lookup_);
  }
}
  • other.dynamicLayers()를 통해 other 그래프의 모든 동적 레이어를 가져옵니다.
  • l_id: 레이어 ID
  • prefix: 레이어의 접두사(Prefix)
  • other_layer: 병합할 동적 레이어

작업 과정:

  1. 레이어 존재 여부 확인:

    • hasLayer(l_id, prefix)를 호출하여 현재 그래프에 해당 동적 레이어가 있는지 확인합니다.
    • 없으면 createDynamicLayer(l_id, prefix)를 통해 새로운 동적 레이어를 생성합니다.
  2. 레이어 병합:

    • dynamic_layers_[l_id][prefix]->mergeLayer(*other_layer, config, &node_lookup_);를 호출하여 other_layer를 현재 그래프의 동적 레이어에 병합합니다.
    • mergeLayer 함수는 노드, 엣지 등을 병합하고, node_lookup_을 업데이트합니다.

2. 정적 레이어 병합

단계 설명

  • 목적: other 그래프의 정적 레이어를 현재 그래프에 병합합니다.
  • 작업 내용:
    • other의 모든 정적 레이어를 순회합니다.
    • 현재 그래프에 해당 레이어가 있으면 병합을 진행합니다.
    • 제거된 노드와 엣지를 처리하고, 레이어를 병합합니다.

상세 동작

for (auto&& [l_id, other_layer] : other.layers()) {
  if (!hasLayer(l_id)) {
    continue;
  }

  // 제거된 노드 처리
  std::vector<NodeId> removed_nodes;
  other_layer->getRemovedNodes(removed_nodes, config.clear_removed);
  for (const auto& removed_id : removed_nodes) {
    removeNode(removed_id);
  }

  // 제거된 엣지 처리
  std::vector<EdgeKey> removed_edges;
  other_layer->edges_.getRemoved(removed_edges, config.clear_removed);
  for (const auto& removed_edge : removed_edges) {
    layers_[l_id]->removeEdge(removed_edge.k1, removed_edge.k2);
  }

  // 레이어 병합
  layers_[l_id]->mergeLayer(*other_layer, config, &node_lookup_);
}

작업 과정:

  1. 레이어 존재 여부 확인:

    • hasLayer(l_id)를 호출하여 현재 그래프에 해당 정적 레이어가 있는지 확인합니다.
    • 없으면 continue로 다음 레이어로 넘어갑니다.
  2. 제거된 노드 처리:

    • other_layer->getRemovedNodes(removed_nodes, config.clear_removed);를 호출하여 제거된 노드 목록을 가져옵니다.
    • config.clear_removed 플래그에 따라 제거된 노드를 가져올지 결정합니다.
    • 제거된 노드를 현재 그래프에서 removeNode(removed_id);를 통해 삭제합니다.
  3. 제거된 엣지 처리:

    • other_layer->edges_.getRemoved(removed_edges, config.clear_removed);를 호출하여 제거된 엣지 목록을 가져옵니다.
    • 제거된 엣지를 현재 그래프에서 layers_[l_id]->removeEdge(removed_edge.k1, removed_edge.k2);를 통해 삭제합니다.
  4. 레이어 병합:

    • layers_[l_id]->mergeLayer(*other_layer, config, &node_lookup_);를 호출하여 other_layer를 현재 그래프의 해당 레이어에 병합합니다.
    • mergeLayer 함수는 노드, 엣지 등을 병합하고, node_lookup_을 업데이트합니다.

3. 인터레이어 엣지 병합

단계 설명

  • 목적: other 그래프의 인터레이어 엣지를 현재 그래프에 병합합니다.
  • 작업 내용:
    • other의 모든 인터레이어 엣지를 순회합니다.
    • 각 엣지의 소스와 타겟 노드 ID를 병합 후의 ID로 업데이트합니다.
    • 소스와 타겟이 동일하면 해당 엣지를 무시합니다.
    • 부모-자식 관계를 강제할지 여부에 따라 적절한 함수를 호출하여 엣지를 삽입합니다.

상세 동작

for (const auto& id_edge_pair : other.interlayer_edges()) {
  const auto& edge = id_edge_pair.second;
  NodeId new_source = config.getMergedId(edge.source);
  NodeId new_target = config.getMergedId(edge.target);
  if (new_source == new_target) {
    continue;
  }

  if (config.enforce_parent_constraints) {
    insertParentEdge(new_source, new_target, edge.info->clone());
  } else {
    insertEdge(new_source, new_target, edge.info->clone());
  }
}

작업 과정:

  1. 인터레이어 엣지 순회:

    • other.interlayer_edges()를 통해 other 그래프의 모든 인터레이어 엣지를 가져옵니다.
  2. 노드 ID 업데이트:

    • config.getMergedId(edge.source);config.getMergedId(edge.target);를 호출하여 병합 후의 소스와 타겟 노드 ID를 가져옵니다.
    • 이는 노드 병합 등으로 인해 노드 ID가 변경되었을 수 있기 때문입니다.
  3. 동일 노드 여부 확인:

    • new_sourcenew_target이 같으면 자기 자신에 대한 엣지이므로 continue로 넘어갑니다.
  4. 엣지 삽입:

    • config.enforce_parent_constraints 플래그에 따라:
      • true인 경우: insertParentEdge(new_source, new_target, edge.info->clone());를 호출하여 부모-자식 관계를 강제하는 엣지를 삽입합니다.
      • false인 경우: insertEdge(new_source, new_target, edge.info->clone());를 호출하여 일반적인 엣지를 삽입합니다.
    • edge.info->clone()을 통해 엣지의 속성 정보를 복제하여 사용합니다.

4. 동적 인터레이어 엣지 병합

단계 설명

  • 목적: other 그래프의 동적 인터레이어 엣지를 현재 그래프에 병합합니다.
  • 작업 내용:
    • 동작은 인터레이어 엣지 병합과 동일하지만, 동적 인터레이어 엣지를 대상으로 합니다.

상세 동작

for (const auto& id_edge_pair : other.dynamic_interlayer_edges()) {
  const auto& edge = id_edge_pair.second;
  NodeId new_source = config.getMergedId(edge.source);
  NodeId new_target = config.getMergedId(edge.target);
  if (new_source == new_target) {
    continue;
  }

  if (config.enforce_parent_constraints) {
    insertParentEdge(new_source, new_target, edge.info->clone());
  } else {
    insertEdge(new_source, new_target, edge.info->clone());
  }
}
  • 동작은 3번 단계와 동일하며, 대상이 동적 인터레이어 엣지라는 점만 다릅니다.

5. 기타 추가 작업

TODO 항목

// TODO(Yun) check the other mesh info (faces, vertices etc. )
  • 설명: 다른 그래프의 메쉬 정보(면, 정점 등)를 확인하고 병합하는 작업이 필요함을 나타내는 주석입니다.
  • 의미: 현재 메쉬 데이터에 대한 병합은 구현되지 않았으며, 추후 구현이 필요합니다.

함수의 반환값

return true;
  • 설명: 병합 작업이 성공적으로 완료되었음을 나타냅니다.
  • 주의사항: 함수 내에서 오류나 예외 처리가 없으므로, 모든 경우에 true를 반환합니다.

profile
새로운 것이 들어오면 이미 있는 것과 충돌을 시도하라.

0개의 댓글