DMU11.cpp
Go to the documentation of this file.
1 //
2 // Created by leutrim on 11/04/18.
3 //
4 
5 #include <DMU11.h>
6 
7 
9 {
10  bool params = false;
11  // Read parameters
12  while (!params)
13  try
14  {
15  params = nh.getParam("dmu_node/device", device_);
16  }
17  catch (ros::Exception &exception)
18  {
19  ROS_ERROR("Error %s", exception.what());
20  }
21 
22  nh.param("dmu_node/frame_id", frame_id_, std::string("imu"));
23  nh.param("dmu_node/rate", rate_, 200.0);
24 
25  imu_publisher_ = nh.advertise<sensor_msgs::Imu>("imu/data_raw", 10);
26  dmu_raw_publisher_ = nh.advertise<dmu_ros::DMURaw>("dmu/data_raw", 10);
27 }
28 
29 
31 {
32  int trials = 0;
33  do
34  {
35  if (trials++ == 0)
36  std::cout << "Opening serial port: " << device_.c_str() << " \n";
37  else
38  std::cout << "Couldn't open serial port... \n";
39  file_descriptor_ = open(device_.c_str(), O_RDWR | O_NOCTTY);
40  int opts = fcntl(file_descriptor_, F_GETFL);
41  opts = opts & (O_NONBLOCK);
42  fcntl(file_descriptor_, F_SETFL, opts); /*configuration the port*/
43  } while (file_descriptor_ == -1);
44 
45 
46  int diag;
47  trials = 0;
48  do
49  {
50  if (trials++ != 0)
51  std::cout << "Couldn't get the current state.\n";
52  diag = tcgetattr(file_descriptor_, &defaults_);
53  } while (diag == -1 && errno == EINTR);
54 
55  if (cfsetispeed(&defaults_, B460800) < 0 || cfsetospeed(&defaults_, B460800) < 0)
56  {
57  std::cout << "Couldnt set the desired baud rate \n";
58  return -1;
59  }
60 
61 
62  // Define com port options
63  //
64  defaults_.c_cflag |= (CLOCAL | CREAD); // Enable the receiver and set local mode...
65  defaults_.c_cflag &= ~(PARENB | CSIZE); // No parity, mask character size bits
66  defaults_.c_cflag |= CSTOPB; //2 stop bits
67  defaults_.c_cflag |= CS8; // Select 8 data bits
68  defaults_.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
69  defaults_.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG /*| IEXTEN | ECHONL*/);
70  defaults_.c_oflag &= ~OPOST;
71 
72  defaults_.c_cc[VMIN] = 68; //Minimum - two bytes
73  defaults_.c_cc[VTIME] = 0;
74 
75  if (tcsetattr(file_descriptor_, TCSANOW, &defaults_) != 0)
76  {
77  std::cout << "Failed to set attributes to the serial port.\n";
78  return -1;
79  }
80 
81  usleep(10000);
82 
83  // Restart the stream
84  unsigned char buff[3] = {0};
85  buff[0] = 0x04;
86  buff[1] = 0x01;
87  buff[2] = 0x00; // Turn message stream off
88  int size = write(file_descriptor_, buff, 3);
89  if (size != 3)
90  {
91  perror("Stop stream");
92  }
93 
94  if (tcdrain(file_descriptor_) < 0)
95  {
96  perror("Stop stream");
97  }
98 
99  tcflush(file_descriptor_, TCIFLUSH);
100  if (tcdrain(file_descriptor_) < 0)
101  {
102  perror("flush");
103  return -1;
104  }
105 
106  usleep(100000);
107  tcflush(file_descriptor_, TCIFLUSH);
108 
109  buff[0] = 0x04;
110  buff[1] = 0x01;
111  buff[2] = 0x01; // Turn message stream on
112  size = write(file_descriptor_, buff, 3);
113  if (size != 3)
114  {
115  perror("Start stream");
116  }
117 
118  if (tcdrain(file_descriptor_) < 0)
119  {
120  perror("Start stream");
121  }
122 
123  std::cout << "Started reading data from sensor...\n";
124 
125  return 0;
126 }
127 
129 {
130  unsigned char buff[68] = {0};
131 
132  int size = read(file_descriptor_, buff, 68);
133  if (size != 68)
134  {
135  perror("Partial Package Received.");
136  return;
137  }
138  else
139  {
140  int16_t computed_checksum = 0;
141  int16_t input16 = big_endian_to_short(&buff[0]);
142  int16_t int16buff[34] = {0};
143 
144  if (input16 == header_)
145  {
146  for (int i = 0; i < 66; i += 2)
147  {
148  int16buff[i / 2] = big_endian_to_short(&buff[i]);
149  computed_checksum += int16buff[i / 2];
150  }
151 
152  computed_checksum = ~computed_checksum + 0x0001;
153 
154  int16_t checksum = big_endian_to_short(&buff[66]);
155 
156  if (checksum == computed_checksum)
157  doParsing(&int16buff[0]);
158  else
159  {
160  std::cout << "Package is corrupt...\n";
161  std::cout << "Checksum: " << checksum << "\n";
162  std::cout << "Computed Checksum: " << computed_checksum << "\n";
163  return;
164  }
165  }
166  else
167  {
168  std::cout << "Dropped package\n";
169  }
170  }
171 
172 }
173 
175 {
176  if (tcsetattr(file_descriptor_, TCSANOW, &defaults_) < 0)
177  {
178  perror("closePort");
179  }
180  int diag;
181  do
182  {
183  diag = close(file_descriptor_);
184  } while (diag == -1);
185 
186  std::cout << "Serial Port got closed.";
187 
188 }
189 
190 
191 int16_t DMU11::big_endian_to_short(unsigned char *data)
192 {
193  unsigned char buff[2] = {data[1], data[0]};
194  return *reinterpret_cast<int16_t *>(buff);
195 }
196 
197 float DMU11::short_to_float(int16_t *data)
198 {
199  int16_t buff[2] = {data[1], data[0]};
200  return *reinterpret_cast<float *>(buff);
201 }
202 
203 void DMU11::doParsing(int16_t *int16buff)
204 {
205  raw_package_.header.stamp = ros::Time::now();
206  raw_package_.header.frame_id = frame_id_;
207 
208  imu_raw_.header.stamp = raw_package_.header.stamp;
209  imu_raw_.header.frame_id = frame_id_;
210 
211  // Accelerometer
212  raw_package_.linear_acceleration.x = short_to_float(&int16buff[4]);
213  raw_package_.linear_acceleration.y = short_to_float(&int16buff[8]);
214  raw_package_.linear_acceleration.z = short_to_float(&int16buff[12]);
215 
216  imu_raw_.linear_acceleration.x =
217  raw_package_.linear_acceleration.x * g_; // We multiply by g_ to convert from g's into m/s^2
218  imu_raw_.linear_acceleration.y = raw_package_.linear_acceleration.y * g_;
219  imu_raw_.linear_acceleration.z = raw_package_.linear_acceleration.z * g_;
220 
221  // Gyro Rates
222  raw_package_.angular_rate.x = short_to_float(&int16buff[2]);
223  raw_package_.angular_rate.y = short_to_float(&int16buff[6]);
224  raw_package_.angular_rate.z = short_to_float(&int16buff[10]);
225 
226  imu_raw_.angular_velocity.x = raw_package_.angular_rate.x * M_PI / 180; //Convert to rad/s
227  imu_raw_.angular_velocity.y = raw_package_.angular_rate.y * M_PI / 180;
228  imu_raw_.angular_velocity.z = raw_package_.angular_rate.z * M_PI / 180;
229 
230  // Delta thetas
231  raw_package_.delta_theta.x = short_to_float(&int16buff[18]);
232  raw_package_.delta_theta.y = short_to_float(&int16buff[22]);
233  raw_package_.delta_theta.z = short_to_float(&int16buff[26]);
234 
235  // Delta velocities
236  raw_package_.delta_velocity.x = short_to_float(&int16buff[20]);
237  raw_package_.delta_velocity.y = short_to_float(&int16buff[24]);
238  raw_package_.delta_velocity.z = short_to_float(&int16buff[28]);
239 
240 
241  raw_package_.system_startup_flags = int16buff[30];
242  raw_package_.system_operat_flags = int16buff[31];
243 
244 
245  roll_ += raw_package_.delta_theta.x * M_PI / 180;
246  pitch_ += raw_package_.delta_theta.y * M_PI / 180;
247  yaw_ += raw_package_.delta_theta.z * M_PI / 180;
248 
249  tf::Quaternion q;
250  q.setRPY(roll_, pitch_, yaw_);
251 
252  imu_raw_.orientation.x = q.x();
253  imu_raw_.orientation.y = q.y();
254  imu_raw_.orientation.z = q.z();
255  imu_raw_.orientation.w = q.w();
256 
259 
260 }
261 
262 
264 {
265 
266 }
267 
268 
269 
270 
void closePort()
Close the device.
Definition: DMU11.cpp:174
ros::Publisher imu_publisher_
Definition: DMU11.h:23
void publish(const boost::shared_ptr< M > &message) const
int openPort()
Open device.
Definition: DMU11.cpp:30
double roll_
Definition: DMU11.h:42
void doParsing(int16_t *int16buff)
Gets the raw data and converts them to standard ROS IMU message.
Definition: DMU11.cpp:203
std::string frame_id_
Definition: DMU11.h:26
int16_t big_endian_to_short(unsigned char *data)
change big endian 2 byte into short
Definition: DMU11.cpp:191
double pitch_
Definition: DMU11.h:43
double yaw_
Definition: DMU11.h:44
float short_to_float(int16_t *data)
change big endian short into float
Definition: DMU11.cpp:197
void setRPY(const tfScalar &roll, const tfScalar &pitch, const tfScalar &yaw)
bool param(const std::string &param_name, T &param_val, const T &default_val) const
ros::Publisher dmu_raw_publisher_
Definition: DMU11.h:24
int file_descriptor_
Definition: DMU11.h:33
const double g_
Definition: DMU11.h:31
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
struct termios defaults_
Definition: DMU11.h:34
double rate_
Definition: DMU11.h:39
sensor_msgs::Imu imu_raw_
Definition: DMU11.h:38
bool getParam(const std::string &key, std::string &s) const
static Time now()
DMU11(ros::NodeHandle &nh)
Constructor.
Definition: DMU11.cpp:8
dmu_ros::DMURaw raw_package_
Definition: DMU11.h:28
std::string device_
Definition: DMU11.h:25
virtual ~DMU11()
Definition: DMU11.cpp:263
void update()
Read the data received on serial port.
Definition: DMU11.cpp:128
#define ROS_ERROR(...)
int16_t header_
Definition: DMU11.h:32


dmu_ros
Author(s): Leutrim Gruda
autogenerated on Mon Jun 10 2019 13:05:49