hydra 코드 분석 - backend 에서의 semantic mapping

About_work·2024년 10월 21일
0

lifelong scene graph

목록 보기
36/56

src/backend/backend_module.cpp 중, object layer

1. 주요 처리 로직: UpdateObjectsFunctor 사용

  • 코드에서 semantic object객체 레이어로 관리되며, 이를 갱신하는 역할은 UpdateObjectsFunctor가 수행합니다.
  • 이 Functor는 아래와 같이 기본적으로 설정됩니다.
layer_functors_[DsgLayers::OBJECTS] = std::make_shared<UpdateObjectsFunctor>();
  • UpdateObjectsFunctorcallUpdateFunctions() 함수에서 호출됩니다.
  • UpdateObjectsFunctor 함수는 디포메이션 그래프의 최적화가 완료된 후에 각 레이어(객체, 장소 등)를 업데이트합니다.

1.1. Functor를 이용한 객체 업데이트 흐름

  • callUpdateFunctions() 함수에서는, 객체(2) 레이어를 포함한 DSG의 모든 레이어를 Functor를 통해 업데이트
  • 객체 레이어에 대해 구체적으로 살펴보면:
  • 업데이트 호출: UpdateObjectsFunctor::call() 함수가 실행됩니다.
  • 병합 처리:
    • 객체가 가까운 위치에 있을 경우 이를 병합
  • 후처리 클린업 작업:
    • 객체 업데이트 후에는 필요에 따라 후처리 작업이 수행될 수 있으며, 이는 Functor의 클린업 함수에 의해 처리됩니다.

1.2. UpdateObjectsFunctor의 역할

  • 객체 업데이트:
    • 객체 노드 간의 거리 및 속성을 기준으로 병합 작업이 수행
  • 노드 속성 업데이트: 객체의 속성 정보(예: 객체의 의미적 분류, 위치, 크기 등)는 업데이트 과정에서 최신 정보로 반영됨
  • 병합 규칙 적용: 특정 거리 또는 속성의 유사성에 따라 객체 간의 병합이 이루어지며, 이는 그래프의 효율적인 관리와 추론을 돕습니다.

  1. 병합 추적 및 처리:
  • 병합된 객체들에 대한 정보를 merge_tracker를 통해 추적합니다.
  • 이는 병합 후 추적 정보가 필요한 경우에 유용하며, 필요시 병합을 취소할 수도 있습니다.

src/backend/update_objects_functor.cpp

  • src/backend/update_objects_functor.cpp 파일은
    • Hydra Backend 시스템에서 semantic object들을 추적하고 병합(Merge)하는 기능을 수행하는 코드
  • 이 코드에서는 semantic object의 속성 업데이트, 병합 제안, 그리고 관련된 최적화 로직이 구현되어 있습니다.

1. 파일 개요

  • 이 파일은 객체(object)와 관련된 정보를 업데이트하고 관리하는 UpdateObjectsFunctor 클래스를 정의하고 있습니다.
  • 이 클래스는 다음과 같은 역할을 합니다:
  1. Semantic Object의 속성 업데이트:
  • 그래프 내의 객체 노드(Object Node)의 속성을 최신 상태로 유지
  1. 병합 제안(Merge Proposal):
  • 유사한 객체들을 병합할지 여부를 판단하고, 필요 시 병합을 제안
  1. 메쉬 업데이트:
  • 객체의 속성에 따라 메쉬(geometry)를 업데이트하여 환경의 시각적 표현을 유지

2. 주요 알고리즘 분석

2.1 mergeObjectAttributes 함수

  • 이 함수는 여러 개의 객체 노드를 병합하여 하나의 노드 속성으로 통합하며, 메쉬의 정보도 동시에 병합
  • 메쉬와의 연결 정보가 없는 노드들을 병합하거나, 메쉬 업데이트가 실패하는 경우도 처리

동작 흐름:

  1. 첫 번째 노드 속성 복사: 첫 번째 노드의 속성을 복사한 후, 병합 과정에서 사용할 속성 객체로 초기화
  2. 속성 병합: 주어진 노드 리스트의 나머지 노드들에 대해 mesh_connections 속성(메쉬와의 연결 정보)을 병합
    • utils::mergeIndices 함수를 사용하여 각 노드의 mesh_connections 속성을 통합
  3. 메쉬 업데이트:
  • 병합된 노드의 새로운 mesh_connections을 이용해 객체의 메쉬(geometry)를 업데이트
  • 만약 메쉬 업데이트가 실패하면, 병합된 결과가 유효하지 않다는 로그를 남rㅣㅁ
  1. 속성 반환: 병합된 속성 객체를 반환하여 병합된 결과를 다른 프로세스에서 사용할 수 있도록 합니다.

2.2 UpdateObjectsFunctor 클래스

hooks() 메서드

  • 기능: hooks() 메서드는 객체 업데이트 시 사용할 추가적인 훅(hook)을 반환하는 역할
  • allow_connection_merging 플래그가 활성화되어 있다면, mergeObjectAttributes 함수를 merge 훅으로 등록하여 객체 간의 병합이 가능하도록 합니다.

call() 메서드

  • 가장 중요한 함수로, 객체 노드의 상태를 업데이트하고 병합을 제안하는 역할을 합니다.
동작 흐름:
  1. 메쉬 정보 활용:
  • 업데이트 시 사용할 메쉬 데이터를 가져옵니다.
  • 메쉬 업데이트는 노드의 물리적 위치와 3D 정보(geometry)에 반영됩니다.
  1. 객체 레이어 생성:
  • LayerView 객체를 사용하여 객체 레이어를 생성
    • 이때 루프 클로저(loop closure)가 발생한 경우에는
      • 전체 객체 레이어를 사용하고,
    • 그렇지 않으면
      • 활성화된 객체들만 선택
  1. 객체 속성 업데이트:

    • 객체 노드를 순차적으로 확인하며, 각 노드의 속성(ObjectNodeAttributes)을 업데이트
    • 메쉬 연결 정보가 없는 객체는 무시하고 넘어갑니다.
    • 메쉬 업데이트:
      • updateObjectGeometry() 함수를 호출하여 객체의 메쉬 정보를 최신 상태로 갱신
      • 이 작업이 실패할 경우 경고 메시지를 출력
    • 업데이트된 노드의 속성은 복제(clone())하여 dsg.graph에 반영합니다.
  2. 병합 여부 확인:

    • 만약 병합 설정(info->allow_node_merging)이 활성화되어 있지 않으면, 병합을 건너뜁니다.
    • 병합이 가능하다면, proposeMerge() 함수를 호출하여 특정 객체를 다른 객체와 병합할지 여부를 제안합니다.
    • 병합할 노드가 있다면, 이를 proposals 리스트에 추가하여 최종 병합 목록을 생성합니다.

요약:

  • call() 메서드는 객체 레이어의 각 노드에 대해 속성을 업데이트하고, 필요에 따라 병합을 제안하는 과정을 수행합니다.
  • 최종적으로 병합된 객체 속성을 그래프에 반영하여 시스템의 일관성을 유지합니다.

2.3 proposeMerge() 메서드

  • 기능:
    • 객체 간의 병합 가능성을 제안하는 함수로,
    • 두 객체가 충분히 가까운지(혹은 중첩되는지) 여부를 판단하여 병합을 제안

동작 흐름:

  1. 노드 찾기:
  • 해당 객체의 semantic label을 바탕으로 동일한 레이블을 가진 노드를 검색
  • node_finders를 사용하여 객체를 찾으며, 이때 위치 정보(좌표)를 바탕으로 검색
  1. 병합 후보 확인:
  • 후보 객체들이 병합할 가치가 있는지 확인하기 위해, 후보 객체의 bounding box와 현재 객체의 bounding box를 비교합니다.
  • 서로 포함 관계에 있거나 근접한 객체라면 병합이 제안됩니다.
  1. 병합 결과 반환: 병합이 가능하다면 그 노드의 ID를 반환하고, 그렇지 않으면 std::nullopt을 반환하여 병합하지 않음을 나타냅니다.

요약:

  • proposeMerge()는 특정 객체가 다른 객체와 병합할 가능성을 탐색하고, 객체의 물리적 위치나 bounding box의 포함 관계를 바탕으로 병합 가능성을 판단합니다.

3. 함수 간 상호작용

  1. 객체 속성 업데이트: call() 메서드는 모든 객체 노드를 순회하며, 각각의 속성을 최신 상태로 갱신합니다.
  2. 병합 제안: 병합 설정이 활성화된 경우, 각 객체에 대해 proposeMerge()를 호출하여 병합 가능성을 탐색합니다. 병합이 제안되면, 제안된 병합 후보는 최종적으로 처리됩니다.
  3. 메쉬 업데이트: 객체의 메쉬 정보가 변경되거나, 병합이 발생하면 updateObjectGeometry() 함수를 통해 메쉬의 변형을 반영합니다.

4. 추가 파일 및 로직 참고

  • 이 코드에서는 객체의 메쉬 업데이트와 병합 로직이 중요한 역할을 합니다.
  • 메쉬 업데이트bounding box 처리와 관련된 세부적인 로직을 더 이해하기 위해서는 다음 파일들을 참고할 수 있습니다:
  • hydra/utils/mesh_utilities.hmesh_utilities.cpp:
    • 메쉬 관련 유틸리티 함수들이 정의된 파일로, 메쉬 업데이트(updateObjectGeometry)와 관련된 구체적인 동작을 확인할 수 있습니다.

src/utils/mesh_utilities.cpp

  • src/utils/mesh_utilities.cpp 파일에서는 메쉬(mesh) 데이터를 기반으로 객체의 위치(centroid)와 bounding box를 업데이트하고, 메쉬 블록들을 관리하는 기능들을 구현하고 있습니다.
  • 이 파일에서 제공하는 함수들은 메쉬와 객체의 기하학적 관계를 관리하며, 객체의 위치와 크기를 반영하는 데 중요한 역할을 합니다.

1. 파일 개요

  • 이 파일은 메쉬(mesh)를 다루는 유틸리티 함수들을 제공합니다. 주요 목표는 객체들의 속성(예: 위치, bounding box 등)을 메쉬 데이터를 기반으로 계산하고, 이를 업데이트하는 것
  • 또한, 메쉬의 활성 블록(active blocks)을 관리하여 비활성 블록을 제외한 부분만 따로 추출하는 기능도 포함하고 있습니다.

2. 주요 알고리즘 분석

2.1 updateNodeCentroid 함수

  • 이 함수는 주어진 메쉬 데이터에서 객체의 중심(centroid)를 계산하고, 이를 객체 속성(NodeAttributes)에 반영하는 역할을 합니다.

동작 흐름:

  1. 초기화: 중심 좌표 centroidEigen::Vector3d::Zero()로 초기화하고, 유효한 좌표의 개수를 추적하기 위해 num_valid 변수를 0으로 설정합니다.

  2. 인덱스 순회: 주어진 indices 벡터를 순회하면서, 각 인덱스에 해당하는 메쉬의 좌표를 가져옵니다.

    • mesh.pos(idx)를 호출하여 인덱스에 해당하는 메쉬 좌표를 가져옵니다. 이 좌표는 Eigen::Vector3d 형식으로 변환됩니다.
  3. 유효한 좌표 확인: 메쉬 좌표가 유효한 값인지 확인합니다.

    • pos.array().isFinite().all()을 통해 좌표 값이 유한한지 확인합니다. 만약 유한하지 않다면 해당 좌표를 무시하고 다음 인덱스로 넘어갑니다.
  4. 중심 좌표 계산:

  • 유효한 좌표일 경우, 해당 좌표를 누적하여 centroid에 더해줍니다.
  • 동시에 유효한 좌표의 개수를 세기 위해 num_valid를 증가시킵니다.
  1. 평균 계산: 모든 인덱스를 순회한 후, 유효한 좌표의 개수가 0이 아닌 경우, centroid를 유효한 좌표의 개수로 나누어 평균을 계산합니다. 이를 통해 객체의 중심 좌표를 계산하게 됩니다.

  2. 객체 속성 업데이트: 계산된 중심 좌표를 attrs.position에 저장합니다. 이때, 유효한 좌표가 없으면 false를 반환하여 업데이트 실패를 알립니다.

요약:

updateNodeCentroid() 함수는 주어진 메쉬 인덱스를 바탕으로 객체의 중심 좌표(centroid)를 계산하는 알고리즘입니다. 좌표가 유효한지 확인하고, 유효한 좌표만으로 중심을 계산하여 객체의 위치를 갱신합니다.


2.2 updateObjectGeometry 함수

  • 이 함수는 객체의 기하학적 속성(centroid, bounding box)을 업데이트하는 역할을 하며, 메쉬 데이터를 기반으로 객체의 bounding boxcentroid를 계산합니다.

동작 흐름:

  1. 메쉬 연결 정보 설정:

    • indices가 제공되지 않으면, 객체의 mesh_connections 정보를 사용하여 메쉬의 연결 정보를 설정합니다.
    • 이는 객체와 메쉬가 어떻게 연결되어 있는지 나타냅니다.
  2. Bounding Box 생성:

    • BoundingBox::MeshAdaptor를 사용하여 메쉬 데이터를 BoundingBox에 맞게 적응시킵니다.
    • adaptormesh_connections 또는 indices에 해당하는 메쉬 데이터를 기준으로 객체의 bounding box를 계산할 수 있게 도와줍니다.
    • BoundingBox 객체를 생성하고, 객체의 bounding_box 속성을 업데이트합니다.
  3. 중심 좌표 업데이트:

    • updateNodeCentroid() 함수를 호출하여 객체의 중심 좌표를 계산합니다. 이때, indices가 제공되면 해당 인덱스를, 그렇지 않으면 mesh_connections을 기반으로 중심을 계산합니다.
  4. 결과 반환:

    • 중심 좌표 계산에 성공하면 true를, 실패하면 false를 반환합니다. 이를 통해 객체의 기하학적 속성 업데이트 성공 여부를 알립니다.

요약:

updateObjectGeometry() 함수는 객체의 bounding box중심 좌표를 메쉬 데이터로부터 계산하여 객체 속성에 반영하는 역할을 합니다. 이를 통해 객체의 물리적 특성을 최신 상태로 유지할 수 있습니다.


2.3 getActiveMesh 함수

  • 이 함수는 활성 메쉬 블록(active mesh blocks)만을 추출하여 반환하는 역할을 합니다.
  • 비활성 블록은 메모리 관리 측면에서 제외하며, 필요한 부분만 추출하여 최적화된 메쉬를 구성합니다.

3. 함수 간 상호작용

  1. 객체 속성 업데이트: updateObjectGeometry() 함수는 메쉬의 연결 정보를 사용하여 객체의 bounding box중심 좌표를 업데이트합니다. 이 과정에서 updateNodeCentroid() 함수를 호출하여 중심 좌표를 계산합니다.
  2. 메쉬 활성화: getActiveMesh() 함수는 전체 메쉬에서 활성화된 블록만을 추출하여 효율적인 메쉬 구조를 만듭니다. 이는 메쉬를 처리할 때 불필요한 데이터 처리를 줄여줍니다.

4. 알고리즘적 분석

  1. 메쉬와 객체 간의 관계:
    • 이 파일의 핵심은 메쉬와 객체의 관계를 효율적으로 관리하는 것입니다.
    • 객체가 메쉬에 연결되어 있고, 그 연결을 기반으로 객체의 bounding box중심 좌표를 계산하는 로직이 주요 흐름입니다.
profile
새로운 것이 들어오면 이미 있는 것과 충돌을 시도하라.

0개의 댓글