1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
| #include <termios.h> #include <signal.h> #include <math.h> #include <stdio.h> #include <stdlib.h> #include "ros/ros.h" #include <geometry_msgs/Twist.h>
#define KEYCODE_A 0x61 #define KEYCODE_D 0x64 #define KEYCODE_S 0x73 #define KEYCODE_W 0x77 #define KEYCODE_A_CAP 0x41 #define KEYCODE_D_CAP 0x44 #define KEYCODE_S_CAP 0x53 #define KEYCODE_W_CAP 0x57
class TeleopPR2Keyboard { private: double walk_vel, run_vel, yaw_rate, yaw_rate_run; geometry_msgs::Twist cmd; ros::NodeHandle n_; ros::Publisher vel_pub_;
public: void init() { cmd.linear.x = cmd.linear.y = cmd.angular.z = 0; vel_pub_ = n_.advertise<geometry_msgs::Twist>("cmd_vel", 10); ros::NodeHandle n_private("~"); n_private.param("walk_vel", walk_vel, 0.1); n_private.param("run_vel", run_vel, 0.3); n_private.param("yaw_rate", yaw_rate,0.3); n_private.param("yaw_run_rate", yaw_rate_run, 0.5); } ~TeleopPR2Keyboard() { } void keyboardLoop(); };
int kfd = 0; struct termios cooked, raw;
void quit(int sig) { tcsetattr(kfd, TCSANOW, &cooked); exit(0); }
int main(int argc, char** argv) { ros::init(argc, argv, "keyboard_control"); TeleopPR2Keyboard tpk; tpk.init(); signal(SIGINT,quit); tpk.keyboardLoop();
return(0); }
void TeleopPR2Keyboard::keyboardLoop() { char c; bool dirty=false; tcgetattr(kfd, &cooked); memcpy(&raw, &cooked, sizeof(struct termios)); raw.c_lflag &=~ (ICANON | ECHO); raw.c_cc[VEOL] = 1; raw.c_cc[VEOF] = 2; tcsetattr(kfd, TCSANOW, &raw); puts("Reading from keyboard"); puts("---------------------------"); puts("Use 'WASD' to control the robot"); puts("Press 'Caps' to move faster"); puts("press Ctrl+C to quit"); puts("---------------------------"); for(;;) { if(read(kfd, &c, 1) < 0) { perror("read():"); exit(-1); } cmd.linear.x = cmd.angular.z = 0; switch(c) { case KEYCODE_W: cmd.linear.x = walk_vel; dirty = true; break; case KEYCODE_S: cmd.linear.x = - walk_vel; dirty = true; break; case KEYCODE_A: cmd.angular.z = yaw_rate; dirty = true; break; case KEYCODE_D: cmd.angular.z = - yaw_rate; dirty = true; break; case KEYCODE_W_CAP: cmd.linear.x = run_vel; dirty = true; break; case KEYCODE_S_CAP: cmd.linear.x = - run_vel; dirty = true; break; case KEYCODE_A_CAP: cmd.angular.z = yaw_rate_run; dirty = true; break; case KEYCODE_D_CAP: cmd.angular.z = - yaw_rate_run; dirty = true; break; default: cmd.linear.x = 0; cmd.angular.z = 0; dirty = true; break; } if (dirty == true) { vel_pub_.publish(cmd); } } }
|