Cyber RT 之 Timer Component 实践(apollo 9.0)

news2024/11/26 12:35:16

实验内容

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;//消息id
  optional uint64 timestamp=3;//发送消息的时间戳
}

//定义激光雷达传感器的消息结构
message LidarSensorMsg {
  optional string content =1;//消息内容
  optional uint64 msg_id =2;//消息id
  optional 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的消息writer
  std::shared_ptr<Writer<CameraSensorMsg>> camera_sensor_writer_=nullptr;
  //定义lidar的消息writer
  std::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的writer
  camera_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.coloradmin.cn/o/2219730.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

UE5 gameplay学习 蓝图0 level blueprint

首先在左上角这个位置可以创建一个这个蓝图 我理解这个蓝图适合做全局事件规划啥的 在场景选中一个物体&#xff0c;右侧面板拿到他&#xff0c;直接拖入蓝图&#xff0c;就能操作他了 这里获取到了这个物体&#xff0c;在gamebegin的时候把Z加了500 执行播放的时候能看见他从…

Windows API 一 ----起步

目录 1.介绍主函数入口参数。 2. 简单介绍 Windows.h 这个头文件 小结&#xff0c;也聊一聊 1.介绍主函数入口参数。 第一个参数: HINSTANCE 类型的 参数&#xff0c; 称为“实例句柄“&#xff0c;这个参数唯一标志了我们写的这个程序。 第二个参数&#xff1a; HINSTANCE…

poisson过程——随机模拟(Python和R实现)

Python实现 exponential()使用&#xff0c;自动poisson过程实现。 import numpy as np import matplotlib.pyplot as plt# Parameters lambda_rate 5 # rate parameter (events per time unit) T 10 # total time# Generate Poisson process times np.random.exponential(…

k8s系列-Rancher 上操作的k8s容器网络配置总结

Rancher 上操作的k8s容器网络配置总结 要在 Rancher 中配置Spring Boot 应用 ykhd-zhjgyw-xpwfxfjfl 服务&#xff0c;正确的配置方式如下&#xff1a; 1. 应用程序监听端口 在 application.yaml 文件中&#xff0c;配置的应用监听端口是 10001&#xff0c;并且应用的上下文…

Mycat 详细介绍及入门实战,解决数据库性能问题

一、基本原理 1、数据分片 &#xff08;1&#xff09;、水平分片 Mycat 将一个大表的数据按照一定的规则拆分成多个小表&#xff0c;分布在不同的数据库节点上。例如&#xff0c;可以根据某个字段的值进行哈希取模&#xff0c;将数据均匀的分布到不同的节点上。 这样做的好处…

美摄科技云服务解决方案,方案成熟,接入简单

美摄科技作为视频处理领域的先锋&#xff0c;凭借其强大的技术实力和深厚的行业经验&#xff0c;推出了成熟的云服务解决方案&#xff0c;为轻量化视频制作开辟了全新的道路。 一、成熟方案&#xff0c;接入无忧 美摄科技云服务解决方案的最大亮点在于其成熟度和易用性。我们…

RabbitMQ 入门(四)SpringAMQP五种消息类型(Work Queue)

一、WorkQueue(工作消息队列) Work queues&#xff0c;也被称为&#xff08;Task queues&#xff09;&#xff0c;任务模型。简单来说就是让多个消费者绑定到一个队列&#xff0c;共同消费队列中的消息。 当消息处理比较耗时的时候&#xff0c;可能生产消息的速度会远远大于…

react里实现左右拉伸实战

封装组件&#xff1a; 新建一个resizeBox.tsx文件写上代码如下&#xff1a; import React, { ReactNode, useState, useEffect, useRef } from react; import styles from "./resizeBox.less"; interface ResizableBoxProps {/*** 盒子的宽度*/widthNum?: number;…

比较相同机器上 redis和mysql分别单独承载的 最大连接数量

在相同的机器上&#xff0c;Redis 和 MySQL 的最大连接数量会受到硬件配置&#xff08;如 CPU、内存、网络等&#xff09;、配置参数和应用场景的影响。以下是对 Redis 和 MySQL 在单机环境下最大连接数的比较&#xff1a; Redis 最大连接数量 默认配置&#xff1a; Redis 默…

【2024最新版】网络安全学习路线-适合入门小白

首先说明&#xff0c;我是一名CTF的web手&#xff0c;这是我自己亲身学习网络安全的路线&#xff0c;希望能够帮到大家&#xff0c;我虽然不是大牛&#xff0c;但我也希望能够帮助一些网安小白找到自己学习的方向&#xff0c;后面有就业的详细安全技术要求&#xff0c;如果真想…

yolov8实例分隔

1.查看显卡型号 2.在https://en.wikipedia.org/wiki/CUDA上查看显卡算力&#xff0c;这里显卡为1650&#xff0c;算力为7.5 3.查看显卡算力对应的cuda版本 4slurm上该怎么办&#xff1f; 查看slurm上计算节点cuda版本 查看cuda版本 srun -A 2022099 -J job1 -p Gnode --…

【Echarts 实战指南】解锁动态历史曲线之谜

在工作中&#xff0c;大家是否曾遇到过这样一种需求呢&#xff1f;需获取设备最近 10 分钟的历史数据。设备实时数据每 2 秒推送一次&#xff0c;且要把历史数据曲线变成动态变化的状态。倘若设备最近 10 分钟的历史数据为 20 个点&#xff0c;那么现在每 2 秒就要将最前面的点…

Java爬虫:获取直播带货数据的实战指南

在当今数字化时代&#xff0c;直播带货已成为电商领域的新热点&#xff0c;通过直播平台展示商品并进行销售&#xff0c;有效促进了产品的曝光和销售量的提升。然而&#xff0c;如何在直播带货过程中进行数据分析和评估效果&#xff0c;成为了摆在商家面前的一个重要问题。本文…

工业相机有哪些应用场景

工业相机具有高性能、高稳定性和高可靠性的特点&#xff0c;因此在众多工业领域都有广泛的应用场景。以下是朗观视觉小编总结的一些典型的应用场景&#xff1a; 机器视觉与自动化&#xff1a; 工业相机在机器视觉系统中起着核心作用&#xff0c;用于捕捉和分析物体的图像&#…

【Linux】从多线程同步到生产者消费者模型:多线程编程实践

目录 1.线程的同步 1.1.为什么需要线程的同步&#xff1f; 2.2.条件变量的接口函数 2.生产消费模型 2.1 什么是生产消费模型 2.2.生产者消费者模型优点 2.3.为何要使用生产者消费者模型 3.基于BlockingQueue的生产者消费者模型 3.1为什么要将if判断变成while&#xff…

API的力量:解决编程技术问题的利器

在软件开发的世界里&#xff0c;编程技术问题无处不在。从数据获取到用户认证&#xff0c;从支付处理到地图服务&#xff0c;这些问题的解决方案往往需要深厚的专业知识和大量的开发时间。然而&#xff0c;应用程序编程接口&#xff08;API&#xff09;的出现&#xff0c;为开发…

架构师备考-背诵精华(系统架构设计)

软件架构风格 类型 子类型 说明 数据流风格 批处理 每个处理步骤是一个单独的程序&#xff0c;每一步必须在前一步结束后才能开始&#xff0c;而且数据必须是完整的&#xff0c;以整体的方式传递。 前面的构件处理完&#xff0c;后面构件才能处理&#xff1b;数据完整传输…

(五)若使用LQR控制小车倒立摆,该如何对小车和摆杆的动力学方程线性化?哪些变量是可以进行简化的,线性化后的状态空间方程应该怎么列写

写在前面&#xff1a; 关于lqr控制的讲解&#xff0c;可以观看如下三个视频&#xff1a; 2. LQR数学公式理解_哔哩哔哩_bilibili 如何感性地理解LQR控制&#xff1f;_哔哩哔哩_bilibili LQR简介与使用_哔哩哔哩_bilibili 正文&#xff1a; 在之前系列的文章中我们已经得出…

scala 抽象类

理解抽象类 抽象的定义 定义一个抽象类 &#xff1a;abstract class A {} idea实例 抽象类重写 idea实例 练习 1.abstract2.错3.abstract class A{}4.对

Redis应用高频面试题

Redis 作为一个高性能的分布式缓存系统,广泛应用于后端开发中,因此在后端研发面试中,关于 Redis 的问题十分常见。 本文整理了30个常见的 Redis 面试题目,涵盖了 Redis 的源码、数据结构、原理、集群模式等方面的知识,并附上简要的回答,帮助大家更好地准备相关的面试。 …