ArticulatedObjectLocalizerDynamicSimulation.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 ArmarXSimulation::ArmarXObjects::ArticulatedObjectLocalizerDynamicSimulation
17 * @author Fabian Reister ( fabian dot reister at kit dot edu )
18 * @date 2021
19 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20 * GNU General Public License
21 */
22
24
25// Include headers you only need in function definitions in the .cpp.
26#include <algorithm>
27#include <mutex>
28
29#include <Eigen/Core>
30
31#include <SimoxUtility/algorithm/string/string_tools.h>
32#include <VirtualRobot/Robot.h>
33#include <VirtualRobot/VirtualRobot.h>
34#include <VirtualRobot/XML/RobotIO.h>
35
38
40
41namespace armarx
42{
43
46 {
49
50 defs->component(simulator);
51
52 defs->optional(p.cycleTime, "cycleTime");
53 defs->optional(p.cycleTimeUpdateObjectsInSimulator, "cycleTimeUpdateObjectList");
54 defs->optional(p.objects, "objects", "The objects to (fake) localize.");
55
56 return defs;
57 }
58
60 {
61 addPlugin(articulatedObjectWriterPlugin);
62 addPlugin(articulatedObjectReaderPlugin);
63 }
64
65 void
69
70 void
72 {
74
75 ARMARX_INFO << "Starting `localizeArticulatedObjects` task";
77 this,
79 p.cycleTime,
80 false,
81 "localizeArticulatedObjects");
82 task->start();
83 task->setDelayWarningTolerance(100);
84
85 ARMARX_INFO << "Starting `setupObjects` task";
87 this,
89 p.cycleTimeUpdateObjectsInSimulator,
90 false,
91 "setupObjects");
92 taskUpdateObjects->start();
93 taskUpdateObjects->setDelayWarningTolerance(100);
94 }
95
96 void
101
102 void
106
107 std::string
109 {
110 return "ArticulatedObjectLocalizerDynamicSimulation";
111 }
112
113 void
115 {
116 const auto descriptions = articulatedObjectReaderPlugin->get().queryDescriptions(
117 armarx::DateTime::Now(), std::nullopt);
118
119 std::unordered_map<std::string, std::shared_ptr<VirtualRobot::Robot>> newKnownObjects;
120
121 // read access to shared variable "knownObjects"
122 std::unique_lock lck{knownObjectsMtx};
123 std::unordered_map<std::string, std::shared_ptr<VirtualRobot::Robot>> oldKnownObjects =
124 knownObjects;
125 lck.unlock();
126
127 const auto tryRegister = [&](const std::string& name)
128 {
129 ARMARX_DEBUG << "Checking element '" << name << "' ...";
130
131 const auto isKnownObject = [&name, this](const auto description) -> bool
132 {
133 if (description.name == name)
134 {
135 return true;
136 }
137
138 const auto splits = simox::alg::split(description.name, "/");
139 if (not splits.empty())
140 {
141 if (splits.back() == name)
142 {
143 ARMARX_DEBUG << "Relaxed filter successful: Object description '"
144 << description.name << "' matches '" << name;
145 return true;
146 }
147 }
148
149 return false;
150 };
151
152 const auto it = std::find_if(descriptions.begin(), descriptions.end(), isKnownObject);
153 if (it == descriptions.end())
154 {
155 ARMARX_DEBUG << "Element '" << name << "' is either a robot or an unknown object";
156 return;
157 }
158
159 ARMARX_DEBUG << "Found articulated object '" << name << "'";
160
161 // Avoid loading of already existing robots as it takes some time ...
162 if (oldKnownObjects.count(name) > 0)
163 {
164 newKnownObjects[name] = oldKnownObjects.at(name);
165 return;
166 }
167
168 // New robot. Load it.
169 const auto robot = VirtualRobot::RobotIO::loadRobot(
170 ArmarXDataPath::resolvePath(it->xml.serialize().path),
171 VirtualRobot::RobotIO::eStructure);
172
173 if (robot)
174 {
175 ARMARX_CHECK(newKnownObjects.count(name) == 0)
176 << "At the moment, only one object per class supported.";
177 robot->setName(robot->getName() +
178 "/0"); // mark object as instance '0', similar to scene snapshot
179 newKnownObjects[name] = robot;
180 }
181 };
182
183 // robots can be either active or passive
184 const auto robots = simulator->getRobotNames();
185 std::for_each(robots.begin(), robots.end(), tryRegister);
186
187 {
188 std::lock_guard g{knownObjectsMtx};
189 knownObjects = newKnownObjects;
190 }
191 }
192
194 convert(const VirtualRobot::Robot& obj, const armem::Time& timestamp)
195 {
196 ARMARX_DEBUG << "Filename is " << obj.getFilename();
197
199 .description = {.name = obj.getType(),
201 {"PriorKnowledgeData"}, obj.getFilename()),
202 obj.getFilename()),
203 .visualization = {},
204 .info = {}},
205 .instance = "", // TODO(fabian.reister):
206 .config =
207 {
208 .timestamp = timestamp,
209 .globalPose = Eigen::Isometry3f(obj.getRootNode()->getGlobalPose()),
210 .jointMap = obj.getJointValues(),
211 .proprioception = std::nullopt,
212 },
213 .timestamp = timestamp,
214 };
215 }
216
217 void
219 {
220 // remove objects if the no longer exist in the scene
221 // knownObjects.erase(std::remove_if(knownObjects.begin(), knownObjects.end(), [&](const auto&p) -> bool{
222 // const auto& name = p.first;
223 // if(not simulator->hasRobot(name))
224 // {
225 // ARMARX_INFO << "Articulated object '" << name << "' was removed from the scene.";
226 // return true;
227 // }
228
229 // return false;
230 // }), knownObjects.end());
231 std::lock_guard g{knownObjectsMtx};
232
233 for (const auto& [name, robot] : knownObjects)
234 {
235 // it is possible that the object is no longer in the scene
236 const PoseBasePtr poseBase = [this, &name]() -> PoseBasePtr
237 {
238 try
239 {
240 const auto robotPose = simulator->getRobotPose(name);
241 return robotPose;
242 }
243 catch (...)
244 {
245 return nullptr;
246 }
247 }();
248
249
250 if (not poseBase)
251 {
253 << "No articulatd object pose from simulator for object " << name
254 << " ...";
255 continue;
256 }
257
258 robot->setGlobalPose(PosePtr::dynamicCast(poseBase)->toEigen());
259
260 const auto jointMap = simulator->getRobotJointAngles(name);
261 robot->setJointValues(jointMap);
262
265 obj.instance =
266 static_cast<std::string>("0"); // we assume that there is only one object of a type
267
268 ARMARX_DEBUG << "Publishing new state for object `" << name << "`, instance id: `"
269 << obj.instance << "`";
270
271 articulatedObjectWriterPlugin->get().store(obj, true);
272 }
273 }
274
275
276} // namespace armarx
std::string timestamp()
static std::string getProject(const std::vector< std::string > &projects, const std::string &relativeFilename)
static std::string resolvePath(const std::string &path, bool verbose=true)
Resolves environment variables and home paths and tries to make path absolute.
Default component property definition container.
Definition Component.h:70
std::string getConfigIdentifier()
Retrieve config identifier for this component as set in constructor.
Definition Component.cpp:90
static DateTime Now()
Definition DateTime.cpp:51
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
PluginT * addPlugin(const std::string prefix="", ParamsT &&... params)
The periodic task executes one thread method repeatedly using the time period specified in the constr...
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_DEBUG
The logging level for output that is only interesting while debugging.
Definition Logging.h:184
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:193
armarx::armem::robot_state::Robot ArticulatedObject
Definition types.h:140
armarx::core::time::DateTime Time
This file offers overloads of toIce() and fromIce() functions for STL container types.
armem::articulated_object::ArticulatedObject convert(const VirtualRobot::Robot &obj, const armem::Time &timestamp)
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
Eigen::Vector3f toEigen(const pcl::PointXYZ &pt)