numatac_can_driver.cpp
Go to the documentation of this file.
00001 
00025 #include <string>
00026 #include <stdio.h>
00027 #include <unistd.h>
00028 #include <fcntl.h>
00029 #include <poll.h>
00030 #include <sys/types.h>
00031 #include <sys/socket.h>
00032 #include <sys/ioctl.h>
00033 #include <net/if.h>
00034 
00035 #include <linux/can.h>
00036 #include <linux/can/raw.h>
00037 
00038 #include "numatac_can_driver/numatac_can_driver.h"
00039 #include "ros/ros.h"
00040 
00041 namespace numatac_can_driver
00042 {
00043 
00044 NumaTacCANDriver::NumaTacCANDriver(std::string canbus_dev, uint8_t number_of_sensors):
00045   canbus_dev_(canbus_dev),
00046   is_connected_(false),
00047   number_of_sensors_(number_of_sensors)
00048 {
00049   pac_.resize(number_of_sensors_);
00050   pdc_.resize(number_of_sensors_);
00051 }
00052 
00053 bool NumaTacCANDriver::connect()
00054 {
00055   if ((socket_ = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0)
00056   {
00057     ROS_ERROR("Error while opening socket");
00058     return false;
00059   }
00060 
00061   struct ifreq ifr;
00062 
00063   snprintf (ifr.ifr_name, sizeof(canbus_dev_.c_str()), "%s", canbus_dev_.c_str());
00064 
00065   if (ioctl(socket_, SIOCGIFINDEX, &ifr) < 0)
00066   {
00067     close(socket_);
00068     ROS_ERROR("Error while trying to device");
00069     return false;
00070   }
00071 
00072   struct sockaddr_can addr;
00073   addr.can_family  = AF_CAN;
00074   addr.can_ifindex = ifr.ifr_ifindex;
00075   ROS_DEBUG("%s at index %d", canbus_dev_.c_str(), ifr.ifr_ifindex);
00076 
00077   if (bind(socket_, (struct sockaddr *)&addr, sizeof(addr)) < 0)
00078   {
00079     ROS_ERROR("Error in socket bind");
00080     return false;
00081   }
00082 
00083   struct timeval tv;
00084   tv.tv_sec = 0;
00085   tv.tv_usec = 1;  // microseconds
00086 
00087   setsockopt(socket_, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
00088 
00089   ROS_INFO("Opened Socket CAN on %s", canbus_dev_.c_str());
00090   is_connected_ = true;
00091 
00092   return is_connected_;
00093 }
00094 
00095 
00096 bool NumaTacCANDriver::isConnected()
00097 {
00098   return is_connected_;
00099 }
00100 
00101 
00102 bool NumaTacCANDriver::getData()
00103 {
00104   bt_info biotac;
00105   bt_data data;
00106 
00107   static int sample_count = 0;
00108   const int number_of_samples_in_batch = 1;
00109 
00110   // Read CAN frame
00111   struct can_frame frame;
00112   int bytes = read(socket_, &frame, sizeof(struct can_frame));
00113 
00114   if (bytes > 0)
00115   {
00116     data.index = sample_count;
00117 
00118     for (int i = 0; i < number_of_samples_in_batch; i++)
00119     {
00120       if (sample_count != 0)
00121       {
00122         if (i == 0)
00123         {
00124           data.batch_index++;
00125         }
00126 
00127         if ((i % (biotac.frame.frame_size)) == 0)
00128         {
00129           data.frame_index++;
00130         }
00131 
00132         data.time = 0.0;
00133       }
00134       else
00135       {
00136         data.batch_index = 1;
00137         data.frame_index = 1;
00138         data.time = 0;
00139       }
00140 
00141       data.channel_id = (frame.data[0] & 0x7E) >> 1;
00142 
00143       for (int j = 0; j < number_of_sensors_; j++)
00144       {
00145         // Combine two bytes of CAN message into a word (2 bytes) of data
00146         data.d[j].word = (frame.data[j * 2 + 1] >> 1) * 32 + (frame.data[j * 2 + 2] >> 3);
00147 
00148         // Checking the data parity
00149         if ((parity_values[frame.data[j * 2 + 1] >> 1] == frame.data[j * 2 + 1])
00150          && (parity_values[frame.data[j * 2 + 2] >> 1] == frame.data[j * 2 + 2]))
00151         {
00152           data.bt_parity[j] = PARITY_GOOD;
00153         }
00154         else
00155         {
00156           data.bt_parity[j] = PARITY_BAD;
00157         }
00158       }
00159 
00160       switch (data.channel_id)
00161       {
00162       case numatac_can_driver::PDC:
00163         //  Pressure DC
00164         for (int i = 0; i < number_of_sensors_; i++)
00165         {
00166           pdc_[i] =  data.d[i].word;
00167         }
00168         return true;
00169       case numatac_can_driver::PAC:
00170         //  Pressure AC
00171         for (int i = 0; i < number_of_sensors_; i++)
00172         {
00173           pac_[i] =  data.d[i].word;
00174         }
00175         return false;
00176       default:
00177         return true;
00178       }
00179 
00180       sample_count++;
00181     }
00182   }
00183   else
00184   {
00185     return true;
00186   }
00187 }
00188 
00189 int16_t NumaTacCANDriver::getPAC(uint8_t id)
00190 {
00191   return pac_[id];
00192 }
00193 uint16_t NumaTacCANDriver::getPDC(uint8_t id)
00194 {
00195   return pdc_[id];
00196 }
00197 
00198 }  // namespace numatac_can_driver


numatac_can_driver
Author(s):
autogenerated on Thu Jun 6 2019 21:19:30