Go to the documentation of this file.00001
00002
00003
00004
00005
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
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
00149 std::vector<float> saveAxes = joyMsg.axes;
00150 std::vector<int> saveButtons = joyMsg.buttons;
00151
00152
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
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
00187
00188 joystick = new Joystick(vendorId, productId, name);
00189 if (joystick->isOpen()) {
00190
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
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
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 }