Files
RCS-3000/docs/custom_path/QT_GUI_CUSTOM_PATH_GUIDE.md
2025-11-27 14:22:15 +08:00

7.8 KiB
Raw Blame History

QT GUI 添加自定义路径功能 - 修改指南

概述

本指南将教你如何在现有的 QT GUI (qt_gui_demo.cpp) 中添加自定义路径选择功能。

修改步骤

步骤 1: 添加必要的头文件

在文件开头添加以下头文件第16行之后

#include <QFileDialog>
#include <QMessageBox>

步骤 2: 在 Path Type 下拉框中添加选项

找到 path_combo_ 的初始化部分约第275-279行修改为

path_combo_ = new QComboBox(this);
path_combo_->addItem("Circle Arc");
path_combo_->addItem("Straight Line");
path_combo_->addItem("S-Curve");
path_combo_->addItem("Load from CSV");      // 新增
path_combo_->addItem("Custom Spline");       // 新增

步骤 3: 添加按钮和路径信息标签

在 path_combo_ 初始化后添加以下代码约第280行

control_layout->addLayout(path_layout);

// 添加自定义路径按钮
QHBoxLayout* custom_btn_layout = new QHBoxLayout();

QPushButton* load_csv_btn = new QPushButton("Browse CSV...", this);
connect(load_csv_btn, &QPushButton::clicked, [this]() {
    QString filename = QFileDialog::getOpenFileName(
        this, "Open CSV Path File", "", "CSV Files (*.csv)");
    if (!filename.isEmpty()) {
        if (custom_path_.loadFromCSV(filename.toStdString(), true)) {
            custom_path_loaded_ = true;
            QMessageBox::information(this, "Success", 
                QString("Loaded %1 points from CSV!").arg(
                    custom_path_.getPathPoints().size()));
        } else {
            QMessageBox::warning(this, "Error", "Failed to load CSV file!");
        }
    }
});
custom_btn_layout->addWidget(load_csv_btn);

QPushButton* save_csv_btn = new QPushButton("Save Path...", this);
connect(save_csv_btn, &QPushButton::clicked, [this]() {
    QString filename = QFileDialog::getSaveFileName(
        this, "Save Path as CSV", "my_path.csv", "CSV Files (*.csv)");
    if (!filename.isEmpty() && custom_path_loaded_) {
        if (custom_path_.saveToCSV(filename.toStdString())) {
            QMessageBox::information(this, "Success", "Path saved!");
        }
    }
});
custom_btn_layout->addWidget(save_csv_btn);

control_layout->addLayout(custom_btn_layout);

步骤 4: 添加成员变量

在 MainWindow 类的 private 部分约第522-529行添加

// 在 animation_running_ 之后添加:
PathCurve custom_path_;
bool custom_path_loaded_ = false;

步骤 5: 修改 generateControl() 方法

找到 generateControl() 方法约第330行修改路径创建部分

void generateControl() {
    updateAGVModel();

    PathCurve path;
    QString path_type = path_combo_->currentText();

    if (path_type == "Load from CSV") {
        if (!custom_path_loaded_) {
            QMessageBox::warning(this, "Warning", 
                "Please load a CSV file first using 'Browse CSV...' button!");
            return;
        }
        path = custom_path_;
    } 
    else if (path_type == "Custom Spline") {
        if (!custom_path_loaded_) {
            // 如果没有预加载,让用户输入关键点
            bool ok;
            int num_points = QInputDialog::getInt(this, "Spline Input",
                "Number of key points (2-10):", 4, 2, 10, 1, &ok);
            if (!ok) return;

            std::vector<PathPoint> key_points;
            for (int i = 0; i < num_points; ++i) {
                double x = QInputDialog::getDouble(this, "Key Point",
                    QString("Point %1 - X coordinate:").arg(i+1), 
                    i * 3.0, -100, 100, 2, &ok);
                if (!ok) return;
                
                double y = QInputDialog::getDouble(this, "Key Point",
                    QString("Point %1 - Y coordinate:").arg(i+1),
                    (i % 2) * 3.0, -100, 100, 2, &ok);
                if (!ok) return;
                
                key_points.push_back(PathPoint(x, y));
            }

            path.generateSpline(key_points, 200, 0.5);
            custom_path_ = path;
            custom_path_loaded_ = true;
        } else {
            path = custom_path_;
        }
    }
    else if (path_type == "Circle Arc") {
        path.generateCircleArc(5.0, 0.0, 5.0, M_PI, M_PI / 2, 100);
    } else if (path_type == "Straight Line") {
        PathPoint start(0, 0, 0, 0);
        PathPoint end(10, 0, 0, 0);
        path.generateLine(start, end, 100);
    } else if (path_type == "S-Curve") {
        PathPoint p0(0, 0, 0, 0);
        PathPoint p1(3, 2, 0, 0);
        PathPoint p2(7, 2, 0, 0);
        PathPoint p3(10, 0, 0, 0);
        path.generateCubicBezier(p0, p1, p2, p3, 100);
    }

    // 验证路径
    if (path.getPathPoints().empty()) {
        QMessageBox::warning(this, "Error", "Invalid path!");
        return;
    }

    // 其余代码保持不变...
    tracker_->setReferencePath(path);
    // ...
}

步骤 6: 添加 QInputDialog 头文件(可选,用于简单输入)

如果使用 QInputDialog在文件开头添加

#include <QInputDialog>

完整修改示例(精简版)

如果你想要最简单的实现,只需做以下 3 处修改:

修改 1: 头文件第1行附近

#include "path_tracker.h"
#include <QApplication>
// ... 现有的 includes ...
#include <QFileDialog>        // 添加
#include <QMessageBox>        // 添加

修改 2: 添加成员变量MainWindow 类 private 部分)

private:
    // ... 现有成员 ...
    bool animation_running_ = false;
    
    // 添加以下两行:
    PathCurve custom_path_;
    bool custom_path_loaded_ = false;
};

修改 3: 修改路径类型选择和控制生成

在 path_combo_ 添加项后约第279行

path_combo_->addItem("Load from CSV");

在 generateControl() 中添加约第336行

if (path_type == "Load from CSV") {
    QString filename = QFileDialog::getOpenFileName(
        this, "Open CSV", "", "CSV Files (*.csv)");
    if (filename.isEmpty()) return;
    
    if (!path.loadFromCSV(filename.toStdString(), true)) {
        QMessageBox::warning(this, "Error", "Failed to load CSV!");
        return;
    }
} else if (path_type == "Circle Arc") {
    // 原有代码...

编译

修改完成后重新编译:

cd build
cmake ..
cmake --build .

运行增强版 GUI

./agv_qt_gui

使用方法

  1. 启动程序
  2. 在 "Path Type" 下拉框中选择 "Load from CSV"
  3. 点击 "Generate Control" 会弹出文件选择对话框
  4. 选择你的 CSV 文件(例如 examples/custom_path.csv
  5. 程序会加载路径并显示可视化
  6. 点击 "Start Animation" 查看 AGV 跟踪效果

CSV 文件格式示例

创建一个 my_path.csv 文件:

# My custom path
# x, y
0, 0
2, 1
4, 3
6, 4
8, 4
10, 3
12, 1
14, 0

高级功能(可选)

如果需要更完整的功能(样条插值对话框、保存路径等),可以参考已创建的完整版本:

examples/qt_gui_enhanced.cpp

该文件包含:

  • 完整的样条插值对话框
  • CSV 加载和保存功能
  • 路径信息显示
  • 更好的用户界面

故障排除

问题 1: 编译错误 "loadFromCSV 未定义"

解决方案: 确保已经:

  1. 修改了 include/path_curve.h 添加方法声明
  2. CMakeLists.txt 中添加了 src/path_curve_custom.cpp
  3. 重新运行 cmake 和编译

问题 2: CSV 文件加载失败

解决方案:

  • 检查 CSV 格式是否正确
  • 确保文件路径正确
  • 尝试使用绝对路径

问题 3: QT6 未找到

解决方案:

  • 安装 QT6 或设置 Qt6 的环境变量
  • 确保 Qt6_DIR 或 CMAKE_PREFIX_PATH 指向 Qt6 的安装路径

总结

通过以上修改,你的 QT GUI 现在支持:

  • 从 CSV 文件加载自定义路径
  • 使用样条插值创建平滑路径
  • 保存路径到 CSV
  • 所有原有的预设路径类型

Enjoy your enhanced AGV path tracking GUI! 🚀