rawlog_record_node.cpp
Go to the documentation of this file.
00001 /***********************************************************************************
00002  * Revised BSD License *
00003  * Copyright (c) 2014, Markus Bader <markus.bader@tuwien.ac.at> *
00004  * All rights reserved. *
00005  *                                                                                 *
00006  * Redistribution and use in source and binary forms, with or without *
00007  * modification, are permitted provided that the following conditions are met: *
00008  *     * Redistributions of source code must retain the above copyright *
00009  *       notice, this list of conditions and the following disclaimer. *
00010  *     * Redistributions in binary form must reproduce the above copyright *
00011  *       notice, this list of conditions and the following disclaimer in the *
00012  *       documentation and/or other materials provided with the distribution. *
00013  *     * Neither the name of the Vienna University of Technology nor the *
00014  *       names of its contributors may be used to endorse or promote products *
00015  *       derived from this software without specific prior written permission. *
00016  *                                                                                 *
00017  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00018  *AND *
00019  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00020  **
00021  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
00022  * DISCLAIMED. IN NO EVENT SHALL Markus Bader BE LIABLE FOR ANY *
00023  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES *
00024  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00025  **
00026  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND *
00027  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
00028  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00029  **
00030  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00031  **                       *
00032  ***********************************************************************************/
00033 
00034 #include "rawlog_record_node.h"
00035 #include <boost/interprocess/sync/scoped_lock.hpp>
00036 
00037 #include <mrpt_bridge/pose.h>
00038 #include <mrpt_bridge/laser_scan.h>
00039 #include <mrpt_bridge/marker_msgs.h>
00040 #include <mrpt_bridge/time.h>
00041 
00042 #include <mrpt/version.h>
00043 using namespace mrpt::maps;
00044 using namespace mrpt::obs;
00045 
00046 int main(int argc, char** argv)
00047 {
00048     ros::init(argc, argv, "rawlog_record");
00049     ros::NodeHandle n;
00050     RawlogRecordNode my_node(n);
00051     my_node.init();
00052     my_node.loop();
00053     return 0;
00054 }
00055 
00056 RawlogRecordNode::~RawlogRecordNode() {}
00057 RawlogRecordNode::RawlogRecordNode(ros::NodeHandle& n)
00058     : RawlogRecord(new RawlogRecordNode::ParametersNode()),
00059       n_(n)
00060 {
00061 }
00062 
00063 RawlogRecordNode::ParametersNode* RawlogRecordNode::param()
00064 {
00065     return (RawlogRecordNode::ParametersNode*)param_;
00066 }
00067 
00068 void RawlogRecordNode::init()
00069 {
00070     updateRawLogName(mrpt::system::getCurrentLocalTime());
00071     ROS_INFO("rawlog file: %s", param_->raw_log_name.c_str());
00072     if (param_->record_range_scan) {
00073         subLaser_ = n_.subscribe("scan", 1, &RawlogRecordNode::callbackLaser, this);
00074     }
00075     if (param_->record_bearing_range) {
00076         subMarker_ = n_.subscribe ( "marker", 1, &RawlogRecordNode::callbackMarker, this );
00077     }
00078     subOdometry_ = n_.subscribe ( "odom", 1, &RawlogRecordNode::callbackOdometry, this );
00079 }
00080 
00081 void RawlogRecordNode::loop()
00082 {
00083     ros::spin();
00084 }
00085 
00086 bool RawlogRecordNode::waitForTransform(
00087     mrpt::poses::CPose3D& des, const std::string& target_frame,
00088     const std::string& source_frame, const ros::Time& time,
00089     const ros::Duration& timeout, const ros::Duration& polling_sleep_duration)
00090 {
00091     tf::StampedTransform transform;
00092     try
00093     {
00094         if (param_->debug)
00095             ROS_INFO(
00096                 "debug: waitForTransform(): target_frame='%s' "
00097                 "source_frame='%s'",
00098                 target_frame.c_str(), source_frame.c_str());
00099 
00100         listenerTF_.waitForTransform(
00101             target_frame, source_frame, time, polling_sleep_duration);
00102         listenerTF_.lookupTransform(
00103             target_frame, source_frame, time, transform);
00104     }
00105     catch (tf::TransformException)
00106     {
00107         ROS_INFO(
00108             "Failed to get transform target_frame (%s) to source_frame (%s)",
00109             target_frame.c_str(), source_frame.c_str());
00110         return false;
00111     }
00112     mrpt_bridge::convert(transform, des);
00113     return true;
00114 }
00115 
00116 void RawlogRecordNode::convert(const nav_msgs::Odometry& src, mrpt::obs::CObservationOdometry &des) {
00117     mrpt_bridge::convert(src.header.stamp, des.timestamp);
00118     mrpt_bridge::convert(src.pose.pose, des.odometry);
00119     std::string odom_frame_id = tf::resolve(param()->tf_prefix, param()->odom_frame_id);
00120     des.sensorLabel = odom_frame_id;
00121     des.hasEncodersInfo = false;
00122     des.hasVelocities = false;
00123 
00124 }
00125 
00126 void RawlogRecordNode::callbackOdometry(const nav_msgs::Odometry& _msg)
00127 {
00128     //ROS_INFO("callbackOdometry");
00129     if(!last_odometry_) {
00130         last_odometry_ = mrpt::make_aligned_shared<CObservationOdometry>();
00131     }
00132     convert(_msg, *last_odometry_);
00133     addObservation(_msg.header.stamp);
00134 
00135 }
00136 
00137 void RawlogRecordNode::callbackLaser(const sensor_msgs::LaserScan& _msg)
00138 {
00139     //ROS_INFO("callbackLaser");
00140     if(!last_range_scan_) {
00141         last_range_scan_ = mrpt::make_aligned_shared<CObservation2DRangeScan>();
00142     }
00143     mrpt::poses::CPose3D sensor_pose_on_robot;
00144 
00145     if (getStaticTF(_msg.header.frame_id, sensor_pose_on_robot)) {
00146         mrpt_bridge::convert(_msg, sensor_pose_on_robot, *last_range_scan_);
00147 
00148         addObservation(_msg.header.stamp);
00149 
00150     }
00151 }
00152 
00153 void RawlogRecordNode::callbackMarker(const marker_msgs::MarkerDetection& _msg)
00154 {
00155     //ROS_INFO("callbackMarker");
00156     if(!last_bearing_range_) {
00157         last_bearing_range_ = mrpt::make_aligned_shared<CObservationBearingRange>();
00158     }
00159     if(!last_beacon_range_) {
00160         last_beacon_range_ = mrpt::make_aligned_shared<CObservationBeaconRanges>();
00161     }
00162     mrpt::poses::CPose3D sensor_pose_on_robot;
00163 
00164     if (getStaticTF(_msg.header.frame_id, sensor_pose_on_robot)) {
00165         mrpt_bridge::convert(_msg, sensor_pose_on_robot, *last_bearing_range_);
00166         last_bearing_range_->sensor_std_range  = param_->bearing_range_std_range;
00167         last_bearing_range_->sensor_std_yaw    = param_->bearing_range_std_yaw;
00168         last_bearing_range_->sensor_std_pitch  = param_->bearing_range_std_pitch;
00169         
00170         mrpt_bridge::convert(_msg, sensor_pose_on_robot, *last_beacon_range_);
00171         last_beacon_range_->stdError = param_->bearing_range_std_range;
00172         addObservation(_msg.header.stamp);
00173     }
00174     
00175 }
00176 
00177 void RawlogRecordNode::addObservation(const ros::Time& time) {
00178 
00179 
00180     sync_attempts_sensor_frame_++;
00181     if(sync_attempts_sensor_frame_ > 10) ROS_INFO("Problem to syn data for sensor frame!");
00182 
00183     if(!last_odometry_) return;
00184     CObservationOdometry::Ptr odometry = mrpt::make_aligned_shared<CObservationOdometry>();
00185     *odometry = *last_odometry_;
00186     pRawLog->addObservationMemoryReference(odometry);
00187 
00188     CObservation2DRangeScan::Ptr range_scan;
00189     CObservationBearingRange::Ptr bearing_range;
00190     CObservationBeaconRanges::Ptr beacon_range;
00191 
00192     if (param_->record_range_scan) {
00193         if(!last_range_scan_) return;
00194         if( fabs(mrpt::system::timeDifference(last_odometry_->timestamp, last_range_scan_->timestamp)) > param()->sensor_frame_sync_threshold) {
00195             return;
00196         }
00197         range_scan = mrpt::make_aligned_shared<CObservation2DRangeScan>();
00198         *range_scan = *last_range_scan_;
00199         pRawLog->addObservationMemoryReference(range_scan);
00200     }
00201 
00202     if (param_->record_bearing_range) {
00203         if(!last_bearing_range_) return;
00204         if( fabs(mrpt::system::timeDifference(last_odometry_->timestamp, last_bearing_range_->timestamp)) > param()->sensor_frame_sync_threshold) {
00205             return;
00206         }
00207         bearing_range = mrpt::make_aligned_shared<CObservationBearingRange>();
00208         *bearing_range = *last_bearing_range_;
00209         pRawLog->addObservationMemoryReference(bearing_range);
00210     }
00211     if (param_->record_beacon_range) {
00212         if(!last_beacon_range_) return;
00213         if( fabs(mrpt::system::timeDifference(last_odometry_->timestamp, last_beacon_range_->timestamp)) > param()->sensor_frame_sync_threshold) {
00214             return;
00215         }
00216         beacon_range = mrpt::make_aligned_shared<CObservationBeaconRanges>();
00217         *beacon_range = *last_beacon_range_;
00218         pRawLog->addObservationMemoryReference(beacon_range);
00219     }
00220 
00221 
00222     static std::shared_ptr<mrpt::poses::CPose2D> lastOdomPose;
00223     if(!lastOdomPose) {
00224         lastOdomPose = std::make_shared<mrpt::poses::CPose2D>();
00225         *lastOdomPose = odometry->odometry;
00226     }
00227 
00228     mrpt::poses::CPose2D incOdoPose = odometry->odometry - *lastOdomPose;
00229 
00230     CActionRobotMovement2D odom_move;
00231     odom_move.timestamp = odometry->timestamp;
00232     odom_move.computeFromOdometry(incOdoPose, param_->motionModelOptions);
00233     CActionCollection::Ptr action = mrpt::make_aligned_shared<CActionCollection>();
00234     action->insert(odom_move);
00235     pRawLogASF->addActionsMemoryReference(action);
00236 
00237     CSensoryFrame::Ptr sf = mrpt::make_aligned_shared<CSensoryFrame>();
00238     if (param_->record_range_scan) {
00239         CObservation::Ptr obs_range_scan = CObservation::Ptr(range_scan);
00240         sf->insert(obs_range_scan);
00241     }
00242 
00243     if (param_->record_bearing_range) {
00244         CObservation::Ptr obs_bearing_range = CObservation::Ptr(bearing_range);
00245         sf->insert(obs_bearing_range);
00246     }
00247     if (param_->record_beacon_range) {
00248         CObservation::Ptr obs_bearing_range = CObservation::Ptr(beacon_range);
00249         sf->insert(obs_bearing_range);
00250     }
00251     pRawLogASF->addObservationsMemoryReference(sf);
00252 
00253     *lastOdomPose = odometry->odometry;
00254 
00255     sync_attempts_sensor_frame_ = 0;
00256     
00257 }
00258 
00259 bool RawlogRecordNode::getStaticTF(std::string source_frame, mrpt::poses::CPose3D &des)
00260 {
00261     std::string target_frame_id = tf::resolve(param()->tf_prefix, param()->base_frame_id);
00262     std::string source_frame_id = source_frame;
00263     std::string key = target_frame_id + "->" + source_frame_id;
00264     mrpt::poses::CPose3D pose;
00265     tf::StampedTransform transform;
00266 
00267     if (static_tf_.find(key) == static_tf_.end()) {
00268 
00269         try
00270         {
00271             if (param_->debug)
00272                 ROS_INFO(
00273                     "debug: updateLaserPose(): target_frame_id='%s' source_frame_id='%s'",
00274                     target_frame_id.c_str(), source_frame_id.c_str());
00275 
00276             listenerTF_.lookupTransform(
00277                 target_frame_id, source_frame_id, ros::Time(0), transform);
00278             tf::Vector3 translation = transform.getOrigin();
00279             tf::Quaternion quat = transform.getRotation();
00280             pose.x() = translation.x();
00281             pose.y() = translation.y();
00282             pose.z() = translation.z();
00283             tf::Matrix3x3 Rsrc(quat);
00284             mrpt::math::CMatrixDouble33 Rdes;
00285             for (int c = 0; c < 3; c++)
00286                 for (int r = 0; r < 3; r++) Rdes(r, c) = Rsrc.getRow(r)[c];
00287             pose.setRotationMatrix(Rdes);
00288             static_tf_[key] = pose;
00289             ROS_INFO("Static tf '%s' with '%s'",
00290                      key.c_str(), pose.asString().c_str());
00291         }
00292         catch (tf::TransformException ex)
00293         {
00294             ROS_INFO("getStaticTF");
00295             ROS_ERROR("%s", ex.what());
00296             ros::Duration(1.0).sleep();
00297             return false;
00298         }
00299     }
00300     des = static_tf_[key];
00301     return true;
00302 
00303 }


mrpt_rawlog
Author(s):
autogenerated on Mon Sep 18 2017 03:12:13