PX4模块设计之三十四:ControlAllocator模块

2023-05-16

PX4模块设计之三十四:ControlAllocator模块

  • 1. ControlAllocator模块简介
  • 2. 模块入口函数
    • 2.1 主入口control_allocator_main
    • 2.2 自定义子命令custom_command
  • 3. ControlAllocator模块重要函数
    • 3.1 task_spawn
    • 3.2 instantiate
    • 3.3 init
    • 3.4 Run
  • 4. 总结
  • 5. 参考资料

1. ControlAllocator模块简介

### Description
This implements control allocation. It takes torque and thrust setpoints
as inputs and outputs actuator setpoint messages.

controller <command> [arguments...]
 Commands:
   start

   stop

   status        print status info

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

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

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

2. 模块入口函数

2.1 主入口control_allocator_main

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

control_allocator_main
 └──> return ControlAllocator::main(argc, argv)

2.2 自定义子命令custom_command

模块仅支持start/stop/status命令,不支持其他自定义命令。

ControlAllocator::custom_command
 └──> return print_usage("unknown command");

3. ControlAllocator模块重要函数

3.1 task_spawn

这里主要初始化了RCUpdate对象,后续通过WorkQueue来完成进行轮询。

ControlAllocator::task_spawn
 ├──> ControlAllocator *instance = new ControlAllocator();
 ├──> <instance>
 │   ├──> _object.store(instance);
 │   ├──> _task_id = task_id_is_work_queue;
 │   └──> <instance->init()>
 │       └──>return PX4_OK;
 ├──> <else>
 │   └──> PX4_ERR("alloc failed");
 ├──> delete instance;
 ├──> _object.store(nullptr);
 ├──> _task_id = -1;
 └──> return PX4_ERROR;

3.2 instantiate

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

3.3 init

在task_spawn中使用,对_input_rc_sub成员变量进行事件回调注册(当有input_rc消息时,会调用SubscriptionCallbackWorkItem::ScheduleNow,再触发RCUpdate::Run过程)。

ControlAllocator::init
 ├──> <!_vehicle_torque_setpoint_sub.registerCallback()>
 │   ├──> PX4_ERR("callback registration failed");
 │   └──> return false;
 ├──> <!_vehicle_thrust_setpoint_sub.registerCallback()>
 │   ├──> PX4_ERR("callback registration failed");
 │   └──> return false;
 ├──> <ENABLE_LOCKSTEP_SCHEDULER> // Backup schedule would interfere with lockstep
 │   └──> ScheduleDelayed(50_ms);
 └──> return true;

3.4 Run

根据设定,计算扭矩和推力值。

ControlAllocator::Run
 ├──> [优雅退出处理]
 ├──> <ENABLE_LOCKSTEP_SCHEDULER> // Backup schedule would interfere with lockstep
 │   └──> ScheduleDelayed(50_ms)
 ├──> <_parameter_update_sub.updated() && !_armed>
 │   ├──> _parameter_update_sub.copy(&param_update)
 │   └──> <_handled_motor_failure_bitmask == 0> // We don't update the geometry after an actuator failure, as it could lead to unexpected results (e.g. a user could add/remove motors, such that the bitmask isn't correct anymore)
 │       ├──> updateParams()
 │       └──> parameters_updated()
 ├──> <_num_control_allocation == 0 || _actuator_effectiveness == nullptr>
 │   └──> return
 ├──> <_vehicle_status_sub.update(&vehicle_status)>
 │   ├──> _armed = vehicle_status.arming_state == vehicle_status_s::ARMING_STATE_ARMED
 │   ├──> ActuatorEffectiveness::FlightPhase flight_phase{ActuatorEffectiveness::FlightPhase::HOVER_FLIGHT}
 │   ├──> <vehicle_status.vehicle_type == vehicle_status_s::VEHICLE_TYPE_ROTARY_WING> // Check if the current flight phase is HOVER or FIXED_WING
 │   │   └──> flight_phase = ActuatorEffectiveness::FlightPhase::HOVER_FLIGHT
 │   ├──> <else>
 │   │   └──> flight_phase = ActuatorEffectiveness::FlightPhase::FORWARD_FLIGHT
 │   ├──> <vehicle_status.is_vtol && vehicle_status.in_transition_mode> // Special cases for VTOL in transition
 │   │   ├──> <vehicle_status.in_transition_to_fw) {
 │   │   │   └──> flight_phase = ActuatorEffectiveness::FlightPhase::TRANSITION_HF_TO_FF
 │   │   └──> <else>
 │   │       └──> flight_phase = ActuatorEffectiveness::FlightPhase::TRANSITION_FF_TO_HF
 │   └──> _actuator_effectiveness->setFlightPhase(flight_phase)// Forward to effectiveness source
 ├──> const float dt = math::constrain(((now - _last_run) / 1e6f), 0.0002f, 0.02f)  // Guard against too small (< 0.2ms) and too large (> 20ms) dt's.
 ├──> <_vehicle_torque_setpoint_sub.update(&vehicle_torque_setpoint)>  // Run allocator on torque changes
 │   ├──> _torque_sp = matrix::Vector3f(vehicle_torque_setpoint.xyz)
 │   ├──> do_update = true
 │   └──> _timestamp_sample = vehicle_torque_setpoint.timestamp_sample
 ├──> <_vehicle_thrust_setpoint_sub.update(&vehicle_thrust_setpoint)> // Run allocator on thrust setpoint changes if the torque setpoint
 │   ├──> _thrust_sp = matrix::Vector3f(vehicle_thrust_setpoint.xyz)
 │   └──> <dt > 5_ms>  // has not been updated for more than 5ms
 │       ├──> do_update = true
 │       └──> _timestamp_sample = vehicle_thrust_setpoint.timestamp_sample
 ├──> <do_update>
 │   ├──> _last_run = now
 │   ├──> check_for_motor_failures()
 │   ├──> update_effectiveness_matrix_if_needed(EffectivenessUpdateReason::NO_EXTERNAL_UPDATE)   //发布actuator_servos_trim消息
 │   ├──> [Set control setpoint vector(s) ]
 │   │		matrix::Vector<float, NUM_AXES> c[ActuatorEffectiveness::MAX_NUM_MATRICES]
 │   │		c[0](0) = _torque_sp(0)
 │   │		c[0](1) = _torque_sp(1)
 │   │		c[0](2) = _torque_sp(2)
 │   │		c[0](3) = _thrust_sp(0)
 │   │		c[0](4) = _thrust_sp(1)
 │   │		c[0](5) = _thrust_sp(2)
 │   ├──> <_num_control_allocation > 1>
 │   │   ├──> _vehicle_torque_setpoint1_sub.copy(&vehicle_torque_setpoint)
 │   │   ├──> _vehicle_thrust_setpoint1_sub.copy(&vehicle_thrust_setpoint)
 │   │   ├──> c[1](0) = vehicle_torque_setpoint.xyz[0]
 │   │   ├──> c[1](1) = vehicle_torque_setpoint.xyz[1]
 │   │   ├──> c[1](2) = vehicle_torque_setpoint.xyz[2]
 │   │   ├──> c[1](3) = vehicle_thrust_setpoint.xyz[0]
 │   │   ├──> c[1](4) = vehicle_thrust_setpoint.xyz[1]
 │   │   └──> c[1](5) = vehicle_thrust_setpoint.xyz[2]
 │   └──> <for (int i = 0 i < _num_control_allocation ++i)>
 │       ├──> _control_allocation[i]->setControlSetpoint(c[i])
 │       ├──> _control_allocation[i]->allocate()// Do allocation
 │       ├──> _actuator_effectiveness->updateSetpoint(c[i], i, _control_allocation[i]->_actuator_sp)
 │       ├──> <_has_slew_rate>
 │       │   └──> _control_allocation[i]->applySlewRateLimit(dt)
 │       └──> _control_allocation[i]->clipActuatorSetpoint()
 ├──> publish_actuator_controls()  // Publish actuator setpoint and allocator status(actuator_motors/actuator_servos)
 └──> <now - _last_status_pub >= 5_ms>
     ├──> publish_control_allocator_status()     // 发布control_allocator_status消息
     └──> _last_status_pub = now

4. 总结

具体逻辑业务后续再做深入,从模块代码角度:

  • 输入
uORB::SubscriptionCallbackWorkItem _vehicle_torque_setpoint_sub{this, ORB_ID(vehicle_torque_setpoint)};  /**< vehicle torque setpoint subscription */
uORB::SubscriptionCallbackWorkItem _vehicle_thrust_setpoint_sub{this, ORB_ID(vehicle_thrust_setpoint)};	 /**< vehicle thrust setpoint subscription */

uORB::Subscription _vehicle_torque_setpoint1_sub{ORB_ID(vehicle_torque_setpoint), 1};  /**< vehicle torque setpoint subscription (2. instance) */
uORB::Subscription _vehicle_thrust_setpoint1_sub{ORB_ID(vehicle_thrust_setpoint), 1};	 /**< vehicle thrust setpoint subscription (2. instance) */

uORB::SubscriptionInterval _parameter_update_sub{ORB_ID(parameter_update), 1_s};

uORB::Subscription _vehicle_status_sub{ORB_ID(vehicle_status)};
uORB::Subscription _failure_detector_status_sub{ORB_ID(failure_detector_status)};
  • 输出
uORB::Publication<control_allocator_status_s>	_control_allocator_status_pub{ORB_ID(control_allocator_status)};	/**< actuator setpoint publication */

uORB::Publication<actuator_motors_s>	_actuator_motors_pub{ORB_ID(actuator_motors)};
uORB::Publication<actuator_servos_s>	_actuator_servos_pub{ORB_ID(actuator_servos)};
uORB::Publication<actuator_servos_trim_s>	_actuator_servos_trim_pub{ORB_ID(actuator_servos_trim)};

5. 参考资料

【1】PX4开源软件框架简明简介
【2】PX4模块设计之十一:Built-In框架
【3】PX4模块设计之十二:High Resolution Timer设计
【4】PX4模块设计之十三:WorkQueue设计
【5】PX4模块设计之十七:ModuleBase模块
【6】PX4模块设计之三十:Hysteresis类
【7】PX4 modules_main

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PX4模块设计之三十四:ControlAllocator模块 的相关文章

  • PX4+QGC+jmavsim软件在环仿真

    一 环境修改 参考官方手册jMAVSim 仿真模拟 PX4 Developer Guide xff0c 以上环境基于上一篇内容 xff0c 未完成ROS 43 jmavsim 43 QGC环境搭建的请移步Ubuntu18 04下px4 43
  • PX4二次开发中查无资料的踩坑总结

    写在前 xff1a 2021年9月下旬开始摸索px4飞控的二次开发 xff0c 从C 43 43 零基础到第一个修改算法后的版本稳定运行 xff0c 大概用了2个月 xff0c 从12月初改用新版本px4源码到现在又过去了约1个月 xff0
  • PX4使用I2C方式添加自定义传感器(1)

    PX4使用I2C方式添加自定义传感器 xff08 1 xff09 前言 毕业设计就是要在PX4上添加一个传感器 xff08 角度传感器 xff09 xff0c 由于板子上的接口数量很少 xff0c 很是宝贵 最后只能选择通过I2C通信方式
  • px4自定义mavlink收不到消息的问题

    px4版本1 12稳定版 最近在做px4二次开发相关工作 按照网上的一些教程自定义了一个mavlink消息用来控制无人机 按照教程里面的单独开了一个xml来定义消息 最后生成的消息在px4端通过流传输的方式自己写的客户端可以收到消息 但是客
  • 【2020-8-9】APM,PX4,GAZEBO,MAVLINK,MAVROS,ROS之间的关系以及科研设备选型

    0 概述 无人机自主飞行平台可以分为四个部分 xff1a 动力平台 xff0c 飞行控制器 xff0c 机载电脑和模拟平台 动力平台 xff1a 负责执行飞行任务 xff0c 包括螺旋桨 电机 机架等 xff0c 用于科研的一般都是F380
  • PX4/Pixhawk---uORB深入理解和应用

    The Instructions of uORB PX4 Pixhawk 软件体系结构 uORB 主题发布 主题订阅 1 简介 1 1 PX4 Pixhawk的软件体系结构 PX4 Pixhawk的软件体系结构主要被分为四个层次 xff0c
  • 关于PX4中的高度若干问题

    飞行的高度是如何测量的 xff1f 地面的高度和海平面的高度差别很大 xff0c 飞控又是如何有效判别进行降落的 xff1f 这是我脑子里的疑问 搜索的一圈发现很少有人讨论这方面的问题 xff0c 于是本次我就直接看一下源代码 xff0c
  • PX4 Bootloader下载及编译过程中的问题解决

    买来的雷迅的板子都是Bootloader已经烧进去了 xff0c Fireware也已经刷进去了 如果是自制的板子 xff0c 上位机根本没法识别板子 xff0c 必须先烧写下载Bootloader后编译好的bin文件 这篇记一下自己下载及
  • Ubuntu下构建PX4软件

    本搭建过程基于http dev px4 io starting building html xff0c 希望大家互相交流学习 原文 xff1a Building PX4 Software xff08 构建PX4软件 xff09 PX4 ca
  • px4源码编译指南

    px4源码编译指南 强烈推荐大家去看官网的英文文档 xff0c 国内的博客杂七杂八 xff0c 官网的中文也很久没有更新 xff0c 这几天自己踩了很多坑 xff0c 写个教程希望能帮助到大家 xff08 本文选用平台是pixhawk1 1
  • px4 avoidance笔记

    最近在用px4官方的avoidance代码跑硬件避障 xff0c 官方介绍了只要生成符合sensor msgs PointCloud2点云信息就能使用 xff0c 因此为了应用长基线双目 xff0c 没有使用realsense的相机 xff
  • PX4 ---- Mixer

    文章目录 Mixer 混合控制 作用输入输出装载混控文件MAVROS代码解析总结示例MAINAUX Mixer 混合控制 作用 经过位置控制和姿态控制后 xff0c 控制量通过 actuator controls发布 xff0c 其中 co
  • PX4 -- EKF2

    文章目录 EKF2参数高度估计Range Finder滤波 单变量更新单变量更新对多变量的影响 EKF2 参数 EKF2 中有一类 GATE 参数 当测量值在 VAR GATE 范围内才会更新值 高度估计 四种高度控制方法 xff1a 气压
  • PX4模块设计之十三:WorkQueue设计

    PX4模块设计之十三 xff1a WorkQueue设计 1 WorkQueue启动2 WorkQueue接口2 1 基本接口2 2 辅助接口2 3 WorkQueue任务函数2 3 1 Flat Build2 3 2 Protected
  • PX4模块设计之十七:ModuleBase模块

    PX4模块设计之十七 xff1a ModuleBase模块 1 ModuleBase模块介绍2 ModuleBase类介绍3 ModuleBase类功能介绍3 1 模块入口3 2 模块启动3 3 模块停止3 4 状态查询3 5 任务回调3
  • PX4模块设计之十八:Logger模块

    PX4模块设计之十八 xff1a Logger模块 1 Logger模块简介2 模块入口函数2 1 主入口logger main2 2 自定义子命令Logger custom command2 3 日志主题uORB注册 3 重要实现函数3
  • PX4模块设计之二十三:自定义FlightTask

    PX4模块设计之二十三 xff1a 自定义FlightTask Step1 创建飞行模式文件夹Step2 创建飞行模式源代码和CMakeLists txt文件Step3 更新CMakeLists txt文件Step4 更新FlightTas
  • Px4源码框架结构图

    此篇blog的目的是对px4工程有一个整体认识 xff0c 对各个信号的流向有个了解 xff0c 以及控制算法采用的控制框架 PX4自动驾驶仪软件 可分为三大部分 xff1a 实时操作系统 中间件和飞行控制栈 1 NuttX实时操作系统 提
  • PX4软件在环仿真注意点

    注 xff1a 最新内容参考PX4 user guide 点击此处 PX4下载指定版本代码和刷固件的三种方式 点击此处 PX4sitl固件编译方法 点击此处 PX4开发指南 点击此处 PX4无人机仿真 Gazebo 点击此处 px4仿真 知
  • PX4——Range Finder 篇

    Range Finder 此处选用的是 Benewake 下的 Lidar 参数设置 General Configuration 除了官方的参数设置外 xff0c 我在 EKF2 中还找到了 EKF2 RNG AID 参数 xff0c 用来

随机推荐

  • 查理·芒格:让自己配得上想要的东西

    巴菲特说他一生遇人无数 xff0c 从来没有遇到过像查理这样的人 94岁的查理 芒格毕业于哈佛大学法学院 xff0c 是沃伦 巴菲特的黄金搭档 xff0c 伯克夏 哈撒韦公司的副主席 xff0c 芒格的头脑是原创性的 xff0c 从来不受任
  • PX4模块设计之十九:Replay模块

    PX4模块设计之十九 xff1a Replay模块 1 Replay模块简介2 模块入口函数2 1 主入口replay main2 2 自定义子命令Replay custom command 3 重要实现函数3 1 Replay task
  • TX12 + ExpressLRS 915MHz RC控制链路配置及问题汇总

    TX12 43 ExpressLRS 915MHz RC控制链路配置及问题汇总 1 硬件配置1 1 TX12遥控器1 2 发射 接受机 2 问题汇总2 1 ELRS接收机无法点亮 第一次 2 2 ELRS接收机无法点亮 第二次 2 3 触发
  • PX4模块设计之二十:PX4应用平台初始化

    PX4模块设计之二十 xff1a PX4应用平台初始化 1 PX4应用平台介绍2 PX4应用平台初始化实现3 讨论和思考4 参考资料 在PX4启动过程章节的基础上 xff0c 可以深入分析下PX4应用平台 xff08 框架 xff09 的实
  • PX4模块设计之二十一:uORB消息管理模块

    PX4模块设计之二十一 xff1a uORB消息管理模块 1 uORB模块构建模式2 uORB消息管理函数2 1 状态查询2 2 资源利用2 3 模块启动2 4 模块停止3 uORB消息接口3 1 消息主题注册3 2 消息主题去注册3 3
  • PX4模块设计之二十二:FlightModeManager模块

    PX4模块设计之二十二 xff1a FlightModeManager模块 1 FlightModeManager简介2 FlightModeManager启动3 FlightModeManager模块重要实现3 1 custom comm
  • PX4模块设计之二十三:自定义FlightTask

    PX4模块设计之二十三 xff1a 自定义FlightTask Step1 创建飞行模式文件夹Step2 创建飞行模式源代码和CMakeLists txt文件Step3 更新CMakeLists txt文件Step4 更新FlightTas
  • PX4模块设计之二十四:内部ADC模块

    PX4模块设计之二十四 xff1a 内部ADC模块 1 内部ADC模块简介2 模块入口函数2 1 主入口board adc main2 2 自定义子命令custom command 3 内部ADC模块重要函数3 1 task spawn3
  • PX4模块设计之二十五:DShot模块

    PX4模块设计之二十五 xff1a DShot模块 1 DShot模块简介2 DShot类继承关系3 模块入口函数3 1 主入口dshot main3 2 自定义子命令custom command 4 DShot模块重要函数4 1 task
  • PX4模块设计之二十六:BatteryStatus模块

    PX4模块设计之二十六 xff1a BatteryStatus模块 1 BatteryStatus模块简介2 模块入口函数2 1 主入口battery status main2 2 自定义子命令custom command 3 Batter
  • PX4模块设计之二十七:LandDetector模块

    PX4模块设计之二十七 xff1a LandDetector模块 1 LandDetector模块简介2 模块入口函数2 1 主入口land detector main2 2 自定义子命令custom command 3 LandDetec
  • CentOS-7 中安装VS Code 并启动

    VSCode安装 安装平台 xff1a CentOS7 安装方法 xff1a 1 在官网上下载64位 xff08 或者32位 xff09 的rpm包 xff08 官网地址 xff1a https code visualstudio com
  • PX4模块设计之二十八:RCInput模块

    PX4模块设计之二十八 xff1a RCInput模块 1 RCInput模块简介2 模块入口函数2 1 主入口rc input main2 2 自定义子命令custom command2 3 模块状态print status 重载 3 R
  • PX4模块设计之二十九:RCUpdate模块

    PX4模块设计之二十九 xff1a RCUpdate模块 1 RCUpdate模块简介2 模块入口函数2 1 主入口rc update main2 2 自定义子命令custom command2 3 模块状态print status 重载
  • PX4模块设计之三十:Hysteresis类

    PX4模块设计之三十 xff1a Hysteresis类 1 Hysteresis类简介2 Hysteresis类成员变量介绍3 Hysteresis类迟滞逻辑4 Hysteresis类重要方法4 1 Hysteresis bool ini
  • PX4模块设计之三十一:ManualControl模块

    PX4模块设计之三十一 xff1a ManualControl模块 1 ManualControl模块简介2 模块入口函数2 1 主入口manual control main2 2 自定义子命令custom command 3 Manual
  • PX4模块设计之三十二:AttitudeEstimatorQ模块

    PX4模块设计之三十二 xff1a AttitudeEstimatorQ模块 1 AttitudeEstimatorQ模块简介2 模块入口函数2 1 主入口attitude estimator q main2 2 自定义子命令custom
  • PX4模块设计之三十三:Sensors模块

    PX4模块设计之三十三 xff1a Sensors模块 1 Sensors模块简介2 模块入口函数2 1 主入口sensors main2 2 自定义子命令custom command2 3 模块状态print status 重载 3 Se
  • 树莓派(Raspberry Pi)miniDLNA服务搭建

    树莓派 Raspberry Pi miniDLNA服务搭建 1 MiniDLNA简介2 安装前提3 安装步骤4 服务配置5 进程配置6 参考资料7 补充资料7 1 配置外置硬盘 xff08 媒体库 xff09 7 2 配置samba符号链接
  • PX4模块设计之三十四:ControlAllocator模块

    PX4模块设计之三十四 xff1a ControlAllocator模块 1 ControlAllocator模块简介2 模块入口函数2 1 主入口control allocator main2 2 自定义子命令custom command