Files
OrcaSlicer/doc/developer-reference/Axis_Component_Limits_Explained.md
xiaoyeliu b43cfaaaf9 2.2.0 flutter & WCP & Network Test (#54)
* 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
2025-12-09 10:39:27 +08:00

409 lines
8.6 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 轴向速度和加速度限制详解:斜向移动如何计算
## 核心问题
对于一条斜向G-code命令`G1 X100 Y100 F6000`,如何应用各轴的速度/加速度限制?
## 关键概念:分量 vs 合成
### 1. 速度的分解
**位置**: `src/libslic3r/GCode/GCodeProcessor.cpp:2804-2824`
```cpp
// 计算每个轴的速度分量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命令**:
```gcode
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: 计算各轴速度分量
```cpp
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
```
**检查过程**:
```cpp
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: 应用降速(如果需要)
```cpp
curr.feedrate *= min_feedrate_factor; // 100 × 1.0 = 100 mm/s
```
## 示例2: Z轴限制导致降速
### 场景: 斜向上移动
**G-code命令**:
```gcode
G1 X100 Y100 Z20 F6000
```
**物理参数**:
```
delta_X = 100mm
delta_Y = 100mm
delta_Z = 20mm
距离 = √(100² + 100² + 20²) = 144.57mm
目标速度 = 100 mm/s
```
### 计算各轴速度分量
```cpp
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轴限制
```cpp
// 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
```
### 应用降速
```cpp
// 降低整体速度
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`
```cpp
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轴加速度限制
**场景**: 高挤出率的打印移动
```gcode
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轴加速度分量
```cpp
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. 找最严格的限制
```cpp
min_feedrate_factor = 1.0
for each axis:
if ( > )
factor = /
min_feedrate_factor = min(min_feedrate_factor, factor)
// 使用最小的factor最严格的限制
*= min_feedrate_factor
```
## 实际例子:打印一条线
### G-code
```gcode
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轴限制才起作用
```
## 总结
### 关键点
1. **限制的是分量**,不是合成速度
2. **分量 = 合成速度 × (轴移动量 / 总距离)**
3. **降速保持方向**,所有轴同比例降速
4. **最严格限制**决定最终速度
### 计算公式
```
轴速度分量 = 合成速度 × (delta_轴 / 总距离)
如果 轴速度分量 > 轴限制:
降速因子 = 轴限制 / 轴速度分量
合成速度 *= 降速因子
同样适用于加速度!
```
### 物理意义
这个设计确保:
- 每个轴的电机不超过物理限制
- 移动方向始终正确
- 在满足所有限制的前提下尽可能快
这就是为什么即使是斜向移动,各轴的速度/加速度限制仍然有效!