Esempio n. 1
0
def main():
    rospy.init_node("line_follower")  #initialize ros node
    print("starting line follower")
    rate = rospy.Rate(30)

    # Instantiating classes
    fetcher = LineDataFetcher()  # fetches line data
    publisher = VESCPublisher()  # publishes control command to VESC
    line_follower = LineFollower(
    )  # passed line data thru PID controller to generate the control signal
    heading_ctrl = PID_ctrl(Kp = heading_ctrl_Kp, Ki = 0., Kd = 0., \
          i_max = 0., i_min = 0., \
          ctrl_max = heading_ctrl_ctrl_max, ctrl_min = heading_ctrl_ctrl_min) # control based on line angle
    lateral_ctrl = PID_ctrl(Kp = lateral_ctrl_Kp, Ki = lateral_ctrl_Ki, Kd = lateral_ctrl_Kd, \
          i_max = lateral_ctrl_i_max, i_min = lateral_ctrl_i_min, \
          ctrl_max = lateral_ctrl_ctrl_max, ctrl_min = lateral_ctrl_ctrl_min) # control based on lateral offset

    # Initializations
    timestamp = time.time()
    heading_ctrl.t_prev = timestamp
    heading_ctrl.t_curr = timestamp
    lateral_ctrl.t_prev = timestamp
    lateral_ctrl.t_curr = timestamp

    while not rospy.is_shutdown():
        timestamp = time.time()

        line_data = fetcher.get_linedata()  # fetch line data
        line_follower.import_linedata(
            line_data)  #, trav_dist) # import line data to line follower
        line_follower.calculate_ctrl(
            heading_ctrl, lateral_ctrl,
            timestamp)  # calculate the steering control
        line_follower.set_servo_control()

        motor, servo = line_follower.get_ECU_data()

        servo_reg = servo / 180 * pi
        servo_reg = min(max(servo_reg, -0.34), 0.34)
        motor_reg = min(max(motor, -2.0), 2.0)

        print("Servo", servo)
        print("Servo_reg", servo_reg)
        print("Motor", motor)
        print("Motor_reg", motor_reg)
        print("t", timestamp)

        ads_msg = ADS()
        ads_msg.header.seq += 1
        ads_msg.header.stamp.secs = timestamp
        ads_msg.drive.steering_angle = servo_reg
        ads_msg.drive.speed = motor_reg

        publisher.pub_vesc_msg(ads_msg)

        rate.sleep()
Esempio n. 2
0
 def __init__(self):
     self.VESC_msg = ADS()
     self.VESC_pub = rospy.Publisher(
         "/vesc/low_level/ackermann_cmd_mux/input/navigation",
         ADS,
         queue_size=1)
def main():
    rospy.init_node("HallNavwithObjDet")
    rate = rospy.Rate(40)
    servo = 0.
    motor = 0.
    
    control = PID_ctrl(Kp = Kp, Ki = Ki, Kd = Kd, \
                    i_max = i_max, i_min = i_min, \
                    ctrl_max = ctrl_max, ctrl_min = ctrl_min) # PID controller 
    fetcher = LidarFetcher() # gets lidar data
    publisher = VESCPublisher() # publishes control command to VESC                        
    timestamp = time.time()

    lidardata = fetcher.get_lidardata()
    while lidardata == []: # while lidar data has not been populated
        print("Waiting for Lidar data to populate")
        lidardata = fetcher.get_lidardata() # update lidardata
        
    # get lidar characteristics
    ang_min = lidardata.angle_min / pi * 180 # minimum lidar scan angle in degrees
    ang_max = lidardata.angle_max / pi * 180 # maximum lidar scan angle in degrees
    ang_step = lidardata.angle_increment / pi *180 # lidar angle increment
    
    zedfetcher = ZEDFetcher()
    detection = zedfetcher.get_zed_data()
    detectedtime = timestamp
    print("1")
    while not rospy.is_shutdown():
        print("1.5")
        timestamp = time.time()
        detection = zedfetcher.get_zed_data()
        detected = False
        if detection == []: # check if lidar data is populated
            continue
            
        for i in detection.bounding_boxes:
            if (i.Class in objects):
                print("DETECTED ", i.Class, "at ", timestamp)
                detected = True
                break
        print("2")
        ads_msg = ADS()
        lidardata = fetcher.get_lidardata() # get lidar data
        if lidardata == []: # check if lidar data is populated
            continue # if not populated --> skip to next iteration

        right_dist = lidardata.ranges[180] # extract right distance
        front_dist = lidardata.ranges[int(540 - col_ang*4):int(540 + col_ang*4 + 1)] # extract a range of front measurements 
        left_dist = lidardata.ranges[900] # extract left distance
        
        print('right', right_dist)
        print('front', front_dist[int(len(front_dist)/2)])
        print('left', left_dist)
        #print('all', type(lidardata.ranges))
        
        # check if any of the front distance measurements are below a certain threshold
        front_blocked = False  
        min_front = min(front_dist)     

        print('min_front', min_front)
        
        if min_front < front_thresh:
            front_blocked = True
            print("3")
        if min_front < abs_stop_thresh:
            #motor = 0
            if lidardata.ranges[540] < max_lidar_range:
                goBack(init_front_dist = lidardata.ranges[540], rev_dist= reverse_dist, rate = rate, \
                        ads_msg = ads_msg, fetcher = fetcher, publisher = publisher)
            print("Too close to obstacle ahead. Cannot move")
            
        elif (detected and (timestamp - detectedtime) > 11.0):
            print("Im not going to drive past the stop sign")
            detectedtime = timestamp
            print("DETECTED at ", timestamp)
            for i in range(stoptime):
                timestamp = time.time()
                ads_msg.header.seq+=1
                ads_msg.header.stamp.secs = timestamp
                ads_msg.drive.steering_angle = 0
                ads_msg.drive.speed = 0
                    
                publisher.pub_vesc_msg(ads_msg) # publish the message
                rate.sleep() # sleep until next iteration  

        elif (front_blocked): # check if front is blocked
            if(left_dist < left_thresh): # check if left is blocked
                if(right_dist < right_thresh): # check if right is blocked
                    # this is a deadend
                    motor = 0.
                    print("deadend")
                else:
                    # blocked ahead but opening on right side (hallway on right side)
                    # sharp right turn
                    motor = default_turn
                    servo = MAX_servo
                    print("rightturn")
            else:
                # blocked ahead but opening on left side (hallway on left side)
                # sharp left turn
                motor = default_turn
                servo = MIN_servo
                print("leftturn")
        else:
            if(left_dist < left_thresh): # check if there is a close wall/object to the left
                # nothing ahead + wall to left
                # regulate left distance through PID
                motor = default_forward
                servo = - control.apply_pid(des_value = PID_thresh, current_value = left_dist, timestamp = timestamp)
                print("PID control")
            else:
                # nothing ahead + opening to the left (hallway on left side)
                # sharp left turn
                motor = default_turn
                servo = MIN_servo
                print("leftturn")
        print("4")
        # populate the message to send to the ESC        
        ads_msg.header.seq+=1
        ads_msg.header.stamp.secs = timestamp
        ads_msg.drive.steering_angle = servo
        ads_msg.drive.speed = motor
        
        publisher.pub_vesc_msg(ads_msg) # publish the message
        rate.sleep() # sleep until next iteration