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

如何修改代码实现机器人电机速度渐变,解决转向不一致问题

机器人电机速度渐变与转向一致性问题修复建议

问题说明

需要实现机器人移动时电机速度渐变(先慢后快再慢),现有逻辑:

  • 超声波传感器检测距离≥16cm时,机器人前进约15cm后右转
  • 检测距离≤15cm时,机器人左转
    当前转向动作不一致,推测由电机突然启停导致,尝试用for循环实现速度渐变但未生效,需修复代码。

初始代码

if (distance >= 16) {
    motors.setLeftSpeed(100);
    motors.setRightSpeed(100);
    delay(1120);
    motors.setLeftSpeed(100);
    motors.setRightSpeed(-100);
    delay(1000);
}

digitalWrite(trigPin, LOW);
delayMicroseconds(2);

digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);

duration = pulseIn(echoPin, HIGH);
distance = duration * 0.034 / 2;
if (distance <= 15) {
    motors.setLeftSpeed(-100);
    motors.setRightSpeed(100);
    delay(900);
}

无效的修改代码

if (distance >= 16) {
    for (int speed = 200; speed >= 0; speed--) {
        motors.setLeftSpeed(100);
        motors.setRightSpeed(100);
        delay(1120);
        motors.setLeftSpeed(100);
        motors.setRightSpeed(-100);
        delay(1000);
    }
}

if (distance <= 15) {
    for (int speed = 200; speed >= 0; speed--) {
        motors.setLeftSpeed(-100);
        motors.setRightSpeed(100);
        delay(900);
    }
}

核心问题分析

  1. 无效修改的for循环未使用循环变量speed,全程固定速度100执行完整动作,完全没实现渐变逻辑
  2. 原代码依赖delay()阻塞程序,导致超声波检测不及时,且电机突然满速启停会产生机械冲击,引发转向误差

修复后的代码示例

// 定义速度参数,根据电机实际性能调整
const int MAX_SPEED = 100;
const int ACCEL_STEP = 5; // 每次增速/减速的步长
const int ACCEL_DELAY = 20; // 每步速度变化的间隔(ms)

// 前进动作:先加速→匀速→减速
void moveForwardGradually() {
    // 加速阶段
    for (int speed = 0; speed <= MAX_SPEED; speed += ACCEL_STEP) {
        motors.setLeftSpeed(speed);
        motors.setRightSpeed(speed);
        delay(ACCEL_DELAY);
    }
    // 匀速前进(抵消渐变阶段的时间消耗,保证总前进距离与原逻辑一致)
    delay(1120 - (MAX_SPEED / ACCEL_STEP) * ACCEL_DELAY * 2);
    // 减速阶段
    for (int speed = MAX_SPEED; speed >= 0; speed -= ACCEL_STEP) {
        motors.setLeftSpeed(speed);
        motors.setRightSpeed(speed);
        delay(ACCEL_DELAY);
    }
    motors.setLeftSpeed(0);
    motors.setRightSpeed(0);
}

// 右转动作:渐变启停
void turnRightGradually() {
    // 右转加速
    for (int speed = 0; speed <= MAX_SPEED; speed += ACCEL_STEP) {
        motors.setLeftSpeed(speed);
        motors.setRightSpeed(-speed);
        delay(ACCEL_DELAY);
    }
    // 匀速右转(抵消渐变阶段的时间消耗,保证转向角度与原逻辑一致)
    delay(1000 - (MAX_SPEED / ACCEL_STEP) * ACCEL_DELAY * 2);
    // 右转减速
    for (int speed = MAX_SPEED; speed >= 0; speed -= ACCEL_STEP) {
        motors.setLeftSpeed(speed);
        motors.setRightSpeed(-speed);
        delay(ACCEL_DELAY);
    }
    motors.setLeftSpeed(0);
    motors.setRightSpeed(0);
}

// 左转动作:渐变启停
void turnLeftGradually() {
    // 左转加速
    for (int speed = 0; speed <= MAX_SPEED; speed += ACCEL_STEP) {
        motors.setLeftSpeed(-speed);
        motors.setRightSpeed(speed);
        delay(ACCEL_DELAY);
    }
    // 匀速左转(抵消渐变阶段的时间消耗,保证转向角度与原逻辑一致)
    delay(900 - (MAX_SPEED / ACCEL_STEP) * ACCEL_DELAY * 2);
    // 左转减速
    for (int speed = MAX_SPEED; speed >= 0; speed -= ACCEL_STEP) {
        motors.setLeftSpeed(-speed);
        motors.setRightSpeed(speed);
        delay(ACCEL_DELAY);
    }
    motors.setLeftSpeed(0);
    motors.setRightSpeed(0);
}

// 主逻辑
void loop() {
    // 超声波检测
    digitalWrite(trigPin, LOW);
    delayMicroseconds(2);
    digitalWrite(trigPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPin, LOW);

    duration = pulseIn(echoPin, HIGH);
    distance = duration * 0.034 / 2;

    if (distance >= 16) {
        moveForwardGradually();
        turnRightGradually();
    } else if (distance <= 15) {
        turnLeftGradually();
    }
}

关键说明

  • 将动作拆分为独立函数,逻辑更清晰,便于调整参数
  • 每个动作都实现了加速→匀速→减速的渐变过程,避免电机突然启停产生的机械冲击
  • 调整了匀速阶段的delay时长,抵消渐变阶段的时间消耗,保证总动作的距离/角度与原逻辑一致
  • 超声波检测移到主循环最前端,确保每次动作前都能获取最新的距离数据

内容的提问来源于stack exchange,提问作者Elo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 19:42:52