teleop.cpp
Go to the documentation of this file.
00001 #include <geometry_msgs/Twist.h>
00002 #include <std_msgs/Empty.h>
00003 #include <iostream>
00004 #include "universal_teleop/Control.h"
00005 #include "teleop.h"
00006 
00007 using namespace std;
00008 namespace teleop = universal_teleop;
00009 
00010 teleop::Teleop::Teleop(void) : n("~"), override_enabled(false)
00011 {
00012   /* load mappings */
00013   joy_axes = { {"pitch", 1}, {"roll", 0}, {"yaw", 3}, {"vertical",2} };
00014   n.param("joy_axes", joy_axes, joy_axes);
00015   for (auto& j : joy_axes) joy_axis_map[j.second] = j.first;
00016   
00017   map<string, int> joy_buttons = { {"override", 4}, {"start", 2}, {"stop", 1}, {"takeoff", 10}, {"land", 11} };
00018   n.param("joy_buttons", joy_buttons, joy_buttons);
00019   for (auto& j : joy_buttons) joy_button_map[j.second] = j.first;
00020 
00021   std::map<std::string, int> keys = { {"override", 32}, {"start", 113}, {"stop", 97}, {"takeoff", 121}, {"land", 104} };
00022   n.param("keys", keys, keys);
00023   for (auto& k : keys) key_map[k.second] = k.first;
00024 
00025   axis_scales = { { "pitch", 1.0f }, { "roll", 1.0f }, { "yaw", 1.0f }, { "vertical", 1.0f } };
00026   n.param("scales", axis_scales, axis_scales);
00027   for (auto& k: axis_scales) cout << k.first << " " << k.second << endl;
00028 
00029   /* subscribe to input sources */
00030   joy_sub = n.subscribe("/joy", 1, &Teleop::joystick_event, this);
00031   keyup_sub = n.subscribe("/keyboard/keyup", 1, &Teleop::keyboard_up_event, this);
00032   keydown_sub = n.subscribe("/keyboard/keydown", 1, &Teleop::keyboard_down_event, this);
00033 
00034   /* publish events and control commands */  
00035   pub_vel = n.advertise<geometry_msgs::Twist>("/robot/cmd_vel", 5);
00036   
00037   pub_event = n.advertise<teleop::Event>("events", 5);
00038   pub_control = n.advertise<teleop::Control>("controls", 1);
00039 
00040   /* special events for UAV commands */
00041   pub_takeoff = n.advertise<std_msgs::Empty>("/robot/takeoff", 5);
00042   pub_land = n.advertise<std_msgs::Empty>("/robot/land", 5);
00043   pub_emergency = n.advertise<std_msgs::Empty>("/robot/reset", 5);
00044 }
00045 
00046 void teleop::Teleop::process_event(const teleop::Event& e)
00047 {
00048   if (e.event == "override") {
00049     if (e.state == 0 && override_enabled) {
00050       // when releasing override, stop robot 
00051       geometry_msgs::Twist vel;
00052       vel.linear.x = vel.linear.y = vel.linear.z = 0;
00053       vel.angular.x = vel.angular.y = 1; // non-zero to avoid hovering when zero-ing controls
00054       vel.angular.z = 0;
00055       pub_vel.publish(vel);
00056     }
00057     override_enabled = e.state;
00058   }
00059   else {
00060     if (override_enabled && e.state) {
00061       if (e.event == "takeoff") pub_takeoff.publish(std_msgs::Empty());
00062       else if (e.event == "land") pub_land.publish(std_msgs::Empty());
00063       else if (e.event == "emergency") pub_emergency.publish(std_msgs::Empty());
00064     }
00065   }
00066   pub_event.publish(e);
00067 }
00068 
00069 void teleop::Teleop::joystick_event(const sensor_msgs::Joy::ConstPtr& joy)
00070 {
00071   if (last_joy_msg.axes.empty()) {
00072     last_joy_msg = *joy;
00073     for (auto& b : last_joy_msg.buttons) b = 0;
00074   }
00075 
00076   // process buttons
00077   for (uint32_t b = 0; b < joy->buttons.size(); b++) {
00078     if (joy->buttons[b] != last_joy_msg.buttons[b]) {
00079       teleop::Event e;
00080       if (joy_button_map.find(b) == joy_button_map.end()) e.event = "unknown";
00081       else e.event = joy_button_map[b];
00082       e.state = joy->buttons[b];      
00083       process_event(e);
00084     }
00085   }
00086 
00087   // process axis
00088   for (uint32_t a = 0; a < joy->axes.size(); a++) {
00089     if (joy->axes[a] != last_joy_msg.axes[a]) {
00090       teleop::Control c;
00091       if (joy_axis_map.find(a) == joy_axis_map.end()) c.control = "unknown";
00092       else c.control = joy_axis_map[a];
00093       c.value = joy->axes[a];      
00094       pub_control.publish(c);
00095     }
00096   }
00097   
00098   last_joy_msg = *joy;
00099 }
00100 
00101 void teleop::Teleop::keyboard_up_event(const keyboard::Key::ConstPtr& key)
00102 {
00103   ROS_INFO_STREAM("keyup: " << key->code);
00104   teleop::Event e;
00105   if (key_map.find(key->code) == key_map.end()) e.event = "unknown";
00106   else e.event = key_map[key->code];
00107   e.state = 0;
00108   process_event(e);
00109 }
00110 
00111 void teleop::Teleop::keyboard_down_event(const keyboard::Key::ConstPtr& key)
00112 {
00113   teleop::Event e;
00114   if (key_map.find(key->code) == key_map.end()) e.event = "unknown";
00115   else e.event = key_map[key->code];
00116   e.state = 1;
00117   process_event(e);
00118 }
00119 
00120 void teleop::Teleop::control(void)
00121 {
00122   if (override_enabled) {
00123     geometry_msgs::Twist vel;
00124     vel.linear.x = last_joy_msg.axes[joy_axes["pitch"]] * axis_scales["pitch"];
00125     vel.linear.y = last_joy_msg.axes[joy_axes["roll"]] * axis_scales["roll"];
00126     vel.linear.z = last_joy_msg.axes[joy_axes["vertical"]] * axis_scales["vertical"];
00127     vel.angular.x = vel.angular.y = 1; // non-zero to avoid hovering when zero-ing controls
00128     vel.angular.z = last_joy_msg.axes[joy_axes["yaw"]] * axis_scales["yaw"];
00129     pub_vel.publish(vel);
00130   }
00131 }
00132 
00133 


universal_teleop
Author(s):
autogenerated on Thu Aug 27 2015 15:32:46