graph.cpp
Go to the documentation of this file.
00001 #include "transform_graph/graph.h"
00002 
00003 #include <map>
00004 #include <string>
00005 #include <utility>
00006 #include <vector>
00007 
00008 #include "Eigen/Dense"
00009 #include "Eigen/Geometry"
00010 
00011 #include "transform_graph/explicit_types.h"
00012 #include "transform_graph/transform.h"
00013 
00014 using std::pair;
00015 using std::string;
00016 
00017 typedef pair<string, string> FrameKey;
00018 
00019 namespace transform_graph {
00020 Graph::Graph() : transforms_(), graph_() {}
00021 
00022 void Graph::Add(const std::string& name, const RefFrame& source,
00023                 const Transform& transform) {
00024   graph_.AddEdge(source.id(), name);
00025   transforms_[FrameKey(source.id(), name)] = transform;
00026 }
00027 
00028 bool Graph::CanTransform(const string& frame1_id,
00029                          const string& frame2_id) const {
00030   std::vector<string> path;
00031   graph_.Path(frame1_id, frame2_id, &path);
00032   return path.size() > 0;
00033 }
00034 
00035 bool Graph::ComputeDescription(const LocalFrame& local_frame,
00036                                const RefFrame& reference_frame,
00037                                Transform* transform) const {
00038   std::vector<string> path;
00039   graph_.Path(reference_frame.id(), local_frame.id(), &path);
00040 
00041   if (path.size() == 0) {
00042     return false;
00043   }
00044 
00045   Eigen::Affine3d result = Eigen::Affine3d::Identity();
00046   for (size_t i = 1; i < path.size(); ++i) {
00047     Eigen::Affine3d working = Eigen::Affine3d::Identity();
00048     bool success = GetTransform(path[i - 1], path[i], &working);
00049     if (!success) {
00050       return false;
00051     }
00052     result = result * working;
00053   }
00054   *transform = result;
00055 
00056   return true;
00057 }
00058 
00059 bool Graph::ComputeMapping(const From& from, const To& to,
00060                            Transform* transform) const {
00061   return ComputeDescription(to.id(), RefFrame(from.id()), transform);
00062 }
00063 
00064 bool Graph::DescribePose(const Transform& in, const Source& source_frame,
00065                          const Target& target_frame, Transform* out) const {
00066   std::vector<string> path;
00067   graph_.Path(target_frame.id(), source_frame.id(), &path);
00068 
00069   if (path.size() == 0) {
00070     return false;
00071   }
00072 
00073   Eigen::Affine3d result = Eigen::Affine3d::Identity();
00074   for (size_t i = 1; i < path.size(); ++i) {
00075     Eigen::Affine3d working = Eigen::Affine3d::Identity();
00076     bool success = GetTransform(path[i - 1], path[i], &working);
00077     if (!success) {
00078       return false;
00079     }
00080     result = result * working;
00081   }
00082   result = result * in.matrix();
00083   *out = result;
00084 
00085   return true;
00086 }
00087 
00088 bool Graph::MapPose(const Transform& in, const From& from_frame,
00089                     const To& to_frame, Transform* out) const {
00090   return DescribePose(in, Source(to_frame.id()), Target(from_frame.id()), out);
00091 }
00092 
00093 bool Graph::DescribePosition(const Position& in, const Source& local_frame,
00094                              const Target& reference_frame,
00095                              Position* out) const {
00096   std::vector<string> path;
00097   graph_.Path(reference_frame.id(), local_frame.id(), &path);
00098 
00099   if (path.size() == 0) {
00100     return false;
00101   }
00102 
00103   Eigen::Vector3d result = in.vector();
00104   // Iterate backward to do fewer multiplications.
00105   for (int i = static_cast<int>(path.size()) - 2; i >= 0; --i) {
00106     Eigen::Affine3d working = Eigen::Affine3d::Identity();
00107     bool success = GetTransform(path[i], path[i + 1], &working);
00108     if (!success) {
00109       return false;
00110     }
00111     result = working * result;
00112   }
00113   *out = result;
00114 
00115   return true;
00116 }
00117 
00118 bool Graph::MapPosition(const Position& in, const From& frame_in,
00119                         const To& frame_out, Position* out) const {
00120   return DescribePosition(in, Source(frame_out.id()), Target(frame_in.id()),
00121                           out);
00122 }
00123 
00124 bool Graph::GetTransform(const std::string& source, const std::string& target,
00125                          Eigen::Affine3d* out) const {
00126   FrameKey key(source, target);
00127   FrameKey inverse_key(target, source);
00128   std::map<FrameKey, Transform>::const_iterator it = transforms_.find(key);
00129   if (it != transforms_.end()) {
00130     *out = it->second.matrix();
00131     return true;
00132   } else {
00133     it = transforms_.find(inverse_key);
00134     if (it != transforms_.end()) {
00135       *out = it->second.inverse().matrix();
00136       return true;
00137     }
00138   }
00139   return false;
00140 }
00141 }  // namespace transform_graph


transform_graph
Author(s):
autogenerated on Sat Jun 8 2019 19:23:43