毫米波雷达全屋监测:中国计算机设计大赛国二项目复盘
桌上放着一块墨绿色的PCB板,大概只有硬币大小。这是项目最核心的零件,一块毫米波雷达模块。
在那段为了中国大学生计算机设计大赛准备的日子里,这块板子几乎每天都和我面对面。它没有摄像头,不记录画面,也不会引发任何关于隐私的焦虑。但在它的视界里,房间里的人并不是不可见的。它能捕捉到胸腔微小的起伏,能算出身边人的呼吸频率,甚至能感知到心跳。
我们最初的想法很简单,就是想做一个“润物细无声”的智能家居系统。现在的智能家居大多需要人去妥协,你要么对着空气喊唤醒词,要么在手机屏幕上找开关。我们希望系统是沉默且聪明的。你走进房间,它知道你来了;你在沙发上睡着,心跳和呼吸变得平缓,它察觉了,于是灯光暗下来;你起身去了卧室,客厅的灯就自动熄灭。
对于一个在广州商学院这样一所民办本科读软件工程的学生来说,想要在简历上留下点能让人多看一眼的东西,靠名校光环是不现实的。我能依靠的只有折腾,用一行行代码和一块块焊出来的板子去证明自己。这几年保持着4.02的绩点,拿了两次国奖,其实归根结底,也就是在这些看似枯燥的事情上多花了一些时间。
项目的技术方案定得比较务实,没有用太多花哨的东西。硬件层面上,核心是基于FMCW(调频连续波)技术的毫米波雷达。为了处理雷达吐出来的数据,我们用了一块树莓派4B作为边缘计算节点。温湿度、光照这些常规的环境数据,则交给了STM32加上一堆基础传感器来做补充。
软件这边,是我相对熟悉的领域。前端用 React 配合 Ant Design Pro 糊了一个可视化的监控大盘,深色模式,数据图表实时滚动,看着有点科幻感。后端是标准的 Spring Boot MVC,写了 REST API 处理常规请求,数据的实时推送则交给了 WebSocket。Android 客户端是用 Java 原生写的,没有用跨平台框架,只是为了在旧手机上跑得更流畅些。
架构图画出来很清晰,但真正动手把这些东西串联起来的时候,才发现到处都是坑。
最难的部分,毫无疑问是雷达信号的处理。
毫米波雷达不像温湿度传感器那样,调个接口就能直接返回具体的数值。它返回的是 IF(中频)信号。在串口调试助手里看,那就是一长串毫无规律的数字,像一团乱麻。
要从这团乱麻里找出人的呼吸和心跳,需要经过一系列的数学变换。首先是做 FFT(快速傅里叶变换),把时域信号转换成频域信号,提取出距离和速度的信息。人的呼吸频率大概在 0.1 到 0.5 Hz 之间,心跳大概在 1 到 3 Hz 之间。理论上,只要在频谱上找到这两个频段的峰值,就能得出数据。
但现实环境太嘈杂了。
刚开始测试的时候,数据抖动得非常厉害。我坐在雷达前面一动不动,屏幕上的心跳数值却能在 60 到 120 之间反复横跳。后来发现,机箱风扇的细微震动、头顶空调吹出的风、甚至我在键盘上打字时手臂的轻微晃动,在毫米波的视野里,都被放大成了巨大的干扰信号。生命体征的微波信号完全被这些环境噪声淹没了。
那两周时间,我几乎都在和这些噪声作斗争。查论文,看别人的开源代码,尝试加各种滤波器。先是用巴特沃斯带通滤波器把呼吸和心跳的频段切出来,然后加上滑动平均滤波去平滑数据。
我还记得那个下午,为了测试算法的准确性,我把自己关在宿舍里,拔了风扇,关了空调。我坐在椅子上,屏住呼吸,盯着屏幕上的波形。当波形终于变成一条平滑的直线,而当我重新开始呼吸,屏幕上随即出现规律的正弦波时,那种感觉很奇妙。就像是在一片嘈杂的白噪音里,终于听到了自己真实的心跳声。
初赛是网评,交了文档和演示视频后,顺利进入了复赛。复赛要求去现场答辩,评委不仅要听 PPT,还要看实物演示。
带着一堆裸露着杜邦线的硬件去外地比赛,本身就是一种冒险。答辩前一天晚上,我们在酒店房间里做最后的联调。通上电,树莓派的红灯亮了,但代表读取 SD 卡的绿灯却迟迟没有闪烁。
树莓派挂了。
不知道是因为路上颠簸导致的静电,还是酒店插座的电压不稳,或者是那张用了两年的廉价 SD 卡终于迎来了它的寿命终点。系统进不去,意味着所有的后端服务、边缘计算环境全都没了。
当时已经是晚上十一点。没有时间去抱怨或者沮丧。我下楼找了个网吧,买了个读卡器,重新下载树莓派的系统镜像。烧录系统,重新配置网络,装 Java 环境,装 Python 依赖,把代码从 GitHub 上拉下来重新编译。整个过程机械而安静,同行的队友在旁边帮着重新检查 STM32 的接线。
弄完一切,看懂终端里跑出熟悉的启动日志,已经是凌晨三点。窗外的街道很空,只有几盏路灯亮着。
第二天在会场,我们把设备一件一件从塑料收纳盒里拿出来,摆在铺着红布的长条桌上。插上电源,屏幕亮起来,WebSocket 成功连接,数据开始在图表上平稳地流动。
评委是几个年纪挺大的高校老师。他们对那些花哨的前端界面没有太多停留,而是直接问了几个很现实的问题。比如,如果房间里有两个人,雷达的信号怎么区分。我没有去编造完美的答案,而是如实说明了当前单发单收雷达在多目标分离上的局限性,以及我们目前只能做到单人高精度监测的现状。
他们点了点头,没再多问。
比赛的结果出来,拿了全国二等奖。这比我们最初预期的要好一点。晚上大家去吃了一顿稍微好点的火锅,算是庆祝。
现在回想起来,这个国二的证书或许在找工作时只是一个加分项,但那个在深夜里对着屏幕调滤波算法的自己,那个在网吧里焦急看着进度条的自己,才是这个项目留给我最真实的东西。它让我知道,从一个模糊的想法到一个能在桌面上稳定运行的系统,中间需要填平多少个坑。
项目的核心代码,特别是毫米波雷达信号处理和前后端通信的那部分,我整理后放到了 GitHub 上。地址是 github.com/poboll。
它算不上什么惊世骇俗的开源大作,只是一个普通本科生在探索技术边界时留下的一点脚印。如果你刚好也在做类似方向的折腾,或者在处理 FFT 和滤波时遇到了同样的困惑,希望这些代码能让你少熬几个夜。