def test_update_forward_should_update_state(self):
        state = State(has_taken_off=True,
                      x_meters=1,
                      y_meters=2,
                      z_meters=3,
                      orientation_degrees=60)
        actual = self.state_updater.update(Command.forward(1), state)
        expected = State(has_taken_off=True,
                         time_used_seconds=1 / 0.5,
                         x_meters=1 + sqrt(3) / 2,
                         y_meters=2 + 0.5,
                         z_meters=3,
                         orientation_degrees=60)
        self.assertEqual(expected, actual)

        state = State(has_taken_off=True,
                      x_meters=1,
                      y_meters=2,
                      z_meters=3,
                      orientation_degrees=240)
        actual = self.state_updater.update(Command.forward(1), state)
        expected = State(has_taken_off=True,
                         time_used_seconds=1 / 0.5,
                         x_meters=1 - sqrt(3) / 2,
                         y_meters=2 - 0.5,
                         z_meters=3,
                         orientation_degrees=240)
        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)
Exemple #3
0
 def test_corrupted_command_should_not_affect_correct_type(self):
     command = Command.forward(1)
     corrupted_command = Command.forward(1)
     corrupted_command._opcode = "corrupted"
     self.assertNotEqual(command, corrupted_command)
     self.assertEqual("forward", Command.forward(1).opcode)
     self.assertEqual([1], Command.forward(1).operands)
     self.assertEqual("corrupted", corrupted_command.opcode)
     self.assertEqual([1], corrupted_command.operands)
Exemple #4
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])
Exemple #5
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)
Exemple #6
0
 def test_forward_with_int_parameter_should_return_correct_command(self):
     actual = generate_commands("""
         main() { takeoff(); forward(1); land(); }
     """)
     expected = [
         SingleDroneCommand("DEFAULT", Command.takeoff()),
         SingleDroneCommand("DEFAULT", Command.forward(1)),
         SingleDroneCommand("DEFAULT", Command.land())
     ]
     self.assertEqual(expected, actual)
Exemple #7
0
 def test_forward_with_drone_name_should_return_correct_command(self):
     actual = generate_commands(
         """
         main() { DRONE1.takeoff(); DRONE1.forward(1); DRONE1.land(); }
     """,
         drone_config_map={"DRONE1": DefaultDroneConfig()})
     expected = [
         SingleDroneCommand("DRONE1", Command.takeoff()),
         SingleDroneCommand("DRONE1", Command.forward(1)),
         SingleDroneCommand("DRONE1", Command.land())
     ]
     self.assertEqual(expected, actual)
 def visitForward(self, ctx: xDroneParser.ForwardContext) -> None:
     exprs = [self.visit(expr) for expr in ctx.expr()]
     if ctx.DOT():
         drone_expr, expr = exprs
     else:
         drone_expr, expr = None, exprs[0]
     if expr.type != Type.int() and expr.type != Type.decimal():
         raise CompileError(
             "Expression {} should have type int or decimal, but is {}".
             format(expr, expr.type))
     drone_name = self._get_drone_name(drone_expr)
     self._get_latest_commands().append(
         SingleDroneCommand(drone_name, Command.forward(expr.value)))
 def test_function_procedure_in_procedure(self):
     commands = generate_commands("""
         function func(int i) return int {
           return i * i;
         }
         procedure proc(int i) {
           forward(i);
         }
         procedure proc2() {
           takeoff();
           proc(func(10));
           proc(func(10));
           land();
         }
         main () {
           proc2();
         }
         """)
     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)
Exemple #10
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)
    def test_check_single_drone_command_should_detect_collision_and_give_error(self):
        drone_commands = [SingleDroneCommand("DRONE1", Command.takeoff()),
                          SingleDroneCommand("DRONE2", Command.takeoff()),
                          SingleDroneCommand("DRONE1", Command.right(1)),
                          SingleDroneCommand("DRONE2", Command.wait(1)),
                          SingleDroneCommand("DRONE2", Command.rotate_left(90)),
                          SingleDroneCommand("DRONE2", Command.forward(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))
 def test_loops_in_function(self):
     commands = generate_commands("""
         function func(int i) return int {
           while i < 10 {
             i <- i + 1;
           }
           return i;
         }
         main () {
           takeoff();
           forward(func(1));
           land();
         }
         """)
     expected_commands = [SingleDroneCommand("DEFAULT", Command.takeoff()),
                          SingleDroneCommand("DEFAULT", Command.forward(10)),
                          SingleDroneCommand("DEFAULT", Command.land())]
     self.assertEqual(expected_commands, commands)
 def test_recursion(self):
     commands = generate_commands("""
         function func(int i) return int {
           if i >= 10 {
             return 10;
           }
           return func(i + 1);
         }
         main () {
           takeoff();
           forward(func(1));
           land();
         }
         """)
     expected_commands = [SingleDroneCommand("DEFAULT", Command.takeoff()),
                          SingleDroneCommand("DEFAULT", Command.forward(10)),
                          SingleDroneCommand("DEFAULT", Command.land())]
     self.assertEqual(expected_commands, commands)
 def test_loops_in_function(self):
     commands = generate_commands("""
         procedure proc(int i) {
           while i < 10 {
             i <- i + 1;
           }
           forward(i);
         }
         main () {
           takeoff();
           proc(1);
           land();
         }
         """)
     expected_commands = [SingleDroneCommand("DEFAULT", Command.takeoff()),
                          SingleDroneCommand("DEFAULT", Command.forward(10)),
                          SingleDroneCommand("DEFAULT", Command.land())]
     self.assertEqual(expected_commands, commands)
Exemple #15
0
 def test_if_true_without_else_should_run_correct_commands(self):
     actual_st = SymbolTable()
     actual_commands = generate_commands("""
         main () {
           takeoff();
           if true {
             int a <- 1;
             forward(a);
           }
           land();
         }
         """, symbol_table=actual_st)
     expected_st = SymbolTable()
     self.assertEqual(expected_st, actual_st)
     expected_commands = [SingleDroneCommand("DEFAULT", Command.takeoff()),
                          SingleDroneCommand("DEFAULT", Command.forward(1)),
                          SingleDroneCommand("DEFAULT", Command.land())]
     self.assertEqual(expected_commands, actual_commands)
Exemple #16
0
 def test_execute_single_drone_command(self):
     single_commands = [
         SingleDroneCommand("name1", Command.takeoff()),
         SingleDroneCommand("name1", Command.land()),
         SingleDroneCommand("name2", Command.up(1.1)),
         SingleDroneCommand("name2", Command.down(1.2)),
         SingleDroneCommand("name2", Command.left(1.3)),
         SingleDroneCommand("name2", Command.right(1.4)),
         SingleDroneCommand("name2", Command.forward(1.5)),
         SingleDroneCommand("name2", Command.backward(1.6)),
         SingleDroneCommand("name2", Command.rotate_left(91)),
         SingleDroneCommand("name2", Command.rotate_right(92)),
         SingleDroneCommand("name2", Command.wait(1))
     ]
     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(single_commands)
         calls = [
             call.wait_sync(),
             call.takeoff(tello=1),
             call.wait_sync(),
             call.land(tello=1),
             call.wait_sync(),
             call.up(110, tello=2),
             call.wait_sync(),
             call.down(120, tello=2),
             call.wait_sync(),
             call.left(130, tello=2),
             call.wait_sync(),
             call.right(140, tello=2),
             call.wait_sync(),
             call.forward(150, tello=2),
             call.wait_sync(),
             call.back(160, tello=2),
             call.wait_sync(),
             call.rotate_ccw(91, tello=2),
             call.wait_sync(),
             call.rotate_cw(92, tello=2),
             call.wait_sync(),
             call.pause(1)
         ]
         self.fly.assert_has_calls(calls)
 def test_call_function_should_run_commands_and_return(self):
     commands = generate_commands("""
         function func(int i, int j) return int {
           up(i + j);
           down(i);
           return i + j;
         }
         main () {
           takeoff();
           forward(func(100, 200));
           land();
         }
         """)
     expected_commands = [SingleDroneCommand("DEFAULT", Command.takeoff()),
                          SingleDroneCommand("DEFAULT", Command.up(300)),
                          SingleDroneCommand("DEFAULT", Command.down(100)),
                          SingleDroneCommand("DEFAULT", Command.forward(300)),
                          SingleDroneCommand("DEFAULT", Command.land())]
     self.assertEqual(expected_commands, commands)
 def test_recursion(self):
     commands = generate_commands("""
         procedure proc(int i) {
           if i >= 10 {
             forward(10);
             return;
           }
           proc(i + 1);
         }
         main () {
           takeoff();
           proc(1);
           land();
         }
         """)
     expected_commands = [SingleDroneCommand("DEFAULT", Command.takeoff()),
                          SingleDroneCommand("DEFAULT", Command.forward(10)),
                          SingleDroneCommand("DEFAULT", Command.land())]
     self.assertEqual(expected_commands, commands)
Exemple #19
0
 def test_while_should_run_correct_commands(self):
     actual = SymbolTable()
     actual_commands = generate_commands("""
         main () {
           takeoff();
           int a <- 1;
           while a < 5 {
             a <- a + 1;
             forward(a);
           }
           land();
         }
         """, symbol_table=actual)
     expected = SymbolTable()
     expected.store("a", Expression(Type.int(), 5, ident="a"))
     self.assertEqual(expected, actual)
     expected_commands = [SingleDroneCommand("DEFAULT", Command.takeoff())] + \
                         [SingleDroneCommand("DEFAULT", Command.forward(i)) for i in [2, 3, 4, 5]] + \
                         [SingleDroneCommand("DEFAULT", Command.land())]
     self.assertEqual(expected_commands, actual_commands)
Exemple #20
0
 def test_check_single_drone_command_other_command_when_not_taken_off_should_give_error(
         self):
     commands = [
         Command.land(),
         Command.up(1),
         Command.down(1),
         Command.left(1),
         Command.right(1),
         Command.forward(1),
         Command.backward(1),
         Command.rotate_left(90),
         Command.rotate_right(90)
     ]
     for command in commands:
         with self.assertRaises(SafetyCheckError) as context:
             drone_commands = [SingleDroneCommand("DRONE1", command)]
             BoundaryChecker(self.boundary_config).check(
                 drone_commands, self.state_updater_map)
         self.assertTrue(
             "'{}' command used when drone 'DRONE1' has not been taken off".
             format(command.opcode) in str(context.exception))
Exemple #21
0
 def test_for_with_step_should_run_correct_commands_and_update_symbol_table(self):
     actual_st = SymbolTable()
     actual_commands = generate_commands("""
         main () {
           takeoff();
           int i;
           int a <- 0;
           for i from 0 to 9 step 2 {
             a <- a + 1;
             forward(i);
           }
           land();
         }
         """, symbol_table=actual_st)
     expected_st = SymbolTable()
     expected_st.store("i", Expression(Type.int(), 8, ident="i"))
     expected_st.store("a", Expression(Type.int(), 5, ident="a"))
     self.assertEqual(expected_st, actual_st)
     expected_commands = [SingleDroneCommand("DEFAULT", Command.takeoff())] + \
                         [SingleDroneCommand("DEFAULT", Command.forward(i)) for i in [0, 2, 4, 6, 8]] + \
                         [SingleDroneCommand("DEFAULT", Command.land())]
     self.assertEqual(expected_commands, actual_commands)
Exemple #22
0
 def test_if_false_with_else_should_run_correct_commands(self):
     actual = SymbolTable()
     actual_commands = generate_commands("""
         main () {
           takeoff();
           if false {
             int a <- 1;
             forward(a);
           } else {
             int a <- 2;
             int b <- 3;
             forward(b);
           }
           land();
         }
         """, symbol_table=actual)
     expected = SymbolTable()
     self.assertEqual(expected, actual)
     expected_commands = [SingleDroneCommand("DEFAULT", Command.takeoff()),
                          SingleDroneCommand("DEFAULT", Command.forward(3)),
                          SingleDroneCommand("DEFAULT", Command.land())]
     self.assertEqual(expected_commands, actual_commands)
 def test_scope(self):
     actual = SymbolTable()
     commands = generate_commands("""
         function func(int i) return int {
           int j <- 100;
           while i < 10 {
             i <- i + 1;
           }
           return i;
         }
         main () {
           takeoff();
           int i <- 1;
           forward(func(i));
           land();
         }
         """, symbol_table=actual)
     expected_commands = [SingleDroneCommand("DEFAULT", Command.takeoff()),
                          SingleDroneCommand("DEFAULT", Command.forward(10)),
                          SingleDroneCommand("DEFAULT", Command.land())]
     self.assertEqual(expected_commands, commands)
     expected = SymbolTable()
     expected.store("i", Expression(Type.int(), 1, ident="i"))
     self.assertEqual(expected, actual)
    def test_convert_command(self):
        commands = [
            SingleDroneCommand("DRONE1", Command.takeoff()),
            SingleDroneCommand("DRONE1", Command.up(1)),
            SingleDroneCommand("DRONE1", Command.down(1)),
            SingleDroneCommand("DRONE1", Command.left(1)),
            SingleDroneCommand("DRONE1", Command.right(1)),
            SingleDroneCommand("DRONE1", Command.forward(1)),
            SingleDroneCommand("DRONE1", Command.backward(1)),
            SingleDroneCommand("DRONE1", Command.rotate_left(1)),
            SingleDroneCommand("DRONE1", Command.rotate_right(1)),
            ParallelDroneCommands(
                [[
                    ParallelDroneCommands(
                        [[], [SingleDroneCommand("DRONE1", Command.up(1))]])
                ],
                 [
                     SingleDroneCommand("DRONE2", Command.takeoff()),
                     SingleDroneCommand("DRONE2", Command.land())
                 ]]),
            SingleDroneCommand("DRONE1", Command.land()),
            SingleDroneCommand("DRONE1", Command.wait(1))
        ]
        drone_config_map = {
            "DRONE1": DroneConfig((1, 2, 3), 1, 90, 2),
            "DRONE2": DroneConfig((0, 0, 0), 1, 90, 1)
        }
        expected = {
            "config": [{
                "name": "DRONE1",
                "init_pos": [1, 2, 3],
                "speed": 1,
                "rotate_speed": 90,
                "takeoff_height": 2
            }, {
                "name": "DRONE2",
                "init_pos": [0, 0, 0],
                "speed": 1,
                "rotate_speed": 90,
                "takeoff_height": 1
            }],
            "commands": [{
                "type": "single",
                "name": "DRONE1",
                "action": "takeoff",
                "values": []
            }, {
                "type": "single",
                "name": "DRONE1",
                "action": "up",
                "values": [1]
            }, {
                "type": "single",
                "name": "DRONE1",
                "action": "down",
                "values": [1]
            }, {
                "type": "single",
                "name": "DRONE1",
                "action": "left",
                "values": [1]
            }, {
                "type": "single",
                "name": "DRONE1",
                "action": "right",
                "values": [1]
            }, {
                "type": "single",
                "name": "DRONE1",
                "action": "forward",
                "values": [1]
            }, {
                "type": "single",
                "name": "DRONE1",
                "action": "backward",
                "values": [1]
            }, {
                "type": "single",
                "name": "DRONE1",
                "action": "rotate_left",
                "values": [1]
            }, {
                "type": "single",
                "name": "DRONE1",
                "action": "rotate_right",
                "values": [1]
            }, {
                "type":
                "parallel",
                "branches": [[{
                    "type":
                    "parallel",
                    "branches": [[],
                                 [{
                                     "type": "single",
                                     "name": "DRONE1",
                                     "action": "up",
                                     "values": [1]
                                 }]]
                }],
                             [{
                                 "type": "single",
                                 "name": "DRONE2",
                                 "action": "takeoff",
                                 "values": []
                             }, {
                                 "type": "single",
                                 "name": "DRONE2",
                                 "action": "land",
                                 "values": []
                             }]]
            }, {
                "type": "single",
                "name": "DRONE1",
                "action": "land",
                "values": []
            }, {
                "type": "single",
                "name": "DRONE1",
                "action": "wait",
                "values": [1]
            }]
        }
        actual = SimulationConverter().convert(commands, drone_config_map)

        self.assertEqual(expected,
                         json.loads(zlib.decompress(b64decode(actual))))
Exemple #25
0
 def test_forward(self):
     self.assertEqual(Command.forward(1), Command.forward(1))
     self.assertEqual("forward", Command.forward(1).opcode)
     self.assertEqual([1], Command.forward(1).operands)
     self.assertEqual("Command: { opcode: forward, operands: [1] }",
                      str(Command.forward(1)))
Exemple #26
0
 def test_dji_tello_executor_should_send_correct_message(self) -> None:
     mocked_socket = Mock()
     mocked_socket.recvfrom = Mock(return_value=(b'ok', ('192.168.10.1',
                                                         8889)))
     mocked_socket.sendto = Mock()
     commands = [
         Command.takeoff(),
         Command.up(1),
         Command.down(1),
         Command.left(1),
         Command.right(1),
         Command.forward(1),
         Command.backward(1),
         Command.rotate_left(90),
         Command.rotate_right(90),
         Command.wait(0),
         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"up 100", ('192.168.10.1', 8889)),
         call(b"down 100", ('192.168.10.1', 8889)),
         call(b"left 100", ('192.168.10.1', 8889)),
         call(b"right 100", ('192.168.10.1', 8889)),
         call(b"forward 100", ('192.168.10.1', 8889)),
         call(b"back 100", ('192.168.10.1', 8889)),
         call(b"ccw 90", ('192.168.10.1', 8889)),
         call(b"cw 90", ('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'",
         "INFO:root:received response: ok",
         "INFO:root:sent message: b'takeoff'",
         "INFO:root:received response: ok",
         "INFO:root:sent message: b'up 100'",
         "INFO:root:received response: ok",
         "INFO:root:sent message: b'down 100'",
         "INFO:root:received response: ok",
         "INFO:root:sent message: b'left 100'",
         "INFO:root:received response: ok",
         "INFO:root:sent message: b'right 100'",
         "INFO:root:received response: ok",
         "INFO:root:sent message: b'forward 100'",
         "INFO:root:received response: ok",
         "INFO:root:sent message: b'back 100'",
         "INFO:root:received response: ok",
         "INFO:root:sent message: b'ccw 90'",
         "INFO:root:received response: ok",
         "INFO:root:sent message: b'cw 90'",
         "INFO:root:received response: ok",
         "INFO:root:sent message: b'land'",
         "INFO:root:received response: ok"
     ]
     self.assertEqual(expected_log, log.output)