ncd_parser.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011, Ivan Dryanovski, William Morris
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * * Neither the name of the CCNY Robotics Lab nor the names of its
14  * contributors may be used to endorse or promote products derived from
15  * this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #include "ncd_parser/ncd_parser.h"
31 
32 int main(int argc, char** argv)
33 {
34  if(argc != 4)
35  {
36  printf("usage is `rosrun ncd_parser ncd_parser filename.alog`\n");
37  return 1;
38  }
39 
40  ros::init (argc, argv, "ncd_parser");
41  NCDParser parser(argv[1]);
42  sleep(2);
43  parser.launch();
44  return 0;
45 }
46 
47 NCDParser::NCDParser(char* filename):filename_(filename)
48 {
49  ROS_INFO ("Starting NCDParser");
50 
51  ros::NodeHandle nh;
52  ros::NodeHandle nh_private ("~");
53 
56  lastTime_ = -1;
57 
58  // **** parameters
59 
60  if (!nh_private.getParam ("start", start_))
61  start_ = 0.0;
62  if (!nh_private.getParam ("end", end_))
63  end_ = -1;
64  if (!nh_private.getParam ("rate", rate_))
65  rate_ = 1.0;
66 
67  if (rate_ == 0) ROS_FATAL("rate parameter cannot be 0");
68 
69  // **** topics
70 
71  leftLaserPublisher_ = nh.advertise<sensor_msgs::LaserScan>("scan", 100);
72  rightLaserPublisher_ = nh.advertise<sensor_msgs::LaserScan>("scan", 100);
73 }
74 
76 {
77  ROS_INFO ("Shutting down NCDParser");
78 }
79 
81 {
82  std::ifstream aLogFile;
83  aLogFile.open(filename_);
84 
85  if(!aLogFile.is_open())
86  ROS_FATAL("Could not open %s\n", filename_);
87 
88  int lineCounter = 0;
89  std::string line;
90 
91  // **** skip first lines
92 
93  for (int i = 0; i < 210; i++)
94  {
95  getline(aLogFile, line);
96  lineCounter++;
97  }
98 
99  // **** iterate over rest of file
100 
101  while (getline(aLogFile, line))
102  {
103  lineCounter++;
104  std::vector<std::string> tokens;
105  tokenize(line, tokens, " ");
106 
107  // skip incomplete line
108  if (tokens.size() < 4) continue;
109 
110  // skip log entries before start time
111  if (strtod(tokens[0].c_str(), NULL) <= start_) continue;
112 
113  // stop if time is bigger than end point time
114  if (strtod(tokens[0].c_str(), NULL) > end_ && end_ != -1)
115  {
116  std::cout << strtod(tokens[0].c_str(), NULL) << ", " << end_ << std::endl;
117  ROS_INFO("Reached specified end time.");
118  break;
119  }
120 
121  // publish messages
122  if (tokens[1].compare("LMS_LASER_2D_LEFT") == 0)
124  else if (tokens[1].compare("LMS_LASER_2D_RIGHT") == 0)
126  else if (tokens[1].compare("ODOMETRY_POSE") == 0)
127  publishTfMessages(tokens);
128  else
129  continue;
130 
131  // wait before publishing next message
132 
133  double time = extractValue(tokens[3], "time=");
134 
135  if(lastTime_ == -1) lastTime_ = time;
136  else
137  {
138  ros::Duration d = (ros::Time(time) - ros::Time(lastTime_)) * ( 1.0 / rate_);
139  lastTime_ = time;
140  if (d.toNSec() > 0) d.sleep();
141  }
142  }
143 }
144 
145 void NCDParser::publishLaserMessage(const std::vector<std::string>& tokens,
146  const std::string& laserFrame,
147  const ros::Publisher& publisher)
148 {
149  ROS_DEBUG("Laser message");
150 
151  sensor_msgs::LaserScan scan;
152 
153  double time = extractValue(tokens[3], "time=");
154 
155  scan.header.stamp = ros::Time(time);
156  scan.header.frame_id = laserFrame;
157 
158  scan.angle_min = extractValue(tokens[3], "minAngle=") * DEG_TO_RAD;
159  scan.angle_max = extractValue(tokens[3], "maxAngle=") * DEG_TO_RAD;
160  scan.angle_increment = extractValue(tokens[3], "angRes=") * DEG_TO_RAD;
161  scan.range_min = RANGE_MIN;
162  scan.range_max = RANGE_MAX;
163  scan.ranges = extractArray(tokens[3], "Range=[181]");
164  scan.intensities = extractArray(tokens[3], "Reflectance=[181]");
165 
166  publisher.publish(scan);
167 }
168 
169 void NCDParser::publishTfMessages(const std::vector<std::string>& tokens)
170 {
171  ROS_DEBUG("Tf message");
172 
173  // extract time
174  double time = extractValue(tokens[3], "time=");
175 
176  // extract x, y, theta
177  std::vector<float> xytheta = extractArray(tokens[3], "Pose=[3x1]");
178  double x = xytheta[0];
179  double y = xytheta[1];
180  double z = 0.0;
181  double theta = xytheta[2];
182 
183  // extract Pitch
184  double pitch = extractValue(tokens[3], "Pitch=");
185 
186  // extract Roll
187  double roll = extractValue(tokens[3], "Roll=");
188 
189  tf::Quaternion rotation;
190  rotation.setRPY (roll, pitch, theta);
191  worldToOdom_.setRotation (rotation);
192 
193  tf::Vector3 origin;
194  origin.setValue (x, y, z);
195  worldToOdom_.setOrigin (origin);
196 
198  tfBroadcaster_.sendTransform(worldToOdomStamped);
199 
201  tfBroadcaster_.sendTransform(odomToLeftLaserStamped);
202 
204  tfBroadcaster_.sendTransform(odomToRightLaserStamped);
205 }
206 
207 void NCDParser::tokenize (const std::string& str,
208  std::vector <std::string> &tokens,
209  std::string sentinel)
210 {
211  std::string::size_type lastPos = str.find_first_not_of (sentinel, 0);
212  std::string::size_type pos = str.find_first_of (sentinel, lastPos);
213 
214  while (std::string::npos != pos || std::string::npos != lastPos)
215  {
216  std::string stringToken = str.substr (lastPos, pos - lastPos);
217  tokens.push_back (stringToken);
218  lastPos = str.find_first_not_of (sentinel, pos);
219  pos = str.find_first_of (sentinel, lastPos);
220  }
221 }
222 
223 std::vector<float> NCDParser::extractArray(std::string s, std::string pattern)
224 {
225  int n0 = s.find(pattern);
226  int n1 = s.find("{", n0);
227  int n2 = s.find("}", n1);
228  std::string valueList = s.substr(n1+1, n2-n1-1);
229 
230  std::vector<float> values;
231  std::vector<std::string> s_values;
232  tokenize(valueList, s_values, ",");
233 
234  for (unsigned int i = 0; i < s_values.size(); i++)
235  values.push_back(strtod(s_values[i].c_str(), NULL));
236 
237  return values;
238 }
239 
240 double NCDParser::extractValue(std::string s, std::string pattern)
241 {
242  int n1 = s.find(pattern);
243  int n2 = s.find(",", n1);
244  std::string s_value = s.substr(n1+pattern.length(), n2-n1-pattern.length());
245  return strtod(s_value.c_str(), NULL);
246 }
247 
248 
250 {
251  double x = -0.270;
252  double y = -0.030;
253  double z = 0.495;
254  double roll = 180.0 * DEG_TO_RAD;
255  double pitch = 90.0 * DEG_TO_RAD;
256  double yaw = -90.0 * DEG_TO_RAD;
257 
258  tf::Quaternion rotation;
259  rotation.setRPY (roll, pitch, yaw);
260  odomToLeftLaser_.setRotation (rotation);
261 
262  tf::Vector3 origin;
263  origin.setValue (x, y, z);
264  odomToLeftLaser_.setOrigin (origin);
265 }
266 
268 {
269  double x = 0.270;
270  double y = -0.030;
271  double z = 0.495;
272  double roll = 90.0 * DEG_TO_RAD;
273  double pitch = -90.0 * DEG_TO_RAD;
274  double yaw = 180.0 * DEG_TO_RAD;
275 
276  tf::Quaternion rotation;
277  rotation.setRPY (roll, pitch, yaw);
278  odomToRightLaser_.setRotation (rotation);
279 
280  tf::Vector3 origin;
281  origin.setValue (x, y, z);
282  odomToRightLaser_.setOrigin (origin);
283 }
const double RANGE_MAX
Definition: ncd_parser.h:43
d
tf::TransformBroadcaster tfBroadcaster_
Definition: ncd_parser.h:62
TFSIMD_FORCE_INLINE void setRotation(const Quaternion &q)
#define ROS_FATAL(...)
const double DEG_TO_RAD
Definition: ncd_parser.h:40
void publish(const boost::shared_ptr< M > &message) const
std::vector< double > values
const std::string odomFrame_
Definition: ncd_parser.h:46
char * filename_
Definition: ncd_parser.h:54
tf::Transform worldToOdom_
Definition: ncd_parser.h:64
bool sleep() const
double end_
Definition: ncd_parser.h:56
double extractValue(std::string s, std::string pattern)
Definition: ncd_parser.cpp:240
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
void launch()
Definition: ncd_parser.cpp:80
const std::string leftLaserFrame_
Definition: ncd_parser.h:47
TFSIMD_FORCE_INLINE const tfScalar & y() const
TFSIMD_FORCE_INLINE void setValue(const tfScalar &x, const tfScalar &y, const tfScalar &z)
ros::Publisher leftLaserPublisher_
Definition: ncd_parser.h:59
void publishLaserMessage(const std::vector< std::string > &tokens, const std::string &laserFrame, const ros::Publisher &publisher)
Definition: ncd_parser.cpp:145
void tokenize(const std::string &str, std::vector< std::string > &tokens, std::string sentinel)
Definition: ncd_parser.cpp:207
double start_
Definition: ncd_parser.h:56
std::vector< float > extractArray(std::string s, std::string pattern)
Definition: ncd_parser.cpp:223
virtual ~NCDParser()
Definition: ncd_parser.cpp:75
void setRPY(const tfScalar &roll, const tfScalar &pitch, const tfScalar &yaw)
int main(int argc, char **argv)
Definition: ncd_parser.cpp:32
#define ROS_INFO(...)
int64_t toNSec() const
void createOdomToRightLaserTf()
Definition: ncd_parser.cpp:267
void createOdomToLeftLaserTf()
Definition: ncd_parser.cpp:249
void sendTransform(const StampedTransform &transform)
TFSIMD_FORCE_INLINE const tfScalar & x() const
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
const double RANGE_MIN
Definition: ncd_parser.h:42
TFSIMD_FORCE_INLINE const tfScalar & z() const
tf::Transform odomToRightLaser_
Definition: ncd_parser.h:66
const std::string worldFrame_
Definition: ncd_parser.h:45
bool getParam(const std::string &key, std::string &s) const
parser
ros::Publisher rightLaserPublisher_
Definition: ncd_parser.h:60
void publishTfMessages(const std::vector< std::string > &tokens)
Definition: ncd_parser.cpp:169
NCDParser(char *filename)
Definition: ncd_parser.cpp:47
double lastTime_
Definition: ncd_parser.h:57
double rate_
Definition: ncd_parser.h:55
tf::Transform odomToLeftLaser_
Definition: ncd_parser.h:65
const std::string rightLaserFrame_
Definition: ncd_parser.h:48
TFSIMD_FORCE_INLINE void setOrigin(const Vector3 &origin)
#define ROS_DEBUG(...)


ncd_parser
Author(s): Ivan Dryanovski
autogenerated on Mon Jun 10 2019 15:08:47