目录
路径规划包括全局路径规划和局部路径规划。
ROS 的navigation官方功能包提供了三种全局路径规划器:carrot_planner、global_planner、navfn。我们通常使用的是navfn,如果机器人执行一些特殊任务而navfn不支持的话就需要自己写一个全局路径规划区并注册到ROS系统。
ROS的全局路径规划器是以lib插件形式(pluginlib)存在的,通过配置move_base 中base_global_planner参数指定实际路径规划执行时采用的全局路径规划器,这种设计大大提高了navigation包的可扩展性。
ROS官网wiki有详细的教程指导如何为ROS添加自定义的全局路径规划器。主要思路是:直接拷贝一份现成的全局路径规划器代码包,将软件包中的相关名字修改成想要的,最后实现下自己的makeplan方法即可。
为了向ROS添加一个新的全局路径规划器,新的路径规划器必须遵守nav_core包中定义的。
nav_core::BaseGlobalPlanner C ++接口。一旦编写了全局路径规划器,它必须作为插件添加到ROS中,以便它可以被move_base包使用。
(1)编写路径规划类
Class Header/类头文件
第一步是为遵循nav_core::BaseGlobalPlanner的路径规划器编写一个新类,然后在该类中重写initialize,makePlan方法。。在carrot_planner.h中可以找到一个类似的例子作为参考。
(2)为全局规划类创建插件
1.注册规划器作为BaseGlobalPlanner插件:
这是通过指令PLUGINLIB_EXPORT_CLASS(global_planner::GlobalPlanner, nav_core::BaseGlobalPlanner)完成的。其中,global_planner::GlobalPlanner为自己定义的命名空间::类。为此,必须包含库 #include <pluginlib/class_list_macros.h>。
宏PLUGINLIB_EXPORT_CLASS:允许一个类被动态加载,标记为一个导出的类。可以放在构成插件库的任何源(.cpp)文件中,通常放在导出类的.cpp文件的末尾。
插件描述文件:
XML文件,用于以机器可读格式存储有关插件的所有重要信息。它包含有关插件库的信息,插件的名称,插件的类型等。
举例rrt_star_planner_plugin.xml:
<library path="lib/librrt_star_global_planner">
<class name="RRTstar_planner/RRTstarPlannerROS" type="RRTstar_planner::RRTstarPlannerROS" base_class_type="nav_core::BaseGlobalPlanner">
<description>This is RRT Star Global Planner Plugin by Rafael Barreto.</description>
</class>
</library>
在第一行 <library path="lib/librrt_star_global_planner">我们指定插件库的路径。我们的例子,路径是lib/librrt_star_global_planner,其中lib是目录中的文件夹 ~/catkin_ws/devel/。
在第二行中,我们首先指定我们将在move_base启动文件中使用的RRTstar_planner插件的名称作为参数,它指定了要在nav_core中使用的全局规划器。通常使用命名空间(RRTstar_planner)后跟斜杠,然后使用类( RRTstarPlannerROS)的名称来指定插件的名称。如果不指定名称,那么名称将等于该类型,在这种情况下将是RRTstar_planner::RRTstarPlannerROS。它建议指定名称以避免混淆。该类型指定了实现插件的类的名称,在我们的例子中是RRTstar_planner::RRTstarPlannerROS,而base_class_type指定了实现插件的基类的名称,在我们的例子中是nav_core::BaseGlobalPlanner。
第三行所述<description> 标记提供关于插件的简要说明。有关插件描述文件及其相关标签/属性的详细说明。
为什么我们需要这个描述文件? 除了代码宏,我们需要这个文件,以允许ROS系统自动发现,加载。插件描述文件还包含重要信息,如插件的描述,不适合加在宏定义里。
注册插件到ROS包系统:
待补充
2.makePlan()方法实现:在开始和目标参数用来获取初始位置和目标位置。在该说明性实现中,以起始位置(plan.push_back(start)))作为开始的规划变量。然后,在for循环中,将在规划中静态插入虚拟位置,然后将目标位置作为最后一个位置插入规划。然后,此规划路径将发送到move_base全局规划模块,该模块将通过ROS话题nav_msgs/Path进行发布,然后将由本地规划模块接收。
现在,全局规划类已经完成,您已准备好进行第二步,即为全局规划类创建插件,将其集成到move_base包的全局规划模块nav_core::BaseGlobalPlanner中。
(3)编译
要编译上面创建的全局规划库,必须将其添加到CMakeLists.txt中。添加代码:
add_library(global_planner_lib src/path_planner/global_planner/global_planner.cpp)
然后在终端中运行catkin_make,在catkin工作空间目录中生成二进制文件。这将在lib目录中创建库文件 ~/catkin_ws/devel/lib/libglobal_planner_lib。观察到“lib”附加到CMakeLists.txt中声明的库名global_planner_lib
bool makePlan(start,goal,plan)的方法必须要重写。最终规划将存储在方法的参数std::vector<geometry_msgs::PoseStamped>& plan 中。该规划将通过插件自动发布为话题。
ROS与navigation教程-编写自定义全局路径规划
使用自定义RRT*全局规划器建图导航这篇文章很好上手,但是由于全局路径一直更新,加上使用的rrt算法,很有可能导致路径一直在变,需要改进。
如何使此根路径转到:“/dashboard”而不仅仅是http://example.com?root:to=>'dashboard#index',:constraints=>lambda{|req|!req.session[:user_id].blank?} 最佳答案 您可以通过以下方式实现:root:to=>redirect('/dashboard')match'/dashboard',:to=>"dashboard#index",:constraints=>lambda{|req|!req.session[:user_id].b
我需要根据字符串路径的长度将字符串路径数组转换为符号、哈希和数组的数组给定以下数组:array=["info","services","about/company","about/history/part1","about/history/part2"]我想生成以下输出,对不同级别进行分组,根据级别的结构混合使用符号和对象。产生以下输出:[:info,:services,about:[:company,history:[:part1,:part2]]]#altsyntax[:info,:services,{:about=>[:company,{:history=>[:part1,:pa
我有一个gem,它有一个根据Rails.env的不同行为的方法:defself.envifdefined?(Rails)Rails.envelsif...现在我想编写一个规范来测试这个代码路径。目前我是这样做的:Kernel.const_set(:Rails,nil)Rails.should_receive(:env).and_return('production')...没关系,只是感觉很丑。另一种方法是在spec_helper中声明:moduleRails;end而且效果也很好。但也许有更好的方法?理想情况下,这应该有效:rails=double('Rails')rails.sho
我正在尝试将$stdout设置为临时写入一个文件,然后返回到一个文件。test.rb:old_stdout=$stdout$stdout.reopen("mytestfile.out",'w+')puts"thisgoesinmytestfile"$stdout=old_stdoutputs"thisshouldbeontheconsole"$stdout.reopen("mytestfile1.out",'w+')puts"thisgoesinmytestfile1:"$stdout=old_stdoutputs"thisshouldbebackontheconsole"这是输出。r
Organization和Image具有一对一的关系。Image有一个名为filename的列,它存储文件的路径。我在Assets管道中包含这样一个文件:app/assets/other/image.jpg。播种时如何包含此文件的路径?我已经在我的种子文件中尝试过:@organization=...@organization.image.create!(filename:File.open('app/assets/other/image.jpg'))#Ialsotried:#@organization.image.create!(filename:'app/assets/other/i
在许多ruby类之间共享记录器实例的最佳(正确)方法是什么?现在我只是将记录器创建为全局$logger=Logger.new变量,但我觉得有更好的方法可以在不使用全局变量的情况下执行此操作。如果我有以下内容:moduleFooclassAclassBclassC...classZend在所有类之间共享记录器实例的最佳方式是什么?我是以某种方式在Foo模块中声明/创建记录器还是只是使用全局$logger没问题? 最佳答案 在模块中添加常量:moduleFooLogger=Logger.newclassAclassBclassC..
如何在出现异常时指定全局救援,如果您将Sinatra用于API或应用程序,您将如何处理日志记录? 最佳答案 404可以在not_found方法的帮助下处理,例如:not_founddo'Sitedoesnotexist.'end500s可以通过调用带有block的错误方法来处理,例如:errordo"Applicationerror.Plstrylater."end错误的详细信息可以通过request.env中的sinatra.error访问,如下所示:errordo'Anerroroccured:'+request.env['si
我读过这个:Let’sstartwithasimpleRubyprogram.We’llwriteamethodthatreturnsacheery,personalizedgreeting.defsay_goodnight(name)result="Goodnight,"+namereturnresultend我的理解是,方法是定义在类中的函数或子程序,可以关联到类(类方法)或对象(实例方法)。那么,如果它不是在类中定义的,怎么可能是方法呢? 最佳答案 当你在Ruby中以这种方式在全局范围内定义一个函数时,它在技术上变成了Obje
我安装了ruby、yeoman,当我运行我的项目时,出现了这个错误:Warning:Running"compass:dist"(compass)taskWarning:YouneedtohaveRubyandCompassinstalledthistasktowork.Moreinfo:https://github.com/gruUse--forcetocontinue.Use--forcetocontinue.我有进入可变session目标的路径,但它不起作用。谁能帮帮我? 最佳答案 我必须运行这个:geminstallcom
是否有内置的Ruby方法或众所周知的库可以返回对象的整个方法查找链?Ruby查看一系列令人困惑的类(如thisquestion中所讨论)以查找与消息对应的实例方法,如果没有类响应消息,则调用接收方的method_missing。我将以下代码放在一起,但我确信它遗漏了某些情况或者它是否100%正确。请指出任何缺陷并指导我找到一些更好的代码(如果存在)。defmethod_lookup_chain(obj,result=[obj.singleton_class])ifobj.instance_of?Classreturnadd_modules(result)ifresult.last==B