apollo_logo
9
0

第五章:使用Cyber RT进行相机仿真

实验内容

现需要实现车辆跟踪功能,摄像头以图片的方式采集到了道路信息,并在车流中锁定目标车辆,然后需要截取目标车辆所属的局部图片信息,再以话题的方式发布出去,请问应该如何实现?

因此本实验编写程序模拟摄像头驱动,要求该驱动可以发布仿真图像数据。并在DreamView中显示图像,结果如下图所示仿真了一张棋盘图片:

实验目的

该需求是一个典型的发布订阅实现,发布方是自实现程序,订阅方是DreamView,而被传输的数据则是图片消息,因此,该案例涉及的核心点有三个需要学习:

  1. 如何编写话题发布方?
  2. 如何组织图片消息?图片消息需要自定义吗?消息格式是怎样的?
  3. 如何使用DreamView显示订阅到的图片消息?

实验流程

在前面的教程中,我们已经系统性的学习过CyberRT的通信机制了,这其中就包含话题发布实现。而图片消息作为极其常用的一种消息载体,Apollo中已经内置了相关proto文件,我们直接调用即可。dremview作为一款可视化工具,我们只需了解并掌握其相关操作方式即可。该案例实现流程如下:

1. 安装DreamView;

2. 搭建项目框架;

3. 编写程序主逻辑;

4. 构建执行程序,并使用DreamView查看结果。

<1> 安装DreamView;

如果您还未安装DreamView,请参考如下链接进行安装并了解其使用:https://apollo.baidu.com/community/Apollo-Homepage-Document/Apollo_Doc_CN_8_0?doc=%2F%25E5%25AE%2589%25E8%25A3%2585%25E8%25AF%25B4%25E6%2598%258E%2F%25E8%25BD%25AF%25E4%25BB%25B6%25E5%258C%2585%25E5%25AE%2589%25E8%25A3%2585%2FQuickStart-%25E8%25BD%25AF%25E4%25BB%25B6%25E5%258C%2585%25E6%2596%25B9%25E5%25BC%258F

<2> 搭建项目框架;

2-1.创建工程目录,工程目录创建如下所示:

camera_demo
|-- driver
|-- camera_sim
| |-- BUILD
| |-- camera_driver.cc
|--BUILD
|--camera_demo.BUILD
|--cyberfile.xml

2-2.编辑包管理相关配置文件

包管理相关配置文件主要指camera_demo下的BUILD、camera_demo.BUILD以及cyberfile.xml。在BUILD文件中请输入如下内容:

load("//tools/install:install.bzl", "install", "install_src_files")
install(
name = "install",
data = [
"camera_demo.BUILD",
"cyberfile.xml",
],
deps = [
"//camera_demo/driver/camera_sim:install",
],
)
install_src_files(
name = "install_src",
src_dir = ["."],
dest = "camera_demo/src",
filter = "*",
deps = [
"//camera_demo/driver/camera_sim:install_src",
]
)

在cyberfile.xml中输入如下内容:

<package>
<name>camera_demo</name>
<version>1.0.0</version>
<description>
camera_demo
</description>
<maintainer email="AD-platform">AD-platform@baidu.com</maintainer>
<type>module</type>
<src_path>//camera_demo</src_path>
<license>BSD</license>
<author>Apollo</author>
<depend type="binary" repo_name="cyber">cyber-dev</depend>
<builder>bazel</builder>
</package>

2-3.编写源文件以及BUILD文件

在 camera_driver.cc 中请输入如下内容:

#include <cyber/cyber.h>
int main(int argc, char const *argv[])
{
apollo::cyber::Init(argv[0]);
AINFO << "相机仿真案例!";
return 0;
}

在 BUILD 文件中,请输入如下内容:

load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library")
load("//tools/install:install.bzl", "install", "install_src_files")
load("//tools:cpplint.bzl", "cpplint")
package(default_visibility = ["//visibility:public"])
# https://docs.bazel.build/versions/master/be/c-cpp.html#cc_library
cc_binary(
name = "camera_driver",
srcs = ["camera_driver.cc"],
deps = ["//cyber",
],
)
install(
name = "install",
runtime_dest = "camera_demo/bin",
targets = [
":camera_driver"
],
)
install_src_files(
name = "install_src",
src_dir = ["."],
dest = "camera_demo/src/cyberatest",
filter = "*",
)

2-4.测试

2-4.编译文件

在apollo_workspace目录下执行buildtool编译指令。

buildtool build -p camera_demo

编译完成后,系统会在/opt/apollo/neo/bin目录下生成可执行文件camera_driver

2-5.运行可执行文件

为了可以在终端输出运行日志,请先调用如下指令:

export GLOG_alsologtostderr=1

然后调用如下指令进入/opt/apollo/neo/bin/目录并执行可执行程序:

cd /opt/apollo/neo/bin/
./camera_driver

如果终端能够正常输出日志信息,说明框架搭建完毕。

<3> 编写程序主逻辑;

3-1. 修改 camera_driver.cc 为如下内容:

/*
需求: 发布摄像头仿真数据。
实现:
1.头文件;
2.初始化 cyber 框架;
3.创建节点;
4.创建发布者;
5.组织数据并发布;
6.等待关闭。
*/
#include "cyber/cyber.h"
#include "modules/common_msgs/sensor_msgs/sensor_image.pb.h"
using apollo::drivers::Image;
int main(int argc, char *argv[])
{
apollo::cyber::Init(argv[0]);
// 3.创建节点;
auto talker_node = apollo::cyber::CreateNode("camear_sim_node");
// 4.创建发布者;
auto talker = talker_node->CreateWriter<Image>("/image_sim");
// 5.组织数据并发布;
size_t width = 500;
size_t height = 350;
size_t cell = 50; // 单元格宽度
size_t step = width * 3; // 一行像素数
char black = 200;
char white = 10;
apollo::cyber::Rate rate(10.0);
while (apollo::cyber::OK())
{
// 组织数据
auto msg = std::make_shared<Image>();
msg->set_frame_id("camera");
auto now = apollo::cyber::Time::Now();
msg->set_measurement_time(now.ToSecond());
msg->set_width(width);
msg->set_height(height);
msg->set_encoding("rgb8");
msg->set_step(msg->width() * 3); // 一图片行的元素个数
size_t length = msg->width() * msg->height() * 3;
char value[length];
for (size_t i = 0; i < height; i++) // 遍历像素行
{
for (size_t j = 0; j < step; j++) // 遍历列
{
// 当前字节索引 value[i * step + j]
int index = i * step + j;
// 行赋值
if (i / cell % 2 == 0) // 偶数行
{
value[index] = black;
} else
{
value[index] = white;
}
// 列赋值
// 偶数列,无需更改
if (j / 3 / cell % 2 == 1) // 奇数列,取反
{
value[index] = value[index] == white ? black : white;
}
}
}
msg->set_data(value);
//发布
talker->Write(msg);
rate.Sleep();
}
// 6.等待关闭。
apollo::cyber::WaitForShutdown();
return 0;
}

3-2. 修改 BUILD 文件,要在 cc_binary 中添加图片相关 proto 依赖,修改后如下所示:

cc_binary(
name = "camera_driver",
srcs = ["camera_driver.cc"],
deps = ["//cyber",
"//modules/common_msgs/sensor_msgs:sensor_image_cc_proto",
],
)

<4> 构建执行程序,并使用DreamView查看结果。

程序编写完毕,具体运行步骤如下:
4-1. 请首先参考第2-4 、2-5所示,编译并运行程序。
4-2. 打开新的终端,启动DreamView:

aem bootstrap start

4-3. 在浏览器中输入http://localhost:8888,访问 DreamView:

4-4. 然后做如下操作:

  • 打开 Sim Control 按钮;
  • 打开 Camera Sensor 按钮;
  • 右侧的 Camera View 面板中打开话题下拉列表并设置为 /image_sim,则将显示图片信息,如下图:

至此,实验结束。

原创声明,本文由作者授权发布于Apollo开发者社区,未经许可,不得转载。
发表评论已发表 0 条评论
登录后可评论,请前往 登录
暂无评论~快去发表自己的独特见解吧!
目录
实验内容
实验目的
实验流程
<1> 安装DreamView;
<2> 搭建项目框架;
<3> 编写程序主逻辑;
<4> 构建执行程序,并使用DreamView查看结果。