Ejemplo n.º 1
0
    def __init__(self):
        self.arrive = 0.1
        self.x = 0.0
        self.y = 0.0
        self.yaw = 0.0
        self.vx = 0.0
        self.vw = 0.0
        # init plan_config for once
        self.dwa = DWAPlanner()
        self.threshold = self.dwa.max_v_speed * self.dwa.predict_time
        self.thres = 0.3

        self.laser_lock = Lock()
        self.lock = Lock()
        self.path = Path()

        self.tf = tf.TransformListener()
        self.path_sub = rospy.Subscriber('/course_agv/global_path', Path,
                                         self.pathCallback)
        self.vel_pub = rospy.Publisher('/webService/cmd_vel',
                                       Twist,
                                       queue_size=1)
        self.midpose_pub = rospy.Publisher('/course_agv/mid_goal',
                                           PoseStamped,
                                           queue_size=1)
        self.laser_sub = rospy.Subscriber('/scan_emma_nav_front', LaserScan,
                                          self.laserCallback)
        self.planner_thread = None

        self.count = 0
        pass
    def __init__(self):
        self.arrive = 0.2  # standard for arrival self.arrive = 0.1
        self.x = 0.0
        self.y = 0.0
        self.yaw = 0.0
        self.vx = 0.0
        self.vw = 0.0
        # init plan_config for once
        self.dwa = DWAPlanner()
        # self.max_speed = 0.8  # [m/s]
        # self.predict_time = 2  # [s]
        # self.threshold = self.max_speed * self.predict_time
        self.threshold = 1.5

        self.laser_lock = Lock()
        self.lock = Lock()
        self.path = Path()
        self.tf = tf.TransformListener()
        # get path & initPlaning
        self.path_sub = rospy.Subscriber('/course_agv/global_path', Path,
                                         self.pathCallback)

        self.vel_pub = rospy.Publisher('/webService/cmd_vel',
                                       Twist,
                                       queue_size=1)
        # self.vel_pub = rospy.Publisher('/course_agv/velocity',
        #                                Twist,
        #                                queue_size=1)

        # mid_goal pub
        self.midpose_pub = rospy.Publisher('/course_agv/mid_goal',
                                           PoseStamped,
                                           queue_size=1)

        # get laser & update obstacle
        # self.laser_sub = rospy.Subscriber('/scan_emma_nav_front', LaserScan,
        #                                   self.laserCallback)
        self.laser_sub = rospy.Subscriber('/course_agv/laser/scan', LaserScan,
                                          self.laserCallback)
        self.planner_thread = None
        self.listener = keyboard.Listener(on_press=self.on_press)
class LocalPlanner:
    def __init__(self):
        self.arrive = 0.2  # standard for arrival self.arrive = 0.1
        self.x = 0.0
        self.y = 0.0
        self.yaw = 0.0
        self.vx = 0.0
        self.vw = 0.0
        # init plan_config for once
        self.dwa = DWAPlanner()
        # self.max_speed = 0.8  # [m/s]
        # self.predict_time = 2  # [s]
        # self.threshold = self.max_speed * self.predict_time
        self.threshold = 1.5

        self.laser_lock = Lock()
        self.lock = Lock()
        self.path = Path()
        self.tf = tf.TransformListener()
        # get path & initPlaning
        self.path_sub = rospy.Subscriber('/course_agv/global_path', Path,
                                         self.pathCallback)

        self.vel_pub = rospy.Publisher('/webService/cmd_vel',
                                       Twist,
                                       queue_size=1)
        # self.vel_pub = rospy.Publisher('/course_agv/velocity',
        #                                Twist,
        #                                queue_size=1)

        # mid_goal pub
        self.midpose_pub = rospy.Publisher('/course_agv/mid_goal',
                                           PoseStamped,
                                           queue_size=1)

        # get laser & update obstacle
        # self.laser_sub = rospy.Subscriber('/scan_emma_nav_front', LaserScan,
        #                                   self.laserCallback)
        self.laser_sub = rospy.Subscriber('/course_agv/laser/scan', LaserScan,
                                          self.laserCallback)
        self.planner_thread = None
        self.listener = keyboard.Listener(on_press=self.on_press)
        # self.listener.start()

    def on_press(self, key):

        if key == keyboard.Key.up:
            self.vx = 1.0
            self.vw = 0.0
        elif key == keyboard.Key.down:
            self.vx = -1.0
            self.vw = 0.0
        elif key == keyboard.Key.left:
            self.vx = 0.0
            self.vw = 1.0
        elif key == keyboard.Key.right:
            self.vx = 0.0
            self.vw = -1.0
        print("v, w: ", self.vx, self.vw)
        self.publishVel(zero=False)

    # update pose & update goal
    # self.plan_goal (in the robot frame)
    # self.goal_dis  (distance from the final goal)
    def updateGlobalPose(self):
        try:
            self.tf.waitForTransform("/map", "/base_footprint", rospy.Time(),
                                     rospy.Duration(4.0))
            (self.trans,
             self.rot) = self.tf.lookupTransform('/map', '/base_footprint',
                                                 rospy.Time(0))
        except (tf.LookupException, tf.ConnectivityException,
                tf.ExtrapolationException):
            print("get tf error!")
        euler = tf.transformations.euler_from_quaternion(self.rot)
        roll, pitch, yaw = euler[0], euler[1], euler[2]
        self.x = self.trans[0]
        self.y = self.trans[1]
        self.yaw = yaw
        # get nearest path node
        ind = self.goal_index
        self.goal_index = len(self.path.poses) - 1
        while ind < len(self.path.poses):
            p = self.path.poses[ind].pose.position
            dis = math.hypot(p.x - self.x, p.y - self.y)
            # print('mdgb;; ',len(self.path.poses),ind,dis)
            if dis < self.threshold:
                self.goal_index = ind
            ind += 1
        goal = self.path.poses[self.goal_index]
        self.midpose_pub.publish(goal)
        # lgoal = self.tf.transformPose("/base_footprint", goal)
        lgoal = self.tf.transformPose("/base_footprint", goal)
        self.plan_goal = np.array(
            [lgoal.pose.position.x, lgoal.pose.position.y])
        self.goal_dis = math.hypot(
            self.x - self.path.poses[-1].pose.position.x,
            self.y - self.path.poses[-1].pose.position.y)

    # get obstacle (in robot frame)
    def laserCallback(self, msg):
        # print("get laser msg!!!!",msg)
        self.laser_lock.acquire()
        # preprocess
        # print("i am here!")
        self.ob = [[100, 100]]
        angle_min = msg.angle_min
        angle_increment = msg.angle_increment
        for i in range(len(msg.ranges)):
            a = angle_min + angle_increment * i
            r = msg.ranges[i]
            if r < self.threshold:
                self.ob.append([math.cos(a) * r, math.sin(a) * r])
        self.laser_lock.release()

    # update ob
    def updateObstacle(self):
        self.laser_lock.acquire()
        self.plan_ob = []
        self.plan_ob = np.array(self.ob)
        self.laser_lock.release()

    # get path & initPlaning
    def pathCallback(self, msg):
        # print("get path msg!!!!!",msg)
        self.path = msg
        self.lock.acquire()
        self.initPlanning()
        self.lock.release()
        # if self.planner_thread == None:
        #     self.planner_thread = Thread(target=self.planThreadFunc)
        #     self.planner_thread.start()
        # pass
        self.planThreadFunc()

    def initPlanning(self):
        self.goal_index = 0
        self.vx = 0.0
        self.vw = 0.0
        self.dis = 99999
        self.updateGlobalPose()
        cx = []
        cy = []
        for pose in self.path.poses:
            cx.append(pose.pose.position.x)
            cy.append(pose.pose.position.y)
        # self.goal = np.array([cx[0], cy[0]])
        self.plan_cx, self.plan_cy = np.array(cx), np.array(cy)
        self.plan_goal = np.array([cx[-1], cy[-1]])
        #self.plan_x = np.array([self.x, self.y, self.yaw, self.vx, self.vw])
        self.plan_x = np.array([0.0, 0.0, 0.0, self.vx, self.vw])

    def planThreadFunc(self):
        print("running planning thread!!")
        while True:
            self.lock.acquire()
            self.planOnce()
            self.lock.release()
            if self.goal_dis < self.arrive:
                print("arrive goal!")
                print(self.goal_dis)
                print(self.arrive)
                break
            time.sleep(0.001)
        print("exit planning thread!!")
        self.lock.acquire()
        self.publishVel(True)
        self.lock.release()
        # self.planning_thread = None
        pass

    def planOnce(self):
        self.updateGlobalPose()
        # Update plan_x [x(m), y(m), yaw(rad), v(m/s), omega(rad/s)]
        #self.plan_x = [self.x,self.y,self.yaw, self.vx, self.vw]
        self.plan_x = np.array([0.0, 0.0, 0.0, self.vx, self.vw])
        # Update obstacle
        self.updateObstacle()
        u = self.dwa.plan(self.plan_x, self.plan_goal, self.plan_ob)
        # alpha = 0.5
        # self.vx = u[0] * alpha + self.vx * (1 - alpha)
        # self.vw = u[1] * alpha + self.vw * (1 - alpha)
        self.vx = u[0]
        self.vw = u[1]
        print("v, w: ", self.vx, self.vw)
        # self.vx, self.vw = 0, 0
        # print("mdbg; ",u)
        self.publishVel(zero=False)
        pass

    # send v,w
    def publishVel(self, zero=False):
        if zero:
            self.vx = 0
            self.vw = 0
        cmd = Twist()
        cmd.linear.x = self.vx
        cmd.angular.z = self.vw
        self.vel_pub.publish(cmd)
Ejemplo n.º 4
0
class LocalPlanner:
    def __init__(self):
        self.arrive = 0.1
        self.x = 0.0
        self.y = 0.0
        self.yaw = 0.0
        self.vx = 0.0
        self.vw = 0.0
        # init plan_config for once
        self.dwa = DWAPlanner()
        self.threshold = self.dwa.max_v_speed * self.dwa.predict_time
        self.thres = 0.3

        self.laser_lock = Lock()
        self.lock = Lock()
        self.path = Path()

        self.tf = tf.TransformListener()
        self.path_sub = rospy.Subscriber('/course_agv/global_path', Path,
                                         self.pathCallback)
        self.vel_pub = rospy.Publisher('/webService/cmd_vel',
                                       Twist,
                                       queue_size=1)
        self.midpose_pub = rospy.Publisher('/course_agv/mid_goal',
                                           PoseStamped,
                                           queue_size=1)
        self.laser_sub = rospy.Subscriber('/scan_emma_nav_front', LaserScan,
                                          self.laserCallback)
        self.planner_thread = None

        self.count = 0
        pass

    def updateGlobalPose(self):
        try:
            self.tf.waitForTransform("/map", "/base_footprint", rospy.Time(),
                                     rospy.Duration(4.0))
            (self.trans,
             self.rot) = self.tf.lookupTransform('/map', '/base_footprint',
                                                 rospy.Time(0))
        except (tf.LookupException, tf.ConnectivityException,
                tf.ExtrapolationException):
            print("get tf error!")
        euler = tf.transformations.euler_from_quaternion(self.rot)
        roll, pitch, yaw = euler[0], euler[1], euler[2]
        self.x = self.trans[0]
        self.y = self.trans[1]
        self.yaw = yaw

    def laserCallback(self, msg):
        self.laser_lock.acquire()
        # preprocess
        self.ob = [[100, 100]]
        angle_min = msg.angle_min
        angle_increment = msg.angle_increment
        for i in range(len(msg.ranges)):
            a = angle_min + angle_increment * i
            r = msg.ranges[i]
            if r < 1.6 and r > 0.1:
                self.ob.append([math.cos(a) * r, math.sin(a) * r])
        self.laser_lock.release()
        pass

    def u2t(self, u):
        w = u[2]
        x = u[0]
        y = u[1]
        return np.array([[math.cos(w), -math.sin(w), x],
                         [math.sin(w), math.cos(w), y], [0, 0, 1]])

    def updateObstacle(self):
        self.laser_lock.acquire()
        self.plan_ob = []
        self.plan_ob = np.array(self.ob)

        #do transformation from robot coordinate to global coordinate
        trans = self.u2t([self.x, self.y, self.yaw])
        temp = np.ones([len(self.plan_ob), 1])
        self.plan_ob = np.concatenate((self.plan_ob, temp), axis=1)
        self.plan_ob = trans.dot(self.plan_ob.T)
        self.plan_ob = self.plan_ob.T
        self.plan_ob = self.plan_ob[:, 0:2]

        self.laser_lock.release()
        pass

    def pathCallback(self, msg):
        self.path = msg
        self.lock.acquire()
        self.initPlanning()
        self.lock.release()
        # if self.planner_thread == None:
        #     self.planner_thread = Thread(target=self.planThreadFunc)
        #     self.planner_thread.start()
        # pass
        self.planThreadFunc()

    def initPlanning(self):
        self.goal_index = 0
        self.vx = 0.0
        self.vw = 0.0
        self.dis = 99999
        self.updateGlobalPose()
        cx = []
        cy = []
        for pose in self.path.poses:
            cx.append(pose.pose.position.x)
            cy.append(pose.pose.position.y)
        self.goal = np.array([cx[0], cy[0]])
        self.plan_cx, self.plan_cy = np.array(cx), np.array(cy)
        self.destination = np.array([cx[-1], cy[-1]])
        self.plan_goal = np.array([cx[-1], cy[-1]])
        self.plan_x = np.array([0.0, 0.0, 0.0, self.vx, self.vw])
        pass

    def planThreadFunc(self):
        print("running planning thread!!")
        i = 0
        for pose in self.path.poses:
            if i == 0:
                i = 1
                continue
            else:
                self.goal_node = np.array(
                    [pose.pose.position.x, pose.pose.position.y])

                goal = pose
                self.midpose_pub.publish(goal)
                self.goal_node = np.array(
                    [goal.pose.position.x, goal.pose.position.y])
                while True:
                    self.lock.acquire()
                    # start = time.time()
                    # self.planOnce()
                    end = time.time()
                    # print('this plan time cost:', end-start)
                    self.lock.release()
                    self.updateGlobalPose()
                    self.goal_dis = math.hypot(self.x - pose.pose.position.x,
                                               self.y - pose.pose.position.y)
                    print('goal_dis:', self.goal_dis)
                    if i == len(self.path.poses) - 1:
                        threshold = 0.3
                    else:
                        threshold = 0.4
                    if self.goal_dis < 0.4:
                        print("arrive one goal node!")
                    time.sleep(0.001)
                self.lock.acquire()
                self.publishVel(True)
                self.lock.release()
                self.planning_thread = None
            i += 1

        self.publishVel(True)
        print('at goal!')

    def planOnce(self):
        self.updateGlobalPose()
        # Update plan_x [x(m), y(m), yaw(rad), v(m/s), omega(rad/s)]
        self.plan_x = [self.x, self.y, self.yaw, self.vx, self.vw]
        # Update obstacle
        self.updateObstacle()
        u = self.dwa.plan(self.plan_x, self.goal_node, self.plan_ob)
        alpha = 0.5
        self.vx = u[0] * alpha + self.vx * (1 - alpha)
        self.vw = u[1] * alpha + self.vw * (1 - alpha)
        print("v, w: ", self.vx, self.vw)
        # print("mdbg; ",u)
        self.publishVel()
        pass

    def publishVel(self, zero=False):
        if zero:
            self.vx = 0
            self.vw = 0
        cmd = Twist()
        cmd.linear.x = self.vx
        cmd.angular.z = self.vw
        self.vel_pub.publish(cmd)