




已阅读5页,还剩6页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
进程/应用之间的通信(例如将传感器应用的传感器数据发送到姿态滤波应用)是PX4软件架构的关键部分。进程(通常又被叫做节点(node)通过命名为总线(buses)进行消息交换的过程被称作订阅主题(topics)。在PX4中,一个订阅主题仅包含一个消息类型,比如vehicle_attitude订阅主题传输一个包含姿态结构(滚转、俯仰和偏航估计)的消息。节点可以在总线/订阅主题上发布(publish)一个消息(发送数据)或者订阅(subscribe)一个总线/订阅主题(接收数据)。应用并不知道在与谁通信,1个订阅主题可以有多个发布器和订阅器。这种设计模式阻止了锁定的问题(locking issues),在机器人领域非常常见。为了使这更为高效,通常在总线上只有一个消息,并且不会有队列。这种发布/订阅机制由微对象请求处理器microobject request broker (uORB)实现。快速开始这是一个简单但是完整的发布器(publisher)/订阅器(subscriber)组合,发布器发布一个叫做random_integer的订阅主题,并使用随机的整数更新订阅主题。订阅器检查并打印这些更新。topic.h1. /*declarethetopic*/2. ORB_DECLARE(random_integer);3. /*definethedatastructurethatwillbepublishedwheresubscriberscanseeit*/4. structrandom_integer_data5. intr;6. ;publisher.c1. #include2. /*createtopicmetadata*/3. ORB_DEFINE(random_integer);4. /*filehandlethatwillbeusedforpublishing*/5. staticinttopic_handle;6. intinit()7. 8. /*generatetheinitialdataforfirstpublication*/9. structrandom_integer_datard=.r=random(),;10. /*advertisethetopicandmaketheinitialpublication*/11. topic_handle=orb_advertise(ORB_ID(random_integer),&rd);12. 13. intupdate_topic()14. 15. /*generateanewrandomnumberforpublication*/16. structrandom_integer_datard=.r=random(),;17. /*publishthenewdatastructure*/18. orb_publish(ORB_ID(random_integer),topic_handle,&rd);19. subscriber.c1. #include2. /*filehandlethatwillbeusedforsubscribing*/3. staticinttopic_handle;4. intinit()5. 6. /*subscribetothetopic*/7. topic_handle=orb_subscribe(ORB_ID(random_integer);8. 9. voidcheck_topic()10. 11. boolupdated;12. structrandom_integer_datard;13. /*checktoseewhetherthetopichasupdatedsincethelasttimewereadit*/14. orb_check(topic_handle,&updated);15. if(updated)16. /*makealocalcopyoftheupdateddatastructure*/17. orb_copy(ORB_ID(random_integer),topic_handle,&rd);18. printf(Randomintegerisnow%dn,rd.r);19. 20. 发布过程发布过程包含三个独立却相关联的动作:定义订阅主题,通告订阅主题,并且发布更新。定义订阅主题作为一种在元件之间提供通用接口的方式,系统定义了许多标准的订阅主题。如果一个发布器希望使用某一标准的订阅主题和其相关的数据结构,不需要再做额外的工作。常规订阅主题为了定义一个常规的订阅主题,发布器需要为订阅器建一个可用的头文件(上面的topic.h)。在这个头文件里必须包含: 将订阅主题的名字作为参数的一个ORB_DECLARE()宏实例。 一个用于描述将发布数据结构的结构定义。订阅主题的名字应该是描述性的;PX4的命名规则是是使用下划线分开订阅主题的名字;组件的名字应该首先使用通用的词汇。例如,原始传感器数据在sensors_raw订阅主题中进行发布。除了头文件,发布器必须包含一个ORB_DEFINE()宏实例在源文件中,该文件可以在构建固件时被编译和链接(见publisher.c示例)。这个宏来构建由ORB使用的数据结构,从而唯一表示这个topic。可选的订阅主题(optionaltopic)如果一个由软件组件发布的订阅主题是可选的,并且可能不会出现在固件中,头文件可以使用ORB_DECLARE_OPTIONAL()宏代替。以这种方式声明的订阅主题需要由发布器进行特别的处理,但是还有一些以下需要讨论的考虑,订阅器在处理可选订阅主题时必须要注意。通告(advertise)订阅主题在数据发布到一个订阅主题时,必须首先通告。发布器使用如下的API通告一个新的订阅主题:1. /*2. *Advertiseasthepublisherofatopic.3. *4. *Thisperformstheinitialadvertisementofatopic;itcreatesthetopic5. *nodein/objifrequiredandwritestheinitialdata.6. *7. *parammetaTheuORBmetadata(usuallyfromtheORB_ID()macro)8. *forthetopic.topicuORB元数据(通常来自ORB_ID()宏)9. *paramdataApointertotheinitialdatatobepublished.指向将要publish初始数据的指针。10. *Fortopicspublishedbyinterrupthandlers,theadvertisement11. *mustbeperformedfromnon-interruptcontext.12. *returnERRORonerror,otherwisereturnsahandle13. *thatcanbeusedtopublishtothetopic.14. *Ifthetopicinquestionisnotknown(duetoan15. *ORB_DEFINE_OPTIONALwithnocorrespondingORB_DECLARE)16. *thisfunctionwillreturn-1andseterrnotoENOENT.17. */18. externintorb_advertise(conststructorb_metadata*meta,constvoid*data);通告同时为订阅主题发布初始数据。API的meta参数是由ORB_DEFINE()宏产生的数据指针,通常使用ORB_ID()宏提供,该宏执行从订阅主题名到元数据结构名的转换。需要注意的是,可以从中断句柄中发布实时更新,但是通告订阅主题必须在常规线程的情况下。多个发布器一个发布器一次只能通告一个订阅主题,然而发布器可能会关闭订阅主题句柄(这是个文件句柄,可以简单的传递到close()函数),然后由另外一个发布器通告订阅主题。发布更新一个订阅主题被通告后,从通告那里返回的句柄可以使用如下的API,用于对订阅主题发布更新:1. /*2. *Publishnewdatatoatopic.3. *4. *Thedataisatomicallypublishedtothetopicandanywaitingsubscribers5. *willbenotified.Subscribersthatarenotwaitingcancheckthetopic6. *forupdatesusingorb_checkand/ororb_stat.7. *8. *handleThehandlereturnedfromorb_advertise.9. *parammetaTheuORBmetadata(usuallyfromtheORB()macro)10. *forthetopic.11. *paramdataApointertothedatatobepublished.12. *returnOKonsuccess,ERRORotherwisewitherrnosetaccordingly.13. */14. externintorb_publish(conststructorb_metadata*meta,inthandle,constvoid*data);需要注意的是ORB并不缓存多个更新,当订阅器检查订阅主题时,只会看到最近的一个更新。订阅订阅一个订阅主题需要如下: 一个ORB_DEFINE()或者ORB_DEFINE_OPTIONAL()宏(例如,在订阅器中包含的头文件) 在订阅主题中发布的数据结构定义。(通常来自相同的头文件)假如这些条件都满足,订阅器使用下面的API来订阅一个订阅主题。1. /*2. *Subscribetoatopic.3. *4. *Thereturnedvalueisafiledescriptorthatcanbepassedtopoll()5. *inordertowaitforupdatestoatopic,aswellasorb_read,6. *orb_checkandorb_stat.7. *8. *Subscriptionwillsucceedevenifthetopichasnotbeenadvertised;9. *inthiscasethetopicwillhaveatimestampofzero,itwillnever10. *signalapoll()event,checkingwillalwaysreturnfalseanditcannot11. *becopied.Whenthetopicissubsequentlyadvertised,poll,check,12. *statandcopycallswillreacttotheinitialpublicationthatis13. *performedaspartoftheadvertisement.14. *15. *Subscriptionwillfailifthetopicisnotknowntothesystem,i.e.16. *thereisnothinginthesystemthathasdefinedthetopicandthusit17. *canneverbepublished.18. *19. *parammetaTheuORBmetadata(usuallyfromtheORB_ID()macro)20. *forthetopic.21. *returnERRORonerror,otherwisereturnsahandle22. *thatcanbeusedtoreadandcheckthetopicforupdates.23. *Ifthetopicinquestionisnotknown(duetoan24. *ORB_DEFINE_OPTIONALwithnocorrespondingORB_DECLARE)25. *thisfunctionwillreturn-1andseterrnotoENOENT.26. */27. externintorb_subscribe(conststructorb_metadata*meta);订阅一个可选的订阅主题时,如果订阅主题不存在的话,将会失败。然而其他的所有订阅都会成功,并创建订阅主题,即使这并没有经发布器通告。这极大的降低了仔细安排系统启动顺序的需要。对一项任务可以执行的订阅数目并没有具体的限制。取消对一个订阅主题的订阅,使用如下的API:1. /*2. *Unsubscribefromatopic.3. *4. *paramhandleAhandlereturnedfromorb_subscribe.5. *returnOKonsuccess,ERRORotherwisewitherrnosetaccordingly.6. */7. externintorb_unsubscribe(inthandle);从订阅主题中拷贝数据订阅器并不是引用存储在ORB中的数据,或者与其他订阅器共享数据;而是在其请求下,将数据从ORB中拷贝出来存放在每一个订阅器对应的临时缓冲区中。这一拷贝就避免了锁定问题,并使得发布器和订阅器的API都变的简单。也允许订阅器及时根据自己的使用需求对数据进行修改。当订阅器希望得到发布到订阅主题的最近数据拷贝时,使用如下的API:1. /*2. *Fetchdatafromatopic.3. *4. *parammetaTheuORBmetadata(usuallyfromtheORB()macro)5. *forthetopic.6. *paramhandleAhandlereturnedfromorb_subscribe.7. *parambufferPointertothebufferreceivingthedata.8. *returnOKonsuccess,ERRORotherwisewitherrnosetaccordingly.9. */10. externintorb_copy(conststructorb_metadata*meta,inthandle,void*buffer);复制可以保证数据是最新发布的。更新检查在订阅器调用orb_copy函数后,可以使用如下的API检查从上一个时间开始,订阅主题是否接收到了新的发布。1. /*2. *Checkwhetheratopichasbeenpublishedtosincethelastorb_copy.3. *4. *Thischeckcanbeusedtodeterminewhethertocopyfromthetopicwhen5. *notusingpoll(),ortoavoidtheoverheadofcallingpoll()whenthe6. *topicislikelytohaveupdated.7. *8. *Updatesaretrackedonaper-handlebasis;thiscallwillcontinueto9. *returntrueuntilorb_copyiscalledusingthesamehandle.Thisinterface10. *shouldbepreferredovercallingorb_statduetotheracewindowbetween11. *statandcopythatcanleadtomissedupdates.12. *13. *paramhandleAhandlereturnedfromorb_subscribe.14. *paramupdatedSettotrueifthetopichasbeenpublishedsincethe15. *lasttimeitwascopiedusingthishandle.16. *returnOKifthecheckwassuccessful,ERRORotherwisewith17. *errnosetaccordingly.18. */19. externintorb_check(inthandle,bool*updated);当订阅主题在通告之前,已经被订阅,这个API将会返回没有更新,直到订阅主题被通告。发布时间戳订阅器可以使用如下的API检查订阅主题最近一次发布的时间:1. /*2. *Returnthelasttimethatthetopicwaspublished.3. *4. *paramhandleAhandlereturnedfromorb_subscribe.5. *paramtimeReturnsthetimethatthetopicwaspublished,orzeroifithas6. *neverbeenpublished/advertised.7. *returnOKonsuccess,ERRORotherwisewitherrnosetaccordingly.8. */9. externintorb_stat(inthandle,uint64_t*time);当调用这个功能时,需要仔细检查,因为并不能保证在调用返回后订阅主题不会紧接着就发布。等待更新依赖于发布作为数据源的订阅器,其可以同时具有任意数量等待发布的订阅。这一功能通过使用poll()函数实现,与文件描述符等待数据具有相同的方式。这之所以可以工作,是因为订阅本身实际上也是文件描述符。下面的例子展示的是,订阅器具有三个独立的订阅,等待到每一个的发布,当收到这些发布时进行回应。如果第二轮没有到任意订阅的更新,更新超时计数器,并发布给其他订阅器。color_counter.h1. ORB_DECLARE(color_red);2. ORB_DECLARE(color_green);3. ORB_DECLARE(color_blue);4. ORB_DECLARE(color_timeouts);5. 6. /*structurepublishedtocolor_red,color_green,color_blueandcolor_timeouts*/7. structcolor_update8. 9. intnumber;10. ;11. color_counter.c12. #include13. 14. ORB_DEFINE(color_timeouts,structcolor_update);15. 16. void17. subscriber(void)18. 19. intsub_red,sub_green,sub_blue;20. intpub_timeouts;21. inttimeouts=0;22. structcolor_updatecu;23. 24. /*subscribetocolortopics*/25. sub_red=orb_subscribe(ORB_ID(color_red);26. sub_green=orb_subscribe(ORB_ID(color_green);27. sub_blue=orb_subscribe(ORB_ID(color_blue);28. 29. /*advertisethetimeouttopic*/30. cu.number=0;31. pub_timeouts=orb_advertise(ORB_ID(color_timeouts),&cu);32. 33. /*loopwaitingforupdates*/34. for(;)35. 36. /*waitforupdatesora1-secondtimeout*/37. structpollfdfds3=38. .fd=sub_red,.events=POLLIN,39. .fd=sub_green,.events=POLLIN,40. .fd=sub_blue,.events=POLLIN41. ;42. intret=poll(fds,3,1000);43. 44. /*checkforatimeout*/45. if(ret=0)46. puts(timeout);47. cu.number=+timeouts;48. orb_publish(ORB_ID(color_timeouts),pub_timeouts,&cu);49. 50. /*checkforcolorupdates*/51. else52. 53. if(fds0.revents&POLLIN)54. orb_copy(ORB_ID(color_red),sub_red,&cu);55. printf(redisnow%dn,cu.number);56. 57. if(fds1.revents&POLLIN)58. orb_copy(ORB_ID(color_green),sub_green,&
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年中国风筝LED无人机编队表演师认证考试备考指南
- 2025年医药卫生类考试趋势分析及应对策略
- 2025年中国机械制造工程师认证考试模拟题集
- 2025年中子、电子及Γ辐照装置项目合作计划书
- 2025年智能楼宇照明项目合作计划书
- 2025年智能配电自动化项目合作计划书
- 2025年滴鼻剂项目合作计划书
- 跨境电商物流 题库试题及答案 任务四 跨境电商进口物流配送方式
- 2025年增采原油起振机合作协议书
- 安徽省合肥市巢湖市2024-2025学年下学期八年级数学期末试卷(含答案)
- 保险行业组织发展
- 人工智能在财务预测中的应用-全面剖析
- 药品临床综合评价解读
- 输液反应应急预案及流程
- 计算机基础知识完整课件
- 针灸理疗院感风险评估与应对措施
- 水库巡查基本知识
- 2025年中国人寿:养老险北京分公司招聘笔试参考题库含答案解析
- 临床输血规范指南
- 动火作业安全培训题库
- 物业管理中的服务质量监控与改进机制
评论
0/150
提交评论