Apollo 10.0
自动驾驶开放平台
pad_terminal.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2017 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
17#include "modules/common_msgs/chassis_msgs/chassis.pb.h"
18#include "modules/common_msgs/control_msgs/pad_msg.pb.h"
19
20#include "cyber/common/log.h"
21#include "cyber/common/macros.h"
22#include "cyber/cyber.h"
23#include "cyber/init.h"
24#include "cyber/time/clock.h"
25#include "cyber/time/time.h"
29
30namespace {
31
40
41class PadTerminal {
42 public:
43 PadTerminal() : node_(CreateNode("pad_terminal")) {}
44 void init() {
45 chassis_reader_ = node_->CreateReader<Chassis>(
46 FLAGS_chassis_topic, [this](const std::shared_ptr<Chassis> &chassis) {
47 on_chassis(*chassis);
48 });
49
50 pad_writer_ = node_->CreateWriter<PadMessage>(FLAGS_pad_topic);
51 terminal_thread_.reset(new std::thread([this] { terminal_thread_func(); }));
52 }
53 void help() {
54 AINFO << "COMMAND:\n";
55 AINFO << "\t0: reset to manual drive mode.";
56 AINFO << "\t1: auto drive mode.";
57 AINFO << "\tctrl + c: exit.";
58 AINFO << "\tother: print help.";
59 }
60 void send(int cmd_type) {
61 PadMessage pad;
62 if (cmd_type == RESET_COMMAND) {
63 pad.set_action(DrivingAction::RESET);
64 AINFO << "sending reset action command.";
65 } else if (cmd_type == AUTO_DRIVE_COMMAND) {
66 pad.set_action(DrivingAction::START);
67 AINFO << "sending start action command.";
68 }
69 apollo::common::util::FillHeader("terminal", &pad);
70 pad_writer_->Write(pad);
71 AINFO << "send pad_message OK";
72 }
73
74 void on_chassis(const Chassis &chassis) {
75 static bool is_first_emergency_mode = true;
76 static int64_t count_start = 0;
77 static bool waiting_reset = false;
78
79 // check if chassis enter security mode, if enter, after 10s should reset to
80 // manual
81 if (chassis.driving_mode() == Chassis::EMERGENCY_MODE) {
82 if (is_first_emergency_mode) {
83 count_start = Clock::Now().ToNanosecond() / 1e3;
84 is_first_emergency_mode = false;
85 AINFO << "detect emergency mode.";
86 } else {
87 int64_t diff = Clock::Now().ToNanosecond() / 1e3 - count_start;
88 if (diff > EMERGENCY_MODE_HOLD_TIME) {
89 count_start = Clock::Now().ToNanosecond() / 1e3;
90 waiting_reset = true;
91 // send a reset command to control
92 send(RESET_COMMAND);
93 AINFO << "trigger to reset emergency mode to manual mode.";
94 } else {
95 // nothing to do
96 }
97 }
98 } else if (chassis.driving_mode() == Chassis::COMPLETE_MANUAL) {
99 if (waiting_reset) {
100 is_first_emergency_mode = true;
101 waiting_reset = false;
102 AINFO << "emergency mode reset to manual ok.";
103 }
104 }
105 }
106
107 void terminal_thread_func() {
108 int mode = 0;
109 bool should_exit = false;
110 while (std::cin >> mode) {
111 switch (mode) {
112 case 0:
113 send(RESET_COMMAND);
114 break;
115 case 1:
116 send(AUTO_DRIVE_COMMAND);
117 break;
118 case 9:
119 should_exit = true;
120 break;
121 default:
122 help();
123 break;
124 }
125 if (should_exit) {
126 break;
127 }
128 }
129 }
130
131 void stop() { terminal_thread_->join(); }
132
133 private:
134 std::unique_ptr<std::thread> terminal_thread_;
135 const int ROS_QUEUE_SIZE = 1;
136 const int RESET_COMMAND = 1;
137 const int AUTO_DRIVE_COMMAND = 2;
138 const int EMERGENCY_MODE_HOLD_TIME = 4 * 1000000;
139 std::shared_ptr<Reader<Chassis>> chassis_reader_;
140 std::shared_ptr<Writer<PadMessage>> pad_writer_;
141 std::shared_ptr<Node> node_;
142};
143} // namespace
144
145int main(int argc, char **argv) {
146 apollo::cyber::Init("pad_terminal");
147 FLAGS_alsologtostderr = true;
148 FLAGS_v = 3;
149 google::ParseCommandLineFlags(&argc, &argv, true);
150 PadTerminal pad_terminal;
151 pad_terminal.init();
152 pad_terminal.help();
154 pad_terminal.stop();
155 return 0;
156}
a singleton clock that can be used to get the current timestamp.
Definition clock.h:39
static Time Now()
PRECISION >= 1000000 means the precision is at least 1us.
Definition clock.cc:40
Node is the fundamental building block of Cyber RT.
Definition node.h:44
Reader subscribes a channel, it has two main functions:
Definition reader.h:69
uint64_t ToNanosecond() const
convert time to nanosecond.
Definition time.cc:83
int main(int argc, char **argv)
#define AINFO
Definition log.h:42
Some string util functions.
void WaitForShutdown()
Definition state.h:50
bool Init(const char *binary_name, const std::string &dag_info)
Definition init.cc:98
std::unique_ptr< Node > CreateNode(const std::string &node_name, const std::string &name_space)
Definition cyber.cc:33