rl_locomotion 编译过程三

CMakeLists.txt 逐段解释

c 复制代码
cmake_minimum_required(VERSION 3.10)
project(_raisim_gym_torch)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/raisimGymTorch/env/bin)
SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/raisimGymTorch/env/bin)
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/raisimGymTorch/env/bin)


MACRO(SUBDIRLIST result curdir)
    SET(dirlist "")
    LIST(APPEND dirlist rsg_a1_task)
    LIST(APPEND dirlist dagger_a1)
    SET(${result} ${dirlist})
ENDMACRO()

####################
### dependencies ###
####################
set(Dependencies)

add_subdirectory(../thirdParty/pybind11 pybind11)
find_package(Eigen3 REQUIRED)
find_package(OpenMP REQUIRED)

if (UNIX AND NOT APPLE AND NOT ANDROID AND NOT WEBGL AND NOT WIN32)
    set(RAISIM_OS linux)
    list(APPEND CMAKE_PREFIX_PATH ../raisim/${RAISIM_OS})
elseif(APPLE)
    set(RAISIM_OS mac)
    list(APPEND CMAKE_PREFIX_PATH ../raisim/${RAISIM_OS})
    list(APPEND Dependencies OpenMP::OpenMP_CXX)
elseif(WIN32)
    set(RAISIM_OS win32)
    list(APPEND CMAKE_PREFIX_PATH ../raisim/${RAISIM_OS}/mt_debug)
    list(APPEND CMAKE_PREFIX_PATH ../thirdParty)
    list(APPEND Dependencies Ws2_32)
    set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}/raisimGymTorch/env/bin)
    set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}/raisimGymTorch/env/bin)
    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}/raisimGymTorch/env/bin)
endif()

find_package(raisim CONFIG REQUIRED)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}")

#######################
### src and linking ###
#######################
SUBDIRLIST(SUBDIRS ${CMAKE_CURRENT_SOURCE_DIR}/raisimGymTorch/env/envs)
set(RAISIMGYM_ENV_DIR ${CMAKE_CURRENT_SOURCE_DIR}/raisimGymTorch/env/envs)

FOREACH(subdir ${SUBDIRS})
    pybind11_add_module(${subdir} raisimGymTorch/env/raisim_gym.cpp raisimGymTorch/env/Yaml.cpp)
    target_link_libraries(${subdir} PRIVATE raisim::raisim ${Dependencies})
    target_include_directories(${subdir} PUBLIC ${EIGEN3_INCLUDE_DIRS} ${RAISIMGYM_ENV_DIR}/${subdir})
    target_compile_options(${subdir} PRIVATE -mtune=native -fPIC -O3 -g -mno-avx2)
    target_compile_definitions(${subdir} PRIVATE "-DRAISIMGYM_TORCH_ENV_NAME=${subdir}")

    if (CMAKE_BUILD_TYPE STREQUAL "DEBUG" OR CMAKE_BUILD_TYPE STREQUAL "Debug")
        message("[RAISIM_GYM] BUILDING THE DEBUG APP for ${subdir}")
        add_executable(${subdir}_debug_app raisimGymTorch/env/debug_app.cpp raisimGymTorch/env/Yaml.cpp)
        target_link_libraries(${subdir}_debug_app PRIVATE raisim::raisim)
        target_include_directories(${subdir}_debug_app PUBLIC raisimGymTorch/env/envs/${subdir} ${EIGEN3_INCLUDE_DIRS})
        if(WIN32)
            target_link_libraries(${subdir}_debug_app PRIVATE Ws2_32)
        else()
            target_compile_options(${subdir}_debug_app PRIVATE -mtune=native -fPIC -g -O0 -mno-avx2)
        endif()
    endif()
ENDFOREACH()

1. 基础设置

cmake 复制代码
cmake_minimum_required(VERSION 3.10)
project(_raisim_gym_torch)
set(CMAKE_CXX_STANDARD 14)

项目名称为 _raisim_gym_torch,使用 C++14 标准。

2. 输出目录

cmake 复制代码
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/raisimGymTorch/env/bin)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/raisimGymTorch/env/bin)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/raisimGymTorch/env/bin)

所有编译产物(.so.a、可执行文件)统一输出到 raisimGymTorch/env/bin/

3. 子目录列表宏

cmake 复制代码
MACRO(SUBDIRLIST result curdir)
    SET(dirlist "")
    LIST(APPEND dirlist rsg_a1_task)
    LIST(APPEND dirlist dagger_a1)
    SET(${result} ${dirlist})
ENDMACRO()

定义了两个编译目标:rsg_a1_task(特权策略环境)和 dagger_a1(蒸馏环境)。每增加一个新任务环境,只需在这里加一行 LIST(APPEND ...)

  1. 这是一个CMake宏(MACRO),名为SUBDIRLIST
  2. 它接受两个参数:resultcurdir
  3. 函数内部:
    • 创建一个空列表dirlist
    • 向列表中添加两个元素:rsg_a1_taskdagger_a1
    • dirlist的值赋给result参数指定的变量

这个宏的作用是返回一个包含两个子目录名称的列表:rsg_a1_taskdagger_a1

虽然参数curdir被声明了,但在函数体内并没有使用它,这可能是一个设计上的疏忽或者是为了保持接口一致性而保留的。

详细解释:
代码行 功能说明
MACRO(SUBDIRLIST result curdir) 定义宏,接受两个参数:result(输出变量名)和 curdir(当前目录,未使用)
SET(dirlist "") 初始化一个空列表 dirlist
LIST(APPEND dirlist rsg_a1_task) 向列表添加第一个子目录名:rsg_a1_task
LIST(APPEND dirlist dagger_a1) 向列表添加第二个子目录名:dagger_a1
SET(${result} ${dirlist}) 将列表内容赋值给调用者指定的输出变量
ENDMACRO() 宏定义结束
使用方式:
less 复制代码
SUBDIRLIST(my_subdirs ${CMAKE_CURRENT_SOURCE_DIR})
# 执行后,my_subdirs 将包含:["rsg_a1_task", "dagger_a1"]
注意点:
  • 参数 curdir 在宏体内并未被使用,这可能是为了保持接口兼容性而保留的占位参数
  • 返回的子目录列表是硬编码的,不依赖于实际的文件系统扫描
  • 这是一个典型的 CMake 模块化技巧,用于集中管理需要处理的子项目列表

4. 依赖项

cmake 复制代码
add_subdirectory(../thirdParty/pybind11 pybind11)  # Python-C++ 桥接
find_package(Eigen3 REQUIRED)      # 矩阵运算库
find_package(OpenMP REQUIRED)      # CPU 并行
find_package(raisim CONFIG REQUIRED)  # Raisim 物理引擎

假设 raisim 安装在 ../raisim/linux/ 下。Windows/Mac 走不同的路径分支。

5. 核心编译逻辑 --- 循环构建

cmake 复制代码
FOREACH(subdir ${SUBDIRS})  # subdir = rsg_a1_task, dagger_a1
    # ① pybind11 模块
    pybind11_add_module(${subdir}
        raisimGymTorch/env/raisim_gym.cpp       # 绑定代码
        raisimGymTorch/env/Yaml.cpp             # YAML 解析
    )
    target_link_libraries(${subdir} PRIVATE raisim::raisim ${Dependencies})
    target_include_directories(${subdir} PUBLIC
        ${EIGEN3_INCLUDE_DIRS}
        ${RAISIMGYM_ENV_DIR}/${subdir}          # 各自的 Environment.hpp
    )
    target_compile_options(${subdir} PRIVATE -mtune=native -fPIC -O3 -g -mno-avx2)
    target_compile_definitions(${subdir} PRIVATE
        "-DRAISIMGYM_TORCH_ENV_NAME=${subdir}"   # 关键宏!
    )
ENDFOREACH()

关键设计 ------ 宏 RAISIMGYM_TORCH_ENV_NAME

两个目标(rsg_a1_taskdagger_a1编译同一份 raisim_gym.cpp,但通过不同的宏定义,产生不同的 pybind11 模块名:

cpp 复制代码
// raisim_gym.cpp
#ifndef ENVIRONMENT_NAME
  #define ENVIRONMENT_NAME RaisimGymEnv
#endif

PYBIND11_MODULE(RAISIMGYM_TORCH_ENV_NAME, m) {
  // 模块名: rsg_a1_task 或 dagger_a1
  py::class_<VectorizedEnvironment<ENVIRONMENT>>(m, RSG_MAKE_STR(ENVIRONMENT_NAME))
  ...
}

ENVIRONMENT 类本身来自各自子目录下的 Environment.hpp(通过 target_include_directories 区分)。

-mno-avx2 标志:禁用 AVX2 指令集。Raisim 的某些内部实现在 AVX2 上有兼容性问题(可能是数值精度差异),故显式禁用。


执行结果总结

运行 python setup.py develop(内部调用 cmake + make)后:

less 复制代码
raisimGymTorch/env/bin/
├── rsg_a1_task.cpython-38-x86_64-linux-gnu.so   ← 特权策略环境模块
├── dagger_a1.cpython-38-x86_64-linux-gnu.so     ← 蒸馏策略环境模块
├── (Debug模式下还有 rsg_a1_task_debug_app, dagger_a1_debug_app)
产物 编译自 模块名 Environment.hpp 来源
rsg_a1_task.so raisim_gym.cpp + Yaml.cpp + raisim rsg_a1_task envs/rsg_a1_task/
dagger_a1.so 同一份 raisim_gym.cpp + Yaml.cpp + raisim dagger_a1 envs/dagger_a1/

Python 侧导入:

python 复制代码
from raisimGymTorch.env.bin import rsg_a1_task   # 加载 .so
from raisimGymTorch.env.bin import dagger_a1     # 加载 .so

# 使用
env = rsg_a1_task.RaisimGymEnv(resourceDir, cfg_yaml_string)
env = dagger_a1.RaisimGymEnv(resourceDir, cfg_yaml_string)

一句话总结 :CMakeLists.txt 通过一个循环 + 宏定义,用同一套 C++ 模板代码VectorizedEnvironment<ENVIRONMENT> + raisim_gym.cpp)编译出两个独立的 Python 扩展模块 ,分别加载不同的 Environment.hpp 头文件,对应两个训练阶段的不同观测空间和环境逻辑。

相关推荐
麦哲思科技任甲林11 小时前
全变更蒸馏:让AI编程成为一个可进化的系统
人工智能·ai编程·蒸馏·skills·harness工程·回顾
郝学胜_神的一滴14 小时前
CMake 012:Linux 下动态库与可执行程序的单文件构建
c++·cmake
皮皮木子15 小时前
rl_locomotion 编译过程四
编译·cmake
强盛机器学习~17 小时前
2026热门方向!基于强化学习的多无人机移动边缘计算与路径规划研究(完整代码&数据)
人工智能·matlab·无人机·边缘计算·强化学习·无人机路径规划
春日见19 小时前
强化学习方法分类:
人工智能·机器学习·分类·数据挖掘·强化学习
鸿乃江边鸟19 小时前
Starrocks BE 在Mac编译以及遇到的问题解决
starrocks·mac·编译
特立独行的猫a19 小时前
Fast DDS & Fast DDS Spy Windows x64 编译安装完全指南
windows·编译·安装·fastdds·fastddsspy
dozenyaoyida3 天前
RISC-V嵌入式开发:彻底解决“undefined reference to isatty“错误全攻略
经验分享·c·cmake·嵌入式开发·isatty·没有定义问题
盼小辉丶3 天前
PyTorch强化学习实战——使用高级组件复现DQN
pytorch·深度学习·强化学习