Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008 #include <telekyb_joystick/Joystick.hpp>
00009
00010 #include <linux/joystick.h>
00011 #include <sensor_msgs/Joy.h>
00012 #include <telekyb_base/ROS.hpp>
00013
00014 #include <geometry_msgs/Vector3Stamped.h>
00015
00016
00017 #include <boost/algorithm/string.hpp>
00018 #include <boost/lexical_cast.hpp>
00019
00020
00021 #define MAX_NUMBER_AXES 20
00022 #define MAX_NUMBER_BUTTONS 50
00023
00024 namespace TELEKYB_NAMESPACE {
00025
00026
00027 Joystick::Joystick()
00028 : BaseJoystick("", false)
00029 {
00030
00031 }
00032
00033 Joystick::Joystick(const std::string& devPath_, bool autoOpen_)
00034 : BaseJoystick(devPath_, autoOpen_)
00035 {
00036
00037 options = JoystickOptions::InstancePtr();
00038 nodeHandle = ROSModule::Instance().getNodeNameNodeHandle();
00039 pubJoy = nodeHandle.advertise<sensor_msgs::Joy>(options->tPubName->getValue(), 1 );
00040 if (options->tPublishVector3->getValue()) {
00041 pubVector3 = nodeHandle.advertise<geometry_msgs::Vector3Stamped>(options->tPubName->getValue() + "_vector3", 1 );
00042 }
00043
00044 }
00045
00046 Joystick::~Joystick()
00047 {
00048
00049 }
00050
00051 void Joystick::run()
00052 {
00053 if (!isOpen()) {
00054 ROS_ERROR("Joystick %s not open. Cannot enter runloop. ", devPath.c_str());
00055 return;
00056 }
00057
00058
00059 std::vector<int> buttonRemapping = options->tButtonRemapping->getValue();
00060
00061 for (unsigned int i = 0; i < buttonRemapping.size(); ++i) {
00062 if (buttonRemapping[i] < 0 || buttonRemapping[i] > MAX_NUMBER_BUTTONS ) {
00063 ROS_ERROR("Wrong button mapping for button %d, value must be between 0 and %d "
00064 ,i, MAX_NUMBER_BUTTONS);
00065 ROS_ERROR("Setting identity for button %d", i);
00066 buttonRemapping[i] = i;
00067 }
00068 }
00069 std::vector<int> axisRemapping = options->tAxesRemapping->getValue();
00070
00071 for (unsigned int i = 0; i < axisRemapping.size(); ++i) {
00072 if (axisRemapping[i] < 0 || axisRemapping[i] > MAX_NUMBER_AXES ) {
00073 ROS_ERROR("Wrong axes mapping for axis %d, value must be between 0 and %d "
00074 ,i, MAX_NUMBER_AXES);
00075 ROS_ERROR("Setting identity for axis %d", i);
00076 axisRemapping[i] = i;
00077 }
00078 }
00079 std::vector<double> axisMultiplier = options->tAxisMultiplier->getValue();
00080
00081 double autorepeat_rate = options->tAutoRepeatRate->getValue();
00082 double autorepeat_interval = 1.0 / autorepeat_rate;
00083 double coalesce_interval = options->tCoalesceInterval->getValue();
00084 double scale = -1. / (1. - options->tDeadZone->getValue()) / 32767.;
00085 double unscaled_deadzone = 32767. * options->tDeadZone->getValue();
00086
00087
00088 js_event event;
00089 struct timeval tv;
00090 tv.tv_sec = 1;
00091 tv.tv_usec = 0;
00092 bool publish_now = false;
00093 bool publish_soon = false;
00094 bool tv_set = false;
00095 bool publication_pending = false;
00096
00097 fd_set set;
00098 sensor_msgs::Joy joyMsg;
00099
00100 while (ros::ok()) {
00101
00102 publish_now = false;
00103 publish_soon = false;
00104
00105 FD_ZERO(&set);
00106 FD_SET(joystick_fd, &set);
00107
00108 int select_out = select(joystick_fd + 1, &set, NULL, NULL, &tv);
00109 if (select_out == -1) {
00110 tv.tv_sec = 0;
00111 tv.tv_usec = 0;
00112
00113 continue;
00114
00115 }
00116
00117 if (FD_ISSET(joystick_fd, &set)) {
00118 if (read(joystick_fd, &event, sizeof(js_event)) == -1 && errno != EAGAIN)
00119 break;
00120
00121
00122 joyMsg.header.stamp = ros::Time().now();
00123 switch (event.type) {
00124 case JS_EVENT_BUTTON:
00125 case JS_EVENT_BUTTON | JS_EVENT_INIT:
00126
00127 if (event.number >= buttonRemapping.size()) {
00128
00129 int old_size = buttonRemapping.size();
00130 buttonRemapping.resize(event.number + 1);
00131 for (unsigned int i = old_size; i < buttonRemapping.size(); i++) {
00132
00133 buttonRemapping[i] = i;
00134 }
00135 }
00136
00137 if (buttonRemapping[event.number] >= joyMsg.buttons.size()) {
00138 int old_size = joyMsg.buttons.size();
00139 joyMsg.buttons.resize(buttonRemapping[event.number] + 1);
00140 for (unsigned int i = old_size; i < joyMsg.buttons.size(); i++) {
00141 joyMsg.buttons[i] = 0.0;
00142 }
00143 }
00144
00145
00146 joyMsg.buttons[buttonRemapping[event.number]] = (event.value ? 1 : 0);
00147
00148
00149
00150
00151
00152
00153 if (!(event.type & JS_EVENT_INIT))
00154 publish_now = true;
00155 else
00156 publish_soon = true;
00157 break;
00158 case JS_EVENT_AXIS:
00159 case JS_EVENT_AXIS | JS_EVENT_INIT:
00160
00161 if (event.number >= axisRemapping.size()) {
00162
00163 int old_size = axisRemapping.size();
00164 axisRemapping.resize(event.number + 1);
00165 for (unsigned int i = old_size; i < axisRemapping.size(); i++) {
00166
00167 axisRemapping[i] = i;
00168 }
00169 }
00170
00171 if (axisRemapping[event.number] >= axisMultiplier.size()) {
00172 int old_size = axisMultiplier.size();
00173 axisMultiplier.resize(axisRemapping[event.number] + 1);
00174 for (unsigned int i = old_size; i < axisMultiplier.size(); i++)
00175 axisMultiplier[i] = 1.0;
00176 }
00177
00178 if (axisRemapping[event.number] >= joyMsg.axes.size()) {
00179 int old_size = joyMsg.axes.size();
00180 joyMsg.axes.resize(axisRemapping[event.number] + 1);
00181 for (unsigned int i = old_size; i < joyMsg.axes.size(); i++)
00182 joyMsg.axes[i] = 0.0;
00183 }
00184 if (!(event.type & JS_EVENT_INIT))
00185 {
00186 double val = event.value;
00187
00188 if (val > unscaled_deadzone)
00189 val -= unscaled_deadzone;
00190 else if (val < -unscaled_deadzone)
00191 val += unscaled_deadzone;
00192 else
00193 val = 0;
00194 joyMsg.axes[axisRemapping[event.number]] = val * scale * axisMultiplier[axisRemapping[event.number]];
00195 }
00196
00197 publish_soon = true;
00198 break;
00199 default:
00200 ROS_WARN("joy_node: Unknown event type. Please file a ticket. time=%u, value=%d, type=%Xh, number=%d", event.time, event.value, event.type, event.number);
00201 break;
00202 }
00203 } else if (tv_set)
00204 publish_now = true;
00205
00206 if (publish_now) {
00207
00208
00209
00210
00211 if (options->tPublishVector3->getValue() && joyMsg.axes.size() >= 3) {
00212 geometry_msgs::Vector3Stamped vec3Msg;
00213 vec3Msg.header.stamp = ros::Time::now();
00214 vec3Msg.vector.x = joyMsg.axes[0];
00215 vec3Msg.vector.y = joyMsg.axes[1];
00216 vec3Msg.vector.z = joyMsg.axes[2];
00217 pubVector3.publish(vec3Msg);
00218 }
00219
00220 pubJoy.publish(joyMsg);
00221 publish_now = false;
00222 tv_set = false;
00223 publication_pending = false;
00224 publish_soon = false;
00225 }
00226
00227
00228
00229 if (!publication_pending && publish_soon) {
00230 tv.tv_sec = trunc(coalesce_interval);
00231 tv.tv_usec = (coalesce_interval - tv.tv_sec) * 1e6;
00232 publication_pending = true;
00233 tv_set = true;
00234
00235 }
00236
00237
00238 if (!tv_set && autorepeat_rate > 0) {
00239 tv.tv_sec = trunc(autorepeat_interval);
00240 tv.tv_usec = (autorepeat_interval - tv.tv_sec) * 1e6;
00241 tv_set = true;
00242
00243 }
00244
00245 if (!tv_set) {
00246 tv.tv_sec = 1;
00247 tv.tv_usec = 0;
00248 }
00249
00250
00251 }
00252 }
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271 }