ROS大型工程学习(二) 怎么阅读大型工程
基本思路是由点到面,由浅到深。
1、首先从launch文件入手。
文件中会看到比如:
<node ns="room_exploration" pkg="ipa_room_exploration" type="room_exploration_server" name="room_exploration_server" output="screen" respawn="true" respawn_delay="">
<rosparam command="load" file="$(find ipa_room_exploration)/ros/launch/room_exploration_action_server_params.yaml"/>
</node>
node里可以看出来节点写在哪个文件中。
rosparam中写里参数规定在哪个文件里。
我们先看参数yaml文件。
2、yaml文件。
随便粘贴一段,从命名可以大致猜出是干什么的。然后转到cpp文件中搜索这些参数,看看到底写了什么。
room_exploration_algorithm: # # display final trajectory plan step by step
# bool
display_trajectory: true # delate the points with the same pose in the trajectory,to optimze the trajectory
# bool
delate_points: true # map correction
# ==============
# Applies a closing operation to neglect inaccessible areas and map errors/artifacts if the map_correction_closing_neighborhood_size parameter is larger than .
# The parameter then specifies the iterations (or neighborhood size) of that closing operation.
map_correction_closing_neighborhood_size:
3、cpp文件
先找main函数。比如:
int main(int argc, char** argv)
{
ros::init(argc, argv, "room_exploration_server");
ros::Time::init(); ros::NodeHandle nh("~"); RoomExplorationServer explorationObj(nh, ros::this_node::getName()); ros::spin(); return ;
}
解读:
第3、4行:初始化,声明一个节点叫room_exploration_server。
第6行: ros::NodeHandle nh("~");把节点参数加载进来,动态加载参数。
第8行:开始启用节点。看类RoomExplorationServer定义在哪里,找到相应位置,进入下一步。
4、类的定义
接上一步,看类的定义。
比如:
RoomExplorationServer::RoomExplorationServer(ros::NodeHandle nh, std::string name_of_the_action) :
node_handle_(nh),
room_exploration_server_(node_handle_, name_of_the_action, boost::bind(&RoomExplorationServer::exploreRoom, this, _1), false)
{
// Parameters
std::cout << "\n--------------------------\nRoom Exploration Parameters:\n--------------------------\n";
node_handle_.param("room_exploration_algorithm", room_exploration_algorithm_, );
std::cout << "room_exploration/room_exploration_algorithm = " << room_exploration_algorithm_ << std::endl;
node_handle_.param("display_trajectory", display_trajectory_, false);
std::cout << "room_exploration/display_trajectory = " << display_trajectory_ << std::endl;
node_handle_.param("delate_points", delate_points_, false);
std::cout << "room_exploration/delate_points = " << delate_points_ << std::endl;
node_handle_.param("map_correction_closing_neighborhood_size", map_correction_closing_neighborhood_size_, );
std::cout << "room_exploration/map_correction_closing_neighborhood_size = " << map_correction_closing_neighborhood_size_ << std::endl;
node_handle_.param("return_path", return_path_, true);
std::cout << "room_exploration/return_path = " << return_path_ << std::endl;
node_handle_.param("execute_path", execute_path_, false);
std::cout << "room_exploration/execute_path = " << execute_path_ << std::endl;
node_handle_.param("goals_eps", goal_eps_, 0.17);
std::cout << "room_exploration/goals_eps = " << goal_eps_ << std::endl;
node_handle_.param("use_dyn_goal_eps", use_dyn_goal_eps_, true);
std::cout << "room_exploration/use_dyn_goal_eps = " << use_dyn_goal_eps_ << std::endl;
node_handle_.param("interrupt_navigation_publishing", interrupt_navigation_publishing_, false);
std::cout << "room_exploration/interrupt_navigation_publishing = " << interrupt_navigation_publishing_ << std::endl;
node_handle_.param("revisit_areas", revisit_areas_, false);
std::cout << "room_exploration/revisit_areas = " << revisit_areas_ << std::endl;
node_handle_.param("left_sections_min_area", left_sections_min_area_, 0.01);
std::cout << "room_exploration/left_sections_min_area_ = " << left_sections_min_area_ << std::endl;
global_costmap_topic_ = "/move_base_linear/global_costmap/costmap"; // 给move_base_linear发送costmap
node_handle_.param<std::string>("global_costmap_topic", global_costmap_topic_);
std::cout << "room_exploration/global_costmap_topic = " << global_costmap_topic_ << std::endl;
node_handle_.param<std::string>("coverage_check_service_name", coverage_check_service_name_, "/room_exploration/coverage_check_server/coverage_check");
std::cout << "room_exploration/coverage_check_service_name = " << coverage_check_service_name_ << std::endl;
map_frame_ = "map";
node_handle_.param<std::string>("map_frame", map_frame_);
std::cout << "room_exploration/map_frame = " << map_frame_ << std::endl;
camera_frame_ = "base_link";
node_handle_.param<std::string>("camera_frame", camera_frame_);
std::cout << "room_exploration/camera_frame = " << camera_frame_ << std::endl; if (room_exploration_algorithm_ == ) // set boustrophedon exploration parameters
{
node_handle_.param("min_cell_area", min_cell_area_, 10.0);
std::cout << "room_exploration/min_cell_area_ = " << min_cell_area_ << std::endl;
node_handle_.param("path_eps", path_eps_, 2.0);
std::cout << "room_exploration/path_eps_ = " << path_eps_ << std::endl;
node_handle_.param("grid_obstacle_offset", grid_obstacle_offset_, 0.0);
std::cout << "room_exploration/grid_obstacle_offset_ = " << grid_obstacle_offset_ << std::endl;
node_handle_.param("max_deviation_from_track", max_deviation_from_track_, -);
std::cout << "room_exploration/max_deviation_from_track_ = " << max_deviation_from_track_ << std::endl;
node_handle_.param("cell_visiting_order", cell_visiting_order_, );
std::cout << "room_exploration/cell_visiting_order = " << cell_visiting_order_ << std::endl;
ROS_INFO("You have chosen the boustrophedon exploration method.");
}
else if (room_exploration_algorithm_ == ) // set energyfunctional explorator parameters
{
node_handle_.param("grid_obstacle_offset", grid_obstacle_offset_, 0.0);
std::cout << "room_exploration/grid_obstacle_offset_ = " << grid_obstacle_offset_ << std::endl;
ROS_INFO("You have chosen the energy functional exploration method.");
}
if (revisit_areas_ == true)
ROS_INFO("Areas not seen after the initial execution of the path will be revisited.");
else
ROS_INFO("Areas not seen after the initial execution of the path will NOT be revisited."); // min area for revisiting left sections
path_pub_ = node_handle_.advertise<nav_msgs::Path>("coverage_path", ); //Start action server
room_exploration_server_.start();
ROS_INFO("Action server for room exploration has been initialized......");
}
不难看出,这一步骤和前面的很多步骤联系到了一起。
类中先是加载里句柄, ros::NodeHandle nh("~")在第3步中提到过。
然后,声明了各项参数,在第2步的yaml文件中写过(最后的参数取值当然是以yaml文件中为准)
然后是一些不同选择的参数有不同的功能。
类定义完成后,就开始看各个类函数究竟干了些什么。
5、函数
这个就看自己需要哪些功能了,一般来说,函数是按照功能模块划分的。
如果你是看导航的工程文件,分析思路是:
先按照常理分析:导航时第一步是不是应该有个目标点(有了目标点才能开始规划路径,很好理解)?那么目标点就作为函数的切入点,找到goal传到了哪里,从传入的函数开始阅读,按照功能一步一步往下推(比如,找到目标点后,是不是需要知道机器人本体、地图信息和障碍物信息?然后生成代价地图?接着进行全局规划,知道机器人运动的大方向?再进行局部规划,实时更新障碍物信息?等等。。。。),常听到的A×、Dji算法实际上就写在规划里了。
以上所讲的是一种思维,大型工程如何下手的思维。只要思维培养好,剩下的就是编程和算法本身的学习问题了。而在工程中应用的算法,也基本都是开源算法改的。
作为学生或研究人员,还是希望大家深究算法内在逻辑,踏踏实实学习数学和编程知识,把基础打牢,科研这事急不得。
有什么问题欢迎留言探讨。
ROS大型工程学习(二) 怎么阅读大型工程的更多相关文章
- ROS大型工程学习(一) 必须了解的基本文件
一.Cmake文件 阅读工程,首先点开CMakeLists 文件,会定义一些库和可执行文件.首先看可执行文件,rosrun的就是这个节点navigator add_executable(navigat ...
- ROS actionlib学习(二)
在ROS actionlib学习(一)中的例子展示了actionlib最基本的用法,下面我们看一个稍微实际一点的例子,用actionlib计算斐波那契数列,并发布反馈(feedback)和结果(res ...
- [spring源码学习]二、IOC源码——配置文件读取
一.环境准备 对于学习源码来讲,拿到一大堆的代码,脑袋里肯定是嗡嗡的,所以从代码实例进行跟踪调试未尝不是一种好的办法,此处,我们准备了一个小例子: package com.zjl; public cl ...
- ReactJS入门学习二
ReactJS入门学习二 阅读目录 React的背景和基本原理 理解React.render() 什么是JSX? 为什么要使用JSX? JSX的语法 如何在JSX中如何使用事件 如何在JSX中如何使用 ...
- ROS actionlib学习(三)
下面这个例子将展示用actionlib来计算随机变量的均值和标准差.首先在action文件中定义goal.result和feedback的数据类型,其中goal为样本容量,result为均值和标准差, ...
- Android JNI学习(二)——实战JNI之“hello world”
本系列文章如下: Android JNI(一)——NDK与JNI基础 Android JNI学习(二)——实战JNI之“hello world” Android JNI学习(三)——Java与Nati ...
- emberjs学习二(ember-data和localstorage_adapter)
emberjs学习二(ember-data和localstorage_adapter) 准备工作 首先我们加入ember-data和ember-localstorage-adapter两个依赖项,使用 ...
- TweenMax动画库学习(二)
目录 TweenMax动画库学习(一) TweenMax动画库学习(二) TweenMax动画库学习(三) Tw ...
- Hbase深入学习(二) 安装hbase
Hbase深入学习(二) 安装hbase This guidedescribes setup of a standalone hbase instance that uses the local fi ...
- Struts2框架学习(二) Action
Struts2框架学习(二) Action Struts2框架中的Action类是一个单独的javabean对象.不像Struts1中还要去继承HttpServlet,耦合度减小了. 1,流程 拦截器 ...
随机推荐
- 「CH6201」走廊泼水节
「CH6201」走廊泼水节 传送门 考虑 \(\text{Kruskal}\) 的过程以及用到一个最小生成树的性质即可. 在联通两个联通块时,我们肯定会选择最小的一条边来连接这两个联通块,那么这两个联 ...
- Spring Boot整合Mybatis(注解方式和XML方式)
其实对我个人而言还是不够熟悉JPA.hibernate,所以觉得这两种框架使用起来好麻烦啊. 一直用的Mybatis作为持久层框架, JPA(Hibernate)主张所有的SQL都用Java代码生成, ...
- linux 从一台服务器向另台服务器复制文件
使用scp命令: sudo scp -P 2222 username@192.168.0.200:/home/db/db_data.sql.gz /home/db/db_data.sql.gz scp ...
- Sublime设置html头部
1.Ctrl + N,新建一个文档:2.Ctrl + Shift + P,打开命令模式,再输入 sshtml 进行模糊匹配,将语法切换到html模式:3.输入 !,再按下 Tab键或者 Ctrl + ...
- python生成器三元表达式
使用yield返回 例如: def test(): yield 1 yield 2 yield 3 yield 4 v = test() print(v.__next__()) print(v.__ ...
- Spark教程——(3)编写spark-shell测试Demo
创建一个文件aa.txt,随便写点内容: hello world! aa aa d d dg g 登录HDFS文件系统: [root@node1 ~]# su hdfs 在HDFS文件系统中创建文件目 ...
- JS截取腾讯视频和去除视频广告
一:腾讯视频截取 H5视频播放除了video标签以外,还有iframe嵌套视频 项目需求是用户输入腾讯视频的html链接,如 https://v.qq.com/x/page/y0116k2vspw.h ...
- JS原生编写实现留言板功能
实现这个留言板功能比较简单,所以先上效果图: 实现用户留言内容,留言具体时间. <script> window.onload = function(){ var oMessageBox = ...
- saveToken介绍二
Struts的Token(令牌)机制能够很好的解决表单重复提交的问题,基本原理是:服务器端在处理到达的请求之前,会将请求中包含的令牌值与保存在当前用户会话中的令牌值进行比较,看是否匹配.在处理完该 ...
- 题解 P5043 【【模板】树同构([BJOI2015]树的同构)】
进入正题 题意:将所有树结构相同的树归类. 思路 嗯,这道题让我们把树的结构归类,自然而然就想到了哈希,我们对这整颗树哈希一遍.然后判同构就十分之简单了.只需要找哈希值一样的树就可以了. 其实真得很简 ...