This commit is contained in:
CaiXiang
2025-11-14 16:09:58 +08:00
commit af65c2425d
74 changed files with 14650 additions and 0 deletions

View File

@@ -0,0 +1,303 @@
# QT GUI 添加自定义路径功能 - 修改指南
## 概述
本指南将教你如何在现有的 QT GUI (`qt_gui_demo.cpp`) 中添加自定义路径选择功能。
## 修改步骤
### 步骤 1: 添加必要的头文件
在文件开头添加以下头文件第16行之后
```cpp
#include <QFileDialog>
#include <QMessageBox>
```
### 步骤 2: 在 Path Type 下拉框中添加选项
找到 `path_combo_` 的初始化部分约第275-279行修改为
```cpp
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行
```cpp
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行添加
```cpp
// 在 animation_running_ 之后添加:
PathCurve custom_path_;
bool custom_path_loaded_ = false;
```
### 步骤 5: 修改 generateControl() 方法
找到 `generateControl()` 方法约第330行修改路径创建部分
```cpp
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在文件开头添加
```cpp
#include <QInputDialog>
```
## 完整修改示例(精简版)
如果你想要最简单的实现,只需做以下 3 处修改:
### 修改 1: 头文件第1行附近
```cpp
#include "path_tracker.h"
#include <QApplication>
// ... 现有的 includes ...
#include <QFileDialog> // 添加
#include <QMessageBox> // 添加
```
### 修改 2: 添加成员变量MainWindow 类 private 部分)
```cpp
private:
// ... 现有成员 ...
bool animation_running_ = false;
// 添加以下两行:
PathCurve custom_path_;
bool custom_path_loaded_ = false;
};
```
### 修改 3: 修改路径类型选择和控制生成
在 path_combo_ 添加项后约第279行
```cpp
path_combo_->addItem("Load from CSV");
```
在 generateControl() 中添加约第336行
```cpp
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") {
// 原有代码...
```
## 编译
修改完成后重新编译:
```bash
cd build
cmake ..
cmake --build .
```
运行增强版 GUI
```bash
./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` 文件:
```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: QT5 未找到
**解决方案:**
- 安装 QT5: `sudo apt-get install qt5-default` (Linux)
- 或下载 QT5 并设置环境变量
## 总结
通过以上修改,你的 QT GUI 现在支持:
- ✅ 从 CSV 文件加载自定义路径
- ✅ 使用样条插值创建平滑路径
- ✅ 保存路径到 CSV
- ✅ 所有原有的预设路径类型
Enjoy your enhanced AGV path tracking GUI! 🚀