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;
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
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
00146 data.d[j].word = (frame.data[j * 2 + 1] >> 1) * 32 + (frame.data[j * 2 + 2] >> 3);
00147
00148
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
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
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 }