模型加载基础:文件格式与数据预处理

做运动控制仿真,第一步就是加载模型数据。这一步看似简单,但坑不少。我见过不少新手,模型加载不对,后面全白干。

今天咱们聊聊三种最常见的文件格式:MAT、HDF5、JSON。以及怎么用 Python 把它们读进来,再做好预处理。

三种文件格式,各有各的脾气

先看个对比表,心里有个底:

格式 后缀 特点 适用场景
MAT .mat MATLAB 原生格式,支持矩阵、结构体、元胞数组 与 MATLAB 团队协作、遗留项目
HDF5 .h5 / .hdf5 分层数据格式,支持大数据集、并行 I/O 大型仿真数据、深度学习模型权重
JSON .json 纯文本,可读性强,结构灵活 配置文件、轻量级数据交换

我个人习惯:小规模模型用 JSON,中等规模用 MAT,大规模仿真数据用 HDF5。你想想看,一个几百兆的 .mat 文件,用 JSON 存?那打开速度能急死人。

MAT 文件加载:scipy.io.loadmat 实战

MAT 文件在运动控制领域太常见了。很多老工程师用 MATLAB 建好模型,导出 .mat 文件给我们做二次开发。

加载代码很简单:

import scipy.io as sio

# 加载 MAT 文件
data = sio.loadmat('robot_model.mat')

# 查看所有变量名
print(data.keys())

# 提取模型参数
mass_matrix = data['M']      # 质量矩阵
coriolis = data['C']         # 科里奥利矩阵
gravity = data['G']          # 重力向量
joint_limits = data['qlim']  # 关节限位

嗯,这里要注意。loadmat 返回的是一个字典,键是变量名,值是 numpy 数组。但有个坑——MATLAB 的索引从 1 开始,Python 从 0 开始。我刚开始做项目时没注意这个,算出来的关节力矩全偏了,排查了整整一下午。

避坑指南:MATLAB 导出的矩阵默认是 Fortran 顺序(列优先),而 numpy 默认是 C 顺序(行优先)。加载后建议用 np.ascontiguousarray() 转换一下,否则后续矩阵运算可能出问题。

数据预处理:别让脏数据毁了你的仿真

模型加载进来,不等于就能直接用。我遇到过太多次了——模型参数里有 NaN、有单位不一致、有维度对不上。

预处理我一般分三步走:

  1. 检查完整性:有没有缺失值?有没有 NaN?
  2. 检查一致性:单位对不对?维度匹配吗?
  3. 检查合理性:质量矩阵正定吗?关节限位合理吗?

代码示例:

import numpy as np

def preprocess_model(data):
    # 1. 检查 NaN
    for key, val in data.items():
        if isinstance(val, np.ndarray):
            if np.any(np.isnan(val)):
                print(f'警告:{key} 包含 NaN 值')
                # 用 0 填充或插值
                val = np.nan_to_num(val, nan=0.0)
    
    # 2. 检查维度
    M = data['M']  # 期望 6x6
    if M.shape != (6, 6):
        raise ValueError(f'质量矩阵维度错误:{M.shape},期望 (6, 6)')
    
    # 3. 检查正定性
    eigenvalues = np.linalg.eigvals(M)
    if np.any(eigenvalues <= 0):
        print('警告:质量矩阵非正定,可能包含奇异位形')
    
    return data
我的小技巧:预处理函数最好写成独立的模块,每次加载模型都跑一遍。我曾经因为偷懒没做检查,结果仿真跑到一半矩阵奇异,程序直接崩了。从那以后,预处理成了我的铁律。

HDF5 与 JSON 的加载要点

HDF5 加载用 h5py 库:

import h5py

with h5py.File('simulation_data.h5', 'r') as f:
    # 查看顶层组
    print(list(f.keys()))
    
    # 读取数据集
    joint_trajectory = f['trajectory/joint_positions'][:]
    timestamps = f['trajectory/time'][:]

JSON 加载更直接:

import json

with open('config.json', 'r') as f:
    config = json.load(f)

# 提取参数
dh_params = config['dh_parameters']
gear_ratios = config['gear_ratios']

说白了,JSON 适合存配置参数,HDF5 适合存大规模时序数据。MAT 文件则介于两者之间。

知识体系总览

下面这张图,把本章的核心逻辑串起来了:

模型加载与预处理流程 原始模型文件 MAT 格式 HDF5 格式 JSON 格式 scipy.io.loadmat h5py.File json.load 数据预处理 完整性检查 一致性检查 合理性检查

从原始文件出发,先判断格式,选对加载方法,再走预处理三步检查。每一步都不能省。

核心要点:模型加载不是简单的文件读取,而是数据质量的第一道防线。预处理做得好,后面仿真调试能省一半时间。