PythonApplicationManager.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 ArmarXCore::ArmarXObjects::PythonApplicationManager
17  * @author Rainer Kartmann ( rainer dot kartmann 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 <algorithm>
26 
27 #include <SimoxUtility/algorithm/string.h>
28 
32 
33 namespace armarx
34 {
35 
36  const simox::meta::EnumNames<PythonApplicationManager::VenvType>
41  };
42 
43  void
45  const std::string& prefix)
46  {
47  defs->required(
48  armarxPackageName, prefix + "10_ArmarXPackageName", "Name of the ArmarX package.");
49  defs->optional(armarxPythonPackagesDir,
50  prefix + "11_ArmarXPythonPackagesDir",
51  "Directory where python packages are located (relative to the root of the "
52  "ArmarX package).");
53 
54  defs->required(pythonPackageName,
55  prefix + "20_PythonPackageName",
56  "Name of the Python package in the ArmarXPackage/python/ directory.");
57  defs->required(pythonScriptPath,
58  prefix + "21_PythonScriptPath",
59  "Path to the python script (inside the python package).");
60  defs->optional(pythonScriptArgumentsString,
61  prefix + "22_PythonScriptArgs",
62  "Whitespace separated list of arguments.");
63  defs->optional(pythonPathEntriesString,
64  prefix + "23_PythonPathEntries",
65  "Colon-separated list of paths to add to the PYTHONPATH.");
66  defs->optional(pythonPoetry, prefix + "24_PythonPoetry", "Use python poetry.");
67 
68  defs->optional(venvName, prefix + "30_venv.Name", "Name of the virtual environment.");
69  {
70  std::stringstream ss;
71  ss << "Type of the virtual environment."
72  << "\n\t- " << VenvTypeNames.to_name(VenvType::Auto)
73  << " \tDerive automatically."
74  << "\n\t- " << VenvTypeNames.to_name(VenvType::Dedicated)
75  << "\tSearch inside the python package root directory."
76  << "\n\t- " << VenvTypeNames.to_name(VenvType::Shared)
77  << " \tSearch in the shared_envs directory.";
78  defs->optional(venvType, prefix + "31_venv.Type", ss.str()).map(VenvTypeNames);
79  }
80 
81 
82  defs->optional(
83  workingDir,
84  prefix + "40_WorkingDirectory",
85  "If set, this path is used as working directory for the python script (overriding "
86  "BinaryPathAsWorkingDirectory)."
87  "\n${HOME} for env vars, $C{RobotAPI:BINARY_DIR} for CMakePackageFinder vars");
88  }
89 
90  void
91  PythonApplicationManager::Properties::read(PropertyUser& props, const std::string& prefix)
92  {
94 
95  if (props.getProperty<std::string>(prefix + "40_WorkingDirectory").isSet())
96  {
97  workingDir =
98  props.getProperty<std::string>("WorkingDirectory").getValueAndReplaceAllVars();
99  };
100 
101  pythonScriptArgumentsVector =
102  simox::alg::split(pythonScriptArgumentsString, " ", true, true);
103  pythonPathEntriesVector = simox::alg::split(pythonPathEntriesString, ":", true, true);
104  }
105 
108  {
111 
112  properties.defineProperties(defs, "py.");
113 
114  defs->defineOptionalProperty<bool>(
115  "BinaryPathAsWorkingDirectory",
116  false,
117  "If true the path of the binary is set as the working directory.");
118  defs->defineOptionalProperty<bool>(
119  "RestartInCaseOfCrash",
120  false,
121  "Whether the application should be restarted in case it crashed.");
122 
123  defs->defineOptionalProperty<bool>(
124  "DisconnectInCaseOfCrash",
125  true,
126  "Whether this component should disconnect as long as the application is not running.");
127  defs->defineOptionalProperty<int>(
128  "FakeObjectStartDelay",
129  0,
130  "Delay in ms after which the fake armarx object is started on which other apps can "
131  "depend. Not used if property FakeObjectDelayedStartKeyword is used.");
132  defs->defineOptionalProperty<std::string>(
133  "FakeObjectDelayedStartKeyword",
134  "",
135  "If not empty, the start up of the fake armarx object will be delayed until this "
136  "keyword is found in the stdout of the subprocess.");
137  defs->defineOptionalProperty<int>(
138  "KillDelay",
139  2000,
140  "Delay ins ms before the subprocess is killed after sending the stop signal");
141  defs->defineOptionalProperty<bool>(
142  "PythonUnbuffered",
143  true,
144  "If true, PYTHONUNBUFFERED=1 is added to the environment variables.");
145  defs->defineOptionalProperty<bool>("RedirectToArmarXLog",
146  true,
147  "If true, all outputs from the subprocess are printed "
148  "with ARMARX_LOG, otherwise with std::cout");
149  defs->defineOptionalProperty<Ice::StringSeq>(
150  "AdditionalEnvVars",
151  {},
152  "Comma-seperated list of env-var assignment, e.g. MYVAR=1,ADDPATH=/tmp");
153  defs->defineOptionalProperty<Ice::StringSeq>(
154  "Dependencies",
155  {},
156  "Comma-seperated list of Ice Object dependencies. The external app will only be "
157  "started after all dependencies have been found.");
158 
159  return defs;
160  }
161 
162  std::filesystem::path
164  {
165  CMakePackageFinder finder("ArmarXCore");
166  ARMARX_CHECK(finder.packageFound());
167 
168  std::filesystem::path armarxCoreRootPath = finder.getPackageDir();
169  std::filesystem::path armarxCliPath = armarxCoreRootPath / "etc" / "python";
170  return armarxCliPath;
171  }
172 
173  void
175  {
176  ARMARX_TRACE;
177 
178  properties.read(*this, "py.");
179  paths.derive(properties);
180  ARMARX_INFO << paths;
181 
182  {
183  std::stringstream originalPythonPath;
184  if (char* pp = getenv("PYTHONPATH"))
185  {
186  originalPythonPath << pp;
187  }
188  std::vector<std::string> pythonPath = simox::alg::split(originalPythonPath.str(), ":");
189 
190  std::stringstream message;
191  {
192  /* We have to remove the entry of the ArmarX command line interface
193  * (".../armarx/ArmarXCore/etc/python").
194  *
195  * Reason: The ArmarX command line tool (armarx start, armarx gui, ...)
196  * is now running from a proper virtual environment. So inside the "armarx gui"
197  * process, the path of that venv is in the PYTHONPATH.
198  * This can cause "import armarx" to try to import the command line tool
199  * instead of the ArmarX python bindings (which are probably installed
200  * in the called virtual environment).
201  */
202  const std::filesystem::path armarxCliPath = getArmarXCliPath();
203  if (auto it =
204  std::find(pythonPath.begin(), pythonPath.end(), armarxCliPath.string());
205  it != pythonPath.end())
206  {
207  message << "(Removed '" << *it << "' from PYTHONPATH.)";
208  pythonPath.erase(it);
209  }
210  }
211  pythonPath.push_back(this->paths.pythonPackagePath.string());
212  pythonPath.push_back(properties.pythonPathEntriesString);
213 
214  const std::string newPythonpath = simox::alg::join(pythonPath, ":");
215 
216  ARMARX_INFO << "Setting PYTHONPATH:\n\t" << newPythonpath
217  << "\nOriginal PYTHONPATH:\n\t" << originalPythonPath.str() << "\n"
218  << message.str();
219  ;
220  setenv("PYTHONPATH", newPythonpath.c_str(), 1);
221  }
222 
223  inputOk = true;
224 
226  }
227 
228  void
230  {
231  ARMARX_TRACE;
232 
233  if (inputOk)
234  {
236  }
237  }
238 
239  void
241  {
242  ARMARX_TRACE;
243 
244  if (inputOk)
245  {
247  }
248  }
249 
250  void
252  {
253  ARMARX_TRACE;
254 
255  if (inputOk)
256  {
258  }
259  }
260 
261  std::string
263  {
264  return paths.workingDir;
265  }
266 
267  std::string
269  {
270  return paths.pythonBinPath;
271  }
272 
273  void
275  {
276  // Script path
277  args.push_back(paths.pythonScriptPath);
278  // Script args
279  args.insert(args.end(),
280  properties.pythonScriptArgumentsVector.begin(),
281  properties.pythonScriptArgumentsVector.end());
282  }
283 
284  std::ostream&
285  operator<<(std::ostream& os, const PythonApplicationManager::Paths& paths)
286  {
287  os << "ArmarX package path: \t" << paths.armarxPackagePath;
288  os << "\nPython package path: \t" << paths.pythonPackagePath;
289  os << "\nPython script path: \t" << paths.pythonScriptPath;
290  os << "\nVenv path: \t" << paths.venvPath;
291  os << "\nPython binary path: \t" << paths.pythonBinPath;
292  os << "\nWorking directory: \t" << paths.workingDir;
293  return os;
294  }
295 
296  void
298  {
299  ARMARX_TRACE;
300 
301  namespace fs = std::filesystem;
302 
303  armarxPackagePath = findArmarXPackagePath(properties);
304  pythonPackagePath = findPythonPackagePath(properties);
305  pythonScriptPath = findPythonScriptPath(properties);
306 
307  if (properties.pythonPoetry)
308  {
309  std::string cmd = std::string("cd ") +
310  reinterpret_cast<const char*>(pythonPackagePath.u8string().c_str()) +
311  ";poetry env info -p --ansi";
312 
313  std::array<char, 128> buffer;
314 
315  // https://stackoverflow.com/questions/76867698/what-does-ignoring-attributes-on-template-argument-mean-in-this-context
316  // std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd.c_str(), "r"), pclose);
317  std::unique_ptr<FILE, int(*)(FILE*)> pipe(popen(cmd.c_str(), "r"), pclose);
318  if (!pipe)
319  {
320  throw std::runtime_error("popen() failed!");
321  }
322  while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr)
323  {
324  std::string s = buffer.data();
325  s.erase(std::remove(s.begin(), s.end(), '\n'), s.end());
326  venvPath += s;
327  }
328  }
329  else
330  {
331  venvPath = findVenvPath(properties);
332  }
333  pythonBinPath = findPythonBinaryPath(properties);
334 
335  if (properties.workingDir.empty())
336  {
337  workingDir = pythonScriptPath.parent_path();
338  }
339  else
340  {
341  workingDir = properties.workingDir;
342  }
343  }
344 
347  const PythonApplicationManager::Properties& properties) const
348  {
350  if (!finder.packageFound())
351  {
352  std::stringstream ss;
353  ss << "Could not find ArmarX package '" << properties.armarxPackageName << "'.";
354  throw armarx::LocalException(ss.str());
355  }
356  return finder.getPackageDir();
357  }
358 
361  const PythonApplicationManager::Properties& properties) const
362  {
363  return armarxPackagePath / properties.armarxPythonPackagesDir /
364  properties.pythonPackageName;
365  }
366 
369  const PythonApplicationManager::Properties& properties) const
370  {
371  std::vector<path> candidates{pythonPackagePath / properties.pythonPackageName /
372  properties.pythonScriptPath,
373  pythonPackagePath / properties.pythonScriptPath};
374 
375  if (std::optional<path> p = checkCandidateFiles(candidates))
376  {
377  return p.value();
378  }
379  else
380  {
381  std::stringstream ss;
382  ss << "Could not find python script '" << properties.pythonScriptPath << "' "
383  << "in python package '" << properties.pythonPackageName << "' "
384  << "in ArmarX package '" << properties.armarxPackageName << "'. \n"
385  << "Checked candidates: ";
386  for (const path& candidate : candidates)
387  {
388  ss << "\n" << candidate;
389  }
390  throw armarx::LocalException(ss.str());
391  }
392  }
393 
396  const PythonApplicationManager::Properties& properties) const
397  {
398  ARMARX_TRACE;
399 
400  path venvPath;
401  switch (properties.venvType)
402  {
403  case VenvType::Dedicated:
404  venvPath = getDedicatedVenvPath(properties);
405  break;
406 
407  case VenvType::Shared:
408  venvPath = getSharedVenvPath(properties);
409  break;
410 
411  case VenvType::Auto:
412  {
413  std::vector<path> candidates{
414  getDedicatedVenvPath(properties),
415  getSharedVenvPath(properties),
416  };
417  if (std::optional<path> p = checkCandidateDirectories(candidates))
418  {
419  venvPath = p.value();
420  }
421  else
422  {
423  std::stringstream ss;
424  ss << "Could not find dedicated or shared venv '" << properties.venvName << "' "
425  << "in python package '" << properties.pythonPackageName << "' "
426  << "in ArmarX package '" << properties.armarxPackageName << "'. \n"
427  << "Checked candidates: ";
428  for (const path& candidate : candidates)
429  {
430  ss << "\n" << candidate;
431  }
432  throw armarx::LocalException(ss.str());
433  }
434  }
435  break;
436  }
437 
438  if (std::filesystem::is_directory(venvPath))
439  {
440  return venvPath;
441  }
442  else
443  {
444  std::stringstream ss;
445  ss << "Could not find "
446  << simox::alg::to_lower(VenvTypeNames.to_name(properties.venvType)) << " venv '"
447  << properties.venvName << "' ";
448  switch (properties.venvType)
449  {
450  case VenvType::Auto:
451  break;
452  case VenvType::Dedicated:
453  ss << "in python package '" << properties.pythonPackageName << "' ";
454  break;
455  case VenvType::Shared:
456  break;
457  }
458  ss << "in ArmarX package '" << properties.armarxPackageName << "'. \n";
459  ss << "Expected path: \n" << venvPath;
460  throw armarx::LocalException(ss.str());
461  }
462  }
463 
464  auto
466  const PythonApplicationManager::Properties& properties) const -> path
467  {
468  ARMARX_TRACE;
469 
470  const path pythonBinPath = venvPath / "bin" / "python";
471 
472  if (std::filesystem::is_regular_file(pythonBinPath))
473  {
474  return pythonBinPath;
475  }
476  else
477  {
478  std::stringstream ss;
479  ss << "Could not find python binary "
480  << "in " << simox::alg::to_lower(VenvTypeNames.to_name(properties.venvType))
481  << " venv '" << properties.venvName << "' ";
482  switch (properties.venvType)
483  {
484  case VenvType::Auto:
485  break;
486  case VenvType::Dedicated:
487  ss << "in python package '" << properties.pythonPackageName << "' ";
488  break;
489  case VenvType::Shared:
490  break;
491  }
492  ss << "in ArmarX package '" << properties.armarxPackageName << "'. \n";
493  ss << "Expected path: \n" << pythonBinPath;
494  throw armarx::LocalException(ss.str());
495  }
496  }
497 
498  auto
500  -> path
501  {
502  return pythonPackagePath / properties.venvName;
503  }
504 
505  auto
507  {
508  return armarxPackagePath / properties.armarxPythonPackagesDir / sharedVenvsDir /
509  properties.venvName;
510  }
511 
512  std::optional<PythonApplicationManager::Paths::path>
514  const std::vector<PythonApplicationManager::Paths::path>& candidates)
515  {
516  return checkCandidatePaths(
517  candidates, [](const path& p) { return std::filesystem::is_regular_file(p); });
518  }
519 
520  std::optional<PythonApplicationManager::Paths::path>
522  const std::vector<PythonApplicationManager::Paths::path>& candidates)
523  {
524  return checkCandidatePaths(candidates,
525  [](const path& p) { return std::filesystem::is_directory(p); });
526  }
527 
528  std::optional<PythonApplicationManager::Paths::path>
530  const std::vector<PythonApplicationManager::Paths::path>& candidates,
531  std::function<bool(PythonApplicationManager::Paths::path)> existsFn)
532  {
533  auto it = std::find_if(candidates.begin(), candidates.end(), existsFn);
534  if (it != candidates.end())
535  {
536  return *it;
537  }
538  else
539  {
540  return std::nullopt;
541  }
542  }
543 
544 } // namespace armarx
armarx::PythonApplicationManager::Properties::pythonPoetry
bool pythonPoetry
Definition: PythonApplicationManager.h:105
PythonApplicationManager.h
armarx::PythonApplicationManager::Properties::pythonScriptPath
std::string pythonScriptPath
Definition: PythonApplicationManager.h:94
armarx::PythonApplicationManager::onExitComponent
void onExitComponent() override
Definition: PythonApplicationManager.cpp:251
armarx::CMakePackageFinder::packageFound
bool packageFound() const
Returns whether or not this package was found with cmake.
Definition: CMakePackageFinder.cpp:511
LocalException.h
armarx::PythonApplicationManager::Paths::findPythonScriptPath
path findPythonScriptPath(const Properties &properties) const
Definition: PythonApplicationManager.cpp:368
armarx::ExternalApplicationManager::onConnectComponent
void onConnectComponent() override
Definition: ExternalApplicationManager.cpp:200
armarx::PythonApplicationManager::Paths::derive
void derive(const Properties &properties)
Definition: PythonApplicationManager.cpp:297
armarx::PythonApplicationManager::Paths::findArmarXPackagePath
path findArmarXPackagePath(const Properties &properties) const
Definition: PythonApplicationManager.cpp:346
armarx::PythonApplicationManager::Properties::read
void read(PropertyUser &props, const std::string &prefix="")
Definition: PythonApplicationManager.cpp:91
armarx::PythonApplicationManager::VenvTypeNames
static const simox::meta::EnumNames< VenvType > VenvTypeNames
Definition: PythonApplicationManager.h:63
armarx::PythonApplicationManager::Paths::getDedicatedVenvPath
path getDedicatedVenvPath(const Properties &properties) const
Definition: PythonApplicationManager.cpp:499
armarx::CMakePackageFinder
The CMakePackageFinder class provides an interface to the CMake Package finder capabilities.
Definition: CMakePackageFinder.h:52
armarx::PythonApplicationManager::Paths::venvPath
path venvPath
Definition: PythonApplicationManager.h:125
message
message(STATUS "Boost-Library-Dir: " "${Boost_LIBRARY_DIRS}") message(STATUS "Boost-LIBRARIES
Definition: CMakeLists.txt:8
armarx::PythonApplicationManager::VenvType::Auto
@ Auto
armarx::PythonApplicationManager::Properties::defineProperties
void defineProperties(armarx::PropertyDefinitionsPtr defs, const std::string &prefix="")
Definition: PythonApplicationManager.cpp:44
armarx::PythonApplicationManager::VenvType::Dedicated
@ Dedicated
httplib::detail::case_ignore::to_lower
unsigned char to_lower(int c)
Definition: httplib.h:346
armarx::PythonApplicationManager::Properties::venvType
VenvType venvType
Definition: PythonApplicationManager.h:103
ARMARX_CHECK
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
Definition: ExpressionException.h:82
armarx::PythonApplicationManager::Properties::armarxPackageName
std::string armarxPackageName
Definition: PythonApplicationManager.h:89
armarx::PythonApplicationManager::Paths::pythonPackagePath
path pythonPackagePath
Definition: PythonApplicationManager.h:123
armarx::getArmarXCliPath
std::filesystem::path getArmarXCliPath()
Definition: PythonApplicationManager.cpp:163
armarx::ExternalApplicationManager::onInitComponent
void onInitComponent() override
Definition: ExternalApplicationManager.cpp:153
armarx::PythonApplicationManager::Paths::checkCandidateDirectories
static std::optional< path > checkCandidateDirectories(const std::vector< path > &candidates)
Definition: PythonApplicationManager.cpp:521
ARMARX_TRACE
#define ARMARX_TRACE
Definition: trace.h:77
armarx::PythonApplicationManager::Paths::checkCandidateFiles
static std::optional< path > checkCandidateFiles(const std::vector< path > &candidates)
Definition: PythonApplicationManager.cpp:513
armarx::CMakePackageFinder::getPackageDir
std::string getPackageDir() const
Returns the top level path of a source package.
Definition: CMakePackageFinder.h:156
armarx::PythonApplicationManager::Paths::pythonBinPath
path pythonBinPath
Definition: PythonApplicationManager.h:126
armarx::PythonApplicationManager::Properties
Definition: PythonApplicationManager.h:87
armarx::PythonApplicationManager::deriveApplicationPath
std::string deriveApplicationPath() const override
Definition: PythonApplicationManager.cpp:268
armarx::PythonApplicationManager::createPropertyDefinitions
armarx::PropertyDefinitionsPtr createPropertyDefinitions() override
Definition: PythonApplicationManager.cpp:107
armarx::PythonApplicationManager::onDisconnectComponent
void onDisconnectComponent() override
Definition: PythonApplicationManager.cpp:240
armarx::PythonApplicationManager::onConnectComponent
void onConnectComponent() override
Definition: PythonApplicationManager.cpp:229
armarx::PythonApplicationManager::Paths::findPythonBinaryPath
path findPythonBinaryPath(const Properties &properties) const
Definition: PythonApplicationManager.cpp:465
armarx::PythonApplicationManager::Paths::findPythonPackagePath
path findPythonPackagePath(const Properties &properties) const
Definition: PythonApplicationManager.cpp:360
armarx::ExternalApplicationManager::onDisconnectComponent
void onDisconnectComponent() override
Definition: ExternalApplicationManager.cpp:207
armarx::PythonApplicationManager::addApplicationArguments
void addApplicationArguments(Ice::StringSeq &args) override
Definition: PythonApplicationManager.cpp:274
armarx::Component::getConfigIdentifier
std::string getConfigIdentifier()
Retrieve config identifier for this component as set in constructor.
Definition: Component.cpp:79
CMakePackageFinder.h
armarx::PythonApplicationManager::Paths::path
std::filesystem::path path
Definition: PythonApplicationManager.h:116
armarx::PythonApplicationManager::onInitComponent
void onInitComponent() override
Definition: PythonApplicationManager.cpp:174
armarx::PythonApplicationManager::Paths::pythonScriptPath
path pythonScriptPath
Definition: PythonApplicationManager.h:124
armarx::PythonApplicationManager::Properties::armarxPythonPackagesDir
std::string armarxPythonPackagesDir
Definition: PythonApplicationManager.h:90
armarx::ComponentPropertyDefinitions
Default component property definition container.
Definition: Component.h:69
armarx::PythonApplicationManager::Properties::venvName
std::string venvName
Definition: PythonApplicationManager.h:102
armarx::PythonApplicationManager::Paths::checkCandidatePaths
static std::optional< path > checkCandidatePaths(const std::vector< path > &candidates, std::function< bool(path)> existsFn)
Definition: PythonApplicationManager.cpp:529
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:181
armarx::PythonApplicationManager::Paths::findVenvPath
path findVenvPath(const Properties &properties) const
Definition: PythonApplicationManager.cpp:395
armarx::PropertyUser::getProperty
Property< PropertyType > getProperty(const std::string &name)
Property creation and retrieval.
Definition: PropertyUser.h:180
magic_enum::detail::find
constexpr std::size_t find(string_view str, char_type c) noexcept
Definition: magic_enum.hpp:309
IceUtil::Handle< class PropertyDefinitionContainer >
armarx::operator<<
std::ostream & operator<<(std::ostream &os, const PythonApplicationManager::Paths &paths)
Definition: PythonApplicationManager.cpp:285
armarx::PythonApplicationManager::VenvType::Shared
@ Shared
armarx::ExternalApplicationManager::onExitComponent
void onExitComponent() override
Definition: ExternalApplicationManager.cpp:213
armarx::PythonApplicationManager::deriveWorkingDir
std::string deriveWorkingDir() const override
Definition: PythonApplicationManager.cpp:262
armarx::PythonApplicationManager::Properties::pythonPackageName
std::string pythonPackageName
Definition: PythonApplicationManager.h:93
armarx::PythonApplicationManager::Properties::workingDir
std::string workingDir
Definition: PythonApplicationManager.h:107
armarx::PythonApplicationManager::Paths
Definition: PythonApplicationManager.h:114
armarx::PropertyUser
Abstract PropertyUser class.
Definition: PropertyUser.h:63
armarx::PythonApplicationManager::Properties::pythonScriptArgumentsVector
std::vector< std::string > pythonScriptArgumentsVector
Definition: PythonApplicationManager.h:97
armarx::PythonApplicationManager::Paths::workingDir
path workingDir
Definition: PythonApplicationManager.h:127
armarx::PythonApplicationManager::Paths::armarxPackagePath
path armarxPackagePath
Definition: PythonApplicationManager.h:122
armarx::PythonApplicationManager::Paths::getSharedVenvPath
path getSharedVenvPath(const Properties &properties) const
Definition: PythonApplicationManager.cpp:506
armarx::PythonApplicationManager::Properties::pythonScriptArgumentsString
std::string pythonScriptArgumentsString
Whitespace separated list of arguments.
Definition: PythonApplicationManager.h:96
armarx::ctrlutil::s
double s(double t, double s0, double v0, double a0, double j)
Definition: CtrlUtil.h:33
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:27
PluginEnumNames.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:38
armarx::PythonApplicationManager::Properties::pythonPathEntriesString
std::string pythonPathEntriesString
Definition: PythonApplicationManager.h:98