14#include <IceUtil/Optional.h>
16#include <nlohmann/json.hpp>
17#include <nlohmann/json_fwd.hpp>
23#include <RobotAPI/interface/skills/SkillManagerInterface.h>
24#include <RobotAPI/interface/skills/SkillMemoryInterface.h>
34 def->optional(properties.shortcutPath,
36 "Add path of predefined dashboards. Syntax: Package/folderName/fileName");
41 SkillDashboard::getTimeout(
const std::string& skillId)
43 constexpr bool addToDependencies =
false;
44 const auto& managerPrx =
52 const auto& splitIt = skillId.find(
'/');
53 std::string provider =
"";
54 std::string nameSkill =
"";
56 if (splitIt == std::string::npos)
61 provider = skillId.substr(0, splitIt);
62 nameSkill = skillId.substr(splitIt + 1);
63 skills::manager::dto::ProviderID providerId{.providerName = provider};
65 skills::manager::dto::SkillID skillIdDTO{.providerId = providerId, .skillName = nameSkill};
67 IceUtil::Optional<armarx::skills::manager::dto::SkillDescription> skillDescDTO =
68 managerPrx->getSkillDescription(skillIdDTO);
74 const auto& dto = *skillDescDTO;
79 SkillDashboard::updateTimeoutForShortcut(
const SkillShortcut& shortcut)
81 armarx::core::time::Duration timeout = getTimeout(shortcut.skillId);
82 std::unique_lock timeoutsLock(shortcutNameToTimeoutsMutex);
83 this->shortcutNameToTimeouts[shortcut.shortcutName] = timeout;
84 timeoutsLock.unlock();
88 SkillDashboard::loadShortcuts(
const std::string& packagepath)
90 std::scoped_lock l(registeredShortcutsMutex);
91 this->registeredShortcuts = std::vector<SkillShortcut>();
92 std::stringstream ss(packagepath);
94 std::vector<std::string> result;
95 while (std::getline(ss, item,
'/'))
97 result.push_back(item);
99 if (result.size() < 3)
104 this->packageName = result[0];
106 std::string absoluteFilepath;
107 std::string filename;
108 armarx::CMakePackageFinder finder(result[0]);
109 if (finder.packageFound())
113 std::string packageDataDir = finder.getDataDir();
119 std::string relativeFilename;
120 for (
size_t i = 1; i < result.size() - 1; i++)
122 if (!relativeFilename.empty())
124 relativeFilename +=
"/";
126 relativeFilename += result[i];
129 this->pathToDashboard = relativeFilename;
130 this->dahsboardName = result[result.size() - 1];
134 ARMARX_INFO <<
"Located file at:" << absoluteFilepath;
135 filename = result[result.size() - 1] +
".json";
139 std::ifstream file(absoluteFilepath +
"/" + filename);
140 nlohmann::json jsonData;
149 for (
const auto& item : jsonData[
"shortcuts"])
151 SkillShortcut shortcut;
152 shortcut.skillArgs = item[
"skill_args"].dump(2);
153 shortcut.skillId = item[
"skill_id"];
154 if (item.contains(
"icon_name"))
156 shortcut.iconName = item[
"icon_name"];
160 shortcut.iconName =
"";
162 shortcut.shortcutName = item[
"skill_shortcut_name"];
164 this->registeredShortcuts.push_back(shortcut);
180 if (not properties.shortcutPath.empty())
182 loadShortcuts(properties.shortcutPath);
194 return this->registeredShortcuts;
197 SkillShortcutWithTimeoutList
200 std::vector<SkillShortcutWithTimeout> shortcutsWithTimeout;
201 std::scoped_lock l(registeredShortcutsMutex);
202 for (
const auto& shortcut : this->registeredShortcuts)
204 this->updateTimeoutForShortcut(shortcut);
205 SkillShortcutWithTimeout shortcutWithTimeout;
206 shortcutWithTimeout.shortcutName = shortcut.shortcutName;
207 shortcutWithTimeout.skillId = shortcut.skillId;
208 shortcutWithTimeout.skillArgs = shortcut.skillArgs;
209 shortcutWithTimeout.iconName = shortcut.iconName;
211 std::shared_lock timeoutsLock(shortcutNameToTimeoutsMutex);
212 shortcutWithTimeout.timeout.microSeconds =
213 this->shortcutNameToTimeouts[shortcut.shortcutName].toMicroSeconds();
214 timeoutsLock.unlock();
216 shortcutsWithTimeout.push_back(shortcutWithTimeout);
218 return shortcutsWithTimeout;
224 std::scoped_lock l(registeredShortcutsMutex);
225 for (
const SkillShortcut& shortcut : this->registeredShortcuts)
227 if (shortcut.shortcutName == name)
233 return SkillShortcut();
239 if (newShortcut.shortcutName !=
"")
241 if (
getShortcut(newShortcut.shortcutName).shortcutName ==
"")
243 std::unique_lock l(registeredShortcutsMutex);
244 this->registeredShortcuts.push_back(newShortcut);
246 this->updateTimeoutForShortcut(newShortcut);
247 ARMARX_INFO <<
"Added shortcut " << newShortcut.shortcutName;
251 std::optional<SkillShortcut> updatedShortcut;
252 std::unique_lock l(registeredShortcutsMutex);
253 for (SkillShortcut& shortcut : this->registeredShortcuts)
255 if (shortcut.shortcutName == newShortcut.shortcutName)
257 shortcut.skillId = newShortcut.skillId;
258 shortcut.skillArgs = newShortcut.skillArgs;
259 shortcut.iconName = newShortcut.iconName;
261 updatedShortcut = shortcut;
267 this->updateTimeoutForShortcut(*updatedShortcut);
277 std::scoped_lock l(registeredShortcutsMutex);
278 for (
auto it = this->registeredShortcuts.begin(); it != this->registeredShortcuts.end();
281 if (it->shortcutName == name)
283 this->registeredShortcuts.erase(it);
284 std::unique_lock timeoutsLock(shortcutNameToTimeoutsMutex);
285 this->shortcutNameToTimeouts.erase(name);
286 timeoutsLock.unlock();
296 this->shortcutOrder = order;
299 std::vector<std::string>
302 return std::vector<std::string>{
303 this->packageName, this->pathToDashboard, this->dahsboardName};
308 const std::string& folder,
309 const std::string& name,
310 const ::Ice::Current&)
312 std::string path =
package + "/" + folder + "/" + name;
313 return loadShortcuts(path);
318 const std::string& folder,
319 const std::string& name,
320 const ::Ice::Current&)
325 std::unordered_map<std::string, SkillShortcut> lookup;
326 lookup.reserve(registeredShortcuts.size());
327 std::shared_lock shortcutsLock(registeredShortcutsMutex);
328 for (
const auto& s : registeredShortcuts)
330 lookup[s.shortcutName] = s;
332 shortcutsLock.unlock();
335 for (
const auto& name : this->shortcutOrder)
338 auto it = lookup.find(name);
339 if (it == lookup.end())
344 const auto& shortcut = it->second;
346 nlohmann::json skillArgs_json = nlohmann::json::parse(shortcut.skillArgs);
348 j[
"shortcuts"].push_back({
349 {
"skill_shortcut_name", shortcut.shortcutName},
350 {
"skill_id", shortcut.skillId},
351 {
"skill_args", skillArgs_json},
352 {
"icon_name", shortcut.iconName},
356 std::string absoluteFilename;
361 std::string packageDataDir = finder.
getDataDir();
365 std::filesystem::create_directories(packageDataDir +
"/" + folder);
367 std::string relativeFilename(folder);
371 ARMARX_INFO <<
"Located file at:" << absoluteFilename;
372 std::string filename = name +
".json";
373 std::ofstream outFile(absoluteFilename +
"/" + filename);
374 outFile << std::setw(4) << j << std::endl;
376 ARMARX_INFO <<
"Insert " <<
package << "/" << folder << "/" << name
377 << " into the component property.";
static bool getAbsolutePath(const std::string &relativeFilename, std::string &storeAbsoluteFilename, const std::vector< std::string > &additionalSearchPaths={}, bool verbose=true)
static void addDataPaths(const std::string &dataPathList)
The CMakePackageFinder class provides an interface to the CMake Package finder capabilities.
std::string getDataDir() const
bool packageFound() const
Returns whether or not this package was found with cmake.
std::string getConfigIdentifier()
Retrieve config identifier for this component as set in constructor.
Property< PropertyType > getProperty(const std::string &name)
Ice::ObjectPrx getProxy(long timeoutMs=0, bool waitForScheduler=true) const
Returns the proxy of this object (optionally it waits for the proxy)
SkillShortcutWithTimeoutList getShortcutsWithTimeout(const ::Ice::Current &=::Ice::Current()) override
void onInitComponent() override
bool importShortcuts(const std::string &package, const std::string &folder, const std::string &name, const ::Ice::Current &=::Ice::Current()) override
void deleteShortcut(const std::string &name, const ::Ice::Current &=::Ice::Current()) override
void addNewShortcut(const SkillShortcut &newShortcut, const ::Ice::Current &=::Ice::Current()) override
void onDisconnectComponent() override
SkillShortcut getShortcut(const std::string &name, const ::Ice::Current &=::Ice::Current()) override
SkillShortcutList getShortcuts(const ::Ice::Current &=::Ice::Current()) override
armarx::PropertyDefinitionsPtr createPropertyDefinitions() override
void saveShortcutOrder(const std::vector< std::string > &order, const ::Ice::Current &=::Ice::Current()) override
void exportShortcuts(const std::string &package, const std::string &folder, const std::string &name, const ::Ice::Current &=::Ice::Current()) override
void onConnectComponent() override
std::vector< std::string > getPathStructure(const ::Ice::Current &=::Ice::Current()) override
void onExitComponent() override
static Duration MicroSeconds(std::int64_t microSeconds)
Constructs a duration in microseconds.
static Duration Seconds(std::int64_t seconds)
Constructs a duration in seconds.
#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_ERROR
The logging level for unexpected behaviour, that must be fixed.
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
This file offers overloads of toIce() and fromIce() functions for STL container types.
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.