弹道解算

RoboMaster OSS 这位讲解的弹道解算非常的详尽,所以我也只简单讲解,具体的公式推导就看里面

   Eigen::Vector3d Barrel_Solve(Eigen::Vector3d position);             // 解算枪管移动角度
   /** 抬升角度计算 */
   float airResistanceSolve(Eigen::Vector3d Pos);
   float BulletModel(float x, float v, float angle);

枪管解算

/**
 *  函数名: Barrel_Solve
 *  传入: Eigen::Vector3d position
 *  传出: Vector3d rpy
 *  功能: 通过传入的坐标计算枪管移动角度
 */
Eigen::Vector3d AngleSolve::Barrel_Solve(Eigen::Vector3d position) {
    Eigen::Vector3d rpy;
    rpy[2] = -atan2(position[0],position[1]) / CV_PI*180.0;
    rpy[1] = atan2(position[2],position[1]) / CV_PI*180.0;
    rpy[0] = atan2(position[2],position[0]) / CV_PI*180.0;

    // 单独计算抬升角度 | atan2()计算角度在车旋转180度之后会解算出[90-180]
    rpy[1] = airResistanceSolve(position);
    // 添加枪管补偿
    rpy[0] += Barrel_offset_angle[0];
    rpy[1] += Barrel_offset_angle[1];
    rpy[2] += Barrel_offset_angle[2];

    return rpy;
}

这里需要注意的就是atan2函数,这个函数的取值范围是 -180~180


对于yaw数据来说,我们直接使用就行,但是呢,pitch数据不能直接使用,因为子弹会下坠

所以我们需要对Pitch数据单独计算,引入空气阻力模型,根据距离解算下坠距离,从而得到我们实际应该抬升的角度

airResistanceSolve函数

空气阻力计算模型

float AngleSolve::airResistanceSolve(Eigen::Vector3d Pos) {

    // -----------要水平距离的融合,否则计算的距离会少,在视野边缘处误差会大----------
    float x = (float)sqrt(Pos[0]*Pos[0]+ Pos[1]*Pos[1]);
    float y = (float)Pos[2];

    float y_temp, y_actual, dy;
    float Solve_pitch;
    y_temp = y;
    bullet_speed = 25;
    // 迭代法 | 使用弹道模型对落点高度进行计算,直到落点高度达到要求,得到抬升角度
    for (int i = 0; i < 20; i++)
    {
        Solve_pitch = (float)atan2(y_temp, x);                        // 计算当前枪管抬升角度
        y_actual = BulletModel(x, bullet_speed, Solve_pitch);           // 得到落点高度
        dy = y - y_actual;                                               // 计算落点高度和目标高度的误差
        y_temp = y_temp + dy;                                            // 误差补偿

        //! 误差精度达到一定要求
        if (fabsf(dy) < 0.00001) {
            break;
        }
    }
    Solve_pitch = Solve_pitch*180.f/CV_PI;  // 解算角度
    return Solve_pitch;
}

这里的迭代法名为 “牛顿迭代法” 有兴趣可以去了解

我们通过计算落点的高度,不断的调整落点高度,实现误差基本为0,如图

所以我们就需要不断的迭代高度,使得实际命中点和目标点重合

/**
 *  函数名: BulletModel
 *  传入: float x, float v, float angle       (水平距离,弹速,抬升角度)
 *  传出: float y                             (落点高度)
 *  功能: 通过传入的坐标计算枪管移动角度
 *  弹道模型推导:
 *  https://robomaster-oss.github.io/rmoss_tutorials/#/rmoss_core/rmoss_projectile_motion/projectile_motion_iteration
 */
float AngleSolve::BulletModel(float x, float v, float angle) { //x:m,v:m/s,angle:rad
    float t,y;
    t = (float)((exp(SMALL_AIR_K * x) - 1) / (SMALL_AIR_K * v * cos(angle)));
    y = (float)(v * sin(angle) * t - GRAVITY * t * t/* * cos(ab_pitch)*/ / 2);
    return y;
}

下面就是实际的一个推导

results matching ""

    No results matching ""