尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Besiege中造三进制机械计算机:从三态编码到全加器实现

Besiege中造三进制机械计算机:从三态编码到全加器实现 在 Besiege 里做机械三进制计算机最容易产生“先试试”冲动的模块往往是全加器因为它逻辑清晰、规模可控又直接决定后续所有算术单元能否工作。真正动手之后会发现三进制全加器不是简单换一张真值表它要求整个信号系统从头设计每一位信号如何表示加法如何用机械结构完成进位如何从连续旋转中提取出来这三个问题在二进制场景里几乎不用考虑。这里记录的是我在 Besiege 中搭建机械三进制全加器的部分开发过程。内容按“三态编码 - 真值表 - 机械结构 - 测试台 - 排错 - 扩展”的顺序展开。如果你也在 Besiege 里做机械逻辑或者想了解三进制计算机如何从一个算术单元开始落成实体这份笔记可以作为一套可对照的实现方案。1. 先想清楚三进制机械计算机为什么从全加器开始1.1 三进制在机械表达上的优势二进制信号在机械世界里是最容易表达的一个开关有开和关两个状态一个轴有正转和停转两个状态。但二进制需要更多位数才能表达同样范围机械零件数量会随位数增长而快速膨胀。三进制每一位可以表达 0、1、2 三个状态。从信息密度看三进制单位状态携带的信息量比二进制更高。更重要的是三进制允许出现“无信号、正向信号、反向信号”三种语义这和齿轮的正转、停转、反转天然对应。机械结构不擅长区分“符号位”但很擅长直接反转运动方向所以三态在物理层面反而比二进制更自然。1.2 全加器是算术后端的地基无论二进制还是三进制加法都是最基本的运算。乘法可以拆成多次加法减法可以按补码或对称码转成加法计数器、累加器、状态机也都依赖加法器。在整台三进制计算机里全加器承担的是“一位加法 进位”的核心职责。如果全加器不能在物理上稳定工作后续每个模块都会继承同样的误差。先把这个单元跑通等于验证了三态编码、齿轮传动、角度取模、进位提取四条关键链路之后的模块只是把这些链路组合起来。1.3 Besiege 做机械逻辑的适用性和边界Besiege 适合做这件事因为所有零件都受物理模拟约束齿轮、铰链、活塞、结构件可以自由组合不需要写驱动代码就能观察真实的机械行为。玩家可以通过暂停、逐帧观察、手动旋转输入轴等方式完成调试。限制也很明显。物理模拟会引入齿轮间隙、结构抖动、零件弹性齿轮比稍大一点角度误差就会被放大。零件数量增加后帧率会下降卡死和抖动也更频繁。因此游戏内机械计算机的每一级结构都要尽量短、尽量轻尽量少用超长传动链。这类限制和真实机械计算机设计中的误差控制、公差分析很相似。2. 用角度定义三态信号2.1 三态角度编码0 度、120 度、240 度我采用角度作为三态信号的物理载体。普通三进制数值 0、1、2 分别映射到 0°、120°、240° 三个旋转角度三进制数值普通三进制角度平衡三进制角度语义00°0°零1120°120°正一2240°-120°负一或二选择 120° 间隔而不是 90° 或 180°原因在于圆周 360° 被三等分后三个状态之间距离最大物理读数不容易发生歧义。如果使用 0°、90°、180°状态间隔只有 90°齿轮间隙稍大就会让输出落在两态之间。不要用 90° 作为三态间隔。120° 间隔会在取模和进位环节留下更大的容错空间。在平衡三进制中240° 可以理解为 -120°本质上是同一个角度。机械齿轮天然支持反转所以负角度不需要额外符号位。2.2 输入轴的构造和稳定方法每个输入信号由一个旋转铰链实现。铰链转轴上固定一个细长结构件作为指针指针指向刻度盘上的 0°、120° 或 240°就表示当前输入为 0、1 或 2。为了让输入角度稳定我在指针位置附近设置了限位块。手动调整输入时先暂停游戏旋转指针到目标刻度附近然后恢复物理模拟让结构在限位块的约束下稳定下来。测试阶段建议让输入轴保持较短的力臂减少旋转零件的转动惯量避免指针因为惯性来回摆动。部件清单可以参考下面的文本配置输入轴模块 1. 旋转铰链 x1 2. 细长木块 x1作为指针 3. 带刻度底座 x1固定在铰链下方 4. 限位木块 x2 或 x3卡住指针的稳定位置2.3 信号传递的接口约定模块与模块之间的信号通过同轴齿轮或皮带传递。上游模块输出角度下游模块读取同一角度因此传动比必须保持 1:1否则角度会被缩放三态位置会整体偏离。接口约定如下上游输出轴角度等于当前三进制值对应的角度。下游读取轴必须与上游保持同一转向。齿轮咬合方向影响正负号搭完第一个齿轮组后要先做一次 0° 到 120° 的验证。每一级传动链尽量只经过一个齿轮对减少反冲间隙。这段约定是整台机械计算机的通信协议。没有统一接口后续每一层模块都要单独校零排查成本会成倍增加。3. 全加器的运算关系与真值表3.1 从二进制全加器到三进制全加器二进制全加器计算的是S (A B Cin) mod 2 C (A B Cin) div 2三进制全加器把模数和除数从 2 改成 3S (A B Cin) mod 3 C (A B Cin) div 3这里的 A、B、Cin 都在 0、1、2 中取值。要注意三进制进位的范围不是只有 0 和 1而是可能取 0、1、2。例如2 2 2 6 6 mod 3 0S 0 6 div 3 2C 2进位为 2在二进制全加器里不存在。这正是三进制全加器比二进制复杂的核心原因。3.2 普通三进制全加器的真值表完整真值表有 27 行。为了避免手工表格过长我用 Python 脚本生成完整结果搭建完机械结构后可以直接拿这份输出做对照。def ternary_full_adder(a, b, cin): total a b cin return total % 3, total // 3 def angle(value): return [0, 120, 240][value] print(A B C S C_out) print(- * 24) for a in range(3): for b in range(3): for cin in range(3): s, c ternary_full_adder(a, b, cin) print(f{angle(a):3d} {angle(b):3d} {angle(cin):3d} f{angle(s):3d} {angle(c):3d})运行这段脚本需要本机安装 Python 3保存为adder_truth_table.py后执行python3 adder_truth_table.py它会输出 27 行角度对照表例如0 0 0 0 0 120 120 0 240 0 120 120 120 0 120 240 240 0 120 120 240 240 240 0 240中间若干行代表其它输入组合。机械测试时需要逐行对照不能只挑几个看着顺眼的组合验证。下面是小样本检查表适合搭建过程中快速筛查ABCinSC_out0000011020120012201111101221210221122202验证小表时注意S 和 C_out 都是角度编码不是十进制数值。比如2 2 1等于 5三进制表示为12因此 S 等于“1”对应的 120°C_out 等于“1”对应的 120°。3.3 从普通三进制推广到平衡三进制普通三进制数值范围是 0 到 2平衡三进制数值范围是 -1、0、1。平衡三进制的好处是负数不需要额外符号位正反转天然由角度符号表达。平衡三进制的全加器同样满足total A B Cin S total 除以 3 的平衡余数范围 -1、0、1 C_out total 除以 3 的平衡商范围 -1、0、1可以用 Python 验证平衡三进制的计算规则def balanced_ternary_adder(a, b, cin): total a b cin q (total 1) // 3 r total - 3 * q return r, q for a in (-1, 0, 1): for b in (-1, 0, 1): for cin in (-1, 0, 1): s, c balanced_ternary_adder(a, b, cin) if a b cin in (-3, -2, 2, 3): print(fA{a:2d} B{b:2d} C{cin:2d} - S{s:2d} C{c:2d})运行结果会显示边界情况例如A-1 B-1 C-1 - S 0 C-1 A-1 B-1 C 0 - S 1 C-1 A 1 B 1 C 0 - S-1 C 1 A 1 B 1 C 1 - S 0 C 1平衡三进制在机械上的实现并不需要额外加结构因为旋转角度 120° 和 -120° 其实就是同一个物理位置。实际开发时可以把普通三进制当作第一版验证对象跑通后再把角度编码整体平移成平衡三进制。4. 机械全加器的第一版结构4.1 总体思路三个输入角度先求和机械全加器不需要做任何“判断”它只需要做三件事把输入轴角度加起来取 360° 余数输出本位再提取走过的整圈数输出进位。在机械世界角度叠加的基本结构是齿轮差速结构。简单理解两个输入齿轮带动同一个输出机构输出角度等于两个输入角度按一定比例合成后的结果。调整齿轮比可以让输出接近输入之和也可以让输出等于输入之差。第一版结构采用两级差速第一级A B - T1 第二级T1 Cin - T_totalT_total 的最大值是三个输入的整数和。当 A、B、Cin 都取 240° 时240° 240° 240° 720°也就是说总角度输出轴最多转两整圈。这个范围对应三进制最大加法结果 6。实际搭建时游戏里没有现成的“差速器”零件需要使用齿轮和转轴组合模拟。第一版验证时不要求输出严格等于 A B Cin只要输出随输入单调、且同一组输入每次读数一致就可以通过刻度盘标定出真实映射。4.2 Sum 输出利用 360 度循环实现取模总角度 T_total 是一个连续旋转角但任何机械轴旋转到 360° 时都会回到 0°。因此直接在 T_total 轴上接一个指针指针读数天然就是 T_total mod 360°。这个取模过程不需要额外零件。S 输出角度就是S (A B Cin) mod 360°例如A240°, B240°, Cin0° T_total480° 指针读数120°120° 对应三进制数值 1而2 2 0的三进制结果是11本位是 1符合预期。取模是免费的因为旋转轴本身就是一个循环计数器。但这也意味着进位信息丢失了必须通过另一条路径提取。4.3 进位提取减法加 3 比 1 减速进位 C_out 可以通过 T_total 与 S 的差值得到。因为T_total - S 360° × 进位圈数进位为 0 时差值为 0°进位为 1 时差值为 360°进位为 2 时差值为 720°。为了让进位也变成三态角度需要把差值除以 3。360° 除以 3 等于 120°720° 除以 3 等于 240°正好对应三态进位角度。机械上实现这一分段的过程是用第二级差速结构输出 T_total 和 S 的差值。将差值轴经过一组 3:1 减速齿轮。减速后的输出接到进位指针。结构关系可以写成T_total - S - 3:1 减速齿轮 - C_out 指针第一版落地时T_total 和 S 来自两条不同传动链齿轮间隙会在减法阶段被放大。实测中进位角度出现 3° 到 5° 的偏移属于正常范围偏差超过 15° 时就要检查传动链长度和齿轮咬合松紧。4.4 关键参数速查下表是搭建过程中最重要的参数参数建议值说明输入角度0°、120°、240°三态信号编码输入范围3 个输入轴A、B、CinT_total 最大角度720°三个输入都为 240° 时Sum 输出范围0° 到 360°物理轴自动取模进位提取齿轮比3:1将差值角度转成三态进位测试用例数27 组三输入全排列允许误差5° 以内超过需要检查传动链第一版不用追求零误差。先把“逻辑对”跑出来再通过缩短传动链、增加限位、加固齿轮座来降低误差。5. 搭建测试台并验证真值表5.1 测试台的结构检查全加器之前我先搭了一个独立测试台。测试台负责提供稳定的输入源并把输出固定到便于读数的位置。测试台包含1. 三个输入轴手动旋转带刻度盘 2. 一个 Sum 输出轴带指针 3. 一个 C_out 输出轴带指针 4. 固定底座连接所有模块输入轴使用旋转铰链输出轴使用同轴齿轮引出。所有轴承座都用结构件加固避免高负载下整个底座翻转。测试台的摆放原则是输入区和输出区分离。输入在左侧输出在右侧中间是齿轮传动模块。这样
返回列表