@danren-aa120
2020-06-16T01:07:03.000000Z
字数 4372
阅读 480
ROS
1 The move_base package supports any global planner adhering to the nav_core::BaseGlobalPlanner interface specified in the nav_core package and any local planner adhering to the nav_core::BaseLocalPlanner interface specified in the nav_core package.
2The move_base node also maintains two costmaps, one for the global planner, and one for a local planner (see the costmap_2d package) that are used to accomplish navigation tasks.
3机器人被卡住时怎么办?
The move_base node may optionally perform recovery behaviors when the robot perceives itself as stuck. By default, the move_base node will take the following actions to attempt to clear out space:
First, obstacles outside of a user-specified region will be cleared from the robot's map. Next, if possible, the robot will perform an in-place rotation to clear out space. If this too fails, the robot will more aggressively clear its map, removing all obstacles outside of the rectangular region in which it can rotate in place. This will be followed by another in-place rotation. If all this fails, the robot will consider its goal infeasible and notify the user that it has aborted. These recovery behaviors can be configured using the recovery_behaviors parameter, and disabled using the recovery_behavior_enabled parameter.
4 The Navigation Stack was developed on a square robot, so its performance will be best on robots that are nearly square or circular. It does work on robots of arbitrary shapes and sizes, but it may have difficulty with large rectangular robots in narrow spaces like doorways.
5 the current navigation stack only accepts sensor data published using either the sensor_msgs/LaserScan Message type or the sensor_msgs/PointCloud Message type.
6 Orientation filter
As a post-processing step, an orientation can be added to the points on the path. With use of the ~orientation_mode parameter (dynamic reconfigure), the following orientation modes can be set:
None=0 (No orientations added except goal orientation)
Forward=1 (Positive x axis points along path, except for the goal orientation)
Interpolate=2 (Orientations are a linear blend of start and goal pose)
ForwardThenInterpolate=3 (Forward orientation until last straightaway, then a linear blend until the goal pose)
Backward=4 (Negative x axis points along the path, except for the goal orientation)
Leftward=5 (Positive y axis points along the path, except for the goal orientation)
Rightward=6 (Negative y axis points along the path, except for the goal orientation)
The orientation of point i is calculated using the positions of i - orientation_window_size and i + orientation_window_size
. The window size can be altered to smoothen the orientation calculation.
7 ros::Publisher current_goal_pub_, vel_pub_, action_goal_pub_;
ros::Subscriber goal_sub_;
ros::ServiceServer make_plan_srv_, clear_costmaps_srv_;
8.pluginlib是一个使用C++实现的库, 用于在ROS包里面动态的加载或卸载plugin. plugin满足一些条件的, 可以从运行库(例如共享对象, 动态链接库)中动态加载的类. Plugin在扩展或修改应用的行为上很有优势, 并不需要知道原始类的源码, 也许你在编写代码时, 也并不知道你将会用到哪个plugin, 而是在运行时通过参数载入才确定具体的plugin.假设现在有一个ROS包polygon_interface_package, 里面包含一个polygon基类, 同时, 另外还有两个不同的polygon, 一个是rectangle, 存在于rectangle_plugin包, 另外一个是triangle, 存在于triangle_plugin包. 我们希望rectangle和triangle都被系统支持.
为了能够动态加载一个类, 那么, 这个类必须是一个被标注的, 并且导入到系统的一个类. 这个过程, 需要使用宏PLUGINLIB_EXPORT_CLASS来完成. 一般情况下, 这个宏放在实现文件(.cpp)中. 类似如下:
#include <pluginlib/class_list_macros.h>
#include <polygon_interface_package/polygon.h>
#include <rectangle_package/rectangle.h>
// 具体参数意义, 见下文
PLUGINLIB_EXPORT_CLASS(rectangle_namespace::Rectangle, polygon_namespace::Polygon)
每个Plugin都需要由一个插件描述文件, 是一个XML格式机器可读的文件. 包含一些必要的信息, 例如路径, 插件类型, 插件名称等. 类似如下:
library path="lib/librectangle">
class type="rectangle_namespace::Rectangle" base_class_type="polygon_namespace::Polygon">
description>
This is a rectangle plugin
/description>
/class>
/library>
为了使pluginlib能够查询到所有可用的插件, 需要在package.xml文件中添加export的tag块. 类似如下:
<export>
<polygon_interface_package plugin="${prefix}/rectangle_plugin.xml" />
</export>
一个值得注意的地方, 为了使上述export命令正确执行, 还需要在build和run依赖项中添加如下信息:
<build_depend>polygon_interface_package</build_depend>
<run_depend>polygon_interface_package</run_depend>
9. NodeHandles节点类
ros::NodeHandle类有两个作用:
首先,在roscpp程序的内部,它提供了RAII方式启动和关闭。
其次,它提供了一个额外的层命令空间解决方案,可以使组件更容易写。
自动启动和关闭
ros::NodeHandle管理内部的引用计数
开始节点:
ros::NodeHandle nh;
创建时候,如果内部节点没有开始,ros::NodeHandle会开始节点,ros::NodeHandle实例销毁,节点就会关闭。
命名空间
查阅ROS命名空间文档
NodeHandle可以指定命名空间给构造器:
ros::NodeHandle nh("my_namespace");
这使得任何相对名称可用,NodeHandle相对于/my_namespace而不是 。
也可以指定父NodeHandle和命名空间:
ros::NodeHandle nh1("ns1");
ros::NodeHandle nh2(nh1, "ns2");
这个放nh2 进入/ns1/ns2 命名空间.
全局名称
你可以指定全局名,如:
ros::NodeHandle nh("/my_global_namespace");
这通常不鼓励,因为它阻止了节点被推为命名空间(如roslaunch)。然而,有时在代码中使用全局名称可能是有用的。
私有名称
直接使用私有名称比使用带有私有名称的nodehandle方法会更令人混淆。
相反,你必须在一个私有空间创建一个新的nodehandle:
ros::NodeHandle nh("~my_private_namespace");
ros::Subscriber sub = nh.subscribe("my_private_topic", ...);