Apollo 10.0
自动驾驶开放平台
external_command_demo.cc
浏览该文件的文档.
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
18
19#include <poll.h>
20
21#include <cctype>
22
23#include "modules/external_command/external_command_demo/proto/sweeper_custom_command.pb.h"
24
25#include "cyber/common/file.h"
27
29
31 : command_id_(0), module_name_("demo") {}
32
34 action_command_client_ =
36 CommandStatus>("/apollo/external_command/action");
37 chassis_command_client_ =
39 CommandStatus>("/apollo/external_command/chassis");
40 free_space_command_client_ =
42 CommandStatus>("/apollo/external_command/free_space");
43 lane_follow_command_client_ =
46 "/apollo/external_command/lane_follow");
47 path_follow_command_client_ =
50 "/apollo/external_command/path_follow");
51 speed_command_client_ =
52 node_
54 "/apollo/external_command/speed");
55 valet_parking_command_client_ =
58 "/apollo/external_command/valet_parking");
59 status_client_ =
62 "/apollo/external_command/command_status");
64 "modules/external_command/external_command_demo/conf/"
65 "demo_config.pb.txt",
66 &demo_config_);
67 return true;
68}
69
71 int8_t revent = 0; // short
72 struct pollfd fd = {STDIN_FILENO, POLLIN, revent};
73 switch (poll(&fd, 1, 100)) {
74 case -1:
75 std::cout << "Failed to read keyboard" << std::endl;
76 return false;
77 case 0:
78 return true;
79 default:
80 char data[50];
81 std::cin.getline(data, 50);
82 std::string input_command_string = data;
83 if (input_command_string == "pull_over") {
84 // Pull over.
85 SendActionCommand(
87 } else if (input_command_string == "stop") {
88 // Stop planning.
90 } else if (input_command_string == "start") {
91 // Start planning.
93 } else if (input_command_string == "clear") {
94 // Start planning.
95 SendActionCommand(
97 } else if (input_command_string == "manual") {
98 // Switch manual mode.
99 SendActionCommand(
101 } else if (input_command_string == "auto") {
102 // Switch auto mode.
103 SendActionCommand(
105 } else if (input_command_string == "vin") {
106 // Send vin validation.
108 } else if (input_command_string == "enter_mission") {
109 // Enter mission model.
110 SendActionCommand(
112 } else if (input_command_string == "exit_mission") {
113 // Exit mission model.
114 SendActionCommand(
116 } else if (input_command_string == "chassis") {
117 SendVehicleSignalCommand();
118 } else if (input_command_string == "custom_chassis") {
119 SendCustomChassisCommand();
120 } else if (input_command_string.find("set_speed") != std::string::npos) {
121 auto index = input_command_string.find("set_speed");
122 std::string speed_value_string = input_command_string.substr(
123 index + std::string("set_speed").length(),
124 input_command_string.length());
125 if (!speed_value_string.empty()) {
126 double speed_value = std::atof(speed_value_string.c_str());
127 SendSpeedCommand(speed_value);
128 } else {
129 AWARN << "Input format is invalid, please input format like: "
130 "set_speed 1.5";
131 }
132 } else if (input_command_string == "increase_speed") {
133 double speed_factor = 1.2;
134 SendSpeedFactorCommand(speed_factor);
135 } else if (input_command_string == "decrease_speed") {
136 double speed_factor = 0.8;
137 SendSpeedFactorCommand(speed_factor);
138 } else if (input_command_string == "restore_speed") {
139 RestoreSpeed();
140 } else if (input_command_string == "lane") {
141 // Modify way point as needed.
143 way_point.set_x(0.0);
144 way_point.set_y(0.0);
145 way_point.set_heading(0.0);
146 std::vector<apollo::external_command::Pose> way_points;
147 way_points.emplace_back(way_point);
149 end_pose.set_x(10.0);
150 end_pose.set_y(0.0);
151 end_pose.set_heading(0.0);
152 SendLaneFollowCommand(way_points, end_pose,
153 demo_config_.target_speed());
154 } else if (input_command_string == "path_loc") {
155 SendPathFollowCommandWithLocationRecord(
157 } else if (input_command_string == "path_path") {
158 SendPathFollowCommandWithPathRecord(
160 } else if (input_command_string == "valet_parking") {
161 std::string parking_spot_id = "451089045";
162 SendValetParkingCommand(parking_spot_id, demo_config_.target_speed());
163 } else if (input_command_string.find("command_status") !=
164 std::string::npos) {
165 // Input command with format: command_status=XX, where XX is the
166 // command_id
167 const size_t start_pos = std::string("command_status=").length();
168 const size_t end_pos = input_command_string.length();
169 if (end_pos <= start_pos) {
170 std::cout
171 << "Please check command status with format: command_status=XX!"
172 << std::endl;
173 break;
174 }
175 std::string command_id_string =
176 input_command_string.substr(start_pos, end_pos);
177 command_id_string.erase(
178 std::remove_if(command_id_string.begin(), command_id_string.end(),
179 ::isspace),
180 command_id_string.end());
181 uint64_t id = std::atoi(command_id_string.c_str());
182 CheckCommandStatus(id);
183 } else if (input_command_string == "free1") {
185 end_pose.set_x(437556.02);
186 end_pose.set_y(4432540.34);
187 end_pose.set_heading(1.8);
188 std::vector<apollo::external_command::Point> way_points;
193 point1.set_x(437536.29);
194 point1.set_y(4432560.69);
195 point2.set_x(437536.29);
196 point2.set_y(4432510.69);
197 point3.set_x(437576.29);
198 point3.set_y(4432510.69);
199 point4.set_x(437576.29);
200 point4.set_y(4432560.69);
201 way_points.emplace_back(point1);
202 way_points.emplace_back(point2);
203 way_points.emplace_back(point3);
204 way_points.emplace_back(point4);
205
206 SendFreespaceCommand(way_points, end_pose);
207 } else {
208 std::cout << "Invalid input!" << input_command_string << std::endl;
209 }
210 }
211 return true;
212}
213
214void ExternalCommandDemo::SendActionCommand(
216 auto command = std::make_shared<apollo::external_command::ActionCommand>();
217 FillCommandHeader(command);
218 command->set_command(action_command_type);
219 std::cout << "Sending action command: " << command->DebugString()
220 << std::endl;
221 auto response = action_command_client_->SendRequest(command);
222 if (nullptr == response) {
223 std::cout << "Command sending failed, please check the service is on!\n"
224 << std::endl;
225 } else {
226 std::cout << "******Finish sending command.******\n" << std::endl;
227 }
228}
229
230void ExternalCommandDemo::SendVehicleSignalCommand() {
231 // Send left turn signal.
232 auto command = std::make_shared<apollo::external_command::ChassisCommand>();
233 FillCommandHeader(command);
234 command->mutable_basic_signal()->set_turn_signal(
236 std::cout << "Sending chassis command: " << command->DebugString()
237 << std::endl;
238 auto response = chassis_command_client_->SendRequest(command);
239 if (nullptr == response) {
240 std::cout << "Command sending failed, please check the service is on!\n"
241 << std::endl;
242 } else {
243 std::cout << "******Finish sending command.******\n" << std::endl;
244 }
245}
246
247void ExternalCommandDemo::SendCustomChassisCommand() {
248 // Send left turn signal.
249 auto command = std::make_shared<apollo::external_command::ChassisCommand>();
250 FillCommandHeader(command);
251 // Set custom command.
252 auto custom_operation = command->mutable_custom_operation();
253 // Set custom command values.
255 sweeper_command.set_is_turn_on_brush(true);
256 sweeper_command.set_sweeping_speed(2.0);
257 custom_operation->PackFrom(sweeper_command);
258 std::cout << "Sending custom chassis command: " << command->DebugString()
259 << std::endl;
260 auto response = chassis_command_client_->SendRequest(command);
261 if (nullptr == response) {
262 std::cout << "Command sending failed, please check the service is on!\n"
263 << std::endl;
264 } else {
265 std::cout << "******Finish sending command.******\n" << std::endl;
266 }
267}
268
269void ExternalCommandDemo::SendPathFollowCommandWithPathRecord(
270 const std::string& record_path) {
271 // Read planning data from record file and use the planning path points
272 // as the path of PathFollowCommand.
273 apollo::planning::ADCTrajectory record_planning_data;
274 // Get the path points from record planning data.
275 std::shared_ptr<apollo::external_command::PathFollowCommand>
276 path_follow_command =
277 std::make_shared<apollo::external_command::PathFollowCommand>();
278 ReadPathFromPathRecord(record_path, path_follow_command->mutable_way_point());
279 // Set header and command id of PathFollowCommand.
280 FillCommandHeader(path_follow_command);
281 // Set path boundary of path.
282 auto path_boundary = path_follow_command->mutable_boundary_with_width();
283 path_boundary->set_left_path_width(demo_config_.left_path_width());
284 path_boundary->set_right_path_width(demo_config_.right_path_width());
285 // Set target speed.
286 path_follow_command->set_target_speed(demo_config_.target_speed());
287 auto response = path_follow_command_client_->SendRequest(path_follow_command);
288 if (nullptr == response) {
289 std::cout << "Command sending failed, please check the service is on!\n"
290 << std::endl;
291 } else {
292 std::cout << "******Finish sending command.******\n" << std::endl;
293 }
294}
295
296void ExternalCommandDemo::SendPathFollowCommandWithLocationRecord(
297 const std::string& record_dir) {
298 // Read planning data from record file and use the planning path points
299 // as the path of PathFollowCommand.
300 std::shared_ptr<apollo::external_command::PathFollowCommand>
301 path_follow_command =
302 std::make_shared<apollo::external_command::PathFollowCommand>();
303 std::vector<std::string> record_files =
304 apollo::cyber::common::ListSubPaths(record_dir, DT_REG);
305 std::string dir_prefix = record_dir + '/';
306 for (const auto file_name : record_files) {
307 ReadPathFromLocationRecord(dir_prefix + file_name,
308 path_follow_command->mutable_way_point());
309 }
310
311 // Set header and command id of PathFollowCommand.
312 FillCommandHeader(path_follow_command);
313 // Set path boundary of path.
314 auto path_boundary = path_follow_command->mutable_boundary_with_width();
315 path_boundary->set_left_path_width(demo_config_.left_path_width());
316 path_boundary->set_right_path_width(demo_config_.right_path_width());
317 // Set target speed.
318 path_follow_command->set_target_speed(demo_config_.target_speed());
319 auto response = path_follow_command_client_->SendRequest(path_follow_command);
320 if (nullptr == response) {
321 std::cout << "Command sending failed, please check the service is on!\n"
322 << std::endl;
323 } else {
324 std::cout << "******Finish sending command.******\n" << std::endl;
325 }
326}
327
328void ExternalCommandDemo::SendSpeedCommand(double speed) {
329 auto command = std::make_shared<apollo::external_command::SpeedCommand>();
330 FillCommandHeader(command);
331 command->set_target_speed(speed);
332 std::cout << "Sending speed command: " << command->DebugString() << std::endl;
333 auto response = speed_command_client_->SendRequest(command);
334 if (nullptr == response) {
335 std::cout << "Command sending failed, please check the service is on!\n"
336 << std::endl;
337 } else {
338 std::cout << "******Finish sending command.******\n" << std::endl;
339 }
340}
341
342void ExternalCommandDemo::SendSpeedFactorCommand(double speed_factor) {
343 auto command = std::make_shared<apollo::external_command::SpeedCommand>();
344 FillCommandHeader(command);
345 command->set_target_speed_factor(speed_factor);
346 std::cout << "Sending speed factor command: " << command->DebugString()
347 << std::endl;
348 auto response = speed_command_client_->SendRequest(command);
349 if (nullptr == response) {
350 std::cout << "Command sending failed, please check the service is on!\n"
351 << std::endl;
352 } else {
353 std::cout << "******Finish sending command.******\n" << std::endl;
354 }
355}
356
357void ExternalCommandDemo::RestoreSpeed() {
358 auto command = std::make_shared<apollo::external_command::SpeedCommand>();
359 FillCommandHeader(command);
360 command->set_is_restore_target_speed(true);
361 std::cout << "Restore speed: " << command->DebugString() << std::endl;
362 auto response = speed_command_client_->SendRequest(command);
363 if (nullptr == response) {
364 std::cout << "Command sending failed, please check the service is on!\n"
365 << std::endl;
366 } else {
367 std::cout << "******Finish sending command.******\n" << std::endl;
368 }
369}
370
371void ExternalCommandDemo::SendLaneFollowCommand(
372 const std::vector<apollo::external_command::Pose>& way_points,
373 const apollo::external_command::Pose& end, double target_speed) {
374 auto command =
375 std::make_shared<apollo::external_command::LaneFollowCommand>();
376 FillCommandHeader(command);
377 // Copy way_points
378 for (const auto& point : way_points) {
379 auto way_point = command->add_way_point();
380 way_point->CopyFrom(point);
381 }
382 // Copy end point
383 command->mutable_end_pose()->CopyFrom(end);
384 if (target_speed > 0.0) {
385 command->set_target_speed(target_speed);
386 }
387 std::cout << "Sending lane follow command: " << command->DebugString()
388 << std::endl;
389 auto response = lane_follow_command_client_->SendRequest(command);
390 if (nullptr == response) {
391 std::cout << "Command sending failed, please check the service is on!\n"
392 << std::endl;
393 } else {
394 std::cout << "******Finish sending command.******\n" << std::endl;
395 }
396}
397
398void ExternalCommandDemo::SendFreespaceCommand(
399 const std::vector<apollo::external_command::Point>& way_points,
401 auto command = std::make_shared<apollo::external_command::FreeSpaceCommand>();
402 FillCommandHeader(command);
403 // Copy way_points
404 auto roi_point = command->mutable_drivable_roi();
405 for (const auto& point : way_points) {
406 roi_point->add_point()->CopyFrom(point);
407 }
408 // Copy end point
409 command->mutable_parking_spot_pose()->CopyFrom(end);
410 std::cout << "Sending lane follow command: " << command->DebugString()
411 << std::endl;
412 auto response = free_space_command_client_->SendRequest(command);
413 if (nullptr == response) {
414 std::cout << "Command sending failed, please check the service is on!\n"
415 << std::endl;
416 } else {
417 std::cout << "******Finish sending command.******\n" << std::endl;
418 }
419}
420void ExternalCommandDemo::SendValetParkingCommand(
421 const std::string& parking_spot_id, double target_speed) {
422 auto command =
423 std::make_shared<apollo::external_command::ValetParkingCommand>();
424 FillCommandHeader(command);
425 command->set_parking_spot_id(parking_spot_id);
426 if (target_speed > 0.0) {
427 command->set_target_speed(target_speed);
428 }
429 std::cout << "Sending valet parking command: " << command->DebugString()
430 << std::endl;
431 auto response = valet_parking_command_client_->SendRequest(command);
432 if (nullptr == response) {
433 std::cout << "Command sending failed, please check the service is on!\n"
434 << std::endl;
435 } else {
436 std::cout << "******Finish sending command.******\n" << std::endl;
437 }
438}
439
440void ExternalCommandDemo::ReadPathFromPathRecord(
441 const std::string& record_file,
442 google::protobuf::RepeatedPtrField<apollo::external_command::Point>*
443 waypoints) {
444 std::cout << "ReadPathFromPathRecord: " << record_file << std::endl;
445 apollo::cyber::record::RecordReader reader(record_file);
446 if (!reader.IsValid()) {
447 std::cout << "Fail to open " << record_file << std::endl;
448 return;
449 }
450
451 apollo::planning::ADCTrajectory planning_trajectory;
453 while (reader.ReadMessage(&message)) {
454 if (message.channel_name == "/apollo/planning") {
455 if (planning_trajectory.ParseFromString(message.content)) {
456 break;
457 }
458 }
459 }
460 waypoints->Clear();
461 const auto& trajectory_points = planning_trajectory.trajectory_point();
462 for (const auto input_point : trajectory_points) {
463 auto output_point = waypoints->Add();
464 output_point->set_x(input_point.path_point().x());
465 output_point->set_y(input_point.path_point().y());
466 }
467}
468
469void ExternalCommandDemo::CheckCommandStatus(const uint64_t command_id) {
470 auto command =
471 std::make_shared<apollo::external_command::CommandStatusRequest>();
472 FillCommandHeader(command);
473 command->set_command_id(command_id);
474 std::cout << "Sending check command: " << command->DebugString() << std::endl;
475 auto response = status_client_->SendRequest(command);
476 if (nullptr == response) {
477 std::cout << "Check status failed!\n" << std::endl;
478 } else {
479 std::cout << response->DebugString();
480 std::cout << "******Finish checking command.******\n" << std::endl;
481 }
482}
483
484void ExternalCommandDemo::ReadPathFromLocationRecord(
485 const std::string& record_file,
486 google::protobuf::RepeatedPtrField<apollo::external_command::Point>*
487 waypoints) const {
488 std::cout << "ReadPathFromLocationRecord: " << record_file << std::endl;
489 apollo::cyber::record::RecordReader reader(record_file);
490 if (!reader.IsValid()) {
491 std::cout << "Fail to open " << record_file << std::endl;
492 return;
493 }
496 double last_x = 0.0;
497 double last_y = 0.0;
498 bool is_last_poistion_set = false;
499 while (reader.ReadMessage(&message)) {
500 if (message.channel_name == "/apollo/localization/pose") {
501 if (localization.ParseFromString(message.content)) {
502 const auto& position = localization.pose().position();
503 if (!is_last_poistion_set) {
504 last_x = position.x();
505 last_y = position.y();
506 is_last_poistion_set = true;
507 continue;
508 }
509 // Save the location to path with min_distance.
510 if (abs(last_x - position.x()) > demo_config_.min_distance_error() ||
511 abs(last_y - position.y()) > demo_config_.min_distance_error()) {
512 auto output_point = waypoints->Add();
513 output_point->set_x(position.x());
514 output_point->set_y(position.y());
515 last_x = position.x();
516 last_y = position.y();
517 }
518 }
519 }
520 }
521}
bool Proc() override
The Proc logic of the component, which called by the CyberRT frame.
std::shared_ptr< Node > node_
#define AWARN
Definition log.h:43
bool GetProtoFromFile(const std::string &file_name, google::protobuf::Message *message)
Parses the content of the file specified by the file_name as a representation of protobufs,...
Definition file.cc:132
std::vector< std::string > ListSubPaths(const std::string &directory_path, const unsigned char d_type)
List sub-paths.
Definition file.cc:353
Basic data struct of record message.
std::string content
The content of the message.
std::string channel_name
The channel name of the message.
optional apollo::localization::Pose pose
optional apollo::common::PointENU position
Definition pose.proto:26
repeated apollo::common::TrajectoryPoint trajectory_point