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

2023-05-16

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

  • 1. icm20689模块简介
  • 2. 模块入口函数
    • 2.1 主入口icm20689_main
    • 2.2 自定义子命令custom_command
    • 2.3 模块状态print_status【重载】
  • 3. ICM20689模块重要函数
    • 3.1 模块启动ThisDriver::module_start
    • 3.2 模块停止ThisDriver::module_stop
    • 3.3 模块状态ThisDriver::module_status
    • 3.4 设备实例对象初始化I2CSPIDriver::instantiate_default
    • 3.5 ICM20689设备实例对象初始化ICM20689::init
    • 3.6 设备实例对象任务I2CSPIDriver::Run()
    • 3.7 ICM20689设备实例对象任务ICM20689::RunImpl
  • 4. 总结
  • 5. 参考资料

1. icm20689模块简介

icm20689 <command> [arguments...]
 Commands:
   start
     [-s]        Internal SPI bus(es)
     [-S]        External SPI bus(es)
     [-b <val>]  board-specific bus (default=all) (external SPI: n-th bus
                 (default=1))
     [-c <val>]  chip-select pin (for internal SPI) or index (for external SPI)
     [-m <val>]  SPI mode
     [-f <val>]  bus frequency in kHz
     [-q]        quiet startup (no message if no device found)
     [-R <val>]  Rotation
                 default: 0

   stop

   status        print status info

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

class ICM20689 : public device::SPI, public I2CSPIDriver<ICM20689>
class I2CSPIDriver : public I2CSPIDriverBase
class I2CSPIDriverBase : public px4::ScheduledWorkItem, public I2CSPIInstance
class ScheduledWorkItem : public WorkItem
class WorkItem : public IntrusiveSortedListNode<WorkItem *>, public IntrusiveQueueNode<WorkItem *>
class I2CSPIInstance : public ListNode<I2CSPIInstance *>


ICM20689  //类继承关系
 ├──> I2CSPIDriver
 │   └──> I2CSPIDriverBase
 │       ├──> px4::ScheduledWorkItem
 │       │   └──> WorkItem
 │       │       ├──> IntrusiveSortedListNode
 │       │       └──> IntrusiveQueueNode
 │       └──> I2CSPIInstance
 │           └──> ListNode
 └──> device::SPI

注2:ICM20689模块就是针对ICM20689硬件芯片进行管理和数据采集的模块。

2. 模块入口函数

2.1 主入口icm20689_main

模块支持start/stop/status命令,除此以外支持BusCLIArguments的I2C/SPI默认参数选项"RXIa:Ssc: m:kb:f:q"。

icm20689_main
 ├──> using ThisDriver = ICM20689
 ├──> BusCLIArguments cli{false, true}
 ├──> cli.default_spi_frequency = SPI_SPEED
 ├──> <while ((ch = cli.getOpt(argc, argv, "R:")) != EOF)>
 │   └──> <case 'R'>
 │       ├──> cli.rotation = (enum Rotation)atoi(cli.optArg())
 │       └──> break
 ├──> const char *verb = cli.optArg()
 ├──> <!verb>
 │   ├──> ThisDriver::print_usage()
 │   └──> return -1
 ├──> BusInstanceIterator iterator(MODULE_NAME, cli, DRV_IMU_DEVTYPE_ICM20689)
 ├──> <!strcmp(verb, "start")>
 │   └──> return ThisDriver::module_start(cli, iterator)   //模块启动
 ├──> <(!strcmp(verb, "stop")>
 │   └──> return ThisDriver::module_stop(iterator)  //模块停止
 ├──> <!strcmp(verb, "status")>
 │   └──> return ThisDriver::module_status(iterator)  //模块状态
 ├──> ThisDriver::print_usage()
 └──> return -1

2.2 自定义子命令custom_command

注:该模块采用了纯C语言代码实现,在main函数中直接执行命令,无需ModuleBase的custom_command重载实现。

2.3 模块状态print_status【重载】

该模块采用了纯C语言代码实现,在main函数中直接执行ThisDriver::print_usage()函数,无需ModuleBase的模块状态print_status重载实现。

ICM20689::print_usage

void ICM20689::print_usage()
{
	PRINT_MODULE_USAGE_NAME("icm20689", "driver");
	PRINT_MODULE_USAGE_SUBCATEGORY("imu");
	PRINT_MODULE_USAGE_COMMAND("start");
	PRINT_MODULE_USAGE_PARAMS_I2C_SPI_DRIVER(false, true);
	PRINT_MODULE_USAGE_PARAM_INT('R', 0, 0, 35, "Rotation", true);
	PRINT_MODULE_USAGE_DEFAULT_COMMANDS();
}

3. ICM20689模块重要函数

3.1 模块启动ThisDriver::module_start

启动过程会将以下驱动信息关联到设备实例上:

  1. static I2CSPIDriverBase *I2CSPIDriver::instantiate_default(const I2CSPIDriverConfig &config, int runtime_instance)
  2. int ICM20689::init()
  3. void ICM20689::RunImpl()
  4. void I2CSPIDriver::Run() final
ThisDriver::module_start(ICM20689::module_start)
 └──> I2CSPIDriver::module_start
     └──> I2CSPIDriverBase::module_start

注:I2CSPIDriverBase::module_start会进行第一次的Run激活(px4::WorkItemSingleShot)。

3.2 模块停止ThisDriver::module_stop

ThisDriver::module_stop(ICM20689::module_stop)
 └──> I2CSPIDriverBase::module_stop

注:I2CSPIDriverBase类的通用方法,不在这里展开。

3.3 模块状态ThisDriver::module_status

ThisDriver::module_status(ICM20689::module_status)
 └──> I2CSPIDriverBase::module_status

注:I2CSPIDriverBase类的通用方法,不在这里展开。

3.4 设备实例对象初始化I2CSPIDriver::instantiate_default

该方法在I2CSPIDriverBase::module_start函数里面调用,其目的是新建一个设备对象实例,并进行初始化。

I2CSPIDriver::instantiate_default
 ├──> instance = new T(config)   // 新建一个ICM20689设备对象实例
 ├──> <!instance>
 │   ├──> PX4_ERR("alloc failed")
 │   └──> return nullptr
 ├──> <OK != instance->init()>  // ICM20689设备对象实例初始化
 │   ├──> delete instance
 │   └──> return nullptr
 └──> return instance

3.5 ICM20689设备实例对象初始化ICM20689::init

ICM20689设备实例对象初始化

ICM20689::init
 ├──> int ret = SPI::init()  // SPI总线初始化
 ├──> <ret != PX4_OK>
 │   ├──> DEVICE_DEBUG("SPI::init failed (%i)", ret)
 │   └──> return ret
 └──> return Reset() ? 0 : -1  // 重置模块,然后触发ScheduleNow

3.6 设备实例对象任务I2CSPIDriver::Run()

ICM20689设备初始化时以及设置定时时间,定时轮询Run过程,并调用业务实现方法RunImpl。

I2CSPIDriver::Run
 ├──> static_cast<T *>(this)->RunImpl()
 └──> <should_exit()>
     └──> exit_and_cleanup()  //优雅退出处理

3.7 ICM20689设备实例对象任务ICM20689::RunImpl

根据ICM20689模块业务状态机变化,进行业务操作,发布gyro, accel, temperature消息

ICM20689::RunImpl
 ├──> const hrt_abstime now = hrt_absolute_time()
 └──> switch (_state) {
     ├──> <case STATE::RESET>
     │   ├──> [PWR_MGMT_1: Device Reset	]
     │   └──> ScheduleDelayed(100_ms)
     ├──> <case STATE::WAIT_FOR_RESET>
     │   ├──> <Reset OK??? (RegisterRead(Register::WHO_AM_I) == WHOAMI)  && (RegisterRead(Register::PWR_MGMT_1) == 0x40)>
     │   │   ├──> [offset registers (factory calibration) should not change during normal operation]
     │   │   ├──> [Wakeup and reset digital signal path		
     │   │   ├──> [_state = STATE::CONFIGURE  // if reset succeeded then configure
     │   │   └──> ScheduleDelayed(35_ms) // max 35 ms start-up time from sleep
     │   └──> <else Reset failed>  // RESET not complete
     │       ├──> <hrt_elapsed_time(&_reset_timestamp) > 1000_ms>  // Reset failed, retrying
     │       │   ├──> _state = STATE::RESET
     │       │   └──> ScheduleDelayed(100_ms)
     │       └──> <else>  // Reset not complete, check again in 10 ms
     │           └──> ScheduleDelayed(10_ms)
     ├──> <case STATE::CONFIGURE>
     │   ├──> <Configure()> // if configure succeeded then start reading from FIFO
     │   │   ├──> _state = STATE::FIFO_READ
     │   │   │   ├──> <DataReadyInterruptConfigure()>
     │   │   │   │   ├──> _data_ready_interrupt_enabled = true
     │   │   │   │   └──> ScheduleDelayed(100_ms)  // backup schedule as a watchdog timeout
     │   │   │   └──> <else>
     │   │   │       ├──> _data_ready_interrupt_enabled = false
     │   │   │       └──> ScheduleOnInterval(_fifo_empty_interval_us, _fifo_empty_interval_us)
     │   │   └──> FIFOReset()
     │   └──> <else > // CONFIGURE not complete
     │       ├──> <hrt_elapsed_time(&_reset_timestamp) > 1000_ms>  // Configure failed, resetting
     │       │   └──> _state = STATE::RESET
     │       ├──> <else>   // Configure failed, retrying
     │       └──> ScheduleDelayed(100_ms)
     └──> <case STATE::FIFO_READ>
         ├──> [Execption handling procedures]
         ├──> [Update temperature readings]
         └──> [Update gyro and accel]  //FIFORead function and ProcessGyro/ProcessAccel

4. 总结

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

  • 输入: 芯片(硬件)

  • 输出: 修改OSD显示内容

uORB::PublicationMulti<sensor_gyro_s> _sensor_pub{ORB_ID(sensor_gyro)};
uORB::PublicationMulti<sensor_gyro_fifo_s>  _sensor_fifo_pub{ORB_ID(sensor_gyro_fifo)};

uORB::PublicationMulti<sensor_accel_s> _sensor_pub{ORB_ID(sensor_accel)};
uORB::PublicationMulti<sensor_accel_fifo_s>  _sensor_fifo_pub{ORB_ID(sensor_accel_fifo)};

注1:参考class PX4Accelerometer和class PX4Gyroscope。

注2:参考ICM 20689芯片规格书: DS-000143-ICM-20689-TYP-v1.1.pdf

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
【8】PX4模块设计之四十一:I2C/SPI Bus Instance基础知识

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

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

  • pixhawk: px4代码初学分析:追溯电机控制--pwm输出

    追溯电机控制 pwm输出 正常工作状态下pwm输出过程简述 xff1a 其他状态下pwm输出 xff1a 正常工作状态下pwm输出过程简述 xff1a 姿态解算部分得出姿态控制量通过px4io cpp把姿态控制量发送给IOIO串口读取姿态控
  • 【8-12】树莓派部署t265+px4飞控实现无人机视觉定位

    在之前的文章中 xff0c 我们已经成功在树莓派 xff08 ubuntu mate 18 04 xff09 上部署了T265的追踪摄像头 本文将利用MAVROS协议 xff0c 将T265测量的位姿信息发送给px4固件 xff0c 实现室
  • PX4位置控制offboard模式说明

    offboard模式的开发及应用 一 px4固件的模式 px4固件支持10几种飞行模式 xff0c 从代码结构上分析 xff0c 分为基本模式 自定义模式和自定义子模式 1 基本模式 基本模式又分为 xff0c 位置控制模式 自稳模式 手动
  • PX4 GAZEBO无人机添加相机并进行图像识别

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

    PX4无人机 键盘控制飞行代码 仿真效果 实机效果 由于图片限制5M以内 xff0c 只能上传一小段了 xff0c 整段视频请点击链接 Pixhawk 6c 无人机 键盘控制无人机 Offboard模式 核心 xff1a 发布 mavros
  • PX4源代码下载编译

    sudo git clone https github com PX4 PX4 Autopilot git recursivegit submodule update init recursivegit submodule update r
  • 无人机仿真—PX4编译,gazebo仿真及简单off board控制模式下无人机起飞

    无人机仿真 PX4编译 xff0c gazebo仿真及简单off board控制模式下无人机起飞 前言 在上篇记录中 xff0c 已经对整体的PX4仿真环境有了一定的了解 xff0c 现如今就要开始对无人机进行起飞等仿真环境工作 xff0c
  • PX4 ---- Mixer

    文章目录 Mixer 混合控制 作用输入输出装载混控文件MAVROS代码解析总结示例MAINAUX Mixer 混合控制 作用 经过位置控制和姿态控制后 xff0c 控制量通过 actuator controls发布 xff0c 其中 co
  • PX4模块设计之一:SITL & HITL模拟框架

    PX4模块设计之一 xff1a SITL amp HITL模拟框架 1 模拟框架1 1 SITL模拟框架1 2 HITL模拟框架 2 模拟器类型3 MAVLink API4 总结 基于PX4开源软件框架简明简介的框架设计 xff0c 逐步分
  • PX4模块设计之六:PX4-Fast RTPS(DDS)简介

    64 TOC PX4模块设计之六 xff1a PX4 Fast RTPS DDS 简介 基于PX4开源软件框架简明简介的框架设计 xff0c 逐步分析内部模块功能设计 PX4 Fast RTPS DDS 具有实时发布 订阅uORB消息接口
  • 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模块设计之四十五:param模块

    PX4模块设计之四十五 xff1a param模块 1 param模块简介2 模块入口函数param main3 重要函数列表4 总结5 参考资料 1 param模块简介 Description Command to access and
  • PX4模块设计之四十六:dataman模块

    PX4模块设计之四十六 xff1a dataman模块 1 dataman模块简介2 模块入口函数dataman main3 dataman模块重要函数3 1 start3 2 stop3 3 status3 4 task main 4 A
  • mavros连接px4失败的usb-ttl原因

    问题描述 xff1a 最近在搞mavros xff0c 以方便协处理器和pixhawk通讯 xff0c 在按照官网教程安装mavros xff0c 设置px4 xff0c 连接硬件之后发现mavros卡在中间下不去 xff1a MAVROS
  • PX4-4-任务调度

    PX4所有的功能都封装在独立的模块中 xff0c uORB是任务间数据交互和同步的工具 xff0c 而管理和调度每个任务 xff0c PX4也提供了一套很好的机制 xff0c 这一篇我们分享PX4的任务调度机制 我们以PX4 1 11 3版
  • PX4 OffBoard Control

    终于还是走上了这一步 xff0c 对飞控下手 xff0c 可以说是一张白纸了 记录一下学习的过程方便以后的查阅 目录 一 ubuntu18 04配置px4编译环境及mavros环境 二 PX4的OffBoard控制 1 搭建功能包 2 编写
  • PX4项目学习::(七)飞控栈:commander

    PX4的飞行控制程序通过模块来实现 xff0c 与飞控相关的模块主要有commander xff0c navigator xff0c pos control xff0c att control这几个 xff0c 分别可以在src modul
  • PX4项目学习::(五)模块代码启动流程

    54条消息 PX4 模块代码启动流程 zhao23333的博客 CSDN博客
  • PX4:Policy “CMP0097“ is not known to this version of CMake.

    make px4 fmu v3 时报的错 CMake版本的问题 由https blog csdn net zhizhengguan article details 118380965推测 xff0c 删除cmake policy也没事 ma
  • 大神浅谈无人机飞控软件设计 系统性总结

    写在前面 深感自己对飞控软件 算法的知识点过于杂乱 很久没有进行系统的总结了 因此决定写几篇文章记录一些飞控开发过程的知识点 主要是针对一些软件 算法部分进行讨论 如内容有错误 欢迎指出 1 飞控软件的基本模块 无人机能够飞行主要是依靠传感

随机推荐