是的,如果 AllWorkingData
的大小需要匹配 WorkingData
的存储逻辑,且 WorkingData
存储的是按方向区分的数据,那么 AllWorkingData
的大小限制应该是 WorkingData
大小的两倍。
因为 WorkingData
分为两个方向(LEFT
和 RIGHT
),它们分别限制大小为 ( 1.5n ),而 AllWorkingData
包含了所有方向的数据,因此大小限制应为 ( 2 \times 1.5n = 3n )。
修改后的代码
#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; // 滑动平均窗口大小
int maxSizeWorkingData = 1.5 * n; // WorkingData 每个方向的最大大小
int maxSizeAllWorkingData = 2 * maxSizeWorkingData; // AllWorkingData 的最大大小
bool useDirection = true; // 补偿模式开关,true 表示按方向,false 表示不按方向
// 限制存储数据的大小
void limitDataSize() {
for (int dir = 0; dir < 2; ++dir) {
if (WorkingData[dir].size() > maxSizeWorkingData) {
WorkingData[dir].erase(WorkingData[dir].begin());
}
}
if (AllWorkingData.size() > maxSizeAllWorkingData) {
AllWorkingData.erase(AllWorkingData.begin());
}
}
// 获取最近 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) {
// Step 1: 计算补偿值
double compensation = calculateCompensation(currentArm, currentDir);
// Step 2: 移动到作业位置(模拟移动)
cout << "Arm: " << currentArm
<< ", Dir: " << (currentDir == LEFT ? "LEFT" : "RIGHT")
<< ", Position: " << i
<< ", Compensation: " << fixed << setprecision(2) << compensation
<< endl;
// Step 3: 保存当前作业数据到末尾
PostBondCompensationData data = {i, currentArm, currentDir, 0.0, compensation, 0.0};
WorkingData[currentDir].push_back(data);
AllWorkingData.push_back(data);
// 限制数据大小
limitDataSize();
// Step 4: 识别实际偏差值,更新最后一条数据
double actualDeviation = (rand() % 100 - 50) / 10.0; // 模拟偏差值在 [-5, 5]
WorkingData[currentDir].back().X = actualDeviation;
AllWorkingData.back().X = actualDeviation;
// 打印实际偏差值
cout << "Actual Deviation: " << fixed << setprecision(2) << actualDeviation << endl;
// Step 5: 更新作业方向
if (i % 5 == 4) { // 模拟蛇形运动,每 5 个位置反转方向
currentDir = (currentDir == LEFT ? RIGHT : LEFT);
}
// Step 6: 更新机械臂编号(交替作业)
currentArm = 1 - currentArm;
}
return 0;
}
修改点
-
maxSizeAllWorkingData
调整:- 设置为
2 * maxSizeWorkingData
,即 ( 3n )。
- 设置为
-
limitDataSize
函数更新:- 按方向限制
WorkingData
大小为maxSizeWorkingData
。 - 限制
AllWorkingData
大小为maxSizeAllWorkingData
。
- 按方向限制
-
逻辑保持一致:
- 补偿值计算、数据保存和更新的逻辑未改变,只增加了更精确的数据存储大小管理。
输出示例
Arm: 0, Dir: LEFT, Position: 0, Compensation: 0.00
Actual Deviation: -3.10
Arm: 1, Dir: LEFT, Position: 1, Compensation: 0.00
Actual Deviation: 2.50
Arm: 0, Dir: LEFT, Position: 2, Compensation: 0.00
Actual Deviation: -1.20
Arm: 1, Dir: LEFT, Position: 3, Compensation: 0.00
Actual Deviation: 1.90
Arm: 0, Dir: LEFT, Position: 4, Compensation: 0.00
Actual Deviation: 0.80
...
总结
WorkingData
每个方向限制大小为 ( 1.5n )。AllWorkingData
总大小限制为 ( 3n )。- 此设计更符合逻辑,且避免数据存储过大导致性能问题。