def test_joints_to_kdl(self):
     arm = ArmInterface()
     for idx, name in zip(range(len(arm.joint_names)), arm.joint_names):
         for t in ['positions', 'torques']:
             jnt_array = arm.joints_to_kdl(t, last_joint=name)
             self.assertEquals(jnt_array.rows(), idx + 1,
                               'Invalid number of joints, joint_idx=%d, last_joint=%s, n_joints=%d' % (idx, name, jnt_array.rows()))
示例#2
0
 def test_joints_to_kdl(self):
     arm = ArmInterface()
     for idx, name in zip(range(len(arm.joint_names)), arm.joint_names):
         for t in ['positions', 'torques']:
             jnt_array = arm.joints_to_kdl(t, last_joint=name)
             self.assertEquals(
                 jnt_array.rows(), idx + 1,
                 'Invalid number of joints, joint_idx=%d, last_joint=%s, n_joints=%d'
                 % (idx, name, jnt_array.rows()))
class KinematicsService(object):
    def __init__(self):
        ns = [
            item for item in rospy.get_namespace().split('/') if len(item) > 0
        ]
        if len(ns) != 2:
            rospy.ROSException(
                'The controller must be called in the manipulator namespace')

        self._namespace = ns[0]
        self._arm_name = ns[1]

        if self._namespace[0] != '/':
            self._namespace = '/' + self._namespace

        if self._namespace[-1] != '/':
            self._namespace += '/'
        # The arm interface loads the parameters from the URDF file and
        # parameter server and initializes the KDL tree
        self._arm_interface = ArmInterface()

        self._base_link = self._arm_interface.base_link
        self._tip_link = self._arm_interface.tip_link

        self._tip_frame = PyKDL.Frame()

        # KDL Solvers
        self._ik_v_kdl = PyKDL.ChainIkSolverVel_pinv(self._arm_interface.chain)
        self._ik_p_kdl = PyKDL.ChainIkSolverPos_NR(
            self._arm_interface.chain, self._arm_interface._fk_p_kdl,
            self._ik_v_kdl)
        self._dyn_kdl = PyKDL.ChainDynParam(self._arm_interface.chain,
                                            PyKDL.Vector.Zero())

        # Add a callback function to calculate the end effector's state by each
        # update of the joint state
        self._arm_interface.add_callback('joint_states',
                                         self.on_update_endeffector_state)
        # Publish the current manipulability index at each update of the joint
        # states
        # self._arm_interface.add_callback('joint_states',
        #                                  self.publish_man_index)

        # Publish the end effector state
        self._endeffector_state_pub = rospy.Publisher('endpoint_state',
                                                      EndPointState,
                                                      queue_size=1)

        # Publish the manipulability index
        self._man_index_pub = rospy.Publisher('man_index',
                                              Float64,
                                              queue_size=1)

        self._services = dict()
        # Provide the service to calculate the inverse kinematics using the KDL solver
        self._services['ik'] = rospy.Service('ik_solver', SolveIK,
                                             self.solve_ik)

    @property
    def joint_names(self):
        return self._arm_interface.joint_names

    @property
    def joint_angles(self):
        return self._arm_interface.joint_angles

    @property
    def joint_velocities(self):
        return self._arm_interface.joint_velocities

    @property
    def joint_efforts(self):
        return self._arm_interface.joint_efforts

    @property
    def home(self):
        return self._arm_interface.home

    def solve_ik(self, req):
        out = SolveIKResponse()
        out.isValid = False
        out.joints = JointState()

        pos = [req.pose.position.x, req.pose.position.y, req.pose.position.z]
        orientation = [
            req.pose.orientation.x, req.pose.orientation.y,
            req.pose.orientation.z, req.pose.orientation.w
        ]

        if result_ik is not None:
            for i, name in zip(range(len(self.joint_names)), self.joint_names):
                out.joints.name.append(name)
                out.joints.position.append(result_ik[i])
            out.isValid = True
        return out

    def inverse_kinematics(self, position, orientation=None, seed=None):
        ik = PyKDL.ChainIkSolverVel_pinv(self._arm_interface.chain)
        pos = PyKDL.Vector(position[0], position[1], position[2])
        if orientation is not None:
            rot = PyKDL.Rotation()
            rot = rot.Quaternion(orientation[0], orientation[1],
                                 orientation[2], orientation[3])
        # Populate seed with current angles if not provided
        seed_array = PyKDL.JntArray(self._arm_interface.n_joints)
        if seed is not None:
            seed_array.resize(len(seed))
            for idx, jnt in enumerate(seed):
                seed_array[idx] = jnt
        else:
            seed_array = self._arm_interface.joints_to_kdl('positions')

        # Make IK Call
        if orientation:
            goal_pose = PyKDL.Frame(rot, pos)
        else:
            goal_pose = PyKDL.Frame(pos)
        result_angles = PyKDL.JntArray(self._arm_interface.n_joints)

        if self._ik_p_kdl.CartToJnt(seed_array, goal_pose, result_angles) >= 0:
            result = np.array(list(result_angles))
            return result
        else:
            return None

    def publish_man_index(self):
        # Retrieve current jacobian matrix
        w_msg = Float64()
        w_msg.data = self._arm_interface.man_index
        self._man_index_pub.publish(w_msg)

    def on_update_endeffector_state(self):
        state_msg = EndPointState()
        # Store everything in the end point state message
        state_msg.pose.position.x = self._arm_interface.endeffector_pose[
            'position'][0]
        state_msg.pose.position.y = self._arm_interface.endeffector_pose[
            'position'][1]
        state_msg.pose.position.z = self._arm_interface.endeffector_pose[
            'position'][2]

        state_msg.pose.orientation.x = self._arm_interface.endeffector_pose[
            'orientation'][0]
        state_msg.pose.orientation.y = self._arm_interface.endeffector_pose[
            'orientation'][1]
        state_msg.pose.orientation.z = self._arm_interface.endeffector_pose[
            'orientation'][2]
        state_msg.pose.orientation.w = self._arm_interface.endeffector_pose[
            'orientation'][3]

        state_msg.twist.linear.x = self._arm_interface.endeffector_twist[
            'linear'][0]
        state_msg.twist.linear.y = self._arm_interface.endeffector_twist[
            'linear'][1]
        state_msg.twist.linear.z = self._arm_interface.endeffector_twist[
            'linear'][2]

        state_msg.twist.angular.x = self._arm_interface.endeffector_twist[
            'angular'][0]
        state_msg.twist.angular.y = self._arm_interface.endeffector_twist[
            'angular'][1]
        state_msg.twist.angular.z = self._arm_interface.endeffector_twist[
            'angular'][2]

        state_msg.wrench.force.x = self._arm_interface.endeffector_wrench[
            'force'][0]
        state_msg.wrench.force.y = self._arm_interface.endeffector_wrench[
            'force'][1]
        state_msg.wrench.force.z = self._arm_interface.endeffector_wrench[
            'force'][2]

        state_msg.wrench.torque.x = self._arm_interface.endeffector_wrench[
            'torque'][0]
        state_msg.wrench.torque.y = self._arm_interface.endeffector_wrench[
            'torque'][0]
        state_msg.wrench.torque.z = self._arm_interface.endeffector_wrench[
            'torque'][0]

        self._endeffector_state_pub.publish(state_msg)