Ejemplo n.º 1
0
    def get_height_filter(self):
        """
        Gets the height filter applied to the readings.
        The units of this filter are those set by :meth:`set_units`

        :return: The height filter

            .. code-block:: python

                {"minimum": minimum,
                "maximum": maximum}

        :rtype: dict
        """
        try:
            self._send(pack("<BB", 0x12, 0x00))
            res = unpack("<BBhh", self._read())
            if res[0] == 0x12 and res[1] == 0x01:
                minimum = units.convert_distance_from_si(
                    self.distance_units, res[2] / 1000)
                maximum = units.convert_distance_from_si(
                    self.distance_units, res[3] / 1000)
                return {"minimum": minimum, "maximum": maximum}
            else:
                raise Exception("Invalid response")
        except Exception:
            raise Exception("Failed to get height filter")
Ejemplo n.º 2
0
    def set_angle_filter(self, minimum, maximum):
        """
        Sets the angle filter to apply to the readings (in degrees).

        0 degrees is center, negative angles are to the left of the sensor, positive angles are to the right.


        :param minimum: The minimum angle (-60 to +60)
        :type minimum: int
        :param maximum: The maximum angle (-60 to +60)
        :type maximum: int
        """
        if not (isinstance(minimum, int) and -55 <= minimum <= 55):
            raise ValueError(
                "Angle filter minimum must be an integer between -55 and +55")

        if not (isinstance(maximum, int) and -55 <= maximum <= 55):
            raise ValueError(
                "Angle filter maximum must be an integer between -55 and +55")

        if maximum < minimum:
            raise ValueError(
                "Angle filter maximum must be greater than the minimum")

        try:
            self._send(pack("<BBbb", 0x07, 0x02, minimum, maximum))
            res = unpack("<BBbb", self._read())
            if res[0] == 0x07 and res[1] == 0x01:
                return True
            else:
                raise Exception("Invalid response")
        except Exception:
            raise Exception("Failed to get angle filter")
Ejemplo n.º 3
0
    def set_auto_start(self, auto_start):
        """
        Sets the auto start settings.

        Auto start immediately starts the RadarIQ sensor on power on.

        :param auto_start: The auto start setting (True or False)
        :type auto_start: bool
        """

        if not isinstance(auto_start, bool):
            raise ValueError("Auto start must be a boolean")

        try:
            self._send(pack("<BBB", 0x17, 0x02, int(auto_start)))
            res = unpack("<BBB", self._read())
            if res[0] == 0x17 and res[1] == 0x01:
                if res[2] == int(auto_start):
                    return True
                else:
                    raise Exception("Auto start did not set correctly")
            else:
                raise Exception("Invalid response")
        except Exception:
            raise Exception("Failed to set auto start")
Ejemplo n.º 4
0
    def set_frame_rate(self, frame_rate):
        """
        Sets the frequency with which to capture frames of data.

        :param frame_rate: The frame rate frames/second)
        :type frame_rate: int
        """

        if not isinstance(frame_rate, int):
            raise ValueError("Frame rate must be an integer")

        if not 0 <= frame_rate <= 20:
            raise ValueError("Frame rate must be between 0 and 20 fps")

        try:
            self._send(pack("<BBB", 0x04, 0x02, frame_rate))
            res = unpack("<BBB", self._read())
            if res[0] == 0x04 and res[1] == 0x01:
                if res[2] == frame_rate:
                    return True
                else:
                    raise Exception("Frame rate did not set correctly")
            else:
                raise Exception("Invalid response")
        except Exception:
            raise Exception("Failed to set frame rate")
Ejemplo n.º 5
0
    def start(self, samples=0, clear_buffer=True):
        """
        Start to capture data into the queue. To fetch data use get_data() and to stop capture call stop_capture().

        When capturing data in a non-continuous mode. The data capture will automatically stop once the number of
        samples has been received.

        :param samples: The number of samples to capture (0 = continuous)
        :type samples: int
        :param clear_buffer: When set any data currently on the buffer will be cleared before beginning capture
        :type clear_buffer: bool
        """
        try:
            if clear_buffer is True:
                self.connection.emtpy_queue()
                self.data_queue.empty()
            self._send(pack("<BBB", 0x64, 0x00, samples))
            self.is_capturing = True
            t = threading.Thread(target=self._get_data_thread)
            t.start()
            self.capture_max = samples
            self.capture_count = 0

        except Exception:
            raise Exception("Failed to start data capture")
Ejemplo n.º 6
0
    def get_radar_application_versions(self):
        """
        Gets the version of the radar applications.

        :return: The radar application versions
        :rtype: dict
        """
        try:
            data = {
                'controller': ['', 0, 0, 0],
                'application_1': ['', 0, 0, 0],
                'application_2': ['', 0, 0, 0],
                'application_3': ['', 0, 0, 0],
            }
            self._send(pack("<BBB", 0x14, 0x00, 0x01))
            res = unpack("<BBB20sBBH", self._read())  # Slot 1
            if res[0] == 0x14 and res[1] == 0x01 and res[2] == 1:
                data['controller'] = [
                    res[3].decode().rstrip('\x00'), res[4], res[5], res[6]
                ]

            self._send(pack("<BBB", 0x14, 0x00, 0x02))
            res = unpack("<BBB20sBBH", self._read())  # Slot 2
            if res[0] == 0x14 and res[1] == 0x01 and res[2] == 2:
                data['application_1'] = [
                    res[3].decode().rstrip('\x00'), res[4], res[5], res[6]
                ]

            self._send(pack("<BBB", 0x14, 0x00, 0x03))
            res = unpack("<BBB20sBBH", self._read())  # Slot 3
            if res[0] == 0x14 and res[1] == 0x01 and res[2] == 3:
                data['application_2'] = [
                    res[3].decode().rstrip('\x00'), res[4], res[5], res[6]
                ]

            self._send(pack("<BBB", 0x14, 0x00, 0x04))
            res = unpack("<BBB20sBBH", self._read())  # Slot 4
            if res[0] == 0x14 and res[1] == 0x01 and res[2] == 4:
                data['application_3'] = [
                    res[3].decode().rstrip('\x00'), res[4], res[5], res[6]
                ]

            return data
        except Exception as err:
            raise Exception("Failed to get radar versions")
Ejemplo n.º 7
0
 def stop(self):
     """
     Stops capturing of data.
     """
     try:
         self._send(pack("<BB", 0x65, 0x00))
     except Exception:
         raise Exception("Failed to stop data capture")
     self.is_capturing = False
Ejemplo n.º 8
0
 def save(self):
     """
     Saves the settings to the sensor.
     """
     try:
         self._send(pack("<BB", 0x09, 0x02))
         res = unpack("<BB", self._read())
         if res[0] == 0x09 and res[1] == 0x01:
             return True
         else:
             raise Exception("Invalid response")
     except Exception:
         raise Exception("Failed to save settings")
Ejemplo n.º 9
0
    def get_point_density(self):
        """
        Gets the point density setting.

        :return: Point density. See `Point Density Options`_
        :rtype: int
        """
        try:
            self._send(pack("<BB", 0x10, 0x00))
            res = unpack("<BBB", self._read())
            if res[0] == 0x10 and res[1] == 0x01:
                return res[2]
            else:
                raise Exception("Invalid response")
        except Exception:
            raise Exception("Failed to get point density setting")
Ejemplo n.º 10
0
    def get_moving_filter(self):
        """
        Gets the moving objects filter applied to the readings.

        :return: moving filter. See `Moving filter`_
        :rtype: str
        """
        try:
            self._send(pack("<BB", 0x08, 0x00))
            res = unpack("<BBB", self._read())
            if res[0] == 0x08 and res[1] == 0x01:
                return res[2]
            else:
                raise Exception("Invalid response")
        except Exception:
            raise Exception("Failed to get moving filter")
Ejemplo n.º 11
0
    def get_object_type_mode(self):
        """
        Gets the object type mode from the sensor.

        :return: The object type mode. See `Object Type Modes`_
        :rtype: int
        """
        try:
            self._send(pack("<BB", 0x16, 0x00))
            res = unpack("<BBB", self._read())
            if res[0] == 0x16 and res[1] == 0x01:
                return res[2]
            else:
                raise Exception("Invalid response")
        except Exception:
            raise Exception("Failed to get object type mode")
Ejemplo n.º 12
0
    def scene_calibration(self):
        """
        Calibrate the sensor to remove any near-field objects from the scene.

        This is useful to:
        * Remove effects of an enclosure
        * Hide static objects directly in front of the sensor

        To use this feature, mount the sensor, ensure that there are no objects within 1m of the sensor then run
        :meth:`scene_calibration`. Once run the scene calibration will be saved to the sensor
        """
        try:
            self._send(pack("<BB", 0x15, 0x02))
            _ = self._read()
        except Exception:
            raise Exception("Failed to perform scene calibration")
Ejemplo n.º 13
0
    def get_auto_start(self):
        """
        Gets the autostart setting.

        :return: True or False
        :rtype: bool
        """
        try:
            self._send(pack("<BB", 0x17, 0x00))
            res = unpack("<BBB", self._read())
            if res[0] == 0x17 and res[1] == 0x01:
                return bool(res[2])
            else:
                raise Exception("Invalid response")
        except Exception:
            raise Exception("Failed to get auto start")
Ejemplo n.º 14
0
    def get_mode(self):
        """
        Gets the capture mode from the sensor.

        :return: The capture mode. See `Capture Modes`_
        :rtype: int
        """
        try:
            self._send(pack("<BB", 0x05, 0x00))
            res = unpack("<BBB", self._read())
            if res[0] == 0x05 and res[1] == 0x01:
                return res[2]
            else:
                raise Exception("Invalid response")
        except Exception:
            raise Exception("Failed to get mode")
Ejemplo n.º 15
0
    def get_frame_rate(self):
        """
        Gets the frequency with which to capture frames of data (frames/second) from the sensor.

        :return: The frame rate as it is set in the sensor
        :rtype: int
        """
        try:
            self._send(pack("<BB", 0x04, 0x00))
            res = unpack("<BBB", self._read())
            if res[0] == 0x04 and res[1] == 0x01:
                return res[2]
            else:
                raise Exception("Invalid response")
        except Exception:
            raise Exception("Failed to get frame rate")
Ejemplo n.º 16
0
    def get_sensitivity(self):
        """
        Get the point sensitivity setting.

        :return: Sensitivity setting. See `Sensitivity values`_.
        :rtype: int
        """
        try:
            self._send(pack("<BB", 0x11, 0x00))
            res = unpack("<BBB", self._read())
            if res[0] == 0x11 and res[1] == 0x01:
                return res[2]
            else:
                raise Exception("Invalid response")
        except Exception:
            raise Exception("Failed to get sensitivity setting")
Ejemplo n.º 17
0
    def encode(self, src):
        """
        Encodes data from src.
        Adds header and footer to bytes to start and end of packet respectively.
        Escapes any header, footer or escape bytes.
        Does not support messages over 255.

        :param src Data needing to be encoded
        :type src: bytes
        :return: Encoded packet
        :rtype: bytes
        """

        # Add CRC to the source string (so it can be encoded)
        crc = self.crc16_ccitt(src)
        src += pack("<H", crc)
        src_idx = 0

        # Add packet header
        dest = PACKET_HEAD_BYTES
        # Loop through data, check for footer bytes in data and escape them
        while src_idx <= len(src):
            char = src[src_idx:src_idx + 1]
            if char == PACKET_HEAD_BYTES:
                dest += PACKET_ESC_BYTES
                dest += int_to_bytes(PACKET_HEAD ^ PACKET_XOR)

            elif char == PACKET_FOOT_BYTES:
                dest += PACKET_ESC_BYTES
                dest += int_to_bytes(PACKET_FOOT ^ PACKET_XOR)

            elif char == PACKET_ESC_BYTES:
                dest += PACKET_ESC_BYTES
                dest += int_to_bytes(PACKET_ESC ^ PACKET_XOR)

            else:
                dest += char
            src_idx += 1

        # Add the packet footer
        dest += PACKET_FOOT_BYTES

        if len(dest) > 255:
            raise Exception(
                "Encoded packet is greater than the maximum of 255 bytes")

        return dest
Ejemplo n.º 18
0
    def get_version(self):
        """
        Gets the version of the hardware and firmware.

        :return: The sensor version (firmware and hardware)
        :rtype: dict
        """
        try:
            self._send(pack("<BB", 0x01, 0x00))
            res = unpack("<BBBBHBBH", self._read())
            if res[0] == 0x01 and res[1] == 0x01:
                return {"firmware": list(res[2:5]), "hardware": list(res[5:8])}
            else:
                raise Exception("Invalid response")

        except Exception:
            raise Exception("Failed to get version")
Ejemplo n.º 19
0
    def get_serial_number(self):
        """
        Gets the serial of the sensor.

        :return: The sensors serial number
        :rtype: str
        """
        try:
            self._send(pack("<BB", 0x02, 0x00))
            res = unpack("<BBLL", self._read())
            if res[0] == 0x02 and res[1] == 0x01:
                return "{}-{}".format(res[2], res[3])
            else:
                raise Exception("Invalid response")

        except Exception:
            raise Exception("Failed to get serial")
Ejemplo n.º 20
0
    def reset(self, code):
        """
        Resets the sensor.

        :param code: The reset code. See `Reset codes`_
        :type code: int
        """
        if not 0 <= code <= 1:
            raise ValueError("Invalid reset code")

        try:
            self._send(pack("<BBB", 0x03, 0x02, code))
            res = unpack("<BB", self._read())
            if res[0] == 0x03 and res[1] == 0x01:
                return True
            else:
                raise Exception("Invalid response")
        except Exception:
            raise Exception("Failed to reset sensor")
Ejemplo n.º 21
0
    def set_distance_filter(self, minimum, maximum):
        """
        Sets the distance filter applied to the readings.

        :param minimum: The minimum distance (in units as specified by :meth:`set_units`)
        :type minimum: number
        :param maximum: The maximum distance (in units as specified by :meth:`set_units`)
        :type maximum: number
        """
        minimum = int(
            units.convert_distance_to_si(self.distance_units, minimum) * 1000)
        maximum = int(
            units.convert_distance_to_si(self.distance_units, maximum) * 1000)

        if not (isinstance(minimum, int) and 0 <= minimum <= 10000):
            raise ValueError(
                "Distance filter minimum must be a number between 0 and 10000mm"
            )

        if not (isinstance(maximum, int) and 0 <= maximum <= 10000):
            raise ValueError(
                "Distance filter maximum must be a number between 0 and 10000mm"
            )

        if maximum < minimum:
            raise ValueError(
                "Distance filter maximum must be greater than the minimum")

        try:
            self._send(pack("<BBHH", 0x06, 0x02, minimum, maximum))
            res = unpack("<BBHH", self._read())
            if res[0] == 0x06 and res[1] == 0x01:
                if res[2] == minimum and res[3] == maximum:
                    return True
                else:
                    raise Exception("Distance filter did not set correctly")
            else:
                raise Exception("Invalid response")
        except Exception:
            raise Exception("Failed to set distance filter")
Ejemplo n.º 22
0
    def set_moving_filter(self, moving):
        """
        Sets the moving filter to apply to the readings.

        :param moving: One of MOVING_BOTH, MOVING_OBJECTS_ONLY
        :type moving: int
        """

        if not (isinstance(moving, int) and 0 <= moving <= 1):
            raise ValueError("Moving filter value is invalid")
        try:
            self._send(pack("<BBB", 0x08, 0x02, moving))
            res = unpack("<BBB", self._read())
            if res[0] == 0x08 and res[1] == 0x01:
                if res[2] == moving:
                    return True
                else:
                    raise Exception("Moving filter did not set correctly")
            else:
                raise Exception("Invalid response")
        except Exception:
            raise Exception("Failed to set moving filter")
Ejemplo n.º 23
0
    def set_point_density(self, density):
        """
        Sets the point density setting.

        :param density: The point density to set. See `Point Density Options`_
        :type density: int
        """
        if not 0 <= density <= 2:
            raise ValueError("Invalid point density setting")

        try:
            self._send(pack("<BBB", 0x10, 0x02, density))
            res = unpack("<BBB", self._read())
            if res[0] == 0x10 and res[1] == 0x01:
                if res[2] == density:
                    return True
                else:
                    raise Exception("Point density did not set correctly")
            else:
                raise Exception("Invalid response")
        except Exception:
            raise Exception("Failed to set the point density")
Ejemplo n.º 24
0
    def set_mode(self, mode):
        """
        Sets the capture mode for the sensor.

        :param mode: See `Capture Modes`_
        :type mode: int
        :return: None
        """
        if not 0 <= mode <= 1:
            raise ValueError("Invalid mode")

        try:
            self._send(pack("<BBB", 0x05, 0x02, mode))
            res = unpack("<BBB", self._read())
            if res[0] == 0x05 and res[1] == 0x01:
                if res[2] == mode:
                    return True
                else:
                    raise Exception("Mode did not set correctly")
            else:
                raise Exception("Invalid response")
        except Exception:
            raise Exception("Failed to set mode")
Ejemplo n.º 25
0
    def get_angle_filter(self):
        """
        Gets the angle filter applied to the readings (in degrees).

        0 degrees is center, negative angles are to the left of the sensor, positive angles are to the right.

        :return: The angle filter.
         .. code-block:: python

            {"minimum": minimum,
             "maximum": maximum}

        :rtype: dict
        """
        try:
            self._send(pack("<BB", 0x07, 0x00))
            res = unpack("<BBbb", self._read())
            if res[0] == 0x07 and res[1] == 0x01:
                return {"minimum": res[2], "maximum": res[3]}
            else:
                raise Exception("Invalid response")
        except Exception:
            raise Exception("Failed to get angle filter")
Ejemplo n.º 26
0
    def set_sensitivity(self, sensitivity):
        """
        Sets the the sensitivity setting to apply to the readings.

        :param sensitivity: The sensitivity setting to set. See `Sensitivity values`_.
        :type sensitivity: int
        """
        if not (isinstance(sensitivity, int) and 0 <= sensitivity <= 9):
            raise ValueError("Sensitivity must be an integer between 0 and 9")

        try:
            self._send(pack("<BBB", 0x11, 0x02, sensitivity))
            res = unpack("<BBB", self._read())
            if res[0] == 0x11 and res[1] == 0x01:
                if res[2] == sensitivity:
                    return True
                else:
                    raise Exception(
                        "Sensitivity setting did not set correctly")
            else:
                raise Exception("Invalid response")
        except Exception:
            raise Exception("Failed to set the sensitivity setting")
Ejemplo n.º 27
0
    def set_object_type_mode(self, mode):
        """
        Sets the object type mode for the sensor.

        :param mode: See `Object Type Modes`_
        :type mode: int
        :return: None
        """
        if not 0 <= mode <= 1:
            raise ValueError("Invalid object type mode")

        try:
            self._send(pack("<BBB", 0x16, 0x02, mode))
            res = unpack("<BBB", self._read())
            if res[0] == 0x16 and res[1] == 0x01:
                if res[2] == mode:
                    return True
                else:
                    raise Exception(
                        "Object Tracking mode did not set correctly")
            else:
                raise Exception("Invalid response")
        except Exception:
            raise Exception("Failed to set object tracking mode")