You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何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);
        }
    }
}

循环无法退出的核心原因

  1. 传感器读取被干扰
    trajAdjust函数中先调用high(9),紧接着调用rc_time(9,1),但rc_time函数本身会自动拉低引脚再计时充电时间,手动设置high(9)会干扰传感器的正常采样流程,导致ptFront读数不准确,始终低于18000的阈值。

  2. 转向逻辑有效性不足
    当左右两侧均检测到障碍物时,代码固定执行右转操作drive_rampStep(35, -35)。如果机器人处于墙角、狭窄通道等位置,这种转向幅度可能不足以让机器人脱离墙面区域,导致ptFront始终满足<=18000的循环条件。

  3. 缺少超时机制
    循环仅依赖ptFront的读数作为退出条件,一旦传感器出现异常(比如接线松动、环境光干扰导致读数始终卡在阈值以下),就会进入死循环,没有兜底的退出逻辑。

  4. 边界区间未覆盖
    传感器检测白色墙面时<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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 18:03:11