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公里左…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄
文|魏琳华 编|王一粟 一场大会,聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中,汇集了学界、创业公司和大厂等三方的热门选手,关于多模态的集中讨论达到了前所未有的热度。其中,…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具
文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...
OkHttp 中实现断点续传 demo
在 OkHttp 中实现断点续传主要通过以下步骤完成,核心是利用 HTTP 协议的 Range 请求头指定下载范围: 实现原理 Range 请求头:向服务器请求文件的特定字节范围(如 Range: bytes1024-) 本地文件记录:保存已…...

HBuilderX安装(uni-app和小程序开发)
下载HBuilderX 访问官方网站:https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本: Windows版(推荐下载标准版) Windows系统安装步骤 运行安装程序: 双击下载的.exe安装文件 如果出现安全提示&…...
【决胜公务员考试】求职OMG——见面课测验1
2025最新版!!!6.8截至答题,大家注意呀! 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:( B ) A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...
Unit 1 深度强化学习简介
Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...
MySQL用户和授权
开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务: test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...

Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

云原生玩法三问:构建自定义开发环境
云原生玩法三问:构建自定义开发环境 引言 临时运维一个古董项目,无文档,无环境,无交接人,俗称三无。 运行设备的环境老,本地环境版本高,ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...
IP如何挑?2025年海外专线IP如何购买?
你花了时间和预算买了IP,结果IP质量不佳,项目效率低下不说,还可能带来莫名的网络问题,是不是太闹心了?尤其是在面对海外专线IP时,到底怎么才能买到适合自己的呢?所以,挑IP绝对是个技…...