基于Rokid AR眼镜的IMU动作识别喝水提醒助手开发实践

📅 发布时间:2026/10/6 14:26:32
基于Rokid AR眼镜的IMU动作识别喝水提醒助手开发实践
春节那几天我一边跟家里人嗑瓜子聊天一边刷手机看消息猛然发现一个问题一天下来水杯在桌上几乎没怎么动过。过年期间作息打乱、饮食偏咸偏油身体其实比平时更需要水分但注意力根本不在喝水这回事上。后来我想了个主意——既然手上戴着Rokid AR眼镜干脆自己做了一个AR喝水提醒助手让提醒直接出现在眼前而不是靠手机震动。这篇文章就把这个项目的完整思路、设计取舍、实现过程和踩坑记录都摊开来讲。这个项目说白了就是在Rokid AR眼镜上运行一个轻量级应用利用眼镜的IMU惯性测量单元数据判断用户的抬手、放杯动作配合设定好的时间间隔在镜片视野中投射出喝水提示。你不用掏出手机不用看手表只要视野里浮现一行字和一个小动画你就知道该喝水了。项目适合三类人一是手头有AR眼镜、想拿它做点实用小工具的开发者二是对空间计算和体感交互感兴趣的产品经理三是单纯想在春节期间保持状态、又不想被手机打扰的普通用户。1. 项目背景与核心思路拆解1.1 为什么选择Rokid AR眼镜来做喝水提醒市面上做提醒的工具很多手机闹钟、智能手表、微信小程序哪个不是“拿起就提醒”但它们都有一个通病——提醒的打扰成本太高。手机通知弹出来你至少要解锁屏幕看一眼手表震动你得抬手腕确认一下。春节期间手边全是瓜子壳和果盘手机放在沙发缝隙里手表可能被厚外套盖住这两条路都不够顺。AR眼镜不一样。它的显示层始终在你的视野前方不遮挡大部分视线又能在需要时把文字和图形叠到现实场景里。Rokid系列眼镜是目前国内消费级AR设备里量产成熟度较高的一档光波导显示方案带来的优势很明显镜片通透度好环境光透过率高戴着它跟人说话不至于显得太奇怪而且彩色显示效果比早期单色方案要友好得多。更重要的是它的开发环境对Android开发者非常熟悉——基于 Android 生态扩展接入速度比想象中快。我不需要一个能监测心率血氧的“健康管家”我只需要一个在我忽略喝水这件事情的时候轻轻推我一下的“提示板”。AR眼镜恰好就是这个位置存在感不强但提醒的存在感极强。1.2 项目要解决的核心问题和功能定位这个项目定位很明确轻交互、低打扰、可视化。不是做成一个“健康数据平台”不去测你喝了多少毫升也不记录历史趋势——那些事情手机App做得更好。我需要解决的只有三个问题。第一什么时候提醒。春节期间作息混乱固定间隔比“每天八杯水”更实用。我按用户可调的间隔时间默认45分钟触发提醒保证一天下来至少有个七八次的提示频率。第二怎么提醒才不烦人。直接弹一个大弹窗在视野中央一秒内能看清提醒内容然后立即淡化消失不要长时间占据视觉重心。我选择了“文字—图标—进度环”的组合主文字提示“该喝水啦”旁边一个水杯图标下方一条环形进度指示距离上次提醒过去了多久信息密度刚好。第三怎么感知“你真的在喝水”。这里我不打算搞摄像头识别毕竟喝水这个动作在AR眼镜的视觉范围内不一定能被捕捉。我用了IMU传感器的方案当用户喝水时手腕眼镜会有一个比较明显的“抬手——倾斜——放下”的复合动作。通过处理三轴加速度计和陀螺仪的数据可以识别出这个动作识别到后就把提醒状态重置开始下一轮计时。1.3 功能范围与版本规划这个项目的第一版只做了四个功能模块定时提醒、抬手识别、提醒界面渲染、设置页面。没有云端同步没有历史统计没有多设备联动。拿第一版上手的理由很简单和所有AR应用一样最不可控的就是头戴设备的交互体验必须先把“显示—感知—反馈”这条链路跑通再去谈更多功能。如果一开始就加了一堆统计报表、账户系统反而会拖慢验证核心体验的节奏。过程中我严格做了边界控制不接网络请求所有逻辑本地完成减少因网络波动导致的提醒失败不引入第三方语音助手直接用系统TTS播报短促提示音不做后台保活策略用户主动开启应用后保持前台运行避免后台被杀2. 显示方案选型与空间交互逻辑2.1 光波导显示的技术背景与Rokid的适配AR眼镜的显示方案基本分两类一类是Birdbath鸟盆式一类是光波导Optical Waveguide。Rokid的消费级产品线上光波导是被用得比较激进的。光波导方案的核心原理是把微型显示屏通常是一个Micro OLED的光信号通过衍射光栅耦合进入一片透明基板在基板内部经过多次全反射传播最终在另一个光栅区域耦合出去投射到人眼。听起来很玄但你可以把它想象成“光在玻璃里面走迷宫”——光从侧面进去在玻璃里拐好几个弯再从正面出口出来。因为整个传播过程都在透明基板内完成所以镜片不需要做成很厚的光学模组眼镜外形接近普通墨镜而且环境光的透过率很高。这就是为什么戴着光波导AR眼镜看东西不会感觉眼前蒙了一层雾。但光波导也有代价。它对光线的耦合效率有损耗实际入眼亮度通常只有显示屏原始亮度的10%20%左右。在室内场景还能接受如果窗外阳光直射偶尔会出现画面变淡的情况。我在项目开发时特意把界面背景色做成深色半透明底把文字和图标的对比度调高就是为了对抗室内光线变化带来的可读性问题。在代码层面的适配关键是Display坐标和渲染层级的处理。Rokid眼镜的显示驱动在底层把眼镜屏映射成一个虚拟的显示平面应用可以把它当成一块额外的屏幕来画UI。但这个屏幕不是传统的矩形平面它有空间偏移和光学畸变。我用标准的Android渲染接口绘图时发现最稳妥的方式是直接使用系统为AR设备提供的扩展Display不自己做畸变校正——在Rokid的开发框架里眼部追踪和屏幕映射都处理好了。开发者需要做的只是把UI布局控制在中间安全区域。2.2 视觉安全区间的设计与注视交互AR眼镜UI和手机UI最大的区别是视野范围有限且分散注意力。手机屏幕是你可以一直盯着的眼镜则不行——你会来回看前方的人和物。如果提醒文字出现在视野边缘用户要转动眼球去找那种体验非常拉胯。我调研了Rokid的显示虚像距离和视场角参数后结合自己实戴的感觉把主要提醒区域限定在视野中心偏下的位置大概是横向中心线以下20%到40%的区域。这个位置的好处是不会挡住你看人的脸但又在余光可及的范围内。为了看清细节人眼会自然向下扫视这个动作比转动头部要自然得多。交互上我没有做手势识别而是利用Rokid眼镜自带的头部追踪IMU数据把“注视”作为一种触发机制。比如提醒弹出后如果检测到用户头部在3秒内保持基本静止转动角度小于阈值就认为用户已经看到了提醒然后自动淡出。如果在3秒内头部持续大幅度摆动说明用户正在忙别的事提醒就多停留几秒但最长不超过8秒避免产生“甩不掉的弹窗”的烦躁感。2.3 为什么没有选择Google Play Services for AR方案写代码的时候有朋友提醒我既然AR的热度这么高为啥不直接上Google的ARCoreGoogle Play Services for AR这个方案我确实认真考虑过但最后还是否了。原因很现实ARCore的核心能力是运动追踪、平面检测、光照估计它需要调用摄像头对环境进行持续SLAM运算。这对手机场景没问题但眼镜形态的AR设备有特殊性——Rokid这类眼镜的核心显示不在手机上而是独立的眼镜显示单元它的系统做了大量针对光波导显示的处理。如果你引入ARCore你的应用会依赖摄像头数据流功耗大发热快而且在室内走动频繁的场景下SLAM的初始化反而容易失败。反观我的需求一个喝水提醒根本不需要识别平面不需要放置虚拟物体。只要传感器显示就够了。所以选择技术栈时需求边界必须清晰。ARCore的技术名声再响不符合当前场景就是制造复杂度。2.4 显示驱动的对接经验整个项目对接显示部分时我最深的体会是Rokid眼镜的系统里眼镜屏幕驱动是通过一个系统服务来管理的。应用侧有两种使用方式。方式一创建一块独立的Presentation把它显示到眼镜的Display上。这种方式适合跑AOSP原生应用的场景优点是代码改动小直接复用Android的开发经验。我前期原型就是用Presentation跑通的。方式二使用Rokid提供的AR渲染框架在眼镜侧的SurfaceTexture上直接绘制OpenGL内容。画面更新频率更高能做更复杂的动画但对OpenGL基础有要求。我后期为了做喝水提醒的水波纹动画才切换到方式二。切换之后提醒界面的水波动画才真正流畅起来。原来用普通View绘制时帧率一高就掉帧因为View层级要走系统的Choreographer对AR这种高刷新显示来说不是最优路径。而OpenGL直绘可以把纹理更新放到渲染线程里整个动画的负载很少。3. 提醒策略设计与喝水动作识别3.1 提醒间隔怎么定才合理参数计算逻辑喝水提醒的间隔必须依据人的饮水和代谢规律来设计而不是拍脑袋随便填。我参考了常见的健康建议——成年人单次饮水200250ml每天饮水总量约1.52L——这意味着一天大概需要610次饮水。把清醒时间按16小时计算平均间隔是96160分钟。但问题是春节期间进食油腻、咸味重、聊天多水分流失高于平时理应增加频次。我在项目里把默认间隔设置为45分钟是这么算的按一天的清醒时间16小时45分钟一次一天足以触发约21次提醒。即使有效执行率只有50%即有一半的提醒被忽略或没喝水也能达到10次左右的饮水收益覆盖一天的基础需水量。你可能会觉得45分钟太频繁但在测试中我发现提醒弹出后用户并不会立刻喝往往是“看到提醒继续忙过几分钟才喝”所以实际喝水间隔远大于提醒间隔。把间隔设短一点其实是给真实执行留出余量。同时我开放了间隔设置提供三档30分钟加速模式、45分钟标准、60分钟佛系。所有档位都是可动态调整的不需要重启应用。3.2 基于IMU的抬手喝水动作识别识别“喝水”这个动作是项目里最有意思也最折磨人的部分。先明确物理基础用户戴着AR眼镜如果用户端起水杯喝水头部会自然仰起同时手臂带动身体有一个短暂的轻微后仰。这个动作反映在眼镜的IMU数据里就是绕X轴横滚轴的角度变化和Z轴航向轴的角速度变化同时出现一个明显波峰。我设计了如下识别流程采集原始数据从系统传感器管理器获取TYPE_ACCELEROMETER和TYPE_GYROSCOPE数据采样频率设为50Hz每20ms一次足以捕捉23秒内的完整动作。滑动窗口处理取最近120个采样点约2.4秒作为一个窗口实时计算该窗口内的角速度峰值和加速度方差。姿态估算用互补滤波把加速度计和陀螺仪数据融合估算出俯仰角Pitch变化。喝水时俯仰角会出现约15°30°的负向变化头部后仰。判定条件我做了三个逻辑判断窗口内俯仰角变化超过12°横滚角速度最大值超过140°/s整个动作持续时间在0.8秒到2.5秒之间这三个条件全部满足才认为是一次有效的喝水动作。从实际测试来看这套识别逻辑的召回率该识别的识别出来了还不错但有明显的误触低头看手机、捡东西、转头看身后都有可能触发。为了降误报我在代码里加了一个“冷却判断”——上次识别成功后的10秒内不再进行动作识别判定。另一个改进是加入头部的线性加速度阈值如果线性加速度过大超过了正常喝水时的加速度范围则判定为低头或弯腰取消喝水动作。3.3 提醒与动作识别的协同策略这里有一个关键的逻辑链条提醒触发→用户执行喝水→动作识别确认→重置定时器。但用户不一定每次都在提醒后才喝水也可能自己想起来主动喝。如果用户主动喝了水但系统不知道还按老时间提醒那提醒就变得煞风景了。所以我把动作识别模块设计成两个模式并行跑模式一被动监测。任何时候都在后台跑动作识别如果识别到喝水动作就把计时器重置不立即弹出提醒。模式二主动提醒。计时器到点后触发提醒视觉反馈同时接下来3分钟内加强动作识别灵敏度把俯仰角阈值从12°降低到8°确保用户马上喝完水后系统能感知到不会出现“刚喝完又提醒”的尴尬。3.4 提醒界面细节文字、图形与动画的配合提醒界面的视觉设计既要抓眼球又不能扰人。我做了三个层次第一层是主提醒卡片中央一个水滴图标旁边“该喝水啦”四个字字体大小设置为虚像距离下视角约4°的尺寸。在Rokid眼镜的显示距离下这个尺寸大约是手机屏幕上24sp的感觉属于一眼能看清但不占满视野的大小。第二层是进度环在卡片下方绘制一个环形进度条显示距下次提醒的剩余时间比例。这个进度环的设计很讨巧——它既是一个状态指示也是一种软性倒计时压力让人觉得“差的越来越少了”潜意识里提升执行意愿。第三层是水波纹扩散效果提醒弹出时水滴图标的外圈会有一个不断向外扩散的圆环动画持续1.5秒之后自动停止。这个动画是纯OpenGL绘制的循环触发不消耗额外资源。4. 核心开发流程与代码要点4.1 开发环境搭建与项目结构先把环境摆清楚。我用的硬件是Rokid AR眼镜USB-C连接至一台Android开发主机系统版本Android 13。开发机是一台MacBook ProIDE用Android Studio FlamingoSDK版本34minSdkVersion设为30。项目结构上没有复杂的东西四个包com.cny.drink ├── activity // 主Activity和设置页Activity ├── render // OpenGL渲染线程和界面绘制 ├── sensor // IMU数据采集与动作识别算法 └── timer // 提醒调度与状态管理核心的类文件其实不超过10个整体代码量大约2000行。早期原型为了验证可行性我甚至用了更简单的方式——直接在Activity的onCreate里注册传感器监听然后用标准View绘制提醒UI。这样跑通后再逐步替换成OpenGL方案。4.2 传感器数据采集的细节采样率与线程传感器采集的坑第一个就是采样率。IMU的原始数据如果直接丢给算法线程会因为Android系统的调度抖动导致窗口内的数据分布不均匀。我的处理方式是在传感器回调里只做数据缓存用一个环形缓冲区RingBuffer存储原始采样值在另一个独立线程里以固定的50Hz逻辑时钟从缓冲区中读取数据做窗口计算。这样即使系统回调频率有点抖动算法侧的数据节奏也是稳定的。第二个坑是传感器坐标系的差异。Rokid眼镜的IMU坐标系跟手机不完全一样需要先做一次坐标映射否则计算出的俯仰角方向是反的。我把这个映射常量提取成了一个工具类方便调试时微调。4.3 OpenGL渲染层的核心实现OpenGL渲染部分重点说两个关键环节纹理加载和透明背景。纹理加载我用的最简单的方案把提醒界面的素材做成一整张PNG透明图在初始化时用GLUtils.texImage2D加载为2D纹理然后在绘制时用两个三角形拼成的矩形来贴图。这样不需要复杂的矢量绘制逻辑一张图搞定所有静态元素。文字部分我则用Bitmap生成纹理——先通过Canvas把文字画到Bitmap上再上传为纹理。这样虽然多一次CPU到GPU的拷贝但对于这种低频更新的场景完全够用。透明背景这块有个容易踩坑的细节在AR眼镜上你的渲染Surface最终要和透明镜片叠加所以清除颜色必须设置为RGBA全零0,0,0,0。如果你用默认的黑色清屏渲染结果会显示成一块黑色背景大煞风景。代码如下// 初始化时启用混合 glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // 每一帧清除时颜色全部置0 glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT);4.4 提醒调度的实现避免重复触发的锁机制调度器用的是Handler Looper的轻量方案不引入额外框架。核心逻辑是一个线程安全的单例TimerManager内部维护当前状态空闲、提醒中、识别加强中和下一提醒时间戳。在状态流转上我最开始写了几个状态标记后来演进成有限状态机因为状态多了以后if-else维护太蠢了public class ReminderStateMachine { enum State { IDLE, // 等待中 REMINDING, // 正在显示提醒 COOLDOWN, // 提醒后的冷却期 HYDRATION_WINDOW // 喝水动作识别加强期 } // 状态切换必须经过一个唯一的transition()方法 // 避免回调线程竞争导致状态错乱 }这个状态机帮我解决了一个很实际的问题如果提醒弹出后用户正好在喝水动作识别也同时触发两个模块同时尝试更新计时器会导致计时器被重置两次。状态机通过“提醒状态中不允许动作识别重置计时器”的规则从源头规避了这个冲突。4.5 核心算法的参数调优记录这部分我直接放出测试结果方便你对照参考。下表是我在不同动作识别阈值参数下做的实测统计样本量是30次喝水动作加30次干扰动作低头、转头| 阈值组合 | 俯仰角阈值(°) | 角速度阈值(°/s) | 误报次数 | 漏报次数 | 识别耗时(ms) | |---|---|---|---|---| | 组合A | 8° | 100°/s | 6 | 1 | 620 | | 组合B | 12° | 140°/s | 1 | 3 | 780 | | 组合C | 12° | 100°/s | 3 | 2 | 700 | | 组合D | 16° | 160°/s | 0 | 7 | 840 |组合B是误报和漏报的平衡点30次里漏了3次误报仅1次。组合A漏报少但误报让人崩溃——低头看瓜子袋直接给我判定成喝水频繁重置计时器。这提醒了我一个原则与其追求不漏过每一次喝水不如优先保证误报低因为误报会破坏提醒节奏降低用户对系统的信任。5. 开发中常见问题与排查经验5.1 设备启动报错错误代码40这个标题里提到的“错误代码40”确实是我在真机调试时撞上的第一个拦路虎。现象是连接Rokid眼镜后启动应用直接崩溃Logcat里出现一段错误信息指向一个枚举值40翻译过来大概意思是“显示设备未就绪”。排查过程非常刺激。我先以为是权限没给检查了AndroidManifest确认了相关权限。然后怀疑是眼镜没正确握手重新插拔了几次无效。最后我把应用的启动流程改成延迟初始化——不在onCreate时立刻请求显示设备而是把眼镜显示初始化放到首帧渲染之前做一个异步等待Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 等待AR显示设备就绪 mReady new CountDownLatch(1); ArDisplayManager.getInstance().registerCallback(new Callback() { Override public void onDisplayReady() { mReady.countDown(); } }); new Thread(() - { mReady.await(3, TimeUnit.SECONDS); runOnUiThread(() - initRenderAndStart()); }).start(); }这种做法本质上是把“启动即崩溃”改成了“准备好了再启动”实测下稳定多了。如果你也遇到类似问题我建议把设备就绪回调当成首个依赖而不是盲目依赖系统服务的默认状态。5.2 GPU渲染掉帧与功耗问题提醒动画在晴天窗边环境一跑掉帧就明显了。排查后发现问题出在纹理尺寸我加载的整张UI贴图是1080P分辨率每帧都对整张纹理做混合和采样对移动GPU的压力超标。解决方法是把所有纹理预缩放至720P并且在绘制时用Viewport裁剪到实际需要的区域只绘制提醒卡片所在的矩形范围四周的透明区域直接跳过。这样一帧的填充率下降了一个数量级动画恢复到60fps。功耗这块我严格控制了渲染频率提醒状态动画期间保持60fps提醒淡出后立即降到15fps的“省电模式”空闲时直接停帧。这个策略在1小时测试中眼镜侧温度比全速渲染低了约4.5℃对长时间佩戴的舒适感影响明显。5.3 传感器数据漂移和温度干扰IMU长时间运行后陀螺仪会出现零偏漂移最直接的表现是俯仰角慢慢偏移导致喝水动作识别的基线不准。这个问题在刚开机时几乎不存在但戴了20分钟之后就开始出现了。我的应对策略有两个第一个是零偏校准。在应用启动后的前10秒假设用户头部保持静止采集陀螺仪数据的均值作为零偏在后续计算中减去这个均值。第二个策略是“窗口内动态基准”——不用绝对俯仰角而是用窗口内俯仰角的变化量作为判定特征。变化量不受长期漂移影响鲁棒性好很多。这也是为什么我在最终判定条件里用的是“俯仰角变化超过12°”而不是“俯仰角绝对值大于某个数值”。5.4 佩戴舒适度镜腿发热的取舍Rokid眼镜整机集成度很高运算单元虽然大部分在手机端但眼镜本体仍有部分驱动IC和显示芯片连续运行半小时后镜腿区域会明显发热。我在项目里做了两种妥协一是把提醒动画的持续时长控制在1.5秒避免长时间高负载渲染二是在非提醒间隔内主动停帧让GPU进入低功耗状态。这两个改动让长时间佩戴时镜腿温度控制在一个可接受的范围。如果你戴着眼镜从早用到晚我建议你准备一个支持PD快充的移动电源。眼镜的功耗虽然不大但连续用一整天还是有点吃紧。另外提醒一点镜腿发热时不要用手长时间触摸镜腿金属部分那不只是温度问题还有静电敏感元件的因素在里面。5.5 常见问题速查表问题现象可能原因解决办法启动时报错代码40显示设备未就绪就初始化渲染改用延迟初始化设备就绪回调提醒动画掉帧纹理尺寸过大/未裁剪绘制区域预缩放纹理用Viewport裁剪渲染区域动作识别漏报多俯仰角阈值过高调低到12°适当提高角速度阈值至140°/s动作识别误报多低头动作被当成喝水增加线性加速度条件降低低头动作触发概率长时间运行后识别失真陀螺仪零偏漂移启动时零偏校准窗口内变化量判断提醒刚结束又触发定时器被重复重置引入状态机阻止提醒状态下的动作识别重置界面在户外看不清环境光太强导致对比度不足加深背景底提高图标对比度必要时降低文字亮度6. 春节场景下的实际应用体验与优化方向6.1 春节七天实际使用观察春节在家实际用了整整七天有几个数据比较有参考价值。按默认45分钟间隔跑下来一天大概触发18~22次提醒实际发生喝水动作通过动作识别模块记录大约9~12次执行率在50%60%之间。这个数据符合设定预期——提醒只是创造饮水条件不是强制喝水执行率过半就意味着一天的饮水量已经达到健康标准。最明显的使用场景是下午和晚上。下午一边打牌一边看手机注意力高度集中以前常常三四个小时不喝水戴上眼镜后视野边缘突然浮现的“该喝水啦”确实打断了我的专注状态但方式是软性的——它不震动、不响铃只是静静地在那里。你不理它它就慢慢淡出你抬头扫一眼已经完成了信息传递。晚上陪家人看电视时客厅灯光较暗光波导显示在这种环境下的清晰度很好提醒文字就像浮在电视画面上方一样但又不遮挡画面内容。这一点体验远超手机——手机屏幕亮起的那一瞬间全家人都知道你在看手机而眼镜上的提醒只有你自己知道。6.2 从喝水提醒到健康小助手的扩展想象虽然第一版功能收敛得很克制但我在使用中已经看到了一些很有价值的扩展方向。比如结合Rokid眼镜没有心率传感器这一点但可以接入外部心率带的BLE数据来做“活动量-饮水需求”联动调节。步数多、心率高的时候主动缩短提醒间隔久坐不动打牌时提醒间隔拉长避免过度打扰。另一个方向是语音反馈。Rokid眼镜支持TTS播报在提醒弹出时用低音量说一句“喝口水吧”比纯粹的视觉提示更有温度。不过要小心音量问题——我在测试中发现TTS播报容易吓到旁边的人毕竟大家不知道你的眼镜在跟你说话。所以我加了“亲友在场免语音”的开关通过检测周围声音强度来智能切换。如果你计划复刻这个项目建议你优先做两件事第一把IMU动作识别的阈值表跑一遍找到你自己佩戴习惯下的最佳平衡点第二准备一个稳定的Android开发环境先把基础的OpenGL渲染跑通再去叠加传感器逻辑。AR应用的调试周期比普通App长因为每一轮验证都要戴上设备走进真实场景时间成本不可忽视。这个项目做到最后给我的体会反而不是“技术有多难”而是AR眼镜这个形态天然适合做“轻量生活助手”。它不像手机那样需要你主动拿起也不像智能音箱那样需要你靠近说话。它就在你眼前用最低的姿态完成最实际的服务。春节过完后眼镜收进抽屉但那种“眼前浮现提醒”的体验我至今觉得非常值得做。如果你手头也有Rokid或其他AR眼镜下一个春节前花一个周末把这个小项目搭起来你会比全家人都更早感受到AR在日常生活中的价值。