2023年电赛---运动目标控制与自动追踪系统(E题)OpenMV方案

前言

(1)废话少说,很多人可能无法访问GitHub,所以我直接贴出可能要用的代码。此博客还会进行更新,先贴教程和代码
(2)
<1>视频教程: https://singtown.com/learn/49603/
<2>OpenMV追云台官方Github链接 :https://github.com/SingTown/OpenMV-Pan-Tilt/tree/master/pan-tilt/src
(3)有些人肯定说红点太小了,OpenMV不行精度不够,看这个C站上做出来的阈值代码:https://blog.csdn.net/weixin_52385589/article/details/126334744
(4)赛事方肯定不可能直接让你上现成的玩意,不然比赛的意义在哪里?我看了一下网上的一些讨论。肯定是要用摄像头的,K210好像有官方库,K210的同学可以了解一下。
(5)OpenMV的话需要多训练,建议最好做灯光补偿,毕竟OpenMV对灯光要求很高,环境光线一点要稳定!!!
注意:有网友反馈,官方说不能使用灯光补偿。我没得到相关信息,请各位确认之后再决定要不要使用灯光补偿。
(6)各位,有问题尽量C站私信。因为评论太多了,我容易漏掉。(虽然写评论区可以给我加热度,哭)
(7)这篇博客是会根据情况实时更新的,所以请各位注意刷新。
(8)再次强调,提供的都是伪代码!!!肯定会报错!!!要自己调整!!!我只提供思路,饭都端上来了,还不能吃吗?!
(9)更新日记:
<1>2023年8月2日,上午9点。OpenMV官方的追云台代码,以及相关解读。
<2>2023年8月2日,上午10点。增加C站另一位大佬的调试结果代码。
<3>2023年8月2日,下午2点。更改错别字,增加基础题思路。
<4>2023年8月2日,下午2点10分。增加网友的一些提问。
<5>2023年8月2日,下午2点40分。更改了前言部分,希望各位问问题私信我,因为写在评论区有时候会被刷新掉。
<6>2023年8月2日,下午2点50分。更新了基础题的思路,第四问还有待商榷。
<7>2023年8月2日,下午3点。更新了网友的一些问题
<8>2023年8月2日,下午3点40分。关于OpenMV的鱼眼畸变可能带来的问题,增加了软硬件解决方案。
<9>2023年8月2日,下午4点35分。关于代码报错问题回复,器件选择问题。
<10>2023年8月2日,下午5点30分。更新关于购买推荐的OpenMV云台可能导致的问题,以及据说可行的现成方案。
<11>2023年8月2日,下午6点。更新鱼眼畸变代码报错问题,基础题的第一问和第二问代码给出来了
<12>2023年8月2日,下午6点20分。更新了关于博客视频的资料在哪里,关于代码怎么获取。
<13>2023年8月2日,下午6点40分。关于K210,OpenART mini,OpenMV代码问题回答。
<14>2023年8月2日,下午7点30分。回答网友,舵机抽搐问题,OpenMV与主控通讯,第一问和第二问舵机控制不稳定。
<15>2023年8月2日,下午9点20分。更新推荐舵机,数字舵机比模拟舵机精度更高。
<16>2023年8月3日,12点睡觉前最后一次更新。关于激光和OpenMV安装位置。
<17>2023年8月3日,9点50分。更新了OpenART mini移植到OpenMV的方案,将网友回答专门组成了一篇博客。
<18>2023年8月3日,10点30分。更新发挥题目思路。
<19>2023年8月3日,11点30分。将目前反馈可行方案放在了最醒目的地方。
<20>2023年8月4日,9点20分。将基础题第三问进行了微调。将基础题和发挥题分离。发挥题还在补充思路,基础题也会在中午前补充完思路。请不要着急。
<21>2023年8月4日,10点30分。基础题的所有测试思路都给出来了,伪代码也给了,硬件测试思路也给了,还做不出来,真的就一点救都没有了。

网上所宣传的现成可行方案

OpenART mini的同学看这个

(1)我看网上有人说OpenART mini有一个现成的方案。如果会OpenART mini的同学,可以尝试。以下是这个资料
(2)百度网盘资料:
OpenART min模块资料链接:https://pan.baidu.com/s/1yoCNXzci_dfHzW33emxdLA
提取码:mxx8

在这里插入图片描述

(3)关于云台控制:
<1>云台由两个舵机组成,下面的舵机控制偏航角(左右)旋转,上面的舵机控制俯仰角(上下)旋转。
<2>如果在云台上面安装一个激光发射装置,当我们控制单个舵机旋转时,观察激光路径发现是一条直线,并且云台的两个舵机路径分别是一个水平和一个垂直的直线,如果我们同时控制两个舵机旋转的舵机就可以实现在一个面的任意位置激光投影。
<3>若此时我们需要控制舵机按照设定的固定路径移动,当路径为线段时,仅需要知道线段的起点坐标和终点坐标即可(坐标对应舵机的高电平时间,也就是占空比),如果直接将起点和终点输出到云台舵机,会发现虽然到达了起点和终点,但路径并非直线路径,这是由于X轴和Y轴移动距离不一致而产生的,因此需要将这条线段细分,比如通过起点坐标和终点坐标将线段细分为1000份,每次仅移动一份的距离,此时就会发现激光的路径沿着线段逐渐移动了。
<4>如果需要移动的路径为一个闭合矩形,我们仅需得到矩形的四个角的坐标,按照上面线段的分段移动的方式,分别将四条边细分后再控制舵机逐渐移动,即可实现看起来较为丝滑的闭合矩形路径。
<5>在编写控制程序时,如果采用这样分段移动的方式,那么我们可以将程序段放置在周期中断内执行,此时就可以确立单次移动的时间,从而控制整体的移动速度。移动速度的控制是必须的,不管是路径稳定还是点位追踪都需要涉及到移动速度的精准控制。
(4)E题中所涉及到的主控型号赛题没有任何限制,可以使用智能车竞赛中的核心板(例如RT1064、TC264、CH32V307、STC),其中RT1064主板有三个舵机接口,可以比较方便控制云台,激光也没有限制,只要求了光斑大小小于等于1厘米即可。
(4)关于这个方案的相关影像资料:

1

2


5


4

6

OpenMV的同学看这个

点开这个链接:2023年电赛—运动目标控制与自动追踪系统(E题)OpenART mini的代码移植到OpenMV

硬件注意事项

接线问题

(1)我们这里是使用的OpenMV的P8和P7引脚。所以建议引脚如下图引出。
(2)舵机一般是5V供电,所以注意VCC是供5V的电压。而右边那两个GND和VCC是连接OpenMV的。如果右边的VCC是连接OpenMV的VIN引脚,就可以供5V电。如果是连接OpenMV的3.3V引脚,iu只能供3.3V电压。否则OpenMV会被烧掉!
(3)舵机的VCC要直接连接电池,因为如果通过OpenMV连接,OpenMV的输出电流太小,带不动舵机!

在这里插入图片描述

云台购买推荐

(1)一开始我推荐使用这一款。后面根据别人反馈,精度不够。所以我还是推荐我之前吐槽的那个奇奇怪怪的舵机啊。(被打脸了,哈哈哈)

在这里插入图片描述

(2)推荐这一款,虽然不需要这么大的扭矩,但是他是数字舵机,精度更高。

在这里插入图片描述

OpenMV鱼眼畸变

(1)我刚刚上机测试了一下,突然发现OpenMV存在鱼眼畸变。
(2)鱼眼畸变就是,摄像出来的图片就像鱼的眼睛看到的图片一样,不是平的。
(3)这个会不会有影响不清楚。
(4)从硬件上处理办法就是换一个无畸变镜头,官方链接 :
https://item.taobao.com/item.htm?spm=a1z10.1-c-s.w5003-18207055866.1.6b0b1dc1nPB6IZ&id=601956249175&scene=taobao_shop
(5)来不及的话,可以使用软件方法。但是我测试了,好像没有反应。
<1>我们购买的OpenMV的默认镜头是带鱼眼效果的,所以需要进行畸变矫正(注意:此处运算量大,不建议长时间使用OpenMV不然会发烫很严重
<2>因为我们这里没有指定是传入的zoom,x_corr,y_corr的值,所以按照顺序,传入的1.8是给strength。我们可以调节这个值,来查看即便矫正的效果,建议从1.8开始尝试。
<3>zoom就是进行图像缩放,比如10X10的图像,为0.5,就算5X5的图像。建议为默认值,只需要调节strength就行了。
<4>后面这个x和y是什么,官方文档没有解释。
(6)真的太多人不喜欢认真看博客了,说了是伪代码,要自己调整。还要问!我这里还是给这真正0~基础的人,贴出来,别再问了!

import sensor, image
img = sensor.snapshot() # 截取一张图片
img.lens_corr(1.8)  #去除鱼眼畸变

在这里插入图片描述

出现Frame capture has timed out. 帧捕获超时了

(1)如果是我贴出来的代码,出现这个bug。你重新开机启动应该就可以了。
(2)如果还不可以,就说明你OpenMV坏了。要快点换一个。

在这里插入图片描述

基础题思路

(1)以下均为个人思路,仅供参考。
(2)个人认为基础题不需要使用PID,只需要一个OpenMV,两个舵机,一个云台就可以了。
(3)OpenMV控制舵机的教程:OpenMV输出PWM,实现对舵机控制
(4)根据网友反馈,本题不需要用PID!常见的数字舵机就行了!!!别跟我扯算法!!!

第一问—复位

(1)这个比较简单,我感觉只需要写入一个固定值,给舵机一个固定的PWM就可以了。
(2)关于按键问题,你们可以使用下面的函数实现。
<1>这里的pyb.Pin第一个参数是你用于读取按键值的。
<2>第二个参数可以获得引脚上的按键值。
<3>按键电路如下,并联上一个104的电容,是用于硬件消抖。

import pyb
p = pyb.Pin("P0", pyb.Pin.IN)
key_value = p.value() # Returns 0 or 1.

在这里插入图片描述

第二问—沿A4纸移动

(1)和第一问一样,我认为写一个死的程序就行了,因为他的屏幕给定了0.5m*0.5m。
(2)有一些人问第一问和第二问切换问题

import pyb, time
p = pyb.Pin("P0", pyb.Pin.IN)
clock = time.clock() # 追踪帧率,影响不大
while True:
	key_value = p.value() # Returns 0 or 1.
    if key_value == 1:
        key_time_first  = clock.tick() #开始计时
        Task1 = 1
        while key_value == 1: #一直等待松手
            pass
    if key_value == 0:  #确认松手
        key_time_last = clock.avg()
        if(key_time_last-key_time_first> 2000) :  #如果按键按下时间超过2s
            # 进入任务2
            pass   # 这个是表示不进行任何操作!!!
        elif Task1 == 1 : #如果按键按下时间小于1s
            # 进入任务1
            pass

第三问—黑色边框检测

(1)时间太紧急了,我就讲一下思路。
<1>我们使用blobs = img.find_rects([red_threshold]),找到黑色边框。
<2>调用max_blob = find_max(blobs),找到最大的黑色边框。因为可能存在其他的干扰。
<3>找到边框之后,调用max_blob.x(),max_blob.y(),max_blob.w(),max_blob.h()分别获得识别到的边框左上角的x坐标,y坐标,宽度和长度。
<4>不明白的可以看下面这个图,假设0包含的地方是屏幕,11选中的是黑框内,我们最终返回的值如下图。
(2)有网友提供,说出现了NameError:name img isn’t defined的报错。是因为我只是截取了代码中的一部分。前面的没写,为了方便新手朋友使用,我还是加上。
(3)但是,请各位注意,摄像头的初始化

import sensor, image, time

sensor.reset() # 初始化摄像头传感器
sensor.set_pixformat(sensor.RGB565) # 使用 RGB565 彩图
sensor.set_framesize(sensor.QQVGA) # 使用 QQVGA 分辨率
sensor.skip_frames(10) #跳过几帧,让新的设置生效。
sensor.set_auto_whitebal(False) # 因为是颜色识别,所以需要把白平衡关闭
clock = time.clock() # 追踪帧率,影响不大
#__________________________________________________________________
#定义寻找最大色块的函数,因为图像中有多个色块,所以追踪最大的那个
def find_max(blobs):
    max_size=0
    for blob in blobs:
        if blob[2]*blob[3] > max_size:
            max_blob=blob
            max_size = blob[2]*blob[3]
    return max_blob
#__________________________________________________________________
while(True):
	clock.tick() # 跟踪快照()之间经过的毫秒数。
	img = sensor.snapshot() # 截取一张图片
	blobs =  img.find_rects(threshold = 10000) #识别矩形框
	max_blob = find_max(blobs)  #调用上面自定义函数,找到最大色块
	max_blob.x()  #返回识别区域左上角的x坐标
	max_blob.y()  #返回识别区域左上角的y坐标
	max_blob.w()  #返回识别区域的宽度
	max_blob.h()  #返回识别区域的长度

在这里插入图片描述

第四问—黑色边框检测

(1)这个和第三问舵机控制有区别,第三问是一个舵机一个舵机的控制。而这一题需要两个舵机同时控制。
(2)看2023年电赛—运动目标控制与自动追踪系统(E题)OpenART mini的代码移植到OpenMV这一篇博客

关于基础题的硬件调试思路

(1)需要准备的器材:示波器,信号发生器,万用表。
(2)很多人反馈数字舵机不行,我的方法不行。而也有一部分同学说我的方法是可行的。所以说我希望各位先测试一下,是不是自己硬件上出现的问题。

数字舵机,机械结构的检测方法

(1)我们先找到一个信号发生器,让信号发生器上产生一个PWM波形。然后通过调节信号发生器上的PWM,让云台沿着正方形框框移动。
(2)同时,我们观察是否能够很好的运行。如果可以,记录下来沿着正方形框框运动的四个点位PWM值。 如果不可以很好的运行,说明你的云台或者说舵机有问题,快点换!
(3)如果可以,我们开始测量舵机的最小分辨率。数字舵机是有一个最小分辨率的,比如说,你一个20ms周期的方波,高电平是500us和高电平550us的情况可能是一样的!也就是说,你这一款舵机的分辨率达不到50us的精度!
(4)测试舵机分辨率,我建议从500us开始测试。然后改变了高电平持续时间,一直调整到发现舵机有移动了!那么就说明找到了舵机分辨率。找到分辨率之后,记录下来,之后有用。

PWM输出的稳定性测量

(1)你将上面记录下来的PWM值,编程写出来。然后拿示波器测试,看看能否产生指定的PWM值。
(2)如果示波器上能够输出你记录的四个点位,否则说明你程序有问题或者是主控坏了。那么把结构拼装好。然后开机测试,注意,这里不需要进行图像识别!!!只是单纯的四个PWM点位输出!!!
(3)如果云台能够按照指定的四个点位运行,那么你第二问就做出来了 。如果没有,说明你接线有问题!
(4)怎么知道哪里接线有问题呢?那万用表测试,开到蜂鸣器挡位,一点一点的测试主控和云台的接线,如果发现哪里蜂鸣器不叫,或者是叫的断断续续的,说明有可能接线不稳定!!!
(5)这个时候就要加上焊锡固定了。

如何找到PWM输出量和图像数据的关系

(1)找关系的事情,我建议OpenMV先和电脑连接上,使用print函数将矩形的四个点位数据打印到电脑终端。
(2)然后拿信号发生器输出PWM,看看舵机每运转动一个最小分辨率,像素点移动多少。找到像素点移动的值之后,记录像素点,和PWM高电平变化。进行建模分析,应该是线性关系。
(3)建模完成之后,将这个线性关系编程,然后第三问就做出来了。

关于第四问的细分路线

(1)这个时候,上面用信号发生器检测出来的舵机最小分辨率就有作用了。
(2)我们通过线性建模关系和最小分辨率,可以计算出,此次运动要进行多少次细分。也不一定要根据最小分辨率来啊!
(3)伪代码如下

//假设这是一个20ms的中断
void 20ms_interrupt()
{
	x_PWM_max = x_linearity(x_img); //通过你找到的线性关系,将像素点值转换成PWM值
	y_PWM_max = y_linearity(y_img); //通过你找到的线性关系,将像素点值转换成PWM值
	if(x_PWM_current < x_PWM_max ) //PWM限幅
	{
		x_PWM_current += x_PWM_interval; //每次增加最小分辨率个PWM值
		PWM_SET(x_PWM_current ); //调用PWM输出函数,将PWM值输出
	}
	if(y_PWM_current < y_PWM_max ) //PWM限幅
	{
		y_PWM_current += y_PWM_interval; //每次增加最小分辨率个PWM值
		PWM_SET(y_PWM_current ); //调用PWM输出函数,将PWM值输出
	}
}

发挥题思路链接

点开链接:2023年电赛—运动目标控制与自动追踪系统(E题)发挥题思路

网友提问 和 E题官方解释

问问题前先看这个!
点开这个链接:2023年电赛—运动目标控制与自动追踪系统(E题)关于网友的问题回复

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

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

相关文章

自己实现Linux 的 cp指令

cp指令 Linux的cp指令就是复制文件&#xff1a; cp: 拷贝(cp 拷贝的文件 要拷贝到的地址或文件)&#xff0c;cp b.c test.c 将b.c拷成test.c的一个新文件 Linux 系统初识_mjmmm的博客-CSDN博客 实现思路 打开源文件读文件内容到缓冲区创建新文件将读到的文件内容全部写入新文…

在家下载Springer、IEEE、ScienceDirect等数据库论文的论文下载工具

Springer、IEEE、ScienceDirec数据库是我们查找外文文献常用数据库&#xff0c;当我们没有数据库使用权限的时该如何下载这些数据库的学术论文呢&#xff1f;下面就讲解一下在家下载数据库学术文献的论文下载工具。 一、查找下载外文文献&#xff0c;我们可以谷歌学术检索&…

LeetCode-Java(05)

19. 删除链表的倒数第 N 个结点 两个方法&#xff0c;方法一是先走一遍链表得出链表长度&#xff0c;再走第二遍&#xff0c;找到倒数第n个数。方法二是双指针&#xff0c;首先快指针就比慢指针多走n步&#xff0c;然后这俩指针同步走&#xff0c;快指针走到头了&#xff0c;慢…

python-Excel数据模型文档转为MySQL数据库建表语句(需要连接数据库)-工作小记

将指定Excel文档转为create table 建表语句。该脚本适用于单一且简单的建表语句 呈现效果 代码 # -*- coding:utf-8 -*- # Time : 2023/8/2 17:50 # Author: 水兵没月 # File : excel_2_mysql建表语句.py import reimport pandas as pd import mysql.connectordb 库名mydb m…

List集合的对象传输的两种方式

说明&#xff1a;在一些特定的情况&#xff0c;我们需要把对象中的List集合属性存入到数据库中&#xff0c;之后把该字段取出来转为List集合的对象使用&#xff08;如下图&#xff09; 自定义对象 public class User implements Serializable {/*** ID*/private Integer id;/*…

python编写小程序有界面,python编写小程序的运行

大家好&#xff0c;小编为大家解答python编写小程序怎么看代码的的问题。很多人还不知道python编写小程序的运行&#xff0c;现在让我们一起来看看吧&#xff01; Python第一个简单的小游戏 temp input("请猜一猜姐姐的幸运数字是&#xff1a; ") guess int(temp) …

蓝桥杯上岸每日N题 第八期 (全球变暖)!!!

蓝桥杯上岸每日N题第八期(全球变暖)&#xff01;&#xff01;&#xff01; 同步收录 &#x1f447; 蓝桥杯上岸必背&#xff01;&#xff01;&#xff01;(第五期BFS) 大家好 我是寸铁&#x1f4aa; 冲刺蓝桥杯省一模板大全来啦 &#x1f525; 蓝桥杯4月8号就要开始了 &am…

Python(六十八)元组的创建方式

❤️ 专栏简介&#xff1a;本专栏记录了我个人从零开始学习Python编程的过程。在这个专栏中&#xff0c;我将分享我在学习Python的过程中的学习笔记、学习路线以及各个知识点。 ☀️ 专栏适用人群 &#xff1a;本专栏适用于希望学习Python编程的初学者和有一定编程基础的人。无…

.Net6 Web Core API 配置 Autofac 封装 --- 依赖注入

目录 一、NuGet 包导入 二、Autofac 封装类 三、Autofac 使用 四、案例测试 下列封装 采取程序集注入方法, 单个依赖注入, 也适用, 可<依赖注入>的地方配置 一、NuGet 包导入 Autofac Autofac.Extensions.DependencyInjection Autofac.Extras.DynamicProxy 二、Auto…

AIDL与HIDL核心概念

目录 一. 概述 二. 核心流程的核心理解 三. 一些术语 四. 参考样例 一. 概述 AIDL和HIDL都是主要用于跨进程通信&#xff0c;本质是Binder通信。 总体流程都是先写.aidl文件或.hal文件&#xff0c;这个文件只有接口定义哦不是实现&#xff0c;然后利用工具自动生成代码&a…

kafka 理论知识

1 首先要了解kafka是什么 Kafka是一个分布式的消息订阅系统 1.1 kafka存储消息的过程 消息被持久化到一个topic中&#xff0c;topic是按照“主题名-分区”存储的&#xff0c;一个topic可以分为多个partition&#xff0c;在parition(分区)内的每条消息都有一个有序的id号&am…

【修正-高斯拉普拉斯滤波器-用于平滑和去噪】基于修正高斯滤波拉普拉斯地震到达时间自动检测研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

unraid docker桥接模式打不开页面,主机模式正常

unraid 80x86版filebrowser&#xff0c;一次掉电后&#xff0c;重启出现权限问题&#xff0c;而且filebrowser的核显驱动不支持amd的VA-API 因为用不上核显驱动&#xff0c;解压缩功能也用不上&#xff0c;官方版本的filebrowser还小巧一些&#xff0c;18m左右 安装的时候总是…

第三章 图论 No.3 flody之多源汇最短路,传递闭包,最小环与倍增

文章目录 多源汇最短路&#xff1a;1125. 牛的旅行传递闭包&#xff1a;343. 排序最小环&#xff1a;344. 观光之旅345. 牛站 flody的四个应用&#xff1a; 多源汇最短路传递闭包找最小环恰好经过k条边的最短路 倍增 多源汇最短路&#xff1a;1125. 牛的旅行 1125. 牛的旅行 …

数学建模—多元线性回归分析

第一部分&#xff1a;回归分析的介绍 定义&#xff1a;回归分析是数据分析中最基础也是最重要的分析工具&#xff0c;绝大多数的数据分析问题&#xff0c;都可以使用回归的思想来解决。回归分析的人数就是&#xff0c;通过研究自变量X和因变量Y的相关关系&#xff0c;尝试去解释…

医疗知识图谱问答 ——Neo4j 基本操作

前言 说到问答机器人&#xff0c;就不得不说一下 ChatGPT 啦。一个预训练的大预言模型&#xff0c;只要是人类范畴内的知识&#xff0c;似乎他回答得都井井有条&#xff0c;从写文章到写代码&#xff0c;再到解决零散琐碎的问题&#xff0c;不光震撼到我们普通人&#xff0c;就…

本地 shell无法连接centos 7 ?

1、首先检查是否安装ssh服务&#xff1b; yum list installed | grep openssh-server# 没有安装尝试安装下 yum install openssh-server 2、检查ssh服务是否开启 systemctl status sshd.service# 未开启&#xff0c;开启下 systemctl start sshd.service # 将sshd 服务添…

MySQL多表查询 (超详细)

一、多表关系 项目开发中&#xff0c;在进行数据库表结构设计时&#xff0c;会根据业务需求及业务模块之间的关系&#xff0c;分析并设计表结构&#xff0c;由于业务之间相互关联&#xff0c;所以各个表结构之间也存在着各种联系&#xff0c;基本上分为三种: 一对多&#xff0…

类与对象【中】

欢迎来到Cefler的博客&#x1f601; &#x1f54c;博客主页&#xff1a;那个传说中的man的主页 &#x1f3e0;个人专栏&#xff1a;题目解析 &#x1f30e;推荐文章&#xff1a;题目大解析2 目录 &#x1f449;&#x1f3fb;类的默认6个成员函数&#x1f449;&#x1f3fb;构造…

常用HTML标签大全

&#x1f9d1;‍&#x1f4bb;作者名称&#xff1a;DaenCode &#x1f3a4;作者简介&#xff1a;啥技术都喜欢捣鼓捣鼓&#xff0c;喜欢分享技术、经验、生活。 &#x1f60e;人生感悟&#xff1a;尝尽人生百味&#xff0c;方知世间冷暖。 文章目录 一.HTML介绍二.HTML使用2.1.…