TransformReader.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of ArmarX.
3  *
4  * ArmarX is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  *
8  * ArmarX is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  *
16  * @author Fabian Reister ( fabian dot reister at kit dot edu )
17  * @date 2021
18  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
19  * GNU General Public License
20  */
21 
22 #include "TransformReader.h"
23 
24 #include <algorithm>
25 #include <iterator>
26 #include <numeric>
27 
28 // Ice
29 #include <IceUtil/Time.h>
30 
31 // Eigen
32 #include <Eigen/Geometry>
33 
34 // Simox
35 #include <SimoxUtility/algorithm/get_map_keys_values.h>
36 #include <SimoxUtility/algorithm/string/string_tools.h>
37 #include <SimoxUtility/color/cmaps.h>
38 #include <SimoxUtility/math/pose/interpolate.h>
39 
40 // ArmarX
44 
45 // this package
53 #include <RobotAPI/libraries/armem_robot_state/aron/Transform.aron.generated.h>
59 
61 {
63  memoryReader(t.memoryReader), properties(t.properties), propertyPrefix(t.propertyPrefix)
64  {
65 
66  }
67 
69 
70  void
72  {
73  ARMARX_DEBUG << "TransformReader: registerPropertyDefinitions";
74 
75  const std::string prefix = propertyPrefix;
76 
77  def->optional(properties.localizationSegment,
78  prefix + "localizationSegment",
79  "Name of the localization memory core segment to use.");
80 
81  def->optional(properties.memoryName, prefix + "Memory");
82  }
83 
84  void
86  {
87  // Wait for the memory to become available and add it as dependency.
88  ARMARX_INFO << "TransformReader: Waiting for memory '" << properties.memoryName << "' ...";
89  try
90  {
91  memoryReader = memoryNameSystem.useReader(properties.memoryName);
92  ARMARX_INFO << "TransformReader: Connected to memory '" << properties.memoryName;
93  }
95  {
96  ARMARX_ERROR << e.what();
97  return;
98  }
99  }
100 
102  TransformReader::getGlobalPose(const std::string& agentName,
103  const std::string& robotRootFrame,
104  const armem::Time& timestamp) const
105  {
106  const TransformQuery query{.header = {.parentFrame = GlobalFrame,
107  .frame = robotRootFrame,
108  .agent = agentName,
109  .timestamp = timestamp}};
110 
111  return lookupTransform(query);
112  }
113 
114  // std::vector<std::string> buildTransformChainArbitrary(const
115  // std::map<std::string, armem::ProviderSegment>& providerSegments, const
116  // std::string& parentFrame, const std::string& frame){
117 
118  // std::map<std::string, std::string> tf;
119 
120  // // build string representation of transforms
121  // for(const auto& [name, segment]: providerSegments){
122  // const auto frames = simox::alg::split(name, ",");
123  // if (frames.size() != 2){
124  // ARMARX_WARNING << "Segment name " << name << " not understood";
125  // continue;
126  // }
127 
128  // tf.insert(frame[0], frame[1]);
129  // }
130 
131  // // find
132 
133  // }
134 
135 
138  {
139  const auto& timestamp = query.header.timestamp;
140  ARMARX_DEBUG << "Looking up transform at timestamp " << timestamp;
141 
142  const IceUtil::Time durationEpsilon = IceUtil::Time::milliSeconds(-1);
143  (void)durationEpsilon;
144 
145  // Query all entities from provider.
147 
148  // clang-format off
149  qb
150  .coreSegments().withName(properties.localizationSegment)
151  .providerSegments().withName(query.header.agent) // agent
152  .entities().all() // parentFrame,frame
154  // clang-format on
155 
156  try
157  {
158  std::scoped_lock l(memoryReaderMutex);
159  const armem::client::QueryResult qResult = memoryReader.query(qb.buildQueryInput());
160  ARMARX_DEBUG << "Lookup result in reader: " << qResult;
161 
162  if (not qResult.success)
163  {
164  return {.transform =
165  {
166  .header = query.header,
167  },
169  .errorMessage = "Error in tf lookup '" + query.header.parentFrame + " -> " +
170  query.header.frame + "' : " + qResult.errorMessage};
171  }
172 
173  const auto& localizationCoreSegment =
174  qResult.memory.getCoreSegment(properties.localizationSegment);
175 
177  return TransformHelper::lookupTransform(localizationCoreSegment, query);
178  }
179  catch (...)
180  {
181  ARMARX_VERBOSE << "Lookup Transform failure" << GetHandledExceptionString();
182  return TransformResult{.transform =
183  {
184  .header = query.header,
185  },
187  .errorMessage = "Error in tf lookup '" +
188  query.header.parentFrame + " -> " +
189  query.header.frame + "' : Memory exception."};
190  }
191  }
192 
193 } // namespace armarx::armem::client::robot_state::localization
armarx::armem::client::query::EntitySelector::all
EntitySelector & all() override
Definition: selectors.cpp:96
ARMARX_VERBOSE
#define ARMARX_VERBOSE
Definition: Logging.h:180
armarx::armem::client::query::ProviderSegmentSelector::entities
EntitySelector & entities()
Start specifying entities.
Definition: selectors.cpp:123
TransformReader.h
armarx::armem::client::robot_state::localization::TransformReader::lookupTransform
TransformResult lookupTransform(const TransformQuery &query) const override
Definition: TransformReader.cpp:137
armarx::armem::client::query::Builder::buildQueryInput
QueryInput buildQueryInput() const
Definition: Builder.cpp:11
armarx::armem::client::robot_state::localization
Definition: interfaces.h:33
armarx::armem::client::robot_state::localization::TransformReader::registerPropertyDefinitions
void registerPropertyDefinitions(::armarx::PropertyDefinitionsPtr &def) override
Definition: TransformReader.cpp:71
armarx::armem::client::query::EntitySelector::snapshots
SnapshotSelector & snapshots()
Start specifying entity snapshots.
Definition: selectors.cpp:86
armarx::armem::common::robot_state::localization::TransformResult::Status::ErrorFrameNotAvailable
@ ErrorFrameNotAvailable
armarx::armem::common::robot_state::localization::TransformQuery
Definition: types.h:75
armarx::armem::common::robot_state::localization::TransformResult::transform
::armarx::armem::robot_state::Transform transform
Definition: types.h:36
armarx::GlobalFrame
const std::string GlobalFrame
Definition: FramedPose.h:62
types.h
query_fns.h
armarx::armem::client::QueryResult
Result of a QueryInput.
Definition: Query.h:50
TransformHelper.h
armarx::GetHandledExceptionString
std::string GetHandledExceptionString()
Definition: Exception.cpp:147
armarx::armem::robot_state::TransformHeader::parentFrame
std::string parentFrame
Definition: types.h:33
armarx::armem::robot_state::Transform::header
TransformHeader header
Definition: types.h:43
armarx::armem::common::robot_state::localization::TransformQuery::header
::armarx::armem::robot_state::TransformHeader header
Definition: types.h:77
armarx::armem::robot_state::TransformHeader::frame
std::string frame
Definition: types.h:34
FramedPose.h
armarx::armem::client::query::Builder::coreSegments
CoreSegmentSelector & coreSegments()
Start specifying core segments.
Definition: Builder.cpp:38
MemoryRemoteGui.h
ARMARX_DEBUG
#define ARMARX_DEBUG
Definition: Logging.h:177
armarx::armem::client::robot_state::localization::TransformReader::connect
void connect(armem::client::MemoryNameSystem &memoryNameSystem) override
Definition: TransformReader.cpp:85
armarx::armem::client::query::CoreSegmentSelector::withName
CoreSegmentSelector & withName(const std::string &name) override
Definition: selectors.cpp:177
error.h
armarx::armem::client::MemoryNameSystem::useReader
Reader useReader(const MemoryID &memoryID)
Use a memory server and get a reader for it.
Definition: MemoryNameSystem.cpp:184
armarx::armem::robot_state::TransformHeader::timestamp
armem::Time timestamp
Definition: types.h:38
armarx::armem::common::robot_state::localization::TransformResult
Definition: types.h:34
aron_conversions.h
armarx::armem::robot_state::TransformHeader::agent
std::string agent
Definition: types.h:36
ARMARX_ERROR
#define ARMARX_ERROR
Definition: Logging.h:189
Factory.h
armarx::armem::Time
armarx::core::time::DateTime Time
Definition: forward_declarations.h:13
armarx::armem::client::robot_state::localization::TransformReader
Brief description of class ExampleClient.
Definition: TransformReader.h:43
memory_definitions.h
CycleUtil.h
ExpressionException.h
armarx::armem::client::robot_state::localization::TransformReader::TransformReader
TransformReader()=default
armarx::armem::client::robot_state::localization::TransformReader::~TransformReader
~TransformReader() override
armarx::core::time::DateTime
Represents a point in time.
Definition: DateTime.h:24
armarx::armem::client::query::ProviderSegmentSelector::withName
ProviderSegmentSelector & withName(const std::string &name) override
Definition: selectors.cpp:140
armarx::armem::robot_state::constants::localizationCoreSegment
const std::string localizationCoreSegment
Definition: constants.h:29
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:174
armarx::armem::client::query::SnapshotSelector::beforeOrAtTime
SnapshotSelector & beforeOrAtTime(Time timestamp)
Definition: selectors.cpp:68
IceUtil::Handle< class PropertyDefinitionContainer >
armarx::armem::common::robot_state::localization::TransformResult::Status::Error
@ Error
Time.h
Builder.h
armarx::armem::common::robot_state::localization::TransformHelper
Definition: TransformHelper.h:41
armarx::armem::client::MemoryNameSystem
The memory name system (MNS) client.
Definition: MemoryNameSystem.h:69
armarx::armem::error::CouldNotResolveMemoryServer
Indicates that a query to the Memory Name System failed.
Definition: mns.h:26
armarx::armem::client::query::Builder
The query::Builder class provides a fluent-style specification of hierarchical queries.
Definition: Builder.h:22
armarx::armem::client::query::CoreSegmentSelector::providerSegments
ProviderSegmentSelector & providerSegments()
Start specifying provider segments.
Definition: selectors.cpp:160
Logging.h
armarx::armem::client::Reader::query
QueryResult query(const QueryInput &input) const
Perform a query.
Definition: Reader.cpp:33
ice_conversions.h
armarx::armem::client::robot_state::localization::TransformReader::getGlobalPose
TransformResult getGlobalPose(const std::string &agentName, const std::string &robotRootFrame, const armem::Time &timestamp) const override
Definition: TransformReader.cpp:102