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)…...
ESP32-S3模组上跑通ES8388(10)
接前一篇文章:ESP32-S3模组上跑通ES8388(9) 二、利用ESP-ADF操作ES8388 2. 详细解析 上一回解析了es8388_init函数中的第3段代码(也是实际与ES8388寄存器打交道的第1段代码),本回继续往下解析。为了便于理…...
AI/ML 基础知识与常用术语全解析
目录 一.引言 二.AI/ML 基础知识 1.人工智能(Artificial Intelligence,AI) (1).定义 (2).发展历程 (3).应用领域 2.机器学习(Machine Learning,ML) (1).定义 (2).学习方式 ①.监督学习 ②.无监督…...
【C#设计模式(15)——命令模式(Command Pattern)】
前言 命令模式的关键通过将请求封装成一个对象,使命令的发送者和接收者解耦。这种方式能更方便地添加新的命令,如执行命令的排队、延迟、撤销和重做等操作。 代码 #region 基础的命令模式 //命令(抽象类) public abstract class …...
Could not resolve com.android.tools.build:gradle:7.4.2.
Android Studio编译项目报错如下,始终无法下载解析7.4.2的gradle classpath A problem occurred configuring root project aistudyclient_questionlib. > Could not resolve all files for configuration :classpath.> Could not resolve com.android.tools…...
uniapp在App端定义全局弹窗,当打开关闭弹窗会触发onShow、onHide生命周期怎么解决?
在uniapp(App端)中实现自定义弹框,可以通过创建一个透明页面来实现。点击进入当前页面时,页面背景会变透明,用户可以根据自己的需求进行自定义,最终效果类似于弹框。 遇到问题:当打开弹窗(进入弹窗页面)就会触发当前页…...
2024 ccpc 辽宁省赛 E(构造 思维?)L(二分+一点点数论知识?)
E 题意: 可以注意到: 我的两种方格都四个方格的大小。 所以 如果存在一种摆放方式 那么 4|nm。 再考虑一种特殊的情况 22 ,此时虽然我的积是4 但是无法摆放的。 1>对于 4 | n,或者 4 | m.我直接摆放第二种方格就可以了。 如果我n 是4 的…...
IIC 随机写+多次写 可以控制写几次
verilog module icc_tx#(parameter SIZE 2 , //用来控制写多少次 比如地址是0000 一个地址只能存放8bit数据 超出指针就会到下一个地址0001parameter CLK_DIV 50_000_000 ,parameter SPEED 100_000 ,parameter LED 50 )( input wire c…...
基于SpringBoot+Vue的汽车票网上预订系统-无偿分享 (附源码+LW+调试)
目录 1. 项目技术 2. 功能菜单 3. 部分功能截图 4. 研究背景 5. 研究目的 6. 可行性分析 6.1 技术可行性 6.2 经济可行性 6.3 操作可行性 7. 系统设计 7.1 概述 7.2 系统流程和逻辑 7.3 系统结构 8. 数据库设计 8.1 数据库ER图 (1)公告信…...
net9 abp vnext 多语言通过数据库动态管理
通过数据库加载实现动态管理,用户可以自己修改界面显示的文本,满足国际化需求 如图所示,前端使用tdesign vnext 新建表TSYS_Localization与TSYS_LocalizationDetail 国旗图标下载网址flag-icons: Free Country Flags in SVG 在Shared下创建下图3个文件 …...
pip安装github上的开源软件包
1、若本机中安装的有git,可使用githttps方式安装 # 以安装pyfolio软件包为例,安装指令如下 pip install githttps://github.com/quantopian/pyfolio.git 2、若本机中没有安装git,可以直接使用软件包的zip地址进行安装 # 以安装pyfolio软件包为例,安装…...
【LeetCode刷题之路】120:三角形最小路径和的两种解法(动态规划优化)
LeetCode刷题记录 🌐 我的博客主页:iiiiiankor🎯 如果你觉得我的内容对你有帮助,不妨点个赞👍、留个评论✍,或者收藏⭐,让我们一起进步!📝 专栏系列:LeetCode…...
架构04-透明多级分流系统
零、文章目录 架构04-透明多级分流系统 1、透明多级分流系统 (1)概述 **定义:**透明多级分流系统是指在用户请求从客户端发出到最终查询或修改数据库信息的过程中,通过多个技术部件对流量进行合理分配,以提高系统的…...
云原生后端开发:构建现代化可扩展的服务
随着微服务架构的普及和容器化技术的成熟,云原生后端开发成为了构建现代化、可扩展系统的关键。本文将从云原生理念出发,结合实际案例,探讨如何使用 Kubernetes、服务网格、微服务架构等技术构建高效的云原生后端。 一、云原生的核心理念 1.…...
在Windows和Linux系统上获取网卡MAC地址及相关信息所有常用方法整理
摘要 在网络管理和故障排除中,了解如何获取网卡的MAC地址、IP地址以及网卡名称是系统管理员必备的技能。本文将介绍在Windows和Linux系统上手动获取网卡MAC地址的方法,并提供脚本以自动化获取服务器中网卡信息的过程。这些技巧和工具将帮助新手系统管理…...
制作苹果IOS.APP所使用步骤和方法-有步骤视情况待完善
1.获取开发工具 首先,您需要下载并安装Xcode。Xcode是苹果开发iOS和macOS应用程序的官方集成开发环境(IDE)。它包含了必要的工具,例如代码编辑器、调试器、编译器和界面构建器。Xcode可在Mac App Store中免费下载。 2.学习Swift或…...
【conda】全面解析 Conda 配置文件:从完整示例到最佳实践
目录 引言一、Conda 配置文件示例1.1 中英文注释示例1.2 文件编码格式 二、详细解释2.1 ssl_verify: true2.2 channels2.3 envs_dirs2.4 pkgs_dirs2.5 custom_channels2.6 remote_read_timeout_secs 和 remote_connect_timeout_secs2.7 show_channel_urls2.8 default_packages2…...
ffmpeg命令详解
原文网址:ffmpeg命令详解_IT利刃出鞘的博客-CSDN博客 简介 本文介绍ffmpeg命令的用法。 命令示例 1.mp4和avi的基本互转 ffmpeg -i D:\input.mp4 E:\output.avi ffmpeg -i D:\input.avi E:\output.mp4 -i 表示input,即输入。后面填一个输入地址和一…...
asyncio.run() 里面嵌套 asyncio.run() 可以吗?
[TOC](asyncio.run() 里面嵌套 asyncio.run() 可以吗?) 在 Python 的异步编程中,asyncio 是一个非常重要的模块,它提供了编写单线程并发代码的基础设施。asyncio.run() 是一个方便的函数,用于运行一个协程并管理事件循环的生命周…...
flutter in_app_purchase google支付 PG-GEMF-01错误
问题:PG-GEMF-01错误 flutter 使用in_app_purchase插件升降级订阅时报错PG-GEMF-01。 解决方案: 升降级订阅时,确保不调用 MethodCallHandlerImpl.java文件中的 setObfuscatedAccountId()方法、setObfuscatedProfileId()方法 原因…...
Flink 离线计算
文章目录 一、样例一:读 csv 文件生成 csv 文件二、样例二:读 starrocks 写 starrocks三、样例三:DataSet、Table Sql 处理后写入 StarRocks四、遇到的坑 <dependency><groupId>org.apache.flink</groupId><artifactId&…...
排序算法之插入排序篇
插入排序 思路: 就是将没有排序的元素逐步地插入到已经排好序的元素后面,保持元素的有序 视频的实现过程如下: 插入排序全过程 代码实现过程如下: public static void Insertion(int[] arr) { for (int i 1; i < arr.length…...
(11)(2.2) BLHeli32 and BLHeli_S ESCs(二)
文章目录 前言 1 传递支持 前言 BLHeli 固件和配置应用程序的开发是为了允许配置 ESC 并提供额外功能。带有此固件的 ESC 允许配置定时、电机方向、LED、电机驱动频率等。在尝试使用 BLHeli 之前,请按照 DShot 设置说明进行操作(DShot setup instructions)。 1 传…...
Unity之一键创建自定义Package包
内容将会持续更新,有错误的地方欢迎指正,谢谢! Unity之一键创建自定义Package包 TechX 坚持将创新的科技带给世界! 拥有更好的学习体验 —— 不断努力,不断进步,不断探索 TechX —— 心探索、心进取! …...
【AI】JetsonNano启动时报错:soctherm OC ALARM
1、问题描述 将JetsonNano烧写SD卡镜像为Ubuntu20.04后,启动时报错:soctherm OC ALARM,启动失败;然后系统一直重启 2、原因分析 “soctherm OC ALARM”是检测到系统温度超过安全阈值时发出的过热警告。 “soctherm”代表系统…...
道路机器人识别交通灯,马路,左右转,黄线,人行道,机器人等路面导航标志识别-使用YOLO标记
数据集分割 train组66% 268图片 validation集22% 91图片 test集12% 48图片 预处理 没有采用任何预处理步骤。 增强 未应用任何增强。 数据集图片: 交通灯 马路 右转 向右掉头 机器人识别 人行横道 黄线 直行或右转 数据集下载: 道路…...
电子应用设计方案-31:智能AI音响系统方案设计
智能 AI 音响系统方案设计 一、引言 智能 AI 音响作为一种新兴的智能家居设备,通过融合语音识别、自然语言处理、音频播放等技术,为用户提供便捷的语音交互服务和高品质的音乐体验。本方案旨在设计一款功能强大、性能稳定、用户体验良好的智能 AI 音响系…...
SQL优化与性能——数据库设计优化
数据库设计优化是提高数据库性能、确保数据一致性和支持业务增长的关键环节。无论是大型企业应用还是小型项目,合理的数据库设计都能够显著提升系统性能、减少冗余数据、优化查询响应时间,并降低维护成本。本章将深入探讨数据库设计中的几个关键技术要点…...
脑网络组织与心跳动力学之间的耦合测量
摘要 近年来,人们对脑心相互作用的研究兴趣日益浓厚。许多研究提出了新的方法来探究大脑与心脏如何通信,从而对一些神经功能有了新的认识。然而,大多数框架只关注单个脑区域与心跳动态之间的相互作用,忽略了大脑的功能网络会随着…...
图像显示的是矩阵的行和列,修改为坐标范围。
x 3; y 3; f1x x^2 y^2; guance1 f1x; F (x, y) sqrt((x.^2 y.^2 - guance1).^2); % 使用点乘 [x, y] meshgrid(0:1:5, 0:1:5); Z F(x, y); figure; imagesc(Z); % 由于 imagesc 使用矩阵索引作为坐标,我们需要手动添加刻度 % 这里我们假设 x 和 y 的范围…...
一体化数据安全平台uDSP 入选【年度创新安全产品 TOP10】榜单
近日,由 FreeBuf 主办的 FCIS 2024 网络安全创新大会在上海隆重举行。大会现场揭晓了第十届 WitAwards 中国网络安全行业年度评选获奖名单,该评选自 2015 年举办以来一直饱受赞誉,备受关注,评选旨在以最专业的角度和最公正的态度&…...
[免费]SpringBoot+Vue景区订票(购票)系统【论文+源码+SQL脚本】
大家好,我是java1234_小锋老师,看到一个不错的SpringBootVue大景区订票(购票)系统,分享下哈。 项目视频演示 【免费】SpringBootVue景区订票(购票)系统 Java毕业设计_哔哩哔哩_bilibili 项目介绍 现代经济快节奏发展以及不断完善升级的信息…...
力扣215:数组中第K大的元素
给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。 请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。 你必须设计并实现时间复杂度为 O(n) 的算法解决此问题。 示例 1: 输入: [3,2,1,5,6,4],k 2 …...
永久停用PostgreSQL 归档功能
文章目录 引言永久停用归档功能归档的优势归档的劣势开启归档的情况关闭归档的情况see also引言 PostgreSQL 是一个开源的关系型数据库系统,支持数据归档(WAL),可以实现数据备份、恢复和灾难恢复等功能。在使用 PostgreSQL 的过程中,如果 PostgreSQL 数据库开启了归档(a…...
23种设计模式-原型(Prototype)设计模式
文章目录 一.什么是原型设计模式?二.原型模式的特点三.原型模式的结构四.原型模式的优缺点五.原型模式的 C 实现六.原型模式的 Java 实现七. 代码解析八.总结 类图: 原型设计模式类图 一.什么是原型设计模式? 原型模式(Prototype…...
【Linux】-学习笔记06
第二章、时间同步服务器 2.1时间同步服务器的使用 2.1.1系统时区时间的管理 timedatectl set-time "2024-02-13 10:41:55" ##设定系统时间 timedatectl list-timezones ##显示系统的所有时区 timedatectl set-timezone "Asia/Shangh…...
李永平:以科技创新为引擎,驱动中国国际未来产业研究院不断前行
作者:李望 在科技创新与产业升级的滚滚洪流中,唯有洞察未来者,方能引领时代浪潮。近日,中国国际未来产业研究院迎来了重量级嘉宾——李永平院士。他的加盟,为研究院注入了全新的活力。作为业界的领军人物,李永平院士将担任研究院常务副院长、资深专家及高级法律顾问,共同规划未…...
netconf 代码架构
NETCONF(Network Configuration Protocol)是一种基于 XML 的网络配置管理协议,主要用于在网络设备之间进行配置管理、状态监控和操作。它被设计为一种可扩展的协议,并且在自动化网络管理中扮演着重要角色。NETCONF 通过安全的通信…...
【查询目录】.NET开源 ORM 框架 SqlSugar 系列
.NET开源 ORM 框架 SqlSugar 系列 【开篇】.NET开源 ORM 框架 SqlSugar 系列【入门必看】.NET开源 ORM 框架 SqlSugar 系列【实体配置】.NET开源 ORM 框架 SqlSugar 系列【Db First】.NET开源 ORM 框架 SqlSugar 系列【Code First】.NET开源 ORM 框架 SqlSugar 系列【数据事务…...
广域网技术
企业需要通过广域网将这些分散在不同地理位置的分支机构连接起来 早期广域网技术概述 广域网:连接不同地区局域网的网络,能够横跨几个洲提供远距离通信,形成国际性的远程网络 广域网设备角色介绍: CE:用户端连接服务…...
基于Java Springboot 求职招聘平台
一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术:Html、Css、Js、Vue2、Element-ui 数据库:MySQL 后端技术:Java、Spring Boot、MyBatis 三、运行环境 开发工具:IDEA 数据库&…...
C学习:移位幻影之左移一个负数,会发生什么?
C学习:移位幻影之左移一个负数,会发生什么? 问题背景无符号数移位问题有符号数移位操作使低位置零问题 问题背景 C语言中,移位是个简单的问题,但又是个高风险的问题。 简单在于,大部分场景都可以理解为乘或…...
[2024年3月10日]第15届蓝桥杯青少组stema选拔赛C++中高级(第二子卷、编程题(2))
方法一(string): #include <iostream> #include <string> using namespace std;// 检查是否为回文数 bool isPalindrome(int n) {string str to_string(n);int left 0, right str.size() - 1;while (left < right) {if (s…...
加载语言包的方式
推荐方式:使用 JSON 或 XML 文件结合解析库 JSON: 优点:轻量级,结构清晰,解析库(如 nlohmann/json)易用。示例内容: json 复制代码 { "en": { "greeting": &qu…...
深入了解 Adam 优化器对显存的需求:以 LLaMA-2 7B 模型为例 (中英双语)
中文版 深入了解 Adam 优化器对显存的额外需求:模型参数与优化器状态的显存开销分析 在深度学习模型的训练过程中,显存是一个关键的资源,尤其在处理大型语言模型或深度神经网络时。训练时的显存需求不仅包括模型参数本身,还涉及…...
深入理解CSS语法:掌握Web开发的基石
深入理解CSS语法:掌握Web开发的基石 在构建现代网页的过程中,层叠样式表(CSS)扮演着至关重要的角色。它不仅负责定义HTML元素的视觉表现,还极大地增强了Web内容的可访问性和用户体验。本文将深入探讨CSS的语法、书写位…...
基于python爬虫的智慧人才数据分析系统
废话不多说,先看效果图 更多效果图可私信我获取 源码分享 import os import sysdef main():"""Run administrative tasks."""os.environ.setdefault(DJANGO_SETTINGS_MODULE, 智慧人才数据分析系统.settings)try:from django.core.m…...
创建maven私人创库nexus
1.到官网下载nexus-3.74.0-05-unix.tar.gz包,若下载慢可以去这里下载地址 2.上传到liunx的根目录opt文件中,然后解压命令: tar -xzf nexus-3.74.0-05-unix.tar.gz 3.解压后会得到两个文件夹nexus-3.74.0-05 和 sonatype-work ,…...
眼部按摩仪WT2605音频蓝牙语音芯片方案 单芯片实现语音提示及控制/手机无线音频传输功能
随着科技的快速发展,人们的生活方式也在不断改变,智能化、便捷化的产品逐渐成为市场的主流。眼部按摩仪作为一种结合了现代科技与健康生活理念的产品,受到了广大消费者的青睐。而在众多眼部按摩仪中,采用WT2605音频蓝牙芯片的方案…...
【面试题】2025年百度校招Java后端面试题
文章目录 前言一、网络IO1、服务器处理并发请求有哪几种方式?2、说一下select,poll,epoll的区别?3、Java 有一种现代的处理方式,属于异步I/O,是什么?redis,nginx,netty 是…...