何时换线,取决于使用量,而不是日期。同样是一个月,每周打一次球的人和每周打四次球的人,在球场上花的时间相差四倍。日历按相同的节奏推进,但球线承受的负荷并非如此。
String GOAT最初也是这样设计的:穿线日期加上按天数计算的周期。我自己也会给球拍穿线,所以一次又一次遇到这个基准失效的情况。练得很凶的一周和几乎没打球的一周,却在同一天收到同样的提醒。
把基准从日期改为使用量,是显而易见的解决方案,但问题恰恰卡在这一步。打球时长这种数据,在训练结束、你估算"今天大概打了两个半小时"的那一刻,就已经从数据变成了记忆。击球数则根本无法靠自己去数。我在做一款记录球线的应用,却没有办法记录球线实际做了多少工作。
手表应用正是为了填补这个空白而存在的。在Apple Watch或Galaxy Watch上开始一次训练,它就会记录击球数和打球时长,这些记录随后用于换线决策。
要做到这一点,首先要跨过一个限制。在网球场上,球员通常把手表戴在没有握拍的那只手腕上,因为戴在持拍手上会妨碍握拍,而且会直接承受冲击。但对于统计击球数来说,这个习惯反而是不利的:球被击中瞬间的冲击,在握拍的手臂上表现得最明显,传到另一只手臂时则弱得多。因此,基于手腕传感器的击球计数,通常都是从"手表戴在持拍手"这个前提出发的。
String GOAT选择不去改变这个习惯。手表还是戴在你原本就习惯戴的地方——非持拍手腕。
这篇文章写给自己给球拍穿线、或者自己管理换线周期的球员。内容涵盖检测原理、实际准确度,以及这些记录如何影响换线决策。
要点速览
- 支持的设备 — watchOS 9.0及以上(Apple Watch Series 4及更新机型)、Wear OS 3.0及以上(包括Galaxy Watch)。需配合已配对手机上的应用使用。
- 佩戴位置 — 非持拍手腕。
- 记录内容 — 击球数、打球时长、心率、消耗卡路里,以及户外GPS路线。
- 准确度 — 空挥拍和走动不会被计数。整体底线击球的检测率约为四分之三,单反会被低估。
- 用途 — 累计打球时长会与各类球线的使用寿命基准进行比较,让提醒基于实际使用量而非日历日期。
从微弱信号中读出击球
震动信号确实会传到另一只手臂,只是很微弱。真正需要的不是更强的信号,而是一个经过训练、能够读懂微弱信号的模型。
String GOAT采用的是KAIST研究团队发布的Silent Impact模型,这个模型专为从未握拍手臂的动作中识别击球冲击而设计。该研究已在UIST 2024(ACM用户界面软件与技术研讨会,作者Park、Yang、Jo)上发表,并以CC BY 4.0协议发布,允许商业使用但需注明出处。String GOAT在应用的开源许可页面中对此进行了署名。论文发表于ACM Digital Library。
分析在手机上进行,而不是在手表上。手表负责采集传感器数据并发送出去,手机再把数据输入模型。由于整个过程都在设备本地完成,球场网络信号不稳定并不会影响检测。
一次训练会记录哪些内容
选择球拍,在手表应用中开始训练,以下内容会持续累积,直到结束训练为止。
| 项目 | 说明 |
|---|---|
| 击球数 | 检测到的击球冲击次数 |
| 打球时长 | 从训练开始到结束的时间 |
| 心率 | 平均值、最大值以及各心率区间的时长 |
| 消耗卡路里 | 来自手表的健康数据 |
| 距离与路线 | 开启GPS的户外训练 |
支持的设备为watchOS 9.0及以上(Apple Watch Series 4及更新机型)以及Wear OS 3.0及以上(包括Galaxy Watch)。手表应用需要配合已配对手机上的String GOAT应用使用,因此手机应用是必需的。
准确度到底如何
击球数一出现在屏幕上,就会让人忍不住问一句"这准吗?"。下面的数据来自我们在自家应用中的实测,而不是论文中报告的性能——手表硬件以及围绕它的处理流程一旦发生变化,同一个模型的表现也会随之不同。
先说站得住脚的部分。空挥拍(没有击中球)不会被计入。在室内测试中,30次空挥拍被记录为0次,行走和静止不动同样记录为0。这个模型检测的是球被击中的那一刻,而不是挥拍动作本身,所以拿着球拍在场上走动或捡球时,数字并不会往上涨。在以正手为主的测试中,统计出的次数与实际击球次数几乎一致。
再说不足的地方。
- 整体底线击球(从底线击打落地反弹后的正手和反手)的检测率约为四分之三。统计出的次数可能低于实际击球数。
- 单反被低估得最明显。这可能是因为模型的训练数据中,单反球员的样本非常少。
- 连续过快的截击可能会被漏记。紧挨着发生的几次击球有时会被合并统计为一次。
- 不区分击球类型。系统不会告诉你哪些是正手、反手,哪些是截击。
所以这不是裁判那种精确到每一次的计数,而更接近一个可以在训练之间互相比较的负荷参考值。用来看看今天是不是比上周练得更狠,或者这条球线到目前为止承受了多少负荷,已经足够;但不该把它当成一个可以照单全收的精确数字。
累计记录如何驱动换线提醒
这里自然会有一个问题:既然计数不精确,它又怎么能用来做判断呢?真正驱动提醒的其实是打球时长,而不是击球数。时长取自训练的开始和结束时间,因此是实测值,而不是估算值。
训练保存后,打球时长会按球拍分别累积。String GOAT会把这个累计时长,与该类型球线的使用寿命基准进行比较。聚酯线、多芯线和天然羊肠线的耐用时长各不相同,因此每种类型都有各自的基准值,这些数值来自对已发表资料的整理和核对。球线可能在断裂之前性能就已经明显下降,这一点Tennis Warehouse University的测试也有相关记录。
改变的不是提醒出现的时间点,而是提醒所依据的东西。判断依据不再是"穿线已经一个月了",而是"这条球线实际被使用了多少小时"。每月打一次球的人和每周打四次球的人,不会再在同一天收到同样的提醒。
击球数同样按球拍累积。把它和打球时长放在一起看,就能区分出哪条球线承受了更多的击球冲击,哪条球线虽然时长相同、但实际击球次数少得多。
结合张力测量,判断会更精准
仅凭打球时长和击球数,判断已经比按日历更准确。但这两者说到底,只描述了球线被使用了多少,并不能说明它此刻处于什么状态。
描述状态另有一套数据:穿线后立即测得的张力,以及之后测量的DT(动态张力,即拍面硬度)。在登记球线时输入初始DT,它就会成为基准值;此后每一次测量,都会新增一个数据点。
手表数据为此增加了第二个维度。你不再只是问张力在多少天里下降了多少,而是可以问张力是在打了多少球的过程中下降了多少。任意两次测量之间的击球数,由手表提供。
随着数据点不断积累,String GOAT会延伸这条变化轨迹,估算张力何时会降到临界值。这个临界值综合了相对基准值的衰减率和主观评分,输出结果是预计换线日期,或者剩余可用击球数。只要存在张力测量数据,系统就会自动采用这种方式——具体使用哪种信号,取决于有哪些数据可用,而不是一个可手动切换的设置项。
