Пример #1
0
    def test_checksum_func_incomplete(self):
        """Check that the compute_checksum function fails when the
        "byte_seq" argument is incomplete (len(byte_seq) < 3)."""

        byte_seq = (0x01, 0x02)                      # incomplete packet

        with self.assertRaises(ValueError):
            pk.compute_checksum(byte_seq)
Пример #2
0
    def test_checksum_func_wrong_id_byte(self):
        """Check that the compute_checksum function fails when the "id" byte
        of the "byte_seq" argument has a wrong value (too high value)."""

        byte_seq = (0xff,)             # wrong id
        byte_seq += (4,)               # length
        byte_seq += (0x02, 0x2b, 0x01) # read the temperature of the dynamixel

        with self.assertRaises(ValueError):
            pk.compute_checksum(byte_seq)
Пример #3
0
    def test_checksum_func_wrong_byte_type(self):
        """Check that the compute_checksum function fails when an item of the
        "byte_seq" argument has a wrong type (float)."""

        # Check with None
        byte_seq = (0x01, None, 0x02, 0x2b, 0x01)    # wrong type

        with self.assertRaises(TypeError):
            pk.compute_checksum(byte_seq)

        # Check with float
        byte_seq = (0x01, 1.0, 0x02, 0x2b, 0x01)     # wrong type

        with self.assertRaises(TypeError):
            pk.compute_checksum(byte_seq)

        # Check with string
        byte_seq = (0x01, "hi", 0x02, 0x2b, 0x01)    # wrong type

        with self.assertRaises(TypeError):
            pk.compute_checksum(byte_seq)

        # Check with tuple
        byte_seq = (0x01, (), 0x02, 0x2b, 0x01)      # wrong type

        with self.assertRaises(TypeError):
            pk.compute_checksum(byte_seq)
Пример #4
0
    def test_checksum_func_wrong_byte_value(self):
        """Check that the compute_checksum function fails when an item of the
        "byte_seq" argument has a wrong value (too low or too high)."""

        # Too low value
        byte_seq = (0x01, -1, 0x02, 0x2b, 0x01)      # wrong value

        with self.assertRaises(ValueError):
            pk.compute_checksum(byte_seq)

        # Too high value
        byte_seq = (0x01, 0xffff, 0x02, 0x2b, 0x01)  # wrong value

        with self.assertRaises(ValueError):
            pk.compute_checksum(byte_seq)
Пример #5
0
    def test_checksum_func_wrong_length_byte(self):
        """Check that the compute_checksum function fails when the "length"
        byte of the "byte_seq" argument has a wrong value (too low or too
        high).
        """

        # Too low value
        byte_seq = (1,)                # id
        byte_seq += (1,)               # wrong length
        byte_seq += (0x02, 0x2b, 0x01) # read the temperature of the dynamixel

        with self.assertRaises(ValueError):
            pk.compute_checksum(byte_seq)

        # Too high value
        byte_seq = (1,)                # id
        byte_seq += (9,)               # wrong length
        byte_seq += (0x02, 0x2b, 0x01) # read the temperature of the dynamixel

        with self.assertRaises(ValueError):
            pk.compute_checksum(byte_seq)
Пример #6
0
    def test_checksum_func_example1(self):
        """Check the "compute_checksum" function using the example 2 of the
        Dynamixel user guide: "Reading the internal temperature of the
        Dynamixel actuator with an ID of 1" (p.20)."""

        byte_seq = (1,)                # id
        byte_seq += (4,)               # length
        byte_seq += (0x02, 0x2b, 0x01) # read the temperature of the dynamixel

        checksum_byte = pk.compute_checksum(byte_seq)
        expected_checksum_byte = 0xcc

        self.assertEqual(checksum_byte, expected_checksum_byte)
Пример #7
0
    def test_checksum_func_good_arg_type(self):
        """Check the "compute_checksum" function using the example 2 of the
        Dynamixel user guide: "Reading the internal temperature of the
        Dynamixel actuator with an ID of 1" (p.20)."""

        # Check with a tuple
        byte_seq = (0x01, 0x04, 0x02, 0x2b, 0x01)

        checksum_byte = pk.compute_checksum(byte_seq)
        expected_checksum_byte = 0xcc

        self.assertEqual(checksum_byte, expected_checksum_byte)

        # Check with a list
        byte_seq = [0x01, 0x04, 0x02, 0x2b, 0x01]

        checksum_byte = pk.compute_checksum(byte_seq)
        expected_checksum_byte = 0xcc

        self.assertEqual(checksum_byte, expected_checksum_byte)

        # Check with a bytes string
        byte_seq = bytes((0x01, 0x04, 0x02, 0x2b, 0x01))

        checksum_byte = pk.compute_checksum(byte_seq)
        expected_checksum_byte = 0xcc

        self.assertEqual(checksum_byte, expected_checksum_byte)

        # Check with a bytearray
        byte_seq = bytearray((0x01, 0x04, 0x02, 0x2b, 0x01))

        checksum_byte = pk.compute_checksum(byte_seq)
        expected_checksum_byte = 0xcc

        self.assertEqual(checksum_byte, expected_checksum_byte)
Пример #8
0
    def __init__(self, packet):

        # Check the argument and convert it to "bytes" if necessary.
        # Assert "packet" items are in range (0, 0xff).
        # "TypeError" and "ValueError" are sent by the "bytes" constructor if
        # necessary.
        # The statement "tuple(packet)" implicitely rejects integers (and all
        # non-iterable objects) to compensate the fact that the bytes
        # constructor doesn't reject them: bytes(6) is valid and returns
        # b'\x00\x00\x00'.
        self._bytes = bytes(tuple(packet))

        # Assert the argument is a sequence with at least 6 items.
        if len(self._bytes) < 6:
            raise ValueError("Incomplete packet.")

        # Check the header bytes.
        # Should be tested before the length and checksum because if the header
        # is wrong then the length and the checksum are wrong too (thus testing
        # the header first gives a more relevant information when its value is
        # wrong).
        if bytes(self.header) != b'\xff\xff':
            raise ValueError("Wrong header (should be b'\xff\xff').")

        # Check length (length = num_params + 2 = full_packet_length - 4).
        # Should be tested before the checksum because if the length is wrong
        # then the checksum is wrong too (thus testing the length first gives a
        # more relevant information when its value is wrong).
        if self.length != len(self._bytes) - 4:
            raise ValueError('Wrong length byte.')

        # Verify the checksum.
        computed_checksum = pk.compute_checksum(self._bytes[2:-1])
        if computed_checksum != self.checksum:
            raise StatusChecksumError('Wrong checksum.')

        # Check error bit flags.
        if self.instruction_error:
            raise InstructionError()

        if self.overload_error:
            raise OverloadError()

        if self.checksum_error:
            raise InstructionChecksumError()

        if self.range_error:
            raise RangeError()

        if self.overheating_error:
            raise OverheatingError()

        if self.angle_limit_error:
            raise AngleLimitError()

        if self.input_voltage_error:
            raise InputVoltageError()

        # Check the ID byte
        if not(0x00 <= self.dynamixel_id <= 0xfd):
            msg = "Wrong dynamixel_id, a value in range (0, 0xFD) is required."
            raise ValueError(msg)
Пример #9
0
    def __init__(self, dynamixel_id, instruction, parameters=None):

        # Check the parameters byte.
        # "TypeError" and "ValueError" are raised by the "bytes" constructor if
        # necessary.
        # The statement "tuple(parameters)" implicitely rejects integers (and
        # all non-iterable objects) to compensate the fact that the bytes
        # constructor doesn't reject them: bytes(3) is valid and returns
        # b'\x00\x00\x00'.
        if parameters is None:
            parameters = bytes()
        else:
            parameters = bytes(tuple(parameters))

        # Add the header bytes.
        self._bytes = bytearray((0xff, 0xff))

        # Check and add the Dynamixel ID byte.
        # "TypeError" and "ValueError" are raised by the "bytearray.append()"
        # if necessary.
        if 0x00 <= dynamixel_id <= 0xfe:
            self._bytes.append(dynamixel_id)
        else:
            if isinstance(dynamixel_id, int):
                msg = ("Wrong dynamixel_id value, "
                       "an integer in range(0x00, 0xfe) is required.")
                raise ValueError(msg)
            else:
                raise TypeError("Wrong dynamixel_id type (integer required).")

        # Add the length byte.
        self._bytes.append(len(parameters) + 2)

        # Check and add the instruction byte.
        # "TypeError" and "ValueError" are raised by the "bytearray.append()"
        # if necessary.
        if instruction in INSTRUCTIONS:
            self._bytes.append(instruction)
        else:
            if isinstance(instruction, int):
                msg = "Wrong instruction, should be in ({})."
                instructions_str = utils.pretty_hex_str(INSTRUCTIONS)
                raise ValueError(msg.format(instructions_str))
            else:
                raise TypeError("Wrong instruction type (integer required).")

        # Check and add the parameter bytes.
        nb_param_min = NUMBER_OF_PARAMETERS[self.instruction]['min']
        nb_param_max = NUMBER_OF_PARAMETERS[self.instruction]['max']

        if nb_param_min <= len(parameters) <= nb_param_max:
            self._bytes.extend(parameters)
        else:
            msg = ("Wrong number of parameters: {} parameters "
                   "(min expected={}; max expected={}).")
            nb_param = len(parameters)
            raise ValueError(msg.format(nb_param, nb_param_min, nb_param_max))

        # Add the checksum byte.
        computed_checksum = pk.compute_checksum(self._bytes[2:])
        self._bytes.append(computed_checksum)
Пример #10
0
    def __init__(self, dynamixel_id, instruction, parameters=None):

        # Check the parameters byte.
        # "TypeError" and "ValueError" are raised by the "bytes" constructor if
        # necessary.
        # The statement "tuple(parameters)" implicitely rejects integers (and
        # all non-iterable objects) to compensate the fact that the bytes
        # constructor doesn't reject them: bytes(3) is valid and returns
        # b'\x00\x00\x00'.
        if parameters is None:
            parameters = bytes()
        else:
            parameters = bytes(tuple(parameters))

        # Add the header bytes.
        self._bytes = bytearray((0xff, 0xff))

        # Check and add the Dynamixel ID byte.
        # "TypeError" and "ValueError" are raised by the "bytearray.append()"
        # if necessary.
        if 0x00 <= dynamixel_id <= 0xfe:
            self._bytes.append(dynamixel_id)
        else:
            if isinstance(dynamixel_id, int):
                msg = ("Wrong dynamixel_id value, "
                       "an integer in range(0x00, 0xfe) is required.")
                raise ValueError(msg)
            else:
                raise TypeError("Wrong dynamixel_id type (integer required).")

        # Add the length byte.
        self._bytes.append(len(parameters) + 2)

        # Check and add the instruction byte.
        # "TypeError" and "ValueError" are raised by the "bytearray.append()"
        # if necessary.
        if instruction in INSTRUCTIONS:
            self._bytes.append(instruction)
        else:
            if isinstance(instruction, int):
                msg = "Wrong instruction, should be in ({})."
                instructions_str = utils.pretty_hex_str(INSTRUCTIONS)
                raise ValueError(msg.format(instructions_str))
            else:
                raise TypeError("Wrong instruction type (integer required).")

        # Check and add the parameter bytes.
        nb_param_min = NUMBER_OF_PARAMETERS[self.instruction]['min']
        nb_param_max = NUMBER_OF_PARAMETERS[self.instruction]['max']

        if nb_param_min <= len(parameters) <= nb_param_max:
            self._bytes.extend(parameters)
        else:
            msg = ("Wrong number of parameters: {} parameters "
                   "(min expected={}; max expected={}).")
            nb_param = len(parameters)
            raise ValueError(msg.format(nb_param, nb_param_min, nb_param_max))

        # Add the checksum byte.
        computed_checksum = pk.compute_checksum(self._bytes[2:])
        self._bytes.append(computed_checksum)
Пример #11
0
    def test_checksum_func_wrong_arg_type(self):
        """Check that the compute_checksum function fails when the
        "byte_seq" argument has a wrong type."""

        # Check with None
        byte_seq = None                              # wrong type

        with self.assertRaises(TypeError):
            pk.compute_checksum(byte_seq)

        # Check with an integer
        byte_seq = 0                                 # wrong type

        with self.assertRaises(TypeError):
            pk.compute_checksum(byte_seq)

        # Check with an integer
        byte_seq = 1                                 # wrong type

        with self.assertRaises(TypeError):
            pk.compute_checksum(byte_seq)

        # Check with an integer
        byte_seq = 3                                 # wrong type

        with self.assertRaises(TypeError):
            pk.compute_checksum(byte_seq)

        # Check with a float
        byte_seq = 1.0                               # wrong type

        with self.assertRaises(TypeError):
            pk.compute_checksum(byte_seq)

        # Check with a string
        byte_seq = "hello"                           # wrong type

        with self.assertRaises(TypeError):
            pk.compute_checksum(byte_seq)