feat: 添加多线程框架与轴周期接口
- 新增 MotionTickThread 线程模块 - main.cpp: 引入双线程架构(UserAppThread + MotionTickThread) - Axis: 新增 cycle() 接口,添加 #pragma once 头文件保护 - App/CMakeLists.txt: 链接 pthread,重组源文件列表 - .gitignore: 排除 docs/html、.vscode、compile_commands.json
This commit is contained in:
@@ -1,3 +1,6 @@
|
|||||||
build
|
build
|
||||||
|
docs/html
|
||||||
|
.vscode/
|
||||||
|
compile_commands.json
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+6
-4
@@ -6,12 +6,13 @@ project(MotionApp
|
|||||||
VERSION 0.1
|
VERSION 0.1
|
||||||
DESCRIPTION "Test")
|
DESCRIPTION "Test")
|
||||||
|
|
||||||
# 指定在当前目录或以下目录下通过命令(如 add_executable() )链接稍后创建的任何目标时要使用的库或标志
|
set(SOURCE_FILES
|
||||||
LINK_LIBRARIES(m)
|
${CMAKE_CURRENT_SOURCE_DIR}/Src/main.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/Src/MotionTickThread.cpp
|
||||||
|
)
|
||||||
|
|
||||||
# 工程源文件
|
# 工程源文件
|
||||||
add_executable(${PROJECT_NAME}
|
add_executable(${PROJECT_NAME} ${SOURCE_FILES})
|
||||||
./Src/main.cpp)
|
|
||||||
|
|
||||||
# 工程包含目录
|
# 工程包含目录
|
||||||
include_directories(./Inc)
|
include_directories(./Inc)
|
||||||
@@ -19,6 +20,7 @@ include_directories(./Inc)
|
|||||||
# 链接 moduleA,自动继承其 PUBLIC 的头文件路径和编译属性
|
# 链接 moduleA,自动继承其 PUBLIC 的头文件路径和编译属性
|
||||||
target_link_libraries(${PROJECT_NAME}
|
target_link_libraries(${PROJECT_NAME}
|
||||||
PRIVATE # 如果 moduleB 只是内部使用 moduleA,选 PRIVATE
|
PRIVATE # 如果 moduleB 只是内部使用 moduleA,选 PRIVATE
|
||||||
|
pthread
|
||||||
MotionLib
|
MotionLib
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
/**
|
||||||
|
* @file MotionTickThread.h
|
||||||
|
* @author
|
||||||
|
* @brief
|
||||||
|
* @version 0.1
|
||||||
|
* @date 2026-07-03
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2026
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
#include "Axis.h"
|
||||||
|
#include "Types.h"
|
||||||
|
|
||||||
|
|
||||||
|
void MotionTickThread(std::unique_ptr<std::vector<plcopen::Axis>> axisList);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
/**
|
||||||
|
* @file MotionTickThread.cpp
|
||||||
|
* @author
|
||||||
|
* @brief
|
||||||
|
* @version 0.1
|
||||||
|
* @date 2026-07-03
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2026
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "MotionTickThread.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
*
|
||||||
|
* @param axisList
|
||||||
|
*/
|
||||||
|
void MotionTickThread(std::unique_ptr<std::vector<plcopen::Axis>> axisList)
|
||||||
|
{
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
for (auto& axis : *axisList) {
|
||||||
|
axis.cycle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
+46
-2
@@ -1,8 +1,52 @@
|
|||||||
|
/**
|
||||||
|
* @file main.cpp
|
||||||
|
* @author
|
||||||
|
* @brief
|
||||||
|
* @version 0.1
|
||||||
|
* @date 2026-07-03
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2026
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <thread>
|
||||||
|
#include <mutex>
|
||||||
|
#include <vector>
|
||||||
|
#include "MotionTickThread.h"
|
||||||
#include "Axis.h"
|
#include "Axis.h"
|
||||||
|
#include "Types.h"
|
||||||
|
|
||||||
|
static int UserAppThread();
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<plcopen::Axis> axisList;
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
plcopen::Axis axis();
|
|
||||||
|
plcopen::Axis axis1(1, "axis1");
|
||||||
|
plcopen::Axis axis2(2, "axis2");
|
||||||
|
axisList.push_back(axis1);
|
||||||
|
axisList.push_back(axis2);
|
||||||
|
|
||||||
|
std::thread userAppThread(UserAppThread);
|
||||||
|
std::thread motionTickThread(MotionTickThread,
|
||||||
|
std::move(std::make_unique<std::vector<plcopen::Axis>>(axisList)));
|
||||||
|
|
||||||
|
motionTickThread.join();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int UserAppThread()
|
||||||
|
{
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,9 @@
|
|||||||
* @copyright Copyright (c) 2026
|
* @copyright Copyright (c) 2026
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#include "Types.h"
|
#include "Types.h"
|
||||||
|
|
||||||
namespace plcopen {
|
namespace plcopen {
|
||||||
@@ -54,6 +57,10 @@ public:
|
|||||||
* \param name 轴名称
|
* \param name 轴名称
|
||||||
*/
|
*/
|
||||||
explicit Axis(UINT axisNo = 1, std::string name = "Axis1");
|
explicit Axis(UINT axisNo = 1, std::string name = "Axis1");
|
||||||
|
|
||||||
|
void cycle();
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AXIS_REF ref_;
|
AXIS_REF ref_;
|
||||||
MC_AXIS_STATE state_ = MC_AXIS_STATE::Disabled;
|
MC_AXIS_STATE state_ = MC_AXIS_STATE::Disabled;
|
||||||
|
|||||||
@@ -18,4 +18,10 @@ Axis::Axis(UINT axisNo, std::string name) {
|
|||||||
ref_.axisName = std::move(name);
|
ref_.axisName = std::move(name);
|
||||||
ref_.axis = this;
|
ref_.axis = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Axis::cycle()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,129 @@
|
|||||||
|
# Axis 类必须属性
|
||||||
|
|
||||||
|
`Axis` 是 PLCopen 运动控制库的核心仿真类,实现 IEC 61131-3 单轴状态机与运动学。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. 当前已实现
|
||||||
|
|
||||||
|
### 1.1 轴标识与自引用 — `AXIS_REF ref_`
|
||||||
|
|
||||||
|
| 字段 | 类型 | 说明 |
|
||||||
|
|------|------|------|
|
||||||
|
| `axisNo` | `UINT` | 轴编号,由用户在构造时指定,默认 1 |
|
||||||
|
| `axisName` | `std::string` | 轴名称,默认 `"Axis1"` |
|
||||||
|
| `axis` | `Axis*` | 指向自身实例的指针,供功能块间接访问轴对象 |
|
||||||
|
|
||||||
|
> `AXIS_REF` 在 IEC 61131-3 中是 `VAR_IN_OUT` 参数,本实现中构造时自绑定。
|
||||||
|
|
||||||
|
### 1.2 轴状态 — `MC_AXIS_STATE state_`
|
||||||
|
|
||||||
|
当前状态机状态,初始值为 `Disabled`。可能的取值:
|
||||||
|
|
||||||
|
```
|
||||||
|
Disabled → Standstill → DiscreteMotion / ContinuousMotion / Homing
|
||||||
|
→ Stopping
|
||||||
|
ErrorStop
|
||||||
|
SynchronizedMotion (预留)
|
||||||
|
```
|
||||||
|
|
||||||
|
状态转换由 `cycle()` 方法驱动(尚未实现)。
|
||||||
|
|
||||||
|
### 1.3 构造函数
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
explicit Axis(UINT axisNo = 1, std::string name = "Axis1");
|
||||||
|
```
|
||||||
|
|
||||||
|
初始化 `ref_` 并自绑定 `axis` 指针,`state_` 默认 `Disabled`。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. 必须扩展的属性(待实现)
|
||||||
|
|
||||||
|
按照 PLCopen 规范,完整的轴模型还需以下属性。
|
||||||
|
|
||||||
|
### 2.1 运动学属性
|
||||||
|
|
||||||
|
| 属性 | 类型 | 说明 |
|
||||||
|
|------|------|------|
|
||||||
|
| `position_` | `REAL` | 当前指令位置 |
|
||||||
|
| `actualPosition_` | `REAL` | 当前实际位置 |
|
||||||
|
| `velocity_` | `REAL` | 当前速度 |
|
||||||
|
| `actualVelocity_` | `REAL` | 实际速度 |
|
||||||
|
| `acceleration_` | `REAL` | 当前加速度 |
|
||||||
|
| `deceleration_` | `REAL` | 当前减速度 |
|
||||||
|
|
||||||
|
### 2.2 活动指令 — `MotionCommand activeCommand_`
|
||||||
|
|
||||||
|
当前正在执行的运动指令参数快照,类型为 `MotionCommand`:
|
||||||
|
|
||||||
|
| 字段 | 类型 | 说明 |
|
||||||
|
|------|------|------|
|
||||||
|
| `type` | `MotionCommandType` | 指令类型(点到点 / 速度 / 停止 / 暂停 / 回零) |
|
||||||
|
| `targetPosition` | `REAL` | 目标位置 |
|
||||||
|
| `targetVelocity` | `REAL` | 目标速度 |
|
||||||
|
| `maxVelocity` | `REAL` | 最大速度 |
|
||||||
|
| `acceleration` | `REAL` | 加速度 |
|
||||||
|
| `deceleration` | `REAL` | 减速度 |
|
||||||
|
| `homePosition` | `REAL` | 回零位置 |
|
||||||
|
| `resultingState` | `MC_AXIS_STATE` | 指令完成后要进入的状态 |
|
||||||
|
|
||||||
|
### 2.3 功率与使能
|
||||||
|
|
||||||
|
| 属性 | 类型 | 说明 |
|
||||||
|
|------|------|------|
|
||||||
|
| `powerEnabled_` | `BOOL` | 功率级是否使能 |
|
||||||
|
| `homed_` | `BOOL` | 是否已完成回零 |
|
||||||
|
|
||||||
|
### 2.4 错误管理
|
||||||
|
|
||||||
|
| 属性 | 类型 | 说明 |
|
||||||
|
|------|------|------|
|
||||||
|
| `errorId_` | `MC_ERROR_ID` | 当前错误码,`mcNoError` 表示正常 |
|
||||||
|
| `errorStop_` | `BOOL` | 是否触发错误停止 |
|
||||||
|
|
||||||
|
### 2.5 轴状态机方法 — `cycle()`
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
void cycle(REAL deltaTime);
|
||||||
|
```
|
||||||
|
|
||||||
|
每周期由应用层调用,执行:
|
||||||
|
1. 根据 `activeCommand_` 计算运动学输出
|
||||||
|
2. 更新 `position_` / `velocity_`
|
||||||
|
3. 评估状态转换条件
|
||||||
|
4. 在离散运动到达目标时自动切换到 `Standstill`
|
||||||
|
|
||||||
|
### 2.6 功能块交互接口
|
||||||
|
|
||||||
|
| 方法 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| `acceptCommand(const MotionCommand&)` | 接收功能块下发的运动指令 |
|
||||||
|
| `doPower(BOOL enable)` | 功率使能/去使能 |
|
||||||
|
| `doStop()` / `doHalt()` | 停止 / 暂停 |
|
||||||
|
| `doReset()` | 从 ErrorStop 恢复 |
|
||||||
|
| `doHome(REAL homePos)` | 发起回零 |
|
||||||
|
| `readStatus()` | 读取当前状态快照 |
|
||||||
|
| `readError()` | 读取当前错误码 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. 完整属性清单(含待实现)
|
||||||
|
|
||||||
|
```
|
||||||
|
Axis
|
||||||
|
├── ref_ (AXIS_REF) ✅ 已实现
|
||||||
|
├── state_ (MC_AXIS_STATE) ✅ 已实现
|
||||||
|
├── position_ (REAL) ⬜ 位置
|
||||||
|
├── actualPosition_ (REAL) ⬜ 实际位置
|
||||||
|
├── velocity_ (REAL) ⬜ 速度
|
||||||
|
├── actualVelocity_ (REAL) ⬜ 实际速度
|
||||||
|
├── acceleration_ (REAL) ⬜ 加速度
|
||||||
|
├── deceleration_ (REAL) ⬜ 减速度
|
||||||
|
├── activeCommand_ (MotionCommand) ⬜ 活动指令
|
||||||
|
├── powerEnabled_ (BOOL) ⬜ 功率使能
|
||||||
|
├── homed_ (BOOL) ⬜ 回零完成
|
||||||
|
├── errorId_ (MC_ERROR_ID) ⬜ 错误码
|
||||||
|
└── errorStop_ (BOOL) ⬜ 错误停止
|
||||||
|
```
|
||||||
Reference in New Issue
Block a user