/****************Apollo源码分析****************************
Copyright 2018 The File Authors & zouyu. All Rights Reserved.
Contact with: 1746430162@qq.com 181663309504
源码主要是c++实现的,也有少量python,git下载几百兆,其实代码不太多,主要是地图和数据了大量空间,主要程序
在apollo/modules目录中,
在apollo/modules目录中,
我们把它分成以下几部分(具体说明见各目录下的modules):
感知:感知当前位置,速度,障碍物等等
Apollo/modules/perception
预测:对场景下一步的变化做出预测
Apollo/modules/prediction
规划:
(1) 全局路径规划:通过起点终点计算行驶路径
Apollo/modules/routing
(2) 规划当前轨道:通过感知,预测,路径规划等信息计算轨道
Apollo/modules/planning
(3) 规划转换成命令:将轨道转换成控制汽车的命令(加速,制动,转向等)
Apollo/modules/control
其它
(1) 输入输出
i. Apollo/modules/drivers 设备驱动
ii. Apollo/modules/localization 位置信息
iii. Apollo/modules/monitor 监控模块
iv. Apollo/modules/canbus 与汽车硬件交互
v. Apollo/modules/map 地图数据
vi. Apollo/modules/third_party_perception 三方感知器支持
(2) 交互
i. Apollo/modules/dreamview 可视化模块
ii. Apollo/modules/hmi 把汽车当前状态显示给用户
(3) 工具
i. Apollo/modules/calibration 标注工具
ii. Apollo/modules/common 支持其它模块的公共工具
iii. Apollo/modules/data 数据工具
iv. Apollo/modules/tools 一些Python工具
(4) 其它
i. Apollo/modules/elo 高精度定位系统,无源码,但有文档
ii. Apollo/modules/e2e 收集传感器数据给PX2,ROS
自动驾驶系统先通过起点终点规划出整体路径(routing);然后在行驶过程中感知(perception)当前环境
(识别车辆行人路况标志等),并预测下一步发展;然后把已知信息都传入规划模块(planning),规划出之后的轨道;
控制模块(control)将轨道数据转换成对车辆的控制信号,通过汽车交互模块(canbus)控制汽车.
(识别车辆行人路况标志等),并预测下一步发展;然后把已知信息都传入规划模块(planning),规划出之后的轨道;
控制模块(control)将轨道数据转换成对车辆的控制信号,通过汽车交互模块(canbus)控制汽车.
我觉得这里面算法技术含量最高的是感知perception和规划planning,具体请见本博客中各模块的分析代码。
/****************************************************************************************
/******************************************************************************
* Copyright 2017 The Apollo Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*****************************************************************************/
#include "modules/common/adapters/adapter.h"
#include <cmath>
#include <string>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "modules/common/adapters/adapter_gflags.h"
#include "modules/localization/proto/localization.pb.h"
namespace apollo {
namespace common {
namespace adapter {
using IntegerAdapter = Adapter<int>;
TEST(AdapterTest, Empty) {
IntegerAdapter adapter("Integer", "integer_topic", 10);
EXPECT_TRUE(adapter.Empty());
}
TEST(AdapterTest, Observe) {
IntegerAdapter adapter("Integer", "integer_topic", 10);
adapter.OnReceive(173);
// Before calling Observe.
EXPECT_TRUE(adapter.Empty());
// After calling Observe.
adapter.Observe();
EXPECT_FALSE(adapter.Empty());
}
TEST(AdapterTest, GetLatestObserved) {
IntegerAdapter adapter("Integer", "integer_topic", 10);
adapter.OnReceive(173);
adapter.Observe();
EXPECT_FALSE(adapter.Empty());
EXPECT_EQ(173, adapter.GetLatestObserved());
adapter.OnReceive(5);
adapter.OnReceive(7);
// Before calling Observe() again.
EXPECT_FALSE(adapter.Empty());
EXPECT_EQ(173, adapter.GetLatestObserved());
adapter.Observe();
// After calling Observe() again.
EXPECT_FALSE(adapter.Empty());
EXPECT_EQ(7, adapter.GetLatestObserved());
}
TEST(AdapterTest, History) {
IntegerAdapter adapter("Integer", "integer_topic", 3);
adapter.OnReceive(1);
adapter.OnReceive(2);
adapter.Observe();
{
// Currently the history contains [2, 1].
std::vector<IntegerAdapter::DataPtr> history(adapter.begin(),
adapter.end());
EXPECT_EQ(2, history.size());
EXPECT_EQ(2, *history[0]);
EXPECT_EQ(1, *history[1]);
}
adapter.OnReceive(0);
adapter.OnReceive(0);
adapter.OnReceive(0);
adapter.OnReceive(0);
adapter.OnReceive(0);
adapter.OnReceive(0);
adapter.OnReceive(0);
adapter.OnReceive(3);
adapter.OnReceive(4);
adapter.OnReceive(5);
{
// Although there are more messages, without calling Observe,
// the history is still [2, 1].
std::vector<IntegerAdapter::DataPtr> history(adapter.begin(),
adapter.end());
EXPECT_EQ(2, history.size());
EXPECT_EQ(2, *history[0]);
EXPECT_EQ(1, *history[1]);
}
adapter.Observe();
{
// After calling Observe(), the history starts from 5. Since we only
// maintain 3 elements in this adapter, 1 and 2 will be thrown out.
//
// History should be 5, 4, 3.
std::vector<IntegerAdapter::DataPtr> history(adapter.begin(),
adapter.end());
EXPECT_EQ(3, history.size());
EXPECT_EQ(5, *history[0]);
EXPECT_EQ(4, *history[1]);
EXPECT_EQ(3, *history[2]);
}
}
TEST(AdapterTest, Callback) {
IntegerAdapter adapter("Integer", "integer_topic", 3);
// Set the callback to act as a counter of messages.
int count = 0;
adapter.AddCallback([&count](int x) { count += x; });
adapter.OnReceive(11);
adapter.OnReceive(41);
adapter.OnReceive(31);
EXPECT_EQ(11 + 41 + 31, count);
}
using MyLocalizationAdapter = Adapter<localization::LocalizationEstimate>;
TEST(AdapterTest, Dump) {
FLAGS_enable_adapter_dump = true;
std::string temp_dir = std::getenv("TEST_TMPDIR");
MyLocalizationAdapter adapter("local", "local_topic", 3, temp_dir);
localization::LocalizationEstimate loaded;
localization::LocalizationEstimate msg;
msg.mutable_header()->set_sequence_num(17);
adapter.OnReceive(msg);
apollo::common::util::GetProtoFromASCIIFile(temp_dir + "/local/17.pb.txt",
&loaded);
EXPECT_EQ(17, loaded.header().sequence_num());
msg.mutable_header()->set_sequence_num(23);
adapter.OnReceive(msg);
apollo::common::util::GetProtoFromASCIIFile(temp_dir + "/local/23.pb.txt",
&loaded);
EXPECT_EQ(23, loaded.header().sequence_num());
}
} // namespace adapter
} // namespace common
} // namespace apollo
/******************************************************************************
* Copyright 2017 The Apollo Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*****************************************************************************/
#include
"modules/common/adapters/adapter.h"
#include
<cmath>
#include
<string>
#include
"gmock/gmock.h"
#include
"gtest/gtest.h"
#include
"modules/common/adapters/adapter_gflags.h"
#include
"modules/localization/proto/localization.pb.h"
namespace
apollo
{
namespace
common
{
namespace
adapter
{
using
IntegerAdapter
=
Adapter
<
int
>
;
TEST
(AdapterTest, Empty) {
//适配器测试
IntegerAdapter
adapter
(
"Integer"
,
"integer_topic"
,
10
);
EXPECT_TRUE
(adapter.
Empty
());
}
TEST
(AdapterTest, Observe) {
IntegerAdapter
adapter
(
"Integer"
,
"integer_topic"
,
10
);
adapter.
OnReceive
(
173
);
// Before calling Observe.
EXPECT_TRUE
(adapter.
Empty
());
// After calling Observe.
adapter.
Observe
();
EXPECT_FALSE
(adapter.
Empty
());
}
TEST
(AdapterTest, GetLatestObserved) {
//获得消息队列中最新的消息。
IntegerAdapter
adapter
(
"Integer"
,
"integer_topic"
,
10
);
adapter.
OnReceive
(
173
);
adapter.
Observe
();
EXPECT_FALSE
(adapter.
Empty
());
EXPECT_EQ
(
173
, adapter.
GetLatestObserved
());
adapter.
OnReceive
(
5
);
adapter.
OnReceive
(
7
);
// Before calling Observe() again.
EXPECT_FALSE
(adapter.
Empty
());
EXPECT_EQ
(
173
, adapter.
GetLatestObserved
());
adapter.
Observe
();
// After calling Observe() again.
EXPECT_FALSE
(adapter.
Empty
());
EXPECT_EQ
(
7
, adapter.
GetLatestObserved
());
}
TEST
(AdapterTest, History) {
IntegerAdapter
adapter
(
"Integer"
,
"integer_topic"
,
3
);
adapter.
OnReceive
(
1
);
adapter.
OnReceive
(
2
);
adapter.
Observe
();
{
// Currently the history contains [2, 1].
std::vector
<
IntegerAdapter::DataPtr
>
history
(adapter.
begin
(),
adapter.
end
());
EXPECT_EQ
(
2
, history.
size
());
EXPECT_EQ
(
2
,
*
history[
0
]);
EXPECT_EQ
(
1
,
*
history[
1
]);
}
adapter.
OnReceive
(
0
);
adapter.
OnReceive
(
0
);
adapter.
OnReceive
(
0
);
adapter.
OnReceive
(
0
);
adapter.
OnReceive
(
0
);
adapter.
OnReceive
(
0
);
adapter.
OnReceive
(
0
);
adapter.
OnReceive
(
3
);
adapter.
OnReceive
(
4
);
adapter.
OnReceive
(
5
);
{
// Although there are more messages, without calling Observe,
// the history is still [2, 1].
std::vector
<
IntegerAdapter::DataPtr
>
history
(adapter.
begin
(),
adapter.
end
());
EXPECT_EQ
(
2
, history.
size
());
EXPECT_EQ
(
2
,
*
history[
0
]);
EXPECT_EQ
(
1
,
*
history[
1
]);
}
adapter.
Observe
();
{
// After calling Observe(), the history starts from 5. Since we only
// maintain 3 elements in this adapter, 1 and 2 will be thrown out.
//
// History should be 5, 4, 3.
std::vector
<
IntegerAdapter::DataPtr
>
history
(adapter.
begin
(),
adapter.
end
());
EXPECT_EQ
(
3
, history.
size
());
EXPECT_EQ
(
5
,
*
history[
0
]);
EXPECT_EQ
(
4
,
*
history[
1
]);
EXPECT_EQ
(
3
,
*
history[
2
]);
}
}
TEST
(AdapterTest, Callback) {
IntegerAdapter
adapter
(
"Integer"
,
"integer_topic"
,
3
);
// Set the callback to act as a counter of messages.
int
count
=
0
;
adapter.
AddCallback
([
&
count](
int
x) { count
+=
x; });
adapter.
OnReceive
(
11
);
adapter.
OnReceive
(
41
);
adapter.
OnReceive
(
31
);
EXPECT_EQ
(
11
+
41
+
31
, count);
}
using
MyLocalizationAdapter
=
Adapter
<
localization::LocalizationEstimate
>
;
//实例化adapter.
/×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××
在这个头文件modules/common/adapters/adapter.h中会有一个adapter的基类:
Adapter(const std::string& adapter_name, const std::string& topic_name,
size_t message_num, const std::string& dump_dir = "/tmp")
××××××××××××××××××××××××××××××××××××8××/
/×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××
在这个头文件modules/common/adapters/adapter.h中会有一个adapter的基类:
Adapter(const std::string& adapter_name, const std::string& topic_name,
size_t message_num, const std::string& dump_dir = "/tmp")
××××××××××××××××××××××××××××××××××××8××/
TEST
(AdapterTest, Dump) {
FLAGS_enable_adapter_dump
=
true
;
std::string temp_dir
=
std::getenv
(
"TEST_TMPDIR"
);//测试数据缓存地址。
MyLocalizationAdapter
adapter
(
"local"
,
"local_topic"
,
3
, temp_dir);//local适配器名称。
//local_topic会话名称。 3代表消息数量。
//temp_dir数据缓存地址。
//local_topic会话名称。 3代表消息数量。
//temp_dir数据缓存地址。
localization::LocalizationEstimate loaded;//定位数据实例化。
localization::LocalizationEstimate msg;//消息实例化。
msg.
mutable_header
()->
set_sequence_num
(
17
);//消息数量。
adapter.
OnReceive
(msg);//消息接收。
apollo::common::util::GetProtoFromASCIIFile
(temp_dir
+
"/local/17.pb.txt"
,
&
loaded);//装载缓存文件
EXPECT_EQ
(
17
, loaded.
header
().
sequence_num
());
msg.
mutable_header
()->
set_sequence_num
(
23
);
adapter.
OnReceive
(msg);
apollo::common::util::GetProtoFromASCIIFile
(temp_dir
+
"/local/23.pb.txt"
,
&
loaded);
EXPECT_EQ
(
23
, loaded.
header
().
sequence_num
());
}
}
// namespace adapter
}
// namespace common
}
// namespace apollo