Example #1
0
class Baxter(object):
    """
    Iinterface for controlling the real and simulated
    Baxter robot.
    """
    def __init__(self,
                 sim=False,
                 config=None,
                 time_step=1.0,
                 rate=100.0,
                 missed_cmds=20000.0):
        """
        Initialize Baxter Interface

        Args:
            sim (bool): True specifies using the PyBullet simulator
                False specifies using the real robot
            arm (str): 'right' or 'left'
            control (int): Specifies control type
                TODO: change to str ['ee', 'position', 'velocity']
            config (class): Specifies joint ranges, ik null space paramaters, etc
            time_step (float):
                TODO: probably get rid of this
            rate (float):
            missed_cmds (float):
        """
        self.sim = sim
        self.dof = {
            'left': {
                'ee': 6,
                'position': 7,
                'velocity': 7
            },
            'right': {
                'ee': 6,
                'position': 7,
                'velocity': 7
            },
            'both': {
                'ee': 12,
                'position': 14,
                'velocity': 14
            }
        }

        if self.sim:
            import pybullet as p
            import baxter_pybullet_interface as pybullet_interface
            self.baxter_path = "assets/baxter_robot/baxter_description/urdf/baxter.urdf"
            self.time_step = time_step
        else:
            import rospy
            from baxter_pykdl import baxter_kinematics
            import baxter_interface
            from baxter_interface import CHECK_VERSION, Limb, Gripper
            from geometry_msgs.msg import PoseStamped, Pose, Point, Quaternion
            from std_msgs.msg import Header
            from baxter_core_msgs.srv import SolvePositionIK, SolvePositionIKRequest
            self.rate = rate
            self.freq = 1 / rate
            self.missed_cmds = missed_cmds
        self.config = config
        self.initial_setup()

    def set_command_time_out(self):
        """
        Set command timeout for sending ROS commands
        """
        if self.sim:
            pass
        else:
            self.left_arm.set_command_timeout(self.freq * self.missed_cmds)
            self.right_arm.set_command_timeout(self.freq * self.missed_cmds)
        return

    def initial_setup(self):
        if self.sim:
            # load baxter
            objects = [p.loadURDF(self.baxter_path, useFixedBase=True)]
            self.baxter_id = objects[0]
            print("baxter_id: ", self.baxter_id)
            if self.config:
                self.use_nullspace = True
                self.use_orientation = True
                self.ll = self.config.nullspace.ll
                self.ul = self.config.nullspace.ul
                self.jr = self.config.nullspace.jr
                self.rp = self.config.nullspace.rp
            else:
                self.use_nullspace = False
            self.create_arms()
        else:
            self.create_arms()
            self.set_command_time_out()
            self.control_rate = rospy.Rate(self.rate)

    def reset(self, initial_pose=None):
        if self.sim:
            self._reset_sim(initial_pose)
        else:
            self._reset_real(initial_pose)

    def _reset_real(self, initial_pose=None):
        self.enable()
        time.sleep(0.5)
        self.set_initial_position('right')
        self.set_initial_position('left', blocking=True)
        self.calibrate_grippers()

    def _reset_sim(self, control_type=None, initial_pose=None):
        # set control type
        if control_type == 'position' or control_type == 'ee' or control_type is None:
            control_mode = p.POSITION_CONTROL
        elif control_type == 'velocity':
            control_mode = p.VELOCITY_CONTROL
        elif control_mode == 'torque':
            control_mode = p.TORQUE_CONTROL
        else:
            raise ValueError(
                "control_type must be in ['position', 'ee', 'velocity', 'torque']."
            )
        # set initial position
        if initial_pose:
            for joint_index, joint_val in initial_pose:
                p.resetJointState(0, joint_index, joint_val)
                p.setJointMotorControl2(self.baxter_id,
                                        jointIndex=joint_index,
                                        controlMode=control_mode,
                                        targetPosition=joint_val)
        else:
            num_joints = p.getNumJoints(self.baxter_id)
            for joint_index in range(num_joints):
                p.setJointMotorControl2(self.baxter_id,
                                        joint_index,
                                        control_mode,
                                        maxForce=self.config.max_force)
        return

    def create_arms(self):
        """
        Create arm interface objects for Baxter.

        An arm consists of a Limb and its Gripper.
        """
        # create arm objects
        if self.sim:
            self.left_arm = pybullet_interface.Limb(self.baxter_id, "left",
                                                    self.config)
            # self.left_arm.gripper = pybullet_interface.Gripper("left")

            self.right_arm = pybullet_interface.Limb(self.baxter_id, "right",
                                                     self.config)
            # self.right_arm.gripper = pybullet_interface.Gripper("right")
        else:
            self.left_arm = Limb("left")
            self.left_arm.gripper = Gripper("left")
            self.left_arm.kin = baxter_kinematics("left")

            self.right_arm = Limb("right")
            self.right_arm.gripper = Gripper("right")
            self.right_arm.kin = baxter_kinematics("right")
        return

    def calibrate_grippers(self):
        """
        (Blocking) Calibrates gripper(s) if not
        yet calibrated
        """
        if not self.left_arm.gripper.calibrated():
            self.left_arm.gripper.calibrate()
        if not self.right_arm.gripper.calibrated():
            self.right_arm.gripper.calibrate()
        return

    def enable(self):
        self._rs = baxter_interface.RobotEnable(CHECK_VERSION)
        self._init_state = self._rs.state().enabled
        self._rs.enable()

    def shutdown(self):
        pass

    def set_joint_velocities(self, arm, joint_velocities):
        """
        Set joint velocites for a given arm

        Args
            arm (str): 'left' or 'right' or 'both'
            joint_velocities (list or tuple or numpy array):
                Array of len 7 or 14
        """
        if arm == 'left':
            action_dict = self.create_action_dict('left', 'velocity',
                                                  joint_velocities)
            self.left_arm.set_joint_velocities(action_dict)
        elif arm == 'right':
            action_dict = self.create_action_dict('right', 'velocity',
                                                  joint_velocities)
            self.right_arm.set_joint_velocities(action_dict)
        elif arm == 'both':
            l_velocities = joint_velocities[:7]
            r_velocities = joint_velocities[7:]
            l_action_dict = self.create_action_dict('left', 'velocity',
                                                    l_velocities)
            r_action_dict = self.create_action_dict('right', 'velocity',
                                                    r_velocities)
            self.left_arm.set_joint_velocities(l_action_dict)
            self.right_arm.set_joint_velocities(r_action_dict)
        return

    def move_to_joint_positions(self, arm, joint_positions):
        """
        Move specified arm to give joint positions

        (This function is blocking.)

        Args
            arm (str): 'left' or 'right' or 'both'
            joint_positionns (list or tuple or numpy array):
                Array of len 7 or 14
        """
        if arm == 'left':
            action_dict = self.create_action_dict('left', 'position',
                                                  joint_positions)
            self.left_arm.move_to_joint_positions(action_dict)
        elif arm == 'right':
            action_dict = self.create_action_dict('right', 'position',
                                                  joint_positions)
            self.right_arm.move_to_joint_positions(action_dict)
        elif arm == 'both':
            l_joints = joint_positions[:7]
            r_joints = joint_positions[7:]
            l_action_dict = self.create_action_dict('left', 'position',
                                                    l_joints)
            r_action_dict = self.create_action_dict('right', 'position',
                                                    r_joints)
            self.left_arm.move_to_joint_positions(l_action_dict)
            self.right_arm.move_to_joint_positions(r_action_dict)
        return

    def set_joint_positions(self, arm, joint_positions):
        """
        Move specified arm to give joint positions

        (This function is not blocking.)

        Args
            arm (str): 'left' or 'right' or 'both'
            joint_positionns (list or tuple or numpy array):
                Array of len 7 or 14
        """
        if arm == 'left':
            action_dict = self.create_action_dict('left', 'position',
                                                  joint_positions)
            self.left_arm.set_joint_positions(action_dict)
        elif arm == 'right':
            action_dict = self.create_action_dict('right', 'position',
                                                  joint_positions)
            self.right_arm.set_joint_positions(action_dict)
        elif arm == 'both':
            l_joints = joint_positions[:7]
            r_joints = joint_positions[7:]
            l_action_dict = self.create_action_dict('left', 'position',
                                                    l_joints)
            r_action_dict = self.create_action_dict('right', 'position',
                                                    r_joints)
            self.left_arm.set_joint_positions(l_action_dict)
            self.right_arm.set_joint_positions(r_action_dict)
        return

    def move_to_ee_pose(self, arm, pose, blocking=True):
        """
        Move end effector to specified pose

        Args
            arm (string): "left" or "right" or "both"
            pose (list):
                if arm == 'left' or arm == 'right':
                    pose = [X, Y, Z, r, p, w]
                else:
                    pose = left_pose + right _pose
        """
        if arm == "both":
            left_pose = pose[:6]
            right_pose = pose[6:]
            left_joints = self.ik('left', left_pose)
            right_joints = self.ik('right', right_pose)
            if blocking:
                self.left_arm.move_to_joint_positions(left_joints)
                self.right_arm.move_to_joint_positions(right_joints)
            else:
                self.left_arm.set_joint_positions(left_joints)
                self.right_arm.set_joint_positions(right_joints)
        elif arm == "left":
            joints = self.ik(arm, pose)
            if blocking:
                self.left_arm.move_to_joint_positions(joints)
            else:
                self.left_arm.set_joint_positions(joints)
        elif arm == "right":
            joints = self.ik(arm, pose)
            if blocking:
                self.right_arm.move_to_joint_positions(joints)
            else:
                self.right_arm.set_joint_positions(joints)
        else:
            raise ValueError("Arm must be 'right', 'left', or 'both'")
        return

    def get_ee_pose(self, arm, mode=None):
        """
        Returns end effector pose for specified arm.

        End effector pose is a list of values corresponding to the 3D cartesion coordinates
        and roll (r), pitch (p), and yaw (w) Euler angles.

        Args
            arm (string): "right" or "left"
            mode (string): "Quaternion" or "quaterion" or "quat"
        Returns
            pose (list): Euler angles [X,Y,Z,r,p,w] or Quaternion [X,Y,Z,x,y,z,w]
        """
        if arm == 'left' or arm == 'right':
            pos = self.get_ee_position(arm)
            orn = self.get_ee_orientation(arm, mode)
            return pos + orn
        elif arm == 'both':
            l_pos = self.get_ee_position('left')
            l_orn = self.get_ee_orientation('left', mode)
            r_pos = self.get_ee_position('right')
            r_orn = self.get_ee_orientation('right', mode)
            return l_pos + l_orn + r_pos + r_orn

    def get_ee_position(self, arm):
        """
        Returns end effector position for specified arm.

        Returns the 3D cartesion coordinates of the end effector.
        Args
            arm (string): "left" or "right" or "both"
        Returns
            [X,Y,Z]
        """
        if arm not in ['left', 'right', 'both']:
            raise ValueError("Arg arm should be 'left' or 'right' or 'both'.")
        if arm == "left":
            return list(self.left_arm.endpoint_pose()['position'])
        elif arm == "right":
            return list(self.right_arm.endpoint_pose()['position'])
        elif arm == "both":
            return list(self.left_arm.endpoint_pose()['position']) + list(
                self.right_arm.endpoint_pose()['position'])

    def get_ee_orientation(self, arm, mode=None):
        """
        Returns a list of the orientations of the end effectors(s)
        Args
            arm (string): "right" or "left" or "both"
            mode (string): specifies angle representation
        Returns
            orn (list): list of Euler angles or Quaternion
        """
        if arm not in ['left', 'right', 'both']:
            raise ValueError("Arg arm should be 'left' or 'right'.")
        if arm == "left":
            orn = list(self.left_arm.endpoint_pose()['orientation'])
        elif arm == "right":
            orn = list(self.right_arm.endpoint_pose()['orientation'])
        elif arm == "both":
            orn = list(self.left_arm.endpoint_pose()['orientation']) + list(
                self.right_arm.endpoint_pose()['orientation'])
        return list(p.getEulerFromQuaternion(orn))

    def get_joint_angles(self, arm):
        """
        Get joint angles for specified arm

        Args
            arm(strin): "right" or "left" or "both"

        Returns
            joint_angles (list): List of joint angles starting from the right_s0 ('right_upper_shoulder')
                and going down the kinematic tree to the end effector.
        """
        if arm == "left":
            joint_angles = self.left_arm.joint_angles()
        elif arm == "right":
            joint_angles = self.right_arm.joint_angles()
        elif arm == "both":
            joint_angles = self.left_arm.joint_angles(
            ) + self.right_arm.joint_angles()
        else:
            raise ValueError("Arg arm should be 'left' or 'right' or 'both'.")
        if not self.sim:
            joint_angles = joint_angles.values()
        return joint_angles

    def get_joint_velocities(self, arm):
        """
        Get joint velocites for specified arm
        """
        if arm == "left":
            return self.left_arm.joint_velocities()
        elif arm == "right":
            return self.right_arm.joint_velocities()
        elif arm == "both":
            return self.left_arm.joint_velocities(
            ) + self.right_arm.joint_velocities()
        else:
            raise ValueError("Arg arm should be 'left' or 'right' or 'both'.")
        if not self.sim:
            joint_velocities = joint_velocities.values()
        return joint_velocities

    def get_joint_efforts(self, arm):
        """
        Get joint torques for specified arm
        """
        if arm == "left":
            return self.left_arm.joint_effort()
        elif arm == "right":
            return self.right_arm.joint_efforts()
        elif arm == "both":
            return self.left_arm.joint_efforts(
            ) + self.right_arm.joint_efforts()
        else:
            raise ValueError("Arg arm should be 'left' or 'right' or 'both'.")
        if not self.sim:
            joint_efforts = joint_efforts.values()
        return

    def apply_action(self, arm, control_type, action):
        """
        Apply a joint action

        Blocking on real robot

        Args
            action - list or tuple specifying end effector pose(6DOF * num_arms)
                    or joint angles (7DOF * num_arms)
        """
        # verify action
        verified, err = self._verify_action(arm, control_type, action)
        if not verified:
            raise err
        # execute action
        if control_type == 'position':
            self._apply_position_control(arm, action)
        elif control_type == 'ee':
            self._apply_ee_control(arm, action)
        elif control_type == 'velocity':
            self._apply_velocity_control(arm, action)
        elif control_type == 'torque':
            self._apply_torque_control(arm, action)
        else:
            raise ValueError(
                "Control type must be ['ee', 'position', 'velocity', 'torque']"
            )

    def _verify_action(self, arm, control_type, action):
        """
        Verify type and dimension of action

        Args
            arm (str): "left" or "right" or "both"
            action (list): list of floats len will vary depending on action type

        Returns
            bool: True if action is right dimension, false otherwise
        """
        if arm not in ["left", "right", "both"]:
            return False, ValueError("Arg arm must be string")
        if control_type not in ['ee', 'position', 'velocity', 'torque']:
            return False, ValueError(
                "Arg control_type must be one of ['ee', 'position', 'velocity', 'torque']"
            )
        if not isinstance(action, (list, tuple, np.ndarray)):
            return False, TypeError("Action must be a list or tuple.")
        if len(action) != self.dof[arm][control_type]:
            return False, ValueError("Action must have len {}".format(
                self.dof * num_arms))
        return True, ""

    def _apply_torque_control(self, arm, action):
        """
        As of right now, setting joint torques does not
        does not command the robot as expected
        """
        raise NotImplementedError(
            'Cannot apply torque control. Try using joint position or velocity control'
        )

    def _apply_velocity_control(self, arm, action):
        """
        Apply velocity control to a given arm

        Args
            arm (str): 'right' or 'left'
            action (list, tuple, or numpy array) of len 7
        """
        if self.sim:
            pass
        else:
            if arm == 'left':
                action_dict = self
                self.right_arm.set_joint_velocities
            if arm == 'right':
                pass
            if arm == 'both':
                pass
        return

    def _apply_position_control(self, arm, action, blocking=True):
        """
        Apply a joint action
        Args:
            arm (str): 'right', 'left', or 'both'
            action - list or array of joint angles
            blocking (bool): If true, wait for arm(s) to reach final position(s)
        """
        action = list(action)
        if blocking:
            self.move_to_joint_positions(arm, action)
        else:
            self.set_joint_positions(arm, action)
        return

    def _apply_ee_control(self, arm, action, blocking=True):
        """
        Apply action to move Baxter end effector(s)

        Args
            arm (str): 'left' or 'right' or 'both'
            action (list, tuple, or numpy array)
            blocking: Bool
        """
        action = list(action)
        if self.sim:
            if arm == 'left' or arm == 'right':
                self.move_to_ee_pose(arm, action)
            elif arm == 'both':
                if self.sim:
                    joint_indices = self.left_arm.indices + self.right_arm.indices
                    self.left_arm.move_to_joint_positions(
                        actions, joint_indices)
        else:
            self.move_to_ee_pose(arm, action, blocking)
        return

    def fk(self, arm, joints):
        """
        Calculate forward kinematics

        Args
            arm (str): 'right' or 'left'
            joints (list): list of joint angles

        Returns
            pose(list): [x,y,z,r,p,w]
        """
        if arm == 'right':
            pose = list(self.right_arm.kin.forward_position_kinematics(joints))
        elif arm == 'left':
            pose = list(self.left_arm.kin.forward_position_kinematics(joints))
        else:
            raise ValueError("Arg arm must be 'right' or 'left'")
        return pose[:3] + list(self.quat_to_euler(pose[3:]))

    def _ik(self, arm, pos, orn=None, seed=None):
        """
        Calculate inverse kinematics

        Args
            arm (str): 'right' or 'left'
            pos (list): [X, Y, Z]
            orn (list): [r, p, w]
            seed (int): for setting random seed

        Returns
            joint angles (list): A list of joint angles

        Note: This will probably fail if orn is not included
        """
        if orn is not None:
            orn = list(self.euler_to_quat(orn))
        if arm == 'right':
            joint_angles = self.right_arm.kin.inverse_kinematics(pos, orn)
        elif arm == 'left':
            joint_angles = self.left_arm.kin.inverse_kinematics(pos, orn, seed)
        else:
            raise ValueError("Arg arm must be 'right' or 'left'")
        return list(joint_angles.tolist())

    def ik(self, arm, ee_pose):
        """
        Calculate inverse kinematics for a given end effector pose

        Args
            ee_pose (list or tuple of floats): 6 dimensional array specifying
                the position and orientation of the end effector
            arm (string): "right" or "left"

        Return
            joints (list): A list of joint angles
        """
        if self.sim:
            joints = self._sim_ik(arm, ee_pose)
        else:
            joints = self._real_ik(arm, ee_pose)
        if not joints:
            print("IK failed. Try running again or changing the pose.")
        return joints

    def _sim_ik(self, arm, ee_pose):
        """
        (Sim) Calculate inverse kinematics for a given end effector pose

        Args:
            ee_pose (tuple or list): [pos, orn] of desired end effector pose
                pos - x,y,z
                orn - r,p,w
            arm (string): "right" or "left"
        Returns:
            joint_angles (list): List of joint angles
        """
        if arm == 'right':
            ee_index = self.right_arm.ee_index
        elif arm == 'left':
            ee_index = self.left_arm.ee_index
        elif arm == 'both':
            pass
        else:
            raise ValueError("Arg arm must be 'left', 'right', or 'both'.")
        pos = ee_pose[:3]
        orn = ee_pose[3:]
        if (self.use_nullspace == 1):
            if (self.use_orientation == 1):
                joints = p.calculateInverseKinematics(self.baxter_id, ee_index,
                                                      pos, orn, self.ll,
                                                      self.ul, self.jr,
                                                      self.rp)
            else:
                joints = p.calculateInverseKinematics(self.baxter_id,
                                                      ee_index,
                                                      pos,
                                                      lowerLimits=self.ll,
                                                      upperLimits=self.ul,
                                                      jointRanges=self.jr,
                                                      restPoses=self.rp)
        else:
            if (self.use_orientation == 1):
                joints = p.calculateInverseKinematics(self.baxter_id,
                                                      ee_index,
                                                      pos,
                                                      orn,
                                                      jointDamping=self.jd)
            else:
                joints = p.calculateInverseKinematics(self.baxter_id, ee_index,
                                                      pos)
        return joints

    def _real_ik(self, arm, ee_pose):
        """
        (Real) Calculate inverse kinematics for a given end effector pose

        Args:
            ee_pose (tuple or list): [pos, orn] of desired end effector pose
                pos - x,y,z
                orn - r,p,w
        Returns:
            joint_angles (dict): Dictionary containing {'joint_name': joint_angle}
        """
        pos = ee_pose[:3]
        orn = ee_pose[3:]
        orn = self.euler_to_quat(orn)

        ns = "ExternalTools/" + arm + "/PositionKinematicsNode/IKService"
        iksvc = rospy.ServiceProxy(ns, SolvePositionIK)
        ikreq = SolvePositionIKRequest()
        hdr = Header(stamp=rospy.Time.now(), frame_id='base')

        ik_pose = PoseStamped()
        ik_pose.pose.position.x = pos[0]
        ik_pose.pose.position.y = pos[1]
        ik_pose.pose.position.z = pos[2]
        ik_pose.pose.orientation.x = orn[0]
        ik_pose.pose.orientation.y = orn[1]
        ik_pose.pose.orientation.z = orn[2]
        ik_pose.pose.orientation.w = orn[3]
        ik_pose.header = hdr
        ikreq.pose_stamp.append(ik_pose)
        try:
            rospy.wait_for_service(ns, 5.0)
            resp = iksvc(ikreq)
            limb_joints = dict(
                zip(resp.joints[0].name, resp.joints[0].position))
            return limb_joints
        except (rospy.ServiceException, rospy.ROSException), e:
            # rospy.logerr("Service call failed: %s" % (e,))
            return
class vision_server():
    
    def __init__(self):

        rospy.init_node('vision_server_right')
        
        self.pub = rospy.Publisher('/robot/xdisplay', Image, latch=True)
        self.busy = False
        self.dx = 0
        self.dy = 0
        self.avg_dx = -1
        self.avg_dy = -1
        self.H = homography()
        self.framenumber = 0
        self.history_x = np.arange(0,10)*-1
        self.history_y = np.arange(0,10)*-1
        self.bowlcamera = None
        self.newPosition = True
        self.foundBowl = 0
        self.centerx = 400
        
        #self.centerx = 250
        self.centery = 150
        #self.centery = 190
        self.coefx = 0.1/(526-369)
        self.coefy = 0.1/(237-90)
        self.v_joint = np.arange(7)
        self.v_end = np.arange(6)
        self.cmd = {}
        self.found = False
        self.finish = 0
        self.distance = 10
        self.gripper = Gripper("right")
        #self.gripper.calibrate()

        cv2.namedWindow('image')
        self.np_image = np.zeros((400,640,3), np.uint8)
        cv2.imshow('image',self.np_image)
        #self._set_threshold()

        
        s = rospy.Service('vision_server_vertical', Vision, self.handle_vision_req)
        camera_topic = '/cameras/right_hand_camera/image'
        self.right_camera = rospy.Subscriber(camera_topic, Image, self._on_camera)
        ifr = rospy.Subscriber("/robot/range/right_hand_range/state", Range, self._read_distance)
        print "\nReady to use right hand vision server\n" 

        self.kin = baxter_kinematics('right')
        self.J = self.kin.jacobian()
        self.J_inv = self.kin.jacobian_pseudo_inverse()
        self.jointVelocity = np.asarray([1,2,3,4,5,6,7],np.float32)
        self.control_arm = Limb("right")
        self.control_joint_names = self.control_arm.joint_names()
        
        #print np.dot(self.J,self.jointVelocity)

    def _read_distance(self,data):

        self.distance = data.range



    def _set_threshold(self):
        
        cv2.createTrackbar('Min R(H)','image',0,255,nothing)
        cv2.createTrackbar('Max R(H)','image',255,255,nothing)
        cv2.createTrackbar('Min G(S)','image',0,255,nothing)
        cv2.createTrackbar('Max G(S)','image',255,255,nothing)
        cv2.createTrackbar('Min B(V)','image',0,255,nothing)
        cv2.createTrackbar('Max B(V)','image',255,255,nothing)

    def get_joint_velocity(self):
        cmd = {}
        velocity_list = np.asarray([1,2,3,4,5,6,7],np.float32)
        for idx, name in enumerate(self.control_joint_names):
            v = self.control_arm.joint_velocity( self.control_joint_names[idx])
            velocity_list[idx] = v
            cmd[name] = v 
        return velocity_list

    def list_to_dic(self,ls):
        cmd = {}
        for idx, name in enumerate(self.control_joint_names):
            v = ls.item(idx)
            cmd[name] = v 
        return cmd

    def PID(self):

        Kp = 0.5
        vy = -Kp*self.dx
        vx = -Kp*self.dy
        return vx,vy

    def _on_camera(self, data):

        self.busy = True
        self.framenumber += 1
        index = self.framenumber % 10
        cv2.namedWindow('image')
        cv_image = cv_bridge.CvBridge().imgmsg_to_cv(data, "bgr8")
        np_image = np.asarray(cv_image)
        image_after_process, mask = self.image_process(np_image)
        self.history_x[index] = self.dx*100
        self.history_y[index] = self.dy*100
        self.avg_dx = np.average(self.history_x)/100
        self.avg_dy = np.average(self.history_y)/100

        # if abs(self.dx)<0.01 and abs(self.dy)<0.01:
        #     self.found = True
        # else:
        #     self.found = False


        
        vx, vy = self.PID()
        self.v_end = np.asarray([(1-((abs(vx)+abs(vy))*5))*0.03,vy,vx,0,0,0],np.float32)
        #self.v_end = np.asarray([0,0,0,0,0,0.05],np.float32)
        self.v_joint = np.dot(self.J_inv,self.v_end)
        self.cmd = self.list_to_dic(self.v_joint)
              
        

        self.busy = False

        cv2.imshow('image',image_after_process)
        
        cv2.waitKey(1)


    def image_process(self,img):

        # min_r = cv2.getTrackbarPos('Min R(H)','image')
        # max_r = cv2.getTrackbarPos('Max R(H)','image')
        # min_g = cv2.getTrackbarPos('Min G(S)','image')
        # max_g = cv2.getTrackbarPos('Max G(S)','image')
        # min_b = cv2.getTrackbarPos('Min B(V)','image')
        # max_b = cv2.getTrackbarPos('Max B(V)','image')

        # min_r = 0
        # max_r = 57
        # min_g = 87  
        # max_g = 181
        # min_b = 37
        # max_b = 70

        min_r = 0
        max_r = 58
        min_g = 86  
        max_g = 255
        min_b = 0
        max_b = 255


        min_color = (min_r, min_g, min_b)
        max_color = (max_r, max_g, max_b)

        #img = cv2.flip(img, flipCode = -1)
        hsv_img = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
        mask = cv2.inRange(hsv_img, min_color, max_color)
        

        result = cv2.bitwise_and(img, img, mask = mask)
        mask_bool = np.asarray(mask, bool)
        label_img = morphology.remove_small_objects(mask_bool, 1000, connectivity = 1)
        objects = measure.regionprops(label_img)

        if objects != []:
            self.found = True
            target = objects[0]
            box = target.bbox
            cv2.rectangle(img,(box[1],box[0]),(box[3],box[2]),(0,255,0),3)
            
            dx_pixel=target.centroid[1]-self.centerx
            dy_pixel=target.centroid[0]-self.centery
            
            dx=dx_pixel*self.coefx
            dy=dy_pixel*self.coefy

            angle = target.orientation           
            cv2.circle(img,(int(target.centroid[1]),int(target.centroid[0])),10,(0,0,255),-1)
                       
            self.dx = dx
            self.dy = dy
            #print self.dx,self.dy

        else:
            self.found = False
            self.dx = 0
            self.dy = 0


        return img, mask_bool

    def handle_vision_req(self, req):
        #resp = VisionResponse(req.requestID, 0, self.avg_dx, self.avg_dy)
        self.finish = 0
        if self.found == True:
            if self.distance > 0.07:
                self.control_arm.set_joint_velocities(self.cmd) 
                #rospy.sleep(0.02)
            else:
                self.finish = 1


        resp = VisionResponse(req.requestID, self.finish, self.dx, self.dy)

        
        return resp

    def clean_shutdown(self):
        print "Server finished"
        cv2.imwrite('box_img.png', self.blank_image)
        rospy.signal_shutdown("Done")
        sys.exit()
Example #3
0
def main():
    rospy.init_node('baxter_kinematics')
    kin = baxter_kinematics('left')
    pos = [0.582583, -0.180819, 0.216003]
    rot = [0.03085, 0.9945, 0.0561, 0.0829]

    fl = fcntl.fcntl(sys.stdin.fileno(), fcntl.F_GETFL)
    fcntl.fcntl(sys.stdin.fileno(), fcntl.F_SETFL, fl | os.O_NONBLOCK)

    # Read initial positions:
    from sensor_msgs.msg import JointState
    from baxter_interface import Limb

    right_arm = Limb('right')
    left_arm = Limb('left')

    joints = left_arm.joint_names()
    positions = left_arm.joint_angles()
    velocities = left_arm.joint_velocities()
    force = convert_dict_to_list('left', left_arm.joint_efforts())

    # Initial states
    q_previous = positions  # Starting joint angles
    q_dot_previous = velocities  # Starting joint velocities
    x_previous = kin.forward_position_kinematics(
    )  # Starting end effector position
    x_dot_previous = np.zeros((6, 1))

    # Set model parameters:
    m = 1
    K = 0.2
    C = 15
    B = 12

    while True:
        '''                
        Following code breaks loop upon user input (enter key)
        '''
        try:
            stdin = sys.stdin.read()
            if "\n" in stdin or "\r" in stdin:
                return_to_init(joints, 'left')
                break
        except IOError:
            pass

        # Gather Jacobian information:
        J = kin.jacobian()
        J_T = kin.jacobian_transpose()
        J_PI = kin.jacobian_pseudo_inverse()
        J_T_PI = np.linalg.pinv(J_T)

        # Extract sensor data:
        from sensor_msgs.msg import JointState
        from baxter_interface import Limb

        right_arm = Limb('right')
        left_arm = Limb('left')

        # Information is published at 100Hz by default (every 10ms=.01sec)
        time_step = 0.01

        joints = left_arm.joint_names()
        positions = convert_dict_to_list('left', left_arm.joint_angles())
        velocities = convert_dict_to_list('left', left_arm.joint_velocities())
        force = convert_dict_to_list('left', left_arm.joint_efforts())

        force_mag = np.linalg.norm(force)
        print(force_mag)

        if (force_mag < 28):  # Add deadzone
            continue
        else:
            from sensor_msgs.msg import JointState
            from baxter_interface import Limb

            right_arm = Limb('right')
            left_arm = Limb('left')

            joints = left_arm.joint_names()
            positions = convert_dict_to_list('left', left_arm.joint_angles())
            velocities = convert_dict_to_list('left',
                                              left_arm.joint_velocities())
            force = convert_dict_to_list('left', left_arm.joint_efforts())

            positions = np.reshape(positions, [7, 1])  # Converts to matrix
            velocities = np.reshape(velocities, [7, 1])  # Converts to matrix
            force = np.reshape(force, [7, 1])  # Converts to matrix

            x = kin.forward_position_kinematics()
            x = x[:-1]
            x_ref = np.reshape(x, [6, 1])  # Reference position

            x_ref_dot = J * velocities  # Reference velocities

            t_stop = 10
            t_end = time.time() + t_stop  # Loop timer (in seconds)

            # Initial plot parameters
            time_plot_cum = 0
            time_vec = [time_plot_cum]
            pos_vec = [x_ref[1][0]]

            # For integral control
            x_ctrl_cum = 0
            time_cum = 0.00001  # Prevent divide by zero
            x_ctrl_prev = 0  # Initial for derivative ctrl

            while time.time() < t_end:
                from sensor_msgs.msg import JointState
                from baxter_interface import Limb

                right_arm = Limb('right')
                left_arm = Limb('left')

                J = kin.jacobian()
                J_T = kin.jacobian_transpose()
                J_PI = kin.jacobian_pseudo_inverse()
                J_T_PI = np.linalg.pinv(J_T)

                joints = left_arm.joint_names()
                positions = convert_dict_to_list('left',
                                                 left_arm.joint_angles())
                velocities = convert_dict_to_list('left',
                                                  left_arm.joint_velocities())
                force = convert_dict_to_list('left', left_arm.joint_efforts())

                positions = np.reshape(positions, [7, 1])  # Converts to matrix
                velocities = np.reshape(velocities,
                                        [7, 1])  # Converts to matrix
                force = np.reshape(force, [7, 1])  # Converts to matrix

                x = kin.forward_position_kinematics()
                x = x[:-1]
                x_current = np.reshape(x, [6, 1])

                x_dot_current = J * velocities

                # Only interested in y-axis:
                x_dot_current[0] = 0
                #x_dot_current[1]=0
                x_dot_current[2] = 0
                x_dot_current[3] = 0
                x_dot_current[4] = 0
                x_dot_current[5] = 0

                x_ddot = derivative(x_dot_previous, x_dot_current, time_step)

                # Model goes here
                f = J_T_PI * force  # spacial force

                # Only interested in y-axis:
                f[0] = [0]
                #f[1]=[0]
                f[2] = [0]
                f[3] = [0]
                f[4] = [0]
                f[5] = [0]

                x_des = ((B * f - m * x_ddot - C *
                          (x_dot_current - x_ref_dot)) /
                         K) + x_ref  # Spring with damper

                # Control robot
                Kp = 0.0004
                Ki = 0.00000022
                Kd = 0.0000005

                x_ctrl = x_current - x_des

                # Only interested in y-axis:
                x_ctrl[0] = 0
                #x_ctrl[1]=0
                x_ctrl[2] = 0
                x_ctrl[3] = 0
                x_ctrl[4] = 0
                x_ctrl[5] = 0

                q_dot_ctrl = J_T * np.linalg.inv(J * J_T + np.identity(6)) * (
                    -Kp * x_ctrl - Ki * (x_ctrl_cum) - Kd *
                    (x_ctrl_prev - x_ctrl) / time_step)

                q_dot_ctrl_list = convert_mat_to_list(q_dot_ctrl)
                q_dot_ctrl_dict = convert_list_to_dict(joints, q_dot_ctrl_list)

                left_arm.set_joint_velocities(
                    q_dot_ctrl_dict)  # Velocity control function

                # Update plot info
                time_cum += .05
                time_vec.append(time_cum)

                pos_vec.append(x_current[1][0])

                # Update integral control parameters
                x_ctrl_cum += x_ctrl * time_step

                # Update derivative control parameters
                x_ctrl_prev = x_ctrl

                # Update values before next loop
                x_previous = x_current  # Updates previous position for next loop iteration
                x_dot_previous = x_dot_current  # Updates previous velocity for next loop iteration

            print(time_vec)
            print(pos_vec)
            plt.plot(time_vec, pos_vec)
            plt.title('Position over time')
            plt.xlabel('Time (sec)')
            plt.ylabel('Position')
            plt.show()

            stop_joints(q_dot_ctrl_dict)
            left_arm.set_joint_velocities(q_dot_ctrl_dict)
            time.sleep(1)
            break
Example #4
0
class vision_server():
    def __init__(self):

        rospy.init_node('vision_server_right')

        self.pub = rospy.Publisher('/robot/xdisplay', Image, latch=True)
        self.busy = False
        self.dx = 0
        self.dy = 0
        self.avg_dx = -1
        self.avg_dy = -1
        self.H = homography()
        self.framenumber = 0
        self.history_x = np.arange(0, 10) * -1
        self.history_y = np.arange(0, 10) * -1
        self.bowlcamera = None
        self.newPosition = True
        self.foundBowl = 0
        self.centerx = 400

        #self.centerx = 250
        self.centery = 150
        #self.centery = 190
        self.coefx = 0.1 / (526 - 369)
        self.coefy = 0.1 / (237 - 90)
        self.v_joint = np.arange(7)
        self.v_end = np.arange(6)
        self.cmd = {}
        self.found = False
        self.finish = 0
        self.distance = 10
        self.gripper = Gripper("right")
        #self.gripper.calibrate()

        cv2.namedWindow('image')
        self.np_image = np.zeros((400, 640, 3), np.uint8)
        cv2.imshow('image', self.np_image)
        #self._set_threshold()

        s = rospy.Service('vision_server_vertical', Vision,
                          self.handle_vision_req)
        camera_topic = '/cameras/right_hand_camera/image'
        self.right_camera = rospy.Subscriber(camera_topic, Image,
                                             self._on_camera)
        ifr = rospy.Subscriber("/robot/range/right_hand_range/state", Range,
                               self._read_distance)
        print "\nReady to use right hand vision server\n"

        self.kin = baxter_kinematics('right')
        self.J = self.kin.jacobian()
        self.J_inv = self.kin.jacobian_pseudo_inverse()
        self.jointVelocity = np.asarray([1, 2, 3, 4, 5, 6, 7], np.float32)
        self.control_arm = Limb("right")
        self.control_joint_names = self.control_arm.joint_names()

        #print np.dot(self.J,self.jointVelocity)

    def _read_distance(self, data):

        self.distance = data.range

    def _set_threshold(self):

        cv2.createTrackbar('Min R(H)', 'image', 0, 255, nothing)
        cv2.createTrackbar('Max R(H)', 'image', 255, 255, nothing)
        cv2.createTrackbar('Min G(S)', 'image', 0, 255, nothing)
        cv2.createTrackbar('Max G(S)', 'image', 255, 255, nothing)
        cv2.createTrackbar('Min B(V)', 'image', 0, 255, nothing)
        cv2.createTrackbar('Max B(V)', 'image', 255, 255, nothing)

    def get_joint_velocity(self):
        cmd = {}
        velocity_list = np.asarray([1, 2, 3, 4, 5, 6, 7], np.float32)
        for idx, name in enumerate(self.control_joint_names):
            v = self.control_arm.joint_velocity(self.control_joint_names[idx])
            velocity_list[idx] = v
            cmd[name] = v
        return velocity_list

    def list_to_dic(self, ls):
        cmd = {}
        for idx, name in enumerate(self.control_joint_names):
            v = ls.item(idx)
            cmd[name] = v
        return cmd

    def PID(self):

        Kp = 0.5
        vy = -Kp * self.dx
        vx = -Kp * self.dy
        return vx, vy

    def _on_camera(self, data):

        self.busy = True
        self.framenumber += 1
        index = self.framenumber % 10
        cv2.namedWindow('image')
        cv_image = cv_bridge.CvBridge().imgmsg_to_cv(data, "bgr8")
        np_image = np.asarray(cv_image)
        image_after_process, mask = self.image_process(np_image)
        self.history_x[index] = self.dx * 100
        self.history_y[index] = self.dy * 100
        self.avg_dx = np.average(self.history_x) / 100
        self.avg_dy = np.average(self.history_y) / 100

        # if abs(self.dx)<0.01 and abs(self.dy)<0.01:
        #     self.found = True
        # else:
        #     self.found = False

        vx, vy = self.PID()
        self.v_end = np.asarray(
            [(1 - ((abs(vx) + abs(vy)) * 5)) * 0.03, vy, vx, 0, 0, 0],
            np.float32)
        #self.v_end = np.asarray([0,0,0,0,0,0.05],np.float32)
        self.v_joint = np.dot(self.J_inv, self.v_end)
        self.cmd = self.list_to_dic(self.v_joint)

        self.busy = False

        cv2.imshow('image', image_after_process)

        cv2.waitKey(1)

    def image_process(self, img):

        # min_r = cv2.getTrackbarPos('Min R(H)','image')
        # max_r = cv2.getTrackbarPos('Max R(H)','image')
        # min_g = cv2.getTrackbarPos('Min G(S)','image')
        # max_g = cv2.getTrackbarPos('Max G(S)','image')
        # min_b = cv2.getTrackbarPos('Min B(V)','image')
        # max_b = cv2.getTrackbarPos('Max B(V)','image')

        # min_r = 0
        # max_r = 57
        # min_g = 87
        # max_g = 181
        # min_b = 37
        # max_b = 70

        min_r = 0
        max_r = 58
        min_g = 86
        max_g = 255
        min_b = 0
        max_b = 255

        min_color = (min_r, min_g, min_b)
        max_color = (max_r, max_g, max_b)

        #img = cv2.flip(img, flipCode = -1)
        hsv_img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
        mask = cv2.inRange(hsv_img, min_color, max_color)

        result = cv2.bitwise_and(img, img, mask=mask)
        mask_bool = np.asarray(mask, bool)
        label_img = morphology.remove_small_objects(mask_bool,
                                                    1000,
                                                    connectivity=1)
        objects = measure.regionprops(label_img)

        if objects != []:
            self.found = True
            target = objects[0]
            box = target.bbox
            cv2.rectangle(img, (box[1], box[0]), (box[3], box[2]), (0, 255, 0),
                          3)

            dx_pixel = target.centroid[1] - self.centerx
            dy_pixel = target.centroid[0] - self.centery

            dx = dx_pixel * self.coefx
            dy = dy_pixel * self.coefy

            angle = target.orientation
            cv2.circle(img, (int(target.centroid[1]), int(target.centroid[0])),
                       10, (0, 0, 255), -1)

            self.dx = dx
            self.dy = dy
            #print self.dx,self.dy

        else:
            self.found = False
            self.dx = 0
            self.dy = 0

        return img, mask_bool

    def handle_vision_req(self, req):
        #resp = VisionResponse(req.requestID, 0, self.avg_dx, self.avg_dy)
        self.finish = 0
        if self.found == True:
            if self.distance > 0.07:
                self.control_arm.set_joint_velocities(self.cmd)
                #rospy.sleep(0.02)
            else:
                self.finish = 1

        resp = VisionResponse(req.requestID, self.finish, self.dx, self.dy)

        return resp

    def clean_shutdown(self):
        print "Server finished"
        cv2.imwrite('box_img.png', self.blank_image)
        rospy.signal_shutdown("Done")
        sys.exit()
def main():
    rospy.init_node('baxter_kinematics')    
    kin = baxter_kinematics('left')        
    pos = [0.582583, -0.180819, 0.216003]
    rot = [0.03085, 0.9945, 0.0561, 0.0829]
    
    fl = fcntl.fcntl(sys.stdin.fileno(), fcntl.F_GETFL)
    fcntl.fcntl(sys.stdin.fileno(), fcntl.F_SETFL, fl | os.O_NONBLOCK)
    
    # Read initial positions:
    from sensor_msgs.msg import JointState
    from baxter_interface import Limb

    right_arm=Limb('right')
    left_arm=Limb('left')

    joints=left_arm.joint_names()
    positions=convert_dict_to_list('left',left_arm.joint_angles())
    velocities=convert_dict_to_list('left',left_arm.joint_velocities())
    force=convert_dict_to_list('left',left_arm.joint_efforts())                

    positions=np.reshape(positions,[7,1])               # Converts to matrix       
    velocities=np.reshape(velocities,[7,1])             # Converts to matrix
    force=np.reshape(force,[7,1])                       # Converts to matrix  
    
    # Initial states
    q_previous=positions                            # Starting joint angles
    q_dot_previous=velocities                       # Starting joint velocities
    x_previous=kin.forward_position_kinematics()    # Starting end effector position
    x_dot_previous=np.zeros((6,1))
    
    # Set model parameters:
    C=50
    B=1
    f_des=np.reshape(np.array([0,15,0,0,0,0]),[6,1])   
    
    J=kin.jacobian()
    J_T=kin.jacobian_transpose()
    J_PI=kin.jacobian_pseudo_inverse()
    J_T_PI=np.linalg.pinv(J_T)
    
    x=kin.forward_position_kinematics()
    x=x[:-1]
    x_ref=np.reshape(x,[6,1])               # Reference position
    
    x_ref_dot=J*velocities                  # Reference velocities
    
    t_stop=15
    t_end=time.time()+t_stop                    # Loop timer (in seconds)
    
    # Initial plot parameters
    time_cum=0
    time_vec=[time_cum]
    
    f=J_T_PI*force
    force_vec=[convert_mat_to_list(f[1])[0]]
    
    while time.time()<t_end:
        from sensor_msgs.msg import JointState
        from baxter_interface import Limb
    
        right_arm=Limb('right')
        left_arm=Limb('left')       
        
        J=kin.jacobian()
        J_T=kin.jacobian_transpose()
        J_PI=kin.jacobian_pseudo_inverse()
        J_T_PI=np.linalg.pinv(J_T)    
        
        joints=left_arm.joint_names()
        positions=convert_dict_to_list('left',left_arm.joint_angles())
        velocities=convert_dict_to_list('left',left_arm.joint_velocities())
        force=convert_dict_to_list('left',left_arm.joint_efforts())                
        
        positions=np.reshape(positions,[7,1])               # Converts to matrix       
        velocities=np.reshape(velocities,[7,1])             # Converts to matrix
        force=np.reshape(force,[7,1])                       # Converts to matrix      
        
        x=kin.forward_position_kinematics()
        x=x[:-1]
        x_current=np.reshape(x,[6,1])
        
        x_dot_current=J*velocities
        
        # Only interested in y-axis:
        x_dot_current[0]=0
        #x_dot_current[1]=0
        x_dot_current[2]=0
        x_dot_current[3]=0
        x_dot_current[4]=0
        x_dot_current[5]=0                
        
        # Model goes here
        f=J_T_PI*force                # spacial force

        # Only interested in y-axis:
        f[0]=[0]
        #f[1]=[0]                  
        f[2]=[0]
        f[3]=[0]                       
        f[4]=[0]
        f[5]=[0]
        

        x_dot_des=-B*(f_des+f)/C                         # Impedance control
        
        # Control robot                
        q_dot_ctrl=J_PI*x_dot_des                           # Use this for damper system
        q_dot_ctrl=np.multiply(q_dot_ctrl,np.reshape(np.array([1,0,0,0,0,0,0]),[7,1]))  # y-axis translation corresponds to first shoulder joint rotation
        
        q_dot_ctrl_list=convert_mat_to_list(q_dot_ctrl)
        q_dot_ctrl_dict=convert_list_to_dict(joints,q_dot_ctrl_list)
        
        left_arm.set_joint_velocities(q_dot_ctrl_dict)      # Velocity control function
        
        # Update values before next loop
        x_previous=x_current                        # Updates previous position for next loop iteration
        x_dot_previous=x_dot_current                # Updates previous velocity for next loop iteration
        
        # Update plot info
        time_cum+=.05                               
        time_vec.append(time_cum)
        
        force_vec.append(convert_mat_to_list(f[1])[0])
        
    
    print(time_vec)
    print(force_vec)
    plt.plot(time_vec,force_vec)
    plt.title('Force applied over time')
    plt.xlabel('Time (sec)')
    plt.ylabel('Force (N)')
    plt.show()
    
    time.sleep(1)