距离估算
使用固定角度摄像头
如果您的视觉追踪摄像头安装在机器人上,使得地面平面与其视线之间的角度不会改变,那么您可以使用此技术非常准确地计算到目标的距离。然后,您可以使用此距离值来驱动机器人前进或后退以达到最佳射程,或调整发射机构的功率。
请参见下图。在此情况下,所有变量都是已知的:目标高度(h2)是已知的,因为它是场地的属性。您的摄像头离地面的高度(h1)是已知的,其安装角度也是已知的(a1)。Limelight(或您的视觉系统)可以告诉您到目标的 y 角度(a2)。

我们可以使用以下方程求解 d:
tan(a1+a2) = (h2-h1) / d
"d = (h2-h1) / tan(a1+a2)"
"tan" 函数通常期望输入以弧度为单位。要将角度测量值从度转换为弧度,请乘以 (3.14159/180.0)。请参见下面的完整代码示例。
- Java
- C++
NetworkTable table = NetworkTableInstance.getDefault().getTable("limelight");
NetworkTableEntry ty = table.getEntry("ty");
double targetOffsetAngle_Vertical = ty.getDouble(0.0);
// 您的 limelight 从完全垂直位置向后旋转了多少度?
double limelightMountAngleDegrees = 25.0;
// 从 Limelight 镜头中心到地面的距离
double limelightLensHeightInches = 20.0;
// 从目标到地面的距离
double goalHeightInches = 60.0;
double angleToGoalDegrees = limelightMountAngleDegrees + targetOffsetAngle_Vertical;
double angleToGoalRadians = angleToGoalDegrees * (3.14159 / 180.0);
// 计算距离
double distanceFromLimelightToGoalInches = (goalHeightInches - limelightLensHeightInches) / Math.tan(angleToGoalRadians);
std::shared_ptr<NetworkTable> table = nt::NetworkTableInstance::GetDefault().GetTable("limelight");
double targetOffsetAngle_Vertical = table->GetNumber("ty",0.0);
// 您的 limelight 从完全垂直位置向后旋转了多少度?
double limelightMountAngleDegrees = 25.0;
// 从 Limelight 镜头中心到地面的距离
double limelightLensHeightInches = 20.0;
// 从目标到地面的距离
double goalHeightInches = 60.0;
double angleToGoalDegrees = limelightMountAngleDegrees + targetOffsetAngle_Vertical;
double angleToGoalRadians = angleToGoalDegrees * (3.14159 / 180.0);
// 计算距离
double distanceFromLimelightToGoalInches = (goalHeightInches - limelightLensHeightInches)/tan(angleToGoalRadians);
使用此技术时,仔细选择摄像头的安装角度非常重要。您希望在距离太近和太远时都能看到目标。您还不希望此角度发生变化,因此请牢固安装,并避免在安装结构中使用槽孔。
如果您在确定角度 a1 时遇到困难,您也可以使用上述方程来求解 a1。只需将机器人放置在已知距离处(从摄像头镜头测量),然后用相同的方程求解 a1。
在目标与摄像头高度几乎相同的情况下,此技术不适用。
使用面积估算距离
另一种简单的距离估算方法是使用您正在追踪的轮廓面积。这是一种非常简单的实现方法,但不会给您非常准确的结果。您只需将视觉摄像头从已知距离对准目标,并记录色块的面积。确保您使用的是真实场地视觉目标的准确表示,并确保您从期望的射击位置对准它。然后,您可以从几个不同的距离执行此操作,并根据这些值制作一个表格。在 2016 年,我们使用此方法根据与目标的距离来调整我们双轴云台的瞄准。