예제 #1
0
 def run_single_trajectory(self, trajectory):  # 运行单个trajectory
     if trajectory.posture == FlyPosture.hovering:
         return
     commander = DuplicablePositionHlCommander(self._cf)
     commander.take_off()
     current_point = 0
     while True:
         point = trajectory.get_next_point()
         if point is not None:
             current_point = point  # 不是最后一个点的话赋值
             self._status.current_end_point = trajectory.get_current_end_point()  # 更新当前终点
             if self._status.current_posture == 'avoiding':
                 time.sleep(0.3)  # 避障的时候更新点的速度减慢
                 continue
             elif CFFlyTask._switch_pair_list['formation'][0] == self._cf.link_uri:  # 是否为交换无人机
                 self.formation_fly_to_charge(
                     self._status.current_position, CFFlyTask._switch_pair_list['charging'][1])
                 with self._status_lock:
                     self._status.current_posture = FlyPosture.charging
                 return
             else:
                 commander.go_to(current_point[0],current_point[1],current_point[2])
                 time.sleep(0.1)
         else:
             while CFFlyTask.not_close_enough(self._status, current_point):  # 有可能避障完成之后已经便利到终点,但是偏离实际位置,所以还是要修正的,修正过程中也会有避障可能
                 if self._status.current_posture == 'avoiding':
                     time.sleep(0.1)
                     continue
                 elif CFFlyTask._switch_pair_list['formation'][0] == self._cf.link_uri:
                     self.formation_fly_to_charge(
                         self._status.current_position, CFFlyTask._switch_pair_list['charging'][1])
                     with self._status_lock:
                         self._status.current_posture = FlyPosture.charging
                     return
                 else:
                     commander.go_to(current_point[0],current_point[1],current_point[2])
                     time.sleep(0.1)
             return
예제 #2
0
 def run(self):
     self._need_take_off = True
     while self._trajectory_index < len(self._trajectory_list) and not CFFlyTask.emergency_shutdown :
         if self._status.current_posture == FlyPosture.charging:
             return
         trajectory = self._trajectory_list[self._trajectory_index]
         if not trajectory.is_over():
             print('about to run single trajectory')
             self.run_single_trajectory(trajectory)
         if CFFlyTask.emergency_shutdown:
             break
         if self._status.current_posture == FlyPosture.charging:
             return
         with CFFlyTask._sync_number_lock:  # 完成一段的飞行序列,进入悬停等待状态
             with self._status_lock:
                 self._status.current_posture = FlyPosture.hovering
             CFFlyTask._sync_number += 1
         while CFFlyTask._sync_number % CFFlyTask._formation_number != 0:  # 在悬停等待的时候可能发生避障或者无人机更换
             time.sleep(0.1)
             if CFFlyTask.emergency_shutdown:
                 break
             if self._status.current_posture == FlyPosture.avoiding_hovering:
                 time.sleep(0.2)
                 continue
             elif CFFlyTask._switch_pair_list['formation'][0] == self._cf.link_uri:
                 self.formation_fly_to_charge(
                     self._status.current_position, CFFlyTask._switch_pair_list['charging'][1])
                 with self._status_lock:
                     self._status.current_posture = FlyPosture.charging
                 return
         self._trajectory_index += 1
         with self._status_lock:
             self._status.current_posture = FlyPosture.flying
     commander = DuplicablePositionHlCommander(self._cf)  # 飞行完所有序列之后,停掉无人机,eventually_land会修改状态为over,用于将无人机线程停掉。
     commander.set_cf_status(self._status)
     commander.eventually_land()
예제 #3
0
    def switch_to_charge(formation_cf, charging_cf, status_list):
        # 获取两个uri的scf
        formation_cf_uri = formation_cf.link_uri
        charging_cf_uri = charging_cf.link_uri
        charging_cf_position = []  # 充电中的无人机位置 注:下文所有注释都用‘charging_cf’表示这一架无人机
        const_charging_cf_position = []
        formation_cf_position = []  # 编队中的无人机位置 注:下文所有注释都用‘formation_cf’表示这一架无人机
        const_formation_cf_position = []
        min_x_distance = 0.15  # 当前无人机和队列中其他x轴上的最小距离
        min_y_distance = 0.15
        min_z_distance = 0.15
        min_xy_distance = math.sqrt(min_x_distance ** 2 + min_y_distance ** 2)  # 当前无人机和队伍中其他无人机在xy平面上的最小距离
        current_z_distance = 0
        current_xy_distance = 0
        print('all variable initialize')
        print('inswitch', status_list)
        for j in range(len(status_list)):
            print('at the start of changing')
            print(status_list[j].current_position)
            print(status_list[j].uri)
            print(status_list[j].current_battery)
        # 根据uri获取'charging_cf'的位置
        for sts in status_list:
            if charging_cf_uri == sts.uri:
                charging_cf_position = sts.current_position  # 建立引用
                const_charging_cf_position = copy.copy(sts.current_position)  # 按值传递

        # 根据uri获取'formation_cf'无人机位置
        for sts in status_list:
            if formation_cf_uri == sts.uri:
                formation_cf_position = sts.current_position
                const_formation_cf_position = copy.copy(sts.current_position)

        # 注册Status list
        DuplicablePositionHlCommander.set_class_status_list(status_list)

        # 初始化formation_hl_commander
        formation_hl_commander = DuplicablePositionHlCommander(formation_cf, formation_cf_position[0],
                                                               formation_cf_position[1], formation_cf_position[2], 0.3,
                                                               formation_cf_position[2],
                                                               controller=DuplicablePositionHlCommander.CONTROLLER_MELLINGER)
        print(formation_cf_uri, 'formation_hl_commander create')
        print(formation_cf_uri, 'formation start changing xy position')
        # 1.1记录formation_cf和队列中任意一架飞机在xy平面方向的距离
        # 扫描所有飞行中x负半轴方向的飞机,如果x轴的距离太近,判断y轴方向的距离
        while current_xy_distance < min_xy_distance:
            for i in range(len(status_list)):
                if (formation_cf_uri != status_list[i].uri
                        and status_list[i].current_posture == FlyPosture.hovering
                        and abs(status_list[i].current_position[0] - formation_cf_position[0]) < min_x_distance):
                    if (status_list[i].current_position[1] - formation_cf_position[1] > 0 and
                            status_list[i].current_position[1] - formation_cf_position[1] < min_y_distance):
                        # y轴正方向min_y_distance距离内有无人机,要向负方向飞行一段,实际场景中无人机不能靠的太近
                        formation_hl_commander.go_to(formation_cf_position[0], formation_cf_position[1] - 0.1,
                                                     formation_cf_position[2], 0.3)
                        time.sleep(1)
                    elif (formation_cf_position[1] - status_list[i].current_position[1] > 0 and
                          formation_cf_position[1] - status_list[i].current_position[1] < min_y_distance):
                        # y轴负方向上有无人机且距离过近,要向y正方向飞行一段
                        formation_hl_commander.go_to(formation_cf_position[0], formation_cf_position[1] + 0.1,
                                                     formation_cf_position[2], 0.3)
                        time.sleep(1)

            # xy方向调整完成之后
            # 计算所有无人机和编队无人机之间的最短距离
            current_xy_distance = 999999  # 重新赋值一个大数方便判断
            for i in range(len(status_list)):
                if formation_cf_uri != status_list[i].uri and status_list[i].current_posture == FlyPosture.hovering:
                    # current_xy_distance = 根号(dx*dy)
                    if (math.sqrt((formation_cf_position[0] - status_list[i].current_position[0]) ** 2
                                  + (formation_cf_position[1] - status_list[i].current_position[
                        1]) ** 2) < current_xy_distance):
                        current_xy_distance = math.sqrt(
                            (formation_cf_position[0] - status_list[i].current_position[0]) ** 2 \
                            + (formation_cf_position[1] - status_list[i].current_position[1]) ** 2)
        print(formation_cf_uri, 'formation start changing z position')
        # 1.2formation_cf调整z轴,如果z方向有距离无人机太近的无人机,当前无人机向下飞行
        while current_z_distance < min_z_distance:
            for i in range(len(status_list)):
                if (abs(formation_cf_position[2] - status_list[i].current_position[2]) < min_z_distance
                        and formation_cf_uri != status_list[i].uri
                        and status_list[i].current_posture == FlyPosture.hovering):
                    formation_hl_commander.go_to(formation_cf_position[0], formation_cf_position[1],
                                                 formation_cf_position[2] - 0.1, 0.3)
                    print('I have go to z-0.1')
                    print(formation_cf_position[2])
                    time.sleep(1)
            # 进行完for循环之后formation_cf与其他无人机不在同一个Z上
            current_z_distance = 999999
            for i in range(len(status_list)):
                if status_list[i].uri != formation_cf_uri and status_list[i].current_posture == FlyPosture.hovering:
                    print(status_list[i].uri, 'and', formation_cf_uri, 'is comparing')
                    if abs(formation_cf_position[2] - status_list[i].current_position[2]) < current_z_distance:
                        print(formation_cf_position[2], status_list[i].current_position[2], 'about to minus each other')
                        for j in range(len(status_list)):
                            print(status_list[j].current_position)
                        current_z_distance = abs(formation_cf_position[2] - status_list[i].current_position[2])
                        print(current_z_distance)
        # z轴调整完毕
        # 在这里悬停,等待charging_cf的调整。先从xy方向飞到充电板正上方,再降落
        # 这里能不能用多线程?

        # 2.1初始化charging_cf控制
        charging_hl_commander = DuplicablePositionHlCommander(charging_cf, charging_cf_position[0],
                                                              charging_cf_position[1], charging_cf_position[2], 0.3,
                                                              0.5,
                                                              controller=DuplicablePositionHlCommander.CONTROLLER_MELLINGER)

        print('charging_hl_commander create')

        charging_hl_commander.take_off()
        print('already take off')
        time.sleep(1)
        print(charging_cf_position[0], charging_cf_position[1], charging_cf_position[2])
        print('charging_hl_commander create changing z position')
        # 2.2控制charging_cf归队,往上飞
        current_z_distance = 0
        while current_z_distance < min_z_distance:
            for i in range(len(status_list)):
                if status_list[i].uri != charging_cf_uri and status_list[i].current_posture == FlyPosture.hovering:
                    if abs(charging_cf_position[2] - status_list[i].current_position[2]) < min_z_distance:
                        charging_hl_commander.go_to(charging_cf_position[0],
                                                    charging_cf_position[1], charging_cf_position[2] + 0.1, 0.3)
            # 计算charging_cf与集群中无人机在z轴方向上的距离
            current_z_distance = 999999
            for i in range(len(status_list)):
                if status_list[i].uri != charging_cf_uri and status_list[i].current_posture == FlyPosture.hovering:
                    if abs(charging_cf_position[2] - status_list[i].current_position[2]) < current_z_distance:
                        current_z_distance = abs(charging_cf_position[2] - status_list[i].current_position[2])

        print('charging_hl_commander go to formation xy')
        # 2.3charging_cf飞到现在formation_cf的xy位置,因为它已经经过了多轮调整
        charging_hl_commander.go_to(formation_cf_position[0],
                                    formation_cf_position[1], charging_cf_position[2])

        # 1.3formation_cf降落到充电座上
        formation_hl_commander.go_to(const_charging_cf_position[0], const_charging_cf_position[1],
                                     formation_cf_position[2], 0.3)
        # 这里其实应该看一下降落的时候会不会碰到东西但是不看也行
        formation_hl_commander.land(0.3)

        # 2.4判断min_xy_distance,飞到formation_cf原来的z的高度,再回到xy位置

        # current_xy_distance = 0
        # while current_xy_distance < min_xy_distance:
        #     #记录当前飞机和队列中任意一架飞机在xy平面方向的距离
        #     #扫描所有x负半轴方向的飞机,如果x轴的距离太近,判断y轴方向的距离
        #     for i in range(len(status_list)):
        #         if(charging_cf_uri == status_list[i].uri):
        #             pass
        #         elif (status_list[i].current_position[0] - charging_cf_position[0] >-min_x_distance and
        #                 status_list[i].current_position[0] - charging_cf_position[0] <min_x_distance):
        #             if (status_list[i].current_position[1] - charging_cf_position[1] >0 and
        #                 status_list[i].current_position[1] - charging_cf_position[1] < min_y_distance):
        #                 #y轴正方向min_y_distance距离内有无人机,要向负方向飞行一段,实际场景中无人机不能靠的太近
        #                 charging_hl_commander.go_to(charging_cf_position[0],
        #                                             charging_cf_position[1]-0.1,charging_cf_position[2],0.3)
        #             elif (charging_cf_position[1] - status_list[i].current_position[1] > 0 and
        #                 charging_cf_position[1] - status_list[i].current_position[1] < min_y_distance):
        #                 #y轴负方向上有无人机且距离过近,要向y正方向飞行一段
        #                 charging_hl_commander.go_to(charging_cf_position[0],
        #                                             charging_cf_position[1] + 0.1, charging_cf_position[2], 0.3)
        #
        #     current_xy_distance = 999999    #重新赋值一个大数方便判断
        #     for i in range(len(status_list)):
        #         if(charging_cf_uri != status_list[i].uri):
        #             #current_xy_distance = sqrt(dx**2+dy**2)
        #             if(math.sqrt(abs((charging_cf_position[0]-status_list[i].current_position[0])\
        #                          *(charging_cf_position[1]-status_list[i].current_position[1]))) < current_xy_distance):
        #                 current_xy_distance = math.sqrt(abs((charging_cf_position[0]-status_list[i].current_position[0])**2\
        #                          +(charging_cf_position[1]-status_list[i].current_position[1])**2))
        # end while

        # charging_cf飞到formation_cf原来的高度,然后返回相同的xy位置,
        # 这里也没有进行更多判断,存在危险
        # charging_hl_commander.go_to(charging_cf_position[0],charging_cf_position[1],const_formation_cf_position[2],0.3)
        charging_hl_commander.go_to(const_formation_cf_position[0], const_formation_cf_position[1],
                                    const_formation_cf_position[2], 0.3)
예제 #4
0
    def run_single_trajectory(self, trajectory):  # 运行单个trajectory
        #print('flying trajectory ',self._trajectory_index)
        if trajectory.posture == FlyPosture.hovering:
            return
        print(self._cf.link_uri)
        commander = DuplicablePositionHlCommander(self._cf)
        commander.set_cf_status(self._status)
        if self._need_take_off:
            #print('right before take off')
            commander.take_off()
            #print('already take off')
            self._need_take_off = False
        current_point = 0
        initial_point = True
        #print('enter run_single_trajectory while true')
        while True and not CFFlyTask.emergency_shutdown:
            point = trajectory.get_next_point()
            #print('current point is', point)
            if point is not None:
                if initial_point:
                    while CFFlyTask.not_close_enough(self._status.current_position, point):
                        commander.go_to(point[0], point[1], point[2],0.5)
                        #print('getting close to start_position')
                    initial_point = False
                current_point = point  # 不是最后一个点的话赋值
                end_point = trajectory.get_current_end_point()  # 更新当前终点
                if end_point != None:
                    self._status.current_end_point[0] = end_point[0]
                    self._status.current_end_point[1] = end_point[1]
                    self._status.current_end_point[2] = end_point[2]
                if self._status.current_posture == FlyPosture.avoiding_flying:
                    time.sleep(0.3)  # 避障的时候更新点的速度减慢
                    continue
                elif CFFlyTask._switch_pair_list['formation'][0] == self._cf.link_uri:  # 是否为交换无人机
                    self.formation_fly_to_charge(
                        self._status.current_position, CFFlyTask._switch_pair_list['charging'][1])
                    with self._status_lock:
                        self._status.current_posture = FlyPosture.charging
                    return
                else:
                    commander.go_to(current_point[0],current_point[1],current_point[2],0.5)
                    print('cf',self._cf.link_uri,'is not avoiding and go_to',current_point[0],current_point[1],current_point[2],0.5)
                    time.sleep(0.1)
            else:
                while self._status.current_posture == FlyPosture.avoiding_flying:
                    time.sleep(0.1)
                while CFFlyTask.not_close_enough(self._status.current_position, current_point):  # 有可能避障完成之后已经便利到终点,但是偏离实际位置,所以还是要修正的,修正过程中也会有避障可能
                    if self._status.current_posture == FlyPosture.avoiding_flying:
                        time.sleep(0.1)
                        continue
                    elif CFFlyTask._switch_pair_list['formation'][0] == self._cf.link_uri:
                        self.formation_fly_to_charge(
                            self._status.current_position, CFFlyTask._switch_pair_list['charging'][1])
                        with self._status_lock:
                            self._status.current_posture = FlyPosture.charging
                        return
                    else:
                        commander.go_to(current_point[0],current_point[1],current_point[2],0.5)
                       # print('getting close to end_position')

                return
    def outer_callback(timestamp, data, logconf):
        return update_cfstatus(timestamp, data, logconf, status, uri)
    log_conf.data_received_cb.add_callback(outer_callback)
    print('about to start log')
    log_conf.start()
if __name__ == '__main__':
    switch_pair_list = {'formation': ['00', [0, 0, 0]], 'charging': ['00', [0, 0, 0]]}  
    # Initialize the low-level drivers (don't list the debug drivers)
    cflib.crtp.init_drivers(enable_debug_driver=False)
    cf_status_lock1 = threading.Lock()
# cf_status_lock3 = threading.Lock()  # 访问status.current_posture时所需要的锁

# CFStatus, in the final version we may use a list to store it
    status1 = CFStatus(URI, FlyPosture.flying, cf_status_lock1)
    status_list = [status1]
    CFFlyTask.set_switch_pair_list(switch_pair_list)
    task1 = CFFlyTask(Crazyflie(), status1, [CFTrajectoryFactory.arch([1,1,1],[-1,-1,1],[-1,1,0]),CFTrajectoryFactory.arch([-1,-1,1],[1,1,1],[-1,1,0])])
    DuplicablePositionHlCommander.set_class_status_list(status_list)
    with SyncCrazyflie(URI, cf=Crazyflie(rw_cache='./cache')) as scf:
        #task1.set_cf_afterword(scf.cf)
        add_callback_to_singlecf(URI,scf,status1)
        commander = DuplicablePositionHlCommander(scf.cf)
        commander.take_off()
        commander.go_to(1,1,1)
        print('after take off sleep 2s')
        time.sleep(10)
        commander.land()
        #task1.run()
      # We take off when the commander is create
                 
    log_conf.data_received_cb.add_callback(outer_callback)
    print('about to start log')
    log_conf.start()


if __name__ == '__main__':
    switch_pair_list = {
        'formation': ['00', [0, 0, 0]],
        'charging': ['00', [0, 0, 0]]
    }
    # Initialize the low-level drivers (don't list the debug drivers)
    cflib.crtp.init_drivers(enable_debug_driver=False)
    cf_status_lock1 = threading.Lock()
    # cf_status_lock3 = threading.Lock()  # 访问status.current_posture时所需要的锁

    # CFStatus, in the final version we may use a list to store it
    status1 = CFStatus(URI, FlyPosture.flying, cf_status_lock1)
    status_list = [status1]
    CFFlyTask.set_switch_pair_list(switch_pair_list)
    task1 = CFFlyTask(Crazyflie(), status1, [
        CFTrajectoryFactory.arch([1, 1, 1], [-1, -1, 1], [-1, 1, 0]),
        CFTrajectoryFactory.arch([-1, -1, 1], [1, 1, 1], [-1, 1, 0])
    ])
    DuplicablePositionHlCommander.set_class_status_list(status_list)
    with SyncCrazyflie(URI, cf=Crazyflie(rw_cache='./cache')) as scf:
        task1.set_cf_afterword(scf.cf)
        add_callback_to_singlecf(URI, scf, status1)
        task1.run()
    # We take off when the commander is create