Pixhawk(APM固件) ArduPilot的遥控器读取及油门转换

Pixhawk(APM固件) ArduPilot的遥控器读取及油门转换

1.遥控器硬件连接

Futaba的接收机通过Sbus连接到PX4IO芯片上,即STM32F10X的芯片上,PX4IO与PX4FMU(STM32F42X)通过串口相连,这样接收机数据就由PX4IO读取并送到PX4FMU中,本博客记录ArduPilot上层读取遥控器数据及油门转换的过程。

2.遥控器各通道数据读取

ArduCopter.cpp中定义了rc_loop这个scheduler,以100Hz的速度运行,rc_loop函数也定义在此文件中,其定义如下:
void Copter::rc_loop()
{
    // Read radio and 3-position switch on radio
    // -----------------------------------------
    read_radio();
    read_control_switch();
}
read_radio用来读取各个通道的PWM值,并进行角度或范围的转换。 read_control_switch根据上一函数读到的PWM值判断开关的位置,并作进一步处理。今天主要看read_radio.此函数定义在radio.cpp中,原型如下:
    static uint32_t last_update_ms = 0;
    uint32_t tnow_ms = millis();


    if (hal.rcin->new_input()) {
        last_update_ms = tnow_ms;
        ap.new_radio_frame = true;
        RC_Channel::set_pwm_all();


        set_throttle_and_failsafe(channel_throttle->radio_in);
        set_throttle_zero_flag(channel_throttle->control_in);


        // flag we must have an rc receiver attached
        if (!failsafe.rc_override_active) {
            ap.rc_receiver_present = true;
        }


        // update output on any aux channels, for manual passthru
        RC_Channel_aux::output_ch_all();
    }else{
        uint32_t elapsed = tnow_ms - last_update_ms;
        // turn on throttle failsafe if no update from the RC Radio for 500ms or 2000ms if we are using RC_OVERRIDE
        if (((!failsafe.rc_override_active && (elapsed >= FS_RADIO_TIMEOUT_MS)) || (failsafe.rc_override_active && (elapsed >= FS_RADIO_RC_OVERRIDE_TIMEOUT_MS))) &&
            (g.failsafe_throttle && (ap.rc_receiver_present||motors.armed()) && !failsafe.radio)) {
            Log_Write_Error(ERROR_SUBSYSTEM_RADIO, ERROR_CODE_RADIO_LATE_FRAME);
            set_failsafe_radio(true);
        }
    }
}
第一步判断是否有新的输入,主要是通过判断orb_check出来的数据的时间戳,是否与我们上次读取的时间戳一致来完成的,源代码在libraries/AP_HAL_PX4/RCInput.cpp中,注意其中的_timer_tick函数是定时器(软件的)触发运行的。
有输入的话,就通过RC_Channel::set_pwm_all()读取并转换所有的通道,其定义如下:
void
RC_Channel::set_pwm_all(void)
{
    for (uint8_t i=0; i         if (rc_ch[i] != NULL) {
            rc_ch[i]->set_pwm(rc_ch[i]->read());
        }
    }
}
在这一函数中通过rc_ch[i]->read()读取该通道的PWM值,并调用set_pwm函数。
// read input from APM_RC - create a control_in value
void
RC_Channel::set_pwm(int16_t pwm)
{
    radio_in = pwm;


    if (_type == RC_CHANNEL_TYPE_RANGE) {
        control_in = pwm_to_range();
    } else {
        //RC_CHANNEL_TYPE_ANGLE, RC_CHANNEL_TYPE_ANGLE_RAW
        control_in = pwm_to_angle();
    }
}
这一函数将读到的PWM值记录到radio_in变量中,并根据此通道的type调用pwm_to_range或pwm_to_rangle,将值赋给control_in。type的赋值过程为,ArduCopter.cpp中的setup函数调用system.cpp中的init_ardupilot函数,此函数调用radio.cpp中的init_rc_in,在此函数中完成对主要通道的参数的修改。

油门通道的type为RC_CHANNEL_TYPE_RANGE,所以调用pwm_to_range,此函数直接调用pwm_to_range_dz,分析见下图。

Pixhawk(APM固件) ArduPilot的遥控器读取及油门转换_第1张图片
用matlab画出其曲线,如下:

自此,便完成了遥控器数据的读取,及把油门通道的PWM值转换为0-1000的范围值,即0%到100%。

在control_stabilize中,通过get_pilot_desired_throttle对上述的油门做了进一步转换,主要目的是使油门在中间的时候,能够按照THR_MID定义的值输出,并同时对其他的油门scale。当把THR-MID设置为300,500时,可以得到下面曲线。


Pixhawk(APM固件) ArduPilot的遥控器读取及油门转换_第2张图片

你可能感兴趣的:(Pixhawk(APM固件) ArduPilot的遥控器读取及油门转换)