news 2026/8/31 7:52:47

MATLAB连杆机构运动学仿真:从曲柄滑块到多杆机构GIF动画

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
MATLAB连杆机构运动学仿真:从曲柄滑块到多杆机构GIF动画

用 MATLAB 做机械连杆机构运动学仿真,最吸引人的部分不是画出一条曲线,而是把四杆、五杆、六杆、曲柄滑块、曲柄连杆这类机构变成屏幕上连续运动的动画,并导出 GIF 动图,直接放进报告、论文或演示文档里。很多刚开始接触这个方向的人会以为,仿真必须用 ADAMS 或 SolidWorks Motion 才能完成,其实针对平面机构运动学,MATLAB 完全可以胜任,而且能更清楚地看到每一步推导和每一条曲线。

这篇文章以曲柄滑块机构为最小案例,从几何约束推导位置方程,到 MATLAB 实现动画,再到导出 GIF,之后再展开四杆、五杆、六杆机构的建模思路。如果你是零基础,不需要先学完所有 MATLAB 功能,只需要会用矩阵、函数、plot 这类基础能力。整篇内容按“先理解原理,再准备环境,然后写代码,最后排查问题”的顺序组织,读完以后可以自己改参数、换机构、生成自己的动图。

1. 先用几何约束理解连杆机构运动学仿真的主线

1.1 机构运动学的核心是位置方程

连杆机构是一个由多个构件通过运动副连接起来的系统。平面机构中最常见的运动副是转动副和移动副。每个运动副都会限制构件的运动自由度。做运动学仿真时,不需要关心力和质量,只需要回答一个问题:在给定主动件位置的情况下,其他构件处于什么位置。

回答这个问题的基础是位置方程。任何平面连杆机构都能写成若干个闭环向量方程。以曲柄滑块机构为例,曲柄一端固定在原点,另一端连着连杆,连杆再连着滑块,滑块只能沿水平导轨滑动。把曲柄记为向量 r,把连杆记为向量 l,那么闭环关系可以写成:

r + l = xB · x轴方向

这里的 xB 是滑块中心在水平导轨上的位置。将向量方程拆成水平和竖直两个分量,就得到两个标量方程。给定曲柄角度后,就能解出滑块位置和连杆摆角。

初学仿真时,最容易犯的错误是直接画机构简图,然后靠肉眼调整形状。这种做法只能看个大概,不能计算位移、速度和加速度,也不能生成连续的 GIF 动图。正确做法是把机构简化为几何变量,建立位置方程,再交给 MATLAB 去解。

1.2 为什么优先写解析式而不是直接画图

直接画图的优点是直观,缺点是难复用。当你只是测试一组参数时,画图能应付;当你要批量修改曲柄长度、连杆长度、角速度,并输出 100 组动画时,就必须让计算和绘图分离。

曲柄滑块机构有一个显式解。设曲柄长度为 r,连杆长度为 l,曲柄角度为 theta,滑块无偏置时,滑块位置可以写成:

xB = r * cos(theta) + sqrt(l^2 - r^2 * sin(theta)^2)

这个公式来自一个简单的几何事实:滑块的 x 坐标等于曲柄投影加上连杆投影。由于连杆长度固定,竖直方向上有:

l * sin(phi) = -r * sin(theta)

所以连杆摆角 phi 也能直接求出来。

四杆机构、五杆机构、六杆机构通常没有这么明确的显式解,需要使用数值方法求解位置方程。理解曲柄滑块机构的显式解,可以帮助你先验证 MATLAB 的绘图和 GIF 生成流程,然后再把同样的流程迁移到更复杂的机构上。

注意:位置方程写错,动画再漂亮也没有意义。每一步求解前,先检查方程是否满足几何约束。

1.3 动画和 GIF 导出的完整链路

在 MATLAB 中生成动图,一般不是“边运动边录屏”,而是先计算完整数据,再按帧绘制图形,最后把每一帧合成一个 GIF 文件。

这个链路可以分为四段:

  1. 定义机构参数,生成时间数组或驱动角度数组。
  2. 对每个时刻求解机构位置,得到所有关键点坐标。
  3. 使用 plot、line、rectangle 等函数绘制机构简图,并更新每一帧的坐标数据。
  4. 用 getframe 抓取当前图像,再用 imwrite 写入 GIF 文件。

GIF 文件和普通视频的差别在于:GIF 是逐帧图片序列,可以通过 DelayTime 控制播放速度,也可以通过 RGB 索引颜色减少文件大小。

2. 环境准备:MATLAB 基础配置和目录规划

2.1 确认版本和工具箱

本文示例不依赖额外硬件,也不需要安装 Simscape Multibody。基础 MATLAB 环境足以完成大部分平面机构运动学仿真。示例代码中使用到 gradient、plot、getframe、imwrite、rgb2ind 等,这些在常规 MATLAB 环境中都能正常运行。

如果在扩展部分使用 fsolve 解四杆机构,需要确认当前 MATLAB 安装是否包含 Optimization Toolbox。不同版本和不同授权状态下,可用工具箱不同。最稳妥的方式是在命令行窗口执行:

ver

该命令会列出当前 MATLAB 已经安装的工具箱。也可以执行:

which fsolve

如果有输出路径,说明 fsolve 可用;如果提示未找到,则说明需要安装 Optimization Toolbox,或者考虑自己实现牛顿迭代。

在学习阶段,建议先把环境定位在“基础 MATLAB + 常用绘图函数”,不要一上来就依赖复杂工具箱。工具越少,越容易理解机构运动学本身。

2.2 项目目录和脚本分层

建议为连杆机构仿真单独建立一个目录,不要把所有脚本堆在工作路径中。一个简单的目录结构如下:

kinematic_sim/ ├── main_crank_slider.m ├── position_crank_slider.m ├── draw_mechanism.m └── export_gif.m

实际学习中,只要建立 main_crank_slider.m 一个脚本即可。目录分层的核心目的是让“计算”“绘图”“导出”三类代码可以分离。

如果是一个更大的连杆机构项目,可以按这个方式规划:

  • 参数文件:保存杆长、角速度、帧数、仿真时长。
  • 位置求解函数:输入驱动角度,输出所有铰点坐标。
  • 绘图函数:接收坐标数据,绘制当前一帧。
  • 主脚本:组合参数、计算、绘图和导出。

2.3 设置统一的绘图环境

为了让动画稳定,避免图形变形或抖动,在绘图前要设置几个关键参数。最常见的是坐标轴比例和坐标范围。如果忽略坐标轴比例,圆形可能会显示成椭圆,机构简图会失真。

推荐在创建坐标轴后执行:

daspect([1 1 1]); xlim([-2 5]); ylim([-3 3]);

daspect 用于设置数据纵横比,相当于 axis equal 的底层控制方式。使用 xlim 和 ylim 固定坐标范围后,每一帧图形的视野不会变化,动图看起来更稳定。

3. 曲柄滑块机构:从位置方程到 GIF 动画的最小实现

3.1 建立几何模型和参数表

以经典曲柄滑块机构为例,设曲柄长度为 r,连杆长度为 l,曲柄角速度为 omega,滑块无偏置。仿真时只计算一个周期,帧数为 N。

参数含义示例值说明
r曲柄长度1单位需要统一,例如米
l连杆长度3必须大于 r,否则机构无法成立
omega曲柄角速度2 rad/s决定仿真周期
N一周期帧数60帧数越多 GIF 越平滑,文件也越大
T一个运动周期2*pi/omega旋转一周对应一个周期

当 l 小于 r 时,公式 sqrt(l^2 - r^2 * sin(theta)^2) 会出现负数,滑块位置会变成 NaN。这是参数设置中最常见的坑。

3.2 位置求解

在 MATLAB 中,先把时间数组写出来:

r = 1; l = 3; omega = 2; N = 60; T = 2 * pi / omega; t = linspace(0, T, N); theta = omega * t;

然后计算曲柄端点 A 和滑块位置 B。A 的坐标是:

xA = r * cos(theta); yA = r * sin(theta);

B 的坐标是:

xB = r * cos(theta) + sqrt(l^2 - r^2 * sin(theta).^2); yB = zeros(size(theta));

注意这里使用了数组运算符号 .^ 和 .*,不要写成型如 sqrt(l^2 - r^2 * sin(theta)^2) 的矩阵写法,否则可能产生维度错误。

连杆摆角可以直接用反三角函数计算:

phi = -asin(r * sin(theta) / l);

这个 phi 表示连杆与水平方向的夹角。取负号是因为默认机构位于导轨上方,连杆端点 A 在上方时,连杆摆角为负。如果机构采用其他装配方向,需要调整符号。

3.3 计算位移、速度和加速度

速度可以用解析法,也可以用数值差分。对于入门阶段,推荐先用 gradient 做数值差分,因为它对数组长度没有限制,直接返回与位置数组等长的结果:

vB = gradient(xB, t); aB = gradient(vB, t);

如果需要更精确的结果,可以对位置公式求导。滑块速度的理论表达式为:

vB = -r * omega * sin(theta) - r^2 * omega * sin(theta) * cos(theta) / sqrt(l^2 - r^2 * sin(theta)^2)

在 MATLAB 中对应:

vB_exact = -r * omega * sin(theta) ... - r^2 * omega .* sin(theta) .* cos(theta) ./ sqrt(l^2 - r^2 .* sin(theta).^2);

数值差分和解析解在多数情况下非常接近,但当帧数很少时,数值差分会产生明显误差。建议在练习时将两种结果画在同一张图里,观察差异。

3.4 绘制机构动画并导出 GIF

下面是一个可以直接运行的最小脚本。它完成位置计算、动画绘制和 GIF 导出三个任务。

% main_crank_slider.m clear; clc; close all; % 参数 r = 1; l = 3; omega = 2; N = 60; T = 2 * pi / omega; t = linspace(0, T, N); theta = omega * t; % 位置计算 xA = r * cos(theta); yA = r * sin(theta); xB = r * cos(theta) + sqrt(l^2 - r^2 * sin(theta).^2); yB = zeros(size(theta)); % 速度与加速度数值差分 vB = gradient(xB, t); aB = gradient(vB, t); % 创建图形窗口 fig = figure('Color', 'white', 'Position', [100 100 800 600]); ax = axes('Parent', fig); hold(ax, 'on'); grid(ax, 'on'); daspect([1 1 1]); xlim([-2 5]); ylim([-3 3]); % 预绘制机构 h_crank = plot([0 xA(1)], [0 yA(1)], 'b-o', 'LineWidth', 2, 'MarkerSize', 6); h_rod = plot([xA(1) xB(1)], [yA(1) yB(1)], 'r-o', 'LineWidth', 2, 'MarkerSize', 6); h_slider = rectangle('Position', [xB(1) - 0.3, -0.2, 0.6, 0.4], ... 'FaceColor', [0.8 0.8 0.8], 'EdgeColor', 'k'); % 背景轨迹 plot(xA, yA, 'k:', 'LineWidth', 1); plot(xB, yB, 'g--', 'LineWidth', 1); % 导出 GIF filename = 'crank_slider.gif'; for i = 1:N set(h_crank, 'XData', [0 xA(i)], 'YData', [0 yA(i)]); set(h_rod, 'XData', [xA(i) xB(i)], 'YData', [yA(i) yB(i)]); set(h_slider, 'Position', [xB(i) - 0.3, -0.2, 0.6, 0.4]); title(ax, sprintf('t = %.2fs, theta = %.1f deg', t(i), rad2deg(theta(i)))); drawnow; frame = getframe(fig); im = frame2im(frame); [A, map] = rgb2ind(im, 256); if i == 1 imwrite(A, map, filename, 'gif', 'LoopCount', Inf, 'DelayTime', 1/30); else imwrite(A, map, filename, 'gif', 'WriteMode', 'append', 'DelayTime', 1/30); end end % 绘制滑块位移、速度、加速度曲线 figure('Color', 'white'); subplot(3, 1, 1); plot(t, xB, 'b-', 'LineWidth', 1.5); ylabel('xB'); grid on; title('滑块位移'); subplot(3, 1, 2); plot(t, vB, 'r-', 'LineWidth', 1.5); ylabel('vB'); grid on; title('滑块速度'); subplot(3, 1, 3); plot(t, aB, 'm-', 'LineWidth', 1.5); xlabel('时间 t/s'); ylabel('aB'); grid on; title('滑块加速度');

代码中有几个关键点:

  • 使用 set 更新线条数据,而不是每次调用 plot 新建线条,这样动画更流畅。
  • 每帧都执行 getframe 抓取图像,再使用 imwrite 写入 GIF。
  • 第一次写入 GIF 时使用 LoopCount 和 DelayTime,后续帧使用 WriteMode 为 append。
  • 如果算法速度慢,可以减少 N,或者将 DelayTime 调大。

3.5 运行验证与结果检查

运行脚本后,应该能在图形窗口中看到曲柄带动连杆运动,滑块在水平导轨上往复移动。同时,当前目录下会生成 crank_slider.gif 文件。

验证结果是否合理可以从几个角度检查。

滑块位移曲线的取值范围应为 [l - r, l + r]。当 r = 1、l = 3 时,xB 应该在 [2, 4] 之间。如果发现 xB 超过这个范围,说明位置公式或参数有误。

滑块速度曲线应该表现出周期性和正负交替。在曲柄角度接近 0 和接近 pi 时,滑块速度的绝对值有较大差异,这反映了连杆对运动的非线性影响。

如果 GIF 文件只有静止画面,说明 getframe 或 imwrite 没有放在循环内。如果动画卡顿,可以检查每一帧是否执行了重绘操作。

4. 推广到四杆、五杆、六杆机构

4.1 四杆机构的位置闭环方程

四杆机构是最常见的平面连杆机构,由机架、曲柄、连杆和摇杆组成。设两个固定铰链分别为 O2 和 O4,O2 到 O4 的距离为 d。曲柄长度 r2,连杆长度 r3,摇杆长度 r4。

将机构写成闭环向量方程:

r2 * exp(i * theta2) + r3 * exp(i * theta3) = d + r4 * exp(i * theta4)

拆成实部和虚部后,得到两个方程:

r2 * cos(theta2) + r3 * cos(theta3) = d + r4 * cos(theta4) r2 * sin(theta2) + r3 * sin(theta3) = r4 * sin(theta4)

给定主动角 theta2,未知量为 theta3 和 theta4。用 fsolve 可以求解:

r2 = 1; r3 = 3; r4 = 2; d = 2.5; theta2 = linspace(0, 2*pi, 100); theta3 = zeros(size(theta2)); theta4 = zeros(size(theta2)); sol = [0.5; 2.0]; for k = 1:numel(theta2) F = @(x) [r2 * cos(theta2(k)) + r3 * cos(x(1)) - d - r4 * cos(x(2)); r2 * sin(theta2(k)) + r3 * sin(x(1)) - r4 * sin(x(2))]; options = optimoptions('fsolve', 'Display', 'off', 'TolFun', 1e-12); sol = fsolve(F, sol, options); theta3(k) = sol(1); theta4(k) = sol(2); end

这段代码中,sol 会随着时间步推进不断更新。使用上一时刻的解作为当前时刻的初始值,是为了保证角度曲线连续,避免数值解在某个位置突然跳到另一个装配模式。

注意:四杆机构必须满足 Grashof 条件才可能让曲柄整周回转。最短杆与最长杆长度之和应小于等于其余两杆长度之和。否则仿真只能在有限角度范围内进行。

4.2 五杆、六杆机构和多环路建模思路

五杆机构通常由两个输入驱动,或者由于增加了一个闭环而具有更复杂的运动学特性。六杆机构则常见于瓦特六杆机构、史蒂芬森六杆机构等。

这些机构的共同点是:系统中有多个闭环,每个闭环都能写出若干约束方程。

以五杆机构为例,可以把它看成两个二杆组串联。一般选择主动件角度作为输入,其余被动关节角度作为未知量。将所有闭环方程写成一个列向量 F,再对 F 调用 fsolve。目标是找到所有被动关节角度,使得每个闭环的向量和为零。

通用框架可以这样组织:

function X = solve_position(q_driver, X0) F = @(X) mechanism_loop(q_driver, X); options = optimoptions('fsolve', 'Display', 'off'); X = fsolve(F, X0, options); end function F = mechanism_loop(q_driver, X) % 根据机构结构整理所有环路方程 F = [ loop1_equation_x(q_driver, X); loop1_equation_y(q_driver, X); loop2_equation_x(q_driver, X); loop2_equation_y(q_driver, X) ]; end

这种方式适合五杆、六杆以及更复杂的平面机构。你不需要为每一种机构单独推导显式位置公式,只需要准确列出闭环方程。

4.3 机构参数配置表

多杆机构仿真前,建议把参数集中放在一个表或结构体中。以下是一个典型的参数配置表:

机构类型需要定义的参数典型变量
曲柄滑块曲柄长度,连杆长度,滑块偏置r, l, offset
四杆机构曲柄、连杆、摇杆、机架长度r2, r3, r4, d
五杆机构机架、主动杆、两个连杆、末端杆r1, r2, r3, r4, r5
六杆机构多个闭环,需列出所有杆长和固定铰位置按机构建模

参数不要硬编码在多个地方。推荐把所有参数定义在主脚本开头,或放到一个 params 结构体中:

params.r = 1; params.l = 3; params.omega = 2; params.N = 60;

这样后续批量修改参数会更方便。

4.4 多杆仿真必须注意的数值问题

多杆机构的数值求解比曲柄滑块复杂得多,常见问题有三种。

第一,初始值问题。fsolve 是数值迭代算法,初始值选择不当会不收敛或收敛到错误解。推荐使用上一时刻的解作为当前时刻初始值,并且在第一个时间步手工选择一个符合装配模式的初始值。

第二,装配模式问题。同一个四杆机构在给定主动角下通常存在两个装配构型,一组在上方,一组在下方。算法最终得到哪一个,取决于初始值。如果发现动画机构在某一帧突然翻转,多半是装配模式发生了切换。解决方案是固定初始值方向,或者在每次迭代后检查关节角度是否发生大幅度跳变。

第三,奇异位形问题。当机构运动到死点附近时,Jacobian 矩阵接近奇异,数值迭代可能失去精度。这时需要增大计算帧数,或者在接近奇异位置时使用更小的角度步长。

5. 常见报错、抖动和排查路径

5.1 动画只有静止图形

现象:脚本运行结束,只显示一个静态机构图,GIF 文件没有生成,或者生成的 GIF 只有一帧。

排查顺序:

  1. 检查 getframe 是否在循环内部。
  2. 检查 imwrite 是否在循环内部。
  3. 检查循环变量 i 是否被更新。
  4. 检查当前目录是否有写入权限。

如果 getframe 放在循环外,它只会抓取最后一帧画面。如果 imwrite 只执行一次且没有使用 WriteMode 为 append,则只生成一帧。推荐将抓帧和写帧放在同一层循环中。

5.2 滑块位置出现 NaN 或空白

现象:动画过程中,滑块突然消失,或者命令行输出 NaN。

原因通常是 sqrt 内出现负数:

l^2 - r^2 * sin(theta)^2 < 0

这可能是因为曲柄长度大于连杆长度,也可能是参数单位不一致。检查方式是输出 sqrt 的最小值:

min(l^2 - r^2 * sin(theta).^2)

如果最小值小于 0,说明机构参数本身不满足装配条件。此时需要缩短曲柄长度、加长连杆长度,或者减小角度范围。

5.3 fsolve 不收敛或结果跳变

现象:运行四杆机构程序时,某个时间步报错,或者 theta3、theta4 出现不连续跳跃。

处理步骤:

  1. 先打印每一步的求解结果,观察跳变发生在哪个角度附近。
  2. 检查初始值是否来自上一时刻的求解结果。
  3. 检查 Grashof 条件是否满足。
  4. 增大帧数,减小相邻时间步的角度变化量。
  5. 调整 fsolve 的容差,例如 TolFun = 1e-10。

如果 fsolve 仍然失败,可以考虑使用最小二乘优化函数 lsqnonlin,它会返回残差最小的解,比 fsolve 更稳健,但速度更慢。

5.4 GIF 文件过大或播放卡顿

现象:生成的 GIF 文件达到几百 MB,播放时明显卡顿。

原因有几种:

  • 帧数太多,如 N=300。
  • 每帧使用 256 色索引图,但图像尺寸很大。
  • DelayTime 设置过小。

建议做法:

  • 将 N 控制在 30 到 60 帧。
  • 使用 rgb2ind 时添加参数 'nodither',减少颜色抖动带来的数据量。
  • 设置 figure 尺寸为常规屏幕大小,无需导出生视频级分辨率。
  • 按需调整 DelayTime,常用 1/24 到 1/30 秒。

5.5 中文乱码和字体问题

MATLAB 在部分系统中,中文注释或坐标轴标题会显示为方块。这不是代码逻辑问题,而是字体支持问题。可以在代码开头设置默认字体:

set(0, 'DefaultAxesFontName', 'SimHei');

如果系统没有对应字体,特别是 Linux 服务器环境下,可以将代码中的中文标题改成英文标题,避免乱码影响结果展示。

6. 练习建议、工程规范和扩展方向

6.1 入门到精通的练习路径

第一阶段,先熟悉曲柄滑块脚本。修改 r、l、omega,观察滑块位移曲线和 GIF 动画的变化。这个阶段的重点是理解参数变化如何影响机构运动。

第二阶段,给曲柄滑块机构加入偏置量。滑块不再沿原点水平线通过,而是偏移一定高度。此时需要重新推导位置公式,xg、phi 的表达式会变得更复杂。这个练习能帮助你理解偏置对机构性能的影响。

第三阶段,实现四杆机构的位置求解,并生成动画。需要处理 fsolve 的初始值、装配模式和 Grashof 条件。

第四阶段,实现五杆或六杆机构。可以采用通用闭环方程框架,将所有环路约束写进 mechanism_loop 函数。

第五阶段,在机构上添加任意标记点,例如连杆中点、质心点,输出这些点的轨迹曲线。

6.2 参数化仿真和批量导出

实际研究工作中,经常需要比较不同杆长组合下的运动特性。可以用循环批量生成结果,并把参数和文件名对应起来:

r_list = [0.8, 1.0, 1.2]; for i = 1:length(r_list) r = r_list(i); % 重新计算机构和导出动画 filename = sprintf('crank_slider_r%.1f.gif', r); end

批量仿真时需要格外注意 GIG 文件命名。推荐把关键参数写进文件名,避免大量结果文件相互覆盖。

6.3 从运动学升级到动力学和 Simscape

本文解决的是运动学问题:给定主动件运动,求解其他构件的位置、速度和加速度。动力学问题则要回答:在给定驱动力矩和外力的情况下,机构如何运动。这需要引入质量、转动惯量、约束反力、阻尼等参数,通常使用微分方程和数值积分求解。

如果后续需要研究复杂

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/31 7:52:31

基于MATLAB的手写数字识别系统:BP神经网络与GUI界面实现全解析

简介&#xff1a;本资源是一套面向计算机及相关专业本科生的MATLAB手写数字识别毕业设计项目源码&#xff0c;融合传统图像处理与深度学习方法&#xff0c;完整实现MNIST数据集上的数字识别任务&#xff0c;并配备可交互GUI界面&#xff0c;适用于课程设计、期末大作业及毕业设…

作者头像 李华
网站建设 2026/8/31 7:52:06

用Claude Code打造AI员工:语音控制、屏幕接管与自动构建实战

Claude Code 是 Anthropic 官方推出的命令行 AI 编程助手&#xff0c;它把大模型能力直接放进了终端&#xff0c;让模型可以读取项目文件、执行命令、修改代码、处理 Git 操作。听上去它是一个“写代码工具”&#xff0c;但如果把 Claude Code 当作自动化工作的控制核心&#x…

作者头像 李华
网站建设 2026/8/31 7:51:31

用LLM为Emacs的EWW浏览器装上AI阅读助手

在 Emacs 里浏览网页&#xff0c;很多人第一反应是折腾半天还不如直接切到 Chrome。确实&#xff0c;EWW 这类内置浏览器能打开页面&#xff0c;但遇到广告密集、正文混乱的长文章&#xff0c;阅读体验几乎劝退。不过现在情况正在变化&#xff1a;LLM 的能力越来越容易通过 HTT…

作者头像 李华
网站建设 2026/8/31 7:51:17

4台Mac跑671B大模型:exo 分布式AI集群本地推理指南

4台Mac跑671B大模型&#xff1a;exo 分布式AI集群本地推理指南 【免费下载链接】exo Run frontier AI locally. 项目地址: https://gitcode.com/GitHub_Trending/exo8/exo exo 是一个本地大模型分布式推理框架&#xff1a;在多台 Apple Silicon 或 Linux 机器上各跑一条…

作者头像 李华