
ROS源代码阅读(1)
ros源码阅读
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几种数据定义:
roscpp_core/cpp_common/include/ros/datatypes.h
typedef std::vector<std::pair<std::string, std::string> > VP_string;
typedef std::vector<std::string> V_string;
typedef std::set<std::string> S_string;
typedef std::map<std::string, std::string> M_string;
typedef std::pair<std::string, std::string> StringPair;
参考自:
ROS源代码阅读(1):找切入点_正心公子的博客-CSDN博客https://blog.csdn.net/wanghuiquan0712/article/details/78010697
更多推荐
所有评论(0)