Exemple #1
0
class DriveForwardNode:
    def __init__(self):
        self.drive_publisher = rospy.Publisher(
            '/vesc/high_level/ackermann_cmd_mux/input/nav_0',
            AckermannDriveStamped,
            queue_size=10)
        self.odom_subscriber = rospy.Subscriber('/vesc/odom',
                                                Odometry,
                                                self.odom_callback,
                                                queue_size=10)

        self.drive_controller = PIDController(kP=1)
        self.steer_controller = PIDController(kP=0.01)
        self.drive_msg = AckermannDriveStamped()

    def odom_callback(self, msg):
        x = msg.pose.pose.position.x
        y = msg.pose.pose.position.y
        q = msg.pose.pose.orientation
        roll, pitch, yaw = tf.transformations.euler_from_quaternion(
            (q.x, q.y, q.z, q.w))
        #steer_output = self.steer_controller.output(yaw, 0)
        steer_output = -1
        drive_output = self.drive_controller.output(x, 0)
        print("Error: %s" % (x - 0))
        self.drive_msg.drive.steering_angle = steer_output
        self.drive_msg.drive.speed = drive_output
        self.drive_publisher.publish(self.drive_msg)
Exemple #2
0
class StateMachineNode:
    def __init__(self):
        rospy.init_node('state_machine')

        self.drive_publisher = rospy.Publisher(DRIVE_PUBLISHER_TOPIC,
                                               AckermannDriveStamped,
                                               queue_size=10)
        self.laser_subscriber = rospy.Subscriber(LASER_SUBSCRIBER_TOPIC,
                                                 LaserScan,
                                                 self.laser_callback,
                                                 queue_size=10)
        self.markers_subscriber = rospy.Subscriber(AR_TAG_SUBSCRIBER_TOPIC,
                                                   AlvarMarkers,
                                                   self.markers_callback,
                                                   queue_size=10)

        self.pf_controller = PotentialFieldController(gain=0.3)
        self.pid_controller = PIDController(kP=1.8)

        self.laser_data = []
        self.state = State.potential_field
        self.drive_msg = AckermannDriveStamped()
        self.drive_msg.drive.speed = 0.7
        self.goal_dist = 0.3

    def laser_callback(self, msg):
        self.laser_data = msg.ranges

    def markers_callback(self, msg):
        self.check_state(msg.markers)
        print("State: %s" % self.state)

        if self.state == State.potential_field:
            self.drive_msg.drive.steering_angle = self.pf_controller.output(
                self.laser_data)
        else:
            end = int(0.7 * len(self.laser_data))
            perpendicular_dist = 0.0

            if self.state == State.follow_left:
                perpendicular_dist = min(self.laser_data[end:])
            elif self.state == State.follow_right:
                perpendicular_dist = min(self.laser_data[:end])

            print("Dist: %s" % perpendicular_dist)
            print("Error: %s" % (perpendicular_dist - self.goal_dist))
            self.drive_msg.drive.steering_angle = -self.pid_controller.output(
                perpendicular_dist, self.goal_dist)
        self.drive_publisher.publish(self.drive_msg)

    def check_state(self, markers):
        ids = [m.id for m in markers]
        if 23 in ids:
            self.state = State.potential_field
        elif 18 in ids or 22 in ids:
            self.state = State.follow_left
        elif 19 in ids:
            self.state = State.follow_right
Exemple #3
0
class WallFollowerNode:
    def __init__(self):
        rospy.init_node(STATE_MACHINE_NODE_NAME)

        self.laser_subscriber = rospy.Subscriber('/scan',
                                                 LaserScan,
                                                 self.laser_callback,
                                                 queue_size=10)
        self.drive_publisher = rospy.Publisher(
            '/vesc/high_level/ackermann_cmd_mux/input/nav_0',
            AckermannDriveStamped,
            queue_size=10)

        self.steering_controller = PIDController(kP=1.2, kD=0)

        self.drive_msg = AckermannDriveStamped()
        self.cv_bridge = CvBridge()

        self.goal_distance = 0.8
        self.drive_speed = 1.2

    def laser_callback(self, msg):

        cur_dist = min(
            msg.ranges[int(0.4 * len(msg.ranges)):int(0.6 * len(msg.ranges))])
        front_dist = msg.ranges(len(msg.ranges) / 2)

        steering_output = self.steering_controller.output(
            cur_dist, self.goal_distance)

        if front_dist < 2.0:
            self.drive_speed = 0.7
        else:
            self.drive_speed = 1.2

        self.drive_msg.drive.steering_angle = output
        self.drive_msg.drive.speed = self.drive_speed
        print("Distance from wall: %s" % cur_dist)
        print("Error: %s" % (cur_dist - self.goal_distance))
        print("State: %s" % self.state)
        self.drive_publisher.publish(self.drive_msg)
Exemple #4
0
class Drive:
    def __init__(self):
        self.drive_publisher = rospy.Publisher(DRIVE_TOPIC,
                                               AckermannDriveStamped,
                                               queue_size=10)
        self.laser_subscriber = rospy.Subscriber(LASER_TOPIC,
                                                 LaserScan,
                                                 self.laser_callback,
                                                 queue_size=10)
        self.odom_subscriber = rospy.Subscriber(ODOM_TOPIC,
                                                Odometry,
                                                self.odom_callback,
                                                queue_size=10)

        self.middle_pid_controller = PIDController(kP=0.58)
        self.turn_pid_controller = PIDController(kP=0.92)
        self.angle_pid_controller = PIDController(kP=0.001)
        self.ptf_controller = PotentialFieldController(steer_gain=4.4,
                                                       speed_gain=1.0,
                                                       alpha=0.92,
                                                       mu=0.06)

        self.drive_msg = AckermannDriveStamped()
        self.laser_data = []
        self.pose = None

        self.is_referenced = False
        self.reference_dist = 0.0
        self.reference_angle = 0.0

        self.safety_min_dist = 0.25
        self.adjustment = 30

    def drive_safety(self):
        speed = -0.7
        angle = 0.0
        if self.safety_check:
            angle = -1.0
        else:
            angle = 1.0
        self.drive(angle, speed)

    def safety_check(self):
        return self.laser_data[300] > self.laser_data[780]

    def is_safe(self):
        front_dist = self.laser_data[len(self.laser_data) / 2]
        print("Front dist: %s " % front_dist)
        return front_dist > self.safety_min_dist

    def drive_middle(self, speed):
        left_dist, right_dist = self.get_dists()
        angle = -self.middle_pid_controller.output(left_dist - right_dist, 0)
        print("Error: %s" % (left_dist - right_dist))
        self.drive(angle, speed)

    def drive_left(self, goal_dist, speed):
        left_dist, _ = self.get_dists()
        angle = -self.turn_pid_controller.output(left_dist, goal_dist)
        print("Error: %s" % (goal_dist - left_dist))
        self.drive(angle, speed)

    def drive_right(self, goal_dist, speed):
        _, right_dist = self.get_dists()
        angle = self.turn_pid_controller.output(right_dist, goal_dist)
        print("Error: %s " % (goal_dist - right_dist))
        self.drive(angle, speed)

    def drive_potential(self, speed):
        #laser_scan = self.laser_data[int(0.1*len(self.laser_data)):int(0.9*len(self.laser_data))]
        angle, new_speed = self.ptf_controller.output(self.laser_data)
        print("Angle: %s " % angle + " Speed: %s" % new_speed)
        self.drive(-angle, speed)

    def drive_straight(self, speed, dist):
        if self.pose is not None:
            if not self.is_referenced:
                self.reference_dist = self.pose.x
                self.reference_angle = self.pose.angle
                self.is_referenced = True
                print("Referecenced")

            pos_error = self.pose.x - self.reference_dist
            print("Change in dist: %s " % pos_error)

            if abs(pos_error) < dist:
                angular_output = self.angle_pid_controller.output(
                    self.pose.angle, self.reference_angle)
                self.drive(angular_output, speed)
                return False

            self.is_referenced = False
            return True
        return False

    def drive(self, angle, speed):
        self.drive_msg.drive.speed = speed
        self.drive_msg.drive.steering_angle = angle
        print("Angle: %s " % angle + " Speed: %s" % speed)
        self.drive_publisher.publish(self.drive_msg)

    def get_dists(self):
        offset = len(self.laser_data) / 4
        adjustment = 0
        left_dist = min(self.laser_data[len(self.laser_data) -
                                        offset:len(self.laser_data) - offset +
                                        self.adjustment])
        right_dist = min(self.laser_data[offset:offset + self.adjustment])
        #left_dist = min(self.laser_data[int(0.5 * len(self.laser_data)):int(0.9 * len(self.laser_data))])
        #right_dist = min(self.laser_data[int(0.1 * len(self.laser_data)):int(0.5 * len(self.laser_data))])
        return left_dist, right_dist

    def laser_callback(self, msg):
        self.laser_data = msg.ranges

    def odom_callback(self, msg):
        p = msg.pose.pose.position
        q = msg.pose.pose.orientation
        x, y = p.x, p.y
        _, _, yaw = tf.transformations.euler_from_quaternion(
            (q.x, q.y, q.z, q.w))
        self.pose = Pose(x=x, y=y, angle=yaw)
Exemple #5
0
class StateMachineNode:
    def __init__(self):
        rospy.init_node(STATE_MACHINE_NODE_NAME)

        self.ar_subscriber = rospy.Subscriber('/ar_pose_marker',
                                              AlvarMarkers,
                                              self.ar_callback,
                                              queue_size=10)
        self.img_subscriber = rospy.Subscriber('/zed/rgb/image_rect_color',
                                               Image,
                                               self.img_callback,
                                               queue_size=10)
        self.laser_subscriber = rospy.Subscriber('/scan',
                                                 LaserScan,
                                                 self.laser_callback,
                                                 queue_size=10)
        self.drive_publisher = rospy.Publisher(
            '/vesc/high_level/ackermann_cmd_mux/input/nav_0',
            AckermannDriveStamped,
            queue_size=10)

        self.steering_controller = PIDController(kP=1.4, kD=0)

        self.drive_msg = AckermannDriveStamped()
        self.cv_bridge = CvBridge()

        self.goal_tag = -1
        self.goal_distance = 0.7
        self.drive_speed = 1.2
        self.ar_tag_threshold = 0.8

        self.is_found = False
        self.state = State.search_for_face

    def ar_callback(self, msg):
        if len(msg.markers) > 0:
            for tag in msg.markers:
                id = tag.id
                print("I see id %s" % id)
                if id == self.goal_tag and self.state == State.search_for_tag\
                        and tag.pose.pose.position.z < self.ar_tag_threshold:
                    self.state = State.found_tag
                    self.is_found = True
                elif self.is_found:
                    self.state = State.search_for_face
                    self.is_found = False
        elif self.is_found:
            self.state = State.search_for_face
            self.is_found = False

    def img_callback(self, msg):
        global faces_encodings

        img_cv = self.cv_bridge.imgmsg_to_cv2(msg, 'bgr8')
        rows, cols = img_cv.shape[0], img_cv.shape[1]
        #        img_left = img_cv[:, :int(0.9*cols)]
        img_left = img_cv

        # Collect results of face detection
        results = face_recognition.compare_faces(faces_encodings, img_left)

        distances = face_recognition.face_distance(faces_encodings, img_left)
        # Array containing the indices of found faces
        found_faces = [i for i in range(len(results)) if results[i] == True]
        print(results)
        #        if len(found_faces) > 0 and self.state == State.search_for_face:
        if len(found_faces) > 0:
            print("I see faces")
            # List of tuples containing the distance AND the found index
            found_distances = [(distances[found_faces[j]], j)
                               for j in range(len(found_faces))]
            min_area = float('inf')
            index = 0
            for area, i in found_distances:
                if area < min_area:
                    min_area = area
                    index = i
            self.goal_tag = index + 1
            self.state = State.found_face
        # If it no longer sees the face yet it's still in the found state
        elif (self.goal_tag -
              1) not in found_faces and self.state == State.found_face:
            self.state = State.search_for_tag

    def laser_callback(self, msg):

        output = 0.0
        cur_dist = min(
            msg.ranges[int(0.4 * len(msg.ranges)):int(0.85 * len(msg.ranges))])

        if cur_dist > 1.5:
            output = -1.0
        else:
            output = -self.steering_controller.output(cur_dist,
                                                      self.goal_distance)
        if self.state == State.search_for_face or self.state == State.found_tag:
            self.drive_speed = 1.2
        elif self.state == State.search_for_tag or self.state == State.found_face:
            self.drive_speed = -1.2

        self.drive_msg.drive.steering_angle = output
        self.drive_msg.drive.speed = self.drive_speed
        print("Distance from wall: %s" % cur_dist)
        print("Error: %s" % (cur_dist - self.goal_distance))
        print("State: %s" % self.state)
        self.drive_publisher.publish(self.drive_msg)
Exemple #6
0
class WallFollowerNode:

    def __init__(self):
        rospy.init_node('wall_follower')
        self.laser_subscriber = rospy.Subscriber('/scan', LaserScan,self.laser_callback, queue_size=10)
        self.drive_publisher = rospy.Publisher('/drive', AckermannDriveStamped, queue_size=10)
        #flag
        self.right = 0
        self.left = 0
        #inizializzo Pid
        self.steering_controller = PIDController(kP=1.2, kD=0.0)
        #creo messaggio
        self.drive_msg = AckermannDriveStamped()
        # self.scan = LaserScan()
        self.goal_distance = 1.2
        self.color=[]
        self.diffr= 0
   

 
    def laser_callback(self,msg):
        #fascio frontale
        cur_dist = min(msg.ranges[int(0.45*len(msg.ranges)):int(0.55*len(msg.ranges))])
        # laterale a -2.47  dx dietro
        side_dist_r1 = min(msg.ranges[int(0*len(msg.ranges)):int(0.01*len(msg.ranges))])
        #   dx  avanti
        side_dist_r2 = min(msg.ranges[int(0.33*len(msg.ranges)):int(0.34*len(msg.ranges))])  
        #  sx avanti
        side_dist_l1 = min(msg.ranges[int(0.65*len(msg.ranges)):int(0.8*len(msg.ranges))]) 
        # sx dietro
        side_dist_l2 = min(msg.ranges[int(0.8*len(msg.ranges)):int(len(msg.ranges))])
        # di fronte
        front_dist = msg.ranges[int(len(msg.ranges)/2)] 
        # angolo 0
        destra = msg.ranges[int(18)]

        #self.color = msg.intensities[int(len(msg.intensities)/2)]

        # color = min(ms[int(0.5*len(msg.ranges)):int(0.5*len(msg.ranges))])
        
        steering_output = self.steering_controller.output(cur_dist, self.goal_distance)

        if side_dist_r1 > 1.4:
         self.right = 0
         self.drive_msg.drive.steering_angle = 0
        if side_dist_l2 > 1.4:
         self.left = 0
         self.drive_msg.drive.steering_angle = 0
        if side_dist_r1 < 1.4:
         self.right = 1
        if side_dist_l2 < 1.4:
         self.left = 1
        
        # trova corridoio
        if destra > side_dist_r2:
         if destra > side_dist_r1:
             if destra > 3.5  and destra < 4:  
                 #gira a dx per 1 secondo                                              
                 self.turn()

        self.diffr = side_dist_r2-side_dist_r1 
        # procedi dritto muro lontano 
        if cur_dist > 1.4 :
         self.drive_msg.drive.speed = steering_output
         self.drive_msg.drive.steering_angle = 0
        #gira a dx
        if self.diffr > 0.1:
         self.drive_msg.drive.steering_angle = -1.2     
     
        
        # muro avanti gira a sx
        if cur_dist < 1.4 :          
         self.drive_msg.drive.steering_angle = +1.2
         self.drive_msg.drive.speed = 0.5      
        

         # muro a sinistra vicino gira a dx
         if side_dist_l2 < 1.4:
             self.drive_msg.drive.steering_angle = -1.2
             self.left = 1                         
       
  

   
        
        ###################  vari print   ################################


        #print("angle: %s" % self.steering_angle.output(self.laser_data))             
        #print("Distance from wall: %s" % front_dist)                
        #print("Colore: %s" % self.color)
        #print("LEFT: %s" % side_dist_l2)
        print("RIGHT1: %s" % side_dist_r1)
        print("destra: %s" % destra) 
        print("RIGHT2: %s" % side_dist_r2)
        print("ZERO: %s" % msg.ranges[int(0)])
        #print("diffr: %s" % self.diffr)
        #print("angle_increment: %s" % msg.angle_increment)        
        #print("min_angle: %s" % msg.angle_min)  



        ##################################################################



 

       
        #pubblica messaggio
        self.drive_publisher.publish(self.drive_msg)

    def turn (self):
        # gira a dx per 1 secondo        
        self.drive_msg.drive.steering_angle = -1.8
        self.drive_msg.drive.speed = 1
        self.drive_publisher.publish(self.drive_msg)
        rospy.sleep(1)
        cur_dist = min(msg.ranges[int(0.45*len(msg.ranges)):int(0.55*len(msg.ranges))])
        if cur_dist < 1:
          rospy.spin()
Exemple #7
0
class StateMachineNode:
    def __init__(self):
        rospy.init_node(STATE_MACHINE_NODE_NAME)

        self.drive_publisher = rospy.Publisher(
            '/vesc/high_level/ackermann_cmd_mux/input/nav_0',
            AckermannDriveStamped,
            queue_size=10)

        self.ar_subscriber = rospy.Subscriber('/ar_pose_marker',
                                              AlvarMarkers,
                                              self.ar_callback,
                                              queue_size=10)
        print "Ar subscriber created"
        self.img_subscriber = rospy.Subscriber('/zed/rgb/image_rect_color',
                                               Image,
                                               self.img_callback,
                                               queue_size=10)
        print "Img subscriber created"
        self.laser_subscriber = rospy.Subscriber('/scan',
                                                 LaserScan,
                                                 self.laser_callback,
                                                 queue_size=10)
        #      print "Laser subscriber created"
        #       self.drive_publisher = rospy.Publisher('/vesc/high_level/ackermann_cmd_mux/input/nav_0', AckermannDriveStamped,
        #                                               queue_size=10)
        print "Drive publisher created"

        self.steering_controller = PIDController(kP=0.1)

        self.drive_msg = AckermannDriveStamped()
        self.cv_bridge = CvBridge()

        self.goal_tag = -1
        self.goal_distance = 0.7
        self.drive_speed = 0.7
        self.ar_tag_threshold = 0.8

        self.state = State.search_face

        self.haar = cv2.CascadeClassifier(
            './haarcascade_frontalface_default.xml')

    def ar_callback(self, msg):
        if len(msg.markers) > 0:
            if self.goal_tag in msg.markers and self.state == State.search_tag:
                tagdata = [x for x in msg.markers if x.id == self.goal_tag][0]
                if tagdata.pose.pose.position < self.ar_tag_threshold: return
                self.state = State.approach_tag
                self.drive_speed = 0.7
            elif self.goal_tag not in msg.markers and self.state == State.approach_tag:
                self.state = State.search_face

    def img_callback(self, msg):
        global faces_encodings

        img_cv = self.cv_bridge.imgmsg_to_cv2(msg, 'bgr8')
        rows, cols = img_cv.shape[0], img_cv.shape[1]
        # Find face in image
        faces = self.haar.detectMultiScale(img_cv,
                                           scaleFactor=1.1,
                                           minNeighbors=5)
        if self.state == State.search_face:
            for x, y, w, h in faces:
                # Get encoding
                encoding = face_recognition.face_encodings(
                    img_cv[x:x + w + 1:, y:y + h + 1:, :],
                    known_face_locations=None)
                # Compare the encoding to the list of faces
                results = face_recognition.api.compare_faces(
                    faces_encodings, encoding)
                if any(results):
                    self.goal_tag = min(
                        [i for i in range(len(results)) if results[i] == True])
                    self.state = State._face
        elif self.state == State.approach_face and len(faces) == 0:
            self.state = State.search_tag
            self.drive_speed = -0.7

    def laser_callback(self, msg):
        # If it's searching for a face or a tag, stay away from walls
        if self.state == State.search_face or self.state == State.search_tag:
            self.goal_distance = 0.7
        # If it's found something, approach it
        elif self.state == State.approach_face or self.state == State.approach_tag:
            self.goal_distance = 0.2

        cur_dist = min(msg.ranges[int(0.5 * len(msg.ranges)):])
        output = self.steering_controller.output(cur_dist, self.goal_distance)

        self.drive_msg.drive.steering_angle = output
        self.drive_msg.drive.speed = self.drive_speed

        self.drive_publisher.publish(self.drive_msg)