Skip to content

Commit

Permalink
New vector field planner impelementation (#268)
Browse files Browse the repository at this point in the history
* new vector field planner and added move end effector pose vector field

* add move to end effector pose test cases

* refactor code and format

* add new tests to plan to end effector pose

* add functions of enabling collision checking and dof limit checking

* fix doc strings

* add velocity gain to support controlling in complex scenarios

* add new class for collision error

* address JS's comments

* address JS's comments and add doc strings for some member variables

* Fix const-correctness in ConfigurationSpaceVectorField

* Fix code style

* fix doc string style

* Add invalid max distance variable

* update cpde style

* fix typos

* address Mike's comments

* add parameter for constraint check resolution

* add doc strings, moved implementation details, add plannerStatus as output

* address Mike's comments

* update for formatting

* address Mike's comments

* address Mike's comments

* change to use TestableIntersection

* fix doc strings

* add changelog.md
  • Loading branch information
dqyi11 authored Dec 10, 2017
1 parent 738ef61 commit 9267dbd
Show file tree
Hide file tree
Showing 24 changed files with 1,730 additions and 827 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
* Planner

* Added World class: [#243](https://github.com/personalrobotics/aikido/pull/243), [#252](https://github.com/personalrobotics/aikido/pull/252)
* Added vector field planner [#246](https://github.com/personalrobotics/aikido/pull/246), [#262](https://github.com/personalrobotics/aikido/pull/262)
* Added vector field planner [#246](https://github.com/personalrobotics/aikido/pull/246), [#262](https://github.com/personalrobotics/aikido/pull/262), [#268](https://github.com/personalrobotics/aikido/pull/268)

* RViz

Expand Down
126 changes: 126 additions & 0 deletions include/aikido/planner/vectorfield/BodyNodePoseVectorField.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
#ifndef AIKIDO_PLANNER_VECTORFIELD_BODYNODEPOSEVECTORFIELD_HPP_
#define AIKIDO_PLANNER_VECTORFIELD_BODYNODEPOSEVECTORFIELD_HPP_

#include <dart/dynamics/BodyNode.hpp>
#include <aikido/planner/vectorfield/VectorField.hpp>
#include <aikido/statespace/dart/MetaSkeletonStateSpace.hpp>

namespace aikido {
namespace planner {
namespace vectorfield {

/// This class is a vector field over a MetaSkeletonStateSpace that is
/// defined in terms of a Cartesian vector field over the pose of a
/// BodyNode in that MetaSkeleton.
/// The Jacobian pseudoinverse is used to map velocities in se(3) to
/// velocities in configuration space.
/// If multiple solutions exist, i.e. the kinematic chain leading to
/// the BodyNode in the MetaSkeleton is redundant, then a heuristic is
/// used to select velocities from the null space to avoid violating
/// joint limits.
class BodyNodePoseVectorField : public VectorField
{
public:
/// Constructor.
///
/// \param[in] stateSpace MetaSkeleton state space.
/// \param[in] bn Body node of end-effector.
/// \param[in] maxStepSize The maximum step size used to guarantee
/// that the integrator does not step out of joint limits.
/// \param[in] jointLimitpadding If less then this distance to joint
/// limit, velocity is bounded in that direction to 0.
/// \param[in] enforceJointVelocityLimits Whether joint velocity limits
/// are considered in computation.
BodyNodePoseVectorField(
aikido::statespace::dart::MetaSkeletonStateSpacePtr
metaSkeletonStateSpace,
dart::dynamics::BodyNodePtr bodyNode,
double maxStepSize,
double jointLimitPadding,
bool enforceJointVelocityLimits = false);

// Documentation inherited.
bool evaluateVelocity(
const aikido::statespace::StateSpace::State* state,
Eigen::VectorXd& qd) const override;

// Documentation inherited.
VectorFieldPlannerStatus evaluateStatus(
const aikido::statespace::StateSpace::State* state) const override;

/// Evaluate Cartesian velocity by current pose of body node.
///
/// \param[in] pose Current pose of body node.
/// \param[out] cartesianVelocity Cartesian velocity defined in se(3).
virtual bool evaluateCartesianVelocity(
const Eigen::Isometry3d& pose,
Eigen::Vector6d& cartesianVelocity) const = 0;

/// Evaluate current pose to determine the status of planning.
///
/// \param[in] pose Current pose of body node.
/// \return Status of planner.
virtual VectorFieldPlannerStatus evaluateCartesianStatus(
const Eigen::Isometry3d& pose) const = 0;

// Documentation inherited.
bool evaluateTrajectory(
const aikido::trajectory::Trajectory& trajectory,
const aikido::constraint::Testable* constraint,
double evalStepSize,
double& evalTimePivot,
bool excludeEndTime) const override;

/// Return meta skeleton state space.
aikido::statespace::dart::MetaSkeletonStateSpacePtr
getMetaSkeletonStateSpace();

/// Return const meta skeleton state space.
aikido::statespace::dart::ConstMetaSkeletonStateSpacePtr
getMetaSkeletonStateSpace() const;

/// Returns meta skeleton.
dart::dynamics::MetaSkeletonPtr getMetaSkeleton();

/// Returns const meta skeleton.
dart::dynamics::ConstMetaSkeletonPtr getMetaSkeleton() const;

/// Returns body node of end-effector.
dart::dynamics::BodyNodePtr getBodyNode();

/// Returns const body node of end-effector.
dart::dynamics::ConstBodyNodePtr getBodyNode() const;

protected:
/// Meta skeleton state space.
aikido::statespace::dart::MetaSkeletonStateSpacePtr mMetaSkeletonStateSpace;

/// Meta Skeleton
dart::dynamics::MetaSkeletonPtr mMetaSkeleton;

/// BodyNode
dart::dynamics::BodyNodePtr mBodyNode;

/// Maximum step size of integrator.
double mMaxStepSize;

/// Padding of joint limits.
double mJointLimitPadding;

/// Joint velocities lower limits.
Eigen::VectorXd mVelocityLowerLimits;

/// Joint velocities upper limits.
Eigen::VectorXd mVelocityUpperLimits;

/// Enfoce joint velocity limits
bool mEnforceJointVelocityLimits;
};

using BodyNodePoseVectorFieldPtr = std::shared_ptr<BodyNodePoseVectorField>;

} // namespace vectorfield
} // namespace planner
} // namespace aikido

#endif // AIKIDO_PLANNER_VECTORFIELD_BODYNODEPOSEVECTORFIELD_HPP_
Original file line number Diff line number Diff line change
@@ -1,81 +1,91 @@
#ifndef AIKIDO_PLANNER_VECTORFIELD_MOVEENDEFFECTOROFFSETVECTORFIELD_HPP_
#define AIKIDO_PLANNER_VECTORFIELD_MOVEENDEFFECTOROFFSETVECTORFIELD_HPP_

#include <aikido/planner/vectorfield/VectorFieldPlanner.hpp>
#include <aikido/planner/vectorfield/BodyNodePoseVectorField.hpp>

namespace aikido {
namespace planner {
namespace vectorfield {

/// Vector field for moving end-effector by a direction and distance.
/// It defines a vector field in meta-skeleton state space that moves
/// an end-effector a desired offset with move-hand-straight constraint.
/// The move-hand-straight constraint is defined by the direction and
/// distance range [minimum distance, maximum distance).
/// Movement less than minimum distance will return failure.
/// The motion will not move further than maximum distance.
///
/// This class defines two callback functions for vectorfield planner.
/// One for generating joint velocity in MetaSkeleton state space,
/// and one for determining vectorfield planner status.
class MoveEndEffectorOffsetVectorField
class MoveEndEffectorOffsetVectorField : public BodyNodePoseVectorField
{
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
/// Constructor
///
/// \param[in] _bn Body node of end-effector
/// \param[in] _linearVelocity Linear velocity in all the directions
/// \param[in] _startTime Start time of a planned trajectory
/// \param[in] _endTime End time of a planned trajectory
/// \param[in] _timestep Time step size
/// \param[in] _linearGain Gain of P control on linear deviation
/// \param[in] _linearTolerance Tolerance on linear deviation
/// \param[in] _angularGain Gain of P control on angular deviation
/// \param[in] _angularTolerance Tolerance on angular deviation
/// \param[in] _optimizationTolerance Tolerance on optimization
/// \param[in] _padding Padding to the boundary
/// \param[in] stateSpace MetaSkeleton state space.
/// \param[in] bn Body node of end-effector.
/// \param[in] direction Unit vector in the direction of motion.
/// \param[in] minDistance Minimum distance in meters.
/// \param[in] maxDistance Maximum distance in meters. Maximum distance
/// should be larger than minimum distance so that a feasible solution
/// could be found.
/// \param[in] positionTolerance Constraint tolerance in meters.
/// \param[in] angularTolerance Constraint tolerance in radians.
/// \param[in] linearGain Proportional control gain that corrects linear
/// orthogonal error.
/// \param[in] rotationGain Proportional control gain that corrects
/// rotational error
/// \param[in] maxStepSize The maximum step size used to guarantee
/// that the integrator does not step out of joint limits.
/// \param[in] jointLimitPadding If less then this distance to joint
/// limit, velocity is bounded in that direction to 0.
MoveEndEffectorOffsetVectorField(
dart::dynamics::BodyNodePtr _bn,
const Eigen::Vector3d& _linearVelocity,
double _startTime,
double _endTime,
double _timestep,
double _linearGain = 1.,
double _linearTolerance = 0.01,
double _angularGain = 1.,
double _angularTolerance = 0.01,
double _optimizationTolerance = 1e-3,
double _padding = 1e-5);
aikido::statespace::dart::MetaSkeletonStateSpacePtr stateSpace,
dart::dynamics::BodyNodePtr bn,
const Eigen::Vector3d& direction,
double minDistance,
double maxDistance,
double positionTolerance,
double angularTolerance,
double maxStepSize,
double jointLimitPadding);

/// Vectorfield callback function
///
/// \param[in] _stateSpace MetaSkeleton state space
/// \param[in] _t Current time being planned
/// \param[out] _dq Joint velocities
/// \return Whether joint velocities are successfully computed
bool operator()(
const aikido::statespace::dart::MetaSkeletonStateSpacePtr& _stateSpace,
double _t,
Eigen::VectorXd& _dq);
// Documentation inherited.
bool evaluateCartesianVelocity(
const Eigen::Isometry3d& pose,
Eigen::Vector6d& cartesianVelocity) const override;

/// Vectorfield planning status callback function
///
/// \param[in] _stateSpace MetaSkeleton state space
/// \param[in] _t Current time being planned
/// \return Status of planning
VectorFieldPlannerStatus operator()(
const aikido::statespace::dart::MetaSkeletonStateSpacePtr& _stateSpace,
double _t);
// Documentation inherited.
VectorFieldPlannerStatus evaluateCartesianStatus(
const Eigen::Isometry3d& pose) const override;

private:
dart::dynamics::BodyNodePtr mBodynode;
Eigen::Vector3d mVelocity;
Eigen::Vector3d mLinearDirection;
double mStartTime;
double mEndTime;
double mTimestep;
double mLinearGain;
double mLinearTolerance;
double mAngularGain;
protected:
/// Movement direction.
Eigen::Vector3d mDirection;

/// Minimum movement distance.
double mMinDistance;

/// Maximum distance allowed to move.
double mMaxDistance;

/// Tolerance of linear deviation error.
double mPositionTolerance;

/// Tolerance of angular error.
double mAngularTolerance;
double mOptimizationTolerance;
double mPadding;

/// Linear gain of a proportional control that corrects linear orthogonal
/// error.
double mLinearGain;

/// Rotation gain of a proportional control that corrects rotational error.
double mRotationGain;

/// Start pose of the end-effector.
Eigen::Isometry3d mStartPose;
Eigen::Isometry3d mTargetPose;
};

} // namespace vectorfield
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#ifndef AIKIDO_PLANNER_VECTORFIELD_MOVEENDEFFECTORPOSEVECTORFIELD_HPP_
#define AIKIDO_PLANNER_VECTORFIELD_MOVEENDEFFECTORPOSEVECTORFIELD_HPP_

#include <aikido/planner/vectorfield/BodyNodePoseVectorField.hpp>

namespace aikido {
namespace planner {
namespace vectorfield {

/// Vector field for moving end-effector to a goal pose in SE(3).
/// It defines a vector field in meta-skeleton state space that moves
/// an end-effector a desired pose in SE(3) by following a geodesic
/// loss function in SE(3) via an optimized Jacobian.
/// The geodesic loss function is defined as the geodesic (shortest
/// path) from the current pose to the goal pose.
///
/// This class defines two callback functions for vectorfield planner.
/// One for generating joint velocity in MetaSkeleton state space,
/// and one for determining vectorfield planner status.
class MoveEndEffectorPoseVectorField : public BodyNodePoseVectorField
{
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
/// Constructor.
///
/// \param[in] stateSpace MetaSkeleton state space.
/// \param[in] bn Body node of end-effector.
/// \param[in] goalPose Desired end-effector pose.
/// \param[in] poseErrorTolerance Constraint error tolerance in meters.
/// \param[in] r Conversion of radius to meters in computing Geodesic
/// distance.
/// \param[in] maxStepSize The maximum step size used to guarantee
/// that the integrator does not step out of joint limits.
/// \param[in] jointLimitPadding If less then this distance to joint
/// limit, velocity is bounded in that direction to 0.
MoveEndEffectorPoseVectorField(
aikido::statespace::dart::MetaSkeletonStateSpacePtr stateSpace,
dart::dynamics::BodyNodePtr bn,
const Eigen::Isometry3d& goalPose,
double poseErrorTolerance,
double r,
double maxStepSize,
double jointLimitPadding);

// Documentation inherited.
bool evaluateCartesianVelocity(
const Eigen::Isometry3d& pose,
Eigen::Vector6d& cartesianVelocity) const override;

// Documentation inherited.
VectorFieldPlannerStatus evaluateCartesianStatus(
const Eigen::Isometry3d& pose) const override;

protected:
/// Goal pose.
Eigen::Isometry3d mGoalPose;

/// Tolerance of pose error.
double mPoseErrorTolerance;

/// Conversion ratio from radius to meter.
double mConversionRatioFromRadiusToMeter;
};

} // namespace vectorfield
} // namespace planner
} // namespace aikido

#endif // ifndef
// AIKIDO_PLANNER_VECTORFIELD_MOVEENDEFFECTORPOSEVECTORFIELD_HPP_
Loading

0 comments on commit 9267dbd

Please sign in to comment.