如何手工DIV一个小车:基于树莓派和总线舵机的智能小车实现

成品演示:bilibili - 悄悄的魔法书
代码仓库:github - flying forever 或者 gitee - 清风莫追

文章目录

  • 1 引言
    • 1.1 课题背景
    • 1.2 课题意义
    • 1.3 课题目的
  • 2 课题相关知识与开发环境
  • 3 课题的总体设计
  • 4 课题的详细设计与实现
    • 4.1 小车物理结构
      • 4.1.1 轮子
      • 4.1.2 舵机组装
      • 4.1.3 轮子安装到舵机
      • 4.1.3 防倾倒底盘
    • 4.2 运动模块
      • 4.2.1 嵌入式硬件介绍
      • 4.2.2 单轮独立控制模式
      • 4.2.3 双轮控制模式
      • 4.2.4 动作序列模式
    • 4.3 无线控制
      • 4.3.1 网络结构
      • 4.3.2 服务器程序搭建
      • 4.3.3 客户端设计
    • 4.4 带语义理解的语音控制
      • 4.4.1 语音输入识别
        • 1、WebSpeechAPI
        • 2、stt开源语音识别模型
      • 4.4.2 多API竞速并发
      • 4.4.3 基于大模型的语义理解
      • 4.4.4 进一步展望
  • 5 课题测试
    • 5.1 树莓派本机
    • 5.2 语音控制
    • 5.3 上手操作
  • 6 总结

1 引言

1.1 课题背景

在嵌入式实训课程的要求下,我们需要完成一个和嵌入式硬件搭边的作品设计。鉴于我对stm32不算熟悉,但手里有一块树莓派和一只6自由度机械臂,而且在一个无聊的深夜,我机缘巧合之下用牙签和胶带粘合出了一只轮子,并成功绑定在舵机转轴上。因此我决定,组装一个小车。

早在几个月之前开发web网站时,我就在考虑做语音指令控制的功能。然而当时觉得过于高级,对我技术可行性不高,只是一个妄想,故一直未有尝试。但最近一番折腾之下略有了解,我决定把语音控制功能加到小车上去,变成“智能小车”。

1.2 课题意义

每每看见别人的光彩夺目,便为自己的大学旅途深感羞愧,仿佛光阴虚过,学问毫无,碌碌于一次次考试的应付。然而,理论学习脱离了综合性的实践,它就找不着自己的位置,人就没有自己的方向。

虽然没有涉及动手编写高级的算法,但这是一个综合性较强的作品。涉及技术攘括了我大学以来学习的许多课程与领域:python语言,人工智能,Web后端框架,前端UI与逻辑,计算机网络,Linux操作系统,以及与嵌入式相关的——舵机硬件控制。而将它们融于一体的智能小车,算我交上的一份小小答卷。

1.3 课题目的

实现一个支持客户端按键、语音输入两种控制方式的智能小车。并在制作过程中,体会这些零散的课程与技术,是如何支撑起一个综合性的系统,它们各自作为怎样的角色,相互之间又如何地协作。

2 课题相关知识与开发环境

在后文相应部分也有一些说明,这里做下汇总。

  1. 硬件-嵌入式材料:树莓派3B,树莓派扩展板,电源,总线舵机两个,舵机总线两根。
  2. 硬件-DIY材料:牙签、胶带、橡皮筋若干,小木块两个,可乐瓶,水果网套。(并不固定,缺少的材料可自行寻找替代品。
  3. 软件技术-客户端:html+css+javascript, bootstrap, remixicon图标库。
  4. 软件技术-服务器-树莓派:python3.7.3,flask,ZLSDK*(众灵科技提供,控制舵机,没有也没关系,可自己想办法向串口发字符串)*
  5. 软件技术-服务器-语音识别:
    • stt开源模型。github开源地址:https://github.com/jianchang512/stt 。(可选的,你完全可以使用其它的语音识别,无论开源模型、网络API接口。)
    • 讯飞星火大模型api,官方文档:星火认知大模型服务说明 | 讯飞开放平台文档中心 (xfyun.cn) 。
  6. 调试工具:(以下所有都不是必需的,理论上cmd命令行就能干)
    • Xftp7。用于windows电脑与树莓派之间传输文件。
    • Xshell7。ssh远程连接树莓派的命令行终端。
    • RealVNC Viewer。连接树莓派图形界面。(众灵科技提供)
    • nmap。搜索局域网中的活动设备。
    • gpt。人手一个,不懂就问。
    • Remote Development(VSCode插件)。远程连接树莓派,然后你可以像在本地写代码一样流畅。
  7. 相关资料:
    • 树莓派AI视觉机械臂 Jibot3-PI 使用手册。(需要看树莓派及其扩展板介绍,以及总线舵机两个部分。这里不便提供文档,如果你买了众灵科技的舵机,自然会有,否则自行寻找舵机相关资料)

3 课题的总体设计

本作品以树莓派和总线舵机为硬件基础,通过手工DIV组装,最终实现的是一个网络远程控制的智能小车。提供了一个手机客户端的操作界面,可以直接控制小车进行前进、后退、转弯等等操作。同时提供了语音控制,让小车完成用户要求的操作。当然,这些操作需要是被预定义好的。

客户端运行在浏览器中,使用html+css设计界面元素及布局,javascrip编写控制逻辑,通过http请求与部署在树莓派上的后端Flask服务器通信,Flask根据请求参数生成舵机指令字符串,控制舵机的转动,舵机带动轮子,以实现小车运动控制。

在这里插入图片描述

4 课题的详细设计与实现

4.1 小车物理结构

小车主体的制作材料如下:树莓派3B,总线舵机两个,牙签、胶带、橡皮筋若干,小木块两个,可乐瓶,水果网套。

除了轮子有用到胶带粘合。其它部分都只是通过橡皮筋绑定,未来拆卸也会很方便。通过恰当的绑定方式,它具有“哈尔的移动城堡”一样,稍显混乱却具有弹性恢复力的稳定结构。

在这里插入图片描述

4.1.1 轮子

一共是四层结构。

使用牙签骨架,圈上柔软的纸巾胎面。对于轮子的圆度问题,加上了裁剪的塑料瓶。对于抓地力问题,加上了泡沫圈。使用胶带和橡皮筋多层绑定。

4.1.2 舵机组装

每个舵机是单轴的,小车使用两个舵机横向绑定。

使用单纯的橡皮筋力学绑定,缝隙夹住纸块以填充。整体结构具有弹性稳定性和恢复力。

4.1.3 轮子安装到舵机

制作的轮子使用胶带和橡皮筋的双层绑定,固定在舵机的转轴上。

4.1.3 防倾倒底盘

两轮装置必然产生平衡问题。因此在前后加入支撑结构,将牙签用橡皮筋以特殊方式绑在小木块上,受到地面向上支持力时,具有回弹能力。

成品如下。

在这里插入图片描述

4.2 运动模块

4.2.1 嵌入式硬件介绍

电子硬件包括:树莓派3B,树莓派扩展板,电源,总线舵机两个,相应总线两根。通过总线将控制板与舵机连上即可。

树莓派介绍

树莓派介绍Raspberry Pi,中文名为“树莓派”,简写为 RPi,或 RasPi/RPI,是一款只有信用卡大小的计算机。它是一款基于 ARM 的微型电脑主板,可连接键盘、鼠标和网线,同时拥有视频模拟信号的电视输出接口和 HDMI 高清视频输出接口。

扩展板介绍

此款树莓派扩展板是由杭州众灵科技有限公司研发的一款集PWM 舵机控制(标准舵机和 9g 小舵机控制)、本店总线设备控制(总线舵机,总线马达等)、传感器连接,手柄和红外控制的控制器。接口丰富,功能强大。

在这里插入图片描述

总线舵机介绍

传统 PWM 舵机是通过单片机发送 PWM 信号控制舵机转动,总线舵机是舵机内部带有一个主控芯片,内部已完成 PWM 信号控制。只需要通过串口发送字符串指令即可控制舵机。舵机内部的芯片也可以检测舵机的工作状态,所以通过串口也可以读取舵机的角度,切换工作状态。

舵机参数

  1. 舵机供电范围 4.8-8.4V。
  2. 扭力 15kg/cm。
  3. 八种角度工作模式, 270 度角度控制正反转、180 度角度控制正反转、360 度定圈连续旋转正反转、360 度定时连续旋转正反转八种工作模式可切换,同一个舵机可在这八种角度工作模式下
    供用户切换。
  4. 单总线通讯,波特率 115200,舵机之间通过总线串联。 每个舵机都有自己 ID 号,舵机默认 ID 为 0,用户可通过命令改变舵机 ID,255 代表广播地址。
  5. 可回读角度,用户可读取舵机当前实时位置。
  6. 串口指令控制,无需用户编写舵机 PWM 驱动程序, 控制简单。

舵机提供的串口指令(节选)如下。

在这里插入图片描述

4.2.2 单轮独立控制模式

连接在总线上面的每个舵机可以分别独立接收和执行串口指令,独立运动。每个舵机有自己的id,通过指定id,就可以单独操作总线上的某个舵机。

我这里的舵机设置的id分别是左轮子3号,右轮子1号。当然,这个是可以在0~254自由设置的。

此外需要设置舵机的工作模式,这款总线舵机一共有8种工作模式。这里我采用的是模式7(马达模式360度定圈顺时针模式)和模式8(逆时针)。注意硬件连接时两个舵机的朝向是相反的,因此在小车整体向前运动时,左轮舵机采用模式7,则同时右轮舵机需要采用模式8。

class Car:'''提供小车基本动作的封装。'''leftId = 3rightId = 1leftForwardMod = 7  # 左轮(id=3):7前8后 | 右轮(id=2):8前7后......

舵机控制指令封装。

以下代码将串口种使用的字符串指令中,我们需要用到的部分,封装成了函数。这样我们就方便地通过参数进行调用。轮子需要能够向前、向后运动,因此每次运动时需要先发送工作模式设置指令(控制顺时针、逆时针),然后再发送旋转指令。

class Cmds:'''舵机控制指令封装'''@staticmethoddef wheel_mod_cmd(id: int=255, mod: int=1):'''左轮(id=3):7前8后 | 右轮(id=2):8前7后'''return f'#{id:03d}PMOD{mod}!'@staticmethoddef wheel_move_cmd(id: int=255, pwm: int=1700, time: int=1):return f'#{id:03d}P{pwm:04d}T{time:04d}!'@staticmethoddef stop(id: int=255):return f'#{id:03d}PDST!'

小车动作封装。

上面的控制指令封装面向的对象仍然是舵机,使用id、mod(舵机运动模式)等与具体硬件性质相关的参数。

我接下来将舵机作为小车的轮子,进行更抽象的封装。下面包含了movestop两个动作,进行传入参数的解析,并向串口发送相应的指令。

class Car:'''提供小车基本动作的封装。'''...@staticmethoddef mod_reverse(mod: int):return 8 if mod == 7 else 7@staticmethoddef move(forward=True, left=True, pwm: int=1700, t: int=1, excute=True):'''一个轮子的一次移动@excute: False则不执行,仅仅返回命令字符串'''whell_id = Car.leftId if left else Car.rightIdmod_id = Car.leftForwardMod if not forward: mod_id += 1if not left:mod_id = Car.mod_reverse(mod_id)cmd1 = Cmds.wheel_mod_cmd(id=whell_id, mod=mod_id)cmd2 = Cmds.wheel_move_cmd(id=whell_id, pwm=pwm, time=t)if excute:# 否则仅仅返回命令myUart.uart_send_str(cmd1)time.sleep(0.4)  # 否则可能不转myUart.uart_send_str(cmd2)return f'{cmd1} {cmd2}'@staticmethoddef stop(id: int=255):cmd = Cmds.stop(id=id)myUart.uart_send_str(cmd)return cmd...

4.2.3 双轮控制模式

单轮分别控制,理论上可以让小车做出非常灵活的动作,但是这对操作者提出了一定的要求——是有难度的。你有可能半天总在原地打转。

因此我决定进一步封装双轮同时控制。我们可以直接在前面单轮控制的基础上封装,并不复杂。但是,如果简单地顺序调用两次前面的move指令,在实际操作时两个轮子动作之间会产生明显的延迟。

总线舵机支持动作组操作,将可以同时执行的多条指令连接起来,加上“{}”,就可以叠加同时控制多个舵机。比如:{G0000#000P1602T1000!#001P2500T0000!#002P1500T1000!}。

因此在前面的move函数中设置了excute参数,可以在调用时并不实际执行而仅返回相应的指令字符串。于是我们可以在move_double函数中进行进一步的解析和组合,达到双轮同时运动的效果。

class Car:'''提供小车基本动作的封装。'''......@staticmethoddef move_double(forward=True, pwml: int=1700, pwmr: int=1700, t: int=1, turn_left: bool=None):'''两只轮子一起动,使用动作组。(可以差速转弯)'''# 单向运动 | 原地转圈if turn_left is None:fl = fr = forwardelif turn_left:fl, fr = False, Trueelse:fl, fr = True, Falsecmdl = Car.move(forward=fl, left=True, pwm=pwml, t=t, excute=False).split()cmdr = Car.move(forward=fr, left=False, pwm=pwmr, t=t,  excute=False).split()group_mod = '{' + cmdl[0] + cmdr[0] + '}'group_move = '{' + cmdl[1] + cmdr[1] + '}'myUart.uart_send_str(group_mod)time.sleep(0.4)myUart.uart_send_str(group_move)return f'{group_mod} {group_move}'

4.2.4 动作序列模式

很自然地,将一些预定义动作的连续执行封装起来,我们就可以在一次调用中让小车进行丰富的动作,比如:S形走位。然而并不能简单地连续把它们调用一遍。因为舵机的指令是打断式的,即:后面的指令并不会等待前面的执行完。

因此,在发送串口指令后,需要暂停相应的时间等待运动完成。

class CarShow:'''小车的组合动作展示'''@staticmethoddef S_move():'''S形状走位'''groups = [{'forward': True, 'pwml': 1600, 'pwmr': 1600, 't': 1}, {'forward': True, 'pwml': 2000, 'pwmr': 2000, 't': 1, 'turn_left': False},{'forward': True, 'pwml': 1800, 'pwmr': 2500, 't': 4},{'forward': True, 'pwml': 2500, 'pwmr': 1800, 't': 4},{'forward': True, 'pwml': 2500, 'pwmr': 2500, 't': 1, 'turn_left': True},   ]for g in groups:Car.move_double(**g)time.sleep(g['t'])

4.3 无线控制

4.3.1 网络结构

在本次实训中,我打算使用局域网无线通信,这样可以方便地将电脑、手机和树莓派三者拉到同一局域网中。而且实现简单,只需要将某一设备作为热点即可。电脑、手机、树莓派都可以作为热点,但只有将手机作为热点时,电脑和树莓派是可以访问互联网的,查找资料和调试更加方便。

(注意:如果将电脑连接手机热点,然后将树莓派连电脑热点,此时树莓派和手机并不在同一局域网。电脑、手机创建热点时,会分别创建一个独立的局域网。)

综上,将手机作为热点,树莓派和电脑连接它。

但问题是,手机通常并不能查看连接到它的设备的ip地址(仅仅显示mac地址)。我们可以使用nmap工具,进行局域网活动设备扫描。

  • 工具下载:Download the Free Nmap Security Scanner for Linux/Mac/Windows

运行命令如下,图中192.168.43.1是作为热点的手机;在电脑命令行运行ipconfig可以获取电脑ip,这里是192.168.43.166。因此,下面的192.168.43.91即为树莓派ip地址。

nmap -sn 192.168.43.0/24

在这里插入图片描述

4.3.2 服务器程序搭建

我选择了将树莓派作为服务器,收到请求后即可本地调用相应的动作函数,更为方便。服务器程序使用python语言,flask框架编写。服务器和客户端主要采用流行的json数据格式通信。

代码较长不全部贴出,详见附件。通常只需要对数据进行简单处理后,调用运动模块中相应类方法即可。(下面的INPI变量用于调试,在配置文件config.py中设置。因为在你的电脑上调试程序时,没法真正执行对应的动作控制指令。

@app.route('/car', methods=['POST'])
def car():'''小车控制@forward: bool, 前进 / 后退@left: bool, 左轮 / 右轮@pwm: int, 速度@time: int, 持续时间'''data = request.jsonprint('[car]', data)forward, left, pwm, time = data['forward'], data['left'], data['pwm'], data['time']if INPI:cmd = Car.move(forward=forward, left=left, pwm=pwm, t=time)return jsonify(cmd)return jsonify(True)

注意将运行端口设置为0.0.0.0,这样将可以接收局域网中其它设备的请求。

app.run(debug=True, host="0.0.0.0", port=5000)

4.3.3 客户端设计

我采用浏览器作为客户端。无论手机还是电脑,通常都会有浏览器。

这部分涉及的主要是一些web技术,如flask配套的jinja2模板引擎,jquery.js。使用javascript语言在用户操作时,向服务器发起相应的请求。作为小车的控制面板,相比按钮,图标的风格会更加适洽,因此用到了remixicon图标库。以及,使用bootstrap进行一些布局控制。

在手机端横屏界面效果如下。

在这里插入图片描述

客户端包含3个动态参数:左右轮分别的运行速度,以及每次运动的时间。两个轮子以不同的速度同时转动,即可执行转弯操作。在每个图标上监听用户的点击操作,根据js变量值即可向服务器发起请求,进行相应的运动控制。

下面是一段javascript代码示例,用于小车的整体前进或后退操作。

		$('.run').on('click', function () {var forward = true;if ($(this).hasClass('backward')) {forward = false;}fetch('/car_double', {method: 'POST',headers: {'Content-Type': 'application/json'},body: JSON.stringify({forward: forward,pwml: left_pwm + 1500,pwmr: right_pwm + 1500,time: run_time})}).then(response => response.json()).then(data => {printc(data)})})

4.4 带语义理解的语音控制

常见的语音控制方式,是关键词识别。然而,如果我们身边可以语音控制的设备躲起来,或者具有丰富的操作和指令。那么,记住繁杂的命令词会是我们沉重的负担。

为此本作中采用了两级识别结构,1)语音识别,从音频到说话内容的字符串;2)语义匹配,从字符串到小车能执行的命令词。

下面是语音识别中,整体的数据流程。更多的细节在后文介绍。

在这里插入图片描述

4.4.1 语音输入识别

1、WebSpeechAPI

本作采用浏览器客户端,现在许多浏览器已经提供了本地的识别接口,通过js调用即可。运行在浏览器本地。

改接口识别准确率较高,但识别时间不稳定,常常从不到1s至8~9s不等。

2、stt开源语音识别模型

开源仓库地址:https://github.com/jianchang512/stt

stt是一个离线运行的本地语音识别转文字工具,基于 fast-whipser 开源模型,可将视频/音频中的人类声音识别并转为文字,可输出json格式、srt字幕带时间戳格式、纯文字格式。可用于自行部署后替代 openai 的语音识别接口或百度语音识别等,准确率基本等同openai官方api接口。

将该模型部署在电脑本地,可以由客户端发起附带音频文件的请求,获取识别结果。

但由于我电脑算力受限,且配置gpu时遇到了障碍,只能运行较小的模型版本(base,141MB)。识别速度较稳定,在2s左右,但准确率相对低一些。

4.4.2 多API竞速并发

基于上述情况,我在客户端中实现了两种识别方式的并发。采用最快的那一个识别结果。(如果有一个又快有准的模型,则不必这样。)

如图,使用全局变量RACEID进行识别任务的同步控制。当一种识别方式返回结果时,将RACEID加一,那么另一种识别方式迟到的结果将不再被采用,以避免小车执行重复动作。

在这里插入图片描述

4.4.3 基于大模型的语义理解

前面的语音输入已经可以通过识别命令词,实现对小车的控制。是的,在简单的实验作品中,这已经足够了。但随着智能技术的持续渗透,我们身边会有越来越多的智能设备。如果对每个设备,以及设备的每个功能,我们都需要记住它具体的命令词——这无疑是一份巨大的负担。

而当今的大模型,为模糊指令的识别提供了可能。需要小车前进时,你可以说“往前走”,“向前跑”,而不必再纠结具体的指令词。

在本作品的实现中,利用了讯飞提供的星火大模型接口,以http进行调用。只需要通过编写恰当的prompt,即可让大模型完成指定任务。

平台地址:平台简介 | 讯飞开放平台文档中心 (xfyun.cn)

我使用prompt模板如下,可以传入语音识别阶段得到用户说话内容content,和小车预定义的支持指令集results两个参数。返回与content匹配的相应指令。

def zl_http(content='别站个歪的!', results=['向左转', '向右转', '立正'], model='general'):'''向spark模型发起文本转指令的请求'''prompt = f"\1. 你是一个自然语言转文本指令的助手,有如下文本指令:{results}。\2. 你的职责是根据用户说的话,从上述文本指令中选择和用户的话最相似的一个。\3. 你的输出应当仅仅是一个文本指令,不要说多余的话。\4. 输出必须是完全一致的文本指令,不能包含任何额外的解释或说明。\下面我说:{content}"...

4.4.4 进一步展望

上述实现的“语义理解”,仍然依赖于小车预定义了哪些支持的指令。如果你想让它“托马斯旋转”而它并没有这个预定义的动作,那么它要么做出错误的行为,要么只会呆在原地。

如果可以将文本到舵机控制指令的环节直接打通,通过用户要求自动生成相应的舵机指令序列,它将会像一个真正的智能小车。然而基于对其技术难度的评估,在这次作品中并未实现。

5 课题测试

5.1 树莓派本机

因为涉及实际硬件的控制,一键将所有用例跑一遍的测试方式不很方便。下面采用交互的方式,运行在树莓派的终端*(我是通过vscode插件远程连接了)*,控制轮子的实际运动。终端打印了舵机执行的指令。这里不便展现出实际的运动效果。

控制正常。

在这里插入图片描述

5.2 语音控制

下面是在电脑浏览器,测试语音控制模块。首先启动程序。

# 在树莓派的项目目录
python3 app_pi.py
# 在电脑stt模型目录
python3 start.py

可以看到每次语音输入后,控制台有4行显示。前3行是识别的内容,第4行是匹配到的指令。下图中“前进。”、“广(往)前跑。”、“快跑!”都成功匹配到了指令“前进”。

这次测试中都是采纳了stt模型的识别结果,WebSpeech确实会速度不怎么稳定。

在这里插入图片描述

5.3 上手操作

可以流畅地操作控制,不会很明显的延迟感。实际操作效果可以参考b站视频:https://www.bilibili.com/video/BV1aMhCeLEi4/ (当时还没有做双轮控制模式)。只需要启动树莓派的程序即可。

python3 app_pi.py

在这里插入图片描述

6 总结

这次实训一共3周,然而前2周因为时而要准备期末考试,为避免挂科,实在没法安心搞实训。但最后一周时成功集中精神,也让人久违地体会到了动手制作的乐趣。

坦而言之,在不搞嵌入式的同学们心里,这实训会是一门“水课”。在不远的独木桥头,花这样的时间当然是件奢侈的事情。也许出于爱玩的天性,我还是想动手做点东西。

事情时而会从巧合里开始,在埋头中结束。这次实训中我算是用上了身边能想到的各种材料,在面对问题反复琢磨时,时间逃得很快。而一旦成功,心里涌起的兴奋也是藏不住的,甚至觉得不真实:还真让我给干成了。直到最后成品做出来,我才敢把自己的选题告诉老师。

大学的最后一次实训课了,日后回头一看,应该也不算空空如也。


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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

2024年最新ComfyUI汉化及manager插件安装详解!

前言 在ComfyUI文生图详解中,学习过如果想要安装相应的模型,需要到模型资源网站(抱抱脸、C站、魔塔、哩布等)下载想要的模型,手动安装到ComfyUI安装目录下对应的目录中。 为了简化这个流程,我们需要安装Co…

如何在 PostgreSQL 中实现数据的去重操作,尤其是对于复杂的数据结构?

文章目录 一、基本数据类型的去重二、多列数据的去重三、复杂数据结构的去重(一)数组类型的去重(二)JSON 类型的去重(三)结构体类型(复合类型)的去重 四、使用 GROUP BY 进行去重五、…

数据结构--堆,堆排序

1.树概念及结构 1.1树的概念 树是一种 非线性 的数据结构,它是由 n ( n>0 )个有限结点组成一个具有层次关系的集合。 把它叫做树是因 为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的 。 有一个 特殊的结…

自动高速开箱机:如何助力电商物流行业

在电商飞速发展的今天,物流行业也迎来了前所未有的挑战与机遇。为了满足消费者对快速、高效、安全的配送需求,各大电商平台和物流公司纷纷寻求技术革新,其中,自动高速开箱机凭借其独特的优势,在电商物流中崭露头角&…

vulnhub-Os-hackNos-3(包含多种靶机获取不了IP地址情况)

下载靶机 通过VMware搭建 网络问题是个关键点 我们点击开启虚拟机,到开机的页面我们回车选择第二个Ubuntu的高级选项 (如果出不来这个选择界面,开机时按下shift键) 进到高级选项,我们再次回车选择第二个进入Linux内核版本的恢复模式 回车后…

BaseServlet的封装

创建BaseServlet的必要性 如果不创建BaseServlet,现在我们只要实现一个功能,我们就需要创建一个servlet! 例如:用户模块(登录,注册,退出录,激活,发送邮件等等功能) 也就是说,我们必须要创建一…

Vue3使用ref绑定组件获取valueRef.value为null的解决

问题: onMounted(() > {nextTick(()>{console.log(treeselectRef, treeselectRef.value);console.log(treeselectRef.value, treeselectRef.value);}); });输出: 查看绑定和定义都没有问题,还是获取不到 解决:使用getCur…

YOLOv5+DecoupleHead解耦头(YOLOx)

一、解耦头原理 在目标检测中,分类任务和回归任务之间的冲突是一个众所周知的问题。因此,用于分类和定位的解耦头被广泛应用于大多数一级和二级探测器。但是,由于YOLO系列的主干和特征金字塔(如FPN, PAN)不断演化,它们的检测头仍然是耦合的。 从下表可以看出,头耦合时端…

leetcode 1398 购买了产品A和产品B却没有购买产品C的顾客(postgresql)

需求 Customers 表: ---------------------------- | Column Name | Type | ---------------------------- | customer_id | int | | customer_name | varchar | ---------------------------- customer_id 是这张表的主键。 customer_name 是顾客的名称。 Order…

水果商城系统 SpringBoot+Vue

1、技术栈 技术栈:SpringBootVueMybatis等使用环境:Windows10 谷歌浏览器开发环境:jdk1.8 Maven mysql Idea 数据库仅供学习参考 【已经答辩过的毕业设计】 项目源码地址 2、功能划分 3、效果演示

【软件分享】我们为分类而生—eCognition

分类是各位小伙伴入门遥感需要做的一项基础的工作,在进行遥感影像中的地物进行分类和提取时,如何提高分类精度,常常令人头疼。今天小编带来此前接触过的一个工具,他的名字是—eCognition,感觉比ENVI好用,在…

gui创新点charts图表

import javax.swing.*; import java.awt.*;public class ComboChartExample extends JPanel {Overrideprotected void paintComponent(Graphics g) {super.paintComponent(g);// 数据int[] values {100, 200, 150, 300, 250};int[] lineValues {120, 180, 160, 280, 230};Str…

掌上教务系统-计算机毕业设计源码84604

摘要 在数字化教育日益成为主流的今天,教务管理系统的智能化和便捷性显得尤为重要。为满足学校、教师、学生及家长对教务管理的高效需求,我们基于Spring Boot框架设计并实现了一款掌上教务系统。该系统不仅具备课程分类管理功能,使各类课程信…

Git 查看、新建、删除、切换分支

Git 是一个版本控制系统,软件开发者用它来跟踪应用程序的变化并进行项目协作。 分支的诞生便于开发人员在彼此独立的环境中进行开发工作。主分支(通常是 main 或 master)可以保持稳定,而新的功能或修复可以在单独的分支中进行开发…

猫咪健康新选择!福派斯鲜肉猫粮里的果蔬纤维大揭秘

你们是不是对福派斯鲜肉猫粮中那些丰富的果蔬粗纤维特别好奇呢?🤔 其实,这些看似简单的粗纤维,对猫咪的健康可是大有裨益的! 粗纤维在猫粮中起到多种重要作用,并且对猫咪的健康和消化系统有着显著的影响。以…

运维系列.Nginx中使用HTTP压缩功能

运维专题 Nginx中使用HTTP压缩功能 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite:http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this article:https://blog.csdn.net/qq_28550…

linux 安装Openjdk1.8

一、在线安装 1、更新软件包 sudo apt-get update 2、安装openjdk sudo apt-get install openjdk-8-jdk 3、配置openjdk1.8 openjdk默认会安装在/usr/lib/jvm/java-8-openjdk-amd64 vim ~/.bashrc export JAVA_HOME/usr/lib/jvm/java-8-openjdk-amd64 export JRE_HOME${J…

计算机网络-组播数据转发原理

一、组播数据转发原理 前面已经学习了组播的基本概念和网络组成结构了,今天来学习下组播数据的转发。首先我们要先明确组播网络也是和单播一样需要网络可达的,因此也是需要单播网络支持的基础上配置组播转发数据。单播网络不通组播网络就没有意义了。 组…

docker 本地部署大模型(ollama)

docker 安装 ollama docker search ollama docker pull ollama/ollama###docker下载ollama部署 docker run -d -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama### 下载模型 docker exec -it ollama ollama pull llama3### 交互式运行模型docker exec -i…

Python采集京东标题,店铺,销量,价格,SKU,评论,图片

京东的许多数据是通过 JavaScript 动态加载的,包括销量、价格、评论和评论时间等信息。我们无法仅通过传统的静态网页爬取方法获取到这些数据。需要使用到如 Selenium 或 Pyppeteer 等能够模拟浏览器行为的工具。 另外,京东的评论系统是独立的一个系统&a…