if (! paths[i].empty()) { double cur_x = agvs[i].getCurrentX(); double cur_y = agvs[i].getCurrentY(); Node* next_node = paths[i][0]; float speed = agvs[i].getSpeed(); float distance = sqrt(pow(next_node->x - cur_x, 2) + pow(next_node->y - cur_y, 2)); int steps = ceil(distance / (speed * 0.015)); // 计算需要移动的步数 float power_consumption = distance / 20; //_MAP[cur_x][cur_y] = 1; for (int j = 1; j <= steps; j++) { float time = j *100 / speed; // 每步所需时间 QTimer::singleShot(time, this, &, i, next_node, cur_x, cur_y, power_consumption, j, steps { if (j == 1) { //离开当前位置时将标记设为0 //MAP[cur_x][cur_y] = 0; } float ratio = static_cast<float>(j) / steps; double new_x = cur_x + ratio * (next_node->x - cur_x); double new_y = cur_y + ratio * (next_node->y - cur_y); agvs[i].setCurrentX(new_x); agvs[i].setCurrentY(new_y); std:: cout <<"AGV"<<"("<< new_x << "," << new_y << ")" << endl; // 更新电量 agvs[i].setpower(agvs[i].power - power_consumption / steps); this->update(); // 在窗口中重绘 }); } },AGV(1,1.08333) AGV(1,1.16667) AGV(1,1.25) AGV(1,1.08333) AGV(1,1.33333) AGV(1,1.16667) AGV(1,1.41667) AGV(1,1.25) AGV(1,1.08333) AGV(1,1.5),爲什麽會有很多重複的,怎麽修改
时间: 2024-01-21 10:04:47 浏览: 68
出现重复的原因是因为在循环中使用了异步的方式,在多个定时器同时触发的情况下会导致位置更新出现重复。可以通过使用同步的方式来解决这个问题,具体的做法是将循环中的代码改为:
```cpp
for (int j = 1; j <= steps; j++) {
float ratio = static_cast<float>(j) / steps;
double new_x = cur_x + ratio * (next_node->x - cur_x);
double new_y = cur_y + ratio * (next_node->y - cur_y);
// 更新电量
agvs[i].setpower(agvs[i].power - power_consumption / steps);
// 在窗口中重绘
agvs[i].setCurrentX(new_x);
agvs[i].setCurrentY(new_y);
this->update();
// 延时一定时间再执行下一步
QThread::msleep(100);
}
```
这样修改后,循环中的代码会同步执行,每移动一步都会等待一段时间再执行下一步,可以避免出现位置重复的情况。
相关问题
if (! paths[i].empty()) { double cur_x = agvs[i].getCurrentX(); double cur_y = agvs[i].getCurrentY(); Node* next_node = paths[i][0]; float speed = agvs[i].getSpeed(); float distance = sqrt(pow(next_node->x - cur_x, 2) + pow(next_node->y - cur_y, 2)); int steps = ceil(distance / (speed * 1)); // 计算需要移动的步数 float power_consumption = distance / 20; //_MAP[cur_x][cur_y] = 1; for (int j = 1; j <= steps; j++) { float time = j * 100.0 / speed; // 每步所需时间 QTimer::singleShot(time, this, &, i, next_node, cur_x, cur_y, power_consumption, j, steps { if (j == 1) { // 离开当前位置时将标记设为0 //MAP[cur_x][cur_y] = 0; } float ratio = static_cast<float>(j) / steps; double new_x = cur_x + ratio * (next_node->x - cur_x); double new_y = cur_y + ratio * (next_node->y - cur_y); agvs[i].setCurrentX(new_x); agvs[i].setCurrentY(new_y); std:: cout << "("<< agvs[i].getCurrentX() << "," << agvs[i].getCurrentY() << ")" << endl; // 更新电量 agvs[i].setpower(agvs[i].power - power_consumption / steps); this->update(); // 在窗口中重绘 }); } }Qtimer的time是多少
在这段代码中,根据机器人的速度和移动距离计算出需要移动的步数 steps,然后通过循环变量 j 来迭代每一步的移动。在每一步移动中,通过计算每步所需时间 time,使用 QTimer::singleShot 函数来实现定时器,以便在一定的时间间隔后执行回调函数。
具体来说,每步所需时间 time 的计算公式为:
```float time = j * 100.0 / speed;```
其中,j 表示当前步数,100.0 是一个常数,表示每个时间单位的长度,speed 是机器人的速度。
因此,每步所需的时间间隔是根据机器人的速度和步数计算出来的,单位是毫秒。
if (! paths[i].empty()) { double cur_x = agvs[i].current_x; double cur_y = agvs[i].current_y; Node* next_node = paths[i][0]; float speed = agvs[i].getSpeed(); float distance = sqrt(pow(next_node->x - cur_x, 2) + pow(next_node->y - cur_y, 2)); int steps = ceil(distance / (speed * 0.015)); // 计算需要移动的步数 float power_consumption = distance / 20; //_MAP[cur_x][cur_y] = 1; for (int j = 1; j <= steps; j++) { float time = j *300 / speed; // 每步所需时间 QTimer::singleShot(time, this, &, i, next_node, cur_x, cur_y, power_consumption, j, steps { // if (j == 1) { // //离开当前位置时将标记设为0 // //MAP[cur_x][cur_y] = 0; // } float ratio = static_cast<float>(j) / steps; double new_x = cur_x + ratio * (next_node->x - cur_x); double new_y = cur_y + ratio * (next_node->y - cur_y); agvs[i].setCurrentX(new_x); agvs[i].setCurrentY(new_y); std:: cout <<"AGV"<<"("<< new_x << "," << new_y << ")" << endl; // 更新电量 agvs[i].setpower(agvs[i].power - power_consumption / steps); this->update(); // 在窗口中重绘 }); } },小車隨著new_x的坐標移動,爲什麽會出現倒退的情況,怎麽修改
出现倒退的情况可能是因为在计算新的位置时,使用了当前位置和目标位置之间的比例,但是由于 QTimer 是异步的,一些步骤可能会在目标位置已经更新之后才完成,这样就会出现一些错误的位置计算,从而导致小车倒退。
为了避免这种情况,可以将单个动作的时间间隔设置得更短一些,例如将 QTimer 的时间间隔从 300 毫秒改为 30 毫秒。这样做可以使移动的步数更多,每一步的距离更短,从而减小计算误差。
修改后的代码如下:
```
if (! paths[i].empty()) {
double cur_x = agvs[i].current_x;
double cur_y = agvs[i].current_y;
Node* next_node = paths[i][0];
float speed = agvs[i].getSpeed();
float distance = sqrt(pow(next_node->x - cur_x, 2) + pow(next_node->y - cur_y, 2));
int steps = ceil(distance / (speed * 0.015)); // 计算需要移动的步数
float power_consumption = distance / 20;
//_MAP[cur_x][cur_y] = 1;
for (int j = 1; j <= steps; j++) {
float time = j * 30 / speed; // 每步所需时间
QTimer::singleShot(time, this, [&](){
float ratio = static_cast<float>(j) / steps;
double new_x = cur_x + ratio * (next_node->x - cur_x);
double new_y = cur_y + ratio * (next_node->y - cur_y);
agvs[i].setCurrentX(new_x);
agvs[i].setCurrentY(new_y);
std:: cout <<"AGV"<<"("<< new_x << "," << new_y << ")" << endl;
// 更新电量
agvs[i].setpower(agvs[i].power - power_consumption / steps);
this->update(); // 在窗口中重绘
});
}
}
```
在修改后的代码中,我们将 QTimer 的时间间隔从 300 毫秒改为了 30 毫秒,同时修改了 lambda 函数中的参数列表,确保了所有的参数都被正确地传递。这样做可以使小车的移动更加平滑,减少计算误差,从而避免出现倒退的情况。
阅读全文