Ardusub源码剖析(1)——AP_Arming_Sub
代码
AP_Arming_Sub.h
#pragma once#include <AP_Arming/AP_Arming.h>class AP_Arming_Sub : public AP_Arming {
public:AP_Arming_Sub() : AP_Arming() { }/* Do not allow copies */CLASS_NO_COPY(AP_Arming_Sub);bool rc_calibration_checks(bool display_failure) override;bool pre_arm_checks(bool display_failure) override;bool has_disarm_function() const;bool disarm(AP_Arming::Method method, bool do_disarm_checks=true) override;bool arm(AP_Arming::Method method, bool do_arming_checks=true) override;protected:bool ins_checks(bool display_failure) override;
};
AP_Arming_Sub.cpp
#include "AP_Arming_Sub.h"
#include "Sub.h"bool AP_Arming_Sub::rc_calibration_checks(bool display_failure)
{const RC_Channel *channels[] = {sub.channel_roll,sub.channel_pitch,sub.channel_throttle,sub.channel_yaw};return rc_checks_copter_sub(display_failure, channels);
}bool AP_Arming_Sub::has_disarm_function() const {bool has_shift_function = false;// make sure the craft has a disarm button assigned before it is armed// check all the standard btn functionsfor (uint8_t i = 0; i < 16; i++) {switch (sub.get_button(i)->function(false)) {case JSButton::k_shift :has_shift_function = true;break;case JSButton::k_arm_toggle :return true;case JSButton::k_disarm :return true;}}// check all the shift functions if there's shift assignedif (has_shift_function) {for (uint8_t i = 0; i < 16; i++) {switch (sub.get_button(i)->function(true)) {case JSButton::k_arm_toggle :case JSButton::k_disarm :return true;}}}return false;
}bool AP_Arming_Sub::pre_arm_checks(bool display_failure)
{if (armed) {return true;}// don't allow arming unless there is a disarm button configuredif (!has_disarm_function()) {check_failed(display_failure, "Must assign a disarm or arm_toggle button");return false;}return AP_Arming::pre_arm_checks(display_failure);
}bool AP_Arming_Sub::ins_checks(bool display_failure)
{// call parent class checksif (!AP_Arming::ins_checks(display_failure)) {return false;}// additional sub-specific checksif (check_enabled(ARMING_CHECK_INS)) {char failure_msg[50] = {};if (!AP::ahrs().pre_arm_check(false, failure_msg, sizeof(failure_msg))) {check_failed(ARMING_CHECK_INS, display_failure, "AHRS: %s", failure_msg);return false;}}return true;
}bool AP_Arming_Sub::arm(AP_Arming::Method method, bool do_arming_checks)
{static bool in_arm_motors = false;// exit immediately if already in this functionif (in_arm_motors) {return false;}in_arm_motors = true;if (!AP_Arming::arm(method, do_arming_checks)) {AP_Notify::events.arming_failed = true;in_arm_motors = false;return false;}#if HAL_LOGGING_ENABLED// let logger know that we're armed (it may open logs e.g.)AP::logger().set_vehicle_armed(true);
#endif// disable cpu failsafe because initialising everything takes a whilesub.mainloop_failsafe_disable();// notify that arming will occur (we do this early to give plenty of warning)AP_Notify::flags.armed = true;// call notify update a few times to ensure the message gets outfor (uint8_t i=0; i<=10; i++) {AP::notify().update();}#if CONFIG_HAL_BOARD == HAL_BOARD_SITLsend_arm_disarm_statustext("Arming motors");
#endifAP_AHRS &ahrs = AP::ahrs();sub.initial_armed_bearing = ahrs.yaw_sensor;if (!ahrs.home_is_set()) {// Reset EKF altitude if home hasn't been set yet (we use EKF altitude as substitute for alt above home)// Always use absolute altitude for ROV// ahrs.resetHeightDatum();// AP::logger().Write_Event(LogEvent::EKF_ALT_RESET);} else if (!ahrs.home_is_locked()) {// Reset home position if it has already been set before (but not locked)if (!sub.set_home_to_current_location(false)) {// ignore this failure}}hal.util->set_soft_armed(true);// enable output to motorssub.enable_motor_output();// finally actually arm the motorssub.motors.armed(true);#if HAL_LOGGING_ENABLED// log flight mode in case it was changed while vehicle was disarmedAP::logger().Write_Mode((uint8_t)sub.control_mode, sub.control_mode_reason);
#endif// reenable failsafesub.mainloop_failsafe_enable();// perf monitor ignores delay due to armingAP::scheduler().perf_info.ignore_this_loop();// flag exiting this functionin_arm_motors = false;// if we do not have an ekf origin then we can't use the WMM tablesif (!sub.ensure_ekf_origin()) {gcs().send_text(MAV_SEVERITY_WARNING, "Compass performance degraded");if (check_enabled(ARMING_CHECK_PARAMETERS)) {check_failed(ARMING_CHECK_PARAMETERS, true, "No world position, check ORIGIN_* parameters");return false;}}// return successreturn true;
}bool AP_Arming_Sub::disarm(const AP_Arming::Method method, bool do_disarm_checks)
{// return immediately if we are already disarmedif (!sub.motors.armed()) {return false;}if (!AP_Arming::disarm(method, do_disarm_checks)) {return false;}#if CONFIG_HAL_BOARD == HAL_BOARD_SITLsend_arm_disarm_statustext("Disarming motors");
#endifauto &ahrs = AP::ahrs();// save compass offsets learned by the EKF if enabledif (ahrs.use_compass() && AP::compass().get_learn_type() == Compass::LEARN_EKF) {for (uint8_t i=0; i<COMPASS_MAX_INSTANCES; i++) {Vector3f magOffsets;if (ahrs.getMagOffsets(i, magOffsets)) {AP::compass().set_and_save_offsets(i, magOffsets);}}}// send disarm command to motorssub.motors.armed(false);// reset the missionsub.mission.reset();#if HAL_LOGGING_ENABLEDAP::logger().set_vehicle_armed(false);
#endifhal.util->set_soft_armed(false);// clear input holdssub.clear_input_hold();return true;
}
解析
头文件
.h代码定义了一个名为 AP_Arming_Sub
的 C++ 类,它继承自 AP_Arming
类。此类提供了一个子类化 AP_Arming
的例子,其中添加了一些基类的方法。以下是详细解释:
#pragma once
#pragma once
是一个预处理器指令,用于防止文件被多次包含。当编译器看到这个指令时,它会确保该文件在一个编译过程中只被包含一次,即使它被多次#include
。
#include <AP_Arming/AP_Arming.h>
- 这行代码包含了
AP_Arming
类定义的头文件。AP_Arming
是一个库负责处理无人机启动和关闭相关的逻辑。
class AP_Arming_Sub : public AP_Arming {
- 这里定义了一个新的类
AP_Arming_Sub
,它继承自AP_Arming
类。public
关键字表示AP_Arming
是一个公共基类。
public:AP_Arming_Sub() : AP_Arming() { }
- 这部分定义了一个公共构造函数
AP_Arming_Sub
。构造函数使用成员初始化列表语法: AP_Arming()
来调用基类AP_Arming
的构造函数。
/* Do not allow copies */CLASS_NO_COPY(AP_Arming_Sub);
- 这一行是一个注释,说明了不希望这个类被复制。虽然
CLASS_NO_COPY
宏在这里没有被定义,但它通常用于在类定义中禁用复制构造函数和赋值操作符,以防止类的无意复制。
bool rc_calibration_checks(bool display_failure) override;bool pre_arm_checks(bool display_failure) override;bool has_disarm_function() const;
- 这些是
AP_Arming_Sub
类的公共成员函数声明。它们覆盖了基类AP_Arming
中的虚函数。override
关键字明确表示这些函数是覆盖基类的虚函数。rc_calibration_checks
:用于执行遥控器校准检查。pre_arm_checks
:用于执行武器启动前的检查。has_disarm_function
:用于检查是否解锁。
bool disarm(AP_Arming::Method method, bool do_disarm_checks=true) override;bool arm(AP_Arming::Method method, bool do_arming_checks=true) override;
- 这些函数覆盖了基类中的武器解除和武器启动功能,允许子类自定义这些行为。
Method
是一个属于AP_Arming
类的枚举类型,用于指定解除或启动武器的方法。
protected:bool ins_checks(bool display_failure) override;
- 这部分声明了一个受保护的成员函数
ins_checks
,它覆盖了基类中的虚函数。protected
关键字表示这个函数是供派生类和基类内部使用的,但不供外部访问。这个函数用于执行惯性导航系统(INS)检查。
源文件
#include "AP_Arming_Sub.h"
#include "Sub.h"
- 这两行包含了必要的头文件,以便编译器知道
AP_Arming_Sub
类和Sub
类(或结构体)的定义。 "AP_Arming_Sub.h"
是包含AP_Arming_Sub
类声明的头文件。"Sub.h"
包含一个名为Sub
的类或结构体的定义,这个Sub
类(以下称为“子类”)代表一个特定的无人机子系统的配置。
AP_Arming_Sub::rc_calibration_checks(bool display_failure)
bool AP_Arming_Sub::rc_calibration_checks(bool display_failure)
{
- 这里定义了
AP_Arming_Sub
类的rc_calibration_checks
成员函数。此函数接受一个布尔参数display_failure
,它指示是否应该显示校准失败的信息。
const RC_Channel *channels[] = {sub.channel_roll,sub.channel_pitch,sub.channel_throttle,sub.channel_yaw};
- 这里定义了一个
RC_Channel
类型的指针数组channels
,它包含指向四个不同通道的指针。这些通道通常代表多旋翼或无人机的遥控器控制通道:channel_roll
:横滚通道,控制无人机左右倾斜。channel_pitch
:俯仰通道,控制无人机前后倾斜。channel_throttle
:油门通道,控制无人机的升力。channel_yaw
:偏航通道,控制无人机的旋转方向。
sub
是一个Sub
类型的对象,它包含了这些通道的引用或指针。
return rc_checks_copter_sub(display_failure, channels);
}
- 这行代码调用了
rc_checks_copter_sub
函数(这个函数可能在当前文件或其他文件中定义),并将display_failure
和channels
数组作为参数传递。这个函数的目的是执行具体的遥控器校准检查,并返回一个布尔值,指示检查是否通过。 - 返回值会被传递回调用
rc_calibration_checks
的地方,指示校准检查是否成功。
AP_Arming_Sub::has_disarm_function() const
bool AP_Arming_Sub::has_disarm_function() const {
has_disarm_function
是AP_Arming_Sub
类的一个const
成员函数,这意味着它不会修改类的任何成员变量。const
关键字用在成员函数的声明和定义中,以确保函数调用不会改变对象的状态。
bool has_shift_function = false;
- 定义一个布尔变量
has_shift_function
,用于跟踪是否存在“shift”功能按钮。
// make sure the craft has a disarm button assigned before it is armed// check all the standard btn functionsfor (uint8_t i = 0; i < 16; i++) {switch (sub.get_button(i)->function(false)) {case JSButton::k_shift :has_shift_function = true;break;case JSButton::k_arm_toggle :return true;case JSButton::k_disarm :return true;}}
- 这段代码遍历前16个按钮(假设设备有16个按钮),检查每个按钮的标准功能(非“shift”功能)。
sub.get_button(i)
获取第i
个按钮对象的指针。function(false)
调用按钮对象的function
方法,传递false
表示不检查“shift”功能。- 如果按钮的功能是
JSButton::k_shift
,则设置has_shift_function
为true
。 - 如果按钮的功能是
JSButton::k_arm_toggle
或JSButton::k_disarm
,则直接返回true
,因为这表示存在解除武器功能。
// check all the shift functions if there's shift assignedif (has_shift_function) {for (uint8_t i = 0; i < 16; i++) {switch (sub.get_button(i)->function(true)) {case JSButton::k_arm_toggle :case JSButton::k_disarm :return true;}}}
- 如果检测到有
shift
功能按钮,则再次遍历所有按钮,这次检查它们的“shift”功能。 function(true)
这次传递true
来检查按钮的“shift”功能。- 如果任何一个按钮的“shift”功能是
JSButton::k_arm_toggle
或JSButton::k_disarm
,则返回true
。
return false;
}
- 如果遍历所有按钮后没有找到解除武器功能,则返回
false
。
AP_Arming_Sub::pre_arm_checks(bool display_failure)
bool AP_Arming_Sub::pre_arm_checks(bool display_failure)
bool
: 表示这个函数返回一个布尔类型的值,即true
或false
。AP_Arming_Sub::
: 指定pre_arm_checks
函数是AP_Arming_Sub
类的成员函数。pre_arm_checks
: 函数名,意味着执行预启动检查。(bool display_failure)
: 函数接收一个名为display_failure
的布尔型参数,这个参数用来决定是否显示检查失败的信息。
{if (armed) {return true;}
- 这段代码检查一个名为
armed
的变量(一个成员变量,表示系统是否已经启动)。 - 如果系统已经启动(
armed
为true
),则函数直接返回true
,不需要进行进一步的检查。
// don't allow arming unless there is a disarm button configuredif (!has_disarm_function()) {check_failed(display_failure, "Must assign a disarm or arm_toggle button");return false;}
- 这部分代码检查是否存在一个配置好的解锁按钮。
!has_disarm_function()
: 如果has_disarm_function()
函数返回false
(表示没有配置解锁按钮),则执行以下代码。check_failed(display_failure, "Must assign a disarm or arm_toggle button")
: 调用一个名为check_failed
的函数,它用来记录错误信息或显示错误消息。传递的字符串说明了错误的原因。return false;
: 如果没有配置解锁按钮,则返回false
,表示预检查失败。
return AP_Arming::pre_arm_checks(display_failure);
}
- 这行代码调用基类
AP_Arming
的pre_arm_checks
函数,继续执行进一步的预启动检查。 - 如果这个基类的预检查也返回
true
,则整个pre_arm_checks
函数返回true
,否则返回false
。
AP_Arming_Sub::ins_checks(bool display_failure)
bool AP_Arming_Sub::ins_checks(bool display_failure)
bool
: 表示这个函数返回一个布尔类型的值,即true
或false
。AP_Arming_Sub::
: 指定ins_checks
函数是AP_Arming_Sub
类的成员函数。ins_checks
: 函数名,意味着执行与INS相关的预启动检查。(bool display_failure)
: 函数接收一个名为display_failure
的布尔型参数,用来决定是否显示检查失败的信息。
{// call parent class checksif (!AP_Arming::ins_checks(display_failure)) {return false;}
- 这段代码调用基类
AP_Arming
的ins_checks
函数,执行与INS相关的通用预启动检查。 - 如果基类的检查返回
false
,表示检查失败,那么这个函数也立即返回false
。
// additional sub-specific checksif (check_enabled(ARMING_CHECK_INS)) {
- 这段代码检查是否启用了特定的检查项
ARMING_CHECK_INS
。check_enabled
根据传入的参数来确定是否执行后续的检查。
char failure_msg[50] = {};if (!AP::ahrs().pre_arm_check(false, failure_msg, sizeof(failure_msg))) {check_failed(ARMING_CHECK_INS, display_failure, "AHRS: %s", failure_msg);return false;}}
char failure_msg[50] = {};
: 定义一个字符数组failure_msg
,用来存储可能的错误信息,大小为50个字符。AP::ahrs().pre_arm_check(false, failure_msg, sizeof(failure_msg))
: 调用AP::ahrs()
对象的pre_arm_check
方法。AP::ahrs()
返回一个AHRS
(Attitude and Heading Reference System)类的实例。pre_arm_check
方法执行与AHRS相关的检查,如果检查失败,它将错误信息写入failure_msg
数组,并返回false
。- 如果
pre_arm_check
返回false
,则执行以下代码:check_failed(ARMING_CHECK_INS, display_failure, "AHRS: %s", failure_msg);
: 调用check_failed
函数,它用于记录错误信息或显示错误消息。它接收检查项标识符ARMING_CHECK_INS
,是否显示失败的标志display_failure
,以及格式化的错误信息字符串,其中%s
将被failure_msg
中的内容替换。return false;
: 如果检查失败,则返回false
。
return true;
}
- 如果所有的检查都通过,则函数返回
true
。
AP_Arming_Sub::arm(AP_Arming::Method method, bool do_arming_checks)
bool AP_Arming_Sub::arm(AP_Arming::Method method, bool do_arming_checks)
{static bool in_arm_motors = false;
- 声明一个静态布尔变量
in_arm_motors
,用于防止函数重入。
// exit immediately if already in this functionif (in_arm_motors) {return false;}
- 如果
in_arm_motors
为true
,表示函数已经在执行中,为了避免重入,直接返回false
。
in_arm_motors = true;
- 设置
in_arm_motors
为true
,表示当前正在执行启动过程。
if (!AP_Arming::arm(method, do_arming_checks)) {AP_Notify::events.arming_failed = true;in_arm_motors = false;return false;}
- 调用基类
AP_Arming
的arm
方法尝试启动。如果返回false
,表示启动失败,设置通知事件,重置in_arm_motors
,并返回false
。
#if HAL_LOGGING_ENABLED// let logger know that we're armed (it may open logs e.g.)AP::logger().set_vehicle_armed(true);
#endif
- 如果启用了日志记录功能,通知日志系统车辆已启动。
// disable cpu failsafe because initialising everything takes a whilesub.mainloop_failsafe_disable();
- 禁用主循环故障安全,因为在初始化过程中可能会有较长时间的延迟。
// notify that arming will occur (we do this early to give plenty of warning)AP_Notify::flags.armed = true;// call notify update a few times to ensure the message gets outfor (uint8_t i=0; i<=10; i++) {AP::notify().update();}
- 设置通知标志表明车辆将要启动,并通过多次调用更新函数确保通知消息被发送。
#if CONFIG_HAL_BOARD == HAL_BOARD_SITLsend_arm_disarm_statustext("Arming motors");
#endif
- 如果配置为SITL(软件在环仿真),发送状态文本消息表明正在启动电机。
AP_AHRS &ahrs = AP::ahrs();
- 获取AHRS(姿态和航向参考系统)实例的引用。
sub.initial_armed_bearing = ahrs.yaw_sensor;
- 设置初始启动时的航向。
if (!ahrs.home_is_set()) {// Reset EKF altitude if home hasn't been set yet (we use EKF altitude as substitute for alt above home)// Always use absolute altitude for ROV// ahrs.resetHeightDatum();// AP::logger().Write_Event(LogEvent::EKF_ALT_RESET);} else if (!ahrs.home_is_locked()) {// Reset home position if it has already been set before (but not locked)if (!sub.set_home_to_current_location(false)) {// ignore this failure}}
- 如果家位置未设置,则重置EKF高度;如果家位置未锁定,则重置为当前位置。
hal.util->set_soft_armed(true);
- 设置软启动标志,表明系统已启动。
// enable output to motorssub.enable_motor_output();
- 启用电机输出。
// finally actually arm the motorssub.motors.armed(true);
- 最终启动电机。
#if HAL_LOGGING_ENABLED// log flight mode in case it was changed while vehicle was disarmedAP::logger().Write_Mode((uint8_t)sub.control_mode, sub.control_mode_reason);
#endif
- 如果启用了日志记录,记录当前的飞行模式。
// reenable failsafesub.mainloop_failsafe_enable();
- 重新启用主循环故障安全。
// perf monitor ignores delay due to armingAP::scheduler().perf_info.ignore_this_loop();
- 通知性能监视器忽略由于启动导致的延迟。
// flag exiting this functionin_arm_motors = false;
- 标记退出此函数,将
in_arm_motors
重置为false
。
// if we do not have an ekf origin then we can't use the WMM tablesif (!sub.ensure_ekf_origin()) {gcs().send_text(MAV_SEVERITY_WARNING, "Compass performance degraded");if (check_enabled(ARMING_CHECK_PARAMETERS)) {check_failed(ARMING_CHECK_PARAMETERS, true, "No world position, check ORIGIN_* parameters");return false;}}
- 如果EKF原点未设置,则发送警告并检查是否启用了参数检查。如果启用了,则记录失败并返回
false
。
// return successreturn true;
}
- 如果所有步骤都成功完成,则返回
true
。
AP_Arming_Sub::disarm(const AP_Arming::Method method, bool do_disarm_checks)
bool AP_Arming_Sub::disarm(const AP_Arming::Method method, bool do_disarm_checks)
{
- 声明一个返回布尔值的函数
disarm
,它接收两个参数:解锁方法method
和一个布尔值do_disarm_checks
,后者指定是否执行解锁前的检查。
// return immediately if we are already disarmedif (!sub.motors.armed()) {return false;}
- 如果电机已经处于未启动状态(即已解锁),则立即返回
false
。
if (!AP_Arming::disarm(method, do_disarm_checks)) {return false;}
- 调用基类
AP_Arming
的disarm
方法尝试解锁。如果返回false
,表示解锁失败,因此直接返回false
。
#if CONFIG_HAL_BOARD == HAL_BOARD_SITLsend_arm_disarm_statustext("Disarming motors");
#endif
- 如果配置为SITL(软件在环仿真),发送状态文本消息表明正在解锁电机。
auto &ahrs = AP::ahrs();
- 获取AHRS(姿态和航向参考系统)实例的引用。
// save compass offsets learned by the EKF if enabledif (ahrs.use_compass() && AP::compass().get_learn_type() == Compass::LEARN_EKF) {for (uint8_t i=0; i<COMPASS_MAX_INSTANCES; i++) {Vector3f magOffsets;if (ahrs.getMagOffsets(i, magOffsets)) {AP::compass().set_and_save_offsets(i, magOffsets);}}}
- 如果启用了指南针,并且EKF学习了指南针偏移量,则保存这些偏移量。
// send disarm command to motorssub.motors.armed(false);
- 向电机发送解锁命令,将电机设置为未启动状态。
// reset the missionsub.mission.reset();
- 重置任务,可能是指飞行任务或一系列预定的动作。
#if HAL_LOGGING_ENABLEDAP::logger().set_vehicle_armed(false);
#endif
- 如果启用了日志记录功能,通知日志系统车辆已解锁。
hal.util->set_soft_armed(false);
- 更新软启动状态,表明系统已解锁。
// clear input holdssub.clear_input_hold();
- 清除输入保持状态,这可能是为了确保在解锁后不会有任何悬挂的输入命令影响系统。
return true;
}
- 如果解锁过程成功完成,则返回
true
。
相关文章:
Ardusub源码剖析(1)——AP_Arming_Sub
代码 AP_Arming_Sub.h #pragma once#include <AP_Arming/AP_Arming.h>class AP_Arming_Sub : public AP_Arming { public:AP_Arming_Sub() : AP_Arming() { }/* Do not allow copies */CLASS_NO_COPY(AP_Arming_Sub);bool rc_calibration_checks(bool display_failure)…...
【NLP 2、机器学习简介】
人生的苦难不过伏尔加河上的纤夫 —— 24.11.27 一、机器学习起源 机器学习的本质 —— 找规律 通过一定量的训练样本找到这些数据样本中所蕴含的规律 规律愈发复杂,机器学习就是在其中找到这些的规律,挖掘规律建立一个公式,导致对陌生的数…...
数据结构与算法——N叉树(自学笔记)
本文参考 N 叉树 - LeetBook - 力扣(LeetCode)全球极客挚爱的技术成长平台 遍历 前序遍历:A->B->C->E->F->D->G后序遍历:B->E->F->C->G->D->A层序遍历:A->B->C->D->…...
【趣味升级版】斗破苍穹修炼文字游戏HTML,CSS,JS
目录 图片展示 开始游戏 手动升级(满100%即可升级) 升级完成,即可解锁打怪模式 新增功能说明: 如何操作: 完整代码 实现一个简单的斗破苍穹修炼文字游戏,你可以使用HTML、CSS和JavaScript结合来构建…...
【Oracle】个人收集整理的Oracle常用SQL及命令
【建表】 create table emp( id number(12), name nvarchar2(20), primary key(id) ); 【充值一】 insert into emp select rownum,dbms_random.string(*,dbms_random.value(6,20)) from dual connect by level<101; 【充值二】 begin for i in 1..100 loop inser…...
Linux内核4.14版本——ccf时钟子系统(5)——通用API
1. clk_get 1.1 __of_clk_get_by_name 1.2 clk_get_sys 2. clk_prepare_enable 2.1 clk_prepare 2.2 clk_enable 3. clk_set_rate 1. clk_get clock get是通过clock名称获取struct clk指针的过程,由clk_get、devm_clk_get、clk_get_sys、of_clk_get、of_clk_g…...
安装MySQL 5.7 亲测有效
前言:本文是笔者在安装MySQL5.7时根据另一位博主大大的安装教程基础上做了一些修改而成 首先在这里表示对博主大大的感谢 下面附博主大大地址 下面的步骤言简意赅 跟着做就不会出错 希望各位读者耐下心来 慢慢解决安装中出现的问题~MySQL 5.7 安装教程(全…...
《Django 5 By Example》阅读笔记:p455-p492
《Django 5 By Example》学习第 16 天,p455-p492 总结,总计 38 页。 一、技术总结 1.myshop (1)打折功能 使用折扣码实现,但是折扣码是手动生成的,感觉实际业务中应该不是这样的。 (2)推荐功能 使用 Redis 做缓存࿰…...
Element-UI 官网的主题切换动画
文章目录 实现圆形扩散过渡动画 实现一下 Element-UI 官网的主题切换动画加粗样式 实现 首先我们起一个 html 文件,写一个按钮,以及简单的背景颜色切换,来模拟主题的切换 想要实现过渡效果,需要先用到一个 JavaScript 的原生方…...
Golang 构建学习
Golang 构建学习 如何搭建Golang开发环境 1. 下载GOlang包 https://golang.google.cn/dl/ 在地址上下载Golang 2. 配置包环境 修改全局环境变量,GOPROXY,GOPATH,GOROOT GOPROXYhttps://goproxy.cn,direct GOROOT"" // go二进…...
VM Virutal Box的Ubuntu虚拟机与windows宿主机之间设置共享文件夹(自动挂载,永久有效)
本文参考如下链接 How to access a shared folder in VirtualBox? - Ask Ubuntu (1)安装增强功能(Guest Additions) 首先,在网上下载VBoxGuestAdditions光盘映像文件 下载地址:Index of http://…...
分析 系统滴答时钟(tickClock),设置72MHz系统周期,如何实现1毫秒的系统时间?
一、CubeMX相关配置 1.1 相关引脚配置 1.2 相关时钟数配置 1.3 打开程序源码 二、相关函数分析...
C++优选算法十七 多源BFS
1.单源最短路问题 一个起点一个终点。 定义:在给定加权图中,选择一个顶点作为源点,计算该源点到图中所有其他顶点的最短路径长度。 2.多源最短路问题 定义:多源最短路问题指的是在图中存在多个起点,需要求出从这些…...
Mongodb入门到放弃
Mongodb分片概括 分片在多台服务器上分布数据的方法, Mongodb使用分片来支持具有非常大的数据集和高吞吐量的操作的部署 具有大数据集和高吞吐量应用程序的数据库系统,可以挑战单台服务器的容量。 例如,高查询率可以耗尽服务器的cpu容量&…...
青藤云安全携手财信证券,入选金融科技创新应用优秀案例
11月29日,由中国信息通信研究院主办的第四届“金信通”金融科技创新应用案例评选结果正式发布。财信证券与青藤云安全联合提交的“基于RASP技术的API及数据链路安全治理项目”以其卓越的创新性和先进性,成功入选金融科技创新应用优秀案例。 据悉&#x…...
在CentOS系统中安装工具包的时候报错的解决方法
我刚装了一个新的虚拟机,打算安装一些工具出现了错误信息 执行的命令如下: yum install -y yum-utils device-mapper-persistent-data lvm2错误信息如下 Cannot find a valid baseurl for repo: base/7/x86_64搜索了一下原因有好几种。 一是网络不通…...
cad软件打不开报错cad acbrandres dll加载失败
一切本来很顺利哒 但是,当我用快捷方式打开时,就出现了这个错误。进入文件路径,是有这个的; 在文件路径直接打开,也会提示错误 原因竟然是我改了个名字: 随便选的文件路径,空的,文件名为Acr…...
14、保存与加载PyTorch训练的模型和超参数
文章目录 1. state_dict2. 模型保存3. check_point4. 详细保存5. Docker6. 机器学习常用库 1. state_dict nn.Module 类是所有神经网络构建的基类,即自己构建一个深度神经网络也是需要继承自nn.Module类才行,并且nn.Module中的state_dict包含神经网络中…...
【前端开发】JS+Vuew3请求列表数据并分页
应用技术:原生JavaScript Vue3 $(function () {ini(); });function ini() {const { createApp, ref, onMounted } Vue;createApp({setup() {const data ref({studentList: [],page: 1,pageSize: 10,});const getStudentList async (page, key) > {window.ons…...
Trimble X12助力电力管廊数据采集,为机器人巡视系统提供精准导航支持
地下电缆是一个城市重要的基础设施,它不仅具有规模大、范围广、空间分布复杂等特点,更重要的是它还承担着信息传输、能源输送等与人们生活息息相关的重要功能,也是一个城市赖以生存和发展的物质基础。 01、项目概述 本次项目是对某区域2公里左…...
Docker 清理镜像策略详解
文章目录 前言一、删除 Docker 镜像1. 查看当前镜像2. 删除单个镜像3. 删除多个镜像4. 删除所有未使用的镜像5. 删除悬空的 Docker 镜像6. 根据模式删除镜像7. 删除所有镜像 二、删除 Docker 容器1. 查找容器2. 删除一个或多个特定容器3. 退出时删除容器4. 删除所有已退出的容器…...
【Linux】TCP网络编程
目录 V1_Echo_Server V2_Echo_Server多进程版本 V3_Echo_Server多线程版本 V3-1_多线程远程命令执行 V4_Echo_Server线程池版本 V1_Echo_Server TcpServer的上层调用如下,和UdpServer几乎一样: 而在InitServer中,大部分也和UDP那里一样&…...
排序学习整理(2)
上集回顾 排序学习整理(1)-CSDN博客 2.3 交换排序 交换排序的基本思想是:根据序列中两个记录键值的比较结果,交换这两个记录在序列中的位置。 特点: 通过比较和交换操作,将键值较大的记录逐步移动到序列…...
AI蛋白质设计与人工智能药物设计
AI蛋白质设计与人工智能药物设计 AI蛋白质设计 一、蛋白质相关的深度学习简介 1.基础概念 1.1.机器学习简介:从手写数字识别到大语言模型 1.2.蛋白质结构预测与设计回顾 1.3.Linux简介 1.4.代码环境:VS code和Jupyter notebook* 1.5.Python关键概…...
IOS ARKit进行图像识别
先讲一下基础控涧,资源的话可以留言,抽空我把它传到GitHub上,这里没写收积分,竟然充值才能下载,我下载也要充值,牛! ARSCNView 可以理解画布或者场景 1 配置 ARWorldTrackingConfiguration AR追…...
初级数据结构——二叉搜索树
目录 前言一、定义二、基本操作三、时间复杂度分析四、变体五、动态图解六、代码模版七、经典例题[1.——700. 二叉搜索树中的搜索](https://leetcode.cn/problems/search-in-a-binary-search-tree/)代码题解 [2.——938. 二叉搜索树的范围和](https://leetcode.cn/problems/ra…...
C++设计模式之组合模式中如何实现同一层部件的有序性
在组合模式中,为了实现同一层上部件的有序性,可以采取以下几种设计方法: 1. 使用有序集合 使用有序集合(如 std::list、std::vector 或其他有序容器)来存储和管理子部件。这种方法可以确保子部件按照特定顺序排列&am…...
duxapp RN 端使用AppUpgrade 进行版本更新
版本更新包含了组件和工具的组合 注册 下面这是 duxcms 入口文件检查更新的注册方法,注册的同时会检查更新 import {request,updateApp,userConfig } from ./utils// 检查app更新 setTimeout(async () > {if (process.env.TARO_ENV rn) {// eslint-disable-n…...
【计网】自定义序列化反序列化(三) —— 实现网络版计算器【下】
🌎实现网络版计算器【下】 本次序列化与反序列化所用到的代码,Tcp服务自定义序列化反序列化实现网络版计算器。 文章目录: 实实现网络版计算器【下】 客户端实现 基于守护进程的改写 🚀客户端实现 在这之前,…...
神经网络中的优化方法(一)
目录 摘要Abstract1. 与纯优化的区别1.1 经验风险最小化1.2 代理损失函数1.3 批量算法和小批量算法 2. 神经网络中优化的挑战2.1 病态2.2 局部极小值2.3 高原、鞍点和其他平坦区域2.4 悬崖和梯度爆炸2.5 长期依赖2.6 非精确梯度2.7 局部和全局结构间的弱对应 3. 基本算法3.1 随…...
网络规划设计师历年真题百度网盘/北京网站优化外包
“世界不能没有开源”,“开源正在杀死软件开发”,“开源不过是一些理想主义者的美梦”,“你开源我赞美,要我开源我不干”。关于开源,我们能聊的太多。而“中国化”的开源,却总是受到不少的质疑与诋毁。但在…...
成立公司注册资金可以随便写吗/百度seo新规则
内容出自极客时间专栏《Linux 性能优化实战》 CPU 的性能指标那么多,CPU 性能分析工具一抓一大把,换成实际的工作场景,该观察什么指标、选择哪个性能工具呢? 不要担心,今天我就以多年的性能优化经验,为你总…...
有域名了 怎么做网站/seo建设
如果你频繁的在你的系统中安装/卸载,那么不时的清理一下你的系统是十分必要的。 在Ubuntu终端中执行如下命令:sudo apt-get autoremove屏幕输出是这个样子的: Reading package lists… DoneBuilding dependency treeReading state informatio…...
wordpress做小程序/搜索引擎关键词排名优化
NEW关注Tech逆向思维视频号最新视频→【最骇人的5起自动驾驶“杀人”事故】出品|脑极体文|燕良最影响人类生命质量的疾病排在首位的就是癌症了。古人谈虎色变,今人谈癌色变。癌症这类疾病早已经不是年老体弱的人专属,而是越来越趋…...
dedecms做多语言的网站/seo网站推广软件 快排
在JAVA程序中,性能问题的大部分原因并不在于JAVA语言,而是程序本身。养成良好的编码习惯非常重要,能够显著地提升程序性能。 1 尽量在合适的场合使用单例 使用单例可以减轻加载的负担,缩短加载的时间,提高加载的效率&a…...
网站备案 论坛/百度云服务器官网
root-tools 项目地址:root-toolsRootToolsNeo 正式发布啦~ RootTools 是一款专注于给 root 后的用户提供方便的软件。主要提供: 应用冻结 不删除系统内的应用,而是将其冻结,在需要时可以解冻,但是别乱来哦,…...