yura/rplidar

View on GitHub
lib/rplidar/response_descriptor.rb

Summary

Maintainability
A
0 mins
Test Coverage
module Rplidar
  DATA_TYPE_DEVICE_INFO   = 0x4
  DATA_TYPE_CURRENT_STATE = 0x6
  DATA_TYPE_SCAN          = 0x81

  SEND_MODE_SINGLE_REQUEST_SINGLE_RESPONSE   = 0x0
  SEND_MODE_SINGLE_REQUEST_MULTIPLE_RESPONSE = 0x1

  # Incapsulates Response Descriptor processing. Format of Response Descriptor:
  #
  # Start Flag 1   Start Flag 2    Data Response Length  Send Mode  Data Type
  # 1 byte (0xA5)  1 bytes (0x5A)  30 bits               2 bits     1 byte
  class ResponseDescriptor < Response
    def check_response
      check_header
      check_payload
    end

    def check_header
      unless correct_first_byte?
        raise 'Wrong first byte of the response descriptor: ' \
          "'#{int_to_hex(raw_response[0])}'"
      end

      unless correct_second_byte?
        raise 'Wrong second byte of the response descriptor: ' \
          "'#{int_to_hex(raw_response[1])}'"
      end
    end

    def check_payload
      unless correct_send_mode?
        raise 'Wrong send mode value of the response descriptor: ' \
          "'#{int_to_hex(send_mode)}'"
      end

      unless correct_data_type?
        raise 'Wrong data type value of the response descriptor: ' \
          "'#{int_to_hex(data_type)}'"
      end
    end

    def correct_first_byte?
      raw_response[0] == 0xA5
    end

    def correct_second_byte?
      raw_response[1] == 0x5A
    end

    def correct_send_mode?
      [
        SEND_MODE_SINGLE_REQUEST_SINGLE_RESPONSE,
        SEND_MODE_SINGLE_REQUEST_MULTIPLE_RESPONSE
      ].include?(send_mode)
    end

    def correct_data_type?
      [
        DATA_TYPE_DEVICE_INFO, DATA_TYPE_CURRENT_STATE, DATA_TYPE_SCAN
      ].include?(data_type)
    end

    def data_response_length
      (raw_response[4] << 16) + (raw_response[3] << 8) + raw_response[2]
    end

    # The 2 bits Send Mode field describes the request/response mode
    # of the current session. Values:
    # * 0x0 - Single Request - Single Response mode, RPLIDAR will send
    #         only one data response packet in the current session.
    # * 0x1 - Single Request - Multiple Response mode, RPLIDAR will
    #         continuously send out data response packets with the same format
    #         in the current session.
    # * 0x2 and 0x3 are reserved for future use
    def send_mode
      raw_response[5] >> 6
    end

    # The 1byte Data Type describes the type of the incoming
    # data response packets.
    def data_type
      raw_response[6]
    end

    def response
      {
        data_response_length: data_response_length,
        send_mode: send_mode,
        data_type: data_type
      }
    end

    private

    def int_to_hex(value)
      if value
        "0x#{value.to_s(16).upcase}"
      else
        value.inspect
      end
    end
  end
end