Skip to content

伺服电机使用指南(Servo Guide)​

约 1202 个字 248 行代码 预计阅读时间 7 分钟

什么是伺服电机?​

伺服电机(Servo Motor)是一种精确控制角度位置的电机,它与普通直流电机(DC Motor)的主要区别在于:

  • 角度控制:伺服电机可以精确控制旋转到特定角度并保持该位置

  • 内置闭环反馈:内置位置传感器实时监测位置并调整

  • 有限旋转范围:标准伺服通常只能旋转 0-180 度(或 0-270 度)

  • 应用场景:适合需要精确角度控制的场景,如机器人爪子、舵机等

FTC 中的伺服电机类型​

FTC 机器人控制系统支持两种主要类型的伺服电机:

  • 标准伺服电机(Standard Servo):角度范围通常为 0-180 度由Servo类控制用于机器人爪子、机构锁定装置等

  • 角度范围通常为 0-180 度

  • 由Servo类控制

  • 用于机器人爪子、机构锁定装置等

  • 连续旋转伺服(Continuous Rotation Servo):可以 360 度连续旋转实际上更像是具有内置速度控制器的直流电机由CRServo类控制用于需要持续旋转但速度精确控制的应用

  • 可以 360 度连续旋转

  • 实际上更像是具有内置速度控制器的直流电机

  • 由CRServo类控制

  • 用于需要持续旋转但速度精确控制的应用

FTC 中的伺服电机类​

1.Servo类​

  • 这是控制标准伺服电机的主要类,用于精确的角度控制。

这是控制标准伺服电机的主要类,用于精确的角度控制。

  • Interface Servo 10.2.0

Interface Servo 10.2.0

主要方法:​

方法 描述
setPosition(double position) 设置伺服电机位置(0.0-1.0 范围)
getPosition() 获取当前设置的位置值
scaleRange(double min, double max) 重新定义伺服电机的范围
setDirection(Servo.Direction direction) 设置伺服电机旋转方向

代码示例:​

// 获取伺服电机引用
Servo myServo = hardwareMap.get(Servo.class, "servo_name");

// 设置伺服电机旋转方向
myServo.setDirection(Servo.Direction.FORWARD); // 或 REVERSE

// 移动到中间位置 (90度)
myServo.setPosition(0.5);

// 移动到最小位置 (0度)
myServo.setPosition(0.0);

// 移动到最大位置 (180度)
myServo.setPosition(1.0);

// 只使用0.2-0.8范围(避免极限位置)
myServo.scaleRange(0.2, 0.8);
myServo.setPosition(0.5); // 现在这个值会被映射到缩放后的范围内

2.CRServo类​

用于控制连续旋转伺服电机,实现方向和速度控制。

主要方法:​

方法 描述
setPower(double power) 设置伺服电机的旋转速度和方向 (-1.0 到 1.0)
getPower() 获取当前设置的功率值
setDirection(CRServo.Direction direction) 设置旋转方向

代码示例:​

// 获取连续旋转伺服电机引用
CRServo myCRServo = hardwareMap.get(CRServo.class, "cr_servo_name");

// 设置旋转方向
myCRServo.setDirection(CRServo.Direction.FORWARD); // 或 REVERSE

// 以最大速度正向转动
myCRServo.setPower(1.0);

// 以半速反向转动
myCRServo.setPower(-0.5);

// 停止旋转
myCRServo.setPower(0.0);

3.ServoController类​

这是控制多个伺服电机的控制器类,用于更高级的操作。

主要方法:​

方法 描述
pwmEnable() 启用 PWM 信号输出
pwmDisable() 禁用 PWM 信号输出
getPwmStatus() 获取 PWM 状态

代码示例:​

// 获取伺服控制器引用
ServoController controller = hardwareMap.get(ServoController.class, "servo_controller");

// 启用PWM信号
controller.pwmEnable();

// 禁用PWM信号(伺服将停止保持位置)
controller.pwmDisable();

常见的伺服电机使用场景​

1. 机器人爪子控制​

/**
 * 机器人爪子控制示例
 */
public class ClawExample extends LinearOpMode {
    Servo leftClaw;
    Servo rightClaw;

    // 爪子位置常量
    final double CLAW_OPEN = 0.7;
    final double CLAW_CLOSED = 0.1;

    @Override
    public void runOpMode() {
        // 获取伺服引用
        leftClaw = hardwareMap.get(Servo.class, "left_claw");
        rightClaw = hardwareMap.get(Servo.class, "right_claw");

        // 设置方向(假设爪子镜像安装)
        leftClaw.setDirection(Servo.Direction.FORWARD);
        rightClaw.setDirection(Servo.Direction.REVERSE);

        // 初始化为闭合状态
        leftClaw.setPosition(CLAW_CLOSED);
        rightClaw.setPosition(CLAW_CLOSED);

        waitForStart();

        while (opModeIsActive()) {
            // 使用游戏手柄按钮控制爪子
            if (gamepad1.a) {
                // 按A打开爪子
                leftClaw.setPosition(CLAW_OPEN);
                rightClaw.setPosition(CLAW_OPEN);
            } else if (gamepad1.b) {
                // 按B关闭爪子
                leftClaw.setPosition(CLAW_CLOSED);
                rightClaw.setPosition(CLAW_CLOSED);
            }

            telemetry.addData("左爪位置", leftClaw.getPosition());
            telemetry.addData("右爪位置", rightClaw.getPosition());
            telemetry.update();
        }
    }
}

2. 伺服电机扫描​

/**
 * 伺服电机扫描示例(例如传感器平台)
 */
public class ServoScanExample extends LinearOpMode {
    Servo scanServo;

    // 扫描范围和步长
    final double MIN_POS = 0.1;
    final double MAX_POS = 0.9;
    final double STEP = 0.01;

    @Override
    public void runOpMode() {
        scanServo = hardwareMap.get(Servo.class, "scan_servo");
        scanServo.setPosition(MIN_POS);

        waitForStart();

        // 往复扫描
        boolean increasing = true;
        double position = MIN_POS;

        while (opModeIsActive()) {
            // 更新伺服位置
            if (increasing) {
                position += STEP;
                if (position >= MAX_POS) {
                    increasing = false;
                }
            } else {
                position -= STEP;
                if (position <= MIN_POS) {
                    increasing = true;
                }
            }

            scanServo.setPosition(position);

            telemetry.addData("扫描位置", position);
            telemetry.update();
            sleep(20); // 短暂延迟使运动更平滑
        }
    }
}

3. 连续旋转伺服用作轮子​

/**
 * 使用连续旋转伺服作为轮子
 */
public class CRServoWheelsExample extends LinearOpMode {
    CRServo leftWheel;
    CRServo rightWheel;

    @Override
    public void runOpMode() {
        // 获取连续旋转伺服引用
        leftWheel = hardwareMap.get(CRServo.class, "left_wheel");
        rightWheel = hardwareMap.get(CRServo.class, "right_wheel");

        // 配置方向使前进时两轮朝相反方向转动
        leftWheel.setDirection(CRServo.Direction.FORWARD);
        rightWheel.setDirection(CRServo.Direction.REVERSE);

        waitForStart();

        while (opModeIsActive()) {
            // 获取游戏手柄输入
            double drive = -gamepad1.left_stick_y; // 前后移动
            double turn = gamepad1.right_stick_x;  // 左右转向

            // 计算电机功率
            double leftPower = drive + turn;
            double rightPower = drive - turn;

            // 限制功率在-1.0到1.0范围内
            leftPower = Math.max(-1.0, Math.min(1.0, leftPower));
            rightPower = Math.max(-1.0, Math.min(1.0, rightPower));

            // 设置伺服功率
            leftWheel.setPower(leftPower);
            rightWheel.setPower(rightPower);

            telemetry.addData("左轮功率", leftPower);
            telemetry.addData("右轮功率", rightPower);
            telemetry.update();
        }
    }
}

伺服电机的高级技巧​

1. 缩放范围​

某些情况下,您可能想要限制伺服电机的运动范围,避免机械干涉或优化控制范围:

// 标准范围是0.0-1.0,对应0-180度
// 缩放为0.2-0.8,对应约36-144度
servo.scaleRange(0.2, 0.8);

// 现在设置位置将在新范围内映射
servo.setPosition(0.0); // 实际位置为0.2
servo.setPosition(1.0); // 实际位置为0.8
servo.setPosition(0.5); // 实际位置为0.5

2. 平滑伺服运动​

伺服电机突然移动会导致机械冲击,可以使用渐进式移动实现平滑过渡:

/**
 * 平滑伺服运动示例
 */
public void moveServoSmooth(Servo servo, double targetPosition, double step) {
    double currentPosition = servo.getPosition();

    // 逐步移动到目标位置
    if (targetPosition > currentPosition) {
        for (double pos = currentPosition; pos < targetPosition; pos += step) {
            servo.setPosition(pos);
            sleep(10); // 短暂延迟
        }
    } else {
        for (double pos = currentPosition; pos > targetPosition; pos -= step) {
            servo.setPosition(pos);
            sleep(10); // 短暂延迟
        }
    }

    // 确保到达最终位置
    servo.setPosition(targetPosition);
}

// 使用示例
moveServoSmooth(armServo, 0.8, 0.01);

3. 同步多个伺服​

当多个伺服电机需要同步移动时(如机器人两侧的升降机构):

/**
 * 同步两个伺服电机移动
 */
public void moveSyncedServos(Servo servo1, Servo servo2, double targetPosition, double step) {
    double current1 = servo1.getPosition();
    double current2 = servo2.getPosition();

    // 计算每个伺服的步长,确保同时到达目标
    double distance1 = Math.abs(targetPosition - current1);
    double distance2 = Math.abs(targetPosition - current2);
    double ratio = distance1 > 0 ? distance2 / distance1 : 1.0;

    double step1 = step;
    double step2 = step * ratio;

    // 逐步移动到目标位置
    while (Math.abs(current1 - targetPosition) > step ||
           Math.abs(current2 - targetPosition) > step) {

        // 更新第一个伺服
        if (current1 < targetPosition) {
            current1 = Math.min(current1 + step1, targetPosition);
        } else {
            current1 = Math.max(current1 - step1, targetPosition);
        }

        // 更新第二个伺服
        if (current2 < targetPosition) {
            current2 = Math.min(current2 + step2, targetPosition);
        } else {
            current2 = Math.max(current2 - step2, targetPosition);
        }

        // 设置位置
        servo1.setPosition(current1);
        servo2.setPosition(current2);

        sleep(10); // 短暂延迟
    }

    // 确保到达最终位置
    servo1.setPosition(targetPosition);
    servo2.setPosition(targetPosition);
}

伺服电机配置和故障排除​

1. 配置文件设置​

在 FTC 机器人控制器应用程序中,您需要正确配置伺服电机:

  • 在"Configure Robot"界面创建或编辑配置文件

  • 添加伺服控制器(通常内置在控制中心)

  • 为每个伺服分配唯一名称和端口号

  • 选择正确的伺服类型(Servo 或 CRServo)

2. 常见问题与解决方法​

问题 可能原因 解决方法
伺服不移动 连接松动或断开 检查接线和连接器
配置名称不匹配 确认代码中的名称与配置文件匹配
PWM 被禁用 检查pwmEnable()是否被调用
伺服抖动 电源不足 检查电池电压,确保足够供电
位置频繁变化 减少位置更新频率
移动方向相反 方向设置错误 使用setDirection()反转方向
位置不准确 机械连接松动 检查物理连接和齿轮啮合
超出物理限制 使用scaleRange()限制运动范围

总结​

伺服电机是 FTC 机器人中精确角度控制的关键组件。通过使用Servo和CRServo类,您可以实现从简单的爪子控制到复杂的机构操作等各种功能。记住根据您的应用选择合适的伺服类型,正确配置方向和范围,并考虑使用平滑移动来减少机械应力。

随着经验的积累,您可以开发出更复杂的伺服控制策略,如基于传感器的闭环控制或协调多个伺服的复杂序列动作。

参考链接和资源​

官方文档​

  • FTC SDK 官方文档- FTC 机器人控制系统官方文档

颜色主题调整