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

Update stomp plugins ik code #46

Merged

Conversation

jrgnicho
Copy link
Member

This PR makes some important changes:

  • Replaced custom ik code with trac_ik due to better robustness and success rate.
  • Updated the Stomp planner and plugins to use new track_ik functionality
  • Tool constraints are no longer set in the Stomp yaml file, they are set in the motion plan request instead. The planer then determines the constraints from the request and evaluate that the goal has been met given the specified cartesian tolerances and tool pose.

I haven't added a formal unit test, however I have tested the planning under various scenarios (joint goal, fully constrained tool and under constrained) with nodes that aren't part of this repo. I can make those into formal unit test if requested although that may take a bit more time.

@jrgnicho jrgnicho force-pushed the update-stomp-plugins-ik-code branch from 0e5c4c0 to 9960a65 Compare July 17, 2017 14:12
- cartesian_convergence: A vector of convergence values for each cartesian DOF [vx vy vz wx wy wz].
- joint_update_rates: The rates at which to update the joints during numerical ik computations.
- max_ik_iterations: Limit on the number of iterations allowed for numerical ik computations.
- class: The class name.S
Copy link
Contributor

Choose a reason for hiding this comment

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

Typo?

@simonschmeisser
Copy link
Contributor

It's nice to see that stomp can now plan to cartesian goals using this branch. However I still have some issues (I try to configure my stomp to use both cartesian and joint goals, just like ompl can handle it). However it seems that I should use different configs for them

Here is my config for joint goals

stomp/manipulator:
  group_name: manipulator
  optimization:
    num_timesteps: 100
    num_iterations: 100
    num_iterations_after_valid: 5    
    num_rollouts: 20
    max_rollouts: 100
    initialization_method: 1 #[1 : LINEAR_INTERPOLATION, 2 : CUBIC_POLYNOMIAL, 3 : MININUM_CONTROL_COST
    control_cost_weight: 1.0
  task:
    noise_generator:
      - class: stomp_moveit/NormalDistributionSampling
        stddev: [0.1, 0.1, 0.1, 0.1, 0.1, 0.1]
    cost_functions:
      - class: stomp_moveit/CollisionCheck
        collision_penalty: 1.0
        cost_weight: 1.0
        kernel_window_percentage: 0.2
        longest_valid_joint_move: 0.05 
#      - class: stomp_moveit/ObstacleDistanceGradient
#        max_distance: 0.2
#        cost_weight: 1.0
#        longest_valid_joint_move: 0.05 
    noisy_filters:
      - class: stomp_moveit/JointLimits
        lock_start: True
        lock_goal: True
      - class: stomp_moveit/MultiTrajectoryVisualization
        line_width: 0.01
        rgb: [0, 255, 0]
        marker_array_topic: stomp_trajectories
        marker_namespace: noisy
    update_filters:
      - class: stomp_moveit/PolynomialSmoother
        poly_order: 5
      - class: stomp_moveit/TrajectoryVisualization
        line_width: 0.01
        rgb: [191, 0, 255]
        error_rgb: [255, 0, 0]
        publish_intermediate: True
        marker_topic: stomp_trajectory
        marker_namespace: optimized

This will give me an error for cartesian goals:

[ERROR] [1500574844.106980908]: Failed to save goal state
[ERROR] [1500574844.107009112]: Failed to set Plan Request on noisy filter JointLimits/manipulator

If I add goal sampling with the following config:

stomp/manipulator:
  group_name: manipulator
  optimization:
    num_timesteps: 100
    num_iterations: 100
    num_iterations_after_valid: 5    
    num_rollouts: 20
    max_rollouts: 100
    initialization_method: 1 #[1 : LINEAR_INTERPOLATION, 2 : CUBIC_POLYNOMIAL, 3 : MININUM_CONTROL_COST
    control_cost_weight: 1.0
  task:
    noise_generator:
      - class: stomp_moveit/NormalDistributionSampling
        stddev: [0.1, 0.1, 0.1, 0.1, 0.1, 0.1]
    cost_functions:
      - class: stomp_moveit/CollisionCheck
        collision_penalty: 1.0
        cost_weight: 1.0
        kernel_window_percentage: 0.2
        longest_valid_joint_move: 0.05 
#      - class: stomp_moveit/ObstacleDistanceGradient
#        max_distance: 0.2
#        cost_weight: 1.0
#        longest_valid_joint_move: 0.05 
    noisy_filters:
      - class: stomp_moveit/JointLimits
        lock_start: True
        lock_goal: False
      - class: stomp_moveit/MultiTrajectoryVisualization
        line_width: 0.01
        rgb: [0, 255, 0]
        marker_array_topic: stomp_trajectories
        marker_namespace: noisy
    update_filters:
      - class: stomp_moveit/ConstrainedCartesianGoal
        constrained_dofs: [1, 1, 1, 1, 1, 1]
        cartesian_convergence: [0.005, 0.005, 0.005, 0.01, 0.01, 0.01]
        joint_update_rates: [0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5]
        max_ik_iterations: 100
      - class: stomp_moveit/PolynomialSmoother
        poly_order: 5
      - class: stomp_moveit/TrajectoryVisualization
        line_width: 0.01
        rgb: [191, 0, 255]
        error_rgb: [255, 0, 0]
        publish_intermediate: True
        marker_topic: stomp_trajectory
        marker_namespace: optimized


I run into some issues:

  • for joint goals it will output
    [ WARN] [150575156.258329981]: ConstrainedCartesianGoal/manipulator a cartesian goal pose in MotionPlanRequest was not provided,calculating it from FK

and use ik even though we already have a ik solution (the joint goal)

  • sometimes it finds a nice solution but does not converge ( I'm not exactly sure this was because I had a high value (50) for num_iterations_after_valid or because it wouldn't accept the goal as "converged")

  • when I use the noise parameters from the sample config file it will sometimes start with a initial trajectory that passes through the origin/robot base and is stuck there

  • I cannot quantify that yet, but using the ConstrainedCartesianGoal, the trajectory seems to stick more easily to local minima/invalid paths

  • most disturbing: after a joint goal, the next cartesian goal will end up somewhere close to or at that position (the previous joint goal) which can be as far as 1m appart from the actual cartesian goal.

Thanks for your great work, I hope most of this is just misconfiguration on my side. I'm new to stomp but I really enjoy the results so far

and I got a general question: Do you intend to later generalize this to use the default ik plugin (usually ikfast in our case) instead of tracIK?

@jrgnicho
Copy link
Member Author

@simonschmeisser Thanks for reviewing and testing this, I'd use the configuration for the 'manipulator_tool' group instead, the one you have tested still uses an old (and possibly invalid) configuration. However, I should update the configuration for the 'manipulator' group to prevent others from running a bad configuration.
The Trac_ik solver takes tolerances while the kinematics base class doesn't allow for this. For this reason I don't see us using the default ik plugin within stomp.

@Levi-Armstrong
Copy link
Member

@jrgnicho Is this ready to be merged?

@simonschmeisser
Copy link
Contributor

simonschmeisser commented Jul 21, 2017

@jrgnicho Sorry I somehow messed up and used the wrong git branch, fixed that now. Anyway I updated to the following config:

stomp/manipulator:
  group_name: manipulator
  optimization:
    num_timesteps: 100
    num_iterations: 100
    num_iterations_after_valid: 5    
    num_rollouts: 20
    max_rollouts: 100
    initialization_method: 3 #[1 : LINEAR_INTERPOLATION, 2 : CUBIC_POLYNOMIAL, 3 : MININUM_CONTROL_COST
    control_cost_weight: 1.0
  task:
    noise_generator:
      - class: stomp_moveit/GoalGuidedMultivariateGaussian
        stddev: [0.05, 0.4, 1.2, 0.4, 0.4, 0.1]
#      #- class: stomp_moveit/NormalDistributionSampling
#        #stddev: [0.1, 0.1, 0.1, 0.1, 0.1, 0.1]
    cost_functions:
      - class: stomp_moveit/CollisionCheck
        collision_penalty: 1.0
        cost_weight: 1.0
        kernel_window_percentage: 0.2
        longest_valid_joint_move: 0.05 
#      - class: stomp_moveit/ObstacleDistanceGradient
#        max_distance: 0.2
#        cost_weight: 1.0
#        longest_valid_joint_move: 0.05 
      - class: stomp_moveit/ToolGoalPose
        position_cost_weight: 0.5
        orientation_cost_weight: 0.5
    noisy_filters:
      - class: stomp_moveit/JointLimits
        lock_start: True
        lock_goal: False
      - class: stomp_moveit/MultiTrajectoryVisualization
        line_width: 0.01
        rgb: [0, 255, 0]
        marker_array_topic: stomp_trajectories
        marker_namespace: noisy
    update_filters:
      - class: stomp_moveit/ConstrainedCartesianGoal
      - class: stomp_moveit/PolynomialSmoother
        poly_order: 5
      - class: stomp_moveit/TrajectoryVisualization
        line_width: 0.01
        rgb: [191, 0, 255]
        error_rgb: [255, 0, 0]
        publish_intermediate: True
        marker_topic: stomp_trajectory
        marker_namespace: optimized

And now have some issues again:

  • the frame of the pose does not seem to be respected:
    We have a global fixed "world_frame", rotated by 90° is "base_link" which is the beginning of the group "manipulator"
    We send poses in "world_frame" like this:
if (movePlan.m_activeTarget == POSE || movePlan.m_activeTarget == POSITION || movePlan.m_activeTarget == ORIENTATION) {

        geometry_msgs::PoseStamped msg;
        tf::poseEigenToMsg(movePlan.m_goalPose, msg.pose);
        msg.header.stamp = ros::Time(0.0);
        msg.header.frame_id = "world_frame";

        moveit_msgs::Constraints c = kinematic_constraints::constructGoalConstraints(m_lastLink, msg, goal_position_tolerance_, goal_orientation_tolerance_);
        if (movePlan.m_activeTarget == ORIENTATION)
          c.position_constraints.clear();
        if (movePlan.m_activeTarget == POSITION)
          c.orientation_constraints.clear();
        request.goal_constraints.resize(1);
        request.goal_constraints[0] = kinematic_constraints::mergeConstraints(request.goal_constraints[0], c);

stomp tries to plan towards the pose with reference to "base_link"

  • planning always fails
    I think this might be related but even though we get a nice trajectory preview to the goal (in the wrong frame, no matter if joint or cartesian goal) it is never accepted as valid. I can see the goal spheres moving around wildly in a rectangular region of about 10x2x2 cm (estimated)

grafik

The displayed coordinate system is "base_link" while "world frame" is rotated by -90° around z, ie x pointing towards the observer. The goal would have been to the right of the right hand box

grafik

Another example, here the robot is supposed to move to the slightly transparent position but plans to a 90° rotated goal instead

@jrgnicho
Copy link
Member Author

@simonschmeisser the code may be ignoring the coordinate frame for the goal tool pose, I'll look into this. Is your testing setup available ?

@jrgnicho
Copy link
Member Author

@Levi-Armstrong it's nor ready to be merge yet, I'll address the issues @simonschmeisser has exposed and push the fixes.

@simonschmeisser
Copy link
Contributor

@jrgnicho unfortunately it's not available. I can try creating a test case on Tuesday the earliest, sorry

@jrgnicho
Copy link
Member Author

@simonschmeisser that'd be helpful if you can. Thanks

@simonschmeisser
Copy link
Contributor

@jrgnicho Sorry for the delay, had some important visitors here

grafik

I forked your branch to provide you with a testcase: https://github.com/isys-vision/industrial_moveit/tree/update-stomp-plugins-ik-code

@jrgnicho
Copy link
Member Author

@simonschmeisser, excellent, I'll test my changes with this setup. Thank you

@jrgnicho
Copy link
Member Author

jrgnicho commented Aug 1, 2017

@simonschmeisser I made some changes to map the robot base coordinate system to the target's frame id. Could you test again?

* @param constraints A moveit_msgs message that encapsulates the cartesian constraints specifications.
* @param tool_pose The tool pose as specified in the constraint in the target_frame.
* @param tolerance The tolerance values on the tool pose as specified in the constraint message.
* @param target_frame The coordinate frame of the tool pose. If black the model root is used
Copy link
Contributor

Choose a reason for hiding this comment

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

Typo: If black the model root is used -> If blank? or If empty

* @param constraints A moveit_msgs message that encapsulates the cartesian constraints specifications.
* @param tool_pose The tool pose as specified in the constraint message.
* @param tolerance The tolerance values on the tool pose as specified in the constraint message.
* @param target_frame The coordinate frame of the tool pose. If black the model root is used
Copy link
Contributor

Choose a reason for hiding this comment

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

same typo here :)

@simonschmeisser
Copy link
Contributor

@jrgnicho it works a lot better than before and plans to correct positions (both pose and joint goals). Cool!

For joint targets I get an error:
[ERROR] [1501586543.595969287]: Constraint is empty
but it still works in some cases. However in quite a few cases it doesn't. Looking at the proposed trajectory it already has a valid solution after the first iteration but after reaching the max number of iterations it aborts claiming that no valid solution has been found. I guess its related to the missing goal constraints and it somehow rejects all goal positions as invalid? If so there should be some more specific error message in addition to:
[ERROR] [1501587166.346616852]: STOMP failed to find a valid solution after 101 iterations

@jrgnicho
Copy link
Member Author

jrgnicho commented Aug 1, 2017

@simonschmeisser , I'll take a look and see why it fails with joint goals. How are you sending a motion plan, through a service call or the move group interface? Even though both methods should be equivalent, the constraints created to represent the motion plan tend to differ.

@simonschmeisser
Copy link
Contributor

We copied from MoveGroup and are thus using the PlanningPipeline (I hope it's not too much code)

    moveit_msgs::MotionPlanRequest request;
    request.group_name = "manipulator";
    request.num_planning_attempts = 4;
    request.max_velocity_scaling_factor = 1.0;
    request.allowed_planning_time = 20.0;
    request.planner_id = "RRTConnectkConfigDefault";
    request.workspace_parameters = moveit_msgs::WorkspaceParameters();

    const double goal_joint_tolerance_ = 1e-4;
    const double goal_position_tolerance_ = 1e-4; // 0.1 mm
    const double goal_orientation_tolerance_ = 1e-3; // ~0.1 deg



    robot_state::robotStateToRobotStateMsg(*movePlan.m_startState, request.start_state);

    if (movePlan.m_activeTarget == JOINT)
    {

      request.goal_constraints.resize(1);
      request.goal_constraints[0] = kinematic_constraints::constructGoalConstraints(*movePlan.m_goalState, m_planningSceneMonitor->getRobotModel()->getJointModelGroup("manipulator"), goal_joint_tolerance_);

    } else if (movePlan.m_activeTarget == POSE || movePlan.m_activeTarget == POSITION || movePlan.m_activeTarget == ORIENTATION) {

        geometry_msgs::PoseStamped msg;
        tf::poseEigenToMsg(movePlan.m_goalPose, msg.pose);
        msg.header.stamp = ros::Time(0.0);
        msg.header.frame_id = "world_frame";

        moveit_msgs::Constraints c = kinematic_constraints::constructGoalConstraints(m_lastLink, msg, goal_position_tolerance_, goal_orientation_tolerance_);
        if (movePlan.m_activeTarget == ORIENTATION)
          c.position_constraints.clear();
        if (movePlan.m_activeTarget == POSITION)
          c.orientation_constraints.clear();
        request.goal_constraints.resize(1);
        request.goal_constraints[0] = kinematic_constraints::mergeConstraints(request.goal_constraints[0], c);

    } else {

        ROS_ERROR("Unable to construct goal representation");
        m_semaphore.release();
        return moveit::planning_interface::MoveItErrorCode::INVALID_GOAL_CONSTRAINTS;
    }

    //if (path_constraints_)
    //  request.path_constraints = *path_constraints_;

    bool success;
    planning_interface::MotionPlanResponse res;

    if (scene) {
        success = planning_pipeline_->generatePlan(scene, request, res);
    } else {
        planning_scene_monitor::LockedPlanningSceneRO ps(m_planningSceneMonitor);
        success = planning_pipeline_->generatePlan(ps, request, res);
    }

@jrgnicho
Copy link
Member Author

jrgnicho commented Aug 1, 2017

OK, this should help, I'll try to work on it tonight. Thanks

@simonschmeisser
Copy link
Contributor

@jrgnicho I'll be in vacation for the next four weeks so no testing from my side till september, sry

@jrgnicho
Copy link
Member Author

Sorry @simonschmeisser I've been swamped lately. I think you've given me enough feedback to fix the issues you had described. Thank

@simonschmeisser
Copy link
Contributor

hey @jrgnicho any news?

@jrgnicho
Copy link
Member Author

jrgnicho commented Dec 5, 2017

@simonschmeisser I'll resume working on this around mid December.

@bmagyar
Copy link
Contributor

bmagyar commented Jan 15, 2018

Big +1 for this, I've done the same myself for my ICRA work (which got rejected) and now working on IROS with the same codebase. I could try to merge this and that cartesian seed code and submit a PR with them. Opinions?

@simonschmeisser
Copy link
Contributor

@bmagyar no objections from my side on somebody fixing this ;) I won't be able to find out why Joint goals fail and how to fix it too soon

@davetcoleman
Copy link
Collaborator

@raghavendersahdev is trying to migrate more stomp integration into the main moveit and we want to port the stomp_moveit plugin over. i don't want to lose this suggested PR but reading through it, it seems momentum has been lost on getting it finished. any updates on this PR?

@simonschmeisser
Copy link
Contributor

@davetcoleman I'm afraid I won't be able to do anything on it too soon.

@jrgnicho
Copy link
Member Author

After merging #77 this PR is ready for review.

@simonschmeisser
Copy link
Contributor

I'll first continue doing functional reviews, I saw nothing obviously wrong/bad when looking through the diff but will repeat that once I'm back into the code

I'm using a 6-DOF fixed robot as seen in screenshots above. It has a gripper with one DOF and one mimic joint attached which is in a different JointModelGroup (and not actually controlled by MoveIt!). My current configuration is as follows:

https://gist.github.com/simonschmeisser/ec19cdabefa2e6e56e3381f278b2ab48

Case 1: noisy_filters: JointLimits/lock_goal : True && JointTarget

This case often works but not necessarily. It often invalidates a valid trajectory during "post refinement"/iterations after valid and then starts optimizing anew. I thought you added a step-back to a previous valid solution, that might be missing here?
https://gist.github.com/simonschmeisser/71986a056ea6a6d6be2408ad4b846c84

Case 2: noisy_filters: JointLimits/lock_goal : True && PoseTarget

[DEBUG] [1541600083.991517045]: STOMP Found no seed trajectory
[ERROR] [1541600083.997600134]: Failed to save goal state
[ERROR] [1541600083.997666402]: Failed to set Plan Request on noisy filter JointLimits/manipulator

Case 3: lock_goal: False && JointTarget

Many goals are evaluated (see spheres in screenshot) but none seem to match validity requirements.

grafik

https://gist.github.com/simonschmeisser/a011a3a3588cfbc0add4784a80b02ac1

Case 4: lock_goal: False && PoseTarget

Visualization looks about the same as case 3, seems to suffer from same goal validity problems

https://gist.github.com/simonschmeisser/8e7fdc4fa6875cda9f79ab3a04872b90

I'm not sure which of these are regressions and which bugs existed before, but I think those issues sound fixable and will have a look myself now.

else
{
// reverting updates as no improvement was made
parameters_optimized_ -= parameters_updates_;
Copy link
Contributor

Choose a reason for hiding this comment

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

we need to set back parameters_valid_ here as well as the previous solution might have been valid:

      // is now valid again
      if (parameters_valid_prev_)
        parameters_valid_ = true;

or more simply

  // set back validity as well, previous might have been valid
 parameters_valid_ = parameters_valid_prev_;

this fixes "Case 1:"

Copy link
Member Author

Choose a reason for hiding this comment

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

I've rearrange this part so as to set the current trajectory to valid when it was reverted to the previous valid one.

Copy link
Contributor

@simonschmeisser simonschmeisser left a comment

Choose a reason for hiding this comment

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

Case 2 can be fixed here:

for(auto& jc : gc.joint_constraints)

if there are no joint constraints, this should succeed as well, I modified it to read as following:

  // saving goal state
  if(lock_goal_)
  {
    bool goal_state_saved = false;
    bool has_joint_constraints = false;
    for(auto& gc: req.goal_constraints)
    {

      if (gc.joint_constraints.empty())
          continue;
      else
          has_joint_constraints = true;

      for(auto& jc : gc.joint_constraints)
      {
        goal_state_->setVariablePosition(jc.joint_name,jc.position);
        goal_state_saved = true;
      }

      if(!goal_state_->satisfiesBounds(robot_model_->getJointModelGroup(group_name_)))
      {
        ROS_WARN("%s Requested Goal State is out of bounds",getName().c_str());
      }

      break;
    }

    if(has_joint_constraints && !goal_state_saved)
    {
      ROS_ERROR_STREAM("Failed to save goal state");
      return false;
    }
  }

Not sure if that should end up in a separate PR, I can do so if preferred

tool_goal_tolerance_ << ptol, ptol, ptol, rtol, rtol, rtol;
}

break;
Copy link
Contributor

Choose a reason for hiding this comment

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

What is the intention of that break?

Copy link
Member Author

Choose a reason for hiding this comment

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

I think I wanted to stop inspecting the constraints once a valid one was found but I my implementation of this intent might've not quite reflected that.

}

break;
Copy link
Contributor

Choose a reason for hiding this comment

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

previously that would break only if found_goal == true

Copy link
Member Author

Choose a reason for hiding this comment

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

I modified this to break out of the look when this condition is met.

@simonschmeisser
Copy link
Contributor

ToolGoalPose seems to generate Goals outside the GoalConstraints, that's why Case 3 and 4 fail:

[DEBUG] [1541607840.750424697]: ToolGoalPose/manipulator last tool error:    -0.00088938 -0.00150005  -0.0107384 -0.00456815   -0.017096  0.00107027
[DEBUG] [1541607840.750453765]: ToolGoalPose/manipulator used tool tolerance: 0.0001      0.0001       0.0001     0.001         0.001     0.001

I will have a look at that tomorrow

@@ -278,7 +288,7 @@ bool GoalGuidedMultivariateGaussian::generateNoise(const Eigen::MatrixXd& parame
return true;
}

bool GoalGuidedMultivariateGaussian::generateRandomGoal(const Eigen::VectorXd& seed_joint_pose,Eigen::VectorXd& goal_joint_pose)
bool GoalGuidedMultivariateGaussian::generateRandomGoal(const Eigen::VectorXd& reference_joint_pose,Eigen::VectorXd& goal_joint_pose)
Copy link
Contributor

Choose a reason for hiding this comment

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

In my observations (case 3 and case4) this function always returns exactly the same joint_position, thus goal_joint_noise in line 266 is all zero. This is not the main problem however. In 284 all trajectory points (==cols) get noise applied. That includes the last column, which is the goal. The sampling noise might be bigger than the goal tolerance however. So if I add
noise.rightCols(1) = goal_joint_noise;
before

parameters_noise = parameters + noise;
Case 3 and case 4 work again.

Why the goal noise is all zero remains to be fixed

Copy link
Member Author

Choose a reason for hiding this comment

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

In my observations (case 3 and case4) this function always returns exactly the same joint_position, thus goal_joint_noise in line 266 is all zero

The goal noise will be zero whenever the cartesian tolerances are small.

The sampling noise might be bigger than the goal tolerance however.

Yes, but the Constrained cartesian goal filter applied later on should enforce the constraints at the goal

I add
noise.rightCols(1) = goal_joint_noise;

I did make this change, however in my test setup it caused stomp to fail very frequently. My guess is that some noise at the goal (even if it's in violation of the requested constraint) allows exploring more reachable goal configurations.

Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm, I have no such thing as a "Constrained cartesian goal filter" in my configuration, should I?

Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm, so when I add - class: stomp_moveit/ConstrainedCartesianGoal as you have it in the example file it sometimes works (ca 60%) but there are still some failures whereas when effectively disabling the noise as in a few comments above it always works. (Except for cases where we compare to the "other" representation of the euler angles). The right thing here would probably be to constrain the noise to be within the goal tolerances

Copy link
Member Author

@jrgnicho jrgnicho Dec 14, 2018

Choose a reason for hiding this comment

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

The Constrained cartesian goal filter enforces the goal tolerances. I'm till puzzled by how you are getting better results when the noise is zeroed out, not sure what to make of that.

Copy link
Member Author

Choose a reason for hiding this comment

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

I also noticed that your stomp_moveit/ToolGoalPose cost function uses 25.0 for the weights. I've been using 0.5 for both

- class: stomp_moveit/ToolGoalPose
        position_cost_weight: 25.0
        orientation_cost_weight: 25.0

The plugin assumes that they add up to 1. My fault for not documenting that

Copy link
Contributor

Choose a reason for hiding this comment

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

Well I haven't checked that thoroughly this time, but last iteration the noise was too big so it would always be just outside the tolerances

maybe additionally you could add an error/warning if this does not add up to 1 (or normalize it). I will check on Monday if that changes anything

@simonschmeisser
Copy link
Contributor

@jrgnicho would you like a PR against your branch or do you prefer fixing it yourself?

@simonschmeisser
Copy link
Contributor

another issue (but probably another PR ...)

[DEBUG] [1541690370.660762891]: ToolGoalPose/manipulator last tool error: 5.28708e-05 0.000100097  6.2889e-05     3.14147    -3.14112     3.14106
[DEBUG] [1541690370.660820099]: ToolGoalPose/manipulator used tool tolerance: 0.0001 0.0001 0.0001  0.001  0.001  0.001

we had similar exciting issues with euler angles recently and switched to comparing in angle-axis format. Not sure how that translates to the limits we currently have though

@davetcoleman
Copy link
Collaborator

+1 to merging this 2 year old PR!!

@simonschmeisser
Copy link
Contributor

For me two open issues remain but we might want to merge this anyway to move ahead

  • more robust goal checking for cartesian goals (angle axis notation?)
  • thread safety?

I observed a crash when running stomp from multiple threads but have not yet investigated this

@jrgnicho
Copy link
Member Author

I've addressed @simonschmeisser comments. My test setup consisted of the stomp demo launch roslaunch stomp_test_kr210_moveit_config demo.launch along with this utility to send various types of plan request to 'move_group'.
If anyone would like to replicate my test setup, my inputs to the moveit utility program were the following:

# copy and paste one line from this list into the terminal and hit enter.
## Joint Goals
1 1.0 -1.57 0.0 0.01 0.01 0.01 1.0
1 -1.0 1.57 0.0 0.01 0.01 0.01 1.0

## Cartesian Position
2 2.0 2.0 0.6 0.015 0.04 0.02
2 -1.5 2.0 0.6 0.015 0.04 0.02

## Cartesian Orientation
3 0.0 -3.14 0.0 3.0 0.03 3.0


## Cartesian Pose
4 1.0 2.0 1.4 0.015 0.04 0.02
4 -1.0 2.0 1.4 0.015 0.04 0.02
4 -0.5 2.0 1.8 0.015 0.04 0.02

@jrgnicho
Copy link
Member Author

I observed a crash when running stomp from multiple threads but have not yet investigated this

@simonschmeisser I haven't had it crash on me yet so I'm not sure how to replicate this.

@simonschmeisser
Copy link
Contributor

I observed a crash when running stomp from multiple threads but have not yet investigated this

@simonschmeisser I haven't had it crash on me yet so I'm not sure how to replicate this.

We plan many possible alternative "routes"/picks from worker threads in our application. So stomp is run simultaneously a couple of times (~5). This worked fine with ompl as there is some sort of thread affine cache but I'm not sure if that is within the planning pipeline or within the plugin. Will check that and also try to pin down the origin of the crash

@simonschmeisser
Copy link
Contributor

Ok, looking a bit at the code it is quite obvious that stomp core is not threadsafe. Which is totally ok. So in a follow up PR we would need to implement this in StompPlannerManager::getPlanningContext: either just create a new StompPlanner per request and discard it later on or check if caching (and locking) instances as OMPL does it really helps anything.

@simonschmeisser
Copy link
Contributor

side note: if you add #include <random> in kinematics.cpp this also compiles on melodic/bionic :)

@jrgnicho
Copy link
Member Author

@simonschmeisser will you be ok with merging this as is?

@simonschmeisser
Copy link
Contributor

Yes totally, we can iron out smaller stuff separately later on. Thanks!

Copy link
Contributor

@simonschmeisser simonschmeisser left a comment

Choose a reason for hiding this comment

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

LGTM

@jrgnicho
Copy link
Member Author

We plan many possible alternative "routes"/picks from worker threads in our application. So stomp is run simultaneously a couple of times (~5). This worked fine with ompl as there is some sort of thread affine cache but I'm not sure if that is within the planning pipeline or within the plugin. Will check that and also try to pin down the origin of the crash

Is this mode of planning done outside of the move_group node workflow?

@simonschmeisser
Copy link
Contributor

yes, we have our own equivalent classes ... it could be implemented as a MoveGroupCapability though

@jrgnicho
Copy link
Member Author

@simonschmeisser thanks for your patience in reviewing this PR.

@jrgnicho jrgnicho merged commit 9a2da66 into ros-industrial:kinetic-devel Dec 17, 2018
@jrgnicho
Copy link
Member Author

jrgnicho commented Dec 17, 2018

yes, we have our own equivalent classes ... it could be implemented as a MoveGroupCapability though

Yes I'm not surprised that it would crash in a multithreaded application as the stomp_core class wasn't made to be used in that type of context and so it lacks important thread-safety features. Creating a stomp_core instance per plan request as you mentioned in a previous comment is likely to work OK however you'll have to fare the cost of having multiple (potentially large) Eigen matrices.

@simonschmeisser
Copy link
Contributor

Nice!

I'll try that approach and measure the costs soonish

@jrgnicho jrgnicho deleted the update-stomp-plugins-ik-code branch April 2, 2019 18:42
@jrgnicho jrgnicho restored the update-stomp-plugins-ik-code branch April 2, 2019 18:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants