vex LemLib的运动链
简介
当我们有一条无法用单一运动来描述的路径时,我们会使用运动链。例如,想象一下我们想要像这样绕过一个障碍物:
如果有人想到在这条路径上使用纯追踪,那是个不错的选择!但有时纯追踪并不是最佳选择。通常,通过图形用户界面创建路径并进行调整需要花费大量时间。考虑一下,如果你在五分钟后有一场比赛,并且需要快速更改路径。那你会怎么做呢? 也许你会想到使用两个
Chassis::moveToPose运动,如下所示: 现在,这将花费更少的编程时间,但由于在中途停止,在比赛中也会花费更多时间。因此,为了加快速度,我们可以不停下来!
什么是运动链?
运动链是将多个运动连接在一起,使得它们之间没有明显的停顿。这在不使用纯追踪或当你更看重速度而不是精度时,对于定义路径非常有用。
最小速度
为了确保机器人不会减速,我们将指定机器人可以达到的最小速度。这个minSpeed会覆盖所有东西(slew、PID、maxSlipSpeed),但不会覆盖maxSpeed。它也不会覆盖二维运动中的转弯。这意味着如果minSpeed=127,那么机器人仍然能够转向目标,但即使如此,它也不会非常准确。
退出
但是等等,如果我们总是以一定速度以上移动,那么我们将永远无法减速停下来。如果我们永远无法停下来,那么运动将一直运行直到超时结束。这就是earlyExitRange参数和Chassis::cancelMotion()发挥作用的地方。
提前退出范围
一旦误差低于earlyExitRange,运动将自动退出并继续进行。对于角运动,这个参数以度为单位测量,但对于移动到点和姿势,这个参数以英寸为单位测量。
运动取消
Chassis::cancelMotion()和Chassis::cancelAllMotions()允许用户随时取消一个运动。这对于定义自己的自定义退出条件非常有用,例如一旦球被摄入就退出:
void intakeBall() {
chassis.setPose(0, 0, 0);
lemlib::Pose intakeBallTarget(0, 24);
// 旋转摄入装置
intake();
// 向球移动
chassis.moveToPoint(intakeBallTarget.x, intakeBallTarget.y, 1500, {.minSpeed=48});
// 等待直到球被摄入。
// 或者直到运动停止,之后摄入装置的状态不太可能改变,我们将浪费时间
while (chassis.isInMotion() &&!isBallInIntake()) {
pros::delay(10); // 不要消耗所有的 CPU 资源
}
// 取消并继续下一个运动,因为第一个运动的目的已经完成。
// 如果在检测到球之前运动已经退出,那么这将什么也不做。
chassis.cancelMotion();
}示例
简介示例
让我们回顾一下简介中的示例,看看你实际上可能如何实现它。 以下是你在代码中实现这个运动的方法:
void goAroundObstacle() {
chassis.setPose(0, 0, 90);
// 绕过障碍物以防止撞到它
chassis.moveToPose(
48,
-24,
90,
2000,
{.minSpeed=72,.earlyExitRange=8}
// 最小速度为 72 意味着底盘在接近目标点时会减速,但不会完全停止。
// 提前退出范围为 8 意味着运动将在距离目标点 8 英寸处退出。
);
// 前往目标位置
chassis.moveToPose(64, 3, 0, 2000);
}转弯示例
有时你可能想在运动开始时进行转弯,为moveToPose创建更好的路径。如果下一个运动的最小速度很高,这一点尤其重要,因为这会导致运动不会等到面向目标,而是立即开始向前移动。
这是一个可能的用例图: 以下是你实现这个运动的方法:
// 将底盘转向 90 度,使其背向目标
chassis.swingToHeading(
90,
500,
{.minSpeed = 127,.earlyExitRange = 20}
// 最小速度为 127 意味着底盘将尽可能快地进行这个转弯。
// 提前退出范围为 20 意味着底盘一旦进入目标角度的 20 度范围内就会退出。
);
// 在这个运动点,底盘以 127 的速度移动并且背向目标,朝向目标点。
// 现在我们可以将底盘移动到所需的点
chassis.moveToPose(120, 10, 0, 1000);本文来自 [LemLib](https://lemlib.readthedocs.io/en/stable),经翻译发布于此以供大家学习使用!侵删!