rawlog_record_node.cpp
Go to the documentation of this file.
1 /***********************************************************************************
2  * Revised BSD License *
3  * Copyright (c) 2014, Markus Bader <markus.bader@tuwien.ac.at> *
4  * All rights reserved. *
5  * *
6  * Redistribution and use in source and binary forms, with or without *
7  * modification, are permitted provided that the following conditions are met: *
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 Vienna University of Technology nor the *
14  * names of its contributors may be used to endorse or promote products *
15  * derived from this software without specific prior written permission. *
16  * *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  *AND *
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20  **
21  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
22  * DISCLAIMED. IN NO EVENT SHALL Markus Bader BE LIABLE FOR ANY *
23  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES *
24  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  **
26  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND *
27  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29  **
30  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  ** *
32  ***********************************************************************************/
33 
34 #include "rawlog_record_node.h"
35 
36 #include <mrpt/ros1bridge/laser_scan.h>
37 #include <mrpt/ros1bridge/pose.h>
38 #include <mrpt/ros1bridge/time.h>
40 
41 #include <boost/interprocess/sync/scoped_lock.hpp>
42 
43 using namespace mrpt::maps;
44 using namespace mrpt::obs;
45 
46 int main(int argc, char** argv)
47 {
48  ros::init(argc, argv, "rawlog_record");
50  RawlogRecordNode my_node(n);
51  my_node.init();
52  my_node.loop();
53  return 0;
54 }
55 
58 
60 {
61  updateRawLogName(mrpt::system::now());
62  ROS_INFO("rawlog file: %s", base_param_.raw_log_name.c_str());
64  {
65  subLaser_ =
66  n_.subscribe("scan", 1, &RawlogRecordNode::callbackLaser, this);
67  }
69  {
70  subMarker_ =
71  n_.subscribe("marker", 1, &RawlogRecordNode::callbackMarker, this);
72  }
73  subOdometry_ =
75 }
76 
78 
80  mrpt::poses::CPose3D& des, const std::string& target_frame,
81  const std::string& source_frame, const ros::Time& time,
82  const ros::Duration& timeout, const ros::Duration& polling_sleep_duration)
83 {
84  geometry_msgs::TransformStamped transform;
85  try
86  {
87  transform = tf_buffer_.lookupTransform(
88  target_frame, source_frame, time, timeout);
89  }
90  catch (const tf2::TransformException& e)
91  {
92  ROS_WARN(
93  "Failed to get transform target_frame (%s) to source_frame (%s): "
94  "%s",
95  target_frame.c_str(), source_frame.c_str(), e.what());
96  return false;
97  }
98  tf2::Transform tx;
99  tf2::fromMsg(transform.transform, tx);
100  des = mrpt::ros1bridge::fromROS(tx);
101  return true;
102 }
103 
105  const nav_msgs::Odometry& src, mrpt::obs::CObservationOdometry& des)
106 {
107  des.timestamp = mrpt::ros1bridge::fromROS(src.header.stamp);
108  des.odometry =
109  mrpt::poses::CPose2D(mrpt::ros1bridge::fromROS(src.pose.pose));
110 
111  std::string odom_frame_id = param_.odom_frame_id;
112  des.sensorLabel = odom_frame_id;
113  des.hasEncodersInfo = false;
114  des.hasVelocities = false;
115 }
116 
117 void RawlogRecordNode::callbackOdometry(const nav_msgs::Odometry& _msg)
118 {
119  // ROS_INFO("callbackOdometry");
120  if (!last_odometry_)
121  {
122  last_odometry_ = CObservationOdometry::Create();
123  }
124  convert(_msg, *last_odometry_);
125  addObservation(_msg.header.stamp);
126 }
127 
128 void RawlogRecordNode::callbackLaser(const sensor_msgs::LaserScan& _msg)
129 {
130  // ROS_INFO("callbackLaser");
131  if (!last_range_scan_)
132  {
133  last_range_scan_ = CObservation2DRangeScan::Create();
134  }
135  mrpt::poses::CPose3D sensor_pose_on_robot;
136 
137  if (getStaticTF(_msg.header.frame_id, sensor_pose_on_robot))
138  {
139  mrpt::ros1bridge::fromROS(
140  _msg, sensor_pose_on_robot, *last_range_scan_);
141 
142  addObservation(_msg.header.stamp);
143  }
144 }
145 
146 void RawlogRecordNode::callbackMarker(const marker_msgs::MarkerDetection& _msg)
147 {
148  // ROS_INFO("callbackMarker");
149  if (!last_bearing_range_)
150  {
151  last_bearing_range_ = CObservationBearingRange::Create();
152  }
153  if (!last_beacon_range_)
154  {
155  last_beacon_range_ = CObservationBeaconRanges::Create();
156  }
157  mrpt::poses::CPose3D sensor_pose_on_robot;
158 
159  if (getStaticTF(_msg.header.frame_id, sensor_pose_on_robot))
160  {
162  _msg, sensor_pose_on_robot, *last_bearing_range_);
163 
164  last_bearing_range_->sensor_std_range =
167  last_bearing_range_->sensor_std_pitch =
169 
171  _msg, sensor_pose_on_robot, *last_beacon_range_);
173  addObservation(_msg.header.stamp);
174  }
175 }
176 
178 {
181  ROS_INFO("Problem to syn data for sensor frame!");
182 
183  if (!last_odometry_) return;
184  auto odometry = CObservationOdometry::Create();
185  *odometry = *last_odometry_;
186  pRawLog.insert(odometry);
187 
188  CObservation2DRangeScan::Ptr range_scan;
189  CObservationBearingRange::Ptr bearing_range;
190  CObservationBeaconRanges::Ptr beacon_range;
191 
193  {
194  if (!last_range_scan_) return;
195  if (fabs(mrpt::system::timeDifference(
196  last_odometry_->timestamp, last_range_scan_->timestamp)) >
198  {
199  return;
200  }
201  range_scan = CObservation2DRangeScan::Create();
202  *range_scan = *last_range_scan_;
203  pRawLog.insert(range_scan);
204  }
205 
207  {
208  if (!last_bearing_range_) return;
209  if (fabs(mrpt::system::timeDifference(
210  last_odometry_->timestamp, last_bearing_range_->timestamp)) >
212  {
213  return;
214  }
215  bearing_range = CObservationBearingRange::Create();
216  *bearing_range = *last_bearing_range_;
217  pRawLog.insert(bearing_range);
218  }
220  {
221  if (!last_beacon_range_) return;
222  if (fabs(mrpt::system::timeDifference(
223  last_odometry_->timestamp, last_beacon_range_->timestamp)) >
225  {
226  return;
227  }
228  beacon_range = CObservationBeaconRanges::Create();
229  *beacon_range = *last_beacon_range_;
230  pRawLog.insert(beacon_range);
231  }
232 
233  static std::shared_ptr<mrpt::poses::CPose2D> lastOdomPose;
234  if (!lastOdomPose)
235  {
236  lastOdomPose = std::make_shared<mrpt::poses::CPose2D>();
237  *lastOdomPose = odometry->odometry;
238  }
239 
240  mrpt::poses::CPose2D incOdoPose = odometry->odometry - *lastOdomPose;
241 
242  CActionRobotMovement2D odom_move;
243  odom_move.timestamp = odometry->timestamp;
244  odom_move.computeFromOdometry(incOdoPose, base_param_.motionModelOptions);
245  auto action = CActionCollection::Create();
246  action->insert(odom_move);
247  pRawLogASF.insert(action);
248 
249  auto sf = CSensoryFrame::Create();
251  {
252  CObservation::Ptr obs_range_scan = CObservation::Ptr(range_scan);
253  sf->insert(obs_range_scan);
254  }
255 
257  {
258  CObservation::Ptr obs_bearing_range = CObservation::Ptr(bearing_range);
259  sf->insert(obs_bearing_range);
260  }
262  {
263  CObservation::Ptr obs_bearing_range = CObservation::Ptr(beacon_range);
264  sf->insert(obs_bearing_range);
265  }
266  pRawLogASF.insert(sf);
267 
268  *lastOdomPose = odometry->odometry;
269 
271 }
272 
274  std::string source_frame, mrpt::poses::CPose3D& des)
275 {
276  std::string target_frame_id = param_.base_frame_id;
277  std::string source_frame_id = source_frame;
278  std::string key = target_frame_id + "->" + source_frame_id;
279  mrpt::poses::CPose3D pose;
280 
281  geometry_msgs::TransformStamped tfGeom;
282 
283  if (static_tf_.find(key) == static_tf_.end())
284  {
285  if (base_param_.debug)
286  {
287  ROS_INFO(
288  "debug: updateLaserPose(): target_frame_id='%s' "
289  "source_frame_id='%s'",
290  target_frame_id.c_str(), source_frame_id.c_str());
291  }
292 
293  try
294  {
295  tfGeom = tf_buffer_.lookupTransform(
296  target_frame_id, source_frame_id, ros::Time(0));
297  }
298  catch (const tf2::TransformException& ex)
299  {
300  ROS_INFO("getStaticTF");
301  ROS_ERROR("%s", ex.what());
302  ros::Duration(1.0).sleep();
303  return false;
304  }
305 
306  tf2::Transform transform;
307  tf2::fromMsg(tfGeom.transform, transform);
308 
309  tf2::Vector3 translation = transform.getOrigin();
310  tf2::Quaternion quat = transform.getRotation();
311  pose.x() = translation.x();
312  pose.y() = translation.y();
313  pose.z() = translation.z();
314  tf2::Matrix3x3 Rsrc(quat);
315  mrpt::math::CMatrixDouble33 Rdes;
316  for (int c = 0; c < 3; c++)
317  for (int r = 0; r < 3; r++) Rdes(r, c) = Rsrc.getRow(r)[c];
318  pose.setRotationMatrix(Rdes);
319  static_tf_[key] = pose;
320  ROS_INFO(
321  "Static tf '%s' with '%s'", key.c_str(), pose.asString().c_str());
322  }
323  des = static_tf_[key];
324  return true;
325 }
unsigned int sync_attempts_sensor_frame_
CRawlog pRawLog
Definition: rawlog_record.h:79
ParametersNode param_
mrpt::obs::CObservationBearingRange::Ptr last_bearing_range_
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
bool getStaticTF(std::string source_frame, mrpt::poses::CPose3D &des)
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
void callbackLaser(const sensor_msgs::LaserScan &)
int main(int argc, char **argv)
bool waitForTransform(mrpt::poses::CPose3D &des, const std::string &target_frame, const std::string &source_frame, const ros::Time &time, const ros::Duration &timeout, const ros::Duration &polling_sleep_duration=ros::Duration(0.01))
#define ROS_WARN(...)
ros::Subscriber subOdometry_
CActionRobotMovement2D::TMotionModelOptions motionModelOptions
Definition: rawlog_record.h:73
virtual geometry_msgs::TransformStamped lookupTransform(const std::string &target_frame, const std::string &source_frame, const ros::Time &time, const ros::Duration timeout) const
mrpt::obs::CObservation2DRangeScan::Ptr last_range_scan_
TF2SIMD_FORCE_INLINE Vector3 & getOrigin()
#define ROS_INFO(...)
void fromMsg(const A &, B &b)
CRawlog pRawLogASF
Definition: rawlog_record.h:80
ROSCPP_DECL void spin()
void convert(const nav_msgs::Odometry &src, mrpt::obs::CObservationOdometry &des)
action
std::map< std::string, mrpt::poses::CPose3D > static_tf_
TF2SIMD_FORCE_INLINE const Vector3 & getRow(int i) const
void addObservation(const ros::Time &time)
Parameters base_param_
Definition: rawlog_record.h:77
ros::NodeHandle n_
void updateRawLogName(const mrpt::system::TTimeStamp &t)
bool fromROS(const marker_msgs::MarkerDetection &_msg, const mrpt::poses::CPose3D &sensorPoseOnRobot, mrpt::obs::CObservationBearingRange &_obj)
Quaternion getRotation() const
void callbackOdometry(const nav_msgs::Odometry &)
mrpt::obs::CObservationBeaconRanges::Ptr last_beacon_range_
mrpt::obs::CObservationOdometry::Ptr last_odometry_
ros::Subscriber subLaser_
bool sleep() const
#define ROS_ERROR(...)
RawlogRecordNode(ros::NodeHandle &n)
void callbackMarker(const marker_msgs::MarkerDetection &)
commands
tf2_ros::Buffer tf_buffer_
ros::Subscriber subMarker_


mrpt_rawlog
Author(s):
autogenerated on Thu Jun 1 2023 03:07:08