当前位置: 首页 > news >正文

PH47代码框架软件二次开发极简教程

 1. 教程说明

本教程适用于对飞控及Stm32程序设计比较熟悉的二次开发者快速掌握PH47框架的使用要点。本教程仅对PH47框架中最主要的二次开发特性进行简要说明,建议与框架中\DevStudio\Algorithms\Controller_Demo.cpp(.h)示例代码配合学习。关于二次开发特性中的详细或高级内容,请参见《PH47框架二次开发教程》。

对于飞控或是Stm32编程不是太熟练的开发者,建议先了解学习Stm32程序设计相关内容,以及《PH47框架二次开发教程》。

1.1 基本概念

  • 时间相关、循环控制、调试功能大部分基本功能由框架层全局函数实现。
  • 整个PH47框架内,数据读取、写入、交换等操作均依托框架层的数据总线系统(frm.bus),以frm.bus.Function()方式使用。
  • 机载调参参数(控制参数)的读取、写入存储均通过框架层的参数系统core.para实现,以core.para.Function()方式使用。
  • 用户代码一般位于应用层Application当中实现。应用层为用户提供了初始化、快速循环,普通循环、慢速循环函数,以及GCS上行指令响应函数、控制台指令响应函数等重要函数框架供用户扩充使用。

2. 基本全局功能函数使用

2.1 常用全局时间函数

函  数

功 能 描 述

HAL_Delay()

用于ms 级延时,执行时独占系统资源

osDelay()

用于ms 级延时。osDelay() 依赖于 FreeRTOS 启动完成,延时期间可以将系统资源轮换给其他线程使用

gDelay_us()

用于 us 级别延时。延时时间不要超过 1000us

gGetMills()

获取调用时刻距离 mcu 加电启动时刻的ms时间间隔, 获取数据范围为 4294967296ms,即1193 hour

gGetMills_f()

获取精确到小数点后3位的ms时间, 即精确到us。

gGetMills_f()在运行时间超过4800s后会溢出重置为 0 后重新开始计时

gGetMicros() 

获取mcu加电以来的us时间。

注意: us计时器溢出时间为600s

2.2 调试功能使用

函  数

功 能 描 述

TRACE()

使用邮件队列方式显示格式化字符串。

具有线程安全性,且连续调用能够确保顺序正确。依赖于 PH47 框架的启动完成, 框架启动前不能正常工作。显示时刻会晚于函数调用时刻(滞后不高于 10ms 级别)   。

TRACE("\r\ndemo> 1. TRACE at %.3fms", gGetMills_f());   

gPrintf()

使用中断方式显示格式化字符串。

不依赖于框架的启动完成。连续密集调用时显示的先后顺序可能会发生改变

gPrintf("\r\ndemo> 2. gPrintf at %.3fms", gGetMills_f());  

ASSERT(f)

表达式f真值确认。

若表示式f为false,则核心板状态指示LED连续快速闪烁,当前线程执行停止在ASSERT()语句处,同时在调试串口输出ASSERT语句所在的文件名及代码行号。

bus.arDbg_1[10]

bus.arDbg_2[10]

调试专用总线数据项。只需将调试数据赋值给总线数据项即可。

PH47框架已经预置了调试数据的下行发送机制,用户无需自己实现。

调试数据默认下行发送频率为25hz,运行过程中可调整。

3 使用CFreqDiv类进行循环频率控制

  • 1/3: 在.h文件中定义一个CFreqDiv类对象_FreqDemo_1Hz
CFreqDiv _FreqDemo_1Hz;
  • 2/3: 适当位置对_FreqDemo_1Hz对象进行初始化,如在.cpp文件初始化函数中,设定循环间隔。
_FreqDemo_1Hz.SetRunInv_ms(1000);  // 循环控制间隔为 1000ms, 即 1Hz
  • 3/3: 在需要进行循环频率控制的位置通过IsSetRunInv_ms()函数判断是否达到循环控制条件。此处注意:_FreqDemo_1Hz对象的IsSetRunInv_ms()函数调用在同一循环中只能在一个位置出现一次,不能在多个不同位置多次调用。
if(_FreqDemo_1Hz.IsSetRunInv_ms())
{// do something…
}

4. 数据总线基本操作

数据总线系统为整个PH47代码框架提供了设置、获取、交换数据的方法和途径。以及获取诸如设置获取数据时间戳,数据设置时间间隔,数据权限控制等功能。

数据总线系统由一系列总线数据项(Bus item)构成,总线数据项既可以是包含了一个数据简单类型(如 uint8_t,int32,float等)的数据项,也可以是多个具有相关性的数据构成的复杂类型数据项,如结构变量。

4.1 数据总线系统文件包含

用户要在自己的代码文件中使用数据总线功能,只需在自己的.cpp文件开始出加入如下文件包含:

#include"../../Frame/UseGlobalObject.h"   //文件包含路径根据实际情况确定

数据总线中数据项的声明位于如下文件中:

\DevStudio\BoardConfig\Board_BBDB\DataBus_BBDB.h

数据总线中复杂类型数据项(框架内置)的结构声明位于如下文件中:

\DevStudio\Frame\Core\BusItemFormatDef.h

4.2 数据总线功能函数使用

函  数

功 能 描 述

Get()

读取数据总线数值

Vector3f vAcc = bus.sImu.AccRaw.Get();  // 获取总线数据项数值

TRACE("\r\n> Acc %.2f %.2f %.2f", vAcc.x, vAcc.y, vAcc.z);

Set()

设置数据总线数值。

本函数在设置总线数值的同时,对当前总线数据的时间戳进行了设置。

// demo 1

bus.arDbg_2[0].Set(2.234);

// demo 2

MICOLINK_PAYLOAD_RANGE_SENSOR_t payload;

payload.distance = 10.5f;

payload.strength = 1.0f;

bus.OptiFlowTof_MTF01.Set(&payload)// 设置总线数据项数值

GetTimeStamp_ms()

获取 AccRaw 以 ms 为单位时间戳的整数部分,示例见下。

GetTmStampDec_us()

获取 AccRaw 以 ms 为单位时间戳的 3 位小数部分(即精确到 us),示例见下。

GetDt2Prev_us()

获取总线数据项最近两次被设置(Set)之间的时间间隔(us)

// 上述三个函数综合示例

TRACE("\r\n> AccRaw timeTag:%d.%dms dt:%dus",

bus.sImu.AccRaw.GetTimeStamp_ms(),  // 时间戳整数部分(ms)

bus.sImu.AccRaw.GetTmStampDec_us(), // 时间戳小数部分(us)

bus.sImu.AccRaw.GetDt2Prev_us());   // 最近两次设置时间间隔(us)

4.3 全局变量

全局变量变量是一种特殊的总线数据,用于在整个PH47代码框架内表示系统状态,分为bool型和uint8_t型两种类型。整个框架共有48个bool型,8个uint8_t类型全局变量。

PH47代码框架以及CSS插件已经预置了全局变量的发送及解析机制,以5Hz频率下行发送更新。用户在PH47框架中只需对其进行设置或读取即可。

函  数

功 能 描 述

gGetStatus()

GetStatus()

读取全局变量数值。

gGetStatus()等同于GetStatus(),只是前者为全局函数形式,后者需要通过core对象进行引用。

gGetStatus(S_IMU_STILL);    // bool 类型

core.GetStatus(S_RC_ALIVE);

uint8_t uTmp = gGetStatus(S_SYSTEM_STATUS_TAG);   // uint8_t 类型

gSetStatus()

SetStatus()

设置全局状态变量。

参数blForceUpdate为true表示无论当前全局状态变量数值如何都进行设置。

false表示若待设置数值与当前数值相同就不进行设置

gSetStatus(S_WATCH_DOG_MODE, true, true);

4.4 自定义简单类型总线数据项

\DevStudio\BoardConfig\Board_BBDB\DataBus_BBDB.h文件中注释为"用户自定义设置区域"内加入自有总线数据的定义(注意!不要对该区域以外的总线数据声明进行任何修改或删除!):

// <=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>
// 用户自定义参数设置区域, 不得对该区域之外的任何内容进行修改
CBusItem<float> fAspdDiffPress;    // float类型的bus item
// <=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>

之后就可以使用总线相关函数实现各种功能了

4.5 自定义复杂类型总线数据项目

  • 1/3:在需要使用总线的.cpp文件头部加入对数据总线的文件包含:
#include"../../Frame/UseGlobalObject.h"
  • 2/3:在如下文件中加入对复杂类型的结构声明(用户自定义):

\DevStudio\BoardConfig\Board_BBDB\BusItemDef4User.h

struct BUS_ITEM_DEMO
{CBusItem<uint8_t>    Item_A;CBusItem<float>      Item_B;
};
  • 3/3:在\DevStudio\BoardConfig\Board_BBDB\DataBus_BBDB.h文件的“用户自定义参数设置区域”加入总线数据的定义:
// <=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>
// 用户自定义参数设置区域, 不得对该区域之外的任何内容进行修改
BUS_ITEM_DEMO sBusItemDemo;
// <=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>

4.6 自定义全局状态变量

文件DevStudio\BoardConfig\Board_BBP\StateVarDef_BBP.h对全局状态变量的ID进行了定义,此文件中的enum STATUS_BOOLenumSTATUS_UINT枚举分别定义了bool及uint8_t类型的全局状态变量ID。

与自定义总线数据类似,自定义全局状态变量必须位于标注“用户自定义参数设置区域”的区域内。二次开发者不能对该区域意外的任何内容进行删除或修改。

  • 1/2:在DevStudio\BoardConfig\Board_BBDB\StateVarDef_BBDB.h文件的enum STATUS_BOOL声明的用户自定义部分加入S_STATUS_VAR_DEMO声明
// <=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>
// 用户自定义 全局状态变量 设置区域, 不得对该区域之外的任何内容进行修改
S_STATUS_VAR_DEMO,          // 直接定义 id 即可
// <=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>
  • 2/2:之后在程序中需要的地方就可以通过下述函数设置或是获取状态;
gSetStatus(S_STATUS_VAR_DEMO, true);
bool blStatus = gGetStatus(S_STATUS_VAR_DEMO);

5. 机载参数系统基本操作

机载控制参数系统为整个PH47代码框架提供了控制参数的读取、写入、空地间传输等功能的全套使用解决方案。

机载参数数据存储于控制板外置 flash 或 eeprom 存储器中。可通过 CSS控制站以单个或批量的方式下载及上传设定。

5.1 参数系统文件包含

用户要在自己的代码文件中使用参数系统功能,只需在自己的.cpp文件开始处加入如下文件包含:

#include"../../Frame/UseGlobalObject.h"   //文件包含路径根据实际情况确定

参数系统的参数id定义,以及参数默认属性设置(参数字典),分别位于如下文件中:

\DevStudio\BoardConfig\Firmware_BBDB\ParamDict_BBDB.h

\DevStudio\BoardConfig\Firmware_BBDB\ParamDict_BBDB.cpp

5.2 参数系统功能使用

函  数

功 能 描 述

Get()

读取记载参数数值。

Get() 函数获取的参数存储于RAM中,若存储器(flash/e2prom)中参数被CSS上传设定所更新,或被程序中其他参数设定函数所改变,则RAM中参数数值也自动更新,用户无需手动刷新。

// 获取当前设定的遥测通讯波特率

uint32_t uBaudRate = (uint32_t)(core.para.Get(P_BAUD_RATE));

// 获取加速度计x轴偏移量

float fVal = frm.para.Get(P_SENSOR_ACC_OFST_X);

Set()

设置机载调参参数数值。

blForcesave决定是否对存储介质(Flash或EEprom)存储数据进行强制更新。

为 ture时不能进行高速率(>50hz)密集调用,否则有可能造成存储器密集写入超时而导致数据存储失败

// 设置参数数值强制更新存储

core.para.Set(P_SENSOR_ACC_OFST_X, _cal_acc_offset.x, true);

// 仅对RAM当中的参数数值进行更新,控制板重启后丢失

frm.para.Set(P_SENSOR_ACC_OFST_X, blSave)

5.3 自定义参数的实现

  • 1/3:在ParaDict_BBDB.h文件enum PARAID枚举定义的用户区域当中加入新参数P_TEST_USER_1的 id 的定义,无需为id指定特定数值,顺序排列即可。在 CSS 参数下载列表中的顺序以enum PARAID当中的顺序为准。
    // <=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>// 用户自定义参数设置区域, 不得对该区域之外的任何内容进行修改P_TEST_USER_1,       // 自定义参数 id// <=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>
  • 2/3:在ParaDict_BBDB.cpp文件全局数组g_arParaDictMCU[]参数字典的用户区域中加入新参数的属性数据。enum PARAID中参数id的数值及顺序与g_arParaDictMCU[]各元素均无关系,可根据实际需要组织。
    // <=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>// 用户自定义参数设置区域, 不得对该区域之外的任何内容进行修改// 自定义参数 P_TEST_USER_1 的默认属性进行设置//{"TestUser_1", P_TEST_USER_1, 0x0000, 256.0f, 0.0f, 500.0f},   // <=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>
  • 3/3;修改参数字典并编译下载至控制板后,必须通过控制板的调试串口运行一次 "initfstrun;"命令以初始化存储器数据。

6. 遥测通讯系统使用

PH7 代码框架通过 mavlink plus 协议与地面控制站 GCS,或其他无人控制目标进行双向通讯。mavlink plus 协议在mavlink 1.0基础上增加修改了message 设置,并对 GCS 上行控制命令实施真伪性动态甄别。

6.1 遥测通讯系统文件包含

若在用户二次开发代码中使用mavlink通讯功能,那么就需要在自己的代码中加入如下文件包含:

    #include "/DevStudio/Frame/Core/MavlinkInterface.h"#include "/DevStudio/Frame/Core/MavlinkWrap.h"

6.2 遥测通讯系统功能使用

在整个 PH7 代码框架内对 GCS 的数据通讯以core.mavlink.FunName()的形式来使用 mavlink 协议相关功能函数。

对其他控制目标的数据通讯以core.consolelink.FunName()的形式来使用 mavlink 通讯相关功能函数。

PH47代码框架已对Message的下行发送进行了完善的封装,为不同类型的Message设定了不同的发送速率,发送速率在运行过程中可重新设定调整。整个Message的下行发送机制为全自动执行,用户在仅需在发送message时以core.mavlink.AddMsg_xxx()形式调用对应函数,即可将待发送消息加入下行消息发送队列随即自动发送。二次开发用户常用消息发送函数如下:

函  数

功 能 描 述

AddMsg_Ctrl_Base()

下行发送飞控控制器相关数据

AddMsg_Atms_Data()

下行发送大气相关数据

AddMsg_GpsRawInt()

下行发送GPS相关数据

AddMsg_Raw_Imu()

下行发送IMU相关数据

AddMsg_Attitude()

下行发送姿态相关数据

AddMsg_Debug_1()

下行发送调试数据 1

AddMsg_Debug_2()

下行发送调试数据 2

AddMsg_StatusText()

下行发送状态信息

mavlink message 发送示例:

// demo 1: 下行发送心跳包
mavlink_heartbeat_t packet;
memset(&packet, 0x00, sizeof(packet));packet.base_mode     = (uint8_t) 6;         
packet.system_status  = 0xA5;               
packet.autopilot         = BOARD_PH7;
packet.custom_mode      = 0xEE;
packet.mavlink_version = MAVLINK_VERSION;uRet = core.mavlink.AddMsg_HeartBeat(&packet);   // 加入发送队列,随后自动发送

demo 2: 下行发送状态信息

char szTmp[32] = {""};
gFormat(szTmp, "Log %d HIL sim start.", uFlightNum);
core.mavlink.AddMsg_StatusText(szTmp, MAV_SEVERITY_WARNING);// 更多Message发送使用方法可见文件:\DevStudio\Frame\Frame.cpp 当中的
// void MavMsgSnd2GCS_Slow() 函数

7. 应用层框架预制功能函数的使用

PH47框架在应用层\DevStudio\Application\App_BBP.cpp.h文件,即应用层类CAppBBDB中预置了多个供二次开发用户使用的功能函数,用户根据上述函数的功能特性,有针对性的在其中加入自己的代码即可方便的进行二次开发。

函数名称

CAppBBDB类成员函数

功 能 描 述

Init()

PH47框架完全启动后调用该初始化函数

在本函数中可安全使用 ASSERT, TRACE 等依赖于框架启动的函数

FastThread_1000Hz()

快速线程函数,调用频率在400—500hz之间波动。

NormalThread_250Hz()

普通线程函数,调用频率固定为250hz

SlowThread_50Hz()

慢速线程函数,调用频率固定为50hz

HandleRevMavlinkMsg()

mavlink 用户自定义上行控制指令处理函数

HandleConsoleCmd()

调试控制台用户自定义命令处理函数

7.1 程序示例:

普通线程函数示例

void CAppBBDB::NormalThread_250Hz()
{// 获取循环间隔时间float fDt = 0.0f;if(_NormalLoopDt.GetLocalDt_ms(fDt) == false)return;// Controller_Common 示例代码algo._pController_Common->Update(fDt);      
}

接收 mavlink message 用户自定义上行指令处理示例

void CAppBBDB::HandleRevMavlinkMsg(mavlink_command_long_sa_t *pPacket)
{//解析及响应 GCS 上行控制命令if(pRevMsg ->msgid == MAVLINK_MSG_ID_COMMAND_LONG_SA ){mavlink_command_long_sa_t packet;mavlink_msg_command_long_sa_decode(pRevMsg, &packet);if(packet.command == MAV_CMD_USER_DEFINE){  if(packet.param1 == fValue){// User code ...}}}
}

用户自定义调试控制台命令处理函数示例

void CAppBBDB::HandleConsoleCmd(uint8_t *pBuff)
{// pBuff 为用户命令字符串,命令字符串最长不能超过 32 byteif(strcmp((char *) pBuff, "User CMD") == 0){// User code ...}
}

 


更多内容见CSDN博客专栏:无人机飞控icon-default.png?t=O83Ahttps://blog.csdn.net/ss15/category_9690939.html?spm=1001.2014.3001.5482相关资源:PH47: PH47运动控制代码框架.icon-default.png?t=O83Ahttps://gitee.com/ss15/ph47

相关文章:

PH47代码框架软件二次开发极简教程

1. 教程说明 本教程适用于对飞控及Stm32程序设计比较熟悉的二次开发者快速掌握PH47框架的使用要点。本教程仅对PH47框架中最主要的二次开发特性进行简要说明&#xff0c;建议与框架中\DevStudio\Algorithms\Controller_Demo.cpp(.h)示例代码配合学习。关于二次开发特性中的详细…...

SQL Server-导入和导出excel数据-注意事项

环境&#xff1a; win10&#xff0c;SQL Server 2008 R2 之前写过的放在这里&#xff1a; SqlServer_陆沙的博客-CSDN博客 https://blog.csdn.net/pxy7896/category_12704205.html 最近重启ASP.NET项目&#xff0c;在使用sql server导出和导入数据时遇到一些问题&#xff0c;特…...

Linux系统:配置Apache支持CGI(Ubuntu)

配置Apache支持CGI 根据以下步骤配置&#xff0c;实现Apache支持CGI 安装Apache&#xff1a; 可参照文章&#xff1a; Ubuntu安装Apache教程。执行以下命令&#xff0c;修改Apache2配置文件000-default.conf&#xff1a; sudo vim /etc/apache2/sites-enabled/000-default.con…...

qt 序列化和反序列化

序列化&#xff1a;QByteArray buffer; QBuffer bufferDevice(&buffer); bufferDevice.open(QIODevice::WriteOnly); QDataStream out(&bufferDevice); out.setVersion(QDataStream::Qt_5_13); 反序列化&#xff1a; void deserialize(const QByteArray &buffer) {…...

java实现文件变动监听

在文件的内容发生变动时&#xff0c;应用可以感知这种变种&#xff0c;并重新加载文件内容&#xff0c;更新应用内部缓存 实现 轮询&#xff1a;定时器Timer&#xff0c;ScheduledExecutorService 判断文件修改&#xff1a;根据java.io.File#lastModified获取文件的上次修改时…...

Maven的使用

1. Maven 简介 https://maven.apache.org/ Maven 是一个强大的项目管理和构建工具&#xff0c;广泛应用于 Java 项目中&#xff0c;旨在简化项目的依赖管理、构建、测试、部署等工作。Maven 主要通过定义 pom.xml&#xff08;Project Object Model 文件&#xff09;来管理项…...

C++开发进阶1:C++编程命名规范

进行C开发时最基础且最重要的是命名规范&#xff0c;掌握良好的命名规范能增加代码的可读性。 认识文件&#xff1a; .cpp&#xff1a;C 源文件. .h或.hpp&#xff1a;C 头文件 .tpp模板实现文件&#xff08;如果模板定义和实现分开&#xff09; .inl内联文件&#xff0c;…...

Android 图片相识度比较(pHash)

概述 在 Android 中&#xff0c;要比对两张 Bitmap 图片的相似度&#xff0c;常见的方法有基于像素差异、直方图比较、或者使用一些更高级的算法如 SSIM&#xff08;结构相似性&#xff09;和感知哈希&#xff08;pHash&#xff09;。 1. 基于像素的差异比较 可以逐像素比较…...

Gitlab 完全卸载–亲测可行

1、停止gitlab gitlab-ctl stop2.卸载gitlab&#xff08;注意这里写的是gitlab-ce&#xff09; rpm -e gitlab-ce 3、查看gitlab进程 ps aux | grep gitlab 4、杀掉第一个进程&#xff08;就是带有好多.............的进程&#xff09; 5、删除所有包含gitlab文件 find / …...

gitlab操作和管理

详细的说明下这几条指令&#xff1a; Git global setup git config --global user.name “” git config --global user.email “” Create a new repository git clone ssh://git12/letect.git cd vlm-event-secondary-detect git switch -c main touch README.md git add RE…...

ctfshow-web入门-反序列化(web254-web258)

目录 1、web254 2、web255 3、web256 4、web257 5、web258 1、web254 传入符合要求的用户名和密码即可&#xff1a; ?usernamexxxxxx&passwordxxxxxx 拿到 flag&#xff1a;ctfshow{e4795ccd-6bff-44b6-a15c-6c679d802e61} 2、web255 整体逻辑代码和上一道差不多 新…...

repo 命令大全详解(第十一篇 repo init)

repo forall 命令用于在指定的项目上执行给定的命令&#xff0c;非常适合批量操作。 参数分类及解释 基本参数 [<project>...]: 可选&#xff0c;指定要操作的项目。如果不指定&#xff0c;则对所有项目执行命令。 示例: repo forall my_project -c "git status&q…...

ComfyUI | 全新ComfyUI前端操作指南:提升你的工作速度!

随着WebUI基本停更&#xff0c;越来越多的AI创作者转向了ComfyUI。 ComfyUI最大的优势是简洁、高效、占用显存低&#xff0c;工作流模式虽然有一点入门难度&#xff0c;但一旦上手&#xff0c;操作非常舒适。 由于原Stable Diffusion团队的参与&#xff0c;ComfyUI的易用度也…...

nginx解决非人类使用http打开的443,解决网安漏扫时误扫443端口带来的问题

一、问题描述 正常访问https的站点时&#xff0c;使用网址https://www.baidu.com&#xff0c;但会有一种错误的访问请求http://www.baidu.com:443&#xff0c;一般都是非人类所为&#xff0c;如漏洞扫描工具&#xff0c;那么请求以后带来的后果是个错误页面 400 Bad Request T…...

黑马 | Reids | 基础篇

黑马reids基础篇 文章目录 黑马reids基础篇一.初始Redis1.1SQL 和 NoSql的区别1.1.1结构化和非结构化1.1.2关联和非关联1.1.3查询方式1.1.4 事务1.1.5总结 1.2 认识Redis1.3 Redis安装启动默认启动&#xff1a;后台启动&#xff1a;开机自启 1.4 Redis客户端1.4.1.Redis命令行客…...

SAP-换登录界面图片

SMW0 二、SM30 &#xff08;将value值删除&#xff0c;登录图片恢复默认&#xff09; 重新登录&#xff0c;更改成功。...

移动 Web核心笔记(二)

空间转换 空间&#xff1a;是从坐标轴角度定义的 X 、Y 和 Z 三条坐标轴构成了一个立体空间&#xff0c;Z 轴位置与视线方向相同。 空间转换也叫 3D转换 属性&#xff1a;transform 平移 /*单独设置 z轴效果不明显*/ transform: translate3d(x, y, z); transform: translateX(…...

MySQL创建和管理表

1. 基础知识 存储数据是处理数据的第一步&#xff0c;只有正确地把数据存储起来&#xff0c;才能进行有效的处理和分析。 在 MySQL 中&#xff0c;一个完整的数据存储过程总共有 4 步&#xff0c;分别是创建数据库、确认字段、创建数据表、插入数据。 从系统架构的层次上看…...

【从零开始的LeetCode-算法】910. 最小差值 II

给你一个整数数组 nums&#xff0c;和一个整数 k 。 对于每个下标 i&#xff08;0 < i < nums.length&#xff09;&#xff0c;将 nums[i] 变成 nums[i] k 或 nums[i] - k 。 nums 的 分数 是 nums 中最大元素和最小元素的差值。 在更改每个下标对应的值之后&#xf…...

周报 | 24.10.14-24.10.20文章汇总

为了更好地整理文章和发表接下来的文章&#xff0c;以后每周都汇总一份周报。 周报 | 24.10.7-24.10.13文章汇总-CSDN博客 OpenCV与AI深度学习 | T-Rex Label &#xff01;超震撼 AI 自动标注工具&#xff0c;开箱即用、检测一切-CSDN博客 计算机视觉与机器学习 | 目标检测 …...

Codeforce 980 Div2 A-D 题解

A. Profitable Interest Rate 原题 A. Profitable Interest Rate 思路 易推出公式 2 * a - b 代码 #include <bits/stdc.h> //#define int long long#define F(i, a, b) for (int i (a); i < (b); i) #define dF(i, a, b) for (int i (a); i > (b); i--)usi…...

一次代码优化的过程

场景说明&#xff1a; wpf项目&#xff0c;有4个不同的页面&#xff0c;共用一个next按钮&#xff0c;实现点击后跳转到下一个页面。 第一个页面是导入文件&#xff0c;当有2个及以上文件时&#xff0c;会弹窗提示。如下图所示&#xff1a; 之前和之后的代码对比&#xff1a; 之…...

多线程的学习(1)

线程的创建方式 1.继承Thread类 package duoXianCheng;public class MyThread extends Thread{public void run(){System.out.println("hoh");}public static void main(String[] args) {MyThread m1 new MyThread();m1.start();//start启动线程&#xff0c;调用重…...

PyCharm借助MobaXterm跳板机连接服务器

服务器信息&#xff1a; Step 1 MovaXterm→Session→SSH输入服务器信息 Step 2 MovaXterm→Session→SSH→Network setting→SSG gateway(jump host) 输入跳板机信息 键入密码即可 Step 3 MovaXterm→Tunneling→New SSH tunnel 依次输入&#xff1a;A本机端口&#xff0c…...

计算机毕业论文基于Android 的签到系统设计与实现

计算机专业本科毕业设计(论文)开题报告 毕业设计(论文)题目:基于Android的签到系统设计与实现 文章目录 毕业设计论文开题报告一、课题的目的及意义(含国内外的研究现状分析):二、课题任务、重点研究内容、实现途径、条件:摘 要1. 绪论1.1. 研究背景1.2. 研究现状1.3.…...

量化学习-02

1、宏观经济学基础概念 宏观经济简单背景 宏观经济&#xff0c;就是在宏观范畴以全局视角观察经济现象&#xff0c;分析其中的经济总量。该宏观范畴所包含的范围可以指一个国家或地区&#xff0c;是由众多微观个体组成的一个经济体&#xff0c;而这里面的微观个体可以指一个家…...

SAP_MM模块-设置业务合作伙伴类型字段必输(多种方案)

一、业务背景 公司需要把供应商增加一个细分的维度&#xff0c;并且要求该字段设置为必输&#xff0c;防止用户新增供应商时忘记维护。这里给用户找了一个分类的字段&#xff1a;业务合作伙伴类型&#xff0c;本文主要讲解如何设置该字段设置为必填&#xff1b; 注意&#xff…...

STM32平台上实现串口接收不定长数据-实际项目中应用

文章目录 一、中断串口监听方式初始化中断处理串口监听 二、空闲中断方式三、空闲中断DMA方式四、总结 本文将详细介绍在STM32平台上实现串口接收不定长数据的几种方法 一、中断串口监听方式 这种方式也是我早期使用的方式&#xff0c;直接使用寄存器来操作&#xff0c;这种方…...

AWD入门

一、简介 AWD(Attack With Defense&#xff0c;攻防兼备)模式。你需要在一场比赛里要扮演攻击方和防守方&#xff0c;攻者得分&#xff0c;失守者会被扣分。也就是说攻击别人的靶机可以获取 Flag 分数时&#xff0c;别人会被扣分&#xff0c;同时你也要保护自己的主机不被别人…...

T3矩阵看功率

每个像素的T3矩阵&#xff0c;功率等于特征值的和。 不同的像素的T3矩阵相加&#xff0c;可不能用特征分解的相加&#xff0c;因为两个T矩阵的特征向量不同...