WorkingMemoryObjectPoseProvider.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 MemoryX::ArmarXObjects::WorkingMemoryObjectPoseProvider
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 
24 
25 #include <SimoxUtility/algorithm/string.h>
26 #include <SimoxUtility/json.h>
27 #include <VirtualRobot/CollisionDetection/CollisionModel.h>
28 #include <VirtualRobot/ManipulationObject.h>
29 
34 
39 
42 
43 void
44 memoryx::to_json(nlohmann::json& j, const Config& config)
45 {
46  j["objectNames"] = config.objectNames;
47 }
48 
49 void
50 memoryx::from_json(const nlohmann::json& j, Config& config)
51 {
52  j.at("objectNames").get_to(config.objectNames);
53 }
54 
55 namespace memoryx
56 {
57 
60  {
63 
64  defs->component(workingMemory);
65  defs->component(robotStateComponent);
66  defs->component(priorKnowledge);
67 
68  defs->optional(updateFrequency, "UpdateFrequency", "Target number of updates per second.");
69  defs->optional(configFile, "ConfigFile", "Path to the config file.");
70  defs->optional(loadObjectDatasetsStr,
71  "LoadDatasets",
72  "Only load the files for the following datasets, separated by ;. Load all "
73  "if input is empty.");
74 
75  return defs;
76  }
77 
78  std::string
80  {
81  return "WorkingMemoryObjectPoseProvider";
82  }
83 
84  void
86  {
87  configFile = armarx::ArmarXDataPath::resolvePath(configFile);
88  ARMARX_INFO << "Loading config file '" << configFile << "' ...";
89  if (std::filesystem::is_regular_file(configFile))
90  {
91  const nlohmann::json j = nlohmann::read_json(configFile);
92  j.get_to(config);
93  }
94  else
95  {
96  ARMARX_INFO << "No config file at '" << configFile << "'";
97  }
98  }
99 
100  void
102  {
103  ARMARX_CHECK_NOT_NULL(workingMemory);
104  ARMARX_CHECK_NOT_NULL(robotStateComponent);
105  ARMARX_CHECK_NOT_NULL(priorKnowledge);
106 
107  ARMARX_IMPORTANT << "Loading workingmemory and priorknowledge entites and files. This may "
108  "take a while....";
109  attachments.initFromProxies(workingMemory, robotStateComponent);
110 
111  std::vector<std::string> loadDatasets = simox::alg::split(loadObjectDatasetsStr, ";");
112 
113  objectClassSegment.initFromProxy(priorKnowledge, loadDatasets);
114  ARMARX_IMPORTANT << "... done loading!";
115 
116  // A periodic task logs an important info when the cycle time is not met.
117  // To avoid this, we use a running task.
118  task = new armarx::SimpleRunningTask<>(
119  [this]()
120  {
121  armarx::CycleUtil cycle(int(1000 / updateFrequency));
122 
123  while (task && !task->isStopped())
124  {
125  provideObjectInstancesPoses();
126  cycle.waitForCycleDuration();
127  }
128  });
129 
130  task->start();
131  }
132 
133  void
135  {
136  if (task)
137  {
138  task->stop();
139  }
140  }
141 
142  void
144  {
145  }
146 
147  void
148  WorkingMemoryObjectPoseProvider::provideObjectInstancesPoses()
149  {
150  std::scoped_lock lock(mutex);
151  std::vector<ObjectInstancePtr> instances = attachments.queryObjects();
152  provideObjectInstancesPoses(instances);
153  }
154 
155  void
156  WorkingMemoryObjectPoseProvider::provideObjectInstancesPoses(
157  const std::vector<ObjectInstancePtr>& objectInstances)
158  {
160 
161  for (const auto& instance : objectInstances)
162  {
163  objectPoses.push_back(toProvidedObjectPose(instance).toIce());
164  }
165 
166  objectPoseTopic->reportObjectPoses(getName(), objectPoses);
167  }
168 
170  WorkingMemoryObjectPoseProvider::toProvidedObjectPose(const ObjectInstancePtr& instance)
171  {
173 
174  pose.objectType = armarx::objpose::KnownObject;
175  std::string className = instance->getMostProbableClass();
176  if (auto it = config.objectNames.find(className); it != config.objectNames.end())
177  {
178  ARMARX_VERBOSE << deactivateSpam(60) << "Replacing class '" << className << "' by '"
179  << it->second << "'";
180  className = it->second;
181  }
182  pose.objectID = armarx::ObjectID(className);
183  pose.objectID.setInstanceName(instance->getId());
184 
185  pose.objectPose = instance->getPose()->toEigen();
186  pose.objectPoseFrame = instance->getPose()->getFrame();
187  if (pose.objectPoseFrame.empty())
188  {
190  }
191 
192  pose.confidence = instance->getExistenceCertainty();
193  if (instance->hasLocalizationTimestamp())
194  {
195  fromIce(instance->getLocalizationTimestamp(), pose.timestamp);
196  }
197  else
198  {
200  }
201 
202  std::optional<ObjectClassWrapper> objectClass = objectClassSegment.getClass(className);
203  //ARMARX_IMPORTANT << "Looking for class: " << className;
204  if (objectClass)
205  {
206  VirtualRobot::CollisionModelPtr collisionModel =
207  objectClass->manipulationObject->getCollisionModel();
208  VirtualRobot::BoundingBox bb = collisionModel->getBoundingBox(false);
209  Eigen::Vector3f bbMin = bb.getMin();
210  Eigen::Vector3f bbMax = bb.getMax();
211  Eigen::Vector3f extents = bbMax - bbMin;
212  //ARMARX_IMPORTANT << "Bounding box: " << extents.transpose();
213 
214  pose.localOOBB = simox::OrientedBoxf(
215  (0.5 * (bbMin + bbMax)).eval(), Eigen::Quaternionf::Identity(), extents);
216  }
217 
218  pose.providerName = getName();
219 
220  return pose;
221  }
222 
223  armarx::objpose::ProviderInfo
225  {
226  armarx::objpose::ProviderInfo info;
227 
228  return info;
229  }
230 
231  void
233  const AttachObjectToRobotNodeInput& attachment,
234  const Ice::Current&)
235  {
236  std::scoped_lock lock(mutex);
237  attachments.attachObjectToRobotNode(attachment);
238  }
239 
240  void
242  const DetachObjectFromRobotNodeInput& detachment,
243  const Ice::Current&)
244  {
245  std::scoped_lock lock(mutex);
246  attachments.detachObjectFromRobotNode(detachment);
247  }
248 
249 } // namespace memoryx
armarx::ArmarXDataPath::resolvePath
static std::string resolvePath(const std::string &path, bool verbose=true)
Resolves environment variables and home paths and tries to make path absolute.
Definition: ArmarXDataPath.cpp:538
memoryx::from_json
void from_json(const nlohmann::json &j, Config &config)
Definition: WorkingMemoryObjectPoseProvider.cpp:50
armarx::SimpleRunningTask
Usage:
Definition: TaskUtil.h:85
ARMARX_VERBOSE
#define ARMARX_VERBOSE
Definition: Logging.h:187
memoryx::Config::objectNames
std::map< std::string, std::string > objectNames
Definition: WorkingMemoryObjectPoseProvider.h:45
ice_conversions.h
armarx::objpose::ProvidedObjectPose::objectID
armarx::ObjectID objectID
The object ID, i.e. dataset, class name and instance name.
Definition: ProvidedObjectPose.h:44
memoryx::WorkingMemoryObjectPoseProvider::getProviderInfo
armarx::objpose::ProviderInfo getProviderInfo(const Ice::Current &=Ice::emptyCurrent) override
Definition: WorkingMemoryObjectPoseProvider.cpp:224
ARMARX_IMPORTANT
#define ARMARX_IMPORTANT
Definition: Logging.h:190
memoryx::ObjectInstanceToRobotNodeAttachments::attachObjectToRobotNode
void attachObjectToRobotNode(const memoryx::AttachObjectToRobotNodeInput &attachment)
Definition: ObjectInstanceToRobotNodeAttachments.cpp:33
armarx::armem::attachment::ObjectID
armem::MemoryID ObjectID
Definition: types.h:79
armarx::core::time::DateTime::Now
static DateTime Now()
Definition: DateTime.cpp:51
Pose.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::CycleUtil
This util class helps with keeping a cycle time during a control cycle.
Definition: CycleUtil.h:40
memoryx
VirtualRobot headers.
Definition: CommonPlacesTester.cpp:48
ice_conversions.h
memoryx::ObjectClassSegmentWrapper::getClass
std::optional< ObjectClassWrapper > getClass(std::string const &className) const
Definition: ObjectClassSegmentWrapper.cpp:68
armarx::objpose::ProvidedObjectPose::objectPoseFrame
std::string objectPoseFrame
Definition: ProvidedObjectPose.h:47
memoryx::Config
Definition: WorkingMemoryObjectPoseProvider.h:43
memoryx::ObjectInstanceToRobotNodeAttachments::detachObjectFromRobotNode
void detachObjectFromRobotNode(const memoryx::DetachObjectFromRobotNodeInput &detachment)
Definition: ObjectInstanceToRobotNodeAttachments.cpp:64
memoryx::WorkingMemoryObjectPoseProvider::createPropertyDefinitions
armarx::PropertyDefinitionsPtr createPropertyDefinitions() override
Definition: WorkingMemoryObjectPoseProvider.cpp:59
GfxTL::Identity
void Identity(MatrixXX< N, N, T > *a)
Definition: MatrixXX.h:570
memoryx::WorkingMemoryObjectPoseProvider::onInitComponent
void onInitComponent() override
Definition: WorkingMemoryObjectPoseProvider.cpp:85
armarx::core::eigen::fromIce
void fromIce(Eigen::Vector2f &e, const Ice::FloatSeq &ice)
Definition: ice_conversions.cpp:10
memoryx::ObjectClassSegmentWrapper::initFromProxy
void initFromProxy(memoryx::PriorKnowledgeInterfacePrx const &priorKnowledge, const std::vector< std::string > &datasets)
Definition: ObjectClassSegmentWrapper.cpp:16
ObjectID.h
memoryx::to_json
void to_json(nlohmann::json &j, const Config &config)
Definition: WorkingMemoryObjectPoseProvider.cpp:44
memoryx::ObjectInstancePtr
IceInternal::Handle< ObjectInstance > ObjectInstancePtr
Definition: ObjectInstance.h:43
armarx::ObjectPoseProviderPluginUser::objectPoseTopic
objpose::ObjectPoseStorageInterfacePrx objectPoseTopic
Definition: ObjectPoseProviderPlugin.h:50
memoryx::ObjectInstanceToRobotNodeAttachments::initFromProxies
void initFromProxies(const WorkingMemoryInterfacePrx &workingMemory, const armarx::RobotStateComponentInterfacePrx &robotStateComponent)
Set the proxies.
Definition: ObjectInstanceToRobotNodeAttachments.cpp:19
MemoryXCoreObjectFactories.h
armarx::CycleUtil::waitForCycleDuration
IceUtil::Time waitForCycleDuration()
This function will wait (virtual or system time) until the cycle time is reached.
Definition: CycleUtil.cpp:53
armarx::objpose::ProvidedObjectPose::providerName
std::string providerName
Name of the providing component.
Definition: ProvidedObjectPose.h:37
WorkingMemoryObjectPoseProvider.h
armarx::core::eigen::toIce
void toIce(const Eigen::Vector2f &e, Ice::FloatSeq &ice)
Definition: ice_conversions.cpp:17
memoryx::WorkingMemoryObjectPoseProvider::onConnectComponent
void onConnectComponent() override
Definition: WorkingMemoryObjectPoseProvider.cpp:101
armarx::objpose::ProvidedObjectPoseSeq
std::vector< ProvidedObjectPose > ProvidedObjectPoseSeq
Definition: forward_declarations.h:25
memoryx::WorkingMemoryObjectPoseProvider::onDisconnectComponent
void onDisconnectComponent() override
Definition: WorkingMemoryObjectPoseProvider.cpp:134
CycleUtil.h
armarx::objpose::ProvidedObjectPose
An object pose provided by an ObjectPoseProvider.
Definition: ProvidedObjectPose.h:24
armarx::Component::getConfigIdentifier
std::string getConfigIdentifier()
Retrieve config identifier for this component as set in constructor.
Definition: Component.cpp:79
armarx::objpose::ProvidedObjectPose::objectType
ObjectType objectType
Known or unknown object.
Definition: ProvidedObjectPose.h:39
ObjectInstance.h
ProvidedObjectPose.h
armarx::ComponentPropertyDefinitions
Default component property definition container.
Definition: Component.h:69
TimeUtil.h
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:181
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::objpose::ProvidedObjectPose::localOOBB
std::optional< simox::OrientedBoxf > localOOBB
Object bounding box in object's local coordinate frame.
Definition: ProvidedObjectPose.h:61
memoryx::WorkingMemoryObjectPoseProvider::detachObjectFromRobotNode
void detachObjectFromRobotNode(const DetachObjectFromRobotNodeInput &detachment, const Ice::Current &) override
Definition: WorkingMemoryObjectPoseProvider.cpp:241
armarx::ManagedIceObject::getName
std::string getName() const
Retrieve name of object.
Definition: ManagedIceObject.cpp:108
memoryx::ObjectInstanceToRobotNodeAttachments::queryObjects
std::vector< ObjectInstancePtr > queryObjects()
Get all entities from objectInstanceSegment and cast them to ObjectInstance.
Definition: ObjectInstanceToRobotNodeAttachments.cpp:88
armarx::objpose::ProvidedObjectPose::confidence
float confidence
Confidence in [0, 1] (1 = full, 0 = none).
Definition: ProvidedObjectPose.h:55
memoryx::WorkingMemoryObjectPoseProvider::attachObjectToRobotNode
void attachObjectToRobotNode(const AttachObjectToRobotNodeInput &attachment, const Ice::Current &) override
Definition: WorkingMemoryObjectPoseProvider.cpp:232
armarx::objpose::ProvidedObjectPose::timestamp
DateTime timestamp
Source timestamp.
Definition: ProvidedObjectPose.h:57
memoryx::WorkingMemoryObjectPoseProvider::getDefaultName
std::string getDefaultName() const override
Definition: WorkingMemoryObjectPoseProvider.cpp:79
memoryx::WorkingMemoryObjectPoseProvider::onExitComponent
void onExitComponent() override
Definition: WorkingMemoryObjectPoseProvider.cpp:143
ArmarXDataPath.h
armarx::objpose::ProvidedObjectPose::objectPose
Eigen::Matrix4f objectPose
Definition: ProvidedObjectPose.h:46
armarx::split
std::vector< std::string > split(const std::string &source, const std::string &splitBy, bool trimElements=false, bool removeEmptyElements=false)
Definition: StringHelpers.cpp:38
armarx::ObjectID::setInstanceName
void setInstanceName(const std::string &instanceName)
Definition: ObjectID.h:42