基于yolov7与arduino的眼睛跟随模块

基于yolov7与arduino的眼睛跟随模块

  • 整个模块的介绍
  • 摄像模块
  • 图片传输模块
  • 图像检测模块
  • 控制模块
  • 动力模块

整个模块的介绍

我们首先需要一个图片收集的模块来对当前的图片进行收集然后将图片传至服务端对图片中的眼睛利用YOLO进行检测最后将数据传至arduino使其控制动力模块来进行位置调整使目标一直与眼睛处于一个水平线

摄像模块

这里我们使用ESP32-cam来获取照片并通过无线网络来上传至服务器
ESP32-CAM
要使用它我们首先需要下载支持esp32的库
下载教程: https://blog.csdn.net/qq_62975494/article/details/132539804
烧录时我们选择AI Thinker
在这里插入图片描述

图片传输模块

我们通过esp32的wifi模式对拍摄到的图片进行传输
与服务端建立连接->发送第一张图片->等待服务端指令->收到指令后继续发送->等待指令
客户端代码(esp32-cam)

/*
网络调试助手
https://soft.3dmgame.com/down/213757.html
*/
#include <Arduino.h>
#include <WiFi.h>
#include "esp_camera.h"
#include <vector>
 
const char *ssid = "xxo";   wifi id
const char *password = "12345678";  wifi密码
const IPAddress serverIP(10,218,19,53); //欲访问的地址
uint16_t serverPort = 8080;         //服务器端口号
 
#define maxcache 1430
 
WiFiClient client; //声明一个客户端对象,用于与服务器进行连接
 
//CAMERA_MODEL_AI_THINKER类型摄像头的引脚定义
#define PWDN_GPIO_NUM     32
#define RESET_GPIO_NUM    -1
#define XCLK_GPIO_NUM      0
#define SIOD_GPIO_NUM     26
#define SIOC_GPIO_NUM     27
 
#define Y9_GPIO_NUM       35
#define Y8_GPIO_NUM       34
#define Y7_GPIO_NUM       39
#define Y6_GPIO_NUM       36
#define Y5_GPIO_NUM       21
#define Y4_GPIO_NUM       19
#define Y3_GPIO_NUM       18
#define Y2_GPIO_NUM        5
#define VSYNC_GPIO_NUM    25
#define HREF_GPIO_NUM     23
#define PCLK_GPIO_NUM     22
 
static camera_config_t camera_config = {
    .pin_pwdn = PWDN_GPIO_NUM,
    .pin_reset = RESET_GPIO_NUM,
    .pin_xclk = XCLK_GPIO_NUM,  
    .pin_sscb_sda = SIOD_GPIO_NUM,
    .pin_sscb_scl = SIOC_GPIO_NUM,
    
    .pin_d7 = Y9_GPIO_NUM,
    .pin_d6 = Y8_GPIO_NUM,
    .pin_d5 = Y7_GPIO_NUM,
    .pin_d4 = Y6_GPIO_NUM,
    .pin_d3 = Y5_GPIO_NUM,
    .pin_d2 = Y4_GPIO_NUM,
    .pin_d1 = Y3_GPIO_NUM,
    .pin_d0 = Y2_GPIO_NUM,
    .pin_vsync = VSYNC_GPIO_NUM,
    .pin_href = HREF_GPIO_NUM,
    .pin_pclk = PCLK_GPIO_NUM,
    
    .xclk_freq_hz = 20000000,  //帧率
    .ledc_timer = LEDC_TIMER_0,
    .ledc_channel = LEDC_CHANNEL_0,
    
    .pixel_format = PIXFORMAT_JPEG,
    .frame_size = FRAMESIZE_VGA,    //图片格式
    .jpeg_quality = 12, //PEG图片质量(jpeg_quality),0-63,数字越小质量越高
    .fb_count = 1,
};
void wifi_init()
{
    WiFi.mode(WIFI_STA);
    WiFi.setSleep(false); //关闭STA模式下wifi休眠,提高响应速度
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED)
    {
        delay(500);
        Serial.print(".");
    }
    Serial.println("WiFi Connected!");
    Serial.print("IP Address:");
    Serial.println(WiFi.localIP());
}
esp_err_t camera_init() {
    //initialize the camera
    esp_err_t err = esp_camera_init(&camera_config);
    if (err != ESP_OK) {
        Serial.println("Camera Init Failed");
        return err;
    }
    sensor_t * s = esp_camera_sensor_get();
    //initial sensors are flipped vertically and colors are a bit saturated
    if (s->id.PID == OV2640_PID) {
    //        s->set_vflip(s, 1);//flip it back
    //        s->set_brightness(s, 1);//up the blightness just a bit
    //        s->set_contrast(s, 1);
    }
    Serial.println("Camera Init OK!");
    return ESP_OK;
}
 
void setup()
{
    Serial.begin(115200);
    wifi_init();
    camera_init();
}
 
void loop()
{
    Serial.println("Try To Connect TCP Server!");
    if (client.connect(serverIP, serverPort)) //尝试访问目标地址
    {
        Serial.println("Connect Tcp Server Success!");
        //client.println("Frame Begin");  //46 72 61 6D 65 20 42 65 67 69 6E // 0D 0A 代表换行  //向服务器发送数据
        while (1){       
          camera_fb_t * fb = esp_camera_fb_get();
          uint8_t * temp = fb->buf; //这个是为了保存一个地址,在摄像头数据发送完毕后需要返回,否则会出现板子发送一段时间后自动重启,不断重复
          if (!fb)
          {
              Serial.println( "Camera Capture Failed");
          }
          else
          { 
            //先发送Frame Begin 表示开始发送图片 然后将图片数据分包发送 每次发送1430 余数最后发送 
            //完毕后发送结束标志 Frame Over 表示一张图片发送完毕 
            client.print("Frame Begin"); //一张图片的起始标志
            // 将图片数据分段发送
            int leng = fb->len;
            int timess = leng/maxcache;
            int extra = leng%maxcache;
            for(int j = 0;j< timess;j++)
            {
              client.write(fb->buf, maxcache); 
              for(int i =0;i< maxcache;i++)
              {
                fb->buf++;
              }
            }
            client.write(fb->buf, extra);
            client.print("Frame Over");      // 一张图片的结束标志
            Serial.print("This Frame Length:");
            Serial.print(fb->len);
            Serial.println(".Succes To Send Image For TCP!");
            //return the frame buffer back to the driver for reuse
            fb->buf = temp; //将当时保存的指针重新返还
            esp_camera_fb_return(fb);  //这一步在发送完毕后要执行,具体作用还未可知。        
          }
          //等待服务端回应
          while (1) //如果已连接或有收到的未读取的数据
        {
            if (client.available()) //如果有数据可读取
            {
                String line = client.readStringUntil('\n'); //读取数据到换行符
                Serial.print("读取到数据:");
                Serial.println(line);
                break;
            }
        }
        }
        
        while (client.connected() || client.available()) //如果已连接或有收到的未读取的数据
        {
            if (client.available()) //如果有数据可读取
            {
                String line = client.readStringUntil('\n'); //读取数据到换行符
                Serial.print("ReceiveData:");
                Serial.println(line);
                client.print("--From ESP32--:Hello Server!");    
            }
        }
        Serial.println("close connect!");
        //client.stop(); //关闭客户端
        
    }
    else
    {
        Serial.println("Connect To Tcp Server Failed!After 10 Seconds Try Again!");
        client.stop(); //关闭客户端
    }
    delay(10000);
}

服务端我们使用python来进行编写

import socket
import threading
import time

import bluetooth

begin_data = b'Frame Begin'
end_data = b'Frame Over'

v=0

def handle_sock(sock, addr):

    global v
    print('----------开始接收-------')
    temp_data = b''

    while 1:

        if 1:
            
            print(11111111111111111111111111111111)
            data = sock.recv(1430)
            # 如果这一帧数据包的开头是 b'Frame Begin' 则是一张图片的开始
            if data[0:len(begin_data)] == begin_data:
                # 将这一帧数据包的开始标志信息(b'Frame Begin')清除   因为他不属于图片数据
                data = data[len(begin_data):len(data)]
                # 判断这一帧数据流是不是最后一个帧 最后一针数据的结尾时b'Frame Over'
                while data[-len(end_data):] != end_data:
                    temp_data = temp_data + data  # 不是结束的包 讲数据添加进temp_data
                    data = sock.recv(1430)  # 继续接受数据 直到接受的数据包包含b'Frame Over' 表示是这张图片的最后一针
                # 判断为最后一个包 将数据去除 结束标志信息 b'Frame Over'
                temp_data = temp_data + data[0:(len(data) - len(end_data))]  # 将多余的(\r\nFrame Over)去掉 其他放入temp_data
                
                with open(f'./eyes/{v}.jpg', 'wb') as fp:
                    fp.write(temp_data)
                v=v+1


                print("接收到的数据包大小:" + str(len(temp_data)))  # 显示该张照片数据大小

                print('------接收下一张图片--------')
                            #cv2.imshow('server_frame', r_img)
                            #print("接收到的数据包大小:" + str(len(temp_data)))  # 显示该张照片数据大小
                temp_data = b''  # 清空数据 便于下一章照片使用
                            #处理数据
                a=input()

                sock.send("1".encode('utf-8'))
                
        time.sleep(1)
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('10.218.19.53', 8080))
server.listen(5)
CONNECTION_LIST = []

# 主线程循环接收客户端连接
while True:
    sock, addr = server.accept()
    CONNECTION_LIST.append(sock)
    print('Connect--{}'.format(addr))
    # 连接成功后开一个线程用于处理客户端
    client_thread = threading.Thread(target=handle_sock, args=(sock, addr))
    client_thread.start()

通过传输模块我们就可以将esp32获取的图片存至服务端的指定位置等待检测模块的目标检测
使用esp32-cam连接热点时我们需要将热点的网络频带调制2.4因为它不支持5G频带

在这里插入图片描述

图像检测模块

此模块中我们将使用yolov7对传输模块传输来的图片数据进行检测然后通过蓝牙将检测到的数据发送至控制模块
数据集的训练请参考

数据集训练: https://blog.csdn.net/qq_62975494/article/details/129786717
云GPU的使用: https://blog.csdn.net/qq_62975494/article/details/136565413

import torch
# 加载本地模型
device = torch.device("cuda")
model = torch.hub.load('D:/AI/yolov7-main', 'custom',
                       'D:\AI\yolov7-main\weights\last2.pt',
                       source='local', force_reload=False)
while 1:

    if 1:
        # 使用模型
        model = model.to(device)
        # 开始推理
        results = model('./eyes.jpg')
        # 过滤模型
        xmins = results.pandas().xyxy[0]['xmin']
        ymins = results.pandas().xyxy[0]['ymin']
        xmaxs = results.pandas().xyxy[0]['xmax']
        ymaxs = results.pandas().xyxy[0]['ymax']
        class_list = results.pandas().xyxy[0]['class']
        confidences = results.pandas().xyxy[0]['confidence']
        newlist = []
        for xmin, ymin, xmax, ymax, classitem, conf in zip(xmins, ymins, xmaxs, ymaxs, class_list, confidences):
            if classitem == 0 and conf > 0.5:
                newlist.append([int(xmin), int(ymin), int(xmax), int(ymax), conf])
        print(newlist)
#图片格式640x480   240

newlist中储存的就是图片中检测到的目标
然后我们需要通过计算将所要移动的距离通过蓝牙发送给控制模块(arduino)

python使用蓝牙发送数据

import time
import bluetooth

sock = bluetooth.BluetoothSocket(bluetooth.RFCOMM)
sock.connect(("98:DA:20:04:C1:67", 1))
time.sleep(3)
while 1:
    a = input()
    sock.send(a)
    time.sleep(2)

控制模块

控制模块我们使用arduino控制模块主要负责动力模块的控制和接收检测模块得到的结果
arduino蓝牙模块使用: https://blog.csdn.net/catzhaojia/article/details/119243058
arduino超声波测距: https://blog.csdn.net/TonyIOT/article/details/103232332
控制模块模块图
在这里插入图片描述

#include <SoftwareSerial.h> 
// Pin10接HC05的TXD
// Pin1接HC05的RXD

String comdata = "";
int timeb=0;
SoftwareSerial BT(10, 11); 
char val;
// 设定SR04连接的数字引脚
const int trigPin = 7; //设置接受引脚
const int echoPin = 8; //设置发射引脚


float sound_spd=343;//声速初始值
float distance; //距离


void setup() {
  Serial.begin(115200); 
  Serial.println("bluetooth is ready!蓝牙准备就绪");
  BT.begin(9600);
   pinMode(trigPin, OUTPUT); 
  // 要检测引脚上输入的脉冲宽度,需要先设置为输入状态
  pinMode(echoPin, INPUT);   
pinMode(6, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
digitalWrite(5, LOW);
  Serial.println("HC-SR04-2019.7.14测距开始:");
digitalWrite(23, HIGH);
digitalWrite(24, LOW);
digitalWrite(25, LOW);
}
 
void loop() {
// 产生一个10us的高脉冲去触发TrigPin 
  digitalWrite(trigPin, LOW); 
  delayMicroseconds(2); 
  //产生高脉冲前线产生2us低脉冲,确保高脉冲的纯净
  digitalWrite(trigPin, HIGH); 
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW); 
    // 检测脉冲宽度,并计算出距离
  distance = pulseIn(echoPin, HIGH)/ 58.00;
 
        Serial.print(distance);                                //把得到的距离值通过串口通信返回给电脑,通过串口监视器显示出来
        Serial.println("cm"); 

 if(distance<=20){
  digitalWrite(6, HIGH);
 }
else{
  digitalWrite(6, LOW);
}
 delay(300);                                  //500mS测量一次


  while (BT.available() > 0)  
    {
        comdata += char(BT.read());
        delay(2);
    }
    if (comdata.length() > 0)
    {
        Serial.println(comdata);
        timeb=comdata.toFloat();
        if(timeb<0){
          下降
        }
        else if(timeb>0&&timeb<998){
          上升
        }
        else if(timeb==999){
          不动
        }
        comdata = "";
    }
}

动力模块

动力模块用来控制升降平台的升降由于需要24v电源无法由主板直接供电所以我们使用继电器用主板的5v电压来控制更高的电压
arduino继电器使用: https://blog.csdn.net/TonyIOT/article/details/82875925

在这里插入图片描述

继电器1用来控制上升接IN1连接arduino 4号引脚
继电器2用来控制下降接IN2连接arduino 5号引脚
继电器1来控制整个动力模块的电源通断接IN3连接arduino 3号引脚
电源与升降台连接图
在这里插入图片描述

#include <SoftwareSerial.h> 
// Pin10接HC05的TXD
// Pin1接HC05的RXD

String comdata = "";
int timeb=0;
SoftwareSerial BT(10, 11); 
char val;
// 设定SR04连接的数字引脚
const int trigPin = 7; //设置接受引脚
const int echoPin = 8; //设置发射引脚


float sound_spd=343;//声速初始值
float distance; //距离


void setup() {
  Serial.begin(115200); 
  Serial.println("bluetooth is ready!蓝牙准备就绪");
  BT.begin(9600);
   pinMode(trigPin, OUTPUT); 
  // 要检测引脚上输入的脉冲宽度,需要先设置为输入状态
  pinMode(echoPin, INPUT);   
pinMode(6, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
digitalWrite(5, LOW);
  Serial.println("HC-SR04-2019.7.14测距开始:");
digitalWrite(23, HIGH);
digitalWrite(24, LOW);
digitalWrite(25, LOW);
}
 
void loop() {




// 产生一个10us的高脉冲去触发TrigPin 
  digitalWrite(trigPin, LOW); 
  delayMicroseconds(2); 
  //产生高脉冲前线产生2us低脉冲,确保高脉冲的纯净

  digitalWrite(trigPin, HIGH); 
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW); 


    // 检测脉冲宽度,并计算出距离
  distance = pulseIn(echoPin, HIGH)/ 58.00;
 
        Serial.print(distance);                                //把得到的距离值通过串口通信返回给电脑,通过串口监视器显示出来
        Serial.println("cm"); 

 if(distance<=20){
  digitalWrite(6, HIGH);
 }
else{
  digitalWrite(6, LOW);
}
 delay(300);                                  //500mS测量一次







  while (BT.available() > 0)  
    {
        comdata += char(BT.read());
        delay(2);
    }
    if (comdata.length() > 0)
    {
        Serial.println(comdata);
        timeb=comdata.toFloat();
        if(timeb<0){
          digitalWrite(3, LOW); 
          digitalWrite(5, HIGH);
          delay(timeb*1000*-1);
          digitalWrite(3, HIGH); 
          digitalWrite(5, LOW);
        }
        else if(timeb>0&&timeb<998){
          digitalWrite(3, LOW); 
          digitalWrite(4, HIGH);
          Serial.println(timeb);
          delay(timeb*1000);
          digitalWrite(3, HIGH); 
          digitalWrite(4, LOW);
        }
        else if(timeb==999){
          digitalWrite(3, LOW); 
          digitalWrite(5, HIGH);
          delay(1000);
          
          digitalWrite(5, LOW);
          
          digitalWrite(4, HIGH);
          delay(1000);
          digitalWrite(3, HIGH); 
          digitalWrite(4, LOW);
        }
        comdata = "";
    }

   
 
  
}

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

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

相关文章

物奇平台超距断连无蓝牙广播问题解决方法

是否需要申请加入数字音频系统研究开发交流答疑群(课题组)?可加我微信hezkz17, 本群提供音频技术答疑服务,+群赠送语音信号处理降噪算法,蓝牙耳机音频,DSP音频项目核心开发资料, 物奇平台超距断连无蓝牙广播问题解决方法 一 问题反馈 二解决方法: 1 运行流程分析 对应代…

【RabbitMQ】RabbitMQ的交换机

交换机类型 在上文中&#xff0c;都没有交换机&#xff0c;生产者直接发送消息到队列。而一旦引入交换机&#xff0c;消息发送的模式会有很大变化&#xff1a;可以看到&#xff0c;在订阅模型中&#xff0c;多了一个exchange角色&#xff0c;而且过程略有变化&#xff1a; Pub…

数据结构与算法第三套试卷小题

1.删除链表节点 **分析&#xff1a;**首先用指针变量q指向结点A的后继结点B&#xff0c;然后将结点B的值复制到结点A中&#xff0c;最后删除结点B。 2.时间复杂度的计算 **分析&#xff1a;**当涉及嵌套循环的时候&#xff0c;我们可以直接分析内层循环即可&#xff0c;看内…

小白优化Oracle的利器”sqltrpt.sql”脚本

SQL调优顾问是Oracle自带的一个功能强大的内部诊断工具&#xff0c;用于对性能不佳的SQL语句给出优化建议。但如果从命令行调用它比较麻烦&#xff0c;幸运的是&#xff0c;Oracle提供了一个方便的内置脚本“sqltrpt.sql”&#xff0c;简化了调用过程。 sqltrpt.sql脚本位于Or…

实践:qemu 运行 linux riscv with AIA(APLICIMSIC)

RISCV架构 Linux AIA支持 目标&#xff1a;在 Qemu 中运行一个支持 riscv aia 的 linux 翻译参考自&#xff1a;https://lwn.net/Articles/963231/ 文章日期&#xff1a;2024年2月22日&#xff0c;星期四&#xff08;截至2024年3月&#xff0c;最新&#xff09; 这个网站里在不…

EasyExcel导出自定义表格

谈到新技术&#xff0c;每个人都会有点恐惧&#xff0c;怕处理不好。确实&#xff0c;第一次使用新技术会遇到很多坑&#xff0c;这次使用 EasyExcel 这个新技术去做 excel 导出&#xff0c;还要给表格加样式&#xff0c;遇到不同的版本问题&#xff0c;遇到颜色加错了地方&…

JavaEE企业开发新技术2

目录 2.7 Field类的基本概念 文字性概念描述&#xff1a; Field类 2.8 Field的基本操作-1 2.9 Field的基本操作-2 分析&#xff1a; 2.10 Field 的综合练习 总结&#xff1a; 和equals的区别&#xff1a; 使用 比较 使用equals比较 2.7 Field类的基本概念 文字性…

OpenCV 图像的几何变换

一、图像缩放 1.API cv2.resize(src, dsize, fx0,fy0,interpolation cv2.INTER_LINEAR) 参数&#xff1a; ①src &#xff1a;输入图像 ②dsize&#xff1a;绝对尺寸 ③fx&#xff0c;fy&#xff1a;相对尺寸 ④interpolation&#xff1a;插值方法 2.代码演示 import cv2 …

前端报错404,nginx正常、gateway没有转发请求

问题描述&#xff1a;前端报错 404 Not Found 原因&#xff1a;nacos中对应服务没有上线&#xff0c;下线后&#xff0c;可以启动本地服务&#xff0c;然后在测试上调试代码。&#xff01;&#xff01; 记住重启对应服务&#xff0c;也不会自动上线。

JVM的内存区域

JVM内存区域最粗略的划分可以分为堆和栈&#xff0c;当然&#xff0c;按照虚拟机规范&#xff0c;可以划分为以下几个、区域 Java虚拟机运行时数据区 JVM内存分为线程私有区和线程共享区&#xff0c;其中方法区和堆是线程共享区&#xff0c;虚拟机栈、本地方法栈和程序计数器是…

植物病害识别:YOLO水稻病害识别/分类数据集(2000多张,2个类别,yolo标注)

YOLO水稻病害识别/分类数据集&#xff0c;包含疾病和正常2类&#xff0c;共2000多张图像&#xff0c;yolo标注完整&#xff0c;可直接训练。 适用于CV项目&#xff0c;毕设&#xff0c;科研&#xff0c;实验等 需要此数据集或其他任何数据集请私信

floodfill算法题目

前言 大家好&#xff0c;我是jiantaoyab&#xff0c;在下面的题目中慢慢体会floodFill算法&#xff0c;虽然是新的算法&#xff0c;但是用的思想和前面的文章几乎一样&#xff0c;代码格式也几乎一样&#xff0c;但不要去背代码 图像渲染 https://leetcode.cn/problems/flood…

事物的传播属性

事务传播属性是Spring框架在处理事务时的一个重要概念&#xff0c;它定义了在事务方法被另一个事务方法调用时&#xff0c;如何处理事务边界的行为。这些属性是通过Spring的Transactional注解中的propagation属性来设置的。下面是几个常见的Spring事务传播属性&#xff1a; *RE…

生成式 AI:使用 Pytorch 通过 GAN 生成合成数据

导 读 生成对抗网络&#xff08;GAN&#xff09;因其生成图像的能力而变得非常受欢迎&#xff0c;而语言模型&#xff08;例如 ChatGPT&#xff09;在各个领域的使用也越来越多。这些 GAN 模型可以说是人工智能/机器学习目前主流的原因&#xff1b; 因为它向每个人&#xff0…

RK3568 xhci主控挂死问题

串口日志 rootjenet:~# [18694.115430] xhci-hcd xhci-hcd.1.auto: xHCI host not responding to stop endpoint command. [18694.125667] xhci-hcd xhci-hcd.1.auto: xHCI host controller not responding, assume dead [18694.125977] xhci-hcd xhci-hcd.1.auto: HC died; c…

微软模拟飞行器回放功能

参考b站up主&#xff0c;欢迎大家去关注&#xff1a;https://www.bilibili.com/video/BV1Z34y1P7zz/?spm_id_from333.880.my_history.page.click&vd_source4e0b40493e2382633fab2ddc1bb1d9cc 下载网址&#xff1a;https://flightsim.to/file/8163/flight-recorder 坠毁检…

嘿!AI 编码新玩法上线!

随着 AI 智能浪潮到来&#xff0c;AI 编码助手成为越来越多开发者的必备工具&#xff0c;将开发者从繁重的编码工作中解放出来&#xff0c;极大地提高了编程效率&#xff0c;帮助开发者实现更快、更好的代码编写。 通义灵码正是这样一款基于阿里云通义代码大模型打造的智能编码…

如何保证消息的顺序性

先看看顺序会错乱的场景&#xff1a;RabbitMQ&#xff1a;一个 queue&#xff0c;多个 consumer&#xff0c;这不明显乱了&#xff1a; 解决方案&#xff1a;

代码背后的女性:突破性别壁垒的技术先驱

个人主页&#xff1a;17_Kevin-CSDN博客 收录专栏&#xff1a;《程序人生》 引言 在计算机科学的历史长河中&#xff0c;有许多杰出的女性为这个领域的发展做出了重要贡献。她们不仅在技术上取得了卓越成就&#xff0c;还打破了性别壁垒&#xff0c;为后来的女性树立了榜样。今…

22 Dytechlab Cup 2022C. Ela and Crickets(思维、找规律、模拟)

思路就是找规律 可以发现&#xff0c;当拐点在角落时的情况和不在角落的情况是不同 当拐点在角落时&#xff0c;只有目标点的横纵坐标其中的一个和它相同时&#xff0c;这时才可能到达。 否则&#xff0c;我们就简单的例子可以看一下&#xff0c;当一个 2 ∗ 2 2*2 2∗2的矩阵的…