基于视觉识别的自动采摘机器人设计与实现

一、前言

1.1 项目介绍

【1】项目功能介绍

随着科技的进步和农业现代化的发展,农业生产效率与质量的提升成为重要的研究对象。其中,果蔬采摘环节在很大程度上影响着整个产业链的效益。传统的手工采摘方式不仅劳动强度大、效率低下,而且在劳动力成本逐渐上升的背景下,越来越难以满足大规模种植基地的需求。人工采摘还可能因不规范的操作导致果实损伤,影响商品果率。

基于视觉识别技术的自动采摘机器人的研发,正是针对这一问题提出的创新解决方案。本项目采用树莓派4B作为主控芯片,因其具有强大的计算能力和丰富的扩展接口,可以方便地集成各种传感器和执行机构,实现对复杂环境下的实时图像采集与处理。

项目利用百度飞浆(PaddlePaddle)深度学习框架中的目标检测和分类算法,通过安装在机器人上的高清摄像头获取果树图像,并进行实时分析,精准识别出果实的位置、大小以及成熟度等信息。当成功识别到目标果实后,主控系统将根据识别结果快速计算出机械手臂的最佳运动路径,控制其移动至指定位置,以最适宜的方式完成果实的高效、无损采摘。

基于视觉识别的自动采摘机器人设计与实现项目旨在解决传统农业中人工采摘的瓶颈问题,通过人工智能与自动化技术的深度融合,提高果园管理的智能化水平,降低劳动成本,提高生产效率,从而推动我国乃至全球农业产业向更加智能、高效的现代农业转型。

image-20240221234847550

image-20240221234907193

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

【2】设计实现的功能

(1)视觉识别:借助高性能的摄像头和图像处理算法(本项目采用百度飞浆的目标识别和分类算法),机器人能够捕捉到果园中的果实图像,并准确地从中识别出目标果实。

(2)定位与导航:在识别到果实后,系统会通过计算果实的空间坐标和距离,确定机械手臂需要到达的精确位置。同时,机器人会根据果园内的环境信息和路径规划算法,自动导航至目标果实附近。

(3)机械手臂控制:一旦机器人到达目标位置,机械手臂会在系统的精确控制下,自动调整姿态和动作,以轻柔而准确的方式采摘果实。这一过程涉及到复杂的机械动力学和协同控制算法,确保采摘动作的高效和安全。

(4)果实收集与处理:采摘下来的果实会被机器人收集到专门的容器中,以便后续的分拣、包装和处理。系统还可以对采摘的果实进行数量统计和质量评估,为农业生产提供有价值的数据支持。

本项目实现的功能是一个完整的自动采摘机器人系统,从视觉识别到机械手臂控制,再到果实收集与处理,形成了一个高效、智能的自动化采摘流程。这不仅大大提高了农业生产的效率和质量,也展示了人工智能技术在现代农业领域的广阔应用前景。

【3】项目硬件模块组成

(1)主控板:采用树莓派4B开发板作为整个系统的主控芯片。树莓派是一款功能强大且易于使用的计算机主板,具备高性能的处理器、充足的内存和存储空间,以及丰富的接口和扩展功能,可以满足本项目对计算和控制的需求。

(2)视觉系统:视觉系统包括高性能的摄像头和图像处理单元。摄像头负责捕捉果园中的图像信息,而图像处理单元则基于百度飞浆的目标识别和分类算法,对图像进行处理和分析,以识别和定位目标果实。

(3)机械手臂:机械手臂是实现自动采摘的关键部件,由多个关节和执行器组成,可以在三维空间内自由移动和旋转。通过精确的控制算法,机械手臂能够准确地到达目标果实的位置,并执行采摘动作。

(4)传感器和导航系统:为了实现自动导航和精确定位,项目中还集成了多种传感器和导航系统。这些传感器可以感知环境信息,如距离、方位、障碍物等,而导航系统则根据这些信息规划出机器人的最佳路径。

(4)电源和供电系统:为了保证机器人的持续工作,项目中还包括了电源和供电系统。电源负责为各个硬件模块提供稳定的电力供应,而供电系统则可以根据实际需要调整电力输出,以满足机器人在不同工作状态下的能耗需求。

本项目的硬件模块组成包括主控板、视觉系统、机械手臂、传感器和导航系统、电源和供电系统以及其他辅助模块。这些硬件模块相互协作,共同实现了基于视觉识别的自动采摘机器人系统的功能。

【3】功能总结

系统集成了先进的视觉识别技术、机械手臂控制技术以及自动导航技术,能够自动识别和定位果园中的目标果实,并通过机械手臂完成采摘动作。整个过程无需人工干预,实现了果园采摘的自动化和智能化。

功能包括果实的自动识别和定位、机械手臂的自动导航和控制以及果实的自动收集和处理。通过高性能的摄像头和图像处理算法,系统能够准确捕捉和识别目标果实的图像信息;借助精确的导航和控制算法,机械手臂能够自动导航至果实位置并完成采摘;最后,采摘下来的果实会被自动收集并进行后续处理。

本项目的功能实现不仅提高了果园采摘的效率和准确性,降低了人力成本,同时也为农业生产的现代化和智能化发展提供了新的解决方案和思路。该系统的成功应用将为农业生产带来革命性的变革,推动农业向更高效、更环保、更可持续的方向发展。

1.2 设计思路

(1)需求分析:对果园采摘的实际需求进行分析,明确项目需要解决的问题和达到的目标。了解果园的环境特点、果实类型和生长状况,以及采摘作业的流程和要求,为后续设计提供基础依据。

(2)技术选型:根据需求分析的结果,选择合适的技术方案。选用树莓派4B开发板作为主控芯片,利用其高性能的处理器和丰富的接口资源,实现机器人的控制和管理。同时,采用百度飞浆的目标识别和分类算法,通过视觉系统实现对目标果实的准确识别和定位。

(3)硬件设计:根据技术选型,设计机器人的硬件结构。包括摄像头的选型和布局,确保能够捕捉到清晰、稳定的图像信息;机械手臂的设计和选型,使其能够适应果园环境和采摘需求;导航和传感器系统的设计和选型,实现机器人的自动导航和精确定位。

(4)软件设计:编写机器人的控制程序和算法。通过图像处理算法实现对目标果实的识别和定位,将结果传递给导航和控制系统;根据导航和传感器系统提供的信息,规划机器人的运动路径和动作,控制机械手臂完成采摘动作;实现果实的计数、分类和收集等功能,以及数据的存储和传输。

(5)系统集成与测试:将各个硬件模块和软件程序进行集成,并进行系统测试和调试。确保各个模块之间的通信和协作正常,机器人能够准确识别和采摘目标果实,并实现自动导航和收集等功能。

1.3 系统功能总结

功能模块功能描述
视觉识别- 通过高性能摄像头捕捉果园图像
- 利用百度飞浆的目标识别和分类算法,识别目标果实
- 确定果实的空间坐标和距离
导航与定位- 根据果园环境信息和路径规划算法,自动导航至目标果实附近
- 集成多种传感器,感知环境信息,如距离、方位、障碍物等
机械手臂控制- 在系统精确控制下,自动调整姿态和动作,采摘果实
- 确保采摘动作的高效和安全
果实收集与处理- 采摘下来的果实被自动收集到专门容器中
- 对采摘的果实进行数量统计和质量评估
- 提供数据支持,为农业生产决策提供参考
通信与监控- 实现远程监控和控制功能

二、树莓派4B环境搭建

【1】硬件环境介绍

树莓派是什么?Raspberry Pi(中文名为“树莓派”,简写为RPi,或者RasPi/RPi)是为学生计算机编程教育而设计,只有信用卡大小的卡片式电脑,其系统基于Linux。

image-20230222220821492

【2】资料下载

第一步,先将树莓派4B需要使用的资料下载下来。

image-20230222214743788

【3】准备需要的配件

(1)准备一张至少32G的TFT卡,用来烧写系统。

(2)准备一个读卡器,方便插入TFT卡,好方便插入到电脑上拷贝系统

(3)树莓派主板一个

(4)一根网线(方便插路由器上与树莓派连接)

(5)一根type-C的电源线。用自己Android手机的数据线就行,拿手机充电器供电。

image-20230222215214788

image-20230222215230700

image-20230222215246793

【4】准备烧写系统

(1)安装镜像烧写工具

image-20230222215354199

image-20230222215404779

(2)格式化SD卡

将TFT卡通过读卡器插入到电脑上,将TFT卡格式化。

image-20230222215625025

image-20230222215701338

(3)烧写系统

**接下来准备烧写的系统是这一个系统:**将系统解压出来。

image-20230222223022944

然后打开刚才安装好的镜像烧写工具,在软件中选择需要安装的 img(镜像)文件,“Device”下选择SD的盘符,然后选择“Write”,然后就开始安装系统了,根据你的SD速度,安装过程有快有慢。

注意:从网盘下载下来的镜像如果没有解压就先解压,释放出img文件。

image-20230222220145324

下面是烧写的流程:

image-20230222220325807

点击YES,开始烧写。

image-20230222220347360

烧写过程中:

image-20230222220422721

安装结束后会弹出完成对话框,说明安装就完成了,如果不成功,需要关闭防火墙一类的软件,重新插入SD进行安装。

image-20230222222036811

需要注意的是,安装完,windows系统下看到SD只有74MB了,这是正常现象,因为linux下的磁盘分区win下是看不到的。 烧录成功后windows系统可能会因为无法识别分区而提示格式化分区,此时**千万不要格式化!不要格式化!不要格式化!**点击取消,然后弹出内存卡,插入到树莓派上。

image-20230222222207411

至此,树莓派烧写成功。

【5】启动系统

(1)树莓派供电

由于我买的树莓派开发板不带电源线,就采用Android手机的充电线供电。 使用Type-C供电时,要求电源头的参数要求,电压是5V,电流是3A。

我的充电器是小米的120W有线快充,刚好满足要求。

image-20230222221409160

image-20230222221435491

(2)启动树莓派(以Type-C供电示例)

烧写完后把MicroSD卡直接插入树莓派的MicroSD卡插槽,如果有显示器就连接显示器,有DHMI线机也可以连接外接的显示器,有鼠标、键盘都可以插上去,就可以进入树莓派系统了。

但是,我这块板子就一个主板,什么都没有。就拿网线将树莓派的网口与路由器连接。

image-20230222223207997

上电之后,开发板的指示灯会闪烁,说明已经启动。

(3)查看开发板的IP地址

现在板子没屏幕,想要连接板子,只能通过SSH远程登录的方式,当前烧写的这个系统默认开机就启动了SSH,所以只要知道开发板的IP地址就可以远程登录进去。

**如何知道树莓派板子的IP地址?**方法很多,最简单是直接登录路由器的后台界面查看连接进入的设备。

我使用的小米路由器,登录后台,看到了树莓派的IP地址。

image-20230222223441177

(4)SSH方式登录开发板

当前烧写系统的登录账号和密码如下:

账号:pi 密码:yahboom

打开SSH远程登录工具:PuTTY_0.67.0.0.exe

image-20230222223700940

输入IP地址和端口号,点击open。

image-20230222223752958

然后输入账号和密码。

image-20230222223815162

输入用户名 pi按下回车,然后再输入密码 yahboom。 注意:Linux下为了保护隐私,输入密码是不可见的,你只需要正常输入,按下回车键确定 即可。

正常情况下,就登录成功了。

image-20230222223840293

接下来看看联网情况。 ping一下百度测试互联网是否畅通,因为接下来要在线安装软件包。

ping www.baidu.com

image-20230222224200466

可以看到网络没有问题。

提示: 按下 Ctrl + C 可以终止命令行。 这算是Linux基础。

【6】windows远程登录桌面

为了方便图形化方式开发,可以使用windows系统通过远程桌面登录树莓派,就可以看到界面了,不过需要先安装工具。

(1)安装xdrp

在树莓派的命令行终端输入命令:

sudo apt-get install xrdp

按下回车之后,会弹出确认窗口。输入 y之后,按下回车,继续安装。

image-20230222224534775

安装完毕:

image-20230222224724318

(2)打开windows远程桌面

在windows电脑上打开运行命令的窗口,输入mstsc来打开远程桌面。

image-20230222224920925

打开远程桌面的窗口:

image-20230222224953096

(3)连接树莓派远程桌面

打开远程桌面后,输入树莓派开发板的IP地址,点击连接。

image-20230222225040460

如果弹出窗口,就选择

image-20230222225121454

接下来就进入到树莓派开发板的远程桌面的登录窗口了。

image-20230222225204850

接下来输入面账号和密码。

账号:pi 密码:yahboom

输入后点击OK按钮登录。

image-20230222225405070

正常情况下,就顺利的进入树莓派的桌面了。接下来就可以进行远程桌面开发了。

image-20230222225519317

【7】扩展树莓派SD卡可用空间

树莓派系统默认启动时,树莓派默认没有把整个存储空间拓展到整张卡中,如果需要使用整个SD卡,这时候可以通过人为的把存储空间拓展到整张卡上。

(1)查看内存使用情况

打开命令行终端,输入df -h 命令。

image-20230222225925276

(2)扩展内存

<1> 打开树莓派命令行终端输入:

pi@raspberrypi:~ $ sudo raspi-config

<2> 在弹出的命令行里选择Advanced Options

image-20230222230513705

<3> 选择第一个选项。

image-20230222230539460

<4> 点击确定

image-20230222230550004

<5> 点击右边的Finish按钮保存退出。

确定之后,关闭界面,系统会自动重启,重启之后,使用df命令查看是否扩展成功(我这里插的是32G的SD卡)。

可以看到,我的系统已经扩展成功了,目前可以内存空间是19G。

image-20230222230727040

【8】树莓派连接WIFI

(1)配置需要连接的WIFI

点击右上角的数据连接图标,打开WIFI列表,点击想要的WIFI进行连接。

image-20230302232003214

输入密码:

image-20230302232119543

连接成功后的效果:

image-20230302232504724

(2)通过WIFI的IP地址登录远程桌面

在路由器的后台可以看到,目前树莓派连入了两个IP地址。接下来把网线拔掉,使用WIFI无线也可以直接连接无线桌面,这样就不用插网线了。

image-20230302232814697

账号和密码:

账号:pi 密码:yahboom

三、代码设计

3.1 舵机控制代码(机械手臂控制)

C语言代码: 使用wiringPi库控制树莓派上的GPIO引脚,实现对舵机的控制。通过servo_rotate()函数可以控制舵机旋转到指定的角度。在main()函数中,使用键盘输入获取目标角度,并调用servo_rotate()函数控制舵机旋转到目标角度。

舵机的控制方式为PWM脉冲宽度调制,即将角度转换为脉宽值并输出对应的高低电平信号。将舵机信号线连接到GPIO18引脚,通过digitalWrite()函数输出高低电平来控制舵机旋转。

#include <wiringPi.h>
#include <stdio.h>

#define SERVO_PIN 18 // SG90舵机信号线连接的GPIO引脚

void servo_rotate(int angle) {
    int pulse_width = (angle * 11) + 500; // 将角度转换为脉宽值
    digitalWrite(SERVO_PIN, HIGH); // 输出高电平
    delayMicroseconds(pulse_width); // 延时脉宽值对应的时间
    digitalWrite(SERVO_PIN, LOW); // 输出低电平
    delay(20 - pulse_width / 1000); // 延时剩余时间
}

int main(void) {
    wiringPiSetupGpio(); // 初始化wiringPi库
    pinMode(SERVO_PIN, OUTPUT); // 将舵机信号线接口设为输出模式

    while(1) {
        // 从键盘输入目标角度
        printf("Enter the angle to rotate (0-180): ");
        fflush(stdout);
        int angle;
        scanf("%d", &angle);

        // 旋转到目标角度
        if(angle >= 0 && angle <= 180) {
            servo_rotate(angle);
        } else {
            printf("Invalid angle! Please enter an angle between 0 and 180.\n");
        }
    }

    return 0;
}

Pyhon代码: 使用RPi.GPIO库来控制树莓派上的GPIO引脚,实现对舵机的控制。通过setup()函数进行初始化设置,并通过set_angle()函数控制舵机旋转到指定的角度。

main()函数中,使用键盘输入获取目标角度,并调用set_angle()函数控制舵机旋转到目标角度。

import RPi.GPIO as GPIO
import time

SERVO_PIN = 18  # SG90舵机信号线连接的GPIO引脚

def setup():
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(SERVO_PIN, GPIO.OUT)
    global servo_pwm
    servo_pwm = GPIO.PWM(SERVO_PIN, 50)  # 创建PWM对象,频率设置为50Hz
    servo_pwm.start(0)  # 启动PWM输出,初始占空比设为0

def set_angle(angle):
    duty_cycle = (angle / 18) + 2.5  # 将角度转换为占空比值
    servo_pwm.ChangeDutyCycle(duty_cycle)
    time.sleep(0.3)  # 等待舵机转到指定角度

def main():
    setup()

    while True:
        # 从键盘输入目标角度
        angle = int(input("Enter the angle to rotate (0-180): "))

        # 旋转到目标角度
        if 0 <= angle <= 180:
            set_angle(angle)
        else:
            print("Invalid angle! Please enter an angle between 0 and 180.")

if __name__ == '__main__':
    try:
        main()
    finally:
        servo_pwm.stop()  # 停止PWM输出
        GPIO.cleanup()  # 清理GPIO资源

3.2 调用算法识别目标

(1)安装PaddlePaddle和PaddleDetection库:

  • 先安装Python和pip。然后,打开终端并执行以下命令安装PaddlePaddle和PaddleDetection库:

    pip install paddlepaddle paddlepaddle-gpu
    pip install paddlehub
    pip install paddlehub -i https://pypi.tuna.tsinghua.edu.cn/simple
    

(2)下载预训练模型:

  • 百度飞桨提供了预训练的目标检测模型,可以从PaddleDetection的GitHub页面下载这些模型。选择适合的任务的模型,并将其解压到合适的目录中。

(3)编写调用代码:

  • 创建一个Python脚本文件,例如detect_fruits.py,并使用以下代码编写脚本:

    import paddlehub as hub
    import cv2
    
    def detect_fruits(image_path, model_path):
        # 加载模型
        module = hub.Module(name='yolov3_mobilenet_v1_coco2017')
        input_dict = {'image': [image_path]}
    
        # 目标检测
        results = module.object_detection(data=input_dict)
    
        # 处理结果
        for result in results:
            if len(result['data']) > 0:
                for obj in result['data']:
                    label = obj['label']
                    confidence = obj['confidence']
                    left, top, right, bottom = obj['left'], obj['top'], obj['right'], obj['bottom']
                    print(f"Label: {label}, Confidence: {confidence:.2f}")
                    print(f"Bounding Box: ({left}, {top}), ({right}, {bottom})")
    
        # 可视化结果
        img = cv2.imread(image_path)
        for result in results:
            module.visualize(data=result, output_dir='output', score_thresh=0.5, use_visualize=True, visualization=True, plot_bbox=True, save_bbox_txt=True, image=img)
    
    if __name__ == '__main__':
        image_path = 'path/to/your/image.jpg'  # 替换为你的图片路径
        model_path = 'path/to/your/model'  # 替换为你的模型路径
        detect_fruits(image_path, model_path)
    

    在上面的代码中,使用PaddleHub库加载了预训练的yolov3_mobilenet_v1_coco2017模型,并将其应用于指定的图像。然后,处理检测结果并进行输出。最后,使用OpenCV库可视化结果并保存到指定目录中。

(4)运行脚本:

  • 将目标果实图像放置在与脚本相同的目录下(或根据需要修改图像路径)。然后,在终端中执行以下命令运行脚本:

    python detect_fruits.py
    

脚本将分析图像并输出检测到的目标果实的标签、置信度和边界框。会生成一个带有目标果实标注的图像。

3.3 机器人小车控制代码

小车的电机驱动采用L298N模块,连接在GPIO17、GPIO18、GPIO27和GPIO22上。 使用了wiringPi库来控制树莓派上的GPIO引脚,实现对小车电机驱动的控制。通过setup()函数进行初始化设置,并通过forward()backward()turn_left()turn_right()函数控制小车前进、后退和转弯。其中,stop()函数用于停止小车运动。

#include <wiringPi.h>

#define MOTOR_ENA_PIN 0  // L298N模块ENA引脚连接的GPIO引脚
#define MOTOR_ENB_PIN 2  // L298N模块ENB引脚连接的GPIO引脚
#define MOTOR_IN1_PIN 3  // L298N模块IN1引脚连接的GPIO引脚
#define MOTOR_IN2_PIN 4  // L298N模块IN2引脚连接的GPIO引脚
#define MOTOR_IN3_PIN 5  // L298N模块IN3引脚连接的GPIO引脚
#define MOTOR_IN4_PIN 6  // L298N模块IN4引脚连接的GPIO引脚

void setup() {
    wiringPiSetup();  // 初始化wiringPi库
    pinMode(MOTOR_ENA_PIN, OUTPUT);
    pinMode(MOTOR_ENB_PIN, OUTPUT);
    pinMode(MOTOR_IN1_PIN, OUTPUT);
    pinMode(MOTOR_IN2_PIN, OUTPUT);
    pinMode(MOTOR_IN3_PIN, OUTPUT);
    pinMode(MOTOR_IN4_PIN, OUTPUT);
}

void forward() {
    digitalWrite(MOTOR_IN1_PIN, HIGH);
    digitalWrite(MOTOR_IN2_PIN, LOW);
    digitalWrite(MOTOR_IN3_PIN, LOW);
    digitalWrite(MOTOR_IN4_PIN, HIGH);
    digitalWrite(MOTOR_ENA_PIN, HIGH);
    digitalWrite(MOTOR_ENB_PIN, HIGH);
}

void backward() {
    digitalWrite(MOTOR_IN1_PIN, LOW);
    digitalWrite(MOTOR_IN2_PIN, HIGH);
    digitalWrite(MOTOR_IN3_PIN, HIGH);
    digitalWrite(MOTOR_IN4_PIN, LOW);
    digitalWrite(MOTOR_ENA_PIN, HIGH);
    digitalWrite(MOTOR_ENB_PIN, HIGH);
}

void turn_left() {
    digitalWrite(MOTOR_IN1_PIN, LOW);
    digitalWrite(MOTOR_IN2_PIN, HIGH);
    digitalWrite(MOTOR_IN3_PIN, LOW);
    digitalWrite(MOTOR_IN4_PIN, HIGH);
    digitalWrite(MOTOR_ENA_PIN, HIGH);
    digitalWrite(MOTOR_ENB_PIN, HIGH);
}

void turn_right() {
    digitalWrite(MOTOR_IN1_PIN, HIGH);
    digitalWrite(MOTOR_IN2_PIN, LOW);
    digitalWrite(MOTOR_IN3_PIN, HIGH);
    digitalWrite(MOTOR_IN4_PIN, LOW);
    digitalWrite(MOTOR_ENA_PIN, HIGH);
    digitalWrite(MOTOR_ENB_PIN, HIGH);
}

void stop() {
    digitalWrite(MOTOR_ENA_PIN, LOW);
    digitalWrite(MOTOR_ENB_PIN, LOW);
}

int main() {
    setup();

    while (1) {
        // 从键盘输入指令
        char cmd = getchar();
        getchar();  // 忽略回车符

        // 根据指令执行动作
        switch (cmd) {
            case 'w':  // 前进
                forward();
                break;
            case 's':  // 后退
                backward();
                break;
            case 'a':  // 左转
                turn_left();
                break;
            case 'd':  // 右转
                turn_right();
                break;
            case 'x':  // 停止
                stop();
                break;
            default:
                break;
        }
    }

    return 0;
}

四、总结

随着农业技术的不断进步,自动化、智能化已成为现代农业生产的重要趋势。本项目通过结合视觉识别技术、机器人技术和自动化控制技术,成功设计并实现了基于视觉识别的自动采摘机器人系统。这一创新性的成果不仅提高了果园采摘的效率和准确性,降低了人力成本,还为农业生产的现代化和智能化发展提供了新的解决方案和思路。

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

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

相关文章

163邮箱SMTP端口号及服务器地址详细设置?

163邮箱SMTP端口号是什么&#xff1f;163邮件SMTP设置教程&#xff1f; 除了基本的邮箱账号和密码外&#xff0c;还需要了解SMTP服务器地址和端口号&#xff0c;以及相应的设置。这些设置对于确保邮件能够顺利发送至关重要。下面&#xff0c;蜂邮EDM将详细介绍163邮箱SMTP端口…

http和https的区别是什么?

–前言 传输信息安全性不同、连接方式不同、端口不同、证书申请方式不同 一、传输信息安全性不同 1、http协议&#xff1a;是超文本传输协议&#xff0c;信息是明文传输。如果攻击者截取了Web浏览器和网站服务器之间的传输报文&#xff0c;就可以直接读懂其中的信息。 2、h…

《Redis 设计与实现》读书概要

注&#xff1a; 《Redis 设计与实现》一书基于 Redis 2.9 版本编写&#xff0c;部分内容已过时&#xff0c;过时之处本文会有所说明。本文为读书笔记&#xff0c;部分简单和日常使用较少的知识点未记录。原书网页版地址 https://redisbook.com/ 一、底层数据结构 SDS(Simple Dy…

微信小程序固定头部-CSS实现

效果图 代码逻辑&#xff1a;设置头部的高度&#xff0c;浮动固定后&#xff0c;再加个这个高度的大小的外边距 .weui-navigation-bar {position: fixed;top: 0px;left: 0px;right: 0px;height:90px; } .weui-navigation-bar_bottom{height:90px; }

【React架构 - Scheduler中的MessageChannel】

前序 我们都知道JS代码是在浏览器5个进程(下面有介绍)中渲染进程中的Js引擎线程执行的&#xff0c;其他还有GUI渲染线程、定时器线程等&#xff0c;而页面的布局和绘制是在GUI线程中完成的&#xff0c;这些线程之间是互斥的&#xff0c;所以在执行Js的同时会阻塞页面的渲染绘制…

仿牛客网项目---社区首页的开发实现

从今天开始我们来写一个新项目&#xff0c;这个项目是一个完整的校园论坛的项目。主要功能模块&#xff1a;用户登录注册&#xff0c;帖子发布和热帖排行&#xff0c;点赞关注&#xff0c;发送私信&#xff0c;消息通知&#xff0c;社区搜索等。这篇文章我们先试着写一下用户的…

数据可视化之旅:电商销售看板的制作与心得

作为一名电商工作者&#xff0c;每天都需要与海量的销售数据打交道。在数据海洋中&#xff0c;如何快速准确地找到关键信息&#xff0c;优化销售策略&#xff0c;是摆在我面前的一大挑战。在了解市面上众多可视化产品后&#xff0c;我选择尝试了山海鲸可视化软件&#xff0c;这…

2024年小程序云开发CMS内容管理无法使用,无法同步内容模型到云开发数据库的解决方案,回退老版本CMS内容管理的最新方法

一&#xff0c;问题描述 最近越来越多的同学找石头哥&#xff0c;说cms用不了&#xff0c;其实是小程序官方最近又搞大动作了&#xff0c;偷偷的升级的云开发cms&#xff08;内容管理&#xff09;以下都称cms&#xff0c;不升级不要紧&#xff0c;这一升级&#xff0c;就导致我…

【架构之路】糟糕程序员的20个坏习惯,切记要改掉

文章目录 强烈推荐前言&#xff1a;坏习惯:总结&#xff1a;强烈推荐专栏集锦写在最后 强烈推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站:人工智能 前言&#xff1a; 优秀的程序员…

matlab实现不同窗滤波器示例

1 汉明窗低通滤波器 &#xff1a; 在Matlab中使用汉明窗设计低通滤波器可以通过fir1函数实现。汉明窗通常用于设计滤波器&#xff0c;可以提供更突出的频率特性。 下面是一个示例代码&#xff0c;演示如何在Matlab中使用汉明窗设计低通滤波器&#xff1a; % 定义滤波器参数 fs …

Scrapy与分布式开发:框架原生去重机制源码解析与不足分析

框架原生去重机制源码解析与不足分析 导语 在网络爬虫和数据采集领域,去重机制是一个至关重要的环节。随着互联网的迅速发展,数据量呈爆炸式增长,如何在海量数据中高效地筛选出有价值且唯一的信息,成为了一个亟待解决的问题。去重机制正是为了解决这一问题而诞生的。 Sc…

docker中hyperf项目配置虚拟域名

在使用hyperf框架时&#xff0c;直接用了docker环境进行开发 下载镜像运行容器 docker run --name hyperf -v /data/project:/data/project -p 9501:9501 -itd -w /data/project --privileged -u root --entrypoint /bin/sh 镜像ID配置docker-compose.yml version: "3.…

东崎仪表案例-中国新能源汽车产业全面崛起

以下部分数据信息来源&#xff1a;澎湃新闻 1月9日&#xff0c;韩国研究机构SNE Research公布了全球动力电池市场的新一轮统计数据。2023年1—11月&#xff0c;全球登记的电动汽车&#xff08;EV、PHEV、HEV&#xff09;电池装车量约为624.4GWh&#xff0c;比2022年同期增长41.…

Qt SQLite的创建和使用

重点&#xff1a; 1.SQLite创建数据库内容方法 链接&#xff1a;SQLite Expert Personal的简单使用-CSDN博客 2.和数据库进行链接方法 QSqlDatabase DB; //数据库连接bool MainWindow::openDatabase(QString aFile) {DBQSqlDatabase::addDatabase("QSQLITE"); /…

高刷显示器 - HKC VG253KM

&#x1f525;&#x1f525; 今天来给大家揭秘一款电竞神器 - HKC VG253KM 高刷电竞显示器&#xff01;这款显示器可是有着雄鹰展翅般的设计灵感&#xff0c;背后的大鹏展翅鹰翼图腾让人过目难忘。那么&#xff0c;这款显示器到底有哪些过人之处呢&#xff1f;一起来看看吧&…

vue中使用prettier

前言&#xff1a;prettier是一款有态度的代码格式化工具&#xff0c;它可以集成在IDE中&#xff0c;如VS Code、Web Storm等&#xff0c;也可以安装到我们开发的项目里面。本文主要讲解在Vue中集成prettier的过程&#xff0c;可以便于代码检测和格式化。 prettier官网 从官网的…

使用MyBatisPlus实现向数据库中存储List类型的数据

使用MyBatisPlus实现向数据库中存储List类型的数据 问题描述 建表时&#xff0c;表中的这五个字段为json类型 但是在入库的时候既不能写入数据&#xff0c;也不能查询出数据。 解决方案&#xff1a; 1.首先明确&#xff0c;数据存入的时候是经过了数据类型转化&#xff0c…

ElementUI修改el-tab-pane自定义动态添加class并修改组件样式

参考&#xff1a;ElementUI修改el-tab-pane自定义添加class并修改组件样式_el-tab-pane更换样式-CSDN博客 需求&#xff1a;tab 列表 动态添加class 标识当前版本 1&#xff1a;在调用列表接口的接口里面 初始化调用handleClick()方法 2&#xff1a;tab 点击时 再调用一下…

Mysql索引3--索引优化规则

目录 1、索引失效场景 1、1、不遵循最左前缀法则 &#xff0c;导致索引失效 1、2、范围查询 &#xff0c;导致失效 1、3 索引列进行运算&#xff0c;导致失效 ​1、4字符串不加引号&#xff0c;到账失效 1、5头部模糊匹配&#xff0c;导致失效 1、6 or连接条件只有一个有…

10分钟SkyWalking与SpringBoot融合并整合到Linux中

1.依赖配置 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2.2.0.RELEASE</version></dependency><dependency><groupId>org.springframe…