//模擬小車行駛 for (int i = 0; i < agvs.size(); i++) { for (int j = 0; j < tasks.size(); j++) { if (tasks[j].id == agvs[i].get_task_id()) { completed_task_index = j; break; } } if (tasks[completed_task_index].completed == 2 ) { // 如果已经完成任务 paths[i].clear(); continue; // 跳过此次循环 } if (! paths[i].empty()) { int cur_x = agvs[i].getCurrentX(); int cur_y = agvs[i].getCurrentY(); Node* next_node = paths[i][0]; float speed = agvs[i].getSpeed(); float distance = sqrt(pow(next_node->x - agvs[i].getCurrentX(), 2) + pow(next_node->y - agvs[i].getCurrentY(), 2)); float time = distance / speed * 1000; //_MAP[cur_x][cur_y] = 1; QTimer::singleShot(time, this, [&, i, next_node, cur_x, cur_y]() { // 离开当前位置时将标记设为0 //_MAP[cur_x][cur_y] = 0; agvs[i].setCurrentX(next_node->x); agvs[i].setCurrentY(next_node->y); this->update(); // 在窗口中重绘 }); } } }, for (int i = 0; i < agvs.size(); i++) { if (agvs[i].getLoad()){ painter.drawPixmap(agvs[i].getCurrentX()*25+200-(nodeSpacing-nodeSize)/2,(agvs[i].getCurrentY()+1)*25+50-(nodeSpacing-nodeSize)/2,25,25,QPixmap(":/new/prefix1/agvload.png").scaled(25,25)); } else { painter.drawPixmap(agvs[i].getCurrentX()*25+200-(nodeSpacing-nodeSize)/2,(agvs[i].getCurrentY()+1)*25+50-(nodeSpacing-nodeSize)/2,25,25,QPixmap(":/new/prefix1/agv1.png").scaled(25,25)); } },增加代碼:如果path不爲空,且沒有空指針等異常情況,繪製出agv從path中獲取的行駛路綫
时间: 2023-12-27 19:04:33 浏览: 47
可以在第一个for循环的内部添加如下代码:
```
if (!paths[i].empty() && paths[i][0] != nullptr) {
Node* next_node = paths[i][0];
painter.setPen(QPen(Qt::red, 2));
painter.drawLine(agvs[i].getCurrentX()*25+200, (agvs[i].getCurrentY()+1)*25+50, next_node->x*25+200, (next_node->y+1)*25+50);
}
```
这段代码会在每次AGV移动时,根据AGV当前位置和路径中下一个节点的位置画一条红线作为路径线路。需要注意的是,要在画线之前先判断paths[i]是否为空,和paths[i][0]是否为空指针,以避免程序崩溃。
相关问题
//分配小車 AGVScheduler scheduler; scheduler.assign_task_to_agv(tasks, agvs);//開始分配任務 // 遍历所有 AGV,更新位置和状态 for (int i = 0; i < agvs.size(); i++) { if (agvs[i].available_ == 0 && agvs[i].run_== 0 ) { moveAgvs(i); std:: cout << "agv.id:"<< agvs[i].id_ << "___task.id :" << agvs[i].task_id << endl; } },,修改爲,使用多綫程去設置agv運行
可以将原来的遍历所有 AGV 的代码封装在一个函数中,然后使用多线程去调用这个函数。具体实现方法如下:
1. 将分配小车的代码和遍历所有 AGV 的代码分别放在两个函数中。
```c++
void assignAgv(std::vector<Task>& tasks, std::vector<Agv>& agvs) {
AGVScheduler scheduler;
scheduler.assign_task_to_agv(tasks, agvs); // 开始分配任务
}
void updateAgv(std::vector<Agv>& agvs, int i) {
if (agvs[i].available_ == 0 && agvs[i].run_ == 0) {
moveAgvs(i);
std::cout << "agv.id:" << agvs[i].id_ << "___task.id :" << agvs[i].task_id << std::endl;
}
}
```
2. 使用多线程去调用这两个函数,可以使用 C++11 中的 `std::thread` 类,代码如下:
```c++
std::vector<std::thread> threads;
threads.push_back(std::thread(&assignAgv, std::ref(tasks), std::ref(agvs))); // 分配小车
for (int i = 0; i < agvs.size(); i++) {
threads.push_back(std::thread(&updateAgv, std::ref(agvs), i)); // 更新 AGV
}
for (auto& t : threads) {
t.join();
}
```
这段代码会创建一个线程池,首先创建一个线程去调用 `assignAgv` 函数分配小车,然后遍历所有 AGV,为每个 AGV 创建一个线程去调用 `updateAgv` 函数更新 AGV。最后使用 `join` 函数等待所有线程执行完毕。
注意:由于多线程会同时访问 AGV 和 Task 数据,需要对它们进行加锁保护,避免出现不可预测的结果。
std::vector<std::thread> threads; threads.push_back(std::thread(&AGVScheduler::assign_task_to_agv, std::ref(tasks), std::ref(agvs))); // 分配小车 for (int i = 0; i < agvs.size(); i++) { threads.push_back(std::thread(&moveAgvs, i)); // 更新 AGV } for (auto& t : threads) { t.join(); }
这段代码也是使用 C++11 中的多线程库 `std::thread` 进行并行编程。首先定义了一个 `std::vector<std::thread>` 类型的变量 `threads`,用于存储线程。接下来的代码创建了一个新的线程,执行函数是 `AGVScheduler::assign_task_to_agv`,传入的参数是 `tasks` 和 `agvs`。这个函数的作用是将任务分配给 AGV。然后,使用 `for` 循环创建了 `agvs.size()` 个新的线程,执行函数是 `moveAgvs`,参数是 `i`。最后一个 `for` 循环等待所有线程运行完毕,调用 `join()` 函数阻塞当前线程,直到线程结束。和之前的代码相比,这段代码的区别在于将任务分配给 AGV 的函数 `AGVScheduler::assign_task_to_agv` 放在了新的线程中运行,而不是在主线程中运行。这样可以更好地利用多核 CPU 的性能,提高程序的效率。
阅读全文