当前位置:网站首页>ROS源代码阅读(1)
ROS源代码阅读(1)
2022-08-11 02:12:00 【斗转星移3】
ros工作空间创建教程
http://wiki.ros.org/kinetic/Installation/Source1、首先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
边栏推荐
- 【oops-framework】模板项目【oops-game-kit】使用简介
- 软件测试面试题:测试用例与测试脚本?
- 数论基础-整除(编程例题)
- TRCX: doping process analysis
- 八.数据的存储
- 通过热透镜聚焦的高斯光束
- 基于 HPSO 与多核 LSSVM 的网络入侵检测
- ARM development (4) How to read the chip manual for novice Xiaobai, bare metal driver development steps and pure assembly to achieve lighting, assembly combined with c lighting, c to achieve lighting
- Engineering Design of Single-sided PCB Routing Impedance
- 软件测试面试题:单元测试的策略有哪些?
猜你喜欢

八.数据的存储

gRPC闭包调度器

联盛德W801系列6-从微信小程序的角度来分析W801的蓝牙通信源码(indicate方式)
![报错处理:org.xml.sax.SAXParseException: 不允许有匹配 “[xX][mM][lL]“ 的处理指令目标](/img/35/650c92ac4c5fc2d5826f3216a09e65.png)
报错处理:org.xml.sax.SAXParseException: 不允许有匹配 “[xX][mM][lL]“ 的处理指令目标

paddle2.3和torch1.8在SentenceBert上的性能对比

从键入网址到网页显示的详细过程

年薪30W,BAT抢着要,懂面试技巧的测试人究竟多吃香?

最新国产电源厂家及具体型号pin-to-pin替代手册发布

本周四晚19:00知识赋能第六期第5课丨OpenHarmony WiFi子系统

ARM开发(四)新手小白如何阅读芯片手册,裸机驱动开发步骤以及纯汇编实现点灯,汇编结合c点灯,c实现点灯
随机推荐
年薪30W,BAT抢着要,懂面试技巧的测试人究竟多吃香?
漏洞管理计划的未来趋势
本周四晚19:00知识赋能第六期第5课丨OpenHarmony WiFi子系统
划分字母区间[贪心->空间换时间->数组hash优化]
隐私计算融合应用研究
MySQL - an SQL in MySQL is how to be performed?
WeChat public account background management
第二课第一周第4-6节 医学预后案例欣赏+作业解析
压力能变成动力
How to realize the repeatable design of FPGA
深度学习中的模型设计
Tomca启动闪退问题如何解决
[Detailed explanation of C data storage] (1) - in-depth analysis of the storage of shaping data in memory
comp3331-9331-22t1-midterm复习辅导-tutorial week 5
Lianshengde W801 series 6-Analyze the Bluetooth communication source code of W801 from the perspective of WeChat applet (indicate method)
The latest domestic power supply manufacturers and pin-to-pin replacement manuals for specific models are released
async和await的理解和用法
【websocket】
nvidia-smi:控制你的 GPU
redis学习五redis的持久化RDB,fork,copyonwrite,AOF,RDB&AOF混合使用