mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-06-11 22:43:04 +00:00
* Add docs about time_estimate * Fix: Problems with graceful program exit caused by Flutter refactoring * Add: sw_OpenBrowser() & sw_OpenOrcaWebview * Fix: NetworkTestDialog Crash & Add: Lan Device test \ cloud test
8.6 KiB
8.6 KiB
轴向速度和加速度限制详解:斜向移动如何计算
核心问题
对于一条斜向G-code命令,如 G1 X100 Y100 F6000,如何应用各轴的速度/加速度限制?
关键概念:分量 vs 合成
1. 速度的分解
位置: src/libslic3r/GCode/GCodeProcessor.cpp:2804-2824
// 计算每个轴的速度分量(feedrate)
for (unsigned char a = X; a <= E; ++a) {
curr.axis_feedrate[a] = curr.feedrate * delta_pos[a] * inv_distance;
// 这里计算的是每个轴的速度分量
curr.abs_axis_feedrate[a] = std::abs(curr.axis_feedrate[a]);
if (curr.abs_axis_feedrate[a] != 0.0f) {
float axis_max_feedrate = get_axis_max_feedrate(..., static_cast<Axis>(a));
if (axis_max_feedrate != 0.0f)
min_feedrate_factor = std::min<float>(min_feedrate_factor,
axis_max_feedrate / curr.abs_axis_feedrate[a]);
}
}
// 如果有轴超限,按比例降低整体速度
curr.feedrate *= min_feedrate_factor;
详细示例:斜向移动
示例1: 45度对角线移动
G-code命令:
G1 X100 Y100 F6000
物理参数:
起点: (0, 0)
终点: (100, 100)
delta_X = 100mm
delta_Y = 100mm
距离 = √(100² + 100²) = 141.42mm
目标速度 = 6000 mm/min = 100 mm/s
步骤1: 计算各轴速度分量
inv_distance = 1 / 141.42 = 0.00707
// X轴速度分量
axis_feedrate[X] = 100 mm/s × 100mm × 0.00707
= 100 × 0.707
= 70.7 mm/s
// Y轴速度分量
axis_feedrate[Y] = 100 mm/s × 100mm × 0.00707
= 70.7 mm/s
// Z轴速度分量
axis_feedrate[Z] = 0 mm/s (无Z移动)
// E轴速度分量(假设挤出10mm)
axis_feedrate[E] = 100 mm/s × 10mm × 0.00707
= 7.07 mm/s
物理意义:
- 打印头沿对角线以100 mm/s移动
- X轴方向的速度分量是70.7 mm/s
- Y轴方向的速度分量是70.7 mm/s
- 验证: √(70.7² + 70.7²) = 100 mm/s ✓
步骤2: 检查各轴速度限制
假设配置:
machine_max_speed_x = 500 mm/s
machine_max_speed_y = 500 mm/s
machine_max_speed_z = 12 mm/s
machine_max_speed_e = 120 mm/s
检查过程:
min_feedrate_factor = 1.0
// X轴检查
abs_axis_feedrate[X] = 70.7 mm/s
axis_max_feedrate[X] = 500 mm/s
70.7 < 500 ✓ 不需要降速
factor = 500 / 70.7 = 7.07
min_feedrate_factor = min(1.0, 7.07) = 1.0
// Y轴检查
abs_axis_feedrate[Y] = 70.7 mm/s
axis_max_feedrate[Y] = 500 mm/s
70.7 < 500 ✓ 不需要降速
min_feedrate_factor = min(1.0, 7.07) = 1.0
// E轴检查
abs_axis_feedrate[E] = 7.07 mm/s
axis_max_feedrate[E] = 120 mm/s
7.07 < 120 ✓ 不需要降速
min_feedrate_factor = min(1.0, 16.97) = 1.0
结果: min_feedrate_factor = 1.0,所有轴都不超限,保持100 mm/s
步骤3: 应用降速(如果需要)
curr.feedrate *= min_feedrate_factor; // 100 × 1.0 = 100 mm/s
示例2: Z轴限制导致降速
场景: 斜向上移动
G-code命令:
G1 X100 Y100 Z20 F6000
物理参数:
delta_X = 100mm
delta_Y = 100mm
delta_Z = 20mm
距离 = √(100² + 100² + 20²) = 144.57mm
目标速度 = 100 mm/s
计算各轴速度分量
inv_distance = 1 / 144.57 = 0.00692
axis_feedrate[X] = 100 × 100 × 0.00692 = 69.2 mm/s
axis_feedrate[Y] = 100 × 100 × 0.00692 = 69.2 mm/s
axis_feedrate[Z] = 100 × 20 × 0.00692 = 13.84 mm/s ⚠️
检查Z轴限制
// Z轴检查
abs_axis_feedrate[Z] = 13.84 mm/s
axis_max_feedrate[Z] = 12 mm/s
13.84 > 12 ✗ 超限!
// 计算需要降速的因子
factor = 12 / 13.84 = 0.867
min_feedrate_factor = min(1.0, 0.867) = 0.867
应用降速
// 降低整体速度
curr.feedrate *= 0.867
curr.feedrate = 100 × 0.867 = 86.7 mm/s
// 重新计算各轴速度分量
axis_feedrate[X] = 69.2 × 0.867 = 60.0 mm/s
axis_feedrate[Y] = 69.2 × 0.867 = 60.0 mm/s
axis_feedrate[Z] = 13.84 × 0.867 = 12.0 mm/s ✓ 刚好等于限制
// 验证
√(60² + 60² + 12²) = 86.7 mm/s ✓
结果: 由于Z轴限制12 mm/s,整体速度从100降到86.7 mm/s
加速度的分量计算(完全相同的逻辑)
位置: GCodeProcessor.cpp:2834-2838
for (unsigned char a = X; a <= E; ++a) {
float axis_max_acceleration = get_axis_max_acceleration(..., static_cast<Axis>(a));
// 计算这个轴的加速度分量
float axis_acceleration_component = acceleration × |delta_pos[a]| × inv_distance;
if (axis_acceleration_component > axis_max_acceleration)
// 降低整体加速度以满足这个轴的限制
acceleration = axis_max_acceleration / (|delta_pos[a]| × inv_distance);
}
示例3: E轴加速度限制
场景: 高挤出率的打印移动
G1 X50 Y50 E25 F3000
参数:
delta_X = 50mm
delta_Y = 50mm
delta_E = 25mm
距离 = √(50² + 50² + 25²) = 75mm
速度 = 50 mm/s
初始加速度 = 20000 mm/s²
E轴最大加速度 = 5000 mm/s²
计算E轴加速度分量
inv_distance = 1/75 = 0.01333
// E轴加速度分量
E_accel_component = 20000 × 25 × 0.01333
= 20000 × 0.3333
= 6666.7 mm/s²
// 检查E轴限制
6666.7 > 5000 ✗ 超限!
// 调整整体加速度
acceleration = 5000 / (25 × 0.01333)
= 5000 / 0.3333
= 15000 mm/s²
结果:
- 初始加速度20000被降到15000
- E轴分量刚好是5000 mm/s²
- X、Y轴分量相应降低
可视化理解
速度矢量分解
对于 G1 X100 Y100 F6000 (100 mm/s)
Y轴
↑
│ 70.7 mm/s
│
│ ╱
│ ╱ 合成速度
│ ╱ 100 mm/s
│╱
─────┼──────────→ X轴
│ 70.7 mm/s
│
合成速度 = √(Vx² + Vy²) = √(70.7² + 70.7²) = 100 mm/s
如果X轴限制为50 mm/s
原始:
Vx = 70.7 mm/s > 50 ✗ 超限!
降速因子:
factor = 50 / 70.7 = 0.707
降速后:
Vx = 70.7 × 0.707 = 50 mm/s ✓
Vy = 70.7 × 0.707 = 50 mm/s ✓
合成 = √(50² + 50²) = 70.7 mm/s
Y轴
↑
│ 50 mm/s
│
│ ╱
│ ╱ 70.7 mm/s (降速后)
│╱
─────┼──────────→ X轴
│ 50 mm/s
关键理解
1. 限制的是分量
轴向速度限制检查的是:
- 每个轴的速度分量
- 不是合成速度
例子:
G1 X100 Y100 F10000 (合成速度166.7 mm/s)
即使合成速度很高,但如果:
- X轴分量 = 118 mm/s < 500 (X轴限制)
- Y轴分量 = 118 mm/s < 500 (Y轴限制)
则不会降速!
2. 保持方向不变
降速时:
- 所有轴按相同比例降速
- 保持移动方向不变
- 只改变速度大小
原始: (Vx, Vy, Vz) = (70.7, 70.7, 13.84)
降速: (Vx, Vy, Vz) = (60.0, 60.0, 12.0) ← 都乘以0.867
方向: Vx:Vy:Vz = 70.7:70.7:13.84 = 60:60:12 ✓ 方向不变
3. 找最严格的限制
min_feedrate_factor = 1.0
for each axis:
if (轴分量 > 轴限制)
factor = 轴限制 / 轴分量
min_feedrate_factor = min(min_feedrate_factor, factor)
// 使用最小的factor(最严格的限制)
速度 *= min_feedrate_factor
实际例子:打印一条线
G-code
G1 X0 Y0 Z0.2 E0
G1 X100 Y50 Z0.2 E5 F3000
第二条命令分析
移动参数:
delta_X = 100mm
delta_Y = 50mm
delta_Z = 0mm
delta_E = 5mm
距离 = √(100² + 50²) = 111.8mm
目标速度 = 3000 mm/min = 50 mm/s
速度分量:
inv_distance = 1/111.8 = 0.00894
Vx = 50 × 100 × 0.00894 = 44.7 mm/s
Vy = 50 × 50 × 0.00894 = 22.35 mm/s
Vz = 0 mm/s
Ve = 50 × 5 × 0.00894 = 2.24 mm/s
检查限制(假设标准配置):
Vx = 44.7 < 500 ✓
Vy = 22.35 < 500 ✓
Vz = 0 < 12 ✓
Ve = 2.24 < 120 ✓
所有轴都不超限,保持50 mm/s
如果降低Z轴限制到1 mm/s(极端例子):
即使Vz = 0,也不受影响(因为没有Z移动)
只有当有Z移动时,Z轴限制才起作用
总结
关键点
- 限制的是分量,不是合成速度
- 分量 = 合成速度 × (轴移动量 / 总距离)
- 降速保持方向,所有轴同比例降速
- 最严格限制决定最终速度
计算公式
轴速度分量 = 合成速度 × (delta_轴 / 总距离)
如果 轴速度分量 > 轴限制:
降速因子 = 轴限制 / 轴速度分量
合成速度 *= 降速因子
同样适用于加速度!
物理意义
这个设计确保:
- 每个轴的电机不超过物理限制
- 移动方向始终正确
- 在满足所有限制的前提下尽可能快
这就是为什么即使是斜向移动,各轴的速度/加速度限制仍然有效!