组合动作:完整自动程序Combining Actions: A Complete Autonomous Program
5.1 把积木搭起来5.1 Putting the Building Blocks Together
前面几节我们学了三个"积木":In the previous lessons we learned three "building blocks":
- driveStraight() — 用编码器直走Drive straight using encoders
- turnToHeading() — 用陀螺仪转弯Turn using the gyroscope
- 机构控制Mechanism control — Level 2 学过的夹爪、升降等Claw, lift, etc. from Level 2
现在把它们串联起来,写一个完整的自动程序。Now let's chain them together to write a complete autonomous program.
5.2 完整例子:拿一个得分物5.2 Full Example: Picking Up a Scoring Object
假设场景:机器人从起点出发,前进 → 转弯 → 前进 → 夹住得分物 → 后退 → 转弯 → 前进到得分区。Scenario: Robot starts from the starting position, drives forward -> turns -> drives forward -> grabs scoring object -> reverses -> turns -> drives to scoring zone.
// 已有的函数(前面学的)
void driveStraight(double deg) {
LeftMotor.setPosition(0, degrees);
RightMotor.setPosition(0, degrees);
if (deg > 0) {
LeftMotor.spinFor(forward, deg, degrees, false);
RightMotor.spinFor(forward, deg, degrees);
} else {
LeftMotor.spinFor(reverse, -deg, degrees, false);
RightMotor.spinFor(reverse, -deg, degrees);
}
}
void turnToHeading(double targetDeg) {
while (fabs(IMU.heading(degrees) - targetDeg) > 1.5) {
double error = targetDeg - IMU.heading(degrees);
double speed = fabs(error) * 0.5;
if (speed > 40) speed = 40;
if (speed < 8) speed = 8;
if (error > 0) {
LeftMotor.spin(forward, speed, percent);
RightMotor.spin(reverse, speed, percent);
} else {
LeftMotor.spin(reverse, speed, percent);
RightMotor.spin(forward, speed, percent);
}
wait(10, msec);
}
LeftMotor.stop();
RightMotor.stop();
}
// 自动程序:拿一个得分物并送到得分区
void autonomous() {
// 第 1 步:前进到得分物附近
driveStraight(600);
// 第 2 步:转向对准得分物
turnToHeading(45);
// 第 3 步:前进一小段,靠近得分物
driveStraight(200);
// 第 4 步:夹住得分物
ClawMotor.spinFor(forward, 90, degrees);
// 第 5 步:后退
driveStraight(-200);
// 第 6 步:转向得分区
turnToHeading(180);
// 第 7 步:前进到得分区
driveStraight(800);
// 第 8 步:放下得分物
ClawMotor.spinFor(reverse, 90, degrees);
// 第 9 步:后退脱离
driveStraight(-300);
}
// 已有的函数(前面学的)
void driveStraight(double deg) {
LeftMotor.setPosition(0, degrees);
RightMotor.setPosition(0, degrees);
if (deg > 0) {
LeftMotor.spinFor(forward, deg, degrees, false);
RightMotor.spinFor(forward, deg, degrees);
} else {
LeftMotor.spinFor(reverse, -deg, degrees, false);
RightMotor.spinFor(reverse, -deg, degrees);
}
}
void turnToHeading(double targetDeg) {
while (fabs(IMU.heading(degrees) - targetDeg) > 1.5) {
double error = targetDeg - IMU.heading(degrees);
double speed = fabs(error) * 0.5;
if (speed > 40) speed = 40;
if (speed < 8) speed = 8;
if (error > 0) {
LeftMotor.spin(forward, speed, percent);
RightMotor.spin(reverse, speed, percent);
} else {
LeftMotor.spin(reverse, speed, percent);
RightMotor.spin(forward, speed, percent);
}
wait(10, msec);
}
LeftMotor.stop();
RightMotor.stop();
}
void autonomous() {
driveStraight(600);
turnToHeading(45);
driveStraight(200);
ClawMotor.spinFor(forward, 90, degrees);
driveStraight(-200);
turnToHeading(180);
driveStraight(800);
ClawMotor.spinFor(reverse, 90, degrees);
driveStraight(-300);
}
// 已有的函数(前面学的)
void driveStraight(double deg) {
double startL = left_motor.get_position();
double startR = right_motor.get_position();
left_motor.move_absolute(startL + deg, 100);
right_motor.move_absolute(startR + deg, 100);
while (fabs(left_motor.get_position() - (startL + deg)) > 5 ||
fabs(right_motor.get_position() - (startR + deg)) > 5) {
pros::delay(10);
}
}
void turnToHeading(double targetDeg) {
while (fabs(imu.get_heading() - targetDeg) > 1.5) {
double error = targetDeg - imu.get_heading();
double speed = fabs(error) * 0.5;
if (speed > 50) speed = 50;
if (speed < 10) speed = 10;
if (error > 0) {
left_motor.move(speed);
right_motor.move(-speed);
} else {
left_motor.move(-speed);
right_motor.move(speed);
}
pros::delay(10);
}
left_motor.move(0);
right_motor.move(0);
}
void autonomous() {
driveStraight(600);
turnToHeading(45);
driveStraight(200);
claw_motor.move_absolute(90, 100);
pros::delay(500);
driveStraight(-200);
turnToHeading(180);
driveStraight(800);
claw_motor.move_absolute(0, 100);
pros::delay(500);
driveStraight(-300);
}
看到了吗?有了封装好的函数,写自动程序就像写步骤清单:See? With wrapped functions, writing autonomous is like writing a step-by-step checklist:
- 前进 600 度Drive forward 600 degrees
- 转到 45 度Turn to 45 degrees
- 前进 200 度Drive forward 200 degrees
- 夹住Grab
- 后退 200 度Reverse 200 degrees
- 转到 180 度Turn to 180 degrees
- 前进 800 度Drive forward 800 degrees
- 放下Release
- 后退 300 度Reverse 300 degrees
5.3 调试技巧:一步一步测5.3 Debugging Tips: Test Step by Step
不要一口气写完所有步骤再测。Don't write all the steps at once and then test.先写第 1 步,测通了再加第 2 步,再测通,再加第 3 步......每一步确认没问题了再往下加。 Write step 1 first, test it, then add step 2, test again, then add step 3... Only add the next step after confirming the previous one works.
为什么?因为如果一次写完 9 步,跑出来结果不对,你不知道是哪一步出了问题。但如果一步步加,出问题的一定是最新加的那一步。Why? Because if you write all 9 steps at once and something goes wrong, you won't know which step is the problem. But if you add one step at a time, the issue must be the most recently added step.
- 先只写
driveStraight(600),跑一次,确认距离对不对Start with justdriveStraight(600), run once, check if the distance is correct - 距离不对?调整数值。对了?加下一步Distance wrong? Adjust the value. Correct? Add the next step
- 加
turnToHeading(45),跑一次,确认角度对不对AddturnToHeading(45), run once, check if the angle is correct - 重复这个过程,直到所有步骤都测通Repeat this process until all steps are verified
这样做看似慢,实际比"写完再调"快得多。This seems slow, but it's actually much faster than "write everything then debug."
5.4 常见问题清单5.4 Common Issues Checklist
- 直走偏了Drives crooked → 检查左右电机方向是否正确,编码器是否清零Check if left/right motor directions are correct and encoder is reset
- 转弯角度不对Wrong turn angle → 确认陀螺仪已校准,检查 heading 范围是 0-360Confirm gyroscope is calibrated, check heading range is 0-360
- 机构动作没执行Mechanism didn't activate → 检查是不是被上一步的 spinFor 阻塞了Check if it's being blocked by a previous spinFor call
- 时间超过 15 秒Takes more than 15 seconds → 减少步骤,或者提高速度。比赛系统到 15 秒会强制停止Reduce steps or increase speed. The competition system forces a stop at 15 seconds
- 撞到对面机器人Collided with opponent → 策略问题,考虑走对手不太可能走的路线Strategic issue -- consider taking a path the opponent is unlikely to take
写一段自动程序,完成以下动作:Write an autonomous program that completes these actions:
- 前进 400 度Drive forward 400 degrees
- 右转到 90 度Turn right to 90 degrees
- 前进 300 度Drive forward 300 degrees
- 后退 300 度Reverse 300 degrees
写完之后回答:调试自动程序最有效的方法是什么?After writing, answer: What's the most effective way to debug an autonomous program?