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

[DoNotMerge] Twist controller extensions #121

Closed

Conversation

fmessmer
Copy link
Contributor

rebase of #110

  • Added a new constraint for Joint Singularity Avoidance (JSA). This doesn't work right now and we're trying to change this constraint to maximize the manipulability rate and find a better gain for the new introduced singularity avoidance algorithm
  • Added new singularity avoidance algorithm with 3 new parameters in the RQT dynamic reconfigure (damping_delta, damping_gain, damping_slope). This behaves in singular positions better and calculates for each joint its own damping value lambda. (cp. the old one calculated one damping value for all joints)
  • Added base_active mode for stack_of_tasks controller. I wasn't able to verify this 100 % since the base_active doesn't behave as I want to ( extension_ratio needs to be derived dynamically ). The new singularity avoidance algorithm with manipulability optimization might be the right way to achieve this goal. We want to test this until Friday.

Do not merge yet!
I'm still trying to understand what extensions have been added, whether they work correctly as well as whether they are worth keeping

@fmessmer
Copy link
Contributor Author

I will formally and syntactically work on this PR.

@ipa-bfb could you afterwards explain the new features to me as you worked with @ipa-fxm-cm on this...

# ==================================== Controller interfaces =================================================================================
ctrl_interface = gen.add_group("Controller Interfaces", "ctrl_interface")
ctrl_interface.add("controller_interface", int_t, 0, "The controller interface to use", 0, None, None, edit_method=controller_interface_enum)
ctrl_interface.add("integrator_smoothing", double_t, 0, "The factor used for exponential smoothing during simpson integration)", 0.2, 0, 1)

# ==================================== Damping and truncation (singular value adaption) ====================================================
damp_trunc = gen.add_group("Damping and Truncation", "damping_truncation")
damp_trunc.add("numerical_filtering", bool_t, 0, "Numerical Filtering yes/no", False)
damp_trunc.add("damping_method", int_t, 0, "The damping method to use.", 2, None, None, edit_method=damping_method_enum)
damp_trunc.add("singularity_avoidance", int_t, 0, "Singularity avoidance method", 0, None, None, edit_method=singularity_avoidance_enum)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ipa-bfb
Why has numerical_filtering been removed?
Why is singularity_avoidance now an option within Damping and Truncation?

/* BEGIN JointSingularityAvoidance ************************************************************************************/
/// Class providing methods that realize a JointSingularityAvoidance constraint.
template <typename T_PARAMS, typename PRIO = uint32_t>
class JointSingularityAvoidance : public ConstraintBase<T_PARAMS, PRIO>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ipa-bfb
JointSingularityAvoidance is a ConstraintBase so no DampingBase!
To me this sounds like the JSA should be configurable as as Constraint and thus not mess up with the DampingMethods, i.e. in the cfg

damping_method(MANIPULABILITY),
damping_factor(0.2),
lambda_max(0.1),
w_threshold(0.005),
beta(0.005),
eps_damping(0.003),
eps_truncation(0.001),
damping_delta(0.1),
damping_gain(0.02),
damping_slope(0.05),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ipa-bfb
These parameters are used within JointSingularityAvoidance, right....shouldn't they then be named jsa_delta, jsa_gain, jsa_slope?

DampingMethodTypes damping_method;
double damping_factor;
double lambda_max;
double w_threshold;
double beta;
double eps_damping;
double eps_truncation;
double damping_delta;
double damping_gain;
double damping_slope;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as comment above

@@ -278,6 +292,8 @@ struct TwistControllerParams

// vector of links of the chain to be considered for collision avoidance
std::vector<std::string> collision_check_links;

KDL::Chain chain;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ipa-bfb
What is this used for? Does this need to be a class member?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed as it is not used anywhere

KDL::ChainFkSolverVel_recursive& fk_solver_vel_;

};
/* END JointLimitAvoidance **************************************************************************************/
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

copy-paste

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

@@ -140,7 +140,8 @@ class ConstraintBase : public PriorityBase<PRIO>
prediction_value_(std::numeric_limits<double>::max()),
last_value_(0.0),
last_time_(ros::Time::now()),
last_pred_time_(ros::Time::now())
last_pred_time_(ros::Time::now()),
init_(false)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these things are constraint-specific! So do not put them in the base class!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed because unused anyway

@@ -222,6 +223,8 @@ class ConstraintBase : public PriorityBase<PRIO>
JointStates joint_states_;
KDL::JntArrayVel jnts_prediction_;
Matrix6Xd_t jacobian_data_;
Matrix6Xd_t jacobian_data_old_;
bool init_;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see comment above

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed as both variables are nowhere used

@@ -256,7 +259,7 @@ class ConstraintBase : public PriorityBase<PRIO>
adapted_params.damping_method = CONSTANT;
adapted_params.damping_factor = const_damping_factor;
adapted_params.eps_truncation = 0.0;
adapted_params.numerical_filtering = false;
// adapted_params.numerical_filtering = false;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I definitely want to keep numerical_filtering!

@@ -287,7 +287,8 @@ void CollisionAvoidance<T_PARAMS, PRIO>::calcPartialValues()
{
if (params.frame_names.end() != str_it)
{
Eigen::Vector3d collision_pnt_vector = it->nearest_point_frame_vector - it->frame_vector;
Eigen::Vector3d collision_pnt_vector = it->nearest_point_frame_vector;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ipa-bfb
Why was this computation changed? Why don't we subtract it->frame_vector anymore?

@@ -308,7 +309,8 @@ void CollisionAvoidance<T_PARAMS, PRIO>::calcPartialValues()
uint32_t frame_number = idx + 1; // segment nr not index represents frame number

KDL::JntArray ja = this->joint_states_.current_q_;
KDL::Jacobian new_jac_chain(this->joint_states_.current_q_.rows());
ja.resize((unsigned int)params.dof);
KDL::Jacobian new_jac_chain(ja.rows());
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the dimension still correct when being used with a "KinematicExtension"?

@@ -389,22 +391,21 @@ void CollisionAvoidance<T_PARAMS, PRIO>::calcPredictionValue()

if (params.frame_names.end() != str_it)
{
unsigned int dof;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this variable is not used!

if (this->constraint_params_.current_distances_.size() > 0)
{
uint32_t frame_number = (str_it - params.frame_names.begin()) + 1; // segment nr not index represents frame number
KDL::FrameVel frame_vel;

// ToDo: the fk_solver_vel_ is only initialized for the primary chain - kinematic extensions cannot be considered yet!
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ipa-bfb
Has this been fixed? Otherwise keep the comment!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is not fixed yet....keeping comment and debug output below

// Calculate prediction for pos and vel
int error = this->fk_solver_vel_.JntToCart(this->jnts_prediction_, frame_vel, frame_number);
// Calculate prediction for the mainipulator
int error = this->fk_solver_vel_.JntToCart(jnts_prediction_chain, frame_vel, frame_number);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ipa-bfb
Needs explanation

}


KDL::Twist twist = frame_vel.GetTwist() + predicted_twist_odometry; // predicted frame twist
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ipa-bfb
Needs explanation

@@ -85,6 +85,8 @@ class InverseDifferentialKinematicsSolver

/** CartToJnt for chain using SVD considering KinematicExtensions and various DampingMethods **/
virtual int CartToJnt(const JointStates& joint_states,
const geometry_msgs::Pose pose,
const KDL::Twist& twist,
Copy link
Contributor Author

@fmessmer fmessmer Dec 14, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ipa-bfb
What are the additional arguments used for? Where are they used?

Disslike modification of BaseClass!

@@ -51,7 +51,7 @@ class KinematicExtensionBase

virtual bool initExtension() = 0;
virtual KDL::Jacobian adjustJacobian(const KDL::Jacobian& jac_chain) = 0;
virtual JointStates adjustJointStates(const JointStates& joint_states) = 0;
virtual JointStates adjustJointStates(const JointStates& joint_states, const geometry_msgs::Pose& pose, const KDL::Twist& twist) = 0;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Disslike modification of BaseClass!

@@ -142,7 +144,8 @@ bool CobTwistController::initialize()
{
twist_controller_params_.frame_names.push_back(chain_.getSegment(i).getName());
}
register_link_client_ = nh_.serviceClient<cob_srvs::SetString>("obstacle_distance/registerLinkOfInterest");

register_link_client_ = nh_.serviceClient<cob_srvs::SetString>("/register_links");
Copy link
Contributor Author

@fmessmer fmessmer Dec 14, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is clearly related to #101 - which is still WIP
Try to separate everything related to this feature from the TwistController-Extensions feature, i.e. JointSingularityAvoidance

@@ -164,7 +167,7 @@ bool CobTwistController::initialize()
ros::Duration(1.0).sleep();

/// initialize ROS interfaces
obstacle_distance_sub_ = nh_.subscribe("obstacle_distance", 1, &CallbackDataMediator::distancesToObstaclesCallback, &callback_data_mediator_);
obstacle_distance_sub_ = nh_.subscribe("/obstacle_distances", 1, &CallbackDataMediator::distancesToObstaclesCallback, &callback_data_mediator_);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see comment above

@@ -309,7 +315,7 @@ void CobTwistController::checkSolverAndConstraints(cob_twist_controller::TwistCo
{
if (!register_link_client_.exists())
{
ROS_ERROR("ServiceServer 'obstacle_distance/registerLinkOfInterest' does not exist. CA not possible");
ROS_ERROR("ServiceServer '/register_links' does not exist. CA not possible");
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see comment above

}
result = svd_V * S * svd.matrixU().transpose();
break;
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ipa-bfb
Please provide link to literature! Where do these formulae come from?


result = svd.matrixV() * singularValuesInv.asDiagonal() * svd.matrixU().transpose();
break;
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ipa-bfb
Please provide link to literature! Where do these formulae come from?

singularValuesInv(i) = (singularValues(i) < eps_truncation) ? 0.0 : singularValues(i) / denominator;
}

result = svd.matrixV() * singularValuesInv.asDiagonal() * svd.matrixU().transpose();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ipa-bfb
Please provide link to literature! Where do these formulae come from?

@@ -54,7 +54,8 @@ class IPseudoinverseCalculator
*/
virtual Eigen::MatrixXd calculate(const TwistControllerParams& params,
boost::shared_ptr<DampingBase> db,
const Eigen::MatrixXd& jacobian) const = 0;
const Eigen::MatrixXd& jacobian,
const JointStates& joint_states) const = 0;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Disslike modification of BaseClass!

@fmessmer
Copy link
Contributor Author

fmessmer commented Dec 14, 2016

In particular, I disslike the API-changes of:

  1. KinematicExtensionBase::adjustJointStates()
-        virtual JointStates adjustJointStates(const JointStates& joint_states) = 0;
+        virtual JointStates adjustJointStates(const JointStates& joint_states, const geometry_msgs::Pose& pose, const KDL::Twist& twist) = 0;
  1. IPseudoinverseCalculator::calculate()
         virtual Eigen::MatrixXd calculate(const TwistControllerParams& params,
                                           boost::shared_ptr<DampingBase> db,
-                                          const Eigen::MatrixXd& jacobian) const = 0;
+                                          const Eigen::MatrixXd& jacobian,
+                                          const JointStates& joint_states) const = 0;
  1. InverseDifferentialKinematicsSolver::CartToJnt()
     virtual int CartToJnt(const JointStates& joint_states,
+                          const geometry_msgs::Pose pose,
+                          const KDL::Twist& twist,

@fmessmer
Copy link
Contributor Author

fmessmer commented Dec 15, 2016

Well, I definitely need input from @ipa-bfb here!

However, I am closing other WIP-PRs related to TwistControlExtensions as they will be included in this one:

@bbrito
Copy link
Contributor

bbrito commented Jan 9, 2017

@ipa-fxm I developed a new method for singularity avoidance and joint limit avoidance.

@ipa-fxm-cm helped me implementing this new features. The singularity avoidance was working fine and the joint limit avoidance needs further work.

@ipa-fxm-cm was trying some methods to optimise the manipulability based on a paper btu as far as I know the results were not satisfying.

And so, connected to the implementation of these new methods we have introduced all the changes in #121. This was not the way of doing it so I recommend to not merge this changes.

I will send you an invitation for a meeting to discuss a good implementation of this new method.

@fmessmer
Copy link
Contributor Author

As discussed, @ipa-bfb will provide new PRs for his new SA and JLA methods....
Afterwards, we will see what is still left useful from this PR here

@fmessmer fmessmer changed the title [WIP] Twist controller extensions [DoNotMerge] Twist controller extensions Jan 14, 2017
@fmessmer
Copy link
Contributor Author

I'll close this as it is unmergable and most features of this PR are WIP/untested/superseded...

@fmessmer fmessmer closed this Mar 29, 2017
@fmessmer fmessmer deleted the twist_controller_extensions branch March 29, 2017 16:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants