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.