Apollo 10.0
自动驾驶开放平台
motion_command_processor_base.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 <memory>
24#include <string>
25#include <vector>
26
27#include "modules/common_msgs/external_command_msgs/command_status.pb.h"
28#include "modules/common_msgs/planning_msgs/planning_command.pb.h"
29#include "modules/common_msgs/routing_msgs/routing.pb.h"
30#include "modules/external_command/command_processor/command_processor_base/proto/command_processor_config.pb.h"
31
32#include "cyber/cyber.h"
40
45namespace apollo {
46namespace external_command {
47
53template <typename T>
55 public:
57
58 ~MotionCommandProcessorBase() override = default;
59
60 bool Init(const std::shared_ptr<cyber::Node>& node) override;
66 bool GetCommandStatus(int64_t command_id,
67 CommandStatus* status) const override;
68
69 protected:
70 const std::shared_ptr<apollo::external_command::LaneWayTool>& GetLaneWayTool()
71 const {
72 return lane_way_tool_;
73 }
81 virtual bool Convert(const std::shared_ptr<T>& command,
82 std::shared_ptr<apollo::routing::RoutingRequest>&
83 routing_request) const = 0;
90 std::vector<apollo::routing::LaneWaypoint>* lane_way_points) const;
97 std::shared_ptr<apollo::routing::RoutingRequest>& routing_request) const;
104 void OnCommand(const std::shared_ptr<T>& command,
105 std::shared_ptr<CommandStatus>& status);
113 const std::shared_ptr<T>& command,
114 const std::shared_ptr<apollo::planning::PlanningCommand>&
115 planning_command) const = 0;
116
117 std::shared_ptr<cyber::Service<T, CommandStatus>> command_service_;
118 std::shared_ptr<WriterHandle> planning_command_writer_;
119 std::shared_ptr<WriterHandle> routing_response_writer_;
120
121 std::shared_ptr<apollo::routing::Routing> routing_;
122 std::shared_ptr<apollo::external_command::LaneWayTool> lane_way_tool_;
126
127 private:
128 std::mutex mutex_;
129};
130
131template <typename T>
133 : command_service_(nullptr),
134 planning_command_writer_(nullptr),
135 routing_(std::make_shared<apollo::routing::Routing>()),
136 lane_way_tool_(nullptr),
137 message_reader_(MessageReader::Instance()) {
138 last_received_command_.set_command_id(-1);
139}
140
141template <typename T>
143 const std::shared_ptr<cyber::Node>& node) {
144 // Init function of base class should be invoked first.
145 if (!CommandProcessorBase::Init(node)) {
146 AERROR << "MotionCommandProcessorBase init failed!";
147 return false;
148 }
149 lane_way_tool_ =
150 std::make_shared<apollo::external_command::LaneWayTool>(node);
151 routing_->Init();
152 // Create service for input command.
153 const auto& config = GetProcessorConfig();
154 command_service_ = node->CreateService<T, CommandStatus>(
155 config.input_command_name(),
156 [this](const std::shared_ptr<T>& command,
157 std::shared_ptr<CommandStatus>& status) {
158 this->OnCommand(command, status);
159 });
160
161 CHECK_GT(config.output_command_name().size(), 0);
162 // Create writer for output command.
164 attr.set_channel_name(config.output_command_name().Get(0));
165 auto qos = attr.mutable_qos_profile();
167 qos->set_reliability(
169 qos->set_durability(
171 auto message_writer = MessageWriter::Instance();
172 planning_command_writer_ =
173 message_writer->RegisterMessage<apollo::planning::PlanningCommand>(
174 attr, config.planning_command_history_name());
175 routing_response_writer_ =
176 message_writer->RegisterMessage<apollo::routing::RoutingResponse>(
177 FLAGS_routing_response_topic);
178 // Create reader for input command status.
179 CHECK_GT(config.input_command_status_name().size(), 0);
180 planning_command_status_name_ = config.input_command_status_name().Get(0);
181 message_reader_->RegisterMessage<CommandStatus>(
182 planning_command_status_name_);
183 return true;
184}
185
186template <typename T>
188 int64_t command_id, CommandStatus* status) const {
189 CHECK_NOTNULL(status);
190 if (last_received_command_.command_id() == command_id) {
191 status->set_command_id(command_id);
192 auto* latest_planning_command_status =
193 message_reader_->GetMessage<CommandStatus>(
194 planning_command_status_name_);
195 if (nullptr == latest_planning_command_status) {
197 status->set_message("Cannot get planning command status!");
198 return true;
199 }
200 status->CopyFrom(*latest_planning_command_status);
201 return true;
202 }
203 return false;
204}
205
206template <typename T>
208 const std::shared_ptr<T>& command, std::shared_ptr<CommandStatus>& status) {
209 CHECK_NOTNULL(command);
210 CHECK_NOTNULL(status);
211 if (command->has_header()) {
212 double timestamp = apollo::cyber::Clock::NowInSeconds();
213 AINFO << std::setprecision(12) << "timestamp: " << timestamp << " "
214 << "request for " << command->header().timestamp_sec();
215 if (timestamp - command->header().timestamp_sec() > 2.0) {
216 AINFO << "request for " << command->header().module_name()
217 << " has been timeouted";
218 return;
219 }
220 }
221 last_received_command_.CopyFrom(*command);
222 status->set_command_id(command->command_id());
223 // Convert command to RoutingRequest.
224 std::shared_ptr<apollo::routing::RoutingRequest> routing_request = nullptr;
225 bool convert_result = Convert(command, routing_request);
226 if (!convert_result) {
227 status->set_status(CommandStatusType::ERROR);
228 status->set_message("Cannot convert command to RoutingRequest: " +
229 command->DebugString());
230 return;
231 }
232 // Search routing.
233 std::string module_name = "UNKNOWN";
234 if (command->has_header()) {
235 module_name = command->header().module_name();
236 }
237 std::lock_guard<std::mutex> guard(this->mutex_);
238 auto planning_command = std::make_shared<apollo::planning::PlanningCommand>();
239 common::util::FillHeader(module_name, planning_command.get());
240 if (nullptr != routing_request) {
241 AINFO << "Process routing: " << routing_request->DebugString();
242 auto routing_response =
243 std::make_shared<apollo::routing::RoutingResponse>();
244 if (!routing_->Process(routing_request, routing_response.get())) {
245 status->set_status(CommandStatusType::ERROR);
246 status->set_message("Cannot get routing of command: " +
247 command->DebugString());
248 AERROR << "Routing process failed! ";
249 return;
250 }
251 planning_command->mutable_lane_follow_command()->CopyFrom(
252 *routing_response);
253 // Publish routing response to display on HMI.
254 routing_response_writer_->Write(routing_response);
255 }
256 // Process command except RoutingRequest.
257 if (!ProcessSpecialCommand(command, planning_command)) {
258 AERROR << "Process special command failed!";
259 return;
260 }
261 planning_command->set_command_id(command->command_id());
262 // Set target_speed.
263 if (command->has_target_speed()) {
264 planning_command->set_target_speed(command->target_speed());
265 }
266 planning_command->set_is_motion_command(true);
267 // Send routing response to planning module.
268 planning_command_writer_->Write(planning_command);
269 AINFO << "publish: " << planning_command->DebugString();
270 status->set_status(CommandStatusType::RUNNING);
271}
272
273template <typename T>
275 std::vector<apollo::routing::LaneWaypoint>* lane_way_points) const {
276 CHECK_NOTNULL(lane_way_points);
277 // Get the current vehicle pose as start pose.
278 if (!lane_way_tool_->GetVehicleLaneWayPoints(lane_way_points)) {
279 AERROR << "Get lane near start pose failed!";
280 return false;
281 }
282 return true;
283}
284
285template <typename T>
287 std::shared_ptr<apollo::routing::RoutingRequest>& routing_request) const {
288 CHECK_NOTNULL(routing_request);
289 // Get the current vehicle pose as start pose.
290 auto start_pose = routing_request->add_waypoint();
291 if (!lane_way_tool_->GetVehicleLaneWayPoint(start_pose)) {
292 AERROR << "Get lane near start pose failed!";
293 return false;
294 }
295 return true;
296}
297
298} // namespace external_command
299} // namespace apollo
static double NowInSeconds()
gets the current time in second.
Definition clock.cc:56
virtual bool Init(const std::shared_ptr< cyber::Node > &node)
virtual bool Convert(const std::shared_ptr< T > &command, std::shared_ptr< apollo::routing::RoutingRequest > &routing_request) const =0
Convert moving command to RoutingRequest.
virtual bool ProcessSpecialCommand(const std::shared_ptr< T > &command, const std::shared_ptr< apollo::planning::PlanningCommand > &planning_command) const =0
Process special command except RoutingRequest.
bool GetCommandStatus(int64_t command_id, CommandStatus *status) const override
Get the command status.
std::shared_ptr< cyber::Service< T, CommandStatus > > command_service_
bool SetStartPose(std::vector< apollo::routing::LaneWaypoint > *lane_way_points) const
Set the start pose of lane_way_points with current vehicle pose.
bool SetStartPose(std::shared_ptr< apollo::routing::RoutingRequest > &routing_request) const
Set the start pose of RoutingRequest with current vehicle pose.
const std::shared_ptr< apollo::external_command::LaneWayTool > & GetLaneWayTool() const
void OnCommand(const std::shared_ptr< T > &command, std::shared_ptr< CommandStatus > &status)
Process the incoming lane follow command.
std::shared_ptr< apollo::external_command::LaneWayTool > lane_way_tool_
bool Init(const std::shared_ptr< cyber::Node > &node) override
#define AERROR
Definition log.h:44
#define AINFO
Definition log.h:42
Some string util functions.
class register implement
Definition arena_queue.h:37
Definition future.h:29