8 #include <ros/package.h>     9 #include <geometry_msgs/TransformStamped.h>    10 #include <nav_msgs/MapMetaData.h>    11 #include <sensor_msgs/LaserScan.h>    12 #include <tf/transform_listener.h>    15 #include <sensor_msgs/Range.h>    16 #include <yaml-cpp/yaml.h>    17 #include <dynamic_reconfigure/server.h>    18 #include <pses_simulation/RangeSensorConfig.h>    31 template <> 
struct convert<geometry_msgs::Pose>
    38   static Node 
encode(
const geometry_msgs::Pose& rhs)
    41     node.push_back(rhs.position.x);
    42     node.push_back(rhs.position.y);
    43     node.push_back(rhs.position.z);
    53   static bool decode(
const Node& node, geometry_msgs::Pose& rhs)
    55     if (!node.IsSequence() || node.size() != 3)
    60     rhs.position.x = node[0].as<
double>();
    61     rhs.position.y = node[1].as<
double>();
    62     rhs.position.z = node[2].as<
double>();
    93                           nav_msgs::MapMetaData& mapInfo)
    96       (
unsigned int)((laser.position.x - mapInfo.origin.position.x) /
    99       (
unsigned int)((-laser.position.y - mapInfo.origin.position.y) /
   101   return cv::Point(grid_x, grid_y);
   113                      const std::string& target_frame,
   114                      const tf::TransformListener& listener,
   115                      geometry_msgs::Pose* position, std::vector<double>* rpy)
   117   bool transformReady = 
false;
   118   tf::StampedTransform stf;
   119   tf::Stamped<tf::Pose> tmp;
   120   geometry_msgs::PoseStamped tmp2;
   125     transformReady = listener.waitForTransform(
   126         base_frame, target_frame, ros::Time(0), ros::Duration(0.01));
   128   catch (tf::TransformException ex)
   130     ROS_ERROR(
"%s", ex.what());
   137       listener.lookupTransform(base_frame, target_frame, ros::Time(0), stf);
   139     catch (tf::TransformException ex)
   141       ROS_ERROR(
"%s", ex.what());
   143     tmp = tf::Stamped<tf::Pose>(stf, stf.stamp_, base_frame);
   144     tf::poseStampedTFToMsg(tmp, tmp2);
   145     *position = tmp2.pose;
   149       tf::quaternionMsgToTF(tmp2.pose.orientation, q);
   150       tf::Matrix3x3(q).getRPY((*rpy)[0], (*rpy)[1], (*rpy)[2]);
   152     catch (std::exception ex)
   154       ROS_ERROR(
"%s", ex.what());
   168                     pses_simulation::RangeSensorConfig* dynConfig)
   170   sensor->setConfig(config);
   172   ROS_DEBUG(
"Config was set");
   179 static const std::string
   181     ros::package::getPath(
"pses_simulation") + 
"/data/map/map.pgm";
   182 static const std::string
   185     ros::package::getPath(
"pses_simulation") + 
"/data/map/map.yaml";
   198   if (nh->hasParam(
"laser_sim/loop_rate_laserscan"))
   200     nh->getParam(
"laser_sim/loop_rate_laserscan", loopRate);
   215   if (nh->hasParam(
"laser_sim/laser_scan_topic"))
   217     nh->getParam(
"laser_sim/laser_scan_topic", laserScanTopic);
   231   if (nh->hasParam(
"laser_sim/map_location"))
   233     nh->getParam(
"laser_sim/map_location", mapLocation);
   246                               std::string& mapMetadataLocation)
   248   if (nh->hasParam(
"laser_sim/map_metadata_location"))
   250     nh->getParam(
"laser_sim/map_metadata_location", mapMetadataLocation);
   264   if (nh->hasParam(
"laser_sim/laserscan_frame_id"))
   266     nh->getParam(
"laser_sim/laserscan_frame_id", laserscanFrameID);
   280   if (nh->hasParam(
"laser_sim/map_frame_id"))
   282     nh->getParam(
"laser_sim/map_frame_id", mapFrameID);
   296 int main(
int argc, 
char** argv)
   299   ros::init(argc, argv, 
"simulation_laserscan");
   302   std::string laserScanTopic, mapLocation, mapMetadataLocation,
   303       laserscanFrameID, mapFrameID;
   313   dynamic_reconfigure::Server<pses_simulation::RangeSensorConfig> server;
   314   dynamic_reconfigure::Server<pses_simulation::RangeSensorConfig>::CallbackType
   316   pses_simulation::RangeSensorConfig dynConfig;
   318   ros::Publisher scanPub =
   319       nh.advertise<sensor_msgs::LaserScan>(laserScanTopic, 10);
   321   sensor_msgs::LaserScan scan;
   324   nav_msgs::MapMetaData mapInfo;
   325   YAML::Node imgMetaInfo = YAML::LoadFile(mapMetadataLocation);
   326   double resolution = imgMetaInfo[
"resolution"].as<
double>();
   327   geometry_msgs::Pose origin = imgMetaInfo[
"origin"].as<geometry_msgs::Pose>();
   328   mapInfo.origin = origin;
   329   mapInfo.resolution = resolution;
   332   cv::Mat map = cv::imread(mapLocation, 1);
   333   cv::cvtColor(map, map, CV_RGB2GRAY);
   337   rs_laser.setMap(map);
   338   rs_laser.setMapMetaData(mapInfo);
   341   server.setCallback(f);
   344   tf::TransformListener listener;
   345   geometry_msgs::Pose position;
   346   std::vector<double> rpy(3, 0.0);
   349   ros::Time currentTime = ros::Time::now();
   352   ros::Rate loop_rate(loopRate);
   355     currentTime = ros::Time::now();
   356     scan.header.stamp = currentTime;
   357     scan.header.frame_id = laserscanFrameID;
   358     scan.angle_increment = 
rs::degToRad(dynConfig.laser_angular_resolution);
   359     scan.range_min = dynConfig.laser_min_sensor_distance;
   360     scan.range_max = dynConfig.laser_max_sensor_distance;
   367     getPositionInfo(mapFrameID, laserscanFrameID, listener, &position, &rpy);
   369     scan.ranges = *rs_laser.getLaserScan(gridPose, 
rs::radToDeg(rpy[2]));
   372     scanPub.publish(scan);
 The rs::RangeSensor class simulates different range finder sensors based on the given rs::SensorType ...
 
int main(int argc, char **argv)
Main function of this ros node. 
 
cv::Point setGridPosition(geometry_msgs::Pose &laser, nav_msgs::MapMetaData &mapInfo)
Calculate the occupancy grid postion of a given pose. 
 
Header file for the rs::RangeSensor class. 
 
static const std::string DEFAULT_MAP_FRAME_ID
 
void fetchMapMetadataLocation(ros::NodeHandle *nh, std::string &mapMetadataLocation)
Get map meta data location launch parameter. 
 
void fetchMapLocation(ros::NodeHandle *nh, std::string &mapLocation)
Get map location launch parameter. 
 
static const std::string DEFAULT_MAP_METADATA_LOCATION
 
static Node encode(const geometry_msgs::Pose &rhs)
Encodes a pose message to YAML::Node containing x,y,z variables. 
 
void fetchMapFrameID(ros::NodeHandle *nh, std::string &mapFrameID)
Get map frame id launch parameter. 
 
static const std::string DEFAULT_MAP_LOCATION
 
void fetchLoopRate(ros::NodeHandle *nh, double &loopRate)
Get loop rate launch parameter. 
 
static bool decode(const Node &node, geometry_msgs::Pose &rhs)
Decodes a YAML::Node containing x,y,z variables to a pose message. 
 
This namespace groups all typedefs, utility functions and parameter getter used in the simulation_las...
 
void fetchLaserscanFrameID(ros::NodeHandle *nh, std::string &laserscanFrameID)
Get laser scan frame id launch parameter. 
 
void getPositionInfo(const std::string &base_frame, const std::string &target_frame, const tf::TransformListener &listener, geometry_msgs::Pose *position, std::vector< double > *rpy)
Get the current postion of a sensor from the tf transformation service. 
 
std::shared_ptr< geometry_msgs::Pose > pose_msg_ptr
shortcut for a pointer to a pose message 
 
double radToDeg(double angle)
Conversion from radiants to degrees. 
 
static const std::string DEFAULT_LASER_SCAN_TOPIC
 
This namespace contains special functionality to parse from .yaml files or write to ...
 
std::shared_ptr< sensor_msgs::LaserScan > scan_msg_ptr
shortcut for a pointer to a laser scan message 
 
void configCallback(pses_simulation::RangeSensorConfig &config, uint32_t level, rs::RangeSensor *sensor, pses_simulation::RangeSensorConfig *dynConfig)
Sets the RangeSensorConfig object of this sensor simulation. 
 
static const std::string DEFAULT_LASERSCAN_FRAME_ID
 
double degToRad(double angle)
Conversion from degrees to radiants. 
 
double correctYawAngle(const double theta, const double increment)
Calculate a correct euler angle after incrementing/decrementing. 
 
static const double DEFAULT_LOOP_RATE
 
void fetchLaserScanTopic(ros::NodeHandle *nh, std::string &laserScanTopic)
Get laser scan topic launch parameter.