PX4开源飞控位置控制解析

2023-05-16

位置控制的总体思路为串级PID控制算法,内环为对速度的PID控制,外环为对位置的比例控制,被控对象为四旋翼无人机,被控量为四旋翼无人机输出的推力矢量和,将测量到的位置与速度进行反馈,与期望位置和期望速度进行比较,实现控制。本文以AUTO模式中的FollowTarget模式为例,介绍其中的控制原理。
这里写图片描述

一、期望位置的产生

  在PX4中,期望位置由经纬度与海拔构成。由navigator模块发布的由三个具有时间序列的期望位置构成的pos_sp_triplet提取产生。Pos_sp_triplet包含prev_sp、curr_sp、next_sp三个期望位置点,在followTarget模式下,只有prev_sp和curr_sp即前一个期望位置点与当前的期望位置点有效,next_sp并不予以使用。然而由navigator模块传入的curr_sp并不是实际输入以上控制系统中的期望位置。期望位置的产生仍需进行进一步的加工,以保证其合理性,确保在每个采样间隔时间段内四旋翼都能收敛到期望位置。合理性包括对四旋翼航迹进行平滑与规划,并使当前位置距离期望位置是最大速度在采样间隔时间内可到达的,前一个目标点prev_sp与当前期望位置pos_sp之间的距离也是采样间隔时间段内最大速度可以达到的。
  1.1、其对航迹的平滑与规划。采用了cross sphere line方法。首先将prev_sp、curr_sp和pos(当前四旋翼在本地坐标系中的坐标)转换到scale空间内prev_sp_s、curr_sp_s和pos_s,转换为即将距离无量纲归一化,使模为1的矢量表示最大速度时四旋翼可以移动的距离。令转换到scale空间内的三个位置点prev_sp_s、curr_sp_s和pos_s分别为a、b、c。令a_b=b-a,得向量a_b由前一期望位置指向当前期望位置。将点c投影至a_b即得投影点d。Ab_n为a_b方向上的单位向量。cd_len为c点与d点之间距离。pos_sp_s为经1次修正的scale空间中的期望位置。
  Pos_sp_s的计算方法:
  这里写图片描述
  以d为圆心做单位圆在a、b、c构成的平面上。当c和圆心d之间距离小于半径1时,令直线过c点,垂直于该点与圆心d的连线,与圆相交于两点,其中一点为x。根据勾股定理可得d_x距离。在a_b方向上,如果c在b位置前面,那么pos_sp_s为b。否则pos_sp_s为d+ab_norm*dx。当c_d距离大于等于半径时,如果在a_b方向上,a在c前面,那么pos_sp_s为a,如果c在b前面,那么目标点为b。如果c的投影在a_b之间,那么目标点为c的投影点d。求得目标点pos_sp_s即经过cross sphere line计算的,在sacle空间里的期望位置。将pos_sp_s用p表示。
  当c相对于a、b处于不同位置时,对应p处于不同的位置:
  这里写图片描述

bool
MulticopterPositionControl::cross_sphere_line(const math::Vector<3> &sphere_c, float sphere_r,
        const math::Vector<3> line_a, const math::Vector<3> line_b, math::Vector<3> &res)
{
    /* project center of sphere on line */
    /* normalized AB */
    math::Vector<3> ab_norm = line_b - line_a;
    ab_norm.normalize();
    math::Vector<3> d = line_a + ab_norm * ((sphere_c - line_a) * ab_norm);
    float cd_len = (sphere_c - d).length();

    if (sphere_r > cd_len) {
        /* we have triangle CDX with known CD and CX = R, find DX */
        float dx_len = sqrtf(sphere_r * sphere_r - cd_len * cd_len);

        if ((sphere_c - line_b) * ab_norm > 0.0f) {
            /* target waypoint is already behind us */
            res = line_b;

        } else {
            /* target is in front of us */
            res = d + ab_norm * dx_len; // vector A->B on line
        }

        return true;

    } else {
        /* have no roots, return D */
        res = d; /* go directly to line */

        /* previous waypoint is still in front of us */
        if ((sphere_c - line_a) * ab_norm < 0.0f) {
            res = line_a;
        }

        /* target waypoint is already behind us */
        if ((sphere_c - line_b) * ab_norm > 0.0f) {
            res = line_b;
        }

        return false;
    }
}

  1.2、检查期望位置从当前位置出发的可达性。在scale空间中,再次检查当前期望位置与当前位置之间的距离如果超过1则说明四旋翼即使采用最大速度飞行也无法达到期望位置,需要将从pos点到pos_sp_s的向量单位化。
  这里写图片描述

bool near = cross_sphere_line(pos_s, 1.0f, prev_sp_s, curr_sp_s, pos_sp_s);

                    if (!near) {
                        /* we're far away from trajectory, pos_sp_s is set to the nearest point on the trajectory */
                        pos_sp_s = pos_s + (pos_sp_s - pos_s).normalized();
                    }

  1.3、检查修正2次后的期望位置pos_sp_s相对curr_sp_s是否存在移动速度过快的情况。比较的方法为计算从curr_sp_s到pos_sp_s的距离curr_pos1_m是否超过采样间隔时间dt,如果超过说明期望位置修正过大,应将其重新修正。
  这里写图片描述
  这里写图片描述

/* move setpoint not faster than max allowed speed */
        math::Vector<3> pos_sp_old_s = _pos_sp.emult(scale);

        /* difference between current and desired position setpoints, 1 = max speed */
        math::Vector<3> d_pos_m = (pos_sp_s - pos_sp_old_s).edivide(_params.pos_p);
        float d_pos_m_len = d_pos_m.length();

        if (d_pos_m_len > dt) {
            pos_sp_s = pos_sp_old_s + (d_pos_m / d_pos_m_len * dt).emult(_params.pos_p);
        }

  至此经过3次修正,得出scale空间中的期望位置pos_sp_s,将其转化为本地坐标系中的pos_sp即为输入位置控制系统中的期望位置。

_pos_sp = pos_sp_s.edivide(scale);

二、期望速度的产生

  根据系统结构图_vel_sp=(_pos_sp-pos)*_params.pos_p,期望速度等于位置误差乘以比例系数。这样产生的速度还需经过三次处理,分别为四旋翼跟随目标的速度不低于目标,水平和竖直两个方向上的速度不能超过各自的最大速度,和两通道上的速度的变化速度不能超过最大加速度。
  2.1、跟随目标的速度不低于目标。用Ft_vel记录下当前四旋翼水平方向的速度矢量。Cos_radio记录下当前水平方向的速度矢量与水平方向期望速度之间的夹角的cos值。当cos值大于0时,即两速度方向夹角小于90度。计算ft_vel。
  这里写图片描述
  这里写图片描述
  若cos值小于等于0,即两速度夹角大于90度时,设置ft_vel为0。在水平方向上比较x,y两个轴方向ft_vel和_vel_sp哪个数值比较大,令_vel_sp在两个轴上的分量分别等于各自轴上较大的一方。以此达到僚机的速度不小于长机的速度,产生适当追赶的效果。

/* do not go slower than the follow target velocity when position tracking is active (set to valid)*/

if (_pos_sp_triplet.current.type == position_setpoint_s::SETPOINT_TYPE_FOLLOW_TARGET &&
velocity_valid &&_pos_sp_triplet.current.position_valid) {

  math::Vector<3> ft_vel(_pos_sp_triplet.current.vx,         _pos_sp_triplet.current.vy, 0);

  float cos_ratio = (ft_vel * _vel_sp) / (ft_vel.length() * _vel_sp.length());

  // only override velocity set points when uav is traveling in same direction as target and vector component
  // is greater than calculated position set point velocity component

  if (cos_ratio > 0) {
    ft_vel *= (cos_ratio);
    // min speed a little faster than target vel
    ft_vel += ft_vel.normalized() * 1.5f;

  } else {
          ft_vel.zero();
  }

  _vel_sp(0) = fabs(ft_vel(0)) > fabs(_vel_sp(0)) ? ft_vel(0) : _vel_sp(0);
  _vel_sp(1) = fabs(ft_vel(1)) > fabs(_vel_sp(1)) ? ft_vel(1) : _vel_sp(1);

  // track target using velocity only

}
// limit vertical acceleration
float acc_v = (_vel_sp(2) - _vel_sp_prev(2)) / dt;

if (fabsf(acc_v) > 2 * _params.acc_hor_max) {
    acc_v /= fabsf(acc_v);
    _vel_sp(2) = acc_v * 2 * _params.acc_hor_max * dt + _vel_sp_prev(2);
}

  2.2、水平方向与竖直方向双通道的速度限幅。检查vel_sp在水平方向的分量是否超过了该方向上的最大飞行速度,如果超过了则进行等比例缩放。检查_vel_sp在竖直方向上是否超过了最大上升或者下降的速度,如果超过了对其进行限幅。
  这里写图片描述

/* make sure velocity setpoint is saturated in xy*/
float vel_norm_xy = sqrtf(_vel_sp(0) * _vel_sp(0) +_vel_sp(1) * _vel_sp(1));

if (vel_norm_xy > _params.vel_max(0)) {
    /* note assumes vel_max(0) == vel_max(1) */
    _vel_sp(0) = _vel_sp(0) * _params.vel_max(0) / vel_norm_xy;
    _vel_sp(1) = _vel_sp(1) * _params.vel_max(1) / vel_norm_xy;
}

/* make sure velocity setpoint is saturated in z*/
if (_vel_sp(2) < -1.0f * _params.vel_max_up) {
    _vel_sp(2) = -1.0f * _params.vel_max_up;
}

if (_vel_sp(2) >  _params.vel_max_down) {
    _vel_sp(2) = _params.vel_max_down;
}

  2.3、水平方向与竖直方向双通道加速度限幅。检查当前_vel_sp与prev_vel_sp在dt时间内产生的水平与竖直方向的加速度,是否超过各自通道的最大加速度,如果超过了对其限幅至最值。
  这里写图片描述

// limit total horizontal acceleration
math::Vector<2> acc_hor;
acc_hor(0) = (_vel_sp(0) - _vel_sp_prev(0)) / dt;
acc_hor(1) = (_vel_sp(1) - _vel_sp_prev(1)) / dt;

if (acc_hor.length() > _params.acc_hor_max) {
    acc_hor.normalize();
    acc_hor *= _params.acc_hor_max;
    math::Vector<2> vel_sp_hor_prev(_vel_sp_prev(0),         _vel_sp_prev(1));
    math::Vector<2> vel_sp_hor = acc_hor * dt + vel_sp_hor_prev;
    _vel_sp(0) = vel_sp_hor(0);
    _vel_sp(1) = vel_sp_hor(1);
}

// limit vertical acceleration
float acc_v = (_vel_sp(2) - _vel_sp_prev(2)) / dt;

if (fabsf(acc_v) > 2 * _params.acc_hor_max) {
    acc_v /= fabsf(acc_v);
    _vel_sp(2) = acc_v * 2 * _params.acc_hor_max * dt +   _vel_sp_prev(2);
}

三、期望姿态的产生

  内环速度PID控制器产生了推力的设定值,再由推力计算得姿态的期望值。
  PID计算公式:
  这里写图片描述
  这里写图片描述

vel_err = _vel_sp - _vel;
thrust_sp = vel_err.emult(_params.vel_p) + _vel_err_d.emult(_params.vel_d) + thrust_int

  vel_err为速度误差,_vel_err_d为速度误差的导数。P为比例系数,D为微分系数,I为积分系数。
  thrust_int 为速度误差的积分,更新公式为:
  这里写图片描述

/* update integrals */
if (_control_mode.flag_control_velocity_enabled && !saturation_xy) {
    thrust_int(0) += vel_err(0) * _params.vel_i(0) * dt;
    thrust_int(1) += vel_err(1) * _params.vel_i(1) * dt;
}

if (_control_mode.flag_control_climb_rate_enabled && !saturation_z) {
    thrust_int(2) += vel_err(2) * _params.vel_i(2) * dt;

    /* protection against flipping on ground when landing */
    if (thrust_int(2) > 0.0f) {
        thrust_int(2) = 0.0f;
    }
}

  3.1、PID控制器得出期望推力。PID得出的推力期望值为thrust_sp,在此基础上需要依次进行三次修正分别为:确保升力大于最小升力,保证四旋翼的倾斜程度不超过最大倾斜角,保证推力的期望值不超过最大推力。
  3.1.1、确保升力大于最小值。当-thrust_sp(2) < thr_min时,令thrust_sp(2) = -thr_min。

/* limit min lift */
if (-thrust_sp(2) < thr_min) {
    thrust_sp(2) = -thr_min;
    saturation_z = true;
}

  3.1.2、为保证四旋翼不超过其最大倾斜角。保持竖直方向的升力不变,计算当前水平方向推力是否超过水平方向可提供的最大推力,如果超过将其等比例缩小,使推力的合力为最大推力值。

if (_control_mode.flag_control_velocity_enabled || _control_mode.flag_control_acceleration_enabled) {

    /* limit max tilt */
    if (thr_min >= 0.0f && tilt_max < M_PI_F / 2 - 0.05f) {
        /* absolute horizontal thrust */
        float thrust_sp_xy_len = math::Vector<2>(thrust_sp(0),       thrust_sp(1)).length();

        if (thrust_sp_xy_len > 0.01f) {
        /* max horizontal thrust for given vertical thrust*/
        float thrust_xy_max = -thrust_sp(2) * tanf(tilt_max);

            if (thrust_sp_xy_len > thrust_xy_max) {
                float k = thrust_xy_max / thrust_sp_xy_len;
                thrust_sp(0) *= k;
                thrust_sp(1) *= k;
                saturation_xy = true;
            }
        }
    }
}

  3.1.3、限制最大推力。当z轴预设推力超过最大值时,令z轴向上的推力为最大值,x、y轴上的推力置为0。当z轴推力为正,但未超过最大推力时,保持z轴的推力不变,等比例缩小x、y轴的推力。当推力向下时,并且整体推力大于最大推力时,整体等比缩小至推力矢量模值为最大值。
  这里写图片描述

thrust_abs = thrust_sp.length(); /* recalculate because it might have changed */

if (thrust_abs > thr_max) {
    if (thrust_sp(2) < 0.0f) {
        if (-thrust_sp(2) > thr_max) {
            /* thrust Z component is too large, limit it */
            thrust_sp(0) = 0.0f;
            thrust_sp(1) = 0.0f;
            thrust_sp(2) = -thr_max;
            saturation_xy = true;
            saturation_z = true;

         } else {
         /* preserve thrust Z component and lower XY, keeping altitude is more important than position */
         float thrust_xy_max = sqrtf(thr_max * thr_max - thrust_sp(2) * thrust_sp(2));
         float thrust_xy_abs = math::Vector<2>(thrust_sp(0), thrust_sp(1)).length();
         float k = thrust_xy_max / thrust_xy_abs;
         thrust_sp(0) *= k;
         thrust_sp(1) *= k;
         saturation_xy = true;
         }

    } else {
    /* Z component is negative, going down, simply limit thrust vector */
    float k = thr_max / thrust_abs;
    thrust_sp *= k;
    saturation_xy = true;
    saturation_z = true;
    }

    thrust_abs = thr_max;
}

  3.2、由期望推力得出期望姿态。为了实现设计的推力矢量方向,四旋翼的机体z轴应与推力矢量方向相反。机体x轴方向即机头方向应处于的方向的计算方法为,将期望航向在水平面向右旋转旋转90度,再用其叉乘期望姿态时的机体z轴。机体y轴的方向为,机体z轴叉乘机体x轴方向。令矩阵R每一列的数值分别对应机体x、y、z轴方向上,单位矢量在北东地坐标系下的坐标值,即得表示期望姿态的方向余弦矩阵。利用方向余弦矩阵即可转换成表示期望姿态的四元数,送至姿态控制器。
  方向余弦矩阵转四元数:
  这里写图片描述

/* calculate attitude setpoint from thrust vector */
if (_control_mode.flag_control_velocity_enabled || _control_mode.flag_control_acceleration_enabled) {
    /* desired body_z axis = -normalize(thrust_vector) */
    math::Vector<3> body_x;
    math::Vector<3> body_y;
    math::Vector<3> body_z;

    if (thrust_abs > SIGMA) {
        body_z = -thrust_sp / thrust_abs;

    } else {
        /* no thrust, set Z axis to safe value */
        body_z.zero();
        body_z(2) = 1.0f;
    }

    /* vector of desired yaw direction in XY plane, rotated by PI/2 */
    math::Vector<3> y_C(-sinf(_att_sp.yaw_body), cosf(_att_sp.yaw_body), 0.0f);

    if (fabsf(body_z(2)) > SIGMA) {
        /* desired body_x axis, orthogonal to body_z */
        body_x = y_C % body_z;

        /* keep nose to front while inverted upside down */
        if (body_z(2) < 0.0f) {
            body_x = -body_x;
        }

        body_x.normalize();

        } else {
            /* desired thrust is in XY plane, set X downside to construct correct matrix,
            * but yaw component will not be used actually */
            body_x.zero();
            body_x(2) = 1.0f;
        }

        /* desired body_y axis */
        body_y = body_z % body_x;

        /* fill rotation matrix */
        for (int i = 0; i < 3; i++) {
            R(i, 0) = body_x(i);
            R(i, 1) = body_y(i);
            R(i, 2) = body_z(i);
        }

        /* copy quaternion setpoint to attitude setpoint topic */
        matrix::Quatf q_sp = R;
        memcpy(&_att_sp.q_d[0], q_sp.data(), sizeof(_att_sp.q_d));
        _att_sp.q_d_valid = true;

        /* calculate euler angles, for logging only, must not be used for control */
        matrix::Eulerf euler = R;
        _att_sp.roll_body = euler(0);
        _att_sp.pitch_body = euler(1);
        /* yaw already used to construct rot matrix, but actual rotation matrix can have different yaw near singularity */

}

四、总结

  由导航模块产生上一个期望位置和当前期望位置,位置控制部分对当前期望位置基于控制需要进行3次修正,产生有效的期望位置。期望位置与位置估计模块产生的真实位置比较,得出位置误差,位置误差乘以位置比例系数得出粗略的期望速度。对粗略的期望速度进行3次产生有效的期望速度。期望速度与姿态估计模块产生的真实速度比较,得出速度误差,计算速度误差的导数,采用PID算法,将速度误差乘以比例系数,速度误差的导数乘以微分系数,将速度误差的积分乘以积分系数,三者求和即为粗略的推力矢量和。对粗略的推力矢量和进行2次修正,得到有效的推力矢量和。由推力矢量和即可得出机体坐标系三轴的方向,将表示三轴方向的方向余弦矩阵转换为四元数表示。四元数表示的期望姿态由此产生,送至姿态控制器,经mixer与电机驱动输出推力,至此完成PX4开源飞控中位置控制的全部过程。


版权声明:本文为博主原创文章,未经博主允许不得转载。https://blog.csdn.net/weixin_37501173/article/details/80035051

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PX4开源飞控位置控制解析 的相关文章

  • CVPR2019目标检测方法进展

    目标检测是很多计算机视觉应用的基础 xff0c 比如实例分割 人体关键点提取 人脸识别等 xff0c 它结合了目标分类和定位两个任务 现代大多数目标检测器的框架是 two stage xff0c 其中目标检测被定义为一个多任务学习问题 xf
  • ubuntu16.04+cuda8.0+cudnn+opencv3.0+caffe

    一 ubuntu16 04安装 开机F12进入BIOS的设备启动菜单 xff0c 选择U盘启动 安装类型 xff0c 选择其他选项 xff0c 进行分区 Swap xff1a 逻辑分区 xff0c 20GB 空间起始位置 交换空间 boot
  • Linux 用户态通过中断切换到内核态详解

    文章目录 一 用户态与内核态二 中断三 任务状态段四 Linux 进程从用户态切换到内核态的过程五 参考资料 一 用户态与内核态 Linux 把内存主要分为 4 个段 xff0c 分别是内核代码段 内核数据段 用户代码段 用户数据段 内核两
  • PX4中串口名称、设备名称、端口名称对应关系

    这里规定了各种uart usart的波特率 bufsize等配置 xff0c boards px4 fmu v5 nuttx config nsh defconfig CONFIG STM32F7 UART4 span class toke
  • PX4调试过程中的小问题

    使用USB直连飞控可以开始校准 xff0c 但是用无线的方式开始任一传感器的校准都报错 xff1a Transition denied SHUTDOWN to INIT 明明飞控正常上电 xff0c 也许报了个错说 critical bat
  • PX4中IMU传感器的数据经过了哪些处理后被使用的?

    注 xff1a 所用PX4的代码版本为当前master最新版9e309f62a9b1731caae96000b824aa96661e67ad 2019年11月所写 xff0c 新版本有所不同 xff0c 尚未更新 IMU的数据 xff1a
  • WARNING: [Vivado 12-13340] WARNING: [Vivado 12-13277]

    仿真的时候遇问题 xff1a WARNING Vivado 12 13340 Unable to auto find GCC executables from simulator install path path not set WARN
  • 二.因子图优化学习---董靖博士在深蓝学院的公开课学习(2)

    专栏系列文章如下 xff1a https blog csdn net weixin 36773706 article details 122440411 https blog csdn net weixin 36773706 article
  • 四.因子图优化学习---对因子图优化的粗浅理解

    专栏系列文章如下 xff1a 一 因子图优化学习 董靖博士在深蓝学院的公开课学习 xff08 1 xff09 goldqiu的博客 CSDN博客 二 因子图优化学习 董靖博士在深蓝学院的公开课学习 xff08 2 xff09 goldqiu
  • 多传感器融合SLAM、导航研究和学习专栏汇总

    从2021年9月份开始学习多传感器融合SLAM xff0c 期间也发了不少博客记录学习过程 xff0c 自己对SLAM的认识也逐渐加深 xff0c 以前一些博客中会有一些错误的地方还未及时去修正 xff0c 敬请谅解 由于课题组需要和自身发
  • 启航篇——四旋翼飞行器之入坑两年心路历程和毕设总结

    笔者今年大四毕业 xff0c 由于之前参加比赛及准备考研 xff0c 没有时间总结这两年来做四旋翼飞行器的心得体会 现在借毕业设计这个契机 xff0c 想把这件事做了 xff0c 算是两年的收尾工作 xff0c 也是个新的开始 先从介绍这两
  • Gazebo学习笔记(一)

    搭建一个移动车 ctrl 43 m 进入到gazebo编辑界面 ctrl 43 m 进入到gazebo编辑界面 1 搭建一个车底盘 xff0c 选择simple shapes 的box xff0c 点击后在编辑框中释放 2 利用resize
  • 1分钟教会你二进制撩妹(汉)读心术

    近些年来 xff0c 小魔发现 xff0c 对于年轻的男女而言 xff0c 一些传统的节日似乎都变成了情人节或者脱单节 xff0c 就连 光棍节 xff0c 实际上很多人都是抱着节前或者是当天脱单而过的 双11 光棍节 即将来临 xff0c
  • 树莓派光敏传感器控制LED小灯的开关

    今天来做一个关于光敏传感器的使用demo xff0c 如图 xff0c 我采用的是普通用于开发的光敏传感器 传感器的基板上有两个LED xff0c 上一个是表示DO的高低电平 xff0c 下一个表示是否通电 当挡住传感头之后 xff0c D
  • Opencv+YOLO3目标检测/C++

    1 引言 YOLO3能够快速识别图片和视频中的80种物体 xff0c 而且实时性强 xff0c 准确度接近SSD Opencv是目前最流行的开源图像处理库 xff0c 使用Opencv能够非常方便的对图像进行处理 Opencv4 0已经包含
  • Linux安装Docker

    安装前菜 如何卸载Docker 1 查询docker安装包 yum list installed grep docker 2 删除安装包 yum remove docker 3 删除镜像 容器等 rm rf var lib docker 下
  • 北邮初试+复试经验分享

    初试情况 xff1a 政治 53 英语 70 数学 122 计算机综合 xff08 803 xff09 110 一些相关的基本情况 xff1a 本科专业数学 本科期间学过数据结构 通过了英语四六级 本科成绩还算可以 初试材料选择 xff08
  • apt命令概述

    目录 Linux软件仓库 软件源配置 apt命令 常见的命令如下 xff1a 常见的用法 示例 xff1a 使用apt安装redis软件 Linux软件仓库 Ubuntu采用集中式的软件仓库机制 xff0c 将各式各样 的软件包分门别类地存
  • 索引覆盖与回表

    懂的越多 xff0c 不懂的越多 上回书说到 xff1a 什么情况下 xff0c 索引下推没办法提高sql查询效率 xff1f 表info主键id名称name值value别名realname 对于info表 xff0c 我们现在有 xff0
  • Ubuntu18.04安装实时内核Preempt-RT

    文章目录 1 安装环境2 安装依赖包3 查看内核版本4 下载新的内核和对应的Preempt RT补丁5 解压缩6 打补丁7 配置内核8 编译内核9 校验结果10 重启11 测试12 调整分辨率 1 安装环境 Ubuntu18 04内核版本

随机推荐