为何trajAdjust函数中while循环在条件不成立时无法退出?
问题:trajAdjust函数的while循环无法退出
ptFront变量与Parallax Propeller开发板上的QT电路相连:当光电晶体管检测到白色墙面时,其值降至18000以下;检测到非白色物体时,值升至20000-50000以上。目前发现trajAdjust函数中的while循环在条件失效时仍持续运行,通过连接至引脚6的LED电路已确认该循环从未退出,需找出原因以实现机器人与非墙面物体的交互。
相关代码
#include "simpletools.h" #include "abdrive360.h" #include "ping.h" int irLeft, irRight, ptFloor, ptFront; // IR变量 int main() { high(9); high(8); low(26); low(27); low(6); drive_setRampStep(12); while (1) { ptFront = rc_time(9, 1); ptFloor = rc_time(8, 1); freqout(11, 1, 38000); // 检测左右障碍物 irLeft = input(10); freqout(1, 1, 38000); irRight = input(2); // 漫游与避障逻辑 if (irRight == 1 && irLeft == 1) { // 无障碍物? drive_rampStep(35, 35); } else if (irLeft == 0 && irRight == 0 && ptFront > 18000) { // 左右均有障碍物且非墙面? print("oh robot!"); robotFight(); } else if ((irLeft==0||irRight==0)&& ptFront < 18000) { // 左右有障碍物且为墙面? trajAdjust(); } else if (ptFloor <= 10000) { // 检测到凹陷? pit(); } } } void trajAdjust() { while (ptFront <= 18000) { // 实现轨迹调整逻辑 // 可包含转向以避开障碍物(墙面) high(9); high(6); freqout(11, 1, 38000); // 检测左右障碍物 irLeft = input(10); freqout(1, 1, 38000); irRight = input(2); ptFront = rc_time(9, 1); // 循环内更新ptFront print("ptFront= %d \n",ptFront); if (irLeft == 0 && irRight == 1) { // 仅左侧传感器检测到障碍物,右转 drive_rampStep(35, -35); print("left wall \n"); } else if (irLeft == 1 && irRight == 0) { // 仅右侧传感器检测到障碍物,左转 drive_rampStep(-35, 35); print("right wall \n"); } else if (irLeft == 0 && irRight == 0) { // 两侧均检测到障碍物 // 优先单方向转向 drive_rampStep(35, -35); // 示例调整,需微调 } else { // 前方无障碍物或仅单侧检测到 // 直行或按需调整 drive_rampStep(35, 35); } } } void pit() { //凹陷处理逻辑 } void robotFight() { while (ptFront > 18000 && irRight == 0 && irLeft == 0) { // 用超声波传感器测距 int range = ping_cm(4); // 打印距离至终端(可选) print("Distance to target: %d cm\n", range); // 定义目标距离范围(5-8cm) int minRange = 5; int maxRange = 8; if (range > maxRange) { drive_rampStep(35, 35); } else if (range < minRange && range > 5) { drive_rampStep(-35, -35); } else if (range >= minRange && range <= maxRange) { drive_rampStep(0, 0); } } }
循环无法退出的核心原因
传感器读取被干扰
trajAdjust函数中先调用high(9),紧接着调用rc_time(9,1),但rc_time函数本身会自动拉低引脚再计时充电时间,手动设置high(9)会干扰传感器的正常采样流程,导致ptFront读数不准确,始终低于18000的阈值。转向逻辑有效性不足
当左右两侧均检测到障碍物时,代码固定执行右转操作drive_rampStep(35, -35)。如果机器人处于墙角、狭窄通道等位置,这种转向幅度可能不足以让机器人脱离墙面区域,导致ptFront始终满足<=18000的循环条件。缺少超时机制
循环仅依赖ptFront的读数作为退出条件,一旦传感器出现异常(比如接线松动、环境光干扰导致读数始终卡在阈值以下),就会进入死循环,没有兜底的退出逻辑。边界区间未覆盖
传感器检测白色墙面时<18000,非白色物体时>20000,中间存在18000-20000的空白区间。如果机器人移动到该区间,ptFront的值既不满足墙面条件也不满足非墙面条件,循环也无法退出。
修复建议
- 移除干扰传感器的代码:删除trajAdjust函数中的
high(9),让rc_time自行处理引脚电平,确保读数准确。 - 优化转向逻辑:在左右均有障碍物的场景下,先执行后退动作再转向,或者增大转向幅度,比如改为
drive_rampStep(50, -50),确保机器人能脱离墙面。示例:else if (irLeft == 0 && irRight == 0) { // 先后退再右转 drive_rampStep(-35, -35); pause(500); drive_rampStep(50, -50); } - 添加超时机制:在trajAdjust的循环中加入计数器,达到一定次数后强制退出,避免死循环。示例:
void trajAdjust() { int timeout = 0; const int MAX_TIMEOUT = 150; while (ptFront <= 18000 && timeout < MAX_TIMEOUT) { timeout++; high(6); // 原有传感器检测与转向逻辑... ptFront = rc_time(9, 1); // ... } low(6); // 退出后关闭LED } - 调整阈值边界:将循环条件改为
ptFront < 20000,覆盖18000-20000的空白区间,确保机器人检测到非白色物体时能及时退出循环。
内容的提问来源于stack exchange,提问作者spazedyoda
相关产品推荐
相关产品推荐

