估算距离
使用固定角度相机
如果您的视觉跟踪相机安装在机器人上,使得地平面与其视线之间的角度不会改变,那么您可以使用这种技术来非常准确地计算到目标的距离。然后,您可以使用这个距离值来驱动机器人前进和后退,以达到完美的范围,或调整发射机构的功率。
请看下面的图表。在这种情况下,所有变量都是已知的:目标的高度(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年,我们使用这种方法根据我们离目标的距离来调整我们的2轴炮塔的瞄准。