Skip to content

Add ConfigurationToTSRwithTrajectoryConstraint #566

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

Open
wants to merge 9 commits into
base: gilwoo/planner_dart
Choose a base branch
from
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#ifndef AIKIDO_PLANNER_DART_CRRTCONFIGURATIONTOTSRWITHTRAJECTORYCONSTRAINTPLANNER_HPP_
#define AIKIDO_PLANNER_DART_CRRTCONFIGURATIONTOTSRWITHTRAJECTORYCONSTRAINTPLANNER_HPP_

#include "aikido/planner/dart/ConfigurationToTSRPlanner.hpp"
#include "aikido/planner/dart/ConfigurationToTSRwithTrajectoryConstraint.hpp"
#include "aikido/robot/util.hpp"
#include "aikido/statespace/dart/MetaSkeletonStateSpace.hpp"
#include "aikido/trajectory/Trajectory.hpp"

namespace aikido {
namespace planner {
namespace dart {

class CRRTConfigurationToTSRwithTrajectoryConstraintPlanner
: public dart::SingleProblemPlanner<
CRRTConfigurationToTSRwithTrajectoryConstraintPlanner,
ConfigurationToTSRwithTrajectoryConstraint>
{
public:
// Expose the implementation of Planner::plan(const Problem&, Result*) in
// SingleProblemPlanner. Note that plan() of the base class takes Problem
// while the virtual function defined in this class takes SolvableProblem,
// which is simply ConfigurationToTSRwithTrajectoryConstraint.
using SingleProblemPlanner::plan;

/// Constructor
///
/// \param[in] stateSpace State space that this planner associated with.
/// \param[in] metaSkeleton MetaSkeleton to use for planning.
/// \param[in] timelimit Timelimit for planning.
/// \param[in] crrtParameters CRRT planner parameters.
CRRTConfigurationToTSRwithTrajectoryConstraintPlanner(
statespace::dart::ConstMetaSkeletonStateSpacePtr stateSpace,
::dart::dynamics::MetaSkeletonPtr metaSkeleton,
double timelimit,
robot::util::CRRTPlannerParameters crrtParameters);

/// \copydoc SingleProblemPlanner::plan()
virtual trajectory::TrajectoryPtr plan(
const SolvableProblem& problem, Result* result = nullptr) final;

protected:
const robot::util::CRRTPlannerParameters mCRRTParameters;

// Planning timelimit
const double mTimelimit;
};

} // namespace dart
} // namespace planner
} // namespace aikido

#endif // AIKIDO_PLANNER_DART_CRRTCONFIGURATIONTOTSRWITHTRAJECTORYCONSTRAINTPLANNER_HPP_
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#ifndef AIKIDO_PLANNER_DART_CONFIGURATIONTOTSRWITHTRAJECTORYCONSTRAINT_HPP_
#define AIKIDO_PLANNER_DART_CONFIGURATIONTOTSRWITHTRAJECTORYCONSTRAINT_HPP_

#include "aikido/planner/dart/ConfigurationToTSR.hpp"

namespace aikido {
namespace planner {
namespace dart {

/// Planning problem to plan to a given single Task Space Region (TSR).
class ConfigurationToTSRwithTrajectoryConstraint : public ConfigurationToTSR
{
public:
/// Constructor. Note that this constructor takes the start state from the
/// current state of the passed MetaSkeleton.
///
/// \param[in] stateSpace State space.
/// \param[in] metaSkeleton MetaSkeleton that getStartState will return the
/// current state of when called.
/// \param[in] endEffectorBodyNode BodyNode to be planned to move to a desired
/// TSR.
/// \param[in] goalTSR Goal TSR.
/// \param[in] constraintTsr The constraint TSR for the trajectory.
/// \param[in] constraint Trajectory-wide constraint that must be satisfied.
/// \throw If \c stateSpace is not compatible with \c constraint's state
/// space.
ConfigurationToTSRwithTrajectoryConstraint(
statespace::dart::ConstMetaSkeletonStateSpacePtr stateSpace,
::dart::dynamics::ConstMetaSkeletonPtr metaSkeleton,
::dart::dynamics::ConstBodyNodePtr endEffectorBodyNode,
constraint::dart::ConstTSRPtr goalTSR,
constraint::dart::ConstTSRPtr constraintTSR,
constraint::ConstTestablePtr constraint = nullptr);

/// Constructor. Note that this constructor sets the start state on
/// construction.
///
/// \param[in] stateSpace State space.
/// \param[in] startState Start state to plan from.
/// \param[in] endEffectorBodyNode BodyNode to be planned to move to a desired
/// TSR.
/// \param[in] maxSamples Maximum number of TSR samples to plan to.
/// \param[in] goalTSR Goal TSR.
/// \param[in] constraintTsr The constraint TSR for the trajectory
/// \param[in] constraint Trajectory-wide constraint that must be satisfied.
/// \throw If \c stateSpace is not compatible with \c constraint's state
/// space.
ConfigurationToTSRwithTrajectoryConstraint(
statespace::dart::ConstMetaSkeletonStateSpacePtr stateSpace,
const statespace::dart::MetaSkeletonStateSpace::State* startState,
::dart::dynamics::ConstBodyNodePtr endEffectorBodyNode,
constraint::dart::ConstTSRPtr goalTSR,
constraint::dart::ConstTSRPtr constraintTSR,
constraint::ConstTestablePtr constraint = nullptr);

/// Return the trajectory constraint TSR
constraint::dart::ConstTSRPtr getConstraintTSR() const;

protected:
/// Constraint TSR
const constraint::dart::ConstTSRPtr mConstraintTSR;
};

} // namespace dart
} // namespace planner
} // namespace aikido

#endif // AIKIDO_PLANNER_DART_CONFIGURATIONTOTSRWITHTRAJECTORYCONSTRAINT_HPP_
2 changes: 2 additions & 0 deletions src/planner/dart/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ set(sources
ConfigurationToEndEffectorOffsetPlanner.cpp
ConfigurationToTSR.cpp
ConfigurationToTSRPlanner.cpp
ConfigurationToTSRwithTrajectoryConstraint.cpp
CRRTConfigurationToTSRwithTrajectoryConstraintPlanner.cpp
util.cpp
)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
#include "aikido/planner/dart/CRRTConfigurationToTSRwithTrajectoryConstraintPlanner.hpp"

#include <ompl/geometric/planners/rrt/RRTConnect.h>

#include "aikido/constraint.hpp"
#include "aikido/constraint/CyclicSampleable.hpp"
#include "aikido/constraint/FiniteSampleable.hpp"
#include "aikido/constraint/NewtonsMethodProjectable.hpp"
#include "aikido/constraint/Testable.hpp"
#include "aikido/constraint/TestableIntersection.hpp"
#include "aikido/constraint/dart/InverseKinematicsSampleable.hpp"
#include "aikido/distance/defaults.hpp"
#include "aikido/planner/ompl/Planner.hpp"
#include "aikido/statespace/GeodesicInterpolator.hpp"
#include "aikido/statespace/StateSpace.hpp"
#include "aikido/statespace/dart/MetaSkeletonStateSaver.hpp"
#include "aikido/statespace/dart/MetaSkeletonStateSpace.hpp"

namespace aikido {
namespace planner {
namespace dart {

using constraint::CyclicSampleable;
using constraint::NewtonsMethodProjectable;
using constraint::Sampleable;
using constraint::Testable;
using constraint::dart::createProjectableBounds;
using constraint::dart::createSampleableBounds;
using constraint::dart::createTestableBounds;
using constraint::dart::FrameDifferentiable;
using constraint::dart::FrameTestable;
using constraint::dart::InverseKinematicsSampleable;
using constraint::dart::TSR;
using distance::createDistanceMetric;
using planner::ompl::planCRRTConnect;
using statespace::GeodesicInterpolator;
using statespace::dart::MetaSkeletonStateSaver;
using statespace::dart::MetaSkeletonStateSpace;

using ::dart::dynamics::BodyNode;
using ::dart::dynamics::InverseKinematics;

//==============================================================================
CRRTConfigurationToTSRwithTrajectoryConstraintPlanner::
CRRTConfigurationToTSRwithTrajectoryConstraintPlanner(
statespace::dart::ConstMetaSkeletonStateSpacePtr stateSpace,
::dart::dynamics::MetaSkeletonPtr metaSkeleton,
double timelimit,
robot::util::CRRTPlannerParameters crrtParameters)
: dart::SingleProblemPlanner<
CRRTConfigurationToTSRwithTrajectoryConstraintPlanner,
ConfigurationToTSRwithTrajectoryConstraint>(
std::move(stateSpace), std::move(metaSkeleton))
, mCRRTParameters(std::move(crrtParameters))
, mTimelimit(timelimit)
{
// Do nothing
}

//==============================================================================
trajectory::TrajectoryPtr
CRRTConfigurationToTSRwithTrajectoryConstraintPlanner::plan(
const SolvableProblem& problem, Result* /*result*/)
{
std::size_t projectionMaxIteration = mCRRTParameters.projectionMaxIteration;
double projectionTolerance = mCRRTParameters.projectionTolerance;

auto robot = mMetaSkeleton->getBodyNode(0)->getSkeleton();
std::lock_guard<std::mutex> lock(robot->getMutex());

// Save the current state of the stateSpace
auto saver = MetaSkeletonStateSaver(mMetaSkeleton);
DART_UNUSED(saver);

// Create seed constraint
std::shared_ptr<Sampleable> seedConstraint = createSampleableBounds(
mMetaSkeletonStateSpace, mCRRTParameters.rng->clone());

// TODO: DART may be updated to check for single skeleton
if (mMetaSkeleton->getNumDofs() == 0)
throw std::invalid_argument("MetaSkeleton has 0 degrees of freedom.");

auto skeleton = mMetaSkeleton->getDof(0)->getSkeleton();
for (size_t i = 1; i < mMetaSkeleton->getNumDofs(); ++i)
{
if (mMetaSkeleton->getDof(i)->getSkeleton() != skeleton)
throw std::invalid_argument("MetaSkeleton has more than 1 skeleton.");
}

auto bodyNode = problem.getEndEffectorBodyNode();
auto goalTsr = problem.getGoalTSR();
auto constraintTsr = problem.getConstraintTSR();

// Create an IK solver with metaSkeleton dofs
auto ik = InverseKinematics::create(const_cast<BodyNode*>(bodyNode.get()));

ik->setDofs(mMetaSkeleton->getDofs());

// create goal sampleable
auto goalSampleable = std::make_shared<InverseKinematicsSampleable>(
mMetaSkeletonStateSpace,
mMetaSkeleton,
std::make_shared<CyclicSampleable>(std::const_pointer_cast<TSR>(goalTsr)),
seedConstraint,
ik,
mCRRTParameters.maxNumTrials);

// create goal testable
auto goalTestable = std::make_shared<FrameTestable>(
std::const_pointer_cast<MetaSkeletonStateSpace>(mMetaSkeletonStateSpace),
mMetaSkeleton,
bodyNode.get(),
std::const_pointer_cast<TSR>(goalTsr));

// create constraint sampleable
auto constraintSampleable = std::make_shared<InverseKinematicsSampleable>(
mMetaSkeletonStateSpace,
mMetaSkeleton,
std::const_pointer_cast<TSR>(constraintTsr),
seedConstraint,
ik,
mCRRTParameters.maxNumTrials);

// create constraint projectable
auto frameDiff = std::make_shared<FrameDifferentiable>(
std::const_pointer_cast<MetaSkeletonStateSpace>(mMetaSkeletonStateSpace),
mMetaSkeleton,
bodyNode.get(),
std::const_pointer_cast<TSR>(constraintTsr));

std::vector<double> projectionToleranceVec(
frameDiff->getConstraintDimension(), projectionTolerance);
auto constraintProjectable = std::make_shared<NewtonsMethodProjectable>(
frameDiff, projectionToleranceVec, projectionMaxIteration);

// Current state
auto startState = mMetaSkeletonStateSpace->getScopedStateFromMetaSkeleton(
mMetaSkeleton.get());

// Call planner
auto traj = planCRRTConnect(
startState,
goalTestable,
goalSampleable,
constraintProjectable,
mMetaSkeletonStateSpace,
std::make_shared<GeodesicInterpolator>(mMetaSkeletonStateSpace),
createDistanceMetric(mMetaSkeletonStateSpace),
constraintSampleable,
std::const_pointer_cast<constraint::Testable>(problem.getConstraint()),
createTestableBounds(mMetaSkeletonStateSpace),
createProjectableBounds(mMetaSkeletonStateSpace),
mTimelimit,
mCRRTParameters.maxExtensionDistance,
mCRRTParameters.maxDistanceBtwProjections,
mCRRTParameters.minStepSize,
mCRRTParameters.minTreeConnectionDistance);

return traj;
}

} // namespace dart
} // namespace planner
} // namespace aikido
60 changes: 60 additions & 0 deletions src/planner/dart/ConfigurationToTSRwithTrajectoryConstraint.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#include "aikido/planner/dart/ConfigurationToTSRwithTrajectoryConstraint.hpp"

#include "aikido/constraint/Testable.hpp"

namespace aikido {
namespace planner {
namespace dart {

//==============================================================================
ConfigurationToTSRwithTrajectoryConstraint::
ConfigurationToTSRwithTrajectoryConstraint(
statespace::dart::ConstMetaSkeletonStateSpacePtr stateSpace,
::dart::dynamics::ConstMetaSkeletonPtr metaSkeleton,
::dart::dynamics::ConstBodyNodePtr endEffectorBodyNode,
constraint::dart::ConstTSRPtr goalTSR,
constraint::dart::ConstTSRPtr constraintTSR,
constraint::ConstTestablePtr constraint)
: ConfigurationToTSR(
std::move(stateSpace),
std::move(metaSkeleton),
std::move(endEffectorBodyNode),
0, // This parameter is not used in this class.
std::move(goalTSR),
std::move(constraint))
, mConstraintTSR(constraintTSR)
{
// Do nothing.
}

//==============================================================================
ConfigurationToTSRwithTrajectoryConstraint::
ConfigurationToTSRwithTrajectoryConstraint(
statespace::dart::ConstMetaSkeletonStateSpacePtr stateSpace,
const statespace::dart::MetaSkeletonStateSpace::State* startState,
::dart::dynamics::ConstBodyNodePtr endEffectorBodyNode,
constraint::dart::ConstTSRPtr goalTSR,
constraint::dart::ConstTSRPtr constraintTSR,
constraint::ConstTestablePtr constraint)
: ConfigurationToTSR(
std::move(stateSpace),
startState,
std::move(endEffectorBodyNode),
0, // This parameter is not used in this class.
std::move(goalTSR),
std::move(constraint))
, mConstraintTSR(constraintTSR)
{
// Do nothing.
}

//==============================================================================
constraint::dart::ConstTSRPtr
ConfigurationToTSRwithTrajectoryConstraint::getConstraintTSR() const
{
return mConstraintTSR;
}

} // namespace dart
} // namespace planner
} // namespace aikido