PX4 如何切换到offboard 模式

2023-05-16

最近研究px4的offboard模式,如何切换到offboard模式一筹莫展,便跟踪源代码至commander module。

一、 handle_command函数

  从dronekit发送设定offboard模式的mavlink信息至飞控,相关命令经mavlink模块解析得到关于vehicle_command的主题。

def PX4setMode(mavMode): vehicle._master.mav.command_long_send(vehicle._master.target_system, vehicle._master.target_component, mavutil.mavlink.MAV_CMD_DO_SET_MODE, 0, 1, mavMode, 0, 0, 0, 0, 0)


由handle_command函数中

                                } else if (custom_main_mode == PX4_CUSTOM_MAIN_MODE_OFFBOARD) {
/* OFFBOARD */
main_ret = main_state_transition(status_local, commander_state_s::MAIN_STATE_OFFBOARD, main_state_prev, &status_flags, &internal_state);
}

相关信息要跟踪至main_state_transition。

二、main_state_transition

   main_state_transition(struct vehicle_status_s *status, main_state_t new_main_state, uint8_t &main_state_prev,
     status_flags_s *status_flags, struct commander_state_s *internal_state)
{
transition_result_t ret = TRANSITION_DENIED;


/* transition may be denied even if the same state is requested because conditions may have changed */
switch (new_main_state) {

case commander_state_s::MAIN_STATE_OFFBOARD:


/* need offboard signal */
if (!status_flags->offboard_control_signal_lost) {
ret = TRANSITION_CHANGED;
}


break;


     if (ret == TRANSITION_CHANGED) {
if (internal_state->main_state != new_main_state) {
main_state_prev = internal_state->main_state;
internal_state->main_state = new_main_state;
internal_state->timestamp = hrt_absolute_time();


} else {
ret = TRANSITION_NOT_CHANGED;
}
}


return ret;

从以上可知,status_flags->offboard_control_signal_lost 是一个重要的标志位,为0才能使ret = TRANSITION_CHANGED,才能进而可以使main_state_prev = internal_state->main_state;internal_state->main_state = new_main_state。


三、继续跟踪set_nav_state函数

switch (internal_state->main_state)

case commander_state_s::MAIN_STATE_OFFBOARD:


/* require offboard control, otherwise stay where you are */
if (status_flags->offboard_control_signal_lost && !status->rc_signal_lost) {
enable_failsafe(status, old_failsafe, mavlink_log_pub, reason_no_rc);


if (status_flags->offboard_control_loss_timeout && offb_loss_rc_act < 5 && offb_loss_rc_act >= 0) {
if (offb_loss_rc_act == 3 && status_flags->condition_global_position_valid
   && status_flags->condition_home_position_valid) {
status->nav_state = vehicle_status_s::NAVIGATION_STATE_AUTO_RTL;


} else if (offb_loss_rc_act == 0 && status_flags->condition_global_position_valid) {
status->nav_state = vehicle_status_s::NAVIGATION_STATE_POSCTL;


} else if (offb_loss_rc_act == 1 && status_flags->condition_local_altitude_valid) {
status->nav_state = vehicle_status_s::NAVIGATION_STATE_ALTCTL;


} else if (offb_loss_rc_act == 2) {
status->nav_state = vehicle_status_s::NAVIGATION_STATE_MANUAL;


} else if (offb_loss_rc_act == 4 && status_flags->condition_global_position_valid) {
status->nav_state = vehicle_status_s::NAVIGATION_STATE_AUTO_LAND;


} else if (status_flags->condition_local_altitude_valid) {
status->nav_state = vehicle_status_s::NAVIGATION_STATE_DESCEND;


} else {
status->nav_state = vehicle_status_s::NAVIGATION_STATE_TERMINATION;
}


} else {
if (status_flags->condition_global_position_valid) {
status->nav_state = vehicle_status_s::NAVIGATION_STATE_POSCTL;


} else if (status_flags->condition_local_altitude_valid) {
status->nav_state = vehicle_status_s::NAVIGATION_STATE_ALTCTL;


} else {
status->nav_state = vehicle_status_s::NAVIGATION_STATE_TERMINATION;
}
}


} else if (status_flags->offboard_control_signal_lost && status->rc_signal_lost) {
enable_failsafe(status, old_failsafe, mavlink_log_pub, reason_no_rc);


if (status_flags->offboard_control_loss_timeout && offb_loss_act < 3 && offb_loss_act >= 0) {
if (offb_loss_act == 2 && status_flags->condition_global_position_valid
   && status_flags->condition_home_position_valid) {
status->nav_state = vehicle_status_s::NAVIGATION_STATE_AUTO_RTL;


} else if (offb_loss_act == 1 && status_flags->condition_global_position_valid) {
status->nav_state = vehicle_status_s::NAVIGATION_STATE_AUTO_LOITER;


} else if (offb_loss_act == 0 && status_flags->condition_global_position_valid) {
status->nav_state = vehicle_status_s::NAVIGATION_STATE_AUTO_LAND;


} else if (status_flags->condition_local_altitude_valid) {
status->nav_state = vehicle_status_s::NAVIGATION_STATE_DESCEND;


} else {
status->nav_state = vehicle_status_s::NAVIGATION_STATE_TERMINATION;
}


} else {
if (status_flags->condition_global_position_valid) {
status->nav_state = vehicle_status_s::NAVIGATION_STATE_AUTO_LOITER;


} else if (status_flags->condition_local_altitude_valid) {
status->nav_state = vehicle_status_s::NAVIGATION_STATE_DESCEND;


} else {
status->nav_state = vehicle_status_s::NAVIGATION_STATE_TERMINATION;
}
}


} else {
status->nav_state = vehicle_status_s::NAVIGATION_STATE_OFFBOARD;
}


default:
break;
}


return status->nav_state != nav_state_old;
}


要根据不同的status_flags切换到不同的控制模式。最重要的是使status_flags->offboard_control_signal_lost 为0.

 

四、跟踪status_flags->offboard_control_signal_lost

orb_check(offboard_control_mode_sub, &updated);


if (updated) {
orb_copy(ORB_ID(offboard_control_mode), offboard_control_mode_sub, &offboard_control_mode);
}


if (offboard_control_mode.timestamp != 0 &&
   offboard_control_mode.timestamp + OFFBOARD_TIMEOUT > hrt_absolute_time()) {
if (status_flags.offboard_control_signal_lost) {
status_flags.offboard_control_signal_lost = false;
status_flags.offboard_control_loss_timeout = false;
status_changed = true;
}


} else {
if (!status_flags.offboard_control_signal_lost) {
status_flags.offboard_control_signal_lost = true;
status_changed = true;
}


/* check timer if offboard was there but now lost */
if (!status_flags.offboard_control_loss_timeout && offboard_control_mode.timestamp != 0) {
if (offboard_loss_timeout < FLT_EPSILON) {
/* execute loss action immediately */
status_flags.offboard_control_loss_timeout = true;


} else {
/* wait for timeout if set */
status_flags.offboard_control_loss_timeout = offboard_control_mode.timestamp +
OFFBOARD_TIMEOUT + offboard_loss_timeout * 1e6f < hrt_absolute_time();
}


if (status_flags.offboard_control_loss_timeout) {
status_changed = true;
}
}
}


可发现status_flags.offboard_control_signal_lost与 offboard_control_mode.timestamp 及OFFBOARD_TIMEOUT相关.OFFBOARD_TIMEOUT为固定值,0.5s。继续跟踪offboard_control_mode.timestamp至mavlink_receiver.cpp中。

在MavlinkReceiver::handle_message_set_position_target_local_ned(mavlink_message_t *msg)中可发现

offboard_control_mode.timestamp = hrt_absolute_time();

从这些信息可以发现如果要切换到offboard 模式,msgid为SET_POSITION_TARGET_LOCAL_NED的mavlink信息发送频率要大于2HZ,即至少0.5s要发送一次。



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

PX4 如何切换到offboard 模式 的相关文章

  • C++11向线程函数传递参数

    template span class token operator lt span class Function span class token punctuation span class span class token punct
  • C++11之std::future对象使用说明

    std future介绍 在前面几篇文章中基本都用到thread对象 xff0c 它是C 43 43 11中提供异步创建多线程的工具 但是我们想要从线程中返回异步任务结果 xff0c 一般需要依靠全局变量 xff1b 从安全角度看 xff0
  • delete 和 delete[]真正区别

    我们通常从教科书上看到这样的说明 xff1a delete 释放new分配的单个对象指针指向的内存 delete 释放new分配的对象数组指针指向的内存 那么 xff0c 按照教科书的理解 xff0c 我们看下下面的代码 xff1a spa
  • 【转】使用Android MediaCodec 硬解码延时问题分析

    最近做项目用到Android native层的MediaCodec的接口对H264进行解码 xff0c 通过在解码前和解码后加打印日志 xff0c 发现解码耗时200多ms xff0c 和IOS的解码耗时10ms相比实在是延时好大 后来研究
  • 数据异常检测

    数据下载 xff1a 链接 xff1a https pan baidu com s 1ePMpmTBeoECBFFgPZQrPAg 提取码 xff1a qkg2 两维数据异常检测 xff08 使用高斯原始模型 xff09 代码 span c
  • 数据通信保镖---链路聚合

    目录 前言 一 链路聚合技术产生背景 二 链路聚合基本原理 三 链路聚合手工模式 四 LACPDU 五 活动接口及链路选举步骤 六 负载分担 七 负载分担模式 八 配置命令 1 创建链路聚合组 前言 随着社会迅速的发展 xff0c 网络业务
  • BGP基础讲解

    文章目录 一 BGP起源二 BGG基本概念与注意事项三 BGP原理概述四 BGP路由条目的来源 宣告 引入 聚合五 通告原则 重要 xff01 xff01 xff01 六 相关配置命令 一 BGP起源 网络不断扩大 xff0c 为了方便管理
  • LNK1107 文件无效或损坏: 无法在 0xBE2 处读取

    LNK1107 文件无效或损坏 无法在 0xBE2 处读取 LNK1107 文件无效或损坏 无法在 0xBE2 处读取 4 15test D ITK res lib libhdf5 settings 1 的问题解决 解决 解决办法 xff1
  • Linux开机卡在/dev/sda1:clean,***files,***blocks解决方案

    Linux开机卡在 dev sda1 xff1a clean xff0c files blocks解决方案
  • 未能初始化 成员 “itk::ImageIOBase::UNKNOWNPIXELTYPE“

    如题 xff0c 在联合VTK ITK Qt编译的时候遇到了 xff0c 原因 xff1a 没有在CMakeLists txt中加ITK相关代码 xff0c 因为是直接拿别人的工程来用 xff0c 改正 xff1a 添加ITK相关代码 xf
  • 2021-09-17

    https d2lzkl7pfhq30w cloudfront net pub archive epel 6 x86 64 以上是epel的新地址
  • 蓝桥杯2021 砝码称重 动态规划(JAVA)

    题目 你有一架天平和N个砝码 xff0c 这N个砝码重量依次是W1 xff0c W2 xff0c WN 请你计算一共可以称出多少种不同的重量 xff1f 注意砝码可以放在天平两边 输入格式 输入的第一行包含一个整数N 第二行包含N个整数 x
  • SpringBoot连接数据库报空指针异常

    加了 64 SpringBootTest和 64 Test还是报空指针异常 原因 64 Test导入的包不对 原来是 span class token keyword import span span class token namespa
  • 解决80端口被占用问题

    解决80端口被占用问题 1 win 43 r xff0c 输入cmd xff0c 回车 2 命令行输入 netstat ano 3 前几行本地地址为0 0 0 0 80 xff0c 每一行的最后对应一个pid号 xff0c 如下图中的215
  • go 学习中遇到的问题及解决

    Go学习中遇到的若干问题及解决 1 go test进行单元测试时 xff0c 出现undefined方法或者command line arguments build failed 解决方案问题解决参考 2 go操作Mysql2 1 将表名作
  • IDEA中将pom.xml中的依赖一起打jar包的问题

    IDEA中将依赖一起打进jar包 试过了其它和很多方法 xff0c 很多都没用 试了下面的内容 xff0c 就成功了 1 在pom xml文件中加入如下内容 xff1a span class token tag span class tok
  • go字符串

    go中的字符串 1 字面量 操作符 级联 1 1 字面量 字符串字面量使用双引号 xff08 xff09 或反引号 xff08 96 96 xff09 创建 如 text1 span class token operator 61 span
  • go中return返回的相关问题

    return go语言中return语句可以带返回值 xff0c 也支持不带返回值 下面是不带返回值的一些问题 1 前言 下面这段话来自 Go语言程序设计 p146 可以在有一到多个命名返回值的函数中 xff0c 写无需声明返回值的retu
  • Go中整型类型及其范围

    类型取值范围int依赖平台 xff0c 可能是int32或int64int8 128 127uint80 255int16 32 768 32 767uint160 65 535int32 2 147 483 648 2 147 483 6
  • 博士怎么读文献?

    https www zhihu com question 37781628知乎上的问答 无论是国内外的博士在写论文的时候都需要阅读大量的文献 xff0c 而这些文献一般都多而杂 xff0c 如果没有一定的方法一定会觉得无从下手 那么读这些文

随机推荐