PX4代码学习系列博客(6)——offboard模式位置控制代码分析(之前转载过,这是第二次转载了)

2023-05-16

我刚刚发现这篇文章去年八月份的时候转载过一次了

https://blog.csdn.net/sinat_16643223/article/details/107874349

转载自:https://blog.csdn.net/iamqianrenzhan/article/details/78066369

PX4代码学习系列博客(6)——offboard模式位置控制代码分析

仟人斩 2017-09-22 19:49:03 2961 收藏 17

分类专栏: px4 文章标签: pixhawk PX4 offboard 位置控制

最后发布:2017-09-22 19:49:03首次发布:2017-09-22 19:49:03

版权声明:本文为博主原创文章,遵循<a href="http://creativecommons.org/licenses/by-sa/4.0/" target="_blank" rel="noopener"> CC 4.0 BY-SA </a>版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/iamqianrenzhan/article/details/78066369

版权

分析offboard模式的代码需要用到以下几个模块

local_position_estimator
mavlink
mc_pos_control
mc_att_control
mixer

程序数据走向

mavlink

一般的offboard模式需要给飞控发送两条mavlink消息:

//飞控在接收到mavlink设置点消息的时候执行下面函数
void MavlinkReceiver::handle_message_set_position_target_local_ned(mavlink_message_t *msg)
{
    //这个函数把消息解析后发布了两个消息:
    //offboard_control_mode和position_setpoint_triplet
}
//飞控在接收到mavlink当前点消息用来进行外部位置估计的时候执行下面函数
void MavlinkReceiver::handle_message_att_pos_mocap(mavlink_message_t *msg)
{
    //这个函数把消息解析后发布消息:
    //att_pos_mocap
}

首先分析handle_message_set_position_target_local_ned这个函数发出的两条消息各是什么内容
发出的offboard_control_mode_s结构体:

offboard_control_mode.timestamp = hrt_absolute_time();
offboard_control_mode.ignore_position = (bool)(set_position_target_local_ned.type_mask & 0x7);
offboard_control_mode.ignore_alt_hold = (bool)(set_position_target_local_ned.type_mask & 0x4);
offboard_control_mode.ignore_velocity = (bool)(set_position_target_local_ned.type_mask & 0x38);
offboard_control_mode.ignore_acceleration_force = (bool)(set_position_target_local_ned.type_mask & 0x1C0);
bool is_force_sp = (bool)(set_position_target_local_ned.type_mask & (1 << 9));
offboard_control_mode.ignore_attitude = (bool)(set_position_target_local_ned.type_mask & 0x400);
offboard_control_mode.ignore_bodyrate = (bool)(set_position_target_local_ned.type_mask & 0x800);

读取的vehicle_control_mode_s结构体判断当前是否是offboard模式,如果是则发送position_setpoint_triplet消息
发出的position_setpoint_triplet_s结构体:

pos_sp_triplet.current.type
pos_sp_triplet.timestamp = hrt_absolute_time();
pos_sp_triplet.previous.valid = false;
pos_sp_triplet.next.valid = false;
pos_sp_triplet.current.valid = true;
pos_sp_triplet.current.position_valid = true;
pos_sp_triplet.current.x = set_position_target_local_ned.x;
pos_sp_triplet.current.y = set_position_target_local_ned.y;
pos_sp_triplet.current.z = set_position_target_local_ned.z;
pos_sp_triplet.current.velocity_valid = true;
pos_sp_triplet.current.vx = set_position_target_local_ned.vx;
pos_sp_triplet.current.vy = set_position_target_local_ned.vy;
pos_sp_triplet.current.vz = set_position_target_local_ned.vz;
pos_sp_triplet.current.acceleration_valid = true;
pos_sp_triplet.current.a_x = set_position_target_local_ned.afx;
pos_sp_triplet.current.a_y = set_position_target_local_ned.afy;
pos_sp_triplet.current.a_z = set_position_target_local_ned.afz;
pos_sp_triplet.current.acceleration_is_force = is_force_sp;
pos_sp_triplet.current.yaw_valid = true;
pos_sp_triplet.current.yaw = set_position_target_local_ned.yaw;
pos_sp_triplet.current.yawspeed_valid = true;
pos_sp_triplet.current.yawspeed = set_position_target_local_ned.yaw_rate;

local_position_estimator

在Firmware\src\modules\local_position_estimator\sensors下的mocap.cpp中有这么一行

static const uint32_t       MOCAP_TIMEOUT =     200000; // 0.2 s

这代表att_pos_mocap消息的发送频率必须大于5Hz,不然就会timeout,但是在实际测试过程中,发送的频率在30Hz以上才能稳定不timeout,这是因为它的程序写的太苛刻,只要每两帧有效数据的时间戳间隔大于0.2s就会timeout。

在Firmware\src\modules\local_position_estimator下的BlockLocalPositionEstimator.cpp中有这么一段

if (mocapUpdated) {
    if (_sensorTimeout & SENSOR_MOCAP) 
    {
        mocapInit();
    {
        mocapCorrect();
    }
}

只要超时就会重新初始化。

如果外部估计的位置足够精确,可以选择不用飞控上的其他传感器,可以在参数LPE_FUSION中设置。

mc_pos_control

然后转到旋翼的位置控制模块:
在目录E:\github\Firmware\src\modules\mc_pos_control下的mc_pos_control_main.cpp文件
打开task_main函数,发现

_pos_sp_triplet_sub = orb_subscribe(ORB_ID(position_setpoint_triplet));
_control_mode_sub = orb_subscribe(ORB_ID(vehicle_control_mode));

它订阅了position_setpoint_triplet和vehicle_control_mode这两个消息。
然后是

update_velocity_derivative();
//这个函数用来更新速度偏差,如果目标位置丢失,则速度偏差为0。
do_control(dt);
//这里面的一些分支判断用的是vehicle_control_mode_s这个结构体。

do_control调用了

control_non_manual(dt);

control_non_manual调用了

control_offboard(dt);
control_position();

control_offboard用来判断是位置控制还是姿态控制并把控制量获取并发布。
我这里用的是位置和偏航角控制,所以在这个函数中执行的内容有

_pos_sp(0) = _pos_sp_triplet.current.x;
_pos_sp(1) = _pos_sp_triplet.current.y;
_run_pos_control = true;
_hold_offboard_xy = false;
_att_sp.yaw_body = _pos_sp_triplet.current.yaw;

最后发布vehicle_local_position_setpoint这个消息

_local_pos_sp.timestamp = hrt_absolute_time();
_local_pos_sp.x = _pos_sp(0);
_local_pos_sp.y = _pos_sp(1);
_local_pos_sp.z = _pos_sp(2);
_local_pos_sp.yaw = _att_sp.yaw_body;
_local_pos_sp.vx = _vel_sp(0);
_local_pos_sp.vy = _vel_sp(1);
_local_pos_sp.vz = _vel_sp(2);
orb_advertise(ORB_ID(vehicle_local_position_setpoint), &_local_pos_sp);

control_position调用calculate_velocity_setpoint函数和calculate_thrust_setpoint函数,calculate_velocity_setpoint根据位置偏差计算速度偏差,里面代码不长,直接贴出

void MulticopterPositionControl::control_position(float dt)
{
    calculate_velocity_setpoint(dt);

    if (_control_mode.flag_control_climb_rate_enabled || _control_mode.flag_control_velocity_enabled ||
        _control_mode.flag_control_acceleration_enabled) 
    {
        calculate_thrust_setpoint(dt);

    } else {
        _reset_int_z = true;
    }
}

在计算速度设置点函数calculate_velocity_setpoint中:

/* run position & altitude controllers, if enabled (otherwise use already computed velocity setpoints) */
if (_run_pos_control) 
{

    // If for any reason, we get a NaN position setpoint, we better just stay where we are.
    if (PX4_ISFINITE(_pos_sp(0)) && PX4_ISFINITE(_pos_sp(1))) 
    {
        _vel_sp(0) = (_pos_sp(0) - _pos(0)) * _params.pos_p(0);
        _vel_sp(1) = (_pos_sp(1) - _pos(1)) * _params.pos_p(1);

    } else 
    {
        _vel_sp(0) = 0.0f;
        _vel_sp(1) = 0.0f;
        warn_rate_limited("Caught invalid pos_sp in x and y");

    }
}

limit_altitude();

if (_run_alt_control) 
{
    if (PX4_ISFINITE(_pos_sp(2))) 
    {
        _vel_sp(2) = (_pos_sp(2) - _pos(2)) * _params.pos_p(2);

    } else 
    {
        _vel_sp(2) = 0.0f;
        warn_rate_limited("Caught invalid pos_sp in z");
    }
}
//后面是对起飞速度的设置和各个方向速度的一个限制。

calculate_thrust_setpoint函数根据速度设置点计算姿态设置点然后发布姿态设置点vehicle_attitude_setpoint。

mc_att_control

再转到姿态控制模块
它订阅了vehicle_control_mode和vehicle_attitude_setpoint这两个消息。

_v_control_mode_sub = orb_subscribe(ORB_ID(vehicle_control_mode));
_v_att_sp_sub = orb_subscribe(ORB_ID(vehicle_attitude_setpoint));

姿态控制模块把姿态设置点转换为需要的角速度。
从位置设置点到最后的三个方向的设置角速度,中间代码仔细分析比较复杂,具体的数学公式整理起来是一个浩大的工程,一个大概的思路是:

这里写图片描述

这个模块把姿态设置点转化为角速率设置点,然后在mixer中控制电机。

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

PX4代码学习系列博客(6)——offboard模式位置控制代码分析(之前转载过,这是第二次转载了) 的相关文章

  • px4自定义mavlink收不到消息的问题

    px4版本1 12稳定版 最近在做px4二次开发相关工作 按照网上的一些教程自定义了一个mavlink消息用来控制无人机 按照教程里面的单独开了一个xml来定义消息 最后生成的消息在px4端通过流传输的方式自己写的客户端可以收到消息 但是客
  • 编译PX4固件

    PX4编译 文章目录 PX4编译疑难杂症bug1bug2catkin build isolated 官方脚本Step1Step2 安装常用依赖Step3 创建并运行脚本Step4 补全代码子模块Step5 验证仿真 官方offboard 例
  • Ubuntu18.04安装PX4踩坑、报错及解决方案整理

    笔者最近需要跑无人机巡检大坝的仿真 xff0c 于是在自己的Ubuntu2018 04中开始安装PX4 xff0c 问过不少之前已经装过PX4的师兄和同学 xff0c 都曾在PX4安装过程中踩过许多坑 xff0c 耗费了不少时间 xff0c
  • PX4 GAZEBO无人机添加相机并进行图像识别

    PX4 GAZEBO无人机添加摄像头并进行图像识别 在之前完成了ROS的安装和PX4的安装 xff0c 并可以通过roslaunch启动软件仿真 接下来为无人及添加相机 xff0c 并将图像用python函数读取 xff0c 用于后续操作
  • PX4无人机 - 键盘控制飞行代码

    PX4无人机 键盘控制飞行代码 仿真效果 实机效果 由于图片限制5M以内 xff0c 只能上传一小段了 xff0c 整段视频请点击链接 Pixhawk 6c 无人机 键盘控制无人机 Offboard模式 核心 xff1a 发布 mavros
  • 基于F4/F7/H7飞控硬件和px4飞控固件的廉价自主无人机系统(1)-飞控

    前言 穿越机F4 F7 H7飞控是一系列采用stm32系列F4xx和F7xx处理器的飞控的统称 xff0c 是目前穿越机爱好者非常喜欢使用的飞控硬件 xff0c 其价格也非常便宜180 xff5e 410 而px4则是一款常见的开源飞控固件
  • 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飞控之PWM输出控制

    PX4飞控之PWM输出控制 多旋翼电调如好盈XRotor xff0c DJI通用电调等都支持PWM信号来传输控制信号 常用的400Hz电调信号对应周期2500us xff0c 一般使用高电平时间1000us 2000us为有效信号区间 xf
  • Offboard Control

    1 将RC开关映射到场外模式激活 在QGroundControl中加载参数并查找RC MAP OFFB SW参数 xff0c 您可以为其分配要用于激活板外模式的RC通道2 2 启用配套计算机界面 设置默认的随播计算机消息流TELEM 2 x
  • PX4 ---- Mixer

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

    文章目录 室内飞行ROS amp PX4Pose Data 飞机配置MAVROS 基于工训赛 VIO 飞行总结 室内飞行 ROS amp PX4 Pose Data 飞机配置 VIO 参考此处 xff0c 采用 T265 配置 相机与飞控机
  • 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模块设计之三十九:Commander模块

    PX4模块设计之三十九 xff1a Commander模块 1 Commander模块简介2 模块入口函数2 1 主入口commander main2 2 自定义子命令custom command 3 Commander模块重要函数3 1
  • PX4模块设计之四十六:dataman模块

    PX4模块设计之四十六 xff1a dataman模块 1 dataman模块简介2 模块入口函数dataman main3 dataman模块重要函数3 1 start3 2 stop3 3 status3 4 task main 4 A
  • Px4源码框架结构图

    此篇blog的目的是对px4工程有一个整体认识 xff0c 对各个信号的流向有个了解 xff0c 以及控制算法采用的控制框架 PX4自动驾驶仪软件 可分为三大部分 xff1a 实时操作系统 中间件和飞行控制栈 1 NuttX实时操作系统 提
  • PX4模块设计之二十七:LandDetector模块

    PX4模块设计之二十七 xff1a LandDetector模块 1 LandDetector模块简介2 模块入口函数2 1 主入口land detector main2 2 自定义子命令custom command 3 LandDetec
  • PX4通过参数脚本给飞控导入参数

    PX4通过参数脚本给飞控导入参数 先找一架正常能飞的无人机连接地面站 在参数页面右上角点击工具 gt 保存到文件 保存的时候文件名注明参数的相关信息 然后将需要加载参数的无人机连接至地面站 xff0c 注意需要加载参数的无人机必须和保存的参
  • 无人机PX4使用动捕系统mocap的位置实现控制+MAVROS

    动捕系统Optitrack xff0c 有很高的定位精度 xff0c 能够给无人机提供比较精确的位置信息 xff0c 因此如果实验室有条件 xff0c 都可以买一套动捕系统 动捕系统的原理 xff1a 光学式动作捕捉依靠一整套精密而复杂的光
  • Offboard例程的python版本

    因为python的库很丰富 xff0c 有现成的解方程库 xff0c 比如sympy 自己写了一份python版本的自动起飞2m的程序 假设自定义的包名为offb xff0c 在offb下新建scripts文件夹 xff0c 将py文件放在

随机推荐