Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1725925
  • 博文数量: 98
  • 博客积分: 667
  • 博客等级: 上士
  • 技术积分: 1631
  • 用 户 组: 普通用户
  • 注册时间: 2009-04-27 15:59
个人简介

一沙一世界 一树一菩提

文章分类

全部博文(98)

文章存档

2021年(8)

2020年(16)

2019年(8)

2017年(1)

2016年(11)

2015年(17)

2014年(9)

2013年(4)

2012年(19)

2011年(1)

2009年(4)

分类: 嵌入式

2019-12-25 23:26:22

这个也是很久以前的笔记。
         commander模块,在px4中,这个模块是管理中心。commander模块的主函数是commander_thread_main函数,这个函数在进入循环以前建立一个处理低优先级的线程commander_low_prio_loop。这个线程的循环在文件commander.cpp中大概3830行左右。

    这个循环是循环检索vechicle_command的urb,看是否有有效的comander,有就处理,如果是高优先级的直接跳过。
commander_thread_main函数的2839-2850行,是检测vehicle_command是否有更新,有就进行handle_command函数处理。在这个函数里主要根据cmd->command执行不同的switch-case语句。然后根据不同的cmd参数,执行main_state_transition()函数切换不同的模式,实现代码主要在state_machine_helper.cpp文件中444-447行,设置internal_state->main_state为新的main state。


在commander_thread_main函数的循环中,执行了handle_command函数,这个函数检查当前状态是否满足欲修改成的新状态。同样的文件中大概2929--2939行,执行set_nav_state函数。在set_nav_state函数中,检查是否有其它意外情况,没有的话根据inter_state的main_state设置vehicle_status_s的nav_state.下面继续在同一文件的2961-2967行,也是重点,这部分代码主要是把上面的状态修改告诉其它模块。


在commander.cpp中,3830行的commander_low_prio_loop中,也检测vehicle_command的uorb。当这个低优先级线程接收到vehicle_command时,处理一些优先级偏低的命令。而这个命令的发出,即uorb的publish在哪呢?mavlink_receive.cpp中,具体哪个模块发出来的,下回分解。


接上次,从2961行开始,先set_control_mode,这个设置是根据具体的nav_state来的,所以修改了nav_state,需要重新设置control mode,并且根据新模式设置需要哪些控制量,这些控制量在mc_pos_control_main.cpp和mc_att_control_main.cpp使用。
然后publish这个设置好的control mode。然后把修改以后的vehicle_status_s也publish出去。


### 2017-5-19 阅读px4代码之commander.cpp和navigator_main.cpp文件
PC机上的QGC通过mavlink向飞控发送命令,比如takeoff。流程是这样的。
commander.cpp文件中的commmander_thread_main函数中的循环通过下面几行代码检测pc发送过来的命令:


orb_check(cmd_sub, &updated);
        if(updated)
        obr_copy(ORB_ID(vehicle_command), cmd_sub, &smd);

同时,在navigator_main.cpp文件中也通过orb_check检查这个文件描述符。

在commander.cpp文件中,检测到有这个uorb ID上有更新,就执行2853行的handle_command函数。如果我们在QGC先执行takeoff命令,QGC会先发送loiter命令:PX4_CUSTOM_SUB_MODE_AUTO_LOITER。然后通过函数main_state_transition设置internal_state的main_state为commander_state_s::MAIN_STATE_AUTO_LOITER.最后退出handle_command函数


继续下面执行set_anv_state函数。这个函数根据internal_state的main_state参数设置vehicle_status_s的nav_state,对应的loiter参数设置为vehicle_status_s::NAVIGATOR_STATE_AUTO_LOITER。然后退出set_nav_state函数。紧接着下面publish出去。
    
    在navigator_main循环里,会一直通过uorb检测vehicle_status_s的状态是否更新,来得到commander模块修改后的状态。根据日志跟踪,在我们执行takeoff命令时,QGC会先发送一个loiter命令,紧接着发送一个takeoff命令。最后,在navigator_main函数里设置执行具体的_takeoff工作模式。但是地面站直接发送过来给navigator模块的命令就几个,很少很少。绝大多数具体的让飞机飞到哪的命令都是commander模块发出来的。毕竟他是大脑嘛,前面说commander模块根据收到的地面站发来的飞行模式命令作出一系列的状态修改,最后publish出来,navigator等待的就是这个。收到后,设置具体飞行模式。navigator一共大概有10个模式。navigator结构体有一个navigator_mode_array数组,所有的模式都放在这个数组里。还有一个navigator_mode的指针,这个指针就是当前的模式,它指向navigator_mode_array数组里的某一元素。在主函数靠下的地方,这个数组的每一个元素都会运行run函数,这个run函数会会根据参数执行每一个具体模式的run函数,这里用到的父类的run函数,实际里面执行的是子类的三个函数:on_inactive, on_activation和on_active。这三个函数就是具体模式准备--启动--工作的三个阶段。如果navigator_mode指向哪个具体模式,那么对应数组的run函数参数就是true,其它都是false,这样只有navigator_mode指向的模式启动正常true流程,其它都是false流程。    运行navigator_mode指向的具体模式的run函数。比如,我们当前指向mission模式。这样就可以循环执行mission任务了。说的比较简介,有不正确的地方欢迎大家一起交流。
阅读(354460) | 评论(0) | 转发(0) |
0

上一篇:px4 mavlink阅读记录

下一篇:apm阅读笔记1

给主人留下些什么吧!~~