HumanMemory.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  * @package RobotAPI::ArmarXObjects::ExampleMemory
17  * @author Rainer Kartmann ( rainer dot kartmann at kit dot edu )
18  * @date 2020
19  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20  * GNU General Public License
21  */
22 
23 #include "HumanMemory.h"
24 
25 #include <exception>
26 
27 #include <qnamespace.h>
28 
29 #include <SimoxUtility/algorithm/apply.hpp>
30 #include <VirtualRobot/VirtualRobot.h>
31 
34 
36 #include <RobotAPI/interface/armem/commit.h>
41 
43 #include <VisionX/libraries/armem_human/aron/HumanPose.aron.generated.h>
44 
46 {
47 
50  {
53 
54  setMemoryName("Human");
55 
56  profileSegment.defineProperties(defs, "profile.");
57  personInstanceSegment.defineProperties(defs, "instance");
58  poseSegment.defineProperties(defs, "pose.");
59  faceRecognitionSegment.defineProperties(defs, "face.");
60  identificationSegment.defineProperties(defs, "ident.");
61 
62  return defs;
63  }
64 
66  profileSegment(iceAdapter()),
67  personInstanceSegment(iceAdapter()),
68  poseSegment(iceAdapter()),
69  faceRecognitionSegment(iceAdapter()),
70  identificationSegment(iceAdapter()),
71  visu(poseSegment, faceRecognitionSegment, personInstanceSegment)
72  {
73  addPlugin(virtualRobotReaderPlugin);
74  }
75 
76  std::string
78  {
79  return "HumanMemory";
80  }
81 
82  void
84  {
85  profileSegment.init();
86  personInstanceSegment.init();
87  poseSegment.init();
88  faceRecognitionSegment.init();
89  identificationSegment.init();
90  visu.init();
91 
92  workingMemory().addCoreSegment("RecognizedAction");
93  }
94 
95  void
97  {
99  }
100 
101  void
103  {
104  }
105 
106  void
108  {
109  }
110 
112  HumanMemory::getSynchronizedRobot(const std::string& robotName,
113  const armarx::DateTime& timestamp)
114  {
115  // seach and retrieve robot
116  auto& robot = [&]() -> VirtualRobot::RobotPtr&
117  {
118  // retrieve robot from memory if it is not in cache
119  if (robots.count(robotName) == 0)
120  {
121  auto newRobot = virtualRobotReaderPlugin->get().getRobot(robotName);
122  ARMARX_CHECK_NOT_NULL(newRobot)
123  << "Failed to obtain robot with name `" << robotName << "`.";
124 
125  robots[robotName] = newRobot;
126  }
127 
128  return robots.at(robotName);
129  }();
130 
131  // synchronize robot
132  bool const success = virtualRobotReaderPlugin->get().synchronizeRobot(*robot, timestamp);
133 
134  if (not success)
135  {
136  // throw armarx::LocalException(
137  // "Failed synchronizing the robot to calculate the global human pose from a reported "
138  // "human pose in camera coordinate system. Query timestamp is '")
139  // << timestamp << "'.";
140  return nullptr;
141  }
142 
143  return robot;
144  }
145 
146  void
148  const ::armarx::aron::data::dto::AronDictSeq& dictSeq,
149  const ::std::string& providerName,
150  const ::armarx::core::time::dto::DateTime& iceTimestamp,
151  const ::Ice::Current& /*c*/)
152  {
153  if (dictSeq.empty())
154  {
155  return;
156  }
157 
158  // convert from ice
159  armarx::DateTime timestamp;
160  fromIce(iceTimestamp, timestamp);
161 
162  // convert to our aron type
163  const auto toHumanPose = [](const ::armarx::aron::data::dto::DictPtr& dict)
164  { return armarx::human::arondto::HumanPose::FromAron(dict); };
165 
166  std::vector<armarx::human::arondto::HumanPose> humanPoses =
167  simox::alg::apply(dictSeq, toHumanPose);
168 
169  // synchronize robot
170  const std::string robotName =
171  humanPoses.front().keypoints.begin()->second.positionCamera.header.agent;
172 
173  const auto robot = getSynchronizedRobot(robotName, timestamp);
174 
175  if (not robot)
176  {
177  ARMARX_INFO << deactivateSpam(1) << "Failed to obtain robot `" << robotName
178  << "`. Won't commit poses";
179  return;
180  }
181 
182  ARMARX_CHECK_NOT_NULL(robot) << "Failed to obtain robot with name `" << robotName << "`.";
183 
184  // fill global pose info
185  {
186  for (armarx::human::arondto::HumanPose& humanPose : humanPoses)
187  {
188  for (auto& [_, keyPoint] : humanPose.keypoints)
189  {
190  const auto& cameraFrame = keyPoint.positionCamera.header.frame;
191  const auto& agent = keyPoint.positionCamera.header.agent;
192 
193  const FramedPosition keypoint(
194  keyPoint.positionCamera.position, cameraFrame, agent);
195  // ARMARX_IMPORTANT << VAROUT(keyPoint.positionCamera.position.transpose());
196 
197  // global pose
198  {
199  keyPoint.positionGlobal = armarx::arondto::FramedPosition();
200  armarx::toAron(keyPoint.positionGlobal.value(),
201  armarx::FramedPosition(keypoint.toGlobalEigen(robot),
203  agent));
204  }
205 
206  // pose in root frame
207  {
208  keyPoint.positionRobot = armarx::arondto::FramedPosition();
209  armarx::toAron(keyPoint.positionRobot.value(),
210  armarx::FramedPosition(keypoint.toRootEigen(robot),
211  robot->getRootNode()->getName(),
212  agent));
213  }
214 
215  // Orientation information available.
216  if (keyPoint.orientationCamera.has_value())
217  {
218  ARMARX_CHECK_EQUAL(keyPoint.orientationCamera->header.frame,
219  keyPoint.positionCamera.header.frame);
220 
221  const FramedPose keypointPose(
222  keyPoint.orientationCamera->orientation.toRotationMatrix(),
223  keyPoint.positionCamera.position,
224  cameraFrame,
225  agent);
226 
227  // global pose
228  {
229  const Eigen::Isometry3f global_T_human(
230  keypointPose.toGlobalEigen(robot));
231 
232  keyPoint.orientationGlobal = armarx::arondto::FramedOrientation();
233 
235  keyPoint.orientationGlobal.value(),
236  armarx::FramedOrientation(Eigen::Matrix3f{global_T_human.linear()},
238  agent));
239  }
240 
241  // pose in root frame
242  {
243  const Eigen::Isometry3f robot_root_T_human(
244  keypointPose.toRootEigen(robot));
245 
246 
247  keyPoint.orientationRobot = armarx::arondto::FramedOrientation();
248 
249  armarx::toAron(keyPoint.orientationRobot.value(),
251  Eigen::Matrix3f{robot_root_T_human.linear()},
252  robot->getRootNode()->getName(),
253  agent));
254  }
255  }
256  }
257  }
258  }
259 
260  // commit human poses
261  commitHumanPoses(humanPoses, providerName, timestamp);
262  }
263 
264  void
266  const std::vector<::armarx::human::arondto::HumanPose>& humanPoses,
267  const std::string& providerName,
268  const armarx::DateTime& timestamp)
269  {
271 
272  const auto providerId = armem::MemoryID(
273  workingMemory().name(), human::PoseSegment::CORE_SEGMENT_NAME, providerName);
274  const auto entityID = providerId.withEntityName("human_poses").withTimestamp(timestamp);
275 
277  update.entityID = entityID;
278  update.sentTime = timestamp; // TODO this is not fully correct
279  update.referencedTime = timestamp;
280 
282  humanPoses.begin(),
283  humanPoses.end(),
284  std::back_inserter(update.instancesData),
285  [](const ::armarx::human::arondto::HumanPose& humanPose) -> armarx::aron::data::DictPtr
286  { return humanPose.toAron(); });
287 
288  commit.add(update);
289 
290  ARMARX_DEBUG << "Committing " << update << " at time " << timestamp;
291 
293  }
294 } // namespace armarx::armem::server::human_memory
armarx::armem::server::human::PersonInstanceSegment::defineProperties
virtual void defineProperties(armarx::PropertyDefinitionsPtr defs, const std::string &prefix="") override
Definition: PersonInstanceSegment.cpp:45
armarx::armem::server::human::Visu::connect
void connect(const viz::Client &arviz, DebugObserverInterfacePrx debugObserver=nullptr)
Definition: Visualization.cpp:53
armarx::armem::Commit
A bundle of updates to be sent to the memory.
Definition: Commit.h:84
framed.h
armarx::FramedPose
The FramedPose class.
Definition: FramedPose.h:280
armarx::armem::server::human::PoseSegment::CORE_SEGMENT_NAME
static const std::string CORE_SEGMENT_NAME
Definition: PoseSegment.h:50
DateTime.h
ARMARX_CHECK_NOT_NULL
#define ARMARX_CHECK_NOT_NULL(ptr)
This macro evaluates whether ptr is not null and if it turns out to be false it will throw an Express...
Definition: ExpressionException.h:206
armarx::GlobalFrame
const std::string GlobalFrame
Definition: FramedPose.h:65
armarx::armem::server::human_memory::HumanMemory::getDefaultName
std::string getDefaultName() const override
Retrieve default name of component.
Definition: HumanMemory.cpp:77
armarx::armem::server::human::facerecog::Segment::init
void init() override
Definition: Segment.cpp:58
armarx::armem::server::plugins::ReadWritePluginUser::setMemoryName
void setMemoryName(const std::string &memoryName)
Definition: ReadWritePluginUser.cpp:25
ice_conversions.h
armarx::ManagedIceObject::addPlugin
PluginT * addPlugin(const std::string prefix="", ParamsT &&... params)
Definition: ManagedIceObject.h:186
HumanMemory.h
armarx::DebugObserverComponentPluginUser::getDebugObserver
const DebugObserverInterfacePrx & getDebugObserver() const
Definition: DebugObserverComponentPlugin.cpp:123
armarx::FramedPosition::toRootEigen
Eigen::Vector3f toRootEigen(const SharedRobotInterfacePrx &referenceRobot) const
Definition: FramedPose.cpp:924
armarx::armem::server::plugins::ReadWritePluginUser::workingMemory
server::wm::Memory & workingMemory()
Definition: ReadWritePluginUser.cpp:106
armarx::FramedPosition::toGlobalEigen
Eigen::Vector3f toGlobalEigen(const SharedRobotInterfacePrx &referenceRobot) const
Definition: FramedPose.cpp:880
armarx::armem::server::human_memory
Definition: ComponentInterface.ice:13
armarx::armem::server::human::profile::Segment::init
void init() override
Definition: Segment.cpp:68
armarx::armem::server::human::Visu::init
void init()
Definition: Visualization.cpp:47
memory_definitions.h
armarx::armem::server::human_memory::HumanMemory::onExitComponent
void onExitComponent() override
Hook for subclass.
Definition: HumanMemory.cpp:107
armarx::armem::server::human_memory::HumanMemory::getSynchronizedRobot
VirtualRobot::RobotPtr getSynchronizedRobot(const std::string &robotName, const armarx::DateTime &timestamp)
Definition: HumanMemory.cpp:112
armarx::FramedPose::toGlobalEigen
Eigen::Matrix4f toGlobalEigen(const SharedRobotInterfacePrx &referenceRobot) const
Definition: FramedPose.cpp:598
PoseSegment.h
FramedPose.h
armarx::armem::server::human_memory::HumanMemory::createPropertyDefinitions
armarx::PropertyDefinitionsPtr createPropertyDefinitions() override
Definition: HumanMemory.cpp:49
armarx::armem::server::segment::SpecializedCoreSegment::init
virtual void init() override
Definition: SpecializedCoreSegment.cpp:47
ARMARX_DEBUG
#define ARMARX_DEBUG
Definition: Logging.h:184
armarx::FramedPosition
The FramedPosition class.
Definition: FramedPose.h:157
armarx::armem::EntityUpdate
An update of an entity for a specific point in time.
Definition: Commit.h:25
ice_conversions.h
armarx::armem::base::MemoryBase::addCoreSegment
CoreSegmentT & addCoreSegment(const std::string &name, aron::type::ObjectPtr coreSegmentType=nullptr, const std::vector< PredictionEngine > &predictionEngines={})
Add an empty core segment with the given name, type and prediction engines.
Definition: MemoryBase.h:259
armarx::armem::server::plugins::ReadWritePluginUser::iceAdapter
MemoryToIceAdapter & iceAdapter()
Definition: ReadWritePluginUser.cpp:112
armarx::armem::server::human::profile::Segment::defineProperties
void defineProperties(armarx::PropertyDefinitionsPtr defs, const std::string &prefix="") override
Definition: Segment.cpp:56
armarx::FramedOrientation
The FramedOrientation class.
Definition: FramedPose.h:215
armarx::armem::server::human_memory::HumanMemory::onInitComponent
void onInitComponent() override
Pure virtual hook for the subclass.
Definition: HumanMemory.cpp:83
armarx::armem::fromIce
void fromIce(const data::MemoryID &ice, MemoryID &id)
Definition: ice_conversions.cpp:31
armarx::armem::server::human::PoseSegment::defineProperties
virtual void defineProperties(armarx::PropertyDefinitionsPtr defs, const std::string &prefix="") override
Definition: PoseSegment.cpp:44
armarx::armem::server::ltm::util::mongodb::detail::update
bool update(mongocxx::collection &coll, const nlohmann::json &query, const nlohmann::json &update)
Definition: mongodb.cpp:68
MemoryToIceAdapter.h
armarx::FramedPose::toRootEigen
Eigen::Matrix4f toRootEigen(const SharedRobotInterfacePrx &referenceRobot) const
Definition: FramedPose.cpp:642
armarx::transform
auto transform(const Container< InputT, Alloc > &in, OutputT(*func)(InputT const &)) -> Container< OutputT, typename std::allocator_traits< Alloc >::template rebind_alloc< OutputT >>
Convenience function (with less typing) to transform a container of type InputT into the same contain...
Definition: algorithm.h:351
armarx::armem::server::plugins::ReadWritePluginUser::commit
virtual data::CommitResult commit(const data::Commit &commit, const Ice::Current &=Ice::emptyCurrent) override
Definition: ReadWritePluginUser.cpp:48
armarx::core::time::DateTime
Represents a point in time.
Definition: DateTime.h:24
armarx::aron::data::DictPtr
std::shared_ptr< Dict > DictPtr
Definition: Dict.h:41
armarx::armem::server::human_memory::HumanMemory::onDisconnectComponent
void onDisconnectComponent() override
Hook for subclass.
Definition: HumanMemory.cpp:102
armarx::Component::getConfigIdentifier
std::string getConfigIdentifier()
Retrieve config identifier for this component as set in constructor.
Definition: Component.cpp:79
armarx::armem::server::human::facerecog::Segment::defineProperties
void defineProperties(armarx::PropertyDefinitionsPtr defs, const std::string &prefix="") override
Definition: Segment.cpp:49
armarx::VariantType::FramedOrientation
const VariantTypeId FramedOrientation
Definition: FramedPose.h:39
armarx::ComponentPropertyDefinitions
Default component property definition container.
Definition: Component.h:69
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:181
armarx::ArVizComponentPluginUser::arviz
armarx::viz::Client arviz
Definition: ArVizComponentPlugin.h:42
IceUtil::Handle
Definition: forward_declarations.h:30
armarx::Logging::deactivateSpam
SpamFilterDataPtr deactivateSpam(float deactivationDurationSec=10.0f, const std::string &identifier="", bool deactivate=true) const
disables the logging for the current line for the given amount of seconds.
Definition: Logging.cpp:99
armarx::armem::server::human::IdentificationSegment::defineProperties
virtual void defineProperties(armarx::PropertyDefinitionsPtr defs, const std::string &prefix="") override
Definition: IdentificationSegment.cpp:41
armarx::toAron
void toAron(arondto::PackagePath &dto, const PackageFileLocation &bo)
GfxTL::Matrix3f
MatrixXX< 3, 3, float > Matrix3f
Definition: MatrixXX.h:649
armarx::VariantType::FramedPosition
const VariantTypeId FramedPosition
Definition: FramedPose.h:38
ARMARX_CHECK_EQUAL
#define ARMARX_CHECK_EQUAL(lhs, rhs)
This macro evaluates whether lhs is equal (==) rhs and if it turns out to be false it will throw an E...
Definition: ExpressionException.h:130
armarx::armem::server::human_memory::HumanMemory::onConnectComponent
void onConnectComponent() override
Pure virtual hook for the subclass.
Definition: HumanMemory.cpp:96
armarx::armem::server::human_memory::HumanMemory::HumanMemory
HumanMemory()
Definition: HumanMemory.cpp:65
armarx::armem::server::MemoryToIceAdapter::commitLocking
data::CommitResult commitLocking(const data::Commit &commitIce, Time timeArrived)
Definition: MemoryToIceAdapter.cpp:166
armarx::status::success
@ success
VirtualRobot::RobotPtr
std::shared_ptr< class Robot > RobotPtr
Definition: Bus.h:19
armarx::armem::server::human_memory::HumanMemory::commitHumanPoses
void commitHumanPoses(const std::vector<::armarx::human::arondto::HumanPose > &humanPoses, const std::string &providerName, const armarx::DateTime &timestamp)
Definition: HumanMemory.cpp:265
armarx::armem::server::human_memory::HumanMemory::commitHumanPosesInCameraFrame
void commitHumanPosesInCameraFrame(const ::armarx::aron::data::dto::AronDictSeq &dictSeq, const ::std::string &providerName, const ::armarx::core::time::dto::DateTime &timestamp, const ::Ice::Current &=::Ice::emptyCurrent) override
Definition: HumanMemory.cpp:147
armarx::human::MemoryID
const armem::MemoryID MemoryID
Definition: memory_ids.cpp:28