ArduPilot 第10章 RC

本文详细解读了ArdupilotArduCopter源码中的遥控器输入初始化过程,包括RCChannels的设置、PWM信号转换为角度或范围、以及如何将RC输入传递到电机进行控制。重点介绍了关键函数如`init_ardupilot()`、`read_radio()`和`radio_passthrough_to_motors()`的工作原理。
摘要由CSDN通过智能技术生成


参考文章
Ardupilot-ArduCopter-3.2.1 源码解读
https://www.renrendoc.com/paper/164558851.html

APM(Ardupilot)——遥控器RC input
https://blog.csdn.net/yinxian5224/article/details/102744285

RC输入和输出
https://emotionfly.blog.csdn.net/article/details/127862084?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-127862084-blog-102836314.235%5Ev43%5Epc_blog_bottom_relevance_base5&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-127862084-blog-102836314.235%5Ev43%5Epc_blog_bottom_relevance_base5&utm_relevant_index=2

APM_ArduCopter源码解析学习(二)——电机库学习
https://blog.csdn.net/zhangfengmei1987/article/details/110448094

四旋翼飞行器搭建教程(px4ardupoilotapm )讲诉
https://www.renrendoc.com/paper/212794803.html

前言

本文介绍ArduPilot 的radio相关内容。

RC 输入:这是飞控板接收来自遥控器的信号。遥控器的摇杆、开关和按钮产生的输入信号被转换为 PWM 信号,用于控制飞行器的运动、姿态和其他功能。例如,升降、横滚、俯仰和偏航通常由 RC 输入控制。

RC 输出:这是飞控板向执行器发送的信号。执行器可以是伺服、电机、电调等。通过调整 PWM 信号的脉冲宽度,可以控制执行器的位置、速度和扭矩。例如,电机的转速、伺服的位置和舵面的角度都由 RC 输出控制。


一、遥控器输入初始化

1.init_ardupilot()

\ArduCopter\system.cpp

void Copter::init_ardupilot()
{
	...
	init_rc_in();               
    rc().init();
	...
}

2.init_rc_in()

横滚通道:[-4500,4500] ;
俯仰通道:[-4500,4500] ;
偏航通道:[-4500,4500] ;
油门通道:[0,1000] ;
其他外部通道值:0-1000
\ArduCopter\radio.cpp

void Copter::init_rc_in()
{
    channel_roll     = rc().channel(rcmap.roll()-1);
    channel_pitch    = rc().channel(rcmap.pitch()-1);
    channel_throttle = rc().channel(rcmap.throttle()-1);
    channel_yaw      = rc().channel(rcmap.yaw()-1);

    // set rc channel ranges
    channel_roll->set_angle(ROLL_PITCH_YAW_INPUT_MAX);
    channel_pitch->set_angle(ROLL_PITCH_YAW_INPUT_MAX);
    channel_yaw->set_angle(ROLL_PITCH_YAW_INPUT_MAX);
    channel_throttle->set_range(1000);

    // set default dead zones
    default_dead_zones();

    // initialise throttle_zero flag
    ap.throttle_zero = true;
}

3.RC_Channels::init

\libraries\RC_Channel\RC_Channels.cpp

void RC_Channels::init(void)
{
    // setup ch_in on channels
    for (uint8_t i=0; i<NUM_RC_CHANNELS; i++) {
        channel(i)->ch_in = i;
    }

    init_aux_all();
}

二、信道读取

1.scheduler_tasks[]

\ArduCopter\Copter.cpp

const AP_Scheduler::Task Copter::scheduler_tasks[] = {
    SCHED_TASK(rc_loop,              100,    130,  3),
    ...
}

2.Copter::rc_loop()

read_radio()用来读取各个通道的PWM值,并进行角度或范围的转换。read_control_switch根据上一函数读到的PWM值判断开关的位置, 并作进一步处理。
\ArduCopter\Copter.cpp

void Copter::rc_loop()
{
    // Read radio and 3-position switch on radio
    // -----------------------------------------
    read_radio();
    rc().read_mode_switch();
}

3.Copter::read_radio()

\ArduCopter\radio.cpp

void Copter::read_radio()
{
    const uint32_t tnow_ms = millis();

    if (rc().read_input()) {
        ap.new_radio_frame = true;

        set_throttle_and_failsafe(channel_throttle->get_radio_in());
        set_throttle_zero_flag(channel_throttle->get_control_in());
    ...
    }
    ...
        
}

3.1.Copter::read_input(void)

\libraries\RC_Channel\RC_Channels.cpp
继续跟踪发现在update中获取各个信道的数据。

bool RC_Channels::read_input(void)
{
    if (hal.rcin->new_input()) {
        _has_had_rc_receiver = true;
    } else if (!has_new_overrides) {
        return false;
    }

    has_new_overrides = false;

    last_update_ms = AP_HAL::millis();

    bool success = false;
    for (uint8_t i=0; i<NUM_RC_CHANNELS; i++) {
        success |= channel(i)->update();
    }

    return success;
}

3.1.1.RC_Channel::update(void)

\libraries\RC_Channel\RC_Channel.cpp

// read input from hal.rcin or overrides
bool RC_Channel::update(void)
{
    if (has_override() && !rc().ignore_overrides()) {
        radio_in = override_value;
    } else if (rc().has_had_rc_receiver() && !rc().ignore_receiver()) {
        radio_in = hal.rcin->read(ch_in);
    } else {
        return false;
    }

	将脉宽调制值转换为配置范围内的值
    if (type_in == ControlType::RANGE) {
        control_in = pwm_to_range();
    } else {
    从当前遥控器输入返回一个角度:“单位是角度的100倍,就是cm角度”(通常-45004500)
        control_in = pwm_to_angle();
    }

    return true;
}

3.1.1.1.RC_Channel::pwm_to_angle()

\libraries\RC_Channel\RC_Channel.cpp

int16_t RC_Channel::pwm_to_angle() const
{
	return pwm_to_angle_dz(dead_zone);
}

3.2.GroupInfo RC_Channel::var_info[]

\libraries\RC_Channel\RC_Channel.cpp

const AP_Param::GroupInfo RC_Channel::var_info[] = {
	...
	AP_GROUPINFO("MIN",  1, RC_Channel, radio_min, 1100),

    AP_GROUPINFO("TRIM", 2, RC_Channel, radio_trim, 1500),

    AP_GROUPINFO("MAX",  3, RC_Channel, radio_max, 1900),
	...
}

3.3.radio_passthrough_to_motors()

上面函数就是传递数据到电机库,参与PID运算,进而控制无人机 。

\ArduCopter\radio.cpp

void Copter::radio_passthrough_to_motors()
{
    motors->set_radio_passthrough(channel_roll->norm_input(),
                                  channel_pitch->norm_input(),
                                  channel_throttle->get_control_in_zero_dz()*0.001f,
                                  channel_yaw->norm_input());
}


总结

本文ArduPilot 的RC相关内容。

  • 13
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值