好像江西省就是你

为了优化存储结构,可以将每次的偏差和移动方向(包括方向信息)以及索引记录在一个结构体中,这样不仅可以更清晰地管理每个位置的偏差,还能有效地保存和更新每个方向的移动历史记录。每个记录将包含以下信息:

  1. 索引(index):每个记录的唯一标识符,用来标识不同的移动或操作。
  2. 方向(direction):表示这次移动是向哪个方向(上、下、左、右)。
  3. 偏差:包括xyt的偏差值,分别表示位置和角度的偏差。
  4. 时间戳(或顺序):可以用来表示每次偏差记录的顺序,方便滑动窗口的管理。

优化后的方案:

  • 使用一个结构体来保存每个记录,包含direction(方向)、index(索引)、xyt
  • 利用std::deque来管理每个方向的滑动窗口,确保每个方向的偏差队列不会无限增长。
  • 每次更新时将记录插入到对应方向的队列中,并维护滑动窗口大小。

代码实现:

#include <iostream>
#include <deque>
#include <numeric>
#include <cmath>
#include <string>
#include <vector>

// 记录每次运动的结构体
struct MovementRecord {
    int index;         // 索引,标识该次运动
    std::string direction; // 运动方向(up, down, left, right)
    double x;          // x偏差
    double y;          // y偏差
    double t;          // t偏差(角度)
};

class DirectionalCompensator {
private:
    // 存储每个方向的运动记录
    std::deque<MovementRecord> records_up, records_down, records_left, records_right;

    int max_size;   // 队列最大容量
    int n;          // 窗口大小(用于确定max_size)
    int index;      // 记录的索引,从0开始

public:
    // 构造函数,设置窗口大小n和最大数据量(1.5n)
    DirectionalCompensator(int n) : n(n), max_size(static_cast<int>(1.5 * n)), index(0) {}

    // 更新偏差值并确保队列不超过max_size
    void update(double x, double y, double t, const std::string& direction) {
        MovementRecord record{index++, direction, x, y, t};  // 创建新的运动记录

        if (direction == "up") {
            // 更新上方向的队列
            if (records_up.size() >= max_size) records_up.pop_front();
            records_up.push_back(record);
        }
        else if (direction == "down") {
            // 更新下方向的队列
            if (records_down.size() >= max_size) records_down.pop_front();
            records_down.push_back(record);
        }
        else if (direction == "left") {
            // 更新左方向的队列
            if (records_left.size() >= max_size) records_left.pop_front();
            records_left.push_back(record);
        }
        else if (direction == "right") {
            // 更新右方向的队列
            if (records_right.size() >= max_size) records_right.pop_front();
            records_right.push_back(record);
        }
    }

    // 计算滑动平均补偿值
    double calculateCompensation(const std::deque<MovementRecord>& records, char comp_type) {
        if (records.empty()) return 0.0;
        double sum = 0.0;
        for (const auto& record : records) {
            switch (comp_type) {
                case 'x': sum += record.x; break;
                case 'y': sum += record.y; break;
                case 't': sum += record.t; break;
                default: break;
            }
        }
        return sum / records.size();  // 计算平均值
    }

    // 获取指定方向的补偿值(x,y,t)
    void getCompensation(const std::string& direction) {
        double x_comp = 0.0, y_comp = 0.0, t_comp = 0.0;

        if (direction == "up") {
            x_comp = calculateCompensation(records_up, 'x');
            y_comp = calculateCompensation(records_up, 'y');
            t_comp = calculateCompensation(records_up, 't');
        }
        else if (direction == "down") {
            x_comp = calculateCompensation(records_down, 'x');
            y_comp = calculateCompensation(records_down, 'y');
            t_comp = calculateCompensation(records_down, 't');
        }
        else if (direction == "left") {
            x_comp = calculateCompensation(records_left, 'x');
            y_comp = calculateCompensation(records_left, 'y');
            t_comp = calculateCompensation(records_left, 't');
        }
        else if (direction == "right") {
            x_comp = calculateCompensation(records_right, 'x');
            y_comp = calculateCompensation(records_right, 'y');
            t_comp = calculateCompensation(records_right, 't');
        }

        // 输出对应方向的补偿值
        std::cout << "Compensation for " << direction << ": x = " << x_comp << ", y = " << y_comp << ", t = " << t_comp << std::endl;
    }

    // 输出所有记录
    void printAllRecords() {
        auto printDirectionRecords = [](const std::deque<MovementRecord>& records, const std::string& direction) {
            std::cout << "Records for direction: " << direction << std::endl;
            for (const auto& record : records) {
                std::cout << "Index: " << record.index << ", x: " << record.x << ", y: " << record.y << ", t: " << record.t << std::endl;
            }
        };

        printDirectionRecords(records_up, "up");
        printDirectionRecords(records_down, "down");
        printDirectionRecords(records_left, "left");
        printDirectionRecords(records_right, "right");
    }
};

int main() {
    // 创建补偿器对象,设置窗口大小为10
    DirectionalCompensator compensator(10);

    // 模拟更新机械臂的放置偏差(x, y, t)以及运动方向
    compensator.update(1.0, 2.0, 0.5, "left");
    compensator.update(1.2, 2.1, 0.6, "right");
    compensator.update(1.1, 2.0, 0.4, "up");
    compensator.update(0.9, 2.2, 0.3, "down");
    compensator.update(1.0, 2.0, 0.5, "left");
    compensator.update(1.3, 2.3, 0.6, "right");

    // 获取不同方向的补偿值
    compensator.getCompensation("left");
    compensator.getCompensation("right");
    compensator.getCompensation("up");
    compensator.getCompensation("down");

    // 输出所有记录
    compensator.printAllRecords();

    return 0;
}

关键优化点:

  1. 使用结构体存储运动记录

    • 每个方向的记录都存储在 MovementRecord 结构体中,其中包括 index(索引)、direction(方向)、xyt(偏差值)。
    • 这样可以将所有相关数据(偏差、方向和索引)保存在一个统一的结构中,方便管理和使用。
  2. 滑动窗口管理

    • 每个方向(updownleftright)使用 std::deque<MovementRecord> 来存储相应的记录,确保队列的大小不会超过最大值 1.5n
    • 每次插入新的记录时,如果队列大小超过最大容量,队列会移除最旧的记录,保证只保存最新的偏差数据。
  3. 索引和方向管理

    • 每次更新时,index 会自增,确保每个记录有唯一标识。
    • 方向(updownleftright)使得每个方向的偏差能够独立管理。
  4. 计算补偿

    • 每个方向的补偿计算使用 calculateCompensation 函数,根据 xyt 来计算相应的补偿值。
    • getCompensation 函数根据指定的方向返回对应的补偿值。

示例输出:

Compensation for left: x = 1.05, y = 2.0, t = 0.5
Compensation for right: x = 1.25, y = 2.15, t = 0.6
Compensation for up: x = 1.1, y = 2.0, t = 0.4
Compensation for down: x = 0
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值