ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question

Are JointPositionControllers supposed to wrap angles on continuous joints?

asked 2014-11-19 16:00:33 -0500

lucasw gravatar image

updated 2020-11-21 11:40:57 -0500

I was expected to be able to give a large position command to a continuous joint and see the joint spin multiple revolutions before arriving at the desired position, instead it appears to be wrapping the angle and sometimes moving in the opposite direction of what is desired. Is it supposed to work like that?

This is Indigo on Ubuntu 14.04, using Gazebo 2.2.3 - perhaps gazebo is wrapping the angle and the controller needs to look for that event and keep internal track of angle.

edit retag flag offensive close merge delete


Hi, were you able to get a solution? Facing the same problem in my setup (Ubuntu 16.04, Gazebo 7). Thanks

harshitsureka gravatar image harshitsureka  ( 2017-03-27 13:37:53 -0500 )edit

No I haven't looked into it. I suspect this needs to be fixed in the source code

lucasw gravatar image lucasw  ( 2017-03-27 14:10:21 -0500 )edit

2 Answers

Sort by ยป oldest newest most voted

answered 2017-03-27 15:03:10 -0500

lucasw gravatar image

updated 2017-03-27 15:32:46 -0500

It looks like the controller is calling shortest_angular_distance on the difference between the current and targeted position (from or /opt/ros/kinetic/include/angles/angles.h)

ros_controllers$ grep -r shortest_angular_distance
joint_trajectory_controller/include/joint_trajectory_controller/joint_trajectory_segment.h:    Scalar dist = angles::shortest_angular_distance(prev_position, next_position);
joint_trajectory_controller/test/joint_trajectory_controller_test.cpp:  // that it has to wrap when in fact it doesn't. This comes from a call to angles::shortest_angular_distance, which
effort_controllers/src/joint_position_controller.cpp:   angles::shortest_angular_distance_with_limits(
effort_controllers/src/joint_position_controller.cpp:    error = angles::shortest_angular_distance(current_position, command_position);
velocity_controllers/src/joint_position_controller.cpp:   angles::shortest_angular_distance_with_limits(
velocity_controllers/src/joint_position_controller.cpp:    error = angles::shortest_angular_distance(current_position, command_position);


 static inline double normalize_angle(double angle)
    double a = normalize_angle_positive(angle);
    if (a > M_PI)
      a -= 2.0 *M_PI;
    return a;

   * \function
   * \brief shortest_angular_distance
   * Given 2 angles, this returns the shortest angular
   * difference.  The inputs and ouputs are of course radians.
   * The result
   * would always be -pi <= result <= pi.  Adding the result
   * to "from" will always get you an equivelent angle to "to".

  static inline double shortest_angular_distance(double from, double to)
    return normalize_angle(to-from);

I think a solution would involve creating a new joint type that doesn't do the the wrapping.

Started an issue here:

edit flag offensive delete link more

answered 2017-03-27 16:37:23 -0500

dcconner gravatar image

updated 2017-03-27 16:38:53 -0500

Can you change URDF to use "Revolute" joint with arbitrarily large joint limits?

Continuous joints are supposed to be like wheels. Revolute joints can spin a limited number of times, but I think they preserve their internal angles.

edit flag offensive delete link more

Question Tools



Asked: 2014-11-19 16:00:33 -0500

Seen: 753 times

Last updated: Mar 27 '17