phidgets_range_sensors.cpp
Go to the documentation of this file.
00001 // see http://www.phidgets.com/products.php?category=2&product_id=3520_0
00002 // distance calculation: Distance (cm) = 2076/(SensorValue - 11)             (the formula is only valid for a SensorValue between 80 to 530)
00003 // TODO: separate into two packages: cob_phidgets_driver (publishing only raw values as sensor_msgs/Range message) and cob_tray_status (evaluating the Range messages to decide if tray is occupied or not, eventually also at which position it is occupied) 
00004 
00005 #include "ros/ros.h"
00006 #include "std_msgs/Bool.h"
00007 #include "sensor_msgs/Range.h"
00008 
00009 #include <libphidgets/phidget21.h>
00010 #include <sstream>
00011 
00012 class Sensor
00013 {
00014         ros::NodeHandle n_;
00015         ros::Publisher pub_range_;
00016         int id_, filter_size_;
00017         std::list<int> vals_;
00018         std::string frame_id_;
00019 public:
00020 
00021         Sensor(const std::string &fr_id, const int id, const int filter_size = 10) :
00022                         id_(id), filter_size_(filter_size), frame_id_(fr_id)
00023         {
00024                 char buffer[256];
00025                 sprintf(buffer, "range_%d", id);
00026                 pub_range_ = n_.advertise<sensor_msgs::Range>(buffer, 0);
00027         }
00028 
00029         void publish()
00030         {
00031                 pub_range_.publish((sensor_msgs::Range) *this);
00032         }
00033 
00034         operator sensor_msgs::Range() const
00035         {
00036                 sensor_msgs::Range msg;
00037                 msg.header.stamp = ros::Time::now();
00038                 msg.header.frame_id = frame_id_;
00039                 msg.radiation_type = sensor_msgs::Range::INFRARED;
00040                 msg.min_range = 0.04;
00041                 msg.max_range = 0.3;
00042                 msg.field_of_view = 0; //not given!
00043 
00044                 int sum = 0, num = 0;
00045                 for (std::list<int>::const_iterator it = vals_.begin();
00046                                 it != vals_.end(); it++)
00047                 {
00048                         sum += *it;
00049                         ++num;
00050                 }
00051                 msg.range = 20.76 / (sum / (double) num - 11.);
00052 
00053                 return msg;
00054         }
00055 
00056         int getId() const
00057         {
00058                 return id_;
00059         }
00060 
00061         void update(const int v)
00062         {
00063                 if ((int)vals_.size() < filter_size_)
00064                         vals_.push_back(v);
00065                 else
00066                 {
00067                         vals_.push_back(v);
00068                         vals_.pop_front();
00069                 }
00070         }
00071 
00072 };
00073 
00074 void display_generic_properties(CPhidgetHandle phid)
00075 {
00076         int sernum, version;
00077         const char *deviceptr, *label;
00078         CPhidget_getDeviceType(phid, &deviceptr);
00079         CPhidget_getSerialNumber(phid, &sernum);
00080         CPhidget_getDeviceVersion(phid, &version);
00081         CPhidget_getDeviceLabel(phid, &label);
00082 
00083         ROS_INFO("%s", deviceptr);
00084         ROS_INFO("Version: %8d SerialNumber: %10d", version, sernum);
00085         ROS_INFO("Label: %s", label);
00086         return;
00087 }
00088 
00089 int IFK_AttachHandler(CPhidgetHandle IFK, void *userptr)
00090 {
00091         //CPhidgetInterfaceKit_setSensorChangeTrigger((CPhidgetInterfaceKitHandle)IFK, 0, 0);
00092         //printf("Attach handler ran!\n");
00093         return 0;
00094 }
00095 
00096 int IFK_SensorChangeHandler(CPhidgetInterfaceKitHandle IFK, void *userptr,
00097                 int Index, int Value)
00098 {
00099         std::vector<Sensor>* g_sensors = (std::vector<Sensor>*) userptr;
00100         for (size_t i = 0; i < g_sensors->size(); i++)
00101                 if ((*g_sensors)[i].getId() == Index)
00102                         (*g_sensors)[i].update(Value);
00103         return 0;
00104 }
00105 
00106 int main(int argc, char **argv)
00107 {
00108         ros::init(argc, argv, "cob_phidgets");
00109 
00110         ros::NodeHandle nh_("~");
00111         std::vector<Sensor> g_sensors;
00112         if (nh_.hasParam("sensors"))
00113         {
00114                 XmlRpc::XmlRpcValue v;
00115                 nh_.param("sensors", v, v);
00116                 for (int i = 0; i < v.size(); i++)
00117                 {
00118                         ROS_ASSERT(v[i].size()>=2);
00119 
00120                         int id = v[i][0];
00121                         std::string fr_id = v[i][1];
00122                         int filter = v.size() > 2 ? (int) v[i][2] : 10;
00123 
00124                         g_sensors.push_back(Sensor(fr_id, id, filter));
00125                 }
00126         }
00127         else
00128         {
00129                 ROS_ERROR("Parameter sensors not set, shutting down node...");
00130                 nh_.shutdown();
00131                 return false;
00132         }
00133 
00134         ros::Rate loop_rate(10);
00135 
00136         //init and open phidget
00137         int numInputs, numOutputs, numSensors;
00138         int err;
00139 
00140         CPhidgetInterfaceKitHandle IFK = 0;
00141         CPhidget_enableLogging(PHIDGET_LOG_VERBOSE, NULL);
00142         CPhidgetInterfaceKit_create(&IFK);
00143         CPhidgetInterfaceKit_set_OnSensorChange_Handler(IFK,
00144                         IFK_SensorChangeHandler, (void*) &g_sensors);
00145         CPhidget_set_OnAttach_Handler((CPhidgetHandle) IFK, IFK_AttachHandler,
00146                         NULL);
00147         //opening phidget
00148         CPhidget_open((CPhidgetHandle) IFK, -1);
00149 
00150         //wait 5 seconds for attachment
00151         ROS_INFO("waiting for phidgets attachement...");
00152         if ((err = CPhidget_waitForAttachment((CPhidgetHandle) IFK, 10000))
00153                         != EPHIDGET_OK)
00154         {
00155                 const char *errStr;
00156                 CPhidget_getErrorDescription(err, &errStr);
00157                 ROS_ERROR("Error waiting for attachment: (%d): %s", err, errStr);
00158                 goto exit;
00159         }
00160         ROS_INFO("... attached");
00161 
00162         display_generic_properties((CPhidgetHandle) IFK);
00163         CPhidgetInterfaceKit_getOutputCount((CPhidgetInterfaceKitHandle) IFK,
00164                         &numOutputs);
00165         CPhidgetInterfaceKit_getInputCount((CPhidgetInterfaceKitHandle) IFK,
00166                         &numInputs);
00167         CPhidgetInterfaceKit_getSensorCount((CPhidgetInterfaceKitHandle) IFK,
00168                         &numSensors);
00169         //CPhidgetInterfaceKit_setOutputState((CPhidgetInterfaceKitHandle)IFK, 0, 1);
00170 
00171         ROS_INFO(
00172                         "Sensors:%d Inputs:%d Outputs:%d", numSensors, numInputs, numOutputs);
00173 
00174         while (ros::ok())
00175         {
00176                 for (size_t i = 0; i < g_sensors.size(); i++)
00177                         g_sensors[i].publish();
00178                 ros::spinOnce();
00179                 loop_rate.sleep();
00180         }
00181 
00182         exit: CPhidget_close((CPhidgetHandle) IFK);
00183         CPhidget_delete((CPhidgetHandle) IFK);
00184 
00185         return 0;
00186 }


cob_phidgets
Author(s): Florian Weisshardt, Benjamin Maidel
autogenerated on Sun Oct 5 2014 23:10:20