Table of Contents

Lidar

Necessary knowledge: [HW] Communication Module, [HW] User Interface Module, [LIB] Serial Interface, [LIB] Graphic LCD, [LIB] Sensors

Theory

SICK Laser Rangefinder (LIDAR)

LIDAR (Light Detection and Ranging) is an optical remote sensing system which can measure the distance of a target by illuminating it with light. LIDAR technology is being used in Robotics for the perception of the environment as well as object classification. The ability of LIDAR technology to provide 2D elevation maps of the terrain, high precision distance to the ground, and approach velocity can enable safe landing of robotic and manned vehicles with a high degree of precision.

Lidar consists of a transmitter which illuminates a target with a laser beam, and a receiver capable of detecting the component of light which is essentially coaxial with the transmitted beam. Receiver sensors calculate a distance, based on the time needed for the light to reach the target and return. A mechanical mechanism with a mirror sweeps the light beam to cover the required scene in a plane or even in three dimensions, using a rotating nodding mirror.

One way to measure the time of flight for the light beam is to use a pulsed laser and then measure the elapsed time directly. Electronics capable of resolving picoseconds are required in such devices and they are therefore very expensive. Another method is to measure the phase shift of the reflected light.

Working principle

Collimated infrared laser is used to the phase-shift measurement. For surfaces, having a roughness greater than the wavelength of the incident light, diffuse reflection will occur. The component of the infrared light will return almost parallel to the transmitted beam for objects.

Phase-shift measurement

The sensor measures the phase shift between the transmitted and reflected signals. The picture shows how this technique can be used to measure distance. The wavelength of the modulating signal obeys the equation:

c = f ∙ τ

where c is the speed of light and f the modulating frequency and τ the known modulating wavelength.

The total distance D' covered by the emitted light is:

D' = B + 2A = B + (θ * τ) / 2π

where A is the measured distance. B is the distance from the phase measurement unit. The required distance D, between the beam splitter and the target, is therefore given by

D = τ * θ / 4π

where θ is the electronically measured phase difference between the transmitted and reflected light beams.

It can be shown that the range is inversely proportional to the square of the received signal amplitude, directly affecting the sensor’s accuracy.

Practice

Map created by Lidar

In autonomous robotics as well as industrial robotics SICK laser rangers are very widely used. The SICK LMS 200 can easily be interfaced through RS-232 or RS-422, providing distance measurements over a 180 degree area up to 80 meters away. This lidar is based on a time-of-flight measurement principle. The example output of one scan measurement result is shown in the picture on the right.

Connection diagram

To make the SICK operational, it must be wired for power and communication. On the back of the SICK there are two connectors that looks like serial port connectors. The connector with the female end is for power and the connector with the male end is for communications. The power and the serial cable should be wired as shown in the picture. Lidar can be connected with Robotic HomeLab Communication module using one of the RS-232 connectors. Power must be taken from external power source and this is not included in Robotic HomLab kit. Required dc power voltage is 24 V.

The SICK receives commands as streams of bytes through the serial port. When transmitting data, it sends back streams of bytes corresponding to distance measurements at a given angle.

To grab data from the SICK, you must first send a start string to tell the sensor to start sending data. This string is:

Hexadecimal Form: 02 00 02 00 20 24 34 08

Decimal Form: 2 0 2 0 32 36 52 8

If the start string is successfully sent, Lidar will begin streaming data over RS232. Incoming data from a scan is sent sequentially as the sensor scans through 180°. For example if the sensor is set to scan 180° with resolution of 0.5° the first data point which was sent will correspond to 0°, the next will correspond to 0.5°, the following to 1°, and so on. This means there is total of 361 data points. Each distance measurement is sent in the form of two bytes. The least signifficant byte is sent first followed by the most signifficant byte. Operating in metric mode the unit for the measurements is in milimeters.

Finally to stop the sensor from sending data a stop string must be sent. This string is:

Hexadecimal Form: 02 00 02 00 20 25 35 08

Decimal Form: 2 0 2 0 32 37 53 8

Following example shows how to initiate Lidar and get the count of package.

#include <stdio.h>
#include <homelab/delay.h>
#include <homelab/pin.h>
#include <homelab/module/lcd_gfx.h>
#include <homelab/usart.h>
 
// Defining USART interface.
usart port = USART(0);
 
// Defining button pins.
pin button1 = PIN(C, 0);
pin button2 = PIN(C, 1);
 
// Initialize
static inline void init()
{
	// Setting buttons pins as inputs.
	pin_setup_input_with_pullup(button1);
	pin_setup_input_with_pullup(button2);
 
	// Set-up of the LCD.
	lcd_gfx_init();
 	// Cleaning the screen.
	lcd_gfx_clear();
 	// Switching on the background light.
	lcd_gfx_backlight(true);	
 	// Displaying the name of the program.
	lcd_gfx_goto_char_xy(3, 1);
	lcd_gfx_write_string("Lidar");
 
	// The set-up of the USART interface.
	usart_init_async
	(
		port,
		USART_DATABITS_8,
		USART_STOPBITS_ONE,
		USART_PARITY_NONE,
		USART_BAUDRATE_ASYNC(9600)
	);		
}
 
// Main program
int main(void)
{	
	unsigned char new_value1, new_value2, old_value1 = 0, old_value2 = 0;
 
	char c;
	int i = 0;
	int count = 0;
	char text[16];
 
	// Initialize
	init();	
 
	// Endless cycle
	while (1)
	{	 
		// Reads buttons states
		new_value1 = pin_get_debounced_value(button1);
		new_value2 = pin_get_debounced_value(button2);
 
		// Button S1 is pressed.
		if((!new_value1) && (old_value1))
		{	
			//Send "02 00 02 00 20 24 34 08" to start scanning.
 
			usart_send_char(port, 0x02);
			usart_send_char(port, 0x00);
			usart_send_char(port, 0x02);
			usart_send_char(port, 0x00);
			usart_send_char(port, 0x20);
			usart_send_char(port, 0x24);
			usart_send_char(port, 0x34);
			usart_send_char(port, 0x08);
		}
 
		// Button S2 is pressed.
		if((!new_value2) && (old_value2))
		{
			//Send "0x 02 00 02 00	20 25 35 08" to stop scanning.
			usart_send_char(port, 0x02);
			usart_send_char(port, 0x00);
			usart_send_char(port, 0x02);
			usart_send_char(port, 0x00);
			usart_send_char(port, 0x20);
			usart_send_char(port, 0x25);
			usart_send_char(port, 0x35);
			usart_send_char(port, 0x08);				
		}
 
		// Remembers the last keys values.
		old_value1 = new_value1;
		old_value2 = new_value2;
 
		// Try to read serial port
		if (usart_try_read_char(port, &c))
		{
			// Find a header "0x 02 81 D6 02 B0 69 41"
			// Very basic package start search.	
			if(c == 0x02) i++;
			if(c == 0x81) i++;			
			if(c == 0xD6) i++;			
			if(c == 0x02) i++;			
			if(c == 0xB0) i++;			
			if(c == 0x69) i++;			
			if(c == 0x41) i++;
 
			//If there is an header
			if(i >= 7)
			{
				//Increse packet counter
				count++;
 
				//Displaying packet count on the LCD.
				lcd_gfx_goto_char_xy(0, 3);
 
				sprintf(text, "Pakette: %i", count);
 
				lcd_gfx_write_string(text);
 
				i=0;
			}
		}					
	}
}