// convert a -angle_max..angle_max to a pwm
uint16_t SRV_Channel::pwm_from_angle(float scaled_value) const
{
if (high_out == 0) {
return servo_trim;
}
if (reversed) {
scaled_value = -scaled_value;
}
scaled_value = constrain_float(scaled_value, -high_out, high_out);
if (scaled_value > 0) {
return servo_trim + uint16_t( (scaled_value * (float)(servo_max - servo_trim)) / (float)high_out);
} else {
return servo_trim - uint16_t( (-scaled_value * (float)(servo_trim - servo_min)) / (float)high_out);
}
}
这段代码定义了一个函数pwm_from_angle
,用于将一个角度值转换为对应的PWM信号值。下面是这段代码的详细解释:
输入参数解释- scaled_value
(float):一个表示角度的值,范围通常在-angle_max
到angle_max
之间。代码解析1. 检查最大输出是否为零:
if (high_out == 0) { return servo_trim; }
如果high_out
(最大输出角度)为零,则直接返回伺服的中立值(servo_trim
)。这通常表示该通道没有配置有效的角度范围。2. 处理反向设置:
if (reversed) { scaled_value = -scaled_value; }
```
如果伺服通道被配置为反向,则将输入值取反。3. 限制输入值在有效范围内:
```cpp scaled_value = constrain_float(scaled_value, -high_out, high_out); ```
使用`constrain_float`函数将输入值限制在`-high_out`到`high_out`的范围内,以防止超出伺服的角度范围。
4. 计算PWM值:
```cpp if (scaled_value > 0) { return servo_trim + uint16_t( (scaled_value * (float)(servo_max - servo_trim)) / (float)high_out); } else { return servo_trim - uint16_t( (-scaled_value * (float)(servo_trim - servo_min)) / (float)high_out); }
- 如果输入值大于零,计算PWM值为中立值加上一个正向偏移量。 - 如果输入值小于或等于零,计算PWM值为中立值减去一个反向偏移量。 - 这里的计算考虑了伺服的角度范围和PWM范围之间的映射关系。
总结这个函数将一个角度值转换为对应的PWM信号值,用于控制伺服电机的位置。它考虑了伺服通道的反向设置、角度范围限制,以及PWM信号的最小和最大值。通过这些步骤,确保伺服电机能够根据输入的角度值正确地移动到目标位置。