24#include "modules/common_msgs/chassis_msgs/chassis.pb.h"
25#include "modules/common_msgs/control_msgs/control_cmd.pb.h"
39 "throttle pedal command delta percentage.");
45 use_acceleration,
false,
46 "switch to use acceleration instead of throttle pedal and brake pedal");
59const uint32_t KEYCODE_O = 0x4F;
61const uint32_t KEYCODE_UP1 = 0x57;
62const uint32_t KEYCODE_UP2 = 0x77;
63const uint32_t KEYCODE_DN1 = 0x53;
64const uint32_t KEYCODE_DN2 = 0x73;
65const uint32_t KEYCODE_LF1 = 0x41;
66const uint32_t KEYCODE_LF2 = 0x61;
67const uint32_t KEYCODE_RT1 = 0x44;
68const uint32_t KEYCODE_RT2 = 0x64;
71const uint32_t KEYCODE_PKBK1 = 0x50;
72const uint32_t KEYCODE_PKBK2 = 0x70;
75const uint32_t KEYCODE_SETT1 = 0x54;
76const uint32_t KEYCODE_SETT2 = 0x74;
77const uint32_t KEYCODE_SETG1 = 0x47;
78const uint32_t KEYCODE_SETG2 = 0x67;
79const uint32_t KEYCODE_SETB1 = 0x42;
80const uint32_t KEYCODE_SETB2 = 0x62;
81const uint32_t KEYCODE_ZERO = 0x30;
84const uint32_t KEYCODE_SETQ1 = 0x51;
85const uint32_t KEYCODE_SETQ2 = 0x71;
88const uint32_t KEYCODE_SETL1 = 0x4C;
89const uint32_t KEYCODE_SETL2 = 0x6C;
92const uint32_t KEYCODE_MODE1 = 0x4D;
93const uint32_t KEYCODE_MODE2 = 0x6D;
96const uint32_t KEYCODE_ESTOP1 = 0x45;
97const uint32_t KEYCODE_ESTOP2 = 0x65;
100const uint32_t KEYCODE_HELP1 = 0x48;
101const uint32_t KEYCODE_HELP2 = 0x68;
106 ResetControlCommand();
107 node_ = CreateNode(
"teleop");
109 static void PrintKeycode() {
111 printf(
"===================== KEYBOARD MAP ===================\n");
112 printf(
"HELP: [%c] |\n", KEYCODE_HELP2);
113 printf(
"Set Action: [%c]+Num\n", KEYCODE_MODE2);
114 printf(
" 0 RESET ACTION\n");
115 printf(
" 1 START ACTION\n");
116 printf(
" 2 VIN_REQ ACTION\n");
117 printf(
"\n-----------------------------------------------------------\n");
118 printf(
"Set Gear: [%c]+Num\n", KEYCODE_SETG2);
119 printf(
" 0 GEAR_NEUTRAL\n");
120 printf(
" 1 GEAR_DRIVE\n");
121 printf(
" 2 GEAR_REVERSE\n");
122 printf(
" 3 GEAR_PARKING\n");
123 printf(
" 4 GEAR_LOW\n");
124 printf(
" 5 GEAR_INVALID\n");
125 printf(
" 6 GEAR_NONE\n");
126 printf(
"\n-----------------------------------------------------------\n");
127 printf(
"Throttle/Speed up: [%c] | \n", KEYCODE_UP2);
128 printf(
"Brake/Speed down: [%c] | \n", KEYCODE_DN2);
129 printf(
"Steer LEFT: [%c] | Steer RIGHT: [%c]\n",
130 KEYCODE_LF2, KEYCODE_RT2);
131 printf(
"Parking Brake: [%c] | Emergency Stop [%c]\n",
132 KEYCODE_PKBK2, KEYCODE_ESTOP2);
133 printf(
"Left/Right Lamp: [%c] | Low beam [%c]\n",
134 KEYCODE_SETQ2, KEYCODE_SETL2);
135 printf(
"\n-----------------------------------------------------------\n");
136 printf(
"Exit: Ctrl + C, then press enter to normal terminal\n");
137 printf(
"===========================================================\n");
140 void KeyboardLoopThreadFunc() {
148 struct termios cooked_;
151 bool parking_brake =
false;
152 bool low_beam =
false;
153 Chassis::GearPosition gear = Chassis::GEAR_INVALID;
155 ControlCommand &control_command_ = control_command();
157 apollo::common::VehicleConfigHelper::Instance()
162 tcgetattr(kfd_, &cooked_);
163 std::memcpy(&raw_, &cooked_,
sizeof(
struct termios));
164 raw_.c_lflag &= ~(ICANON | ECHO);
168 tcsetattr(kfd_, TCSANOW, &raw_);
169 puts(
"Teleop:\nReading from keyboard now.");
170 puts(
"---------------------------");
171 puts(
"Use arrow keys to drive the car.");
172 while (IsRunning()) {
174 if (read(kfd_, &c, 1) < 0) {
178 AINFO <<
"control command : "
179 << control_command_.ShortDebugString().c_str();
183 if (!FLAGS_use_acceleration) {
184 brake = control_command_.brake();
185 throttle = control_command_.throttle();
188 brake = GetCommand(brake, -FLAGS_brake_inc_delta);
189 if (!FLAGS_use_acceleration) {
190 control_command_.set_brake(brake);
193 control_command_.set_acceleration(dec);
196 throttle = GetCommand(throttle, FLAGS_throttle_inc_delta);
197 if (!FLAGS_use_acceleration) {
198 control_command_.set_throttle(throttle);
201 control_command_.set_acceleration(acc);
204 if (!FLAGS_use_acceleration) {
205 AINFO <<
"Throttle = " << control_command_.throttle()
206 <<
", Brake = " << control_command_.brake();
208 AINFO <<
"Acceleration = " << control_command_.acceleration();
213 if (!FLAGS_use_acceleration) {
214 brake = control_command_.brake();
215 throttle = control_command_.throttle();
217 if (throttle > 1e-6) {
218 throttle = GetCommand(throttle, -FLAGS_throttle_inc_delta);
219 if (!FLAGS_use_acceleration) {
220 control_command_.set_throttle(throttle);
223 control_command_.set_acceleration(acc);
226 brake = GetCommand(brake, FLAGS_brake_inc_delta);
227 if (!FLAGS_use_acceleration) {
228 control_command_.set_brake(brake);
231 control_command_.set_acceleration(dec);
234 if (!FLAGS_use_acceleration) {
235 AINFO <<
"Throttle = " << control_command_.throttle()
236 <<
", Brake = " << control_command_.brake();
238 AINFO <<
"Acceleration = " << control_command_.acceleration();
243 steering = control_command_.steering_target();
244 steering = GetCommand(steering, FLAGS_steer_inc_delta);
245 control_command_.set_steering_target(steering);
246 AINFO <<
"Steering Target = " << steering;
250 steering = control_command_.steering_target();
251 steering = GetCommand(steering, -FLAGS_steer_inc_delta);
252 control_command_.set_steering_target(steering);
253 AINFO <<
"Steering Target = " << steering;
257 parking_brake = !control_command_.parking_brake();
258 control_command_.set_parking_brake(parking_brake);
259 AINFO <<
"Parking Brake Toggled: " << parking_brake;
263 control_command_.set_brake(50.0);
264 AINFO <<
"Estop Brake : " << control_command_.brake();
281 if (read(kfd_, &c, 1) < 0) {
284 level = c - KEYCODE_ZERO;
285 gear = GetGear(level);
286 control_command_.set_gear_location(gear);
287 AINFO <<
"Gear set to : " << level;
309 control_command_.mutable_signal()->set_turn_signal(
310 VehicleSignal::TURN_NONE);
311 AINFO <<
"Set Lamp OFF";
312 }
else if (cnt == 1) {
313 control_command_.mutable_signal()->set_turn_signal(
314 VehicleSignal::TURN_LEFT);
315 AINFO <<
"Set Turn Left";
316 }
else if (cnt == 2) {
317 control_command_.mutable_signal()->set_turn_signal(
318 VehicleSignal::TURN_RIGHT);
319 AINFO <<
"Set Turn Right";
320 }
else if (cnt == 3) {
321 control_command_.mutable_signal()->set_turn_signal(
322 VehicleSignal::TURN_HAZARD_WARNING);
323 AINFO <<
"Set Turn Hazard Warning Lamp ON";
328 low_beam = !control_command_.signal().low_beam();
329 control_command_.mutable_signal()->set_low_beam(low_beam);
330 AINFO <<
"Low Beam Toggled: " << low_beam;
335 if (read(kfd_, &c, 1) < 0) {
338 level = c - KEYCODE_ZERO;
339 GetPadMessage(&pad_msg, level);
340 control_command_.mutable_pad_msg()->CopyFrom(pad_msg);
342 control_command_.clear_pad_msg();
352 AINFO <<
"control command after switch : "
353 << control_command_.ShortDebugString().c_str();
355 tcsetattr(kfd_, TCSANOW, &cooked_);
356 AINFO <<
"keyboard_loop thread quited.";
360 ControlCommand &control_command() {
return control_command_; }
362 Chassis::GearPosition GetGear(int32_t gear) {
365 return Chassis::GEAR_NEUTRAL;
367 return Chassis::GEAR_DRIVE;
369 return Chassis::GEAR_REVERSE;
371 return Chassis::GEAR_PARKING;
373 return Chassis::GEAR_LOW;
375 return Chassis::GEAR_INVALID;
377 return Chassis::GEAR_NONE;
379 return Chassis::GEAR_INVALID;
383 void GetPadMessage(PadMessage *pad_msg, int32_t int_action) {
386 switch (int_action) {
389 AINFO <<
"SET Action RESET";
393 AINFO <<
"SET Action START";
397 AINFO <<
"SET Action VIN_REQ";
400 AINFO <<
"unknown action: " << int_action <<
" use default RESET";
403 pad_msg->set_action(action);
407 double GetCommand(
double val,
double inc) {
411 }
else if (val < -100.0) {
418 apollo::common::util::FillHeader(
"control", &control_command_);
419 control_command_writer_->Write(control_command_);
420 ADEBUG <<
"Control Command send OK:" << control_command_.ShortDebugString();
423 void ResetControlCommand() {
424 control_command_.Clear();
425 control_command_.set_throttle(0.0);
426 control_command_.set_brake(0.0);
427 control_command_.set_steering_rate(0.0);
428 control_command_.set_steering_target(0.0);
429 control_command_.set_parking_brake(
false);
430 control_command_.set_speed(0.0);
431 control_command_.set_acceleration(0.0);
432 control_command_.set_reset_model(
false);
433 control_command_.set_engine_on_off(
false);
434 control_command_.set_driving_mode(Chassis::COMPLETE_MANUAL);
435 control_command_.set_gear_location(Chassis::GEAR_INVALID);
436 control_command_.mutable_signal()->set_low_beam(
false);
437 control_command_.mutable_signal()->set_turn_signal(
438 VehicleSignal::TURN_NONE);
441 void OnChassis(
const Chassis &chassis) { Send(); }
445 AERROR <<
"Already running.";
449 chassis_reader_ = node_->CreateReader<Chassis>(
450 FLAGS_chassis_topic, [
this](
const std::shared_ptr<Chassis> &chassis) {
453 control_command_writer_ =
454 node_->CreateWriter<ControlCommand>(FLAGS_control_command_topic);
455 keyboard_thread_.reset(
456 new std::thread([
this] { KeyboardLoopThreadFunc(); }));
457 if (keyboard_thread_ ==
nullptr) {
458 AERROR <<
"Unable to create can client receiver thread.";
467 if (keyboard_thread_ !=
nullptr && keyboard_thread_->joinable()) {
468 keyboard_thread_->join();
469 keyboard_thread_.reset();
470 AINFO <<
"Teleop keyboard stopped [ok].";
475 bool IsRunning()
const {
return is_running_; }
478 std::unique_ptr<std::thread> keyboard_thread_;
479 std::shared_ptr<Reader<Chassis>> chassis_reader_;
480 std::shared_ptr<Writer<ControlCommand>> control_command_writer_;
481 ControlCommand control_command_;
482 bool is_running_ =
false;
483 std::shared_ptr<apollo::cyber::Node> node_;
488int main(int32_t argc,
char **argv) {
490 FLAGS_alsologtostderr =
true;
493 google::ParseCommandLineFlags(&argc, &argv,
true);
497 if (teleop.Start() != 0) {
498 AERROR <<
"Teleop start failed.";
501 Teleop::PrintKeycode();
504 AINFO <<
"Teleop exit done.";
Reader subscribes a channel, it has two main functions:
Cyber has builtin time type Time.
Some string util functions.
bool Init(const char *binary_name, const std::string &dag_info)
std::unique_ptr< Node > CreateNode(const std::string &node_name, const std::string &name_space)
optional double max_deceleration
optional double max_acceleration
The class of VehicleController