3、仿真环境搭建:Python + NumPy + Matplotlib 仿真环境配置,虚拟锚点与标签的生成

好,咱们直接进入正题。仿真环境搭建这件事,说白了就是给你的定位算法搭一个「试验场」。你想想看,真机测试成本高、周期长,而且出了问题你都不知道是算法错了还是硬件抽风了。所以我个人的习惯是——先在仿真里把算法跑通,再上真机。

这一章,我就带你手把手搭一个轻量级的仿真环境。不需要 ROS,不需要昂贵的硬件,一台笔记本就够了。

3.1 环境配置:Python + NumPy + Matplotlib

我建议你用 Python 3.8 以上版本。为什么?因为 NumPy 和 Matplotlib 对高版本 Python 支持更好,而且语法糖用起来也顺手。

安装命令很简单,一行搞定:

pip install numpy matplotlib

嗯,这里要注意:如果你用的是 Anaconda,那这两个库大概率已经装好了。可以用 pip list | grep numpy 检查一下。

我的小习惯: 每次新建项目,我都会创建一个虚拟环境。避免不同项目之间的包版本打架。命令是 python -m venv uwb_env,然后激活它。

3.2 虚拟锚点的生成

锚点是什么?说白了就是位置已知的固定基站。在 UWB 定位里,我们通常需要至少 3 个锚点才能做二维定位,4 个锚点做三维定位。

我在项目中遇到过一种情况:锚点布设得太集中,导致定位精度很差。后来我总结了一个经验——锚点最好分布在空间的四个角落,形成一个「包围圈」。

来看代码:

import numpy as np

# 生成4个虚拟锚点,坐标单位:米
anchors = np.array([
    [0.0, 0.0, 0.0],   # 锚点1:原点
    [10.0, 0.0, 0.0],  # 锚点2:X轴方向
    [0.0, 10.0, 0.0],  # 锚点3:Y轴方向
    [10.0, 10.0, 0.0]  # 锚点4:对角
])

print("锚点坐标:\n", anchors)

这段代码生成了 4 个锚点,分布在 10m × 10m 的方形区域四个角。你想想看,如果标签在这个区域内移动,每个锚点都能收到信号,定位效果自然就好。

避坑指南: 我曾经把锚点放在一条直线上,结果算法直接崩了。因为三点共线时,三角定位的方程组是奇异的,解不出来。所以锚点一定要构成一个「面」或「体」。

3.3 虚拟标签的生成

标签就是我们要定位的目标。在仿真里,我们可以让标签沿着一条轨迹运动,模拟真实场景。

我个人喜欢用两种轨迹:直线运动和圆形运动。直线运动用来测试算法的收敛速度,圆形运动用来测试跟踪的稳定性。

# 生成标签轨迹:匀速直线运动
time_steps = 100
tag_trajectory = np.zeros((time_steps, 3))

for t in range(time_steps):
    tag_trajectory[t] = [0.1 * t, 0.05 * t, 0.0]  # 沿X、Y方向匀速移动

print("标签轨迹形状:", tag_trajectory.shape)

这段代码生成了 100 个时间步的轨迹。每个时间步,标签的位置都往前挪一点。你想想看,这就像一个人在房间里慢慢走动。

3.4 可视化:看一眼你的仿真环境

光有数据不够,得能看见才行。Matplotlib 就是干这个的。

import matplotlib.pyplot as plt

# 绘制锚点和标签轨迹
fig = plt.figure(figsize=(8, 6))
ax = fig.add_subplot(111, projection='3d')

# 锚点用红色星号标记
ax.scatter(anchors[:, 0], anchors[:, 1], anchors[:, 2], 
           c='red', marker='*', s=200, label='锚点')

# 标签轨迹用蓝色线条
ax.plot(tag_trajectory[:, 0], tag_trajectory[:, 1], tag_trajectory[:, 2], 
        'b-', label='标签轨迹')

ax.set_xlabel('X (m)')
ax.set_ylabel('Y (m)')
ax.set_zlabel('Z (m)')
ax.set_title('UWB 定位仿真环境')
ax.legend()
plt.show()

运行这段代码,你会看到一个三维空间。红色的星号是锚点,蓝色的线是标签的运动轨迹。嗯,看到这个图,我心里就有底了。

核心要点: 仿真环境搭建的关键是「可控」。你可以随意调整锚点位置、标签轨迹、噪声大小,然后观察算法的表现。这在真机上是做不到的。

3.5 知识体系:一张图看懂

下面这张 SVG 图,是我梳理的本章知识结构。你看一眼就能明白整个流程:

仿真环境搭建知识体系 环境配置 Python + NumPy + Matplotlib 虚拟锚点生成 4个锚点,包围式布局 虚拟标签生成 直线/圆形轨迹 输出:3D 可视化仿真环境 关键参数与注意事项 • 锚点数量:至少3个(2D)/ 4个(3D) • 锚点布局:避免共线,形成包围圈 • 标签轨迹:直线测收敛,圆形测跟踪 • 仿真步数:100步起步,200步更稳

3.6 完整代码示例

最后,我把上面的代码整合成一个完整的脚本。你直接复制就能跑:

import numpy as np
import matplotlib.pyplot as plt

# 1. 生成锚点
anchors = np.array([
    [0.0, 0.0, 0.0],
    [10.0, 0.0, 0.0],
    [0.0, 10.0, 0.0],
    [10.0, 10.0, 0.0]
])

# 2. 生成标签轨迹
time_steps = 100
tag_trajectory = np.zeros((time_steps, 3))
for t in range(time_steps):
    tag_trajectory[t] = [0.1 * t, 0.05 * t, 0.0]

# 3. 可视化
fig = plt.figure(figsize=(8, 6))
ax = fig.add_subplot(111, projection='3d')
ax.scatter(anchors[:, 0], anchors[:, 1], anchors[:, 2], 
           c='red', marker='*', s=200, label='锚点')
ax.plot(tag_trajectory[:, 0], tag_trajectory[:, 1], tag_trajectory[:, 2], 
        'b-', label='标签轨迹')
ax.set_xlabel('X (m)')
ax.set_ylabel('Y (m)')
ax.set_zlabel('Z (m)')
ax.set_title('UWB 定位仿真环境')
ax.legend()
plt.show()

跑完这段代码,你的仿真环境就搭好了。接下来就可以往里面加噪声、加定位算法了。嗯,这一步很关键,基础打牢了,后面才稳。

总结一下: 这一章我们做了三件事——配环境、生成锚点、生成标签轨迹。这三件事是后续所有定位算法仿真的地基。地基稳了,楼才能盖得高。

可可精品资料库