Moveit::planning_interface::MoveGroupInterface::move() and execute() methods return before trajectory execution is complete in Noetic

asked 2022-01-27 04:37:32 -0500

mp gravatar image

Hello everyone, I am trying to control a KUKA kr10r1100sixx robot with moveit and kuka_eki_hw_interface on ubuntu 20.04 with ROS Noetic. Connection between nodes seems to be correct as I am able to control my real robot from rviz and the moveit API. However, I have a strange behavior with the move() and execute() methods of Moveit::planning_interface::MoveGroupInterface Class. when I call them my robot starts to move and reaches the desire position, BUT the move() and the execute() methods return before the trajectory is completed.

For example with this simple code:

const double tau = 2 * M_PI;

int main(int argc, char **argv){

    ros::init(argc, argv, "move_group_interface");
    ros::NodeHandle node_handle;

    ros::AsyncSpinner spinner(1);
    spinner.start();

    // Setup
    static const std::string PLANNING_GROUP = "kuka_arm";
    moveit::planning_interface::MoveGroupInterface move_group_interface(PLANNING_GROUP);
    moveit::planning_interface::PlanningSceneInterface planning_scene_interface;
    const moveit::core::JointModelGroup* joint_model_group = move_group_interface.getCurrentState()->getJointModelGroup(PLANNING_GROUP);

    moveit::core::RobotStatePtr current_state = move_group_interface.getCurrentState();

    moveit::planning_interface::MoveGroupInterface::Plan my_plan;

    // get the current set of joint values for the group.
    std::vector<double> joint_group_positions;
    current_state->copyJointGroupPositions(joint_model_group, joint_group_positions);

    // Now, let's modify one of the joints
    joint_group_positions[0] = tau/6;  // -1/6 turn in radians
    move_group_interface.setJointValueTarget(joint_group_positions);

    move_group_interface.setMaxVelocityScalingFactor(0.05);
    move_group_interface.setMaxAccelerationScalingFactor(0.05);
    move_group_interface.setStartStateToCurrentState();

    bool success = (move_group_interface.plan(my_plan) == moveit::planning_interface::MoveItErrorCode::SUCCESS);
    std::cout<< "desired position: " << joint_group_positions[0] << std::endl; 
    if(success){
        move_group_interface.execute(my_plan);
    }
    std::cout<< "current position: " << move_group_interface.getCurrentJointValues()[0] << std::endl;

    return 0;
}

my output is :

desired position: 1.0472 
current position: 0.647218

where current position is the position just after execute() has returned.

moreover in the rviz related terminal I have the following output:

You can start planning now!

[ INFO] [1643275596.859554899]: Loading robot model 'kuka_kr10r1100sixx'...
[ INFO] [1643275596.952841080]: Starting planning scene monitor
[ INFO] [1643275596.955281687]: Listening to '/move_group/monitored_planning_scene'
[ INFO] [1643275597.069042839]: Constructing new MoveGroup connection for group 'kuka_arm' in namespace ''
[ INFO] [1643275598.189729895]: Ready to take commands for planning group kuka_arm.
[ INFO] [1643275607.970914515]: Planning request received for MoveGroup action. Forwarding to planning pipeline.
[ INFO] [1643275607.973524865]: Planner configuration 'kuka_arm' will use planner 'geometric::RRTConnect'. Additional configuration parameters will be set when the planner is constructed.
[ INFO] [1643275607.974053888]: kuka_arm/kuka_arm: Starting planning with 1 states already in datastructure
[ INFO] [1643275607.985431161]: kuka_arm/kuka_arm: Created 5 states (2 start + 3 goal)
[ INFO] [1643275607.985503853]: Solution found in 0.011550 seconds
[ INFO] [1643275607.989434298]: SimpleSetup: Path simplification took 0.003820 seconds and changed from 4 to 2 states
[ INFO] [1643275607.990788359]: Execution request received
[ INFO] [1643275611.995134867]: Controller '' successfully finished
[ INFO] [1643275612.050076662]: Completed trajectory execution with status SUCCEEDED ...
[ INFO] [1643275612.050324234]: Execution completed: SUCCEEDED

The last line is printed long before the robot stops.

As the documentation explains that move() and execute() are blocking methods until the traectory is complete, I don't understand the behavior that I'm encountering.

By the way I check the GoalJointTolerance value and it is set to 0.0001.

So,what can be wrong in my code that can explain this behavior? I thought about ... (more)

edit retag flag offensive close merge delete

Comments

Assuming you're using the standard configuration of kuka_eki_hw_interface with a position_controllers/JointTrajectoryController at least the driver side of this should be ok, and just reporting whatever the KRC reports.

You may want to include some more information on your setup (ie: which components, how do you start them, what is their configuration, etc).

If you manually (so without MoveIt) put together a JointTrajectory and submit it as a goal to the JointTrajectoryController, does it also report completion too soon?

gvdhoorn gravatar image gvdhoorn  ( 2022-01-27 05:41:29 -0500 )edit

Hi @gvdhoorn, to send a trajectory to JointTrajectoryController without moveIt! I did something similar to this tutorial : http://wiki.ros.org/Robots/TIAGo/Tuto..., the execution stops after that the trajectory is complete. So playing a trajectory without using moveIt! seems to work fine.

mp gravatar image mp  ( 2022-01-27 11:28:24 -0500 )edit

Then it would seem at least the driver side is behaving.

Which could point to a problem with your MoveIt configuration, but I would not know what that could be.

gvdhoorn gravatar image gvdhoorn  ( 2022-01-27 11:35:42 -0500 )edit

How many seconds does the arm take to make the full movement? What velocity is being reported for the first joint while the joint is moving? If you have restricted the joint to move very slowly, you may have unintentionally triggered the "arm has stopped" state, which would explain why the action client seems to return early.

Mike Scheutzow gravatar image Mike Scheutzow  ( 2022-01-27 19:52:08 -0500 )edit

If the trajectory execution monitor aborted the motion, I would not expect to see this:

[ INFO] [1643275607.990788359]: Execution request received
[ INFO] [1643275611.995134867]: Controller '' successfully finished
[ INFO] [1643275612.050076662]: Completed trajectory execution with status SUCCEEDED ...
[ INFO] [1643275612.050324234]: Execution completed: SUCCEEDED

but:

[ERROR] [1234567890.123456789]: Controller is taking too long to execute trajectory (the expected upper bound for the trajectory execution was X.Y seconds). Stopping trajectory.
[ INFO] [1234567890.123456789]: MoveitSimpleControllerManager: Cancelling execution for
[ INFO] [1234567890.123456789]: Execution completed: TIMED_OUT

it'd still be good to check though.

gvdhoorn gravatar image gvdhoorn  ( 2022-01-28 05:04:08 -0500 )edit

Hi @Mike Scheutzow I did several tests, here are the results:

With MaxVelScalingFactor = 0.05; execute() return after 4.0991s, the real robot stops after 5.5020s and the velocity in the control_msgs/FollowJointTrajectoryActionGoal send to the controller is 0.26 rad/s

With MaxVelScalingFactor = 0.1; execute() return after 2.6044s, the real robot stops after 4.4483s and the velocity in the control_msgs/FollowJointTrajectoryActionGoal send to the controller is 0.52 rad/s

With MaxVelScalingFactor = 0.01; execute() return after 20.112s, the real robot stops after 20.200s and the velocity in the control_msgs/FollowJointTrajectoryActionGoal send to the controller is 0.052 rad/s

my hypothesis is that maybe values in my joint_limits.yaml file (ex: max_velocity: 5.235987755982989 for joint_a1) are not consistent with the real max speed values defined on the robot. But at the moment I haven't found a speed value that works ...(more)

mp gravatar image mp  ( 2022-01-28 07:56:03 -0500 )edit

The velocity limits likely come from the URDF, which has them directly from the datasheet provided by KUKA. I doubt they are different, unless your KRC has lower limits configured for whatever reason.

Personally, I would check acceleration instead.

The URDF does not contain any data on acceleration limits, and it's likely joint_limits.yaml says has_acceleration_limits: false for all joints. Unless something has changed, that will cause MoveIt to use 1.0 rad/s^2, which is rather slow.

KUKA does not tell anyone the acceleration limits, so you'll have to guestimate some and update your joint_limits.yaml.

But all of this is likely not connected to your actual problem. As I wrote earlier, if the trajectory execution manager aborted a trajectory, it should print an ERROR on the console. You don't mention any.

Something makes MoveIt conclude trajectory execution completed already. From your earlier test, it ...(more)

gvdhoorn gravatar image gvdhoorn  ( 2022-01-28 08:19:07 -0500 )edit

Those joint velocities don't seem too slow to me. A few ideas you could try:

Maybe check the MoveItErrorCode status returned by execute() to see if it says anything interesting?

What happens if you don't call the setMax*ScalingFactor() methods?

Mike Scheutzow gravatar image Mike Scheutzow  ( 2022-01-30 07:40:01 -0500 )edit