Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhancement/pose estimator #497

Merged
merged 29 commits into from
Feb 14, 2019
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
e2440aa
Pose estimator enhancement
gilwoolee Jan 27, 2019
da1b722
Add cpp classes in perception
gilwoolee Jan 27, 2019
e27ecaf
clean up hancks for demo
yskim041 Jan 27, 2019
fb1bfc0
update CHANGELOG.md
yskim041 Jan 27, 2019
61a3a24
add a new class DetectedObject and update PoseEstimatorModule
yskim041 Feb 3, 2019
853e11b
minor fixes
yskim041 Feb 3, 2019
f8c7758
Merge branch 'master' into enhancement/pose_estimator
brianhou Feb 3, 2019
4ce2f50
remove the projection height from PoseEstimatorModule
yskim041 Feb 3, 2019
e84d6fd
Merge branch 'enhancement/pose_estimator' of https://github.com/perso…
yskim041 Feb 3, 2019
e874ec9
Merge branch 'master' into enhancement/pose_estimator
brianhou Feb 3, 2019
286359d
document DetectedObject class
yskim041 Feb 4, 2019
062f16f
change 'id' -> 'uid'
yskim041 Feb 4, 2019
4b08f35
Update include/aikido/perception/DetectedObject.hpp
gilwoolee Feb 5, 2019
1ce5724
Update include/aikido/perception/DetectedObject.hpp
gilwoolee Feb 5, 2019
3ac8326
Update include/aikido/perception/DetectedObject.hpp
gilwoolee Feb 5, 2019
b03e20f
Merge branch 'master' into enhancement/pose_estimator
gilwoolee Feb 11, 2019
cc58f6b
change the way to parse a Marker message
yskim041 Feb 12, 2019
c973cc0
Allow nullptr for detectedObjects argument
egordon Feb 12, 2019
bc3bf1b
Added robustness against bad YAML strings, plus more easily-parse-abl…
egordon Feb 12, 2019
527e462
Fixed documentation per comments, tested with simple_perception in ad…
egordon Feb 13, 2019
1633676
Added default argument to detectedObjects.
egordon Feb 13, 2019
9732051
Fixed comments on pull request
egordon Feb 13, 2019
36d422e
Indigo compatibility (no DELETEALL)
egordon Feb 13, 2019
7c3971a
Apply suggestions from code review
brianhou Feb 13, 2019
79f921a
Applied comments from PR review: refactored ObjectDatabase to AssetDa…
egordon Feb 13, 2019
af32515
Clang formatted
egordon Feb 13, 2019
9581880
Fixed PR comments.
egordon Feb 14, 2019
21460a9
Move vector push to end of for loop
egordon Feb 14, 2019
92fa686
Final PR nits.
egordon Feb 14, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@

* Added integrated PoseEstimatorModule: [#336](https://github.com/personalrobotics/aikido/pull/336)
* Added voxel grid perception module: [#448](https://github.com/personalrobotics/aikido/pull/448)
* Added YAML communication between PoseEstimatorModule and third party perception algorithms: [#497](https://github.com/personalrobotics/aikido/pull/497)
egordon marked this conversation as resolved.
Show resolved Hide resolved

* Trajectory

Expand Down
7 changes: 4 additions & 3 deletions include/aikido/perception.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "perception/AprilTagsDatabase.hpp"
#include "perception/AprilTagsModule.hpp"
#include "perception/DetectedObject.hpp"
#include "perception/ObjectDatabase.hpp"
#include "perception/PerceptionModule.hpp"
#include "perception/YamlAprilTagsDatabase.hpp"
#include "perception/PoseEstimatorModule.hpp"
#include "perception/VoxelGridModule.hpp"
#include "perception/shape_conversions.hpp"
89 changes: 89 additions & 0 deletions include/aikido/perception/DetectedObject.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
#ifndef AIKIDO_PERCEPTION_DETECTEDOBJECT_HPP_
#define AIKIDO_PERCEPTION_DETECTEDOBJECT_HPP_

#include <string>
#include "aikido/io/yaml.hpp"

namespace aikido {
namespace perception {

/// DetectedObject delegates a detected object from a third party
egordon marked this conversation as resolved.
Show resolved Hide resolved
/// perception algorithm.

/// A perception algorithm should send information for an object via ROS
/// visualization_msgs/Marker message like the following:
/// Marker.header.frame_id -> detectionFrameID
egordon marked this conversation as resolved.
Show resolved Hide resolved
/// Marker.ns + "_" + Marker.id -> objUid (identity in DART world)
/// Marker.ns -> objAssetDBKey (determines visual asset, see ObjectDatabase)
egordon marked this conversation as resolved.
Show resolved Hide resolved
/// Marker.text -> yamlStr

/// yamlStr contains any types of additional
egordon marked this conversation as resolved.
Show resolved Hide resolved
/// information of the object in YAML format.
/// It also can overwrite the Asset Database Key
/// using "db_key". (see ObjectDatabase for details)
/// Here is an example:
/// \code
/// {
/// "db_key": "food_item",
/// "score": 0.9,
/// "success_rates": [0.4, 0.9, 0.1, 0.2],
/// "strategies": ["vertical_0", "vertical_90", "tilted_0", "tilted_90"],
/// }
/// \endcode

egordon marked this conversation as resolved.
Show resolved Hide resolved
/// Clarification: objUid = DART world ID; objDbKey = visual asset key in ObjectDatabase.

class DetectedObject
{
public:
/// Construct a \c DetectedObject
/// \param[in] objUid Unique ID for object in DART world. Same UID -> Same Object
egordon marked this conversation as resolved.
Show resolved Hide resolved
/// \param[in] objAssetDBKey Key for ObjectDatabase passed into constructor of PoseEstimatorModule. Defines visuals / assets.
egordon marked this conversation as resolved.
Show resolved Hide resolved
/// \param[in] detectionFrameID Frame ID from ROS Marker
/// \param[in] yamlStr String of additional parameters for object. Can override objAssetDBKey with "db_key".
egordon marked this conversation as resolved.
Show resolved Hide resolved
DetectedObject(
const std::string& objUID,
const std::string& objAssetDBKey,
const std::string& detectionFrameID,
const std::string& yamlStr);

virtual ~DetectedObject() = default;

/// Get the unique id of the object
egordon marked this conversation as resolved.
Show resolved Hide resolved
std::string getObjUID();
egordon marked this conversation as resolved.
Show resolved Hide resolved

/// Get the object key for \c ObjectDatabase
std::string getObjDBKey();

/// Get the detection frame id that refers the origin of this object's pose
std::string getDetectionFrameID();

/// Get the map of keys to additional informations
YAML::Node getYamlNode();

/// Get a specific value from the information map by a key and the typename
/// of the field
/// \param[in] key The key (string) of a field in the information map
egordon marked this conversation as resolved.
Show resolved Hide resolved
/// Sequence types (e.g. [1, 2]) can be read into standard containers (e.g. std::vector<double>)
/// Map types are not supported with this function. Please get the manually with getYamlNode().
template <typename T>
T getInfoByKey(const std::string& key);
egordon marked this conversation as resolved.
Show resolved Hide resolved

private:
/// The unique id of the object
std::string mObjUID;

/// The object key for \c ObjectDatabase
std::string mObjDBKey;

/// The detection frame id that refers the origin of this object's pose
std::string mDetectionFrameID;

/// The information map with additional information of this object
YAML::Node mYamlNode;
};

} // namespace perception
} // namespace aikido

#endif // AIKIDO_PERCEPTION_DETECTEDOBJECT_HPP_
6 changes: 3 additions & 3 deletions include/aikido/perception/ObjectDatabase.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
namespace aikido {
namespace perception {

/// Instantiation of ObjectDatabase that reads of JSON file containing the
/// information that maps object keys to the object names and resources.
/// Instantiation of ObjectDatabase (a.k.a. Asset Database) that reads of JSON file containing the
egordon marked this conversation as resolved.
Show resolved Hide resolved
/// information that maps object keys to the object visual assets and resources.

/// The JSON file should have a map with object keys.
/// Each such key points to a nested map, where the keys are
Expand All @@ -23,7 +23,7 @@ namespace perception {
/// Here is an example entry in a JSON file:
/// \code
/// "obj_key": {
/// "resource": "package://pr_ordata/data/objects/obj_filename.urdf",
/// "resource": "package://pr_assets/data/objects/obj_filename.urdf",
/// "name": "obj_name",
/// "offset": [
/// [1.0, 0.0, 0.0, 0.0],
Expand Down
5 changes: 4 additions & 1 deletion include/aikido/perception/PerceptionModule.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef AIKIDO_PERCEPTION_PERCEPTIONMODULE_HPP_
#define AIKIDO_PERCEPTION_PERCEPTIONMODULE_HPP_

#include "aikido/perception/DetectedObject.hpp"
#include "aikido/planner/World.hpp"

namespace aikido {
Expand All @@ -26,13 +27,15 @@ class PerceptionModule
/// \param[in] timestamp Only detections more recent than this timestamp will
/// be accepted. A timestamp of 0 greedily takes the first available message,
/// and is the default behaviour.
/// \param[out] detectedObjects An output vector for detected objects.
/// \return Returns \c false if no detection observed, or if none of the
egordon marked this conversation as resolved.
Show resolved Hide resolved
/// detections has a more recent timestamp than the parameter. Returns \c true
/// otherwise.
virtual bool detectObjects(
const aikido::planner::WorldPtr& env,
ros::Duration timeout,
egordon marked this conversation as resolved.
Show resolved Hide resolved
ros::Time timestamp)
ros::Time timestamp,
std::vector<DetectedObject>* detectedObjects)
= 0;
};

Expand Down
16 changes: 12 additions & 4 deletions include/aikido/perception/PoseEstimatorModule.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#include <ros/ros.h>
#include <tf/transform_listener.h>
#include "aikido/io/CatkinResourceRetriever.hpp"
#include "aikido/io/yaml.hpp"
#include "aikido/perception/DetectedObject.hpp"
#include "aikido/perception/ObjectDatabase.hpp"
#include "aikido/perception/PerceptionModule.hpp"

Expand Down Expand Up @@ -40,19 +42,25 @@ class PoseEstimatorModule : public PerceptionModule
/// pose is transformed
PoseEstimatorModule(
ros::NodeHandle nodeHandle,
std::string markerTopic,
const std::string& markerTopic,
std::shared_ptr<ObjectDatabase> configData,
std::shared_ptr<aikido::io::CatkinResourceRetriever> resourceRetriever,
std::string referenceFrameId,
const std::string& referenceFrameId,
dart::dynamics::Frame* referenceLink);

virtual ~PoseEstimatorModule() = default;

// Documentation inherited
/// Looks for the following information sent via ROS (see \c DetectedObject):
egordon marked this conversation as resolved.
Show resolved Hide resolved
/// visualization_msgs/Marker message like the following:
/// Marker.header.frame_id -> detectionFrameID
/// Marker.ns + "_" + Marker.id -> objUid (identity in DART world)
egordon marked this conversation as resolved.
Show resolved Hide resolved
/// Marker.ns -> objAssetDBKey (determines visual asset, see ObjectDatabase)
bool detectObjects(
const aikido::planner::WorldPtr& env,
ros::Duration timeout = ros::Duration(0.0),
ros::Time timestamp = ros::Time(0.0)) override;
ros::Duration timeout = ros::Duration(),
ros::Time timestamp = ros::Time(0.0),
std::vector<DetectedObject>* detectedObjects = nullptr) override;
egordon marked this conversation as resolved.
Show resolved Hide resolved

private:
/// For the ROS node that will work with the April Tags module
Expand Down
1 change: 1 addition & 0 deletions src/perception/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ set(sources
shape_conversions.cpp
ObjectDatabase.cpp
VoxelGridModule.cpp
DetectedObject.cpp
)

add_library("${PROJECT_NAME}_perception" SHARED ${sources})
Expand Down
70 changes: 70 additions & 0 deletions src/perception/DetectedObject.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#include "aikido/perception/DetectedObject.hpp"

#include <yaml-cpp/exceptions.h>

namespace aikido {
namespace perception {

//==============================================================================
DetectedObject::DetectedObject(
const std::string& objUID,
const std::string& objAssetDBKey,
const std::string& detectionFrameID,
const std::string& yamlStr)
: mObjUID(std::move(objUID))
, mObjDBKey(std::move(objAssetDBKey))
, mDetectionFrameID(std::move(detectionFrameID))
egordon marked this conversation as resolved.
Show resolved Hide resolved
{
// Load YAML nodes from string
try {
mYamlNode = YAML::Load(yamlStr);
mObjDBKey = mYamlNode["db_key"].as<std::string>(mObjDBKey);
} catch(const YAML::Exception &e) {
dtwarn << "[DetectedObject::DetectedObject] YAML String Exception: " << e.what() << std::endl;
mYamlNode = YAML::Load(""); // Create Null Node
}
}

//==============================================================================
std::string DetectedObject::getObjUID()
{
return mObjUID;
}

//==============================================================================
std::string DetectedObject::getObjDBKey()
{
return mObjDBKey;
}

//==============================================================================
std::string DetectedObject::getDetectionFrameID()
{
return mDetectionFrameID;
}

//==============================================================================
YAML::Node DetectedObject::getYamlNode()
{
return mYamlNode;
}

//==============================================================================
template <typename T>
T DetectedObject::getInfoByKey(const std::string& key)
{
T value;
try
{
value = mYamlNode[key].as<T>();
}
catch (const YAML::ParserException& ex)
{
throw std::runtime_error(
"[DetectedObject] Error in converting [" + key + "] field");
}
return value;
}

} // namespace perception
} // namespace aikido
3 changes: 2 additions & 1 deletion src/perception/ObjectDatabase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ void ObjectDatabase::getObjectByKey(
YAML::Node objectNode = mObjData[objectKey];
if (!objectNode)
{
throw std::runtime_error("[ObjectDatabase] Error: invalid object key");
throw std::runtime_error(
"[ObjectDatabase] Error: invalid object key: " + objectKey);
}

// Convert resource field
Expand Down
Loading