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

动态窗口法Dynamic Window Approach在动态环境中避障

以这个博主的代码为基础,加了一个碰撞检测,但是这个碰撞检测目前还不完善,思路应该是这个思路,以后有时间再完善吧。

动态窗口法:【路径规划】局部路径规划算法——DWA算法(动态窗口法)|(含python实现 | c++实现)-CSDN博客

DWA的大致思路就是,在一个线速度和角度的可行二维空间中,进行采样,计算每个可行速度在未来一定时间内的轨迹(假定匀速运动), 对这些轨迹进行评价,取最优轨迹,以最有轨迹对应的当前下一时刻的线速度和角速度,最为速度控制器的v_target。缺点是容易陷入局部最优。

import randomimport numpy as np
import matplotlib.pyplot as plt
import math
import timeclass Config:"""simulation parameter class"""def __init__(self):# robot parameter# 线速度边界self.v_max = 1.0  # [m/s]self.v_min = -0.5  # [m/s]# 角速度边界self.w_max = 40.0 * math.pi / 180.0  # [rad/s]self.w_min = -40.0 * math.pi / 180.0  # [rad/s]# 线加速度和角加速度最大值self.a_vmax = 0.2  # [m/ss]self.a_wmax = 40.0 * math.pi / 180.0  # [rad/ss]# 采样分辨率self.v_sample = 0.01  # [m/s]self.w_sample = 0.1 * math.pi / 180.0  # [rad/s]# 离散时间self.dt = 0.1  # [s] Time tick for motion prediction# 轨迹推算时间长度self.predict_time = 3.0  # [s]# 轨迹评价函数系数self.alpha = 0.15self.beta = 1.0self.gamma = 1.0# Also used to check if goal is reached in both typesself.robot_radius = 1.0  # [m] for collision checkself.judge_distance = 10  # 若与障碍物的最小距离大于阈值(例如这里设置的阈值为robot_radius+0.2),则设为一个较大的常值class DWA:def __init__(self, config) -> None:"""初始化Args:config (_type_): 参数类"""self.dt = config.dtself.v_min = config.v_minself.w_min = config.w_minself.v_max = config.v_maxself.w_max = config.w_maxself.predict_time = config.predict_timeself.a_vmax = config.a_vmaxself.a_wmax = config.a_wmaxself.v_sample = config.v_sample  # 线速度采样分辨率self.w_sample = config.w_sample  # 角速度采样分辨率self.alpha = config.alphaself.beta = config.betaself.gamma = config.gammaself.radius = config.robot_radiusself.judge_distance = config.judge_distancedef dwa_control(self, state, goal, obstacle, ob_dyna, dyna_ob_v):"""滚动窗口算法入口Args:state (_type_): 机器人当前状态--[x,y,yaw,v,w]goal (_type_): 目标点位置,[x,y]obstacle (_type_): 障碍物位置,dim:[num_ob,2]Returns:_type_: 控制量、轨迹(便于绘画)"""control, trajectory = self.trajectory_evaluation(state, goal, obstacle, ob_dyna, dyna_ob_v)return control, trajectorydef cal_dynamic_window_vel(self, v, w, state, obstacle):"""速度采样,得到速度空间窗口Args:v (_type_): 当前时刻线速度w (_type_): 当前时刻角速度state (_type_): 当前机器人状态obstacle (_type_): 障碍物位置Returns:[v_low,v_high,w_low,w_high]: 最终采样后的速度空间"""Vm = self.__cal_vel_limit()Vd = self.__cal_accel_limit(v, w)Va = self.__cal_obstacle_limit(state, obstacle)a = max([Vm[0], Vd[0], Va[0]])b = min([Vm[1], Vd[1], Va[1]])c = max([Vm[2], Vd[2], Va[2]])d = min([Vm[3], Vd[3], Va[3]])return [a, b, c, d]def __cal_vel_limit(self):"""计算速度边界限制VmReturns:_type_: 速度边界限制后的速度空间Vm"""return [self.v_min, self.v_max, self.w_min, self.w_max]def __cal_accel_limit(self, v, w):"""计算加速度限制VdArgs:v (_type_): 当前时刻线速度w (_type_): 当前时刻角速度Returns:_type_:考虑加速度时的速度空间Vd"""v_low = v - self.a_vmax * self.dtv_high = v + self.a_vmax * self.dtw_low = w - self.a_wmax * self.dtw_high = w + self.a_wmax * self.dtreturn [v_low, v_high, w_low, w_high]def __cal_obstacle_limit(self, state, obstacle):"""环境障碍物限制VaArgs:state (_type_): 当前机器人状态obstacle (_type_): 障碍物位置Returns:_type_: 某一时刻移动机器人不与周围障碍物发生碰撞的速度空间Va"""# 不与静态障碍物碰撞v_low = self.v_minv_high = np.sqrt(2 * self._dist(state, obstacle[:, :]) * self.a_vmax)w_low = self.w_minw_high = np.sqrt(2 * self._dist(state, obstacle[:, :]) * self.a_wmax)return [v_low, v_high, w_low, w_high]def trajectory_predict(self, state_init, v, w):"""轨迹推算Args:state_init (_type_): 当前状态---x,y,yaw,v,wv (_type_): 当前时刻线速度w (_type_): 当前时刻线速度Returns:_type_: _description_"""state = np.array(state_init)trajectory = state_time = 0# 在预测时间段内while _time <= self.predict_time:x = KinematicModel(state, [v, w], self.dt)  # 运动学模型trajectory = np.vstack((trajectory, x))_time += self.dtreturn trajectorydef predict_dyna_ob_traj(self, ob_dyna, dyna_ob_v):trajectory = np.zeros((ob_dyna.shape[0], int(self.predict_time / self.dt) + 1, 2))trajectory[0, 0, 0] = ob_dyna[0, 0]trajectory[0, 0, 1] = ob_dyna[0, 1]trajectory[1, 0, 0] = ob_dyna[1, 0]trajectory[1, 0, 1] = ob_dyna[1, 1]time = 0idx = 1while time <= self.predict_time:# 维度:个体数 时刻 坐标trajectory[0, idx, 0] = trajectory[0, idx - 1, 0] + dyna_ob_v[0, 0] * self.dttrajectory[0, idx, 1] = trajectory[0, idx - 1, 1] + dyna_ob_v[0, 1] * self.dttrajectory[1, idx, 0] = trajectory[1, idx - 1, 0] + dyna_ob_v[1, 0] * self.dttrajectory[1, idx, 1] = trajectory[1, idx - 1, 1] + dyna_ob_v[1, 1] * self.dttime += self.dtidx += 1return trajectorydef collision_detection(self, trajectory, traj_dyob):trajectory = np.repeat(trajectory[np.newaxis, :, :], 2, axis=0)distances = np.linalg.norm(trajectory - traj_dyob, axis=2)min_values = np.min(distances, axis=1)min_value = np.min(min_values, axis=0)if min_value < 0.3:return Trueelse:return Falsedef trajectory_evaluation(self, state, goal, obstacle, ob_dyna, ob_dyna_v):"""轨迹评价函数,评价越高,轨迹越优Args:state (_type_): 当前状态---x,y,yaw,v,wdynamic_window_vel (_type_): 采样的速度空间窗口---[v_low,v_high,w_low,w_high]goal (_type_): 目标点位置,[x,y]obstacle (_type_): 障碍物位置,dim:[num_ob,2]Returns:_type_: 最优控制量、最优轨迹"""G_max = -float('inf')  # 最优评价trajectory_opt = state  # 最优轨迹control_opt = [0., 0.]  # 最优控制dynamic_window_vel = self.cal_dynamic_window_vel(state[3], state[4], state, obstacle)  # 第1步--计算速度空间# 在速度空间中按照预先设定的分辨率采样sum_heading, sum_dist, sum_vel = 1, 1, 1  # 不进行归一化for v in np.arange(dynamic_window_vel[0], dynamic_window_vel[1], self.v_sample):for w in np.arange(dynamic_window_vel[2], dynamic_window_vel[3], self.w_sample):trajectory = self.trajectory_predict(state, v, w)  # 第2步--轨迹推算heading_eval = self.alpha * self.__heading(trajectory, goal) / sum_headingdist_eval = self.beta * self.__dist(trajectory, obstacle) / sum_distvel_eval = self.gamma * self.__velocity(trajectory) / sum_velG = heading_eval + dist_eval + vel_eval  # 第3步--轨迹评价if G_max <= G:G_max = Gtrajectory_opt = trajectorycontrol_opt = [v, w]traj_dyob = self.predict_dyna_ob_traj(ob_dyna, ob_dyna_v)collision = self.collision_detection(trajectory_opt[:, :2], traj_dyob)if collision:control_opt = [0, 0]return control_opt, trajectory_optdef _dist(self, state, obstacle):"""计算当前移动机器人距离障碍物最近的几何距离Args:state (_type_): 当前机器人状态obstacle (_type_): 障碍物位置Returns:_type_: 移动机器人距离障碍物最近的几何距离"""ox = obstacle[:, 0]oy = obstacle[:, 1]dx = state[0, None] - ox[:, None]dy = state[1, None] - oy[:, None]r = np.hypot(dx, dy)return np.min(r)def __dist(self, trajectory, obstacle):"""距离评价函数表示当前速度下对应模拟轨迹与障碍物之间的最近距离;如果没有障碍物或者最近距离大于设定的阈值,那么就将其值设为一个较大的常数值。Args:trajectory (_type_): 轨迹,dim:[n,5]obstacle (_type_): 障碍物位置,dim:[num_ob,2]Returns:_type_: _description_"""ox = obstacle[:, 0]oy = obstacle[:, 1]dx = trajectory[:, 0] - ox[:, None]dy = trajectory[:, 1] - oy[:, None]r = np.hypot(dx, dy)return np.min(r) if np.array(r < self.radius + 0.2).any() else self.judge_distancedef __heading(self, trajectory, goal):"""方位角评价函数评估在当前采样速度下产生的轨迹终点位置方向与目标点连线的夹角的误差Args:trajectory (_type_): 轨迹,dim:[n,5]goal (_type_): 目标点位置[x,y]Returns:_type_: 方位角评价数值"""dx = goal[0] - trajectory[-1, 0]dy = goal[1] - trajectory[-1, 1]error_angle = math.atan2(dy, dx)cost_angle = error_angle - trajectory[-1, 2]cost = math.pi - abs(cost_angle)return costdef __velocity(self, trajectory):"""速度评价函数, 表示当前的速度大小,可以用模拟轨迹末端位置的线速度的大小来表示Args:trajectory (_type_): 轨迹,dim:[n,5]Returns:_type_: 速度评价"""return trajectory[-1, 3]def KinematicModel(state, control, dt):"""机器人运动学模型Args:state (_type_): 状态量---x,y,yaw,v,wcontrol (_type_): 控制量---v,w,线速度和角速度dt (_type_): 离散时间Returns:_type_: 下一步的状态"""state[0] += control[0] * math.cos(state[2]) * dtstate[1] += control[0] * math.sin(state[2]) * dtstate[2] += control[1] * dtstate[3] = control[0]state[4] = control[1]return statedef plot_arrow(x, y, yaw, length=0.5, width=0.1):  # pragma: no coverplt.arrow(x, y, length * math.cos(yaw), length * math.sin(yaw),head_length=width, head_width=width)plt.plot(x, y)def plot_robot(x, y, yaw, config):  # pragma: no covercircle = plt.Circle((x, y), config.robot_radius, color="b")plt.gcf().gca().add_artist(circle)out_x, out_y = (np.array([x, y]) +np.array([np.cos(yaw), np.sin(yaw)]) * config.robot_radius)plt.plot([x, out_x], [y, out_y], "-k")def dynamic_ob(t, dyna_ob_v):y1 = (dyna_ob_v[0, 1] * t) % 14x2 = (dyna_ob_v[1, 0] * t) % 9return np.array([[9, y1],[x2, 9]])def do_dwa(current_x=0.0, current_y=0.0, goal_x=10.0, goal_y=10.0, ob=np.array([[-1, -1]])):# initial state [x(m), y(m), yaw(rad), v(m/s), omega(rad/s)]x = np.array([current_x, current_y, math.pi / 8.0, 0.0, 0.0])# goal position [x(m), y(m)]goal = np.array([goal_x, goal_y])config = Config()trajectory = np.array(x)dwa = DWA(config)# fig=plt.figure(1)st_i = 0while True:ob_speed = 0.2dyna_ob_v = np.array([[0, ob_speed],[ob_speed, 0]])ob_dyna = dynamic_ob(st_i, dyna_ob_v)u, predicted_trajectory = dwa.dwa_control(x, goal, ob, ob_dyna, dyna_ob_v)x = KinematicModel(x, u, config.dt)  # simulate robottrajectory = np.vstack((trajectory, x))  # store state historyplt.cla()# for stopping simulation with the esc key.plt.gcf().canvas.mpl_connect('key_release_event',lambda event: [exit(0) if event.key == 'escape' else None])try:plt.plot(predicted_trajectory[:, 0], predicted_trajectory[:, 1], "-g")except:passplt.plot(x[0], x[1], "xr")plt.plot(goal[0], goal[1], "xb")plt.plot(ob[:, 0], ob[:, 1], "ok")plt.plot(ob_dyna[:, 0], ob_dyna[:, 1], "ok")plot_robot(x[0], x[1], x[2], config)plot_arrow(x[0], x[1], x[2])plt.axis("equal")plt.grid(True)plt.pause(0.001)st_i += 1# check reaching goaldist_to_goal = math.hypot(x[0] - goal[0], x[1] - goal[1])if dist_to_goal <= config.robot_radius:print("Goal!!")breakprint("Done")# plt.plot(trajectory[:, 0], trajectory[:, 1], "-r")# plt.pause(0.001)# plt.show()return trajectoryif __name__ == "__main__":num_points = 10points = [(random.uniform(0, 16), random.uniform(0, 16)) for _ in range(num_points)]ob = np.array(points)current_x = 0.0current_y = 0.0goal_x = 10.0goal_y = 10.0current_x = random.randint(-5, 2)current_y = random.randint(2, 7)trajectory = do_dwa(current_x, current_y, goal_x, goal_y, ob=ob)plt.scatter(ob[:, 0], ob[:, 1], c="k")plt.plot(trajectory[:, 0], trajectory[:, 1], "-r")plt.show()print(trajectory)

相关文章:

动态窗口法Dynamic Window Approach在动态环境中避障

以这个博主的代码为基础&#xff0c;加了一个碰撞检测&#xff0c;但是这个碰撞检测目前还不完善&#xff0c;思路应该是这个思路&#xff0c;以后有时间再完善吧。 动态窗口法&#xff1a;【路径规划】局部路径规划算法——DWA算法&#xff08;动态窗口法&#xff09;|&#…...

2023.12.15 FineBI与kettle

1.结构化就是可以用schema描述的数据,就是结构化数据,能转为二维表格, 如CSV,Excel, 2.半结构化就是部分可以转换为二维表格,如JSON,XML 3.非结构化数据,就是完全无法用二维表格表示的数据,如Word文档,Mp4,图片,等文件. kettle的流程 新建转换-构建流图-配置组件-保存运行 使…...

Python tkinter 初探Toplevel控件搭建父子窗口

目录 Toplevel控件搭建父子窗口 最简明的父子窗口框架 改进一&#xff1a;屏蔽和开放按钮 改进二&#xff1a;子窗口始终在主窗口之上 改进三&#xff1a;增加子窗口的关闭协议 改进四&#xff1a;使子窗口长获焦点 总结 Toplevel控件搭建父子窗口 最近&#xff0c;用P…...

SpringCloud源码探析(十二)-基于SpringBoot开发自定义中间件

1.概述 中间件是一种介于操作系统和应用软件之间&#xff0c;为应用软件提供服务功能的软件&#xff0c;按功能划分有消息中间件&#xff08;Kafka、RocketMQ&#xff09;、通信中间件&#xff08;RPC通信中间件&#xff0c;dubbo等&#xff09;&#xff0c;应用服务器等。中间…...

基于CNN+数据增强+残差网络Resnet50的少样本高准确度猫咪种类识别—深度学习算法应用(含全部工程源码)+数据集+模型(一)

系列文章目录 基于CNN数据增强残差网络Resnet50的少样本高准确度猫咪种类识别—深度学习算法应用(含全部工程源码)数据集模型&#xff08;一&#xff09; 基于CNN数据增强残差网络Resnet50的少样本高准确度猫咪种类识别—深度学习算法应用(含全部工程源码)数据集模型&#xf…...

python实现贪吃蛇游戏

文章目录 1、项目说明2、项目预览3、开发必备4、贪吃蛇代码实现4.1、窗口和基本参数实现4.2、绘制背景4.3、绘制墙壁4.4、绘制贪吃蛇4.5、绘制食物4.6、实现长度信息显示4.7、定义游戏暂停界面4.8、定义贪吃蛇死亡界面4.9、实现贪吃蛇碰撞效果4.10、实现添加食物功能4.11、实现…...

ios备忘录怎么导入华为 方法介绍

作为一个常常需要在不同设备间切换的人&#xff0c;我深知备忘录的重要性。那些突如其来的灵感、重要的会议提醒、甚至是生活中的琐碎小事&#xff0c;我们都习惯性地记录在备忘录里。但当我决定从iPhone转向华为时&#xff0c;一个问题困扰了我&#xff1a;如何将那些珍贵的备…...

electron与cesium组件入门应用功能

electron与cesium组件入门应用功能 运行应用效果图&#xff1a; electron应用目录&#xff0c;需要包括三个文件: index.html main.js package.json (一)、创建一个新项目 目录名称&#xff1a;project_helloWolrd (二)、生成package.json文件 npm init --yes(三&#x…...

Jenkins Docker Cloud在Linux应用开发CI中的实践

Jenkins Docker Cloud在Linux应用开发CI中的实践 背景 通过代码提交自动触发CI自动构建、编译、打包是任何软件开发组织必不可少的基建&#xff0c;可以最大程度保证产物的一致性&#xff0c;方便跨组跨部门协作&#xff0c;代码MR等。 Docker在流水线中越来越重要&#xff…...

502 Bad Gateway with nginx + apache + subversion + ssl

svn commit的时候返回 unexpected http status 502 bad gateway on解决方法&#xff0c;参考&#xff1a;https://stackoverflow.com/questions/2479346/502-bad-gateway-with-nginx-apache-subversion-ssl-svn-copy 在nginx中代理svn中添加 location /svn {set $fixed_dest…...

【PostgreSQL内核学习(十八)—— 存储管理(存储管理的体系结构)】

存储管理 概述存储管理器的体系结构存储管理器的主要任务读写元组过程 声明&#xff1a;本文的部分内容参考了他人的文章。在编写过程中&#xff0c;我们尊重他人的知识产权和学术成果&#xff0c;力求遵循合理使用原则&#xff0c;并在适用的情况下注明引用来源。 本文主要参考…...

Android的组件、布局学习

介绍 公司组织架构调整&#xff0c;项目组需要承接其他项目组的android项目&#xff0c;负责维护和开发新需求&#xff0c;故学习下基础语法和项目开发。 组件学习 Toolbarheader布局部分 就是app最顶部的部分 他的显示与否&#xff0c;是与F:\androidProject\android_lear…...

【离散数学】——期末刷题题库(树其一)

&#x1f383;个人专栏&#xff1a; &#x1f42c; 算法设计与分析&#xff1a;算法设计与分析_IT闫的博客-CSDN博客 &#x1f433;Java基础&#xff1a;Java基础_IT闫的博客-CSDN博客 &#x1f40b;c语言&#xff1a;c语言_IT闫的博客-CSDN博客 &#x1f41f;MySQL&#xff1a…...

光模块市场分析与发展趋势预测

光模块是光通信领域的重要组成部分&#xff0c;随着数字经济&#xff0c;大数据&#xff0c;云计算&#xff0c;人工智能等行业的兴起&#xff0c;光模块市场经历了快速发展&#xff0c;逐渐在数据中心、无线回传、电信传输等应用场景中得到广泛应用。本文将基于当前光模块全球…...

Python轴承故障诊断 (八)基于EMD-CNN-GRU并行模型的故障分类

目录 前言 1 经验模态分解EMD的Python示例 2 轴承故障数据的预处理 2.1 导入数据 2.2 制作数据集和对应标签 2.3 故障数据的EMD分解可视化 2.4 故障数据的EMD分解预处理 3 基于EMD-CNN-GRU并行模型的轴承故障诊断分类 3.1 训练数据、测试数据分组&#xff0c;数据分ba…...

鸿蒙实现年月日十分选择框,支持年月日、月日、日、年月日时分、时分切换

import DateTimeUtils from ./DateTimeUtils;CustomDialog export default struct RQPickerDialog {controller: CustomDialogControllertitle: string 这是标题TAG: string RQPickerDialog// 0 - 日期类型&#xff08;年月日&#xff09; 1 - 时间类型&#xff08;时分&a…...

IntelliJ IDE 插件开发 | (三)消息通知与事件监听

系列文章 IntelliJ IDE 插件开发 |&#xff08;一&#xff09;快速入门IntelliJ IDE 插件开发 |&#xff08;二&#xff09;UI 界面与数据持久化IntelliJ IDE 插件开发 |&#xff08;三&#xff09;消息通知与事件监听 前言 在前两篇文章中讲解了关于插件开发的基础知识&…...

VUE小知识点

Vue 是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML、CSS 和 JavaScript 构建&#xff0c;并提供了一套声明式的、组件化的编程模型&#xff0c;帮助你高效地开发用户界面。 Vue 的主要作用是帮助开发者构建现代 Web 应用程序。它允许前端开发人员专注于应用程序…...

深入了解常见的应用层网络协议

目录 1. HTTP协议 1.1. 工作原理 1.2. 应用场景 1.3. 安全性考虑 2. SMTP协议 2.1. 工作原理 2.2. 应用场景 2.3. 安全性考虑 3. FTP协议 3.1. 工作原理 3.2. 应用场景 3.3. 安全性考虑 4. DNS协议 4.1. 工作原理 4.2. 应用场景 4.3. 安全性考虑 5. 安全性考虑…...

网络爬虫 多任务采集

一、JSON文件存储 JSON&#xff0c;全称为 JavaScript 0bject Notation,也就是JavaSript 对象标记&#xff0c;它通过对象和数组的组合来表示数据&#xff0c;构造简洁但是结构化程度非常高&#xff0c;是一种轻量级的数据交换格式。本节中&#xff0c;我们就来了解如何利用 P…...

CTF show Web 红包题第六弹

提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框&#xff0c;很难让人不联想到SQL注入&#xff0c;但提示都说了不是SQL注入&#xff0c;所以就不往这方面想了 ​ 先查看一下网页源码&#xff0c;发现一段JavaScript代码&#xff0c;有一个关键类ctfs…...

【OSG学习笔记】Day 18: 碰撞检测与物理交互

物理引擎&#xff08;Physics Engine&#xff09; 物理引擎 是一种通过计算机模拟物理规律&#xff08;如力学、碰撞、重力、流体动力学等&#xff09;的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互&#xff0c;广泛应用于 游戏开发、动画制作、虚…...

前端导出带有合并单元格的列表

// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...

linux 下常用变更-8

1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行&#xff0c;YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID&#xff1a; YW3…...

Springboot社区养老保险系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;社区养老保险系统小程序被用户普遍使用&#xff0c;为方…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖

在Vuzix M400 AR智能眼镜的助力下&#xff0c;卢森堡罗伯特舒曼医院&#xff08;the Robert Schuman Hospitals, HRS&#xff09;凭借在无菌制剂生产流程中引入增强现实技术&#xff08;AR&#xff09;创新项目&#xff0c;荣获了2024年6月7日由卢森堡医院药剂师协会&#xff0…...

音视频——I2S 协议详解

I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议&#xff0c;专门用于在数字音频设备之间传输数字音频数据。它由飞利浦&#xff08;Philips&#xff09;公司开发&#xff0c;以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...

深度学习水论文:mamba+图像增强

&#x1f9c0;当前视觉领域对高效长序列建模需求激增&#xff0c;对Mamba图像增强这方向的研究自然也逐渐火热。原因在于其高效长程建模&#xff0c;以及动态计算优势&#xff0c;在图像质量提升和细节恢复方面有难以替代的作用。 &#x1f9c0;因此短时间内&#xff0c;就有不…...

C/C++ 中附加包含目录、附加库目录与附加依赖项详解

在 C/C 编程的编译和链接过程中&#xff0c;附加包含目录、附加库目录和附加依赖项是三个至关重要的设置&#xff0c;它们相互配合&#xff0c;确保程序能够正确引用外部资源并顺利构建。虽然在学习过程中&#xff0c;这些概念容易让人混淆&#xff0c;但深入理解它们的作用和联…...

【JavaSE】多线程基础学习笔记

多线程基础 -线程相关概念 程序&#xff08;Program&#xff09; 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序&#xff0c;比如我们使用QQ&#xff0c;就启动了一个进程&#xff0c;操作系统就会为该进程分配内存…...