Application.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of ArmarX.
3  *
4  * Copyright (C) 2011-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5  *
6  * ArmarX is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  * ArmarX is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  *
18  * @package ArmarXCore::core
19  * @author Nils Adermann (naderman at naderman dot de)
20  * @author Kai Welke (welke at kit dot edu)
21  * @author Jan Issac (jan dot issac at gmail dot com)
22  * @author Mirko Waechter (waechter at kit dot edu)
23  * @author Manfred Kroehnert (manfred dot kroehnert at kit dot edu)
24  * @date 2010
25  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
26  * GNU General Public License
27  */
28 
29 #include "Application.h"
30 
31 #include <stddef.h> // for size_t
32 #include <stdlib.h> // for NULL, getenv, system, exit, etc
33 
34 #include <filesystem>
35 #include <fstream>
36 #include <iostream> // for operator<<, ostream, etc
37 #include <sstream> // for basic_stringbuf<>::int_type, etc
38 #include <thread>
39 #include <thread> // for thread
40 #include <utility> // for pair, move
41 
42 #include <unistd.h> // for getpid
43 
44 #include <Ice/Communicator.h> // for Communicator, etc
45 #include <Ice/Initialize.h> // for InitializationData
46 #include <Ice/LocalException.h> // for FileException, etc
47 #include <Ice/NativePropertiesAdmin.h>
48 #include <Ice/ObjectF.h> // for upCast
49 #include <Ice/Process.h> // for ProcessPtr, Process
50 #include <Ice/Properties.h> // for Properties, PropertiesPtr
51 #include <Ice/Properties.h>
52 #include <Ice/PropertiesAdmin.h> // for PropertyDict
53 #include <Ice/PropertiesAdmin.h>
54 #include <IceUtil/Time.h> // for Time
55 
56 #include <SimoxUtility/algorithm/string/string_tools.h>
57 
58 #include "ArmarXCore/core/IceManager.h" // for IceManager
69 #include "ArmarXCore/core/logging/LogSender.h" // for LogSender
70 #include "ArmarXCore/core/logging/Logging.h" // for ARMARX_INFO_S, etc
71 #include "ArmarXCore/interface/core/Log.h" // for MessageType, etc
72 #include "ArmarXCore/interface/core/Profiler.h"
76 
77 #include "../logging/ArmarXLogBuf.h" // for ArmarXLogBuf
78 #include "ApplicationNetworkStats.h" // for ApplicationNetworkStatsPtr
79 #include "ApplicationOptions.h" // for Options, showHelp, etc
80 #include "ApplicationProcessFacet.h" // for ArmarXManagerPtr, etc
81 #include "properties/IceProperties.h" // for IceProperties
82 
83 #ifndef WIN32
84 #include <signal.h> // for signal, SIGABRT, SIGSEGV, etc
85 
86 #include <cstdio>
87 
88 #include <ArmarXCore/core/util/OnScopeExit.h> // for ARMARX_ON_SCOPE_EXIT
89 
90 #include <execinfo.h>
91 #endif
92 
93 #include <stdlib.h>
94 
95 
96 using namespace armarx;
97 
98 // static members for the one application instance (maybe not required anymore???)
99 std::mutex Application::instanceMutex;
100 ApplicationPtr Application::instance;
101 Ice::StringSeq Application::ProjectDependendencies;
102 std::string Application::ProjectName;
103 const std::string Application::ArmarXUserConfigDirEnvVar = "ARMARX_CONFIG_DIR";
104 std::string errormsg = "Segmentation fault - Backtrace: \n";
105 bool crashed = false;
106 
107 
108 void
110 {
111  if (crashed)
112  {
113  return;
114  }
115  crashed = true;
116 
117  // dont allocate memory in segfault
118  if (sig == SIGSEGV)
119  {
120  std::array<void*, 20> array;
121  size_t size;
122  size = backtrace(array.data(), 20);
123 
124 #pragma GCC diagnostic push
125 #pragma GCC diagnostic ignored "-Wunused-result"
126  write(STDERR_FILENO, errormsg.data(), errormsg.size());
127 #pragma GCC diagnostic pop
128  backtrace_symbols_fd(array.data(), size, STDERR_FILENO);
129  exit(EXIT_FAILURE);
130  }
131  // print out all the frames to stderr
132  std::stringstream str;
133 
134  if (sig == SIGABRT)
135  {
136  str << "Error: Abort\nBacktrace:\n";
137  }
138  else
139  {
140  str << "Error: signal " << sig;
141  }
142 
143  ARMARX_FATAL_S << str.str() << "\nBacktrace:\n" << LogSender::CreateBackTrace();
144  if ((sig == SIGSEGV || sig == SIGABRT) && Application::getInstance() &&
145  Application::getInstance()->getProperty<bool>("StartDebuggerOnCrash").getValue())
146  {
147  std::stringstream s;
148  int res;
149  // res = system("which qtcreator");
150  // res = WEXITSTATUS(res);
151  // if (res == EXIT_SUCCESS)
152  {
153  s << "qtcreator -debug " << getpid();
154  ARMARX_IMPORTANT << s.str();
155  res = system(s.str().c_str());
156  res++; // suppress warning
157  }
158  // else
159  // {
160  // ARMARX_INFO_S << "Could not find qtcreator";
161  // }
162  }
163  exit(EXIT_FAILURE);
164 }
165 
166 void
167 Application::loadLibrariesFromProperties()
168 {
169  auto loadLibString = getProperty<std::string>("LoadLibraries").getValue();
170  if (!loadLibString.empty())
171  {
172  if (!libLoadingEnabled)
173  {
174  throw LocalException("Loading of dynamic libraries is not enabled in this application. "
175  "The Application needs to call enableLibLoading()");
176  }
177  auto entries = armarx::Split(loadLibString, ";", true, true);
178  for (auto& entry : entries)
179  {
180  try
181  {
182  std::filesystem::path path;
183  if (armarx::Contains(entry, "/"))
184  {
185  path = entry;
186  }
187  else
188  {
189  auto elements = Split(entry, ":");
190  ARMARX_CHECK_EQUAL(elements.size(), 2);
191  std::string libFileName = "lib" + elements.at(1) + "." +
193  CMakePackageFinder p(elements.at(0));
194  for (auto& libDir : armarx::Split(p.getLibraryPaths(), ";"))
195  {
196  std::filesystem::path testPath(libDir);
197  testPath /= libFileName;
198  if (std::filesystem::exists(testPath))
199  {
200  path = testPath;
201  break;
202  }
203  }
204  if (path.empty())
205  {
206  ARMARX_ERROR << "Could find library '" << libFileName
207  << "' in any of the following paths: " << p.getLibraryPaths();
208  continue;
209  }
210  }
211  ARMARX_CHECK_EXPRESSION(!path.empty());
212  DynamicLibrary lib;
213  lib.setUnloadOnDestruct(false);
214  ARMARX_VERBOSE << "Loading library " << path.string();
215  lib.load(path);
216  }
217  catch (...)
218  {
220  }
221  }
222  }
223 }
224 
225 bool
227 {
228  return forbidThreadCreation;
229 }
230 
231 void
233 {
234  forbidThreadCreation = value;
235  if (forbidThreadCreation)
236  {
237  ARMARX_INFO << "Thread creation with RunningTask and PeriodicTask is now forbidden in this "
238  "process.";
239  }
240  else
241  {
242  ARMARX_INFO << "Thread creation with RunningTask and PeriodicTask is now allowed again in "
243  "this process.";
244  }
245 }
246 
247 void
249 {
250  this->libLoadingEnabled = enable;
251 }
252 
253 void
255 {
256  ARMARX_CHECK_EXPRESSION(commandLineArguments.empty())
257  << "Command line arguments were already set: " << VAROUT(commandLineArguments);
258  commandLineArguments.reserve(argc);
259  for (int i = 0; i < argc; ++i)
260  {
261  commandLineArguments.emplace_back(argv[i]);
262  }
263 }
264 
265 const std::vector<std::string>&
267 {
268  return commandLineArguments;
269 }
270 
271 void
273 {
275  {
276  Application::getInstance()->interruptCallback(sig);
277  }
278 }
279 
280 
281 // main entry point of Ice::Application
283 {
284 }
285 
286 
289 {
290  std::unique_lock lock(instanceMutex);
291 
292  return instance;
293 }
294 
295 void
297 {
298  std::unique_lock lock(instanceMutex);
299 
300  instance = inst;
301 }
302 
303 
304 void
306 {
307  // call base class method
308  PropertyUser::setIceProperties(properties);
309  // set the properties of all components
310  if (armarXManager)
311  {
312  armarXManager->setComponentIceProperties(properties);
313  }
314 }
315 
316 
317 void
318 Application::updateIceProperties(const Ice::PropertyDict& properties)
319 {
320  // call base class method
322  // update the properties of all components
323  if (armarXManager)
324  {
325  armarXManager->updateComponentIceProperties(properties);
326  }
327 }
328 
329 
330 void
331 Application::icePropertiesUpdated(const std::set<std::string>& changedProperties)
332 {
333  if (armarXManager)
334  {
335  if (changedProperties.count("DisableLogging") &&
336  getProperty<bool>("DisableLogging").isSet())
337  {
338  // ARMARX_INFO << "Logging disabled: " << getProperty<bool>("DisableLogging").getValue();
339  armarXManager->enableLogging(!getProperty<bool>("DisableLogging").getValue());
340  }
341 
342  if (changedProperties.count("EnableProfiling"))
343  {
344  armarXManager->enableProfiling(getProperty<bool>("EnableProfiling").getValue());
345  }
346  if (changedProperties.count("Verbosity"))
347  {
348  armarXManager->setGlobalMinimumLoggingLevel(
349  getProperty<MessageTypeT>("Verbosity").getValue());
350  }
351  }
352 }
353 
354 const ThreadPoolPtr&
356 {
357  return threadPool;
358 }
359 
360 
361 int
362 Application::run(int argc, char* argv[])
363 {
364 #ifndef WIN32
365  // register signal handler
366  signal(SIGILL, Application::HandlerFault);
367  signal(SIGSEGV, Application::HandlerFault);
368  signal(SIGABRT, Application::HandlerFault);
369 
370  signal(SIGHUP, Application::HandlerInterrupt);
371  signal(SIGINT, Application::HandlerInterrupt);
372  signal(SIGTERM, Application::HandlerInterrupt);
373 #endif
374 
375  ARMARX_TRACE;
376 
377  // parse options and merge these with properties passed via Ice.Config
378  Ice::PropertiesPtr properties = parseOptionsMergeProperties(argc, argv);
379 
380  // parse help options
381  ARMARX_TRACE;
382 
384  ApplicationOptions::parseHelpOptions(properties, argc, argv);
385 
386  if (options.error)
387  {
388  // error in options
389  return EXIT_FAILURE;
390  }
391  else if (options.showHelp) // display help
392  {
393  showHelp(options);
394  return EXIT_SUCCESS;
395  }
396  else if (options.showVersion)
397  {
398  std::cout << "Version: " << GetVersion() << std::endl;
399  return EXIT_SUCCESS;
400  }
401 
402  ARMARX_TRACE;
403 
404  setIceProperties(properties);
405 
406  // Override environment variables if set.
407  {
408  ARMARX_TRACE;
409 
410  const Ice::PropertyDict& env_props =
411  getPropertyDefinitions()->getProperties()->getPropertiesForPrefix("env");
412 
413  for (const auto& [name, value] : env_props)
414  {
415  const std::string short_name = name.substr(4); // Cut "env.".
416  ARMARX_INFO << "Setting environment variable '" << short_name << "' to value '" << value
417  << "'.";
418  setenv(short_name.c_str(), value.c_str(), 1);
419  }
420  }
421 
422  if (getProperty<std::uint64_t>("SecondsStartupDelay").isSet())
423  {
424  const auto delay = getProperty<std::uint64_t>("SecondsStartupDelay").getValue();
425  ARMARX_INFO << "startup delay: " << delay << " seconds";
426  std::this_thread::sleep_for(std::chrono::seconds{delay});
427  }
428  else
429  {
430  ARMARX_DEBUG << "startup delay is not set";
431  }
432 
433  // extract application name
434  if (getProperty<std::string>("ApplicationName").isSet())
435  {
436  applicationName = getProperty<std::string>("ApplicationName").getValue();
437  }
438  LogSender::SetLoggingGroup(getProperty<std::string>("LoggingGroup").getValue());
439 
440  // Redirect std::cout and std::cerr
441  const bool redirectStdout = getProperty<bool>("RedirectStdout").getValue();
442  ArmarXLogBuf buf("std::cout", MessageTypeT::INFO, false);
443  ArmarXLogBuf errbuf("std::cerr", MessageTypeT::WARN, true);
444  std::streambuf* cout_sbuf = nullptr;
445  std::streambuf* cerr_sbuf = nullptr;
446  if (redirectStdout)
447  {
448  cout_sbuf = std::cout.rdbuf();
449  cerr_sbuf = std::cerr.rdbuf();
450  std::cout.rdbuf(&buf);
451  std::cerr.rdbuf(&errbuf);
452  }
454  {
455  //reset std::cout and std::cerr to original stream
456  if (redirectStdout)
457  {
458  std::cout.rdbuf(cout_sbuf);
459  std::cerr.rdbuf(cerr_sbuf);
460  }
461  };
462 
463  int result = EXIT_SUCCESS;
464 
465  threadPool.reset(new ThreadPool(getProperty<unsigned int>("ThreadPoolSize").getValue()));
466  // create the ArmarXManager and set its properties
467  try
468  {
469  armarXManager = new ArmarXManager(applicationName, communicator());
470  }
471  catch (Ice::ConnectFailedException&)
472  {
473  return EXIT_FAILURE;
474  }
475 
476  armarXManager->setDataPaths(getProperty<std::string>("DataPath").getValue());
477 
478  // set the properties again, since the armarx manager is now available
479  setIceProperties(properties);
480 
482 
483 #ifdef WIN32
484  // register interrupt handler
485  callbackOnInterrupt();
486 #endif
487 
488 
489  if (applicationNetworkStats)
490  {
491  ProfilerListenerPrx profilerTopic =
492  armarXManager->getIceManager()->getTopic<ProfilerListenerPrx>(
493  armarx::Profiler::PROFILER_TOPIC_NAME);
494  applicationNetworkStats->start(profilerTopic, applicationName);
495  }
496 
497  loadLibrariesFromProperties();
498 
499  try
500  {
501  // calls virtual setup in order to allow subclass to add components to the application
502  setup(armarXManager, properties);
503  }
504  catch (...)
505  {
507  armarXManager->shutdown();
508  }
509 
510  // calls exec implementation
511  result = exec(armarXManager);
513 
514  if (shutdownThread)
515  {
516  ARMARX_VERBOSE << "joining shutdown thread!";
517  shutdownThread->join();
518  }
519  ARMARX_VERBOSE << "Application run finished";
520  return result;
521 }
522 
523 /*
524  * the default exec implementation. Exec is always blocking and waits for
525  * shutdown
526  */
527 int
528 Application::exec(const ArmarXManagerPtr& armarXManager)
529 {
530  armarXManager->waitForShutdown();
531 
532  return 0;
533 }
534 
535 
538 {
539  // parse options and merge these with properties passed via Ice.Config
540  // Here, use armarx::IceProperties instead of Ice::Properties
541  // to support property inheritance.
543  ApplicationOptions::mergeProperties(communicator()->getProperties()->clone(), argc, argv));
544 
545  // Load config files passed via ArmarX.Config
546  std::string configFiles = communicator()->getProperties()->getProperty("ArmarX.Config");
547 
548  PropertyDefinition<std::string>::removeQuotes(configFiles, configFiles);
549 
550  // if not set, size is zero
551  // if set with out value (== "1" as TRUE), size is one
552  if (!configFiles.empty() && configFiles.compare("1") != 0)
553  {
554  std::vector<std::string> configFileList = simox::alg::split(configFiles, ",");
555 
556  for (std::string configFile : configFileList)
557  {
558  if (!configFile.empty())
559  {
560  properties->load(configFile);
561  }
562  }
563  }
564  return properties;
565 }
566 
567 
568 void
570 {
571  // perform dummy setup to register ManagedIceObjects
572  ArmarXDummyManagerPtr dummyManager = new ArmarXDummyManager();
573 
574  LogSender::SetLoggingActivated(false, false);
575 
576  setup(dummyManager, getIceProperties());
577 
578  if (options.outfile.empty())
579  {
580  ApplicationOptions::showHelp(this, dummyManager, options, nullptr);
581  }
582  else
583  {
584  std::ofstream out(options.outfile);
585  if (out.is_open())
586  {
587  ApplicationOptions::showHelp(this, dummyManager, options, nullptr, out);
588  }
589  else
590  {
592  ApplicationOptions::showHelp(this, dummyManager, options, nullptr);
593 
594  std::cout << "Could not write to file " << options.outfile << std::endl;
595  }
596  }
597 }
598 
599 
600 std::string
602 {
603  return "ArmarX";
604 }
605 
606 void
607 Application::setName(const std::string& name)
608 {
609  this->applicationName = name;
610 }
611 
612 std::string
614 {
615  return applicationName;
616 }
617 
618 void
620 {
621  ARMARX_INFO_S << "Interrupt received: " << signal;
622  if (applicationNetworkStats)
623  {
624  applicationNetworkStats->stopTask();
625  }
626  if (!shutdownThread)
627  shutdownThread.reset(new std::thread{[this]
628  {
629  if (armarXManager)
630  this->armarXManager->shutdown();
631  }});
632 }
633 
634 void
636 {
637  IceUtil::Time start = IceUtil::Time::now();
638  ARMARX_INFO_S << "Deps: " << dependencies;
639  dependencies = simox::alg::replace_all(dependencies, "\"", "");
640  Ice::StringSeq resultList = simox::alg::split(dependencies, "/");
641 
642  for (size_t i = 0; i < resultList.size(); i++)
643  {
644  CMakePackageFinder pack(resultList[i]);
645 
646  if (pack.packageFound())
647  {
649  }
650  }
651 
652  ARMARX_INFO_S << "loading took " << (IceUtil::Time::now() - start).toMilliSeconds();
653 }
654 
655 std::vector<std::string>
657 {
658  Ice::StringSeq result = getProperty<Ice::StringSeq>("DefaultPackages").getValue();
659  Ice::StringSeq additional = getProperty<Ice::StringSeq>("AdditionalPackages").getValue();
660  result.insert(result.end(), additional.begin(), additional.end());
661 
662  return result;
663 }
664 
665 std::string
667 {
668  char* env_armarx_workspace = getenv("ARMARX_WORKSPACE");
669  char* env_armarx_default_config_dir_name = getenv("ARMARX_CONFIG_DIR_NAME");
670 
671  std::filesystem::path armarx_workspace;
672  std::filesystem::path armarx_config_dir;
673 
674  if (env_armarx_workspace)
675  {
676  armarx_workspace = std::filesystem::path(env_armarx_workspace);
677  }
678  else
679  {
680  char* home = getenv("HOME");
681 
682  if (home)
683  {
684  armarx_workspace = std::filesystem::path(home);
685  }
686  else
687  {
688  armarx_workspace = "~/";
689  }
690  }
691 
692  if (env_armarx_default_config_dir_name)
693  {
694  armarx_config_dir = std::filesystem::path(env_armarx_default_config_dir_name);
695  }
696  else
697  {
698  if (env_armarx_workspace)
699  {
700  armarx_config_dir = "armarx_config";
701  }
702  // Legacy mode.
703  else
704  {
705  armarx_config_dir = ".armarx";
706  }
707  }
708 
709  if (envVarExpanded)
710  {
711  return (armarx_workspace / armarx_config_dir).string();
712  }
713  else
714  {
715  if (env_armarx_workspace)
716  {
717  return "${ARMARX_WORKSPACE}/" + armarx_config_dir.string();
718  }
719  // Legacy mode.
720  else
721  {
722  return "${HOME}/" + armarx_config_dir.string();
723  }
724  }
725 }
726 
729 {
730  return armarXManager;
731 }
732 
733 
734 int
735 Application::doMain(int argc, char* argv[], const Ice::InitializationData& initData, Ice::Int i)
736 {
737  // create copy of initData so the stats object can be added
738  // using const_cast leads to unexpected errors
739  Ice::InitializationData id(initData);
740  loadDefaultConfig(argc, argv, id);
741 
742  // enable the PropertyAdmin ObjectAdapter
743  // https://doc.zeroc.com/display/Ice35/The+Administrative+Object+Adapter
744  if (id.properties->getProperty("Ice.Admin.InstanceName").empty())
745  {
746  id.properties->setProperty("Ice.Admin.InstanceName", this->getName());
747  }
748  if (id.properties->getProperty("Ice.Admin.Endpoints").empty())
749  {
750  id.properties->setProperty("Ice.Admin.Endpoints", "tcp -h 127.0.0.1");
751  }
752 
753  if (initData.properties->getProperty("ArmarX.NetworkStats") == "1")
754  {
755  applicationNetworkStats = new ApplicationNetworkStats();
756  id.observer = applicationNetworkStats;
757 
758  const auto oldFacets = initData.properties->getPropertyAsList("Ice.Admin.Facets");
759  if (oldFacets.empty())
760  {
761  initData.properties->setProperty("Ice.Admin.Facets", "Metrics");
762  }
763  else if (std::find(oldFacets.begin(), oldFacets.end(), "Metrics") == oldFacets.end())
764  {
765  std::stringstream str;
766  str << "Metrics";
767  for (const auto& facet : oldFacets)
768  {
769  str << "," << facet;
770  }
771  initData.properties->setProperty("Ice.Admin.Facets", str.str());
772  }
773  initData.properties->setProperty("IceMX.Metrics.NetworkStats.GroupBy", "none");
774  }
775 
776  return Ice::Application::doMain(argc, argv, id, i);
777 }
778 
779 
780 Ice::StringSeq
782 {
783  const std::string configFileName = "default.cfg";
784  const std::string generatedConfigFileName = "default.generated.cfg";
785  Ice::StringSeq defaultsPaths;
786  char* defaultsPathVar = getenv(ArmarXUserConfigDirEnvVar.c_str());
787  std::filesystem::path absBasePath;
788  if (defaultsPathVar)
789  {
790  absBasePath = defaultsPathVar;
791  }
792  else
793  {
794  absBasePath = std::filesystem::path(GetArmarXConfigDefaultPath());
795  }
796  defaultsPaths.push_back((absBasePath / configFileName).string());
797  defaultsPaths.push_back((absBasePath / generatedConfigFileName).string());
798  return defaultsPaths;
799 }
800 
801 
802 void
803 Application::loadDefaultConfig(int argc, char* argv[], const Ice::InitializationData& initData)
804 {
805  LoadDefaultConfig(initData.properties);
806 }
807 
808 void
810 {
811  const Ice::StringSeq defaultsPath = GetDefaultsPaths();
813 
814  for (std::string path : defaultsPath)
815  {
816  try
817  {
818  p->load(path);
819 
820  Ice::PropertyDict defaultCfg = p->getPropertiesForPrefix("");
821 
822  // copy default config into current config (if values are not already there)
823  for (auto e : defaultCfg)
824  {
825  if (properties->getProperty(e.first).empty())
826  {
827  properties->setProperty(e.first, e.second);
828  }
829  }
830  }
831  catch (Ice::FileException& e)
832  {
833  ARMARX_WARNING_S << "Loading default config failed: " << e.what();
834  }
835  }
836 }
837 
838 
839 const std::string&
841 {
842  return ProjectName;
843 }
844 
845 
846 const Ice::StringSeq&
848 {
849  return ProjectDependendencies;
850 }
851 
852 
855 {
857 }
858 
859 
860 void
862 {
863  std::string dependenciesConfig = getIceProperties()->getProperty("ArmarX.DependenciesConfig");
864 
865  if (!dependenciesConfig.empty())
866  {
867  if (std::filesystem::exists(dependenciesConfig))
868  {
870  prop->load(dependenciesConfig);
871  ArmarXDataPath::addDataPaths(prop->getProperty("ArmarX.ProjectDatapath"));
872  ProjectName = prop->getProperty("ArmarX.ProjectName");
873  std::string dependencies = prop->getProperty("ArmarX.ProjectDependencies");
874  ProjectDependendencies = simox::alg::split(dependencies, ";");
875  }
876  else
877  {
878  /*
879  ARMARX_WARNING_S << "The given project datapath config file '" << datapathConfig << "', that this app depends on, could not be found. \
880  Relative paths to subprojects are not available. Set the property ArmarX.ProjectDatapath to empty, if you do not need the paths.";
881  */
882  }
883  }
884 }
885 
886 
889 {
890  defineOptionalProperty<std::string>(
891  "Config", "", "Comma-separated list of configuration files ");
892  defineOptionalProperty<std::string>(
893  "DependenciesConfig",
894  "./config/dependencies.cfg",
895  "Path to the (usually generated) config file containing all data paths of all dependent "
896  "projects. This property usually does not need to be edited.");
897  defineOptionalProperty<Ice::StringSeq>(
898  "DefaultPackages",
899  {"ArmarXCore",
900  "ArmarXGui",
901  "MemoryX",
902  "RobotAPI",
903  "RobotComponents",
904  "RobotSkillTemplates",
905  "ArmarXSimulation",
906  "VisionX",
907  "SpeechX",
908  "Armar3",
909  "Armar4",
910  "Spoac"},
911  "List of ArmarX packages which are accessible by default. Comma separated List. If you "
912  "want to add your own packages and use all default ArmarX packages, use the property "
913  "'AdditionalPackages'.");
914  defineOptionalProperty<Ice::StringSeq>(
915  "AdditionalPackages",
916  {},
917  "List of additional ArmarX packages which should be in the list of default packages. If "
918  "you have custom packages, which should be found by the gui or other apps, specify them "
919  "here. Comma separated List.");
920 
921  defineOptionalProperty<std::string>("ApplicationName", "", "Application name");
922 
923  defineOptionalProperty<bool>("DisableLogging",
924  false,
925  "Turn logging off in whole application",
927 
928  defineOptionalProperty<MessageTypeT>("Verbosity",
930  "Global logging level for whole application",
932 
933  defineOptionalProperty<std::string>(
934  "LoggingGroup",
935  "",
936  "The logging group is transmitted with every ArmarX log message over Ice in order to group "
937  "the message in the GUI.");
938 
939 
940  defineOptionalProperty<std::string>(
941  "DataPath", "", "Semicolon-separated search list for data files");
942 
943  defineOptionalProperty<std::string>(
944  "CachePath",
945  "mongo/.cache",
946  std::string("Path for cache files. If relative path AND env. variable ") +
948  " is set, the cache path will be made relative to " +
950  ". Otherwise if relative it will be relative to the default ArmarX config dir (" +
952 
953  defineOptionalProperty<bool>("EnableProfiling",
954  false,
955  "Enable profiling of CPU load produced by this application",
957 
958  defineOptionalProperty<bool>(
959  "RedirectStdout", true, "Redirect std::cout and std::cerr to ArmarXLog");
960 
961  defineOptionalProperty<std::string>(
962  "TopicSuffix",
963  "",
964  "Suffix appended to all topic names for outgoing topics. This is mainly used to direct all "
965  "topics to another name for TopicReplaying purposes.");
966 
967  defineOptionalProperty<bool>(
968  "UseTimeServer", false, "Enable using a global Timeserver (e.g. from ArmarXSimulator)");
969 
970  defineOptionalProperty<unsigned int>(
971  "RemoteHandlesDeletionTimeout",
972  3000,
973  "The timeout (in ms) before a remote handle deletes the managed object after the use count "
974  "reached 0. This time can be used by a client to increment the count again (may be "
975  "required when transmitting remote handles)");
976  defineOptionalProperty<bool>("StartDebuggerOnCrash",
977  false,
978  "If this application crashes (segmentation fault) qtcreator will "
979  "attach to this process and start the debugger.");
980  defineOptionalProperty<unsigned int>(
981  "ThreadPoolSize", 1, "Size of the ArmarX ThreadPool that is always running.");
982  defineOptionalProperty<std::string>(
983  "LoadLibraries",
984  "",
985  "Libraries to load at start up of the application. Must be enabled by the Application with "
986  "enableLibLoading(). Format: PackageName:LibraryName;... or /absolute/path/to/library;...");
987  defineOptionalProperty<std::uint64_t>(
988  "SecondsStartupDelay",
989  0,
990  "The startup will be delayed by this number of seconds (useful for debugging)");
991 }
ARMARX_VERBOSE
#define ARMARX_VERBOSE
Definition: Logging.h:180
armarx::Application::run
int run(int argc, char *argv[]) override
Ice::Application replacement for the main function.
Definition: Application.cpp:362
armarx::Application::GetProjectName
static const std::string & GetProjectName()
Definition: Application.cpp:840
armarx::Application::Application
Application()
Application initalizes the Ice::Application base class.
Definition: Application.cpp:282
str
std::string str(const T &t)
Definition: UserAssistedSegmenterGuiWidgetController.cpp:42
armarx::Application::getCommandLineArguments
const std::vector< std::string > & getCommandLineArguments() const
Definition: Application.cpp:266
armarx::ApplicationOptions::mergeProperties
Ice::PropertiesPtr mergeProperties(Ice::PropertiesPtr properties, int argc, char *argv[])
Merge command line options into properties.
Definition: ApplicationOptions.cpp:59
errormsg
std::string errormsg
Definition: Application.cpp:104
armarx::Application::exec
virtual int exec(const ArmarXManagerPtr &armarXManager)
Exec method is the main process of the application.
Definition: Application.cpp:528
armarx::MessageTypeT::WARN
@ WARN
ARMARX_IMPORTANT
#define ARMARX_IMPORTANT
Definition: Logging.h:183
armarx::CMakePackageFinder::packageFound
bool packageFound() const
Returns whether or not this package was found with cmake.
Definition: CMakePackageFinder.cpp:485
armarx::Application::getDefaultPackageNames
std::vector< std::string > getDefaultPackageNames()
getDefaultPackageNames returns the value of the ArmarX.DefaultPackages property It splits the string ...
Definition: Application.cpp:656
armarx::Application::setup
virtual void setup(const ManagedIceObjectRegistryInterfacePtr &registry, Ice::PropertiesPtr properties)=0
Setup method to be implemented by user applications.
OnScopeExit.h
armarx::Application::storeCommandLineArguments
void storeCommandLineArguments(int argc, char *argv[])
Definition: Application.cpp:254
ArmarXManager.h
armarx::MessageTypeT::INFO
@ INFO
armarx::Application::parseOptionsMergeProperties
Ice::PropertiesPtr parseOptionsMergeProperties(int argc, char *argv[])
Parse options given on the commandline and merge them into the regular properties.
Definition: Application.cpp:537
DynamicLibrary.h
armarx::Contains
bool Contains(const ContainerType &container, const ElementType &searchElement)
Definition: algorithm.h:295
armarx::aron::write
void write(WriterT &aron_w, const armarx::FramedPosition &input, typename WriterT::ReturnType &ret, const armarx::aron::Path &aron_p=armarx::aron::Path())
Definition: framed.h:21
armarx::ThreadPool
The ThreadPool class.
Definition: ThreadPool.h:45
armarx::DynamicLibrary::load
void load(std::filesystem::path libPath)
Loads a shared library from the specified path.
Definition: DynamicLibrary.cpp:54
armarx::Application::HandlerFault
static void HandlerFault(int sig)
handlerFault handles signals sendt to the application such as SIGSEGF or SIGABRT (Linux)
Definition: Application.cpp:109
armarx::Application::createPropertyDefinitions
PropertyDefinitionsPtr createPropertyDefinitions() override
Definition: Application.cpp:854
armarx::Split
std::vector< std::string > Split(const std::string &source, const std::string &splitBy, bool trimElements=false, bool removeEmptyElements=false)
Definition: StringHelperTemplates.h:35
armarx::LogSender::SetSendLoggingActivated
static void SetSendLoggingActivated(bool activated=true)
Definition: LogSender.cpp:701
armarx::Application::GetDefaultsPaths
static Ice::StringSeq GetDefaultsPaths()
Definition: Application.cpp:781
armarx::CMakePackageFinder
The CMakePackageFinder class provides an interface to the CMake Package finder capabilities.
Definition: CMakePackageFinder.h:53
armarx::Application::loadDefaultConfig
void loadDefaultConfig(int argc, char *argv[], const Ice::InitializationData &initData)
Definition: Application.cpp:803
armarx::ApplicationOptions::eHelpBrief
@ eHelpBrief
Definition: ApplicationOptions.h:64
armarx::ApplicationOptions::parseHelpOptions
Options parseHelpOptions(Ice::PropertiesPtr properties, int argc, char *argv[])
Parse the help options.
Definition: ApplicationOptions.cpp:68
armarx::LogSender::SetLoggingGroup
static void SetLoggingGroup(const std::string &loggingGroup)
Definition: LogSender.cpp:154
ARMARX_ON_SCOPE_EXIT
#define ARMARX_ON_SCOPE_EXIT
Executes given code when the enclosing scope is left.
Definition: OnScopeExit.h:112
armarx::Application::GetArmarXConfigDefaultPath
static std::string GetArmarXConfigDefaultPath(bool envVarExpanded=true)
Definition: Application.cpp:666
armarx::ApplicationOptions::Options::showHelp
bool showHelp
Definition: ApplicationOptions.h:78
armarx::DynamicLibrary::GetSharedLibraryFileExtension
static std::string GetSharedLibraryFileExtension()
Definition: DynamicLibrary.cpp:157
ApplicationOptions.h
armarx::Application::getArmarXManager
ArmarXManagerPtr getArmarXManager()
Definition: Application.cpp:728
armarx::ThreadPoolPtr
std::shared_ptr< ThreadPool > ThreadPoolPtr
Definition: Application.h:76
armarx::Application::HandlerInterrupt
static void HandlerInterrupt(int sig)
handlerInterrupt handles interrupt signals sent to the application (Linux)
Definition: Application.cpp:272
IceInternal::Handle< ::Ice::Properties >
armarx::ApplicationNetworkStats
The ApplicationNetworkStats class implements the Ice::Instrumentation::CommunicatorObserver interface...
Definition: ApplicationNetworkStats.h:51
armarx::Application::icePropertiesUpdated
void icePropertiesUpdated(const std::set< std::string > &changedProperties) override
This method is called when new Properties are set via setIceProperties().
Definition: Application.cpp:331
ArmarXDummyManager.h
ARMARX_TRACE
#define ARMARX_TRACE
Definition: trace.h:69
cxxopts::value
std::shared_ptr< Value > value()
Definition: cxxopts.hpp:926
armarx::Application::getDomainName
virtual std::string getDomainName()
Retrieve the domain name used for property parsing.
Definition: Application.cpp:601
Property.h
armarx::DynamicLibrary::setUnloadOnDestruct
void setUnloadOnDestruct(bool unload)
Definition: DynamicLibrary.cpp:142
armarx::Application::setInstance
static void setInstance(ApplicationPtr const &inst)
Definition: Application.cpp:296
ManagedIceObject.h
ThreadPool.h
PropertyUser.h
armarx::ApplicationOptions::Options::format
OptionsFormat format
Definition: ApplicationOptions.h:82
ARMARX_DEBUG
#define ARMARX_DEBUG
Definition: Logging.h:177
armarx::ApplicationOptions::Options::showVersion
bool showVersion
Definition: ApplicationOptions.h:79
armarx::PropertyUser::updateIceProperties
virtual void updateIceProperties(const std::map< std::string, std::string > &changes)
Definition: PropertyUser.cpp:115
armarx::Application::getForbidThreadCreation
bool getForbidThreadCreation() const
Definition: Application.cpp:226
armarx::Application::registerDataPathsFromDependencies
void registerDataPathsFromDependencies(std::string dependencies)
Definition: Application.cpp:635
armarx::ApplicationPropertyDefinitions::ApplicationPropertyDefinitions
ApplicationPropertyDefinitions(std::string prefix)
Definition: Application.cpp:887
armarx::ApplicationOptions::Options
Stucture containing the parsed options of the application.
Definition: ApplicationOptions.h:76
IceManager.h
armarx::LogSender::CreateBackTrace
static std::string CreateBackTrace(int linesToSkip=1)
Definition: LogSender.cpp:501
armarx::IceProperties::create
static Ice::PropertiesPtr create(const Ice::PropertiesPtr &iceProperties=nullptr)
Definition: IceProperties.cpp:32
ApplicationNetworkStats.h
armarx::Application::getThreadPool
const ThreadPoolPtr & getThreadPool() const
Definition: Application.cpp:355
ARMARX_ERROR
#define ARMARX_ERROR
Definition: Logging.h:189
armarx::PropertyDefinitionContainer
PropertyDefinitionContainer.
Definition: PropertyDefinitionContainer.h:53
armarx::Application::getInstance
static ApplicationPtr getInstance()
Retrieve shared pointer to the application object.
Definition: Application.cpp:288
armarx::Application
Baseclass for all ArmarX applications.
Definition: Application.h:193
armarx::ApplicationPropertyDefinitions
Application property definition container.
Definition: Application.h:101
ARMARX_WARNING_S
#define ARMARX_WARNING_S
Definition: Logging.h:206
armarx::armem::Time
armarx::core::time::DateTime Time
Definition: forward_declarations.h:13
armarx::Application::getName
std::string getName() const
Retrieve name of the application.
Definition: Application.cpp:613
ExpressionException.h
CMakePackageFinder.h
Ice
Definition: DBTypes.cpp:64
armarx::Application::setIceProperties
void setIceProperties(Ice::PropertiesPtr properties) override
Overrides PropertyUser::setIceProperties() which is called internally.
Definition: Application.cpp:305
ARMARX_CHECK_EXPRESSION
#define ARMARX_CHECK_EXPRESSION(expression)
This macro evaluates the expression and if it turns out to be false it will throw an ExpressionExcept...
Definition: ExpressionException.h:70
armarx::Application::LoadDefaultConfig
static void LoadDefaultConfig(Ice::PropertiesPtr properties)
Definition: Application.cpp:809
armarx::LogSender::SetLoggingActivated
static void SetLoggingActivated(bool activated=true, bool showMessage=true)
setLoggingActivated() is used to activate or disable the logging facilities in the whole application
Definition: LogSender.cpp:687
PropertyDefinition.hpp
armarx::ApplicationOptions::Options::error
bool error
Definition: ApplicationOptions.h:80
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:174
armarx::ArmarXDummyManager
Handles help and documentation generation but does not provide Ice functionality.
Definition: ArmarXDummyManager.h:52
armarx::ArmarXDataPath::addDataPaths
static void addDataPaths(const std::string &dataPathList)
Definition: ArmarXDataPath.cpp:559
armarx::PropertyDefinition::removeQuotes
bool removeQuotes() const
Definition: PropertyDefinition.hpp:266
VAROUT
#define VAROUT(x)
Definition: StringHelpers.h:182
IceUtil::Handle
Definition: forward_declarations.h:29
armarx::CMakePackageFinder::getIncludePaths
std::string getIncludePaths() const
Returns the include paths separated by semi-colons.
Definition: CMakePackageFinder.h:110
LogSender.h
crashed
bool crashed
Definition: Application.cpp:105
armarx::PropertyUser::getPropertyDefinitions
PropertyDefinitionsPtr getPropertyDefinitions()
Returns the component's property definition container.
Definition: PropertyUser.cpp:61
armarx::VariantType::Int
const VariantTypeId Int
Definition: Variant.h:916
ARMARX_FATAL_S
#define ARMARX_FATAL_S
Definition: Logging.h:212
armarx::Application::GetVersion
static std::string GetVersion()
Definition: Application.h:234
armarx::Application::setForbidThreadCreation
void setForbidThreadCreation(bool value)
Definition: Application.cpp:232
ARMARX_INFO_S
#define ARMARX_INFO_S
Definition: Logging.h:195
armarx::PropertyUser::getIceProperties
Ice::PropertiesPtr getIceProperties() const
Returns the set of Ice properties.
Definition: PropertyUser.cpp:229
armarx::DynamicLibrary
The DynamicLibrary class provides a mechanism to load libraries at runtime.
Definition: DynamicLibrary.h:49
armarx::Application::enableLibLoading
void enableLibLoading(bool enable=true)
Definition: Application.cpp:248
Logging.h
armarx::ApplicationOptions::showHelp
void showHelp(ApplicationPtr application, ArmarXDummyManagerPtr dummyManager, Options options, Ice::PropertiesPtr properties, std::ostream &out=std::cout)
Prints help according to the format selection in options.
Definition: ApplicationOptions.cpp:169
armarx::ApplicationOptions::Options::outfile
std::string outfile
Definition: ApplicationOptions.h:81
ARMARX_CHECK_EQUAL
#define ARMARX_CHECK_EQUAL(lhs, rhs)
This macro evaluates whether lhs is equal (==) rhs and if it turns out to be false it will throw an E...
Definition: ExpressionException.h:128
armarx::handleExceptions
void handleExceptions()
Definition: Exception.cpp:142
ApplicationProcessFacet.h
armarx::PropertyDefinitionsPtr
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
Definition: forward_declarations.h:34
IceProperties.h
armarx::ArmarXLogBuf
Definition: ArmarXLogBuf.h:33
armarx::Application::interruptCallback
void interruptCallback(int signal) override
Cleans up connections with IceStorm before terminating the app.
Definition: Application.cpp:619
ArmarXDataPath.h
armarx::PropertyDefinitionBase::eModifiable
@ eModifiable
Definition: PropertyDefinitionInterface.h:58
armarx::Application::ArmarXUserConfigDirEnvVar
static const std::string ArmarXUserConfigDirEnvVar
Definition: Application.h:294
armarx::Application::setName
void setName(const std::string &name)
Set name of the application.
Definition: Application.cpp:607
armarx::PropertyUser::setIceProperties
virtual void setIceProperties(Ice::PropertiesPtr properties)
Sets the Ice properties.
Definition: PropertyUser.cpp:89
armarx::Application::loadDependentProjectDatapaths
void loadDependentProjectDatapaths()
Definition: Application.cpp:861
armarx::ctrlutil::s
double s(double t, double s0, double v0, double a0, double j)
Definition: CtrlUtil.h:31
armarx::ArmarXManager
Main class of an ArmarX process.
Definition: ArmarXManager.h:95
armarx::Application::updateIceProperties
void updateIceProperties(const Ice::PropertyDict &properties) override
Definition: Application.cpp:318
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:28
armarx::Application::GetProjectDependencies
static const Ice::StringSeq & GetProjectDependencies()
Definition: Application.cpp:847
PropertyDefinition.h
Application.h
armarx::split
std::vector< std::string > split(const std::string &source, const std::string &splitBy, bool trimElements=false, bool removeEmptyElements=false)
Definition: StringHelpers.cpp:36
armarx::Application::doMain
int doMain(int argc, char *argv[], const Ice::InitializationData &initData, Ice::Int i) override
Ice::Application::doMain() is called by Ice::Application::main() and does setup of Ice::Communicator ...
Definition: Application.cpp:735
armarx::Application::showHelp
void showHelp(ApplicationOptions::Options &options)
Print help onto the screen or into a file.
Definition: Application.cpp:569