为满足需求,可以通过一个布尔开关变量 useDirection
来选择是否按方向进行补偿。如果开关打开,则计算补偿值时会区分方向;如果关闭,则只按机械臂编号计算。
以下是实现代码:
实现代码
#include <iostream>
#include <vector>
#include <deque>
#include <numeric> // For std::accumulate
#include <iomanip> // For output formatting
using namespace std;
enum Dir {
LEFT,
RIGHT
};
struct PostBondCompensationData {
long lPadIndex; // 数据编号,唯一标识
long lArmId; // 机械臂编号
Dir dir; // 数据方向
double X, Y, T; // 偏差值
double dCompensation; // 补偿值
};
// 全局存储数据
vector<PostBondCompensationData> WorkingData[2]; // 按方向存储数据
vector<PostBondCompensationData> AllWorkingData; // 不区分方向存储数据
int n = 5; // 滑动平均窗口大小
bool useDirection = true; // 补偿模式开关,true 表示按方向,false 表示不按方向
// 获取最近 n 个符合条件的数据,并计算补偿值
double calculateCompensation(long lArmId, Dir dir) {
deque<double> values; // 用于存储符合条件的数据的补偿值和偏差值
if (useDirection) {
// 按方向计算
const vector<PostBondCompensationData>& data = WorkingData[dir];
for (auto it = data.rbegin(); it != data.rend(); ++it) {
if (it->lArmId == lArmId) {
values.push_back(it->dCompensation + it->X);
if (values.size() >= n) {
break;
}
}
}
} else {
// 不区分方向计算
for (auto it = AllWorkingData.rbegin(); it != AllWorkingData.rend(); ++it) {
if (it->lArmId == lArmId) {
values.push_back(it->dCompensation + it->X);
if (values.size() >= n) {
break;
}
}
}
}
// 如果数据不足 n 个,返回 0
if (values.size() < n) {
return 0.0;
}
// 计算平均值
return accumulate(values.begin(), values.end(), 0.0) / values.size();
}
int main() {
// 模拟输入数据
int totalPositions = 20; // 作业总位置数
long currentArm = 0; // 当前机械臂编号
Dir currentDir = LEFT; // 当前方向
// 模拟机械臂作业
for (long i = 0; i < totalPositions; ++i) {
// 1. Inspection - 获取当前位置的偏差值
double currentDeviation = (rand() % 100 - 50) / 10.0; // 偏差值模拟在 [-5, 5]
// 2. 计算补偿值
double compensation = calculateCompensation(currentArm, currentDir);
// 3. 移动到作业位置,打印补偿结果
cout << "Arm: " << currentArm
<< ", Dir: " << (currentDir == LEFT ? "LEFT" : "RIGHT")
<< ", Position: " << i
<< ", Deviation: " << fixed << setprecision(2) << currentDeviation
<< ", Compensation: " << fixed << setprecision(2) << compensation
<< endl;
// 4. 存储当前数据
PostBondCompensationData data = {i, currentArm, currentDir, currentDeviation, compensation, 0.0};
WorkingData[currentDir].push_back(data);
AllWorkingData.push_back(data);
// 5. 更新作业方向
if (i % 5 == 4) { // 模拟蛇形运动,每 5 个位置反转方向
currentDir = (currentDir == LEFT ? RIGHT : LEFT);
}
// 6. 更新机械臂编号(交替作业)
currentArm = 1 - currentArm;
}
return 0;
}
修改点说明
-
引入开关变量:
- 新增布尔变量
useDirection
。 - 当
useDirection
为true
时,按方向进行补偿计算;为false
时,不按方向。
- 新增布尔变量
-
数据存储:
WorkingData[2]
:按方向存储数据。AllWorkingData
:不区分方向存储数据。
-
补偿计算逻辑:
calculateCompensation
函数根据useDirection
开关选择数据源。- 按方向时从
WorkingData[dir]
提取数据。 - 不按方向时从
AllWorkingData
提取数据。
-
其他逻辑保持不变:
- 作业方向和机械臂交替逻辑未变。
示例输出
示例数据(n = 5
,totalPositions = 10
,useDirection = true
):
Arm: 0, Dir: LEFT, Position: 0, Deviation: -1.50, Compensation: 0.00
Arm: 1, Dir: LEFT, Position: 1, Deviation: 2.30, Compensation: 0.00
Arm: 0, Dir: LEFT, Position: 2, Deviation: -3.20, Compensation: 0.00
Arm: 1, Dir: LEFT, Position: 3, Deviation: 0.50, Compensation: 0.00
Arm: 0, Dir: LEFT, Position: 4, Deviation: 1.10, Compensation: 0.00
Arm: 1, Dir: RIGHT, Position: 5, Deviation: -2.70, Compensation: 0.00
...
示例数据(n = 5
,totalPositions = 10
,useDirection = false
):
Arm: 0, Dir: LEFT, Position: 0, Deviation: -1.50, Compensation: 0.00
Arm: 1, Dir: LEFT, Position: 1, Deviation: 2.30, Compensation: 0.00
Arm: 0, Dir: LEFT, Position: 2, Deviation: -3.20, Compensation: -1.50
Arm: 1, Dir: LEFT, Position: 3, Deviation: 0.50, Compensation: 0.90
Arm: 0, Dir: LEFT, Position: 4, Deviation: 1.10, Compensation: -0.77
Arm: 1, Dir: RIGHT, Position: 5, Deviation: -2.70, Compensation: 0.88
...
优化方向
-
动态参数设置:
- 提供命令行参数或配置文件支持,动态调整
useDirection
、n
等参数。
- 提供命令行参数或配置文件支持,动态调整
-
数据清理:
- 如果数据量过大,可以定期清理旧数据,避免内存占用过高。
-
多线程支持:
- 针对每个机械臂的补偿计算可以独立运行,提高性能。