tf_remapper.cpp
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(); /* ++it is called at the end of the loop to allow erasing */) {
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()) { // delete the transform
00074                 it = message.transforms.erase(it);
00075                 continue; // it already points to the next element or end()
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()) { // delete the transform
00082                 it = message.transforms.erase(it);
00083                 continue; // it already points to the next element or end()
00084             } else {
00085                 transform.child_frame_id = this->mappings.at(transform.child_frame_id);
00086             }
00087         }
00088         ++it; // we did not delete the transform, so go to the next one
00089     }
00090 }
00091 
00092 const tf_remapper_cpp::TfRemapper::MappingsType& tf_remapper_cpp::TfRemapper::getMappings() const {
00093     return this->mappings;
00094 }


tf_remapper_cpp
Author(s): Martin Pecka
autogenerated on Tue Mar 19 2019 09:29:23