news 2026/10/23 11:57:47

简单的yolo识别训练并移植到ROS1

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
简单的yolo识别训练并移植到ROS1

第一步:本地环境检测与创建(核心)

训练模型对显卡(GPU)有硬性要求。在本地 Dell 电脑上,我们需要建立一个支持 CUDA 加速的 PyTorch 环境。

1.1 硬件与驱动检查

在 Dell 电脑上打开普通的命令提示符(cmd)或终端,运行以下命令:

nvidia-smi
  • 检查目的:确认你的 Dell 电脑是否有 NVIDIA 显卡(如 RTX 3060/4060 等),并记录下右上角显示的CUDA Version(例如CUDA Version: 12.x或11.x)。这决定了你后续能安装的 PyTorch 版本。

1.2 创建隔离的 Anaconda 虚拟环境

为了不污染你电脑上的其他 Python 项目,建议在本地也创建一个名为yolov5_train的独立虚拟环境。

在 Anaconda Prompt(或终端)中依次输入:

# 1. 创建 Python 3.8 的虚拟环境 conda create -n yolov5_train python=3.8 -y # 2. 激活该虚拟环境 conda activate yolov5_train

检测当前环境:请把下面这行测试脚本直接复制到你当前的终端(确保处于(yolov5_train)环境下)并回车运行:

python3 -c " try: import torch print('✅ PyTorch 已安装,版本:', torch.__version__) print('🔥 GPU 加速(CUDA)状态:', torch.cuda.is_available()) if torch.cuda.is_available(): print(' 显卡型号:', torch.cuda.get_device_name(0)) except ImportError: print('❌ 未检测到 PyTorch') try: import torchvision print('✅ Torchvision 已安装,版本:', torchvision.__version__) except ImportError: print('❌ 未检测到 Torchvision') "

1.3 安装带 CUDA 加速的 PyTorch

根据你 1.1 步骤中查到的 CUDA 版本,去 PyTorch 官网挑选对应的安装命令。

  • 如果是 CUDA 11.x,通用安装命令通常为:

pip install torch==1.12.1+cu113 torchvision==0.13.1+cu113 --extra-index-url https://download.pytorch.org/whl/cu113

1.4 环境验证测试(关键)

环境装好后,必须运行以下脚本验证 GPU 是否真正被 PyTorch 识别。在激活的虚拟环境中输入python进入交互模式:

import torch print("PyTorch版本:", torch.__version__) print("CUDA是否可用:", torch.cuda.is_available()) if torch.cuda.is_available(): print("当前显卡名称:", torch.cuda.get_device_name(0))

  • 通关标准:必须输出CUDA是否可用: True并且正确打印出你的 NVIDIA 显卡型号。如果输出为False,说明安装成了 CPU 版本,无法用来加速训练。

  • 输入exit()退出 Python。

1.5 安装 YOLOv5 依赖源码包

将你小车上的yolov5-pytorch源码整体复制到这台 Dell 电脑上,在终端中cd进入该目录,利用国内源快速安装剩下的工具包:

cd path/to/yolov5-pytorch pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple

第二步:数据标注工具安装以及数据标注

2.1 标注工具(LabelImg)

需要在本地电脑上安装一个图片标注软件,用来框选你的数字。

pip install labelimg # 在终端直接输入 labelimg 即可打开可视化界面

2.2 采集“数字标牌”数据集(核心资产)

  • 拍照采集:用手机或小车摄像头,拍摄比赛/课设中使用的数字标牌(1、2、3、4)。

  • 场景多样性:每个数字至少在不同的光照、不同的距离、不同的侧倾角度下拍摄50 ~ 100 张照片。整个数据集建议在 300 张照片以上。

  • 摆放结构:在yolov5-pytorch根目录下,按照说明书创建VOCdevkit/VOC2007/JPEGImages(放图片)和VOCdevkit/VOC2007/Annotations(放后面生成的 xml 标注)。

2.3 配置文件修改

  • 类别文件:在model_data/下新建num_classes.txt,里面写上:

1 2 3 4
  • 修改路径:修改voc_annotation.py中的classes_path指向这个num_classes.txt,运行它来自动切分出训练集和验证集的索引文件(2007_train.txt)。

2.4 预训练权重垫底(yolov5_s.pth)

  • 训练不能从零瞎猜,需要“站在巨人的肩膀上”。确保你的model_data/目录下有你之前看到的yolov5_s.pth文件。train.py会读取它作为基础特征(骨干网络),在此基础上收敛出你的数字特征。

2.5 启动 LabelImg 标注工具

在终端输入:

labelimg

(如果弹出界面,但终端疯狂报错提示缺少pyqt等,请运行

pip install labelimg -i https://pypi.tuna.tsinghua.edu.cn/simple

后重试)

2.6 进行黄金三配置(最重要,防止格式出错)

打开 LabelImg 的图形化界面后,请立即完成这 3 点设置,这是数据成功的关键:

  1. 确定格式:点击界面左侧工具栏的那个大大的按钮(它默认可能是 YOLO 或 CreateML),多点几次,直到它显示为PascalVOC。

    💡 原因:你的小车代码包默认配置的是 VOC 数据格式,如果我们选错了格式,后面训练时会报错找不到标签。
  2. 设置图片目录 (Open Dir):

    • 点击界面左侧的Open Dir按钮。

    • 选择目录:📁~/yolo5/yolov5-pytorch/VOCdevkit/VOC2007/JPEGImages。

    • 此时你就能在界面上看到你的第一张数字图片了。

  3. 设置保存目录 (Change Save Dir):

    • 点击界面左侧的Change Save Dir按钮。

    • 选择目录:📁~/yolo5/yolov5-pytorch/VOCdevkit/VOC2007/Annotations。

    • 💡 原因:这能确保每一个框选操作生成的.xml标签文件,都被精准地存在它该去的地方。

2.7 开始纯鼠标流标注步骤

配置好后,开始给这 173 张图片“点石成金”:

  1. 启用框选:在键盘上按下W键(Create\RectBox),此时你的鼠标会变成一个十字光标。

  2. 画框:用鼠标十字瞄准图片里你要识别的数字标牌,左键按住不放拖动,拉出一个大小适中、刚好把数字标牌完全包裹住的框。

  3. 输入标签名:松开鼠标左键,会弹出一个输入框。请直接输入你要训练的真实数字:

    • 如果是数字 1,就输入1。

    • 如果是数字 2,就输入2。

    • (依此类推,不要写复杂的名字如“num_1”,只写纯数字标签)。点击 OK。

  4. 保存:按下键盘Ctrl + S(Save),保存这行标注。

    • (此时隔壁的 Annotations 文件夹里会多出一个对应的 xml 文件)

  5. 切换下一张:按下键盘D键(Next Image),LabelImg 会自动加载第 2 张图片。

  6. 重复:重复W(框选) -> 输入数字 ->Ctrl+S(保存) ->D(下一张) 的循环。

# 1. 下载 labelImg 的官方纯源码包 git clone https://github.com/HumanSignal/labelImg.git # 2. cd 进入刚刚下载的源码目录 cd labelImg # 3. 编译出 Linux 系统需要的界面资源文件 pyrcc5 -o libs/resources.py resources.qrc # 4. 直接用 Python 启动源码 python3 labelImg.py

第三步:生成训练索引与启动模型训练

3.1 生成数据索引文件 (2007_train.txt)

训练代码需要通过文本索引文件找到对应图片的标注路径。在终端中确保处于(yolov5_train)虚拟环境下,执行:

# 确保在项目根目录 cd ~/yolo5/yolov5-pytorch # 生成数据集索引文件 python3 voc_annotation.py

检查输出:运行完毕后,项目根目录下会自动生成2007_train.txt和2007_val.txt。可以通过ls -l确认文件已建立。

3.2 启动训练

在你的源码架构(基于 bubbliiiing 版本 yolov5-pytorch)中,核心配置默认已在train.py文件内设置,只需确认代码中classes_path已指向model_data/num_classes.txt。

1. 直接运行默认训练命令(最简指令)
python3 train.py
2. 自定义参数启动命令(推荐)

如果你需要通过命令行动态覆盖参数(如调整 Batch Size、训练轮数等),直接复制并运行以下指令:

python3 train.py \ --model_path model_data/yolov5_s.pth \ --classes_path model_data/num_classes.txt \ --input_shape 640 640 \ --Epoch 50 \ --batch_size 8 \ --num_workers 4 \ --cuda True

💡 Ubuntu 训练常见问题与调试建议

  • 显存溢出 (CUDA Out of Memory):如果显卡显存较小导致报错,将--batch_size调小(例如改成4或2):

    python3 train.py --batch_size 4
  • DataLoader 多进程报错:若提示 multiprocessing 错误,可将--num_workers设为0:

    python3 train.py --num_workers 0
  • 后台挂载训练(防止终端中断):

    nohup python3 train.py > train.log 2>&1 & tail -f train.log # 实时查看后台输出

训练结果与部署

训练启动后,模型权重与日志会自动保存到logs/目录中:

  • best_epoch_weights.pth:准确率最高的模型权重(训练完成后将此文件拷贝到小车端/树莓派端部署使用)。

  • last_epoch_weights.pth:最后一轮训练结束后的权重。

完整全流程:从录制视频 → 抽帧 → LabelImg标注 → 更新ImageSets → 生成训练索引 → 训练 → 导出OAK模型 → ROS部署

适配你的项目:工件实物颜色固定,光照会变化,工件运动距离可变;bubbliiiing‑yolov5‑pytorch;Pascal‑VOC(xml)标签格式。 重点标注:什么时候、用什么命令更新ImageSets/Main下面的txt文件。

0.前期准备

工作目录:~/yolo5

  • oak录制视频输出:~/yolo5/workpiece_video/xxx.mp4(OAK录制的工件视频)
  • yolov5‑pytorch项目路径:~/yolo5/yolov5‑pytorch
  • labelImg路径:~/yolo5/labelImgVOC目录结构(标准)
yolov5‑pytorch/VOCdevkit/VOC2007/ ├─JPEGImages/ #存放所有抽帧jpg图片 ├─Annotations/ #存放对应xml标签,图片和xml同名一一对应 └─ImageSets/Main/ #trainval.txt / train.txt / val.txt / test.txt,**由voc_annotation.py自动生成,不要手动编辑!**

步骤1:OAK录制工件视频

  1. 固定OAK相机支架;工件在实际工作运动区间运动;
  2. 覆盖现场全部实际工作距离(近‑远),包含现场典型光照:正常灯光、轻微阴影、明暗变化;

    ⚠️只录制【实物标准大小、标准本体颜色】工件;不要录制变色、异形、别的物体。

  3. 运行oak_record_video.py录制视频,保存到~/yolo5/workpiece_video/,例如work_01.mp4。

步骤2:视频抽帧,把图片放进JPEGImages

运行video_to_frames.py抽帧,间隔不要太密避免大量重复图片。

cd ~/yolo5 python3 video_to_frames.py
  • 输出图片命名格式:num_target_0000.jpg、num_target_0001.jpg …
  • 将抽帧得到的全部.jpg复制到VOC的JPEGImages文件夹
cp workpiece_images/*.jpg ~/yolo5/yolov5-pytorch/VOCdevkit/VOC2007/JPEGImages/

校验:

ls ~/yolo5/yolov5-pytorch/VOCdevkit/VOC2007/JPEGImages

确认图片全部存在。

步骤3:LabelImg标注(PascalVOC)

cd ~/yolo5/labelImg pyrcc5 -o libs/resources.py resources.qrc python3 labelImg.py

界面设置:

  1. 左上角格式切换为PascalVOC(生成xml,不是YOLO txt)
  2. Open Dir→ 选择:~/yolo5/yolov5‑pytorch/VOCdevkit/VOC2007/JPEGImages
  3. Change Save Dir→ 选择:~/yolo5/yolov5‑pytorch/VOCdevkit/VOC2007/Annotations

标注操作规则:

  1. W画框,框住标准工件;弹出类别输入框填写:target_workpiece;
  2. 无论图片里面有没有工件,必须按 Ctrl+S 保存,生成同名xml,再按D下一张!

    没有工件也要保存空xml,否则后续脚本报xml找不到。 图片名num_target_xxxx.jpg↔ 标签num_target_xxxx.xml,名字必须完全一模一样。

标注完成校验:jpg数量 = xml数量

cd ~/yolo5/yolov5-pytorch/VOCdevkit/VOC2007 ls JPEGImages/*.jpg | wc -l ls Annotations/*.xml | wc -l

两个数字必须相等。

步骤4:更新 ImageSets/Main 的全部txt文件【重点】

⚠️不要手动编辑trainval.txt!不要自己手写文件名进去!bubbliiiing的voc_annotation.py,当annotation_mode = 0时: 脚本会自动扫描Annotations文件夹下面所有真实存在的xml文件,自动生成 ImageSets/Main下面:trainval.txt、train.txt、val.txt、test.txt。 新增/删除图片‑xml之后,只需要重新运行voc_annotation.py,ImageSets内容自动刷新。

  1. 确认voc_annotation.py头部配置
annotation_mode = 0 classes_path = 'model_data/work_classes.txt' trainval_percent = 0.9 train_percent = 0.9 VOCdevkit_path = 'VOCdevkit'
  • annotation_mode=0:①扫描Annotations的xml,重写ImageSets下面全部txt;②再生成根目录的2007_train.txt、2007_val.txt训练索引。
  • annotation_mode=1:仅生成ImageSets下面txt,不生成2007_train/val.txt
  • annotation_mode=2:只读取已有的ImageSets/train.txt、val.txt,不会刷新ImageSets!(新增图片时绝对不要用mode=2)
  1. 确认类别文件model_data/work_classes.txt
cd ~/yolo5/yolov5-pytorch cat model_data/work_classes.txt

内容只有一行,无多余空格换行:

target_workpiece
  1. 运行脚本,自动刷新ImageSets!
python3 voc_annotation.py

输出示例:

Generate txt in ImageSets. train and val size XX train size XX Generate txt in ImageSets done. Generate 2007_train.txt and 2007_val.txt for train done. | target_workpiece | XX |

✔此时VOCdevkit/VOC2007/ImageSets/Main/trainval.txt已经自动更新为当前Annotations内所有xml对应的id。 脚本内部逻辑:读取Annotations下全部.xml,去掉后缀得到图片id,随机划分train/val/test,写入ImageSets下各个txt。

查看ImageSets/Main/trainval.txt确认内容

cat VOCdevkit/VOC2007/ImageSets/Main/trainval.txt

同时项目根目录生成训练用索引文件:2007_train.txt、2007_val.txt,这两个是给train.py读取的。

⚠️重要规则(以后新增图片牢记)

每次新增一批图片+xml:

  1. 把jpg复制进JPEGImages;
  2. labelImg全部标注生成对应xml;
  3. 修改voc_annotation.py确保annotation_mode = 0;
  4. 执行python3 voc_annotation.py,自动刷新ImageSets全部内容,自动生成2007_train/val.txt。

    ❌不要手动修改ImageSets里面任何txt!手动改会出现id和实际xml不一致,报FileNotFound。

步骤5:修改训练相关配置文件

5‑1 train.py 修改

classes_path = 'model_data/work_classes.txt' input_shape = [640, 640] mosaic = False model_path = "model_data/yolov5_s.pth" Freeze_Train = False UnFreeze_Epoch = 100 Unfreeze_batch_size = 8 #显存不足改为4/2 num_workers = 0 eval_flag = True

5‑2 utils/dataloader.py 修改数据增强(适配你的光照变化需求)

打开utils/dataloader.py

  1. get_random_data函数头部参数
def get_random_data(self, annotation_line, input_shape, jitter=.3, hue=0.0, sat=0.25, val=0.30, random=True):
  1. get_random_data_with_Mosaic函数头部参数
def get_random_data_with_Mosaic(self, annotation_line, input_shape, jitter=0.3, hue=0.0, sat=0.25, val=0.30):
  • hue=0.0关闭色相偏移,拒绝识别别的颜色物体;
  • sat、val小扰动模拟现场明暗光照变化;
  • 保留随机scale缩放,适配工件远近运动成像大小变化;
  • 工件非对称:注释掉flip翻转代码。
  • train.py设置mosaic=False,mosaic增强不会执行。

步骤6:开始训练模型

cd ~/yolo5/yolov5-pytorch #前台运行 python3 train.py #或者后台运行 nohup python3 train.py > train_log.txt 2>&1 & tail -f train_log.txt

注意:样本数量过少会触发ZeroDivisionError,此时需要扩充数据集;临时调试可以eval_flag=False并修改utils_fit.py跳过验证loss计算,仅用于跑通流程,不用于实际项目。

训练完成,最优权重:logs/best_epoch_weights.pth

步骤7:导出ONNX,再转OAK的OpenVINO IR模型

⚠️必须用bubbliiiing自带export_onnx.py,不能用ultralytics的export

python export_onnx.py --weights logs/best_epoch_weights.pth --input_shape 640,640 ov-convert model.onnx --output_model workpiece

得到:workpiece.xml、workpiece.bin

步骤8:复制模型、标签到ROS2 oak_arm_detector包

cp workpiece.xml ~/work/2026.7ROS2/1/2026.9.3/2026./nav_ws_x86/src/core/oak_arm_detector/model/workpiece_model/ cp workpiece.bin ~/work/2026.7ROS2/1/2026.9.3/2026./nav_ws_x86/src/core/oak_arm_detector/model/workpiece_model/ echo "target_workpiece" > ~/work/2026.7ROS2/1/2026.9.3/2026./nav_ws_x86/src/core/oak_arm_detector/labels_work.txt

步骤9:编译ROS2包,启动空间检测节点(SpatialDetectionNetwork,深度计算真实物理尺寸过滤)

节点逻辑:不用像素面积过滤,依靠OAK双目深度计算工件真实mm物理长宽做过滤;同时识别机械臂,两者同时满足才输出匹配信号。

cd ~/work/2026.7ROS2/1/2026.9.3/2026./nav_ws_x86 colcon build --packages-select oak_arm_detector source install/setup.bash ros2 launch oak_arm_detector oak_detector.launch.py

新开终端观察话题输出

ros2 topic echo /oak/arm_work_match ros2 topic echo /oak/workpiece_xyz_mm ros2 topic echo /oak/workpiece_real_wh_mm

附录:常见故障点&ImageSets相关坑

  1. ❌手动修改ImageSets/Main/trainval.txt:新增图片之后脚本读取旧id,报xml找不到。 ✅正确:annotation_mode=0运行voc_annotation.py自动扫描Annotations,刷新全部ImageSets内容。
  2. ❌annotation_mode=2运行voc_annotation.py:不会刷新ImageSets,只会读取旧的train.txt/val.txt,新增图片不会加入训练集。
  3. ❌标注图片,图内无工件直接D下一张,不Ctrl+S:缺少xml,voc_annotation.py直接FileNotFound。 ✅正确:每张图片必须Ctrl+S保存,生成同名xml,空目标也是空xml。
  4. 图片删除操作:
  • 删除JPEGImages里面的jpg;
  • 删除Annotations里面对应的xml;
  • 执行python3 voc_annotation.py,annotation_mode=0,ImageSets自动剔除该id。

极简记忆版(新增一批数据只做这几步)

  1. 视频抽帧 → jpg复制进JPEGImages
  2. labelImg全部标注,每张Ctrl+S生成xml
  3. voc_annotation.py保持annotation_mode=0,运行python3 voc_annotation.py👉自动更新ImageSets/Main全部txt,自动生成2007_train.txt、2007_val.txt
  4. 执行训练。

ONNX → OpenVINO IR(xml/bin)完整转换操作步骤

环境状态:已经成功安装openvino‑dev,mo命令可用;已经导出model.onnx(422K) ⚠️新版本mo参数:没有--output_model,改用--output_dir和--model_name

步骤1:切换到onnx所在项目目录

cd ~/yolo5/yolov5-pytorch

确认model.onnx存在:

ls -lh model.onnx

输出示例:-rw‑rw‑r-- 1 a a 422K 10月 8 17:21 model.onnx

步骤2:执行mo模型转换命令

mo --input_model model.onnx --output_dir ./ --model_name workpiece

参数说明:

  • --input_model model.onnx:输入的ONNX模型文件
  • --output_dir ./:输出到当前工作目录
  • --model_name workpiece:生成模型文件前缀,输出workpiece.xml、workpiece.bin

如果出现算子/opset兼容报错,使用带opset参数版本:

mo --input_model model.onnx --output_dir ./ --model_name workpiece --opset 17

日志提示MO command line tool is considered as the legacy conversion API属于版本警告,直接忽略,不影响使用。

步骤3:校验转换输出产物

ls -lh workpiece.xml workpiece.bin

正常会看到两个不为0字节的文件:

  • workpiece.xml:网络拓扑描述文件
  • workpiece.bin:模型权重二进制文件

步骤4:复制xml/bin到ROS2 oak_arm_detector模型目录

cp workpiece.xml ~/work/2026.7ROS2/1/2026.9.3/2026./nav_ws_x86/src/core/oak_arm_detector/model/workpiece_model/ cp workpiece.bin ~/work/2026.7ROS2/1/2026.9.3/2026./nav_ws_x86/src/core/oak_arm_detector/model/workpiece_model/

步骤5:生成类别标签文件labels_work.txt

echo "target_workpiece" > ~/work/2026.7ROS2/1/2026.9.3/2026./nav_ws_x86/src/core/oak_arm_detector/labels_work.txt

步骤6:进入ROS工作空间,编译包并source环境

cd ~/work/2026.7ROS2/1/2026.9.3/2026./nav_ws_x86 colcon build --packages-select oak_arm_detector source install/setup.bash

步骤7:启动OAK识别launch文件

ros2 launch oak_arm_detector oak_detector.launch.py

步骤8:新开终端,监听业务话题,观察输出

ros2 topic echo /oak/arm_work_match ros2 topic echo /oak/workpiece_xyz_mm ros2 topic echo /oak/workpiece_real_wh_mm

部署前必须修改(否则深度尺寸过滤会全部拦截工件)

打开oak_arm_detector/main_double_model.py填入你的工件真实物理毫米尺寸+合理公差

self.real_w_min = xxx self.real_w_max = xxx self.real_h_min = xxx self.real_h_max = xxx

硬性对齐约束:训练图像尺寸640×640 → 导出onnx 640×640 → OAK节点内部推理输入也必须是640×640。

常见问题

  1. mo:未找到命令:执行export PATH=$PATH:~/.local/bin,把用户本地脚本目录加入PATH;
  2. 转换警告legacy conversion API:忽略;
  3. numpy版本冲突警告ml‑dtypes requires numpy>=2.0.0:推理场景可以忽略,当前numpy=1.26.4适配YOLO训练。

完整一键复制整组命令(直接粘贴执行)

cd ~/yolo5/yolov5-pytorch mo --input_model model.onnx --output_dir ./ --model_name workpiece ls -lh workpiece.xml workpiece.bin cp workpiece.xml ~/work/2026.7ROS2/1/2026.9.3/2026./nav_ws_x86/src/core/oak_arm_detector/model/workpiece_model/ cp workpiece.bin ~/work/2026.7ROS2/1/2026.9.3/2026./nav_ws_x86/src/core/oak_arm_detector/model/workpiece_model/ echo "target_workpiece" > ~/work/2026.7ROS2/1/2026.9.3/2026./nav_ws_x86/src/core/oak_arm_detector/labels_work.txt cd ~/work/2026.7ROS2/1/2026.9.3/2026./nav_ws_x86 colcon build --packages-select oak_arm_detector source install/setup.bash ros2 launch oak_arm_detector oak_detector.launch.py
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/21 10:11:12

SpringBoot蔬菜种植管理系统设计与实现:从表结构到远程调试

做了几年毕设相关的技术支持和项目复盘,我陆陆续续接触过不少类似的选题,最近又帮人梳理了一套基于SpringBoot的蔬菜种植管理系统。这题看上去是标准的管理系统CRUD,但真把种植批次、环境监测、农事记录串起来之后,复杂度还是比普…

作者头像 李华
网站建设 2026/10/21 12:02:53

设备老化测试PASS但OS读寄存器全零:路径差异与一致性缺口排查

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/21 12:02:49

游戏引擎架构实战:游戏对象与资源管理核心设计

1. 游戏对象与资源管理到底在解决什么问题聊游戏引擎架构,绕不开两个最核心的东西:游戏对象和资源管理。很多人刚接触引擎的时候,觉得游戏对象不就是场景里那些能看见的模型、灯光、摄像机吗?资源管理不就是加载图片和模型吗&…

作者头像 李华
网站建设 2026/10/21 12:02:48

GSM BSS信令排障:L1-L2-L3分层定位实战指南

简介:本资源是一份聚焦GSM移动通信核心机制的专题讲义,面向通信工程专业学生、网络优化工程师及移动通信初学者,系统解决BSS子系统信令流程理解难、协议分层抽象、实际切换场景难以串联等学习痛点。文档为上海大唐移动通信设备有限公司2000年…

作者头像 李华