ArduPilot开源飞控之飞行模式

ArduPilot开源飞控之飞行模式

  • 1. 源由
  • 2. 飞行模式-已实现
  • 3. 飞行模式-设计
    • 3.1 模式初始化(`init`)
    • 3.2 模式退出(`exit`)
    • 3.3 模式任务(`run`)
    • 3.4 模式切换场景
      • 3.4.1 上电初始化
      • 3.4.2 `EKF FAILSAFE`触发
      • 3.4.3 `do_failsafe_action FAILSAFE`触发
      • 3.4.4 `AP_Avoidance_Copter`触发
      • 3.4.5 Crash触发
      • 3.4.6 围栏设置触发
      • 3.4.7 RC遥控触发
      • 3.4.8 MAVLink触发
      • 3.4.9 飞行模式内部逻辑触发
      • 3.4.10 heli触发
      • 3.4.11 MavLink_FrSkySPort
  • 4. 新增飞行模式
    • Step 1:新增模式名称
    • Step 2:定义基本接口
    • Step 3:补充基本接口实现
    • Step 4:添加类实例
    • Step 5:添加模式映射
    • Step 6:设置默认飞行模式
    • Step 7:地面站配置参数修改
  • 5. 总结
  • 6. 参考资料

1. 源由

ArduPilot开源飞控有各种飞行模式,比如:stablize/acro/auto/guided 等等。基于这些飞行模式,用户可以根据需要选择合适的飞行计划。

  • 花飞、竞速:可以直接采用acro手动模式
  • 任务、航点:可以选择auto飞行模式
  • 异常情况:可以选择诸如RTL飞行模式,自动返航
  • 等等

本章节将会针对飞行模式来整理下ArduPilot在飞行模式上的强大功能,以及整合用户自定义的步骤。

2. 飞行模式-已实现

多旋翼飞行器ArduPilot已经实现的飞行模式如下所述:

    // Auto Pilot Modes enumeration
    enum class Number : uint8_t {
        STABILIZE =     0,  // manual airframe angle with manual throttle
        ACRO =          1,  // manual body-frame angular rate with manual throttle
        ALT_HOLD =      2,  // manual airframe angle with automatic throttle
        AUTO =          3,  // fully automatic waypoint control using mission commands
        GUIDED =        4,  // fully automatic fly to coordinate or fly at velocity/direction using GCS immediate commands
        LOITER =        5,  // automatic horizontal acceleration with automatic throttle
        RTL =           6,  // automatic return to launching point
        CIRCLE =        7,  // automatic circular flight with automatic throttle
        LAND =          9,  // automatic landing with horizontal position control
        DRIFT =        11,  // semi-autonomous position, yaw and throttle control
        SPORT =        13,  // manual earth-frame angular rate control with manual throttle
        FLIP =         14,  // automatically flip the vehicle on the roll axis
        AUTOTUNE =     15,  // automatically tune the vehicle's roll and pitch gains
        POSHOLD =      16,  // automatic position hold with manual override, with automatic throttle
        BRAKE =        17,  // full-brake using inertial/GPS system, no pilot input
        THROW =        18,  // throw to launch mode using inertial/GPS system, no pilot input
        AVOID_ADSB =   19,  // automatic avoidance of obstacles in the macro scale - e.g. full-sized aircraft
        GUIDED_NOGPS = 20,  // guided mode but only accepts attitude and altitude
        SMART_RTL =    21,  // SMART_RTL returns to home by retracing its steps
        FLOWHOLD  =    22,  // FLOWHOLD holds position with optical flow without rangefinder
        FOLLOW    =    23,  // follow attempts to follow another vehicle or ground station
        ZIGZAG    =    24,  // ZIGZAG mode is able to fly in a zigzag manner with predefined point A and point B
        SYSTEMID  =    25,  // System ID mode produces automated system identification signals in the controllers
        AUTOROTATE =   26,  // Autonomous autorotation
        AUTO_RTL =     27,  // Auto RTL, this is not a true mode, AUTO will report as this mode if entered to perform a DO_LAND_START Landing sequence
        TURTLE =       28,  // Flip over after crash

        // Mode number 127 reserved for the "drone show mode" in the Skybrush
        // fork at https://github.com/skybrush-io/ardupilot
    };

其相互之间的关系,如图所示:

在这里插入图片描述
在这里插入图片描述

3. 飞行模式-设计

飞行模式主要是通过以下三个函数来实现飞行模式下,动态飞行应用:

  • 模式初始化(init)
  • 模式任务(run)
  • 模式退出(exit)

3.1 模式初始化(init)

首先,需要完成新模式的初始化过程。

Copter::set_mode
 └──> new_flightmode->init  // e.g. ModeAcro::init

3.2 模式退出(exit)

其次,完成老模式的去初始化,退出之前的模式。

Copter::set_mode
 └──> Copter::exit_mode
     └──> old_flightmode->exit

3.3 模式任务(run)

最后,就是动态运行飞行模式,使用各个内部模块协调处理和应对各种飞行过程中遇到的问题,实现安全飞行。

Copter::update_flight_mode
 └──> flightmode->run

3.4 模式切换场景

ArduPilot飞控系统中模式切换出现的场景涉及很多点位,每个点位都可能出现切换异常,此时,系统将会进行一些默认和失败的异常处理。

这里通过代码,简单的罗列了各种可能发生的场景:

  1. 上电初始化
  2. EKF FAILSAFE触发
  3. do_failsafe_action FAILSAFE触发
  4. AP_Avoidance_Copter触发

3.4.1 上电初始化

init_ardupilot
 └──> Copter::set_mode
     └──> new_flightmode->init  //e.g. ModeStabilize::init

3.4.2 EKF FAILSAFE触发

Copter::ekf_check // 10Hz task
 └──> Copter::failsafe_ekf_event
     └──> Copter::set_mode

3.4.3 do_failsafe_action FAILSAFE触发

do_failsafe_action涉及较多的场景,这里不再赘述了,详见:ArduPilot开源飞控之do_failsafe_action

  1. Copter::set_mode_RTL_or_land_with_pause
  2. Copter::set_mode_SmartRTL_or_land_with_pause
  3. Copter::set_mode_SmartRTL_or_RTL
  4. Copter::set_mode_auto_do_land_start_or_RTL
  5. Copter::set_mode_brake_or_land_with_pause
  6. Copter::set_mode_land_with_pause

3.4.4 AP_Avoidance_Copter触发

AP_Avoidance_Copter主要是避障传感器的应用

Copter::avoidance_adsb_update  // 10Hz task
 └──> AP_Avoidance::update
     ├──> AP_Avoidance::check_startup
     │   └──> <> AP_Avoidance::deinit
     │       └──> <> AP_Avoidance_Copter::handle_recovery
     │           └──> <> AP_Avoidance_Copter::set_mode_else_try_RTL_else_LAND
     │               └──> Copter::set_mode
     └──> AP_Avoidance::handle_avoidance_local
         ├──> AP_Avoidance_Copter::handle_avoidance
         │   ├──> <> Copter::set_mode
         │   ├──> <> AP_Avoidance_Copter::handle_avoidance_vertical
         │   │   └──> AP_Avoidance_Copter::check_flightmode
         │   │       └──> Copter::set_mode
         │   ├──> <> AP_Avoidance_Copter::handle_avoidance_horizontal
         │   │   └──> AP_Avoidance_Copter::check_flightmode
         │   │       └──> Copter::set_mode
         │   └──> <> AP_Avoidance_Copter::handle_avoidance_perpendicular
         │       └──> AP_Avoidance_Copter::check_flightmode
         │           └──> Copter::set_mode
		 │
         └──> <> AP_Avoidance_Copter::handle_recovery
             └──> AP_Avoidance_Copter::set_mode_else_try_RTL_else_LAND
                 └──> Copter::set_mode

3.4.5 Crash触发

当发生Crash时,直接设置飞行模式为LAND。

Copter::motors_output // FAST_TASK
 └──> <> AP_AdvancedFailsafe_Copter::terminate_vehicle
     └──> <g2.afs.should_crash_vehicle()> copter.set_mode(Mode::Number::LAND, ModeReason::TERMINATE)

3.4.6 围栏设置触发

当满足围栏设置条件时,根据围栏触发设置,变更飞行模式。

Copter::fence_check
 └──> <> Copter::set_mode

3.4.7 RC遥控触发

根据遥控器设置,触发飞行模式变更。

  1. RC_Channel_Copter::mode_switch_changed
  2. RC_Channel_Copter::do_aux_function_change_mode
  3. RC_Channel_Copter::do_aux_function

3.4.8 MAVLink触发

MAVLink命令触发飞行模式的变更。

  1. GCS_MAVLINK::_set_mode_common
  2. GCS_MAVLINK_Copter::handle_command_int_do_reposition
  3. GCS_MAVLINK_Copter::handle_command_long_packet

3.4.9 飞行模式内部逻辑触发

由于飞行模式可以认为是一种应用,根据应用场景,有些模式会根据需要进行模式切换。

比如:

  1. ModeBrake::run
  2. ModeFlip::run
  3. ModeLand::nogps_run
  4. ModeRTL::climb_start
  5. ModeRTL::descent_run
  6. ToyMode::update
  7. ToyMode::set_and_remember_mode

3.4.10 heli触发

FRAME_CONFIG == HELI_FRAME 直升机模型作为多旋翼是一种特殊的情况,这里单独有一个类对应处理。

Copter::heli_update_autorotation //  FAST_TASK
 └──> <> Copter::set_mode

3.4.11 MavLink_FrSkySPort

MavLink_FrSkySPort遥控有一个MAVLink的API接口,参考:ArduPilot开源代码之RCInput

注:这部分内容尚不太明朗,目前没有发现遥控器可以通过该协议设置飞控模式。如果有对此了解的朋友,请留言,谢谢!

4. 新增飞行模式

梳理下关于新增一个飞行模式的步骤,详细可参考:Adding a New Flight Mode to Copter

在这里插入图片描述

注:请注意,接下去的描述将会以RTL模式为例。

Step 1:新增模式名称

为新模式选择一个名称,并将其添加到modes.h中control_mode_t枚举的底部。这里以RTL为例。

// Auto Pilot Modes enumeration
enum class Number {
    STABILIZE =     0,  // manual airframe angle with manual throttle
    ACRO =          1,  // manual body-frame angular rate with manual throttle
    ALT_HOLD =      2,  // manual airframe angle with automatic throttle
    AUTO =          3,  // fully automatic waypoint control using mission commands
    GUIDED =        4,  // fully automatic fly to coordinate or fly at velocity/direction using GCS immediate commands
    LOITER =        5,  // automatic horizontal acceleration with automatic throttle
    RTL =           6,  // automatic return to launching point
    CIRCLE =        7,  // automatic circular flight with automatic throttle
    LAND =          9,  // automatic landing with horizontal position control
    DRIFT =        11,  // semi-automous position, yaw and throttle control
    SPORT =        13,  // manual earth-frame angular rate control with manual throttle
    FLIP =         14,  // automatically flip the vehicle on the roll axis
    AUTOTUNE =     15,  // automatically tune the vehicle's roll and pitch gains
    POSHOLD =      16,  // automatic position hold with manual override, with automatic throttle
    BRAKE =        17,  // full-brake using inertial/GPS system, no pilot input
    THROW =        18,  // throw to launch mode using inertial/GPS system, no pilot input
    AVOID_ADSB =   19,  // automatic avoidance of obstacles in the macro scale - e.g. full-sized aircraft
    GUIDED_NOGPS = 20,  // guided mode but only accepts attitude and altitude
    SMART_RTL =    21,  // SMART_RTL returns to home by retracing its steps
    FLOWHOLD  =    22,  // FLOWHOLD holds position with optical flow without rangefinder
    FOLLOW    =    23,  // follow attempts to follow another vehicle or ground station
    ZIGZAG    =    24,  // ZIGZAG mode is able to fly in a zigzag manner with predefined point A and point B
    SYSTEMID  =    25,  // System ID mode produces automated system identification signals in the controllers
    AUTOROTATE =   26,  // Autonomous autorotation
};

Step 2:定义基本接口

为mode.h中的模式定义一个新的类。复制类似的现有模式的类定义并更改类名可能是最简单的(即复制并重命名“class ModeStabilize”为“class ModeNewMode”)。新类应该继承自Mode类,并实现run()、name()和name4()以及可选的init()。

public:
   // inherit constructor
   using Mode::Mode;
   bool init(bool ignore_checks) override;
   void run() override;

protected:
   const char *name() const override { return "NEWMODE"; }
   const char *name4() const override { return "NEWM"; }

注:其他需要的接口,请根据需求自行添加,建议参考已有的飞行模式代码。

Step 3:补充基本接口实现

基于类似的模式(如mode_stabilize.cpp或mode_loiter.cpp)创建一个新的mode_.cpp文件。这个新文件可能会实现init()方法,该方法将在首次进入该模式时调用。如果可以进入模式,则此功能应返回true,如果不能,则返回false。

  • mode_rtl.cpp的initrun方法。
// rtl_init - initialise rtl controller
bool ModeRTL::init(bool ignore_checks)
{
    if (!ignore_checks) {
        if (!AP::ahrs().home_is_set()) {
            return false;
        }
    }
    // initialise waypoint and spline controller
    wp_nav->wp_and_spline_init(g.rtl_speed_cms);
    _state = SubMode::STARTING;
    _state_complete = true; // see run() method below
    terrain_following_allowed = !copter.failsafe.terrain;
    // reset flag indicating if pilot has applied roll or pitch inputs during landing
    copter.ap.land_repo_active = false;

    // this will be set true if prec land is later active
    copter.ap.prec_land_active = false;

#if AC_PRECLAND_ENABLED
    // initialise precland state machine
    copter.precland_statemachine.init();
#endif

    return true;
}
// rtl_run - runs the return-to-launch controller
// should be called at 100hz or more
void ModeRTL::run(bool disarm_on_land)
{
    if (!motors->armed()) {
        return;
    }

    // check if we need to move to next state
    if (_state_complete) {
        switch (_state) {
        case SubMode::STARTING:
            build_path();
            climb_start();
            break;
        case SubMode::INITIAL_CLIMB:
            return_start();
            break;
        case SubMode::RETURN_HOME:
            loiterathome_start();
            break;
        case SubMode::LOITER_AT_HOME:
            if (rtl_path.land || copter.failsafe.radio) {
                land_start();
            } else {
                descent_start();
            }
            break;
        case SubMode::FINAL_DESCENT:
            // do nothing
            break;
        case SubMode::LAND:
            // do nothing - rtl_land_run will take care of disarming motors
            break;
        }
    }

    // call the correct run function
    switch (_state) {

    case SubMode::STARTING:
        // should not be reached:
        _state = SubMode::INITIAL_CLIMB;
        FALLTHROUGH;

    case SubMode::INITIAL_CLIMB:
        climb_return_run();
        break;

    case SubMode::RETURN_HOME:
        climb_return_run();
        break;

    case SubMode::LOITER_AT_HOME:
        loiterathome_run();
        break;

    case SubMode::FINAL_DESCENT:
        descent_run();
        break;

    case SubMode::LAND:
        land_run(disarm_on_land);
        break;
    }
}

Step 4:添加类实例

通过搜索“ModeAcro”,然后在下面的某个地方添加新模式,在Copter.h中实例化新模式类。

#if MODE_ACRO_ENABLED == ENABLED
#if FRAME_CONFIG == HELI_FRAME
    ModeAcro_Heli mode_acro;
#else
    ModeAcro mode_acro;
#endif
#endif
    ModeAltHold mode_althold;
#if MODE_AUTO_ENABLED == ENABLED
    ModeAuto mode_auto;
#endif
#if AUTOTUNE_ENABLED == ENABLED
    ModeAutoTune mode_autotune;
#endif
#if MODE_BRAKE_ENABLED == ENABLED
    ModeBrake mode_brake;
#endif
#if MODE_CIRCLE_ENABLED == ENABLED
    ModeCircle mode_circle;
#endif
#if MODE_DRIFT_ENABLED == ENABLED
    ModeDrift mode_drift;
#endif
#if MODE_FLIP_ENABLED == ENABLED
    ModeFlip mode_flip;
#endif
#if MODE_FOLLOW_ENABLED == ENABLED
    ModeFollow mode_follow;
#endif
#if MODE_GUIDED_ENABLED == ENABLED
    ModeGuided mode_guided;
#endif
    ModeLand mode_land;
#if MODE_LOITER_ENABLED == ENABLED
    ModeLoiter mode_loiter;
#endif
#if MODE_POSHOLD_ENABLED == ENABLED
    ModePosHold mode_poshold;
#endif
#if MODE_RTL_ENABLED == ENABLED
    ModeRTL mode_rtl;
#endif

Step 5:添加模式映射

在mode.cpp中,将新模式添加到mode_from_mode_num()函数中,以创建模式编号和类实例之间的映射。

// return the static controller object corresponding to supplied mode
Mode *Copter::mode_from_mode_num(const Mode::Number mode)
{
    Mode *ret = nullptr;

    switch (mode) {
#if MODE_ACRO_ENABLED == ENABLED
        case Mode::Number::ACRO:
            ret = &mode_acro;
            break;
#endif

        case Mode::Number::STABILIZE:
            ret = &mode_stabilize;
            break;

        case Mode::Number::ALT_HOLD:
            ret = &mode_althold;
            break;

#if MODE_AUTO_ENABLED == ENABLED
        case Mode::Number::AUTO:
            ret = &mode_auto;
            break;
#endif

#if MODE_CIRCLE_ENABLED == ENABLED
        case Mode::Number::CIRCLE:
            ret = &mode_circle;
            break;
#endif

#if MODE_LOITER_ENABLED == ENABLED
        case Mode::Number::LOITER:
            ret = &mode_loiter;
            break;
#endif

#if MODE_GUIDED_ENABLED == ENABLED
        case Mode::Number::GUIDED:
            ret = &mode_guided;
            break;
#endif

        case Mode::Number::LAND:
            ret = &mode_land;
            break;

#if MODE_RTL_ENABLED == ENABLED
        case Mode::Number::RTL:
            ret = &mode_rtl;
            break;
#endif

#if MODE_DRIFT_ENABLED == ENABLED
        case Mode::Number::DRIFT:
            ret = &mode_drift;
            break;
#endif

Step 6:设置默认飞行模式

将新飞行模式添加到config.h中FLIGHT_MODE_1~FLIGHT_MODE_6,使用新模式的编号,如:RTL。

//
// FLIGHT_MODE
//

#ifndef FLIGHT_MODE_1
 # define FLIGHT_MODE_1                  Mode::Number::STABILIZE
#endif
#ifndef FLIGHT_MODE_2
 # define FLIGHT_MODE_2                  Mode::Number::STABILIZE
#endif
#ifndef FLIGHT_MODE_3
 # define FLIGHT_MODE_3                  Mode::Number::STABILIZE
#endif
#ifndef FLIGHT_MODE_4
 # define FLIGHT_MODE_4                  Mode::Number::STABILIZE
#endif
#ifndef FLIGHT_MODE_5
 # define FLIGHT_MODE_5                  Mode::Number::STABILIZE
#endif
#ifndef FLIGHT_MODE_6
 # define FLIGHT_MODE_6                  Mode::Number::RTL
#endif

Step 7:地面站配置参数修改

选择将飞行模式添加到mavlink/ardupilotmega.xml中的COPTER_mode枚举中,因为一些地面站可能会使用此枚举自动填充可用飞行模式列表。

    <enum name="COPTER_MODE">
      <description>A mapping of copter flight modes for custom_mode field of heartbeat.</description>
      <entry value="0" name="COPTER_MODE_STABILIZE"/>
      <entry value="1" name="COPTER_MODE_ACRO"/>
      <entry value="2" name="COPTER_MODE_ALT_HOLD"/>
      <entry value="3" name="COPTER_MODE_AUTO"/>
      <entry value="4" name="COPTER_MODE_GUIDED"/>
      <entry value="5" name="COPTER_MODE_LOITER"/>
      <entry value="6" name="COPTER_MODE_RTL"/>
      <entry value="7" name="COPTER_MODE_CIRCLE"/>
      <entry value="9" name="COPTER_MODE_LAND"/>
      <entry value="11" name="COPTER_MODE_DRIFT"/>
      <entry value="13" name="COPTER_MODE_SPORT"/>
      <entry value="14" name="COPTER_MODE_FLIP"/>
      <entry value="15" name="COPTER_MODE_AUTOTUNE"/>
      <entry value="16" name="COPTER_MODE_POSHOLD"/>
      <entry value="17" name="COPTER_MODE_BRAKE"/>
      <entry value="18" name="COPTER_MODE_THROW"/>
      <entry value="19" name="COPTER_MODE_AVOID_ADSB"/>
      <entry value="20" name="COPTER_MODE_GUIDED_NOGPS"/>
      <entry value="21" name="COPTER_MODE_SMART_RTL"/>
      <entry value="22" name="COPTER_MODE_FLOWHOLD"/>
      <entry value="23" name="COPTER_MODE_FOLLOW"/>
      <entry value="24" name="COPTER_MODE_ZIGZAG"/>
      <entry value="25" name="COPTER_MODE_SYSTEMID"/>
      <entry value="26" name="COPTER_MODE_AUTOROTATE"/>
      <entry value="27" name="COPTER_MODE_AUTO_RTL"/>
    </enum>

5. 总结

本章重点讨论了:

  1. 梳理了当前ArduPilot已经实现的飞行模式,给出了飞行模式之间的类继承关系。
  2. 通过飞行模式的设计,从类实现原理上给出了重要的框架实现接口。
  3. 从切换场景角度阐述了飞行模式复杂性,从而更好的解释了类继承关系的重要性。
  4. 最后,给出了新增自定义飞行模式的方法。

希望,能够通过初步的研读内容,能为后续新增自定义飞控飞行模式带来便捷性。

6. 参考资料

【1】ArduPilot开源飞控系统之简单介绍
【2】ArduPilot之开源代码Task介绍
【3】ArduPilot飞控启动&运行过程简介
【4】ArduPilot开源代码之AP_RCProtocol_CRSF
【5】无人机跟随一维高度避障场景–逻辑分析
【6】ArduPilot开源飞控之do_failsafe_action
【7】ArduPilot开源代码之RCInput

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/80561.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

水库大坝安全监测MCU,提升大坝管理效率的利器!

水库大坝作为防洪度汛的重要设施&#xff0c;承担着防洪抗旱&#xff0c;节流发电的重要作用。大坝的安全直接关系到水库的安全和人民群众的生命财产安全。但因为水库大坝的隐患不易被察觉&#xff0c;发现时往往为时已晚。因此&#xff0c;必须加强对大坝的安全管理。其安全监…

linux 系统中vi 编辑器和库的制作和使用

目录 1 vim 1.1 vim简单介绍 1.2 vim的三种模式 1.3 vim基本操作 1.3.1命令模式下的操作 1.3.2 切换到文本输入模式 1.3.3 末行模式下的操作 2 gcc编译器 2.1 gcc的工作流程 2.2 gcc常用参数 3 静态库和共享&#xff08;动态&#xff09;库 3.1库的介绍 3.2静态…

blender 发射体粒子

发射体粒子的基础设置 选择需要添加粒子的物体&#xff0c;点击右侧粒子属性&#xff0c;在属性面板中&#xff0c;点击加号&#xff0c;物体表面会出现很多小点点&#xff0c;点击空格键&#xff0c;粒子会自动运动&#xff0c;像下雨一样&#xff1b; bender 粒子系统分为两…

AI 绘画Stable Diffusion 研究(八)sd采样方法详解

大家好&#xff0c;我是风雨无阻。 本文适合人群&#xff1a; 希望了解stable Diffusion WebUI中提供的Sampler究竟有什么不同&#xff0c;想知道如何选用合适采样器以进一步提高出图质量的朋友。 想要进一步了解AI绘图基本原理的朋友。 对stable diffusion AI绘图感兴趣的朋…

2023国赛数学建模思路 - 案例:ID3-决策树分类算法

文章目录 0 赛题思路1 算法介绍2 FP树表示法3 构建FP树4 实现代码 建模资料 0 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 1 算法介绍 FP-Tree算法全称是FrequentPattern Tree算法&#xff0c;就是频繁模…

Mybatis的SqlSource SqlNode BoundSql

学习链接 MyBatis SqlSource解析 【Mybatis】Mybatis源码之SqlSource#getBoundSql获取预编译SQL Mybatis中SqlSource解析流程详解 Mybatis TypeHandler解析 图解 Mybatis的SqlSource&SqlNode - processon DynamicSqlSource public class DynamicSqlSource implement…

Java SpringBoot Vue ERP系统

系统介绍 该ERP系统基于SpringBoot框架和SaaS模式&#xff0c;支持多租户&#xff0c;专注进销存财务生产功能。主要模块有零售管理、采购管理、销售管理、仓库管理、财务管理、报表查询、系统管理等。支持预付款、收入支出、仓库调拨、组装拆卸、订单等特色功能。拥有商品库存…

WebGL和OpenGL之间的差异

推荐&#xff1a;使用 NSDT场景编辑器助你快速搭建可二次编辑的3D应用场景 WebGL和OpenGL是与图形处理有关的技术标准&#xff0c;它们在计算机图形中扮演着重要的角色。本文将介绍WebGL和OpenGL的区别&#xff0c;并重点介绍"WebGL"和"OpenGL"的特点。 一…

《算法竞赛·快冲300题》每日一题:“糖果配对”

《算法竞赛快冲300题》将于2024年出版&#xff0c;是《算法竞赛》的辅助练习册。 所有题目放在自建的OJ New Online Judge。 用C/C、Java、Python三种语言给出代码&#xff0c;以中低档题为主&#xff0c;适合入门、进阶。 文章目录 题目描述题解C代码Java代码Python代码 “ 糖…

docker的网络模式

docker0网络 docker容器的 虚拟网关loopback &#xff1a;回环网卡、TCP/IP网卡是否生效virtual bridge&#xff1a;linux 自身继承了一个虚拟化功能&#xff08;kvm架构&#xff09;&#xff0c;是原生架构的一个虚拟化平台&#xff0c;安装了一个虚拟化平台之后就会系统就会自…

excel入门

上下左右移动 enter:换行&#xff0c;向下移动 shiftenter:向上移动 tab:向右移动 shifttab:向左移动 合并居中操作 开始-》合并居中 CtrlM 内容过长盖过了下一个单元格内容 双击列与列之间线 同时修改多行或者多列宽度或者高度 修改单行高度宽度 选中某一行拉取指定高…

电脑提示msvcp140.dll丢失的解决方法,dll组件怎么处理

Windows系统有时在打开游戏或者软件时&#xff0c; 系统会弹窗提示缺少“msvcp140.dll.dll”文件 或者类似错误提示怎么办&#xff1f; 错误背景&#xff1a; msvcp140.dll是Microsoft Visual C Redistributable Package中的一个动态链接库文件&#xff0c;它在运行软件时提…

调整数组使奇数全部都位于偶数前面

题目内容&#xff1a; 输入一个整数数组&#xff0c;实现一个函数&#xff0c; 来调整该数组中数字的顺序使得数组中所有的奇数位于数组的前半部分&#xff0c; 所有偶数位于数组的后半部分。 题目思路&#xff1a; 将奇数部分放在前半部分&#xff0c;偶数部分放在后半部分&am…

【24择校指南】齐鲁工业大学计算机考研考情分析

齐鲁工业大学 考研难度&#xff08;☆&#xff09; 内容&#xff1a;23考情概况&#xff08;拟录取和复试分析&#xff09;、院校概况、23专业目录、23复试详情、各专业考情分析、各科目考情分析。 正文1140字&#xff0c;预计阅读&#xff1a;3分钟。 2023考情概况 齐鲁工…

VB6编程IEEE浮点算法实践

纯代码实现浮点计算实际上对浮点算法的再实践。IEEE浮点表示法是Modbus RTU协议至今还在用的传送编码&#xff0c;更是WITS 1记录标准的基础。以往实现 MKI、CVI&#xff0c;MKL、CVL&#xff0c;MKS、CVS&#xff0c;MKD、CVD在高级语言里封装了现成的语句&#xff0c;现在Pow…

SCF金融公链新加坡启动会 链结创新驱动未来

新加坡迎来一场引人瞩目的金融科技盛会&#xff0c;SCF金融公链启动会于2023年8月13日盛大举行。这一受瞩目的活动将为金融科技领域注入新的活力&#xff0c;并为广大投资者、合作伙伴以及关注区块链发展的人士提供一个难得的交流平台。 在SCF金融公链启动会上&#xff0c; Wil…

相机的位姿在地固坐标系ECEF和ENU坐标系的转换

在地球科学和导航领域&#xff0c;通常使用地心地固坐标系&#xff08;ECEF&#xff0c;Earth-Centered, Earth-Fixed&#xff09;和东北天坐标系&#xff08;ENU&#xff0c;East-North-Up&#xff09;来描述地球上的位置和姿态。如下图所示&#xff1a; ​地心地固坐标ecef和…

什么是B+树?

B树 B树是B树的一种变体&#xff0c;也属于平衡多路查找树&#xff0c;大体结构与B树相同&#xff0c;包含根节点、内部节点和叶子节点。多用于数据库和操作系统的文件系统中&#xff0c;由于B树内部节点不保存数据&#xff0c;所以能在内存中存放更多索引&#xff0c;增加缓存…

R语言实现免疫浸润分析(2)

原始数据承接免疫浸润分析&#xff08;1&#xff09;&#xff0c;下面展示免疫浸润结果&#xff1a; #直接使用IOBR包内的cell_bar_plot pic<-cell_bar_plot(input quantiseq_immo_de[1:20,], title "quanTiseq Cell Fraction") #使用ggplot2 library(ggplot2)…

NLP文本匹配任务Text Matching [有监督训练]:PointWise(单塔)、DSSM(双塔)、Sentence BERT(双塔)项目实践

NLP文本匹配任务Text Matching [有监督训练]&#xff1a;PointWise&#xff08;单塔&#xff09;、DSSM&#xff08;双塔&#xff09;、Sentence BERT&#xff08;双塔&#xff09;项目实践 0 背景介绍以及相关概念 本项目对3种常用的文本匹配的方法进行实现&#xff1a;Poin…
最新文章