电机编码器Motor Encoder
2.1 什么是编码器?2.1 What Is an Encoder?
每个 V5 电机里面都自带一个编码器。你不需要额外买,也不需要额外装——它已经在里面了。Every V5 motor has a built-in encoder. You don't need to buy or install anything extra -- it's already inside.
编码器的作用很简单:记录电机转了多少度。The encoder's job is simple: record how many degrees the motor has turned.
就像汽车的里程表记录开了多少公里一样,编码器记录电机转了多少度。Just like a car's odometer records how many kilometers you've driven, the encoder records how many degrees the motor has turned.
编码器不控制电机——它只是一个计数器。电机转一度,它就加 1;电机反转,它就减 1。The encoder doesn't control the motor -- it's just a counter. Each degree the motor turns, it adds 1; when the motor reverses, it subtracts 1.
2.2 读取电机位置2.2 Reading Motor Position
读取编码器的值非常简单:Reading the encoder value is very simple:
// 创建电机(端口 1,18:1 齿轮比,不反转)
motor LeftFront = motor(PORT1, ratio18_1, false);
// 读取当前位置(单位:度)
double pos = LeftFront.position(degrees);
// 读取当前速度(单位:RPM)
double vel = LeftFront.velocity(rpm);
// 创建电机(端口 1,18:1 齿轮比,不反转)
motor LeftFront = motor(PORT1, ratio18_1, false);
// 读取当前位置(单位:度)
double pos = LeftFront.position(degrees);
// 读取当前速度(单位:RPM)
double vel = LeftFront.velocity(rpm);
// 创建电机(端口 1)
pros::Motor left_front(1);
// 读取当前位置(单位:度)
double pos = left_front.get_position();
// 读取当前速度(单位:RPM)
double vel = left_front.get_actual_velocity();
2.3 重置位置2.3 Resetting Position
编码器从上电开始就在计数。如果你想从 0 开始算,需要先重置:The encoder starts counting from the moment the robot powers on. If you want to start from 0, you need to reset it first:
// 把当前位置设为 0
LeftFront.setPosition(0, degrees);
// 现在 LeftFront.position(degrees) 返回 0
// 电机每转一度,位置加 1
// 把当前位置设为 0
LeftFront.setPosition(0, degrees);
// 现在 LeftFront.position(degrees) 返回 0
// 电机每转一度,位置加 1
// 把当前位置设为 0
left_front.set_zero_position(0);
// 现在 left_front.get_position() 返回 0
// 电机每转一度,位置加 1
2.4 实用代码:走到目标位置2.4 Practical Code: Drive to a Target Position
有了编码器,我们可以这样写:一直走,直到转够了目标度数再停。With the encoder, we can write code like this: keep driving until the motor has turned enough degrees, then stop.
// 向前走 500 度
LeftFront.setPosition(0, degrees);
RightFront.setPosition(0, degrees);
LeftFront.spin(forward);
RightFront.spin(forward);
// 一直检查:还没到 500 度就继续走
while (LeftFront.position(degrees) < 500) {
wait(20, msec); // 每 20 毫秒检查一次
}
LeftFront.stop();
RightFront.stop();
// 向前走 500 度
LeftFront.setPosition(0, degrees);
RightFront.setPosition(0, degrees);
LeftFront.spin(forward);
RightFront.spin(forward);
// 一直检查:还没到 500 度就继续走
while (LeftFront.position(degrees) < 500) {
wait(20, msec); // 每 20 毫秒检查一次
}
LeftFront.stop();
RightFront.stop();
// 向前走 500 度
left_front.set_zero_position(0);
right_front.set_zero_position(0);
left_front.move(80);
right_front.move(80);
// 一直检查:还没到 500 度就继续走
while (left_front.get_position() < 500) {
pros::delay(20); // 每 20 毫秒检查一次
}
left_front.move(0);
right_front.move(0);
这段代码的逻辑:The logic of this code:
- 先把编码器归零Reset the encoder to zero
- 开始前进Start driving forward
- 每 20 毫秒检查一次:走到 500 度了吗?Check every 20 milliseconds: has it reached 500 degrees?
- 到了就停Stop when it arrives
不管电池满不满,不管地面滑不滑——走到 500 度就停,每次都一样。No matter the battery level, no matter how slippery the surface -- it stops at 500 degrees, every single time.
2.5 度数和距离的换算2.5 Converting Degrees to Distance
编码器告诉你电机转了多少度,但你通常关心的是机器人走了多少厘米。The encoder tells you how many degrees the motor has turned, but what you usually care about is how many centimeters the robot has traveled.
换算公式:Conversion formula:
距离 = (度数 / 360) × 轮子周长distance = (degrees / 360) × wheel circumference
轮子周长 = 直径 × 3.14159Wheel circumference = diameter × 3.14159
例:4 英寸轮子的周长 ≈ 4 × 3.14159 ≈ 12.57 英寸 ≈ 31.9 厘米Example: A 4-inch wheel circumference ≈ 4 × 3.14159 ≈ 12.57 inches ≈ 31.9 cm
电机转了 360 度 = 轮子转了一整圈 = 走了 31.9 厘米Motor turns 360 degrees = wheel turns one full rotation = travels 31.9 cm
所以想走 60 厘米:So to travel 60 cm:
目标度数 = (60 / 31.9) × 360 ≈ 677 度target degrees = (60 / 31.9) × 360 ≈ 677 degrees
如果你的轮子直径是 3.25 英寸,想走 50 厘米,电机需要转多少度?If your wheel diameter is 3.25 inches and you want to travel 50 cm, how many degrees does the motor need to turn?
提示:先算周长,再算度数。1 英寸 ≈ 2.54 厘米。Hint: Calculate the circumference first, then the degrees. 1 inch ≈ 2.54 cm.
LeftMotor.setPosition(0, degrees);
LeftMotor.spin(forward);
while (___________) {
wait(20, msec);
}
LeftMotor.stop();
LeftMotor.setPosition(0, degrees);
LeftMotor.spin(forward);
while (___________) {
wait(20, msec);
}
LeftMotor.stop();
left_motor.set_zero_position(0);
left_motor.move(80);
while (___________) {
pros::delay(20);
}
left_motor.move(0);