26#include <experimental/map>
28#include <SimoxUtility/algorithm/string.h>
37#include <range/v3/range/conversion.hpp>
38#include <range/v3/view/filter.hpp>
39#include <range/v3/view/transform.hpp>
43 const std::string SimulationObjectPoseProvider::defaultName =
"SimulationObjectPoseProvider";
57 def->component(simulatorPrx,
"Simulator");
59 def->optional(properties.updateFrequency,
61 "Frequency at which to update the objects in the ObjectMemory.");
63 def->optional(properties.requestAllEntities,
64 "p.requestAllEntities",
65 "True if all entities should be requested all the time.");
67 def->optional(properties.initiallyRequestedEntities,
68 "p.initiallyRequestedEntities",
69 "All entities (comma separated) that should be requested from the beginning "
70 "(e.g. 'Kitchen/multivitamin-juice/0'). "
71 "If you want an entity to be localized for n seconds append ':n'. If you "
72 "want to see all active entities, set the component to DEBUG.");
87 for (
const auto& entity : simox::alg::split(properties.initiallyRequestedEntities,
","))
89 const auto tokens = simox::alg::split(entity,
":");
93 <<
"Could not use multiple durations for localization request '" << entity <<
"'";
95 const auto& objectName = tokens[0];
99 const auto until = tokens.size() == 1
103 activeRequests.insert({objectName, until});
113 poseProviderTask->start();
129 return SimulationObjectPoseProvider::defaultName;
135 return SimulationObjectPoseProvider::defaultName;
138 objpose::provider::RequestObjectsOutput
140 const objpose::provider::RequestObjectsInput& input,
141 const Ice::Current& )
143 if (properties.requestAllEntities)
146 "Requesting an object does not have an effect.";
150 const std::lock_guard l(knownObjectsMutex);
151 const std::lock_guard l2(activeRequestsMutex);
155 objpose::provider::RequestObjectsOutput output;
156 for (
const auto&
id : input.objectIDs)
158 const std::string entityId =
id.dataset +
"/" +
id.className +
"/" +
id.instanceName;
159 if (knownObjects.find(entityId) != knownObjects.end())
161 if (activeRequests.find(entityId) != activeRequests.end())
164 <<
"' is already requested. Updating the request time.";
166 activeRequests[entityId] =
168 output.results[id].success =
true;
172 std::vector<std::string> allNames;
173 allNames.reserve(knownObjects.size());
174 for (
const auto& [name, _] : knownObjects)
176 allNames.push_back(name);
179 <<
"'. All known objects are: " << allNames;
180 output.results[id].success =
false;
186 objpose::ProviderInfo
189 objpose::ProviderInfo info;
190 info.objectType = objpose::KnownObject;
192 info.supportedObjects = {};
197 SimulationObjectPoseProvider::poseProviderTaskRun()
201 while (poseProviderTask and not poseProviderTask->
isStopped())
203 metronome.waitForNextTick();
207 armarx::SceneVisuData sceneData;
210 sceneData = simulatorPrx->getScene();
211 for (
const auto&
object : sceneData.objects)
213 ARMARX_DEBUG <<
"Found object in scene: " <<
object.name;
216 catch (
const Ice::LocalException& e)
218 ARMARX_INFO <<
"Could not get object poses from simulator: " << e.what();
223 <<
" objects and " << sceneData.robots.size() <<
" robots.";
225 std::vector<objpose::ProvidedObjectPose> providedObjects;
227 if (properties.requestAllEntities)
230 providedObjects = getAllPoses(sceneData, now);
235 updateKnownObjects(sceneData);
236 removeExpiredRequests(now);
237 providedObjects = getRequestedPoses(now);
247 catch (
const Ice::LocalException& e)
249 ARMARX_INFO <<
"Could not report object poses to object memory: " << e.what();
255 std::vector<objpose::ProvidedObjectPose>
256 SimulationObjectPoseProvider::getAllPoses(
const armarx::SceneVisuData& sceneData,
259 auto convertPoses = [
this, time](
const auto& simObject)
260 {
return objectPoseFromVisuData(simObject, time); };
262 return sceneData.objects | ranges::views::transform(convertPoses) | ranges::to_vector;
266 SimulationObjectPoseProvider::updateKnownObjects(
const armarx::SceneVisuData& sceneData)
268 const std::scoped_lock l(knownObjectsMutex);
270 knownObjects.clear();
271 for (
const auto&
object : sceneData.objects)
273 knownObjects.insert({
object.name,
object});
278 SimulationObjectPoseProvider::removeExpiredRequests(
const DateTime& time)
280 const std::scoped_lock l2(activeRequestsMutex);
282 auto isTimeout = [time](
const auto& request)
284 const auto& provideUntilTime = request.second;
285 return (not provideUntilTime.isInvalid()) and time > provideUntilTime;
288 std::experimental::erase_if(activeRequests, isTimeout);
291 std::vector<objpose::ProvidedObjectPose>
292 SimulationObjectPoseProvider::getRequestedPoses(
const DateTime& time)
const
294 const std::scoped_lock l(knownObjectsMutex);
295 const std::scoped_lock l2(activeRequestsMutex);
297 auto isRequestedObjectKnown = [
this](
const auto& request)
299 const auto& objectName = request.first;
300 return this->knownObjects.find(objectName) != this->knownObjects.end();
303 auto getPoseFromRequest = [
this, time](
const auto& request)
305 const auto&
object = this->knownObjects.at(request.first);
306 return objectPoseFromVisuData(
object, time);
309 return activeRequests | ranges::views::filter(isRequestedObjectKnown) |
310 ranges::views::transform(getPoseFromRequest) | ranges::to_vector;
314 SimulationObjectPoseProvider::objectPoseFromVisuData(
const armarx::ObjectVisuData& visuData,
317 objpose::ProvidedObjectPose pose;
320 pose.objectType = objpose::ObjectType::KnownObject;
321 pose.isStatic = visuData.staticObject;
323 pose.objectID = armarx::ObjectID(visuData.name);
325 pose.objectPose =
armarx::fromIce(visuData.objectPoses.at(visuData.name));
329 pose.timestamp = time;
Default component property definition container.
std::string getConfigIdentifier()
Retrieve config identifier for this component as set in constructor.
static DateTime Invalid()
static Duration Seconds(std::int64_t seconds)
Constructs a duration in seconds.
static Frequency Hertz(std::int64_t hertz)
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.
std::string getName() const
Retrieve name of object.
Ice::ObjectPrx getProxy(long timeoutMs=0, bool waitForScheduler=true) const
Returns the proxy of this object (optionally it waits for the proxy)
objpose::ObjectPoseStorageInterfacePrx objectPoseTopic
bool isStopped()
Retrieve whether stop() has been called.
void onInitComponent() override
objpose::ProviderInfo getProviderInfo(const Ice::Current &) override
void onDisconnectComponent() override
armarx::PropertyDefinitionsPtr createPropertyDefinitions() override
void onConnectComponent() override
static std::string GetDefaultName()
Get the component's default name.
void onExitComponent() override
objpose::provider::RequestObjectsOutput requestObjects(const objpose::provider::RequestObjectsInput &input, const Ice::Current &) override
std::string getDefaultName() const override
Represents a point in time.
static Duration MilliSeconds(std::int64_t milliSeconds)
Constructs a duration in milliseconds.
Simple rate limiter for use in loops to maintain a certain frequency given a clock.
An object pose provided by an ObjectPoseProvider.
std::string providerName
Name of the providing component.
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
#define ARMARX_INFO
The normal logging level.
#define ARMARX_DEBUG
The logging level for output that is only interesting while debugging.
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
std::string const GlobalFrame
Variable of the global coordinate system.
objpose::AABB toIce(const simox::AxisAlignedBoundingBox &aabb)
This file offers overloads of toIce() and fromIce() functions for STL container types.
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
void fromIce(const std::map< IceKeyT, IceValueT > &iceMap, boost::container::flat_map< CppKeyT, CppValueT > &cppMap)
SimpleRunningTask(Ts...) -> SimpleRunningTask< std::function< void(void)> >