evarobot_sonar.cpp
Go to the documentation of this file.
00001 #include "evarobot_sonar/evarobot_sonar.h"
00002 
00003 /*
00004  * 
00005  * IMSONAR
00006  * 
00007  * 
00008  * */
00009  
00010 int i_error_code = 0;
00011 
00012 IMSONAR::IMSONAR(int fd, 
00013                                                                  int id, 
00014                                                                  int pin,
00015                                                                  boost::shared_ptr<IMDynamicReconfig> _dynamic_params):i_fd(fd), i_id(id), i_pin_no(pin), 
00016                                                                                                         b_is_alive(false), dynamic_params(_dynamic_params)
00017 {
00018         struct sonar_ioc_transfer set_params;
00019         stringstream ss;
00020         
00021         // Publisher
00022         ss << "sonar" << this->i_id;
00023         this->pub_sonar = this->n.advertise<sensor_msgs::Range>(ss.str().c_str(), 10);
00024         
00025         // Diagnostics
00026         this->updater.setHardwareID("IM-SMO20");
00027         this->updater.add(ss.str().c_str(), this, &IMSONAR::ProduceDiagnostics);
00028                 
00029         this->min_freq = this->dynamic_params->d_min_freq; 
00030         this->max_freq = this->dynamic_params->d_max_freq; 
00031         this->pub_sonar_freq = new diagnostic_updater::HeaderlessTopicDiagnostic(ss.str().c_str(), this->updater,
00032                                                                                         diagnostic_updater::FrequencyStatusParam(&min_freq, &max_freq, 0.1, 10));
00033                                                                                         
00034         
00035         // Frame id
00036         ss.str("");
00037         ss << this->n.resolveName(n.getNamespace(), true) << "/sonar" << this->i_id << "_link";
00038                                 
00039         this->sonar_msg.header.frame_id = ss.str();
00040         this->sonar_msg.radiation_type = 0;
00041         
00042         // Set params to driver
00043         set_params.i_gpio_pin = this->i_pin_no;
00044         set_params.i_sonar_id = this->i_id;
00045         ioctl(this->i_fd, IOCTL_SET_PARAM, &set_params);
00046 }
00047 
00048 IMSONAR::~IMSONAR()
00049 {
00050         delete pub_sonar_freq;
00051 }
00052 
00053 bool IMSONAR::Check()
00054 {
00055         int ret_val = 0;
00056         char read_buf[100];
00057         stringstream ss;
00058 
00059         ss << (this->i_id + 100);
00060 
00061         int raw_dist = -1;
00062 
00063         double start, stop;
00064 
00065 
00066         write(this->i_fd, ss.str().c_str(), sizeof(ss.str().c_str()));
00067         usleep(40000);
00068 
00069         start = ros::Time::now().toSec();
00070 
00071         while(raw_dist < 0)
00072         {
00073                 stop = ros::Time::now().toSec();
00074 
00075                 if(stop - start > 0.02)
00076                 {
00077                         ROS_DEBUG("EvarobotSonar: Sonar[%d] is not ALIVE ", this->i_id);
00078                         this->b_is_alive = false;
00079                         return false;
00080                 }
00081 
00082                 //ROS_INFO("Timeout[%d]: %f ", this->i_id, stop-start);
00083                 ss.str("");
00084                 ss << this->i_id;
00085                 strcpy(read_buf, ss.str().c_str());
00086 
00087                 ret_val = read(this->i_fd, read_buf, sizeof(read_buf));
00088                 raw_dist = atoi(read_buf);
00089 
00090         }
00091 
00092         this->b_is_alive = true; 
00093         return true;
00094 
00095 }
00096 
00097 void IMSONAR::Trigger()
00098 {
00099         stringstream ss;
00100         int raw_dist = -1;
00101 
00102         ss << this->i_id;
00103         write(this->i_fd, ss.str().c_str(), sizeof(ss.str().c_str()));
00104 }
00105 
00106 
00107 int IMSONAR::Echo()
00108 {
00109         stringstream ss;
00110         char read_buf[100];
00111         int raw_dist = -1;
00112         int ret_val;
00113 
00114         ss << this->i_id;
00115 
00116         strcpy(read_buf, ss.str().c_str());
00117         
00118         ret_val = read(this->i_fd, read_buf, sizeof(read_buf));
00119         raw_dist = atoi(read_buf);
00120 
00121         this->sonar_msg.range = (float)(raw_dist * 0.0001);
00122         this->sonar_msg.header.stamp = ros::Time::now();
00123         this->sonar_msg.field_of_view = this->dynamic_params->d_fov;
00124         this->sonar_msg.min_range = this->dynamic_params->d_min_range;
00125         this->sonar_msg.max_range = this->dynamic_params->d_max_range;
00126 
00127         return ret_val;
00128 }
00129 
00130 void IMSONAR::Wait()
00131 {
00132         usleep(300000);
00133 }
00134 
00135 void IMSONAR::Publish()
00136 {
00137         if(this->pub_sonar.getNumSubscribers() > 0 || this->dynamic_params->b_always_on)
00138         {
00139                 this->pub_sonar.publish(this->sonar_msg);
00140                 this->pub_sonar_freq->tick();
00141         }
00142 }
00143 
00144 void IMSONAR::ProduceDiagnostics(diagnostic_updater::DiagnosticStatusWrapper &stat)
00145 {
00146         if(i_error_code<0)
00147         {
00148                 stat.summary(diagnostic_msgs::DiagnosticStatus::ERROR, GetErrorDescription(i_error_code).c_str());
00149         i_error_code = 0;
00150         }
00151         else if(this->b_is_alive)
00152         {
00153                 stat.summaryf(diagnostic_msgs::DiagnosticStatus::OK, "Sonar%d is alive!", this->i_id);
00154         }
00155         else
00156         {
00157                 stat.summaryf(diagnostic_msgs::DiagnosticStatus::ERROR, "Sonar%d is NOT alive!", this->i_id);
00158         }
00159 }
00160 
00161 
00162 /*
00163  * 
00164  * IMDynamicReconfig
00165  * 
00166  * 
00167  * */
00168 
00169 void IMDynamicReconfig::CallbackReconfigure(evarobot_sonar::SonarParamsConfig &config, uint32_t level)
00170 {
00171         ROS_DEBUG("EvarobotSonar: Updating Sonar Params...");
00172                 
00173         this->d_fov = config.field_of_view;
00174         this->d_min_range = config.minRange;
00175         this->d_max_range = config.maxRange;
00176         this->b_always_on = config.alwaysOn;
00177 }
00178 
00179 IMDynamicReconfig::IMDynamicReconfig():n_private("~")
00180 {
00181                 // Get Params
00182         n_private.param("alwaysOn", this->b_always_on, false);
00183         n_private.param("field_of_view", this->d_fov, 0.7);
00184         n_private.param("minRange", this->d_min_range, 0.0);
00185         n_private.param("maxRange", this->d_max_range, 5.0);
00186         n_private.param("maxFreq", this->d_max_freq, 10.0);
00187         n_private.param("minFreq", this->d_min_freq, 0.2);
00188                 
00189         ROS_DEBUG("EvarobotSonar: b_always_on: %d", this->b_always_on);
00190         ROS_DEBUG("EvarobotSonar: d_fov: %f", this->d_fov);
00191         ROS_DEBUG("EvarobotSonar: d_min_range: %f", this->d_min_range);
00192         ROS_DEBUG("EvarobotSonar: d_max_range: %f", this->d_max_range);
00193         
00194         
00195         // Dynamic Reconfigure
00196         this->f = boost::bind(&IMDynamicReconfig::CallbackReconfigure, this, _1, _2);
00197         this->srv.setCallback(this->f);
00198 }
00199 
00200 
00201         
00202 
00203 int main(int argc, char **argv)
00204 {
00205         int i_fd;
00206         stringstream ss;
00207         vector<bool> b_sonar_alive;
00208         vector<IMSONAR *> sonar;
00209   
00210   // ROS PARAMS
00211         vector<int> T_i_sonar_pins;
00212         int i_element_no;
00213         double d_frequency;
00214         string str_driver_path;
00215         // rosparams end
00216         
00217         unsigned int u_i_delay = 100*1000; // Note: Delay in ns
00218                 
00219         ros::init(argc, argv, "/evarobot_sonar");
00220         ros::NodeHandle n;
00221         
00222         
00223         n.param<string>("evarobot_sonar/driverPath", str_driver_path, "/dev/evarobotSonar");
00224         n.param<double>("evarobot_sonar/frequency", d_frequency, 10.0);
00225         n.param<int>("evarobot_sonar/element", i_element_no, 3);
00226         n.getParam("evarobot_sonar/sonarPins", T_i_sonar_pins);
00227                 
00228         if(T_i_sonar_pins.size() > MAX_SONAR)
00229         {
00230                 ROS_INFO(GetErrorDescription(-120).c_str());
00231         i_error_code = -120;
00232         }
00233         
00234         
00235         ROS_DEBUG("EvarobotSonar: Number of sonars: %d", T_i_sonar_pins.size());
00236 
00237         i_fd = open(str_driver_path.c_str(), O_RDWR);
00238         
00239         if(i_fd < 0)
00240         {
00241                 ROS_INFO(GetErrorDescription(-121).c_str());
00242         i_error_code = -121;
00243                 exit(-1);
00244         }
00245                 
00246         /*****************************************************************/
00247                         
00248         // Define frequency
00249         ros::Rate loop_rate(d_frequency);
00250         
00251 
00252         // create objects
00253         boost::shared_ptr<IMDynamicReconfig> dyn_params(new IMDynamicReconfig);
00254         
00255         for(uint i = 0; i < T_i_sonar_pins.size(); i++)
00256         {
00257                 b_sonar_alive.push_back(true);
00258                 if(T_i_sonar_pins[i] < MAX_SONAR)
00259                 {
00260                         IMSONAR * dummy_sonar = new IMSONAR(i_fd, T_i_sonar_pins[i], SONAR[T_i_sonar_pins[i]], dyn_params);
00261                         sonar.push_back(dummy_sonar);
00262                 }
00263                 else
00264                 {
00265                         ROS_INFO(GetErrorDescription(-122).c_str());
00266                         i_error_code = -122;
00267                 }
00268         }
00269         double d_dummy = (double)T_i_sonar_pins.size() / (double)i_element_no;
00270         int i_group_max = (int)ceil(d_dummy);
00271         ROS_DEBUG("Group MAX -> %d", i_group_max);
00272         ROS_DEBUG("Pins -> %d", T_i_sonar_pins.size());
00273         ROS_DEBUG("element -> %d", i_element_no);
00274 
00275         int i_check_sonar = 0;
00276 
00277         while(ros::ok())
00278         {
00279 /*              for(int i = 0; i < T_i_sonar_pins.size(); i++)
00280                 {
00281                         sonar[i]->Trigger();
00282                         usleep(40000);
00283                         sonar[i]->Echo();
00284                         sonar[i]->Publish();
00285                         sonar[i]->updater.update();
00286                 }
00287                 ros::spinOnce();*/
00288 
00289                 b_sonar_alive[i_check_sonar] = sonar[i_check_sonar]->Check();
00290                 i_check_sonar++;
00291                 if(i_check_sonar >= T_i_sonar_pins.size())
00292                         i_check_sonar = 0;
00293 
00294                 for(int i_group_no = 0; i_group_no < i_group_max; i_group_no++)
00295                 {
00296                         for(int i = (i_group_no * i_element_no); i < ((i_group_no+1) * i_element_no) && i < T_i_sonar_pins.size(); i++)
00297                         {
00298                                 if(b_sonar_alive[i])
00299                                         sonar[i]->Trigger();
00300                         }
00301                         usleep(40000);
00302 /*                      if(T_i_sonar_pins.size() > 0)
00303                                 sonar[0]->Wait();
00304 */
00305                         for(int i = (i_group_no * i_element_no); i < ((i_group_no+1) * i_element_no) && i < T_i_sonar_pins.size(); i++)
00306                         {
00307                                 if(b_sonar_alive[i])
00308                                 {
00309                                         sonar[i]->Echo();
00310                                         sonar[i]->Publish();
00311                                 }
00312                                 sonar[i]->updater.update();
00313 //                              usleep(500000);
00314                         }
00315                 }
00316                 
00317                 ros::spinOnce();
00318 //              loop_rate.sleep();      
00319         
00320         }
00321         
00322         close(i_fd);
00323         return 0;
00324 }


evarobot_sonar
Author(s): Mehmet Akcakoca
autogenerated on Fri Feb 12 2016 01:15:30