cyberglove_publisher.cpp
Go to the documentation of this file.
00001 
00029 //ROS include
00030 #include <ros/ros.h>
00031 
00032 //generic C/C++ include
00033 #include <string>
00034 #include <sstream>
00035 
00036 #include "cyberglove/cyberglove_publisher.h"
00037 
00038 using namespace ros;
00039 using namespace xml_calibration_parser;
00040 
00041 namespace cyberglove{
00042 
00044   //    CONSTRUCTOR/DESTRUCTOR   //
00046 
00047   CyberglovePublisher::CyberglovePublisher()
00048     : n_tilde("~"), sampling_rate(0.0), publish_counter_max(0), publish_counter_index(0),
00049       path_to_glove("/dev/ttyS0"), publishing(true)
00050   {
00051 
00052     std::string path_to_calibration;
00053     n_tilde.param("path_to_calibration", path_to_calibration, std::string("/etc/robot/calibration.d/cyberglove.cal"));
00054     ROS_INFO("Calibration file loaded for the Cyberglove: %s", path_to_calibration.c_str());
00055 
00056     initialize_calibration(path_to_calibration);
00057 
00058     //set sampling frequency
00059     double sampling_freq;
00060     n_tilde.param("sampling_frequency", sampling_freq, 100.0);
00061     sampling_rate = Rate(sampling_freq);
00062 
00063     // set publish_counter: the number of data we'll average
00064     // before publishing.
00065     double publish_freq;
00066     n_tilde.param("publish_frequency", publish_freq, 20.0);
00067     publish_counter_max = (int)(sampling_freq / publish_freq);
00068 
00069     ROS_INFO_STREAM("Sampling at " << sampling_freq << "Hz ; Publishing at "
00070                     << publish_freq << "Hz ; Publish counter: "<< publish_counter_max);
00071 
00072     // set path to glove
00073     n_tilde.param("path_to_glove", path_to_glove, std::string("/dev/ttyS0"));
00074     ROS_INFO("Opening glove on port: %s", path_to_glove.c_str());
00075 
00076     //initialize the connection with the cyberglove and binds the callback function
00077     serial_glove = boost::shared_ptr<CybergloveSerial>(new CybergloveSerial(path_to_glove, boost::bind(&CyberglovePublisher::glove_callback, this, _1, _2)));
00078 
00079     int res = -1;
00080     cyberglove_freq::CybergloveFreq frequency;
00081 
00082     switch( (int)sampling_freq)
00083     {
00084     case 100:
00085       res = serial_glove->set_frequency(frequency.hundred_hz);
00086       break;
00087     case 45:
00088       res = serial_glove->set_frequency(frequency.fourtyfive_hz);
00089       break;
00090     case 10:
00091       res = serial_glove->set_frequency(frequency.ten_hz);
00092       break;
00093     case 1:
00094       res = serial_glove->set_frequency(frequency.one_hz);
00095       break;
00096     default:
00097       res = serial_glove->set_frequency(frequency.hundred_hz);
00098       break;
00099     }
00100     //No filtering: we're oversampling the data, we want a fast poling rate
00101     res = serial_glove->set_filtering(false);
00102     //We want the glove to transmit the status (light on/off)
00103     res = serial_glove->set_transmit_info(true);
00104     //start reading the data.
00105     res = serial_glove->start_stream();
00106 
00107     //publishes calibrated JointState messages
00108     std::string prefix;
00109     std::string searched_param;
00110     n_tilde.searchParam("cyberglove_prefix", searched_param);
00111     n_tilde.param(searched_param, prefix, std::string());
00112     std::string full_topic = prefix + "/calibrated/joint_states";
00113     cyberglove_pub = n_tilde.advertise<sensor_msgs::JointState>(full_topic, 2);
00114 
00115     //publishes raw JointState messages
00116     n_tilde.searchParam("cyberglove_prefix", searched_param);
00117     n_tilde.param(searched_param, prefix, std::string());
00118     full_topic = prefix + "/raw/joint_states";
00119     cyberglove_raw_pub = n_tilde.advertise<sensor_msgs::JointState>(full_topic, 2);
00120 
00121     //initialises joint names (the order is important)
00122     jointstate_msg.name.push_back("G_ThumbRotate");
00123     jointstate_msg.name.push_back("G_ThumbMPJ");
00124     jointstate_msg.name.push_back("G_ThumbIJ");
00125     jointstate_msg.name.push_back("G_ThumbAb");
00126     jointstate_msg.name.push_back("G_IndexMPJ");
00127     jointstate_msg.name.push_back("G_IndexPIJ");
00128     jointstate_msg.name.push_back("G_IndexDIJ");
00129     jointstate_msg.name.push_back("G_MiddleMPJ");
00130     jointstate_msg.name.push_back("G_MiddlePIJ");
00131     jointstate_msg.name.push_back("G_MiddleDIJ");
00132     jointstate_msg.name.push_back("G_MiddleIndexAb");
00133     jointstate_msg.name.push_back("G_RingMPJ");
00134     jointstate_msg.name.push_back("G_RingPIJ");
00135     jointstate_msg.name.push_back("G_RingDIJ");
00136     jointstate_msg.name.push_back("G_RingMiddleAb");
00137     jointstate_msg.name.push_back("G_PinkieMPJ");
00138     jointstate_msg.name.push_back("G_PinkiePIJ");
00139     jointstate_msg.name.push_back("G_PinkieDIJ");
00140     jointstate_msg.name.push_back("G_PinkieRingAb");
00141     jointstate_msg.name.push_back("G_PalmArch");
00142     jointstate_msg.name.push_back("G_WristPitch");
00143     jointstate_msg.name.push_back("G_WristYaw");
00144 
00145     jointstate_raw_msg.name = jointstate_msg.name;
00146   }
00147 
00148   CyberglovePublisher::~CyberglovePublisher()
00149   {
00150   }
00151 
00152   void CyberglovePublisher::initialize_calibration(std::string path_to_calibration)
00153   {
00154     calibration_parser = XmlCalibrationParser(path_to_calibration);
00155   }
00156 
00157   bool CyberglovePublisher::isPublishing()
00158   {
00159     if (publishing)
00160     {
00161       return true;
00162     }
00163     else
00164     {
00165       return false;
00166     }
00167   }
00168 
00169   void CyberglovePublisher::setPublishing(bool value)
00170   {
00171     publishing = value;
00172   }
00173 
00175   //       CALLBACK METHOD       //
00177   void CyberglovePublisher::glove_callback(std::vector<float> glove_pos, bool light_on)
00178   {
00179     //if the light is off, we don't publish any data.
00180     if( !light_on )
00181     {
00182       publishing = false;
00183       ROS_DEBUG("The glove button is off, no data will be read / sent");
00184       ros::spinOnce();
00185       sampling_rate.sleep();
00186       return;
00187     }
00188     publishing = true;
00189 
00190     //appends the current position to the vector of position
00191     glove_positions.push_back( glove_pos );
00192 
00193     //if we've enough samples, publish the data:
00194     if( publish_counter_index == publish_counter_max )
00195     {
00196       //reset the messages
00197       jointstate_msg.position.clear();
00198       jointstate_msg.velocity.clear();
00199       jointstate_raw_msg.position.clear();
00200       jointstate_raw_msg.velocity.clear();
00201 
00202       //fill the joint_state msg with the averaged glove data
00203       for(unsigned int index_joint = 0; index_joint < CybergloveSerial::glove_size; ++index_joint)
00204       {
00205         //compute the average over the samples for the current joint
00206         float averaged_value = 0.0f;
00207         for (unsigned int index_sample = 0; index_sample < publish_counter_max; ++index_sample)
00208         {
00209           averaged_value += glove_positions[index_sample][index_joint];
00210         }
00211         averaged_value /= publish_counter_max;
00212 
00213         jointstate_raw_msg.position.push_back(averaged_value);
00214         add_jointstate(averaged_value, jointstate_msg.name[index_joint]);
00215       }
00216 
00217       //publish the msgs
00218       cyberglove_pub.publish(jointstate_msg);
00219       cyberglove_raw_pub.publish(jointstate_raw_msg);
00220 
00221       publish_counter_index = 0;
00222       glove_positions.clear();
00223     }
00224 
00225     publish_counter_index += 1;
00226     ros::spinOnce();
00227     sampling_rate.sleep();
00228   }
00229 
00230   void CyberglovePublisher::add_jointstate(float position, std::string joint_name)
00231   {
00232     //get the calibration value
00233     float calibration_value = calibration_parser.get_calibration_value(position, joint_name);
00234     //publish the glove position
00235     jointstate_msg.position.push_back(calibration_value);
00236     //set velocity to 0.
00237     //@TODO : send the correct velocity ?
00238     jointstate_msg.velocity.push_back(0.0);
00239   }
00240 }// end namespace
00241 
00242 
00243 
00244 /* For the emacs weenies in the crowd.
00245 Local Variables:
00246    c-basic-offset: 2
00247 End:
00248 */


cyberglove
Author(s): Ugo Cupcic
autogenerated on Fri Jan 3 2014 12:04:16