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>
36 def->optional(properties.shortcutPath,
38 "Add path of predefined dashboards. Syntax: Package/folderName/fileName");
43 SkillDashboard::getTimeout(
const std::string& skillId)
45 constexpr bool addToDependencies =
false;
46 const auto& managerPrx =
54 const auto& splitIt = skillId.find(
'/');
55 std::string provider =
"";
56 std::string nameSkill =
"";
58 if (splitIt == std::string::npos)
63 provider = skillId.substr(0, splitIt);
64 nameSkill = skillId.substr(splitIt + 1);
65 skills::manager::dto::ProviderID providerId{.providerName = provider};
67 skills::manager::dto::SkillID skillIdDTO{.providerId = providerId, .skillName = nameSkill};
69 IceUtil::Optional<armarx::skills::manager::dto::SkillDescription> skillDescDTO =
70 managerPrx->getSkillDescription(skillIdDTO);
76 const auto& dto = *skillDescDTO;
81 SkillDashboard::updateTimeoutForShortcut(
const SkillShortcut& shortcut)
83 armarx::core::time::Duration timeout = getTimeout(shortcut.skillId);
84 std::unique_lock timeoutsLock(shortcutNameToTimeoutsMutex);
85 this->shortcutNameToTimeouts[shortcut.shortcutName] = timeout;
86 timeoutsLock.unlock();
90 SkillDashboard::loadShortcuts(
const std::string& packagepath)
92 std::scoped_lock l(registeredShortcutsMutex);
93 this->registeredShortcuts = std::vector<SkillShortcut>();
94 std::stringstream ss(packagepath);
96 std::vector<std::string> result;
97 while (std::getline(ss, item,
'/'))
99 result.push_back(item);
101 if (result.size() < 3)
106 this->packageName = result[0];
108 std::string absoluteFilepath;
109 std::string filename;
110 armarx::CMakePackageFinder finder(result[0]);
111 if (finder.packageFound())
115 std::string packageDataDir = finder.getDataDir();
121 std::string relativeFilename;
122 for (
size_t i = 1; i < result.size() - 1; i++)
124 if (!relativeFilename.empty())
126 relativeFilename +=
"/";
128 relativeFilename += result[i];
131 this->pathToDashboard = relativeFilename;
132 this->dahsboardName = result[result.size() - 1];
136 ARMARX_INFO <<
"Located file at:" << absoluteFilepath;
137 filename = result[result.size() - 1] +
".json";
141 std::ifstream file(absoluteFilepath +
"/" + filename);
142 nlohmann::json jsonData;
151 for (
const auto& item : jsonData[
"shortcuts"])
153 SkillShortcut shortcut;
154 shortcut.skillArgs = item[
"skill_args"].dump(2);
155 shortcut.skillId = item[
"skill_id"];
156 if (item.contains(
"icon_name"))
158 shortcut.iconName = item[
"icon_name"];
162 shortcut.iconName =
"";
164 shortcut.shortcutName = item[
"skill_shortcut_name"];
166 this->registeredShortcuts.push_back(shortcut);
172 ARMARX_WARNING <<
"Configured ArmarX package not found for '" << result[0] <<
"'.";
182 if (not properties.shortcutPath.empty())
184 loadShortcuts(properties.shortcutPath);
191 ARMARX_DEBUG <<
"Skills dashboard component connected.";
197 ARMARX_DEBUG <<
"Getting shortcuts … (registered are " << this->registeredShortcuts.size()
199 return this->registeredShortcuts;
202 SkillShortcutWithTimeoutList
206 std::vector<SkillShortcutWithTimeout> shortcutsWithTimeout;
207 std::scoped_lock l(registeredShortcutsMutex);
208 for (
const auto& shortcut : this->registeredShortcuts)
210 this->updateTimeoutForShortcut(shortcut);
211 SkillShortcutWithTimeout shortcutWithTimeout;
212 shortcutWithTimeout.shortcutName = shortcut.shortcutName;
213 shortcutWithTimeout.skillId = shortcut.skillId;
214 shortcutWithTimeout.skillArgs = shortcut.skillArgs;
215 shortcutWithTimeout.iconName = shortcut.iconName;
217 std::shared_lock timeoutsLock(shortcutNameToTimeoutsMutex);
218 shortcutWithTimeout.timeout.microSeconds =
219 this->shortcutNameToTimeouts[shortcut.shortcutName].toMicroSeconds();
220 timeoutsLock.unlock();
222 shortcutsWithTimeout.push_back(shortcutWithTimeout);
224 return shortcutsWithTimeout;
230 std::scoped_lock l(registeredShortcutsMutex);
231 for (
const SkillShortcut& shortcut : this->registeredShortcuts)
233 if (shortcut.shortcutName == name)
239 return SkillShortcut();
245 if (newShortcut.shortcutName !=
"")
247 if (
getShortcut(newShortcut.shortcutName).shortcutName ==
"")
249 std::unique_lock l(registeredShortcutsMutex);
250 this->registeredShortcuts.push_back(newShortcut);
252 this->updateTimeoutForShortcut(newShortcut);
253 ARMARX_INFO <<
"Added shortcut " << newShortcut.shortcutName;
257 std::optional<SkillShortcut> updatedShortcut;
258 std::unique_lock l(registeredShortcutsMutex);
259 for (SkillShortcut& shortcut : this->registeredShortcuts)
261 if (shortcut.shortcutName == newShortcut.shortcutName)
263 shortcut.skillId = newShortcut.skillId;
264 shortcut.skillArgs = newShortcut.skillArgs;
265 shortcut.iconName = newShortcut.iconName;
267 updatedShortcut = shortcut;
273 this->updateTimeoutForShortcut(*updatedShortcut);
283 std::scoped_lock l(registeredShortcutsMutex);
284 for (
auto it = this->registeredShortcuts.begin(); it != this->registeredShortcuts.end();
287 if (it->shortcutName == name)
289 this->registeredShortcuts.erase(it);
290 std::unique_lock timeoutsLock(shortcutNameToTimeoutsMutex);
291 this->shortcutNameToTimeouts.erase(name);
292 timeoutsLock.unlock();
302 this->shortcutOrder = order;
305 std::vector<std::string>
308 return std::vector<std::string>{
309 this->packageName, this->pathToDashboard, this->dahsboardName};
314 const std::string& folder,
315 const std::string& name,
316 const ::Ice::Current&)
318 std::string path =
package + "/" + folder + "/" + name;
319 return loadShortcuts(path);
324 const std::string& folder,
325 const std::string& name,
326 const ::Ice::Current&)
331 std::unordered_map<std::string, SkillShortcut> lookup;
332 lookup.reserve(registeredShortcuts.size());
333 std::shared_lock shortcutsLock(registeredShortcutsMutex);
334 for (
const auto& s : registeredShortcuts)
336 lookup[s.shortcutName] = s;
338 shortcutsLock.unlock();
341 for (
const auto& name : this->shortcutOrder)
344 auto it = lookup.find(name);
345 if (it == lookup.end())
350 const auto& shortcut = it->second;
352 nlohmann::json skillArgs_json = nlohmann::json::parse(shortcut.skillArgs);
354 j[
"shortcuts"].push_back({
355 {
"skill_shortcut_name", shortcut.shortcutName},
356 {
"skill_id", shortcut.skillId},
357 {
"skill_args", skillArgs_json},
358 {
"icon_name", shortcut.iconName},
362 std::string absoluteFilename;
367 std::string packageDataDir = finder.
getDataDir();
371 std::filesystem::create_directories(packageDataDir +
"/" + folder);
373 std::string relativeFilename(folder);
377 ARMARX_INFO <<
"Located file at:" << absoluteFilename;
378 std::string filename = name +
".json";
379 std::ofstream outFile(absoluteFilename +
"/" + filename);
380 outFile << std::setw(4) << j << std::endl;
382 ARMARX_INFO <<
"Insert " <<
package << "/" << folder << "/" << name
383 << " into the component property.";
#define ARMARX_REGISTER_COMPONENT_EXECUTABLE(ComponentT, applicationName)
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_DEBUG
The logging level for output that is only interesting while debugging.
#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.