当前位置: 首页 > article >正文

PIXHAWK(ardupilot4.52)单ic通道输出pwm

可以看到飞控具有16个ic输出通道,理论上每一个通道都可以单独输出pwm,那么怎样才能在固件中让每个通道都单独输出pwm呢?

1、

手动模式下油门控制可以直观的控制pwm输出,

在void ModeManual::update()中可以看到g2.motors.set_throttle(desired_throttle); 就是油门处理函数。可以根据这个函数寻址找到void AP_MotorsUGV::set_throttle(float throttle)函数

//libraries/AR_Motors/AP_MotorsUGV.cpp 
void AP_MotorsUGV::set_throttle(float throttle)
{
    // only allow setting throttle if armed
    if (!hal.util->get_soft_armed()) {
        return;
    }
    // check throttle is between -_throttle_max and  +_throttle_max
    _throttle = constrain_float(throttle, -_throttle_max, _throttle_max);
}

在这个函数中可以看到形参desired_throttle最终是递给了_throttle这个参数。接下来就是在该文件下找哪里使用了_throttle这个参数。

void AP_MotorsUGV::output(bool armed, float ground_speed, float dt)
{
    // soft-armed overrides passed in armed status 以武装状态通过软武装覆盖
    if (!hal.util->get_soft_armed()) {
        armed = false;
        _throttle = 0.0f;
    }

    // clear limit flags
    // output_ methods are responsible for setting them to true if required on each iteration
    //清除限制标志
    //output_方法负责在每次迭代中根据需要将其设置为true
    limit.steer_left = limit.steer_right = limit.throttle_lower = limit.throttle_upper = false;

    // sanity check parameters 健全性检查参数
    sanity_check_parameters();

    // slew limit throttle 回转限制节流阀
    slew_limit_throttle(dt);

    // output for regular steering/throttle style frames 常规转向/油门式车架的输出
    output_regular(armed, ground_speed, _steering, _throttle);

    // output for skid steering style frames 滑移转向式车架的输出
    output_skid_steering(armed, _steering, _throttle, dt);

    // output for omni frames 全帧输出
    output_omni(armed, _steering, _throttle, _lateral);

    // output to sails 输出到帆
    output_sail();

    // send values to the PWM timers for output 将值发送到PWM定时器进行输出
    SRV_Channels::calc_pwm(); //计算所有通道的PWM
    SRV_Channels::cork();
    SRV_Channels::output_ch_all(); //控制pwm输出
    SRV_Channels::push();
}

搜索查找后可以找到void AP_MotorsUGV::output(bool armed, float ground_speed, float dt)这个函数,看名称可以判断为输出函数。_throttle在这个函数中使用了,但是最终都汇聚在SRV_Channels::output_ch_all();函数中,这个就是控制pwm输出函数。

继续寻址。找到SRV_Channels::output_ch_all()的定义。

//libraries/SRV Channel/SRV Channel_aux.cpp 
void SRV_Channels::output_ch_all(void)
{
    uint8_t max_chan = NUM_SERVO_CHANNELS;
#if NUM_SERVO_CHANNELS >= 17
    if (_singleton != nullptr && _singleton->enable_32_channels.get() <= 0) {
        max_chan = 16;
    }
#endif
    for (uint8_t i = 0; i < max_chan; i++) {

        channels[i].output_ch();
    }
}

在函数的末尾可以看到channels[i].output_ch();这个函数,这个函数还不能直接输出定值的pwm,继续寻址。

//libraries/SRV Channel/SRV Channel_aux.cpp 
void SRV_Channel::output_ch(void)
{
#ifndef HAL_BUILD_AP_PERIPH
    int8_t passthrough_from = -1;
    bool passthrough_mapped = false;

    // take care of special function cases 照顾特殊功能例
    switch(function.get())
    {
    case k_manual:              // manual
        passthrough_from = ch_num;
        break;
    case k_rcin1 ... k_rcin16: // rc pass-thru
        passthrough_from = int8_t((int16_t)function - k_rcin1);
        break;
    case k_rcin1_mapped ... k_rcin16_mapped:
        passthrough_from = int8_t((int16_t)function - k_rcin1_mapped);
        passthrough_mapped = true;
        break;
    }
    if (passthrough_from != -1) {
        // we are doing passthrough from input to output for this channel 我们正在为这个通道进行从输入到输出的直通
        RC_Channel *c = rc().channel(passthrough_from);
        if (c) {
            if (SRV_Channels::passthrough_disabled()) {
                output_pwm = c->get_radio_trim();
            } else {
                // non-mapped rc passthrough 非映射rc透传
                int16_t radio_in = c->get_radio_in();
                if (passthrough_mapped) {
                    if (rc().has_valid_input()) {
                        switch (c->get_type()) {
                        case RC_Channel::ControlType::ANGLE:
                            radio_in = pwm_from_angle(c->norm_input_dz() * 4500);
                            break;
                        case RC_Channel::ControlType::RANGE:
                            // convert RC normalised input from -1 to +1 range to 0 to +1 and output as range
                            radio_in = pwm_from_range((c->norm_input_ignore_trim() + 1.0) * 0.5 * 4500);
                            break;
                        }
                    } else {
                        // no valid input.  If we are in radio
                        // failsafe then go to trim values (if
                        // configured for this channel).  Otherwise
                        // use the last-good value
                        if ( ((1U<<passthrough_from) & SRV_Channels::get_rc_fs_mask()) && rc().in_rc_failsafe()) {
                            radio_in = pwm_from_angle(0);
                        } else {
                            radio_in = previous_radio_in;
                        }
                    }
                }
                if (!ign_small_rcin_changes) {
                    output_pwm = radio_in;
                    previous_radio_in = radio_in;
                } else {
                    // check if rc input value has changed by more than the deadzone
                    if (abs(radio_in - previous_radio_in) > c->get_dead_zone()) {
                        output_pwm = radio_in;
                        ign_small_rcin_changes = false;
                    }
                }
            }
        }
    }
#endif // HAL_BUILD_AP_PERIPH
    if (!(SRV_Channels::disabled_mask & (1U<<ch_num))) {
 //       hal.rcout->write(ch_num, output_pwm);//原版

        hal.rcout->write(ch_num, 900+ch_num*70);//实验测试

    }
}

该函数下,前面的都是验证每个通道分别需要多少的pwm输出,函数的最后才是控制单独通道的单独输出。

 hal.rcout->write(ch_num, output_pwm);

其中ch_num即对应通道,output_pwm即需要输出的pwm,在这里修改代码测试一下:

 hal.rcout->write(ch_num, 900+ch_num*70);

修改后,理论上第一个通道输出900,然后后面的通道逐个递增70。

编译完成后下载到飞控中查看ic通道输出。

可以看到ic通道确实是根据设定输出,但是只有前8个通道输出,后面8个却没有输出,这是为啥?


http://www.kler.cn/a/404198.html

相关文章:

  • 《Python浪漫的烟花表白特效》
  • AI一键生成原创花卉印花图案——创新与效率的结合
  • 排序算法(三)--插入排序
  • 【动手学深度学习Pytorch】4. 神经网络基础
  • o1的风又吹到多模态,直接吹翻了GPT-4o-mini
  • Excel - VLOOKUP函数将指定列替换为字典值
  • [QDS]从零开始,写第一个Qt Design Studio到程序调用的项目
  • ChatGPT Search VS Kimi探索版:AI搜索哪家强?!
  • 阶乘之和的尾数
  • 【2024APMCM亚太杯A题】详细解题思路
  • 三、计算机视觉_06YOLO基础知识
  • 深入理解Spring(二)
  • 子矩阵的和(矩阵前缀和)
  • SpringBootTest启动时出现循环依赖问题
  • 机器学习问题之一:协变量偏移(Covariate Shift)
  • 嵌入式Linux移植cJSON库
  • 基于 RBF 神经网络辨识的单神经元 PID 模型参考自适应控制
  • fca考试
  • 每天五分钟深度学习框架pytorch:神经网络模型的参数初始化操作
  • (二)Ubuntu22.04+Stable-Diffusion-webui AI绘画 中英双语插件安装
  • 括号匹配算法
  • Kafka-创建topic源码
  • Flink的Standalone集群模式安装部署
  • 【机器学习chp6】对数几率回归
  • 【AI】人工智能报告解读——中国人工智能的发展
  • #systemverilog# 关于 randomize(a) 却报 b 失败的疑问