无人机飞控2___为所有伺服通道计算脉冲宽度调制(PWM)信号

该代码是伺服通道管理类SRV_Channels中的一个函数,用于为所有伺服通道计算脉冲宽度调制(PWM)信号。

/*
  run calc_pwm for all channels
 */
void SRV_Channels::calc_pwm(void)
{
    // slew rate limit functions
    for (slew_list *slew = _slew; slew; slew = slew->next) {
        if (is_positive(slew->max_change)) {
            // treat negative or zero slew rate as disabled
            functions[slew->func].output_scaled = constrain_float(functions[slew->func].output_scaled, slew->last_scaled_output - slew->max_change, slew->last_scaled_output + slew->max_change);
        }
        slew->last_scaled_output = functions[slew->func].output_scaled;
    }

    WITH_SEMAPHORE(_singleton->override_counter_sem);

    for (uint8_t i=0; i<NUM_SERVO_CHANNELS; i++) {
        // check if channel has been locked out for this loop
        // if it has, decrement the loop count for that channel
        if (override_counter[i] == 0) {
            channels[i].set_override(false);
        } else {
            channels[i].set_override(true);
            override_counter[i]--;
        }
        if (channels[i].valid_function()) {
            channels[i].calc_pwm(functions[channels[i].function.get()].output_scaled);
        }
    }
}

代码解析

  1. 信号变化率限制:
for (slew_list *slew = _slew; slew; slew = slew->next) {        if (is_positive(slew->max_change)) {            functions[slew->func].output_scaled = constrain_float(functions[slew->func].output_scaled, slew->last_scaled_output - slew->max_change, slew->last_scaled_output + slew->max_change);        }        slew->last_scaled_output = functions[slew->func].output_scaled;    }

这段循环通过遍历一个指针列表来限制每个伺服通道的信号变化率。slew->max_change定义了允许的最大变化量。constrain_float函数确保functions[slew->func].output_scaledslew->last_scaled_output ± slew->max_change之间变化。

  1. 信号量锁定:
WITH_SEMAPHORE(_singleton->override_counter_sem);

这行代码用于锁定信号量,确保在更新伺服通道时不会发生竞态条件。信号量是一种同步机制,用于管理资源的访问权限。

  1. 遍历伺服通道:
for (uint8_t i=0; i<NUM_SERVO_CHANNELS; i++) {        if (override_counter[i] == 0) {            channels[i].set_override(false);        } else {            channels[i].set_override(true);            override_counter[i]--;        }        if (channels[i].valid_function()) {            channels[i].calc_pwm(functions[channels[i].function.get()].output_scaled);        }    }
  • 检查通道覆盖状态:

  • 如果override_counter[i]为0,表示当前通道未被覆盖,set_override(false)用于清除覆盖状态。如果override_counter[i]不为0,则设置覆盖状态并减少计数器值。

  • 有效功能检查:

  • 如果通道有有效功能,则调用calc_pwm方法计算PWM值。

总结

calc_pwm函数负责所有伺服通道的PWM计算。

首先限制信号变化率,确保伺服输出变化平滑。然后锁定信号量,确保线程安全。

最后遍历每个通道,更新PWM信号,并处理通道覆盖情况。

你可能感兴趣的:(无人机飞控2___为所有伺服通道计算脉冲宽度调制(PWM)信号)