简介:面向SLAM算法入门与嵌入式定位开发者的树莓派WiFi-SLAM实战项目,以无线信号强度(RSSI)为观测信息,结合同时定位与地图构建技术,在未知室内环境中同步完成设备定位与地图构建,适合机器人导航、室内定位、智能设备自主移动等场景学习与实践。资源压缩包约5.59MB,共16个文件,包含11个Python脚本、2个txt说明、1个md说明,以及jpg与png图片,文件总量不大但功能模块划分清晰。Python源码覆盖信号采集、数据预处理、指纹匹配/粒子滤波定位、数据关联与地图构建等环节,例如核心SLAM主程序、航位推算与数据关联模块等,并提供示例无线/惯性数据、硬件接线图、运行效果图与说明文档,方便对照验证与二次开发。整体目录按testing、analysis、data_collection、images等模块组织,兼具工程性与教学性,可作为课程设计参考,也能用于实际项目原型验证。已有121人学习下载,适合想通过实操理解WiFi-SLAM原理并基于树莓派快速起步的开发者。
1. 树莓派上的 WiFi-SLAM:不做视觉不做激光,用信号强度也能建图
很多人一听到 SLAM,第一反应就是激光雷达、ORB-SLAM、视觉里程计这些重计算量的方案。但在室内定位这个特定场景里,还有一个容易被忽略的路线:不依赖摄像头、不依赖激光,只靠树莓派自带或外接的 WiFi 模块,通过采集周围 AP 的 RSSI 信号强度来做位置估计和地图构建,这就是 WiFi-SLAM。它的核心思路是:WiFi 信号在室内环境的传播路径损耗是相对稳定的,同一位置扫描到的多个 AP 的 RSSI 组合,可以构成一个类似视觉特征点的信号指纹,而这个指纹与空间位置的对应关系,就是可用来定位和建图的“观测模型”。
这个方案特别适合三类人。第一类是在做室内定位系统但不想投入 UWB 或蓝牙基站成本的人,WiFi 基础设施是现成的。第二类是有树莓派 4B 或树莓派 5、想玩 SLAM 但手头没有激光雷达的爱好者,用树莓派自带的 WiFi 模块就能跑通整个闭环。第三类是准备 SLAM 面试或做课程项目的学生,WiFi-SLAM 能把 SLAM 的状态估计框架、信号处理、参数辨识这几个核心知识点全部串起来。
这篇文章会从信号模型讲到树莓派上的数据采集,再手写一个基于扩展卡尔曼滤波和信号指纹的 WiFi-SLAM 核心实现,最后给出在实机上跑通的参数调整方法和验证路径。整个过程不需要额外硬件,树莓派自带的 WiFi 芯片就够了。
2. WiFi 信号模型与 RSSI 建图的理论基础
2.1 路径损耗模型:为什么 RSSI 能当距离传感器用
WiFi 信号在自由空间传播时,接收信号强度与距离之间存在确定的数学关系。最常见的室内模型是对数距离路径损耗模型,公式如下:
RSSI(d) = RSSI_0 - 10 * n * log10(d / d_0) + X_g其中RSSI_0是参考距离d_0(通常取 1 米)处的信号强度,n是路径损耗指数,室内环境一般取 2 到 4,X_g是均值为零的高斯噪声,代表多径效应和人体遮挡带来的随机波动。
这个模型是 WiFi-SLAM 的基石。把它反过来用,已知某个 AP 的RSSI_0和n,就能从一次扫描的 RSSI 值估算出当前节点到该 AP 的距离;同时有多个 AP 的距离估计,就能用三边测量或最小二乘解出位置。这里的核心问题变成:RSSI_0和n怎么来?
两个办法。一个是离线标定,在已知距离的位置采样多组 RSSI,用线性回归拟合出参数。另一个是把这两个参数放进 SLAM 的状态向量里,在建图过程中同时估计,这就是“SLAM 式”的做法——不单独做标定,让滤波器自己学出来。
# 路径损耗模型的最小二乘参数估计 import numpy as np # 采样数据: distance[m], rssi[dBm] samples = np.array([ [1.0, -42], [2.0, -48], [3.0, -52], [5.0, -58], [8.0, -64], [10.0, -67] ]) d = samples[:, 0] rssi = samples[:, 1] x = -10 * np.log10(d) A = np.vstack([x, np.ones_like(x)]).T n, b = np.linalg.lstsq(A, rssi, rcond=None)[0] rssi_0 = b # 1米处参考强度 print(f"路径损耗指数 n = {n:.2f}, RSSI_0 = {rssi_0:.1f} dBm")代码逻辑很直接:把路径损耗公式改写为RSSI = -10n * log10(d) + RSSI_0的线性形式,x就是-10*log10(d),斜率就是n,截距就是RSSI_0。用最小二乘一次拟合出来。这个参数辨识是 WiFi-SLAM 里最容易被忽略但影响最大的环节,n差 0.5,最终定位误差可能差出 2 到 3 米。
2.2 信号指纹地图:把 RSSI 矩阵变成可检索的空间描述
纯距离模型的缺点是抗干扰能力差,人体遮挡、门开关都会让单次 RSSI 测量出现大幅波动。更稳的做法是构建信号指纹地图(Radio Map):把目标区域划分成网格,在每一个网格点上扫描周围所有可见 AP,记录每个 AP 的 MAC 地址和 RSSI 均值,形成一个指纹向量。
指纹地图建好后,在线定位阶段只需要把当前扫描到的 RSSI 向量与地图中的指纹做相似度匹配,就能得到位置估计。这个思路天然适合与粒子滤波结合,每个粒子携带一个假设位置,用当前 RSSI 与地图指纹的匹配度作为粒子权重。
# 树莓派上采集一次WiFi扫描的原始数据 sudo iw dev wlan0 scan | grep -E "BSS|signal" | head -40上面的命令调用无线网卡的扫描功能,输出里能看到每个 AP 的 BSSID(等价于 MAC)和 signal 字段,单位是 dBm。iw比iwlist更适合脚本解析,输出格式稳定,且能直接拿到信号强度。注意这里的wlan0需要根据树莓派实际的无线接口名替换,可以先用ip a确认。
2.3 WiFi-SLAM 与视觉/激光 SLAM 的本质差异
传统的视觉 SLAM 和激光 SLAM 观测模型都很“硬”:激光测距的误差在厘米级,视觉特征匹配的几何约束也很明确。而 WiFi 的 RSSI 观测噪声大、非平稳性强,单次观测的置信度低。这决定了 WiFi-SLAM 在算法设计上必须做两件事:一是把多个 AP 的观测合并成向量,用冗余性压制单点噪声;二是在滤波框架里把过程噪声调大,不让状态估计被单次异常观测带偏。
状态向量 (5维): [x, y, theta, n, RSSI_0] x, y: 机器人位置 theta: 朝向(用于运动模型) n, RSSI_0: 当前AP路径损耗模型参数把 AP 的模型参数放进状态向量,意味着在建图过程中每看到一个 AP,都要同时估计它的位置和信号传播参数。这比“先标定后定位”的二阶段方法更符合 SLAM 的精神——地图和位姿联合估计。
3. 树莓派上的 WiFi 数据采集与环境适配
3.1 扫描命令选择与 RSSI 原始数据捕获
在树莓派上做 WiFi-SLAM,第一步是稳定的数据采集。树莓派 4B 和 5 的板载 WiFi 芯片支持iw扫描命令,但有个细节要注意:iw dev wlan0 scan需要 root 权限,且扫描过程中当前 WiFi 连接会短暂中断。如果树莓派是通过 SSH 连接,扫描会让连接卡顿几秒,这是正常现象。
为了解决这个体验问题,我一般会把扫描封装成一个独立的 Python 脚本,用subprocess调iw,解析结果后存入 SQLite 或 CSV,同时给扫描加上节流控制。一个关键参数是扫描频率,WiFi-SLAM 中数据采集频率不应超过 1Hz,因为 RSSI 本身在短时间内波动很大,高频采集没有增益,反而会给滤波带来相关性噪声。
# rssi_scanner.py - 树莓派WiFi扫描与数据落盘 import subprocess import re import time import csv import sys def scan_once(iface="wlan0"): """执行一次WiFi扫描,返回 (bssid, ssid, rssi) 列表""" try: out = subprocess.check_output( ["sudo", "iw", "dev", iface, "scan"], stderr=subprocess.DEVNULL, timeout=8 ).decode("utf-8", errors="ignore") except subprocess.TimeoutExpired: return [] aps = [] current = {} for line in out.splitlines(): line = line.strip() if line.startswith("BSS"): if current and "signal" in current: aps.append(current) current = {"bssid": line.split()[1].lower()} elif line.startswith("SSID:"): current["ssid"] = line.split(":", 1)[1].strip() elif line.startswith("signal:"): # 格式: signal: -52.00 dBm current["signal"] = float(line.split()[1]) if current and "signal" in current: aps.append(current) return aps if __name__ == "__main__": iface = sys.argv[1] if len(sys.argv) > 1 else "wlan0" filename = sys.argv[2] if len(sys.argv) > 2 else "rssi_log.csv" with open(filename, "a", newline="") as f: writer = csv.writer(f) writer.writerow(["timestamp", "bssid", "ssid", "rssi"]) while True: aps = scan_once(iface) ts = int(time.time()) for ap in aps: writer.writerow([ts, ap["bssid"], ap["ssid"], ap["signal"]]) f.flush() print(f"[{ts}] captured {len(aps)} APs") time.sleep(1.0)这个脚本有几个工程细节值得解释。timeout=8是为了防止iw在某些信道扫描时卡死;errors="ignore"避免个别 AP 的 SSID 含非 UTF-8 字符导致解码失败;每次扫描间隔 1 秒是为了让 RSSI 的噪声充分独立。bssid转小写是为了后续做指纹匹配时避免大小写不一致的坑。
3.2 多信道扫描的时延与覆盖权衡
WiFi 2.4GHz 频段有 13 个信道(中国标准),一次完整扫描要逐个信道监听 Probe Response,耗时通常在 3 到 6 秒之间。如果 AP 分布在多个信道上,扫描周期直接决定了 SLAM 的观测更新率。
树莓派板载 WiFi 模块是单天线单射频,无法同时监听多个信道。替代方案有三个:用多个 USB WiFi 网卡分别锁在不同信道,缺点是占用 USB 口且供电压力大;把路由器设置里固定 AP 到少数挨着的信道(如 1、6、11),扫描时只需跳 3 个信道,速度快一倍;或者调低iw的扫描 dwell time 参数。我在项目中一般推荐第二种,成本为零,效果立竿见影。
3.3 树莓派 GPIO 与运动模型的粗对齐
WiFi-SLAM 里除了 WiFi 观测,还需要运动信息来驱动状态预测。没有轮式编码器时,树莓派可以用以下方式获取粗略位移:把树莓派放在遥控小车上,用 GPIO 接两个红外测速码盘,单位时间脉冲数换算成线速度;或者直接假设机器人做匀速直线运动,用时间间隔乘以设定速度作为位移增量。后者精度差,但当 WiFi 观测更新频率低(0.2~0.5Hz)时,运动误差会被滤波器的过程噪声吸收。
运动模型 (匀速假设): x_k = x_{k-1} + v * dt * cos(theta) y_k = y_{k-1} + v * dt * sin(theta) theta_k = theta_{k-1} + omega * dt这里的v和omega是从码盘或遥控指令里读取的,dt是两帧之间的时间差。跟激光 SLAM 的里程计相比,这种运动模型非常粗糙,所以后面卡尔曼滤波里过程噪声协方差Q要设得大一些。
4. 基于扩展卡尔曼滤波的 WiFi-SLAM 核心实现
4.1 状态向量与观测模型的整体设计
我们把 WiFi-SLAM 的问题建模成 EKF(扩展卡尔曼滤波)下的联合估计。状态向量包含三部分:机器人位姿(x, y, theta)、当前 AP 的路径损耗参数(n, RSSI_0)、以及 AP 自身的坐标(ap_x, ap_y)。观测是当前扫描到的所有 AP 的 RSSI 值。
为了让问题可解,需要把 AP 坐标也放进状态。但这会带来一个维度爆炸的问题:如果环境里有 20 个 AP,状态维度就是 3 + 2 + 20*4 = 85 维。EKF 处理 85 维状态没有压力,但雅可比矩阵计算会变得繁琐。一个工程上的折中是只对信号最强的 5 个 AP 做在线估计,其余 AP 用离线指纹匹配做定位辅助。
# 状态向量结构示意 # [x, y, theta, n0, rssi0_0, ap0_x, ap0_y, n1, rssi0_1, ap1_x, ap1_y, ...] def build_state_vector(pose, ap_params_list): """将位姿和AP参数拼接为状态向量""" state = list(pose) # x, y, theta for p in ap_params_list: state.extend([p["n"], p["rssi_0"], p["x"], p["y"]]) return np.array(state)4.2 EKF 预测与更新:手写核心滤波循环
这里给出一个完整可运行的 EKF 核心代码,重点放在预测和更新两个环节的矩阵运算,以及雅可比矩阵的解析推导。
# wifi_slam_ekf.py import numpy as np class WiFiSlamEKF: def __init__(self, dt=1.0, v=0.3, omega=0.0): self.dt = dt self.v = v self.omega = omega # 状态: [x, y, theta, n0, rssi0_0, ap0_x, ap0_y, n1, rssi0_1, ap1_x, ap1_y] dim = 3 + 4 * 2 # 2个AP示例 self.x = np.zeros(dim) self.x[2] = 0.0 # 初始朝向 # 协方差矩阵,初始给大值表示不确定性高 self.P = np.eye(dim) * 0.1 self.P[0,0] = 0.5; self.P[1,1] = 0.5; self.P[2,2] = 0.3 # 过程噪声 self.Q = np.eye(dim) * 0.01 self.Q[0,0] = 0.2; self.Q[1,1] = 0.2; self.Q[2,2] = 0.1 # 观测噪声 (RSSI标准差约为5dBm) self.R = np.eye(2) * 25.0 def predict(self): """匀速运动模型的状态预测""" x, y, theta = self.x[0], self.x[1], self.x[2] dt = self.dt # 新位姿 new_x = x + self.v * dt * np.cos(theta) new_y = y + self.v * dt * np.sin(theta) new_theta = theta + self.omega * dt # 状态转移雅可比矩阵 F F = np.eye(len(self.x)) F[0, 2] = -self.v * dt * np.sin(theta) F[1, 2] = self.v * dt * np.cos(theta) # AP参数和坐标不变,因此对应行保持单位阵 self.x[0], self.x[1], self.x[2] = new_x, new_y, new_theta self.P = F @ self.P @ F.T + self.Q def update(self, measurements): """ measurements: [(bssid_idx, rssi), ...] 每个测量对应一个AP,AP索引与状态向量中的位置映射 """ # 构建观测残差和雅可比 z = np.array([m[1] for m in measurements]) h = np.array([self._h(m[0], self.x) for m in measurements]) y = z - h H = np.vstack([self._H(m[0], self.x) for m in measurements]) S = H @ self.P @ H.T + self.R[:len(z), :len(z)] K = self.P @ H.T @ np.linalg.inv(S) self.x = self.x + K @ y self.P = (np.eye(len(self.x)) - K @ H) @ self.P def _h(self, ap_idx, state): """观测模型:由AP参数和状态位姿计算预测RSSI""" x, y = state[0], state[1] # 每个AP占用4维:[n, rssi_0, ap_x, ap_y] base = 3 + ap_idx * 4 n = state[base] rssi_0 = state[base + 1] ap_x, ap_y = state[base + 2], state[base + 3] d = np.sqrt((x - ap_x)**2 + (y - ap_y)**2) if d < 0.5: d = 0.5 # 防止距离为零导致log溢出 return rssi_0 - 10 * n * np.log10(d) def _H(self, ap_idx, state): """观测模型对状态向量的雅可比""" H = np.zeros(len(self.x)) x, y = state[0], state[1] base = 3 + ap_idx * 4 n = state[base] ap_x, ap_y = state[base + 2], state[base + 3] d = np.sqrt((x - ap_x)**2 + (y - ap_y)**2) d = max(d, 0.5) # 对x, y求导 H[0] = -10 * n / np.log(10) * (x - ap_x) / d**2 H[1] = -10 * n / np.log(10) * (y - ap_y) / d**2 # 对n求导 H[base] = -10 * np.log10(d) # 对ap_x, ap_y求导(与x,y对称) H[base + 2] = 10 * n / np.log(10) * (x - ap_x) / d**2 H[base + 3] = 10 * n / np.log(10) * (y - ap_y) / d**2 return H这段代码的_H函数是 EKF 能收敛的关键。雅可比矩阵每一个元素都来自路径损耗模型解析求导:RSSI对x的导数等于-10n/(ln10) * (x-ap_x)/d^2,这里特别注意log10求导要乘1/ln10这个因子,很多人第一次写会漏,导致滤波器发散。另外d加了下限保护,避免树莓派定位位置恰好与 AP 坐标重合时出现除零。
观测噪声矩阵self.R = np.eye(2) * 25里的 25 表示 RSSI 标准差约 5dBm,这是室内 WiFi 环境比较典型的值。如果你在开阔空间测试,可以调小到4左右;如果在走廊转角密集的地方,建议调到36以上,否则滤波器会过度信任单次观测。
4.3 初始化与收敛:AP 坐标的种子化策略
EKF 的状态估计高度依赖初始值。机器人初始位姿(0,0,0)没问题,但 AP 坐标如果初始化为(0,0),雅可比矩阵里d接近零会产生奇异性。我一般用的策略是:在运行 EKF 之前,先用 3 次扫描的 RSSI 平均值和路径损耗公式,粗算出 AP 的初始距离,再结合机器人当前朝向给一个扇形区域内的随机方位角,生成 AP 种子坐标。
def init_ap_seed(rssi_samples, n_init=2.5, rssi_0_init=-40): """ 利用多组RSSI样本粗估AP距离,取最小值为半径 返回一个合理的AP初始坐标 """ rssi_med = np.median(rssi_samples) d_est = 10 ** ((rssi_0_init - rssi_med) / (10 * n_init)) d_est = np.clip(d_est, 1.0, 20.0) # 给一个随机方向,后续EKF会修正 bearing = np.random.uniform(-np.pi, np.pi) ap_x = 3.0 * d_est * np.cos(bearing) # 3.0是初始位姿x的估计 ap_y = 3.0 * d_est * np.sin(bearing) return d_est, ap_x, ap_y这里取rssi_med而不是均值,因为 RSSI 噪声有重尾特性,中位数更稳健。np.clip把距离限制在 1 到 20 米,防止log出现极端值。初始种子不要求准,EKF 在后续更新中会逐步修正 AP 坐标,但种子太差会让滤波器陷入局部极值,这个取舍要清楚。
5. 实机部署:树莓派 4B 上的参数调节与精度验证
5.1 树莓派性能占用量化与 I/O 优化
树莓派 4B 跑上面的 EKF 代码完全没有压力。实测在纯 Python(无 NumPy 加速)下,85 维状态向量的单次预测+更新耗时约 12~15ms,加上 RSSI 扫描的 3 秒间隔,CPU 占用率长期在 5% 以下。真正的瓶颈不在算力,而在iw扫描时的无线模块占用——扫描期间树莓派自身的 WiFi 连接会中断。
建议把数据采集脚本设成nice -n 10运行,避免影响 SSH 连接的响应。另外,CSV 落盘时用f.flush()之后不需要频繁fsync,否则 SD 卡的写入寿命会受影响。我这里每 10 次扫描才做一次显式的os.fsync,性能与可靠性兼顾。
实测参考值(树莓派4B, 8GB版): 单次 iw scan: 2.8s~4.2s 解析30个AP: 0.03s EKF单步更新: 0.012s 全程CPU占用: <5% 内存占用: 约45MB5.2 观测噪声 R 与过程噪声 Q 的调参准则
WiFi-SLAM 调参和视觉 SLAM 的调参思路不同,视觉 SLAM 的R可以从特征点重投影误差估计,WiFi 的R则需要实地采集统计。一个可行的做法是:固定位置静止采集 100 次 RSSI,计算标准差,乘以 2 就是R的合理初值。
过程噪声Q的设置与运动模型的不确定性挂钩。如果用码盘测速,Q可以小一些;如果是把树莓派拿在手里走,运动完全未知,Q的对角元素建议设到0.5以上,否则位置协方差收缩过快,后续观测无法纠正偏差。
5.3 精度验证方法与误差分解
验证 WiFi-SLAM 的精度不能只看最终轨迹图,还要拆开看误差来源。我的做法是在室内用卷尺每隔 1 米做一个标记点,推着小车按矩形路线走,每到标记点记录 EKF 估计位置,然后计算 RMSE(均方根误差)。
# 验证脚本片段 import numpy as np ground_truth = np.array([ [0.0, 0.0], [1.0, 0.0], [2.0, 0.0], [3.0, 0.0], [3.0, 1.0], [3.0, 2.0], [2.0, 2.0], [1.0, 2.0], [0.0, 2.0] ]) estimated = np.array([ [0.1, 0.2], [1.2, 0.1], [1.8, 0.4], [3.1, 0.3], [3.4, 1.1], [2.8, 2.3], [2.2, 1.9], [0.9, 2.4], [0.3, 1.8] ]) rmse = np.sqrt(np.mean(np.sum((estimated - ground_truth) ** 2, axis=1))) print(f"RMSE = {rmse:.2f} m")从我的经验看,室内 8m x 8m 环境、5 个 AP、RSSI 标准差约 5dBm 的条件下,WiFi-SLAM 的定位 RMSE 一般在 1.5~3.5 米。这个精度肯定赶不上激光 SLAM 的厘米级,但在仓储机器人分区判断、室内导航的粗定位场景里是够用的。误差的主要来源是 WiFi 信号的多径效应和 AP 坐标的收敛偏差,而不是滤波算法本身。
5.4 长时间运行时的 AP 漂移与地图更新
树莓派跑 WiFi-SLAM 超过 30 分钟后,EKF 估计的 AP 坐标会逐渐偏移——因为环境温湿度变化会改变 WiFi 信号的传播特性。如果发现定位误差逐渐增大,需要做两件事:检查 AP 的n估计值是否偏离了 2~4 的物理合理区间;对信号最强的 AP 增加一次“重观测”,把当前扫描值作为强约束注入滤波器。
6. 进阶:将 WiFi-SLAM 输出接入 ROS 2 导航栈
跑通纯 Python 的 WiFi-SLAM 之后,下一步自然是想让它跟 ROS 2 生态对接,驱动真实的机器人导航。这里有一个务实的接入方案:把 WiFi-SLAM 写成一个 ROS 2 节点,发布nav_msgs/Odometry消息,替代或辅助轮式里程计。
# wifi_slam_ros_node.py - ROS 2 节点骨架 import rclpy from rclpy.node import Node from nav_msgs.msg import Odometry from std_msgs.msg import String class WiFiSlamNode(Node): def __init__(self): super().__init__("wifi_slam_node") self.pub = self.create_publisher(Odometry, "wifi_odom", 10) self.sub = self.create_subscription(String, "rssi_topic", self.rssi_cb, 10) self.ekf = WiFiSlamEKF(dt=1.0, v=0.3) def rssi_cb(self, msg): # msg.data 是JSON格式的RSSI测量 measurements = parse_rssi_json(msg.data) self.ekf.predict() if measurements: self.ekf.update(measurements) odom = Odometry() odom.pose.pose.position.x = self.ekf.x[0] odom.pose.pose.position.y = self.ekf.x[1] odom.pose.pose.orientation.z = np.sin(self.ekf.x[2] / 2) odom.pose.pose.orientation.w = np.cos(self.ekf.x[2] / 2) self.pub.publish(odom)上面代码的核心设计是:把 RSSI 解耦成一个独立的rssi_topic,WiFi-SLAM 节点只订阅数据、发布里程计。这样做的工程意义在于,RSSI 采集可以由单独的 Python 进程用iw完成,与机器人控制回路隔离开,避免扫描命令阻塞导航主循环。发布的消息直接用nav_msgs/Odometry,可以无缝接入 Nav2 的robot_localization做传感器融合——把轮式里程计和 WiFi-SLAM 的输出用扩展卡尔曼滤波组合,定位稳定性会提升不少。
接入成功后的一个验证技巧:在rviz2里同时显示/odom(轮式里程计)和/wifi_odom两条轨迹,如果 WiFi 轨迹的走向与真实运动一致、只是整体偏转或平移,说明 EKF 的位姿更新正常,只是 AP 坐标初值有问题,重跑一次 AP 种子化即可。如果轨迹出现 S 形扭曲,则是观测模型里n的估计发散,优先检查路径损耗指数是否落回 2~4 区间。
小区分一下定位和建图的完整体验:真正跑一圈之后会意识到,WiFi-SLAM 的输出质量上限由信号环境决定,算法只能逼近这个上限。在 AP 稀疏的走廊,5~8 米误差是常态;在 AP 密度高的办公区,1 米左右的定位结果是有机会做到的。树莓派在这个流程里扮演的角色是轻量级计算平台,它的价值是让传感器(WiFi 芯片)和算法(EKF)之间的延迟足够低,从而实现近实时的位姿输出。
本文还有配套的精品资源,点击获取