Component.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 navigation::ArmarXObjects::navigation_skill_provider
17  * @author Fabian Reister ( fabian dot reister at kit dot edu )
18  * @date 2023
19  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20  * GNU General Public License
21  */
22 
23 
24 #include "Component.h"
25 
26 #include <experimental/memory>
27 #include <mutex>
28 #include <string>
29 
34 
36 
38 
49 
51 {
53  {
54  addPlugin(virtualRobotReaderPlugin);
55  addPlugin(costmapReaderPlugin);
56  addPlugin(graphReaderPlugin);
57  addPlugin(roomsReaderPlugin);
58  }
59 
60  const std::string Component::defaultName = skills::constants::NavigationSkillProviderName;
61 
62  namespace
63  {
64  void
65  defineProximityFieldParams(const armarx::PropertyDefinitionsPtr& def,
66  const std::string& prefix,
68  {
69  def->optional(params.reduceVelocity,
70  prefix + ".reduceVelocity",
71  "Whether to first reduce the velocity when coming closer to an obstacle "
72  "before stopping.");
73  def->optional(params.minDistance,
74  prefix + ".minDistance",
75  "The minimum distance, below which the robot will stop.");
76  def->optional(
77  params.maxDistance,
78  prefix + ".maxDistance",
79  "The maximum distance, above which the robot will move with the maximum velocity.");
80  def->optional(
81  params.k,
82  prefix + ".k",
83  "A parameter to adjust how the velocity is reduced when coming closer to "
84  "an obstacle. A higher value means the robot will reduce it's speed later.")
85  .setMin(1);
86  def->optional(
87  params.lambda,
88  prefix + ".lambda",
89  "A parameter to adjust how the velocity is reduced when coming closer to an "
90  "obstacle. A higher value means the robot will reduce it's speed earlier.")
91  .setMin(1);
92  }
93  } // namespace
94 
97  {
100 
101  def->component(navigatorPrx, "navigator");
102 
103  def->required(properties.robotName, "RobotName", "Default robot name.");
104 
105  auto optionalSubSkillID =
106  [&def](armarx::skills::SkillID& skillID, const std::string& nameBase)
107  {
108  ARMARX_CHECK(skillID.providerId.has_value());
109  def->optional(skillID.providerId->providerName, nameBase + ".providerName");
110  def->optional(skillID.skillName, nameBase + ".skillName");
111  };
112 
113  def->required(properties.safetyGuardParams.robotRadius,
114  "p.navigateToLocation.safetyGuardParams.robotRadius",
115  "The robot radius used for distance calculation to the platform.");
116  def->optional(properties.safetyGuardParams.enableHumans,
117  "p.navigateToLocation.safetyGuardParams.enableHumans",
118  "Whether to consider humans for the safety guard.");
119  def->optional(properties.safetyGuardParams.enableLaserScanners,
120  "p.navigateToLocation.safetyGuardParams.enableLaserscanners",
121  "Whether to consider laser scanners for the safety guard.");
122  def->optional(properties.safetyGuardParams.maxVelocity.linear,
123  "p.navigateToLocation.safetyGuardParams.maxVelocityLinear",
124  "The maximum linear velocity.");
125  def->optional(properties.safetyGuardParams.maxVelocity.angular,
126  "p.navigateToLocation.safetyGuardParams.maxVelocityAngular",
127  "The maximum angular velocity.");
128  defineProximityFieldParams(def,
129  "p.navigateToLocation.safetyGuardParams.humanProximityField",
130  properties.safetyGuardParams.humanProximityField);
131  defineProximityFieldParams(
132  def,
133  "p.navigateToLocation.safetyGuardParams.laserScannerProximityField",
134  properties.safetyGuardParams.laserScannerProximityField);
135 
136 
137  optionalSubSkillID(properties.navigateToNamedLocation.subSkillIDs.navigateToLocation,
138  "p.navigateToNamedLocation.subSkillIDs.navigateToLocation");
139  optionalSubSkillID(properties.navigateToChargingStation.subSkillIDs.navigateToNamedLocation,
140  "p.navigateToChargingStation.subSkillIDs.navigateToNamedLocation");
141 
142  return def;
143  }
144 
145  void
147  {
148  // Topics and properties defined above are automagically registered.
149 
150  // Keep debug observer data until calling `sendDebugObserverBatch()`.
151  // (Requies the armarx::DebugObserverComponentPluginUser.)
152  // setDebugObserverBatchModeEnabled(true);
153  }
154 
155  void
157  {
158  // Do things after connecting to topics and components.
159 
160  iceNavigator.setNavigatorComponent(navigatorPrx);
161 
162  {
164  .iceNavigator = iceNavigator,
165  .memoryNameSystem = memoryNameSystem(),
166  };
167  addSkillFactory<skills::NavigateTo>(srv);
168  }
169 
170  {
172  .safetyGuardParamsMutex = std::experimental::make_observer(&safetyGuardParamsMutex),
173  .safetyGuardParams =
174  std::experimental::make_observer(&properties.safetyGuardParams)};
176  .iceNavigator = iceNavigator,
177  .memoryNameSystem = memoryNameSystem(),
178  };
179  addSkillFactory<skills::NavigateToLocation>(prop, srv);
180  }
181 
182  {
184  .locationReader = graphReaderPlugin->get(),
185  };
186  addSkillFactory<skills::NavigateToNamedLocation>(properties.navigateToNamedLocation,
187  services);
188  }
189 
190  {
191  addSkillFactory<skills::NavigateToChargingStation>(
192  properties.navigateToChargingStation);
193  }
194 
195  {
196  skills::MoveXMeters::Services srv{
197  .iceNavigator = iceNavigator,
198  .memoryNameSystem = memoryNameSystem(),
199  };
200  addSkillFactory<skills::MoveXMeters>(srv);
201  }
202 
203  {
204 
205  skills::RotateXDegrees::Services srv{
206  .iceNavigator = iceNavigator,
207  .memoryNameSystem = memoryNameSystem(),
208  };
209  addSkillFactory<skills::RotateXDegrees>(srv);
210  }
211 
212  {
214  .robotName = this->properties.robotName,
215  };
217  .iceNavigator = iceNavigator,
218  .memoryNameSystem = memoryNameSystem(),
219  .robotReader = virtualRobotReaderPlugin->get(),
220  };
221  addSkillFactory<skills::MoveRelativePlanar>(properties, srv);
222  }
223 
224  {
225  ARMARX_CHECK_NOT_NULL(virtualRobotReaderPlugin);
226  ARMARX_CHECK_NOT_NULL(virtualRobotReaderPlugin);
227  ARMARX_CHECK_NOT_NULL(roomsReaderPlugin);
228 
230  .memoryNameSystem = memoryNameSystem(),
231  .virtualRobotReader =
232  virtualRobotReaderPlugin->get(),
233  .costmapReader = costmapReaderPlugin->get(),
234  .roomsReader = roomsReaderPlugin->get(),
235  .arviz = arviz};
236 
237  addSkillFactory<skills::GuideHumanToRoom>(srv);
238  }
239 
240 
241  /* (Requies the armarx::DebugObserverComponentPluginUser.)
242  // Use the debug observer to log data over time.
243  // The data can be viewed in the ObserverView and the LivePlotter.
244  // (Before starting any threads, we don't need to lock mutexes.)
245  {
246  setDebugObserverDatafield("numBoxes", properties.numBoxes);
247  setDebugObserverDatafield("boxLayerName", properties.boxLayerName);
248  sendDebugObserverBatch();
249  }
250  */
251 
252  /* (Requires the armarx::ArVizComponentPluginUser.)
253  // Draw boxes in ArViz.
254  // (Before starting any threads, we don't need to lock mutexes.)
255  drawBoxes(properties, arviz);
256  */
257 
258  // Setup the remote GUI.
259  {
262  }
263  }
264 
265  void
267  {
268  }
269 
270  void
272  {
273  }
274 
275  std::string
277  {
278  return Component::defaultName;
279  }
280 
281  std::string
283  {
284  return Component::defaultName;
285  }
286 
287  void
289  {
290  using namespace armarx::RemoteGui::Client;
291 
292  VBoxLayout root;
293 
294  // thread-safe access to params
295  const auto safetyGuardParams = [this]()
296  {
297  std::lock_guard g{safetyGuardParamsMutex};
298  return properties.safetyGuardParams;
299  }();
300 
301  const auto setSpinBox = [](armarx::RemoteGui::Client::FloatSpinBox& w,
302  float min,
303  float max,
304  int decimals,
305  float step)
306  {
307  w.setRange(min, max);
308  w.setDecimals(decimals);
309  w.setSteps(static_cast<int>((max - min) / step));
310  };
311 
312  {
313  GridLayout grid;
314  int row = 0;
315  grid.add(Label("Enable Humans"), {.row = row, .column = 0})
316  .add(tab.enableHumans, {.row = row++, .column = 1});
317  grid.add(Label("Enable Laserscanner"), {.row = row, .column = 0})
318  .add(tab.enableLaserScanners, {.row = row++, .column = 1});
319  grid.add(armarx::RemoteGui::Client::VSpacer(), {.row = row++, .column = 0});
320  grid.add(Label("Max velocity linear"), {.row = row, .column = 0})
321  .add(tab.maxVelocityLinear, {.row = row++, .column = 1});
322  grid.add(Label("Max velocity angular"), {.row = row, .column = 0})
323  .add(tab.maxVelocityAngular, {.row = row++, .column = 1});
324  root.addChild(grid);
325 
326  tab.enableHumans.setValue(safetyGuardParams.enableHumans);
327  tab.enableLaserScanners.setValue(safetyGuardParams.enableLaserScanners);
328  tab.maxVelocityLinear.setValue(safetyGuardParams.maxVelocity.linear);
329  setSpinBox(tab.maxVelocityLinear, 0, 2000, 1, 1);
330  tab.maxVelocityAngular.setValue(safetyGuardParams.maxVelocity.angular);
331  setSpinBox(tab.maxVelocityAngular, 0, 5, 2, 0.1);
332  }
333  root.addChild(VSpacer());
334 
335  const auto setupProximityFieldGui =
336  [&root, &setSpinBox](RemoteGuiTab::ProximityField& field,
337  const safety_guard::ProximityFieldParams& values,
338  const std::string& label)
339  {
340  GridLayout grid;
341  int row = 0;
342  grid.add(Label("Reduce speed"), {.row = row, .column = 0})
343  .add(field.reduceSpeed, {.row = row++, .column = 1});
344  grid.add(Label("Min distance"), {.row = row, .column = 0})
345  .add(field.minDistance, {.row = row++, .column = 1});
346  grid.add(armarx::RemoteGui::Client::VSpacer(), {.row = row++, .column = 0});
347  grid.add(Label("Max distance"), {.row = row, .column = 0})
348  .add(field.maxDistance, {.row = row++, .column = 1});
349  grid.add(Label("k"), {.row = row, .column = 0})
350  .add(field.k, {.row = row++, .column = 1});
351  grid.add(Label("lambda"), {.row = row, .column = 0})
352  .add(field.lambda, {.row = row++, .column = 1});
353 
354  GroupBox box({grid});
355  box.setLabel(label);
356  root.addChild(box);
357 
358  field.reduceSpeed.setValue(values.reduceVelocity);
359  field.minDistance.setValue(values.minDistance);
360  setSpinBox(field.minDistance, 0, 5000, 1, 1);
361  field.maxDistance.setValue(values.maxDistance);
362  setSpinBox(field.maxDistance, 0, 10000, 1, 1);
363  field.k.setValue(values.k);
364  setSpinBox(field.k, 1, 20, 2, 0.1);
365  field.lambda.setValue(values.lambda);
366  setSpinBox(field.lambda, 1, 20, 2, 0.1);
367  };
368 
369  setupProximityFieldGui(tab.humanProximityField,
370  safetyGuardParams.humanProximityField,
371  "Human proximity field");
372  root.addChild(VSpacer());
373  setupProximityFieldGui(tab.laserScannerProximityField,
374  safetyGuardParams.laserScannerProximityField,
375  "LaserScanner proximity field");
376 
377  RemoteGui_createTab(getName(), root, &tab);
378  }
379 
380  void
381  Component::RemoteGui_update()
382  {
383  std::lock_guard g{safetyGuardParamsMutex};
384 
385  auto& safetyGuardParams = properties.safetyGuardParams;
386 
387  safetyGuardParams.enableHumans = tab.enableHumans.getValue();
388  safetyGuardParams.enableLaserScanners = tab.enableLaserScanners.getValue();
389  safetyGuardParams.maxVelocity.linear = tab.maxVelocityLinear.getValue();
390  safetyGuardParams.maxVelocity.angular = tab.maxVelocityAngular.getValue();
391 
392  const auto readProximityField = [&](const RemoteGuiTab::ProximityField& field,
394  {
395  values.reduceVelocity = field.reduceSpeed.getValue();
396  values.minDistance = field.minDistance.getValue();
397  values.maxDistance = field.maxDistance.getValue();
398  values.k = field.k.getValue();
399  values.lambda = field.lambda.getValue();
400  };
401 
402  readProximityField(tab.humanProximityField, safetyGuardParams.humanProximityField);
403  readProximityField(tab.laserScannerProximityField,
404  safetyGuardParams.laserScannerProximityField);
405  }
406 
407  /* (Requires the armarx::ArVizComponentPluginUser.)
408  void
409  Component::drawBoxes(const Component::Properties& p, viz::Client& arviz)
410  {
411  // Draw something in ArViz (requires the armarx::ArVizComponentPluginUser.
412  // See the ArVizExample in RobotAPI for more examples.
413 
414  viz::Layer layer = arviz.layer(p.boxLayerName);
415  for (int i = 0; i < p.numBoxes; ++i)
416  {
417  layer.add(viz::Box("box_" + std::to_string(i))
418  .position(Eigen::Vector3f(i * 100, 0, 0))
419  .size(20).color(simox::Color::blue()));
420  }
421  arviz.commit(layer);
422  }
423  */
424 
425 
426  ARMARX_REGISTER_COMPONENT_EXECUTABLE(Component, Component::GetDefaultName());
427 
428 } // namespace armarx::navigation::components::navigation_skill_provider
constants.h
armarx::navigation::components::navigation_skill_provider::Component::RemoteGuiTab::ProximityField::k
armarx::RemoteGui::Client::FloatSpinBox k
Definition: Component.h:156
armarx::navigation::components::navigation_skill_provider::Component::RemoteGuiTab::ProximityField::maxDistance
armarx::RemoteGui::Client::FloatSpinBox maxDistance
Definition: Component.h:155
armarx::RemoteGui::Client::FloatSpinBox::getValue
float getValue() const
Definition: Widgets.cpp:352
armarx::navigation::safety_guard::ProximityFieldParams::reduceVelocity
bool reduceVelocity
Definition: LaserBasedProximity.h:46
armarx::navigation::client::IceNavigator::setNavigatorComponent
void setNavigatorComponent(const NavigatorInterfacePrx &navigator)
Definition: IceNavigator.cpp:46
armarx::navigation::skills::NavigateToNamedLocation::Services::locationReader
armarx::navigation::memory::client::graph::Reader locationReader
Definition: NavigateToNamedLocation.h:55
SkillID.h
armarx::navigation::skills::MoveRelativePlanar::Services::iceNavigator
client::IceNavigator & iceNavigator
Definition: MoveRelativePlanar.h:24
armarx::navigation::skills::constants::NavigationSkillProviderName
const std::string NavigationSkillProviderName
Definition: constants.h:28
armarx::skills::SkillID::skillName
std::string skillName
Definition: SkillID.h:41
armarx::RemoteGui::Client::VBoxLayout
Definition: Widgets.h:167
armarx::armem::client::plugins::PluginUser::memoryNameSystem
MemoryNameSystem & memoryNameSystem()
Definition: PluginUser.cpp:20
armarx::navigation::components::navigation_skill_provider::Component::RemoteGuiTab::ProximityField
Definition: Component.h:151
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::RemoteGui::Client::GridLayout::add
GridLayout & add(Widget const &child, Pos pos, Span span=Span{1, 1})
Definition: Widgets.cpp:438
RotateXDegrees.h
NavigateToNamedLocation.h
armarx::max
std::vector< T > max(const std::vector< T > &v1, const std::vector< T > &v2)
Definition: VectorHelpers.h:297
LaserBasedProximity.h
ProsthesisInterface.values
values
Definition: ProsthesisInterface.py:190
std::experimental::fundamentals_v2::make_observer
observer_ptr< _Tp > make_observer(_Tp *__p) noexcept
armarx::RemoteGui::Client::FloatSpinBox::setRange
void setRange(float min, float max)
Definition: Widgets.cpp:330
armarx::navigation::safety_guard::ProximityFieldParams::maxDistance
float maxDistance
Definition: LaserBasedProximity.h:49
armarx::skills::SkillID::providerId
std::optional< ProviderID > providerId
Definition: SkillID.h:40
armarx::navigation::components::navigation_skill_provider::Component::createPropertyDefinitions
armarx::PropertyDefinitionsPtr createPropertyDefinitions() override
Definition: Component.cpp:96
armarx::navigation::components::navigation_skill_provider::Component::createRemoteGuiTab
void createRemoteGuiTab()
This function should be called once in onConnect() or when you need to re-create the Remote GUI tab.
Definition: Component.cpp:288
armarx::ManagedIceObject::addPlugin
PluginT * addPlugin(const std::string prefix="", ParamsT &&... params)
Definition: ManagedIceObject.h:186
armarx::navigation::skills::NavigateToNamedLocation::Services
Definition: NavigateToNamedLocation.h:53
armarx::RemoteGui::Client::VSpacer
Definition: Widgets.h:204
armarx::navigation::components::navigation_skill_provider::Component::Component
Component()
Definition: Component.cpp:52
ARMARX_CHECK
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
Definition: ExpressionException.h:82
armarx::navigation::components::navigation_skill_provider::Component::onExitComponent
void onExitComponent() override
Definition: Component.cpp:271
armarx::navigation::skills::NavigateToLocation::Properties::safetyGuardParamsMutex
std::experimental::observer_ptr< std::mutex > safetyGuardParamsMutex
Definition: NavigateToLocation.h:56
armarx::navigation::skills::NavigateTo::Services
Definition: NavigateTo.h:47
GuideHumanToRoom.h
armarx::RemoteGui::Client::CheckBox::getValue
bool getValue() const
Definition: Widgets.cpp:246
visionx::voxelgrid::Label
uint32_t Label
Type of an object label.
Definition: types.h:6
NavigateToLocation.h
armarx::RemoteGui::Client::GridLayout
Definition: Widgets.h:186
armarx::navigation::components::navigation_skill_provider
Definition: Component.cpp:50
armarx::navigation::components::navigation_skill_provider::Component::getDefaultName
std::string getDefaultName() const override
Definition: Component.cpp:276
armarx::navigation::skills::NavigateToLocation::Services::iceNavigator
client::IceNavigator & iceNavigator
Definition: NavigateToLocation.h:49
armarx::navigation::components::navigation_skill_provider::Component::RemoteGuiTab::ProximityField::reduceSpeed
armarx::RemoteGui::Client::CheckBox reduceSpeed
Definition: Component.h:153
armarx::ARMARX_REGISTER_COMPONENT_EXECUTABLE
ARMARX_REGISTER_COMPONENT_EXECUTABLE(RemoteGuiExample2, RemoteGuiExample2::GetDefaultName())
armarx::navigation::skills::MoveRelativePlanar::Properties
Definition: MoveRelativePlanar.h:29
armarx::navigation::components::navigation_skill_provider::Component::RemoteGuiTab::ProximityField::minDistance
armarx::RemoteGui::Client::FloatSpinBox minDistance
Definition: Component.h:154
armarx::navigation::components::navigation_skill_provider::Component::onDisconnectComponent
void onDisconnectComponent() override
Definition: Component.cpp:266
armarx::navigation::safety_guard::ProximityFieldParams::lambda
float lambda
Definition: LaserBasedProximity.h:54
NavigateTo.h
armarx::RemoteGui::Client::GroupBox
Definition: Widgets.h:193
armarx::navigation::components::navigation_skill_provider::Component
Definition: Component.h:57
armarx::navigation::skills::GuideHumanToRoom::Services::iceNavigator
client::IceNavigator & iceNavigator
Definition: GuideHumanToRoom.h:55
armarx::RemoteGui::Client::FloatSpinBox::setDecimals
void setDecimals(int decimals)
Definition: Widgets.cpp:345
armarx::RemoteGui::Client::FloatSpinBox::setSteps
void setSteps(int steps)
Definition: Widgets.cpp:338
armarx::navigation::components::navigation_skill_provider::Component::RemoteGuiTab::ProximityField::lambda
armarx::RemoteGui::Client::FloatSpinBox lambda
Definition: Component.h:157
armarx::RemoteGui::Client::GroupBox::setLabel
void setLabel(std::string const &text)
Definition: Widgets.cpp:420
Component.h
armarx::LightweightRemoteGuiComponentPluginUser::RemoteGui_startRunningTask
void RemoteGui_startRunningTask()
Definition: LightweightRemoteGuiComponentPlugin.cpp:119
ExpressionException.h
armarx::Component::getConfigIdentifier
std::string getConfigIdentifier()
Retrieve config identifier for this component as set in constructor.
Definition: Component.cpp:79
Decoupled.h
armarx::navigation::components::navigation_skill_provider::Component::GetDefaultName
static std::string GetDefaultName()
Get the component's default name.
Definition: Component.cpp:282
armarx::navigation::safety_guard::ProximityFieldParams
Definition: LaserBasedProximity.h:44
armarx::ComponentPropertyDefinitions
Default component property definition container.
Definition: Component.h:69
PropertyDefinitionContainer.h
armarx::ArVizComponentPluginUser::arviz
armarx::viz::Client arviz
Definition: ArVizComponentPlugin.h:42
armarx::navigation::skills::NavigateToLocation::Services
Definition: NavigateToLocation.h:47
MoveRelativePlanar.h
IceUtil::Handle< class PropertyDefinitionContainer >
armarx::min
std::vector< T > min(const std::vector< T > &v1, const std::vector< T > &v2)
Definition: VectorHelpers.h:327
armarx::navigation::safety_guard::ProximityFieldParams::k
float k
Definition: LaserBasedProximity.h:53
Widgets.h
armarx::navigation::components::navigation_skill_provider::Component::onConnectComponent
void onConnectComponent() override
Definition: Component.cpp:156
NavigateToChargingStation.h
armarx::navigation::skills::MoveRelativePlanar::Services
Definition: MoveRelativePlanar.h:22
armarx::navigation::safety_guard::ProximityFieldParams::minDistance
float minDistance
Definition: LaserBasedProximity.h:48
armarx::RemoteGui::Client
Definition: EigenWidgets.cpp:8
MoveXMeters.h
armarx::skills::SkillID
Definition: SkillID.h:14
armarx::navigation::skills::NavigateTo::Services::iceNavigator
client::IceNavigator & iceNavigator
Definition: NavigateTo.h:49
armarx::RemoteGui::Client::FloatSpinBox
Definition: Widgets.h:93
armarx::navigation::skills::GuideHumanToRoom::Services
Definition: GuideHumanToRoom.h:53
armarx::navigation::skills::NavigateToLocation::Properties
Definition: NavigateToLocation.h:54
armarx::navigation::components::navigation_skill_provider::Component::onInitComponent
void onInitComponent() override
Definition: Component.cpp:146