CMake模块构建工程

This commit is contained in:
chen
2026-07-02 10:24:20 +00:00
parent e606b9e53c
commit d9813ea8fe
8 changed files with 311 additions and 16 deletions
+7
View File
@@ -0,0 +1,7 @@
# 指定 compile_commands.json 所在目录(相对路径)
CompileFlags:
# 告诉 clangdcompile_commands.json 在 build 目录下
CompilationDatabase: build
+28
View File
@@ -0,0 +1,28 @@
# CMake最低版本
cmake_minimum_required(VERSION 3.21)
# 工程名、版本号、工程描述
project(MotionApp
VERSION 0.1
DESCRIPTION "Test")
# C/C++ 标准版本
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 11)
# 指定在当前目录或以下目录下通过命令(如 add_executable() )链接稍后创建的任何目标时要使用的库或标志
LINK_LIBRARIES(m)
# 工程源文件
add_executable(${PROJECT_NAME}
./Src/main.cpp)
# 工程包含目录
include_directories(./Inc)
# 链接 moduleA,自动继承其 PUBLIC 的头文件路径和编译属性
target_link_libraries(${PROJECT_NAME}
PRIVATE # 如果 moduleB 只是内部使用 moduleA,选 PRIVATE
MotionLib
)
+3
View File
@@ -1,5 +1,8 @@
#include "Axis.h"
int main()
{
plcopen::Axis axis();
return 0;
}
+38 -16
View File
@@ -1,21 +1,43 @@
# CMake最低版本
cmake_minimum_required(VERSION 3.21)
cmake_minimum_required(VERSION 3.22)
# 工程名、版本号、工程描述
project(Motion
VERSION 0.1
DESCRIPTION "Test")
project(Motion)
# C/C++ 标准版本
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 11)
# 开启编译数据库导出(强制开启,不被缓存覆盖)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON CACHE INTERNAL "")
# 指定在当前目录或以下目录下通过命令(如 add_executable() )链接稍后创建的任何目标时要使用的库或标志
LINK_LIBRARIES(m)
# 针对 GCC 编译器添加 UTF-8 编码选项
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU") # 仅对 GCC 生效
# 添加 C++ 编译选项
add_compile_options(-finput-charset=UTF-8)
add_compile_options(-fexec-charset=UTF-8)
# 若需要支持 C 语言,补充 C 编译选项
add_compile_options($<$<COMPILE_LANGUAGE:C>:-finput-charset=UTF-8>)
add_compile_options($<$<COMPILE_LANGUAGE:C>:-fexec-charset=UTF-8>)
endif()
# 工程源文件
add_executable(${PROJECT_NAME}
./App/Src/main.cpp)
if(WIN32)
# Windows平台特定的设置
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/build/$<CONFIGURATION>/WIN32")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/build/$<CONFIGURATION>/WIN32")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/build/$<CONFIGURATION>/WIN32/static_lib")
elseif(APPLE)
# Apple平台特定的设置
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/build/$<CONFIGURATION>/APPLE")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/build/$<CONFIGURATION>/APPLE")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/build/$<CONFIGURATION>/APPLE/static_lib")
elseif(UNIX) # 注意:Linux和macOS都满足UNIX为TRUE,所以通常先判断APPLE
# Linux或其他类Unix系统的设置
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/build/$<CONFIGURATION>/UNIX")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/build/$<CONFIGURATION>/UNIX")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/build/$<CONFIGURATION>/UNIX/static_lib")
endif()
# 工程包含目录
include_directories(./Inc)
set(CMAKE_C_STANDARD 17)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_subdirectory(${CMAKE_SOURCE_DIR}/MotionLib)
add_subdirectory(${CMAKE_SOURCE_DIR}/App)
+31
View File
@@ -0,0 +1,31 @@
project(MotionLib
VERSION 0.0.1 # 版本 0.0.1
LANGUAGES CXX # C++
DESCRIPTION "运动控制库" # 描述
)
set(INC_DIRECTORES
${CMAKE_CURRENT_SOURCE_DIR}/Inc
)
set(LIB_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/Src/Axis.cpp
)
set(LIB_HEADERS
${CMAKE_CURRENT_SOURCE_DIR}/Inc/Types.h
${CMAKE_CURRENT_SOURCE_DIR}/Inc/Axis.h
)
add_library(${PROJECT_NAME} SHARED
${LIB_SOURCES}
${LIB_HEADERS}
)
target_include_directories(${PROJECT_NAME}
PUBLIC
${INC_DIRECTORES}
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/Src
)
+63
View File
@@ -0,0 +1,63 @@
/**
* @file Axis.h
* @author your name (you@domain.com)
* @brief
* @version 0.1
* @date 2026-07-02
*
* @copyright Copyright (c) 2026
*
*/
#include "Types.h"
namespace plcopen {
/**
* \enum MotionCommandType
* \brief 内部运动指令类型(功能块 → 轴模型映射)
*/
enum class MotionCommandType {
None, /*!< 无活动指令 */
PointToPoint, /*!< MC_MoveAbsolute / MC_MoveRelative */
Velocity, /*!< MC_MoveVelocity */
Stop, /*!< MC_Stop */
Halt, /*!< MC_Halt */
Home, /*!< MC_Home */
};
/**
* \struct MotionCommand
* \brief 当前活动运动指令的参数快照
*/
struct MotionCommand {
MotionCommandType type = MotionCommandType::None;
REAL targetPosition = 0.0;
REAL targetVelocity = 0.0;
REAL maxVelocity = 0.0;
REAL acceleration = 0.0;
REAL deceleration = 0.0;
REAL homePosition = 0.0;
MC_AXIS_STATE resultingState = MC_AXIS_STATE::DiscreteMotion;
};
/**
* \class Axis
* \brief 单轴仿真对象,实现 PLCopen 轴状态机与运动学
* \note 不要在功能块 cycle() 之外直接修改 Axis 内部状态。
*/
class Axis {
public:
/**
* \brief 构造轴
* \param axisNo 轴编号
* \param name 轴名称
*/
explicit Axis(UINT axisNo = 1, std::string name = "Axis1");
private:
AXIS_REF ref_;
MC_AXIS_STATE state_ = MC_AXIS_STATE::Disabled;
};
}
+121
View File
@@ -0,0 +1,121 @@
/**
* @file types.h
* @author
* @brief
* @version 0.1
* @date 2026-07-02
*
* @copyright Copyright (c) 2026
*
*/
#include <cstdint>
#include <string>
namespace plcopen {
class Axis;
/** \typedef BOOL IEC 61131-3 BOOL 类型映射 */
using BOOL = bool;
/** \typedef REAL IEC 61131-3 REAL 类型映射(双精度浮点) */
using REAL = double;
/** \typedef WORD IEC 61131-3 WORD 类型映射(16 位无符号,常用于 ErrorID */
using WORD = std::uint16_t;
/** \typedef UINT IEC 61131-3 UINT 类型映射(32 位无符号) */
using UINT = std::uint32_t;
/**
* \enum MC_BUFFER_MODE
* \brief 运动指令缓冲与混合模式 (MC_BUFFER_MODE)
*
* 用于带 BufferMode 输入的功能块,决定新指令与当前运动的关系。
*/
enum class MC_BUFFER_MODE : std::uint8_t {
mcAborting = 0, /*!< 默认:立即执行,中断当前运动并清空缓冲 */
mcBuffered = 1, /*!< 等待前一指令 Done 后顺序执行,无混合 */
mcBlendingLow = 2, /*!< 混合:在衔接点取两指令速度的较低值 */
mcBlendingPrevious = 3, /*!< 混合:在衔接点保持前一指令速度 */
mcBlendingNext = 4, /*!< 混合:在衔接点使用当前指令速度 */
mcBlendingHigh = 5, /*!< 混合:在衔接点取两指令速度的较高值 */
};
/**
* \enum MC_DIRECTION
* \brief 定位运动方向 (MC_DIRECTION)
*/
enum class MC_DIRECTION : std::uint8_t {
mcPositiveDirection = 0, /*!< 正向运动 */
mcShortestWay = 1, /*!< 最短路径(线性轴默认策略) */
mcNegativeDirection = 2, /*!< 负向运动 */
mcCurrentDirection = 3, /*!< 保持当前运动方向 */
};
/**
* \enum MC_SOURCE
* \brief 运动数据读取来源 (MC_SOURCE)
*/
enum class MC_SOURCE : std::uint8_t {
mcCommandedValue = 0, /*!< 指令值 */
mcSetValue = 1, /*!< 设定值 */
mcActualValue = 2, /*!< 实际值 */
};
/**
* \enum MC_AXIS_STATE
* \brief 轴状态机状态 (PLCopen 状态图)
*
* \par 典型状态转换
* - Disabled → StandstillMC_Power.Enable = TRUE
* - Standstill → DiscreteMotionMC_MoveAbsolute / MC_MoveRelative
* - Standstill → ContinuousMotionMC_MoveVelocity
* - Standstill → HomingMC_Home
* - 任意 → ErrorStop:轴错误或功率故障
* - ErrorStop → StandstillMC_Reset
*
* \note 同一时刻仅有一个状态位为 TRUE(由 MC_ReadStatus 反映)。
*/
enum class MC_AXIS_STATE : std::uint8_t {
Disabled = 0, /*!< 初始/下电状态,功率未使能 */
Standstill, /*!< 静止,功率已使能,可接受运动指令 */
Homing, /*!< 回零进行中 (MC_Home) */
DiscreteMotion, /*!< 离散运动(点到点),完成后自动停止 */
ContinuousMotion, /*!< 连续运动(如 MC_MoveVelocity */
Stopping, /*!< MC_Stop 激活,减速中且拒绝新运动 */
ErrorStop, /*!< 错误停止,需 MC_Reset 恢复 */
SynchronizedMotion, /*!< 同步运动(Cam/Gear,本库预留) */
};
/**
* \enum MC_ERROR_ID
* \brief 功能块与轴通用错误码
*/
enum class MC_ERROR_ID : WORD {
mcNoError = 0, /*!< 无错误 */
mcInvalidParameter = 1, /*!< 参数非法(如速度 ≤ 0) */
mcInvalidState = 2, /*!< 当前状态不允许该操作 */
mcActionNotAllowed = 3, /*!< 轴未上电或处于 Stopping/ErrorStop */
mcAxisNotPowered = 4, /*!< 轴未使能 */
mcAxisNotHomed = 5, /*!< 轴未完成回零 */
mcCommandAborted = 6, /*!< 指令被中断 */
mcStopActive = 7, /*!< MC_Stop 占用轴 */
mcPowerFailure = 8, /*!< 功率级故障 */
mcFollowingError = 9, /*!< 跟随误差超限 */
};
/**
* \struct AXIS_REF
* \brief 轴引用 (VAR_IN_OUT),所有 MC 功能块的公共轴参数
*
* \details
* 在 IEC 61131-3 程序中作为 VAR_IN_OUT 传递;本 C++ 实现中,
* `axis` 指针由 Axis 对象构造时自动绑定,应用层无需手动设置。
*/
struct AXIS_REF {
UINT axisNo = 0; /*!< 轴编号(用户定义) */
std::string axisName; /*!< 轴名称 */
Axis* axis = nullptr; /*!< 内部绑定指针,指向仿真轴实例 */
};
}
+20
View File
@@ -0,0 +1,20 @@
/**
* @file Axis.cpp
* @author
* @brief
* @version 0.1
* @date 2026-07-02
*
* @copyright Copyright (c) 2026
*
*/
#include "Types.h"
#include "Axis.h"
namespace plcopen {
Axis::Axis(UINT axisNo, std::string name) {
ref_.axisNo = axisNo;
ref_.axisName = std::move(name);
ref_.axis = this;
}
}