cmake_minimum_required(VERSION 3.16)
project(loco_leggedlab_deploy CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# ------------------------------------------------------------------
# 第三方路径（真机为 Orin NX / aarch64）。三者均可用环境变量或 -D 覆盖。
#   UNITREE_SDK2_DIR  默认 $HOME/project/unitree_sdk2
#   ONNXRUNTIME_DIR   默认 <本目录>/onnxruntime-linux-aarch64-1.22.0（需自行下载，见 README）
#   MUJOCO_DIR        默认 $HOME/.mujoco/mujoco-3.3.6（仅仿真需要）
# ------------------------------------------------------------------
if(DEFINED ENV{UNITREE_SDK2_DIR})
  set(_unitree_sdk2_default "$ENV{UNITREE_SDK2_DIR}")
else()
  set(_unitree_sdk2_default "$ENV{HOME}/project/unitree_sdk2")
endif()
if(DEFINED ENV{ONNXRUNTIME_DIR})
  set(_onnxruntime_default "$ENV{ONNXRUNTIME_DIR}")
else()
  set(_onnxruntime_default "${CMAKE_CURRENT_SOURCE_DIR}/onnxruntime-linux-aarch64-1.22.0")
endif()

set(UNITREE_SDK2_DIR  "${_unitree_sdk2_default}"  CACHE PATH "unitree_sdk2 C++ 根目录")
set(ONNXRUNTIME_DIR   "${_onnxruntime_default}"   CACHE PATH "onnxruntime include/lib")
set(MUJOCO_DIR        "$ENV{HOME}/.mujoco/mujoco-3.3.6" CACHE PATH "mujoco 根目录(include+mujoco/mujoco.h, lib/libmujoco.so)")

include_directories(
  ${CMAKE_CURRENT_SOURCE_DIR}/include
  ${UNITREE_SDK2_DIR}/include
  ${UNITREE_SDK2_DIR}/thirdparty/include
  ${UNITREE_SDK2_DIR}/thirdparty/include/ddscxx
  ${UNITREE_SDK2_DIR}/thirdparty/include/ddsc
  ${ONNXRUNTIME_DIR}/include
  ${MUJOCO_DIR}/include
)

link_directories(
  ${UNITREE_SDK2_DIR}/lib/aarch64
  ${UNITREE_SDK2_DIR}/thirdparty/lib/aarch64
  ${ONNXRUNTIME_DIR}/lib
  ${MUJOCO_DIR}/lib
)

# ---- 公共核心（config + fsm + common，不含 DDS Controller）----
# 本组件只注册 passive / fixedpose / loco(leggedlab) 三个策略。
add_library(loco_core STATIC
  src/config.cpp
  src/fsm/fsm.cpp
  src/fsm/fsm_state.cpp
  src/policy/passive.cpp
  src/policy/fixedpose.cpp
  src/policy/loco_mode.cpp
  src/common/ctrlcomp.cpp
  src/common/remote_controller.cpp
  src/common/command_helper.cpp
  src/common/npz_writer.cpp
  src/common/yaml_light.cpp
)
target_link_libraries(loco_core PUBLIC z)

# ---- 真机部署 ----
add_executable(deploy_real
  src/main.cpp
  src/controller.cpp
)
target_link_libraries(deploy_real
  loco_core
  unitree_sdk2
  ddscxx
  ddsc
  onnxruntime
  pthread
  dl
  stdc++fs
)

# ---- 话题记录进程（独立监听 rt/lowstate + rt/lowcmd，不影响控制 loop）----
add_executable(recorder src/recorder.cpp)
target_link_libraries(recorder
  unitree_sdk2
  ddscxx
  ddsc
  pthread
  dl
  stdc++fs
)

# ---- 仿真（headless；若系统有 libglfw3 则带 GUI 渲染）----
find_library(MUJOCO_LIB mujoco HINTS ${MUJOCO_DIR}/lib)
# Ubuntu 提供 libglfw.so（非 libglfw3.so），两种命名都试
find_library(GLFW3_LIB NAMES glfw3 glfw HINTS ${MUJOCO_DIR}/lib)
# glfw3.h 在 Ubuntu 位于 /usr/include/GLFW/glfw3.h，必须用带 GLFW/ 前缀的名字查找
find_path(GLFW3_INC GLFW/glfw3.h HINTS
  /usr/include /usr/local/include ${MUJOCO_DIR}/include)

add_executable(deploy_mujoco src/deploy_mujoco.cpp)
target_link_libraries(deploy_mujoco loco_core onnxruntime unitree_sdk2 ddscxx ddsc pthread dl)
if(MUJOCO_LIB)
  target_link_libraries(deploy_mujoco ${MUJOCO_LIB})
  target_compile_definitions(deploy_mujoco PRIVATE HAS_MUJOCO=1)
  if(GLFW3_LIB AND GLFW3_INC)
    target_include_directories(deploy_mujoco PRIVATE ${GLFW3_INC})
    # glfw(X11 后端) 需要 X11；缺少会导致 XFree 等未定义符号
    target_link_libraries(deploy_mujoco ${GLFW3_LIB} X11)
    target_compile_definitions(deploy_mujoco PRIVATE HAS_GLFW=1)
  endif()
else()
  message(WARNING "libmujoco not found; deploy_mujoco will fail to link")
endif()