文章目录
参考文章
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角度”(通常-4500到4500)
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相关内容。