Joystick.cpp
Go to the documentation of this file.
00001 /*
00002  * Joystick.cpp
00003  *
00004  *  Created on: Oct 24, 2011
00005  *      Author: mriedel
00006  */
00007 
00008 #include <telekyb_hid/Joystick.hpp>
00009 
00010 
00011 #include <fstream>
00012 #include <yaml-cpp/yaml.h>
00013 
00014 #include <sensor_msgs/Joy.h>
00015 #include <telekyb_base/ROS/ROSModule.hpp>
00016 
00017 #include <ros/ros.h>
00018 
00019 #include <boost/algorithm/string.hpp>
00020 
00021 namespace YAML {
00022         template<>
00023    struct convert<TELEKYB_NAMESPACE::JoyAxis> {
00024               static Node encode(const TELEKYB_NAMESPACE::JoyAxis& rhs) {
00025                  Node node;
00026                  node["pos"] = rhs.bytePos;
00027                  node["name"] = rhs.name;
00028                  node["min"] = rhs.min;
00029                  node["max"] = rhs.max;
00030                  return node;
00031               }
00032 
00033               static bool decode(const Node& node, TELEKYB_NAMESPACE::JoyAxis& rhs) {
00034                   if (node["pos"] && node["name"] && node["min"] && node["max"]) {
00035                                  rhs.bytePos = node["pos"].as<int>();
00036                                  rhs.name = node["name"].as<std::string>();
00037                                  rhs.min = node["min"].as<int>();
00038                                  rhs.max = node["max"].as<int>();
00039                                  return true;
00040                  }
00041 
00042                  return false;
00043               }
00044    };
00045 }
00046 
00047 
00048 namespace YAML {
00049 template<>
00050    struct convert<TELEKYB_NAMESPACE::JoyButton> {
00051               static Node encode(const TELEKYB_NAMESPACE::JoyButton& rhs) {
00052                  Node node;
00053                  node["pos"] = rhs.bytePos;
00054                  node["name"] = rhs.name;
00055                  node["value"] = rhs.value;
00056                  node["mask"] = rhs.mask;
00057                  return node;
00058               }
00059 
00060               static bool decode(const Node& node, TELEKYB_NAMESPACE::JoyButton& rhs) {
00061                   if (node["pos"] && node["name"] && node["value"] && node["mask"]) {
00062                          rhs.bytePos = node["pos"].as<int>();
00063                          rhs.name = node["name"].as<std::string>();
00064                          rhs.value = node["value"].as<int>();
00065                          rhs.mask = node["mask"].as<int>();
00066                          return true;
00067                   }
00068                   return false;
00069               }
00070    };
00071 }
00072 
00073 namespace TELEKYB_NAMESPACE {
00074 
00075 Joystick::Joystick(unsigned short int vendorID_ , unsigned short int productID_, const std::string& name_)
00076         : HIDDevice(vendorID_, productID_), name(name_)
00077 {
00078         options = JoystickOptions::InstancePtr();
00079 
00080         nodeHandle = ROSModule::Instance().getNodeNameNodeHandle();
00081 
00082         frameID = getProductString();
00083         std::string topicName = options->tPubName->getValue();
00084         if (options->tJoystickUseProductIDForRosPath->getValue()) {
00085                 topicName = getProductString();
00086                 boost::erase_all(topicName, " ");
00087                 boost::erase_all(topicName, "(");
00088                 boost::erase_all(topicName, ")");
00089                 boost::erase_all(topicName, "-");
00090                 ROS_INFO_STREAM("String: " << topicName);
00091         }
00092         pub = nodeHandle.advertise<sensor_msgs::Joy>(topicName, 100);
00093 
00094         config.setAxisCutOff(options->tDeadZone->getValue());
00095 }
00096 
00097 Joystick::~Joystick()
00098 {
00099 
00100 }
00101 
00102 void Joystick::startThread()
00103 {
00104         thread = new boost::thread(&Joystick::run, this);
00105 }
00106 
00107 void Joystick::joinThread()
00108 {
00109         // block till done
00110         if (thread) {
00111                 thread->join();
00112         }
00113 }
00114 
00115 void Joystick::setVectors(const std::vector<unsigned char>& byteArray_,
00116                 const std::vector<JoyAxis>& axes_, const std::vector<JoyButton>& buttons_)
00117 {
00118         config.setVectors(byteArray_, axes_, buttons_);
00119 
00120         config.setModifiers(options->tButtonRemapping->getValue(),
00121                         options->tAxesRemapping->getValue(), options->tAxisMultiplier->getValue());
00122 
00123 }
00124 
00125 std::string Joystick::getName() const
00126 {
00127         return name;
00128 }
00129 
00130 void Joystick::setName(const std::string& name_)
00131 {
00132         name = name_;
00133 }
00134 
00135 void Joystick::run()
00136 {
00137         hid_set_nonblocking(handle,1);
00138         unsigned char buffer[256];
00139         int res;
00140         sensor_msgs::Joy joyMsg;
00141         joyMsg.header.frame_id = frameID;
00142         while(ros::ok())
00143         {
00144 
00145                 if ((res = hid_read(handle, buffer, sizeof(buffer))) > 0) {
00146 
00147                         joyMsg.header.stamp = ros::Time::now();
00148                         // store values
00149                         std::vector<float> saveAxes = joyMsg.axes;
00150                         std::vector<int> saveButtons = joyMsg.buttons;
00151 
00152                         // Fill new.
00153                         config.parseInput(buffer, joyMsg);
00154 
00155                         bool axesUnchanged = std::equal(saveAxes.begin(), saveAxes.end(), joyMsg.axes.begin());
00156                         bool buttonsUnchanged = std::equal(saveButtons.begin(), saveButtons.end(), joyMsg.buttons.begin());
00157 
00158                         // apply remappings
00159                         if (!(axesUnchanged && buttonsUnchanged)) {
00160                                 pub.publish(joyMsg);
00161                         }
00162 
00163                 }
00164 
00165                 usleep(10);
00166         }
00167 }
00168 
00169 void Joystick::getJoysticks(const std::string& filename, std::vector<Joystick*>& joysticks)
00170 {
00171         std::ifstream fin(filename.c_str());
00172         std::vector<YAML::Node> joystickConfigs = YAML::LoadAll(fin);
00173 
00174         std::string name;
00175         int vendorId;
00176         int productId;
00177 
00178 
00179         for (unsigned int i = 0; i < joystickConfigs.size(); ++i) {
00180                 Joystick* joystick = NULL;
00181                 try {
00182                         name = joystickConfigs[i]["name"].as<std::string>();
00183                         vendorId = joystickConfigs[i]["vendor-id"].as<int>();
00184                         productId = joystickConfigs[i]["product-id"].as<int>();
00185 
00186                         //ROS_INFO("Vendor: %d, Product: %d", vendorId, productId);
00187 
00188                         joystick = new Joystick(vendorId, productId, name);
00189                         if (joystick->isOpen()) {
00190                                 // Create and attach JoystickOptions
00191                                 const YAML::Node& byteNode = joystickConfigs[i]["defaultByte"];
00192                                 std::vector<unsigned char> byteArray(byteNode.size());
00193                                 for(unsigned j=0;j<byteNode.size();j++) {
00194                                         byteArray[j] = byteNode[j].as<int>();
00195                                 }
00196 
00197                                 const YAML::Node& axisNode = joystickConfigs[i]["axes"];
00198                                 std::vector<JoyAxis> axes(axisNode.size());
00199                                 for(unsigned j=0;j<axisNode.size();j++) {
00200                                         //std::cout << axisNode[j];
00201                                         axes[j] = axisNode[j].as<JoyAxis>();
00202                                 }
00203 
00204                                 const YAML::Node& buttonNode = joystickConfigs[i]["buttons"];
00205                                 std::vector<JoyButton> buttons(buttonNode.size());
00206                                 for(unsigned j=0;j<buttonNode.size();j++) {
00207                                         buttons[j] = buttonNode[j].as<JoyButton>();
00208                                 }
00209 
00210                                 // set config
00211                                 joystick->setVectors(byteArray, axes, buttons);
00212 
00213                                 joysticks.push_back(joystick);
00214                         } else {
00215                                 delete joystick;
00216                         }
00217 
00218                 } catch (YAML::Exception &e) {
00219                         ROS_ERROR_STREAM("YAML Exception: " << e.what());
00220                         joysticks.clear();
00221                 } catch (std::runtime_error &e) {
00222                         ROS_ERROR_STREAM("YAML Exception: " << e.what());
00223                         joysticks.clear();
00224                 }
00225         }
00226 
00227         fin.close();
00228 
00229 
00230 }
00231 
00232 } /* namespace telekyb */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends Defines


telekyb_hid
Author(s): mriedel
autogenerated on Mon Nov 11 2013 11:14:51