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

PX4模块设计之二十八:RCInput模块

PX4模块设计之二十八:RCInput模块

  • 1. RCInput模块简介
  • 2. 模块入口函数
    • 2.1 主入口rc_input_main
    • 2.2 自定义子命令custom_command
    • 2.3 模块状态print_status【重载】
  • 3. RCInput模块重要函数
    • 3.1 task_spawn
    • 3.2 instantiate
    • 3.3 init
    • 3.4 Run
  • 4. 总结
  • 5. 参考资料

1. RCInput模块简介

RC遥控支持如下协议:

  1. PPM
  2. SBUS
  3. DSM
  4. SUMD
  5. ST24
  6. CRSF
  7. GHST
### Description
This module does the RC input parsing and auto-selecting the method. Supported methods are:
- PPM
- SBUS
- DSM
- SUMD
- ST24
- TBS Crossfire (CRSF)

rc_input <command> [arguments...]
 Commands:
   start       
     [-d <val>] /dev/ttyS3 "RC device"

   bind          Send a DSM bind command (module must be running)

   stop

   status        print status info

注:print_usage函数是具体对应实现。

class RCInput : public ModuleBase<RCInput>, public ModuleParams, public px4::ScheduledWorkItem

注:RCInput模块采用了ModuleBase和WorkQueue设计。

2. 模块入口函数

2.1 主入口rc_input_main

同样继承了ModuleBase,由ModuleBase的main来完成模块入口。

rc_input_main
 └──> return RCInput::main(argc, argv)

2.2 自定义子命令custom_command

除start/stop/status命令,自定义命令支持bind,主要用于接收机与发射机的绑定。

RCInput::custom_command
 ├──> <SPEKTRUM_POWER><!strcmp(verb, "bind")>
 │   ├──> uORB::Publication<vehicle_command_s> vehicle_command_pub{ORB_ID(vehicle_command)}
 │   ├──> vehicle_command_s vcmd{}
 │   ├──> vcmd.command = vehicle_command_s::VEHICLE_CMD_START_RX_PAIR
 │   ├──> vcmd.timestamp = hrt_absolute_time()
 │   ├──> vehicle_command_pub.publish(vcmd)
 │   └──> return 0
 ├──> <!is_running()>
 │   ├──> int ret = RCInput::task_spawn(argc, argv)
 │   └──> <ret>
 │       └──> return ret
 └──> return print_usage("unknown command")

2.3 模块状态print_status【重载】

这里重载了ModuleBase的print_status方法,将RCInput相关的状态信息进行输出。

RCInput::print_status
 ├──> PX4_INFO("Max update rate: %u Hz", 1000000 / _current_update_interval)
 ├──> <_device[0] != '\0'>
 │   ├──> PX4_INFO("UART device: %s", _device)
 │   └──> PX4_INFO("UART RX bytes: %"  PRIu32, _bytes_rx)
 ├──> PX4_INFO("RC state: %s: %s", _rc_scan_locked ? "found" : "searching for signal", RC_SCAN_STRING[_rc_scan_state])
 ├──> <_rc_scan_locked>
 │   ├──> <RC_SCAN_CRSF>
 │   │   └──> PX4_INFO("CRSF Telemetry: %s", _crsf_telemetry ? "yes" : "no")
 │   ├──> <RC_SCAN_GHST>
 │   │   └──> PX4_INFO("GHST Telemetry: %s", _ghst_telemetry ? "yes" : "no")
 │   ├──> <RC_SCAN_SBUS>
 │   │   └──> PX4_INFO("SBUS frame drops: %u", sbus_dropped_frames())
 │   └──> <other RC Protocol>
 │       └──> [No Prints]
 ├──> <_analog_rc_rssi_stable>
 │   └──> PX4_INFO("vrssi: %dmV", (int)(_analog_rc_rssi_volt * 1000.0f))
 ├──> perf_print_counter(_cycle_perf)
 ├──> perf_print_counter(_publish_interval_perf)
 ├──> <hrt_elapsed_time(&_rc_in.timestamp) < 1_s>
 │   └──> print_message(ORB_ID(input_rc), _rc_in)
 └──> return 0

3. RCInput模块重要函数

3.1 task_spawn

RCInput::task_spawn
 ├──> [解析RC通信设备,默认:RC_SERIAL_PORT] // KakuteF7 --> "/dev/ttyS4"
 ├──> <!device_name && (access(device_name, R_OK | W_OK) == 0)>
 │   └──> return PX4_ERROR // device error
 ├──> RCInput *instance = new RCInput(device_name)
 ├──> <instance == nullptr>
 │   ├──> PX4_ERR("alloc failed")
 │   └──> return PX4_ERROR
 ├──> _object.store(instance)
 ├──> _task_id = task_id_is_work_queue
 ├──> instance->ScheduleOnInterval(_current_update_interval)  //250Hz
 └──> return PX4_OK

3.2 instantiate

注:鉴于该模块不采用任务(线程),所以ModuleBase::run_trampoline无需执行,所以可以不实现。

3.3 init

注:鉴于涉及底层实现,从模块业务角度不再展开,后续有时间我们在深入讨论。

3.4 Run

RCInput::Run
 ├──> [优雅退出处理]
 ├──> [RC设备通信初始化]
 ├──> <_parameter_update_sub.updated()>
 │   ├──> parameter_update_s param_update;
 │   ├──> _parameter_update_sub.copy(&param_update);
 │   └──> updateParams();
 ├──> <_vehicle_status_sub.updated()><_vehicle_status_sub.copy(&vehicle_status)>
 │   └──> _armed = (vehicle_status.arming_state == vehicle_status_s::ARMING_STATE_ARMED)
 ├──> <_vehicle_cmd_sub.update(&vcmd)><vcmd.command == vehicle_command_s::VEHICLE_CMD_START_RX_PAIR>
 │   ├──> uint8_t cmd_ret = vehicle_command_s::VEHICLE_CMD_RESULT_UNSUPPORTED
 │   ├──> <SPEKTRUM_POWER>
 │   │   └──> [DSM bind RxTx]
 │   ├──> vehicle_command_ack_s command_ack{};
 │   ├──> command_ack.command = vcmd.command;
 │   ├──> command_ack.result = cmd_ret;
 │   ├──> command_ack.target_system = vcmd.source_system;
 │   ├──> command_ack.target_component = vcmd.source_component;
 │   ├──> command_ack.timestamp = hrt_absolute_time();
 │   ├──> uORB::Publication<vehicle_command_ack_s> vehicle_command_ack_pub{ORB_ID(vehicle_command_ack)};
 │   └──> vehicle_command_ack_pub.publish(command_ack);
 ├──> <ADC_RC_RSSI_CHANNEL>
 │   └──> [ADC RSSI 信号强度及状态更新]
 ├──> [500ms进行RC协议扫描,支持SBUS/DSM/ST24/SUMD/PPM/CRSF/GHST]
 ├──> [发布ORB_ID(input_rc)消息]
 └──> [超过3秒成功锁定协议,设置RC_INPUT_PROTO]

4. 总结

后续针对RC通信方面可以继续深入单总线串行口底层实现以及各协议格式的深入研究,入口如下:

  1. PPM解析函数 --> hrt_ppm_decode
  2. SBUS解析函数 --> sbus_parse
  3. DSM解析函数 --> dsm_parse
  4. SUMD解析函数 --> sumd_decode
  5. ST24解析函数 --> st24_decode
  6. CRSF解析函数 --> crsf_parse
  7. GHST解析函数 --> ghst_parse
  8. 单总线串口底层初始化 --> RCInput::init

5. 参考资料

【1】PX4开源软件框架简明简介
【2】PX4模块设计之十一:Built-In框架
【3】PX4模块设计之十二:High Resolution Timer设计
【4】PX4模块设计之十三:WorkQueue设计
【5】PX4模块设计之十七:ModuleBase模块
【6】PX4 modules_main
【7】RC Protocols Explained: SBUS, CRSF, PWM, FPort and More

相关文章:

  • windows10安装蓝牙驱动方法步骤
  • SQL语句如何避免在mysql插入重复数据
  • JsonSchema 转换为 Typescript
  • 【区块链 | OpenZeppelin】手把手交易使用OpenZeppelin Upgrades部署可升级智能合约
  • 同一公司开发的多个软件,可以用同一张代码签名证书吗?
  • 深度分析:用户最喜欢用哪种NFT做头像
  • php 小数计算 结果变无限小数解决方案
  • WebRTC研究:丢包与抖动
  • freeswitch的3XX重定向
  • jsp+sql毕业生招聘系统免费系统+论文
  • Java毕业设计-火车订票管理系统
  • SwiftUI 界面状态 成员变量 @State @Buiding immutable
  • Java 进阶集合和数据结构
  • RabbitMQ、RocketMQ、Kafka常见消息队列不得不知道的事
  • 简单工厂模式、工厂模式、抽象工厂模式(含C++代码)
  • 【技术性】Search知识
  • 【剑指offer】让抽象问题具体化
  • Android交互
  • Git初体验
  • js对象的深浅拷贝
  • js继承的实现方法
  • leetcode386. Lexicographical Numbers
  • select2 取值 遍历 设置默认值
  • Web设计流程优化:网页效果图设计新思路
  • WordPress 获取当前文章下的所有附件/获取指定ID文章的附件(图片、文件、视频)...
  • 多线程事务回滚
  • 基于MaxCompute打造轻盈的人人车移动端数据平台
  • 利用阿里云 OSS 搭建私有 Docker 仓库
  • 用quicker-worker.js轻松跑一个大数据遍历
  • 怎么把视频里的音乐提取出来
  • 字符串匹配基础上
  • zabbix3.2监控linux磁盘IO
  • 翻译 | The Principles of OOD 面向对象设计原则
  • ​七周四次课(5月9日)iptables filter表案例、iptables nat表应用
  • #android不同版本废弃api,新api。
  • #window11设置系统变量#
  • (1)SpringCloud 整合Python
  • (4)通过调用hadoop的java api实现本地文件上传到hadoop文件系统上
  • (Ruby)Ubuntu12.04安装Rails环境
  • (分享)一个图片添加水印的小demo的页面,可自定义样式
  • (附源码)计算机毕业设计SSM基于健身房管理系统
  • (精确度,召回率,真阳性,假阳性)ACC、敏感性、特异性等 ROC指标
  • (免费分享)基于springboot,vue疗养中心管理系统
  • (十三)Maven插件解析运行机制
  • (算法)Game
  • (一)utf8mb4_general_ci 和 utf8mb4_unicode_ci 适用排序和比较规则场景
  • (转)AS3正则:元子符,元序列,标志,数量表达符
  • ***检测工具之RKHunter AIDE
  • .NET DevOps 接入指南 | 1. GitLab 安装
  • .NET 中 GetHashCode 的哈希值有多大概率会相同(哈希碰撞)
  • .NET/C# 避免调试器不小心提前计算本应延迟计算的值
  • .NET:自动将请求参数绑定到ASPX、ASHX和MVC(菜鸟必看)
  • .NET面试题(二)
  • .NET轻量级ORM组件Dapper葵花宝典
  • @ConditionalOnProperty注解使用说明