ArduPilot开源飞控之AP_Mount

news/2024/7/10 20:46:22 标签: 开源, Ardupilot

ArduPilot开源飞控之AP_Mount

  • 1. 源由
  • 2. 框架设计
    • 2.1 启动代码
    • 2.2 任务代码 update
    • 2.3 任务代码 update_fast
    • 2.4 任务代码 handle_message
  • 3. 重要例程
    • 3.1 init
    • 3.2 update
    • 3.3 update_fast
    • 3.4 handle_message
  • 4. 总结
  • 5. 参考资料

1. 源由

AP_Mount主要是挂的云台设备,配合相机使用。

当前云台也有各种硬件总线连接方式,并且软件协议也不尽相同,Ardupilot对这方面的支持还是不错的。

为了更好的选择云台,有必要从代码层面了解下目前支持的情况。

2. 框架设计

2.1 启动代码

传统Ardupilot启动方式。

Copter::init_ardupilot
 └──> AP_Mount::init

2.2 任务代码 update

命令状态更新。

SCHED_TASK_CLASS(AP_Mount,             &copter.camera_mount,        update,          50,  75, 108)
 └──> AP_Mount::update

2.3 任务代码 update_fast

云台姿态更新。

FAST_TASK_CLASS(AP_Mount, &copter.camera_mount, update_fast),
 └──> AP_Mount::update_fast

2.4 任务代码 handle_message

MMAVLink命令处理管道。

SCHED_TASK_CLASS(GCS,                  (GCS*)&copter._gcs,          update_receive, 400, 180, 102)
 └──> GCS::update_receive
     └──> GCS_MAVLINK::update_receive
         └──> GCS_MAVLINK_Copter::packetReceived
             └──> GCS_MAVLINK::packetReceived
                 └──> GCS_MAVLINK_Copter::handle_mount_message
                     └──> GCS_MAVLINK::handle_mount_message
                         └──> AP_Mount::handle_message

3. 重要例程

3.1 init

支持以下类型的云台:

  1. AP_Mount_Servo
  2. AP_Mount_SoloGimbal
  3. AP_Mount_Alexmos
  4. AP_Mount_SToRM32
  5. AP_Mount_SToRM32_serial
  6. AP_Mount_Gremsy
  7. AP_Mount_Siyi
  8. AP_Mount_Scripting
  9. AP_Mount_Xacti
  10. AP_Mount_Viewpro
// init - detect and initialise all mounts
void AP_Mount::init()
 │  // check init has not been called before
 ├──> <_num_instances != 0>
 │   └──> return
 │
 │  // perform any required parameter conversion
 ├──> convert_params()
 │
 │  // primary is reset to the first instantiated mount
 ├──> bool primary_set = false
 │
 │  // create mount instance
 ├──> <for (uint8_t instance=0 instance<AP_MOUNT_MAX_INSTANCES instance++)>
 │   ├──> <case Type::Servo> <HAL_MOUNT_SERVO_ENABLED>
 │   │   ├──> _backends[instance] = new AP_Mount_Servo(*this, _params[instance], true, instance)
 │   │   ├──> _num_instances++
 │   │   └──> break
 │   ├──> <case Type::SoloGimbal> <HAL_SOLO_GIMBAL_ENABLED>
 │   │   ├──> _backends[instance] = new AP_Mount_SoloGimbal(*this, _params[instance], instance)
 │   │   ├──> _num_instances++
 │   │   └──> break
 │   ├──> <case Type::Alexmos> <HAL_MOUNT_ALEXMOS_ENABLED>
 │   │   ├──> _backends[instance] = new AP_Mount_Alexmos(*this, _params[instance], instance)
 │   │   ├──> _num_instances++
 │   │   └──> break
 │   ├──> <case Type::SToRM32> <HAL_MOUNT_STORM32MAVLINK_ENABLED>  // check for SToRM32 mounts using MAVLink protocol
 │   │   ├──> _backends[instance] = new AP_Mount_SToRM32(*this, _params[instance], instance)
 │   │   ├──> _num_instances++
 │   │   └──> break
 │   ├──> <case Type::SToRM32_serial> <HAL_MOUNT_STORM32SERIAL_ENABLED>  // check for SToRM32 mounts using serial protocol
 │   │   ├──> _backends[instance] = new AP_Mount_SToRM32_serial(*this, _params[instance], instance)
 │   │   ├──> _num_instances++
 │   │   └──> break
 │   ├──> <case Type::Gremsy> <HAL_MOUNT_GREMSY_ENABLED> // check for Gremsy mounts
 │   │   ├──> _backends[instance] = new AP_Mount_Gremsy(*this, _params[instance], instance)
 │   │   ├──> _num_instances++
 │   │   └──> break
 │   ├──> <case Type::BrushlessPWM> <HAL_MOUNT_SERVO_ENABLED> // check for BrushlessPWM mounts (uses Servo backend)
 │   │   ├──> _backends[instance] = new AP_Mount_Servo(*this, _params[instance], false, instance)
 │   │   ├──> _num_instances++
 │   │   └──> break
 │   ├──> <case Type::Siyi> <HAL_MOUNT_SIYI_ENABLED> // check for Siyi gimbal
 │   │   ├──> _backends[instance] = new AP_Mount_Siyi(*this, _params[instance], instance)
 │   │   ├──> _num_instances++
 │   │   └──> break
 │   ├──> <case Type::Scripting> <HAL_MOUNT_SCRIPTING_ENABLED> // check for Scripting gimbal
 │   │   ├──> _backends[instance] = new AP_Mount_Scripting(*this, _params[instance], instance)
 │   │   ├──> _num_instances++
 │   │   └──> break
 │   ├──> <case Type::Xacti> <HAL_MOUNT_XACTI_ENABLED> // check for Xacti gimbal
 │   │   ├──> _backends[instance] = new AP_Mount_Xacti(*this, _params[instance], instance)
 │   │   ├──> _num_instances++
 │   │   └──> break
 │   ├──> <case Type::Viewpro> <HAL_MOUNT_VIEWPRO_ENABLED> // check for Xacti gimbal
 │   │   ├──> _backends[instance] = new AP_Mount_Viewpro(*this, _params[instance], instance)
 │   │   ├──> _num_instances++
 │   │   └──> break
 │   │
 │   │  // init new instance
 │   └──> <_backends[instance] != nullptr> <!primary_set>
 │       ├──> _primary = instance
 │       └──> primary_set = true
 │
 │  // init each instance, do it after all instances were created, so that they all know things
 └──> <for (uint8_t instance=0 instance<AP_MOUNT_MAX_INSTANCES instance++)>
     └──> <_backends[instance] != nullptr>
         ├──> _backends[instance]->init()
         └──> set_mode_to_default(instance)

3.2 update

直接调用驱动更新云台状态。

// update - give mount opportunity to update servos.  should be called at 10hz or higher
AP_Mount::update
 │  // update each instance
 └──> <for (uint8_t instance=0 instance<AP_MOUNT_MAX_INSTANCES instance++)>
     └──> <_backends[instance] != nullptr>
         └──> _backends[instance]->update()

3.3 update_fast

直接调用驱动更新云台姿态。

// used for gimbals that need to read INS data at full rate
void AP_Mount::update_fast()
 │  // update each instance
 └──> <for (uint8_t instance=0 instance<AP_MOUNT_MAX_INSTANCES instance++)>
     └──> <_backends[instance] != nullptr>
         └──> _backends[instance]->update_fast()

3.4 handle_message

支持MAVLink命令:

  1. MAVLINK_MSG_ID_GIMBAL_REPORT
  2. MAVLINK_MSG_ID_MOUNT_CONFIGURE
  3. MAVLINK_MSG_ID_MOUNT_CONTROL
  4. MAVLINK_MSG_ID_GLOBAL_POSITION_INT
  5. MAVLINK_MSG_ID_GIMBAL_MANAGER_SET_ATTITUDE
  6. MAVLINK_MSG_ID_GIMBAL_MANAGER_SET_PITCHYAW
  7. MAVLINK_MSG_ID_GIMBAL_DEVICE_INFORMATION
  8. MAVLINK_MSG_ID_GIMBAL_DEVICE_ATTITUDE_STATUS
AP_Mount::handle_message
 ├──> <case MAVLINK_MSG_ID_GIMBAL_REPORT>
 │   ├──> handle_gimbal_report(chan, msg)
 │   └──> break
 ├──> <case MAVLINK_MSG_ID_MOUNT_CONFIGURE> <AP_MAVLINK_MSG_MOUNT_CONFIGURE_ENABLED>
 │   ├──> handle_mount_configure(msg)
 │   └──> break
 ├──> <case MAVLINK_MSG_ID_MOUNT_CONTROL> <AP_MAVLINK_MSG_MOUNT_CONTROL_ENABLED>
 │   ├──> handle_mount_control(msg)
 │   └──> break
 ├──> <case MAVLINK_MSG_ID_GLOBAL_POSITION_INT>
 │   ├──> handle_global_position_int(msg)
 │   └──> break
 ├──> <case MAVLINK_MSG_ID_GIMBAL_MANAGER_SET_ATTITUDE>
 │   ├──> handle_gimbal_manager_set_attitude(msg)
 │   └──> break
 ├──> <case MAVLINK_MSG_ID_GIMBAL_MANAGER_SET_PITCHYAW>
 │   ├──> handle_command_gimbal_manager_set_pitchyaw(msg)
 │   └──> break
 ├──> <case MAVLINK_MSG_ID_GIMBAL_DEVICE_INFORMATION>
 │   ├──> handle_gimbal_device_information(msg)
 │   └──> break
 ├──> <case MAVLINK_MSG_ID_GIMBAL_DEVICE_ATTITUDE_STATUS>
 │   ├──> handle_gimbal_device_attitude_status(msg)
 │   └──> break
 └──> <default> <HAL_BOARD_SITL>
     ├──> AP_HAL::panic("Unhandled mount case")
     └──> break

4. 总结

根据AP_Mount的代码实现上,总体可以归纳以下几个方面:

  1. 硬件总线
  2. MAVLink命令分类
  3. 驱动协议格式

因硬件的差异,需要根据代码支持情况进行选择,以便Ardupilot对云台的兼容性支持。

5. 参考资料

【1】ArduPilot开源飞控系统之简单介绍
【2】ArduPilot之开源代码Task介绍
【3】ArduPilot飞控启动&运行过程简介
【4】ArduPilot之开源代码Library&Sketches设计
【5】ArduPilot之开源代码Sensor Drivers设计


http://www.niftyadmin.cn/n/5102874.html

相关文章

Linux:命令行参数和环境变量

文章目录 命令行参数环境变量环境变量的概念常见的环境变量PATH 环境变量表本地变量和环境变量命令分类 本篇主要解决以下问题&#xff1a; 什么是命令行参数命令行参数有什么用环境变量是什么环境变量存在的意义 命令行参数 在学习C语言中&#xff0c;对于main函数当初的写…

为什么非const静态成员变量一定要在类外定义

当我们如下声明了一个类&#xff1a; class A{public:static int sti_data;// 这个语句在c11前不能通过编译&#xff0c;在c11的新标准下&#xff0c;已经能够在声明一个普通变量是就对其进行初始化。int a 10&#xff1b;static const int b 1;//...其他member };// 在类外…

杂记-使用crypto-js的AES进行加密/解密

安装 npm i crypto-js -D使用 import CryptoJS from "crypto-js";const aseKey CryptoJS.enc.Utf8.parse("XX123456"); const IV CryptoJS.enc.Utf8.parse(XX123456);// 加密 export function encryption(value) {let key CryptoJS.enc.Utf8.parse(as…

k8s crd设置额外header

可以通过设置crd.spec.additionalPrinterColumns来实现&#xff1a; apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata:name: crontabs.stable.example.com spec:group: stable.example.comscope: Namespacednames:plural: crontabssingular: cr…

Go 必知的10个命令

Go 是一种非常流行的编程语言&#xff0c;以下是 Go 必知的 10 个命令&#xff1a; 1&#xff0c;go build: 将一个或多个 Go 源文件编译成可执行文件或动态链接库。 2&#xff0c;go run: 直接运行一个或多个 Go 源文件。 3&#xff0c;go fmt: 格式化 Go 源代码。 4&…

爬虫数据获取的秘诀,高效稳定让你爬个够

在当今这个信息爆炸的时代&#xff0c;数据已经成为企业发展和决策的重要依据。而爬虫作为数据采集的重要手段之一&#xff0c;如何保障其高效稳定地爬取数据是许多企业和个人面临的问题。本文将从以下几个方面探讨如何解决这一问题。 一、了解目标网站结构及特征 在编写爬虫…

如何使用python获取ssl证书信息

安装依赖 pip install OpenSSL完整代码 """ Project &#xff1a;ssl证书验证 File &#xff1a;get_ssl.py IDE &#xff1a;PyCharm Author &#xff1a;zhizhuo Date &#xff1a;2023/10/19 10:13 """ import socket import…

Go中的错误处理

健壮的代码需要对意外情况做出正确的反应&#xff0c;如错误的用户输入、错误的网络连接和故障的磁盘。错误处理是识别程序何时处于意外状态的过程&#xff0c;并采取措施记录诊断信息以供以后调试。 不像其他语言要求开发人员使用特殊的语法来处理错误&#xff0c;Go中的错误…