コード例 #1
1
def subscriber_callback(data):
	occupancyMap = transformation(data.data, data.info.width, data.info.height)
	way_points = find_goals(occupancyMap, data.info.width, data.info.height)
	result = random.choice(way_points)

	try:
		planMaker = rospy.ServiceProxy('move_base/make_plan', nav_srv.GetPlan)
		listener = TransformListener()
		listener.waitForTransform("base_link", "map", rospy.Time(), rospy.Duration(4.0))
		t = listener.getLatestCommonTime("base_link", "map")
		position, quaternion = listener.lookupTransform("base_link", "map", t)
		pos_x = position[0]
		pos_y = position[1]
		pos_z = position[2]
		goal_robot = create_goal((result[1]-2000)*data.info.resolution,(result[0]-2000)*data.info.resolution)
		#Make plan with 0.5 meter flexibility, from target pose and current pose (with same header)
		start_pose = create_message(pos_x,pos_y,pos_z,quaternion)

		plan = planMaker(
			start_pose,
			goal_robot.target_pose,
			0.5)
		action_server = actionlib.SimpleActionClient('move_base', mb_msg.MoveBaseAction);
		action_server.wait_for_server()
		send_goal(goal_robot, action_server)

	except rospy.ServiceException, e:
		print "plan service call failed: %s"%e
コード例 #2
0
class FaceCommander(Head):
    def __init__(self):
        Head.__init__(self)
        self._world = 'base'
        self._tf_listener = TransformListener()
        self.set_pan(0)

    def look_at(self, obj=None):
        if obj is None:
            self.set_pan(0)
            return True

        if isinstance(obj, str):
            pose = self._tf_listener.lookupTransform('head', obj, rospy.Time(0))
        else:
            rospy.logerr("FaceCommander.look_at() accepts only strings atm")
            return False

        hyp = transformations.norm(pose)
        adj = pose[0][1]
        angle = pi/2 - arccos(float(adj)/hyp)

        if isnan(angle):
            rospy.logerr('FaceCommander cannot look at {}'.format(obj))
            return False

        self.set_pan(angle)
        return True
コード例 #3
0
class ChallengeProblemLogger(object):
  _knownObstacles = {}
  _placedObstacle = False
  _lastgzlog = 0.0
  _tf_listener = None
  
  def __init__(self,name):
    self._name = name;

    self._experiment_started = False
    self._tf_listener = TransformListener()

    # Subscribe to robot pose ground truth from gazebo
    rospy.Subscriber("/gazebo/model_states", ModelStates, callback=self.gazebo_model_monitor,
                     queue_size=1)

  # Whenever we get a report from Gazebo, map the gazebo coordinate to map coordinates and
  # log this
  # Only do this every second - this should be accurate enough
  # TODO: model is assumed to be the third in the list. Need to make this based
  #       on the array to account for obstacles (maybe)
  def gazebo_model_monitor(self, data):
    if (len(data.pose))<=2:
      return
    data_time = rospy.get_rostime().to_sec()
    if ((self._lastgzlog == 0.0) | (data_time - self._lastgzlog >= 1)):
      # Only do this every second

      # Get the turtlebot model state information (assumed to be indexed at 2)    
      tb_pose = data.pose[2]
      tb_position = tb_pose.position
      self._lastgzlog = data_time

      # Do this only if the transform exists
      if self._tf_listener.frameExists("/base_link") and self._tf_listener.frameExists("/map"):
        self._tf_listener.waitForTransform("/map", "/base_link", rospy.Time(0), rospy.Duration(1))
        (trans,rot) = self._tf_listener.lookupTransform("/map", "/base_link",rospy.Time(0))
        rospy.loginfo("BRASS | Turtlebot | {},{}".format(trans[0], trans[1]))
      
      # Log any obstacle information, but do it only once. This currently assumes one obstacle
      # TODO: test this
      if len(data.name) > 3:
        addedObstacles = {}
        removedObstacles = self._knownObstacles.copy()
        for obs in range(3, len(data.name)-1):
          if (data.name[obs] not in self._knownObstacles):
            addedObstacles[data.name[obs]] = obs
          else:
             self._knownObstacles[data.name[obs]] = obs
 	     del removedObstacles[data.name[obs]]
        
        for key, value in removedObstacles.iteritems():
           rospy.logInfo("BRASS | Obstacle {} | removed".format(key))
           del self._knownObstacles[key]

        for key, value in addedObstacles.iteritems():
	   obs_pos = data.pose[value].position
           rospy.logInfo ("BRASS | Obstacle {} | {},{}".format(key, obs_pos.x, obs_pos.y))
	   self._knownObstacles[key] = value
コード例 #4
0
ファイル: rows_simulator.py プロジェクト: madsbahrt/FroboMind
def calculate_distance_to_rows():
    tflisten = TransformListener()
    dist = []
    for i in range(0,n_rows):
        (veh_trans,veh_rot) = tflisten.lookupTransform("odom","base_footprint",rospy.Time(0))
        
        
    pass
コード例 #5
0
class TfFilter:
    def __init__(self, buffer_size):
        self.tf = TransformListener(True, rospy.Duration(5))
        self.target = ''
        self.buffer = np.zeros((buffer_size, 1))
        self.buffer_ptr = 0
        self.buffer_size = buffer_size
        self.tf_sub = rospy.Subscriber('tf', tfMessage, self.tf_cb)
        self.tf_pub = rospy.Publisher('tf', tfMessage)
        self.srv = rospy.Service(SERVICE, PublishGoal, self.publish_goal_cb)

    def tf_cb(self, msg):
        for t in msg.transforms:
            if t.child_frame_id == self.target:
                time = self.tf.getLatestCommonTime(self.source, self.target)
                p, q = self.tf.lookupTransform(self.source, self.target, time)
                rm = tfs.quaternion_matrix(q)
                # assemble a new coordinate frame that has z-axis aligned with
                # the vertical direction and x-axis facing the z-axis of the
                # original frame
                z = rm[:3, 2]
                z[2] = 0
                axis_x = tfs.unit_vector(z)
                axis_z = tfs.unit_vector([0, 0, 1])
                axis_y = np.cross(axis_x, axis_z)
                rm = np.vstack((axis_x, axis_y, axis_z)).transpose()
                # shift the pose along the x-axis
                self.position = p + np.dot(rm, self.d)[:3]
                self.buffer[self.buffer_ptr] = tfs.euler_from_matrix(rm)[2]
                self.buffer_ptr = (self.buffer_ptr + 1) % self.buffer_size
                self.publish_filtered_tf(t.header)

    def publish_filtered_tf(self, header):
        yaw = np.median(self.buffer)
        q = tfs.quaternion_from_euler(0, 0, yaw - math.pi)
        ts = TransformStamped()
        ts.header = header
        ts.header.frame_id = self.source
        ts.child_frame_id = self.goal
        ts.transform.translation.x = self.position[0]
        ts.transform.translation.y = self.position[1]
        ts.transform.translation.z = 0
        ts.transform.rotation.x = q[0]
        ts.transform.rotation.y = q[1]
        ts.transform.rotation.z = q[2]
        ts.transform.rotation.w = q[3]
        msg = tfMessage()
        msg.transforms.append(ts)
        self.tf_pub.publish(msg)

    def publish_goal_cb(self, r):
        rospy.loginfo('Received [%s] request. Will start publishing %s frame' %
                      (SERVICE, r.goal_frame_id))
        self.source = r.source_frame_id
        self.target = r.target_frame_id
        self.goal = r.goal_frame_id
        self.d = [r.displacement.x, r.displacement.y, r.displacement.z]
        return []
コード例 #6
0
class KinectNiteHelp:
    def __init__(self, name="kinect_listener", user=1):
        # rospy.init_node(name, anonymous=True)
        self.tf = TransformListener()
        self.user = user

    def getLeftHandPos(self):
        if self.tf.frameExists(BASE_FRAME) and self.tf.frameExists("left_hand_1"):
            print " Inside TF IF Get LEft HAnd POS "
            t = self.tf.getLatestCommonTime(BASE_FRAME, "left_hand_1")
            (leftHandPos, quaternion) = self.tf.lookupTransform(BASE_FRAME, "left_hand_1", t)
            return leftHandPos

    def getRightHandPos(self):
        if self.tf.frameExists(BASE_FRAME) and self.tf.frameExists("right_hand_1"):
            t = self.tf.getLatestCommonTime(BASE_FRAME, "right_hand_1")
            (rightHandPos, quaternion) = self.tf.lookupTransform(BASE_FRAME, "right_hand_1", t)
            return rightHandPos
コード例 #7
0
ファイル: transform.py プロジェクト: czhao39/racecar_4
class TransformNode:
    def __init__(self, *args):
        self.tf = TransformListener()
        rospy.Subscriber("/tf", TFMessage, transform, queue_size=1)

    def transform(self, msg):
        if self.tf.frameExists("/base_link") and self.tf.frameExists("/map"):
            t = self.tf.getLatestCommonTime("/base_link", "/map")
            position, quaternion = self.tf.lookupTransform("/base_link", "/map", t)
            print position, quaternion
コード例 #8
0
class TwistToPoseConverter(object):
    def __init__(self):
        self.ee_frame = rospy.get_param('~ee_frame', "/l_gripper_tool_frame")
        self.twist_sub = rospy.Subscriber('/twist_in', TwistStamped, self.twist_cb)
        self.pose_pub = rospy.Publisher('/pose_out', PoseStamped)
        self.tf_listener = TransformListener()

    def get_ee_pose(self, frame='/torso_lift_link', time=None):
        """Get current end effector pose from tf."""
        try:
            now = rospy.Time.now() if time is None else time
            self.tf_listener.waitForTransform(frame, self.ee_frame, now, rospy.Duration(4.0))
            pos, quat = self.tf_listener.lookupTransform(frame, self.ee_frame, now)
        except (LookupException, ConnectivityException, ExtrapolationException, Exception) as e:
            rospy.logwarn("[%s] TF Failure getting current end-effector pose:\r\n %s"
                            %(rospy.get_name(), e))
            return None, None
        return pos, quat

    def twist_cb(self, ts):
        """Get current end effector pose and augment with twist command."""
        cur_pos, cur_quat = self.get_ee_pose(ts.header.frame_id)
        ps = PoseStamped()
        ps.header.frame_id = ts.header.frame_id
        ps.header.stamp = ts.header.stamp
        ps.pose.position.x = cur_pos[0] + ts.twist.linear.x
        ps.pose.position.y = cur_pos[1] + ts.twist.linear.y
        ps.pose.position.z = cur_pos[2] + ts.twist.linear.z
        twist_quat = trans.quaternion_from_euler(ts.twist.angular.x,
                                                 ts.twist.angular.y,
                                                 ts.twist.angular.z)
        final_quat = trans.quaternion_multiply(twist_quat, cur_quat)
        ps.pose.orientation = Quaternion(*final_quat)
        try:
            self.tf_listener.waitForTransform('/torso_lift_link', ps.header.frame_id,
                                              ps.header.stamp, rospy.Duration(3.0))
            pose_out = self.tf_listener.transformPose('/torso_lift_link', ps)
            self.pose_pub.publish(pose_out)
        except (LookupException, ConnectivityException, ExtrapolationException, Exception) as e:
            rospy.logwarn("[%s] TF Failure transforming goal pose to torso_lift_link:\r\n %s"
                           %(rospy.get_name(), e))
コード例 #9
0
class Transformation():
	def __init__(self):
		pub = 0
		self.tf = TransformListener()
		self.tf1 = TransformerROS()
		self.fdata = geometry_msgs.msg.TransformStamped()
		self.fdata_base = geometry_msgs.msg.TransformStamped()
		self.transform = tf.TransformBroadcaster()
		self.wrench = WrenchStamped()
		self.wrench_bl = WrenchStamped()
		
	def wrench_cb(self,msg):
		self.wrench = msg.wrench
		self.transform.sendTransform((0,0,-0.025),quaternion_from_euler(3.14, 0, 3.665195102, 'rxyz'),rospy.Time.now(),'/ft_debug_link','/arm_7_link')
		self.fdata.transform.translation.x = self.wrench.force.x
		self.fdata.transform.translation.y = self.wrench.force.y
		self.fdata.transform.translation.z = self.wrench.force.z
		
		try:
			if self.tf.frameExists("/dummy_link") and self.tf.frameExists("ft_debug_link"):
				t = self.tf.getLatestCommonTime("/dummy_link", "/ft_debug_link")
				(transform_ee_base_position,transform_ee_base_quaternion) = self.tf.lookupTransform("/dummy_link", '/ft_debug_link', t)
	   				#print transform_ee_base_position
	   				#print transform_ee_base_quaternion
	   				#print self.tf1.fromTranslationRotation(transform_ee_base_position,transform_ee_base_quaternion)
		except(tf.LookupException,tf.ConnectivityException):
			print("TRANSFORMATION ERROR")
			sss.say(["error"])	
			#return 'failed'
		
		self.fdata_base.transform.translation.x =((self.tf1.fromTranslationRotation(transform_ee_base_position,transform_ee_base_quaternion)[0,0] * self.fdata.transform.translation.x)+ (self.tf1.fromTranslationRotation(transform_ee_base_position,transform_ee_base_quaternion)[0,1] * self.fdata.transform.translation.y)+ (self.tf1.fromTranslationRotation(transform_ee_base_position,transform_ee_base_quaternion)[0,2] * self.fdata.transform.translation.z)+ (self.tf1.fromTranslationRotation(transform_ee_base_position,transform_ee_base_quaternion)[0,3]))
		
		self.fdata_base.transform.translation.y =((self.tf1.fromTranslationRotation(transform_ee_base_position,transform_ee_base_quaternion)[1,0] * self.fdata.transform.translation.x)+ (self.tf1.fromTranslationRotation(transform_ee_base_position,transform_ee_base_quaternion)[1,1] * self.fdata.transform.translation.y)+ (self.tf1.fromTranslationRotation(transform_ee_base_position,transform_ee_base_quaternion)[1,2] * self.fdata.transform.translation.z)+ (self.tf1.fromTranslationRotation(transform_ee_base_position,transform_ee_base_quaternion)[1,3]))

		self.fdata_base.transform.translation.z =((self.tf1.fromTranslationRotation(transform_ee_base_position,transform_ee_base_quaternion)[2,0] * self.fdata.transform.translation.x)+ (self.tf1.fromTranslationRotation(transform_ee_base_position,transform_ee_base_quaternion)[2,1] * self.fdata.transform.translation.y)+ (self.tf1.fromTranslationRotation(transform_ee_base_position,transform_ee_base_quaternion)[2,2] * self.fdata.transform.translation.z)+ (self.tf1.fromTranslationRotation(transform_ee_base_position,transform_ee_base_quaternion)[2,3]))	
		
		self.wrench_bl.wrench.force.y = self.fdata_base.transform.translation.y
		self.wrench_bl.wrench.force.x = self.fdata_base.transform.translation.x
		self.wrench_bl.wrench.force.z = self.fdata_base.transform.translation.z
		self.wrench_bl.header.stamp = rospy.Time.now();
		self.pub.publish(self.wrench_bl)
コード例 #10
0
ファイル: demo.py プロジェクト: trevorlazarus/crazyflie_ros
class Demo:
    def __init__(self, goals):
        rospy.init_node("demo", anonymous=True)
        self.frame = rospy.get_param("~frame")
        self.pubGoal = rospy.Publisher("goal", PoseStamped, queue_size=1)
        self.listener = TransformListener()
        self.goals = goals
        self.goalIndex = 0

    def run(self):
        self.listener.waitForTransform("/world", self.frame, rospy.Time(), rospy.Duration(5.0))
        goal = PoseStamped()
        goal.header.seq = 0
        goal.header.frame_id = "world"
        while not rospy.is_shutdown():
            goal.header.seq += 1
            goal.header.stamp = rospy.Time.now()
            goal.pose.position.x = self.goals[self.goalIndex][0]
            goal.pose.position.y = self.goals[self.goalIndex][1]
            goal.pose.position.z = self.goals[self.goalIndex][2]
            quaternion = tf.transformations.quaternion_from_euler(0, 0, self.goals[self.goalIndex][3])
            goal.pose.orientation.x = quaternion[0]
            goal.pose.orientation.y = quaternion[1]
            goal.pose.orientation.z = quaternion[2]
            goal.pose.orientation.w = quaternion[3]

            self.pubGoal.publish(goal)

            t = self.listener.getLatestCommonTime("/world", self.frame)
            if self.listener.canTransform("/world", self.frame, t):
                position, quaternion = self.listener.lookupTransform("/world", self.frame, t)
                rpy = tf.transformations.euler_from_quaternion(quaternion)
                if (
                    math.fabs(position[0] - self.goals[self.goalIndex][0]) < 0.3
                    and math.fabs(position[1] - self.goals[self.goalIndex][1]) < 0.3
                    and math.fabs(position[2] - self.goals[self.goalIndex][2]) < 0.3
                    and math.fabs(rpy[2] - self.goals[self.goalIndex][3]) < math.radians(10)
                    and self.goalIndex < len(self.goals) - 1
                ):
                    rospy.sleep(self.goals[self.goalIndex][4])
                    self.goalIndex += 1
コード例 #11
0
class getStepTowardsPoint(smach.State):
    """
    Calculates the next step towards a point defined in userdata.
    """
    def __init__(self):
        smach.State.__init__(self, outcomes=['succeeded'], input_keys=['next_x','next_y'],output_keys=['step_next_x','step_next_y'])
        self.__listen = TransformListener()
        self.__cur_pos = None
        self.__step_next_pos = None
        self.__odom_frame = rospy.get_param("~odom_frame","/odom")
        self.__base_frame = rospy.get_param("~base_frame","/base_footprint")
        self.step = 1
    
    def __get_current_position(self):
        ret = False
        try:
            (self.__cur_pos,rot) = self.__listen.lookupTransform( self.__odom_frame,self.__base_frame,rospy.Time(0))
            ret = True
        except (tf.LookupException, tf.ConnectivityException),err:
            rospy.loginfo("could not locate vehicle")
        return ret
コード例 #12
0
class mbzirc_c2_auto():
    # A few key tasks are achieved in the initializer function:
    #     1. We load the pre-defined search routine
    #     2. We connect to the move_base server in ROS
    #     3. We start the ROS subscriber callback function registering the object
    #     4. We initialize counters in the class to be shared by the various callback routines
    def __init__(self):
        # Name this node, it must be unique
        rospy.init_node('autonomous', anonymous=True)

        # Enable shutdown in rospy (This is important so we cancel any move_base goals
        # when the node is killed)
        rospy.on_shutdown(self.shutdown)
        self.rest_time = rospy.get_param("~rest_time",
                                         0.1)  # Minimum pause at each location
        self.stalled_threshold = rospy.get_param("~stalled_threshold",
                                                 100)  # Loops before stall

        # Goal state return values
        goal_states = [
            'PENDING', 'ACTIVE', 'PREEMPTED', 'SUCCEEDED', 'ABORTED',
            'REJECTED', 'PREEMPTING', 'RECALLING', 'RECALLED', 'LOST'
        ]

        # Set up the goal locations. Poses are defined in the map frame.
        # An easy way to find the pose coordinates is to point-and-click
        # Nav Goals in RViz when running in the simulator.
        # Pose coordinates are then displayed in the terminal
        # that was used to launch RViz.
        self.waypoints = list()

        self.tf = TransformListener()

        #  self.locations = dict()
        #  self.wpname = dict()

        rospack = rospkg.RosPack()
        f = open(
            rospack.get_path('husky_wp') + '/params/pre-defined-standby.txt',
            'r')

        #  ct2 = 0
        with f as openfileobject:
            first_line = f.readline()
            for line in openfileobject:
                nome = [x.strip() for x in line.split(',')]
                #self.wpname[ct2] = nome[0]
                x = Decimal(nome[1])
                y = Decimal(nome[2])
                z = Decimal(nome[3])
                X = Decimal(nome[4])
                Y = Decimal(nome[5])
                Z = Decimal(nome[6])
                #self.locations[self.wpname[ct2]] = Pose(Point(x,y,z), Quaternion(X,Y,Z,1))
                self.waypoints.append(
                    Pose(Point(x, y, z), Quaternion(0, 0, 0, 1)))
                #print self.waypoints
                #time.sleep(1)

    #          ct2 = ct2+1
    #self.wp = -1
    #self.ct4 = 0

        print "Static path has : "
        print len(self.waypoints)
        print " point(s)."
        time.sleep(5)

        # Publisher to manually control the robot (e.g. to stop it, queue_size=5)
        self.cmd_vel_pub = rospy.Publisher('cmd_vel', Twist, queue_size=5)

        # Subscribe to the move_base action server
        self.move_base = actionlib.SimpleActionClient("move_base",
                                                      MoveBaseAction)

        rospy.loginfo("Waiting for move_base action server...")

        # Wait 60 seconds for the action server to become available
        self.move_base.wait_for_server(rospy.Duration(60))

        rospy.loginfo("Connected to move base server")
        rospy.loginfo("Starting navigation test")

        # Initialize a counter to track waypoints
        i = 0

        # Cycle through the four waypoints
        while i < len(self.waypoints) and not rospy.is_shutdown():
            # Update the marker display
            #self.marker_pub.publish(self.markers)
            time.sleep(2)
            # Intialize the waypoint goal
            goal = MoveBaseGoal()

            # Use the map frame to define goal poses
            goal.target_pose.header.frame_id = 'odom'

            # Set the time stamp to "now"
            goal.target_pose.header.stamp = rospy.Time.now()

            # Set the goal pose to the i-th waypoint
            goal.target_pose.pose = self.waypoints[i]

            # Start the robot moving toward the goal
            self.move(goal)

            i += 1
            # check if the goal point is found by the detect_goal node
            if rospy.has_param('/panel_goal'):
                # go to goal the goal goint
                # get parameter
                panel_goal = rospy.get_param("/panel_goal")
                print panel_goal[0]
                print panel_goal[1]
                print panel_goal[2]

                while not rospy.is_shutdown():
                    try:
                        # Find the global coordinate of the UGV
                        (trans, rot) = self.tf.lookupTransform(
                            '/odom', '/base_link', rospy.Time(0))
                        # Calculate the vector between the UGV and the goal point
                        Tx = panel_goal[0] - trans[0]
                        Ty = panel_goal[1] - trans[1]
                        print "Vehicle global coordinates is:"
                        print trans[0]
                        print trans[1]
                        print "The travel vecor is:"
                        print Tx
                        print Ty
                        # Calculate the travel distance between the UGV and the goal point
                        travel_distance = math.sqrt(
                            math.pow(Tx, 2) + math.pow(Ty, 2))
                        print "The travel distance is:"
                        print travel_distance
                        # Calculate a scaling vector to make the UGV stop at 1.5m away from the goal.
                        travel_distance2 = travel_distance - 1.5
                        factor = travel_distance2 / travel_distance
                        print "The scaliing factor is:"
                        print factor
                        Tx = Tx * factor
                        Ty = Ty * factor
                        # Calulate the goal point in the global frame
                        goal_x = trans[0] + Tx
                        goal_y = trans[1] + Ty

                        # Intialize the waypoint goal
                        goal = MoveBaseGoal()

                        # Use the map frame to define goal poses
                        goal.target_pose.header.frame_id = 'odom'

                        # Set the time stamp to "now"
                        goal.target_pose.header.stamp = rospy.Time.now()

                        print "The goal is:"
                        print goal_x
                        print goal_y

                        goal.target_pose.pose = Pose(Point(goal_x, goal_y, 0),
                                                     Quaternion(0, 0, 0, 1))
                        self.move(goal)
                        rospy.loginfo("Reach goal")
                        break

                    except (tf.LookupException, tf.ConnectivityException,
                            tf.ExtrapolationException):
                        rospy.loginfo("No transformation")
                break
            else:
                rospy.loginfo("No goal found")

    def move(self, goal):
        # Send the goal pose to the MoveBaseAction server
        self.move_base.send_goal(goal)

        # Allow 1 minute to get there
        finished_within_time = self.move_base.wait_for_result(
            rospy.Duration(600))

        # If we don't get there in time, abort the goal
        if not finished_within_time:
            self.move_base.cancel_goal()
            rospy.loginfo("Timed out achieving goal")
        else:
            # We made it!
            state = self.move_base.get_state()
            if state == GoalStatus.SUCCEEDED:
                rospy.loginfo("Goal succeeded!")

    def shutdown(self):
        rospy.loginfo("Stopping the robot...")
        self.move_base.cancel_goal()
        rospy.sleep(2)
        self.cmd_vel_pub.publish(Twist())
        rospy.sleep(1)
コード例 #13
0
ファイル: pick.py プロジェクト: minhnh/mas_domestic_robotics
class Pick(ScenarioStateBase):
    def __init__(self, save_sm_state=False, **kwargs):
        ScenarioStateBase.__init__(self,
                                   'pickup',
                                   save_sm_state=save_sm_state,
                                   output_keys=['grasped_object'],
                                   outcomes=[
                                       'succeeded', 'failed',
                                       'failed_after_retrying',
                                       'find_objects_before_picking'
                                   ])
        self.sm_id = kwargs.get('sm_id', 'mdr_demo_throw_table_objects')
        self.state_name = kwargs.get('state_name', 'pick')
        self.timeout = kwargs.get('timeout', 120.)
        self.tf_listener = TransformListener()

        self.number_of_retries = kwargs.get('number_of_retries', 0)
        self.retry_count = 0

    def execute(self, userdata):
        if self.save_sm_state:
            self.save_current_state()

        surface_objects = self.get_surface_objects(surface_prefix='table')
        object_poses = self.get_object_poses(surface_objects)
        surface, obj_to_grasp_idx = self.select_object_for_grasping(
            object_poses)
        obj_to_grasp = ''
        if obj_to_grasp_idx != -1:
            obj_to_grasp = surface_objects[surface][obj_to_grasp_idx]
        else:
            rospy.logerr('Could not find an object to grasp')
            self.say('Could not find an object to grasp')
            return 'find_objects_before_picking'

        dispatch_msg = self.get_dispatch_msg(obj_to_grasp, surface)
        rospy.loginfo('Picking %s from %s' % (obj_to_grasp, surface))
        self.say('Picking ' + obj_to_grasp + ' from ' + surface)
        self.action_dispatch_pub.publish(dispatch_msg)

        self.executing = True
        self.succeeded = False
        start_time = time.time()
        duration = 0.
        while self.executing and duration < self.timeout:
            rospy.sleep(0.1)
            duration = time.time() - start_time

        if self.succeeded:
            rospy.loginfo('%s grasped successfully' % obj_to_grasp)
            self.say('Successfully grasped ' + obj_to_grasp)
            userdata.grasped_object = obj_to_grasp
            return 'succeeded'

        rospy.loginfo('Could not grasp %s' % obj_to_grasp)
        self.say('Could not grasp ' + obj_to_grasp)
        if self.retry_count == self.number_of_retries:
            rospy.loginfo('Failed to grasp %s' % obj_to_grasp)
            self.say('Aborting operation')
            return 'failed_after_retrying'
        rospy.loginfo('Retrying to grasp %s' % obj_to_grasp)
        self.retry_count += 1
        return 'failed'

    def get_surface_objects(self, surface_prefix='table'):
        surface_objects = dict()
        request = rosplan_srvs.GetAttributeServiceRequest()
        request.predicate_name = 'on'
        result = self.attribute_fetching_client(request)
        for item in result.attributes:
            object_on_desired_surface = False
            object_name = ''
            surface_name = ''
            if not item.is_negative:
                for param in item.values:
                    if param.key == 'plane' and param.value.find(
                            surface_prefix) != -1:
                        object_on_desired_surface = True
                        surface_name = param.value
                        if surface_name not in surface_objects:
                            surface_objects[surface_name] = list()
                    elif param.key == 'obj':
                        object_name = param.value
            if object_on_desired_surface:
                surface_objects[surface_name].append(object_name)
        return surface_objects

    def get_object_poses(self, surface_objects):
        object_poses = dict()
        for surface, objects in surface_objects.items():
            object_poses[surface] = list()
            for obj_name in objects:
                try:
                    obj = self.msg_store_client.query_named(
                        obj_name, Object._type)[0]
                    object_poses[surface].append(obj.pose)
                except:
                    rospy.logerr('Error retriving knowledge about %s',
                                 obj_name)
                    pass
        return object_poses

    def select_object_for_grasping(self, object_poses):
        '''Returns the index of the object whose distance is closest to the robot
        '''
        object_surfaces = list()
        distances = dict()
        robot_position = np.zeros(3)
        for surface, poses in object_poses.items():
            object_surfaces.append(surface)
            distances[surface] = list()
            for pose in poses:
                base_link_pose = self.tf_listener.transformPose(
                    'base_link', pose)
                distances[surface].append(
                    self.distance(
                        robot_position,
                        np.array([
                            base_link_pose.pose.position.x,
                            base_link_pose.pose.position.y,
                            base_link_pose.pose.position.z
                        ])))

        min_dist = 1e100
        min_dist_obj_idx = -1
        obj_surface = ''
        for surface, distance_list in distances.items():
            if distance_list:
                surface_min_dist = np.min(distance_list)
                if surface_min_dist < min_dist:
                    min_dist = surface_min_dist
                    min_dist_obj_idx = np.argmin(distance_list)
                    obj_surface = surface
        return obj_surface, min_dist_obj_idx

    def get_robot_pose(self, map_frame='map', base_link_frame='base_link'):
        latest_tf_time = self.tf_listener.getLatestCommonTime(
            base_link_frame, map_frame)
        position, quat_orientation = self.tf_listener.lookupTransform(
            base_link_frame, map_frame, latest_tf_time)
        return position, quat_orientation

    def distance(self, point1, point2):
        return np.linalg.norm(np.array(point1) - np.array(point2))

    def get_dispatch_msg(self, obj_name, surface_name):
        dispatch_msg = plan_dispatch_msgs.ActionDispatch()
        dispatch_msg.name = self.action_name

        arg_msg = diag_msgs.KeyValue()
        arg_msg.key = 'bot'
        arg_msg.value = self.robot_name
        dispatch_msg.parameters.append(arg_msg)

        arg_msg = diag_msgs.KeyValue()
        arg_msg.key = 'obj'
        arg_msg.value = obj_name
        dispatch_msg.parameters.append(arg_msg)

        arg_msg = diag_msgs.KeyValue()
        arg_msg.key = 'plane'
        arg_msg.value = surface_name
        dispatch_msg.parameters.append(arg_msg)

        return dispatch_msg
コード例 #14
0
class FindObstacles(object):
    # we increment self.id at every complete scan.

    # per complete scan, we publish (potentially) multiple PolygonStamped
    # msgs to /obstacles, all with the same header.seq value (self.id)
    def __init__(self, viz=True, experiment=None):
        self.id = 1
        rospy.init_node('obstacles_node')
        self.tf = TransformListener()
        self.num_obj = 11

        pub = rospy.Publisher('/obstacles', Polygons, queue_size=50)

        obstacle_viz = rospy.Publisher('/obstacles_viz',
                                       MarkerArray,
                                       queue_size=50)

        if experiment:
            if experiment == "-b":
                #print("INIT EXPERIMENT")
                goal_pub = rospy.Publisher('/goal_state',
                                           Point32,
                                           queue_size=10)
                human_obs_pub = rospy.Publisher('obstacle2_poly',
                                                PolygonStamped,
                                                queue_size=1)
                human_v_pub = rospy.Publisher('obstacle2_v',
                                              Twist,
                                              queue_size=1)
                self.num_obj = 1
            if experiment == '-6':
                #print("INIT EXPERIMENT")
                human_pub = rospy.Publisher('/human', Point32, queue_size=10)
                human_obs_pub = rospy.Publisher('obstacle2_poly',
                                                PolygonStamped,
                                                queue_size=1)
                human_v_pub = rospy.Publisher('obstacle2_v',
                                              Twist,
                                              queue_size=1)
                self.num_obj = 1
            if experiment == '-g':
                #print("MODE SWITCHING ENABLED")
                goal_pub = rospy.Publisher('/goal_state',
                                           Point32,
                                           queue_size=10)
                human_pub = rospy.Publisher('/human', Point32, queue_size=10)
                human_obs_pub = rospy.Publisher('obstacle2_poly',
                                                Polygons,
                                                queue_size=1)
                human_v_pub = rospy.Publisher('obstacle2_v',
                                              Twist,
                                              queue_size=1)
                self.num_obj = 3

        # keep track of real lines from the last frame
        self.prev_real_lines = set()
        # keep track of img and lines from the last frame
        self.latest_img, self.latest_lines = np.zeros((GRID, GRID)), []

        self.x = [0, 0, 0]
        self.prev = None
        self.prevHuman = None

        # MODE 0: Goal Following, 1: Assistant
        self.mode = 0

        def odom_callback(msg):
            dd, asd, yaw = euler_from_quaternion([
                msg.pose.pose.orientation.x, msg.pose.pose.orientation.y,
                msg.pose.pose.orientation.z, msg.pose.pose.orientation.w
            ])
            self.x = [msg.pose.pose.position.x, msg.pose.pose.position.y, yaw]
            ##print("turtlebot ODOM", self.x)

        def mode_callback(msg):
            self.mode = msg.data

        rospy.Subscriber('/odom', Odometry, odom_callback)
        rospy.Subscriber('/mode', UInt16, mode_callback)

        def find_lines_and_pub(lidar_data):
            #lines, img = find_lines(lidar_data, self.prev_real_lines, self.x)

            # apply transformation
            try:
                pos, qu = self.tf.lookupTransform("/odom", "/base_scan",
                                                  rospy.Time())
                ##print("TRANS", pos, qu)
                t_mat = self.tf.fromTranslationRotation(pos, qu)

                n = len(lidar_data.points)
                p_mat = np.ones((4, n))
                for i in range(n):
                    pt = lidar_data.points[i]
                    p_mat[0, i] = pt.x
                    p_mat[1, i] = pt.y
                    p_mat[2, i] = 0
                p_trans = np.dot(t_mat, p_mat)

            except:
                return

            # process line data into usable form
            lines = set()
            for i in range(n / 2):
                line = ((p_trans[0, 2 * i], p_trans[1, 2 * i]),
                        (p_trans[0, 2 * i + 1], p_trans[1, 2 * i + 1]))
                lines.add(line)

            polys, obs = make_polys(lines, pos)

            # associates meas obs with previous obs
            obs_fil, flag = data_association(obs, self.prev, self.num_obj)

            pts = []
            visual = MarkerArray()

            ctr = 1
            for o in obs_fil:

                # inits kf if one doesn't exist for this obs
                if o.kf == None:
                    #print("INITIALIZING KF")
                    o.kf = o.init_kalman()

                # update kalman
                meas = np.append(o.center, o.area)
                o.mean, o.cov = o.kf.filter_update(o.mean,
                                                   o.cov,
                                                   observation=meas)

                # update
                o.center = [o.mean[0], o.mean[3]]
                o.area = o.mean[6]

                # visualization
                add = Point()
                add.x = o.mean[0]
                add.y = o.mean[3]
                pts.append(add)

                visual.markers.append(o.get_marker_meas(ctr))
                o.update_poly()
                visual.markers.append(o.get_marker(ctr))
                ctr += 1

            marker = Marker()
            marker.header.frame_id = "/odom"
            marker.id = 0
            marker.type = marker.POINTS
            marker.action = marker.ADD
            marker.scale.x = 0.2
            marker.scale.y = 0.2
            marker.scale.z = 0.2
            marker.color.b = 1.0
            marker.color.a = 1.0
            marker.points = pts
            visual.markers.append(marker)
            obstacle_viz.publish(visual)

            # only allow "good" measurements to be the references
            if len(obs_fil) == self.num_obj and not flag:
                self.prev = obs_fil

            # #print("Kalman est:", self.mean)
            if experiment:
                if experiment == "-b":
                    if len(obs_fil) == self.num_obj:
                        o = obs_fil[0]
                        cen = o.center_sq()
                        goal = Point32()
                        goal.x = cen[0]
                        goal.y = cen[1]
                        #goal_pub.publish(goal)
                        #human_pub.publish(o.poly)
                        #human_v_pub.publish(o.toVel())
                if experiment == "-6":
                    if len(obs_fil) == self.num_obj:
                        o = obs_fil[0]
                        cen = o.center_sq()
                        goal = Point32()
                        goal.x = cen[0]
                        goal.y = cen[1]
                        human_pub.publish(goal)
                        human_obs_pub.publish(o.poly)
                        human_v_pub.publish(o.toVel())
                if experiment == "-g":
                    if len(
                            obs_fil
                    ) >= self.num_obj:  # currently hard-coded to assume num_obj objects
                        polys = Polygons()
                        o = checkHuman(obs_fil, prevHuman=self.prevHuman)
                        self.prevHuman = o
                        cen = o.center_sq()
                        human_cen = Point32()
                        human_cen.x = cen[0]
                        human_cen.y = cen[1]
                        for obj in obs_fil:
                            polys.polygons.append(obj.poly)
                            polys.vels.append(obj.toVel())

                        if self.mode == 0:
                            human_pub.publish(human_cen)
                            human_obs_pub.publish(polys)
                            human_v_pub.publish(o.toVel())
                        elif self.mode == 1:
                            goal = Point32()
                            goal.x = human_cen.x
                            goal.y = human_cen.y - 1.5
                            goal_pub.publish(goal)
                            human_pub.publish(human_cen)
                            human_obs_pub.publish(polys)
                            human_v_pub.publish(o.toVel())

        rospy.Subscriber('/publish_line_markers', Marker, find_lines_and_pub)
        #rospy.Subscriber('/scan', LaserScan, find_lines_and_pub)
        #rospy.Subscriber('/scan_filtered', LaserScan, find_lines_and_pub)
        rospy.spin()
コード例 #15
0
class AccurateDocking(RComponent):
    """
    A class used to make a simple docking process
    """
    def __init__(self):
        RComponent.__init__(self)

        self.step = -1
        # array of {'initial': [x,y,theta], 'final': [x,y,theta]}
        self.results = []
        self.ongoing_result = {}
        self.total_iterations = 0
        self.stop = False

    def ros_read_params(self):
        """Gets params from param server"""
        RComponent.ros_read_params(self)

        self.dock_action_name = rospy.get_param('~dock_action_server',
                                                default='pp_docker')
        self.move_action_name = rospy.get_param('~move_action_server',
                                                default='move')

        self.robot_link = rospy.get_param('~base_frame',
                                          default='robot_base_link')

        self.pregoal_link = rospy.get_param(
            '~pregoal_frame', default='laser_test_pregoal_footprint')
        self.goal_link = rospy.get_param('~goal_frame',
                                         default='laser_test_goal_footprint')
        self.reflectors_link = rospy.get_param(
            '~reflectors_frame',
            default='robot_filtered_docking_station_laser')
        # array of [x, y, theta] for the first dock call
        param_offset_1 = rospy.get_param('~pregoal_offset_1',
                                         default='[-0.5, 0, 0]')
        self.pregoal_offset_1 = (param_offset_1.replace('[', '').replace(
            ']', '').replace(',', '')).split(' ')

        if len(self.pregoal_offset_1) != 3:
            self.pregoal_offset_1 = [0, 0, 0]
        else:
            for i in range(len(self.pregoal_offset_1)):
                self.pregoal_offset_1[i] = float(self.pregoal_offset_1[i])
        # array of [x, y, theta] for the second dock call
        param_offset_2 = rospy.get_param('~pregoal_offset_2',
                                         default='[-0.1, 0, 0]')
        self.pregoal_offset_2 = (param_offset_2.replace('[', '').replace(
            ']', '').replace(',', '')).split(' ')

        if len(self.pregoal_offset_2) != 3:
            self.pregoal_offset_2 = [0, 0, 0]
        else:
            for i in range(len(self.pregoal_offset_2)):
                self.pregoal_offset_2[i] = float(self.pregoal_offset_2[i])

        rospy.loginfo("%s::ros_read_params: docker offsets: %s - %s",
                      rospy.get_name(), str(self.pregoal_offset_1),
                      str(self.pregoal_offset_2))

        self.step_back_distance = rospy.get_param('~step_back_distance',
                                                  default=1.3)
        self.consecutive_iterations = rospy.get_param(
            '~consecutive_iterations', default=1)
        self.current_iteration = self.consecutive_iterations

    def ros_setup(self):
        """Creates and inits ROS components"""

        RComponent.ros_setup(self)

        self.tf = TransformListener()

        self.move_action_client = actionlib.SimpleActionClient(
            self.move_action_name, MoveAction)

        self.dock_action_client = actionlib.SimpleActionClient(
            self.dock_action_name, DockAction)

        self.start_docking_server = rospy.Service(
            '~start', Trigger, self.start_docking_service_cb)
        self.stop_docking_server = rospy.Service('~stop', Trigger,
                                                 self.stop_docking_service_cb)
        self.save_results_server = rospy.Service('~save_results', Empty,
                                                 self.save_results_service_cb)

        self.set_pregoal_offset_1 = rospy.Service('~set_pregoal_offset_1',
                                                  SetTransform,
                                                  self.set_pregoal_offset_1_cb)
        self.set_pregoal_offset_2 = rospy.Service('~set_pregoal_offset_2',
                                                  SetTransform,
                                                  self.set_pregoal_offset_2_cb)

        self.docking_status_pub = rospy.Publisher('~status',
                                                  String,
                                                  queue_size=10)
        self.docking_status = "stopped"

        RComponent.ros_setup(self)

    def ros_publish(self):
        '''
        Publish topics at standard frequency
      '''

        self.docking_status_pub.publish(self.docking_status)

        RComponent.ros_publish(self)

    def ready_state(self):
        """Actions performed in ready state"""

        if self.current_iteration < self.consecutive_iterations:

            self.docking_status = "running"

            if self.step != -1:
                try:
                    # Get relative goal position
                    t = self.tf.getLatestCommonTime(self.robot_link,
                                                    self.goal_link)

                    (position, quaternion) = self.tf.lookupTransform(
                        self.robot_link, self.goal_link, t)
                    (_, _, orientation) = euler_from_quaternion(quaternion)
                except Exception as e:
                    rospy.logerr("%s::ready_state: exception: %s",
                                 rospy.get_name(), e)
                    self.docking_status = "error"
                    self.stop = True
                    return

                try:
                    # Get relative goal to the reflectors position
                    t = self.tf.getLatestCommonTime(self.robot_link,
                                                    self.reflectors_link)

                    (position_to_reflectors,
                     quaternion_to_reflectors) = self.tf.lookupTransform(
                         self.robot_link, self.reflectors_link, t)
                    (_, _, orientation_to_reflectors
                     ) = euler_from_quaternion(quaternion_to_reflectors)

                except Exception as e:
                    rospy.logerr("%s::ready_state: exception: %s",
                                 rospy.get_name(), e)
                    self.docking_status = "error"
                    self.error_on_action()
                    return

            if self.step == 0:
                self.ongoing_result = {}
                rospy.loginfo('%s::ros_setup: waiting for server %s',
                              rospy.get_name(), self.move_action_name)
                self.move_action_client.wait_for_server()
                rospy.loginfo('%s::ros_setup: waiting for server %s',
                              rospy.get_name(), self.dock_action_name)
                self.dock_action_client.wait_for_server()

                rospy.loginfo(
                    '%s::ready_state: Initial distance to goal-> x: %.3lf mm, y: %.3lf mm, %.3lf degrees',
                    rospy.get_name(), position[0] * 1000, position[1] * 1000,
                    math.degrees(orientation))
                self.ongoing_result['initial'] = [
                    position[0], position[1],
                    math.degrees(orientation)
                ]
                # Docking
                dock_goal = DockGoal()
                dock_goal.dock_frame = self.pregoal_link
                dock_goal.robot_dock_frame = self.robot_link
                dock_goal.dock_offset.x = self.pregoal_offset_1[0]
                dock_goal.dock_offset.y = self.pregoal_offset_1[1]
                dock_goal.dock_offset.theta = self.pregoal_offset_1[2]
                rospy.loginfo(
                    '%s::ready_state: %d - docking to %s - offset = %s',
                    rospy.get_name(), self.step, self.pregoal_link,
                    str(dock_goal.dock_offset))
                self.dock_action_client.send_goal(dock_goal)
                self.dock_action_client.wait_for_result()
                result = self.dock_action_client.get_result()
                rospy.loginfo('%s::ready_state: %d - result = %s',
                              rospy.get_name(), self.step, str(result.success))

                if result.success == True:
                    self.step = 1
                    rospy.sleep(2)
                else:
                    rospy.logerr("%s::ready_state: Docking failed",
                                 rospy.get_name())
                    self.docking_status = "error"
                    self.error_on_action()

            elif self.step == 1:

                # Docking
                dock_goal = DockGoal()
                dock_goal.dock_frame = self.pregoal_link
                dock_goal.robot_dock_frame = self.robot_link
                dock_goal.dock_offset.x = self.pregoal_offset_2[0]
                dock_goal.dock_offset.y = self.pregoal_offset_2[1]
                dock_goal.dock_offset.theta = self.pregoal_offset_2[2]
                rospy.loginfo(
                    '%s::ready_state: %d - docking to %s - offset = %s',
                    rospy.get_name(), self.step, self.pregoal_link,
                    str(dock_goal.dock_offset))
                self.dock_action_client.send_goal(dock_goal)
                self.dock_action_client.wait_for_result()
                result = self.dock_action_client.get_result()
                rospy.loginfo('%s::ready_state: %d - result = %s',
                              rospy.get_name(), self.step, str(result.success))

                if result.success == True:
                    self.step = 2
                else:
                    rospy.logerr("%s::ready_state: Docking failed",
                                 rospy.get_name())
                    self.error_on_action()

            elif self.step == 2:
                # Orientate robot
                move_goal = MoveGoal()
                move_goal.goal.theta = orientation
                if abs(math.degrees(orientation)) > 0.2:
                    rospy.loginfo(
                        '%s::ready_state: %d - rotating %.3lf degrees to %s',
                        rospy.get_name(), self.step, math.degrees(orientation),
                        self.goal_link)
                    self.move_action_client.send_goal(move_goal)
                    self.move_action_client.wait_for_result()
                    result = self.move_action_client.get_result()
                    rospy.loginfo('%s::ready_state: %d - result = %s',
                                  rospy.get_name(), self.step,
                                  str(result.success))

                    if result.success == True:
                        self.step = 3
                    else:
                        rospy.logerr("%s::ready_state: Move-Rotation failed",
                                     rospy.get_name())
                        self.error_on_action()
                        self.docking_status = "error"
                else:
                    rospy.loginfo(
                        '%s::ready_state: %d - avoids rotating %.3lf degrees to %s',
                        rospy.get_name(), self.step, math.degrees(orientation),
                        self.goal_link)
                    self.step = 3

            elif self.step == 3:
                # Move forward
                move_goal = MoveGoal()
                move_goal.goal.x = position[0]
                rospy.loginfo(
                    '%s::ready_state: %d - moving forward %.3lf meters to %s',
                    rospy.get_name(), self.step, move_goal.goal.x,
                    self.goal_link)
                self.move_action_client.send_goal(move_goal)
                self.move_action_client.wait_for_result()
                result = self.move_action_client.get_result()
                rospy.loginfo('%s::ready_state: %d - result = %s',
                              rospy.get_name(), self.step, str(result.success))

                if result.success == True:
                    rospy.sleep(2)
                    self.step = 4
                else:
                    rospy.logerr("%s::ready_state: Move-Forward failed",
                                 rospy.get_name())
                    self.error_on_action()
                    self.docking_status = "error"

            elif self.step == 4:
                rospy.loginfo(
                    '%s::ready_state: final distance to goal -> x: %.3lf mm, y: %.3lf mm, %.3lf degrees',
                    rospy.get_name(), position[0] * 1000, position[1] * 1000,
                    math.degrees(orientation))
                rospy.loginfo(
                    '%s::ready_state: final distance to reflectors -> x: %.3lf mm, y: %.3lf mm, %.3lf degrees',
                    rospy.get_name(), position_to_reflectors[0] * 1000,
                    position_to_reflectors[1] * 1000,
                    math.degrees(orientation_to_reflectors))
                self.ongoing_result['final'] = [
                    position[0], position[1],
                    math.degrees(orientation)
                ]
                self.results.append(self.ongoing_result)
                if self.step_back_distance == 0.0:
                    self.iteration_success()
                else:
                    self.step = 5

            elif self.step == 5:
                # Move backward
                move_goal = MoveGoal()
                move_goal.goal.x = -self.step_back_distance
                rospy.loginfo(
                    '%s::ready_state: %d - moving backwards %.3lf meters',
                    rospy.get_name(), self.step, move_goal.goal.x)
                self.move_action_client.send_goal(move_goal)
                self.move_action_client.wait_for_result()
                result = self.move_action_client.get_result()
                rospy.loginfo('%s::ready_state: %d - result = %s',
                              rospy.get_name(), self.step, str(result.success))

                if result.success == True:
                    rospy.sleep(2)
                    self.iteration_success()
                else:
                    rospy.logerr("%s::ready_state: Move-Forward failed",
                                 rospy.get_name())
                    self.error_on_action()
                    self.docking_status = "error"

        else:
            self.docking_status = "stopped"

    def error_on_action(self):
        self.step = -1
        self.current_iteration = self.consecutive_iterations

    def iteration_success(self):
        self.current_iteration += 1
        self.total_iterations += 1
        rospy.loginfo('%s::iteration_success: current it = %d - total = %s',
                      rospy.get_name(), self.current_iteration,
                      self.total_iterations)

        if self.stop == True:
            self.stop = False
            if self.current_iteration < self.consecutive_iterations:
                rospy.logwarn(
                    '%s::iteration_success: stopping due to user requirement',
                    rospy.get_name())
                self.current_iteration = self.consecutive_iterations

        if self.current_iteration < self.consecutive_iterations:
            self.step = 0
        else:
            self.step = -1

    def shutdown(self):

        return RComponent.shutdown(self)

    def switch_to_state(self, new_state):
        """Performs the change of state"""

        return RComponent.switch_to_state(self, new_state)

    def stop_docking_service_cb(self, req):
        '''
        stop docking process
      '''

        if self.current_iteration < self.consecutive_iterations:
            self.stop = True
            return True, "Stopping after this iteration (%d of %d) Step = %d" % (
                self.current_iteration + 1, self.consecutive_iterations,
                self.step)
        else:
            return False, "Docking not running"

    def start_docking_service_cb(self, req):
        '''
        start docking process
      '''

        if self.current_iteration < self.consecutive_iterations:
            return False, "Docking is still running. Iteration = (%d of %d) Step = %d" % (
                self.current_iteration + 1, self.consecutive_iterations,
                self.step)
        else:
            self.current_iteration = 0
            self.step = 0
            self.stop = False
            return True, "Starting"

    def save_results_service_cb(self, req):
        '''
        saves current results process
      '''
        rp = rospkg.RosPack()
        filename = 'docking_%s.csv' % (str(datetime.datetime.now()).replace(
            ' ', '_').replace('.', '').replace(':', '-'))

        folder = os.path.join(rp.get_path('accurate_docking'), 'data')
        file_path = folder + '/' + filename
        with open(file_path, 'w') as f:
            for result in self.results:
                f.write("%f,%f,%f,%f,%f,%f\n" %
                        (result['initial'][0], result['initial'][1],
                         result['initial'][2], result['final'][0],
                         result['final'][1], result['final'][2]))

        print(self.results)
        return []

    def set_pregoal_offset_1_cb(self, req):
        '''
        modify pregoal_offset_1
      '''
        self.pregoal_offset_1[0] = req.tf.translation.x
        self.pregoal_offset_1[1] = req.tf.translation.y
        self.pregoal_offset_1[2] = req.tf.translation.z

        ret = ReturnMessage()
        ret.success = True
        ret.message = "Changed pregoal_offset_1"

        return ret

    def set_pregoal_offset_2_cb(self, req):
        '''
        modify pregoal_offset_2
      '''
        self.pregoal_offset_2[0] = req.tf.translation.x
        self.pregoal_offset_2[1] = req.tf.translation.y
        self.pregoal_offset_2[2] = req.tf.translation.z

        ret = ReturnMessage()
        ret.success = True
        ret.message = "Changed pregoal_offset_2"

        return ret
コード例 #16
0
class GripperActionController():
    def __init__(self, controller_namespace, controllers):
        self.controller_namespace = controller_namespace
        self.controllers = {}
        
        for c in controllers:
            self.controllers[c.controller_namespace] = c


    def initialize(self):
        l_controller_name = rospy.get_param('~left_controller_name', 'left_finger_controller')
        r_controller_name = rospy.get_param('~right_controller_name', 'right_finger_controller')
        
        if l_controller_name not in self.controllers:
            rospy.logerr('left_controller_name not found, requested: [%s], available: %s' % (l_controller_name, self.controllers))
            return False
            
        if r_controller_name not in self.controllers:
            rospy.logerr('right_controller_name not found, requested: [%s], available: %s' % (r_controller_name, self.controllers))
            return False
            
        self.l_finger_controller = self.controllers[l_controller_name]
        self.r_finger_controller = self.controllers[r_controller_name]
        
        if self.l_finger_controller.port_namespace != self.r_finger_controller.port_namespace:
            rospy.logerr('%s and %s are connected to different serial ports, this is unsupported' % (l_controller_name, r_controller_name))
            return False
            
        # left and right finger are assumed to be connected to the same port
        self.dxl_io = self.l_finger_controller.dxl_io
        
        self.l_finger_state = self.l_finger_controller.joint_state
        self.r_finger_state = self.r_finger_controller.joint_state
        
        self.l_max_speed = self.l_finger_controller.joint_max_speed
        self.r_max_speed = self.r_finger_controller.joint_max_speed
        
        return True


    def start(self):
        self.tf_listener = TransformListener()
        
        # Publishers
        self.gripper_opening_pub = rospy.Publisher('gripper_opening', Float64)
        self.l_finger_ground_distance_pub = rospy.Publisher('left_finger_ground_distance', Float64)
        self.r_finger_ground_distance_pub = rospy.Publisher('right_finger_ground_distance', Float64)
        
        # Pressure sensors
        # 0-3 - left finger
        # 4-7 - right finger
        num_sensors = 8
        self.pressure = [0.0] * num_sensors
        [rospy.Subscriber('/interface_kit/124427/sensor/%d' % i, Float64Stamped, self.process_pressure_sensors, i) for i in range(num_sensors)]
        
        # pressure sensors are at these values when no external pressure is applied
        self.l_zero_pressure = [0.0, 0.0, 0.0, 0.0]
        self.r_zero_pressure = [0.0, 0.0, 130.0, 0.0]
        self.lr_zero_pressure = self.l_zero_pressure + self.r_zero_pressure
        
        self.l_total_pressure_pub = rospy.Publisher('left_finger_pressure', Float64)
        self.r_total_pressure_pub = rospy.Publisher('right_finger_pressure', Float64)
        self.lr_total_pressure_pub = rospy.Publisher('total_pressure', Float64)
        
        self.close_gripper = False
        self.dynamic_torque_control = False
        self.lower_pressure = 800.0
        self.upper_pressure = 1000.0
        
        # IR sensor
        self.gripper_ir_pub = rospy.Publisher('gripper_distance_sensor', Float64)
        self.ir_distance = 0.0
        rospy.Subscriber('/interface_kit/106950/sensor/7', Float64Stamped, self.process_ir_sensor)
        
        # Temperature monitor and torque control thread
        Thread(target=self.gripper_monitor).start()
        
        # Start gripper opening monitoring thread
        Thread(target=self.calculate_gripper_opening).start()
        
        self.action_server = actionlib.SimpleActionServer('wubble_gripper_action',
                                                          WubbleGripperAction,
                                                          execute_cb=self.process_gripper_action,
                                                          auto_start=False)
        self.action_server.start()
        rospy.loginfo('gripper_freespin_controller: ready to accept goals')


    def stop(self):
        pass


    def __send_motor_command(self, l_desired_torque, r_desired_torque):
        l_motor_id = self.l_finger_controller.motor_id
        r_motor_id = self.r_finger_controller.motor_id
        
        l_trq = self.l_finger_controller.spd_rad_to_raw(l_desired_torque)
        r_trq = self.r_finger_controller.spd_rad_to_raw(r_desired_torque)
        
        self.dxl_io.set_multi_speed( ( (l_motor_id,l_trq), (r_motor_id,r_trq) ) )


    def activate_gripper(self, command, torque_limit):
        if command == WubbleGripperGoal.CLOSE_GRIPPER:
            l_desired_torque = -torque_limit * self.l_max_speed
            r_desired_torque =  torque_limit * self.r_max_speed
        else: # assume opening
            l_desired_torque =  torque_limit * self.l_max_speed
            r_desired_torque = -torque_limit * self.r_max_speed
            
        self.__send_motor_command(l_desired_torque, r_desired_torque)
        
        return max(l_desired_torque, r_desired_torque)


    def gripper_monitor(self):
        rospy.loginfo('Gripper temperature monitor and torque control thread started successfully')
        motors_overheating = False
        max_pressure = 8000.0
        r = rospy.Rate(150)
        
        while not rospy.is_shutdown():
            l_total_pressure = max(0.0, sum(self.pressure[:4]) - sum(self.l_zero_pressure))
            r_total_pressure = max(0.0, sum(self.pressure[4:]) - sum(self.r_zero_pressure))
            pressure = l_total_pressure + r_total_pressure
            
            self.l_total_pressure_pub.publish(l_total_pressure)
            self.r_total_pressure_pub.publish(r_total_pressure)
            self.lr_total_pressure_pub.publish(pressure)
            
            #----------------------- TEMPERATURE MONITOR ---------------------------#
            l_temp = max(self.l_finger_state.motor_temps)
            r_temp = max(self.r_finger_state.motor_temps)
            
            if l_temp >= 75 or r_temp >= 75:
                if not motors_overheating:
                    rospy.logwarn('Disabling gripper motors torque [LM: %dC, RM: %dC]' % (l_temp, r_temp))
                    self.__send_motor_command(-0.5, 0.5)
                    motors_overheating = True
            else:
                motors_overheating = False
                
            #########################################################################
            
            # don't do torque control if not requested or
            # when the gripper is open
            # or when motors are too hot
            if not self.dynamic_torque_control or \
               not self.close_gripper or \
               motors_overheating:
                r.sleep()
                continue
                
            #----------------------- TORQUE CONTROL -------------------------------#
            l_current = self.l_finger_state.goal_pos
            r_current = self.r_finger_state.goal_pos
            
            if pressure > self.upper_pressure:   # release
                pressure_change_step = abs(pressure - self.upper_pressure) / max_pressure
                l_goal = min( self.l_max_speed, l_current + pressure_change_step)
                r_goal = max(-self.r_max_speed, r_current - pressure_change_step)
                
                if l_goal < self.l_max_speed or r_goal > -self.r_max_speed:
                    if self.close_gripper:
                        self.__send_motor_command(l_goal, r_goal)
                        rospy.logdebug('>MAX pressure is %.2f, LT: %.2f, RT: %.2f, step is %.2f' % (pressure, l_current, r_current, pressure_change_step))
            elif pressure < self.lower_pressure: # squeeze
                pressure_change_step = abs(pressure - self.lower_pressure) / max_pressure
                l_goal = max(-self.l_max_speed, l_current - pressure_change_step)
                r_goal = min( self.r_max_speed, r_current + pressure_change_step)
                
                if l_goal > -self.l_max_speed or r_goal < self.r_max_speed:
                    if self.close_gripper:
                        self.__send_motor_command(l_goal, r_goal)
                        rospy.logdebug('<MIN pressure is %.2f, LT: %.2f, RT: %.2f, step is %.2f' % (pressure, l_current, r_current, pressure_change_step))
            ########################################################################
            
            r.sleep()


    def calculate_gripper_opening(self):
        timeout = rospy.Duration(5)
        last_reported = rospy.Time(0)
        r = rospy.Rate(50)
        
        while not rospy.is_shutdown():
            try:
                map_frame_id = 'base_footprint'
                palm_frame_id = 'L7_wrist_roll_link'
                l_fingertip_frame_id = 'left_fingertip_link'
                r_fingertip_frame_id = 'right_fingertip_link'
                
                self.tf_listener.waitForTransform(palm_frame_id, l_fingertip_frame_id, rospy.Time(0), rospy.Duration(0.2))
                self.tf_listener.waitForTransform(palm_frame_id, r_fingertip_frame_id, rospy.Time(0), rospy.Duration(0.2))
                
                l_pos, _ = self.tf_listener.lookupTransform(palm_frame_id, l_fingertip_frame_id, rospy.Time(0))
                r_pos, _ = self.tf_listener.lookupTransform(palm_frame_id, r_fingertip_frame_id, rospy.Time(0))
                
                dx = l_pos[0] - r_pos[0]
                dy = l_pos[1] - r_pos[1]
                dz = l_pos[2] - r_pos[2]
                
                dist = math.sqrt(dx*dx + dy*dy + dz*dz)
                self.gripper_opening_pub.publish(dist)
                
                l_pos, _ = self.tf_listener.lookupTransform(map_frame_id, l_fingertip_frame_id, rospy.Time(0))
                r_pos, _ = self.tf_listener.lookupTransform(map_frame_id, r_fingertip_frame_id, rospy.Time(0))
                
                self.l_finger_ground_distance_pub.publish(l_pos[2])
                self.r_finger_ground_distance_pub.publish(r_pos[2])
            except LookupException as le:
                rospy.logerr(le)
            except ConnectivityException as ce:
                rospy.logerr(ce)
            except tf.Exception as e:
                if rospy.Time.now() - last_reported > timeout:
                    rospy.logerr('TF exception: %s' % str(e))
                    last_reported = rospy.Time.now()
                    
            r.sleep()


    def process_pressure_sensors(self, msg, i):
        self.pressure[i] = msg.data


    def process_ir_sensor(self, msg):
        """
        Given a raw sensor value from Sharp IR sensor (4-30cm model)
        returns an actual distance in meters.
        """
        if msg.data < 80: self.ir_distance = 1.0           # too far
        elif msg.data > 530: self.ir_distance = 0.0        # too close
        else: self.ir_distance =  20.76 / (msg.data - 11)  # just right
        
        self.gripper_ir_pub.publish(self.ir_distance)


    def process_gripper_action(self, req):
        r = rospy.Rate(500)
        timeout = rospy.Duration(2.0)
        
        if req.command == WubbleGripperGoal.CLOSE_GRIPPER:
            self.dynamic_torque_control = req.dynamic_torque_control
            self.lower_pressure = req.pressure_lower
            self.upper_pressure = req.pressure_upper
            
            desired_torque = self.activate_gripper(req.command, req.torque_limit)
            
            if not self.dynamic_torque_control:
                start_time = rospy.Time.now()
                while not rospy.is_shutdown() and \
                      rospy.Time.now() - start_time < timeout and \
                      (not within_tolerance(self.l_finger_state.load, -req.torque_limit, 0.01) or
                       not within_tolerance(self.r_finger_state.load, -req.torque_limit, 0.01)):
                    r.sleep()
            else:
                if desired_torque > 1e-3: rospy.sleep(1.0 / desired_torque)
                
            self.close_gripper = True
            self.action_server.set_succeeded()
        elif req.command == WubbleGripperGoal.OPEN_GRIPPER:
            self.close_gripper = False
            self.activate_gripper(req.command, req.torque_limit)
            
            start_time = rospy.Time.now()
            while not rospy.is_shutdown() and \
                  rospy.Time.now() - start_time < timeout and \
                  (self.l_finger_state.current_pos < 0.8 or
                   self.r_finger_state.current_pos > -0.8):
                r.sleep()
                
            self.__send_motor_command(0.5, -0.5)
            self.action_server.set_succeeded()
        else:
            msg = 'Unrecognized command: %d' % req.command
            rospy.logerr(msg)
            self.action_server.set_aborted(text=msg)
コード例 #17
0
class GripperMarkers:

    _offset = 0.09
    def __init__(self, side_prefix):
        
        self.ik = IK(side_prefix)
        self.side_prefix = side_prefix
        self._im_server = InteractiveMarkerServer('ik_request_markers')
        self._tf_listener = TransformListener()
        self._menu_handler = MenuHandler()
        self._menu_handler.insert('Move arm here', callback=self.move_to_pose_cb)
        self.is_control_visible = False
        self.ee_pose = self.get_ee_pose()
        self.update_viz()
        self._menu_handler.apply(self._im_server, 'ik_target_marker')
        self._im_server.applyChanges()

    def get_ee_pose(self):
        from_frame = '/base_link'
        to_frame = '/' + self.side_prefix + '_wrist_roll_link'
        try:
            t = self._tf_listener.getLatestCommonTime(from_frame, to_frame)
            (pos, rot) = self._tf_listener.lookupTransform(from_frame, to_frame, t)
        except:
            rospy.logwarn('Could not get end effector pose through TF.')
            pos = [1.0, 0.0, 1.0]
            rot = [0.0, 0.0, 0.0, 1.0]

	return Pose(Point(pos[0], pos[1], pos[2]),
			Quaternion(rot[0], rot[1], rot[2], rot[3]))

    def move_to_pose_cb(self, dummy):
        rospy.loginfo('You pressed the `Move arm here` button from the menu.')

        target_pose = GripperMarkers._offset_pose(self.ee_pose)
        ik_solution = self.ik.get_ik_for_ee(target_pose)
    
        #TODO: Send the arms to ik_solution

    def marker_clicked_cb(self, feedback):
        if feedback.event_type == InteractiveMarkerFeedback.POSE_UPDATE:
            self.ee_pose = feedback.pose
            self.update_viz()
            self._menu_handler.reApply(self._im_server)
            self._im_server.applyChanges()

        elif feedback.event_type == InteractiveMarkerFeedback.BUTTON_CLICK:
            rospy.loginfo('Changing visibility of the pose controls.')
            if (self.is_control_visible):
                self.is_control_visible = False
            else:
                self.is_control_visible = True
        else:
            rospy.loginfo('Unhandled event: ' + str(feedback.event_type))

    def update_viz(self):
        
        menu_control = InteractiveMarkerControl()
        menu_control.interaction_mode = InteractiveMarkerControl.BUTTON
        menu_control.always_visible = True
        frame_id = 'base_link'
        pose = self.ee_pose
        
        menu_control = self._add_gripper_marker(menu_control)
        text_pos = Point()
        text_pos.x = pose.position.x
        text_pos.y = pose.position.y
        text_pos.z = pose.position.z + 0.1
        text = 'x=' + str(pose.position.x) + ' y=' + str(pose.position.y) + ' x=' + str(pose.position.z)
        menu_control.markers.append(Marker(type=Marker.TEXT_VIEW_FACING,
                                           id=0, scale=Vector3(0, 0, 0.03),
                                           text=text,
                                           color=ColorRGBA(0.0, 0.0, 0.0, 0.5),
                                           header=Header(frame_id=frame_id),
                                           pose=Pose(text_pos, Quaternion(0, 0, 0, 1))))
        int_marker = InteractiveMarker()
        int_marker.name = 'ik_target_marker'
        int_marker.header.frame_id = frame_id
        int_marker.pose = pose
        int_marker.scale = 0.2
        self._add_6dof_marker(int_marker)
        int_marker.controls.append(menu_control)
        self._im_server.insert(int_marker, self.marker_clicked_cb)

    def _add_gripper_marker(self, control):
        is_hand_open=False
        if is_hand_open:
            angle = 28 * numpy.pi / 180.0
        else:
            angle = 0
        transform1 = tf.transformations.euler_matrix(0, 0, angle)
        transform1[:3, 3] = [0.07691 - GripperMarkers._offset, 0.01, 0]
        transform2 = tf.transformations.euler_matrix(0, 0, -angle)
        transform2[:3, 3] = [0.09137, 0.00495, 0]
        t_proximal = transform1
        t_distal = tf.transformations.concatenate_matrices(transform1, transform2)
        mesh1 = self._make_mesh_marker()
        mesh1.mesh_resource = ('package://pr2_description/meshes/gripper_v0/gripper_palm.dae')
        mesh1.pose.position.x = -GripperMarkers._offset
        mesh1.pose.orientation.w = 1
        mesh2 = self._make_mesh_marker()
        mesh2.mesh_resource = ('package://pr2_description/meshes/gripper_v0/l_finger.dae')
        mesh2.pose = GripperMarkers.get_pose_from_transform(t_proximal)
        mesh3 = self._make_mesh_marker()
        mesh3.mesh_resource = ('package://pr2_description/meshes/gripper_v0/l_finger_tip.dae')
        mesh3.pose = GripperMarkers.get_pose_from_transform(t_distal)
        quat = tf.transformations.quaternion_multiply(
        tf.transformations.quaternion_from_euler(numpy.pi, 0, 0),
        tf.transformations.quaternion_from_euler(0, 0, angle))
        transform1 = tf.transformations.quaternion_matrix(quat)
        transform1[:3, 3] = [0.07691 - GripperMarkers._offset, -0.01, 0]
        transform2 = tf.transformations.euler_matrix(0, 0, -angle)
        transform2[:3, 3] = [0.09137, 0.00495, 0]
        t_proximal = transform1
        t_distal = tf.transformations.concatenate_matrices(transform1,transform2)
        mesh4 = self._make_mesh_marker()
        mesh4.mesh_resource = ('package://pr2_description/meshes/gripper_v0/l_finger.dae')
        mesh4.pose = GripperMarkers.get_pose_from_transform(t_proximal)
        mesh5 = self._make_mesh_marker()
        mesh5.mesh_resource = ('package://pr2_description/meshes/gripper_v0/l_finger_tip.dae')
        mesh5.pose = GripperMarkers.get_pose_from_transform(t_distal)

        control.markers.append(mesh1)
        control.markers.append(mesh2)
        control.markers.append(mesh3)
        control.markers.append(mesh4)
        control.markers.append(mesh5)
        return control

    @staticmethod
    def get_pose_from_transform(transform):
		pos = transform[:3,3].copy()
		rot = tf.transformations.quaternion_from_matrix(transform)
		return Pose(Point(pos[0], pos[1], pos[2]),
				Quaternion(rot[0], rot[1], rot[2], rot[3]))

    @staticmethod
    def _offset_pose(pose):
        transform = GripperMarkers.get_matrix_from_pose(pose)
        offset_array = [GripperMarkers._offset, 0, 0]
        offset_transform = tf.transformations.translation_matrix(offset_array)
        hand_transform = tf.transformations.concatenate_matrices(transform, offset_transform)
        return GripperMarkers.get_pose_from_transform(hand_transform)

    @staticmethod
    def get_matrix_from_pose(pose):
        rotation = [pose.orientation.x, pose.orientation.y,
                pose.orientation.z, pose.orientation.w]
        transformation = tf.transformations.quaternion_matrix(rotation)
        position = [pose.position.x, pose.position.y, pose.position.z]
        transformation[:3, 3] = position
        return transformation

    def _make_mesh_marker(self):
        mesh = Marker()
        mesh.mesh_use_embedded_materials = False
        mesh.type = Marker.MESH_RESOURCE
    	mesh.scale.x = 1.0
        mesh.scale.y = 1.0
        mesh.scale.z = 1.0
        
        target_pose = GripperMarkers._offset_pose(self.ee_pose)
        ik_solution = self.ik.get_ik_for_ee(target_pose)
        
        if (ik_solution == None):
            mesh.color = ColorRGBA(1.0, 0.0, 0.0, 0.6)
        else:
            mesh.color = ColorRGBA(0.0, 1.0, 0.0, 0.6)
            mesh.color = ColorRGBA(0.0, 0.5, 1.0, 0.6)

        return mesh

    def _add_6dof_marker(self, int_marker):
        is_fixed = True
        control = self._make_6dof_control('rotate_x', Quaternion(1, 0, 0, 1), False, is_fixed)
        int_marker.controls.append(control)
        control = self._make_6dof_control('move_x', Quaternion(1, 0, 0, 1), True, is_fixed)
        int_marker.controls.append(control)
        control = self._make_6dof_control('rotate_z', Quaternion(0, 1, 0, 1), False, is_fixed)
        int_marker.controls.append(control)
        control = self._make_6dof_control('move_z', Quaternion(0, 1, 0, 1), True, is_fixed)
        int_marker.controls.append(control)
        control = self._make_6dof_control('rotate_y', Quaternion(0, 0, 1, 1), False, is_fixed)
        int_marker.controls.append(control)
        control = self._make_6dof_control('move_y', Quaternion(0, 0, 1, 1), True, is_fixed)
        int_marker.controls.append(control)

    def _make_6dof_control(self, name, orientation, is_move, is_fixed):
        control = InteractiveMarkerControl()
        control.name = name
        control.orientation = orientation
        control.always_visible = False
        if (self.is_control_visible):
            if is_move:
                control.interaction_mode = InteractiveMarkerControl.MOVE_AXIS
            else:
                control.interaction_mode = InteractiveMarkerControl.ROTATE_AXIS
        else:
            control.interaction_mode = InteractiveMarkerControl.NONE
        if is_fixed:
            control.orientation_mode = InteractiveMarkerControl.FIXED
        return control
コード例 #18
0
ファイル: tensioner.py プロジェクト: qingchenkanlu/IL_ROS_HSR
class Tensioner(object):

    def __init__(self):
        self.torque = Gripper_Torque()
        self.tl = TransformListener()


    def get_translation(self,direction):
        pose = self.tl.lookupTransform(direction,'hand_palm_link',rospy.Time(0))
        trans = pose[0]
        return trans


    def get_rotation(self,direction):
        pose = self.tl.lookupTransform(direction,'hand_palm_link',rospy.Time(0))
        rot = pose[1]
        return tf.transformations.quaternion_matrix(rot)


    def compute_bed_tension(self, wrench, direction):
        x = wrench.wrench.force.x
        y = wrench.wrench.force.y
        z = wrench.wrench.force.z 
        force = np.array([x,y,z,1.0])
        rot = self.get_rotation(direction)
        force_perp = np.dot(rot,force)
        print("\nInside p_pi/bed_making/tensioner.py, `compute_bed_tension()`:")
        print("CURRENT FORCES: {}".format(force))
        print("FORCE PERP: {}".format(force_perp))
        return force_perp[1]


    def force_pull(self, whole_body, direction):
        """Pull to the target `direction`, hopefully with the sheet!
        
        I think this splits it into several motions, at most `cfg.MAX_PULLS`, so
        this explains the occasional pauses with the HSR's motion. This is *per*
        grasp+pull attempt, so it's different from the max attempts per side,
        which I empirically set at 4. Actually he set his max pulls to 3, but
        because of the delta <= 1.0 (including equality) this is 4 also.

        Move the end-effector, then quickly read the torque data and look at the
        wrench. The end-effector moves according to a _fraction_ that is
        specified by `s = 1-delta`, so I _hope_ if there's too much tension
        after that tiny bit of motion, that we'll exit. But maybe the
        discretization into four smaller pulls is not fine enough?
        """
        count = 0
        is_pulling = False
        t_o = self.get_translation(direction)
        delta = 0.0
        while delta <= 1.0:
            s = 1.0 - delta
            whole_body.move_end_effector_pose(
                    geometry.pose(x=t_o[0]*s, y=t_o[1]*s, z=t_o[2]*s),
                    direction
            )
            wrench = self.torque.read_data()
            norm = np.abs(self.compute_bed_tension(wrench,direction))
            print("FORCE NORM: {}".format(norm))
            if norm > cfg.HIGH_FORCE:
                is_pulling = True
            if is_pulling and norm < cfg.LOW_FORCE:
                break
            if norm > cfg.FORCE_LIMT:
                break
            delta += 1.0/float(cfg.MAX_PULLS)
コード例 #19
0
ファイル: head.py プロジェクト: patlican23/robot_eup
class Head:

        # 'LOOK_FORWARD: 'LOOK_FORWARD',
        # 'FOLLOW_RIGHT_EE: 'FOLLOW_RIGHT_EE',
        # 'FOLLOW_LEFT_EE: 'FOLLOW_LEFT_EE',
        # 'GLANCE_RIGHT_EE: 'GLANCE_RIGHT_EE',
        # 'GLANCE_LEFT_EE: 'GLANCE_LEFT_EE',
        # 'NOD: 'NOD',
        # 'SHAKE: 'SHAKE',
        # 'FOLLOW_FACE: 'FOLLOW_FACE',
        # 'LOOK_AT_POINT: 'LOOK_AT_POINT',
        # 'LOOK_DOWN: 'LOOK_DOWN',
        # 'NOD_ONCE : 'NOD_ONCE ',
        # 'SHAKE_ONCE: 'SHAKE_ONCE',

    def __init__(self):
        self.defaultLookatPoint = Point(1,0,1.35)
        self.downLookatPoint = Point(0.5,0,0.5)
        self.targetLookatPoint = Point(1,0,1.35)
        self.currentLookatPoint = Point(1,0,1.35)

        self.currentGazeAction = 'LOOK_FORWARD';
        self.prevGazeAction = self.currentGazeAction
        self.prevTargetLookatPoint = array(self.defaultLookatPoint);

        # Some constants
        self.doNotInterrupt = ['GLANCE_RIGHT_EE', 'GLANCE_LEFT_EE', 'NOD', 'SHAKE'];
        self.nodPositions = [Point(1,0,1.05), Point(1,0,1.55)]
        self.shakePositions = [Point(1,0.2,1.35), Point(1,-0.2,1.35)]
        self.nNods = 5
        self.nShakes = 5

        self.nodCounter = 5
        self.shakeCounter = 5
        self.facePos = None

        ## Action client for sending commands to the head.
        self.headActionClient = SimpleActionClient('/head_traj_controller/point_head_action', PointHeadAction)
        self.headActionClient.wait_for_server()
        rospy.loginfo('Head action client has responded.')

        self.headGoal = PointHeadGoal()
        self.headGoal.target.header.frame_id = 'base_link'
        self.headGoal.min_duration = rospy.Duration(1.0)
        self.headGoal.target.point = Point(1,0,1)

        ## Client for receiving detected faces
        #self.faceClient = SimpleActionClient('face_detector_action', FaceDetectorAction)

        ## Service client for arm states
        self.tfListener = TransformListener()


    ## Callback function to receive ee states and face location
    def getEEPos(self, armIndex):

        fromFrame = '/base_link'
        if (armIndex == 0):
            toFrame = '/r_wrist_roll_link'
        else:
            toFrame = '/l_wrist_roll_link'

        try:
            t = self.tfListener.getLatestCommonTime(fromFrame, toFrame)
            (position, rotation) = self.tfListener.lookupTransform(fromFrame, toFrame, t)
        except:
            rospy.logerr('Could not get the end-effector pose.')
        #objPoseStamped = PoseStamped()
        #objPoseStamped.header.stamp = t
        #objPoseStamped.header.frame_id = '/base_link'
        #objPoseStamped.pose = Pose()
        #relEEPose = self.tfListener.transformPose(toFrame, objPoseStamped)
        return Point(position[0], position[1], position[2])

    def getFaceLocation(self):
        connected = self.faceClient.wait_for_server(rospy.Duration(1.0))
        if connected:
            fgoal = FaceDetectorGoal()
            self.faceClient.send_goal(fgoal)
            self.faceClient.wait_for_result()
            f = self.faceClient.get_result()
            ## If there is one face follow that one, if there are more than one, follow the closest one
            closest = -1
            if len(f.face_positions) == 1:
                closest = 0
            elif len(f.face_positions) > 0:
                closest_dist = 1000

            for i in range(len(f.face_positions)):
                dist = f.face_positions[i].pos.x*f.face_positions[i].pos.x + f.face_positions[i].pos.y*f.face_positions[i].pos.y + f.face_positions[i].pos.z*f.face_positions[i].pos.z
                if dist < closest_dist:
                    closest = i
                    closest_dist = dist

            if closest > -1:
                self.facePos = array([f.face_positions[closest].pos.x, f.face_positions[closest].pos.y, f.face_positions[closest].pos.z])
            else:
                rospy.logwarn('No faces were detected.')
                self.facePos = self.defaultLookatPoint
        else:
            rospy.logwarn('Not connected to the face server, cannot follow faces.')
            self.facePos = self.defaultLookatPoint

    ## Callback function for receiving gaze commands
    def do_gaze_action(self, command):
        #command = goal.action;
        if (self.doNotInterrupt.count(self.currentGazeAction) == 0):
            if (self.currentGazeAction != command or command == 'LOOK_AT_POINT'):
                self.isActionComplete = False
                if (command == 'LOOK_FORWARD'):
                    self.targetLookatPoint = self.defaultLookatPoint
                elif (command == 'LOOK_DOWN'):
                    self.targetLookatPoint = self.downLookatPoint
                elif (command == 'NOD'):
                    self.nNods = 5
                    self.startNod()
                elif (command == 'SHAKE'):
                    self.nShakes = 5
                    self.startShake()
                elif (command == 'NOD_ONCE'):
                    self.nNods = 5
                    self.startNod()
                elif (command == 'SHAKE_ONCE'):
                    self.nShakes = 5
                    self.startShake()
                elif (command == 'GLANCE_RIGHT_EE'):
                    self.startGlance(0)
                elif (command == 'GLANCE_LEFT_EE'):
                    self.startGlance(1)
                elif (command == 'LOOK_AT_POINT'):
                    self.targetLookatPoint = goal.point
                rospy.loginfo('\tSetting gaze action to: ' +
                        command)
                self.currentGazeAction = command

                while (not self.isActionComplete):
                    time.sleep(0.1)

    def isTheSame(self, current, target):
        diff = target - current
        dist = linalg.norm(diff)
        return (dist<0.0001)

    def filterLookatPosition(self, current, target):
        speed = 0.02
        diff = self.point2array(target) - self.point2array(current)
        dist = linalg.norm(diff)
        if (dist>speed):
            step = dist/speed
            return self.array2point(self.point2array(current) + diff/step)
        else:
            return target

    def startNod(self):
        self.prevTargetLookatPoint = self.targetLookatPoint
        self.prevGazeAction = str(self.currentGazeAction)
        self.nodCounter = 0
        self.targetLookatPoint = self.nodPositions[0]

    def startGlance(self, armIndex):
        self.prevTargetLookatPoint = self.targetLookatPoint
        self.prevGazeAction = str(self.currentGazeAction)
        self.glanceCounter = 0
        self.targetLookatPoint = self.getEEPos(armIndex)

    def startShake(self):
        self.prevTargetLookatPoint = self.targetLookatPoint
        self.prevGazeAction = str(self.currentGazeAction)
        self.shakeCounter = 0
        self.targetLookatPoint = self.shakePositions[0]

    def point2array(self, p):
        return array((p.x, p.y, p.z))

    def array2point(self, a):
        return Point(a[0], a[1], a[2])

    def getNextNodPoint(self, current, target):
        if (self.isTheSame(self.point2array(current), self.point2array(target))):
            self.nodCounter += 1
            if (self.nodCounter == self.nNods):
                self.currentGazeAction = self.prevGazeAction
                return self.prevTargetLookatPoint
            else:
                return self.nodPositions[self.nodCounter%2]
        else:
            return target

    def getNextGlancePoint(self, current, target):
        if (self.isTheSame(self.point2array(current), self.point2array(target))):
            self.glanceCounter = 1
            self.currentGazeAction = self.prevGazeAction
            return self.prevTargetLookatPoint
        else:
            return target

    def getNextShakePoint(self, current, target):
        if (self.isTheSame(self.point2array(current), self.point2array(target))):
            self.shakeCounter += 1
            if (self.shakeCounter == self.nNods):
                self.currentGazeAction = self.prevGazeAction
                return self.prevTargetLookatPoint
            else:
                return self.shakePositions[self.shakeCounter%2]
        else:
            return target

    def update(self):

        isActionPossiblyComplete = True
        if (self.currentGazeAction == 'FOLLOW_RIGHT_EE'):
            self.targetLookatPoint = self.getEEPos(0)

        elif (self.currentGazeAction == 'FOLLOW_LEFT_EE'):
            self.targetLookatPoint = self.getEEPos(1)

        elif (self.currentGazeAction == 'FOLLOW_FACE'):
            self.getFaceLocation()
            self.targetLookatPoint = self.facePos

        elif (self.currentGazeAction == 'NOD'):
            self.targetLookatPoint = self.getNextNodPoint(self.currentLookatPoint, self.targetLookatPoint)
            self.headGoal.min_duration = rospy.Duration(0.5)
            isActionPossiblyComplete = False;

        elif (self.currentGazeAction == 'SHAKE'):
            self.targetLookatPoint = self.getNextShakePoint(self.currentLookatPoint, self.targetLookatPoint)
            self.headGoal.min_duration = rospy.Duration(0.5)
            isActionPossiblyComplete = False;

        elif (self.currentGazeAction == 'GLANCE_RIGHT_EE' or self.currentGazeAction == 'GLANCE_LEFT_EE'):
            self.targetLookatPoint = self.getNextGlancePoint(self.currentLookatPoint, self.targetLookatPoint)
            isActionPossiblyComplete = False;

        self.currentLookatPoint = self.filterLookatPosition(self.currentLookatPoint, self.targetLookatPoint)
        if (self.isTheSame(self.point2array(self.headGoal.target.point), self.point2array(self.currentLookatPoint))):
            if (isActionPossiblyComplete):
                if (self.headActionClient.get_state() == GoalStatus.SUCCEEDED):
                    self.isActionComplete = True
        else:
            self.headGoal.target.point = self.currentLookatPoint
            self.headActionClient.send_goal(self.headGoal)

        time.sleep(0.02)
コード例 #20
0
class CardPicker():
    def __init__(self):
        '''
        Initialization class for a Policy

        Parameters
        ----------
        yumi : An instianted yumi robot 
        com : The common class for the robot
        cam : An open bincam class

        debug : bool 

            A bool to indicate whether or not to display a training set point for 
            debuging. 

        '''

        self.robot = hsrb_interface.Robot()

        self.omni_base = self.robot.get('omni_base')
        self.whole_body = self.robot.get('whole_body')

        self.cam = RGBD()
        self.com = COM()

        self.com.go_to_initial_state(self.whole_body)

        self.br = tf.TransformBroadcaster()
        self.tl = TransformListener()
        self.gp = GraspPlanner()

        self.suction = Suction(self.gp, self.cam)

        #thread.start_new_thread(self.ql.run,())
        print "after thread"

    def find_mean_depth(self, d_img):
        '''
        Evaluates the current policy and then executes the motion 
        specified in the the common class
        '''

        indx = np.nonzero(d_img)

        mean = np.mean(d_img[indx])

        return

    def card_pick(self):

        while True:

            c_img = self.cam.read_color_data()
            d_img = self.cam.read_depth_data()
            if (not c_img == None and not d_img == None):

                self.ql = QueryLabeler()
                self.ql.run(c_img)
                data = self.ql.label_data
                del self.ql

                self.suction.find_pick_region(data, c_img, d_img)

                # card_found,cards = self.check_card_found()

                # if(card_found):
                #     self.suction.execute_grasp(cards,self.whole_body)

                # self.com.go_to_initial_state(self.whole_body)

    def check_card_found(self):

        # try:
        transforms = self.tl.getFrameStrings()

        cards = []

        for transform in transforms:
            print transform
            if 'card' in transform:
                print 'got here'
                f_p = self.tl.lookupTransform('head_rgbd_sensor_rgb_frame',
                                              transform, rospy.Time(0))
                cards.append(transform)

        return True, cards
コード例 #21
0
class HandEyeCalibrator(object):
    def __init__(self):

        self._camera_frame = rospy.get_param('%s/camera_frame' % (NODE_NAME, ),
                                             'camera_rgb_optical_frame')
        self._marker_frame = rospy.get_param('%s/marker_frame' % (NODE_NAME, ),
                                             'marker26')
        self._robot_base_frame = rospy.get_param(
            '%s/robot_base_frame' % (NODE_NAME, ), 'world')
        self._ee_frame = rospy.get_param('%s/ee_frame' % (NODE_NAME, ),
                                         'left_arm_7_link')

        self._save_calib_file = rospy.get_param(
            '%s/save_calib_file' % (NODE_NAME, ), 'hand_eye_calib_data.npy')
        self._load_calib_file = rospy.get_param(
            '%s/load_calib_file' % (NODE_NAME, ), 'hand_eye_calib_data.npy')
        self._calib_from_file = rospy.get_param(
            '%s/calibrate_from_file' % (NODE_NAME, ), False)

        rospy.loginfo("Camera frame: %s" % (self._camera_frame, ))
        rospy.loginfo("Marker frame: %s" % (self._marker_frame, ))
        rospy.loginfo("Robot frame: %s" % (self._robot_base_frame, ))
        rospy.loginfo("End-effector frame: %s" % (self._ee_frame, ))
        rospy.loginfo("Calibration filename to save: %s" %
                      (self._save_calib_file, ))
        rospy.loginfo("Calibration filename to load: %s" %
                      (self._load_calib_file, ))
        rospy.loginfo("Calibrate from file: %s" % (self._calib_from_file, ))

        self._camera_base_p = [0.000, 0.022, 0.0]
        self._camera_base_q = [-0.500, 0.500, -0.500, 0.500]

        self._camera_base_transform = self.to_transform_matrix(
            self._camera_base_p, self._camera_base_q)

        self._calib = HandEyeCalib()

        self._br = tf.TransformBroadcaster()
        self._tf = TransformListener()

    def broadcast_frame(self, pt, rot, frame_name="marker"):

        rot = np.append(rot, [[0, 0, 0]], 0)
        rot = np.append(rot, [[0], [0], [0], [1]], 1)
        quat = tuple(tf.transformations.quaternion_from_matrix(rot))
        now = rospy.Time.now()
        self._br.sendTransform((pt[0], pt[1], pt[2]),
                               tf.transformations.quaternion_from_matrix(rot),
                               now, frame_name, 'base')
        print("should have done it!")

    def get_transform(self, base_frame, source_frame):

        if base_frame == source_frame:
            return (0, 0, 0), (0, 0, 0, 1), rospy.Time.now()

        # t = (0,0,0)
        # q = (0,0,0,1)
        time = None
        while time is None:
            try:

                time = self._tf.getLatestCommonTime(source_frame, base_frame)
            except:
                rospy.loginfo(
                    "Failed to get common time between %s and %s. Trying again..."
                    % (
                        source_frame,
                        base_frame,
                    ))

        t = None
        q = None
        try:
            t, q = self._tf.lookupTransform(
                base_frame, source_frame, time
            )  #self._tf_buffer.lookup_transform(frame_name, base_frame, rospy.Time(0), rospy.Duration(5.0))

        except (tf.LookupException, tf.ConnectivityException,
                tf.ExtrapolationException):
            rospy.logerr("Transform could not be queried.")

            return (0, 0, 0), (0, 0, 0, 1), rospy.Time.now()

        translation = (t[0], t[1], t[2])
        quaternion = (q[0], q[1], q[2], q[3])
        # translation = (t.transform.translation.x, t.transform.translation.y, t.transform.translation.z)
        # quaternion = (t.transform.rotation.x, t.transform.rotation.y, t.transform.rotation.z, t.transform.rotation.w)

        return translation, quaternion, time

    def to_transform_matrix(self, t, q):

        t_mat = tf.transformations.translation_matrix(t)
        r_mat = tf.transformations.quaternion_matrix(q)
        transform_mat = np.dot(t_mat, r_mat)

        return transform_mat

    def to_euler(self, transform):
        return np.asarray(tf.transformations.euler_from_matrix(transform))

    def to_translation(self, transform):

        return np.array(transform[:3, 3])

    def calibrate_from_file(self):

        calib_data = np.load(self._load_calib_file).item()

        camera_poses = calib_data['camera_poses']
        ee_poses = calib_data['ee_poses']

        for i in range(len(camera_poses)):
            self._calib.add_measurement(ee_poses[i], camera_poses[i])

        hand_eye_transform = self._calib.calibrate()
        hand_eye_transform = np.matmul(
            hand_eye_transform, np.linalg.inv(self._camera_base_transform))
        print 'Hand-eye transform: ', hand_eye_transform
        translation = self.to_translation(hand_eye_transform)
        euler = self.to_euler(hand_eye_transform)
        print "XYZ:", translation
        print "RPY: ", euler

        # calib_data = {'hand_eye_transform':  {'matrix': hand_eye_transform,
        #                                       'xyz': translation,
        #                                       'rpy': euler},
        #               'camera_poses': self._calib._camera_poses,
        #                'ee_poses': self._calib._ee_poses}
        # np.save('hand_eye_calibration_right.npy', calib_data)

    def calibrate(self):
        from getch import getch
        calibrate = False
        print(
            "Press enter to record to next. Add/Remove/Calibrate/Help? (a/r/c/h)"
        )
        while not calibrate:

            r = getch()

            if r == 'a':
                camera_t, camera_q, _ = self.get_transform(
                    self._camera_frame, self._marker_frame)
                ee_t, ee_q, _ = self.get_transform(self._robot_base_frame,
                                                   self._ee_frame)

                camera_transform = self.to_transform_matrix(camera_t, camera_q)
                ee_transform = self.to_transform_matrix(ee_t, ee_q)
                print "------------%d Poses---------------" % (len(
                    self._calib._ee_poses), )
                print "Camera transform: ", camera_t, camera_q
                print "Hand transform: ", ee_t, ee_q
                print "---------------------------------"
                self._calib.add_measurement(ee_transform, camera_transform)
                print 'Transform has been added for calibration'
            elif r == 'c':
                calibrate = True
            elif r == 'h':
                print(
                    "Press enter to record to next. Add/Remove/Calibrate? (a/r/c/h)"
                )
            elif r == 'r':
                if len(self._calib._ee_poses) > 0:
                    del self._calib._ee_poses[-1]
                    del self._calib._camera_poses[-1]
                    print("Removed last pose")
                else:
                    print("Pose list already empty.")

            elif r in ['\x1b', '\x03']:
                rospy.signal_shutdown("Acquisition finished.")
                break

        if calibrate:
            hand_eye_transform = self._calib.calibrate()

            hand_eye_transform = np.matmul(
                hand_eye_transform, np.linalg.inv(self._camera_base_transform))
            print "Found Transform: ", hand_eye_transform

            translation = self.to_translation(hand_eye_transform)
            euler = self.to_euler(hand_eye_transform)
            print "XYZ:", translation
            print "RPY: ", euler

            calib_data = {
                'hand_eye_transform': {
                    'matrix': hand_eye_transform,
                    'xyz': translation,
                    'rpy': euler
                },
                'camera_poses': self._calib._camera_poses,
                'ee_poses': self._calib._ee_poses
            }

            np.save('hand_eye_calibration_right.npy', calib_data)
            np.save(self._save_calib_file, calib_data)
        else:
            print("Quiting. Bye!")
コード例 #22
0
class mapping():
    def __init__(self):
        self.node_name = rospy.get_name()
        self.tf = TransformListener()
        self.transformer = TransformerROS()
        rospy.loginfo("[%s] Initializing " % (self.node_name))
        #rospy.Subscriber("/pcl_points", PoseArray, self.call_back, queue_size=1, buff_size = 2**24)
        sub_pcl = message_filters.Subscriber("/pcl_points", PoseArray)
        sub_odom = message_filters.Subscriber("/odometry/ground_truth",
                                              Odometry)
        ats = ApproximateTimeSynchronizer((sub_pcl, sub_odom),
                                          queue_size=1,
                                          slop=0.1)
        ats.registerCallback(self.call_back)
        rospy.Subscriber("/move_base_simple/goal",
                         PoseStamped,
                         self.cb_new_goal,
                         queue_size=1)
        self.pub_map = rospy.Publisher('/local_map',
                                       OccupancyGrid,
                                       queue_size=1)
        self.pub_rviz = rospy.Publisher("/wp_line", Marker, queue_size=1)
        self.pub_poses = rospy.Publisher("/path_points",
                                         PoseArray,
                                         queue_size=1)
        self.resolution = 0.25
        self.robot = Pose()
        self.width = 200
        self.height = 200
        self.origin = Pose()
        self.local_map = OccupancyGrid()
        self.dilating_size = 6
        self.wall_width = 3
        self.start_planning = False
        self.transpose_matrix = None
        self.goal = []
        self.astar = AStar()
        self.msg_count = 0
        self.planning_range = 20
        self.frame_id = "map"

    def init_param(self):
        self.occupancygrid = np.zeros((self.height, self.width))
        self.local_map = OccupancyGrid()
        self.local_map.info.resolution = self.resolution
        self.local_map.info.width = self.width
        self.local_map.info.height = self.height
        self.origin.position.x = -self.width * self.resolution / 2. + self.robot.position.x
        self.origin.position.y = -self.height * self.resolution / 2. + self.robot.position.y
        self.local_map.info.origin = self.origin

    def cb_rviz(self, msg):
        self.click_pt = [msg.pose.position.x, msg.pose.position.y]
        self.publish_topic()

    def call_back(self, pcl_msg, odom_msg):
        self.robot = odom_msg.pose.pose
        self.msg_count = self.msg_count + 1
        self.init_param()
        self.local_map.header = pcl_msg.header
        self.local_map.header.frame_id = self.frame_id
        self.get_tf()
        if self.transpose_matrix is None:
            return
        for i in range(len(pcl_msg.poses)):
            p = (pcl_msg.poses[i].position.x, pcl_msg.poses[i].position.y,
                 pcl_msg.poses[i].position.z, 1)
            local_p = np.array(p)
            global_p = np.dot(self.transpose_matrix, local_p)
            x, y = self.map2occupancygrid(global_p)
            width_in_range = (x >= self.width - self.dilating_size
                              or x <= self.dilating_size)
            height_in_range = (y >= self.height - self.dilating_size
                               or y <= self.dilating_size)
            if width_in_range or height_in_range:
                continue  # To prevent point cloud range over occupancy grid range
            self.occupancygrid[y][x] = 100

        # map dilating
        for i in range(self.height):
            for j in range(self.width):
                if self.occupancygrid[i][j] == 100:
                    for m in range(-self.dilating_size,
                                   self.dilating_size + 1):
                        for n in range(-self.dilating_size,
                                       self.dilating_size + 1):
                            if self.occupancygrid[i + m][j + n] != 100:
                                if m > self.wall_width or m < -self.wall_width or n > self.wall_width or n < -self.wall_width:
                                    if self.occupancygrid[i + m][j + n] != 90:
                                        self.occupancygrid[i + m][j + n] = 50
                                else:
                                    self.occupancygrid[i + m][j + n] = 90

        for i in range(self.height):
            for j in range(self.width):
                self.local_map.data.append(self.occupancygrid[i][j])
        self.pub_map.publish(self.local_map)

        if self.start_planning:
            self.path_planning()

    def get_tf(self):
        try:
            position, quaternion = self.tf.lookupTransform(
                "/map", "/X1/front_laser", rospy.Time(0))
            self.transpose_matrix = self.transformer.fromTranslationRotation(
                position, quaternion)
        except (LookupException, ConnectivityException,
                ExtrapolationException):
            print("Nothing Happen")

    def path_planning(self):
        if self.msg_count % 5 != 0:
            return
        self.msg_count = 0
        cost_map = np.zeros((self.height, self.width))
        border = self.planning_range / self.resolution
        h_min = int((self.height - border) / 2.)
        h_max = int(self.height - (self.height - border) / 2.)
        w_min = int((self.height - border) / 2.)
        w_max = int(self.width - (self.width - border) / 2.)
        for i in range(self.width):
            for j in range(self.width):
                if i > h_min and i < h_max:
                    if j > w_min and j < w_max:
                        cost_map[i][j] = self.occupancygrid[i][j]
        start_point = self.map2occupancygrid(
            (self.robot.position.x, self.robot.position.y))
        start = (start_point[1], start_point[0])
        goal = self.map2occupancygrid(self.goal)
        end = (goal[1], goal[0])
        self.astar.initial(cost_map, start, end)
        path = self.astar.planning()
        self.pub_path(path)
        self.rviz(path)

    def cb_new_goal(self, p):
        self.goal = [p.pose.position.x, p.pose.position.y]
        self.start_planning = True

    def occupancygrid2map(self, p):
        x = p[
            0] * self.resolution + self.origin.position.x + self.resolution / 2.
        y = p[
            1] * self.resolution + self.origin.position.y + self.resolution / 2.
        return [x, y]

    def map2occupancygrid(self, p):
        x = int((p[0] - self.origin.position.x) / self.resolution)
        y = int((p[1] - self.origin.position.y) / self.resolution)
        return [x, y]

    def pub_path(self, path):
        poses = PoseArray()
        for i in range(len(path)):
            p = self.occupancygrid2map([path[i][1], path[i][0]])
            pose = Pose()
            pose.position.x = p[0]
            pose.position.y = p[1]
            pose.position.z = 0
            poses.poses.append(pose)
        self.pub_poses.publish(poses)

    def rviz(self, path):
        marker = Marker()
        marker.header.frame_id = self.frame_id
        marker.type = marker.LINE_STRIP
        marker.action = marker.ADD
        marker.scale.x = 0.3
        marker.scale.y = 0.3
        marker.scale.z = 0.3
        marker.color.a = 1.0
        marker.color.r = 1.0
        marker.color.g = 0.
        marker.color.b = 0.
        marker.pose.orientation.x = 0.0
        marker.pose.orientation.y = 0.0
        marker.pose.orientation.z = 0.0
        marker.pose.orientation.w = 1.0
        marker.pose.position.x = 0.0
        marker.pose.position.y = 0.0
        marker.pose.position.z = 0.0
        marker.points = []
        for i in range(len(path)):
            p = self.occupancygrid2map([path[i][1], path[i][0]])
            point = Point()
            point.x = p[0]
            point.y = p[1]
            point.z = 0
            marker.points.append(point)
        self.pub_rviz.publish(marker)
コード例 #23
0
ファイル: Kinova.py プロジェクト: rafaelpossas/kinova-ros
class KinovaUtilities(object):

    JOINT_1_MIN_MAX = (-3.14, 3.14)
    JOINT_2_MIN_MAX = (0.82, 5.46)
    JOINT_3_MIN_MAX = (0.33, 5.95)
    JOINT_4_MIN_MAX = (-3.14, 3.14)
    JOINT_5_MIN_MAX = (-3.14, 3.14)
    JOINT_6_MIN_MAX = (-3.14, 3.14)

    JOINT_4_OFFSET = 6.28325902769
    JOINT_5_OFFSET = -18.8241170548
    JOINT_6_OFFSET = 18.8293733406

    CUBE_GZ_NAME = "cube"

    X_CUBE_MIN = 0.76
    X_CUBE_MAX = 1.03

    Y_CUBE_MIN = 0.55
    Y_CUBE_MAX = 1.05

    def __init__(self):
        super(KinovaUtilities, self).__init__()
        ## First initialize `moveit_commander`_ and a `rospy`_ node:
        moveit_commander.roscpp_initialize(sys.argv)
        rospy.init_node('Kinova_Utilities', anonymous=True)

        ## Instantiate a `RobotCommander`_ object. This object is the outer-level interface to
        ## the robot:
        self.robot = moveit_commander.RobotCommander()

        group_names = self.robot.get_group_names()
        print "============ Robot Groups:", self.robot.get_group_names()

        ## Instantiate a `PlanningSceneInterface`_ object.  This object is an interface
        ## to the world surrounding the robot:
        self.scene = moveit_commander.PlanningSceneInterface()
        self.box_name = "cube"

        ## Instantiate a `MoveGroupCommander`_ object.  This object is an interface
        ## to one group of joints.  In this case the group is the joints in the Panda
        ## arm so we set ``group_name = panda_arm``. If you are using a different robot,
        ## you should change this value to the name of your robot arm planning group.
        ## This interface can be used to plan and execute motions on the Panda:

        self.arm_group_name = "Arm"
        self.arm_group = moveit_commander.MoveGroupCommander(self.arm_group_name)
        print "============ Printing arm joint values"
        #print self.arm_group.get_current_joint_values()

        self.gripper_group_name = "All"
        self.gripper_group = moveit_commander.MoveGroupCommander(self.gripper_group_name)
        print "============ Printing gripper joint values"
        #print self.gripper_group.get_current_joint_values()

        # Sometimes for debugging it is useful to print the entire state of the
        # robot:
        print "============ Printing robot state"
        print self.robot.get_current_state()
        print ""

        current_pose = self.arm_group.get_current_pose()
        print "============ Current Pose"
        print current_pose
        print ""

        # aruco_pose = rospy.wait_for_message('/aruco_single/pose', PoseStamped)
        # rospy.loginfo("Got: " + str(aruco_pose))
        #self.return_home_position()

        self.tf = TransformListener()

        rate = rospy.Rate(10.0)




        #print trans

        # rand_x = random.uniform(self.X_CUBE_MIN, self.X_CUBE_MAX)
        # rand_y = random.uniform(self.Y_CUBE_MIN, self.Y_CUBE_MAX)
        #
        # self.delete_gazebo_object(self.CUBE_GZ_NAME)
        # self.spawn_gazebo_object(x=rand_x, y=rand_y, model_name=self.CUBE_GZ_NAME)
        #
        try:
            self.tf.waitForTransform("/world", "/tag_0", rospy.Time(), rospy.Duration(4))
            now = rospy.Time(0)
            (trans, rot) = self.tf.lookupTransform("/world", "/tag_0", now)
            self.add_rviz_object(self.CUBE_GZ_NAME, trans, rot)
        except TransformException, e:
            rospy.logerr("Could not find the TAG: {0}".format(e))


        #self.add_object("cube", trans,rot)

        # tag_pos = geometry_msgs.msg.PoseStamped()
        # tag_pos.header.frame_id = "tag_0"
        # tag_pos.pose.orientation.w = 1.0
        # start_pos_manual = self.listener.transformPose("world", tag_pos)
        # #
        # rospy.loginfo("Pose via manual TF is: ")
        # rospy.loginfo(start_pos_manual)
        #
        # self.return_home_position()
        self.pre_grasp_face_4(trans)

        # self.return_home_position()
        # self.pre_grasp_face_2(trans)
        # # #
        # self.return_home_position()
        # self.pre_grasp_face_1(trans)

        # self.return_home_position()
        try:
            self.joint_planning()
        except moveit_commander.MoveItCommanderException, e:
            print(e)
コード例 #24
0
ファイル: bad_controller_Uni.py プロジェクト: gnunoe/Cf_ROS
class Controller():
    Manual = 0
    Automatic = 1
    TakeOff = 2

    def __init__(self):
        self.pubNav = rospy.Publisher('cmd_vel', Twist, queue_size=1)
        self.listener = TransformListener()
        rospy.Subscriber("joy", Joy, self._joyChanged)
        rospy.Subscriber("cmd_vel_telop", Twist, self._cmdVelTelopChanged)
        self.cmd_vel_telop = Twist()
        self.pidX = PID(20, 12, 0.0, -30, 30, "x")
        self.pidY = PID(-20, -12, 0.0, -30, 30, "y")
        self.pidZ = PID(15000, 3000.0, 1500.0, 10000, 60000, "z")
        self.pidYaw = PID(-50.0, 0.0, 0.0, -200.0, 200.0, "yaw")
        self.state = Controller.Manual
        self.targetZ = 0.5
        self.lastJoy = Joy()

    def _cmdVelTelopChanged(self, data):
        self.cmd_vel_telop = data
        if self.state == Controller.Manual:
            self.pubNav.publish(data)

    def pidReset(self):
        self.pidX.reset()
        self.pidZ.reset()
        self.pidZ.reset()
        self.pidYaw.reset()

    def _joyChanged(self, data):
        if len(data.buttons) == len(self.lastJoy.buttons):
            delta = np.array(data.buttons) - np.array(self.lastJoy.buttons)
            print ("Buton ok")
            #Button 1
            if delta[0] == 1 and self.state != Controller.Automatic:
                print("Automatic!")
                thrust = self.cmd_vel_telop.linear.z
                print(thrust)
                self.pidReset()
                self.pidZ.integral = thrust / self.pidZ.ki
                self.targetZ = 0.5
                self.state = Controller.Automatic
            #Button 2
            if delta[1] == 1 and self.state != Controller.Manual:
                print("Manual!")
                self.pubNav.publish(self.cmd_vel_telop)
                self.state = Controller.Manual
            #Button 3
            if delta[2] == 1:
                self.state = Controller.TakeOff
                print("TakeOff!")
            #Button 5
            if delta[4] == 1:
                self.targetZ += 0.1
                print(self.targetZ)
            #Button 6
            if delta[5] == 1:
                self.targetZ -= 0.1
                print(self.targetZ)
        self.lastJoy = data

    def run(self):
        thrust = 0
        print("jello")
        while not rospy.is_shutdown():
            if self.state == Controller.TakeOff:
                t = self.listener.getLatestCommonTime("/mocap", "/Nano_Mark")
                if self.listener.canTransform("/mocap", "/Nano_Mark", t):
                    position, quaternion = self.listener.lookupTransform("/mocap", "/Nano_Mark", t)

                    if position[2] > 0.1 or thrust > 50000:
                        self.pidReset()
                        self.pidZ.integral = thrust / self.pidZ.ki
                        self.targetZ = 0.5
                        self.state = Controller.Automatic
                        thrust = 0
                    else:
                        thrust += 100
                        msg = self.cmd_vel_telop
                        msg.linear.z = thrust
                        self.pubNav.publish(msg)

            if self.state == Controller.Automatic:
                # transform target world coordinates into local coordinates
                t = self.listener.getLatestCommonTime("/Nano_Mark", "/mocap")
                print(t);
                if self.listener.canTransform("/Nano_Mark", "/mocap", t):
                    targetWorld = PoseStamped()
                    targetWorld.header.stamp = t
                    targetWorld.header.frame_id = "mocap"
                    targetWorld.pose.position.x = 0
                    targetWorld.pose.position.y = 0
                    targetWorld.pose.position.z = self.targetZ
                    quaternion = tf.transformations.quaternion_from_euler(0, 0, 0)
                    targetWorld.pose.orientation.x = quaternion[0]
                    targetWorld.pose.orientation.y = quaternion[1]
                    targetWorld.pose.orientation.z = quaternion[2]
                    targetWorld.pose.orientation.w = quaternion[3]

                    targetDrone = self.listener.transformPose("/Nano_Mark", targetWorld)

                    quaternion = (
                        targetDrone.pose.orientation.x,
                        targetDrone.pose.orientation.y,
                        targetDrone.pose.orientation.z,
                        targetDrone.pose.orientation.w)
                    euler = tf.transformations.euler_from_quaternion(quaternion)

                    #msg = self.cmd_vel_teleop
                    msg.linear.x = self.pidX.update(0.0, targetDrone.pose.position.x)
                    msg.linear.y = self.pidY.update(0.0, targetDrone.pose.position.y)
                    msg.linear.z = self.pidZ.update(0.0, targetDrone.pose.position.z) #self.pidZ.update(position[2], self.targetZ)
                    msg.angular.z = self.pidYaw.update(0.0, euler[2])
                    #print(euler[2])
                    #print(msg.angular.z)
                    self.pubNav.publish(msg)

            rospy.sleep(0.01)
コード例 #25
0
class ur5_grasp_project(object):
    def __init__(self, joint_values=None):
        rospy.init_node('command_GGCNN_ur5')
        self.joint_values_home = joint_values

        self.tf = TransformListener()

        # Used to change the controller
        self.controller_switch = rospy.ServiceProxy(
            '/controller_manager/switch_controller', SwitchController)

        # actionClient used to send joint positions
        self.client = actionlib.SimpleActionClient(
            'pos_based_pos_traj_controller/follow_joint_trajectory',
            FollowJointTrajectoryAction)
        print("Waiting for server (pos_based_pos_traj_controller)...")
        self.client.wait_for_server()
        print("Connected to server (pos_based_pos_traj_controller)")

        #################
        # GGCNN Related
        #################
        self.d = None
        self.ori_ = None
        self.grasp_cartesian_pose = None
        self.posCB = []
        self.ori = []
        self.gripper_angle_grasp = 0.0
        self.final_orientation = 0.0

        # These offsets are used only in the real robot and need to be calibrated
        self.GGCNN_offset_x = -0.03  # 0.002
        self.GGCNN_offset_y = 0.02  # -0.05
        self.GGCNN_offset_z = 0.058  # 0.013

        self.robotiq_joint_name = rospy.get_param("/robotiq_joint_name")

        # Topic published from GG-CNN Node
        rospy.Subscriber('ggcnn/out/command',
                         Float32MultiArray,
                         self.ggcnn_command_callback,
                         queue_size=1)

        ####################
        # Pipeline Related #
        ####################
        self.classes = rospy.get_param("/classes")
        self.grasp_ready_flag = False
        self.detected_tags = []
        self.tags = [
            'tag_0_corrected', 'tag_1_corrected', 'tag_2_corrected',
            'tag_3_corrected', 'tag_4_corrected', 'tag_5_corrected',
            'tag_6_corrected', 'tag_7_corrected'
        ]

        # These offset for the real camera
        self.tags_position_offset = [0.062, 0.0, 0.062]

        # Subscribers - Topics related to the new grasping pipeline
        rospy.Subscriber('flags/grasp_ready',
                         Bool,
                         self.grasp_ready_callback,
                         queue_size=1)  # Grasp flag
        rospy.Subscriber('flags/reposition_robot_flag',
                         Bool,
                         self.reposition_robot_callback,
                         queue_size=1)  # Reposition flag
        rospy.Subscriber('flags/detection_ready',
                         Bool,
                         self.detection_ready_callback,
                         queue_size=1)  # Detection flag
        rospy.Subscriber('reposition_coord',
                         Float32MultiArray,
                         self.reposition_coord_callback,
                         queue_size=1)
        rospy.Subscriber('/selective_grasping/tag_detections',
                         Int16MultiArray,
                         self.tags_callback,
                         queue_size=1)

        # Publishers
        # Publish the required class so the other nodes such as gg-cnn generates the grasp to the selected part
        self.required_class = rospy.Publisher('pipeline/required_class',
                                              Int8,
                                              queue_size=1)

    def turn_velocity_controller_on(self):
        self.controller_switch(['joint_group_vel_controller'],
                               ['pos_based_pos_traj_controller'], 1)

    def turn_position_controller_on(self):
        self.controller_switch(['pos_based_pos_traj_controller'],
                               ['joint_group_vel_controller'], 1)

    def turn_gripper_velocity_controller_on(self):
        self.controller_switch(['gripper_controller_vel'],
                               ['gripper_controller_pos'], 1)

    def turn_gripper_position_controller_on(self):
        self.controller_switch(['gripper_controller_pos'],
                               ['gripper_controller_vel'], 1)

    def tags_callback(self, msg):
        self.detected_tags = msg.data

    def grasp_ready_callback(self, msg):
        self.grasp_ready_flag = msg.data

    def detection_ready_callback(self, msg):
        self.detection_ready_flag = msg.data

    def reposition_robot_callback(self, msg):
        self.reposition_robot_flag = msg.data

    def reposition_coord_callback(self, msg):
        self.reposition_coords = msg.data

    def ur5_actual_position_callback(self, joint_values_from_ur5):
        """Get UR5 joint angles
		
		The joint states published by /joint_states of the UR5 robot are in wrong order.
		/joint_states topic normally publishes the joint in the following order:
		[elbow_joint, shoulder_lift_joint, shoulder_pan_joint, wrist_1_joint, wrist_2_joint, wrist_3_joint]
		But the correct order of the joints that must be sent to the robot is:
		['shoulder_pan_joint', 'shoulder_lift_joint', 'elbow_joint', 'wrist_1_joint', 'wrist_2_joint', 'wrist_3_joint']
		
		Arguments:
			joint_values_from_ur5 {list} -- Actual angles of the UR5 Robot
		"""
        self.th3, self.th2, self.th1, self.th4, self.th5, self.th6 = joint_values_from_ur5.position
        self.actual_position = [
            self.th1, self.th2, self.th3, self.th4, self.th5, self.th6
        ]

    def genCommand(self, char, command, pos=None):
        """
		Update the command according to the character entered by the user.
		"""
        if char == 'a':
            # command = outputMsg.Robotiq2FGripper_robot_output();
            command.rACT = 1  # Gripper activation
            command.rGTO = 1  # Go to position request
            command.rSP = 255  # Speed
            command.rFR = 150  # Force

        if char == 'r':
            command.rACT = 0

        if char == 'c':
            command.rACT = 1
            command.rGTO = 1
            command.rATR = 0
            command.rPR = 255
            command.rSP = 40
            command.rFR = 150

        # @param pos Gripper width in meters. [0, 0.087]
        if char == 'p':
            command.rACT = 1
            command.rGTO = 1
            command.rATR = 0
            command.rPR = int(
                np.clip(
                    (13. - 230.) / self.gripper_max_width * self.ori + 230., 0,
                    255))
            command.rSP = 40
            command.rFR = 150

        if char == 'o':
            command.rACT = 1
            command.rGTO = 1
            command.rATR = 0
            command.rPR = 0
            command.rSP = 40
            command.rFR = 150

        return command

    def command_gripper(self, action):
        command = outputMsg.Robotiq2FGripper_robot_output()
        command = self.genCommand(action, command)
        self.pub_gripper_command.publish(command)

    def ggcnn_command_callback(self, msg):
        """
		GGCNN Command Subscriber Callback
		"""
        self.tf.waitForTransform("base_link", "object_detected", rospy.Time(0),
                                 rospy.Duration(4.0))  # rospy.Time.now()
        object_pose, object_ori = self.tf.lookupTransform(
            "base_link", "object_detected", rospy.Time(0))
        self.d = list(msg.data)
        object_pose[0] += self.GGCNN_offset_x
        object_pose[1] += self.GGCNN_offset_y
        object_pose[2] += self.GGCNN_offset_z

        self.posCB = object_pose

        self.ori = self.d[3]
        br = TransformBroadcaster()
        br.sendTransform((object_pose[0], object_pose[1], object_pose[2]),
                         quaternion_from_euler(0.0, 0.0, self.ori),
                         rospy.Time.now(), "object_link", "base_link")

    def all_close(self, goal, tolerance=0.00005):
        """Wait until goal is reached in configuration space
		
		This method check if the robot reached goal position since wait_for_result seems to be broken
		Arguments:
			goal {[list]} -- Goal in configuration space (joint values)
		
		Keyword Arguments:
			tolerance {number} -- Minimum error allowed to consider the trajectory completed (default: {0.00005})
		"""

        error = np.sum([(self.actual_position[i] - goal[i])**2
                        for i in range(6)])
        print("> Waiting for the trajectory to finish...")
        while not rospy.is_shutdown() and error > tolerance:
            error = np.sum([(self.actual_position[i] - goal[i])**2
                            for i in range(6)])
        if error < tolerance:
            print(
                "> Trajectory Suceeded!\n")  # whithin the tolerance specified
        else:
            rospy.logerr("> Trajectory aborted.")

    def traj_planner(self,
                     grasp_position,
                     grasp_step='move',
                     way_points_number=10,
                     movement='slow'):
        """Quintic Trajectory Planner
	
		Publish a trajectory to UR5 using quintic splines. 

		Arguments:
			grasp_position {[float]} -- Grasp position [x, y, z]

		Keyword Arguments:
			grasp_step {str} -- Set UR5 movement type (default: {'move'})
			way_points_number {number} -- Number of points considered in trajectory (default: {10})
			movement {str} -- Movement speed (default: {'slow'})
		"""
        if grasp_step == 'pregrasp':
            # we need to take a 'screenshot' of the variables at this specific time
            self.grasp_cartesian_pose = deepcopy(self.posCB)
            self.ori_ = deepcopy(self.ori)

        grasp_cartesian_pose = self.grasp_cartesian_pose
        posCB = self.posCB
        ori = self.ori_
        actual_position = self.actual_position
        d = self.d

        status, goal, joint_pos = IK_TRAJ.traj_planner(
            grasp_position, grasp_step, way_points_number, movement,
            grasp_cartesian_pose, ori, d, actual_position)
        if status:
            self.client.send_goal(goal)
            self.all_close(joint_pos)
        else:
            print("Could not retrieve any IK solution")

    def move_on_shutdown(self):
        self.client.cancel_goal()
        self.client_gripper.cancel_goal()
        print("Shutting down node...")

    def grasp_main(self, point_init_home, depth_shot_point):
        random_classes = [i for i in range(len(self.classes))]

        bin_location = [[-0.65, -0.1, 0.2], [-0.65, 0.1, 0.2]]
        garbage_location = [-0.4, -0.30, 0.10]

        raw_input('=== Press enter to start the grasping process')
        while not rospy.is_shutdown():
            # The grasp is performed randomly and the chosen object is published to
            # the detection node
            if not len(random_classes):
                print(
                    "\n> IMPORTANT! There is no object remaining in the object's picking list. Resetting the objects list...\n"
                )
                random_classes = [i for i in range(len(self.classes))]

            random_object_id = random.sample(random_classes, 1)[0]
            random_classes.pop(random_classes.index(random_object_id))
            print('> Object to pick: ', self.classes[random_object_id])

            # Publish the required class ID so the other nodes such as gg-cnn
            # generates the grasp to the selected part
            self.required_class.publish(random_object_id)

            raw_input("==== Press enter to start the grasping process!")
            if self.detection_ready_flag:
                # Check if the robot needs to be repositioned to reach the object. This flag is published
                # By the detection node. The offset coordinates (self.reposition_coords) are also published
                # by the detection node
                if self.reposition_robot_flag:
                    print('> Repositioning robot...')
                    self.tf.waitForTransform("base_link", "grasping_link",
                                             rospy.Time.now(),
                                             rospy.Duration(4.0))
                    eef_pose, _ = self.tf.lookupTransform(
                        "base_link", "grasping_link", rospy.Time(0))

                    corrected_position = [
                        eef_pose[0] - self.reposition_coords[1],
                        eef_pose[1] + self.reposition_coords[0], eef_pose[2]
                    ]

                    self.traj_planner(corrected_position, movement='fast')
                    raw_input("==== Press enter when the trajectory finishes!")

                # Check if:
                # - The run_ggcn is ready (through grasp_ready_flag);
                # - The detection node is ready (through detection_ready_flag);
                # - The robot does not need to be repositioned (through reposition_robot_flag)
                if self.grasp_ready_flag and self.detection_ready_flag and not self.reposition_robot_flag:
                    raw_input("Move to the pre grasp position")
                    print('> Moving to the grasping position... \n')
                    self.traj_planner([], 'pregrasp', movement='fast')

                    raw_input("Move the gripper")
                    # It closes the gripper a little before approaching the object
                    # to prevent colliding with other objects
                    self.command_gripper('p')

                    raw_input("Move to the grasp position")
                    # Moving the robot to pick the object - BE CAREFULL!
                    self.traj_planner([], 'grasp', movement='slow')

                    raw_input("==== Press enter to close the gripper!")
                    print("Picking object...")
                    self.command_gripper('c')

                    # After a collision is detected, the arm will start the picking action
                    # Different locations were adopted because the camera field of view is not big enough
                    # to detect all the april tags in the environment
                    raw_input("==== Press enter to move the object to the bin")
                    if random_object_id < 5:
                        self.traj_planner(bin_location[0], movement='fast')
                    else:
                        self.traj_planner(bin_location[1], movement='fast')

                    rospy.sleep(2.0)  # waiting for the tag detections

                    selected_tag_status = self.detected_tags[random_object_id]
                    print('selected tag: ', self.tags[random_object_id])
                    # Check if the tag corresponding to the object ID was identified in order to
                    # move the object there
                    if selected_tag_status:
                        self.tf.waitForTransform(
                            "base_link", self.tags[random_object_id],
                            rospy.Time(0),
                            rospy.Duration(2.0))  # rospy.Time.now()
                        ptFinal, oriFinal = self.tf.lookupTransform(
                            "base_link", self.tags[random_object_id],
                            rospy.Time(0))
                        ptFinal = [
                            ptFinal[i] + self.tags_position_offset[i]
                            for i in range(3)
                        ]
                        raw_input("==== Move to the tag")
                        pt_inter = deepcopy(ptFinal)
                        # pt_inter adds 0.1m to the Z coordinate of ptFinal in order to
                        # approach the box before leaving the object there
                        pt_inter[-1] += 0.1
                        self.traj_planner(pt_inter, movement='fast')
                        self.traj_planner(ptFinal, movement='fast')
                    else:
                        # In this case, the camera identifies some other tag but not the tag corresponding to the object
                        print(
                            '> Could not find the box tag. Placing the object anywhere \n'
                        )
                        raw_input('=== Pres enter to proceed')
                        self.traj_planner(garbage_location, movement='fast')

                    print("Placing object...")
                    # After the bin location is reached, the robot will place the object and move back
                    # to the initial position
                    self.command_gripper('o')

                    print("> Moving back to home position...\n")
                    self.traj_planner(point_init_home, movement='fast')
                    self.traj_planner(depth_shot_point, movement='slow')
                    print('> Grasping finished \n')
                else:
                    print('> The requested object could not be grasped! \n')
                    self.traj_planner(depth_shot_point, movement='fast')

            else:
                print('> The requested object was not detected! \n')
コード例 #26
0
class PickAndPlace(object):
    def __init__(self, limb, start_pose, hover_distance=0.15):
        self.start_pose = start_pose
        self.hover_distance = hover_distance
        self.limb = robot_limb.Limb(limb)
        self.gripper = robot_gripper.Gripper(limb)
        self.base = "base_marker"
        self.pick_obj = "obj_marker"
        self.dest = "dest_marker"
        self.destinations = []
        self.queue = Queue.Queue()
        self.tf = TransformListener()
        self.set_scene()
        self.set_limb_planner()
        self.enable_robot()
        self.set_destinations()
        print("Moving Sawyer Arm to Start Position")
        self.move_to_start()

    def set_limb_planner():
        self.right_arm = MoveGroupCommander("right_arm")
        self.right_arm.set_planner_id('RRTConnectkConfigDefault')
        self.right_arm.allow_replanning(True)
        self.right_arm.set_planning_time(7)

    def enable_robot():
        print("Getting robot state... ")
        self._rs = intera_interface.RobotEnable(intera_interface.CHECK_VERSION)
        self._init_state = self._rs.state().enabled
        print("Enabling robot... ")
        self._rs.enable()

    def set_scene():
        self.scene_pub = rospy.Publisher('/planning_scene',
                                         PlanningScene,
                                         queue_size=10)
        self.scene = PlanningSceneInterface()
        rospy.sleep(2)
        self.add_collision_object('turtlebot', 0.8, 0., -0.65, .5, 1.5, .33)
        self.add_collision_object('right_wall', 0., 0.65, 0., 4., .1, 4.)
        self.add_collision_object('left_wall', 0., -0.8, 0., 4., .1, 4.)
        self.add_collision_object('back_wall', -0.6, 0., 0., .1, 4., 4.)
        self.add_collision_object('destination_table', .5, -.4, -.35, 1, .5,
                                  .5)
        self.plan_scene = PlanningScene()
        self.plan_scene.is_diff = True
        self.scene_pub.publish(self.plan_scene)

    def add_collision_object(self, name, x, y, z, xs, ys, zs):
        self.scene.remove_world_object(name)
        o = PoseStamped()
        o.pose.position.x = x
        o.pose.position.y = y
        o.pose.position.z = z
        self.scene.attach_box('base', name, o, [xs, ys, zs])

    def set_destinations(self):
        while len(self.destinations) == 0:
            if self.tf.frameExists(self.base) and self.tf.frameExists(
                    self.dest):
                point, quaternion = self.tf.lookupTransform(
                    self.base, self.dest,
                    self.tf.getLatestCommonTime(self.base, self.dest))
                position = list_to_point(point)
                self.destinations.append(
                    Pose(position=position,
                         orientation=self.start_pose.orientation))

    def add_new_objects_to_queue(self, sleep=True):
        print("Checking if " + self.base + " and " + self.pick_obj +
              " both exist.")
        if self.tf.frameExists(self.base) and self.tf.frameExists(
                self.pick_obj):
            if sleep:
                rospy.sleep(10.0)
                self.add_new_objects_to_queue(sleep=False)
            else:
                print(self.base + " and " + self.pick_obj + " both exist.")
                point, quaternion = self.tf.lookupTransform(
                    self.base, self.pick_obj,
                    self.tf.getLatestCommonTime(self.base, self.pick_obj))
                position = list_to_point(point)
                print("Adding " + self.pick_obj + " to queue")
                obj_location = Pose(position=position,
                                    orientation=self.start_pose.orientation)
                print("Picking Object from:", obj_location)
                self.queue.put(obj_location)

    def complete_pick_place(self):
        if not self.queue.empty():
            start_pose = self.queue.get()
            end_pose = self.destinations[0]
            print("\nPicking...")
            self.pick(start_pose)
            print("\nPlacing...")
            self.place(end_pose)
            print("\Resetting...")
            self.move_to_start()

    def guarded_move_to_joint_position(self, pose):
        self.right_arm.set_pose_target(pose)
        self.right_arm.go()

    def servo_to_pose(self, pose):
        # servo down to release
        self.guarded_move_to_joint_position(pose)

    def approach(self, pose):
        # approach with a pose the hover-distance above the requested pose
        approach = copy.deepcopy(pose)
        approach.position.z += self.hover_distance
        print("approaching:", approach)
        self.guarded_move_to_joint_position(approach)

    def retract(self):
        # retrieve current pose from endpoint
        current_pose = self.limb.endpoint_pose()
        ik_pose = Pose()
        ik_pose.position.x = current_pose['position'].x
        ik_pose.position.y = current_pose['position'].y
        ik_pose.position.z = current_pose['position'].z + self.hover_distance
        ik_pose.orientation.x = current_pose['orientation'].x
        ik_pose.orientation.y = current_pose['orientation'].y
        ik_pose.orientation.z = current_pose['orientation'].z
        ik_pose.orientation.w = current_pose['orientation'].w
        # servo up from current pose
        self.guarded_move_to_joint_position(ik_pose)

    def move_to_start(self):
        print("Moving the right arm to start pose...")
        self.guarded_move_to_joint_position(self.start_pose)
        self.gripper_open()
        rospy.sleep(1.0)
        print("Running. Ctrl-c to quit")

    def gripper_open(self):
        self.gripper.open()
        rospy.sleep(1.0)

    def gripper_close(self):
        self.gripper.close()
        rospy.sleep(1.0)

    def pick(self, pose):
        # open the gripper
        self.gripper_open()
        # servo above pose
        self.approach(pose)
        # servo to pose
        self.servo_to_pose(pose)
        # close gripper
        self.gripper_close()
        # retract to clear object
        self.retract()

    def place(self, pose):
        # servo above pose
        self.approach(pose)
        # servo to pose
        self.servo_to_pose(pose)
        # open the gripper
        self.gripper_open()
        # retract to clear object
        self.retract()
コード例 #27
0
ファイル: drive_forward.py プロジェクト: madsbahrt/FroboMind
class DriveForwardAction():
    """
        Drives x meters either forward or backwards depending on the given distance.
        the velocity should always be positive. 
    """
    def __init__(self,name,odom_frame,base_frame):
        """
        
        @param name: the name of the action
        @param odom_frame: the frame the robot is moving in (odom_combined)
        @param base_frame: the vehicles own frame (usually base_link)
        """
        
        self._action_name = name
        self.__odom_frame = odom_frame
        self.__base_frame = base_frame
        self.__server =  actionlib.SimpleActionServer(self._action_name,drive_forwardAction,auto_start=False)
        self.__server.register_preempt_callback(self.preempt_cb)
        self.__server.register_goal_callback(self.goal_cb)
        
        self.__cur_pos = 0
        self.__start_yaw = 0
        self.__cur_yaw = 0
        
        self.__feedback = drive_forwardFeedback()
        
        self.__listen = TransformListener()
        self.vel_pub = rospy.Publisher("/fmControllers/cmd_vel_auto",Twist)
        
        self.__turn_timeout = 200
        self.__start_time = rospy.Time.now()
        self.turn_vel = 0
        self.new_goal = False
        
        self.fix_offset = 0
        
        self.__server.start()

    def preempt_cb(self):
        rospy.loginfo("Preempt requested")
        self.__publish_cmd_vel(0)
        self.__server.set_preempted()
    
    def goal_cb(self):
        """
            called when we receive a new goal
            the goal contains a desired radius and a success radius in which we check if the turn succeeded or not
            the message also contains if we should turn left or right
        """
        g = self.__server.accept_new_goal()
        self.__desired_amount= g.amount
        self.vel = g.vel
        self.fix_offset = g.fix_offset
        
        self.new_goal = True
    
    def on_timer(self,e):
        """
            called regularly by a ros timer
            in here we simply orders the vehicle to start moving either forward 
            or backwards depending on the distance sign, while monitoring the 
            travelled distance, if the distance is equal to or greater then this
            action succeeds.
        """
        if self.__server.is_active():
            if self.new_goal:
                self.new_goal = False
                if self.__get_start_position():
                    self.__start_time = rospy.Time.now()
                else:
                    self.__server.set_aborted(text="could not find vehicle")
            else:
                if rospy.Time.now() - self.__start_time > rospy.Duration(self.__turn_timeout):
                    self.__server.set_aborted(text="timeout on action")
                    self.__publish_cmd_vel(0)
                else:
                    if self.__get_current_position():
                        if self.__get_distance() >= math.fabs(self.__desired_amount):
                            result = drive_forwardResult()
                            result.end_dist = self.__get_distance()
                            self.__server.set_succeeded(result, "distance covered")
                            self.__publish_cmd_vel(0)
                        else:
                            self.__publish_cmd_vel(1)
                            self.__feedback.progress = self.__get_distance()
                            self.__server.publish_feedback(self.__feedback)
                            
    def __get_distance(self):
        return math.sqrt(math.pow(self.__cur_pos[0][0] - self.__start_pos[0][0],2) +
                         math.pow(self.__cur_pos[0][1] - self.__start_pos[0][1],2))
    
    def __get_start_position(self):
        ret = False
        try:
            self.__start_pos = self.__listen.lookupTransform(self.__odom_frame,self.__base_frame,rospy.Time(0))
            self.__start_yaw = tf.transformations.euler_from_quaternion(self.__start_pos[1])[2]
            ret = True
        except (tf.LookupException, tf.ConnectivityException),err:
            rospy.loginfo("could not locate vehicle")
        
        return ret
コード例 #28
0
ファイル: swarmlib.py プロジェクト: RuslanAgishev/cfcontrol
class Drone:
    def __init__(self, name, obstacles, leader=False):
        self.name = name
        self.tf = '/vicon/' + name + '/' + name
        self.leader = leader
        self.tl = TransformListener()
        self.pose = self.position()
        self.orient = np.array([0, 0, 0])
        self.sp = self.position()
        self.obstacles = obstacles
        self.path = Path()
        self.delta = np.array([0, 0])
        self.near_obstacle = np.zeros(len(obstacles))
        self.radius_impedance = Radius_Impedance()
        self.angular_impedance = Angular_Impedance()
        self.impedance_avel = Impedance_avel()
        self.theta = None
        self.d_theta = pi * np.ones(len(obstacles))
        self.dist_to_drones = np.zeros(3)
        self.dist_to_obst = np.zeros(len(obstacles))
        self.drone_time_array = np.ones(10)
        self.drone_pose_array = np.array(
            [np.ones(10), np.ones(10), np.ones(10)])
        self.rate = rospy.Rate(100)
        self.traj = np.array([0, 0, 0])
        self.feature = self.sp
        self.start = self.position()
        self.goal = self.sp

    def position(self):
        self.tl.waitForTransform("/world", self.tf, rospy.Time(0),
                                 rospy.Duration(1))
        position, quaternion = self.tl.lookupTransform("/world", self.tf,
                                                       rospy.Time(0))
        self.pose = position
        return np.array(position)

    def orientation(self):
        self.tl.waitForTransform("/world", self.tf, rospy.Time(0),
                                 rospy.Duration(1))
        position, quaternion = self.tl.lookupTransform("/world", self.tf,
                                                       rospy.Time(0))
        self.orient = get_angles(np.array(quaternion))
        return get_angles(np.array(quaternion))

    def publish_sp(self):
        publish_pose(self.sp, np.array([0, 0, 0]), self.name + "_sp")

    def publish_position(self):
        publish_pose(self.pose, self.orient, self.name + "_pose")

    def publish_path(self, limit=1000):
        publish_path(self.path, self.sp, self.orient, self.name + "_path",
                     limit)
        #for i in range( 1,len(self.path.poses) ):
        #	print self.name +": "+ str(self.path.poses[i].pose)

    def fly(self):
        # if self.leader:
        # 	limits = np.array([ 2, 2, 2.5 ])
        # 	np.putmask(self.sp, self.sp >= limits, limits)
        # 	np.putmask(self.sp, self.sp <= -limits, -limits)
        publish_goal_pos(self.sp, 0, "/" + self.name)

    def update_pose_theta(self, drone, obstacle, R):
        drone_omega = self.omegaZ(drone.sp, drone.sp - obstacle.position())
        if drone.near_obstacle[
                obstacle.
                id] == 1:  # initial impedance parameters, when the drone is just near the obstacle
            drone.angular_impedance.imp_theta, drone.angular_impedance.imp_omega, drone.angular_impedance.imp_time =\
             drone.angular_impedance.impedance_model(drone.theta, drone.theta, drone_omega, drone.angular_impedance.imp_time)
        else:
            drone.angular_impedance.imp_theta, drone.angular_impedance.imp_omega, drone.angular_impedance.imp_time =\
             drone.angular_impedance.impedance_model(drone.theta, drone.angular_impedance.imp_theta, drone.angular_impedance.imp_omega, drone.angular_impedance.imp_time)

        updated_pose = drone.angular_impedance.pose_from_theta(
            obstacle.position()[:2], R, drone.angular_impedance.imp_theta)
        return updated_pose

    def update_pose_radius(self, pose_prev, drone, dist_to_obstacle, koef):
        if (
                sum(drone.near_obstacle) <= 10
        ):  # 10 is the number of samples to compute velocity from consequent poses
            drone.radius_impedance.imp_vel = drone.velocity(drone.sp)
        drone.radius_impedance.imp_pose, \
        drone.radius_impedance.imp_vel, \
        drone.radius_impedance.imp_time = \
         drone.radius_impedance.impedance_model(drone.delta, drone.radius_impedance.imp_pose, drone.radius_impedance.imp_vel, drone.radius_impedance.imp_time)
        delta_pose = drone.radius_impedance.imp_pose[:2]
        updated_pose = pose_prev + koef * delta_pose
        ''' impedance model vizualization '''
        length = np.linalg.norm(delta_pose)
        yaw = acos(delta_pose[0] / length)
        publish_arrow(np.hstack([updated_pose, drone.sp[2]]), [0, 0, yaw],
                      length, '/delta_pose')

        return updated_pose

    def update_pose_avel(self, pose_prev, average_vel):
        self.impedance_avel.imp_pose, self.impedance_avel.imp_vel, self.impedance_avel.imp_time = \
         self.impedance_avel.impedance_model(average_vel, self.impedance_avel.imp_pose, self.impedance_avel.imp_vel, self.impedance_avel.imp_time)
        updated_pose = pose_prev + 0.15 * self.impedance_avel.imp_pose
        return updated_pose

    def calculate_dist_to_drones(self, drones_poses):
        for i in range(len(drones_poses)):
            self.dist_to_drones[i] = np.linalg.norm(drones_poses[i] - self.sp)

    def dist_to_obstacles(self):
        dist = []
        for i in range(len(self.obstacles)):
            dist.append(
                np.linalg.norm(self.obstacles[i].position()[:2] - self.sp[:2]))
        self.dist_to_obst = dist
        return np.array(dist)

    def omegaZ(self, drone_pose, dist_from_obstacle):
        R = dist_from_obstacle  # 3D-vector
        drone_vel = self.velocity(drone_pose)
        # drone_vel_n = np.dot(drone_vel, R)/(np.linalg.norm(R)**2) * R
        # drone_vel_t = drone_vel - drone_vel_n
        drone_w = np.cross(R, drone_vel)  # / ( np.linalg.norm(R)**2 )

        return drone_w[2]

    def velocity(self, drone_pose):
        for i in range(len(self.drone_time_array) - 1):
            self.drone_time_array[i] = self.drone_time_array[i + 1]
        self.drone_time_array[-1] = time.time()

        for i in range(len(self.drone_pose_array[0]) - 1):
            self.drone_pose_array[0][i] = self.drone_pose_array[0][i + 1]
            self.drone_pose_array[1][i] = self.drone_pose_array[1][i + 1]
            self.drone_pose_array[2][i] = self.drone_pose_array[2][i + 1]
        self.drone_pose_array[0][-1] = drone_pose[0]
        self.drone_pose_array[1][-1] = drone_pose[1]
        self.drone_pose_array[2][-1] = drone_pose[2]

        vel_x = (self.drone_pose_array[0][-1] - self.drone_pose_array[0][0]
                 ) / (self.drone_time_array[-1] - self.drone_time_array[0])
        vel_y = (self.drone_pose_array[1][-1] - self.drone_pose_array[1][0]
                 ) / (self.drone_time_array[-1] - self.drone_time_array[0])
        vel_z = (self.drone_pose_array[2][-1] - self.drone_pose_array[2][0]
                 ) / (self.drone_time_array[-1] - self.drone_time_array[0])

        drone_vel = np.array([vel_x, vel_y, vel_z])

        return drone_vel

    def landing(self, sim=False):
        drone_landing_pose = self.position() if sim == False else self.sp
        while not rospy.is_shutdown():
            self.sp = drone_landing_pose
            drone_landing_pose[2] = drone_landing_pose[2] - 0.007
            self.publish_sp()
            self.publish_path(limit=1000)
            if sim == False:
                self.fly()
            if self.sp[2] < -1.0:
                sleep(1)
                if sim == False:
                    cf1.stop()
                print 'reached the floor, shutdown'
                # rospy.signal_shutdown('landed')
            self.rate.sleep()
コード例 #29
0
ファイル: planner.py プロジェクト: niels-k-dahl/FroboMind
class PositionPlanner:
    """
        Control class taking position goals and generating twist messages accordingly
    """

    def __init__(self):
        # Init control methods
        self.isNewGoalAvailable = self.empty_method()
        self.isPreemptRequested = self.empty_method()
        self.setPreempted = self.empty_method()

        # Get topics and transforms
        self.cmd_vel_topic = rospy.get_param("~cmd_vel_topic", "/fmSignals/cmd_vel")
        self.odom_frame = rospy.get_param("~odom_frame", "/odom")
        self.odometry_topic = rospy.get_param("~odometry_topic", "/fmKnowledge/odom")
        self.base_frame = rospy.get_param("~base_frame", "/base_footprint")
        self.use_tf = rospy.get_param("~use_tf", False)

        # Get general parameters
        self.max_linear_velocity = rospy.get_param("~max_linear_velocity", 2)
        self.max_angular_velocity = rospy.get_param("~max_angular_velocity", 1)
        self.max_initial_error = rospy.get_param("~max_initial_angle_error", 1)

        self.max_distance_error = rospy.get_param("~max_distance_error", 0.2)
        self.use_tf = rospy.get_param("~use_tf", False)
        self.max_angle_error = rospy.get_param("~max_angle_error", math.pi / 4)
        self.retarder = rospy.get_param("~retarder", 0.8)

        # Control loop
        self.lin_p = rospy.get_param("~lin_p", 0.4)
        self.lin_i = rospy.get_param("~lin_i", 0.6)
        self.lin_d = rospy.get_param("~lin_d", 0.0)
        self.ang_p = rospy.get_param("~ang_p", 0.8)
        self.ang_i = rospy.get_param("~ang_i", 0.1)
        self.ang_d = rospy.get_param("~ang_d", 0.05)
        self.int_max = rospy.get_param("~int_max", 0.1)

        # Setup Publishers and subscribers
        if not self.use_tf:
            self.odometry_topic = rospy.get_param("~odometry_topic", "/fmKnowledge/odom")
            self.odom_sub = rospy.Subscriber(self.odometry_topic, Odometry, self.onOdometry)
        self.twist_pub = rospy.Publisher(self.cmd_vel_topic, TwistStamped)

        # Parameters for action server
        self.period = 0.1
        self.retarder_point = 0.3  # distance to target when speed should start declining

        # Init control loop
        self.lin_err = 0.0
        self.ang_err = 0.0
        self.lin_prev_err = 0.0
        self.ang_prev_err = 0.0
        self.lin_int = 0.0
        self.ang_int = 0.0
        self.lin_diff = 0.0
        self.ang_diff = 0.0
        self.distance_error = 0
        self.angle_error = 0
        self.fb_linear = 0.0
        self.fb_angular = 0.0
        self.sp_linear = 0.0
        self.sp_angular = 0.0

        # Init TF listener
        self.__listen = TransformListener()

        # Init controller
        self.corrected = False
        self.rate = rospy.Rate(1 / self.period)
        self.twist = TwistStamped()
        self.destination = Vector(0, 0)
        self.position = Vector(0, 0)
        self.heading = Vector(0, 0)
        self.quaternion = np.empty((4,), dtype=np.float64)

        # Setup Publishers and subscribers
        self.use_tf = False
        if not self.use_tf:
            self.odom_sub = rospy.Subscriber(self.odometry_topic, Odometry, self.onOdometry)
        self.twist_pub = rospy.Publisher(self.cmd_vel_topic, TwistStamped)

    def execute(self, goal):
        # Construct a vector from position goal
        self.destination[0] = goal.x
        self.destination[1] = goal.y
        rospy.loginfo(rospy.get_name() + "Received goal: (%f,%f) ", goal.x, goal.y)
        self.corrected = False

        while not rospy.is_shutdown():
            # Check for new goal
            if self.isNewGoalAvailable():
                break

            # Preemption check
            if self.isPreemptRequested():
                break

            # If position is unreached, publish twist
            if self.publish_twist(self.destination, self.destination):
                # Block
                try:
                    self.rate.sleep()
                except rospy.ROSInterruptException:
                    return "preempted"
            else:
                # Succeed the action - position has been reached
                self.setSucceeded()
                self.stop()
                break

        # Return state
        if self.isPreemptRequested():
            self.setPreempted()
            return "preempted"
        elif rospy.is_shutdown():
            return "aborted"
        else:
            return "succeeded"

    def stop(self):
        # Publish a zero twist to stop the robot
        self.twist.header.stamp = rospy.Time.now()
        self.twist.twist.linear.x = 0
        self.twist.twist.angular.z = 0
        self.twist_pub.publish(self.twist)

    def publish_twist(self, target, goal):
        """
            Method running the control loop. Distinguishes between target and goal to 
            adapt to other planners. For position planning the two will be the same.
        """
        # Get current position
        self.get_current_position()

        # Construct goal path vector
        goal_path = goal - Vector(self.position[0], self.position[1])

        # Calculate distance to goal
        self.distance_error = goal_path.length()

        # If the goal is unreached
        if self.distance_error > self.max_distance_error:
            # Construct target path vector
            target_path = target - Vector(self.position[0], self.position[1])

            # Calculate yaw
            if self.use_tf:
                (roll, pitch, yaw) = tf.transformations.euler_from_quaternion(self.heading)
            else:
                (roll, pitch, yaw) = tf.transformations.euler_from_quaternion(self.quaternion)

            # Construct heading vector
            head = Vector(math.cos(yaw), math.sin(yaw))

            # Calculate angle between heading vector and target path vector
            self.angle_error = head.angle(target_path)

            # Rotate the heading vector according to the calculated angle and test correspondence
            # with the path vector. If not zero sign must be flipped. This is to avoid the sine trap.
            t1 = head.rotate(self.angle_error)
            if target_path.angle(t1) != 0:
                self.angle_error = -self.angle_error

            # Calculate angle between heading vector and goal path vector
            goal_angle_error = head.angle(goal_path)

            # Avoid the sine trap.
            t1 = head.rotate(goal_angle_error)
            if goal_path.angle(t1) != 0:
                goal_angle_error = -goal_angle_error

            # Check if large initial errors have been corrected
            if math.fabs(self.angle_error) < self.max_initial_error:
                self.corrected = True

            # Generate velocity setpoints from distance and angle errors
            self.sp_linear = self.distance_error
            self.sp_angular = self.angle_error

            # Calculate velocity errors for control loop
            self.lin_err = self.sp_linear - self.fb_linear
            self.ang_err = self.sp_angular - self.fb_angular

            # Calculate integrators and implement max
            self.lin_int += self.lin_err * self.period
            if self.lin_int > self.int_max:
                self.lin_int = self.int_max
            if self.lin_int < -self.int_max:
                self.lin_int = -self.int_max
            self.ang_int += self.ang_err * self.period
            if self.ang_int > self.int_max:
                self.ang_int = self.int_max
            if self.ang_int < -self.int_max:
                self.ang_int = -self.int_max

            # Calculate differentiators and save value
            self.lin_diff = (self.lin_prev_err - self.lin_err) / self.period
            self.ang_diff = (self.ang_prev_err - self.ang_err) / self.period
            self.lin_prev_err = self.lin_err
            self.ang_prev_err = self.ang_err

            # Update twist message with control velocities
            self.twist.twist.linear.x = (
                (self.lin_err * self.lin_p) + (self.lin_int * self.lin_i) + (self.lin_diff * self.lin_d)
            )
            self.twist.twist.angular.z = (
                (self.ang_err * self.ang_p) + (self.ang_int * self.ang_i) + (self.ang_diff * self.ang_d)
            )

            # Implement retarder to reduce linear velocity if angle error is too big
            if math.fabs(goal_angle_error) > self.max_angle_error:
                self.twist.twist.linear.x *= self.retarder

            # Implement initial correction speed for large angle errors
            if not self.corrected:
                self.twist.twist.linear.x *= self.retarder ** 2

            # Implement maximum linear velocity and maximum angular velocity
            if self.twist.twist.linear.x > self.max_linear_velocity:
                self.twist.twist.linear.x = self.max_linear_velocity
            if self.twist.twist.linear.x < -self.max_linear_velocity:
                self.twist.twist.linear.x = -self.max_linear_velocity
            if self.twist.twist.angular.z > self.max_angular_velocity:
                self.twist.twist.angular.z = self.max_angular_velocity
            if self.twist.twist.angular.z < -self.max_angular_velocity:
                self.twist.twist.angular.z = -self.max_angular_velocity

            # Prohibit reverse driving
            if self.twist.twist.linear.x < 0:
                self.twist.twist.linear.x = 0

            # If not preempted, add a time stamp and publish the twist
            if not self.isPreemptRequested():
                self.twist.header.stamp = rospy.Time.now()
                self.twist_pub.publish(self.twist)

            return True
        else:
            return False

    def onOdometry(self, msg):
        """
            Callback method for handling odometry messages
        """
        # Extract the orientation quaternion
        self.quaternion[0] = msg.pose.pose.orientation.x
        self.quaternion[1] = msg.pose.pose.orientation.y
        self.quaternion[2] = msg.pose.pose.orientation.z
        self.quaternion[3] = msg.pose.pose.orientation.w

        # Extract the position vector
        self.position[0] = msg.pose.pose.position.x
        self.position[1] = msg.pose.pose.position.y

        # Extract twist
        self.fb_linear = msg.twist.twist.linear.x
        self.fb_angular = msg.twist.twist.angular.z

    def empty_method(self):
        """
            Empty method pointer
        """
        return False

    def get_current_position(self):
        """
            Get current position from tf
        """
        if self.use_tf:
            ret = False
            try:
                (self.position, self.heading) = self.__listen.lookupTransform(
                    self.odom_frame, self.base_frame, rospy.Time(0)
                )  # The transform is returned as position (x,y,z) and an orientation quaternion (x,y,z,w).
                ret = True
            except (tf.LookupException, tf.ConnectivityException), err:
                rospy.loginfo("could not locate vehicle")
            return ret
コード例 #30
0
ファイル: spray.py プロジェクト: sdu-rsd-group1/FroboMind
class SprayAction():
    """
        Drives x meters either forward or backwards depending on the given distance.
        the velocity should always be positive. 
    """
    def __init__(self, name, odom_frame, base_frame):
        """
        
        @param name: the name of the action
        @param odom_frame: the frame the robot is moving in (odom_combined)
        @param base_frame: the vehicles own frame (usually base_link)
        """

        self._action_name = name
        self.__odom_frame = odom_frame
        self.__base_frame = base_frame
        self.__server = actionlib.SimpleActionServer(self._action_name,
                                                     sprayAction,
                                                     auto_start=False)
        self.__server.register_preempt_callback(self.preempt_cb)
        self.__server.register_goal_callback(self.goal_cb)

        self.__cur_pos = 0
        self.__start_pos = 0
        self.__start_yaw = 0
        self.__cur_yaw = 0

        self.__feedback = sprayFeedback()

        self.__listen = TransformListener()
        #self.vel_pub = rospy.Publisher("/fmControllers/cmd_vel_auto",Twist)
        self.spray_pub = rospy.Publisher("/fmControllers/spray", UInt32)

        self.__start_time = rospy.Time.now()
        self.new_goal = False
        self.n_sprays = 0
        self.spray_msg = UInt32()

        self.spray_l = False
        self.spray_cnt = 0

        self.__server.start()

    def preempt_cb(self):
        rospy.loginfo("Preempt requested")
        self.spray_msg.data = 0
        self.spray_pub.publish(self.spray_msg)
        self.__server.set_preempted()

    def goal_cb(self):
        """
            called when we receive a new goal
            the goal contains a desired radius and a success radius in which we check if the turn succeeded or not
            the message also contains if we should turn left or right
        """
        g = self.__server.accept_new_goal()
        self.spray_dist = g.distance
        self.spraytime = g.spray_time

        self.new_goal = True

    def on_timer(self, e):
        """
            called regularly by a ros timer
            in here we simply orders the vehicle to start moving either forward 
            or backwards depending on the distance sign, while monitoring the 
            travelled distance, if the distance is equal to or greater then this
            action succeeds.
        """
        if self.__server.is_active():
            if self.new_goal:
                self.new_goal = False
                self.n_sprays = 0
                self.__get_start_position()
            else:
                if self.__get_current_position():
                    if self.__get_distance() >= self.spray_dist:
                        self.do_spray()
                        self.__get_start_position()
                else:
                    self.__server.set_aborted(None, "could not locate")
                    rospy.logerr("Could not locate vehicle")
                    self.spray_msg.data = 0
                    self.spray_pub.publish(self.spray_msg)

    def __get_distance(self):
        return math.sqrt(
            math.pow(self.__cur_pos[0][0] - self.__start_pos[0][0], 2) +
            math.pow(self.__cur_pos[0][1] - self.__start_pos[0][1], 2))

    def __get_start_position(self):
        ret = False
        try:
            self.__start_pos = self.__listen.lookupTransform(
                self.__odom_frame, self.__base_frame, rospy.Time(0))
            self.__start_yaw = tf.transformations.euler_from_quaternion(
                self.__start_pos[1])[2]
            ret = True
        except (tf.LookupException, tf.ConnectivityException), err:
            rospy.loginfo("could not locate vehicle")

        return ret
コード例 #31
0
class PR2Arm():

    wipe_started = False
    standoff = 0.368  #0.2 + 0.168 (dist from wrist to fingertips)
    torso_min = 0.001  #115
    torso_max = 0.299  #0.295
    dist = 0.

    move_arm_error_dict = {
        -1: "PLANNING_FAILED: Could not plan a clear path to goal.",
        0: "Succeeded [0]",
        1: "Succeeded [1]",
        -2: "TIMED_OUT",
        -3: "START_STATE_IN_COLLISION: Try freeing the arms manually.",
        -4: "START_STATE_VIOLATES_PATH_CONSTRAINTS",
        -5: "GOAL_IN_COLLISION",
        -6: "GOAL_VIOLATES_PATH_CONSTRAINTS",
        -7: "INVALID_ROBOT_STATE",
        -8: "INCOMPLETE_ROBOT_STATE",
        -9: "INVALID_PLANNER_ID",
        -10: "INVALID_NUM_PLANNING_ATTEMPTS",
        -11: "INVALID_ALLOWED_PLANNING_TIME",
        -12: "INVALID_GROUP_NAME",
        -13: "INVALID_GOAL_JOINT_CONSTRAINTS",
        -14: "INVALID_GOAL_POSITION_CONSTRAINTS",
        -15: "INVALID_GOAL_ORIENTATION_CONSTRAINTS",
        -16: "INVALID_PATH_JOINT_CONSTRAINTS",
        -17: "INVALID_PATH_POSITION_CONSTRAINTS",
        -18: "INVALID_PATH_ORIENTATION_CONSTRAINTS",
        -19: "INVALID_TRAJECTORY",
        -20: "INVALID_INDEX",
        -21: "JOINT_LIMITS_VIOLATED",
        -22: "PATH_CONSTRAINTS_VIOLATED",
        -23: "COLLISION_CONSTRAINTS_VIOLATED",
        -24: "GOAL_CONSTRAINTS_VIOLATED",
        -25: "JOINTS_NOT_MOVING",
        -26: "TRAJECTORY_CONTROLLER_FAILED",
        -27: "FRAME_TRANSFORM_FAILURE",
        -28: "COLLISION_CHECKING_UNAVAILABLE",
        -29: "ROBOT_STATE_STALE",
        -30: "SENSOR_INFO_STALE",
        -31: "NO_IK_SOLUTION: Cannot reach goal configuration.",
        -32: "INVALID_LINK_NAME",
        -33: "IK_LINK_IN_COLLISION: Cannot reach goal configuration\
                                      without contact.",
        -34: "NO_FK_SOLUTION",
        -35: "KINEMATICS_STATE_IN_COLLISION",
        -36: "INVALID_TIMEOUT"
    }

    def __init__(self, arm, tfListener=None):
        self.arm = arm
        if not (self.arm == "right" or self.arm == "left"):
            rospy.logerr("Failed to initialize PR2Arm: \
                        Must pass 'right' or 'left'")
            return
        if tfListener is None:
            self.tf = TransformListener()
        else:
            self.tf = tfListener

        if self.arm == "right":
            # PR2: self.arm[0]+ 'arm_controller/joint_trajectory_action',
            arm_controller = "/arm_controllerR/follow_joint_trajectory"
        else:
            arm_controller = "/arm_controller/follow_joint_trajectory"
        self.arm_traj_client = actionlib.SimpleActionClient(
            arm_controller, FollowJointTrajectoryAction)
        rospy.loginfo("Waiting for " + arm_controller)
        if self.arm_traj_client.wait_for_server(rospy.Duration(5)):
            rospy.loginfo("Found " + arm_controller)
        else:
            rospy.logwarn("Cannot find " + arm_controller)

        # same for both pr2 and pr2lite
        self.torso_client = actionlib.SimpleActionClient(
            'torso_controller/position_joint_action',
            SingleJointPositionAction)
        rospy.loginfo("Waiting for torso_controller/position_joint_action \
                       server")
        if self.torso_client.wait_for_server(rospy.Duration(5)):
            rospy.loginfo(
                "Found torso_controller/position_joint_action server")
        else:
            rospy.logwarn("Cannot find torso_controller/position_joint_action \
                           server")

        self.gripper_client = actionlib.SimpleActionClient(
            self.arm[0] + '_gripper_controller/gripper_action',
            Pr2GripperCommandAction)
        rospy.loginfo("Waiting for " + self.arm[0] +
                      "_gripper_controller/gripper_action server")
        if self.gripper_client.wait_for_server(rospy.Duration(5)):
            rospy.loginfo("Found " + self.arm[0] +
                          "_gripper_controller/gripper_action server")
        else:
            rospy.logwarn("Cannot find " + self.arm[0] +
                          "_gripper_controller/gripper_action server")

        # rospy.Subscriber('torso_controller/state',
        #              JointTrajectoryControllerState, self.update_torso_state)

        self.log_out = rospy.Publisher(rospy.get_name() + '/log_out', String)

        rospy.loginfo("Waiting for " + self.arm.capitalize() +
                      " FK/IK Solver services")
        try:
            rospy.wait_for_service("/pr2lite_" + self.arm +
                                   "_arm_kinematics/get_fk")
            rospy.wait_for_service("/pr2lite_" + self.arm +
                                   "_arm_kinematics/get_fk_solver_info")
            rospy.wait_for_service("/pr2lite_" + self.arm +
                                   "_arm_kinematics/get_ik")
            rospy.wait_for_service("/pr2lite_" + self.arm +
                                   "_arm_kinematics/get_constraint_aware_ik")
            rospy.wait_for_service("/pr2lite_" + self.arm +
                                   "_arm_kinematics/get_ik_solver_info")
            self.fk_info_proxy = rospy.ServiceProxy(
                "/pr2lite_" + self.arm + "_arm_kinematics/get_fk_solver_info",
                GetKinematicSolverInfo)
            self.fk_info = self.fk_info_proxy()
            self.fk_pose_proxy = rospy.ServiceProxy(
                "/pr2lite_" + self.arm + "_arm_kinematics/get_fk",
                GetPositionFK, True)
            self.ik_info_proxy = rospy.ServiceProxy(
                "/pr2lite_" + self.arm + "_arm_kinematics/get_ik_solver_info",
                GetKinematicSolverInfo)
            self.ik_info = self.ik_info_proxy()
            self.ik_constraint_aware_pose_proxy = rospy.ServiceProxy(
                "/pr2lite_" + self.arm +
                "_arm_kinematics/get_constraint_aware_ik",
                GetConstraintAwarePositionIK, True)
            self.ik_pose_proxy = rospy.ServiceProxy(
                "/pr2lite_" + self.arm + "_arm_kinematics/get_ik",
                GetPositionIK, True)
            rospy.loginfo("Found FK/IK Solver services")
        except:
            rospy.logerr("Could not find FK/IK Solver services")

        self.set_planning_scene_diff_name= \
                    '/environment_server/set_planning_scene_diff'
        rospy.wait_for_service('/environment_server/set_planning_scene_diff')
        self.set_planning_scene_diff = rospy.ServiceProxy(
            '/environment_server/set_planning_scene_diff',
            SetPlanningSceneDiff)
        self.set_planning_scene_diff(SetPlanningSceneDiffRequest())
        rospy.Subscriber('joint_states', JointState, self.update_joint_state)

        self.test_pose = rospy.Publisher("test_pose", PoseStamped)

    def update_joint_state(self, jtcs):
        self.joint_state_time = jtcs.header.stamp
        # ARD
        if len(self.joint_state_pos) == 0 and len(
                self.ik_info.kinematic_solver_info.joint_names) > 0:
            for joint_state_name in self.ik_info.kinematic_solver_info.joint_names:
                self.joint_state_pos.append(0)
                self.joint_state_vel.append(0)
        i = 0
        for joint in jtcs.name:
            j = 0
            for joint_state_name in self.ik_info.kinematic_solver_info.joint_names:
                if joint == joint_state_name:
                    self.joint_state_pos[j] = jtcs.position[i]
                    self.joint_state_vel[j] = jtcs.velocity[i]
                j += 1
            if joint == "torso_lift_joint":
                self.torso_state = jtcs.position[i]
            i += 1

    def curr_pose(self):

        # (trans,rot) = self.tf.lookupTransform("/torso_lift_link",
        # (trans,rot) = self.tf.lookupTransform("chess_board_raw",
        #                                     # ARD "/"+
        #                                     self.arm+"_wrist_roll_link",
        #                                     rospy.Time(0))
        # print "chess_board_raw curr_pose "
        # print Point(*trans)
        # ARD
        now = rospy.Time.now()
        self.tf.waitForTransform("base_link", self.arm + "_wrist_roll_link",
                                 now, rospy.Duration(1.0))
        # (trans,rot) = self.tf.lookupTransform("/torso_lift_link",
        (trans, rot) = self.tf.lookupTransform(
            "base_link",
            # ARD "/"+
            self.arm + "_wrist_roll_link",
            now)
        cp = PoseStamped()
        cp.header.stamp = rospy.Time.now()
        # cp.header.frame_id = '/torso_lift_link'
        cp.header.frame_id = 'base_link'
        cp.pose.position = Point(*trans)
        cp.pose.orientation = Quaternion(*rot)
        return cp

    def wait_for_stop(self, wait_time=1, timeout=60):
        rospy.sleep(wait_time)
        end_time = rospy.Time.now() + rospy.Duration(timeout)
        while not self.is_stopped():
            if rospy.Time.now() < end_time:
                rospy.sleep(wait_time)
            else:
                raise

    def is_stopped(self):
        time = self.joint_state_time
        vels = self.joint_state_vel
        if (np.allclose(vels, np.zeros(7))
                and (rospy.Time.now() - time) < rospy.Duration(0.1)):
            return True
        else:
            return False

    def adjust_elbow(self, f32):
        request = self.form_ik_request(self.curr_pose())
        angs = list(request.ik_request.ik_seed_state.joint_state.position)
        angs[2] += f32.data
        request.ik_request.ik_seed_state.joint_state.position = angs
        ik_goal = self.ik_pose_proxy(request)
        if ik_goal.error_code.val == 1:
            self.send_joint_angles(ik_goal.solution.joint_state.position)
        else:
            rospy.loginfo("Cannot adjust elbow position further")
            self.log_out.publish(data="Cannot adjust elbow position further")

    def gripper(self, position, effort=30):
        pos = np.clip(position, 0.0, 0.09)
        goal = Pr2GripperCommandGoal()
        goal.command.position = pos
        goal.command.max_effort = effort
        self.gripper_client.send_goal(goal)
        finished_within_time = self.gripper_client.wait_for_result(
            rospy.Duration(15))
        if not (finished_within_time):
            self.gripper_client.cancel_goal()
            rospy.loginfo("Timed out moving " + self.arm + " gripper")
            return False
        else:
            state = self.gripper_client.get_state()
            result = self.gripper_client.get_result()
            if (state == 3):  #3 == SUCCEEDED
                rospy.loginfo("Gripper Action Succeeded")
                return True
            else:
                rospy.loginfo("Gripper Action Failed")
                rospy.loginfo("Failure Result: %s" % result)
                return False

    def pose_relative_trans(self, pose, x=0., y=0., z=0.):
        """Return a pose translated relative to a given pose."""
        ps = deepcopy(pose)
        M_trans = tft.translation_matrix([x, y, z])
        q_ps = [
            ps.pose.orientation.x, ps.pose.orientation.y,
            ps.pose.orientation.z, ps.pose.orientation.w
        ]
        M_rot = tft.quaternion_matrix(q_ps)
        trans = np.dot(M_rot, M_trans)
        ps.pose.position.x += trans[0][-1]
        ps.pose.position.y += trans[1][-1]
        ps.pose.position.z += trans[2][-1]
        #print ps
        return ps

    def pose_relative_rot(self, pose, r=0., p=0., y=0., degrees=True):
        """Return a pose rotated relative to a given pose."""
        ps = deepcopy(pose)
        if degrees:
            r = math.radians(r)
            p = math.radians(p)
            y = math.radians(y)
        des_rot_mat = tft.euler_matrix(r, p, y)
        q_ps = [
            ps.pose.orientation.x, ps.pose.orientation.y,
            ps.pose.orientation.z, ps.pose.orientation.w
        ]
        state_rot_mat = tft.quaternion_matrix(q_ps)
        final_rot_mat = np.dot(state_rot_mat, des_rot_mat)
        ps.pose.orientation = Quaternion(
            *tft.quaternion_from_matrix(final_rot_mat))
        return ps

    def find_approach(self, pose, standoff=0., axis='x'):
        """Return a PoseStamped pointed down the z-axis of input pose."""
        ps = deepcopy(pose)
        if axis == 'x':
            ps = self.pose_relative_rot(ps, p=90)
            ps = self.pose_relative_trans(ps, -standoff)
        return ps

    def calc_dist(self, ps1, ps2):
        """ Return the cartesian distance between the points of 2 poses."""
        p1 = ps1.pose.position
        p2 = ps2.pose.position
        return math.sqrt((p1.x - p2.x)**2 + (p1.y - p2.y)**2 +
                         (p1.z - p2.z)**2)

    def hand_frame_move(self, x, y=0, z=0, duration=None):
        cp = self.curr_pose()
        newpose = self.pose_relative_trans(cp, x, y, z)
        self.dist = self.calc_dist(cp, newpose)
        return newpose

    def build_trajectory(self,
                         finish,
                         start=None,
                         ik_space=0.10,
                         duration=None,
                         tot_points=None):
        if start == None:  # if given one pose, use current position as start, else, assume (start, finish)
            start = self.curr_pose()
            print "start fro curr_pos"
            print start

        #TODO: USE TF TO BASE DISTANCE ON TOOL_FRAME MOVEMENT DISTANCE, NOT WRIST_ROLL_LINK

        # Based upon distance to travel, determine the number of intermediate steps required
        # find linear increments of position.

        print "finish pose"
        print finish
        dist = self.calc_dist(start, finish)  #Total distance to travel
        ik_steps = int(round(dist / ik_space) + 1.)
        rospy.loginfo("IK Steps: %s  Distance: %s " % (ik_steps, dist))
        if tot_points is None:
            tot_points = 1500 * dist
        if duration is None:
            duration = dist * 120

        ik_fracs = np.linspace(
            0, 1, ik_steps
        )  #A list of fractional positions along course to evaluate ik
        tot_points = ik_steps  # ARD
        ang_fracs = np.linspace(0, 1, tot_points)

        seed = None
        x_gap = finish.pose.position.x - start.pose.position.x
        y_gap = finish.pose.position.y - start.pose.position.y
        z_gap = finish.pose.position.z - start.pose.position.z
        print "Arm gaps: x ", x_gap, " y ", y_gap, " z ", z_gap

        qs = [
            start.pose.orientation.x, start.pose.orientation.y,
            start.pose.orientation.z, start.pose.orientation.w
        ]
        qf = [
            finish.pose.orientation.x, finish.pose.orientation.y,
            finish.pose.orientation.z, finish.pose.orientation.w
        ]

        #For each step between start and finish, find a complete pose (linear position changes, and quaternion slerp)
        steps = [PoseStamped() for i in range(len(ik_fracs))]
        for i, frac in enumerate(ik_fracs):
            steps[i].header.stamp = rospy.Time.now()
            steps[i].header.frame_id = start.header.frame_id
            steps[i].pose.position.x = start.pose.position.x + x_gap * frac
            steps[i].pose.position.y = start.pose.position.y + y_gap * frac
            # steps[i].pose.position.z = start.pose.position.z + z_gap*frac
            # ARD: Chess hack for torso height.  Really should fix time on tf?
            steps[
                i].pose.position.z = start.pose.position.z + z_gap * frac - .3
            # steps[i].pose.position.z = start.pose.position.z + z_gap*frac
            new_q = transformations.quaternion_slerp(qs, qf, frac)
            steps[i].pose.orientation.x = new_q[0]
            steps[i].pose.orientation.y = new_q[1]
            steps[i].pose.orientation.z = new_q[2]
            steps[i].pose.orientation.w = new_q[3]
        rospy.loginfo("Planning straight-line path, please wait")
        self.log_out.publish(data="Planning straight-line path, please wait")
        rospy.loginfo("frameid %s %s" %
                      (start.header.frame_id, finish.header.frame_id))

        #Find initial ik for seeding
        req = self.form_constraint_aware_ik_request(steps[0])
        ik_goal = self.ik_constraint_aware_pose_proxy(req)
        print "IK goal"
        print req
        # print req.pose_stamped.pose.position
        # print req.ik_seed_state.name
        # print req.ik_seed_state.position
        for i, name in enumerate(ik_goal.solution.joint_state.name):
            rospy.loginfo("traj joints %s" % name)
            if name == 'left_upper_arm_hinge_joint' or name == 'right_upper_arm_hinge_joint':
                hinge_index = i
            elif name == 'left_shoulder_tilt_joint' or name == 'right_shoulder_tilt_joint':
                shoulder_tilt_index = i

        if len(ik_goal.solution.joint_state.position) == 0:
            print "initial seeding failed"
            seed = None
        #ik_points = list([[0]*7 for i in range(len(ik_fracs))])
        ik_points = list()
        ik_fracs2 = list()
        for i, p in enumerate(steps):
            if (i == 0):
                continue
            #request = self.form_ik_request(p)
            request = self.form_constraint_aware_ik_request(p)
            if seed != None:
                request.ik_request.ik_seed_state.joint_state.position = seed
                request.ik_request.ik_seed_state.joint_state.name = ik_goal.solution.joint_state.name
            ik_goal = self.ik_constraint_aware_pose_proxy(request)
            print "IK goal %d" % (i)
            print request
            # print request.pose_stamped.pose.position
            # print request.ik_seed_state.name
            # print request.ik_seed_state.position
            if len(ik_goal.solution.joint_state.position) != 0:
                seed = list(ik_goal.solution.joint_state.position
                            )  # seed the next ik w/previous points results
                seed[hinge_index] = -1 * seed[shoulder_tilt_index]
                ik_points.append(ik_goal.solution.joint_state.position)
                ik_fracs2.append(ik_fracs[i])
                print "IK solution for %d" % i
            else:
                print "No solution for %d" % i

        rospy.loginfo("linear interp")
        ik_fracs = ik_fracs2
        if len(ik_points) == 0:
            return None

        ik_points = np.array(ik_points)
        # Linearly interpolate angles 10 times between ik-defined points (non-linear in cartesian space, but this is reduced from dense ik sampling along linear path.  Used to maintain large number of trajectory points without running IK on every one.
        angle_points = np.zeros((7, tot_points))
        for i in xrange(7):
            angle_points[i, :] = np.interp(ang_fracs, ik_fracs, ik_points[:,
                                                                          i])

        #Build Joint Trajectory from angle positions
        traj = JointTrajectory()
        traj.header.frame_id = steps[0].header.frame_id
        traj.joint_names = self.ik_info.kinematic_solver_info.joint_names
        for name in traj.joint_names:
            rospy.loginfo("traj joints %s" % name)
        #print 'angle_points', len(angle_points[0]), angle_points
        for i in range(len(angle_points[0])):
            traj.points.append(JointTrajectoryPoint())
            traj.points[i].positions = angle_points[:, i]
            traj.points[i].velocities = [0] * 7
            traj.points[i].time_from_start = rospy.Duration(ang_fracs[i] *
                                                            duration)
        return traj

    def build_follow_trajectory(self, traj):
        # Build 'Follow Joint Trajectory' goal from trajectory (includes tolerances for error)
        traj_goal = FollowJointTrajectoryGoal()
        traj_goal.trajectory = traj
        tolerance = JointTolerance()
        tolerance.position = 0.05
        tolerance.velocity = 0.1
        traj_goal.path_tolerance = [tolerance for i in range(len(traj.points))]
        traj_goal.goal_tolerance = [tolerance for i in range(len(traj.points))]
        traj_goal.goal_time_tolerance = rospy.Duration(3)
        return traj_goal

    def follow_trajectory(self, traj_goal):
        self.arm_traj_client.send_goal(traj_goal)
        self.arm_traj_client.wait_for_result(rospy.Duration(200))

    def move_to_tolerance(self, pose):
        attempt = 0
        prevdist = 0
        while True:
            attempt += 1
            print "Attempt %d" % attempt
            traj = self.build_trajectory(pose, None)
            if traj != None:
                goal = self.build_follow_trajectory(traj)
                self.follow_trajectory(goal)
            curpos = self.curr_pose()
            x_gap = pose.pose.position.x - curpos.pose.position.x
            y_gap = pose.pose.position.y - curpos.pose.position.y
            z_gap = pose.pose.position.z - curpos.pose.position.z
            dist = self.calc_dist(curpos, pose)  #Total distance to travel
            print "Arm dist ", dist, " gaps: x ", x_gap, " y ", y_gap, " z ", z_gap
            if abs(x_gap) <= pose.absolute_position_tolerance.x and abs(
                    y_gap) <= pose.absolute_position_tolerance.y and abs(
                        z_gap) <= pose.absolute_position_tolerance.z:
                return
            if abs(dist - prevdist) < .001:  # .04 inches
                return
            prevdist = dist

    def move_torso(self, pos):
        rospy.loginfo("Moving Torso to reach arm goal")
        goal_out = SingleJointPositionGoal()
        goal_out.position = pos
        self.torso_client.send_goal(goal_out)
        return True

    def fast_move(self, ps, time=0.):
        ik_goal = self.ik_pose_proxy(self.form_ik_request(ps))
        if ik_goal.error_code.val == 1:
            point = JointTrajectoryPoint()
            point.positions = ik_goal.solution.joint_state.position
            self.send_traj_point(point)
        else:
            rospy.logerr("FAST MOVE IK FAILED!")

    def blind_move(self, ps, duration=None):
        (reachable, ik_goal, duration) = self.full_ik_check(ps)
        if reachable:
            self.send_joint_angles(ik_goal.solution.joint_state.position,
                                   duration)

    def check_torso(self, request):
        """
        For unreachable goals, check to see if moving the torso can solve
        the problem.  If yes, return True, and torso adjustment needed.
        If no, return False, and best possible Torso adjustment.
        """
        goal_z = request.ik_request.pose_stamped.pose.position.z
        torso_pos = self.torso_state.actual.positions[0]
        spine_range = [self.torso_min - torso_pos, self.torso_max - torso_pos]

        if abs(goal_z) < 0.005:
            #Already at best position, dont try more (avoid moving to noise)
            rospy.loginfo("Torso Already at best possible position")
            return [False, 0]
        #Find best possible case: shoulder @ goal height, max up, or max down.
        if goal_z >= spine_range[0] and goal_z <= spine_range[1]:
            rospy.loginfo("Goal within spine movement range")
            request.ik_request.pose_stamped.pose.position.z = 0
            opt_tor_move = goal_z
        elif goal_z > spine_range[1]:  #Goal is above possible shoulder height
            rospy.loginfo("Goal above spine movement range")
            request.ik_request.pose_stamped.pose.position.z -= spine_range[1]
            opt_tor_move = spine_range[1]
        else:  #Goal is below possible shoulder height
            rospy.loginfo("Goal below spine movement range")
            request.ik_request.pose_stamped.pose.position.z -= spine_range[0]
            opt_tor_move = spine_range[0]
        #Check best possible case
        print "Optimal Torso move: ", opt_tor_move
        ik_goal = self.ik_pose_proxy(request)
        if ik_goal.error_code.val != 1:
            #Return false: Not achievable, even for best case
            rospy.loginfo("Original goal cannot be reached")
            self.log_out.publish(data="Original goal cannot be reached")
            return [False, opt_tor_move]
        opt_ik_goal = ik_goal

        #Achievable: Find a reasonable solution, move torso, return true
        rospy.loginfo("Goal can be reached by moving spine")
        self.log_out.publish(data="Goal can be reached by moving spine")
        trials = np.linspace(0, opt_tor_move, round(abs(opt_tor_move) / 0.05))
        np.append(trials, opt_tor_move)
        rospy.loginfo("Torso far from best position, finding closer sol.")
        print "Trials: ", trials
        for trial in trials:
            request.ik_request.pose_stamped.pose.position.z = goal_z + trial
            print "Trying goal @ ", goal_z + trial
            ik_goal = self.ik_pose_proxy(request)
            if ik_goal.error_code.val == 1:
                rospy.loginfo("Tried: %s, Succeeded" % trial)
                return [True, trial]
            rospy.loginfo("Tried: %s, Failed" % trial)
        #Broke through somehow, catch error
        return [True, opt_tor_move]

    def full_ik_check(self, ps):
        #Check goal as given, if reachable, return true
        req = self.form_ik_request(ps)
        ik_goal = self.ik_pose_proxy(req)
        if ik_goal.error_code.val == 1:
            self.dist = self.calc_dist(self.curr_pose(), ps)
            return (True, ik_goal, None)
        #Check goal with vertical torso movement, if works, return true
        (torso_succeeded, torso_move) = self.check_torso(req)
        self.move_torso(self.torso_state.actual.positions[0] + torso_move)
        duration = max(4, 85 * abs(torso_move))
        if torso_succeeded:
            ik_goal = self.ik_pose_proxy(req)
            self.dist = self.calc_dist(self.curr_pose(), ps)
            if ik_goal.error_code.val == 1:
                return (True, ik_goal, duration)
            else:
                print "Reported Succeeded, then really failed: \r\n", ik_goal

        #Check goal incrementally retreating hand pose, if works, return true
        pct = 0.98
        curr_pos = self.curr_pose().pose.position
        dx = req.ik_request.pose_stamped.pose.position.x - curr_pos.x
        dy = req.ik_request.pose_stamped.pose.position.y - curr_pos.y
        while pct > 0.01:
            #print "Percent: %s" %pct
            req.ik_request.pose_stamped.pose.position.x = curr_pos.x + pct * dx
            req.ik_request.pose_stamped.pose.position.y = curr_pos.y + pct * dy
            ik_goal = self.ik_pose_proxy(req)
            if ik_goal.error_code.val == 1:
                rospy.loginfo("Succeeded PARTIALLY (%s) with torso" % pct)
                return (True, ik_goal, duration)
            else:
                pct -= 0.02
        #Nothing worked, report failure, return false
        rospy.loginfo("IK Failed: Error Code %s" % str(ik_goal.error_code))
        rospy.loginfo("Reached as far as possible")
        self.log_out.publish(data="Cannot reach farther in this direction.")
        return (False, ik_goal, duration)

    def form_constraint_aware_ik_request(self, ps):
        #print "forming IK request for :%s" %ps
        req = GetConstraintAwarePositionIKRequest()
        req.timeout = rospy.Duration(5)
        req.ik_request.pose_stamped = ps
        req.ik_request.ik_link_name = \
                    self.ik_info.kinematic_solver_info.link_names[-1]
        req.ik_request.ik_seed_state.joint_state.name = \
                    self.ik_info.kinematic_solver_info.joint_names
        req.ik_request.ik_seed_state.joint_state.position = \
                    self.joint_state_pos
        return req

    def form_ik_request(self, ps):
        #print "forming IK request for :%s" %ps
        req = GetPositionIKRequest()
        req.timeout = rospy.Duration(5)
        req.ik_request.pose_stamped = ps
        req.ik_request.ik_link_name = \
                    self.ik_info.kinematic_solver_info.link_names[-1]
        req.ik_request.ik_seed_state.joint_state.name = \
                    self.ik_info.kinematic_solver_info.joint_names
        req.ik_request.ik_seed_state.joint_state.position = \
                    self.joint_state_pos
        return req

    def send_joint_angles(self, angles, duration=None):
        point = JointTrajectoryPoint()
        point.positions = angles
        self.send_traj_point(point, duration)

    def send_traj_point(self, point, time=None):
        if time is None:
            point.time_from_start = rospy.Duration(max(20 * self.dist, 4))
        else:
            point.time_from_start = rospy.Duration(time)
        joint_traj = JointTrajectory()
        joint_traj.header.stamp = rospy.Time.now()
        # ARD
        # joint_traj.header.frame_id = '/torso_lift_link'
        joint_traj.header.frame_id = 'base_link'
        joint_traj.joint_names = self.ik_info.kinematic_solver_info.joint_names
        joint_traj.points.append(point)
        joint_traj.points[0].velocities = [0, 0, 0, 0, 0, 0, 0]
        arm_goal = JointTrajectoryGoal()
        arm_goal.trajectory = joint_traj
        self.arm_traj_client.send_goal(arm_goal)
コード例 #32
0
class ur5_grasp_project(object):
    def __init__(self, joint_values=None):
        rospy.init_node('command_GGCNN_ur5')
        self.joint_values_home = joint_values

        self.tf = TransformListener()

        # Used to change the controller
        self.controller_switch = rospy.ServiceProxy(
            '/controller_manager/switch_controller', SwitchController)

        # actionClient used to send joint positions
        self.client = actionlib.SimpleActionClient(
            'pos_based_pos_traj_controller/follow_joint_trajectory',
            FollowJointTrajectoryAction)
        print("Waiting for server (pos_based_pos_traj_controller)...")
        self.client.wait_for_server()
        print("Connected to server (pos_based_pos_traj_controller)")

        self.picking = False  # Tells the node that the object must follow the gripper

        ##################
        # Gazebo Related #
        ##################
        if args.gazebo:
            self.get_model_coordinates = rospy.ServiceProxy(
                '/gazebo/get_link_state', GetLinkState)
            self.grasp_started = rospy.Publisher(
                'grasp_started', Bool, queue_size=1)  # Detection flag
            self.grasp_object_name = rospy.Publisher('grasp_object_name',
                                                     String,
                                                     queue_size=1)
            self.grasp_object_position = rospy.Publisher(
                'grasp_object_position', Pose, queue_size=1)

            # Subscriber used to read joint values
            rospy.Subscriber('/joint_states',
                             JointState,
                             self.ur5_actual_position_callback,
                             queue_size=1)
            rospy.sleep(1.0)

            # USED FOR COLLISION DETECTION
            self.finger_links = [
                'robotiq_85_right_finger_tip_link',
                'robotiq_85_left_finger_tip_link'
            ]
            # LEFT GRIPPER
            self.string = ""
            rospy.Subscriber(
                '/left_finger_bumper_vals', ContactsState,
                self.monitor_contacts_left_finger_callback)  # ContactState
            self.left_collision = False
            self.contactState_left = ContactState()
            # RIGHT GRIPPER
            rospy.Subscriber(
                '/right_finger_bumper_vals', ContactsState,
                self.monitor_contacts_right_finger_callback)  # ContactState
            self.right_collision = False
            self.contactState_right = ContactState()

            self.client_gripper = actionlib.SimpleActionClient(
                'gripper_controller_pos/follow_joint_trajectory',
                FollowJointTrajectoryAction)
            print("Waiting for server (gripper_controller_pos)...")
            self.client_gripper.wait_for_server()
            print("Connected to server (gripper_controller_pos)")

        #################
        # GGCNN Related #
        #################
        self.posCB = []
        self.ori = []
        self.grasp_cartesian_pose = []
        self.gripper_angle_grasp = 0.0
        self.final_orientation = 0.0
        if args.gazebo:
            self.GGCNN_offset_x = 0.0
            self.GGCNN_offset_y = 0.0
            self.GGCNN_offset_z = 0.020  # 0.019
        else:
            self.GGCNN_offset_x = -0.03  # 0.002
            self.GGCNN_offset_y = 0.02  # -0.05
            self.GGCNN_offset_z = 0.058  # 0.013

        self.ur5_joint_names = rospy.get_param("/ur5_joint_names")
        self.robotiq_joint_name = rospy.get_param("/robotiq_joint_name")

        # Topic published from GG-CNN Node
        rospy.Subscriber('ggcnn/out/command',
                         Float32MultiArray,
                         self.ggcnn_command_callback,
                         queue_size=1)

        ####################
        # Pipeline Related #
        ####################
        self.classes = rospy.get_param("/classes")

        # Topics related to the new grasping pipeline
        rospy.Subscriber('flags/grasp_ready',
                         Bool,
                         self.grasp_ready_callback,
                         queue_size=1)  # Grasp flag
        rospy.Subscriber('flags/reposition_robot_flag',
                         Bool,
                         self.reposition_robot_callback,
                         queue_size=1)  # Reposition flag
        rospy.Subscriber('flags/detection_ready',
                         Bool,
                         self.detection_ready_callback,
                         queue_size=1)  # Detection flag
        rospy.Subscriber('reposition_coord',
                         Float32MultiArray,
                         self.reposition_coord_callback,
                         queue_size=1)
        rospy.Subscriber('/selective_grasping/tag_detections',
                         Int16MultiArray,
                         self.tags_callback,
                         queue_size=1)

        self.tags = [
            'tag_0_corrected', 'tag_1_corrected', 'tag_2_corrected',
            'tag_3_corrected', 'tag_4_corrected', 'tag_5_corrected',
            'tag_6_corrected', 'tag_7_corrected'
        ]

        if args.gazebo:
            self.tags_position_offset = [0.062, 0.0, 0.062]

        self.grasp_flag = False
        self.detected_tags = []

        self.require_class = rospy.Publisher('pipeline/required_class',
                                             Int8,
                                             queue_size=1)

        ###################
        # Robotiq Related #
        ###################
        self.pub_gripper_command = rospy.Publisher(
            'Robotiq2FGripperRobotOutput',
            outputMsg.Robotiq2FGripper_robot_output,
            queue_size=1)
        self.d = None  # msg received from GGCN
        self.gripper_max_width = 0.14

    def turn_velocity_controller_on(self):
        self.controller_switch(['joint_group_vel_controller'],
                               ['pos_based_pos_traj_controller'], 1)

    def turn_position_controller_on(self):
        self.controller_switch(['pos_based_pos_traj_controller'],
                               ['joint_group_vel_controller'], 1)

    def turn_gripper_velocity_controller_on(self):
        self.controller_switch(['gripper_controller_vel'],
                               ['gripper_controller_pos'], 1)

    def turn_gripper_position_controller_on(self):
        self.controller_switch(['gripper_controller_pos'],
                               ['gripper_controller_vel'], 1)

    def tags_callback(self, msg):
        self.detected_tags = msg.data

    def grasp_ready_callback(self, msg):
        self.grasp_flag = msg.data

    def detection_ready_callback(self, msg):
        self.detection_ready_flag = msg.data

    def reposition_robot_callback(self, msg):
        self.reposition_robot_flag = msg.data

    def reposition_coord_callback(self, msg):
        self.reposition_coords = msg.data

    def monitor_contacts_left_finger_callback(self, msg):
        if msg.states:
            self.left_collision = True
            string = msg.states[0].collision1_name
            string_collision = re.findall(r'::(.+?)::', string)[0]
            # print("Left String_collision: ", string_collision)
            if string_collision in self.finger_links:
                string = msg.states[0].collision2_name
                # print("Left Real string (object): ", string)
                self.string = re.findall(r'::(.+?)::', string)[0]
                # print("Left before: ", self.string)
            else:
                self.string = string_collision
                # print("Left in else: ", string_collision)
        else:
            self.left_collision = False

    def monitor_contacts_right_finger_callback(self, msg):
        if msg.states:
            self.right_collision = True
            string = msg.states[0].collision1_name
            string_collision = re.findall(r'::(.+?)::', string)[0]
            # print("Right String_collision: ", string_collision)
            if string_collision in self.finger_links:
                string = msg.states[0].collision2_name
                # print("Right Real string (object): ", string)
                self.string = re.findall(r'::(.+?)::', string)[0]
                # print("Right before: ", self.string)
            else:
                self.string = string_collision
                # print("Right in else: ", self.string)
        else:
            self.right_collision = False

    def ur5_actual_position_callback(self, joint_values_from_ur5):
        """Get UR5 joint angles
		
		The joint states published by /joint_staes of the UR5 robot are in wrong order.
		/joint_states topic normally publishes the joint in the following order:
		[elbow_joint, shoulder_lift_joint, shoulder_pan_joint, wrist_1_joint, wrist_2_joint, wrist_3_joint]
		But the correct order of the joints that must be sent to the robot is:
		['shoulder_pan_joint', 'shoulder_lift_joint', 'elbow_joint', 'wrist_1_joint', 'wrist_2_joint', 'wrist_3_joint']
		
		Arguments:
			joint_values_from_ur5 {list} -- Actual angles of the UR5 Robot
		"""
        if args.gazebo:
            self.th3, self.robotic, self.th2, self.th1, self.th4, self.th5, self.th6 = joint_values_from_ur5.position
            # print("Robotic angle: ", self.robotic)
        else:
            self.th3, self.th2, self.th1, self.th4, self.th5, self.th6 = joint_values_from_ur5.position

        self.actual_position = [
            self.th1, self.th2, self.th3, self.th4, self.th5, self.th6
        ]

    def ggcnn_command_callback(self, msg):
        """
		GGCNN Command Subscriber Callback
		"""
        self.tf.waitForTransform("base_link", "object_detected", rospy.Time(0),
                                 rospy.Duration(4.0))  # rospy.Time.now()
        object_pose, object_ori = self.tf.lookupTransform(
            "base_link", "object_detected", rospy.Time(0))
        self.d = list(msg.data)
        object_pose[0] += self.GGCNN_offset_x
        object_pose[1] += self.GGCNN_offset_y
        object_pose[2] += self.GGCNN_offset_z

        self.posCB = object_pose

        self.ori = self.d[3]
        br = TransformBroadcaster()
        br.sendTransform((object_pose[0], object_pose[1], object_pose[2]),
                         quaternion_from_euler(0.0, 0.0, self.ori),
                         rospy.Time.now(), "object_link", "base_link")

    def get_link_position_picking(self):
        link_name = self.string
        model_coordinates = self.get_model_coordinates(self.string,
                                                       'wrist_3_link')
        self.model_pose_picking = model_coordinates.link_state.pose
        self.grasp_object_position.publish(
            Pose(self.model_pose_picking.position,
                 self.model_pose_picking.orientation))

    def get_ik(self, position):
        """Get the inverse kinematics 
		
		Get the inverse kinematics of the UR5 robot using track_IK package giving a desired intial position
		
		Arguments:
			position {list} -- A position representing x, y and z

		Returns:
			sol {list} -- Joint angles or None if track_ik is not able to find a valid solution
		"""

        camera_support_angle_offset = 0.0

        q = quaternion_from_euler(0.0, -3.14 + camera_support_angle_offset,
                                  0.0)
        # Joint order:
        # ('shoulder_link', 'upper_arm_link', 'forearm_link', 'wrist_1_link', 'wrist_2_link', 'wrist_3_link', 'grasping_link')
        ik_solver = IK("base_link", "grasping_link", solve_type="Distance")
        sol = ik_solver.get_ik([
            0.2201039360819781, -1.573845095552878, -1.521853400505349,
            -1.6151347051274518, 1.5704492904506875, 0.0
        ], position[0], position[1], position[2], q[0], q[1], q[2], q[3])

        if sol is not None:
            sol = list(sol)
            sol[-1] = 0.0
        else:
            print("IK didn't return any solution")

        return sol

    def __build_goal_message_ur5(self):
        goal = FollowJointTrajectoryGoal()
        goal.trajectory = JointTrajectory()
        goal.trajectory.joint_names = self.ur5_joint_names
        goal.goal_tolerance.append(
            JointTolerance('joint_tolerance', 0.1, 0.1, 0))
        goal.goal_time_tolerance = rospy.Duration(5, 0)
        return goal

    def traj_planner(self,
                     cart_pos,
                     grasp_step='move',
                     way_points_number=10,
                     movement='slow'):
        """Quintic Trajectory Planner
		
		Publish a trajectory to UR5 using quintic splines. 
		
		Arguments:
			cart_pos {[float]} -- Grasp position [x, y, z]
		
		Keyword Arguments:
			grasp_step {str} -- Set UR5 movement type (default: {'move'})
			way_points_number {number} -- Number of points considered in trajectory (default: {10})
			movement {str} -- Movement speed (default: {'slow'})
		"""

        offset_from_object = 0.05
        if grasp_step == 'pregrasp':
            self.grasp_cartesian_pose = deepcopy(self.posCB)
            self.grasp_cartesian_pose[-1] += offset_from_object
            joint_pos = self.get_ik(self.grasp_cartesian_pose)
            if joint_pos is not None:
                joint_pos[-1] = self.ori
                self.final_orientation = deepcopy(self.ori)
                self.gripper_angle_grasp = deepcopy(self.d[-2])
        elif grasp_step == 'grasp':
            self.grasp_cartesian_pose[-1] -= offset_from_object
            joint_pos = self.get_ik(self.grasp_cartesian_pose)
            if joint_pos is not None:
                joint_pos[-1] = self.final_orientation
        elif grasp_step == 'move':
            joint_pos = self.get_ik(cart_pos)
            if joint_pos is not None:
                joint_pos[-1] = 0.0

        if joint_pos is not None:
            if movement == 'slow':
                final_traj_duration = 500.0  # total iteractions
            elif movement == 'fast':
                final_traj_duration = 350.0

            v0 = a0 = vf = af = 0
            t0 = 5.0
            tf = (t0 +
                  final_traj_duration) / way_points_number  # tf by way point
            t = tf / 10  # for each movement
            ta = tf / 10  # to complete each movement
            a = [0.0] * 6
            pos_points, vel_points, acc_points = [0.0] * 6, [0.0] * 6, [0.0
                                                                        ] * 6

            goal = self.__build_goal_message_ur5()

            for i in range(6):
                q0 = self.actual_position[i]
                qf = joint_pos[i]

                b = np.array([q0, v0, a0, qf, vf, af]).transpose()
                m = np.array([[1, t0, t0**2, t0**3, t0**4, t0**5],
                              [0, 1, 2 * t0, 3 * t0**2, 4 * t0**3, 5 * t0**4],
                              [0, 0, 2, 6 * t0, 12 * t0**2, 20 * t0**3],
                              [1, tf, tf**2, tf**3, tf**4, tf**5],
                              [0, 1, 2 * tf, 3 * tf**2, 4 * tf**3, 5 * tf**4],
                              [0, 0, 2, 6 * tf, 12 * tf**2, 20 * tf**3]])
                a[i] = np.linalg.inv(m).dot(b)

            for i in range(way_points_number):
                for j in range(6):
                    pos_points[j] = a[j][0] + a[j][1] * t + a[j][2] * t**2 + a[
                        j][3] * t**3 + a[j][4] * t**4 + a[j][5] * t**5
                    vel_points[j] = a[j][1] + 2 * a[j][2] * t + 3 * a[j][
                        3] * t**2 + 4 * a[j][4] * t**3 + 5 * a[j][5] * t**4
                    acc_points[j] = 2 * a[j][2] + 6 * a[j][3] * t + 12 * a[j][
                        4] * t**2 + 20 * a[j][5] * t**3

                goal.trajectory.points.append(
                    JointTrajectoryPoint(
                        positions=pos_points,
                        velocities=vel_points,
                        accelerations=acc_points,
                        time_from_start=rospy.Duration(t)))  #default 0.1*i + 5
                t += ta

            self.client.send_goal(goal)
            self.all_close(joint_pos)
        else:
            print('Could not find a IK solution')

    def all_close(self, goal, tolerance=0.00005):
        """Wait until goal is reached in configuration space
		
		This method check if the robot reached goal position since wait_for_result seems to be broken

		
		Arguments:
			goal {[list]} -- Goal in configuration space (joint values)
		
		Keyword Arguments:
			tolerance {number} -- Minimum error allowed to consider the trajectory completed (default: {0.00005})
		"""

        error = np.sum([(self.actual_position[i] - goal[i])**2
                        for i in range(6)])
        print("> Waiting for the trajectory to finish...")
        while not rospy.is_shutdown() and error > tolerance:
            error = np.sum([(self.actual_position[i] - goal[i])**2
                            for i in range(6)])
        if error < tolerance:
            print(
                "> Trajectory Suceeded!\n")  # whithin the tolerance specified
        else:
            rospy.logerr("> Trajectory aborted.")

    def genCommand(self, char, command, pos=None):
        """
		Update the command according to the character entered by the user.
		"""
        if char == 'a':
            # command = outputMsg.Robotiq2FGripper_robot_output();
            command.rACT = 1  # Gripper activation
            command.rGTO = 1  # Go to position request
            command.rSP = 255  # Speed
            command.rFR = 150  # Force

        if char == 'r':
            command.rACT = 0

        if char == 'c':
            command.rACT = 1
            command.rGTO = 1
            command.rATR = 0
            command.rPR = 255
            command.rSP = 40
            command.rFR = 150

        # @param pos Gripper width in meters. [0, 0.087]
        if char == 'p':
            command.rACT = 1
            command.rGTO = 1
            command.rATR = 0
            command.rPR = int(
                np.clip(
                    (13. - 230.) / self.gripper_max_width * self.ori + 230., 0,
                    255))
            command.rSP = 40
            command.rFR = 150

        if char == 'o':
            command.rACT = 1
            command.rGTO = 1
            command.rATR = 0
            command.rPR = 0
            command.rSP = 40
            command.rFR = 150

        return command

    def command_gripper(self, action):
        command = outputMsg.Robotiq2FGripper_robot_output()
        command = self.genCommand(action, command)
        self.pub_gripper_command.publish(command)

    def gripper_send_position_goal(self,
                                   position=0.3,
                                   velocity=0.4,
                                   action='move'):
        """Send position goal to the gripper
		
		Keyword Arguments:
			position {float} -- Gripper angle (default: {0.3})
			velocity {float} -- Gripper velocity profile (default: {0.4})
			action {str} -- Gripper movement (default: {'move'})
		"""

        self.turn_gripper_position_controller_on()
        duration = 0.2
        if action == 'pre_grasp_angle':
            max_distance = 0.085
            angular_coeff = 0.11
            K = 1  # lower numbers = higher angles
            angle = (max_distance -
                     self.gripper_angle_grasp) / angular_coeff * K
            position = angle
            velocity = 0.4
        elif action == 'pick':
            position = 0.7
            velocity = 0.05
            duration = 8.0

        goal = FollowJointTrajectoryGoal()
        goal.trajectory = JointTrajectory()
        goal.trajectory.joint_names = self.robotiq_joint_name
        goal.trajectory.points.append(
            JointTrajectoryPoint(positions=[position],
                                 velocities=[velocity],
                                 accelerations=[0.0],
                                 time_from_start=rospy.Duration(duration)))
        self.client_gripper.send_goal(goal)
        if action == 'pick':
            while not rospy.is_shutdown(
            ) and not self.left_collision and not self.right_collision:
                pass
            self.client_gripper.cancel_goal()

    def move_home_on_shutdown(self):
        self.client.cancel_goal()
        self.client_gripper.cancel_goal()
        print("Shutting down node...")

    def grasp_main(self, point_init_home, depth_shot_point):
        random_classes = [i for i in range(len(self.classes))]

        bin_location = [[-0.65, -0.1, 0.2], [-0.65, 0.1, 0.2]]
        garbage_location = [-0.4, -0.30, 0.10]

        raw_input('=== Press enter to start the grasping process')
        while not rospy.is_shutdown():
            # The grasp is performed randomly and the chosen object is published to
            # the detection node
            if not len(random_classes):
                print(
                    "\n> IMPORTANT! There is no object remaining in the object's picking list. Resetting the objects list...\n"
                )
                random_classes = [i for i in range(len(self.classes))]

            random_object_id = random.sample(random_classes, 1)[0]
            random_classes.pop(random_classes.index(random_object_id))
            print('> Object to pick: ', self.classes[random_object_id])

            self.require_class.publish(random_object_id)

            # Before pressing ENTER you should observe if the GG-CNN is getting the
            # right grasp on the selected object (green point in the grasp image)
            # just for safety
            raw_input("==== Press enter to start the grasping process!")

            if self.detection_ready_flag:
                if self.reposition_robot_flag:
                    print('repos flag: ', self.reposition_robot_flag)
                    print('> Repositioning robot...')
                    self.tf.waitForTransform("base_link", "grasping_link",
                                             rospy.Time.now(),
                                             rospy.Duration(4.0))
                    eef_pose, _ = self.tf.lookupTransform(
                        "base_link", "grasping_link", rospy.Time(0))

                    corrected_position = [
                        eef_pose[0] - self.reposition_coords[1],
                        eef_pose[1] + self.reposition_coords[0], eef_pose[2]
                    ]

                    self.traj_planner(corrected_position, movement='fast')
                    raw_input("==== Press enter when the trajectory finishes!")

                if self.grasp_flag and self.detection_ready_flag and not self.reposition_robot_flag:
                    print('> Moving to the grasping position... \n')
                    # print("Grasp flag: " + str(self.grasp_flag))
                    # print("Reposition robot flag: " + str( self.reposition_robot_flag))
                    self.traj_planner([], 'pregrasp', movement='fast')

                    # It closes the gripper before approaching the object
                    # It prevents the gripper to collide with other objects when grasping
                    if args.gazebo:
                        self.gripper_send_position_goal(
                            action='pre_grasp_angle')
                    else:
                        self.command_gripper('p')

                    # Moving the robot to pick the object - BE CAREFULL!
                    self.traj_planner([], 'grasp', movement='slow')

                    print("Picking object...")
                    if args.gazebo:
                        self.gripper_send_position_goal(action='pick')
                        self.get_link_position_picking()
                        self.grasp_started.publish(True)
                        self.grasp_object_name.publish(self.string)
                    else:
                        raw_input("==== Press enter to close the gripper!")
                        self.command_gripper('c')

                    # After a collision is detected, the arm will start the picking action
                    raw_input("==== Press enter to move the object to the bin")
                    if random_object_id < 5:
                        self.traj_planner(bin_location[0], movement='fast')
                    else:
                        self.traj_planner(bin_location[1], movement='fast')

                    rospy.sleep(2.0)  # waiting for the tag detections
                    number_of_detected_tags = sum(self.detected_tags)

                    if number_of_detected_tags:
                        selected_tag_status = self.detected_tags[
                            random_object_id]  # if the tag was detected or not
                        print('selected tag: ', self.tags[random_object_id])
                        if selected_tag_status:
                            self.tf.waitForTransform(
                                "base_link", self.tags[random_object_id],
                                rospy.Time(0),
                                rospy.Duration(2.0))  # rospy.Time.now()
                            ptFinal, oriFinal = self.tf.lookupTransform(
                                "base_link", self.tags[random_object_id],
                                rospy.Time(0))
                            ptFinal = [
                                ptFinal[i] + self.tags_position_offset[i]
                                for i in range(3)
                            ]

                            raw_input("==== go to tag")
                            pt_inter = deepcopy(ptFinal)
                            pt_inter[-1] += 0.1
                            self.traj_planner(pt_inter, movement='fast')
                            self.traj_planner(ptFinal, movement='fast')
                        else:
                            # In this case, the camera identifies some other tag but not the tag corresponding
                            # to the object in case
                            print(
                                '> Could not find the box tag. Placing the object anywhere \n'
                            )
                            raw_input('=== Pres enter to proceed')
                            self.traj_planner(garbage_location,
                                              movement='fast')
                    else:
                        # In this case, the robot cannot find any tag
                        print(
                            '> Could not find any tag. Placing the object anywhere \n'
                        )
                        raw_input('=== Pres enter to proceed')
                        self.traj_planner(garbage_location, movement='fast')

                    print("Placing object...")
                    # After the bin location is reached, the robot will place the object and move back
                    # to the initial position
                    # self.picking = False # Detach object
                    if args.gazebo:
                        self.gripper_send_position_goal(0.3)
                        # self.delete_model_service_method() # Not working anymore - need to investigate
                        self.grasp_started.publish(False)
                    else:
                        self.command_gripper('o')

                    print("> Moving back to home position...\n")
                    self.traj_planner(point_init_home, movement='fast')
                    self.traj_planner(depth_shot_point, movement='slow')
                    print('> Grasping finished \n')
                else:
                    print('> The requested object could not be grasped! \n')
                    self.traj_planner(depth_shot_point, movement='fast')

            else:
                print('> The requested object was not detected! \n')
コード例 #33
0
ファイル: manager.py プロジェクト: RoboHubEindhoven/suii
class NavigationManager(object):
    def __init__(self):  #Initializes serveces and clients
        rospy.init_node("NavManager_node", anonymous=True)
        self.move_base_client = SimpleActionClient('move_base', MoveBaseAction)
        self.move_base_client.wait_for_server(rospy.Duration(5))

        rospy.Service('move_to_goal', NavigationGoal, self.goal_handler)
        rospy.Service('reposition', NavigationRepose, self.repose_handler)

        self.reset_costmap = rospy.ServiceProxy('/move_base/clear_costmaps',
                                                Empty)
        self.tf_listener = TransformListener()

        self.goal = MoveBaseGoal()
        #rospy.Timer(rospy.Duration(secs=3,nsecs=0), self.clear_costmap)
        rospy.spin()

    def goal_handler(self, data):  #Processes the NavigationGoal service
        self.goal.target_pose.header.frame_id = 'map'
        self.goal.target_pose.pose.position.x = data.pose.position.x
        self.goal.target_pose.pose.position.y = data.pose.position.y
        self.goal.target_pose.pose.orientation.z = data.pose.orientation.z
        self.goal.target_pose.pose.orientation.w = data.pose.orientation.w

        status = self.send_goal()
        return status

    def repose_handler(self, data):  #Processes the NavigationRepose service
        x_req = data.target.x
        y_req = data.target.y
        linear, angular = self.get_repose_goal_coords(x_req, y_req)

        self.goal.target_pose.header.frame_id = 'map'
        self.goal.target_pose.pose.position.x = linear[0]
        self.goal.target_pose.pose.position.y = linear[1]
        self.goal.target_pose.pose.orientation.z = angular[2]
        self.goal.target_pose.pose.orientation.w = angular[3]

        status = self.send_goal()
        return status

    def send_goal(self):  #Sends a goal to move_base using actionlib
        self.clear_costmap()
        time.sleep(0.2)
        self.move_base_client.send_goal(self.goal)
        status = self.move_base_client.wait_for_result()

        if not status:
            self.move_base_client.cancel_goal()
            rospy.loginfo("move_base failed")
            return 1  #False
        else:
            state = self.move_base_client.get_state()
            if state == GoalStatus.SUCCEEDED:
                rospy.loginfo("Goal reached")
                return 0  #True
            rospy.loginfo("Can't reach goal")
            return 1  #False

    def get_repose_goal_coords(
        self, x_req, y_req
    ):  #Uses the robots actual postion to calcualte the new reposition goal
        (linear,
         angular) = self.tf_listener.lookupTransform('base_link', 'map',
                                                     rospy.Time(0))
        current_x = linear[0]
        current_y = linear[1]
        current_theta = euler_from_quaternion(angular)

        new_x = ((cos(current_theta[2]) * x_req) -
                 (sin(current_theta[2]) * y_req))
        new_y = ((cos(current_theta[2]) * y_req) +
                 (sin(current_theta[2]) * x_req))
        linear[0] += new_x
        linear[1] += new_y
        return linear, angular

    def clear_costmap(self):  #Calls the clear costmap service
        self.reset_costmap()
        rospy.loginfo('Costmap cleared')
コード例 #34
0
ファイル: pr2_arms.py プロジェクト: rgleichman/berkeley_demos
class PR2Arm():
  
    wipe_started = False 
    standoff = 0.368 #0.2 + 0.168 (dist from wrist to fingertips)
    torso_min = 0.001 #115 
    torso_max = 0.299 #0.295 
    dist = 0. 

    move_arm_error_dict = {
         -1 : "PLANNING_FAILED: Could not plan a clear path to goal.", 
          0 : "Succeeded [0]", 
          1 : "Succeeded [1]", 
         -2 : "TIMED_OUT",
         -3 : "START_STATE_IN_COLLISION: Try freeing the arms manually.",
         -4 : "START_STATE_VIOLATES_PATH_CONSTRAINTS",
         -5 : "GOAL_IN_COLLISION",
         -6 : "GOAL_VIOLATES_PATH_CONSTRAINTS",
         -7 : "INVALID_ROBOT_STATE",
         -8 : "INCOMPLETE_ROBOT_STATE",
         -9 : "INVALID_PLANNER_ID",
         -10 : "INVALID_NUM_PLANNING_ATTEMPTS",
         -11 : "INVALID_ALLOWED_PLANNING_TIME",
         -12 : "INVALID_GROUP_NAME",
         -13 : "INVALID_GOAL_JOINT_CONSTRAINTS",
         -14 : "INVALID_GOAL_POSITION_CONSTRAINTS",
         -15 : "INVALID_GOAL_ORIENTATION_CONSTRAINTS",
         -16 : "INVALID_PATH_JOINT_CONSTRAINTS",
         -17 : "INVALID_PATH_POSITION_CONSTRAINTS",
         -18 : "INVALID_PATH_ORIENTATION_CONSTRAINTS",
         -19 : "INVALID_TRAJECTORY",
         -20 : "INVALID_INDEX",
         -21 : "JOINT_LIMITS_VIOLATED",
         -22 : "PATH_CONSTRAINTS_VIOLATED",
         -23 : "COLLISION_CONSTRAINTS_VIOLATED",
         -24 : "GOAL_CONSTRAINTS_VIOLATED",
         -25 : "JOINTS_NOT_MOVING",
         -26 : "TRAJECTORY_CONTROLLER_FAILED",
         -27 : "FRAME_TRANSFORM_FAILURE",
         -28 : "COLLISION_CHECKING_UNAVAILABLE",
         -29 : "ROBOT_STATE_STALE",
         -30 : "SENSOR_INFO_STALE",
         -31 : "NO_IK_SOLUTION: Cannot reach goal configuration.",
         -32 : "INVALID_LINK_NAME",
         -33 : "IK_LINK_IN_COLLISION: Cannot reach goal configuration\
                                      without contact.",
         -34 : "NO_FK_SOLUTION",
         -35 : "KINEMATICS_STATE_IN_COLLISION",
         -36 : "INVALID_TIMEOUT"
         }

    def __init__(self, arm, tfListener=None):
        self.arm = arm
        if not (self.arm == "right" or self.arm=="left"):
            rospy.logerr("Failed to initialize PR2Arm: \
                        Must pass 'right' or 'left'")
            return
        if tfListener is None:
            self.tf = TransformListener()
        else:
            self.tf = tfListener
        
        self.move_arm_client = actionlib.SimpleActionClient(
                                     'move_' + self.arm + '_arm', MoveArmAction)
        rospy.loginfo("Waiting for move_" + self.arm + "_arm server")
        if self.move_arm_client.wait_for_server(rospy.Duration(50)):
            rospy.loginfo("Found move_" + self.arm + "_arm server")
        else:
            rospy.logwarn("Cannot find move_" + self.arm + "_arm server")

        self.arm_traj_client = actionlib.SimpleActionClient(
                               self.arm[0]+
                               '_arm_controller/joint_trajectory_action',
                                JointTrajectoryAction)
        rospy.loginfo("Waiting for " + self.arm[0] + 
                        "_arm_controller/joint_trajectory_action server")
        if self.arm_traj_client.wait_for_server(rospy.Duration(5)):
            rospy.loginfo("Found "+self.arm[0]+
                            "_arm_controller/joint_trajectory_action server")
        else:
            rospy.logwarn("Cannot find " + self.arm[0] + 
                            " _arm_controller/joint_trajectory_action server")

        self.arm_follow_traj_client = actionlib.SimpleActionClient(self.arm[0]+
                                    '_arm_controller/follow_joint_trajectory',
                                    FollowJointTrajectoryAction)
        rospy.loginfo("Waiting for "+self.arm[0]+
                        "_arm_controller/follow_joint_trajectory server")
        if self.arm_follow_traj_client.wait_for_server(rospy.Duration(5)):
            rospy.loginfo("Found "+self.arm[0]+
                           "_arm_controller/follow_joint_trajectory server")
        else:
            rospy.logwarn("Cannot find "+self.arm[0]+
                            "_arm_controller/follow_joint_trajectory server")

        self.torso_client = actionlib.SimpleActionClient(
                                'torso_controller/position_joint_action',
                                SingleJointPositionAction)
        rospy.loginfo("Waiting for torso_controller/position_joint_action \
                       server")
        if self.torso_client.wait_for_server(rospy.Duration(5)):
            rospy.loginfo("Found torso_controller/position_joint_action server")
        else:
            rospy.logwarn("Cannot find torso_controller/position_joint_action \
                           server")

        self.gripper_client = actionlib.SimpleActionClient(
                                self.arm[0]+'_gripper_controller/gripper_action',
                                Pr2GripperCommandAction)
        rospy.loginfo("Waiting for "+self.arm[0]+
                                "_gripper_controller/gripper_action server")
        if self.gripper_client.wait_for_server(rospy.Duration(5)):
            rospy.loginfo("Found "+self.arm[0]+
                            "_gripper_controller/gripper_action server")
        else:
            rospy.logwarn("Cannot find "+self.arm[0]+
                            "_gripper_controller/gripper_action server")
        
        rospy.Subscriber(self.arm[0]+'_arm_controller/state', 
                        JointTrajectoryControllerState, self.update_joint_state)
        rospy.Subscriber('torso_controller/state', 
                        JointTrajectoryControllerState, self.update_torso_state)
        
        self.log_out = rospy.Publisher(rospy.get_name()+'/log_out', String)
        
        rospy.loginfo("Waiting for "+self.arm.capitalize()+" FK/IK Solver services")
        try:
            rospy.wait_for_service("/pr2_"+self.arm+"_arm_kinematics/get_fk")
            rospy.wait_for_service("/pr2_"+self.arm+
                                    "_arm_kinematics/get_fk_solver_info")
            rospy.wait_for_service("/pr2_"+self.arm+"_arm_kinematics/get_ik")
            rospy.wait_for_service("/pr2_"+self.arm+
                                    "_arm_kinematics/get_ik_solver_info")
            self.fk_info_proxy = rospy.ServiceProxy(
                                "/pr2_"+self.arm+
                                "_arm_kinematics/get_fk_solver_info",
                                GetKinematicSolverInfo) 
            self.fk_info = self.fk_info_proxy()
            self.fk_pose_proxy = rospy.ServiceProxy(
                                 "/pr2_"+self.arm+"_arm_kinematics/get_fk",
                                 GetPositionFK, True)    
            self.ik_info_proxy = rospy.ServiceProxy(
                                "/pr2_"+self.arm+
                                "_arm_kinematics/get_ik_solver_info",
                                GetKinematicSolverInfo)
            self.ik_info = self.ik_info_proxy()
            self.ik_pose_proxy = rospy.ServiceProxy(
                                "/pr2_"+self.arm+"_arm_kinematics/get_ik",
                                GetPositionIK, True)    
            rospy.loginfo("Found FK/IK Solver services")
        except:
            rospy.logerr("Could not find FK/IK Solver services")
        
        self.set_planning_scene_diff_name= \
                    '/environment_server/set_planning_scene_diff'
        rospy.wait_for_service('/environment_server/set_planning_scene_diff')
        self.set_planning_scene_diff = rospy.ServiceProxy(
                                '/environment_server/set_planning_scene_diff',
                                SetPlanningSceneDiff)
        self.set_planning_scene_diff(SetPlanningSceneDiffRequest())

        self.test_pose = rospy.Publisher("test_pose", PoseStamped)

    def update_joint_state(self, jtcs):
        self.joint_state_time = jtcs.header.stamp
        self.joint_state_act = jtcs.actual
        self.joint_state_des = jtcs.desired

    def update_torso_state(self, jtcs):
        self.torso_state = jtcs
        
    def curr_pose(self):
        (trans,rot) = self.tf.lookupTransform("/torso_lift_link",
                                            "/"+self.arm[0]+"_wrist_roll_link",
                                            rospy.Time(0))
        cp = PoseStamped()
        cp.header.stamp = rospy.Time.now()
        cp.header.frame_id = '/torso_lift_link'
        cp.pose.position = Point(*trans)
        cp.pose.orientation = Quaternion(*rot)
        return cp
   
    def wait_for_stop(self, wait_time=1, timeout=60):
        rospy.sleep(wait_time)
        end_time = rospy.Time.now()+rospy.Duration(timeout)
        while not self.is_stopped():
            if rospy.Time.now()<end_time:
                rospy.sleep(wait_time)
            else:
                raise

    def is_stopped(self):
        time = self.joint_state_time
        vels = self.joint_state_act.velocities
        if (np.allclose(vels, np.zeros(7)) and
           (rospy.Time.now()-time)<rospy.Duration(0.1)):
            return True
        else:
            return False
    
    def adjust_elbow(self, f32):
        request = self.form_ik_request(self.curr_pose())
        angs =  list(request.ik_request.ik_seed_state.joint_state.position)
        angs[2] += f32.data
        request.ik_request.ik_seed_state.joint_state.position = angs 
        ik_goal = self.ik_pose_proxy(request)
        if ik_goal.error_code.val == 1:
            self.send_joint_angles(ik_goal.solution.joint_state.position)
        else:
            rospy.loginfo("Cannot adjust elbow position further")
            self.log_out.publish(data="Cannot adjust elbow position further")

    def gripper(self, position, effort=30):
        pos = np.clip(position,0.0, 0.09)
        goal = Pr2GripperCommandGoal()
        goal.command.position = pos
        goal.command.max_effort = effort
        self.gripper_client.send_goal(goal)
        finished_within_time = self.gripper_client.wait_for_result(
                                                        rospy.Duration(15))
        if not (finished_within_time):
            self.gripper_client.cancel_goal()
            rospy.loginfo("Timed out moving "+self.arm+" gripper")
            return False
        else:
            state = self.gripper_client.get_state()
            result = self.gripper_client.get_result()
            if (state == 3): #3 == SUCCEEDED
                rospy.loginfo("Gripper Action Succeeded")
                return True
            else:
                rospy.loginfo("Gripper Action Failed")
                rospy.loginfo("Failure Result: %s" %result)
                return False

    def hand_frame_move(self, x, y=0, z=0, duration=None):
        cp = self.curr_pose()
        newpose = pu.pose_relative_trans(cp,x,y,z)
        self.dist = pu.calc_dist(cp, newpose)
        return newpose

    def build_trajectory(self, finish, start=None, ik_space=0.005,
                        duration=None, tot_points=None):
        if start == None: # if given one pose, use current position as start, else, assume (start, finish)
            start = self.curr_pose()
       
        #TODO: USE TF TO BASE DISTANCE ON TOOL_FRAME MOVEMENT DISTANCE, NOT WRIST_ROLL_LINK

        # Based upon distance to travel, determine the number of intermediate steps required
        # find linear increments of position.

        dist = pu.calc_dist(start, finish)     #Total distance to travel
        ik_steps = int(round(dist/ik_space)+1.)   
        print "IK Steps: %s" %ik_steps
        if tot_points is None:
           tot_points = 1500*dist
        if duration is None:
            duration = dist*120
        ik_fracs = np.linspace(0, 1, ik_steps)   #A list of fractional positions along course to evaluate ik
        ang_fracs = np.linspace(0,1, tot_points)  

        x_gap = finish.pose.position.x - start.pose.position.x
        y_gap = finish.pose.position.y - start.pose.position.y
        z_gap = finish.pose.position.z - start.pose.position.z

        qs = [start.pose.orientation.x, start.pose.orientation.y,
              start.pose.orientation.z, start.pose.orientation.w] 
        qf = [finish.pose.orientation.x, finish.pose.orientation.y,
              finish.pose.orientation.z, finish.pose.orientation.w] 

        #For each step between start and finish, find a complete pose (linear position changes, and quaternion slerp)
        steps = [PoseStamped() for i in range(len(ik_fracs))]
        for i,frac in enumerate(ik_fracs):
            steps[i].header.stamp = rospy.Time.now()
            steps[i].header.frame_id = start.header.frame_id
            steps[i].pose.position.x = start.pose.position.x + x_gap*frac
            steps[i].pose.position.y = start.pose.position.y + y_gap*frac
            steps[i].pose.position.z = start.pose.position.z + z_gap*frac
            new_q = transformations.quaternion_slerp(qs,qf,frac)
            steps[i].pose.orientation.x = new_q[0]
            steps[i].pose.orientation.y = new_q[1]
            steps[i].pose.orientation.z = new_q[2]
            steps[i].pose.orientation.w = new_q[3]
        rospy.loginfo("Planning straight-line path, please wait")
        self.log_out.publish(data="Planning straight-line path, please wait")
       
        #For each pose in trajectory, find ik angles
        #Find initial ik for seeding
        req = self.form_ik_request(steps[0])
        ik_goal = self.ik_pose_proxy(req)
        seed = ik_goal.solution.joint_state.position

        ik_points = [[0]*7 for i in range(len(ik_fracs))]
        for i, p in enumerate(steps):
            request = self.form_ik_request(p)
            request.ik_request.ik_seed_state.joint_state.position = seed
            ik_goal = self.ik_pose_proxy(request)
            ik_points[i] = ik_goal.solution.joint_state.position
            seed = ik_goal.solution.joint_state.position # seed the next ik w/previous points results
        ik_points = np.array(ik_points)
        # Linearly interpolate angles 10 times between ik-defined points (non-linear in cartesian space, but this is reduced from dense ik sampling along linear path.  Used to maintain large number of trajectory points without running IK on every one.    
        angle_points = np.zeros((7, tot_points))
        for i in xrange(7):
            angle_points[i,:] = np.interp(ang_fracs, ik_fracs, ik_points[:,i])

        #Build Joint Trajectory from angle positions
        traj = JointTrajectory()
        traj.header.frame_id = steps[0].header.frame_id
        traj.joint_names = self.ik_info.kinematic_solver_info.joint_names
        #print 'angle_points', len(angle_points[0]), angle_points
        for i in range(len(angle_points[0])):
            traj.points.append(JointTrajectoryPoint())
            traj.points[i].positions = angle_points[:,i]
            traj.points[i].velocities = [0]*7
            traj.points[i].time_from_start = rospy.Duration(
                                                ang_fracs[i]*duration)
        return traj

    def build_follow_trajectory(self, traj):
        # Build 'Follow Joint Trajectory' goal from trajectory (includes tolerances for error)
        traj_goal = FollowJointTrajectoryGoal()
        traj_goal.trajectory = traj
        tolerance = JointTolerance()
        tolerance.position = 0.05
        tolerance.velocity = 0.1
        traj_goal.path_tolerance = [tolerance for i in range(len(traj.points))]
        traj_goal.goal_tolerance = [tolerance for i in range(len(traj.points))]
        traj_goal.goal_time_tolerance = rospy.Duration(3)
        return traj_goal

    def move_torso(self, pos):
        rospy.loginfo("Moving Torso to reach arm goal")
        goal_out = SingleJointPositionGoal()
        goal_out.position = pos
        self.torso_client.send_goal(goal_out)
        return True

    def fast_move(self, ps, time=0.):
        ik_goal = self.ik_pose_proxy(self.form_ik_request(ps))
        if ik_goal.error_code.val == 1:
            point = JointTrajectoryPoint()
            point.positions = ik_goal.solution.joint_state.position
            self.send_traj_point(point)
        else:
            rospy.logerr("FAST MOVE IK FAILED!")

    def blind_move(self, ps, duration = None):
        (reachable, ik_goal, duration) = self.full_ik_check(ps)
        if reachable:
            self.send_joint_angles(ik_goal.solution.joint_state.position,
                                   duration)

    def check_torso(self, request):
        """
        For unreachable goals, check to see if moving the torso can solve
        the problem.  If yes, return True, and torso adjustment needed.
        If no, return False, and best possible Torso adjustment.
        """
        goal_z = request.ik_request.pose_stamped.pose.position.z
        torso_pos = self.torso_state.actual.positions[0]
        spine_range = [self.torso_min - torso_pos, self.torso_max - torso_pos]
       
        if abs(goal_z)<0.005:
            #Already at best position, dont try more (avoid moving to noise)
            rospy.loginfo("Torso Already at best possible position")
            return[False, 0]
        #Find best possible case: shoulder @ goal height, max up, or max down. 
        if goal_z >= spine_range[0] and goal_z <= spine_range[1]: 
            rospy.loginfo("Goal within spine movement range")
            request.ik_request.pose_stamped.pose.position.z = 0;
            opt_tor_move = goal_z
        elif goal_z > spine_range[1]:#Goal is above possible shoulder height
            rospy.loginfo("Goal above spine movement range")
            request.ik_request.pose_stamped.pose.position.z -= spine_range[1]
            opt_tor_move = spine_range[1]
        else:#Goal is below possible shoulder height
            rospy.loginfo("Goal below spine movement range")
            request.ik_request.pose_stamped.pose.position.z -= spine_range[0]
            opt_tor_move = spine_range[0]
        #Check best possible case
        print "Optimal Torso move: ", opt_tor_move
        ik_goal = self.ik_pose_proxy(request)
        if ik_goal.error_code.val != 1:
            #Return false: Not achievable, even for best case
            rospy.loginfo("Original goal cannot be reached")
            self.log_out.publish(data="Original goal cannot be reached")
            return [False, opt_tor_move]
        opt_ik_goal = ik_goal
        
        #Achievable: Find a reasonable solution, move torso, return true
        rospy.loginfo("Goal can be reached by moving spine")
        self.log_out.publish(data="Goal can be reached by moving spine")
        trials = np.linspace(0,opt_tor_move,round(abs(opt_tor_move)/0.05))
        np.append(trials,opt_tor_move)
        rospy.loginfo("Torso far from best position, finding closer sol.")
        print "Trials: ", trials
        for trial in trials:
            request.ik_request.pose_stamped.pose.position.z = goal_z + trial
            print "Trying goal @ ", goal_z + trial
            ik_goal = self.ik_pose_proxy(request)
            if ik_goal.error_code.val == 1:
                rospy.loginfo("Tried: %s, Succeeded" %trial)
                return [True, trial]
            rospy.loginfo("Tried: %s, Failed" %trial)
        #Broke through somehow, catch error
        return [True, opt_tor_move]
   

    def full_ik_check(self, ps):
        #Check goal as given, if reachable, return true
        req = self.form_ik_request(ps)
        ik_goal = self.ik_pose_proxy(req)
        if ik_goal.error_code.val == 1:
            self.dist = pu.calc_dist(self.curr_pose(), ps)
            return (True, ik_goal, None)
        #Check goal with vertical torso movement, if works, return true 
        (torso_succeeded, torso_move) = self.check_torso(req)
        self.move_torso(self.torso_state.actual.positions[0]+torso_move)
        duration = max(4,85*abs(torso_move))
        if torso_succeeded:
            ik_goal = self.ik_pose_proxy(req)
            self.dist = pu.calc_dist(self.curr_pose(), ps)
            if ik_goal.error_code.val ==1:
                return (True, ik_goal, duration)
            else:
                print "Reported Succeeded, then really failed: \r\n", ik_goal
        
        #Check goal incrementally retreating hand pose, if works, return true
        pct = 0.98
        curr_pos = self.curr_pose().pose.position
        dx = req.ik_request.pose_stamped.pose.position.x - curr_pos.x
        dy = req.ik_request.pose_stamped.pose.position.y - curr_pos.y
        while pct > 0.01:
            #print "Percent: %s" %pct
            req.ik_request.pose_stamped.pose.position.x = curr_pos.x + pct*dx
            req.ik_request.pose_stamped.pose.position.y = curr_pos.y + pct*dy
            ik_goal = self.ik_pose_proxy(req)
            if ik_goal.error_code.val == 1:
                rospy.loginfo("Succeeded PARTIALLY (%s) with torso" %pct)
                return (True, ik_goal, duration)
            else:
                pct -= 0.02
        #Nothing worked, report failure, return false
        rospy.loginfo("IK Failed: Error Code %s" %str(ik_goal.error_code))
        rospy.loginfo("Reached as far as possible")
        self.log_out.publish(data="Cannot reach farther in this direction.")    
        return (False, ik_goal, duration)

    def form_ik_request(self, ps):
        #print "forming IK request for :%s" %ps
        req = GetPositionIKRequest()
        req.timeout = rospy.Duration(5)
        req.ik_request.pose_stamped = ps 
        req.ik_request.ik_link_name = \
                    self.ik_info.kinematic_solver_info.link_names[-1]
        req.ik_request.ik_seed_state.joint_state.name = \
                    self.ik_info.kinematic_solver_info.joint_names
        req.ik_request.ik_seed_state.joint_state.position = \
                    self.joint_state_act.positions
        return req
    
    def send_joint_angles(self, angles, duration = None):
        point = JointTrajectoryPoint()
        point.positions = angles
        self.send_traj_point(point, duration)

    def send_traj_point(self, point, time=None):
        if time is None: 
            point.time_from_start = rospy.Duration(max(20*self.dist, 4))
        else:
            point.time_from_start = rospy.Duration(time)
        joint_traj = JointTrajectory()
        joint_traj.header.stamp = rospy.Time.now()
        joint_traj.header.frame_id = '/torso_lift_link'
        joint_traj.joint_names = self.ik_info.kinematic_solver_info.joint_names
        joint_traj.points.append(point)
        joint_traj.points[0].velocities = [0,0,0,0,0,0,0]
        arm_goal = JointTrajectoryGoal()
        arm_goal.trajectory = joint_traj
        self.arm_traj_client.send_goal(arm_goal)

    def move_arm_to(self, goal_in):
        (reachable, ik_goal, duration) = self.full_ik_check(goal_in)
        rospy.sleep(duration)
        
        rospy.loginfo("Composing move_"+self.arm+"_arm goal")
        goal_out = MoveArmGoal()
        goal_out.motion_plan_request.group_name = self.arm+"_arm"
        goal_out.motion_plan_request.num_planning_attempts = 10 
        goal_out.motion_plan_request.planner_id = ""
        goal_out.planner_service_name = "ompl_planning/plan_kinematic_path"
        goal_out.motion_plan_request.allowed_planning_time = rospy.Duration(1.0)
        
        pos = PositionConstraint()
        pos.header.frame_id = goal_in.header.frame_id 
        pos.link_name = self.arm[0]+"_wrist_roll_link"
        pos.position = goal_in.pose.position

        pos.constraint_region_shape.type = 0 
        pos.constraint_region_shape.dimensions=[0.01]

        pos.constraint_region_orientation = Quaternion(0,0,0,1)
        pos.weight = 1

        goal_out.motion_plan_request.goal_constraints.position_constraints.append(pos)
    
        ort = OrientationConstraint()    
        ort.header.frame_id=goal_in.header.frame_id
        ort.link_name = self.arm[0]+"_wrist_roll_link"
        ort.orientation = goal_in.pose.orientation
        
        ort.absolute_roll_tolerance = 0.02
        ort.absolute_pitch_tolerance = 0.02
        ort.absolute_yaw_tolerance = 0.02
        ort.weight = 0.5
        goal_out.motion_plan_request.goal_constraints.orientation_constraints.append(ort)
        goal_out.accept_partial_plans = True
        goal_out.accept_invalid_goals = True
        goal_out.disable_collision_monitoring = True
        rospy.loginfo("Sending composed move_"+self.arm+"_arm goal")

        finished_within_time = False
        self.move_arm_client.send_goal(goal_out)
        finished_within_time = self.move_arm_client.wait_for_result(
                                                            rospy.Duration(60))
        if not (finished_within_time):
            self.move_arm_client.cancel_goal()
            self.log_out.publish(data="Timed out achieving "+self.arm+
                                         " arm goal pose")
            rospy.loginfo("Timed out achieving right arm goal pose")
            return False
        else:
            state = self.move_arm_client.get_state()
            result = self.move_arm_client.get_result()
            if (state == 3): #3 == SUCCEEDED
                rospy.loginfo("Action Finished: %s" %state)
                self.log_out.publish(data="Move "+self.arm.capitalize()+
                                          " Arm with Motion Planning: %s"
                                          %self.move_arm_error_dict[
                                                result.error_code.val])
                return True
            else:
                if result.error_code.val == 1:
                    rospy.loginfo("Move_"+self.arm+"_arm_action failed: \
                                    Unable to plan a path to goal")
                    self.log_out.publish(data="Move "+self.arm.capitalize()+
                                        " Arm with Motion Planning Failed: \
                                         Unable to plan a path to the goal")
                elif result.error_code.val == -31:
                    (torso_succeeded, pos) = self.check_torso(
                                                self.form_ik_request(goal_in))
                    if torso_succeeded:
                        rospy.loginfo("IK Failed in Current Position. \
                                        Adjusting Height and Retrying")
                        self.log_out.publish(data="IK Failed in Current \
                                                      Position. Adjusting \
                                                      Height and Retrying")
                        self.move_arm_to(pos)
                    else:
                        rospy.loginfo("Move_"+self.arm+"_arm action failed: %s"
                                        %state)
                        rospy.loginfo("Failure Result: %s" %result)
                        self.log_out.publish(data="Move "+self.arm.capitalize()+
                                                    " Arm with Motion Planning \
                                                    and Torso Check Failed: %s"
                                                    %self.move_arm_error_dict[
                                                        result.error_code.val])
                else:
                    rospy.loginfo("Move_"+self.arm+"_arm action failed: %s" %state)
                    rospy.loginfo("Failure Result: %s" %result)
                    self.log_out.publish(data="Move "+self.arm.capitalize()+
                                                " Arm with Motion Planning \
                                                Failed: %s" 
                                                %self.move_arm_error_dict[
                                                        result.error_code.val])
            return False
コード例 #35
0
class GazeEstimator(object):
    """This class encapsulates a deep neural network for gaze estimation.

    It retrieves two image streams, one containing the left eye and another containing the right eye.
    It synchronizes these two images with the estimated head pose.
    The images are then converted in a suitable format, and a forward pass (one per eye) of the deep neural network
    results in the estimated gaze for this frame. The estimated gaze is then published in the (theta, phi) notation.
    Additionally, two images with the gaze overlaid on the eye images are published."""
    def __init__(self):
        self.image_height = rospy.get_param("~image_height", 36)
        self.image_width = rospy.get_param("~image_width", 60)
        self.bridge = CvBridge()
        self.subjects_bridge = SubjectListBridge()

        self.tf_broadcaster = TransformBroadcaster()
        self.tf_listener = TransformListener()

        self.use_last_headpose = rospy.get_param("~use_last_headpose", True)
        self.tf_prefix = rospy.get_param("~tf_prefix", "gaze")
        self.last_phi_head, self.last_theta_head = None, None

        self.rgb_frame_id_ros = rospy.get_param("~rgb_frame_id_ros",
                                                "/kinect2_nonrotated_link")

        self.headpose_frame = self.tf_prefix + "/head_pose_estimated"
        self.gpu_id = rospy.get_param("~gpu_id", default="0")
        with tensorflow.device("/gpu:{}".format(self.gpu_id)):
            config = tensorflow.ConfigProto(inter_op_parallelism_threads=1,
                                            intra_op_parallelism_threads=1)
            config.gpu_options.allow_growth = True
            config.gpu_options.per_process_gpu_memory_fraction = 0.3
            config.log_device_placement = False
            self.sess = tensorflow.Session(config=config)
            set_session(self.sess)

        model_files = rospy.get_param("~model_files")

        self.models = []
        for model_file in model_files:
            tqdm.write('Load model ' + model_file)
            model = load_model(os.path.join(
                rospkg.RosPack().get_path('rt_gene'), model_file),
                               custom_objects={
                                   'accuracy_angle': accuracy_angle,
                                   'angle_loss': angle_loss
                               })
            # noinspection PyProtectedMember
            model._make_predict_function(
            )  # have to initialize before threading
            self.models.append(model)
        tqdm.write('Loaded ' + str(len(self.models)) + ' models')

        self.graph = tensorflow.get_default_graph()

        self.image_subscriber = rospy.Subscriber('/subjects/images',
                                                 MSG_SubjectImagesList,
                                                 self.image_callback,
                                                 queue_size=3)
        self.subjects_gaze_img = rospy.Publisher('/subjects/gazeimages',
                                                 Image,
                                                 queue_size=3)

        self.average_weights = np.array([0.1, 0.125, 0.175, 0.2, 0.4])
        self.gaze_buffer_c = {}

    def __del__(self):
        if self.sess is not None:
            self.sess.close()

    def estimate_gaze_twoeyes(self, test_input_left, test_input_right,
                              headpose):
        test_headpose = headpose.reshape(1, 2)
        with self.graph.as_default():
            predictions = []
            for model in self.models:
                predictions.append(
                    model.predict({
                        'img_input_L': test_input_left,
                        'img_input_R': test_input_right,
                        'headpose_input': test_headpose
                    })[0])
            mean_prediction = np.mean(np.array(predictions), axis=0)
            if len(
                    self.models
            ) == 1:  # only apply offset for single model, not for ensemble models
                mean_prediction[1] += 0.11
            return mean_prediction

    def visualize_eye_result(self, eye_image, est_gaze):
        """Here, we take the original eye eye_image and overlay the estimated gaze."""
        output_image = np.copy(eye_image)

        center_x = self.image_width / 2
        center_y = self.image_height / 2

        endpoint_x, endpoint_y = gaze_tools.get_endpoint(
            est_gaze[0], est_gaze[1], center_x, center_y, 50)

        cv2.line(output_image, (int(center_x), int(center_y)),
                 (int(endpoint_x), int(endpoint_y)), (255, 0, 0))
        return output_image

    def publish_image(self, image, image_publisher, timestamp):
        """This image publishes the `image` to the `image_publisher` with the given `timestamp`."""
        image_ros = self.bridge.cv2_to_imgmsg(image, "rgb8")
        image_ros.header.stamp = timestamp
        image_publisher.publish(image_ros)

    def input_from_image(self, eye_img_msg, flip=False):
        """This method converts an eye_img_msg provided by the landmark estimator, and converts it to a format
        suitable for the gaze network."""
        cv_image = eye_img_msg
        #cv_image = self.bridge.imgmsg_to_cv2(eye_img_msg, "rgb8")
        if flip:
            cv_image = cv2.flip(cv_image, 1)
        currimg = cv_image.reshape(self.image_height,
                                   self.image_width,
                                   3,
                                   order='F')
        currimg = currimg.astype(np.float32)
        # print('currimg.dtype', currimg.dtype)
        # cv2.imwrite('/home/tobias/test_inplace.png', currimg)
        testimg = np.zeros((1, self.image_height, self.image_width, 3))
        testimg[0, :, :, 0] = currimg[:, :, 0] - 103.939
        testimg[0, :, :, 1] = currimg[:, :, 1] - 116.779
        testimg[0, :, :, 2] = currimg[:, :, 2] - 123.68
        return testimg

    def compute_eye_gaze_estimation(self, subject_id, timestamp, input_r,
                                    input_l):
        """
        subject_id : integer,  id of the subject
        input_x    : cv_image, input image of x eye
        (phi_x)    : double,   phi angle estimated using pupil detection
        (theta_x)  : double,   theta angle estimated using pupil detection
        """
        try:
            lct = self.tf_listener.getLatestCommonTime(
                self.rgb_frame_id_ros, self.headpose_frame + str(subject_id))
            if (timestamp - lct).to_sec() < 0.25:
                tqdm.write('Time diff: ' + str((timestamp - lct).to_sec()))

                (trans_head, rot_head) = self.tf_listener.lookupTransform(
                    self.rgb_frame_id_ros,
                    self.headpose_frame + str(subject_id), lct)
                euler_angles_head = gaze_tools.get_head_pose(
                    trans_head, rot_head)

                phi_head, theta_head = gaze_tools.get_phi_theta_from_euler(
                    euler_angles_head)
                self.last_phi_head, self.last_theta_head = phi_head, theta_head
            else:
                if self.use_last_headpose and self.last_phi_head is not None:
                    tqdm.write('Big time diff, use last known headpose! ' +
                               str((timestamp - lct).to_sec()))
                    phi_head, theta_head = self.last_phi_head, self.last_theta_head
                else:
                    tqdm.write(
                        'Too big time diff for head pose, do not estimate gaze!'
                        + str((timestamp - lct).to_sec()))
                    return

            start_time = time.time()

            est_gaze_c = self.estimate_gaze_twoeyes(
                input_l, input_r, np.array([theta_head, phi_head]))

            self.gaze_buffer_c[subject_id].append(est_gaze_c)

            if len(self.average_weights) == len(
                    self.gaze_buffer_c[subject_id]):
                est_gaze_c_med = np.average(np.array(
                    self.gaze_buffer_c[subject_id]),
                                            axis=0,
                                            weights=self.average_weights)
                self.publish_gaze(est_gaze_c_med, timestamp, subject_id)
                tqdm.write('est_gaze_c: ' + str(est_gaze_c_med))
                return est_gaze_c_med

            tqdm.write('Elapsed: ' + str(time.time() - start_time))
        except (tf.LookupException, tf.ConnectivityException,
                tf.ExtrapolationException, tf.Exception) as tf_e:
            print(tf_e)
        except rospy.ROSException as ros_e:
            if str(ros_e) == "publish() to a closed topic":
                print("See ya")
        return None

    def image_callback(self, subject_image_list, masked_list=None):
        """This method is called whenever new input arrives. The input is first converted in a format suitable
        for the gaze estimation network (see :meth:`input_from_image`), then the gaze is estimated (see
        :meth:`estimate_gaze`. The estimated gaze is overlaid on the input image (see :meth:`visualize_eye_result`),
        and this image is published along with the estimated gaze vector (see :meth:`publish_image` and
        :func:`publish_gaze`)"""
        timestamp = subject_image_list.header.stamp
        subjects_gaze_img = None

        subjects_dict = self.subjects_bridge.msg_to_images(subject_image_list)
        for subject_id, s in subjects_dict.items():
            if subject_id not in self.gaze_buffer_c.keys():
                self.gaze_buffer_c[subject_id] = collections.deque(maxlen=5)

            input_r = self.input_from_image(s.right, flip=False)
            input_l = self.input_from_image(s.left, flip=False)
            gaze_est = self.compute_eye_gaze_estimation(
                subject_id, timestamp, input_r, input_l)

            if gaze_est is not None:
                r_gaze_img = self.visualize_eye_result(s.right, gaze_est)
                l_gaze_img = self.visualize_eye_result(s.left, gaze_est)
                s_gaze_img = np.concatenate((r_gaze_img, l_gaze_img), axis=1)
                if subjects_gaze_img is None:
                    subjects_gaze_img = s_gaze_img
                else:
                    subjects_gaze_img = np.concatenate(
                        (subjects_gaze_img, s_gaze_img), axis=0)

        if subjects_gaze_img is not None:
            gaze_img_msg = self.bridge.cv2_to_imgmsg(
                subjects_gaze_img.astype(np.uint8), "bgr8")
            self.subjects_gaze_img.publish(gaze_img_msg)

    def publish_gaze(self, est_gaze, msg_stamp, subject_id):
        """Publish the gaze vector as a PointStamped."""
        theta_gaze = est_gaze[0]
        phi_gaze = est_gaze[1]
        euler_angle_gaze = gaze_tools.get_euler_from_phi_theta(
            phi_gaze, theta_gaze)
        quaternion_gaze = tf.transformations.quaternion_from_euler(
            *euler_angle_gaze)
        self.tf_broadcaster.sendTransform(
            (0, 0,
             0.05),  # publish it 5cm above the head pose's origin (nose tip)
            quaternion_gaze,
            msg_stamp,
            self.tf_prefix + "/world_gaze" + str(subject_id),
            self.headpose_frame + str(subject_id))
コード例 #36
0
class positionGoalActionServer():
    """
        Action server taking position goals and generating twist messages accordingly
    """
    def __init__(self,name):
        # Get topics and parameters from parameter server
        self.max_linear_velocity = rospy.get_param("~max_linear_velocity",2)
        self.max_angular_velocity = rospy.get_param("~max_angular_velocity",1)
        self.max_distance_error = rospy.get_param("~max_distance_error",0.1)
        self.straight_line = rospy.get_param("~straight_line",False)
        self.straight_line_angle_error = rospy.get_param("~straight_line_angle_error", 0.5)
        
        #self.odometry_topic = rospy.get_param("~odometry_topic","/base_pose_ground_truth")
        self.cmd_vel_topic = rospy.get_param("~cmd_vel_topic","/fmSignals/cmd_vel")

        self.odom_frame = rospy.get_param("~odom_frame","/odom")
        self.base_frame = rospy.get_param("~base_frame","/base_footprint")
        
        #self.odom_sub = rospy.Subscriber(self.odometry_topic, Odometry, self.onOdometry )
        self.twist_pub = rospy.Publisher(self.cmd_vel_topic, TwistStamped)
        
        # Set parameters not yet on server
        self.rate = rospy.Rate(5)
        
        # Init variables
        self.twist = TwistStamped()
        self.destination = vector(0,0)
        self.position = vector(0,0)
        self.quaternion = np.empty((4, ), dtype=np.float64)
        self.distance_error = 0
        self.angle_error = 0
         
        self.z = 0
        self.w = 0

        # Setup TF listener
        self.__listen = TransformListener()
        
        # Setup and start simple action server      
        self._action_name = name
        self._server = actionlib.SimpleActionServer(
            self._action_name, positionAction, auto_start=False, execute_cb=self.execute)
        self._server.register_preempt_callback(self.preempt_cb);
        self._server.start()
        
    def preempt_cb(self):                   
        # Publish zero twist message
        self.twist.header.stamp = rospy.Time.now()
        self.twist.twist.linear.x = 0
        self.twist.twist.angular.z = 0            
        self.twist_pub.publish(self.twist)
        #self._server.set_preempted()
   
    def get_current_position(self):
        ret = False
        try:
            (self.position,self.heading) = self.__listen.lookupTransform( self.odom_frame,self.base_frame,rospy.Time(0)) # The transform is returned as position (x,y,z) and an orientation quaternion (x,y,z,w).
            ret = True
        except (tf.LookupException, tf.ConnectivityException),err:
            rospy.loginfo("could not locate vehicle")
        return ret
コード例 #37
0
class CF():
    def __init__(self, i):
        self.worldFrame = rospy.get_param("~worldFrame", "/world")
        self.frame = 'crazyflie%d' % i
        self.zscale = 3
        self.state = 0
        self.position = []
        self.orientation = []
        self.pref = []
        self.cmd_vel = []
        self.goal = PoseStamped()
        self.goal.header.seq = 0
        self.goal.header.stamp = rospy.Time.now()
        pub_name = '/crazyflie%d/goal' % i
        sub_name = '/crazyflie%d/CF_state' % i
        pub_cmd_diff = '/crazyflie%d/cmd_diff' % i
        sub_cmd_vel = '/crazyflie%d/cmd_vel' % i
        sub_imu_data = '/crazyflie%d/imu' % i
        self.pubGoal = rospy.Publisher(pub_name, PoseStamped, queue_size=1)
        self.pubCmd_diff = rospy.Publisher(pub_cmd_diff, Twist, queue_size=1)
        self.subCmd_vel = rospy.Subscriber(sub_cmd_vel, Twist,
                                           self.cmdCallback)
        self.subGoal = rospy.Subscriber(pub_name, PoseStamped,
                                        self.GoalCallback)
        self.subState = rospy.Subscriber(sub_name, String, self.CfsCallback)
        self.subImu = rospy.Subscriber(sub_imu_data, Imu, self.ImuCallback)
        self.listener = TransformListener()
        self.listener.waitForTransform(self.worldFrame, self.frame,
                                       rospy.Time(), rospy.Duration(5.0))
        self.updatepos()
        self.send_cmd_diff()

    def CfsCallback(self, sdata):
        self.state = int(sdata.data)

    def ImuCallback(self, sdata):
        accraw = sdata.linear_acceleration
        imuraw = np.array([accraw.x, -accraw.y, -accraw.z])
        self.updatepos()
        imuraw = cal_R(self.orientation[1], self.orientation[0],
                       self.orientation[2]).dot(imuraw)
        self.Imu = np.array([imuraw[0], imuraw[1], 9.88 + imuraw[2]])
        self.Gyro = np.array([
            sdata.angular_velocity.x, sdata.angular_velocity.y,
            sdata.angular_velocity.z
        ])

    def GoalCallback(self, gdata):
        self.goal = gdata

    def cmdCallback(self, cdata):
        self.cmd_vel = cdata

    def hover_init(self, pnext, s):
        goal = PoseStamped()
        goal.header.seq = self.goal.header.seq + 1
        goal.header.frame_id = self.worldFrame
        goal.header.stamp = rospy.Time.now()
        if self.state != 1:
            goal.pose.position.x = pnext[0]
            goal.pose.position.y = pnext[1]
            goal.pose.position.z = pnext[2]
            quaternion = tf.transformations.quaternion_from_euler(0, 0, 0)
            goal.pose.orientation.x = quaternion[0]
            goal.pose.orientation.y = quaternion[1]
            goal.pose.orientation.z = quaternion[2]
            goal.pose.orientation.w = quaternion[3]
            self.pubGoal.publish(goal)
            #print "Waiting for crazyflie %d to take off" %i
        else:
            t = self.listener.getLatestCommonTime(self.worldFrame, self.frame)
            if self.listener.canTransform(self.worldFrame, self.frame, t):
                position, quaternion = self.listener.lookupTransform(
                    self.worldFrame, self.frame, t)
                rpy = tf.transformations.euler_from_quaternion(quaternion)
                dx = pnext[0] - position[0]
                dy = pnext[1] - position[1]
                dz = pnext[2] - position[2]
                dq = 0 - rpy[2]

                s = max(s, 0.5)
                goal.pose.position.x = position[0] + s * dx
                goal.pose.position.y = position[1] + s * dy
                goal.pose.position.z = position[2] + s * dz
                quaternion = tf.transformations.quaternion_from_euler(
                    0, 0, rpy[2] + s * dq)
                goal.pose.orientation.x = quaternion[0]
                goal.pose.orientation.y = quaternion[1]
                goal.pose.orientation.z = quaternion[2]
                goal.pose.orientation.w = quaternion[3]
                self.pubGoal.publish(goal)
                error = sqrt(dx**2 + dy**2 + dz**2)
                print 'Hovering error is %0.2f' % error
                if error < 0.1:
                    return 1
        return 0

    def updatepos(self):
        t = self.listener.getLatestCommonTime(self.worldFrame, self.frame)
        if self.listener.canTransform(self.worldFrame, self.frame, t):
            self.position, quaternion = self.listener.lookupTransform(
                self.worldFrame, self.frame, t)
            rpy = tf.transformations.euler_from_quaternion(quaternion)
            self.orientation = rpy

    def goto(self, pnext):
        goal = PoseStamped()
        goal.header.stamp = rospy.Time.now()
        goal.header.seq = self.goal.header.seq + 1
        goal.header.frame_id = self.worldFrame
        goal.pose.position.x = pnext[0]
        goal.pose.position.y = pnext[1]
        goal.pose.position.z = pnext[2]
        quaternion = tf.transformations.quaternion_from_euler(0, 0, 0)
        goal.pose.orientation.x = quaternion[0]
        goal.pose.orientation.y = quaternion[1]
        goal.pose.orientation.z = quaternion[2]
        goal.pose.orientation.w = quaternion[3]
        self.pubGoal.publish(goal)

    def gotoT(self, pnext, s):
        goal = PoseStamped()
        goal.header.stamp = rospy.Time.now()
        goal.header.seq = self.goal.header.seq + 1
        goal.header.frame_id = self.worldFrame
        t = self.listener.getLatestCommonTime(self.worldFrame, self.frame)
        if self.listener.canTransform(self.worldFrame, self.frame, t):
            position, quaternion = self.listener.lookupTransform(
                self.worldFrame, self.frame, t)
            rpy = tf.transformations.euler_from_quaternion(quaternion)
            dx = pnext[0] - position[0]
            dy = pnext[1] - position[1]
            dz = pnext[2] - position[2]
            dq = 0 - rpy[2]

            goal.pose.position.x = position[0] + s * dx
            goal.pose.position.y = position[1] + s * dy
            goal.pose.position.z = position[2] + s * dz
            quaternion = tf.transformations.quaternion_from_euler(
                0, 0, rpy[2] + s * dq)
            goal.pose.orientation.x = quaternion[0]
            goal.pose.orientation.y = quaternion[1]
            goal.pose.orientation.z = quaternion[2]
            goal.pose.orientation.w = quaternion[3]
            self.pubGoal.publish(goal)
            error = sqrt(dx**2 + dy**2 + dz**2)
            print 'error is %0.2f' % error
            if error < 0.1:
                return 1
            else:
                return 0

    def send_cmd_diff(self, roll=0, pitch=0, yawrate=0, thrust=49000):
        # note theoretical default thrust is 39201 equal to 35.89g lifting force
        # actual 49000 is 35.89
        msg = Twist()
        msg.linear.x = -pitch  #note vx is -pitch, see crazyflie_server.cpp line 165
        msg.linear.y = roll  #note vy is roll
        msg.linear.z = thrust
        msg.angular.z = yawrate
        self.pubCmd_diff.publish(msg)
コード例 #38
0
class mbzirc_c2_auto():
    # A few key tasks are achieved in the initializer function:
    #     1. We load the pre-defined search routine
    #     2. We connect to the move_base server in ROS
    #     3. We start the ROS subscriber callback function registering the object
    #     4. We initialize counters in the class to be shared by the various callback routines
    def __init__(self):
        # Name this node, it must be unique
	rospy.init_node('autonomous', anonymous=True)

        # Enable shutdown in rospy (This is important so we cancel any move_base goals
        # when the node is killed)
        rospy.on_shutdown(self.shutdown)
        self.rest_time = rospy.get_param("~rest_time", 0.1) # Minimum pause at each location
        self.stalled_threshold = rospy.get_param("~stalled_threshold", 100) # Loops before stall

        # Goal state return values
        goal_states = ['PENDING', 'ACTIVE', 'PREEMPTED',
                       'SUCCEEDED', 'ABORTED', 'REJECTED',
                       'PREEMPTING', 'RECALLING', 'RECALLED',
                       'LOST']

        # Set up the goal locations. Poses are defined in the map frame.
        # An easy way to find the pose coordinates is to point-and-click
        # Nav Goals in RViz when running in the simulator.
        # Pose coordinates are then displayed in the terminal
        # that was used to launch RViz.
        self.waypoints=list()
         
        
        self.tf = TransformListener()
        






      #  self.locations = dict()
      #  self.wpname = dict()
        
        rospack = rospkg.RosPack()
        f = open(rospack.get_path('husky_wp')+'/params/pre-defined-path2.txt','r')

                                                 

      #  ct2 = 0
        with f as openfileobject:
            first_line = f.readline()
            for line in openfileobject:
                nome = [x.strip() for x in line.split(',')]
                #self.wpname[ct2] = nome[0]
                x = Decimal(nome[1]); y = Decimal(nome[2]); z = Decimal(nome[3])
                X = Decimal(nome[4]); Y = Decimal(nome[5]); Z = Decimal(nome[6])
                #self.locations[self.wpname[ct2]] = Pose(Point(x,y,z), Quaternion(X,Y,Z,1))
                self.waypoints.append(Pose(Point(x,y,z), Quaternion(0,0,0,1)))
                #print self.waypoints         
                #time.sleep(1)
                 


      #          ct2 = ct2+1
        #self.wp = -1
        #self.ct4 = 0

        print "Static path has : "
        print len(self.waypoints)
        print " point(s)."          
        time.sleep(5)

        # Publisher to manually control the robot (e.g. to stop it, queue_size=5)
        self.cmd_vel_pub = rospy.Publisher('cmd_vel', Twist, queue_size=5)

        # Subscribe to the move_base action server
        self.move_base = actionlib.SimpleActionClient("move_base", MoveBaseAction)

        rospy.loginfo("Waiting for move_base action server...")

        # Wait 60 seconds for the action server to become available
        self.move_base.wait_for_server(rospy.Duration(60))

        rospy.loginfo("Connected to move base server")
        rospy.loginfo("Starting navigation test")
        
        # Initialize a counter to track waypoints
        i = 0
        
        # Cycle through the four waypoints
        while i < len(self.waypoints) and not rospy.is_shutdown():
            # Update the marker display
            #self.marker_pub.publish(self.markers)
            
            # Intialize the waypoint goal
            goal = MoveBaseGoal()
            
            # Use the map frame to define goal poses
            goal.target_pose.header.frame_id = 'odom'
            
            # Set the time stamp to "now"
            goal.target_pose.header.stamp = rospy.Time.now()
            
            # Set the goal pose to the i-th waypoint
            goal.target_pose.pose = self.waypoints[i]
            
            # Start the robot moving toward the goal
            self.move(goal)
            
            i += 1            
            if rospy.has_param('/panel_goal'):
		# go to goal the goal goint  
                  # get parameter 
                panel_goal = rospy.get_param("/panel_goal")
                print panel_goal[0];
                print panel_goal[1];
                print panel_goal[2];


                while not rospy.is_shutdown():
                	try:
                		(trans,rot) = self.tf.lookupTransform('/odom', '/base_link', rospy.Time(0)) 
                		Tx=panel_goal[0]-trans[0];
                        	Ty=panel_goal[1]-trans[1];                       
                        	Tx=Tx*0.8
                        	Ty=Ty*0.8
                       		goal_x=trans[0]+Tx
                        	goal_y=trans[1]+Ty




                                # Intialize the waypoint goal
           			goal = MoveBaseGoal()
            
            			# Use the map frame to define goal poses
            			goal.target_pose.header.frame_id = 'odom'
            
            			# Set the time stamp to "now"
            			goal.target_pose.header.stamp = rospy.Time.now()


                                print "The goal is:"
                                print goal_x
                                print goal_y
  
                        	goal.target_pose.pose = Pose(Point(goal_x,goal_y,0), Quaternion(0,0,0,1))
                        	self.move(goal)
                		rospy.loginfo("Reach goal")
                       		break  
          
        		except (tf.LookupException, tf.ConnectivityException, tf.ExtrapolationException):
                        	rospy.loginfo("No transformation")
                break
            else:
                rospy.loginfo("No goal found")

                
                
                
   



    def move(self, goal):
            # Send the goal pose to the MoveBaseAction server
            self.move_base.send_goal(goal)
            
            # Allow 1 minute to get there
            finished_within_time = self.move_base.wait_for_result(rospy.Duration(600)) 
            
            # If we don't get there in time, abort the goal
            if not finished_within_time:
                self.move_base.cancel_goal()
                rospy.loginfo("Timed out achieving goal")
            else:
                # We made it!
                state = self.move_base.get_state()
                if state == GoalStatus.SUCCEEDED:
                    rospy.loginfo("Goal succeeded!")

    def shutdown(self):
        rospy.loginfo("Stopping the robot...")
        self.move_base.cancel_goal()
        rospy.sleep(2)
        self.cmd_vel_pub.publish(Twist())
        rospy.sleep(1)
コード例 #39
0
class GripperMarkers:

    _offset = 0.09
    def __init__(self, side_prefix):
        self._ik_service = IK(side_prefix)

        r_traj_controller_name = '/r_arm_controller/joint_trajectory_action'
        self.r_traj_action_client = SimpleActionClient(r_traj_controller_name, JointTrajectoryAction)
        rospy.loginfo('Waiting for a response from the trajectory action server for RIGHT arm...')
        self.r_traj_action_client.wait_for_server()

        l_traj_controller_name = '/l_arm_controller/joint_trajectory_action'
        self.l_traj_action_client = SimpleActionClient(l_traj_controller_name, JointTrajectoryAction)
        rospy.loginfo('Waiting for a response from the trajectory action server for LEFT arm...')
        self.l_traj_action_client.wait_for_server()

        self.r_joint_names = ['r_shoulder_pan_joint',
                              'r_shoulder_lift_joint',
                              'r_upper_arm_roll_joint',
                              'r_elbow_flex_joint',
                              'r_forearm_roll_joint',
                              'r_wrist_flex_joint',
                              'r_wrist_roll_joint']
        self.l_joint_names = ['l_shoulder_pan_joint',
                              'l_shoulder_lift_joint',
                              'l_upper_arm_roll_joint',
                              'l_elbow_flex_joint',
                              'l_forearm_roll_joint',
                              'l_wrist_flex_joint',
                              'l_wrist_roll_joint']

        rospy.Subscriber('ar_pose_marker', AlvarMarkers, self.marker_cb)
	
	self.side_prefix = side_prefix
        self._im_server = InteractiveMarkerServer("ik_request_markers_{}".format(side_prefix))
	self._tf_listener = TransformListener()
        self._menu_handler = MenuHandler()

        self._menu_handler.insert("Move {} arm here".format(side_prefix), callback=self.move_to_pose_cb)

        self.is_control_visible = False
        self.ee_pose = self.get_ee_pose()
        self.update_viz()
        self._menu_handler.apply(self._im_server, 'ik_target_marker')
        self._im_server.applyChanges()

    def get_ee_pose(self):
	from_frame = '/base_link'
	to_frame = '/' + self.side_prefix + '_wrist_roll_link'
	try:
	    t = self._tf_listener.getLatestCommonTime(from_frame, to_frame)
	    (pos, rot) = self._tf_listener.lookupTransform(from_frame, to_frame, t)
	except Exception as e:
	    rospy.logerr('Could not get end effector pose through TF.')
	    pos = [1.0, 0.0, 1.0]
	    rot = [0.0, 0.0, 0.0, 1.0]
	    import traceback
 	    traceback.print_exc()


	return Pose(Point(pos[0], pos[1], pos[2]),
			Quaternion(rot[0], rot[1], rot[2], rot[3]))

    def move_to_pose_cb(self, dummy):
        target_pose = GripperMarkers._offset_pose(self.ee_pose)
        ik_sol = self._ik_service.get_ik_for_ee(target_pose)
        self.move_to_joints(self.side_prefix, [ik_sol], 1.0)

    def marker_clicked_cb(self, feedback):
        if feedback.event_type == InteractiveMarkerFeedback.POSE_UPDATE:
            self.ee_pose = feedback.pose
            self.update_viz()
            self._menu_handler.reApply(self._im_server)
            self._im_server.applyChanges()

        elif feedback.event_type == InteractiveMarkerFeedback.BUTTON_CLICK:
            rospy.loginfo('Changing visibility of the pose controls.')
            if (self.is_control_visible):
                self.is_control_visible = False
            else:
                self.is_control_visible = True
        else:
            rospy.loginfo('Unhandled event: ' + str(feedback.event_type))

    def marker_cb(self, pose_markers):
        rospy.loginfo('AR Marker Pose updating')
        transform = GripperMarkers.get_matrix_from_pose(pose_markers.markers[0].pose.pose)
        offset_array = [0, 0, .03]
        offset_transform = tf.transformations.translation_matrix(offset_array)
        hand_transform = tf.transformations.concatenate_matrices(transform,
                                                             offset_transform)
        self.ee_pose = GripperMarkers.get_pose_from_transform(hand_transform)
        self.update_viz() 

    def update_viz(self):
        
        menu_control = InteractiveMarkerControl()
        menu_control.interaction_mode = InteractiveMarkerControl.BUTTON
        menu_control.always_visible = True
        frame_id = 'base_link'
        pose = self.ee_pose
        
        menu_control = self._add_gripper_marker(menu_control)
        text_pos = Point()
        text_pos.x = pose.position.x
        text_pos.y = pose.position.y
        text_pos.z = pose.position.z + 0.1
        text = "x=%.3f y=%.3f z=%.3f" % (pose.position.x, pose.position.y, pose.position.z)
        menu_control.markers.append(Marker(type=Marker.TEXT_VIEW_FACING,
                                           id=0, scale=Vector3(0, 0, 0.03),
                                           text=text,
                                           color=ColorRGBA(0.0, 0.0, 0.0, 0.5),
                                           header=Header(frame_id=frame_id),
                                           pose=Pose(text_pos, Quaternion(0, 0, 0, 1))))
        label_pos = Point()
        label_pos.x = pose.position.x
        label_pos.y = pose.position.y
        label_pos.z = pose.position.z
        label = "{} arm".format(self.side_prefix)
        menu_control.markers.append(Marker(type=Marker.TEXT_VIEW_FACING,
                                           id=0, scale=Vector3(0, 0, 0.03),
                                           text=label,
                                           color=ColorRGBA(0.0, 0.0, 0.0, 0.9),
                                           header=Header(frame_id=frame_id),
                                           pose=Pose(label_pos, Quaternion(0, 0, 0, 1))))

        int_marker = InteractiveMarker()
        int_marker.name = 'ik_target_marker'
        int_marker.header.frame_id = frame_id
        int_marker.pose = pose
        int_marker.scale = 0.2
        self._add_6dof_marker(int_marker)
        int_marker.controls.append(menu_control)
        self._im_server.insert(int_marker, self.marker_clicked_cb)

    def _add_gripper_marker(self, control):
        is_hand_open=False
        if is_hand_open:
            angle = 28 * numpy.pi / 180.0
        else:
            angle = 0
        transform1 = tf.transformations.euler_matrix(0, 0, angle)
        transform1[:3, 3] = [0.07691 - GripperMarkers._offset, 0.01, 0]
        transform2 = tf.transformations.euler_matrix(0, 0, -angle)
        transform2[:3, 3] = [0.09137, 0.00495, 0]
        t_proximal = transform1
        t_distal = tf.transformations.concatenate_matrices(transform1, transform2)
        mesh1 = self._make_mesh_marker()
        mesh1.mesh_resource = ('package://pr2_description/meshes/gripper_v0/gripper_palm.dae')
        mesh1.pose.position.x = -GripperMarkers._offset
        mesh1.pose.orientation.w = 1
        mesh2 = self._make_mesh_marker()
        mesh2.mesh_resource = ('package://pr2_description/meshes/gripper_v0/l_finger.dae')
        mesh2.pose = GripperMarkers.get_pose_from_transform(t_proximal)
        mesh3 = self._make_mesh_marker()
        mesh3.mesh_resource = ('package://pr2_description/meshes/gripper_v0/l_finger_tip.dae')
        mesh3.pose = GripperMarkers.get_pose_from_transform(t_distal)
        quat = tf.transformations.quaternion_multiply(
            tf.transformations.quaternion_from_euler(numpy.pi, 0, 0),
            tf.transformations.quaternion_from_euler(0, 0, angle))
        transform1 = tf.transformations.quaternion_matrix(quat)
        transform1[:3, 3] = [0.07691 - GripperMarkers._offset, -0.01, 0]
        transform2 = tf.transformations.euler_matrix(0, 0, -angle)
        transform2[:3, 3] = [0.09137, 0.00495, 0]
        t_proximal = transform1
        t_distal = tf.transformations.concatenate_matrices(transform1,transform2)
        mesh4 = self._make_mesh_marker()
        mesh4.mesh_resource = ('package://pr2_description/meshes/gripper_v0/l_finger.dae')
        mesh4.pose = GripperMarkers.get_pose_from_transform(t_proximal)
        mesh5 = self._make_mesh_marker()
        mesh5.mesh_resource = ('package://pr2_description/meshes/gripper_v0/l_finger_tip.dae')
        mesh5.pose = GripperMarkers.get_pose_from_transform(t_distal)

        control.markers.append(mesh1)
        control.markers.append(mesh2)
        control.markers.append(mesh3)
        control.markers.append(mesh4)
        control.markers.append(mesh5)
        return control

    @staticmethod
    def _offset_pose(pose):
        transform = GripperMarkers.get_matrix_from_pose(pose)
        offset_array = [-GripperMarkers._offset, 0, 0]
        offset_transform = tf.transformations.translation_matrix(offset_array)
        hand_transform = tf.transformations.concatenate_matrices(transform,
                                                             offset_transform)
        return GripperMarkers.get_pose_from_transform(hand_transform)

    @staticmethod
    def get_matrix_from_pose(pose):
        rotation = [pose.orientation.x, pose.orientation.y,
                pose.orientation.z, pose.orientation.w]
        transformation = tf.transformations.quaternion_matrix(rotation)
        position = [pose.position.x, pose.position.y, pose.position.z]
        transformation[:3, 3] = position
        return transformation

    @staticmethod
    def get_pose_from_transform(transform):
	pos = transform[:3,3].copy()
	rot = tf.transformations.quaternion_from_matrix(transform)
	return Pose(Point(pos[0], pos[1], pos[2]),
			Quaternion(rot[0], rot[1], rot[2], rot[3]))

    def _make_mesh_marker(self):
        mesh = Marker()
        mesh.mesh_use_embedded_materials = False
        mesh.type = Marker.MESH_RESOURCE
    	mesh.scale.x = 1.0
        mesh.scale.y = 1.0
        mesh.scale.z = 1.0

        target_pose = GripperMarkers._offset_pose(self.ee_pose)
        ik_sol = self._ik_service.get_ik_for_ee(target_pose)
        if ik_sol == None:
            mesh.color = ColorRGBA(1.0, 0.0, 0.0, 0.6)
        else:
            mesh.color = ColorRGBA(0.0, 1.0, 0.0, 0.6)
        return mesh

    def _add_6dof_marker(self, int_marker):
        is_fixed = True
        control = self._make_6dof_control('rotate_x', Quaternion(1, 0, 0, 1), False, is_fixed)
        int_marker.controls.append(control)
        control = self._make_6dof_control('move_x', Quaternion(1, 0, 0, 1), True, is_fixed)
        int_marker.controls.append(control)
        control = self._make_6dof_control('rotate_z', Quaternion(0, 1, 0, 1), False, is_fixed)
        int_marker.controls.append(control)
        control = self._make_6dof_control('move_z', Quaternion(0, 1, 0, 1), True, is_fixed)
        int_marker.controls.append(control)
        control = self._make_6dof_control('rotate_y', Quaternion(0, 0, 1, 1), False, is_fixed)
        int_marker.controls.append(control)
        control = self._make_6dof_control('move_y', Quaternion(0, 0, 1, 1), True, is_fixed)
        int_marker.controls.append(control)

    def _make_6dof_control(self, name, orientation, is_move, is_fixed):
        control = InteractiveMarkerControl()
        control.name = name
        control.orientation = orientation
        control.always_visible = False
        if (self.is_control_visible):
            if is_move:
                control.interaction_mode = InteractiveMarkerControl.MOVE_AXIS
            else:
                control.interaction_mode = InteractiveMarkerControl.ROTATE_AXIS
        else:
            control.interaction_mode = InteractiveMarkerControl.NONE
        if is_fixed:
            control.orientation_mode = InteractiveMarkerControl.FIXED
        return control

    def move_to_joints(self, side_prefix, positions, time_to_joint):
        '''Moves the arm to the desired joints'''
        traj_goal = JointTrajectoryGoal()
        traj_goal.trajectory.header.stamp = (rospy.Time.now() + rospy.Duration(0.1))
        time_move = time_to_joint
        print "using following positions %s" % positions
        for pose in positions:
            velocities = [0] * len(pose)
            traj_goal.trajectory.points.append(JointTrajectoryPoint(positions=pose,
                            velocities=velocities, time_from_start=rospy.Duration(time_move)))
            time_move += time_to_joint

        if (side_prefix == 'r'):
            traj_goal.trajectory.joint_names = self.r_joint_names
            self.r_traj_action_client.send_goal(traj_goal)
        else:
            traj_goal.trajectory.joint_names = self.l_joint_names
            self.l_traj_action_client.send_goal(traj_goal)
コード例 #40
0
ファイル: spray.py プロジェクト: madsbahrt/FroboMind
class SprayAction:
    """
        Drives x meters either forward or backwards depending on the given distance.
        the velocity should always be positive. 
    """

    def __init__(self, name, odom_frame, base_frame):
        """
        
        @param name: the name of the action
        @param odom_frame: the frame the robot is moving in (odom_combined)
        @param base_frame: the vehicles own frame (usually base_link)
        """

        self._action_name = name
        self.__odom_frame = odom_frame
        self.__base_frame = base_frame
        self.__server = actionlib.SimpleActionServer(self._action_name, sprayAction, auto_start=False)
        self.__server.register_preempt_callback(self.preempt_cb)
        self.__server.register_goal_callback(self.goal_cb)

        self.__cur_pos = 0
        self.__start_pos = 0
        self.__start_yaw = 0
        self.__cur_yaw = 0

        self.__feedback = sprayFeedback()

        self.__listen = TransformListener()
        # self.vel_pub = rospy.Publisher("/fmControllers/cmd_vel_auto",Twist)
        self.spray_pub = rospy.Publisher("/fmControllers/spray", UInt32)

        self.__start_time = rospy.Time.now()
        self.new_goal = False
        self.n_sprays = 0
        self.spray_msg = UInt32()

        self.spray_l = False
        self.spray_cnt = 0

        self.__server.start()

    def preempt_cb(self):
        rospy.loginfo("Preempt requested")
        self.spray_msg.data = 0
        self.spray_pub.publish(self.spray_msg)
        self.__server.set_preempted()

    def goal_cb(self):
        """
            called when we receive a new goal
            the goal contains a desired radius and a success radius in which we check if the turn succeeded or not
            the message also contains if we should turn left or right
        """
        g = self.__server.accept_new_goal()
        self.spray_dist = g.distance
        self.spraytime = g.spray_time

        self.new_goal = True

    def on_timer(self, e):
        """
            called regularly by a ros timer
            in here we simply orders the vehicle to start moving either forward 
            or backwards depending on the distance sign, while monitoring the 
            travelled distance, if the distance is equal to or greater then this
            action succeeds.
        """
        if self.__server.is_active():
            if self.new_goal:
                self.new_goal = False
                self.n_sprays = 0
                self.__get_start_position()
            else:
                if self.__get_current_position():
                    if self.__get_distance() >= self.spray_dist:
                        self.do_spray()
                        self.__get_start_position()
                else:
                    self.__server.set_aborted(None, "could not locate")
                    rospy.logerr("Could not locate vehicle")
                    self.spray_msg.data = 0
                    self.spray_pub.publish(self.spray_msg)

    def __get_distance(self):
        return math.sqrt(
            math.pow(self.__cur_pos[0][0] - self.__start_pos[0][0], 2)
            + math.pow(self.__cur_pos[0][1] - self.__start_pos[0][1], 2)
        )

    def __get_start_position(self):
        ret = False
        try:
            self.__start_pos = self.__listen.lookupTransform(self.__odom_frame, self.__base_frame, rospy.Time(0))
            self.__start_yaw = tf.transformations.euler_from_quaternion(self.__start_pos[1])[2]
            ret = True
        except (tf.LookupException, tf.ConnectivityException), err:
            rospy.loginfo("could not locate vehicle")

        return ret
コード例 #41
0
class vel_control(object):
    def __init__(self, args, joint_values):
        self.args = args
        self.joint_values_home = joint_values

        # CPA PARAMETERS
        # At the end, the disciplacement will take place as a final orientation
        self.Displacement = [0.01, 0.01, 0.01]

        # CPA Parameters
        self.zeta = 0.5  # Attractive force gain of the goal
        self.max_error_allowed_pos_x = 0.010
        self.max_error_allowed_pos_y = 0.010
        self.max_error_allowed_pos_z = 0.006
        self.max_error_allowed_ori = 0.14
        self.dist_att = 0.1  # Influence distance in workspace
        self.dist_att_config = 0.2  # Influence distance in configuration space
        self.alfa_geral = 1.5 # multiply each alfa (position and rotation) equally
        self.gravity_compensation = 9
        self.alfa_pos = 4.5 * self.alfa_geral  # Grad step of positioning - Default: 0.5
        self.alfa_rot = 4 * self.alfa_geral  # Grad step of orientation - Default: 0.4

        # attributes used to receive msgs while publishing new ones
        self.processing = False
        self.new_msg = False
        self.msg = None

        # CPA Parameters
        self.diam_goal = 0.05

        # Topic used to publish vel commands
        self.pub_vel = rospy.Publisher('/joint_group_vel_controller/command', Float64MultiArray,  queue_size=10)

        # Topic used to control the gripper
        self.griper_pos = rospy.Publisher('/gripper/command', JointTrajectory,  queue_size=10)
        self.gripper_msg = JointTrajectory()
        self.gripper_msg.joint_names = ['robotiq_85_left_knuckle_joint']

        # visual tools from moveit
        # self.scene = PlanningSceneInterface("base_link")
        self.marker_publisher = rospy.Publisher('visualization_marker2', Marker, queue_size=10)

        # Subscriber used to read joint values
        rospy.Subscriber('/joint_states', JointState, self.ur5_actual_position, queue_size=10)

        # if true, this node receives messages from publish_dynamic_goal.py
        if self.args.dyntest:
            # Subscriber used to receive goal coordinates from publish_dynamic_goal.py
            rospy.Subscriber('/dynamic_goal', Point, self.get_goal_coordinates, queue_size=10)

        # actionClient used to send joint positions
        self.client = actionlib.SimpleActionClient('pos_based_pos_traj_controller/follow_joint_trajectory', FollowJointTrajectoryAction)
        print "Waiting for server (pos_based_pos_traj_controller)..."
        self.client.wait_for_server()
        print "Connected to server (pos_based_pos_traj_controller)"
        rospy.sleep(1)

        # Standard attributes used to send joint position commands
        self.joint_vels = Float64MultiArray()
        self.goal = FollowJointTrajectoryGoal()
        self.goal.trajectory = JointTrajectory()
        self.goal.trajectory.joint_names = ['shoulder_pan_joint', 'shoulder_lift_joint',
                                            'elbow_joint', 'wrist_1_joint', 'wrist_2_joint',
                                            'wrist_3_joint']
        self.initial_time = 4

        # Class attribute used to perform TF transformations
        self.tf = TransformListener()

        # Denavit-Hartenberg parameters of UR5
        # The order of the parameters is d1, SO, EO, a2, a3, d4, d45, d5, d6
        self.ur5_param = (0.089159, 0.13585, -0.1197, 0.425, 0.39225, 0.10915, 0.093, 0.09465, 0.0823 + 0.15)

    """
    Adds spheres in RVIZ - Used to plot goals and obstacles
    """
    def add_sphere(self, pose, diam, color):
        marker = Marker()
        marker.header.frame_id = "base_link"
        marker.id = 0
        marker.pose.position = Point(pose[0], pose[1], pose[2])
        marker.type = marker.SPHERE
        marker.action = marker.ADD
        marker.scale = Vector3(diam, diam, diam)
        marker.color = color
        self.marker_publisher.publish(marker)

    """
    Function to ensure safety
    """
    def safety_stop(self, ptAtual, wristPt):
        # High limit in meters of the end effector relative to the base_link
        high_limit = 0.01

        # Does not allow wrist_1_link to move above 20 cm relative to base_link
        high_limit_wrist_pt = 0.15

        if ptAtual[-1] < high_limit or wristPt[-1] < high_limit_wrist_pt:
            # Be careful. Only the limit of the end effector is being watched but the other
            # joint can also exceed this limit and need to be carefully watched by the operator
            rospy.loginfo("High limit of " + str(high_limit) + " exceeded!")
            self.home_pos()
            raw_input("\n==== Press enter to load Velocity Controller and start APF")
            turn_velocity_controller_on()

    """
    This function check if the goal position was reached
    """
    def all_close(self, goal, tolerance = 0.015):

        angles_difference = [self.actual_position[i] - goal[i] for i in range(6)]
        total_error = np.sum(angles_difference)

        if abs(total_error) > tolerance:
            return False

        return True

    """
    This function is responsible for closing the gripper
    """
    def close_gripper(self):
        self.gripper_msg.points = [JointTrajectoryPoint(positions=[0.274], velocities=[0], time_from_start=rospy.Duration(0.1))]
        self.griper_pos.publish(self.gripper_msg)

    """
    This function is responsible for openning the gripper
    """
    def open_gripper(self):
        self.gripper_msg.points = [JointTrajectoryPoint(positions=[0.0], velocities=[0], time_from_start=rospy.Duration(1.0))]
        self.griper_pos.publish(self.gripper_msg)

    """
    The joint states published by /joint_staes of the UR5 robot are in wrong order.
    /joint_states topic normally publishes the joint in the following order:
    [elbow_joint, shoulder_lift_joint, shoulder_pan_joint, wrist_1_joint, wrist_2_joint, wrist_3_joint]
    But the correct order of the joints that must be sent to the robot is:
    ['shoulder_pan_joint', 'shoulder_lift_joint', 'elbow_joint', 'wrist_1_joint', 'wrist_2_joint', 'wrist_3_joint']
    """
    def ur5_actual_position(self, joint_values_from_ur5):
        # rospy.loginfo(joint_values_from_ur5)
        if self.args.gazebo:
            self.th3, self.robotic, self.th2, self.th1, self.th4, self.th5, self.th6 = joint_values_from_ur5.position
        else:
            self.th3, self.th2, self.th1, self.th4, self.th5, self.th6 = joint_values_from_ur5.position
        self.actual_position = [self.th1, self.th2, self.th3, self.th4, self.th5, self.th6]

    """
    When to node /dynamic_goal from publish_dynamic_goal.py is used instead of Markers, this
    function is responsible for getting the coordinates published by the node and save it
    as attribute of the class
    """
    def get_goal_coordinates(self, goal_coordinates):
        self.ptFinal = [goal_coordinates.x, goal_coordinates.y, goal_coordinates.z]
        self.add_sphere(self.ptFinal, self.diam_goal, ColorRGBA(0.0, 1.0, 0.0, 1.0))

    """
    Used to test velcoity control under /joint_group_vel_controller/command topic
    """
    def velocity_control_test(self):
        # publishing rate for velocity control
        # Joints are in the order [base, shoulder, elbow, wrist_1, wrist_2, wrist_3]
        rate = rospy.Rate(125)

        while not rospy.is_shutdown():
            self.joint_vels.data = np.array([0.0, 0.0, 0.0, 0.0, 0.0, 0.0])
            self.pub_vel.publish(self.joint_vels)
            rospy.loginfo(self.actual_position)
            rate.sleep()

    """
    Send the HOME position to the robot
    self.client.wait_for_result() does not work well.
    Instead, a while loop has been created to ensure that the robot reaches the
    goal even after the failure.
    """
    def home_pos(self):
        turn_position_controller_on()
        rospy.sleep(0.1)
        print(self.joint_values_home)

        # First point is current position
        try:
            self.goal.trajectory.points = [(JointTrajectoryPoint(positions=self.joint_values_home, velocities=[0]*6, time_from_start=rospy.Duration(self.initial_time)))]
            self.initial_time += 1
            if not self.all_close(self.joint_values_home):
                raw_input("==== Press enter to home the robot!")
                print "'Homing' the robot."
                self.client.send_goal(self.goal)
                self.client.wait_for_result()
                while not self.all_close(self.joint_values_home):
                    self.client.send_goal(self.goal)
                    self.client.wait_for_result()
        except KeyboardInterrupt:
            self.client.cancel_goal()
            raise
        except:
            raise

        print "\n==== The robot is HOME position!"


    """
    Get forces from APF algorithm
    """
    def get_joint_forces(self, ptAtual, ptFinal, oriAtual, dist_EOF_to_Goal, err_ori):

        # Get UR5 Jacobian of each link
        Jacobian = get_geometric_jacobian(self.ur5_param, self.actual_position)

        # Getting attractive forces
        forces_p = np.zeros((3, 1))
        forces_w = np.zeros((3, 1))

        for i in range(3):
            if abs(ptAtual[i] - ptFinal[i]) <= self.dist_att:
                f_att_l = -self.zeta*(ptAtual[i] - ptFinal[i])
            else:
                f_att_l = -self.dist_att*self.zeta*(ptAtual[i] - ptFinal[i])/dist_EOF_to_Goal[i]

            if abs(oriAtual[i] - self.Displacement[i]) <= self.dist_att_config:
                f_att_w = -self.zeta*(oriAtual[i] - self.Displacement[i])
            else:
                f_att_w = -self.dist_att_config*self.zeta*(oriAtual[i] - self.Displacement[i])/dist_EOF_to_Goal[i]

            forces_p[i, 0] = f_att_l
            forces_w[i, 0] = f_att_w

        forces_p = np.asarray(forces_p)
        JacobianAtt_p = np.asarray(Jacobian[5])
        joint_att_force_p = JacobianAtt_p.dot(forces_p)
        joint_att_force_p = np.multiply(joint_att_force_p, [[0.5], [0.1], [1.5], [1], [1], [1]])

        forces_w = np.asarray(forces_w)
        JacobianAtt_w = np.asarray(Jacobian[6])
        joint_att_force_w = JacobianAtt_w.dot(forces_w)
        joint_att_force_w = np.multiply(joint_att_force_w, [[0], [0.1], [0.1], [0.4], [0.4], [0.4]])

        return np.transpose(joint_att_force_p), np.transpose(joint_att_force_w)


    """
    Gets ptFinal and oriAtual
    """
    def get_tf_param(self, approach):
        # Check if a marker is used instead of a dynamic goal published by publish_dynamic_goal.py
        if self.args.armarker:
            # When the marker disappears we get an error and the node is killed. To avoid this
            # we implemented this try function to check if ar_marker_0 frame is available
            try:
                # used when Ar Marker is ON
                ptFinal, oriFinal = self.tf.lookupTransform("base_link", "ar_marker_0", rospy.Time())

                oriFinal = list(euler_from_quaternion(oriFinal))

                # Make YAW Angle goes from 0 to 2*pi
                # Solution proposed by
                # https://answers.ros.org/question/302953/tfquaternion-getangle-eqivalent-for-rospy/
                ptAtual, oriAtual = self.tf.lookupTransform("ar_marker_0", "grasping_link", rospy.Time())
                angle = -1 * 2 * np.arccos(oriAtual[-1])
                oriAtual = list(euler_from_quaternion(oriAtual))
                oriAtual[0] = angle
                self.add_sphere(ptFinal, self.diam_goal, ColorRGBA(0.0, 1.0, 0.0, 1.0))

                if not approach:
                    # Reach the position above the goal (object)
                    ptFinal[-1] += 0.02
                    max_error_allowed_pos_z = self.max_error_allowed_pos_z + ptFinal[-1]
                    return ptFinal, oriAtual, oriFinal, max_error_allowed_pos_z

                max_error_allowed_pos_z = self.max_error_allowed_pos_z

                # Return it if pick is performed
                return ptFinal, oriAtual, oriFinal, max_error_allowed_pos_z
            except:
                if not rospy.is_shutdown():
                    self.home_pos()
                    raw_input("\nWaiting for /ar_marker_0 frame to be available! Press ENTER after /ar_marker_0 shows up.")
                    turn_velocity_controller_on()
                    self.CPA_vel_control(approach)

    """
    Main function related the Artificial Potential Field method
    """
    def CPA_vel_control(self, approach = False):

        # Return the end effector location relative to the base_link
        ptAtual, _ = self.tf.lookupTransform("base_link", "grasping_link", rospy.Time())

        if approach:
            self.alfa_pos = 8 * self.alfa_geral
            self.pos_z = 0.04 if approach else None

        if self.args.gazebo:
            self.alfa_pos = 4.5 * self.alfa_geral * self.gravity_compensation * 0.001 # Grad step of positioning - Default: 0.5
            self.alfa_rot = 4 * self.alfa_geral * 0.01

            if approach:
                self.alfa_pos = 8 * self.alfa_geral * self.gravity_compensation # Grad step of positioning - Default: 0.5
                self.alfa_rot = 6 * self.alfa_geral # Grad step of orientation - Default: 0.4


        # Get ptFinal published by ar_marker_0 frame and the orientation from grasping_link to ar_marker_0
        ptFinal, oriAtual, oriFinal, max_error_allowed_pos_z = self.get_tf_param(approach)

        # Calculate the correction of the orientation relative to the actual orientation
        R, P, Y = -1 * oriAtual[0], -1 * oriAtual[1], 0.0
        corr = [R, P, Y]
        oriAtual = [oriAtual[i] + corr[i] for i in range(len(corr))]
        err_ori = abs(np.sum(oriAtual))

        # Calculate the distance between end effector and goal in each direction
        # it is necessary to approach the object
        dist_vec_x, dist_vec_y, dist_vec_z = np.abs(ptAtual - np.asarray(ptFinal))
        if approach:
            dist_EOF_to_Goal = [dist_vec_x, dist_vec_y, self.pos_z]
        else:
            dist_EOF_to_Goal = [dist_vec_x, dist_vec_y, dist_vec_z]

        # Frequency of the velocity controller pubisher
        # Max frequency: 125 Hz
        rate = rospy.Rate(125)

        while not rospy.is_shutdown() and (dist_vec_z > max_error_allowed_pos_z or dist_vec_y > self.max_error_allowed_pos_y or \
            dist_vec_x > self.max_error_allowed_pos_x or err_ori > self.max_error_allowed_ori):

            # In order to keep orientation constant, we need to correct the orientation
            # of the end effector in respect to the ar_marker_0 orientation
            oriAtual = [oriAtual[i] + corr[i] for i in range(len(corr))]

            # Get absolute orientation error
            err_ori = abs(np.sum(oriAtual))

            # Get attractive linear and angular forces and repulsive forces
            joint_att_force_p, joint_att_force_w = \
                self.get_joint_forces(ptAtual, ptFinal, oriAtual, dist_EOF_to_Goal, err_ori)

            # Publishes joint valocities related to position only
            self.joint_vels.data = np.array(self.alfa_pos * joint_att_force_p[0])

            # If orientation control is turned on, sum actual position forces to orientation forces
            if self.args.OriON:
                self.joint_vels.data = self.joint_vels.data + \
                    self.alfa_rot * joint_att_force_w[0]

            self.pub_vel.publish(self.joint_vels)

            # Get ptFinal published by ar_marker_0 frame and the orientation from grasping_link to ar_marker_0
            # The oriFinal needs to be tracked online because the object will be dynamic
            ptFinal, oriAtual, oriFinal, max_error_allowed_pos_z = self.get_tf_param(approach)

            # Calculate the distance between end effector and goal
            # dist_EOF_to_Goal = np.linalg.norm(ptAtual - np.asarray(ptFinal))
            dist_vec_x, dist_vec_y, dist_vec_z = np.abs(ptAtual - np.asarray(ptFinal))

            # Return the end effector position relative to the base_link
            ptAtual, _ = self.tf.lookupTransform("base_link", "grasping_link", rospy.Time())

            print "Z_position: ", ptAtual[-1]

            # Check wrist_1_link position just for safety
            wristPt, _ = self.tf.lookupTransform("base_link", "wrist_1_link", rospy.Time())

            # Function to ensure safety. It does not allow End Effector to move below 20 cm above the desk
            self.safety_stop(ptAtual, wristPt)

            if approach:
                dist_vec_z = self.pos_z
                # The end effector will move 1 cm below the marker
                if ptAtual[-1] < (ptFinal[-1] - 0.01):
                    print "Break loop."
                    break
                ptAtual = [ptAtual[0], ptAtual[1], self.pos_z]
                dist_EOF_to_Goal = [dist_vec_x, dist_vec_y, self.pos_z]
            else:
                dist_EOF_to_Goal = [dist_vec_x, dist_vec_y, dist_vec_z]

            rate.sleep()
コード例 #42
0
                        type=float)
    parser.add_argument('--normalize',
                        action='store_true',
                        help='scale '
                        'computed likelihoods (see description)')
    args = parser.parse_args()
    args = parser.parse_args(rospy.myargv(sys.argv)[1:])

    marker_pub = rospy.Publisher('pose_likelihood', Marker)
    get_pose_likelihood = rospy.ServiceProxy(
        'pose_likelihood_server/'
        'get_pose_likelihood', GetMultiplePoseLikelihood)

    rospy.sleep(1)
    time = tf_listener.getLatestCommonTime('odom', 'base_link')
    p, q = tf_listener.lookupTransform('odom', 'base_link', time)
    q = quaternion_from_euler(0, 0,
                              euler_from_quaternion(q)[2] + radians(args.yaw))

    def around(base, area, step):
        l = arange(base - step, base - area, -step)
        r = arange(base, base + area, step)
        return hstack([l, r])

    x_range = around(p[0], args.area, args.step)
    y_range = around(p[1], args.area, args.step)

    m = Marker()
    m.header.frame_id = 'odom'
    m.type = Marker.CUBE_LIST
    m.action = Marker.ADD
コード例 #43
0
ファイル: f2p_specific.py プロジェクト: ipa-tys/accompany_tys
            p2 = Point()
            p2.x = humanX
            p2.y = humanY
            p2.z = 0
            marker.points = [p1,p2]
            markerArray.markers.append(marker)
            publisher.publish(markerArray)
            dx = humanX - trans[0]
            dy = humanY - trans[1]
            target_angle = math.atan2(dy, dx)

rospy.Subscriber("/trackedHumansMod", TrackedHumans, trackedHumans_callback)

print("hi")
# sss.say(["hello"])
# sss.move("base", [1,-0.5,0])
print("ho")
while not rospy.is_shutdown():
    # listener1.waitForTransform('/map','/base_link',rospy.Time(),rospy.Duration(5))
    if trackedPerson != "":
        (trans, rot) = listener.lookupTransform('/map','/base_link',rospy.Time(0))
        phi = euler_from_quaternion(rot)
        current_angle = phi[2]
        "Current angle:"
        print phi
        # h = sss.move("base", [trans[0], trans[1], target_angle], False)
        h = sss.move("base", [trans[0], trans[1], target_angle], False)
        rospy.sleep(3)
    else:
        print "not follow"
コード例 #44
0
class Controller():
    Manual = 0
    Automatic = 1
    TakeOff = 2

    def __init__(self):
        self.pubNav = rospy.Publisher('cmd_vel', Twist, queue_size=1)
        self.listener = TransformListener()
        rospy.Subscriber("joy", Joy, self._joyChanged)
        rospy.Subscriber("cmd_vel_telop", Twist, self._cmdVelTelopChanged)
        self.cmd_vel_telop = Twist()
        #self.pidX = PID(20, 12, 0.0, -30, 30, "x")
        #self.pidY = PID(-20, -12, 0.0, -30, 30, "y")
        self.pidX = PID(20, 12, 0.0, -30, 30, "x")
        self.pidY = PID(20, 12, 0.0, -30, 30, "y")
        self.pidZ = PID(15000, 3000.0, 1500.0, 10000, 60000, "z")
        self.pidYaw = PID(-50.0, 0.0, 0.0, -200.0, 200.0, "yaw")
        self.state = Controller.Manual
        self.targetZ = 1
        self.lastJoy = Joy()

    def _cmdVelTelopChanged(self, data):
        self.cmd_vel_telop = data
        if self.state == Controller.Manual:
            self.pubNav.publish(data)

    def pidReset(self):
        self.pidX.reset()
        self.pidZ.reset()
        self.pidZ.reset()
        self.pidYaw.reset()

    def _joyChanged(self, data):
        if len(data.buttons) == len(self.lastJoy.buttons):
            delta = np.array(data.buttons) - np.array(self.lastJoy.buttons)
            print("Buton ok")
            #Button 1
            if delta[0] == 1 and self.state != Controller.Automatic:
                print("Automatic!")
                thrust = self.cmd_vel_telop.linear.z
                print(thrust)
                self.pidReset()
                self.pidZ.integral = thrust / self.pidZ.ki
                self.targetZ = 1
                self.state = Controller.Automatic
            #Button 2
            if delta[1] == 1 and self.state != Controller.Manual:
                print("Manual!")
                self.pubNav.publish(self.cmd_vel_telop)
                self.state = Controller.Manual
            #Button 3
            if delta[2] == 1:
                self.state = Controller.TakeOff
                print("TakeOff!")
            #Button 5
            if delta[4] == 1:
                #self.targetZ += 0.1
                print(self.targetZ)
            #Button 6
            if delta[5] == 1:
                #self.targetZ -= 0.1
                print(self.targetZ)
        self.lastJoy = data

    def run(self):
        thrust = 0
        print("jello")
        while not rospy.is_shutdown():
            if self.state == Controller.TakeOff:
                t = self.listener.getLatestCommonTime("/mocap", "/Nano_Mark2")
                if self.listener.canTransform("/mocap", "/Nano_Mark2", t):
                    position, quaternion = self.listener.lookupTransform(
                        "/mocap", "/Nano_Mark2", t)
                    print(position[0], position[1], position[2])
                    if position[2] > 0.1 or thrust > 50000:
                        self.pidReset()
                        self.pidZ.integral = thrust / self.pidZ.ki
                        #self.targetZ = 0.5
                        self.state = Controller.Automatic
                        thrust = 0
                    else:
                        thrust += 100
                        msg = self.cmd_vel_telop
                        msg.linear.z = thrust
                        self.pubNav.publish(msg)

            if self.state == Controller.Automatic:
                # transform target world coordinates into local coordinates
                t = self.listener.getLatestCommonTime("/mocap", "/Nano_Mark2")
                print(t)
                if self.listener.canTransform("/mocap", "/Nano_Mark2", t):
                    position, quaternion = self.listener.lookupTransform(
                        "/mocap", "/Nano_Mark2", t)
                    print(position[0], position[1], position[2])
                    euler = tf.transformations.euler_from_quaternion(
                        quaternion)
                    print(euler[2])
                    msg = self.cmd_vel_telop
                    #msg.linear.x = self.pidX.update(0.0,-1.0-position[0])
                    #msg.linear.y = self.pidY.update(0.0,-1.0-position[1])
                    msg.linear.z = self.pidZ.update(
                        0.0, 1.0 - position[2]
                    )  #self.pidZ.update(position[2], self.targetZ)
                    #msg.angular.z = self.pidYaw.update(euler[2],0.0)
                    print(msg.linear.x, msg.linear.y, msg.linear.z,
                          msg.angular.z)
                    #print(euler[2])
                    #print(msg.angular.z)
                    self.pubNav.publish(msg)

            rospy.sleep(0.01)
コード例 #45
0
class ArmUtils():
  
    wipe_started = False 
    standoff = 0.368 #0.2 + 0.168 (dist from wrist to fingertips)
    torso_min = 0.0115 
    torso_max = 0.295 
    dist = 0. 

    move_arm_error_dict = {
         -1 : "PLANNING_FAILED: Could not plan a clear path to goal.", 
          0 : "Move Arm Action Aborted on Internal Failure.", 
          1 : "SUCCEEDED", 
         -2 : "TIMED_OUT",
         -3 : "START_STATE_IN_COLLISION: Try freeing the arms manually.",
         -4 : "START_STATE_VIOLATES_PATH_CONSTRAINTS",
         -5 : "GOAL_IN_COLLISION",
         -6 : "GOAL_VIOLATES_PATH_CONSTRAINTS",
         -7 : "INVALID_ROBOT_STATE",
         -8 : "INCOMPLETE_ROBOT_STATE",
         -9 : "INVALID_PLANNER_ID",
         -10 : "INVALID_NUM_PLANNING_ATTEMPTS",
         -11 : "INVALID_ALLOWED_PLANNING_TIME",
         -12 : "INVALID_GROUP_NAME",
         -13 : "INVALID_GOAL_JOINT_CONSTRAINTS",
         -14 : "INVALID_GOAL_POSITION_CONSTRAINTS",
         -15 : "INVALID_GOAL_ORIENTATION_CONSTRAINTS",
         -16 : "INVALID_PATH_JOINT_CONSTRAINTS",
         -17 : "INVALID_PATH_POSITION_CONSTRAINTS",
         -18 : "INVALID_PATH_ORIENTATION_CONSTRAINTS",
         -19 : "INVALID_TRAJECTORY",
         -20 : "INVALID_INDEX",
         -21 : "JOINT_LIMITS_VIOLATED",
         -22 : "PATH_CONSTRAINTS_VIOLATED",
         -23 : "COLLISION_CONSTRAINTS_VIOLATED",
         -24 : "GOAL_CONSTRAINTS_VIOLATED",
         -25 : "JOINTS_NOT_MOVING",
         -26 : "TRAJECTORY_CONTROLLER_FAILED",
         -27 : "FRAME_TRANSFORM_FAILURE",
         -28 : "COLLISION_CHECKING_UNAVAILABLE",
         -29 : "ROBOT_STATE_STALE",
         -30 : "SENSOR_INFO_STALE",
         -31 : "NO_IK_SOLUTION: Cannot reach goal configuration.",
         -32 : "INVALID_LINK_NAME",
         -33 : "IK_LINK_IN_COLLISION: Cannot reach goal configuration without contact.",
         -34 : "NO_FK_SOLUTION",
         -35 : "KINEMATICS_STATE_IN_COLLISION",
         -36 : "INVALID_TIMEOUT"
         }

    def __init__(self, tfListener=None):
        self.move_right_arm_client = actionlib.SimpleActionClient('move_right_arm', arm_navigation_msgs.msg.MoveArmAction)
        rospy.loginfo("Waiting for move_right_arm server")
        if self.move_right_arm_client.wait_for_server(rospy.Duration(50)):
            rospy.loginfo("Found move_right_arm server")
        else:
            rospy.logwarn("Cannot find move_right_arm server")

        self.r_arm_traj_client = actionlib.SimpleActionClient('r_arm_controller/joint_trajectory_action', JointTrajectoryAction)
        rospy.loginfo("Waiting for r_arm_controller/joint_trajectory_action server")
        if self.r_arm_traj_client.wait_for_server(rospy.Duration(5)):
            rospy.loginfo("Found r_arm_controller/joint_trajectory_action server")
        else:
            rospy.logwarn("Cannot find r_arm_controller/joint_trajectory_action server")

        self.r_arm_follow_traj_client = actionlib.SimpleActionClient('r_arm_controller/follow_joint_trajectory', FollowJointTrajectoryAction)
        rospy.loginfo("Waiting for r_arm_controller/follow_joint_trajectory server")
        if self.r_arm_follow_traj_client.wait_for_server(rospy.Duration(5)):
            rospy.loginfo("Found r_arm_controller/follow_joint_trajectory server")
        else:
            rospy.logwarn("Cannot find r_arm_controller/follow_joint_trajectory server")

        self.torso_client = actionlib.SimpleActionClient('torso_controller/position_joint_action', SingleJointPositionAction)
        rospy.loginfo("Waiting for  torso_controller/position_joint_action server")
        if self.torso_client.wait_for_server(rospy.Duration(5)):
            rospy.loginfo("Found torso_controller/position_joint_action server")
        else:
            rospy.logwarn("Cannot find torso_controller/position_joint_action server")

        self.r_gripper_client = actionlib.SimpleActionClient('r_gripper_controller/gripper_action', Pr2GripperCommandAction)
        rospy.loginfo("Waiting for r_gripper_controller/gripper_action server")
        if self.r_gripper_client.wait_for_server(rospy.Duration(5)):
            rospy.loginfo("Found r_gripper_controller/gripper_action server")
        else:
            rospy.logwarn("Cannot find r_gripper_controller/gripper_action server")
        
        rospy.loginfo("Waiting for r_utility_frame_service")
        try:
            rospy.wait_for_service('/r_utility_frame_update', 7.0)
            self.update_frame = rospy.ServiceProxy('/r_utility_frame_update', FrameUpdate)
            rospy.loginfo("Found r_utility_frame_service")
        except:
            rospy.logwarn("Right Utility Frame Service Not available")
        
        #self.joint_state_lock = RLock()
        rospy.Subscriber('r_arm_controller/state', JointTrajectoryControllerState, self.update_joint_state)
        self.torso_state_lock = RLock()
        rospy.Subscriber('torso_controller/state', JointTrajectoryControllerState, self.update_torso_state)
        
        #self.r_arm_command = rospy.Publisher('/r_arm_controller/command', JointTrajectory )
        self.wt_log_out = rospy.Publisher('wt_log_out', String)

        if tfListener is None:
            self.tf = TransformListener()
        else:
            self.tf = tfListener
        self.tfb = TransformBroadcaster()
        
        rospy.loginfo("Waiting for FK/IK Solver services")
        try:
            rospy.wait_for_service('/pr2_right_arm_kinematics/get_fk')
            rospy.wait_for_service('/pr2_right_arm_kinematics/get_fk_solver_info')
            rospy.wait_for_service('/pr2_right_arm_kinematics/get_ik')
            rospy.wait_for_service('/pr2_right_arm_kinematics/get_ik_solver_info')
            self.fk_info_proxy = rospy.ServiceProxy('/pr2_right_arm_kinematics/get_fk_solver_info',
                                                    GetKinematicSolverInfo)
            self.fk_info = self.fk_info_proxy()
            self.fk_pose_proxy = rospy.ServiceProxy('/pr2_right_arm_kinematics/get_fk', GetPositionFK, True)    
            self.ik_info_proxy = rospy.ServiceProxy('/pr2_right_arm_kinematics/get_ik_solver_info',
                                                    GetKinematicSolverInfo)
            self.ik_info = self.ik_info_proxy()
            self.ik_pose_proxy = rospy.ServiceProxy('/pr2_right_arm_kinematics/get_ik', GetPositionIK, True)    
            rospy.loginfo("Found FK/IK Solver services")
        except:
            rospy.logerr("Could not find FK/IK Solver services")
        
        self.set_planning_scene_diff_name = '/environment_server/set_planning_scene_diff'
        rospy.wait_for_service('/environment_server/set_planning_scene_diff')
        self.set_planning_scene_diff = rospy.ServiceProxy('/environment_server/set_planning_scene_diff', SetPlanningSceneDiff)
        self.set_planning_scene_diff(SetPlanningSceneDiffRequest())
    
    def update_joint_state(self, jtcs):
        #self.joint_state_lock.acquire()
        self.joint_state_time = jtcs.header.stamp
        self.joint_state_act = jtcs.actual
        self.joint_state_des = jtcs.desired
        #self.joint_state_lock.release()

    def update_torso_state(self, jtcs):
        self.torso_state_lock.acquire()
        self.torso_state = jtcs
        self.torso_state_lock.release()
        
    def curr_pose(self):
        #print 'Requesting Current Pose'
        (trans,rot) = self.tf.lookupTransform('/torso_lift_link', '/r_wrist_roll_link', rospy.Time(0))
        cp = PoseStamped()
        cp.header.stamp = rospy.Time.now()
        cp.header.frame_id = '/torso_lift_link'
        cp.pose.position = Point(*trans)
        cp.pose.orientation = Quaternion(*rot)
        #print 'Current Pose:', cp
        return cp
   
    def wait_for_stop(self, wait_time=1, timeout=60):
        rospy.sleep(wait_time)
        end_time = rospy.Time.now()+rospy.Duration(timeout)
        while not self.is_stopped():
            if rospy.Time.now()<end_time:
                rospy.sleep(wait_time)
            else:
                raise

    def is_stopped(self):
        #self.joint_state_lock.acquire()
        time = self.joint_state_time
        vels = self.joint_state_act.velocities
        #self.joint_state_lock.release()
        if np.allclose(vels, np.zeros(7)) and (rospy.Time.now()-time)<rospy.Duration(0.1):
            return True
        else:
            return False
    
    def get_fk(self, angles, frame='torso_lift_link', link=-1): # get FK pose of a list of joint angles for the arm
        fk_request = GetPositionFKRequest()
        fk_request.header.frame_id = frame
        fk_request.header.stamp = rospy.Time.now()
        fk_request.fk_link_names =  self.fk_info.kinematic_solver_info.link_names
        fk_request.robot_state.joint_state.header = fk_request.header
        fk_request.robot_state.joint_state.position = angles #self.joint_state_act.positions
        fk_request.robot_state.joint_state.name = self.fk_info.kinematic_solver_info.joint_names
        print 'fk_request:', fk_request
        try:
            return self.fk_pose_proxy(fk_request).pose_stamped[link]
        except rospy.ServiceException, e:
            rospy.loginfo("FK service did not process request: %s" %str(e))
コード例 #46
0
class SimpleGUI(Plugin):

    # For sending speech
    sound_sig = Signal(SoundRequest)

    # Joints for arm poses
    joint_sig = Signal(JointState)

    def __init__(self, context):
        self.prompt_width = 170
        self.input_width = 250

        super(SimpleGUI, self).__init__(context)
        self.setObjectName('SimpleGUI')
        self._widget = QWidget()

        self._sound_client = SoundClient()

        #find relative path for files to load
        self.local_dir = os.path.dirname(__file__)
        self.dir = os.path.join(self.local_dir, './lib/rqt_simplegui/')
        if not os.path.isdir(self.dir):
            os.makedirs(self.dir)

        #need to add any additional subfolders as needed
        if not os.path.isdir(self.dir + 'animations/'):
            os.makedirs(self.dir + 'animations/')

        # Creates a subscriber to the ROS topic, having msg type SoundRequest
        rospy.Subscriber('robotsound', SoundRequest, self.sound_cb)

        QtGui.QToolTip.setFont(QtGui.QFont('SansSerif', 10))
        self.sound_sig.connect(self.sound_sig_cb)

        # Code used for saving/ loading arm poses for the robot
        switch_srv_name = 'pr2_controller_manager/switch_controller'
        rospy.loginfo('Waiting for switch controller service...')
        rospy.wait_for_service(switch_srv_name)
        self.switch_service_client = rospy.ServiceProxy(
            switch_srv_name, SwitchController)

        self.r_joint_names = [
            'r_shoulder_pan_joint', 'r_shoulder_lift_joint',
            'r_upper_arm_roll_joint', 'r_elbow_flex_joint',
            'r_forearm_roll_joint', 'r_wrist_flex_joint', 'r_wrist_roll_joint'
        ]

        self.l_joint_names = [
            'l_shoulder_pan_joint', 'l_shoulder_lift_joint',
            'l_upper_arm_roll_joint', 'l_elbow_flex_joint',
            'l_forearm_roll_joint', 'l_wrist_flex_joint', 'l_wrist_roll_joint'
        ]

        self.all_joint_names = []
        self.all_joint_poses = []

        # Hash tables storing the name of the pose and the
        # associated positions for that pose, initially empty
        self.saved_l_poses = {}
        self.saved_r_poses = {}

        # Hash tables for storing name of animations and the associated pose list
        self.saved_animations = {}

        self.lock = threading.Lock()
        rospy.Subscriber('joint_states', JointState, self.joint_states_cb)

        #parsing for animations
        dir = os.path.dirname(__file__)
        qWarning(dir)
        filename = os.path.join(self.dir, 'animations/')

        ani_path = filename
        ani_listing = os.listdir(ani_path)
        for infile in ani_listing:
            pose_left = []
            pose_right = []
            left_gripper_states = []
            right_gripper_states = []
            line_num = 1
            for line in fileinput.input(ani_path + infile):
                if (line_num % 2 == 1):
                    pose = [float(x) for x in line.split()]
                    pose_left.append(pose[:len(pose) / 2])
                    pose_right.append(pose[len(pose) / 2:])
                else:
                    states = line.split()
                    left_gripper_states.append(states[0])
                    right_gripper_states.append(states[1])
                line_num += 1
            self.saved_animations[os.path.splitext(infile)[0]] = Quad(
                pose_left, pose_right, left_gripper_states,
                right_gripper_states)

        # Create a trajectory action client
        r_traj_controller_name = '/r_arm_controller/joint_trajectory_action'
        self.r_traj_action_client = SimpleActionClient(r_traj_controller_name,
                                                       JointTrajectoryAction)
        rospy.loginfo(
            'Waiting for a response from the trajectory action server for RIGHT arm...'
        )
        self.r_traj_action_client.wait_for_server()

        l_traj_controller_name = '/l_arm_controller/joint_trajectory_action'
        self.l_traj_action_client = SimpleActionClient(l_traj_controller_name,
                                                       JointTrajectoryAction)
        rospy.loginfo(
            'Waiting for a response from the trajectory action server for LEFT arm...'
        )
        self.l_traj_action_client.wait_for_server()

        # Navigation functionality initialization
        self.roomNav = RoomNavigator()

        self._tf_listener = TransformListener()
        self.animPlay = AnimationPlayer(None, None, None, None)

        # Detection and pickup functionality
        self.pap = PickAndPlaceManager(self._tf_listener, self.roomNav,
                                       self.animPlay)

        QtGui.QToolTip.setFont(QtGui.QFont('SansSerif', 10))
        self.joint_sig.connect(self.joint_sig_cb)

        # Create a large vertical box that is top aligned
        large_box = QtGui.QVBoxLayout()
        large_box.setAlignment(QtCore.Qt.AlignTop)
        large_box.setMargin(0)
        large_box.addItem(QtGui.QSpacerItem(10, 0))

        # Buttons for controlling the head of the robot
        head_box = QtGui.QHBoxLayout()
        head_box.addItem(QtGui.QSpacerItem(230, 0))
        head_box.addWidget(self.create_pressed_button('Head Up'))
        head_box.addStretch(1)
        large_box.addLayout(head_box)

        button_box = QtGui.QHBoxLayout()
        button_box.addItem(QtGui.QSpacerItem(80, 0))
        button_box.addWidget(self.create_pressed_button('Head Turn Left'))
        button_box.addWidget(self.create_pressed_button('Head Down'))
        button_box.addWidget(self.create_pressed_button('Head Turn Right'))
        button_box.addStretch(1)
        button_box.setMargin(0)
        button_box.setSpacing(0)
        large_box.addLayout(button_box)

        # Shows what the robot says
        speech_box = QtGui.QHBoxLayout()

        self.speech_label = QtGui.QLabel('Robot has not spoken yet')
        palette = QtGui.QPalette()
        palette.setColor(QtGui.QPalette.Foreground, QtCore.Qt.blue)
        self.speech_label.setPalette(palette)  #
        speech_box.addItem(QtGui.QSpacerItem(100, 0))
        #speech_box.addWidget(self.speech_label) #

        large_box.addLayout(speech_box)

        # Speak button
        speak_button_box = QtGui.QHBoxLayout()
        speech_prompt = QtGui.QLabel('Enter Speech Text:')
        speech_prompt.setFixedWidth(self.prompt_width)
        speak_button_box.addWidget(speech_prompt)
        robot_says = QtGui.QLineEdit(self._widget)
        robot_says.setFixedWidth(self.input_width)
        robot_says.textChanged[str].connect(self.onChanged)  #
        speak_button_box.addWidget(robot_says)
        speak_button_box.addWidget(self.create_button('Speak'))
        speak_button_box.addStretch(1)
        large_box.addLayout(speak_button_box)

        large_box.addItem(QtGui.QSpacerItem(0, 50))

        # Buttons for arm poses
        pose_button_box1 = QtGui.QHBoxLayout()
        pose_button_box1.addItem(QtGui.QSpacerItem(150, 0))
        pose_button_box1.addWidget(self.create_button('Relax Left Arm'))
        pose_button_box1.addWidget(self.create_button('Relax Right Arm'))
        pose_button_box1.addStretch(1)
        large_box.addLayout(pose_button_box1)

        # Buttons for grippers
        gripper_button_box = QtGui.QHBoxLayout()
        gripper_button_box.addItem(QtGui.QSpacerItem(150, 0))
        gripper_button_box.addWidget(self.create_button('Open Left Gripper'))
        gripper_button_box.addWidget(self.create_button('Open Right Gripper'))
        gripper_button_box.addStretch(1)
        large_box.addLayout(gripper_button_box)

        large_box.addItem(QtGui.QSpacerItem(0, 25))

        # Buttons for animation
        animation_box = QtGui.QHBoxLayout()
        play_anim_label = QtGui.QLabel('Select Animation:')
        play_anim_label.setFixedWidth(self.prompt_width)
        animation_box.addWidget(play_anim_label)
        self.saved_animations_list = QtGui.QComboBox(self._widget)
        animation_box.addWidget(self.saved_animations_list)

        pose_time_label = QtGui.QLabel('Duration(sec):')
        pose_time_label.setFixedWidth(100)
        animation_box.addWidget(pose_time_label)
        self.pose_time = QtGui.QLineEdit(self._widget)
        self.pose_time.setFixedWidth(50)
        self.pose_time.setText('2.0')
        animation_box.addWidget(self.pose_time)

        animation_box.addWidget(self.create_button('Play Animation'))
        animation_box.addStretch(1)
        large_box.addLayout(animation_box)

        animation_box2 = QtGui.QHBoxLayout()
        animation_name_label = QtGui.QLabel('Enter Animation Name:')
        animation_name_label.setFixedWidth(self.prompt_width)
        animation_box2.addWidget(animation_name_label)
        self.animation_name = QtGui.QLineEdit(self._widget)
        self.animation_name.setFixedWidth(self.input_width)
        animation_box2.addWidget(self.animation_name)
        animation_box2.addWidget(self.create_button('Save Animation'))
        animation_box2.addStretch(1)
        large_box.addLayout(animation_box2)

        animation_box3 = QtGui.QHBoxLayout()
        pose_name_label = QtGui.QLabel('Enter Pose Name:')
        pose_name_label.setFixedWidth(self.prompt_width)
        animation_box3.addWidget(pose_name_label)
        self.pose_name_temp = QtGui.QLineEdit(self._widget)
        self.pose_name_temp.setFixedWidth(self.input_width)
        animation_box3.addWidget(self.pose_name_temp)
        animation_box3.addWidget(self.create_button('Add Current Pose'))
        animation_box3.addStretch(1)
        large_box.addLayout(animation_box3)

        # Playing around with UI stuff
        play_box = QtGui.QHBoxLayout()
        pose_sequence_label = QtGui.QLabel('Current Pose Sequence:')
        pose_sequence_label.setFixedWidth(self.prompt_width)
        pose_sequence_label.setAlignment(QtCore.Qt.AlignTop)

        self.list_widget = QListWidget()
        self.list_widget.setDragDropMode(QAbstractItemView.InternalMove)
        self.list_widget.setMaximumSize(self.input_width, 200)
        play_box.addWidget(pose_sequence_label)
        play_box.addWidget(self.list_widget)

        play_box.addStretch(1)
        large_box.addLayout(play_box)

        large_box.addItem(QtGui.QSpacerItem(0, 50))

        # Buttons for first row of base controls
        first_base_button_box = QtGui.QHBoxLayout()
        first_base_button_box.addItem(QtGui.QSpacerItem(70, 0))
        first_base_button_box.addWidget(
            self.create_pressed_button('Rotate Left'))
        first_base_button_box.addWidget(self.create_pressed_button('^'))
        first_base_button_box.addWidget(
            self.create_pressed_button('Rotate Right'))
        first_base_button_box.addStretch(1)
        large_box.addLayout(first_base_button_box)

        # Buttons for second row of base controls
        second_base_button_box = QtGui.QHBoxLayout()
        second_base_button_box.addItem(QtGui.QSpacerItem(70, 0))
        second_base_button_box.addWidget(self.create_pressed_button('<'))
        second_base_button_box.addWidget(self.create_pressed_button('v'))
        second_base_button_box.addWidget(self.create_pressed_button('>'))
        second_base_button_box.addWidget(self.create_button('Move to Bin'))
        second_base_button_box.addWidget(self.create_button('Object Detect'))
        second_base_button_box.addWidget(self.create_button('Clean Room'))
        second_base_button_box.addStretch(1)
        large_box.addLayout(second_base_button_box)

        # Animation related items to store intermediate pose co-ordinates to save
        self.animation_map = {}

        self.create_state = False

        self._widget.setObjectName('SimpleGUI')
        self._widget.setLayout(large_box)
        context.add_widget(self._widget)

        # Look straight and down when launched
        self.head_x = 1.0
        self.head_y = 0.0
        self.head_z = 0.5
        self.head_action(self.head_x, self.head_y, self.head_z)

        # Set grippers to closed on initialization
        self.left_gripper_state = ''
        self.right_gripper_state = ''
        self.gripper_action('l', 0.0)
        self.gripper_action('r', 0.0)

        # Lab 6
        self.marker_publisher = rospy.Publisher('visualization_marker', Marker)

        # Saved states for poses
        saved_pose_box = QtGui.QHBoxLayout()
        self.saved_left_poses = QtGui.QLabel('')
        self.saved_right_poses = QtGui.QLabel('')

        saved_pose_box.addWidget(self.saved_left_poses)
        saved_pose_box.addWidget(self.saved_right_poses)
        large_box.addLayout(saved_pose_box)

        # Preload the map of animations
        self.saved_animations_list.addItems(self.saved_animations.keys())

        # Move the torso all the way down
        # self.torso_down(True)

        # Autonomous navigation stuff
        '''
        self.locations = [Pose(Point(2.48293590546, 3.90075874329, 0.000), Quaternion(0.000, 0.000, -0.783917630973, 0.620864838632)),
                         Pose(Point(3.70106744766, 0.304672241211, 0.000), Quaternion(0.000, 0.000, 0.950186880196, -0.311680754463)),
                         Pose(Point(2.57326722145, 1.51304531097, 0.000), Quaternion(0.000, 0.000, 0.96127194482, -0.275601611212)),
                         Pose(Point(1.28060531616, 1.52380752563, 0.000), Quaternion(0.000, 0.000, 0.946345258806, -0.323157316388)),
                         Pose(Point(2.11048603058, 0.420155525208, 0.000), Quaternion(0.000, 0.000, 0.945222393391, -0.326427062346)),
                         Pose(Point(2.82733058929, -0.739856719971, 0.000), Quaternion(0.000, 0.000, 0.945473998362, -0.325697587373)),
                         Pose(Point(1.29184818268, -1.90485572815, 0.000), Quaternion(0.000, 0.000, 0.942275557345, -0.334838429739)),
                         Pose(Point(0.722846984863, -1.0921459198, 0.000), Quaternion(0.000, 0.000, 0.949330143731, -0.314280572424))]
        '''
        self.locations = [
            Pose(Point(2.04748392105, 2.04748010635, 0.000),
                 Quaternion(0.000, 0.000, -0.776968030817, 0.629540053601)),
            Pose(Point(2.34193611145, 1.43208932877, 0),
                 Quaternion(0, 0, -0.841674385779, 0.539985396398)),
            Pose(Point(3.43202018738, -0.258297920227, 0.000),
                 Quaternion(0.000, 0.000, 0.996656413122, -0.0817067572629)),
            Pose(Point(0.931655406952, -1.96435832977, 0.000),
                 Quaternion(0.000, 0.000, 0.691187586713, 0.722675390458)),
            Pose(Point(-0.369112968445, 0.0330476760864, 0.000),
                 Quaternion(0.000, 0.000, 0.0275340398899, 0.999620866453))
        ]

        self.index = 1

        rospy.loginfo("Completed GUI initialization")

    # Event for when text box is changed
    def onChanged(self, text):
        self.speech_label.setText(text)
        self.speech_label.adjustSize()

    def sound_cb(self, sound_request):
        qWarning('Received sound.')
        self.sound_sig.emit(sound_request)

    def create_button(self, name):
        btn = QtGui.QPushButton(name, self._widget)
        btn.setFixedWidth(150)
        btn.clicked.connect(self.command_cb)
        return btn

    def create_pressed_button(self, name):
        btn = QtGui.QPushButton(name, self._widget)
        btn.setFixedWidth(150)
        btn.pressed.connect(self.command_cb)
        btn.setAutoRepeat(True)  # To make sure the movement repeats itself
        return btn

    def sound_sig_cb(self, sound_request):
        qWarning('Received sound signal.')
        qWarning('Robot said: ' + sound_request.arg)
        self.speech_label.setText(sound_request.arg)  #'Robot said: ' +

#a button was clicked

    def command_cb(self):
        button_name = self._widget.sender().text()

        #robot talk button clicked
        if (button_name == 'Speak'):
            qWarning('Robot will say: ' + self.speech_label.text())
            self._sound_client.say(self.speech_label.text())
            self.show_text_in_rviz("Robot is Speaking")

        #gripper button selected
        elif ('Gripper' in button_name):
            self.gripper_click(button_name)

        # Move forward
        elif (button_name == '^'):
            self.base_action(0.25, 0.0, 0.0, 0.0, 0.0, 0.0)

        # Move left
        elif (button_name == '<'):
            self.base_action(0.0, 0.25, 0.0, 0.0, 0.0, 0.0)

        # Move right
        elif (button_name == '>'):
            self.base_action(0.0, -0.25, 0.0, 0.0, 0.0, 0.0)

        # Move back
        elif (button_name == 'v'):
            self.base_action(-0.25, 0.0, 0.0, 0.0, 0.0, 0.0)

        #Rotate Left
        elif (button_name == 'Rotate Left'):
            self.base_action(0.0, 0.0, 0.0, 0.0, 0.0, 0.50)

        # Rotate Right
        elif (button_name == 'Rotate Right'):
            self.base_action(0.0, 0.0, 0.0, 0.0, 0.0, -0.50)

        # A head button selected
        elif ('Head' in button_name):
            self.rotate_head(button_name)

        #An arm button selected
        #third param unused in freeze/relax
        #Second word in button should be side
        elif ('Arm' in button_name):

            arm_side = button_name.split()[1]

            if ('Freeze' in button_name or 'Relax' in button_name):
                new_arm_state = button_name.split()[0]
                self.toggle_arm(arm_side[0].lower(), new_arm_state, True)

                old_arm_state = ''
                if (new_arm_state == 'Relax'):
                    old_arm_state = 'Freeze'
                else:
                    old_arm_state = 'Relax'

                self._widget.sender().setText('%s %s Arm' %
                                              (old_arm_state, arm_side))

        elif ('Play Animation' == button_name):
            self.animPlay.left_poses = self.saved_animations[
                self.saved_animations_list.currentText()].left
            self.animPlay.right_poses = self.saved_animations[
                self.saved_animations_list.currentText()].right
            self.animPlay.left_gripper_states = self.saved_animations[
                self.saved_animations_list.currentText()].left_gripper
            self.animPlay.right_gripper_states = self.saved_animations[
                self.saved_animations_list.currentText()].right_gripper
            if self.pose_time.text() == '':
                self.show_warning('Please enter a duration in seconds.')
            else:
                self.animPlay.play(self.pose_time.text())

        elif ('Animation' in button_name):
            if ('Save' in button_name):
                if self.animation_name.text() == '':
                    self.show_warning('Please enter name for animation')
                else:
                    self.save_animation(self.animation_name.text())
                    self.list_widget.clear()
                    self.animation_name.setText('')

        elif ('Add Current Pose' == button_name):
            if self.pose_name_temp.text() == '':
                self.show_warning('Insert name for pose')
            else:
                self.animation_map[self.pose_name_temp.text()] = Quad(
                    self.get_joint_state('l'), self.get_joint_state('r'),
                    self.left_gripper_state, self.right_gripper_state)
                list_item = QListWidgetItem()
                list_item.setText(self.pose_name_temp.text())
                self.list_widget.addItem(list_item)
                self.pose_name_temp.setText('')

        elif ('Move to Bin' == button_name):
            self.move_to_bin_action()
        elif ('Clean Room' == button_name):
            rospy.loginfo("STARTING AUTONOMOUS MODE")
            self.tuck_arms()

            while (self.index < len(self.locations)):
                self.roomNav.move_to_trash_location(self.locations[self.index])
                # self.index += 1

                self.head_action(1.0, 0, -0.50, True)
                # Returns Nonce if nothing, and the point of the first object it sees otherwise
                map_point = self.pap.detect_objects()

                if (map_point == None):
                    self.index += 1
                else:
                    self.pick_and_move_trash_action()

            rospy.loginfo("FINISHED AUTONOMOUS MODE")
            self.index = 1

        elif ('Object Detect' == button_name):
            self.pick_and_move_trash_action()

    def pick_and_move_trash_action(self, map_point=None):
        if map_point == None:
            self.head_action(1.0, 0, -0.50, True)
            map_point = self.pap.detect_objects()

        if map_point == None:
            return

        # Convert to base link and move towards the object 0.50m away
        map_point = Transformer.transform(self._tf_listener, map_point.pose,
                                          map_point.header.frame_id,
                                          '/base_link')

        rospy.loginfo("Object is " + str(map_point.pose.position.x) + " away")
        '''
        if(map_point.pose.position.x < 0.8):
            self.roomNav.move_to_trash_location(self.locations[self.index - 1])
        '''
        move_back_first = False
        if (map_point.pose.position.x < 0.7):
            move_back_first = True

        map_point.pose.position.x -= 0.450
        map_point = Transformer.transform(self._tf_listener, map_point.pose,
                                          '/base_link', '/map')

        if (move_back_first):
            self.roomNav.move_to_trash_location(self.locations[self.index - 1])

        success = self.roomNav.move_to_trash_location(map_point.pose)
        '''This part of the code strafes the robot left to get closer to the object'''
        '''
        rate = rospy.Rate(10)
        position = Point()
        move_cmd = Twist()
        move_cmd.linear.y = 0.25
        odom_frame = '/odom_combined'
        
        # Find out if the robot uses /base_link or /base_footprint
        try:
            self._tf_listener.waitForTransform(odom_frame, '/base_footprint', rospy.Time(), rospy.Duration(1.0))
            self.base_frame = '/base_footprint'
        except (tf.Exception, tf.ConnectivityException, tf.LookupException):
           try:
               self._tf_listener.waitForTransform(odom_frame, '/base_link', rospy.Time(), rospy.Duration(1.0))
               self.base_frame = '/base_link'
           except (tf.Exception, tf.ConnectivityException, tf.LookupException):
               rospy.loginfo("Cannot find transform between " + odom_frame + " and /base_link or /base_footprint")
               rospy.signal_shutdown("tf Exception")
        
            # Get current position
            position = self.get_odom()
            
            x_start = position.x
            y_start = position.y
            
            # Distance travelled
            distance = 0
            goal_distance = 0.25
            rospy.loginfo("Strafing left")
            # Enter the loop to move along a side
            while distance < goal_distance:
                rospy.loginfo("Distance is at " + str(distance))
                # Publish the Twist message and sleep 1 cycle
                self.base_action(0, 0.25, 0, 0, 0, 0)
                rate.sleep()
                
                # Get the current position
                position = self.get_odom()
                
                # Compute the Euclidean distance from the start
                distance = abs(position.y - y_start) 
        '''

        if (success):
            # Move head to look at the object, this will wait for a result
            self.head_action(0, 0.4, 0.55, True)

            # Move arms to ready pickup position, this will wait for a result before trying to detect and pick up object
            self.animPlay.left_poses = self.saved_animations[
                'ready_pickup'].left
            self.animPlay.right_poses = self.saved_animations[
                'ready_pickup'].right
            self.animPlay.left_gripper_states = self.saved_animations[
                'ready_pickup'].left_gripper
            self.animPlay.right_gripper_states = self.saved_animations[
                'ready_pickup'].right_gripper
            self.animPlay.play('3.0')

            for i in range(0, 3):
                success = self.pap.detect_and_pickup()
                # Move head back to look forward
                # Move head to look at the object, this will wait for a result
                self.head_action(1.0, 0.0, 0.55, True)
                if success:
                    break

            # Move to bin
            self.move_to_bin_action()

    def get_odom(self):
        # Get the current transform between the odom and base frames
        try:
            trans = self._tf_listener.lookupTransform('/odom_combined',
                                                      self.base_frame,
                                                      rospy.Time(0))
        except (tf.Exception, tf.ConnectivityException, tf.LookupException):
            rospy.loginfo("TF Exception")
            return

        return Point(trans[0][0], trans[0][1], trans[0][2])

    # gripper_type is either 'l' for left or 'r' for right
    # gripper position is the position as a parameter to the gripper goal
    def gripper_action(self, gripper_type, gripper_position):
        name_space = '/' + gripper_type + '_gripper_controller/gripper_action'

        gripper_client = SimpleActionClient(name_space, GripperCommandAction)
        gripper_client.wait_for_server()
        gripper_goal = GripperCommandGoal()
        gripper_goal.command.position = gripper_position
        gripper_goal.command.max_effort = 30.0
        gripper_client.send_goal(gripper_goal)
        # update the state of the current gripper being modified
        if (gripper_type == 'l'):
            if (gripper_position == 0.0):
                self.left_gripper_state = 'closed'
            else:
                self.left_gripper_state = 'open'
        else:
            if (gripper_position == 0.0):
                self.right_gripper_state = 'closed'
            else:
                self.right_gripper_state = 'open'

    def base_action(self, x, y, z, theta_x, theta_y, theta_z):
        topic_name = '/base_controller/command'
        base_publisher = rospy.Publisher(topic_name, Twist)

        twist_msg = Twist()
        twist_msg.linear = Vector3(x, y, z)
        twist_msg.angular = Vector3(theta_x, theta_y, theta_z)

        base_publisher.publish(twist_msg)

    # Moves the torso of the robot down to its maximum
    def torso_down(self, wait=False):
        self.torso_client = SimpleActionClient(
            '/torso_controller/position_joint_action',
            SingleJointPositionAction)
        torso_goal = SingleJointPositionGoal()
        torso_goal.position = 0.0
        torso_goal.min_duration = rospy.Duration(5.0)
        torso_goal.max_velocity = 1.0
        self.torso_client.send_goal(torso_goal)
        if wait:
            # wait for the head movement to finish before we try to detect and pickup an object
            finished_within_time = self.torso_client.wait_for_result(
                rospy.Duration(15))
            # Check for success or failure
            if not finished_within_time:
                self.torso_client.cancel_goal()
                rospy.loginfo("Timed out achieving torso movement goal")
            else:
                state = self.torso_client.get_state()
                if state == GoalStatus.SUCCEEDED:
                    rospy.loginfo("Torso movement goal succeeded!")
                    rospy.loginfo("State:" + str(state))
                else:
                    rospy.loginfo(
                        "Torso movement goal failed with error code: " +
                        str(state))

    def head_action(self, x, y, z, wait=False):
        name_space = '/head_traj_controller/point_head_action'
        head_client = SimpleActionClient(name_space, PointHeadAction)
        head_goal = PointHeadGoal()
        head_goal.target.header.frame_id = 'base_link'
        head_goal.min_duration = rospy.Duration(1.0)
        head_goal.target.point = Point(x, y, z)
        head_client.send_goal(head_goal)
        if wait:
            # wait for the head movement to finish before we try to detect and pickup an object
            finished_within_time = head_client.wait_for_result(
                rospy.Duration(5))
            # Check for success or failure
            if not finished_within_time:
                head_client.cancel_goal()
                rospy.loginfo("Timed out achieving head movement goal")
            else:
                state = head_client.get_state()
                if state == GoalStatus.SUCCEEDED:
                    rospy.loginfo("Head movement goal succeeded!")
                    rospy.loginfo("State:" + str(state))
                else:
                    rospy.loginfo(
                        "Head movement goal failed with error code: " +
                        str(self.goal_states[state]))

    def tuck_arms(self):
        rospy.loginfo('Left tuck arms')
        self.animPlay.left_poses = self.saved_animations['left_tuck'].left
        self.animPlay.right_poses = self.saved_animations['left_tuck'].right
        self.animPlay.left_gripper_states = self.saved_animations[
            'left_tuck'].left_gripper
        self.animPlay.right_gripper_states = self.saved_animations[
            'left_tuck'].right_gripper
        self.animPlay.play('3.0')

    def move_to_bin_action(self):
        # First tuck arms
        self.tuck_arms()

        # Move to the bin
        rospy.loginfo('Clicked the move to bin button')
        self.roomNav.move_to_bin()
        # Throw the trash away
        rospy.loginfo('Throwing trash away with left arm')
        self.animPlay.left_poses = self.saved_animations['l_dispose'].left
        self.animPlay.right_poses = self.saved_animations['l_dispose'].right
        self.animPlay.left_gripper_states = self.saved_animations[
            'l_dispose'].left_gripper
        self.animPlay.right_gripper_states = self.saved_animations[
            'l_dispose'].right_gripper
        self.animPlay.play('2.0')
        # Tuck arms again
        self.tuck_arms()

    def shutdown_plugin(self):
        # TODO unregister all publishers here
        pass

    def save_settings(self, plugin_settings, instance_settings):
        # TODO save intrinsic configuration, usually using:
        # instance_settings.set_value(k, v)
        pass

    def restore_settings(self, plugin_settings, instance_settings):
        # TODO restore intrinsic configuration, usually using:
        # v = instance_settings.value(k)
        pass

    def show_text_in_rviz(self, text):
        marker = Marker(type=Marker.TEXT_VIEW_FACING,
                        id=0,
                        lifetime=rospy.Duration(1.5),
                        pose=Pose(Point(0.5, 0.5, 1.45),
                                  Quaternion(0, 0, 0, 1)),
                        scale=Vector3(0.06, 0.06, 0.06),
                        header=Header(frame_id='base_link'),
                        color=ColorRGBA(0.0, 1.0, 0.0, 0.8),
                        text=text)
        self.marker_publisher.publish(marker)

    def show_arrow_in_rviz(self, arrow):
        marker = Marker(type=Marker.ARROW,
                        id=0,
                        lifetime=rospy.Duration(1.5),
                        pose=Pose(Point(0.5, 0.5, 1.45),
                                  Quaternion(0, 0, 0, 1)),
                        scale=Vector3(0.06, 0.06, 0.06),
                        header=Header(frame_id='base_link'),
                        color=ColorRGBA(0.0, 1.0, 0.0, 0.8),
                        arrow=arrow)
        self.marker_publisher.publish(marker)

    def save_animation(self, animation_name):
        if animation_name != '':
            filename = os.path.join(self.dir, 'animations/')
            anim_file = open(filename + animation_name + '.txt', 'w')
            l_animation_queue = []
            r_animation_queue = []
            l_gripper_queue = []
            r_gripper_queue = []
            for i in range(self.list_widget.count()):
                item = self.list_widget.item(i)
                pose_name = item.text()
                anim_file.write(
                    re.sub(
                        ',', '',
                        str(self.animation_map[pose_name].left).strip('[]') +
                        ' ' +
                        str(self.animation_map[pose_name].right).strip('[]')))
                anim_file.write('\n')
                anim_file.write(
                    str(self.animation_map[pose_name].left_gripper) + ' ' +
                    str(self.animation_map[pose_name].right_gripper))
                l_animation_queue.append(self.animation_map[pose_name].left)
                r_animation_queue.append(self.animation_map[pose_name].right)
                l_gripper_queue.append(
                    self.animation_map[pose_name].left_gripper)
                r_gripper_queue.append(
                    self.animation_map[pose_name].right_gripper)
                anim_file.write('\n')
            anim_file.close()

            self.saved_animations[animation_name] = Quad(
                l_animation_queue, r_animation_queue, l_gripper_queue,
                r_gripper_queue)
            self.saved_animations_list.addItem(
                animation_name)  # Bug? Multiple entries

            # Reset the pending queue
            self.l_animation_queue = []
            self.r_animation_queue = []
        else:
            self.show_warning('Please insert name for animation')

    def gripper_click(self, button_name):
        grip_side = ''
        grip_side_text = ''

        if ('Left' in button_name):
            grip_side = 'l'
            grip_side_text = 'left'
        else:
            grip_side = 'r'
            grip_side_text = 'right'

        if ('Open' in button_name):
            grip_action = 20.0
            grip_action_text = 'close'
            qWarning('Robot opened %s gripper' % (grip_side_text))
        else:
            grip_action = 0.0
            grip_action_text = 'open'
            qWarning('Robot closed %s gripper' % (grip_side_text))

        self.show_text_in_rviz(
            "%sing %s Gripper" %
            (grip_action_text.capitalize(), grip_side_text.capitalize()))
        self.gripper_action(grip_side, grip_action)

        self._widget.sender().setText(
            '%s %s Gripper' %
            (grip_action_text.capitalize(), grip_side_text.capitalize()))

    def rotate_head(self, button_name):
        if ('Left' in button_name):
            #qWarning('x: %s, y: %s' % (self.head_x, self.head_y))

            if (self.head_x < -0.8 and self.head_y > 0.0):
                self.show_warning('Can\'t rotate anymore')

            elif (self.head_y < 0.0):
                self.head_x += 0.1
                self.head_y = -((1.0 - self.head_x**2.0)**0.5)
                self.show_text_in_rviz("Turning Head Left")

            else:
                self.head_x -= 0.1
                self.head_y = (1.0 - self.head_x**2.0)**0.5
                self.show_text_in_rviz("Turning Head Left")

            qWarning('x: %s, y: %s' % (self.head_x, self.head_y))
            self.head_action(self.head_x, self.head_y, self.head_z)

        elif ('Up' in button_name):
            if (self.head_z <= 1.6):
                self.head_z += 0.1
                self.show_text_in_rviz("Moving Head Up")
                self.head_action(self.head_x, self.head_y, self.head_z)
            else:
                self.show_warning('Can\'t look up anymore')

        elif ('Down' in button_name):
            if (self.head_z >= -2.2):
                self.head_z -= 0.1
                self.show_text_in_rviz("Moving Head Down")
                self.head_action(self.head_x, self.head_y, self.head_z)
            else:
                self.show_warning('Can\'t look down anymore')

        else:
            #qWarning('x: %s, y: %s' % (self.head_x, self.head_y))
            if (self.head_x < -0.8 and self.head_y < 0.0):
                self.show_warning('Can\'t rotate anymore')

            elif (self.head_y > 0.0):
                self.head_x += 0.1
                self.head_y = (1.0 - self.head_x**2.0)**0.5
                self.show_text_in_rviz("Turning Head Right")

            else:
                self.head_x -= 0.1
                self.head_y = -((1.0 - self.head_x**2.0)**0.5)
                self.show_text_in_rviz("Turning Head Right")

            #qWarning('x: %s, y: %s' % (self.head_x, self.head_y))
            self.head_action(self.head_x, self.head_y, self.head_z)

    def toggle_arm(self, side, toggle, button):
        controller_name = side + '_arm_controller'

        start_controllers = []
        stop_controllers = []
        if (toggle == 'Relax'):
            stop_controllers.append(controller_name)
        else:
            start_controllers.append(controller_name)
        self.set_arm_mode(start_controllers, stop_controllers)

    def set_arm_mode(self, start_controllers, stop_controllers):
        try:
            self.switch_service_client(start_controllers, stop_controllers, 1)
        except rospy.ServiceException:
            rospy.logerr('Could not change arm mode.')

    def joint_states_cb(self, msg):
        '''Callback function that saves the joint positions when a
            joint_states message is received'''
        self.lock.acquire()
        self.all_joint_names = msg.name
        self.all_joint_poses = msg.position
        self.joint_sig.emit(msg)
        self.lock.release()

    def joint_sig_cb(self, msg):
        pass

    def get_joint_state(self, side_prefix):
        '''Returns position for arm joints on the requested side (r/l)'''
        if side_prefix == 'r':
            joint_names = self.r_joint_names
        else:
            joint_names = self.l_joint_names

        if self.all_joint_names == []:
            rospy.logerr("No robot_state messages received yet!\n")
            return None

        positions = []
        self.lock.acquire()
        for joint_name in joint_names:
            if joint_name in self.all_joint_names:
                index = self.all_joint_names.index(joint_name)
                position = self.all_joint_poses[index]
                positions.append(position)
            else:
                rospy.logerr("Joint %s not found!", joint_name)
                self.lock.release()
                return None

        self.lock.release()
        return positions

    def show_warning(self, text):
        qWarning(text)
        msgBox = QMessageBox()
        msgBox.setText(text)
        msgBox.exec_()
コード例 #47
0
class MarkerProcessor(object):
    def __init__(self, use_dummy_transform=False):
        rospy.init_node("star_center_positioning_node")

        self.robot_name = rospy.get_param("~robot_name", "")
        self.odom_frame_name = self.robot_name + "_odom"
        # print self.odom_frame_name
        self.marker_locators = {}
        self.add_marker_locator(MarkerLocator(0, (-6 * 12 * 2.54 / 100.0, 0), 0))
        self.add_marker_locator(MarkerLocator(1, (0.0, 0.0), pi))
        self.add_marker_locator(MarkerLocator(2, (0.0, 10 * 12 * 2.54 / 100.0), 0))
        self.add_marker_locator(MarkerLocator(3, (-6 * 12 * 2.54 / 100.0, 6 * 12 * 2.54 / 100.0), 0))

        self.pose_correction = rospy.get_param("~pose_correction", 0.0)

        self.marker_sub = rospy.Subscriber("ar_pose_marker", ARMarkers, self.process_markers)
        self.odom_sub = rospy.Subscriber("odom", Odometry, self.process_odom, queue_size=10)
        self.star_pose_pub = rospy.Publisher("STAR_pose", PoseStamped, queue_size=10)
        self.continuous_pose = rospy.Publisher("STAR_pose_continuous", PoseStamped, queue_size=10)
        self.tf_listener = TransformListener()
        self.tf_broadcaster = TransformBroadcaster()

    def add_marker_locator(self, marker_locator):
        self.marker_locators[marker_locator.id] = marker_locator

    def process_odom(self, msg):
        p = PoseStamped(header=Header(stamp=rospy.Time(0), frame_id=self.odom_frame_name), pose=msg.pose.pose)
        try:
            STAR_pose = self.tf_listener.transformPose("STAR", p)
            STAR_pose.header.stamp = msg.header.stamp
            self.continuous_pose.publish(STAR_pose)
        except Exception as inst:
            print "error is", inst

    def process_markers(self, msg):
        for marker in msg.markers:
            # do some filtering basd on prior knowledge
            # we know the approximate z coordinate and that all angles but yaw should be close to zero
            euler_angles = euler_from_quaternion(
                (
                    marker.pose.pose.orientation.x,
                    marker.pose.pose.orientation.y,
                    marker.pose.pose.orientation.z,
                    marker.pose.pose.orientation.w,
                )
            )
            angle_diffs = (
                TransformHelpers.angle_diff(euler_angles[0], pi),
                TransformHelpers.angle_diff(euler_angles[1], 0),
            )
            print angle_diffs, marker.pose.pose.position.z
            if (
                marker.id in self.marker_locators
                and 3.0 <= marker.pose.pose.position.z <= 3.6
                and fabs(angle_diffs[0]) <= 0.4
                and fabs(angle_diffs[1]) <= 0.4
            ):
                print "FOUND IT!"
                locator = self.marker_locators[marker.id]
                xy_yaw = list(locator.get_camera_position(marker))
                print "xy_yaw", xy_yaw
                xy_yaw[0] += self.pose_correction * cos(xy_yaw[2])
                xy_yaw[1] += self.pose_correction * sin(xy_yaw[2])
                print xy_yaw
                orientation_tuple = quaternion_from_euler(0, 0, xy_yaw[2])
                pose = Pose(
                    position=Point(x=-xy_yaw[0], y=-xy_yaw[1], z=0),
                    orientation=Quaternion(
                        x=orientation_tuple[0], y=orientation_tuple[1], z=orientation_tuple[2], w=orientation_tuple[3]
                    ),
                )
                # TODO: use markers timestamp instead of now() (unfortunately, not populated currently by ar_pose)
                pose_stamped = PoseStamped(header=Header(stamp=rospy.Time.now(), frame_id="STAR"), pose=pose)
                try:
                    offset, quaternion = self.tf_listener.lookupTransform(
                        self.robot_name + "_base_link", self.robot_name + "_base_laser_link", rospy.Time(0)
                    )
                except Exception as inst:
                    print "Error", inst
                    return
                # TODO: use frame timestamp instead of now()
                pose_stamped_corrected = deepcopy(pose_stamped)
                pose_stamped_corrected.pose.position.x -= offset[0] * cos(xy_yaw[2])
                pose_stamped_corrected.pose.position.y -= offset[0] * sin(xy_yaw[2])
                self.star_pose_pub.publish(pose_stamped_corrected)
                self.fix_STAR_to_odom_transform(pose_stamped_corrected)

    def fix_STAR_to_odom_transform(self, msg):
        """ Super tricky code to properly update map to odom transform... do not modify this... Difficulty level infinity. """
        (translation, rotation) = TransformHelpers.convert_pose_inverse_transform(msg.pose)
        p = PoseStamped(
            pose=TransformHelpers.convert_translation_rotation_to_pose(translation, rotation),
            header=Header(stamp=rospy.Time(), frame_id=self.robot_name + "_base_link"),
        )
        try:
            self.tf_listener.waitForTransform(
                self.robot_name + "_odom", self.robot_name + "_base_link", rospy.Time(), rospy.Duration(1.0)
            )
        except Exception as inst:
            print "whoops", inst
            return
        print "got transform"
        self.odom_to_STAR = self.tf_listener.transformPose(self.robot_name + "_odom", p)
        (self.translation, self.rotation) = TransformHelpers.convert_pose_inverse_transform(self.odom_to_STAR.pose)

    def broadcast_last_transform(self):
        """ Make sure that we are always broadcasting the last map to odom transformation.
            This is necessary so things like move_base can work properly. """
        if not (hasattr(self, "translation") and hasattr(self, "rotation")):
            return
        self.tf_broadcaster.sendTransform(
            self.translation, self.rotation, rospy.get_rostime(), self.odom_frame_name, "STAR"
        )

    def run(self):
        r = rospy.Rate(10)
        while not rospy.is_shutdown():
            self.broadcast_last_transform()
            r.sleep()
コード例 #48
0
        tTC = proxy.getTransform(chainName, space, False)
        print "Transform %s to %s:"%(space_to_str(space),chainName)
        print transform_to_str(tTCSensor)
        print
        T = np.matrix([tTCSensor[0:4],tTCSensor[4:8],tTCSensor[8:12],tTCSensor[12:]])
        #print cam_rotation_matrix()
        DCM = T*cam_rotation_matrix()
        print "Transform %s to %s (with rotated coordinate frame):"%(space_to_str(space),chainName)
        print np_mat_to_str(DCM)

        stamp = rospy.Time()
        frame1 = 'Torso_link'
        frame2 = 'CameraTop_frame'
        try:
            listener.waitForTransform(frame1,frame2,stamp,rospy.Duration(1.0))
            (trans,rot) = listener.lookupTransform(frame1,frame2,stamp)
        except tf.Exception as e:
            print "ERROR using TF"
            print "%s"%(e)
            sys.exit(-1)

        m = transformations.quaternion_matrix(rot)
        for i in range(0,3):
            m[i,3] = trans[i]
        print "[tf] Transform %s to %s:"%(frame1,frame2)
        print np_mat_to_str(m)

        e = np.linalg.norm(DCM - m)
        print "Error is: ",e
        if e > 1e-5:
            print "ERROR: Something is wrong with your TF transformations.  Transforms do not match!"
コード例 #49
0
class NavigateInRowSimple():
    """
    Executor to navigate in a row given an fmMsgs/row message

    
    This executor navigates in a row given a fmMsgs/row message
    the row is navigated based on the desired offset from the row.
    This executor publishes a cmd_vel directly. 

    If the row message received is too old the executor aborts.
    
    If a transform between the robot and odometry frame exists 
    then the distance driven in the row is returned as a result.
    
    """
    __feedback_msg = navigate_in_row_simpleFeedback()
    __goal_msg = navigate_in_row_simpleResult()
    
    def __init__(self,name,rowtopic,odom_frame,vehicle_frame):
        """
            Initialise the action server 
            @param name: the name of the action server to start
            @param rowtopic: the topic id of the row message to use for navigating
            @param odom_frame: the frame in which the robot is moving
            @param vehicle_frame: the frame id of the vehicles base
        """
        
        ## Setup some default values even though they are received via the goal
        self.desired_offset = 0.3
        self.max_out_of_headland_count = 10
        self.pgain = 0.2
        self.distance_scale = 0.1
        self.forward_velocity= 0.5
        
        
        # store the odometry frame id for use in distance calculation
        self.odom_frame = odom_frame
        self.vehicle_frame = vehicle_frame
        
        # reset counters used for detecting loss of rows and headland
        self.outofheadlandcount = 0
        self.left_valid_count = 0
        self.right_valid_count = 0
    
        self.__listen = TransformListener()
 
        self.cur_row = None
        
        self.vel_pub = rospy.Publisher("/fmControllers/cmd_vel_auto",Twist)
        
        self._action_name = name
        self._server = actionlib.SimpleActionServer(self._action_name,navigate_in_row_simpleAction,auto_start=False)
        self._server.register_goal_callback(self.goal_cb)
        self._server.register_preempt_callback(self.preempt_cb);
        
        self._subscriber = rospy.Subscriber(rowtopic, row, callback=self.row_msg_callback)
        self._last_row_msg = None
        
        self._server.start()
        
        
        
        self._timer = rospy.Timer(rospy.Duration(0.1),self.on_timer)
        
    def preempt_cb(self):
        """
            Called when the action client wishes to preempt us.
            Currently we just publish a velocity of zero in order to stop the vehicle.
        """
        rospy.loginfo("preempt received")
        self.__send_safe_velocity()
        self._server.set_preempted()
        
    
    def goal_cb(self):
        """
            Called when we receive a new goal.
            We could inspect the goal before accepting it,
            however for start we only accept it.
        """
        rospy.loginfo("goal received")
        
        g = self._server.accept_new_goal()
        
        self.desired_offset = g.desired_offset_from_row
        self.max_out_of_headland_count = g.headland_timeout
        self.pgain = g.P
        self.distance_scale = g.distance_scale
        self.forward_velocity= g.forward_velcoity
        self.outofheadlandcount = 0
        
        # reset start and end pose
        self.__start_pose = self.get_pose()
        self.__end_pose = None
        
        self.left_valid_count = self.right_valid_count = 0
        
        self.start_time = rospy.Time.now()
        
    def row_msg_callback(self,row):
        """
            Stores the row received
        """
        self.cur_row = row

        
    def get_pose(self):
        """
            returns the pose of the vehicle in the odometry frame
            returns none if the vehicle could not be located
        """
        cur_pos = None
        
        try:
            cur_pos = self.__listen.lookupTransform(self.odom_frame,self.vehicle_frame,rospy.Time(0))
        except (LookupException, ConnectivityException),err:
            rospy.loginfo("could not locate vehicle")
            
        return cur_pos
コード例 #50
0
class Pointmass_Adjust:

    pub_marker = True  #Set to (True) or to not(False) publish rviz marker showing force vector

    mass = 1.0463  #kg 1.0213
    pos_x = 0.0853  #m, in 'l_wrist_roll_link'
    pos_y = 0.0
    pos_z = 0.0
    x_force_offset = 5.62  #5.70 -- These values determined from experiment, used values are adjusted for better qualitative results using rviz
    y_force_offset = -13.56  #14.10
    z_force_offset = 4.30  #-3.88
    x_torque_offset = -0.4025  #0.3899
    y_torque_offset = -0.4175  #0.3804
    z_torque_offset = -0.21875
    adjustment = WrenchStamped()

    def __init__(self):
        rospy.init_node("ft_pointmass_adjustment")
        rospy.Subscriber("netft_data", WrenchStamped, self.adjust)
        self.ft_out = rospy.Publisher('ft_data_pm_adjusted', WrenchStamped)
        self.force_vec_out = rospy.Publisher('ft_force_vector_marker', Marker)
        self.tfl = TransformListener()

    def adjust(self, ft_in):
        ft_out = WrenchStamped()
        ft_out.header.stamp = rospy.Time.now()
        ft_out.header.frame_id = ft_in.header.frame_id
        ft_out.wrench.force.x = ft_in.wrench.force.x - self.x_force_offset + self.adjustment.wrench.force.x
        ft_out.wrench.force.y = ft_in.wrench.force.y - self.y_force_offset + self.adjustment.wrench.force.y
        ft_out.wrench.force.z = ft_in.wrench.force.z - self.z_force_offset + self.adjustment.wrench.force.z
        ft_out.wrench.torque.x = ft_in.wrench.torque.x - self.x_torque_offset - self.adjustment.wrench.torque.x
        ft_out.wrench.torque.y = ft_in.wrench.torque.y - self.y_torque_offset - self.adjustment.wrench.torque.y
        ft_out.wrench.torque.z = ft_in.wrench.torque.z - self.z_torque_offset - self.adjustment.wrench.torque.z

        self.ft_out.publish(ft_out)
        if self.pub_marker:
            marker = self.form_marker(ft_out)
            self.force_vec_out.publish(marker)

    def form_marker(self, ws):
        origin = Point()
        force_point = Point()
        force_point.x = 0.1 * ws.wrench.force.x
        force_point.y = 0.1 * ws.wrench.force.y
        force_point.z = 0.1 * ws.wrench.force.z
        force_vec = Marker()
        force_vec.header.stamp = rospy.Time.now()
        force_vec.header.frame_id = '/l_netft_frame'
        force_vec.ns = "ft_sensor"
        force_vec.action = 0
        force_vec.type = 0
        force_vec.scale.x = 0.1
        force_vec.scale.y = 0.2
        force_vec.scale.z = 1
        force_vec.color.a = 0.75
        force_vec.color.r = 0.0
        force_vec.color.g = 1.0
        force_vec.color.b = 0.1

        force_vec.lifetime = rospy.Duration(1)
        force_vec.points.append(origin)
        force_vec.points.append(force_point)
        return force_vec

    def calc_adjustment(self):
        try:
            (pos, quat) = self.tfl.lookupTransform('/base_link',
                                                   '/l_netft_frame',
                                                   rospy.Time(0))
        except:
            return
        rot = transformations.euler_from_quaternion(quat)
        self.adjustment.wrench.torque.x = self.mass * 9.80665 * self.pos_x * math.sin(
            rot[0])
        self.adjustment.wrench.torque.y = self.mass * 9.80665 * self.pos_x * math.sin(
            rot[1])
        self.adjustment.wrench.torque.z = 0

        grav = PointStamped(
        )  # Generate a 'vector' of the force due to gravity at the ft sensor
        grav.header.stamp = rospy.Time(
            0
        )  #Used to tell tf to grab latest available transform in transformVector3
        grav.header.frame_id = '/base_link'
        grav.point.x = pos[0]
        grav.point.y = pos[1]
        grav.point.z = pos[2] - 9.80665 * self.mass

        netft_grav = self.tfl.transformPoint(
            '/l_netft_frame', grav
        )  #Returns components of the 'gravity force' in each axis of the 'l_netft_frame'
        self.adjustment.wrench.force.x = netft_grav.point.x
        self.adjustment.wrench.force.y = netft_grav.point.y
        self.adjustment.wrench.force.z = netft_grav.point.z

        self.adjustment.header.stamp = rospy.Time.now()
コード例 #51
0
class Controller():
    Manual = 0
    Automatic = 1
    TakeOff = 2

    def __init__(self):
        self.pubNav = rospy.Publisher('cmd_vel', Twist, queue_size=1)
        self.listener = TransformListener()
        rospy.Subscriber("joy", Joy, self._joyChanged)
        rospy.Subscriber("cmd_vel_telop", Twist, self._cmdVelTelopChanged)
        self.cmd_vel_telop = Twist()
        #self.pidX = PID(20, 12, 0.0, -30, 30, "x")
        #self.pidY = PID(-20, -12, 0.0, -30, 30, "y")
        #self.pidZ = PID(15000, 3000.0, 1500.0, 10000, 60000, "z")
        #self.pidYaw = PID(50.0, 0.0, 0.0, -200.0, 200.0, "yaw")
        self.pidX = PID(20, 12.0, 0.2, -30, 30, "x")
        self.pidY = PID(-20, -12.0, -0.2, -30, 30, "y")
        #50000  800
        self.pidZ = PID(15000, 3000.0,  1500.0, 10000, 57000, "z")
        self.pidYaw = PID(50.0, 0.0, 0.0, -200.0, 200.0, "yaw")
        self.state = Controller.Manual
        self.targetZ = 1
        self.targetX = 0.0
        self.targetY = -1.0
        self.des_angle = 90.0
        self.lastZ = 0.0
        self.power = 50000.0
	self.pubVz = rospy.Publisher('vel_z', Float32, queue_size=1)
        self.lastJoy = Joy()

    def _cmdVelTelopChanged(self, data):
        self.cmd_vel_telop = data
        if self.state == Controller.Manual:
            self.pubNav.publish(data)

    def pidReset(self):
        self.pidX.reset()
        self.pidZ.reset()
        self.pidZ.reset()
        self.pidYaw.reset()

    def _joyChanged(self, data):
        if len(data.buttons) == len(self.lastJoy.buttons):
            delta = np.array(data.buttons) - np.array(self.lastJoy.buttons)
            print ("Buton ok")
            #Button 1
            if delta[0] == 1 and self.state != Controller.Automatic:
                print("Automatic!")
                #thrust = self.cmd_vel_telop.linear.z
                #print(thrust)
                self.pidReset()
                self.pidZ.integral = self.power/self.pidZ.ki
                self.lastZ = 0.0
                #self.targetZ = 1
                self.state = Controller.Automatic
            #Button 2
            if delta[1] == 1 and self.state != Controller.Manual:
                print("Manual!")
                self.pubNav.publish(self.cmd_vel_telop)
                self.state = Controller.Manual
            #Button 3
            if delta[2] == 1:
                self.state = Controller.TakeOff
                print("TakeOff!")
            #Button 5
            if delta[4] == 1:
                self.targetY = 0.0
                self.des_angle = -90.0
                #print(self.targetZ)
                #self.power += 100.0
                print(self.power)
                #self.state = Controller.Automatic
            #Button 6
            if delta[5] == 1:
                self.targetY = -1.0
                self.des_angle = 90.0
                #print(self.targetZ)
                #self.power -= 100.0
                print(self.power)
                #self.state = Controller.Automatic
        self.lastJoy = data

    def run(self):
        thrust = 0
        print("jello")
        while not rospy.is_shutdown():
            if self.state == Controller.TakeOff:
                t = self.listener.getLatestCommonTime("/mocap", "/Nano_Mark3")
                if self.listener.canTransform("/mocap", "/Nano_Mark3", t):
                    position, quaternion = self.listener.lookupTransform("/mocap","/Nano_Mark3", t)
                    print(position[0],position[1],position[2])			
                    if position[2] > 0.2 or thrust > 54000:
                        self.pidReset()
                        #self.pidZ.integral = thrust / self.pidZ.ki
                        #self.targetZ = 0.5
                        self.state = Controller.Automatic
                        thrust = 0
                    else:
                        thrust += 100
                        self.power = thrust
                        msg = self.cmd_vel_telop
                        msg.linear.z = thrust
                        self.pubNav.publish(msg)

            if self.state == Controller.Automatic:
                # transform target world coordinates into local coordinates
                t = self.listener.getLatestCommonTime("/mocap","/Nano_Mark3")
                seconds = rospy.get_time()
                print(t)
                if self.listener.canTransform("/mocap","/Nano_Mark3", t):
                    position, quaternion = self.listener.lookupTransform("/mocap","/Nano_Mark3",t)
                    #print(position[0],position[1],position[2])	
                    euler = tf.transformations.euler_from_quaternion(quaternion)
		    #print(euler[2]*(180/math.pi))
                    msg = self.cmd_vel_telop
                    #print(self.power)

                    if self.lastZ == 0.0:
		    	self.lastZ = position[2]
			last_time = seconds;
    		    else:
                        dh = self.targetZ - position[2]
   			v_z = (position[2]-self.lastZ)/((seconds-last_time))
                        #print(v_z)
                    	self.pubVz.publish(v_z)
                        
                        #por encima de goal
                        if dh<0.0:
			    self.power -=50
			    #if v_z>0.0:
		 	    #    self.power -=50
			    #else:
				#self.power +=50
			#por debajo de goal
			if dh>0.0:
                            if self.power > 57000.0:
				self.power = 57000.0
			    else:
				self.power += 50
			    #if v_z<0.0:
			#	self.power +=50
			#    else:
			#	self.power -=50
                    
		    print(self.power)
		    msg.linear.z = self.power

                    #Descompostion of the x and y contributions following the Z-Rotation
                    x_prim = self.pidX.update(0.0, self.targetX-position[0])
                    y_prim = self.pidY.update(0.0,self.targetY-position[1])
                    
                    msg.linear.x = x_prim*math.cos(euler[2]) - y_prim*math.sin(euler[2]) 
                    msg.linear.y = x_prim*math.sin(euler[2]) + y_prim*math.cos(euler[2])                    
                    

                    #---old stuff---  
                    #msg.linear.x = self.pidX.update(0.0, 0.0-position[0])
                    #msg.linear.y = self.pidY.update(0.0,-1.0-position[1])
                    #msg.linear.z = self.pidZ.update(position[2],1.0)
                                        
                    #z_prim = self.pidZ.update(0.0,self.targetZ-position[2])
                    #print(z_prim)
                    #if z_prim < self.power:
                    #    msg.linear.z = self.power
                    #else:
                    #    msg.linear.z = z_prim
                    #msg.linear.z = z_prim

                    #msg.linear.z = self.pidZ.update(0.0,1.0-position[2]) #self.pidZ.update(position[2], self.targetZ)
                    #msg.angular.z = self.pidYaw.update(0.0,self.des_angle + euler[2]*(180/math.pi))
                    print(msg.linear.x,msg.linear.y,msg.linear.z,msg.angular.z)
                    #print(euler[2])
                    #print(msg.angular.z)
                    self.pubNav.publish(msg)

            rospy.sleep(0.01)
コード例 #52
0
ファイル: circle.py プロジェクト: 854768750/crazyflie_ros
class Circle():
    def __init__(self, goals):
        rospy.init_node('circle', anonymous=True)
        self.worldFrame = rospy.get_param("~worldFrame", "/world")
        self.frame = rospy.get_param("~frame")
        self.radius = rospy.get_param("~radius")
        self.freq = rospy.get_param("~freq")
        self.x = rospy.get_param("~x")
        self.y = rospy.get_param("~y")
        self.z = rospy.get_param("~z")
        self.lap = rospy.get_param("~lap")
        self.omega = self.freq * 2 * 3.1415926
        self.pubGoal = rospy.Publisher('goal', PoseStamped, queue_size=1)
        self.listener = TransformListener()
        self.goals = goals
        self.goalIndex = 0

    def run(self):
        self.listener.waitForTransform(self.worldFrame, self.frame,
                                       rospy.Time(), rospy.Duration(5.0))
        #rospy.loginfo("start running!")
        goal = PoseStamped()
        goal.header.seq = 0
        goal.header.frame_id = self.worldFrame
        while not rospy.is_shutdown():
            #rospy.loginfo("start running!")
            goal.header.seq += 1
            goal.header.stamp = rospy.Time.now()
            goal.pose.position.x = self.x
            goal.pose.position.y = self.y
            goal.pose.position.z = self.z
            quaternion = tf.transformations.quaternion_from_euler(
                0, 0, self.goals[self.goalIndex][3])
            goal.pose.orientation.x = quaternion[0]
            goal.pose.orientation.y = quaternion[1]
            goal.pose.orientation.z = quaternion[2]
            goal.pose.orientation.w = quaternion[3]

            self.pubGoal.publish(goal)

            t = self.listener.getLatestCommonTime(self.worldFrame, self.frame)
            if self.listener.canTransform(self.worldFrame, self.frame, t):
                position, quaternion = self.listener.lookupTransform(
                    self.worldFrame, self.frame, t)
                rpy = tf.transformations.euler_from_quaternion(quaternion)
                if     math.fabs(position[0] - self.x) < 0.15 \
                   and math.fabs(position[1] - self.y) < 0.15 \
                   and math.fabs(position[2] - self.z) < 0.15 \
                   and math.fabs(rpy[2] - self.goals[self.goalIndex][3]) < math.radians(10) \
                   and self.goalIndex < len(self.goals) - 2:
                    rospy.sleep(2)
                    self.goalIndex += 1
                    #rospy.loginfo("Index:%lf",self.goalIndex)
                    if self.goalIndex == len(self.goals) - 2:
                        break

        t_start = rospy.Time.now().to_sec()
        #rospy.loginfo("t_start:%lf",t_start)
        t_now = t_start
        while ((not rospy.is_shutdown())
               and (t_now - t_start < self.lap / self.freq)):
            goal.header.seq += 1
            goal.header.stamp = rospy.Time.now()
            goal.pose.position.x = self.x + self.radius * math.sin(
                (t_now - t_start) * self.omega)
            goal.pose.position.y = self.y + self.radius - self.radius * math.cos(
                (t_now - t_start) * self.omega)
            goal.pose.position.z = self.z
            quaternion = tf.transformations.quaternion_from_euler(
                0, 0, (t_now - t_start) * self.omega)
            goal.pose.orientation.x = quaternion[0]
            goal.pose.orientation.y = quaternion[1]
            goal.pose.orientation.z = quaternion[2]
            goal.pose.orientation.w = quaternion[3]
            self.pubGoal.publish(goal)
            t_now = rospy.Time.now().to_sec()
#rospy.loginfo("t_now-t_start:%lf",t_now-t_start)

        while not rospy.is_shutdown():
            goal.header.seq += 1
            goal.header.stamp = rospy.Time.now()
            goal.pose.position.x = self.x
            goal.pose.position.y = self.y
            goal.pose.position.z = self.z
            quaternion = tf.transformations.quaternion_from_euler(
                0, 0, self.goals[self.goalIndex][3])
            goal.pose.orientation.x = quaternion[0]
            goal.pose.orientation.y = quaternion[1]
            goal.pose.orientation.z = quaternion[2]
            goal.pose.orientation.w = quaternion[3]

            self.pubGoal.publish(goal)
            #rospy.loginfo("Index:%lf",self.goalIndex)

            t = self.listener.getLatestCommonTime(self.worldFrame, self.frame)
            if self.listener.canTransform(self.worldFrame, self.frame, t):
                position, quaternion = self.listener.lookupTransform(
                    self.worldFrame, self.frame, t)
                rpy = tf.transformations.euler_from_quaternion(quaternion)
                if     math.fabs(position[0] - self.x) < 0.15 \
                   and math.fabs(position[1] - self.y) < 0.15 \
                   and math.fabs(position[2] - self.z) < 0.15 \
                   and math.fabs(rpy[2] - self.goals[self.goalIndex][3]) < math.radians(10) \
                   and self.goalIndex < len(self.goals) - 1:
                    rospy.sleep(self.goals[self.goalIndex][4])
                    self.goalIndex += 1
コード例 #53
0
ファイル: social_gaze.py プロジェクト: hcrlab/pr2_pbd_app
class SocialGaze:
    def __init__(self):
        self.defaultLookatPoint = Point(1,0,1.35)
        self.downLookatPoint = Point(0.5,0,0.5)
        self.targetLookatPoint = Point(1,0,1.35)
        self.currentLookatPoint = Point(1,0,1.35)
        
        self.currentGazeAction = GazeGoal.LOOK_FORWARD;
        self.prevGazeAction = self.currentGazeAction
        self.prevTargetLookatPoint = array(self.defaultLookatPoint);
        
        # Some constants
        self.doNotInterrupt = [GazeGoal.GLANCE_RIGHT_EE, GazeGoal.GLANCE_LEFT_EE, GazeGoal.NOD, GazeGoal.SHAKE];
        self.nodPositions = [Point(1,0,1.05), Point(1,0,1.55)]
        self.shakePositions = [Point(1,0.2,1.35), Point(1,-0.2,1.35)]
        self.nNods = 5
        self.nShakes = 5

        self.nodCounter = 5
        self.shakeCounter = 5
        self.facePos = None
        
        ## Action client for sending commands to the head.
        self.headActionClient = SimpleActionClient('/head_traj_controller/point_head_action', PointHeadAction)
        self.headActionClient.wait_for_server()
        rospy.loginfo('Head action client has responded.')
    
        self.headGoal = PointHeadGoal()
        self.headGoal.target.header.frame_id = 'base_link'
        self.headGoal.min_duration = rospy.Duration(1.0)
        self.headGoal.target.point = Point(1,0,1)
        
        ## Client for receiving detected faces
        #self.faceClient = SimpleActionClient('face_detector_action', FaceDetectorAction)
        
        ## Service client for arm states
        self.tfListener = TransformListener()
        
        ## Server for gaze requested gaze actions
        self.gazeActionServer = actionlib.SimpleActionServer('gaze_action', GazeAction, self.executeGazeAction, False)
        self.gazeActionServer.start()
    
    ## Callback function to receive ee states and face location
    def getEEPos(self, armIndex):
        
        fromFrame = '/base_link'
        if (armIndex == 0):
            toFrame = '/r_wrist_roll_link'
        else:
            toFrame = '/l_wrist_roll_link'
        
        try:
            t = self.tfListener.getLatestCommonTime(fromFrame, toFrame)
            (position, rotation) = self.tfListener.lookupTransform(fromFrame, toFrame, t)
        except:
            rospy.logerr('Could not get the end-effector pose.')
        #objPoseStamped = PoseStamped()
        #objPoseStamped.header.stamp = t
        #objPoseStamped.header.frame_id = '/base_link'
        #objPoseStamped.pose = Pose()
        #relEEPose = self.tfListener.transformPose(toFrame, objPoseStamped)
        return Point(position[0], position[1], position[2])

    def getFaceLocation(self):
        connected = self.faceClient.wait_for_server(rospy.Duration(1.0))
        if connected:
            fgoal = FaceDetectorGoal()
            self.faceClient.send_goal(fgoal)
            self.faceClient.wait_for_result()
            f = self.faceClient.get_result()
            ## If there is one face follow that one, if there are more than one, follow the closest one
            closest = -1
            if len(f.face_positions) == 1:
                closest = 0
            elif len(f.face_positions) > 0:
                closest_dist = 1000
            
            for i in range(len(f.face_positions)):
                dist = f.face_positions[i].pos.x*f.face_positions[i].pos.x + f.face_positions[i].pos.y*f.face_positions[i].pos.y + f.face_positions[i].pos.z*f.face_positions[i].pos.z
                if dist < closest_dist:
                    closest = i
                    closest_dist = dist
            
            if closest > -1:
                self.facePos = array([f.face_positions[closest].pos.x, f.face_positions[closest].pos.y, f.face_positions[closest].pos.z])
            else:
                rospy.logwarn('No faces were detected.')
                self.facePos = self.defaultLookatPoint
        else:
            rospy.logwarn('Not connected to the face server, cannot follow faces.')
            self.facePos = self.defaultLookatPoint

    ## Callback function for receiving gaze commands
    def executeGazeAction(self, goal):
        command = goal.action;
        if (self.doNotInterrupt.count(self.currentGazeAction) == 0):
            if (self.currentGazeAction != command or command == GazeGoal.LOOK_AT_POINT):
                self.isActionComplete = False
                if (command == GazeGoal.LOOK_FORWARD):
                    self.targetLookatPoint = self.defaultLookatPoint
                elif (command == GazeGoal.LOOK_DOWN):
                    self.targetLookatPoint = self.downLookatPoint
                elif (command == GazeGoal.NOD):
                    self.nNods = 5
                    self.startNod()
                elif (command == GazeGoal.SHAKE):
                    self.nShakes = 5
                    self.startShake()
                elif (command == GazeGoal.NOD_ONCE):
                    self.nNods = 5
                    self.startNod()
                elif (command == GazeGoal.SHAKE_ONCE):
                    self.nShakes = 5
                    self.startShake()
                elif (command == GazeGoal.GLANCE_RIGHT_EE):
                    self.startGlance(0)
                elif (command == GazeGoal.GLANCE_LEFT_EE):
                    self.startGlance(1)
                elif (command == GazeGoal.LOOK_AT_POINT):
                    self.targetLookatPoint = goal.point
                rospy.loginfo('Setting gaze action to:' + str(command))
                self.currentGazeAction = command
    
                while (not self.isActionComplete):
                    time.sleep(0.1)
                self.gazeActionServer.set_succeeded()
            else:
                self.gazeActionServer.set_aborted()
        else:
            self.gazeActionServer.set_aborted()

    def isTheSame(self, current, target):
        diff = target - current
        dist = linalg.norm(diff)
        return (dist<0.0001)

    def filterLookatPosition(self, current, target):
        speed = 0.02
        diff = self.point2array(target) - self.point2array(current)
        dist = linalg.norm(diff)
        if (dist>speed):
            step = dist/speed
            return self.array2point(self.point2array(current) + diff/step)
        else:
            return target
    
    def startNod(self):
        self.prevTargetLookatPoint = self.targetLookatPoint
        self.prevGazeAction = str(self.currentGazeAction)
        self.nodCounter = 0
        self.targetLookatPoint = self.nodPositions[0]
    
    def startGlance(self, armIndex):
        self.prevTargetLookatPoint = self.targetLookatPoint
        self.prevGazeAction = str(self.currentGazeAction)
        self.glanceCounter = 0
        self.targetLookatPoint = self.getEEPos(armIndex)

    def startShake(self):
        self.prevTargetLookatPoint = self.targetLookatPoint
        self.prevGazeAction = str(self.currentGazeAction)
        self.shakeCounter = 0
        self.targetLookatPoint = self.shakePositions[0]
    
    def point2array(self, p):
        return array((p.x, p.y, p.z))
    
    def array2point(self, a):
        return Point(a[0], a[1], a[2])
    
    def getNextNodPoint(self, current, target):
        if (self.isTheSame(self.point2array(current), self.point2array(target))):
            self.nodCounter += 1
            if (self.nodCounter == self.nNods):
                self.currentGazeAction = self.prevGazeAction
                return self.prevTargetLookatPoint
            else:
                return self.nodPositions[self.nodCounter%2]
        else:
            return target

    def getNextGlancePoint(self, current, target):
        if (self.isTheSame(self.point2array(current), self.point2array(target))):
            self.glanceCounter = 1
            self.currentGazeAction = self.prevGazeAction
            return self.prevTargetLookatPoint
        else:
            return target

    def getNextShakePoint(self, current, target):
        if (self.isTheSame(self.point2array(current), self.point2array(target))):
            self.shakeCounter += 1
            if (self.shakeCounter == self.nNods):
                self.currentGazeAction = self.prevGazeAction
                return self.prevTargetLookatPoint
            else:
                return self.shakePositions[self.shakeCounter%2]
        else:
            return target
        
    def update(self):

        isActionPossiblyComplete = True
        if (self.currentGazeAction == GazeGoal.FOLLOW_RIGHT_EE):
            self.targetLookatPoint = self.getEEPos(0)

        elif (self.currentGazeAction == GazeGoal.FOLLOW_LEFT_EE):
            self.targetLookatPoint = self.getEEPos(1)

        elif (self.currentGazeAction == GazeGoal.FOLLOW_FACE):
            self.getFaceLocation()
            self.targetLookatPoint = self.facePos

        elif (self.currentGazeAction == GazeGoal.NOD):
            self.targetLookatPoint = self.getNextNodPoint(self.currentLookatPoint, self.targetLookatPoint)
            self.headGoal.min_duration = rospy.Duration(0.5)
            isActionPossiblyComplete = False;

        elif (self.currentGazeAction == GazeGoal.SHAKE):
            self.targetLookatPoint = self.getNextShakePoint(self.currentLookatPoint, self.targetLookatPoint)
            self.headGoal.min_duration = rospy.Duration(0.5)
            isActionPossiblyComplete = False;
                
        elif (self.currentGazeAction == GazeGoal.GLANCE_RIGHT_EE or self.currentGazeAction == GazeGoal.GLANCE_LEFT_EE):
            self.targetLookatPoint = self.getNextGlancePoint(self.currentLookatPoint, self.targetLookatPoint)
            isActionPossiblyComplete = False;

        self.currentLookatPoint = self.filterLookatPosition(self.currentLookatPoint, self.targetLookatPoint)
        if (self.isTheSame(self.point2array(self.headGoal.target.point), self.point2array(self.currentLookatPoint))):
            if (isActionPossiblyComplete):
                if (self.headActionClient.get_state() == GoalStatus.SUCCEEDED):
                    self.isActionComplete = True
        else:
            self.headGoal.target.point = self.currentLookatPoint
            self.headActionClient.send_goal(self.headGoal)

        time.sleep(0.02)
コード例 #54
0
class Crazyflie:
    def __init__(self, prefix, cf_id, use_tf=False):
        """
        Creates a Crazyflie high-level wrapper
        
        Args:
            prefix (str): ROS namespace of the drone. Ex = "/cf1"
            cf_id (int): drone id. Ex : 1
        """
        self.prefix = prefix
        if use_tf:
            self.tf = TransformListener()
        self.cf_id = cf_id

        rospy.wait_for_service(prefix + "/set_group_mask")
        self.setGroupMaskService = rospy.ServiceProxy(prefix + "/set_group_mask", SetGroupMask)
        rospy.wait_for_service(prefix + "/takeoff")
        self.takeoffService = rospy.ServiceProxy(prefix + "/takeoff", Takeoff)
        rospy.wait_for_service(prefix + "/land")
        self.landService = rospy.ServiceProxy(prefix + "/land", Land)
        rospy.wait_for_service(prefix + "/stop")
        self.stopService = rospy.ServiceProxy(prefix + "/stop", Stop)
        rospy.wait_for_service(prefix + "/go_to")
        self.goToService = rospy.ServiceProxy(prefix + "/go_to", GoTo)
        rospy.wait_for_service(prefix + "/upload_trajectory")
        self.uploadTrajectoryService = rospy.ServiceProxy(prefix + "/upload_trajectory", UploadTrajectory)
        rospy.wait_for_service(prefix + "/start_trajectory")
        self.startTrajectoryService = rospy.ServiceProxy(prefix + "/start_trajectory", StartTrajectory)
        rospy.wait_for_service(prefix + "/update_params")
        self.updateParamsService = rospy.ServiceProxy(prefix + "/update_params", UpdateParams)

    def setGroup(self, groupMask):
        self.setGroupMaskService(groupMask)

    def takeoff(self, targetHeight, duration, groupMask = 0):
        self.takeoffService(groupMask, targetHeight, rospy.Duration.from_sec(duration))

    def land(self, targetHeight, duration, groupMask = 0):
        self.landService(groupMask, targetHeight, rospy.Duration.from_sec(duration))

    def stop(self, groupMask = 0):
        self.stopService(groupMask)

    def goTo(self, goal, yaw, duration, relative = False, groupMask = 0):
        gp = arrayToGeometryPoint(goal)
        self.goToService(groupMask, relative, gp, yaw, rospy.Duration.from_sec(duration))

    def uploadTrajectory(self, trajectoryId, pieceOffset, trajectory):
        pieces = []
        for poly in trajectory.polynomials:
            piece = TrajectoryPolynomialPiece()
            piece.duration = rospy.Duration.from_sec(poly.duration)
            piece.poly_x   = poly.px.p
            piece.poly_y   = poly.py.p
            piece.poly_z   = poly.pz.p
            piece.poly_yaw = poly.pyaw.p
            pieces.append(piece)
        self.uploadTrajectoryService(trajectoryId, pieceOffset, pieces)

    def startTrajectory(self, trajectoryId, timescale = 1.0, reverse = False, relative = True, groupMask = 0):
        self.startTrajectoryService(groupMask, trajectoryId, timescale, reverse, relative)

    def position(self):
        if not self.tf:
            raise RuntimeError("CF instance was created without using tf. set use_tf=True to get position")
        self.tf.waitForTransform("/world", "/cf" + str(self.cf_id), rospy.Time(0), rospy.Duration(10))
        position, quaternion = self.tf.lookupTransform("/world", "/cf" + str(self.cf_id), rospy.Time(0))
        return np.array(position)

    def getParam(self, name):
        return rospy.get_param(self.prefix + "/" + name)

    def setParam(self, name, value):
        rospy.set_param(self.prefix + "/" + name, value)
        self.updateParamsService([name])

    def setParams(self, params):
        for name, value in params.iteritems():
            rospy.set_param(self.prefix + "/" + name, value)
        self.updateParamsService(params.keys())

    def enableHighLevel(self):
        self.setParam("commander/enHighLevel", 1)
コード例 #55
0
ファイル: make_turn.py プロジェクト: madsbahrt/FroboMind
class TurnAction():
    """
        Performs a X degree turn either to the left or right 
        depending on the given goal.
    """
    def __init__(self,name,odom_frame,base_frame):
        """
        
        @param name: the name of the action
        @param odom_frame: the frame the robot is moving in (odom_combined)
        @param base_frame: the vehicles own frame (usually base_link)
        """
        self._action_name = name
        self.__odom_frame = odom_frame
        self.__base_frame = base_frame
        self.__server =  actionlib.SimpleActionServer(self._action_name,make_turnAction,auto_start=False)
        self.__server.register_preempt_callback(self.preempt_cb)
        self.__server.register_goal_callback(self.goal_cb)
        
        self.__cur_pos = 0
        self.__start_yaw = 0
        self.__cur_yaw = 0
        
        self.__feedback = make_turnFeedback()
        
        self.__listen = TransformListener()
        self.vel_pub = rospy.Publisher("/fmControllers/cmd_vel_auto",Twist)
        
        self.__turn_timeout = 200
        self.__start_time = rospy.Time.now()
        self.turn_vel = 0
        self.new_goal = False
        
        self.__server.start()

    def preempt_cb(self):
        rospy.loginfo("Preempt requested")
        self.__publish_cmd_vel(0)
        self.__server.set_preempted()
    
    def goal_cb(self):
        """
            called when we receive a new goal
            the goal contains a desired radius and a success radius in which we check if the turn succeeded or not
            the message also contains if we should turn left or right
        """
        g = self.__server.accept_new_goal()
        self.__desired_amount= g.amount
        self.turn_vel = g.vel
        self.forward_vel = g.forward_vel
        
        self.__cur_pos = None
        self.__cur_yaw = 0
        self.__start_yaw = 0
        
        
        self.new_goal = True
    
    def on_timer(self,e):
        """
            called regularly by a ros timer
            
            This function exevutes the main loop of this action
            if a goal is active a rabbit is placed initially at the desired distance 
            from the robot at either left or right.
        """
        if self.__server.is_active():
            if self.new_goal:
                self.new_goal = False
                if self.__get_start_position():
                    self.__start_time = rospy.Time.now()
                else:
                    self.__server.set_aborted(text="could not find vehicle")
            else:
                if rospy.Time.now() - self.__start_time > rospy.Duration(self.__turn_timeout):
                    self.__server.set_aborted(text="timeout on action")
                    self.__publish_cmd_vel(0)
                else:
                    if self.__get_current_position():
                        if self.__desired_amount > 0:
                            if self.compare_yaw_turn(self.__start_yaw,self.__cur_yaw, self.__desired_amount):
                                result = make_turnResult()
                                result.end_yaw = self.__cur_yaw
                                self.__server.set_succeeded(result, "turn completed")
                                self.__publish_cmd_vel(0)
                            else:
                                self.__publish_cmd_vel(1)
                                
                        else:
                                # notice swap of position and call of yaw
                             if self.compare_yaw_turn(self.__cur_yaw, self.__start_yaw, self.__desired_amount*-1):
                                result = make_turnResult()
                                result.end_yaw = self.__cur_yaw
                                self.__server.set_succeeded(result, "turn completed")
                                self.__publish_cmd_vel(0)
                                
                             else:
                                self.__publish_cmd_vel(1)
                                self.__feedback.start = self.__start_yaw
                                self.__feedback.current = self.__cur_yaw
                                self.__feedback.target= self.__start_yaw + self.__desired_amount
                                self.__server.publish_feedback(self.__feedback)
                    else:
                        self.__publish_cmd_vel(0)
    
    def compare_yaw_turn(self,start,current,amount):
        diff = current - start
        
        if diff > math.pi:
            diff -= 2 * math.pi
        elif diff < - math.pi:
            diff += 2 * math.pi
        
        
        self.__feedback.start = start
        self.__feedback.current = current
        self.__feedback.target = diff
        self.__server.publish_feedback(self.__feedback)
        
        
        if diff >= amount:
            return True
        else:
            return False
            
    
    def __get_start_position(self):
        ret = False
        try:
            self.__start_pos = self.__listen.lookupTransform(self.__odom_frame,self.__base_frame,rospy.Time(0))
            self.__start_yaw = tf.transformations.euler_from_quaternion(self.__start_pos[1])[2]
            ret = True
        except (tf.LookupException, tf.ConnectivityException),err:
            rospy.loginfo("could not locate vehicle")
        
        return ret
コード例 #56
0
class AccurateDocking(RComponent):
    """
    A class used to make a simple docking process
    """
    def __init__(self):
        RComponent.__init__(self)

        self.step = -1
        # array of {'initial': [x,y,theta], 'final': [x,y,theta]}
        self.results = []
        self.ongoing_result = {}
        self.total_iterations = 0
        self.stop = False

    def ros_read_params(self):
        """Gets params from param server"""
        RComponent.ros_read_params(self)

        self.dock_action_name = rospy.get_param('~dock_action_server',
                                                default='pp_docker')
        self.move_action_name = rospy.get_param('~move_action_server',
                                                default='move')

        self.robot_link = rospy.get_param('~base_frame',
                                          default='robot_base_link')

        self.pregoal_link = rospy.get_param(
            '~pregoal_frame', default='laser_test_pregoal_footprint')
        self.goal_link = rospy.get_param('~goal_frame',
                                         default='laser_test_goal_footprint')
        self.reflectors_link = rospy.get_param(
            '~reflectors_frame',
            default='robot_filtered_docking_station_laser')
        # array of [x, y, theta] for the first dock call
        param_offset_1 = rospy.get_param('~pregoal_offset_1',
                                         default='[-0.5, 0, 0]')
        self.pregoal_offset_1 = (param_offset_1.replace('[', '').replace(
            ']', '').replace(',', '')).split(' ')

        if len(self.pregoal_offset_1) != 3:
            self.pregoal_offset_1 = [0, 0, 0]
        else:
            for i in range(len(self.pregoal_offset_1)):
                self.pregoal_offset_1[i] = float(self.pregoal_offset_1[i])
        # array of [x, y, theta] for the second dock call
        param_offset_2 = rospy.get_param('~pregoal_offset_2',
                                         default='[-0.0, 0, 0]')
        self.pregoal_offset_2 = (param_offset_2.replace('[', '').replace(
            ']', '').replace(',', '')).split(' ')

        if len(self.pregoal_offset_2) != 3:
            self.pregoal_offset_2 = [0, 0, 0]
        else:
            for i in range(len(self.pregoal_offset_2)):
                self.pregoal_offset_2[i] = float(self.pregoal_offset_2[i])

        rospy.loginfo("%s::ros_read_params: docker offsets: %s - %s",
                      rospy.get_name(), str(self.pregoal_offset_1),
                      str(self.pregoal_offset_2))

        self.step_back_distance = rospy.get_param('~step_back_distance',
                                                  default=1.3)
        self.consecutive_iterations = rospy.get_param(
            '~consecutive_iterations', default=1)
        self.current_iteration = self.consecutive_iterations

    def ros_setup(self):
        """Creates and inits ROS components"""

        RComponent.ros_setup(self)

        self.tf = TransformListener()

        self.move_action_client = actionlib.SimpleActionClient(
            self.move_action_name, MoveAction)

        self.dock_action_client = actionlib.SimpleActionClient(
            self.dock_action_name, DockAction)

        self.start_docking_server = rospy.Service(
            '~start', Trigger, self.start_docking_service_cb)
        self.stop_docking_server = rospy.Service('~stop', Trigger,
                                                 self.stop_docking_service_cb)
        self.save_results_server = rospy.Service('~save_results', Empty,
                                                 self.save_results_service_cb)

        self.docking_status = rospy.Publisher('~status', String, queue_size=10)

        return 0

    def ready_state(self):
        """Actions performed in ready state"""

        if self.current_iteration < self.consecutive_iterations:

            self.docking_status.publish("running")

            if self.step != -1:
                try:
                    # Get relative goal position
                    t = self.tf.getLatestCommonTime(self.robot_link,
                                                    self.goal_link)

                    (position, quaternion) = self.tf.lookupTransform(
                        self.robot_link, self.goal_link, t)
                    (_, _, orientation) = euler_from_quaternion(quaternion)
                except Exception, e:
                    rospy.logerr("%s::ready_state: exception: %s",
                                 rospy.get_name(), e)
                    self.stop = True
                    return

                try:
                    # Get relative goal to the reflectors position
                    t = self.tf.getLatestCommonTime(self.robot_link,
                                                    self.reflectors_link)

                    (position_to_reflectors,
                     quaternion_to_reflectors) = self.tf.lookupTransform(
                         self.robot_link, self.reflectors_link, t)
                    (_, _, orientation_to_reflectors
                     ) = euler_from_quaternion(quaternion_to_reflectors)

                except Exception, e:
                    rospy.logerr("%s::ready_state: exception: %s",
                                 rospy.get_name(), e)
                    error_on_action()
                    return

            if self.step == 0:
                self.ongoing_result = {}
                rospy.loginfo('%s::ros_setup: waiting for server %s',
                              rospy.get_name(), self.move_action_name)
                self.move_action_client.wait_for_server()
                rospy.loginfo('%s::ros_setup: waiting for server %s',
                              rospy.get_name(), self.dock_action_name)
                self.dock_action_client.wait_for_server()

                rospy.loginfo(
                    '%s::ready_state: Initial distance to goal-> x: %.3lf mm, y: %.3lf mm, %.3lf degrees',
                    rospy.get_name(), position[0] * 1000, position[1] * 1000,
                    math.degrees(orientation))
                self.ongoing_result['initial'] = [
                    position[0], position[1],
                    math.degrees(orientation)
                ]
                # Docking
                dock_goal = DockGoal()
                dock_goal.dock_frame = self.pregoal_link
                dock_goal.robot_dock_frame = self.robot_link
                dock_goal.dock_offset.x = self.pregoal_offset_1[0]
                dock_goal.dock_offset.y = self.pregoal_offset_1[1]
                dock_goal.dock_offset.theta = self.pregoal_offset_1[2]
                rospy.loginfo(
                    '%s::ready_state: %d - docking to %s - offset = %s',
                    rospy.get_name(), self.step, self.pregoal_link,
                    str(dock_goal.dock_offset))
                self.dock_action_client.send_goal(dock_goal)
                self.dock_action_client.wait_for_result()
                result = self.dock_action_client.get_result()
                rospy.loginfo('%s::ready_state: %d - result = %s',
                              rospy.get_name(), self.step, str(result.success))

                if result.success == True:
                    self.step = 1
                    rospy.sleep(2)
                else:
                    rospy.logerr("%s::ready_state: Docking failed",
                                 rospy.get_name())
                    error_on_action()

            elif self.step == 1:

                # Docking
                dock_goal = DockGoal()
                dock_goal.dock_frame = self.pregoal_link
                dock_goal.robot_dock_frame = self.robot_link
                dock_goal.dock_offset.x = self.pregoal_offset_2[0]
                dock_goal.dock_offset.y = self.pregoal_offset_2[1]
                dock_goal.dock_offset.theta = self.pregoal_offset_2[2]
                rospy.loginfo(
                    '%s::ready_state: %d - docking to %s - offset = %s',
                    rospy.get_name(), self.step, self.pregoal_link,
                    str(dock_goal.dock_offset))
                self.dock_action_client.send_goal(dock_goal)
                self.dock_action_client.wait_for_result()
                result = self.dock_action_client.get_result()
                rospy.loginfo('%s::ready_state: %d - result = %s',
                              rospy.get_name(), self.step, str(result.success))

                if result.success == True:
                    self.step = 2
                else:
                    rospy.logerr("%s::ready_state: Docking failed",
                                 rospy.get_name())
                    error_on_action()

            elif self.step == 2:
                # Orientate robot
                move_goal = MoveGoal()
                move_goal.goal.theta = orientation
                if abs(math.degrees(orientation)) > 0.2:
                    rospy.loginfo(
                        '%s::ready_state: %d - rotating %.3lf degrees to %s',
                        rospy.get_name(), self.step, math.degrees(orientation),
                        self.goal_link)
                    self.move_action_client.send_goal(move_goal)
                    self.move_action_client.wait_for_result()
                    result = self.move_action_client.get_result()
                    rospy.loginfo('%s::ready_state: %d - result = %s',
                                  rospy.get_name(), self.step,
                                  str(result.success))

                    if result.success == True:
                        self.step = 3
                    else:
                        rospy.logerr("%s::ready_state: Move-Rotation failed",
                                     rospy.get_name())
                        error_on_action()
                else:
                    rospy.loginfo(
                        '%s::ready_state: %d - avoids rotating %.3lf degrees to %s',
                        rospy.get_name(), self.step, math.degrees(orientation),
                        self.goal_link)
                    self.step = 3

            elif self.step == 3:
                # Move forward
                move_goal = MoveGoal()
                move_goal.goal.x = position[0]
                rospy.loginfo(
                    '%s::ready_state: %d - moving forward %.3lf meters to %s',
                    rospy.get_name(), self.step, move_goal.goal.x,
                    self.goal_link)
                self.move_action_client.send_goal(move_goal)
                self.move_action_client.wait_for_result()
                result = self.move_action_client.get_result()
                rospy.loginfo('%s::ready_state: %d - result = %s',
                              rospy.get_name(), self.step, str(result.success))

                if result.success == True:
                    rospy.sleep(2)
                    self.step = 4
                else:
                    rospy.logerr("%s::ready_state: Move-Forward failed",
                                 rospy.get_name())
                    error_on_action()

            elif self.step == 4:
                rospy.loginfo(
                    '%s::ready_state: final distance to goal -> x: %.3lf mm, y: %.3lf mm, %.3lf degrees',
                    rospy.get_name(), position[0] * 1000, position[1] * 1000,
                    math.degrees(orientation))
                rospy.loginfo(
                    '%s::ready_state: final distance to reflectors -> x: %.3lf mm, y: %.3lf mm, %.3lf degrees',
                    rospy.get_name(), position_to_reflectors[0] * 1000,
                    position_to_reflectors[1] * 1000,
                    math.degrees(orientation_to_reflectors))
                self.ongoing_result['final'] = [
                    position[0], position[1],
                    math.degrees(orientation)
                ]
                self.results.append(self.ongoing_result)
                if self.step_back_distance == 0.0:
                    self.iteration_success()
                else:
                    self.step = 5

            elif self.step == 5:
                # Move backward
                move_goal = MoveGoal()
                move_goal.goal.x = -self.step_back_distance
                rospy.loginfo(
                    '%s::ready_state: %d - moving backwards %.3lf meters',
                    rospy.get_name(), self.step, move_goal.goal.x)
                self.move_action_client.send_goal(move_goal)
                self.move_action_client.wait_for_result()
                result = self.move_action_client.get_result()
                rospy.loginfo('%s::ready_state: %d - result = %s',
                              rospy.get_name(), self.step, str(result.success))

                if result.success == True:
                    rospy.sleep(2)
                    self.iteration_success()
                else:
                    rospy.logerr("%s::ready_state: Move-Forward failed",
                                 rospy.get_name())
                    self.error_on_action()
コード例 #57
0
class MergePoses:

    def __init__(self):

        self.avg_pose = None
        self.tl = TransformListener()

        self.topics = rospy.get_param('~poses',[])
        print self.topics
        if len(self.topics) == 0:
            rospy.logerr('Please provide a poses list as input parameter')
            return
        self.output_pose = rospy.get_param('~output_pose','ar_avg_pose')
        self.output_frame = rospy.get_param('~output_frame', 'rf_map')
        
        self.subscribers = []
        for i in self.topics:
            subi = rospy.Subscriber(i, PoseStamped, self.callback, queue_size=1)
            self.subscribers.append(subi)

        self.pub = rospy.Publisher(self.output_pose, PoseStamped, queue_size=1)
            
        self.mutex_avg = threading.Lock()
        self.mutex_t = threading.Lock()
        
        self.transformations = {}
        
    def callback(self, pose_msg):

        # get transformation to common frame
        position = None
        quaternion = None
        if self.transformations.has_key(pose_msg.header.frame_id):
            position, quaternion = self.transformations[pose_msg.header.frame_id]
        else:
            if self.tl.frameExists(pose_msg.header.frame_id) and \
            self.tl.frameExists(self.output_frame):
                t = self.tl.getLatestCommonTime(self.output_frame, pose_msg.header.frame_id)
                position, quaternion = self.tl.lookupTransform(self.output_frame,
                                                               pose_msg.header.frame_id, t)
                self.mutex_t.acquire()
                self.transformations[pose_msg.header.frame_id] = (position, quaternion)
                self.mutex_t.release()
                rospy.loginfo("Got static transform for %s" % pose_msg.header.frame_id)

        # transform pose
        framemat = self.tl.fromTranslationRotation(position, quaternion)

        posemat = self.tl.fromTranslationRotation([pose_msg.pose.position.x,
                                                   pose_msg.pose.position.y,
                                                   pose_msg.pose.position.z],
                                                  [pose_msg.pose.orientation.x,
                                                   pose_msg.pose.orientation.y,
                                                   pose_msg.pose.orientation.z,
                                                   pose_msg.pose.orientation.w])

        newmat = numpy.dot(framemat,posemat)
        
        xyz = tuple(translation_from_matrix(newmat))[:3]
        quat = tuple(quaternion_from_matrix(newmat))

        tmp_pose = PoseStamped()
        tmp_pose.header.stamp = pose_msg.header.stamp
        tmp_pose.header.frame_id = self.output_frame
        tmp_pose.pose = Pose(Point(*xyz),Quaternion(*quat))
        
        tmp_angles = euler_from_quaternion([tmp_pose.pose.orientation.x,
                                            tmp_pose.pose.orientation.y,
                                            tmp_pose.pose.orientation.z,
                                            tmp_pose.pose.orientation.w])
        
        # compute average
        self.mutex_avg.acquire()
        
        if self.avg_pose == None or (pose_msg.header.stamp - self.avg_pose.header.stamp).to_sec() > 0.5:
            self.avg_pose = tmp_pose
        else:            
            self.avg_pose.header.stamp = pose_msg.header.stamp
            a = 0.7
            b = 0.3
            self.avg_pose.pose.position.x = a*self.avg_pose.pose.position.x + b*tmp_pose.pose.position.x
            self.avg_pose.pose.position.y = a*self.avg_pose.pose.position.y + b*tmp_pose.pose.position.y
            self.avg_pose.pose.position.z = a*self.avg_pose.pose.position.z + b*tmp_pose.pose.position.z

            angles = euler_from_quaternion([self.avg_pose.pose.orientation.x,
                                            self.avg_pose.pose.orientation.y,
                                            self.avg_pose.pose.orientation.z,
                                            self.avg_pose.pose.orientation.w])
            angles = list(angles)
            angles[0] = avgAngles(angles[0], tmp_angles[0], 0.7, 0.3)
            angles[1] = avgAngles(angles[1], tmp_angles[1], 0.7, 0.3)
            angles[2] = avgAngles(angles[2], tmp_angles[2], 0.7, 0.3)

            q = quaternion_from_euler(angles[0], angles[1], angles[2])
            
            self.avg_pose.pose.orientation.x = q[0]
            self.avg_pose.pose.orientation.y = q[1]
            self.avg_pose.pose.orientation.z = q[2]
            self.avg_pose.pose.orientation.w = q[3]

        self.pub.publish(self.avg_pose)
            
        self.mutex_avg.release()
コード例 #58
0
class StatePredictionNode:
    """ This class contains the methods for state prediction """
    def __init__(self):

        rospy.init_node('odometry', anonymous=True)
        self.dt = .02
        self.control_voltages = np.zeros([2, 1])

        self.vl_filter = MedianFilter()
        self.vr_filter = MedianFilter()
        self.vb_filter = MedianFilter()

        self.vl = 0  # left wheel velocity (after filter)
        self.vr = 0  # right wheel velocity (after filter)
        self.vb = 0  # base angular velocity (after filter)

        self.base_imu_ready = False  # base imu is slower than the other IMU's
        # we can't update base velocity all the time

        Q = np.zeros([7, 7])
        Q[0, 0] = 1 * self.dt
        Q[1, 1] = 1 * self.dt
        R = np.eye(3) * .00001
        starting_state = np.zeros([7, 1])
        self.r = .15
        self.l = .55
        self.ekf = ExtendedWMRKalmanFilter(self.r, self.l, Q, R, 2.3364e-04,
                                           -.65, 2.3364e-04, -.65,
                                           starting_state, self.dt)
        self.listener = TransformListener()

        self.i = 0  # print index
        self.j = 0  # move camera index

        self.imus_observed_list = []
        self.ar_observed_list = []
        self.sensed_ar_diff = {
        }  # map from tag_id sensed to array of np.array([dx, dy, dtheta_z])
        self.landmark_map = {}  # map from id to AR TAG obj

        ## ADD PREDEFINED MAPS
        #(tag_num, slam_id, x, y, z, theta_x, theta_y, theta_z, fixed = True)
        self.landmark_map[0] = ARTAG_landmark(0, 1, 0, 1.37, .10, math.pi / 2,
                                              0, 0)
        self.landmark_map[1] = ARTAG_landmark(13, 2, -1.74, 0, .15,
                                              math.pi / 2, 0, math.pi / 2)
        self.landmark_map[3] = ARTAG_landmark(5, 3, 2.84, .15, .32,
                                              math.pi / 2, 0, -math.pi / 2)
        self.landmark_map[2] = ARTAG_landmark(9, 4, 1.37, 1.88, .06,
                                              math.pi / 2, 0, 0)
        self.ekf.add_AR_tag(self.landmark_map[0], np.zeros([3, 3]))
        self.ekf.add_AR_tag(self.landmark_map[1], np.zeros([3, 3]))
        self.ekf.add_AR_tag(self.landmark_map[2], np.zeros([3, 3]))
        self.ekf.add_AR_tag(self.landmark_map[3], np.zeros([3, 3]))
        self.br = tf.TransformBroadcaster()

        ## FILE WRITING INFO
        self.f = open('ekf_data.csv', 'w+')
        self.f.write('time, vl,vr,vx,vy,vtheta,x,y,theta,raw_vl,raw_vr\n')
        self.t0 = time.time()
        self.transform_written = False

        self.write_imu_measurements = [0, 0, 0]

        self.pub = rospy.Publisher('odometry', Odometry, queue_size=1)
        rospy.Subscriber("/imu1", Imu, self._imu1Callback)
        rospy.Subscriber("/imu2", Imu, self._imu2Callback)
        rospy.Subscriber("/imu3", Imu, self._imu3Callback)
        rospy.Subscriber("left_voltage_pwm", Int16, self._leftMotorCallback)
        rospy.Subscriber("right_voltage_pwm", Int16, self._rightMotorCallback)
        rospy.Subscriber("ar_pose_marker", AlvarMarkers, self._arCallback)
        rospy.Subscriber("scan", LaserScan, self._scanCallback)

        self.last_time = rospy.Time.now()

    def _scanCallback(self, data):
        return

    def _leftMotorCallback(self, data):
        self.control_voltages[0] = data.data

    def _rightMotorCallback(self, data):
        self.control_voltages[1] = data.data

    def _imu1Callback(self, data):
        self.imus_observed_list.append('imu1')
        left_wheel_v = -data.angular_velocity.x
        self.write_imu_measurements[0] = left_wheel_v
        if abs(left_wheel_v) < .05:
            self.vl_filter.add_data(0)
            self.vl = self.vl_filter.get_median()
            return

        self.vl_filter.add_data(left_wheel_v)
        self.vl = self.vl_filter.get_median()

    def _imu2Callback(self, data):
        self.imus_observed_list.append('imu2')
        right_wheel_v = -data.angular_velocity.x
        self.write_imu_measurements[1] = right_wheel_v
        if abs(right_wheel_v) < .05:
            self.vr_filter.add_data(0)
            self.vr = self.vr_filter.get_median()
            return

        self.vr_filter.add_data(right_wheel_v)
        self.vr = self.vr_filter.get_median()

    def _imu3Callback(self, data):
        self.imus_observed_list.append('imu3')
        self.vb = data.angular_velocity.z - .01
        self.write_imu_measurements[2] = self.vb
        if abs(self.vb) < .05:
            self.vb = 0
            return

    def _arCallback(self, data):
        for marker in data.markers:
            if marker.id in self.landmark_map:

                tag_frame = 'ar_marker_' + str(marker.id)
                t = self.listener.getLatestCommonTime(tag_frame, 'base')
                p_tr, q_tr = self.listener.lookupTransform(
                    tag_frame, 'base', t)
                H_tr = self.listener.fromTranslationRotation(p_tr, q_tr)

                # IGNORE READING IF IT IS TOO FAR AWAY
                if np.linalg.norm(p_tr) > 2.5:
                    return

                t = self.listener.getLatestCommonTime(tag_frame + '_ref',
                                                      'odom')
                p_ot, q_ot = self.listener.lookupTransform(
                    'odom', tag_frame + '_ref', t)
                H_ot = self.listener.fromTranslationRotation(p_ot, q_ot)

                H_ot = np.dot(H_ot, H_tr)
                angles = transformations.euler_from_matrix(H_ot[0:3, 0:3],
                                                           axes='sxyz')
                self.sensed_ar_diff[marker.id] = np.array([[H_ot[0, 3]],
                                                           [H_ot[1, 3]],
                                                           [angles[2]]])
                self.ar_observed_list.append(
                    marker.id)  # we observed an AR tag!

        return

    def _publish_odom(self):
        state = copy.deepcopy(self.ekf.current_state_estimate)

        ## BUILD AND SEND MSG
        quaternion = tf.transformations.quaternion_from_euler(0, 0, state[6])

        msg = Odometry()
        msg.header.stamp = rospy.Time.now()
        msg.pose.pose.position.x = state[4]
        msg.pose.pose.position.y = state[5]
        msg.pose.pose.position.z = 0
        msg.pose.pose.orientation.x = quaternion[0]
        msg.pose.pose.orientation.y = quaternion[1]
        msg.pose.pose.orientation.z = quaternion[2]
        msg.pose.pose.orientation.w = quaternion[3]

        msg.twist.twist.linear.x = state[2] * math.cos(state[6])
        msg.twist.twist.linear.y = state[2] * math.sin(state[6])
        msg.twist.twist.linear.z = 0
        msg.twist.twist.angular.z = state[3]

        self.pub.publish(msg)

    def _update_with_imus(self):
        if len(self.imus_observed_list) == 0:
            return

        # Initalize intermediary variables
        measurement_list = []
        H_list = []
        R_list = []
        num_states = self.ekf.current_state_estimate.shape[0]

        ## CHECK EACH SENSOR
        if 'imu1' in self.imus_observed_list:
            H_row = np.zeros([1, num_states])
            H_row[0, 0] = 1
            H_list.append(H_row)
            measurement_list.append(self.vl)
            R_list.append(.05)

        if 'imu2' in self.imus_observed_list:
            H_row = np.zeros([1, num_states])
            H_row[0, 1] = 1
            H_list.append(H_row)
            measurement_list.append(self.vr)
            R_list.append(.05)

        if 'imu3' in self.imus_observed_list:
            H_row = np.zeros([1, num_states])
            H_row[0, 3] = 1
            H_list.append(H_row)
            measurement_list.append(self.vb)
            R_list.append(4e-5)

        # BUILD H
        H = H_list[0]
        del H_list[0]
        for h_block in H_list:
            H = np.vstack((H, h_block))

        # BUILD MEASUREMENTS
        measurements = measurement_list[0]
        del measurement_list[0]
        for measurement in measurement_list:
            measurements = np.vstack((measurements, measurement))

        # BUILD R
        R = np.zeros([H.shape[0], H.shape[0]])
        r_index = 0  # element of diagonal to fill
        for r_elem in R_list:
            R[r_index, r_index] = r_elem
            r_index += 1

        # reset things
        self.imus_observed_list = []
        self.ekf.linear_measurement_update(measurements, H, R)

        # record imu measurements used to update kalman filter to write to a file

    def _update_with_landmarks(self):
        if len(self.ar_observed_list) == 0:
            return

        # CHECK ALL LANDMARKS
        for landmark_id in self.landmark_map.keys():
            if landmark_id in self.ar_observed_list:
                measurement = self.sensed_ar_diff[landmark_id]

                H = np.zeros([3, self.ekf.current_prob_estimate.shape[0]])
                H[:, 4:7] = np.eye(3)

                dist = np.linalg.norm(measurement[0:2])
                R = np.eye(3) * dist**3 * .1

                self.ekf.linear_measurement_update(measurement, H, R, True)
                #print measurement

        # reset things
        self.ar_observed_list = []
        self.sensed_ar_diff = {}

    def _publish_tf(self):
        # ROBOT TRANSFORM
        self.last_time = rospy.Time.now()
        state = copy.deepcopy(self.ekf.current_state_estimate)
        for landmark_id in self.landmark_map.keys():
            ar_obj = self.landmark_map[landmark_id]
            self.br.sendTransform((ar_obj.x, ar_obj.y, ar_obj.z),
                 tf.transformations.quaternion_from_euler(ar_obj.theta_x, ar_obj.theta_y, ar_obj.theta_z),\
                 self.last_time,\
                 "ar_marker_" + str(ar_obj.tag_num) + "_ref",\
                 "odom")

        self.br.sendTransform((state[4], state[5], 0),\
                 tf.transformations.quaternion_from_euler(0, 0, state[6]),\
                 self.last_time,\
                 "base_link",\
                 "odom")

        self.br.sendTransform(
            (0, 0, .1), tf.transformations.quaternion_from_euler(0, 0, 0),
            self.last_time, "laser", "base_link")
        self.br.sendTransform(
            (0, 0, 0), tf.transformations.quaternion_from_euler(0, 0, 0),
            self.last_time, "base", "base_link")
        return

    def _update_ekf(self):
        self.ekf.predict(self.control_voltages)
        self._update_with_imus()
        self._update_with_landmarks()

    def _print(self):
        """ Print info to the screen every once and a while """
        self.i += 1
        np.set_printoptions(precision=3, suppress=True)
        if self.i % 40 == 0:
            self.i = 0
            print self.ekf.current_state_estimate[4:7]

    def _write_to_file(self):
        state = copy.deepcopy(self.ekf.current_state_estimate)
        self.f.write(
            str(time.time() - self.t0) + ',' + str(state[0, 0]) + ',' +
            str(state[1, 0]) + ',' + str(state[2, 0]) + ',' +
            str(state[3, 0]) + ',' + str(state[4, 0]) + ',' +
            str(state[5, 0]) + ',' + str(state[6, 0]) + ',' +
            str(state[7, 0]) + ',' + str(self.write_imu_measurements[0]) +
            ',' + str(self.write_imu_measurements[1]) + ',' +
            str(self.write_imu_measurements[2]) + '\n')

    def spin(self):
        r = rospy.Rate(1 / self.dt)
        while not rospy.is_shutdown():
            self._publish_tf()
            self._update_ekf()
            self._print()
            self._publish_odom()
            self._write_to_file()

            self.control_voltages[0] = 0
            self.control_voltages[1] = 0
            r.sleep()
コード例 #59
0
                        type=float)
    parser.add_argument('--step', help='discretization step in meters '
                        '(default: 0.05)', default=0.05, type=float)
    parser.add_argument('--normalize', action='store_true', help='scale '
                        'computed likelihoods (see description)')
    args = parser.parse_args()
    args = parser.parse_args(rospy.myargv(sys.argv)[1:])

    marker_pub = rospy.Publisher('pose_likelihood', Marker)
    get_pose_likelihood = rospy.ServiceProxy('pose_likelihood_server/'
                                             'get_pose_likelihood',
                                             GetMultiplePoseLikelihood)

    rospy.sleep(1)
    time = tf_listener.getLatestCommonTime('odom', 'base_link')
    p, q = tf_listener.lookupTransform('odom', 'base_link', time)
    q = quaternion_from_euler(0, 0, euler_from_quaternion(q)[2] +
                              radians(args.yaw))

    def around(base, area, step):
        l = arange(base - step, base - area, -step)
        r = arange(base, base + area, step)
        return hstack([l, r])

    x_range = around(p[0], args.area, args.step)
    y_range = around(p[1], args.area, args.step)

    m = Marker()
    m.header.frame_id = 'odom'
    m.type = Marker.CUBE_LIST
    m.action = Marker.ADD
コード例 #60
0
ファイル: RobotGame.py プロジェクト: mbfeci/RoboticLearning
class RobotGame():
    def __init__(self):
        rospy.init_node("robotGame")

        self.joint_names = [
            'panda_joint1', 'panda_joint2', 'panda_joint3', 'panda_joint4',
            'panda_joint5', 'panda_joint6', 'panda_joint7'
        ]
        self.his_joint_values = [
            -2.5450077537365753e-08, 2.544688075917041e-08,
            2.3532384855862176e-05, 7.785478886557229e-05,
            -2.0168301624323703e-06, -8.301148533007563e-07,
            -2.2624831839124226e-06
        ]
        self.my_joint_values = self.his_joint_values

        self.arm_joint_upper_limits = np.array(
            [2.8973, 1.7628, 2.8973, 0.0175, 2.8973, 3.7525, 2.8973])
        self.arm_joint_bottom_limits = np.array(
            [-2.8973, -1.7628, -2.8973, -3.0718, -2.8973, -0.0175, -2.8973])
        self.arm_joint_diff = self.arm_joint_upper_limits - self.arm_joint_bottom_limits

        #OPTION 1:

        self.observation_bound = np.array([100] * 13)
        self.action_bound2 = np.array([0.1] * 7)
        self.action_space = spaces.Box(low=-self.action_bound2,
                                       high=self.action_bound2)
        self.observation_space = spaces.Box(low=-self.observation_bound,
                                            high=self.observation_bound)

        #OPTION 2:

        # self.observation_bound = np.array([5]*6)
        # self.action_bound = np.array([0.05]*3)
        # self.action_space = spaces.Box(low=-self.action_bound, high=self.action_bound)
        # self.observation_space = spaces.Box(low=-self.observation_bound, high=self.observation_bound )

        self.action_bound = [(-self.action_bound2).tolist(),
                             self.action_bound2.tolist()]
        self.action_dim = self.action_space.shape[0]
        self.state_dim = self.observation_space.shape[0]
        self.gamma = 1
        self.one_joint_execution_duration = 0.01
        self.execution_time = [(x + 1) * self.one_joint_execution_duration
                               for x in range(7)]

        self.dist_threshold = 0.1
        self.vector_from_center = np.array([0, 0, 0.05])
        self.object_moved_threshold = 0.05

        self.tf = TransformListener()
        self.sub = rospy.Subscriber('/joint_states', JointState, self.jsCB)
        self.box = Box()
        self.manipulator = Manipulator()
        #self.reset()

    def jsCB(self, msg):
        temp_dict = dict(zip(msg.name, msg.position))
        self.his_joint_values = [temp_dict[x] for x in self.joint_names]

    def isInMotion(self):
        for k in range(7):
            val1 = self.my_joint_values[k]
            val2 = self.his_joint_values[k]
            if val1 - val2 > 1.0e-1 or val1 - val2 < -1.0e-1:
                return True
        return False

    def getGripperPose3(self, reference):
        self.tf.waitForTransform(reference, "/panda_leftfinger", rospy.Time(),
                                 rospy.Duration(10))
        t = self.tf.getLatestCommonTime(reference, "/panda_leftfinger")
        position, quaternion = self.tf.lookupTransform(reference,
                                                       "/panda_leftfinger", t)
        return np.array([position[0], position[1], position[2]])

    def getGripperPose2(self):
        pos = self.manipulator.arm.get_current_pose()
        return pos  #np.array([pos.position.x, pos.position.y, pos.position.z])

    def getGripperPose(self, reference):
        self.tf.waitForTransform(reference, "/panda_hand", rospy.Time(),
                                 rospy.Duration(10))
        t = self.tf.getLatestCommonTime(reference, "/panda_hand")
        position, quaternion = self.tf.lookupTransform(reference,
                                                       "/panda_hand", t)
        return np.array([position[0], position[1], position[2]])

    def getRequiredJoints(self, delta):
        pos = self.manipulator.arm.get_current_pose()
        #gripperPos = self.getGripperPose('/panda_link0')
        pos.position.x += delta[0]
        pos.position.y += delta[1]
        pos.position.z += delta[2]
        #pos.orientation = None
        print "IK SOLUTION OF: ", pos
        return self.manipulator.arm.get_IK(pos)

    def getDist(self):
        currentPos = self.getGripperPose('/world')
        pos = self.box.get_position()
        self.destPos = np.array(
            [pos.position.x, pos.position.y, pos.position.z])  #0.05??

        #TODO: CHECK!!!
        #print "box pos (GAZEBO INTERFACE): ", self.destPos
        # self.tf.waitForTransform('/world',"box",rospy.Time(),rospy.Duration(10))
        # t = self.tf.getLatestCommonTime('/world', "box")
        # position, quaternion = self.tf.lookupTransform('/world',"box",t)
        # print "box pos (TF): ", position

        return np.linalg.norm(currentPos - self.destPos -
                              self.vector_from_center)

    def reset(self):
        self.my_joint_values = self.random_joint_initialize()
        self.manipulator.arm.execute_trajectory(
            [self.my_joint_values], [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7])
        self.waitTillReady2()
        pos = Pose()
        pos.position.x = uniform(0.15, 0.4)
        pos.position.y = uniform(-0.3, 0)
        pos.position.z = 0.8
        self.box.set_position(pos)
        self.box.place_on_table()
        rospy.sleep(1)
        pos = self.box.get_position()
        self.startDestPos = np.array(
            [pos.position.x, pos.position.y, pos.position.z])
        self.destPos = np.array(
            [pos.position.x, pos.position.y, pos.position.z])
        #OPTION 1:
        return np.concatenate(
            (self.my_joint_values, self.getGripperPose('world'), self.destPos))

        #OPTION 2:
        #return np.concatenate((self.getGripperPose2(), self.destPos))

    def random_joint_initialize(self):
        return np.random.uniform(self.arm_joint_bottom_limits,
                                 self.arm_joint_upper_limits, 7).tolist()

    def waitTillReady1(self):
        state = self.manipulator.arm.client.get_state()
        print state
        while not state == GoalStatus.SUCCEEDED:
            rospy.sleep(0.01)
            state = self.manipulator.arm.client.get_state()
            if state == GoalStatus.ABORTED:
                self.manipulator.arm.execute_trajectory([self.my_joint_values],
                                                        self.execution_time)
                rospy.sleep(0.01)
                state = self.manipulator.arm.client.get_state()
            print state

    def waitTillReady2(self):
        for k in range(300):
            if not self.isInMotion(): return
            rospy.sleep(0.01)
        print "SOMETHING IS WRONG, STOPPED WAITING AFTER 3 SECS!"
        # while self.isInMotion():
        #     rospy.sleep(0.01)

    def waitTillReady3(self):
        while not self.manipulator.arm.client.wait_for_result():
            rospy.sleep(0.01)
            print self.manipulator.arm.client.wait_for_result()

    def step(self, delta):
        done = False
        prevDist = self.getDist()

        #OPTION 1:
        joint_values = np.clip(self.my_joint_values + delta,
                               self.arm_joint_bottom_limits,
                               self.arm_joint_upper_limits)

        #OPTION 2:
        # joint_values = self.getRequiredJoints(delta)
        # print "IS: ", joint_values

        #OPTION 3:
        #Just go to the object XD
        # stamped_pos = PoseStamped()
        # pos = self.box.get_position()
        # pos.position.z += 0.2
        # pos.orientation = self.getGripperPose2().orientation
        # stamped_pos.pose = pos
        # stamped_pos.header.frame_id = '/world'
        # print stamped_pos
        # pos = self.tf.transformPose("/panda_link0", stamped_pos)
        # print pos

        #joint_values = self.manipulator.arm.get_IK(pos.pose)
        #print joint_values

        # if joint_values is None:
        #     print "Gripper position is out of bounds, penalty -10"
        #     return np.concatenate((self.getGripperPose('/world'), self.destPos)), -10, done, None

        self.my_joint_values = joint_values
        self.manipulator.arm.execute_trajectory([self.my_joint_values],
                                                self.execution_time)

        #OPTION 3 - Continued
        #Burayi sonra sil
        # self.waitTillReady2()
        # pos.pose.position.z -= 0.15
        # joint_values = self.manipulator.arm.get_IK(pos.pose)
        # self.my_joint_values = joint_values
        # self.manipulator.arm.execute_trajectory([self.my_joint_values], self.execution_time)

        self.waitTillReady2()

        curDist = self.getDist()
        reward = -(curDist * curDist + 0.5 * (prevDist - curDist) *
                   (prevDist - curDist))

        #reward = prevDist - curDist
        #print "CURRENT DISTANCE: ", curDist
        #print "Dest pos: ", self.destPos
        info = False
        if curDist <= self.dist_threshold:
            reward += 100
            done = True
            info = True
        elif self.destPos[2] < 0.3:
            print "OBJECT FELL OFF THE GROUND! PENALTY: -10"
            reward -= 10
            done = True
            info = False
        elif np.linalg.norm(self.destPos -
                            self.startDestPos) >= self.object_moved_threshold:
            #print "OBJECT IS MOVED! PENALTY: -20"
            reward -= 10  #TODO: give penalty instead of reward ?
            done = True
            info = False

        #OPTION 1:
        return np.concatenate(
            (self.my_joint_values, self.getGripperPose('world'),
             self.destPos)), reward, done, info

        #OOTION 2:
        #return np.concatenate((self.getGripperPose2(), self.destPos)), reward, done, None

    def done(self):
        self.sub.unregister()
        rospy.signal_shutdown("done")