8 #include <ros/package.h> 9 #include <geometry_msgs/TransformStamped.h> 10 #include <nav_msgs/MapMetaData.h> 11 #include <tf/transform_listener.h> 14 #include <sensor_msgs/Range.h> 15 #include <yaml-cpp/yaml.h> 17 #include <dynamic_reconfigure/server.h> 18 #include <pses_simulation/RangeSensorConfig.h> 30 template <>
struct convert<geometry_msgs::Pose>
37 static Node
encode(
const geometry_msgs::Pose& rhs)
40 node.push_back(rhs.position.x);
41 node.push_back(rhs.position.y);
42 node.push_back(rhs.position.z);
52 static bool decode(
const Node& node, geometry_msgs::Pose& rhs)
54 if (!node.IsSequence() || node.size() != 3)
59 rhs.position.x = node[0].as<
double>();
60 rhs.position.y = node[1].as<
double>();
61 rhs.position.z = node[2].as<
double>();
91 nav_msgs::MapMetaData& mapInfo)
94 (
unsigned int)((sensor.position.x - mapInfo.origin.position.x) /
97 (
unsigned int)((-sensor.position.y - mapInfo.origin.position.y) /
100 return cv::Point(grid_x, grid_y);
112 const std::string& target_frame,
113 const tf::TransformListener& listener,
114 geometry_msgs::Pose* position, std::vector<double>* rpy)
116 bool transformReady =
false;
117 tf::StampedTransform stf;
118 tf::Stamped<tf::Pose> tmp;
119 geometry_msgs::PoseStamped tmp2;
124 transformReady = listener.waitForTransform(
125 base_frame, target_frame, ros::Time(0), ros::Duration(0.01));
127 catch (tf::TransformException ex)
129 ROS_ERROR(
"%s", ex.what());
136 listener.lookupTransform(base_frame, target_frame, ros::Time(0), stf);
138 catch (tf::TransformException ex)
140 ROS_ERROR(
"%s", ex.what());
142 tmp = tf::Stamped<tf::Pose>(stf, stf.stamp_, base_frame);
143 tf::poseStampedTFToMsg(tmp, tmp2);
144 *position = tmp2.pose;
148 tf::quaternionMsgToTF(tmp2.pose.orientation, q);
149 tf::Matrix3x3(q).getRPY((*rpy)[0], (*rpy)[1], (*rpy)[2]);
151 catch (std::exception ex)
153 ROS_ERROR(
"%s", ex.what());
167 pses_simulation::RangeSensorConfig* dynConfig)
169 sensor->setConfig(config);
171 ROS_DEBUG(
"Config was set");
179 ros::package::getPath(
"pses_simulation") +
"/data/map/map.pgm";
181 ros::package::getPath(
"pses_simulation") +
"/data/map/map.yaml";
195 if (nh->hasParam(
"us_sim/loop_rate_laserscan"))
197 nh->getParam(
"us_sim/loop_rate_laserscan", loopRate);
212 if (nh->hasParam(
"us_sim/us_right_topic"))
214 nh->getParam(
"us_sim/us_right_topic", usrTopic);
229 if (nh->hasParam(
"us_sim/us_front_topic"))
231 nh->getParam(
"us_sim/us_front_topic", usfTopic);
246 if (nh->hasParam(
"us_sim/us_left_topic"))
248 nh->getParam(
"us_sim/us_left_topic", uslTopic);
262 if (nh->hasParam(
"us_sim/map_location"))
264 nh->getParam(
"us_sim/map_location", mapLocation);
277 std::string& mapMetadataLocation)
279 if (nh->hasParam(
"us_sim/map_metadata_location"))
281 nh->getParam(
"us_sim/map_metadata_location", mapMetadataLocation);
295 if (nh->hasParam(
"us_sim/us_right_frame_id"))
297 nh->getParam(
"us_sim/us_right_frame_id", usrFrameID);
311 if (nh->hasParam(
"us_sim/us_front_frame_id"))
313 nh->getParam(
"us_sim/us_front_frame_id", usfFrameID);
327 if (nh->hasParam(
"us_sim/us_left_frame_id"))
329 nh->getParam(
"us_sim/us_left_frame_id", uslFrameID);
343 if (nh->hasParam(
"us_sim/map_frame_id"))
345 nh->getParam(
"us_sim/map_frame_id", mapFrameID);
358 int main(
int argc,
char** argv)
361 ros::init(argc, argv,
"simulation_usscan");
364 std::string usrTopic, usfTopic, uslTopic, mapLocation, mapMetadataLocation,
365 usrFrameID, usfFrameID, uslFrameID, mapFrameID;
378 dynamic_reconfigure::Server<pses_simulation::RangeSensorConfig> server;
379 dynamic_reconfigure::Server<pses_simulation::RangeSensorConfig>::CallbackType
381 pses_simulation::RangeSensorConfig dynConfig;
383 ros::Publisher front_us_range =
384 nh.advertise<sensor_msgs::Range>(usfTopic, 10);
385 ros::Publisher left_us_range = nh.advertise<sensor_msgs::Range>(uslTopic, 10);
386 ros::Publisher right_us_range =
387 nh.advertise<sensor_msgs::Range>(usrTopic, 10);
389 sensor_msgs::Range front_range, left_range, right_range;
392 nav_msgs::MapMetaData mapInfo;
393 YAML::Node imgMetaInfo = YAML::LoadFile(mapMetadataLocation);
394 double resolution = imgMetaInfo[
"resolution"].as<
double>();
395 geometry_msgs::Pose origin = imgMetaInfo[
"origin"].as<geometry_msgs::Pose>();
396 mapInfo.origin = origin;
397 mapInfo.resolution = resolution;
400 cv::Mat map = cv::imread(mapLocation, 1);
401 cv::cvtColor(map, map, CV_RGB2GRAY);
405 rs_sonar.setMap(map);
406 rs_sonar.setMapMetaData(mapInfo);
409 server.setCallback(f);
412 tf::TransformListener listener;
413 geometry_msgs::Pose position;
414 std::vector<double> rpy(3, 0.0);
417 ros::Time currentTime = ros::Time::now();
419 front_range.header.frame_id = usfFrameID;
420 front_range.radiation_type = 0;
422 left_range.header.frame_id = uslFrameID;
423 left_range.radiation_type = 0;
425 right_range.header.frame_id = usrFrameID;
426 right_range.radiation_type = 0;
429 ros::Rate loop_rate(loopRate);
432 currentTime = ros::Time::now();
434 front_range.header.stamp = currentTime;
435 front_range.field_of_view =
rs::degToRad(dynConfig.us_field_of_view);
436 front_range.min_range = dynConfig.us_min_sensor_distance;
437 front_range.max_range = dynConfig.us_max_sensor_distance;
439 left_range.header.stamp = currentTime;
440 left_range.field_of_view =
rs::degToRad(dynConfig.us_field_of_view);
441 left_range.min_range = dynConfig.us_min_sensor_distance;
442 left_range.max_range = dynConfig.us_max_sensor_distance;
444 right_range.header.stamp = currentTime;
445 right_range.field_of_view =
rs::degToRad(dynConfig.us_field_of_view);
446 right_range.min_range = dynConfig.us_min_sensor_distance;
447 right_range.max_range = dynConfig.us_max_sensor_distance;
452 front_range.range = rs_sonar.getUSScan(gridPose,
rs::radToDeg(rpy[2]));
457 left_range.range = rs_sonar.getUSScan(gridPose,
rs::radToDeg(rpy[2]));
462 right_range.range = rs_sonar.getUSScan(gridPose,
rs::radToDeg(rpy[2]));
465 front_us_range.publish(front_range);
466 right_us_range.publish(right_range);
467 left_us_range.publish(left_range);
This namespace groups all typedefs, utility functions and parameter getter used in the simulation_us ...
void fetchLoopRate(ros::NodeHandle *nh, double &loopRate)
Get loop rate launch parameter.
The rs::RangeSensor class simulates different range finder sensors based on the given rs::SensorType ...
void fetchMapLocation(ros::NodeHandle *nh, std::string &mapLocation)
Get map location launch parameter.
Header file for the rs::RangeSensor class.
std::shared_ptr< sensor_msgs::Range > scan_msg_ptr
shortcut for a pointer to a range message
void fetchUSRFrameID(ros::NodeHandle *nh, std::string &usrFrameID)
Get right ultra sonic sensor frame id launch parameter.
static const std::string DEFAULT_MAP_LOCATION
static Node encode(const geometry_msgs::Pose &rhs)
Encodes a pose message to YAML::Node containing x,y,z variables.
void fetchMapMetadataLocation(ros::NodeHandle *nh, std::string &mapMetadataLocation)
Get map meta data location launch parameter.
static const std::string DEFAULT_MAP_METADATA_LOCATION
void fetchMapFrameID(ros::NodeHandle *nh, std::string &mapFrameID)
Get map frame id launch parameter.
void fetchUSFTopic(ros::NodeHandle *nh, std::string &usfTopic)
Get front ultra sonic sensor topic launch parameter.
void configCallback(pses_simulation::RangeSensorConfig &config, uint32_t level, rs::RangeSensor *sensor, pses_simulation::RangeSensorConfig *dynConfig)
Sets the RangeSensorConfig object of this sensor simulation.
void fetchUSLTopic(ros::NodeHandle *nh, std::string &uslTopic)
Get left ultra sonic sensor topic launch parameter.
cv::Point setGridPosition(geometry_msgs::Pose &sensor, nav_msgs::MapMetaData &mapInfo)
Calculate the occupancy grid postion of a given pose.
static bool decode(const Node &node, geometry_msgs::Pose &rhs)
Decodes a YAML::Node containing x,y,z variables to a pose message.
static const std::string DEFAULT_MAP_FRAME_ID
static const std::string DEFAULT_US_LEFT_TOPIC
static const std::string DEFAULT_US_RIGHT_FRAME_ID
static const std::string DEFAULT_US_RIGHT_TOPIC
void fetchUSFFrameID(ros::NodeHandle *nh, std::string &usfFrameID)
Get front ultra sonic sensor 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.
int main(int argc, char **argv)
Main function of this ros node.
double radToDeg(double angle)
Conversion from radiants to degrees.
static const std::string DEFAULT_US_FRONT_TOPIC
void fetchUSRTopic(ros::NodeHandle *nh, std::string &usrTopic)
Get right ultra sonic sensor topic launch parameter.
static const std::string DEFAULT_US_FRONT_FRAME_ID
static const double DEFAULT_LOOP_RATE
This namespace contains special functionality to parse from .yaml files or write to ...
double degToRad(double angle)
Conversion from degrees to radiants.
void fetchUSLFrameID(ros::NodeHandle *nh, std::string &uslFrameID)
Get left ultra sonic sensor frame id launch parameter.
static const std::string DEFAULT_US_LEFT_FRAME_ID
std::shared_ptr< geometry_msgs::Pose > pose_msg_ptr
shortcut for a pointer to a pose message