00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include <string>
00030 #include <ros/ros.h>
00031 #include "razer_hydra/hydra.h"
00032 #include "razer_hydra/HydraRaw.h"
00033 #include "razer_hydra/Hydra.h"
00034 #include "tf/tf.h"
00035
00036 #include "sensor_msgs/Joy.h"
00037
00038
00039 #include <tf/transform_broadcaster.h>
00040
00041 using namespace razer_hydra;
00042 using std::string;
00043
00044 int main(int argc, char **argv)
00045 {
00046 ros::init(argc, argv, "hydra_driver");
00047 ros::NodeHandle n, n_private("~");
00048
00049
00050 string device;
00051 n_private.param<std::string>("device", device, "/dev/hidraw0");
00052
00053 bool publish_tf = false;
00054 n_private.param<bool>("publish_tf", publish_tf, false);
00055
00056 int polling_ms = 5;
00057 n_private.param<int>("polling_ms", polling_ms, 5);
00058 if( polling_ms <= 0 ) {
00059 ROS_WARN("polling_ms must be >= 1. Setting to default rate of 5 ms.");
00060 polling_ms = 5;
00061 }
00062
00063
00064
00065 double corner_hz = 2.5;
00066 n_private.param<double>("corner_hz", corner_hz, 2.5);
00067 ROS_INFO("Using filter corner frequency of %.1f Hz", corner_hz);
00068
00069
00070 double pivot_arr[3];
00071 n_private.param<double>("pivot_x", pivot_arr[0], 0.0);
00072 n_private.param<double>("pivot_y", pivot_arr[1], 0.0);
00073 n_private.param<double>("pivot_z", pivot_arr[2], 0.0);
00074 tf::Vector3 pivot_vec(pivot_arr[0], pivot_arr[1], pivot_arr[2]);
00075
00076 double grab_arr[3];
00077 n_private.param<double>("grab_x", grab_arr[0], 0.0);
00078 n_private.param<double>("grab_y", grab_arr[1], 0.0);
00079 n_private.param<double>("grab_z", grab_arr[2], 0.0);
00080 tf::Vector3 grab_vec(grab_arr[0], grab_arr[1], grab_arr[2]);
00081
00082 bool use_grab_frame = false;
00083 n_private.param<bool>("use_grab_frame", use_grab_frame, false);
00084
00085 ROS_INFO("Setting pivot offset [%.3f, %.3f, %.3f]", pivot_vec.x(), pivot_vec.y(), pivot_vec.z());
00086 ROS_INFO("Setting grab offset [%.3f, %.3f, %.3f]", grab_vec.x(), grab_vec.y(), grab_vec.z());
00087 if(use_grab_frame)
00088 ROS_INFO("Sending messages using the 'grab' frame.");
00089 else
00090 ROS_INFO("Sending messages using the 'pivot' frame.");
00091
00092 if(publish_tf)
00093 ROS_INFO("Publishing frame data to TF.");
00094
00095
00096 ros::Publisher raw_pub = n.advertise<razer_hydra::HydraRaw>("hydra_raw", 1);
00097 ros::Publisher calib_pub = n.advertise<razer_hydra::Hydra>("hydra_calib", 1);
00098 ros::Publisher joy_pub = n.advertise<sensor_msgs::Joy>("hydra_joy", 1);
00099 tf::TransformBroadcaster *broadcaster = 0;
00100 if(publish_tf) broadcaster = new tf::TransformBroadcaster();
00101
00102
00103 RazerHydra hydra;
00104 ROS_INFO("opening hydra on %s", device.c_str());
00105 if (!hydra.init(device.c_str()))
00106 {
00107 ROS_FATAL("couldn't open hydra on %s", device.c_str());
00108 return 1;
00109 }
00110 ROS_INFO("starting stream... (first packet takes a few seconds)");
00111 while (n.ok())
00112 {
00113 if (hydra.poll(polling_ms, corner_hz))
00114 {
00115
00116 razer_hydra::HydraRaw msg;
00117 msg.header.stamp = ros::Time::now();
00118 for (int i = 0; i < 6; i++)
00119 msg.pos[i] = hydra.raw_pos[i];
00120 for (int i = 0; i < 8; i++)
00121 msg.quat[i] = hydra.raw_quat[i];
00122 for (int i = 0; i < 2; i++)
00123 msg.buttons[i] = hydra.raw_buttons[i];
00124 for (int i = 0; i < 6; i++)
00125 msg.analog[i] = hydra.raw_analog[i];
00126 raw_pub.publish(msg);
00127
00128 std::vector<geometry_msgs::TransformStamped> transforms(4);
00129
00130
00131 razer_hydra::Hydra h_msg;
00132 h_msg.header.stamp = msg.header.stamp;
00133 for (int i = 0; i < 2; i++)
00134 {
00135 tf::Transform transform(hydra.quat[i], hydra.pos[i]);
00136 tf::Transform t_pivot = transform, t_grab = transform;
00137
00138
00139 t_pivot.setOrigin(transform.getOrigin() + transform.getBasis()*pivot_vec);
00140 tf::transformTFToMsg(t_pivot, transforms[i].transform);
00141
00142
00143 t_grab.setOrigin(transform.getOrigin() + transform.getBasis()*grab_vec);
00144 tf::transformTFToMsg(t_grab, transforms[2+i].transform);
00145
00146 h_msg.paddles[i].transform = use_grab_frame ? transforms[2+i].transform : transforms[i].transform;
00147 }
00148 for (int i = 0; i < 7; i++)
00149 {
00150 h_msg.paddles[0].buttons[i] = hydra.buttons[i];
00151 h_msg.paddles[1].buttons[i] = hydra.buttons[i+7];
00152 }
00153 for (int i = 0; i < 2; i++)
00154 {
00155 h_msg.paddles[0].joy[i] = hydra.analog[i];
00156 h_msg.paddles[1].joy[i] = hydra.analog[i+3];
00157 }
00158 h_msg.paddles[0].trigger = hydra.analog[2];
00159 h_msg.paddles[1].trigger = hydra.analog[5];
00160 calib_pub.publish(h_msg);
00161
00162 if(broadcaster)
00163 {
00164 std::string frames[4] = {"hydra_left_pivot", "hydra_right_pivot", "hydra_left_grab", "hydra_right_grab"};
00165 for(int kk = 0; kk < 4; kk++)
00166 {
00167 transforms[kk].header.stamp = h_msg.header.stamp;
00168 transforms[kk].header.frame_id = "hydra_base";
00169 transforms[kk].child_frame_id = frames[kk];
00170 }
00171
00172 broadcaster->sendTransform(transforms);
00173 }
00174
00175
00176 sensor_msgs::Joy joy_msg;
00177
00178 joy_msg.axes.resize(16);
00179 joy_msg.buttons.resize(16);
00180 joy_msg.header.stamp = h_msg.header.stamp;
00181
00182
00183
00184 joy_msg.axes[0] = -h_msg.paddles[0].joy[0];
00185 joy_msg.axes[1] = h_msg.paddles[0].joy[1];
00186 joy_msg.buttons[1] = h_msg.paddles[0].buttons[6];
00187
00188 joy_msg.axes[2] = -h_msg.paddles[1].joy[0];
00189 joy_msg.axes[3] = h_msg.paddles[1].joy[1];
00190 joy_msg.buttons[2] = h_msg.paddles[1].buttons[6];
00191
00192
00193 joy_msg.buttons[7] = h_msg.paddles[0].buttons[1];
00194 joy_msg.buttons[5] = h_msg.paddles[0].buttons[3];
00195 joy_msg.buttons[6] = h_msg.paddles[0].buttons[2];
00196 joy_msg.buttons[4] = h_msg.paddles[0].buttons[4];
00197
00198 joy_msg.buttons[15] = h_msg.paddles[1].buttons[1];
00199 joy_msg.buttons[13] = h_msg.paddles[1].buttons[3];
00200 joy_msg.buttons[14] = h_msg.paddles[1].buttons[2];
00201 joy_msg.buttons[12] = h_msg.paddles[1].buttons[4];
00202
00203
00204 joy_msg.buttons[0] = h_msg.paddles[0].buttons[5];
00205 joy_msg.buttons[3] = h_msg.paddles[1].buttons[5];
00206
00207
00208 joy_msg.buttons[10] = h_msg.paddles[0].buttons[0];
00209 joy_msg.buttons[8] = h_msg.paddles[0].trigger > 0.15;
00210 joy_msg.axes[8] = h_msg.paddles[0].trigger;
00211
00212 joy_msg.buttons[11] = h_msg.paddles[1].buttons[0];
00213 joy_msg.buttons[9] = h_msg.paddles[1].trigger > 0.15;
00214 joy_msg.axes[9] = h_msg.paddles[1].trigger;
00215
00216
00217 for ( int i=4; i<8; i++ )
00218 {
00219 joy_msg.axes[i] = joy_msg.buttons[i] ? 1.0 : 0.0;
00220 }
00221 for ( int i=10; i<16; i++ )
00222 {
00223 joy_msg.axes[i] = joy_msg.buttons[i] ? 1.0 : 0.0;
00224 }
00225
00226 joy_pub.publish(joy_msg);
00227
00228 ros::spinOnce();
00229 }
00230 }
00231
00232
00233 if(broadcaster) delete broadcaster;
00234 return 0;
00235 }
00236