29#include <experimental/memory>
38#include <Eigen/Geometry>
40#include <Ice/Current.h>
42#include <opencv2/core/eigen.hpp>
44#include <SimoxUtility/color/ColorMap.h>
45#include <SimoxUtility/color/cmaps/colormaps.h>
59#include <RobotAPI/interface/ArViz/Elements.h>
60#include <RobotAPI/interface/aron/Aron.h>
64#include <armarx/navigation/client/ice/NavigatorInterface.h>
92 std::vector<core::Pose>
93 convert(
const std::vector<Eigen::Matrix4f>& wps)
95 std::vector<core::Pose> p;
96 p.reserve(wps.size());
97 std::transform(wps.begin(),
99 std::back_inserter(p),
100 [](
const auto& p) { return core::Pose(p); });
122 addPlugin(laserScannerFeaturesReaderPlugin);
127 ¶meterizationReaderPlugin->get(), ¶meterizationWriterPlugin->get());
155 .graphReader = &graphReaderPlugin->get(),
156 .costmapReader = &costmapReaderPlugin->get(),
157 .costmap3dReader = &costmap3dReaderPlugin->get(),
158 .virtualRobotReader = &virtualRobotReaderPlugin->get(),
159 .humanReader = &humanReaderPlugin->get(),
160 .laserScannerFeaturesReader = &laserScannerFeaturesReaderPlugin->get(),
167 sceneProvider.reset();
169 sceneProvider.emplace(srv, params.sceneCfg);
176 if (not params.disableExecutor)
187 .robotName = params.sceneCfg.robotName,
188 .rtUnitDynamicallyLoadLibraries = params.rtUnitDynamicallyLoadLibraries});
196 introspector.reset();
210 ARMARX_INFO <<
"Initialized. Will now respond to navigation requests.";
219 const bool isAnyNavigatorRunning = std::any_of(navigators.begin(),
221 [](
const auto& p) ->
bool
223 const server::Navigator& navigator =
226 return not navigator.isStopped();
230 if (isAnyNavigatorRunning)
233 <<
"A navigator was running when the component got disconnected. Will try to stop "
234 "as much as possible but expect something to be broken now.";
239 sceneProvider.reset();
241 introspector.reset();
270 const std::string& callerId,
281 sceneProvider->scene(),
292 memoryIntrospectors.emplace_back(
293 std::make_unique<server::MemoryIntrospector>(resultsWriterPlugin->get(), callerId));
296 memoryPublishers.emplace(
298 std::make_unique<server::MemoryPublisher>(
299 &resultsWriterPlugin->get(), &eventsWriterPlugin->get(), callerId));
302 if (executor.has_value())
304 executorPtr = &executor.value();
311 const std::string goalReachedKey =
315 auto goalReachedElement =
324 goalReachedCfg.
posTh = coreCfg.posTh;
325 goalReachedCfg.
oriTh = coreCfg.oriTh;
335 navigators.erase(callerId);
337 std::piecewise_construct,
338 std::forward_as_tuple(callerId),
339 std::forward_as_tuple(
341 .general = params.navigatorGeneralConfig,
342 .goalReachedConfig = goalReachedCfg},
344 .executor = executorPtr,
345 .publisher = memoryPublishers.at(callerId).get(),
346 .introspector = introspector.has_value() ? &(introspector.value()) :
nullptr,
347 .drawer = introspector.has_value() ? &(introspector.value()) :
nullptr,
350 sceneProvider.has_value() ? &sceneProvider.value() :
nullptr}));
356 navigators.erase(callerId);
357 memoryPublishers.erase(callerId);
362 const std::string& navigationMode,
363 const std::string& callerId,
369 <<
" with navigation mode `" << navigationMode <<
"`.";
371 <<
"Navigator config for caller " <<
QUOTED(callerId) <<
" not registered!";
375 navigators.at(callerId).moveTo(
convert(waypoints),
384 <<
"Movement will be paused.";
392 const std::string& navigationMode,
393 const std::string& callerId,
394 const Ice::Current& )
400 <<
"Navigator config for caller " <<
QUOTED(callerId) <<
" not registered!";
402 const auto checkIsActiveNavigator = [&](
const std::string& callerId)
405 if (not activeNavigatorCallerId.has_value())
411 return activeNavigatorCallerId == callerId;
415 <<
"The navigator with id " <<
QUOTED(callerId) <<
" is not active!";
417 navigators.at(callerId).update(
convert(waypoints),
423 const std::string& navigationMode,
424 const std::string& callerId,
425 const Ice::Current&
c)
431 const std::vector<client::WaypointTarget> wps =
client::defrost(waypoints);
434 <<
"Navigator config for caller " <<
QUOTED(callerId) <<
" not registered!";
441 const std::string& navigationMode,
442 const std::string& callerId,
443 const Ice::Current&
c)
448 <<
" with navigation mode `" << navigationMode <<
"`.";
450 <<
"Navigator config for caller " <<
QUOTED(callerId) <<
" not registered!";
456 navigators.at(callerId).moveToAlternatives(
465 <<
"Movement will be paused.";
473 const IceUtil::Optional<std::string>& providerNameIce,
474 const std::string& callerId,
475 const Ice::Current&
c)
482 <<
"Navigator config for caller " <<
QUOTED(callerId) <<
" not registered!";
484 std::optional<std::string> providerName;
487 providerName = providerNameIce.value();
490 navigators.at(callerId).moveToLocation(
location, providerName);
495 const std::string& navigationMode,
496 const std::string& callerId,
504 <<
"Navigator config for caller " <<
QUOTED(callerId) <<
" not registered!";
506 navigators.at(callerId).moveTowards(direction,
512 const std::string& callerId,
517 <<
"Navigator config for caller " <<
QUOTED(callerId) <<
" not registered!";
518 navigators.at(callerId).setVelocityFactor(velocityFactor);
525 <<
"Navigator config for caller " <<
QUOTED(configId) <<
" not registered!";
526 navigators.at(configId).pause();
534 <<
"Navigator config for caller " <<
QUOTED(configId) <<
" not registered!";
535 navigators.at(configId).resume();
544 <<
"Navigator config for caller " <<
QUOTED(configId) <<
" not registered!";
545 navigators.at(configId).stop();
550 memoryPublishers.at(configId)->userAbortTriggered(event);
572 ARMARX_INFO <<
"Trying to emit memory event `UserAbortTriggered`";
578 for (
auto& [callerId, memoryPublisher] : memoryPublishers)
580 memoryPublisher->userAbortTriggered(event);
590 <<
"Navigator config for caller " <<
QUOTED(configId) <<
" not registered!";
591 return navigators.at(configId).isPaused();
598 return sceneProvider->scene();
606 <<
"Navigator config for caller " <<
QUOTED(configId) <<
" not registered!";
607 return navigators.at(configId).isStopped();
627 def->optional(params.occupiedGridThreshold,
628 "p.occupancy_grid.occopied_threshold",
629 "Threshold for each cell to be considered occupied. Increase this value to "
632 def->optional(params.disableExecutor,
634 "If the executor is disabled, the navigator will only plan the trajectory "
635 "but won't execute it.");
637 def->required(params.sceneCfg.robotName,
"p.scene.robotName");
638 def->optional(params.sceneCfg.staticCostmapProviderName,
639 "p.scene.staticCostmapProviderName");
640 def->optional(params.sceneCfg.staticCostmapName,
"p.scene.staticCostmapName");
641 def->optional(params.sceneCfg.costmap3dProviderName,
"p.scene.costmap3dProviderName");
642 def->optional(params.sceneCfg.costmap3dName,
"p.scene.costmap3dName");
643 def->optional(params.sceneCfg.humanProviderName,
"p.scene.humanProviderName");
644 def->optional(params.sceneCfg.laserScannerFeaturesProviderName,
645 "p.scene.laserScannerFeaturesProviderName");
647 def->optional(params.rtUnitDynamicallyLoadLibraries,
648 "p.rtUnitDynamicallyLoadLibraries",
649 "If enabled, the controller library will automatically be loaded in the "
650 "RobotUnit. If disabled (desired), you have to make sure that the controller "
651 "library is listed in the RobotUnit's property `LoadLibraries`");
654 def->optional(params.navigatorGeneralConfig.tasks.replanningUpdatePeriod,
655 "p.navigator.general.replanningPeriod");
658 params.navigatorGeneralConfig.subdivision.enable,
659 "p.navigator.general.subdivision.enable",
660 "Whether to enable global path subdivision when local planner is enabled as well.");
661 def->optional(params.navigatorGeneralConfig.subdivision.localPlannerCostmapThreshold,
662 "p.navigator.general.subdivision.localPlannerCostmapThreshold",
663 "The minimum value in the costmap to enable local planning.");
665 params.navigatorGeneralConfig.subdivision.globalPlanExpansionDistance,
666 "p.navigator.general.subdivision.globalPlanExpansionDistance",
667 "The length by which global planner segments are expaned (in both directions).");
668 def->optional(params.navigatorGeneralConfig.subdivision.minSegmentDistance,
669 "p.navigator.general.subdivision.minSegmentDistance",
670 "The minimum length for a local planner segment (otherwise it is deleted and "
671 "joined with the neighboring global planner segments).");
673 def->optional(params.navigatorGeneralConfig.targetAlternativesFilterTimeSeconds,
674 "p.navigator.general.targetAlternativesFilterTimeSeconds",
675 "The number of seconds to wait before replanning alternatives after all "
676 "alternatives where impossible.");
678 def->optional(params.navigatorGoalReachedConfig.posTh,
"p.navigator.goalReached.posTh");
679 def->optional(params.navigatorGoalReachedConfig.oriTh,
"p.navigator.goalReached.oriTh");
680 def->optional(params.navigatorGoalReachedConfig.linearVelTh,
681 "p.navigator.goalReached.linearVelTh");
682 def->optional(params.navigatorGoalReachedConfig.angularVelTh,
683 "p.navigator.goalReached.angularVelTh");
684 def->optional(params.navigatorGoalReachedConfig.filterCount,
685 "p.navigator.goalReached.filterCount");
693 const auto cmap = simox::color::cmaps::viridis();
694 const float vmax = costmap.
getGrid().array().maxCoeff();
696 const auto asColor = [&cmap, &vmax](
const float distance) -> viz::data::Color
698 const auto color = cmap.at(
distance, 0.F, vmax);
699 return {color.a, color.r, color.g, color.b};
702 auto layer = arviz.
layer(
"costmap_" + name);
704 const std::int64_t cols = costmap.
getGrid().cols();
705 const std::int64_t rows = costmap.
getGrid().rows();
709 std::vector<std::vector<Eigen::Vector3f>> vertices;
710 std::vector<std::vector<viz::data::Color>> colors;
712 for (
int r = 0; r < rows; r++)
714 auto& verticesRow = vertices.emplace_back(cols);
715 auto& colorsRow = colors.emplace_back(cols);
717 for (
int c = 0;
c < cols;
c++)
720 colorsRow.at(
c) = asColor(costmap.
getGrid()(r,
c));
724 mesh.grid2D(vertices, colors);
736 if (not navigatorId.has_value())
741 return &navigators.at(navigatorId.value());
744 std::optional<std::string>
749 const auto isActive = [](
const auto& nameNavPair) ->
bool
751 const auto& [name,
navigator] = nameNavPair;
755 const auto it = std::find_if(navigators.begin(), navigators.end(), isActive);
758 if (it == navigators.end())
773 tab.stopAll.setLabel(
"Stop All");
783 if (tab.stopAll.wasClicked())
#define ARMARX_REGISTER_COMPONENT_EXECUTABLE(ComponentT, applicationName)
armarx::viz::Client & getArvizClient()
static DateTime Now()
Current time on the virtual clock.
Default component property definition container.
std::string getConfigIdentifier()
Retrieve config identifier for this component as set in constructor.
plugins::DebugObserverComponentPlugin & getDebugObserverComponentPlugin()
bool usingProxy(const std::string &name, const std::string &endpoints="")
Registers a proxy for retrieval after initialization and adds it to the dependency list.
PluginT * addPlugin(const std::string prefix="", ParamsT &&... params)
std::string getName() const
Retrieve name of object.
void setLogObjectDiscoveryError(bool logEnabled)
objpose::ObjectPoseClient getClient() const
bool hasElement(const std::string &) const
VariantPtr getElement(const std::string &) const
static PointerType DynamicCast(const VariantPtr &n)
ComponentPlugin & getControlComponentPlugin()
const Grid & getGrid() const
Position toPositionGlobal(const Index &index) const
void moveToLocation(const std::string &location, const IceUtil::Optional< std::string > &providerName, const std::string &callerId, const Ice::Current &c=Ice::emptyCurrent) override
void removeConfig(const std::string &callerId, const Ice::Current &c=Ice::emptyCurrent) override
void onInitComponent() override
void pause(const std::string &callerId, const Ice::Current &c=Ice::emptyCurrent) override
void resume(const std::string &callerId, const Ice::Current &c=Ice::emptyCurrent) override
void setVelocityFactor(float velocityFactor, const std::string &callerId, const Ice::Current &c=Ice::emptyCurrent) override
std::optional< std::string > activeNavigatorId() const
server::Navigator * activeNavigator()
void onDisconnectComponent() override
void moveToAlternatives(const client::detail::TargetAlternatives &targets, const std::string &navigationMode, const std::string &callerId, const Ice::Current &c=Ice::emptyCurrent) override
void RemoteGui_update() override
After calling RemoteGui_startRunningTask, this function is called periodically in a separate thread.
bool isPaused(const std::string &callerId, const Ice::Current &c=Ice::emptyCurrent) override
bool isStopped(const std::string &callerId, const Ice::Current &c=Ice::emptyCurrent) override
PropertyDefinitionsPtr createPropertyDefinitions() override
void updateMoveTo(const std::vector< Eigen::Matrix4f > &waypoints, const std::string &navigationMode, const std::string &callerId, const Ice::Current &c=Ice::emptyCurrent) override
const core::Scene & scene() const
void onConnectComponent() override
void createConfig(const aron::data::dto::DictPtr &stackConfig, const std::string &callerId, const Ice::Current &c=Ice::emptyCurrent) override
static std::string GetDefaultName()
void stop(const std::string &callerId, const Ice::Current &c=Ice::emptyCurrent) override
void onExitComponent() override
void moveTo(const std::vector< Eigen::Matrix4f > &waypoints, const std::string &navigationMode, const std::string &callerId, const Ice::Current &c=Ice::emptyCurrent) override
void moveTowards(const Eigen::Vector3f &direction, const std::string &navigationMode, const std::string &callerId, const Ice::Current &c=Ice::emptyCurrent) override
void stopAllImpl(bool emitMemoryEvent)
void moveTo2(const client::detail::Waypoints &waypoints, const std::string &navigationMode, const std::string &callerId, const Ice::Current &c=Ice::emptyCurrent) override
void createRemoteGuiTab()
This function should be called once in onConnect() or when you need to re-create the Remote GUI tab.
std::string getDefaultName() const override
static server::NavigationStack create(const aron::data::DictPtr ¶ms, const core::Scene &scene, std::experimental::observer_ptr< viz::Client > arviz, std::experimental::observer_ptr< DebugObserverComponentPluginUser > debugObserver)
An executer the server navigator will use to send its control commands to.
ObjectFinder objectFinder
Brief description of class targets.
virtual Layer layer(std::string const &name) const
CommitResult commit(StagedCommit const &commit)
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
#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...
#define ARMARX_INFO
The normal logging level.
#define ARMARX_IMPORTANT
The logging level for always important information, but expected behaviour (in contrast to ARMARX_WAR...
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
#define ARMARX_VERBOSE
The logging level for verbose information.
idempotent void stopAll()
::IceInternal::Handle< Dict > DictPtr
sequence< Waypoint > Waypoints
sequence< TargetAlternative > TargetAlternatives
client::GlobalPlanningStrategy defrost(const client::detail::GlobalPlanningStrategy &strategy)
void visualize(const algorithms::Costmap &costmap, viz::Client &arviz, const std::string &name)
std::vector< Eigen::Vector3f > to3D(const std::vector< Eigen::Vector2f > &v)
const std::string PARAMS_KEY
const simox::meta::EnumNames< StackLayer > StackLayerNames
const simox::meta::EnumNames< NavigationFrame > NavigationFrameNames
This file is part of ArmarX.
core::GoalReachedConfig GoalReachedMonitorConfig
This file is part of ArmarX.
std::vector< core::Pose > convert(const std::vector< Eigen::Matrix4f > &wps)
std::string GetHandledExceptionString()
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
observer_ptr< _Tp > make_observer(_Tp *__p) noexcept
double distance(const Point &a, const Point &b)
void RemoteGui_startRunningTask()
void RemoteGui_createTab(std::string const &name, RemoteGui::Client::Widget const &rootWidget, RemoteGui::Client::Tab *tab)
static GoalReachedConfig FromAron(const aron::data::DictPtr &dict)
Event describing that the user aborted the current execution.
local_planning::LocalPlannerPtr localPlanner