首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >差速轮组的开环及闭环控制算法

差速轮组的开环及闭环控制算法

作者头像
索旭东
发布2026-01-20 14:56:34
发布2026-01-20 14:56:34
1230
举报
文章被收录于专栏:具身小站具身小站

1. 开环速度控制

代码语言:javascript
复制
class OpenLoopController:
    def __init__(self):
        self.left_pwm = 0
        self.right_pwm = 0

    def set_velocity(self, v, omega):
        """设置底盘线速度和角速度"""
        # 计算期望轮速
        v_left, v_right = chassis_to_wheel(v, omega)

        # 转换为轮子转速(RPM)
        rpm_left = (v_left / (2 * 3.14 * wheel_radius)) * 60
        rpm_right = (v_right / (2 * 3.14 * wheel_radius)) * 60

        # 转换为PWM值
        self.left_pwm = rpm_to_pwm(rpm_left)
        self.right_pwm = rpm_to_pwm(rpm_right)

        return self.left_pwm, self.right_pwm

2. 闭环速度控制(PID)

代码语言:javascript
复制
class PIDController:
    def __init__(self, kp, ki, kd):
        self.kp = kp        # 比例系数
        self.ki = ki        # 积分系数
        self.kd = kd        # 微分系数
        self.prev_error = 0
        self.integral = 0

    def update(self, target, current, dt):
        """dt: 时间间隔(秒)"""
        error = target - current

        # 比例项
        p = self.kp * error

        # 积分项(防止积分饱和)
        self.integral += error * dt
        self.integral = max(-100, min(100, self.integral))  # 限幅
        i = self.ki * self.integral

        # 微分项
        d = self.kd * (error - self.prev_error) / dt
        self.prev_error = error

        return p + i + d

class DriveController:
    def __init__(self):
        # 为每个轮子创建PID控制器
        self.pid_left = PIDController(kp=1.0, ki=0.1, kd=0.05)
        self.pid_right = PIDController(kp=1.0, ki=0.1, kd=0.05)

        # 编码器反馈
        self.left_encoder = 0
        self.right_encoder = 0

    def update(self, v_target, omega_target, dt):
        """主控制循环"""
        # 1. 计算目标轮速
        v_left_target, v_right_target = chassis_to_wheel(v_target, omega_target)

        # 2. 获取当前轮速(从编码器)
        v_left_current = self.get_left_speed(dt)
        v_right_current = self.get_right_speed(dt)

        # 3. PID计算PWM调整量
        pwm_left_adjust = self.pid_left.update(v_left_target, v_left_current, dt)
        pwm_right_adjust = self.pid_right.update(v_right_target, v_right_current, dt)

        # 4. 基础PWM + 调整量
        base_pwm = 100  # 基础值
        pwm_left = base_pwm + pwm_left_adjust
        pwm_right = base_pwm + pwm_right_adjust

        return pwm_left, pwm_right

    def get_left_speed(self, dt):
        """从编码器计算实际速度"""
        # 根据编码器脉冲数和时间计算速度
        return 0  # 返回实际速度值

    def get_right_speed(self, dt):
        return 0  # 返回实际速度值

3. 闭环位置控制(轨迹)

代码语言:javascript
复制
class TrajectoryController:
    def __init__(self):
        self.x = 0      # 当前位置x
        self.y = 0      # 当前位置y
        self.theta = 0  # 当前角度

    def move_to_point(self, target_x, target_y, max_speed=0.5):
        """移动到目标点"""
        # 计算距离和角度差
        dx = target_x - self.x
        dy = target_y - self.y
        distance = math.sqrt(dx*dx + dy*dy)

        # 目标角度
        target_angle = math.atan2(dy, dx)
        angle_error = target_angle - self.theta

        # 角度归一化到[-pi, pi]
        while angle_error > math.pi:
            angle_error -= 2*math.pi
        while angle_error < -math.pi:
            angle_error += 2*math.pi

        # 控制策略
        if distance < 0.05:  # 到达目标
            v = 0
            omega = 0
        else:
            # 线速度:距离越近速度越慢
            v = min(max_speed, distance * 0.5)

            # 角速度:转向目标角度
            omega = angle_error * 2.0

            # 限制最大角速度
            omega = max(-1.0, min(1.0, omega))

        return v, omega

4. PID参数调试步骤

  1. 先调P:将I和D设为0,增大P直到出现振荡,然后减小到振荡消失
  2. 再调I:增加I以消除稳态误差
  3. 最后调D:增加D以减少超调,但不要太大
  4. 到达目标点振荡:减小P增益,增加D增益
  5. 响应慢:增加P增益,检查电机功率是否足够
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-01-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 具身小站 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 开环速度控制
  • 2. 闭环速度控制(PID)
  • 3. 闭环位置控制(轨迹)
  • 4. PID参数调试步骤
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档