Go to the documentation of this file.00001 #include <ros/ros.h>
00002 #include <tf_remapper_cpp/tf_remapper.h>
00003 #include <set>
00004
00005 tf_remapper_cpp::TfRemapper::TfRemapper() {}
00006
00007 tf_remapper_cpp::TfRemapper::~TfRemapper() {}
00008
00009 tf_remapper_cpp::TfRemapper::TfRemapper(const std::map<std::string, std::string> mappings, const bool reverse) {
00010 for (TfRemapper::MappingsType::const_iterator it = mappings.begin(); it != mappings.end(); ++it) {
00011 if (it->first.empty())
00012 throw ros::InvalidParameterException("Key 'old' in each mapping has to be set to a nonempty string.");
00013 }
00014
00015 if (!reverse) {
00016 this->mappings = mappings;
00017 } else {
00018 for (std::map<std::string, std::string>::const_iterator it = mappings.begin(); it != mappings.end(); ++it) {
00019 if (!it->second.empty())
00020 this->mappings[it->second] = it->first;
00021 }
00022 }
00023 }
00024
00025 tf_remapper_cpp::TfRemapper::TfRemapper(const XmlRpc::XmlRpcValue& mappingsParam, const bool reverse) {
00026 if(mappingsParam.getType() != XmlRpc::XmlRpcValue::TypeArray)
00027 throw ros::InvalidParameterException("The 'mappings' parameter must be an array of dictionaries.");
00028
00029 for (size_t i = 0; i < mappingsParam.size(); ++i) {
00030 XmlRpc::XmlRpcValue mapping = mappingsParam[i];
00031 if (mapping.getType() != XmlRpc::XmlRpcValue::TypeStruct)
00032 throw ros::InvalidParameterException("The 'mappings' parameter must be an array of dictionaries.");
00033
00034 std::string oldTopic;
00035 std::string newTopic;
00036 const std::string oldKey = (reverse ? "new" : "old");
00037 const std::string newKey = (reverse ? "old" : "new");
00038 for (XmlRpc::XmlRpcValue::iterator it = mapping.begin(); it != mapping.end(); ++it)
00039 {
00040 if (it->second.getType() != XmlRpc::XmlRpcValue::TypeString)
00041 throw ros::InvalidParameterException("Dict values must be strings");
00042 if (it->first == oldKey)
00043 oldTopic = (const std::string&)it->second;
00044 else if (it->first == newKey)
00045 newTopic = (std::string&)it->second;
00046 else
00047 throw ros::InvalidParameterException("Each dict in the mapping has to have only keys 'old' and 'new'.");
00048 }
00049
00050 if (oldTopic.empty() && newTopic.empty())
00051 throw ros::InvalidParameterException("Either 'old' or 'new' key in each mapping has to be set to a "
00052 "nonempty string.");
00053
00054 if (oldTopic == newTopic)
00055 ROS_WARN_STREAM("Remapped topic '" << oldTopic << "' is the same as the old topic.");
00056
00057 if (!oldTopic.empty())
00058 this->mappings[oldTopic] = newTopic;
00059 }
00060 }
00061
00062 tf2_msgs::TFMessage tf_remapper_cpp::TfRemapper::doRemapping(const tf2_msgs::TFMessage& inMessage) const {
00063 tf2_msgs::TFMessage message = inMessage;
00064 this->doRemapping(message);
00065 return message;
00066 }
00067
00068 void tf_remapper_cpp::TfRemapper::doRemapping(tf2_msgs::TFMessage& message) const {
00069 for (std::vector<geometry_msgs::TransformStamped>::iterator it = message.transforms.begin();
00070 it != message.transforms.end(); ) {
00071 geometry_msgs::TransformStamped& transform = *it;
00072 if (this->mappings.find(transform.header.frame_id) != this->mappings.end()) {
00073 if (this->mappings.at(transform.header.frame_id).empty()) {
00074 it = message.transforms.erase(it);
00075 continue;
00076 } else {
00077 transform.header.frame_id = this->mappings.at(transform.header.frame_id);
00078 }
00079 }
00080 if (this->mappings.find(transform.child_frame_id) != this->mappings.end()) {
00081 if (this->mappings.at(transform.child_frame_id).empty()) {
00082 it = message.transforms.erase(it);
00083 continue;
00084 } else {
00085 transform.child_frame_id = this->mappings.at(transform.child_frame_id);
00086 }
00087 }
00088 ++it;
00089 }
00090 }
00091
00092 const tf_remapper_cpp::TfRemapper::MappingsType& tf_remapper_cpp::TfRemapper::getMappings() const {
00093 return this->mappings;
00094 }