Skip to content
Snippets Groups Projects
Commit 02539e19 authored by Rainer Kartmann's avatar Rainer Kartmann
Browse files

Add functions to load recognized and spoken object names

parent 10d4cb9d
No related branches found
No related tags found
1 merge request!118Resolve "Move code from Armar6Skills to ArmarXObjects"
#include <VirtualRobot/XML/ObjectIO.h>
#include <SimoxUtility/algorithm/string.h>
#include <SimoxUtility/filesystem/list_directory.h>
#include <ArmarXCore/core/system/ArmarXDataPath.h>
......@@ -229,6 +230,43 @@ namespace armarx
return loadObstacle(findObject(obj));
}
static std::vector<std::string> _loadNames(
const ObjectFinder& finder,
const ObjectID& objectID,
const bool includeClassName,
const std::function<std::optional<std::vector<std::string>>(const ObjectInfo&)> loadNamesFn)
{
std::vector<std::string> names;
if (includeClassName)
{
names.push_back(simox::alg::to_lower(objectID.className()));
}
if (std::optional<ObjectInfo> info = finder.findObject(objectID))
{
if (std::optional<std::vector<std::string>> loadedNames = loadNamesFn(*info))
{
// Source: https://stackoverflow.com/a/201729
names.insert(names.end(), loadedNames->begin(), loadedNames->end());
}
}
return names;
}
std::vector<std::string> ObjectFinder::loadRecognizedNames(const ObjectID& objectID, bool includeClassName) const
{
return _loadNames(*this, objectID, includeClassName, [](const ObjectInfo& info)
{
return info.loadRecognizedNames();
});
}
std::vector<std::string> ObjectFinder::loadSpokenNames(const ObjectID& objectID, bool includeClassName) const
{
return _loadNames(*this, objectID, includeClassName, [](const ObjectInfo& info)
{
return info.loadSpokenNames();
});
}
ObjectFinder::path ObjectFinder::_rootDirAbs() const
{
return packageDataDir / packageName;
......
......@@ -53,6 +53,32 @@ namespace armarx
static loadObstacle(const std::optional<ObjectInfo>& ts);
VirtualRobot::ObstaclePtr
loadObstacle(const objpose::ObjectPose& obj) const;
/**
* @brief Load names to use when matched when recognizing an object by name.
*
* If the object's names JSON file does not exist, no names will be added from a file.
* If you would like to detect this case, first `findObject()`, then use
* `ObjectInfo::loadRecognizedNames()`, which returns a `std::optional`.
*
* @param includeClassName If true, include the raw class name in the result.
* @see `ObjectInfo::loadRecognizedNames()`
*/
std::vector<std::string> loadRecognizedNames(const ObjectID& objectID, bool includeClassName = false) const;
/**
* @brief Load names to use when verbalizing an object name.
*
* If the object's names JSON file does not exist, no names will be added from a file.
* If you would like to detect this case, first `findObject()`, then use
* `ObjectInfo::loadSpokenNames()`, which returns a `std::optional`.
*
* @param includeClassName If true, include the raw class name in the result.
* @see `ObjectInfo::loadSpokenNames()`
*/
std::vector<std::string> loadSpokenNames(const ObjectID& objectID, bool includeClassName = false) const;
private:
void init() const;
......
#include "ObjectInfo.h"
#include <SimoxUtility/algorithm/string.h>
#include <SimoxUtility/json.h>
#include <SimoxUtility/shapes/AxisAlignedBoundingBox.h>
#include <SimoxUtility/shapes/OrientedBox.h>
......@@ -85,6 +86,11 @@ namespace armarx
return file(".json", "_bb");
}
PackageFileLocation ObjectInfo::namesJson() const
{
return file(".json", "_names");
}
std::optional<simox::AxisAlignedBoundingBox> ObjectInfo::loadAABB() const
{
nlohmann::json j;
......@@ -147,6 +153,47 @@ namespace armarx
return oobb;
}
std::optional<std::vector<std::string>> ObjectInfo::loadRecognizedNames() const
{
return loadNames("recognized_name");
}
std::optional<std::vector<std::string>> ObjectInfo::loadSpokenNames() const
{
return loadNames("spoken_name");
}
std::optional<std::vector<std::string> > ObjectInfo::loadNames(const std::string& jsonKey) const
{
const PackageFileLocation file = namesJson();
if (fs::is_regular_file(file.absolutePath))
{
nlohmann::json json;
try
{
json = nlohmann::read_json(file.absolutePath);
}
catch (const nlohmann::json::exception& e)
{
ARMARX_WARNING << "Failed to parse JSON file " << file.absolutePath << ": \n" << e.what();
return std::nullopt;
}
catch (const std::exception& e)
{
ARMARX_WARNING << "Failed to read file " << file.absolutePath << ": \n" << e.what();
return std::nullopt;
}
return json.at(jsonKey).get<std::vector<std::string>>();
}
else
{
return std::nullopt;
}
}
bool ObjectInfo::checkPaths() const
{
namespace fs = std::filesystem;
......
......@@ -64,6 +64,10 @@ namespace armarx
PackageFileLocation boundingBoxJson() const;
/// File containing recognized and spoken names of objects.
PackageFileLocation namesJson() const;
/**
* @brief Load the AABB (axis-aligned bounding-box) from the bounding box JSON file.
* @return Return the AABB if successful, `std::nullopt` if file does not exist.
......@@ -76,6 +80,17 @@ namespace armarx
*/
std::optional<simox::OrientedBox<float>> loadOOBB() const;
/**
* @brief Load names to use when matched when recognizing an object by name.
* @see `namesJson()`
*/
std::optional<std::vector<std::string>> loadRecognizedNames() const;
/**
* @brief Load names to use when verbalizing an object name.
* @see `namesJson()`
*/
std::optional<std::vector<std::string>> loadSpokenNames() const;
/**
* @brief Checks the existence of expected files.
......@@ -88,6 +103,7 @@ namespace armarx
private:
path objectDirectory() const;
std::optional<std::vector<std::string>> loadNames(const std::string& jsonKey) const;
private:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment