watson_ins_driver.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of https://github.com/AutonomousVehicleLaboratory/watson_ins.git
3  * Copyright 2019 AVL
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, version 3.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <http://www.gnu.org/licenses/>.
16  *
17  * Please contact AVL <avl@eng.ucsd.edu> for any inquiries.
18  */
19 #include "watson_ins_driver.h"
21 #include <tf/transform_datatypes.h>
22 
23 WatsonINSDriver::WatsonINSDriver(std::string path, int baud, int timeout_ms)
24 {
25  ROS_INFO("Connecting to Watson INS...");
26  // perform initialization sequence?
27  serDev = new serial::Serial(path, baud, serial::Timeout::simpleTimeout(timeout_ms));
28  ROS_INFO("Successfully connected to Watson INS");
29 
30  gpsMsgSeq = 0;
31 }
32 
33 #define Hour2Sec(H) (H*60*60)
34 #define Min2Sec(H) (H*60)
35 #define TSec2Nanosec(TS) (TS*100*1000)
36 void WatsonINSDriver::parseGPS(sensor_msgs::NavSatFix &gpsMsg)
37 {
38  int h, m, s, ts;
39 
40  sscanf(insData.timestamp, "%2d%2d%2d.%1d", &h, &m, &s, &ts);
41 
42  gpsMsg.header.seq = gpsMsgSeq++;
43  gpsMsg.header.stamp.sec = Hour2Sec(h) + Min2Sec(m) + s;
44  gpsMsg.header.stamp.nsec = TSec2Nanosec(ts);
45 
46  // Nav Sat Status
47  sensor_msgs::NavSatStatus navSatStatus;
48  navSatStatus.status = sensor_msgs::NavSatStatus::STATUS_SBAS_FIX;
49  // GPS Msg
50  gpsMsg.status = navSatStatus;
51  sscanf(insData.lat, "%lf", &gpsMsg.latitude);
52  sscanf(insData.lon, "%lf", &gpsMsg.longitude);
53  sscanf(insData.alt, "%lf", &gpsMsg.altitude);
54 }
55 
56 #define Degree2Radians(D) (D * M_PI/180)
57 #define Gs2Meters2(G) (G / 0.101972)
58 void WatsonINSDriver::parseIMU(sensor_msgs::Imu &imuMsg)
59 {
60  double roll, pitch, yaw;
61  double x_angular, y_angular, z_angular;
62  double x_accel, y_accel, z_accel;
63  double forward_accel, lateral_accel, vertical_accel;
64 
65  sscanf(insData.yaw, "%lf", &yaw);
66  sscanf(insData.pitch, "%lf", &pitch);
67  sscanf(insData.roll, "%lf", &roll);
68  tf::Quaternion quat_tf;
69  quat_tf.setRPY(roll, pitch, yaw);
70 
71  sscanf(insData.xAccel, "%lf", &x_accel);
72  sscanf(insData.yAccel, "%lf", &y_accel);
73  sscanf(insData.zAccel, "%lf", &z_accel);
74  sscanf(insData.xAngleRate, "%lf", &x_angular);
75  sscanf(insData.yAngleRate, "%lf", &y_angular);
76  sscanf(insData.zAngleRate, "%lf", &z_angular);
77 
78  imuMsg.header.stamp = ros::Time::now();
79  tf::quaternionTFToMsg(quat_tf, imuMsg.orientation);
80  imuMsg.angular_velocity.x = Degree2Radians(x_angular);
81  imuMsg.angular_velocity.y = Degree2Radians(y_angular);
82  imuMsg.angular_velocity.z = Degree2Radians(z_angular);
83  imuMsg.linear_acceleration.x = Gs2Meters2(x_accel);
84  imuMsg.linear_acceleration.y = Gs2Meters2(y_accel);
85  imuMsg.linear_acceleration.z = Gs2Meters2(z_accel);
86 }
87 
89 {
90  switch (insData.dataType[0]) {
91  case 'G':
92  case 'T':
93  case 'I':
94  case 'g':
95  case 't':
96  case 'i':
97  case 'r':
98  return true;
99  }
100  return false;
101 }
102 
103 void WatsonINSDriver::read(sensor_msgs::Imu &imuMsg,
104  sensor_msgs::NavSatFix &fixMsg,
105  bool &validImu, bool &validFix)
106 {
107  validImu = validFix = false;
108 
109  memset(&insData, 0, sizeof(struct ins_data_t));
110 
111  // wait for valid cmd
112  while (1 != serDev->read((uint8_t *)&insData, 1) || !validCmd());
113 
114  int bytesRead = 1;
115  while (bytesRead < sizeof(struct ins_data_t)) {
116  bytesRead += serDev->read(((uint8_t *)&insData) + bytesRead,
117  sizeof(struct ins_data_t) - bytesRead);
118  }
119 
120  switch (insData.dataType[0]) {
121  case 'G':
122  case 'T':
123  parseGPS(fixMsg);
124  parseIMU(imuMsg);
125  validImu = validFix = true;
126  break;
127  case 'I':
128  ROS_INFO("Only IMU data is available");
129  parseIMU(imuMsg);
130  validImu = true;
131  break;
132  case 'g':
133  case 't':
134  case 'i':
135  case 'r':
136  ROS_WARN("Calculated altitude/heading error exceeds ranges");
137  break;
138  default:
139  return;
140  }
141 }
142 
144 {
145  ROS_INFO("Closing Watson INS Driver");
146  serDev->close();
147  delete serDev;
148 }
char timestamp[9]
char xAngleRate[6]
XmlRpcServer s
#define TSec2Nanosec(TS)
struct ins_data_t insData
#define ROS_WARN(...)
char yAngleRate[6]
WatsonINSDriver(std::string path, int baud, int timeout_ms)
#define Min2Sec(H)
char zAngleRate[6]
void read(sensor_msgs::Imu &imuMsg, sensor_msgs::NavSatFix &fixMsg, bool &validImu, bool &validFix)
void setRPY(const tfScalar &roll, const tfScalar &pitch, const tfScalar &yaw)
#define ROS_INFO(...)
static void quaternionTFToMsg(const Quaternion &bt, geometry_msgs::Quaternion &msg)
void parseGPS(sensor_msgs::NavSatFix &gpsMsg)
static Timeout simpleTimeout(uint32_t timeout)
size_t read(uint8_t *buffer, size_t size)
static Time now()
#define Gs2Meters2(G)
char dataType[2]
#define Degree2Radians(D)
#define Hour2Sec(H)
serial::Serial * serDev
void parseIMU(sensor_msgs::Imu &imuMsg)


watson_ins
Author(s): David Paz , Nathan Chan
autogenerated on Sat Jan 11 2020 03:23:08