Beispiel #1
0
 def test_execute_parallel_drone_commands(self):
     parallel_commands = [
         ParallelDroneCommands(
             [[
                 SingleDroneCommand("name1", Command.takeoff()),
                 SingleDroneCommand("name1", Command.land())
             ],
              [
                  SingleDroneCommand("name2", Command.takeoff()),
                  SingleDroneCommand("name2", Command.land())
              ]])
     ]
     with patch(
             'xdrone.command_converters.dji_tello_edu_drone_executor.FlyTello',
             return_value=self.fly_tello):
         executor = DJITelloEduExecutor(self.name_id_map)
         executor.execute_drone_commands(parallel_commands)
         calls = [
             call.wait_sync(),
             call.takeoff(tello=1),
             call.land(tello=1),
             call.takeoff(tello=2),
             call.land(tello=2)
         ]
         self.fly.assert_has_calls(calls)
Beispiel #2
0
 def test_parallel_with_different_drones_should_give_correct_commands(self):
     drone_config_map = {
         "DRONE1": DefaultDroneConfig(),
         "DRONE2": DefaultDroneConfig(),
         "DRONE3": DefaultDroneConfig()
     }
     actual = generate_commands("""
         main() { 
           {DRONE1.takeoff();} || {DRONE2.takeoff();} || {DRONE3.takeoff();}; 
           {
             DRONE1.land();
           } || {
             {DRONE2.land();} || {DRONE3.land();};
           };
         }
     """,
                                drone_config_map=drone_config_map)
     expected = [
         ParallelDroneCommands(
             [[SingleDroneCommand("DRONE1", Command.takeoff())],
              [SingleDroneCommand("DRONE2", Command.takeoff())],
              [SingleDroneCommand("DRONE3", Command.takeoff())]]),
         ParallelDroneCommands(
             [[SingleDroneCommand("DRONE1", Command.land())],
              [
                  ParallelDroneCommands(
                      [[SingleDroneCommand("DRONE2", Command.land())],
                       [SingleDroneCommand("DRONE3", Command.land())]])
              ]])
     ]
     self.assertEqual(expected, actual)
Beispiel #3
0
 def test_immutable(self):
     drone_command = SingleDroneCommand("abc", Command.takeoff())
     drone_name = drone_command.drone_name
     command = drone_command.command
     drone_name += "corrupted"
     command._opcode = "corrupted"
     self.assertEqual("abc", drone_command.drone_name)
     self.assertEqual(Command.takeoff(), drone_command.command)
Beispiel #4
0
 def test_add_already_involved_drones_should_give_error(self):
     parallel_commands = ParallelDroneCommands()
     parallel_commands.add(
         [SingleDroneCommand("DRONE1", Command.takeoff())])
     with self.assertRaises(RepeatDroneNameException) as context:
         parallel_commands.add(
             [SingleDroneCommand("DRONE1", Command.takeoff())])
     self.assertTrue({"DRONE1"}, context.exception.repeated_names)
Beispiel #5
0
 def test_check_takeoff_land_takeoff_land_should_not_give_error(self):
     drone_commands = [
         SingleDroneCommand("DRONE1", Command.takeoff()),
         SingleDroneCommand("DRONE1", Command.land()),
         SingleDroneCommand("DRONE1", Command.takeoff()),
         SingleDroneCommand("DRONE1", Command.land()),
     ]
     BoundaryChecker(self.boundary_config).check(drone_commands,
                                                 self.state_updater_map)
Beispiel #6
0
 def test_add(self):
     parallel_commands = ParallelDroneCommands()
     parallel_commands.add([])
     self.assertEqual([[]], parallel_commands.branches)
     self.assertEqual([set()],
                      parallel_commands.drones_involved_each_branch)
     parallel_commands.add([SingleDroneCommand("abc", Command.takeoff())])
     self.assertEqual([[], [SingleDroneCommand("abc", Command.takeoff())]],
                      parallel_commands.branches)
     self.assertEqual([set(), {"abc"}],
                      parallel_commands.drones_involved_each_branch)
Beispiel #7
0
 def test_eq(self):
     commands1 = [
         None,
         Command.takeoff(),
         Command.land(),
         Command.up(1),
         Command.down(1),
         Command.left(1),
         Command.right(1),
         Command.forward(1),
         Command.backward(1),
         Command.rotate_left(1),
         Command.rotate_right(1),
         Command.wait(1),
         Command.up(2),
         Command.down(2),
         Command.left(2),
         Command.right(2),
         Command.forward(2),
         Command.backward(2),
         Command.rotate_left(2),
         Command.rotate_right(2),
         Command.wait(2)
     ]
     commands2 = [
         None,
         Command.takeoff(),
         Command.land(),
         Command.up(1),
         Command.down(1),
         Command.left(1),
         Command.right(1),
         Command.forward(1),
         Command.backward(1),
         Command.rotate_left(1),
         Command.rotate_right(1),
         Command.wait(1),
         Command.up(2),
         Command.down(2),
         Command.left(2),
         Command.right(2),
         Command.forward(2),
         Command.backward(2),
         Command.rotate_left(2),
         Command.rotate_right(2),
         Command.wait(2)
     ]
     for i in range(len(commands1)):
         for j in range(len(commands2)):
             if i == j:
                 self.assertEqual(commands1[i], commands2[j])
             else:
                 self.assertNotEqual(commands1[i], commands2[j])
Beispiel #8
0
 def test_eq(self):
     parallel_commands1 = ParallelDroneCommands()
     parallel_commands1.add([])
     parallel_commands1.add([SingleDroneCommand("abc", Command.takeoff())])
     parallel_commands2 = ParallelDroneCommands(
         [[], [SingleDroneCommand("abc", Command.takeoff())]])
     parallel_commands3 = ParallelDroneCommands(
         [[SingleDroneCommand("abc", Command.takeoff())], []])
     self.assertEqual(ParallelDroneCommands(), ParallelDroneCommands())
     self.assertEqual(parallel_commands1, parallel_commands2)
     self.assertNotEqual(parallel_commands1, parallel_commands3)
     self.assertNotEqual(None, parallel_commands1)
Beispiel #9
0
 def test_check_single_drone_command_takeoff_when_taken_off_should_give_error(
         self):
     with self.assertRaises(SafetyCheckError) as context:
         drone_commands = [
             SingleDroneCommand("DRONE1", Command.takeoff()),
             SingleDroneCommand("DRONE1", Command.takeoff())
         ]
         BoundaryChecker(self.boundary_config).check(
             drone_commands, self.state_updater_map)
     self.assertTrue(
         "'takeoff' command used when drone 'DRONE1' has already been taken off"
         in str(context.exception))
Beispiel #10
0
 def test_get_drones_involved(self):
     parallel_commands = ParallelDroneCommands()
     self.assertEqual(set(), parallel_commands.get_drones_involved())
     parallel_commands = ParallelDroneCommands(
         [[SingleDroneCommand("DRONE1", Command.takeoff())],
          [SingleDroneCommand("DRONE2", Command.takeoff())],
          [
              ParallelDroneCommands(
                  [[SingleDroneCommand("DRONE3", Command.takeoff())],
                   [SingleDroneCommand("DRONE4", Command.takeoff())]])
          ]])
     self.assertEqual({"DRONE1", "DRONE2", "DRONE3", "DRONE4"},
                      parallel_commands.get_drones_involved())
    def test_check_parallel_drone_command_should_detect_collision_and_give_error(self):
        drone_commands = [SingleDroneCommand("DRONE1", Command.takeoff()),
                          SingleDroneCommand("DRONE2", Command.takeoff()),
                          ParallelDroneCommands([
                              [SingleDroneCommand("DRONE1", Command.right(1))],
                              [SingleDroneCommand("DRONE2", Command.left(1))]
                          ]),
                          SingleDroneCommand("DRONE1", Command.land()),
                          SingleDroneCommand("DRONE2", Command.land())]

        with self.assertRaises(SafetyCheckError) as context:
            self.collision_checker.check(drone_commands, self.state_updater_map)
        self.assertTrue("Collisions might happen!\nCollision might happen between DRONE1 and DRONE2"
                        in str(context.exception))
Beispiel #12
0
 def test_basic_program(self):
     commands = "main() {takeoff(); land();}"
     expected = [
         SingleDroneCommand("DEFAULT", Command.takeoff()),
         SingleDroneCommand("DEFAULT", Command.land())
     ]
     self.assertEqual(expected, generate_commands(commands))
Beispiel #13
0
 def test_dji_tello_executor_if_receive_error_should_print(self) -> None:
     mocked_socket = Mock()
     mocked_socket.recvfrom = Mock(side_effect=Exception('timed out'))
     mocked_socket.sendto = Mock()
     commands = [Command.takeoff(), Command.land()]
     executor = DJITelloExecutor()
     executor.sock.close()
     executor.sock = mocked_socket
     with self.assertLogs(logging.getLogger()) as log:
         executor.execute_commands(commands)
     calls = [
         call(b"command", ('192.168.10.1', 8889)),
         call(b"takeoff", ('192.168.10.1', 8889)),
         call(b"land", ('192.168.10.1', 8889))
     ]
     mocked_socket.sendto.assert_has_calls(calls)
     expected_log = [
         "INFO:root:sent message: b'command'",
         "ERROR:root:Error met when receiving response: timed out",
         "INFO:root:sent message: b'takeoff'",
         "ERROR:root:Error met when receiving response: timed out",
         "INFO:root:sent message: b'land'",
         "ERROR:root:Error met when receiving response: timed out"
     ]
     self.assertEqual(expected_log, log.output)
Beispiel #14
0
 def test_multiple_commands_should_return_correct_command(self):
     actual = generate_commands("""
         main() {
          takeoff();
          up(1);
          down(2);
          left(3);
          right(4);
          forward(5);
          backward(6);
          rotate_left(7);
          rotate_right(8);
          wait(9);
          land(); 
         }
     """)
     expected = [
         SingleDroneCommand("DEFAULT", Command.takeoff()),
         SingleDroneCommand("DEFAULT", Command.up(1)),
         SingleDroneCommand("DEFAULT", Command.down(2)),
         SingleDroneCommand("DEFAULT", Command.left(3)),
         SingleDroneCommand("DEFAULT", Command.right(4)),
         SingleDroneCommand("DEFAULT", Command.forward(5)),
         SingleDroneCommand("DEFAULT", Command.backward(6)),
         SingleDroneCommand("DEFAULT", Command.rotate_left(7)),
         SingleDroneCommand("DEFAULT", Command.rotate_right(8)),
         SingleDroneCommand("DEFAULT", Command.wait(9)),
         SingleDroneCommand("DEFAULT", Command.land())
     ]
     self.assertEqual(expected, actual)
 def test_function_procedure_in_function(self):
     commands = generate_commands("""
         function func(int i) return int {
           while i < 10 {
             i <- i + 1;
           }
           return i;
         }
         procedure proc(int i) {
           forward(i * i);
         }
         function func2(int i) return int {
           proc(func(i));
           return func(i) * func(i);
         }
         main () {
           takeoff();
           forward(func2(1));
           land();
         }
         """)
     expected_commands = [SingleDroneCommand("DEFAULT", Command.takeoff()),
                          SingleDroneCommand("DEFAULT", Command.forward(100)),
                          SingleDroneCommand("DEFAULT", Command.forward(100)),
                          SingleDroneCommand("DEFAULT", Command.land())]
     self.assertEqual(expected_commands, commands)
Beispiel #16
0
 def test_check_in_the_end_not_land_should_give_error(self):
     with self.assertRaises(SafetyCheckError) as context:
         drone_commands = [SingleDroneCommand("DRONE1", Command.takeoff())]
         BoundaryChecker(self.boundary_config).check(
             drone_commands, self.state_updater_map)
     self.assertTrue(
         "Drone 'DRONE1' did not land in the end" in str(context.exception))
Beispiel #17
0
    def test_dji_tello_executor_if_interrupt_error_should_stop_and_emergency(
            self) -> None:
        mocked_socket = Mock()
        mocked_socket.recvfrom = Mock(return_value=(b'ok', ('192.168.10.1',
                                                            8889)))
        mocked_socket.sendto = Mock()

        def mocked_sendto(msg, _):
            if msg == b"takeoff":
                raise KeyboardInterrupt

        mocked_socket.sendto.side_effect = mocked_sendto
        commands = [Command.takeoff(), Command.land()]
        executor = DJITelloExecutor()
        executor.sock.close()
        executor.sock = mocked_socket
        with self.assertLogs(logging.getLogger()) as log:
            executor.execute_commands(commands)
        calls = [
            call(b"command", ('192.168.10.1', 8889)),
            call(b"takeoff", ('192.168.10.1', 8889)),
            call(b"emergency", ('192.168.10.1', 8889))
        ]
        mocked_socket.sendto.assert_has_calls(calls)
        expected_log = [
            "INFO:root:sent message: b'command'",
            "INFO:root:received response: ok",
            "INFO:root:KeyboardInterrupt received. Forced stop."
        ]
        self.assertEqual(expected_log, log.output)
 def test_update_takeoff_should_update_state(self):
     state = State()
     actual = self.state_updater.update(Command.takeoff(), state)
     expected = State(
         has_taken_off=True,
         time_used_seconds=self.drone_config.takeoff_height_meters / 0.5,
         z_meters=self.drone_config.takeoff_height_meters)
     self.assertEqual(expected, actual)
Beispiel #19
0
 def test_land_should_return_correct_command(self):
     actual = generate_commands("""
         main() { takeoff(); land(); }
     """)
     expected = [
         SingleDroneCommand("DEFAULT", Command.takeoff()),
         SingleDroneCommand("DEFAULT", Command.land())
     ]
     self.assertEqual(expected, actual)
Beispiel #20
0
 def test_repr(self):
     parallel_commands = ParallelDroneCommands()
     parallel_commands.add([])
     parallel_commands.add([SingleDroneCommand("abc", Command.takeoff())])
     self.assertEqual(
         "ParallelDroneCommands: { [], " +
         "[SingleDroneCommand: { drone_name: abc, " +
         "command: Command: { opcode: takeoff, operands: [] } }] }",
         repr(parallel_commands))
 def test_check_bad_collision_config_should_not_give_error(self):
     collision_config = CollisionConfig(collision_meters=0.3, time_interval_seconds=0.001)
     collision_checker = CollisionChecker(self.drone_config_map, collision_config)
     drone_commands = [SingleDroneCommand("DRONE1", Command.takeoff()),
                       SingleDroneCommand("DRONE1", Command.land())]
     with self.assertRaises(SafetyCheckError) as context:
         collision_checker.check(drone_commands, self.state_updater_map)
     self.assertTrue("Error occurred during collision check, please retry with better the collision_config."
                     in str(context.exception))
Beispiel #22
0
 def test_backward_with_int_parameter_should_return_correct_command(self):
     actual = generate_commands("""
         main() { takeoff(); backward(1); land(); }
     """)
     expected = [
         SingleDroneCommand("DEFAULT", Command.takeoff()),
         SingleDroneCommand("DEFAULT", Command.backward(1)),
         SingleDroneCommand("DEFAULT", Command.land())
     ]
     self.assertEqual(expected, actual)
Beispiel #23
0
 def test_up_with_decimal_parameter_should_return_correct_command(self):
     actual = generate_commands("""
         main() { takeoff(); up(1.0); land(); }
     """)
     expected = [
         SingleDroneCommand("DEFAULT", Command.takeoff()),
         SingleDroneCommand("DEFAULT", Command.up(1.0)),
         SingleDroneCommand("DEFAULT", Command.land())
     ]
     self.assertEqual(expected, actual)
Beispiel #24
0
 def test_land_with_drone_name_should_return_correct_command(self):
     actual = generate_commands(
         """
         main() { DRONE1.takeoff(); DRONE1.land(); }
     """,
         drone_config_map={"DRONE1": DefaultDroneConfig()})
     expected = [
         SingleDroneCommand("DRONE1", Command.takeoff()),
         SingleDroneCommand("DRONE1", Command.land())
     ]
     self.assertEqual(expected, actual)
Beispiel #25
0
 def test_check_single_drone_command_should_check_state_and_catch_error(
         self):
     boundary_checker = BoundaryChecker(self.boundary_config)
     boundary_checker.boundary_config.check_state = Mock(
         side_effect=SafetyCheckError)
     drone_commands = [
         SingleDroneCommand("DRONE1", Command.takeoff()),
         SingleDroneCommand("DRONE1", Command.land())
     ]
     with self.assertRaises(SafetyCheckError) as context:
         BoundaryChecker(self.boundary_config).check(
             drone_commands, self.state_updater_map)
Beispiel #26
0
 def test_movement_with_no_name_specified_if_only_one_drone_should_use_that_drone(
         self):
     drone_config_map = {"THE_ONE": DefaultDroneConfig()}
     actual = generate_commands("""
         main() { takeoff(); land(); }
     """,
                                drone_config_map=drone_config_map)
     expected = [
         SingleDroneCommand("THE_ONE", Command.takeoff()),
         SingleDroneCommand("THE_ONE", Command.land())
     ]
     self.assertEqual(expected, actual)
Beispiel #27
0
 def test_check_parallel_drone_commands_should_check_state(self):
     boundary_checker = BoundaryChecker(self.boundary_config)
     boundary_checker.boundary_config.check_state = Mock()
     drone_commands = [
         ParallelDroneCommands(
             [[
                 SingleDroneCommand("DRONE1", Command.takeoff()),
                 SingleDroneCommand("DRONE1", Command.land())
             ],
              [
                  SingleDroneCommand("DRONE2", Command.takeoff()),
                  SingleDroneCommand("DRONE2", Command.land())
              ]])
     ]
     BoundaryChecker(self.boundary_config).check(drone_commands,
                                                 self.state_updater_map)
     last_two_calls = [
         call("DRONE1", State(time_used_seconds=2)),
         call("DRONE2", State(time_used_seconds=2, x_meters=1))
     ]
     boundary_checker.boundary_config.check_state.assert_has_calls(
         last_two_calls)
Beispiel #28
0
 def test_eq(self):
     self.assertEqual(SingleDroneCommand("abc", Command.takeoff()),
                      SingleDroneCommand("abc", Command.takeoff()))
     self.assertNotEqual(SingleDroneCommand("", Command.takeoff()),
                         SingleDroneCommand("abc", Command.takeoff()))
     self.assertNotEqual(SingleDroneCommand("abc", Command.takeoff()),
                         SingleDroneCommand("abc", Command.land()))
     self.assertNotEqual(None, SingleDroneCommand("abc", Command.takeoff()))
Beispiel #29
0
 def test_repeat_should_run_correct_commands(self):
     actual_commands = generate_commands("""
         main () {
           takeoff();
           repeat 4 times {
             forward(1);
           }
           land();
         }
         """)
     expected_commands = [SingleDroneCommand("DEFAULT", Command.takeoff())] + \
                         [SingleDroneCommand("DEFAULT", Command.forward(1)) for _ in range(4)] + \
                         [SingleDroneCommand("DEFAULT", Command.land())]
     self.assertEqual(expected_commands, actual_commands)
Beispiel #30
0
 def test_if_with_error_commands_not_entering_should_not_give_error(self):
     actual_commands = generate_commands("""
         main () {
           takeoff();
           if false {
             int a <- "error";
             forward(1);
           }
           land();
         }
         """)
     expected_commands = [SingleDroneCommand("DEFAULT", Command.takeoff()),
                          SingleDroneCommand("DEFAULT", Command.land())]
     self.assertEqual(expected_commands, actual_commands)