Cyber RT 之 Timer Component 实践(apollo 9.0)

devtools/2024/10/21 6:21:48/

实验内容

Component 是 Cyber RT 提供的用来构建功能模块的基础类,Component 有两种类型,分别为 Component 和 TimerComponent。

相较于 Component,TimerComponent 不提供消息融合,也不由消息触发运行,而是由系统定时调用,可用来执行一些例行任务。

本实验将编写一个 TimerComponent 实例,来模拟传感器产生数据。

实验流程

创建TimerComponent模板实例

进入apollo容器,终端执行以下命令,创建实验代码目录

buildtool create --template timer_component component/timer_component_sensor

最终生成component目录,其目录结构如下:

./component/
`-- timer_component_sensor|-- BUILD|-- conf|   |-- timer_component_sensor.conf|   `-- timer_component_sensor.pb.txt|-- cyberfile.xml|-- dag|   `-- timer_component_sensor.dag|-- launch|   `-- timer_component_sensor.launch|-- proto|   |-- BUILD|   `-- timer_component_sensor.proto|-- timer_component_sensor_component.cc`-- timer_component_sensor_component.h
  • BUILD 文件为 TimerComponent 的源码编译的规则文件
  • conf 目录下
    • timer_component_sensor.conf为全局变量配置文件
    • timer_component_sensor.pb.txt为用户在 proto 文件中定义的可配置项的配置文件
    • cyberfile.xmltimer_component_sensor功能包的描述文件
    • dag 目录下的timer_component_sensor.dag文件中描述了timer_component_sensor功能包的依赖关系
  • launch 文件夹下
    • timer_component_sensor.launchtimer_component_sensor功能包的 launch 启动文件
  • proto 文件夹下的
    • BUILD 为用户在 proto 文件夹下定义的 protobuffer 文件的编译规则文件
    • timer_component_sensor.proto文件中用户可以定义自己的消息结构
    • timer_component_sensor.cctimer_component_sensor.h两个文件为 TimerComponent 的源文件和头文件。

定义消息结构 

timer_component_sensor.proto中,添加以下消息数据结构。

syntax = "proto2";package apollo;// message type of channel, just a placeholder for demo,
// you should use `--channel_message_type` option to specify the real message type
//定义相机传感器的消息结构
message CameraSensorMsg {optional string content =1;//消息内容optional uint64 msg_id =2;//消息idoptional uint64 timestamp=3;//发送消息的时间戳
}//定义激光雷达传感器的消息结构
message LidarSensorMsg {optional string content =1;//消息内容optional uint64 msg_id =2;//消息idoptional uint64 timestamp=3;//发送消息的时间戳
}//配置TimerComponentSensorConfig的名称和输出数据的channel
message TimerComponentSensorConfig {optional string camera_name = 1;optional string camera_sensor_topic=2;optional string lidar_name=3;optional string lidar_sensor_topic=4;
};

 在 proto 文件夹下的 BUILD 文件中,添加 protobuffer 文件的编译规则。

load("//tools:apollo_package.bzl", "apollo_package")
load("//tools/proto:proto.bzl", "proto_library")
load("//tools:cpplint.bzl", "cpplint")package(default_visibility = ["//visibility:public"])proto_library(name = "timer_component_sensor_proto",srcs = ["timer_component_sensor.proto"],
)apollo_package()cpplint()

 配置TimerComponent的配置文件

timer_component_sensor.pb.txt中,配置timer_component_sensor.proto文件中定义的可配置项。

camera_name: "camera-sensor"
camera_sensor_topic: "/sensor/camera"lidar_name: "lidar-sensor"
lidar_sensor_topic: "/sensor/lidar"

编写TimerComponent的源文件

修改timer_component_sensor.h文件:

/******************************************************************************* Copyright 2023 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.*****************************************************************************//******************************************************************************* @file timer_component_sensor_component.h*****************************************************************************/#pragma once
#include <memory>#include "cyber/common/macros.h"
#include "cyber/component/component.h"
#include "cyber/component/timer_component.h"
#include "cyber/cyber.h"
#include "component/timer_component_sensor/proto/timer_component_sensor.pb.h"using apollo::cyber::Time;
using apollo::cyber::Writer;namespace apollo {class TimerComponentSensor final: public apollo::cyber::TimerComponent {public:bool Init() override;bool Proc() override;private:apollo::TimerComponentSensorConfig config_;//定义camera的消息writerstd::shared_ptr<Writer<CameraSensorMsg>> camera_sensor_writer_=nullptr;//定义lidar的消息writerstd::shared_ptr<Writer<LidarSensorMsg>> lidar_sensor_writer_=nullptr;
};CYBER_REGISTER_COMPONENT(TimerComponentSensor)} // namespace apollo

修改timer_component_sensor.cc`文件。

/******************************************************************************* Copyright 2023 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.*****************************************************************************//******************************************************************************* @file timer_component_sensor_component.cc*****************************************************************************/#include "component/timer_component_sensor/timer_component_sensor_component.h"namespace apollo {bool TimerComponentSensor::Init() {ACHECK(ComponentBase::GetProtoConfig(&config_))<< "failed to load timer_component_sensor config file "<< ComponentBase::ConfigFilePath();AINFO << "Load config succedded.\n" << config_.DebugString();//创建camera和lidar的writercamera_sensor_writer_=node_->CreateWriter<CameraSensorMsg>(config_.camera_sensor_topic().c_str());lidar_sensor_writer_=node_->CreateWriter<LidarSensorMsg> (config_.lidar_sensor_topic().c_str());AINFO << "Init TimerComponentSensor succedded.";return true;
}bool TimerComponentSensor::Proc() {AINFO << "Proc TimerComponentSensor triggered.";//封装camera消息static int i=0;auto camera_out_msg=std::make_shared<CameraSensorMsg>();camera_out_msg->set_msg_id(++i);camera_out_msg->set_content(config_.camera_name());camera_out_msg->set_timestamp(Time::Now().ToNanosecond());//将camera消息写入通道camera_sensor_writer_->Write(camera_out_msg);//封装lidar消息auto lidar_out_msg=std::make_shared<LidarSensorMsg>();lidar_out_msg->set_msg_id(++i);lidar_out_msg->set_content(config_.lidar_name());lidar_out_msg->set_timestamp(Time::Now().ToNanosecond());//写入lidar消息lidar_sensor_writer_->Write(lidar_out_msg);return true;
}} // namespace apollo

修改 BUILD 文件

load("//tools:apollo_package.bzl", "apollo_cc_library", "apollo_cc_binary", "apollo_package", "apollo_component")
load("//tools:cpplint.bzl", "cpplint")package(default_visibility = ["//visibility:public"])filegroup(name = "timer_component_sensor_files",srcs = glob(["dag/**","launch/**","conf/**",]),
)apollo_component(name = "libtimer_component_sensor_component.so",srcs = ["timer_component_sensor_component.cc",],hdrs = ["timer_component_sensor_component.h",],linkstatic = True,deps = ["//cyber","//component/timer_component_sensor/proto:timer_component_sensor_proto",],
)apollo_package()cpplint()

编译TimerComponent功能包

在终端中,执行以下指令,编译 timer_component_sensor 功能包。

root@in-dev-docker:/apollo_workspace# buildtool build  -p component/timer_component_sensor/

出现如下信息即为编译成功

修改启动配置

修改TimerComponent的dag文件

timer_component_sensor.dag文件中,将 interval 项的值改为 500,即每 500ms 运行一次。interval 值为 TimerComponent 的运行时间间隔。

module_config {module_library : "component/timer_component_sensor/libtimer_component_sensor_component.so"timer_components {class_name : "TimerComponentSensor"config {name: "timer_component_sensor"config_file_path:  "component/timer_component_sensor/conf/timer_component_sensor.pb.txt"flag_file_path:  "component/timer_component_sensor/conf/timer_component_sensor.conf"interval: 500}}
}

修改TimerComponent的launch文件

在<dag_conf>标签内的 dag 文件路径前加上“ ./ ” 。由于目前 cyber 与 apollo 绑定的比较紧密,编译完成后,系统会把编译产出及配置文件拷贝到 apollo 相应目录下,且执行文件时,系统会优先执行 apollo 目录下的文件,这样就会导致此处的配置无法起作用,这里加上“ ./ ”,就是告诉系统使用此处的 dag 文件来运行 component。

<cyber><module><name>communication</name><dag_conf>./communication/dag/communication.dag</dag_conf><process_name>communication</process_name></module>
</cyber>

运行TimerComponent

方式一:使用mainboard运行timer_component_sensor.dag文件

在终端中,输入以下指令,使用 mainboard 工具运行timer_component_sensor.dag文件,运行timer_component_sensor功能包。

mainboard -d ./component/timer_component_sensor/dag/timer_component_sensor.dag

方式二:使用cyber_launch运行timer_component_sensor.launch文件

在终端中,也可以使用 cyber_launch 工具运行timer_component_sensor.launch文件,运行timer_component_sensor功能包。

查看TimerComponent运行结果 

使用cyber_monitor工具查看timer_component_sensor运行结果。

新启一个终端窗口,在终端中输入执行 cyber_monitor 命令,启动cyber_monitor工具。

cyber_monitor

参考:

apollo.baidu.com/community/Apollo-Homepage-Document?doc=BYFxAcGcC4HpYIbgPYBtXIHQCMEEsATAV0wGNkBbWA5UyRFdZWVBEAU0hFgoIH0adPgCY%2BADwCiAVnEBBCeIAcATnETFcgMxKZkgGxKAwkoDsa3YoAi45WdGSLxsYt0SzY%2BXICMa98oAMSgYALF7%2B2NhemsLBJsrCYZqKwors7AikBIp6miYmpFJSXpigFKhAA

Apollo开发者社区_cyber专项课(9.0版)


http://www.ppmy.cn/devtools/127492.html

相关文章

《PyTorch深度学习快速入门教程》学习笔记(第17周)

目录 摘要 Abstract 1. Transforms用途 2. Transforms该如何使用 2.1 transforms.Totensor使用 2.2 需要Tensor数据类型原因 3. 常见的Transforms工具 3.1 __call__魔术方法使用 3.2 Normanize归一化 3.3 Resize裁剪 3.3.1 Resize裁剪方法一 3.3.2 Resize裁剪方法二…

Goland 搭建Gin脚手架

一、使用编辑器goland 搭建gin 打开编辑器 新建项目后 点击 create 二、获得Gin框架的代码 命令行安装 go get -u github.com/gin-gonic/gin 如果安装不上&#xff0c;配置一下环境 下载完成 官网git上下载 这样就下载完成了。、 不过这种方法需要设置一下GOPATH 然后再执…

基于multisim的高频谐振功率放大器设计与仿真

要求的技术指标为&#xff1a;输出功率Po≥125mW&#xff0c;工作中心频率fo6MHz&#xff0c;η>65%&#xff0c;已知&#xff1a;电源供电为12V&#xff0c;负载电阻,RL51Ω,晶体管用2N2219,其主要参数&#xff1a;Pcm1W,Icm750mA,VCES1.5V,fT70MHz,hfe≥10&#xff0c;功率…

KNN(K近邻算法)

k近邻&#xff0c;顾名思义&#xff0c;就是寻找距离测试点最近的 k 个点&#xff0c;根据这 k 个点的标签来判断该测试点的标签。   如下图所示&#xff0c;图中有10个样本点&#xff0c;若要对图中的绿点1分类&#xff0c;k近邻算法采用的策略是&#xff08;下图中 k 值为 …

探索Python中的多线程与多进程

在Python编程中&#xff0c;多线程和多进程是两个重要的概念&#xff0c;它们被用来提高程序的执行效率。本文将深入探讨这两个概念&#xff0c;并对比它们在Python中的实现方式。 一、多线程 多线程是一种并发执行的程序设计方法。在Python中&#xff0c;我们可以使用thread…

[Python学习日记-52] Python 中的 copy 模块 —— shutil

[Python学习日记-52] Python 中的 copy 模块 —— shutil 简介 shutil 模块 简介 在前面的学习当中&#xff0c;我们学习了如何在 Python 中创建文件&#xff0c;这个时候我们基本已经有了写程序的能力了&#xff0c;而有的时候我们也想使用 Python 来对文件进行更多的操作&a…

QT 软件打包为一个单独可执行.exe文件

将 QT 应用程序打包为一个独立的可执行文件 (.exe) 以便于分发通常包括以下几个步骤。以下是详细的流程和说明&#xff1a; 1. 准备环境 确保已经安装了以下软件&#xff1a; Qt SDK&#xff1a;可以从 Qt 官网 下载。Qt Creator&#xff1a;通常包含在 Qt SDK 中。MinGW 或…

一起搭WPF架构之livechart的MVVM使用介绍

一起搭WPF架构之livechart使用介绍 前言ModelViewModelView界面设计界面后端 效果总结 前言 简单的架构搭建已经快接近尾声了&#xff0c;考虑设计使用图表的形式将SQLite数据库中的数据展示出来。前期已经介绍了livechart的安装&#xff0c;今天就详细介绍一下livechart的使用…