文章目录
前言
读书笔记,内容按照百度和北航出版的《自动驾驶平台基础》中的第五章练习,原书代码只给出关键部分,这里补全并提供结果展示。
1 功能介绍
基于障碍物的距离(Distance)与车速(Speed)的两个部件(Component)作为输入,经过算法cal1和cal2两个部件作算法过程处理,使用Control部件输出到CAN总线(AEB精简版)。
每个component连线相当于一个channel,CAN总线报文转换计算提供speed,Radar计算提供distance。speed和distance是基于时间触发的Timercomponent。二者提供cal1和cal2,cal1是当车速大于100时,通过/carstatus/speed2的channel向control发1(制动信号),cal2是当车速大于60且障碍物距离小于80,通过/carstatus/distance2的channel向control发1(否则输出0)。cal1/cal2/control是消息触发型的普通coponent。
2 代码
使用Apollo 3.5平台(Ubuntu18.04),参考《自动驾驶汽车软件计算框架》第五章的方法,对5个conponent新建文件夹,每个文件夹都包含 .cc源文件/.h头文件/.dag摘要文件/.lanuch启动文件/Build关联文件。五个conponent文件放置在/apollo/cyber/examples/conponent文件夹下。
2.1 speed
Build文件
load("//tools:cpplint.bzl", "cpplint")
package(default_visibility = ["//visibility:public"])
cc_binary(
name = "speed.so",
linkopts = ["-shared"],
linkstatic = False,
deps = [":speed_lib"],
)
cc_library(
name = "speed_lib",
srcs = [
"speed.cc",
],
hdrs = [
"speed.h",
],
deps = [
"//cyber",
"//cyber/examples/proto:examples_cc_proto",
],
)
cpplint()
speed.cc文件
#include "cyber/examples/component/speed/speed.h"
#include "cyber/class_loader/class_loader.h"
#include "cyber/component/component.h"
#include "cyber/examples/proto/examples.pb.h"
bool speed::Init() {
speed_writer_ = node_->CreateWriter<Chatter_Test>("/carstatus/speed1");
return true;
}
bool speed::Proc() {
static int i = 0;
auto out_msg = std::make_shared<Chatter_Test>();
out_msg->set_timestamp(i++);
out_msg->set_content(70);
// msg->set_content(content + std::to_string(seq - 1));
speed_writer_->Write(out_msg);
AINFO << "speed: Write drivermsg->"
<< out_msg->content();
return true;
}
Speed.dag文件
module_config {
module_library : "/apollo/bazel-bin/cyber/examples/component/speed/speed.so"
timer_components {
class_name : "speed"
config {
name : "speed"
interval : 1000
}
}
}
speed.h文件
#include <memory>
#include "cyber/class_loader/class_loader.h"
#include "cyber/component/component.h"
#include "cyber/component/timer_component.h"
#include "cyber/examples/proto/examples.pb.h"
using apollo::cyber::examples::proto::Chatter_Test;
using apollo::cyber::Component;
using apollo::cyber::ComponentBase;
using apollo::cyber::TimerComponent;
using apollo::cyber::Writer;
class speed : public TimerComponent {
public:
bool Init() override;
bool Proc() override;
private:
std::shared_ptr<Writer<Chatter_Test>> speed_writer_ = nullptr;
};
CYBER_REGISTER_COMPONENT(speed)
speed.launch文件
<cyber>
<module>
<name>speed</name>
<dag_conf>/apollo/cyber/examples/component/speed/speed.dag</dag_conf>
<process_name>speed</process_name>
</module>
</cyber>
2.2 distance
build文件
load("//tools:cpplint.bzl", "cpplint")
package(default_visibility = ["//visibility:public"])
cc_binary(
name = "distance.so",
linkopts = ["-shared"],
linkstatic = False,
deps = [":distance_lib"],
)
cc_library(
name = "distance_lib",
srcs = [
"distance.cc",
],
hdrs = [
"distance.h",
],
deps = [
"//cyber",
"//cyber/examples/proto:examples_cc_proto",
],
)
cpplint()
distance.cc文件
#include "cyber/examples/component/distance/distance.h"
#include "cyber/class_loader/class_loader.h"
#include "cyber/component/component.h"
#include "cyber/examples/proto/examples.pb.h"
bool distance::Init() {
distance_writer_ = node_->CreateWriter<Chatter_Test>("/carstatus/distance1");
return true;
}
bool distance::Proc() {
static int i = 0;
auto out_msg = std::make_shared<Chatter_Test>();
out_msg->set_timestamp(i++);
out_msg->set_content(70);
// msg->set_content(content + std::to_string(seq - 1));
distance_writer_->Write(out_msg);
AINFO << "distance: Write drivermsg->"
<< out_msg->content();
return true;
}
distance.dag文件
module_config {
module_library : "/apollo/bazel-bin/cyber/examples/component/distance/distance.so"
timer_components {
class_name : "distance"
config {
name : "distance"
interval : 1000
}
}
}
distance.h文件
#include <memory>
#include "cyber/class_loader/class_loader.h"
#include "cyber/component/component.h"
#include "cyber/component/timer_component.h"
#include "cyber/examples/proto/examples.pb.h"
using apollo::cyber::examples::proto::Chatter_Test;
using apollo::cyber::Component;
using apollo::cyber::ComponentBase;
using apollo::cyber::TimerComponent;
using apollo::cyber::Writer;
class distance : public TimerComponent {
public:
bool Init() override;
bool Proc() override;
private:
std::shared_ptr<Writer<Chatter_Test>>distance_writer_ = nullptr;
};
CYBER_REGISTER_COMPONENT(distance)
launch文件
<cyber>
<module>
<name>distance</name>
<dag_conf>/apollo/cyber/examples/component/distance/distance.dag</dag_conf>
<process_name>distance</process_name>
</module>
</cyber>
2.3 cal
build文件
load("//tools:cpplint.bzl", "cpplint")
package(default_visibility = ["//visibility:public"])
cc_binary(
name = "cal1.so",
linkopts = ["-shared"],
linkstatic = False,
deps = [":cal1_lib"],
)
cc_library(
name = "cal1_lib",
srcs = [
"cal1.cc",
],
hdrs = [
"cal1.h",
],
deps = [
"//cyber",
"//cyber/examples/proto:examples_cc_proto",
],
)
cpplint()
cal1.cc文件
#include "cyber/examples/component/cal1/cal1.h"
#include "cyber/time/rate.h"
#include "cyber/class_loader/class_loader.h"
#include "cyber/component/component.h"
#include "cyber/time/time.h"
#include "cyber/cyber.h"
#include "cyber/examples/proto/examples.pb.h"
using apollo::cyber::Rate;
using apollo::cyber::Time;
using apollo::cyber::examples::proto::Chatter_Test;
bool cal1::Init() {
AINFO << "cal1 component init";
cal1_writer_ = node_->CreateWriter<Chatter_Test>("/carstatus/speed2");
return true;
}
bool cal1::Proc(const std::shared_ptr<Chatter_Test>& msg0) {
AINFO << "Start cal1 component Proc [" << msg0->content() << "]";
static int i=0;
auto out_msg = std::make_shared<Chatter_Test>();
if(msg0->content()>100){
out_msg->set_content(1);
}
else{
out_msg->set_content(0);
}
out_msg->set_timestamp(i++);
cal1_writer_->Write(out_msg);
AINFO << "cal1: Write drivermsg->"
<< out_msg->content();
return true;
}
cal1.dag文件
# Define all coms in DAG streaming.
module_config {
module_library : "/apollo/bazel-bin/cyber/examples/component/cal1/cal1.so"
components {
class_name : "cal1"
config {
name : "common"
readers {
channel: "/carstatus/speed1"
}
}
}
}
cal1.h
#include <memory>
#include "cyber/class_loader/class_loader.h"
#include "cyber/component/component.h"
#include "cyber/examples/proto/examples.pb.h"
#include "cyber/component/timer_component.h"
using apollo::cyber::examples::proto::Chatter_Test;
using apollo::cyber::Component;
using apollo::cyber::TimerComponent;
using apollo::cyber::Writer;
class cal1:public Component<Chatter_Test> {
public:
bool Init() override;
bool Proc(const std::shared_ptr<Chatter_Test>& msg0 ) override;
private:
std::shared_ptr<Writer<Chatter_Test>>cal1_writer_= nullptr;
};
CYBER_REGISTER_COMPONENT(cal1)
cal1.launch
<cyber>
<module>
<name>cal1</name>
<dag_conf>/apollo/cyber/examples/component/cal1/cal1.dag</dag_conf>
<process_name>cal1</process_name>
</module>
</cyber>
2.4 cal2
build文件
load("//tools:cpplint.bzl", "cpplint")
package(default_visibility = ["//visibility:public"])
cc_binary(
name = "cal2.so",
linkopts = ["-shared"],
linkstatic = False,
deps = [":cal2_lib"],
)
cc_library(
name = "cal2_lib",
srcs = [
"cal2.cc",
],
hdrs = [
"cal2.h",
],
deps = [
"//cyber",
"//cyber/examples/proto:examples_cc_proto",
],
)
cpplint()
cal2.cc文件
#include "cyber/examples/component/cal2/cal2.h"
#include "cyber/time/rate.h"
#include "cyber/class_loader/class_loader.h"
#include "cyber/component/component.h"
#include "cyber/time/time.h"
#include "cyber/cyber.h"
#include "cyber/examples/proto/examples.pb.h"
using apollo::cyber::Rate;
using apollo::cyber::Time;
using apollo::cyber::examples::proto::Chatter_Test;
bool cal2::Init() {
AINFO << "cal2 component init";
cal2_writer_=node_->CreateWriter<Chatter_Test>("/carstatus/distance2");
return true;
}
bool cal2::Proc(const std::shared_ptr<Chatter_Test>& msg0 ,
const std::shared_ptr<Chatter_Test>& msg1 ) {
AINFO << "Start cal2 component Proc [" << msg0->content() << "] ["
<< msg1->content() << "]";
static int i=0;
auto out_msg = std::make_shared<Chatter_Test>();
if(msg0->content()>60&&msg1->content()<80){
out_msg->set_content(1);
}
else{
out_msg->set_content(0);
}
out_msg->set_timestamp(i++);
cal2_writer_->Write(out_msg);
AINFO<<"cal2:Write drivermsg->"
<<out_msg->content();
return true;
}
cal2.dag文件
# Define all coms in DAG streaming.
module_config {
module_library : "/apollo/bazel-bin/cyber/examples/component/cal2/cal2.so"
components {
class_name : "cal2"
config {
name : "common"
readers {
channel: "/carstatus/speed1"
}
readers {
channel: "/carstatus/distance1"
}
}
}
}
cal2.h文件
#include <memory>
#include "cyber/class_loader/class_loader.h"
#include "cyber/component/component.h"
#include "cyber/examples/proto/examples.pb.h"
#include "cyber/component/timer_component.h"
using apollo::cyber::examples::proto::Chatter_Test;
using apollo::cyber::Component;
using apollo::cyber::TimerComponent;
using apollo::cyber::Writer;
class cal2:public Component<Chatter_Test, Chatter_Test> {
public:
bool Init() override;
bool Proc(const std::shared_ptr<Chatter_Test>& msg0,
const std::shared_ptr<Chatter_Test>& msg1 ) override;
private:
std::shared_ptr<Writer<Chatter_Test>>cal2_writer_= nullptr;
};
CYBER_REGISTER_COMPONENT(cal2)
cal2.launch文件
<cyber>
<module>
<name>cal2</name>
<dag_conf>/apollo/cyber/examples/component/cal2/cal2.dag</dag_conf>
<process_name>cal2</process_name>
</module>
</cyber>
2.5 control
bulid文件
load("//tools:cpplint.bzl", "cpplint")
package(default_visibility = ["//visibility:public"])
cc_binary(
name = "control.so",
linkopts = ["-shared"],
linkstatic = False,
deps = [":control_lib"],
)
cc_library(
name = "control_lib",
srcs = [
"control.cc",
],
hdrs = [
"control.h",
],
deps = [
"//cyber",
"//cyber/examples/proto:examples_cc_proto",
],
)
cpplint()
control.cc文件
#include "cyber/examples/component/control/control.h"
#include "cyber/time/rate.h"
#include "cyber/class_loader/class_loader.h"
#include "cyber/component/component.h"
#include "cyber/time/time.h"
#include "cyber/cyber.h"
#include "cyber/examples/proto/examples.pb.h"
using apollo::cyber::Rate;
using apollo::cyber::Time;
using apollo::cyber::examples::proto::Chatter_Test;
bool control::Init() {
AINFO << "control component init";
control_writer_ = node_->CreateWriter<Chatter_Test>("/carstatus/control1");
return true;
}
bool control::Proc(const std::shared_ptr<Chatter_Test>& msg0,
const std::shared_ptr<Chatter_Test>& msg1 ) {
AINFO << "Start control component Proc [" << msg0->content() << "] ["
<< msg1->content() << "]";
static int i=0;
auto out_msg = std::make_shared<Chatter_Test>();
if(msg0->content()>0||msg1->content()>0){
out_msg->set_content(1);
}
else{
out_msg->set_content(0);
}
out_msg->set_timestamp(i++);
control_writer_->Write(out_msg);
AINFO<<"control:Write drivermsg->"
<<out_msg->content();
return true;
}
control.dag
# Define all coms in DAG streaming.
module_config {
module_library : "/apollo/bazel-bin/cyber/examples/component/control/control.so"
components {
class_name : "control"
config {
name : "common"
readers {
channel: "/carstatus/speed2"
}
readers {
channel: "/carstatus/distance2"
}
}
}
}
control.h文件
#include <memory>
#include "cyber/class_loader/class_loader.h"
#include "cyber/component/component.h"
#include "cyber/examples/proto/examples.pb.h"
#include "cyber/component/timer_component.h"
using apollo::cyber::examples::proto::Chatter_Test;
using apollo::cyber::Component;
using apollo::cyber::TimerComponent;
using apollo::cyber::Writer;
class control:public Component<Chatter_Test, Chatter_Test> {
public:
bool Init() override;
bool Proc(const std::shared_ptr<Chatter_Test>& msg0,
const std::shared_ptr<Chatter_Test>& msg1 ) override;
private:
std::shared_ptr<Writer<Chatter_Test>>control_writer_ = nullptr;
};
CYBER_REGISTER_COMPONENT(control)
control.launch文件
<cyber>
<module>
<name>speed</name>
<dag_conf>/apollo/cyber/examples/component/speed/speed.dag</dag_conf>
<process_name>speed</process_name>
</module>
<module>
<name>distance</name>
<dag_conf>/apollo/cyber/examples/component/distance/distance.dag</dag_conf>
<process_name>distance</process_name>
</module>
<module>
<name>cal1</name>
<dag_conf>/apollo/cyber/examples/component/cal1/cal1.dag</dag_conf>
<process_name>cal1</process_name>
</module>
<module>
<name>cal2</name>
<dag_conf>/apollo/cyber/examples/component/cal2/cal2.dag</dag_conf>
<process_name>cal2</process_name>
</module>
<module>
<name>control</name>
<dag_conf>/apollo/cyber/examples/component/control/control.dag</dag_conf>
<process_name>control</process_name>
</module>
</cyber>
2.6 proto
更新/apollo/cyber/examples/proto/examples.proto文件,增加message Chatter_Test (解决int和String转换问题)。
syntax = "proto2";
package apollo.cyber.examples.proto;
message SamplesTest1 {
optional string class_name = 1;
optional string case_name = 2;
};
message Chatter {
optional uint64 timestamp = 1;
optional uint64 lidar_timestamp = 2;
optional uint64 seq = 3;
optional bytes content = 4;
};
message Driver {
optional string content = 1;
optional uint64 msg_id = 2;
optional uint64 timestamp = 3;
};
message Chatter_Test {
optional uint64 timestamp = 1;
optional uint64 lidar_timestamp = 2;
optional uint64 seq = 3;
optional uint64 content = 4;
};
3 Apollo 运行
使用VS code 运行Docker,可参考优快云_知行合一2018
:使用Visual Studio Code编译、调试Apollo项目介绍的方法,只用到终端-运行生成任务这一步。
Apollo 运行相关步骤如下(在此之前已经使用Ubuntu终端正常运行Apollo):
// VS code 使用Docker运行Apollo(含root)
$ bash docker/scripts/dev_start.sh
$ bash docker/scripts/dev_into.sh
$ bash apollo.sh clean
$ cd ..
$ sudo passwd
$ su root
$ cd apollo
$ ./apollo.sh build cyber
//bash: cyber_launch: command not found, so I added “ source cyber/setup.bash”
$ source cyber/setup.bash
$ cyber_launch start cyber/examples/component/control/control.launch
4 结果展示
在VS code中新建终端,使用Cyber_monitor查看channel
$ cd ..
$ sudo passwd
$ su root
$ cd apollo
$ bash docker/scripts/dev_start.sh
$ bash docker/scripts/dev_into.sh
//$ source cyber/setup.bash
$ cyber_monitor -h
$ cyber_monitor
运行结果(提示通道命名重复,待优化):
5 Apollo 6.0平台代码更新方法
1)增加proto_test文件夹,更改examples.proto内容。
2)更改5个component涉及proto文件夹位置,例如BUILD。
load("//tools:cpplint.bzl", "cpplint")
package(default_visibility = ["//visibility:public"])
cc_binary(
name = "cal1.so",
linkopts = ["-shared"],
linkstatic = False,
deps = [":cal1_lib"],
)
cc_library(
name = "cal1_lib",
srcs = [
"cal1.cc",
],
hdrs = [
"cal1.h",
],
deps = [
"//cyber",
"//cyber/examples/proto_test:examples_cc_proto",
],
)
cpplint()
按照3.5的步骤运行即可。