前言

这一篇分析APM的遥控器数据获取


ArduCopter\Copter.cpp中rc_loop遥控器线程

const AP_Scheduler::Task Copter::scheduler_tasks[] = {SCHED_TASK(rc_loop,              100,    130),SCHED_TASK(throttle_loop,         50,     75),SCHED_TASK(update_GPS,            50,    200),
void Copter::rc_loop()
{// Read radio and 3-position switch on radio// -----------------------------------------read_radio();rc().read_mode_switch();
}

read_radio();

这里开始跳转ArduCopter\Copter.h

    // radio.cppvoid default_dead_zones();void init_rc_in();void init_rc_out();void enable_motor_output();void read_radio();void set_throttle_and_failsafe(uint16_t throttle_pwm);void set_throttle_zero_flag(int16_t throttle_control);void radio_passthrough_to_motors();int16_t get_throttle_mid(void);

这一步不能直接跳转了 看了一下注释找一下radio.cpp文件在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());// RC receiver must be attached if we've just got inputap.rc_receiver_present = true;// pass pilot input through to motors (used to allow wiggling servos while disarmed on heli, single, coax copters)radio_passthrough_to_motors();const float dt = (tnow_ms - last_radio_update_ms)*1.0e-3f;rc_throttle_control_in_filter.apply(channel_throttle->get_control_in(), dt);last_radio_update_ms = tnow_ms;return;}// No radio input this timeif (failsafe.radio) {// already in failsafe!return;}const uint32_t elapsed = tnow_ms - last_radio_update_ms;// turn on throttle failsafe if no update from the RC Radio for 500ms or 2000ms if we are using RC_OVERRIDEconst uint32_t timeout = RC_Channels::has_active_overrides() ? FS_RADIO_RC_OVERRIDE_TIMEOUT_MS : FS_RADIO_TIMEOUT_MS;if (elapsed < timeout) {// not timed out yetreturn;}if (!g.failsafe_throttle) {// throttle failsafe not enabledreturn;}if (!ap.rc_receiver_present && !motors->armed()) {// we only failsafe if we are armed OR we have ever seen an RC receiverreturn;}// Nobody ever talks to us.  Log an error and enter failsafe.AP::logger().Write_Error(LogErrorSubsystem::RADIO, LogErrorCode::RADIO_LATE_FRAME);set_failsafe_radio(true);
}

这里重点关注read_input()这个是通道信号输入的刷新

bool RC_Channels::read_input(void)
{if (!hal.rcin->new_input() && !has_new_overrides) {return false;}has_new_overrides = false;bool success = false;for (uint8_t i=0; i<NUM_RC_CHANNELS; i++) {success |= channel(i)->update();}return success;
}

直接关注hal.rcin->new_input()

bool RC_Channels::read_input(void)
{if (!hal.rcin->new_input() && !has_new_overrides) {return false;}has_new_overrides = false;bool success = false;for (uint8_t i=0; i<NUM_RC_CHANNELS; i++) {success |= channel(i)->update();}return success;
}

channel(i)

    RC_Channel_Copter *channel(const uint8_t chan) override {if (chan >= NUM_RC_CHANNELS) {return nullptr;}return &obj_channels[chan];}

channel(i)->update()信号的读取

radio_in保存读取到的PWM值

bool RC_Channel::update(void)
{if (has_override() && !rc().ignore_overrides()) {radio_in = override_value;} else if (!rc().ignore_receiver()) {radio_in = hal.rcin->read(ch_in);} else {return false;}if (type_in == RC_CHANNEL_TYPE_RANGE) {control_in = pwm_to_range();} else {//RC_CHANNEL_TYPE_ANGLEcontrol_in = pwm_to_angle();}return true;
}

float  rcin[8];         // RC input 0..1

read_mode_switch()

此函数的作用是判断飞行器当前的模式和飞行模式的设置

void RC_Channel::read_mode_switch()
{// calculate position of flight mode switchconst uint16_t pulsewidth = get_radio_in();if (pulsewidth <= 900 || pulsewidth >= 2200) {return;  // This is an error condition}modeswitch_pos_t position;if      (pulsewidth < 1231) position = 0;else if (pulsewidth < 1361) position = 1;else if (pulsewidth < 1491) position = 2;else if (pulsewidth < 1621) position = 3;else if (pulsewidth < 1750) position = 4;else position = 5;if (!debounce_completed(position)) {return;}// set flight mode and simple mode setting//设置飞行模式和简单模式设置mode_switch_changed(position);
}

这里的重点是void RC_Channel_Copter::mode_switch_changed(modeswitch_pos_t new_pos) 函数

ArduCopter\RC_Channel.cpp

void RC_Channel_Copter::mode_switch_changed(modeswitch_pos_t new_pos)
{if (new_pos < 0 || (uint8_t)new_pos > copter.num_flight_modes) {// should not have been calledreturn;}if (!copter.set_mode((Mode::Number)copter.flight_modes[new_pos].get(), ModeReason::RC_COMMAND)) {// alert user to mode change failureif (copter.ap.initialised) {AP_Notify::events.user_mode_change_failed = 1;}return;}// play a tone// alert user to mode change (except if autopilot is just starting up)if (copter.ap.initialised) {AP_Notify::events.user_mode_change = 1;}if (!rc().find_channel_for_option(AUX_FUNC::SIMPLE_MODE) &&!rc().find_channel_for_option(AUX_FUNC::SUPERSIMPLE_MODE)) {// if none of the Aux Switches are set to Simple or Super Simple Mode then// set Simple Mode using stored parameters from EEPROMif (BIT_IS_SET(copter.g.super_simple, new_pos)) {copter.set_simple_mode(2);} else {copter.set_simple_mode(BIT_IS_SET(copter.g.simple_modes, new_pos));}}
}

判断一下是否有模式输入 

if (new_pos < 0 || (uint8_t)new_pos > copter.num_flight_modes) {

// should not have been called

//    const uint8_t num_flight_modes = 6;

return;

}

更改模式和判断模式是否更改成功

if (!copter.set_mode((Mode::Number)copter.flight_modes[new_pos].get(), ModeReason::RC_COMMAND)) {

// alert user to mode change failure

if (copter.ap.initialised) {

AP_Notify::events.user_mode_change_failed = 1;

}

return;

}

其中set_mode有两个重载函数

第一个传参很好理解就是设置成当前的模式而第二个传参modereason 则是接口相当于你模式的来源,我是这么理解的

// interface to set the vehicles mode
enum class ModeReason : uint8_t {UNKNOWN,RC_COMMAND,GCS_COMMAND,RADIO_FAILSAFE,BATTERY_FAILSAFE,GCS_FAILSAFE,EKF_FAILSAFE,GPS_GLITCH,MISSION_END,THROTTLE_LAND_ESCAPE,FENCE_BREACHED,TERRAIN_FAILSAFE,BRAKE_TIMEOUT,FLIP_COMPLETE,AVOIDANCE,AVOIDANCE_RECOVERY,THROW_COMPLETE,TERMINATE,TOY_MODE,CRASH_FAILSAFE,SOARING_FBW_B_WITH_MOTOR_RUNNING,SOARING_THERMAL_DETECTED,SOARING_THERMAL_ESTIMATE_DETERIORATED,VTOL_FAILED_TRANSITION,VTOL_FAILED_TAKEOFF,FAILSAFE, // general failsafes, prefer specific failsafes over this as much as possibleINITIALISED,SURFACE_COMPLETE,BAD_DEPTH,LEAK_FAILSAFE,SERVOTEST,STARTUP,SCRIPTING,UNAVAILABLE,AUTOROTATION_START,AUTOROTATION_BAILOUT,
};

后续更新

Apm飞控学习笔记之-RC_Channel遥控器数据获取-Cxm相关推荐

  1. Apm飞控学习笔记之悬停loiter模式-Cxm

    文章汇集 PX4/APM/飞控的学习笔记前言-Cxm_CHENxiaomingming的博客-CSDN博客_apm和px4哪个好 前言 时隔一段时间又开始琢磨APM飞控了,在上一篇中写了姿态控制,经过 ...

  2. Apm飞控学习笔记-姿态控制-Cxm

    目录 PX4/APM/飞控的学习笔记前言-Cxm_chen_taifu的博客-CSDN博客开始了 开始了终于有时间可以学习飞控了此文章是用来当目录,我会持续更新我的学习之旅,希望能对各位有所帮助如果有 ...

  3. Apm飞控学习笔记之添加我的设备或单片机串口通信-Cxm

    目录 PX4/APM/飞控的学习笔记前言-Cxm_chen_taifu的博客-CSDN博客开始了 开始了终于有时间可以学习飞控了此文章是用来当目录,我会持续更新我的学习之旅,希望能对各位有所帮助如果有 ...

  4. Apm飞控学习笔记之添加我的飞行模式-Cxm

    目录 PX4/APM/飞控的学习笔记前言-Cxm_chen_taifu的博客-CSDN博客开始了 开始了终于有时间可以学习飞控了此文章是用来当目录,我会持续更新我的学习之旅,希望能对各位有所帮助如果有 ...

  5. Apm飞控学习笔记之如何添加自己的功能-Cxm

    目录: PX4/APM/飞控的学习笔记前言-Cxm_chen_taifu的博客-CSDN博客开始了 开始了终于有时间可以学习飞控了此文章是用来当目录,我会持续更新我的学习之旅,希望能对各位有所帮助如果 ...

  6. APM飞控学习笔记——自动模式下一分钟自动降落

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.自动模式简介 二.添加自动降落功能 1.飞控主循环调用逻辑 2.功能添加 总结 前言 APM是一款功能齐全的开源多 ...

  7. 第一篇——APM飞控学习笔记

    关于什么是APM? 可能有很多玩航模或者是向我这样混迹于实验室的垃圾佬(bushi)看到过这个玩意--->>> 从狭义上来说,这个就是APM开源飞控. APM又叫ArduPilot- ...

  8. 基于tiva的匿名飞控学习笔记(1)

    基于tiva的匿名飞控学习笔记(1) 开关状态任务 遥控器数据处理任务 数传数据交换 延时存储任务 开关状态任务 匿名飞控的开关状态任务为函数Swtich_State_Task(u8 dT_ms),定 ...

  9. APM飞控学习之路:1 无人机的分类与发展

    "旧时王谢堂前燕,飞入寻常百姓家".无人机也像那堂前燕,从以前为军事所专属,负责侦查和战斗,飞入民用领域,在航拍.植保.快递.救灾.巡检.拍摄等行业大显身手,无人机+的应用遍地开花 ...

最新文章

  1. spacy spaCy主要功能包括分词、词性标注、词干化、命名实体识别、名词短语提取等等
  2. 光伏电站清扫机器人_轻型光伏电站清扫机器人的制作方法
  3. Winform控件扩展
  4. android发送点击事件,Android 模拟发送事件
  5. 算法-----python实现
  6. [MSP430DriverLib-2]使用延时让LED闪烁
  7. 两个相同矩形脉冲卷积_两个矩形脉冲的卷积
  8. 20个开源Flutter项目推荐
  9. 等保要求的 linux 系统扫描脚本
  10. python isinstance()方法的使用
  11. Python 身份证校验代码
  12. HDU2030-汉字机内码
  13. VMware Fusion CentOS7 下载安装及手动配置静态IP
  14. 近期币圈与美股的相关性
  15. linux创建用户和组
  16. win10启动文件夹在哪 如何设置随系统自动启动
  17. QMS-云质-质量管理软件-闲聊霍尼韦尔用13亿美元收购一家质量管理软件(QMS)小公司
  18. VS Code中将自定义的Snippets绑定到自定义的快捷键上
  19. IDA的详细使用指南以及核心功能讲解
  20. 机器学习之Matplotlib

热门文章

  1. sobel算子梯度 matlab,sobel算子,matlab实现 | 学步园
  2. Codeforces Round #849 (Div. 4) F. Range Update Point Query
  3. js 判断数组中是否存在某个元素(字符串,类等)
  4. php xpath注入工具,科普:XPATH注入
  5. 如何使用Latex将四幅图跨栏排列
  6. 非常受用:HP大中华区总裁孙振耀退休十五天后九大感言
  7. Android SDK Platform Tools
  8. 计算机无法跳转登录页面,电脑连接校园网后CMCC登录界面不能弹出的解决方法...
  9. php setinc,ThinkPHP 数字字段 更新 setInc 与 setDec 方法
  10. Django Q对象