Apollo 11.0
自动驾驶开放平台
message_writer.h
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2023 The Apollo Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *****************************************************************************/
16
21#pragma once
22
23#include <functional>
24#include <map>
25#include <memory>
26#include <string>
27#include <list>
28
29#include "cyber/common/macros.h"
30#include "cyber/cyber.h"
31#include "cyber/time/clock.h"
32
33namespace apollo { // namespace apollo
34namespace external_command { // namespace external_command
35
40 public:
42 const std::shared_ptr<cyber::WriterBase>& writer,
43 const std::shared_ptr<cyber::WriterBase>& history_writer = nullptr)
44 : writer_(writer),
45 history_writer_(history_writer),
46 last_message_(nullptr) {}
52 template <typename T>
53 bool Write(const T& message);
59 template <typename T>
60 bool Write(const std::shared_ptr<T>& message);
64 void WriteLastMessage();
65
66 private:
67 template <typename T>
68 void WriteHistoryMessage();
69
70 std::shared_ptr<cyber::WriterBase> writer_;
71 std::shared_ptr<cyber::WriterBase> history_writer_;
72 std::shared_ptr<google::protobuf::Message> last_message_;
73 std::function<void()> write_history_function_;
74};
75
76template <typename T>
77bool WriterHandle::Write(const T& message) {
78 auto* message_writer = dynamic_cast<cyber::Writer<T>*>(writer_.get());
79 if (nullptr == message_writer) {
80 return false;
81 }
82 message_writer->Write(message);
83 if (nullptr == last_message_) {
84 last_message_ = std::dynamic_pointer_cast<google::protobuf::Message>(
85 std::make_shared<T>());
86 write_history_function_ =
87 std::bind(&WriterHandle::WriteHistoryMessage<T>, this);
88 }
89 last_message_->CopyFrom(message);
90 return true;
91}
92
99template <typename T>
100bool WriterHandle::Write(const std::shared_ptr<T>& message) {
101 CHECK_NOTNULL(message);
102 return Write(*message);
103}
104
106 if (write_history_function_) {
107 write_history_function_();
108 }
109}
110
111template <typename T>
112void WriterHandle::WriteHistoryMessage() {
113 std::shared_ptr<cyber::Writer<T>> history_writer =
114 std::dynamic_pointer_cast<cyber::Writer<T>>(history_writer_);
115 if (nullptr == history_writer) {
116 ADEBUG << "History Writer type is not correct!";
117 return;
118 }
119 std::shared_ptr<T> message = std::dynamic_pointer_cast<T>(last_message_);
120 if (message == nullptr) {
121 ADEBUG << "History message type is not correct!";
122 return;
123 }
124 auto timestamp = apollo::cyber::Clock::NowInSeconds();
125 message->mutable_header()->set_timestamp_sec(timestamp);
126 history_writer->Write(message);
127}
128
130 public:
137 template <typename T>
138 std::shared_ptr<WriterHandle> RegisterMessage(
139 const std::string& channel_name,
140 const std::string& history_channel_name = "");
147 template <typename T>
148 std::shared_ptr<WriterHandle> RegisterMessage(
149 const cyber::proto::RoleAttributes& role_attr,
150 const std::string& history_channel_name = "");
151
152 private:
153 std::map<std::string, std::shared_ptr<WriterHandle>> writer_map_;
154 std::list<std::shared_ptr<WriterHandle>> history_writers_;
155 std::shared_ptr<cyber::Node> node_;
156 // Timer for sending history message for debug.
157 std::unique_ptr<::apollo::cyber::Timer> timer_;
158
160};
161
162template <typename T>
163std::shared_ptr<WriterHandle> MessageWriter::RegisterMessage(
164 const std::string& channel_name, const std::string& history_channel_name) {
165 auto existing_writer_iter = writer_map_.find(channel_name);
166 // Only register writer when it is not registered before.
167 if (existing_writer_iter == writer_map_.end()) {
168 auto writer = node_->CreateWriter<T>(channel_name);
169 if (history_channel_name != "") {
170 auto history_writer = node_->CreateWriter<T>(history_channel_name);
171 writer_map_[channel_name] =
172 std::make_shared<WriterHandle>(writer, history_writer);
173 history_writers_.emplace_back(writer_map_[channel_name]);
174 } else {
175 writer_map_[channel_name] = std::make_shared<WriterHandle>(writer);
176 }
177 return writer_map_[channel_name];
178 }
179 return existing_writer_iter->second;
180}
181
182template <typename T>
183std::shared_ptr<WriterHandle> MessageWriter::RegisterMessage(
184 const cyber::proto::RoleAttributes& role_attr,
185 const std::string& history_channel_name) {
186 const auto& channel_name = role_attr.channel_name();
187 auto existing_writer_iter = writer_map_.find(channel_name);
188 // Only register writer when it is not registered before.
189 if (existing_writer_iter == writer_map_.end()) {
190 auto writer = node_->CreateWriter<T>(role_attr);
191 if (history_channel_name != "") {
192 auto history_writer = node_->CreateWriter<T>(history_channel_name);
193 writer_map_[channel_name] =
194 std::make_shared<WriterHandle>(writer, history_writer);
195 history_writers_.emplace_back(writer_map_[channel_name]);
196 } else {
197 writer_map_[channel_name] = std::make_shared<WriterHandle>(writer);
198 }
199 return writer_map_[channel_name];
200 }
201 return existing_writer_iter->second;
202}
203
204} // namespace external_command
205} // namespace apollo
static double NowInSeconds()
gets the current time in second.
Definition clock.cc:56
virtual bool Write(const MessageT &msg)
Write a MessageT instance
Definition writer.h:166
std::shared_ptr< WriterHandle > RegisterMessage(const std::string &channel_name, const std::string &history_channel_name="")
Register the message writer with the given channel name.
Wrapped Writer with last sent channel.
WriterHandle(const std::shared_ptr< cyber::WriterBase > &writer, const std::shared_ptr< cyber::WriterBase > &history_writer=nullptr)
void WriteLastMessage()
Write the last received message as history.
bool Write(const T &message)
Write the message with the channel name.
#define DECLARE_SINGLETON(classname)
Definition macros.h:52
#define ADEBUG
Definition log.h:41
class register implement
Definition arena_queue.h:37