RPLidar (rplidar v0.1.0)

Module for interfacing with the RPLidar A1/A2/A3 family of 360-degree LiDAR sensors. The RPLidar module is a GenServer that handles communication to and from the LiDAR device via a UART connection and an optional GPIO for motor control.

Once connected and started, this process will send messages to the parent process (or a designated process) the decoded data received from the sensor.

basic-usage

Basic Usage

Once the RPLidar process is started, calling enable_motor will start the motor spinning and calling start_scan will start to receive and decode the packets from the sensor. The calling process (or a PID passed to the start_link function) will start to receive :lidar_packet messages as each one is received from the sensor. These packets contain the decoded information for each sensed point in the format {:lidar_packet, angle, range, quality, received_at}:

  • angle - angle in degrees clockwise that the sensor was pointing when the point was sensed
  • range - range measurement at the given angle in millimeters
  • quality - quality measure of the laser return where 0 is no return and 255 is a full laser return
  • received_at - the value of System.monotonic_time() when the packet was received
def init(_) do
  {:ok, pid} = RPLidar.start_link(uart_device: "ttyS0", motor_enable_pin: 18)

  :ok = RPLidar.enable_motor(pid)
  :ok = RPLidar.start_scan(pid)
  # ...
end

def handle_info({:lidar_packet, angle, range, quality, received_at}, state) do
  # ...
  {:noreply, state}
end

To convert from angle and range to (x,y) coordinates (in meters):

r = angle * Math.pi() / 180.0
d = range / 1000
x = :math.sin(r) * d
y = :math.cos(r) * d

Link to this section Summary

Functions

Returns a specification to start this module under a supervisor.

Disables the motor.

Enable the motor (sets the GPIO selected with the motor_enable_pin option to HIGH, which starts the motor spinning.

After start_scan/1 is called, calling this function will force the device to send measurements without waiting for the motor to reach a threshold RPM.

Polls the device for hardware and firmware info

Resets the device.

Starts the RPLidar process.

Signals the device to start sending measurements.

Signals the device to stop sending measurements.

Link to this section Functions

Link to this function

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

Link to this function

disable_motor(pid)

@spec disable_motor(GenServer.server()) :: :ok

Disables the motor.

Link to this function

enable_motor(pid)

@spec enable_motor(GenServer.server()) :: :ok

Enable the motor (sets the GPIO selected with the motor_enable_pin option to HIGH, which starts the motor spinning.

Note that the datasheet for the RPLidar A1 requires the motor enable pin to be set to the VIN voltage of the motor. In cases where you are supplying, a voltage separate from the voltage of the GPIO pins of your device, you will have to enable the motor in a different way.

Link to this function

force_scan(pid)

@spec force_scan(GenServer.server()) :: :ok

After start_scan/1 is called, calling this function will force the device to send measurements without waiting for the motor to reach a threshold RPM.

@spec get_info(GenServer.server()) :: RPLidar.Comm.info()

Polls the device for hardware and firmware info

@spec reset(GenServer.server()) :: :ok

Resets the device.

Link to this function

start_link(opts \\ [])

@spec start_link(keyword()) :: GenServer.on_start()

Starts the RPLidar process.

options

Options

  • uart_device - UART port to which the LiDAR is connected
  • motor_enable_pin - GPIO pin for controlling the motor on the LiDAR sensor
  • filter - if set to true, points with range of 0.0 or a quailty of 0 will be dropped before sending to the receiving process. (default: false)
  • parent - the PID to send points to (default: self())
Link to this function

start_scan(pid)

@spec start_scan(GenServer.server()) :: :ok

Signals the device to start sending measurements.

Note: Using the normal scan command, the device won't send any measurements until the sensor motor reaches a minimum RPM. Therefore if you call enable_motor/1 after or just before calling start_scan/1, there may be a delay before data is received by the parent process. To start sending measurements immediately regardless of motor speed, call force_scan/1 after calling start_scan/1.

@spec stop_scan(GenServer.server()) :: :ok

Signals the device to stop sending measurements.