Mujoco 学习系列(二)基础功能与xml使用
这篇文章是 Mujoco 学习系列第二篇,主要介绍一些基础功能与 xmI 使用,重点在于如何编写与读懂 xml 文件。
运行这篇博客前请先确保正确安装 Mujoco 并通过了基本功能与GUI的验证,即至少完整下面这个博客的 第二章节 内容:
- Mujoco 学习系列(一)安装与部署
1. 启动仿真器
在第一篇博客中已经介绍了如何通过命令启动仿真器,但实际上mujoco提供了很多种方式启动,不同启动方式在后面的工作中会有不同的作用。
1.1 python 命令行启动
- 只启动仿真器,不加载模型
(mojoco) $ python -m mujoco.viewer
- 启动仿真器,同时加载模型(这里加载自带的小车模型)
(mojoco) $ python -m mujoco.viewer --mjcf=./model/car/car.xml
1.2 python 脚本启动
- 启动仿真器,不加载模型(阻塞)
import mujocomojoco.viewer.launch()
- 启动仿真器,同时加载模型(阻塞)
import mujocomodel_xml_path = "./model/car/car.xml"
mujoco.viewer.launch_from_path(model_xml_path)
上面两种阻塞方式启动后 terminal 会一直等待你在仿真器中操作完并关闭。mujoco 也提供了非阻塞方式启动仿真器 launch_passive(model, data)
,但在启动时必须将模型加载进来,同时需要手动管理 mj_step()
函数,而以阻塞方式启动的仿真器不需要显示调用该函数。因为是非阻塞方式启动,需要将仿真器放在一个循环中,否则一启动就会立刻关闭。
- 启动仿真器,同时加载模型(非阻塞)
import timeimport mujoco
import mujoco.viewermodel_xml_path = "./model/car/car.xml"
model = mujoco.MjModel.from_xml_path(model_xml_path)
data = mujoco.MjData(model)with mujoco.viewer.launch_passive(model=model, data=data) as viewer:while viewer.is_running():step_start = time.time() # 每一帧仿真的开始时间,用于控制仿真的时间步长mujoco.mj_step(model, data) # [核心] 手动推进一次仿真# 给 simulate GUI 加锁,防止数据修改线程与渲染线程出现冲突with viewer.lock():# 这行主要是提升交互体验,你在运行后可以发现环境中每个接触点都会有黄色的圆柱在闪烁viewer.opt.flags[mujoco.mjtVisFlag.mjVIS_CONTACTPOINT] = int(data.time % 2)viewer.sync() # 将最新的数据同步给GUI中并显示# 到达此处说明当前帧的运算和渲染已经结束了,计算一下到下一帧的时间间隔,用于控制仿真节奏# 如果仿真在这一步消耗了很长时间,那么该值是有可能为负time_until_next_step = model.opt.timestep - (time.time() - step_start)if time_until_next_step > 0:time.sleep(time_until_next_step) # 休眠一下后准备计算下一帧
运行之后就可以看到上图中的效果,可以发现在小车三个轮子的位置处有黄色的矮圆柱体在闪烁,这就是代码中 viewer.opt.flags
部分起的作用。
2. 编写 xml 文件
在上一章节中其实遗留了一个问题:多个模型的加载在机器人仿真中是必要的,但 mujoco 本身是不支持同时加载多个 xml
文件的,因为 mujoco 是 面向单物理场景 设计的,只不过有方法来实现这点,上面例子中的小车本质上就是在一个 xml 文件中创建了不同元素并将其组合,多个模型加载问题可以被转化成不同元素但不进行组合。
在编写之前需要先理解 mujoco 如何解析 xml 文件的,特别是哪些标签是核心的、哪些是可以以类形式定义等。
- 官方解释链接:XMLreference.html
我将 xml 的标签分为两类:
- 环境标签:这类标签定义了全局仿真配置,包括重力、第三人称相机视角、密度、时间步长等;
- 对象标签:这类标签是可以继承、包含、相互作用,有点类似代码中的 class;
这种分类方式实际上不严谨,但对于初学者而言可以先这样简化地去理解。
2.1 立方体与平面
首先是最简单的一个例子,在一个空间中有一个立方体和一个平面,期望立方体自由落体后掉在平面上:
<mujoco><!-- 场景 --><worldbody><!-- 光源 --><light diffuse="0.5 0.5 0.5" pos="0 0 3" dir="0 0 -1"/> <!-- 平面 --><geom name="ground" type="plane" size="1 1 0.1" rgba="0.5 0.5 0.5 1"/><!-- 对象 --><body name="cube" pos="0 0 1"><joint type="free"/> <!-- 该对象与外界的链接方式 --><geom type="box" size="0.1 0.1 0.1" rgba="0.0 0.0 0.5 1"/></body></worldbody>
</mujoco>
上面的例子中顶级标签为 <mujoco>
,其他所有对象都在 <worldbody>
标签下,在这个标签中有两个对象 平面 和 立方体。
【Note】:虽然mujoco官方文档和很多教程都告诉你可以省略 name
字段,没有显示声明的情况下会自动分配一个匿名值,但我会将 name
字段一直写上去,因为 mujoco 不允许出现同名对象,同时有 name
字段可以帮你更快定位到问题。
直接运行就可以看到一个立方体自由落体到平面上:
(mujoco) $ python -m mujoco.viewer --mjcf=./merge.xml
实际上在xml中的 平面 也是一个对象,但我个人习惯地面对象不用 body
标签包裹以区分运动对象和地面,所以下面的写法也是正确的:
<mujoco><!-- 场景 --><worldbody><!-- 光源 --><light diffuse="0.5 0.5 0.5" pos="0 0 3" dir="0 0 -1"/> <!-- 平面 --><body name="ground" pos="0 0 0" ><geom type="plane" size="1 1 0.1" rgba="0.5 0.5 0.5 1"/></body><!-- 对象 --><body name="cube" pos="0 0 1"><joint type="free"/><geom type="box" size="0.1 0.1 0.1" rgba="0.0 0.0 0.5 1"/> <!-- 对象的几何形状 --></body></worldbody>
</mujoco>
同理,如果想要在不同位置添加一个新的立方体则如下所示,新的立方体中多了一个 euler
属性表示其初始角度信息,更多属性以及其默认值可以在官网文档中找到:
<mujoco><worldbody><light diffuse="0.5 0.5 0.5" pos="0 0 3" dir="0 0 -1"/> <geom name="ground" type="plane" size="1 1 0.1" rgba="0.5 0.5 0.5 1"/><!-- 立方体1 --><body name="cube1" pos="0 0 1"><joint type="free"/><geom type="box" size="0.1 0.1 0.1" rgba="0.0 0.0 0.5 1"/> </body><!-- 立方体2 --><body name="cube2" pos="0.5 0.5 0.5" euler="0 20 30"><joint type="free"/><geom type="box" size="0.1 0.1 0.1" rgba="0.5 0.0 0.0 1"/></body></worldbody>
</mujoco>
运行后也是两个立方体自由落体,只不过初试高度和角度不同,因此最终落地姿势也不同。
(mujoco) $ python -m mujoco.viewer --mjcf=./merge.xml
2.2 环境标签
通常情况下环境标签是在第一步就需要做的,为了避免不同平台中存在差异,虽然 mujoco 允许在运行过程中修改环境标签的值,例如更改重力方向,但在没有特殊需求的情况下这些值应该被定义为一个静态值。
在 mujoco 中通过 xml 里的 <option>
标签定义环境,可以修改的属性值有以下几个:
我最常用的是下面几个:
- timestep:仿真时间步长,默认 0.002 0.002 0.002s,影响计算速度与精度的最重要参数;
- gravity:重力方向,默认 ( 0 , 0 , − 9.81 ) (0,0,-9.81) (0,0,−9.81);
- density:环境介质密度,默认 0 0 0,可以修改你的仿真环境是在水下还是空气中,默认在空气中;
xml 文件示例如下:
<mujoco><!-- 环境标签 --><option gravity="0 0 -1" /><worldbody><light diffuse="0.5 0.5 0.5" pos="0 0 3" dir="0 0 -1"/> <geom name="ground" type="plane" size="1 1 0.1" rgba="0.5 0.5 0.5 1"/><body name="cube" pos="0 0 1"><joint type="free"/><geom type="box" size="0.1 0.1 0.1" rgba="0.0 0.0 0.5 1"/> </body></worldbody>
</mujoco>
【Note】:注意环境标签 <option>
的位置,由于环境标签是全局作用的,因此需要将其放在顶级域名之下。
2.3 单位与轴
因为存在 万向节死锁 的问题,有些算法会调整 rpy
的旋转顺序,mujoco 提供了标签 <compile>
来定义单位与轴旋转顺序;在没有明确定义的情况下度数单位为 弧度,但也可以通过修改来确定度的单位为 角度;
示例如下:
<mujoco><compiler angle="degree" eulerseq="yzx"/><worldbody><light diffuse="0.5 0.5 0.5" pos="0 0 3" dir="0 0 -1"/> <geom name="ground" type="plane" size="1 1 0.1" rgba="0.5 0.5 0.5 1"/><body name="cube" pos="0 0 1"><joint type="free"/><geom type="box" size="0.1 0.1 0.1" rgba="0.0 0.0 0.5 1"/> </body></worldbody></mujoco>
这些本质上和环境标签是同一类型,都是确定好后不会频繁变化的,因此在曾经结构上也是顶级位置。
2.4 通用资产定义
有些属性或变量可能会被多个对象使用,如果每个对象都重新写一遍会非常冗余,mujoco 提供了 <asset>
标签用来定义通用资产,并且允许对象直接使用。
<mujoco><asset><!-- 定义材质 --><material name="blue" rgba="0 0 0.5 1"/><!-- 定义凸包 --> <mesh name="tetrahedron" vertex="0 0 0 1 0 0 0 1 0 0 0 1"/></asset><worldbody><light diffuse="0.5 0.5 0.5" pos="0 0 3" dir="0 0 -1"/> <geom name="ground" type="plane" size="1 1 0.1" rgba="0.5 0.5 0.5 1"/><body name="cube" pos="0 0 1"><joint type="free"/><!-- 使用材质和凸包 --><geom type="box" size="0.1 0.1 0.1" material="blue" mesh="tetrahedron"/> </body></worldbody></mujoco>
上面的示例中使用了 mesh
这个标签,本质是表面网格,但 网格也可以定义成不带面的网格(本质上是点云)。在这种情况下,即使编译器属性 convexhull
为 false,凸包也会自动构建。这使得直接在 XML 中构建简单形状变得非常简单。例如,可以如下创建金字塔:
如果你想要使用 mesh
原本的含义,即物体表面渲染方式,那么这样写即可:
<mujoco><asset><material name="blue" rgba="0 0 0.5 1"/><!-- 前提是同级目录下有这个文件 --><mesh name="forearm" file="forearm.stl"/></asset><worldbody><light diffuse="0.5 0.5 0.5" pos="0 0 3" dir="0 0 -1"/> <geom name="ground" type="plane" size="1 1 0.1" rgba="0.5 0.5 0.5 1"/><body name="cube" pos="0 0 1"><joint type="free"/><geom type="box" size="0.1 0.1 0.1" material="blue" mesh="forearm"/> </body></worldbody></mujoco>
【Note】:由于 mujoco 不允许相同的 name
属性,因此定义 <asset>
标签时可以用一些带有前缀的变量,如 name="asset_blue"
,这样可以避免在复杂工程中存在名称冲突的情况,特别是有些厂商提供的模型文件中也定义了颜色和材质等对象。
2.5 文件包含
如果把所有的配置都写在一个文件中会非常难以梳理,mujoco 提供了 <include>
标签实现文件包含,我通常会将环境、单位、通用资产的定义写在一个 common.xml
文件中,在主文件中只关注对象的运动关系:
【Note】:所有包含与被包含文件中的元素都必须在 <mujoco>
这个根标签下,这是mujoco识别的依据。
- common.xml 文件
<mujoco><asset><material name="blue" rgba="0 0 0.5 1"/></asset>
</mujoco>
- merge.xml 文件
<mujoco><!-- 包含公共变量与资产 --><include file="./common.xml"/> <worldbody><light diffuse="0.5 0.5 0.5" pos="0 0 3" dir="0 0 -1"/> <geom name="ground" type="plane" size="1 1 0.1" rgba="0.5 0.5 0.5 1"/><body name="cube" pos="0 0 1"><joint type="free"/><geom type="box" size="0.1 0.1 0.1" material="blue"/> </body></worldbody></mujoco>
2.6 关节约束
重头戏来了 <joint>
关节约束。mujoco 对关节约束的定义和 urdf 文件基本一致,允许一下几种形式的约束:
- free:三个平移自由度 + 三个旋转自由度;
- ball:三个旋转自由度的球形关节,四元数 (1,0,0,0) 对应于定义初始状态;
- slide:一个平移自由度的滑动或平移关节,需要明确平移方向;
- hinge:铰链类型创建具有一个旋转自由度的铰链关节,需要明确旋转轴;
【Note】:为了更好的交互效果,这里提前引入了<actuator>
标签,否则无法在仿真器中拖拽。
示例如下:
<mujoco><worldbody><light diffuse="0.5 0.5 0.5" pos="0 0 3" dir="0 0 -1"/><geom name="ground" type="plane" size="5 5 0.1" rgba="0.5 0.5 0.5 1" friction="0.1 0.05 0.05"/><!-- 可拖拽立方体 --><body name="draggable_cube" pos="0 0 1"><joint name="x_slide" type="slide" axis="1 0 0" damping="5" stiffness="50" range="-3 3"/><joint name="y_slide" type="slide" axis="0 1 0" damping="5" stiffness="50" range="-3 3"/><geom name="cube" type="box" size="0.1 0.1 0.1" rgba="0 0.5 0.8 1" mass="5"/></body></worldbody><actuator><!-- 位置伺服控制器 --><position name="x_pos" joint="x_slide" kp="500" kv="20"/><position name="y_pos" joint="y_slide" kp="500" kv="20"/></actuator></mujoco>
启动仿真器后可以在右侧的 Control
面板中拖动滑块以观察立方体运动。
2.7 定义执行器
在上面的小节中提前用到了执行器 <actuator>
,这一小节将更细致介绍如何定义执行器标签来控制环境中的对象,你可以将执行器理解为 电机;
mujoco 提供了很多执行器工具,在其官网文档中点击左侧 XML Reference
连接后往下拉或者搜索 actuator
即可找到可用的执行器标签。为关节或对象添加执行器后就可以在控制对象的时候添加合适的参数,否则所有 joint 都是 free 形式。
我这里只列举我最常用的几个执行器,感兴趣的可以查看其官网并进行实验。
2.7.1 通用执行器 general
通用执行器允许独立设置所有执行器组件,包括传输类型、激活动态、增益类型等。是一个非常灵活的执行器类型,允许用户自定义执行器的动态特性、增益、偏置,可以实现各种类型的执行器,如直接驱动、位置伺服、速度伺服等。
这个例子实现了一个力执行器,为了让滑块能够在力消失时停下来,在地面和滑块中都添加了friction
属性以体现摩擦力:
<mujoco><worldbody><light diffuse="0.5 0.5 0.5" pos="0 0 5" dir="0 0 -1"/> <!-- 地面:高滑动摩擦 --><geom name="ground" type="plane" size="5 5 0.1" pos="0 0 0" rgba="0.5 0.5 0.5 1" friction="1.5 0.3 0.05"solimp="0.9 0.95 0.001" solref="0.02 1"/><!-- 滑块:中等摩擦 --><body name="slider" pos="0 0 0.1"><joint name="slide_joint" type="slide" axis="1 0 0" damping="0.2"/><geom type="box" size="0.2 0.1 0.1" rgba="0 0.5 0.8 1" mass="0.5" friction="1.0 0.2 0.02"/></body></worldbody><actuator><general name="force" joint="slide_joint" ctrlrange="-1 1"/></actuator>
</mujoco>
启动仿真器后在右侧控制面板中拖拽 force
滑块就可以给其传入一个力,点击 Clear all
就可以将力清空然后观察滑块逐渐停下来。
由于 joint 的活动范围可以通过其属性 range
定义,如果不想给物体添加摩擦力也可以通过限制活动范围让物体停下来,停下后即便有力物体也不会继续运动
<mujoco><worldbody><light diffuse="0.5 0.5 0.5" pos="0 0 5" dir="0 0 -1"/> <!-- 地面--><geom name="ground" type="plane" size="5 5 0.1" pos="0 0 0" rgba="0.5 0.5 0.5 1"solimp="0.9 0.95 0.001" solref="0.02 1"/><!-- 滑块 添加了range属性限制活动范围 --><body name="slider" pos="0 0 0.1"><joint name="slide_joint" type="slide" axis="1 0 0" damping="0.2" range="-2 2"/><geom type="box" size="0.2 0.1 0.1" rgba="0 0.5 0.8 1" mass="0.5" /></body></worldbody><actuator><general name="force" joint="slide_joint" ctrlrange="-1 1"/></actuator>
</mujoco>
2.7.2 位置伺服 position
位置伺服在上面的小节中已经用了一次,这个控制器就是一个位置环伺服,有点类似与 PID 一样的控制器,所以你在滑动的时候会发现有一个明显的回调过程,通过修改 kp
和 kv
可以体验阻尼大小。
<mujoco><worldbody><light diffuse="0.5 0.5 0.5" pos="0 0 5" dir="0 0 -1"/> <geom name="ground" type="plane" size="5 5 0.1" pos="0 0 0" rgba="0.5 0.5 0.5 1"solimp="0.9 0.95 0.001" solref="0.02 1"/><body name="slider" pos="0 0 0.1"><joint name="slide_joint" type="slide" axis="1 0 0" damping="0.2" range="-2 2"/><geom type="box" size="0.2 0.1 0.1" rgba="0 0.5 0.8 1" mass="0.5" /></body></worldbody><actuator><position name="position" joint="slide_joint" kp="100" kv="10"/></actuator>
</mujoco>
2.7.3 速度伺服 velocity
既然有位置伺服那当然还有速度伺服,和位置伺服同理,速度伺服也用来调控速度到目标值
<mujoco><worldbody><light diffuse="0.5 0.5 0.5" pos="0 0 5" dir="0 0 -1"/> <geom name="ground" type="plane" size="5 5 0.1" pos="0 0 0" rgba="0.5 0.5 0.5 1"solimp="0.9 0.95 0.001" solref="0.02 1"/><body name="slider" pos="0 0 0.1"><joint name="slide_joint" type="slide" axis="1 0 0" damping="0.2" range="-2 2"/><geom type="box" size="0.2 0.1 0.1" rgba="0 0.5 0.8 1" mass="0.5" /></body></worldbody><actuator><velocity name="velocity" joint="slide_joint" kv="50"/></actuator>
</mujoco>
2.7.4 电机执行器 motor
电机只能输出与关节自由度相同的力和力矩,如果你很明确这个 joint 需要输出的是力,那么建议用这个,虽然通用执行器也可以实现相同的效果,但设置起来没有电机执行器简洁。
<mujoco><worldbody><light diffuse="0.5 0.5 0.5" pos="0 0 5" dir="0 0 -1"/> <geom name="ground" type="plane" size="5 5 0.1" pos="0 0 0" rgba="0.5 0.5 0.5 1"solimp="0.9 0.95 0.001" solref="0.02 1"/><body name="slider" pos="0 0 0.1"><joint name="slide_joint" type="slide" axis="1 0 0" damping="0.2" range="-2 2"/><geom type="box" size="0.2 0.1 0.1" rgba="0 0.5 0.8 1" mass="0.5" /></body></worldbody><actuator><motor name="motor" joint="slide_joint" gear="1"/></actuator>
</mujoco>
2.8 显示坐标轴
坐标轴的显示在仿真中非常重要,打开仿真器后展开左侧工具栏中的 Rendering
标签,通过选择 Frame
即可选择想要显示的坐标轴。
相关文章:

Mujoco 学习系列(二)基础功能与xml使用
这篇文章是 Mujoco 学习系列第二篇,主要介绍一些基础功能与 xmI 使用,重点在于如何编写与读懂 xml 文件。 运行这篇博客前请先确保正确安装 Mujoco 并通过了基本功能与GUI的验证,即至少完整下面这个博客的 第二章节 内容: Mujoc…...

比特授权云外壳加密支持Android 15!
在信息化时代,多数软件供应商需要适配安卓系统,以扩大市场、满足用户需求并提升竞争力。APK作为Android应用的安装包,包含代码、资源、配置文件等运行所需组件,用于在设备端分发和安装应用。企业在分发软件时,需要通过…...

uniapp使用sse连接后端,接收后端推过来的消息(app不支持!!)
小白终成大白 文章目录 小白终成大白前言一、什么是SSE呢?和websocket的异同点有什么?相同点不同点 二、直接上实现代码总结 前言 一般的请求就是前端发 后端回复 你一下我一下 如果需要有什么实时性的 后端可以主动告诉前端的技术 我首先会想到 webso…...

历年复旦大学保研上机真题
2025复旦大学保研上机真题 2024复旦大学保研上机真题 2023复旦大学保研上机真题 在线测评链接:https://pgcode.cn/problem?classification1 最大公共子串 题目描述 输入 3 个子串,输出这 3 个子串的最大公共子串。 输入格式 输入包含 3 个子串&…...

黑马点评-实现安全秒杀优惠券(使并发一人一单,防止并发超卖)
一.实现优惠券秒杀 1.最原始代码: Service public class VoucherOrderServiceImpl extends ServiceImpl<VoucherOrderMapper, VoucherOrder> implements IVoucherOrderService {Resourceprivate ISeckillVoucherService seckillVoucherService;Resourcepriv…...

解决论文中字体未嵌入的问题
文章总览:YuanDaiMa2048博客文章总览 解决论文中字体未嵌入的问题 问题描述解决方案:使用 Adobe PDF 打印机嵌入字体(WPS版)步骤一:打开 PDF 文件步骤二:选择打印到 Adobe PDF步骤三:修改 Adobe…...

leetcode 131. Palindrome Partitioning
目录 一、题目描述 二、方法1、回溯法每次暴力判断回文子串 三、方法2、动态规划回溯法 一、题目描述 分割回文子串 131. Palindrome Partitioning 二、方法1、回溯法每次暴力判断回文子串 class Solution {vector<vector<string>> res;vector<string>…...
Android本地语音识别引擎深度对比与集成指南:Vosk vs SherpaOnnx
技术选型对比矩阵 对比维度VoskSherpaOnnx核心架构基于Kaldi二次开发ONNX Runtime + K2新一代架构模型格式专用格式(需专用工具转换)ONNX标准格式(跨框架通用)中文识别精度89.2% (TDNN模型)92.7% (Zipformer流式模型)内存占用60-150MB30-80MB迟表现320-500ms180-300ms多线程…...

审计报告附注救星!实现Word表格纵向求和+横向计算及其对应的智能校验
在审计工作中,Word附注通常包含很多表格。为了确保附注数字的准确性,我们需要对这些表格进行数字逻辑校验,主要包含两个维度:在纵向上验证合计项金额是否正确;在横向上检查“年末金额年初金额本期增加-本期减少”的勾稽…...

人工智能数学基础实验(四):最大似然估计的-AI 模型训练与参数优化
一、实验目的 理解最大似然估计(MLE)原理:掌握通过最大化数据出现概率估计模型参数的核心思想。实现 MLE 与 AI 模型结合:使用 MLE 手动估计朴素贝叶斯模型参数,并与 Scikit-learn 内置模型对比,深入理解参…...

告别延迟!Ethernetip转modbustcp网关在熔炼车间监控的极速时代
熔炼车间热火朝天,巨大的热风炉发出隆隆的轰鸣声,我作为一名技术操控工,正密切关注着监控系统上跳动的各项参数。这套基于EtherNET/ip的监控系统,是我们车间数字化改造的核心,它将原本分散的控制单元整合在一起&#x…...
Kotlin协程优化Android ANR问题
引言 在Android开发中,ANR(Application Not Responding)是用户体验的致命杀手。当主线程被耗时操作阻塞超过阈值(5秒前台/10秒后台),系统会直接弹窗提示应用无响应。本文将深入剖析如何通过Kotlin协程将耗…...

Visual Studio Code插件离线安装指南:从市场获取并手动部署
Visual Studio Code插件离线安装指南:从市场获取并手动部署 一、场景背景二、操作步骤详解步骤1:访问官方插件市场步骤2:定位目标版本步骤3:提取关键参数步骤4:构造下载链接步骤5:下载与安装 三、注意事项 …...
构建安全AI风险识别大模型:CoT、训练集与Agent vs. Fine-Tuning对比
构建安全AI风险识别大模型:CoT、训练集与Agent vs. Fine-Tuning对比 安全AI风险识别大模型旨在通过自然语言处理(NLP)技术,检测和分析潜在的安全威胁,如数据泄露、合规违规或恶意行为。本文从Chain-of-Thought (CoT)设计、训练集构建、以及Agent-based方法与**AI直接调优…...

计算机视觉---YOLOv1
YOLOv1深度解析:单阶段目标检测的开山之作 一、YOLOv1概述 提出背景: 2016年由Joseph Redmon等人提出,全称"You Only Look Once",首次将目标检测视为回归问题,开创单阶段(One-Stage)…...
无法同步书签,火狐浏览器修改使用国内的账号服务器
自动更新版本后,变为国际服版本的了,点击右上角无法登录firefox,也无法同步书签,现在国际服的火狐浏览器修改使用国内的账号服务器,需要先在搜索框输入 about:config 中改变三项配置,然后重启浏览器,才能正常使用国内的火狐账号服务器 ident…...
动态防御体系实战:AI如何重构DDoS攻防逻辑
1. 传统高防IP的静态瓶颈 传统高防IP依赖预定义规则库,面对SYN Flood、CC攻击等常见威胁时,常因规则更新滞后导致误封合法流量。例如,某电商平台遭遇HTTP慢速攻击时,静态阈值过滤无法区分正常用户与攻击者,导致订单接…...
Kotlin Native与C/C++高效互操作:技术原理与性能优化指南
一、互操作基础与性能瓶颈分析 1.1 Kotlin Native调用原理 Kotlin Native通过LLVM编译器生成机器码,与C/C++的互操作基于以下核心机制: CInterop工具:解析C头文件生成Kotlin/Native绑定(.klib),自动生成类型映射和包装函数双向调用约定: Kotlin调用C:直接通过生成的绑…...

爬虫核心概念与工作原理详解
爬虫核心概念与工作原理详解 1. 什么是网络爬虫? 网络爬虫(Web Crawler)是一种按照特定规则自动抓取互联网信息的程序或脚本,本质是模拟人类浏览器行为,通过HTTP请求获取网页数据并解析处理。 形象比喻:如…...
Flink架构概览,Flink DataStream API 的使用,FlinkCDC的使用
一、Flink与其他组件的协同 Flink 是一个分布式、高性能、始终可用、准确一次(Exactly-Once)语义的流处理引擎,广泛应用于大数据实时处理场景中。它与 Hadoop 生态系统中的组件可以深度集成,形成完整的大数据处理链路。下面我们从…...

vue3前端后端地址可配置方案
在开发vue3项目过程中,需要切换不同的服务器部署,代码中配置的服务需要可灵活配置,不随着run npm build把网址打包到代码资源中,不然每次切换都需要重新run npm build。需要一个配置文件可以修改服务地址,而打包的代码…...
Es6中怎么使用class实现面向对象编程
在 JavaScript 中,面向对象的类可以通过 class 关键字来定义。以下是一个简单的示例,展示了如何定义一个类、创建对象以及添加方法: 基础类定义 // 定义一个类 class MyClass { // 构造函数,用于初始化对象的属性 constructor(pa…...

digitalworld.local: FALL靶场
digitalworld.local: FALL 来自 <digitalworld.local: FALL ~ VulnHub> 1,将两台虚拟机网络连接都改为NAT模式 2,攻击机上做namp局域网扫描发现靶机 nmap -sn 192.168.23.0/24 那么攻击机IP为192.168.23.182,靶场IP192.168.23.4 3&…...

MySQL---库操作
mysql> create database if not exists kuku3; 1.库操作的语法 create database [if not exists] db_name [create_specification [, create_specification] ...] create_specification: [default] character set charset_name [default] collate collation_name详细解释…...

动态规划算法:字符串类问题(2)公共串
0 前言 上节课我们已经讲述了使用动态规划求取回文串长度与数量的方法(和本节课关系不大,感兴趣可以去看字符串类问题(1)回文串),这节课我们继续探索字符串问题中的动态规划问题。 进入本篇文章前&#x…...
uni-app(5):Vue3语法基础上
Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue.js 的核心是一个允许采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统,只关注视图层,…...

深度解析Vue项目Webpack打包分包策略 从基础配置到高级优化,全面掌握性能优化核心技巧
深度解析Vue项目Webpack打包分包策略 从基础配置到高级优化,全面掌握性能优化核心技巧 一、分包核心价值与基本原理 1.1 为什么需要分包 首屏加载优化:减少主包体积,提升TTI(Time to Interactive)缓存利用率提升&am…...
ubuntu下docker安装mongodb-支持单副本集
1.mogodb支持事务的前提 1) MongoDB 版本:确保 MongoDB 版本大于或等于 4.0,因为事务支持是在 4.0 版本中引入的。 2) 副本集配置:MongoDB 必须以副本集(Replica Set)模式运行,即使是单节点副本集&#x…...

spring-boot-starter-data-redis应用详解
一、依赖引入与基础配置 添加依赖 在 pom.xml 中引入 Spring Data Redis 的 Starter 依赖,默认使用 Lettuce 客户端: <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis<…...

5060显卡驱动PyCUDA开发环境搭建
5060显卡驱动PyCUDA开发环境搭建 本文手把手讲解了RTX5060ti显卡从上手尝试折腾,到在最新Ubuntu LTS版本上CUDA开发环境搭建成功的详细流程。 1.1 开机后Ubuntu2404LTS不识别显卡 1.1.1 显卡硬件规格要求 笔者下单的铭瑄电竞之心,安装规格是PCIe …...