当前位置:网站首页>ROS源代码阅读(1)
ROS源代码阅读(1)
2022-08-11 02:12:00 【斗转星移3】
ros工作空间创建教程
http://wiki.ros.org/kinetic/Installation/Source
1、首先ros源码获取可以通过github获取:
https://github.com/ros/ros_comm
git clone https://github.com/ros/ros_comm.git
3、main入口函数
我们知道一个程序入口 都是从main开始的,那么我们就拿维基中ros的一个例程来讲
源码地址:
http://wiki.ros.org/ROS/Tutorials/WritingServiceClient%28c%2B%2B%29
1 #include "ros/ros.h"
2 #include "beginner_tutorials/AddTwoInts.h"
3
4 bool add(beginner_tutorials::AddTwoInts::Request &req,
5 beginner_tutorials::AddTwoInts::Response &res)
6 {
7 res.sum = req.a + req.b;
8 ROS_INFO("request: x=%ld, y=%ld", (long int)req.a, (long int)req.b);
9 ROS_INFO("sending back response: [%ld]", (long int)res.sum);
10 return true;
11 }
12
13 int main(int argc, char **argv)
14 {
15 ros::init(argc, argv, "add_two_ints_server");
16 ros::NodeHandle n;
17
18 ros::ServiceServer service = n.advertiseService("add_two_ints", add);
19 ROS_INFO("Ready to add two ints.");
20 ros::spin();
21
22 return 0;
23 }
main进来就调用了ros::init(argc, argv, "add_two_ints_server");,这个就是可以去ros源码
ros_comm/clients /roscpp/src/init.cpp 中找到入口函数
void init(int& argc, char** argv, const std::string& name, uint32_t options)
如果你看别人写程序也基本都有ros::init(argc, argv, "add_two_ints_server");基本上可以确认这个就是入函数
4、命令行传参
我们在去维基查看ros的命令行使用:
http://wiki.ros.org/ROS/Tutorials/UnderstandingNodes
rosrun turtlesim turtlesim_node __name:=my_turtle
这个使用方法有:=,这个就对应到函数init(int& argc, char** argv, const std::string& name, uint32_t options)中里面的下面的源代码,查找到:=并把:=两边的字符串存在remappings中
for (int i = 0; i < argc; )
{
std::string arg = argv[i];
size_t pos = arg.find(":=");
if (pos != std::string::npos)
{
std::string local_name = arg.substr(0, pos);
std::string external_name = arg.substr(pos + 2);
ROSCPP_LOG_DEBUG("remap: %s => %s", local_name.c_str(), external_name.c_str());
remappings[local_name] = external_name;
// shuffle everybody down and stuff this guy at the end of argv
char *tmp = argv[i];
for (int j = i; j < full_argc - 1; j++)
argv[j] = argv[j+1];
argv[argc-1] = tmp;
argc--;
}
else
{
i++; // move on, since we didn't shuffle anybody here to replace it
}
}
ros源码注释
//入口函数
void init(int& argc, char** argv, const std::string& name, uint32_t options)
{
//追踪M_string可以看到定义typedef std::map<std::string, std::string> M_string;
M_string remappings;
int full_argc = argc;
// now, move the remapping argv's to the end, and decrement argc as needed
//将程序运行传入参数转换为remapping
for (int i = 0; i < argc; )
{
std::string arg = argv[i];
size_t pos = arg.find(":=");
if (pos != std::string::npos)
{
std::string local_name = arg.substr(0, pos);
std::string external_name = arg.substr(pos + 2);
ROSCPP_LOG_DEBUG("remap: %s => %s", local_name.c_str(), external_name.c_str());
remappings[local_name] = external_name;
// shuffle everybody down and stuff this guy at the end of argv
char *tmp = argv[i];
for (int j = i; j < full_argc - 1; j++)
argv[j] = argv[j+1];
argv[argc-1] = tmp;
argc--;
}
else
{
i++; // move on, since we didn't shuffle anybody here to replace it
}
}
//将程序运行传入参数转换为remapping后调用另一个init函数
init(remappings, name, options);
}
//转换传入参数为remapping后调用调用此函数
void init(const M_string& remappings, const std::string& name, uint32_t options)
{
if (!g_atexit_registered)
{
g_atexit_registered = true;
//atexit函数是一个特殊的函数,它是在正常程序退出时调用的函数,我们把他叫为登记函数,
// 一个进程可以登记32个函数,这些函数由exit自动调用,这些函数被称为终止处理函数,
//atexit函数可以登记这些函数。exit调用终止处理函数的顺序和atexit登记的顺序相反,
//如果一个函数被多次登记,也会被多次调用,也就是说退出时将调用atexitCallback这个函数。
atexit(atexitCallback);
}
if (!g_global_queue)
{
g_global_queue.reset(new CallbackQueue);
}
if (!g_initialized)
{
g_init_options = options;
g_ok = true;
ROSCONSOLE_AUTOINIT;
// Disable SIGPIPE
#ifndef WIN32
signal(SIGPIPE, SIG_IGN);
#endif
check_ipv6_environment();
//network相关的初始化
network::init(remappings);
//master相关的初始化
master::init(remappings);
// names:: namespace is initialized by this_node
this_node::init(name, remappings, options);
file_log::init(remappings);
param::init(remappings);
g_initialized = true;
}
}
参考自:
ROS源代码阅读(1):找切入点_正心公子的博客-CSDN博客https://blog.csdn.net/wanghuiquan0712/article/details/78010697
边栏推荐
猜你喜欢
Detailed explanation of common methods of filtering matrix (array) elements in Matlab
请讲一讲JS中的 for...in 与 for...of (下)
Deep Learning [Chapter 2]
【oops-framework】模板项目【oops-game-kit】使用简介
MySQL - an SQL in MySQL is how to be performed?
划分字母区间[贪心->空间换时间->数组hash优化]
[Detailed explanation of C data storage] (1) - in-depth analysis of the storage of shaping data in memory
Vulnhub靶机:GEMINI INC_ 2
报错处理:org.xml.sax.SAXParseException: 不允许有匹配 “[xX][mM][lL]“ 的处理指令目标
联盛德W801系列6-从微信小程序的角度来分析W801的蓝牙通信源码(indicate方式)
随机推荐
[Detailed explanation of C data storage] (1) - in-depth analysis of the storage of shaping data in memory
comp3331-9331-21t1-midterm复习
Please talk about for...in and for...of in JS (below)
Inter-process communication method (2) Named pipe
[4G/5G/6G专题基础-154]: 5G无线准入控制RAC(Radio Admission Control)
如何实现FPGA的可重复性设计
[oops-framework] Template project [oops-game-kit] Introduction
Geogebra 教程之 04 Geogebra 小程序
Shengxin experiment record (part2)--tf.reduce_sum() usage introduction
Engineering Design of Single-sided PCB Routing Impedance
软件测试面试题:性能测试工作?
生信实验记录(part2)--tf.reduce_sum()用法介绍
3342: String manipulation problem solving
如何解决高度塌陷
2022英伟达显卡排名天梯图
0图中等 LeetCode565. 数组嵌套
redis学习五redis的持久化RDB,fork,copyonwrite,AOF,RDB&AOF混合使用
comp3331-9331-22t1-midterm复习辅导-tutorial week 5
Deep Learning [Chapter 2]
学军中学推理社2017届招新试题